[zircon] Add resizable vmo flag where necessary
This change is split out from a previous attempt to change the default
resize behavior. Once this change fully propagates, a second kernel-only
change can be submitted to flip the default behavior.
ZX-2357 #comment [zircon] Add resizable vmo flag where necessary
Change-Id: Ia4765cf19b0fcd60f2a6f8a7aa821542ae9f9df2
diff --git a/garnet/public/rust/fuchsia-zircon/fuchsia-zircon-sys/src/lib.rs b/garnet/public/rust/fuchsia-zircon/fuchsia-zircon-sys/src/lib.rs
index 84c701a..da73341 100644
--- a/garnet/public/rust/fuchsia-zircon/fuchsia-zircon-sys/src/lib.rs
+++ b/garnet/public/rust/fuchsia-zircon/fuchsia-zircon-sys/src/lib.rs
@@ -81,6 +81,7 @@
multiconst!(u32, [
ZX_VMO_NON_RESIZABLE = 1;
+ ZX_VMO_RESIZABLE = 1 << 1;
]);
// TODO: add an alias for this type in the C headers.
@@ -343,6 +344,7 @@
// VM Object clone flags
pub const ZX_VMO_CHILD_COPY_ON_WRITE: u32 = 1;
pub const ZX_VMO_CHILD_NON_RESIZEABLE: u32 = 1 << 1;
+pub const ZX_VMO_CHILD_RESIZABLE: u32 = 1 << 2;
// channel write size constants
pub const ZX_CHANNEL_MAX_MSG_HANDLES: u32 = 64;
diff --git a/garnet/public/rust/fuchsia-zircon/src/vmo.rs b/garnet/public/rust/fuchsia-zircon/src/vmo.rs
index 19a7dd8..ee0e316 100644
--- a/garnet/public/rust/fuchsia-zircon/src/vmo.rs
+++ b/garnet/public/rust/fuchsia-zircon/src/vmo.rs
@@ -146,6 +146,7 @@
#[repr(transparent)]
pub struct VmoOptions: u32 {
const NON_RESIZABLE = sys::ZX_VMO_NON_RESIZABLE;
+ const RESIZABLE = sys::ZX_VMO_RESIZABLE;
}
}
@@ -155,6 +156,7 @@
pub struct VmoChildOptions: u32 {
const COPY_ON_WRITE = sys::ZX_VMO_CHILD_COPY_ON_WRITE;
const NON_RESIZABLE = sys::ZX_VMO_CHILD_NON_RESIZEABLE;
+ const RESIZABLE = sys::ZX_VMO_CHILD_RESIZABLE;
}
}
@@ -199,7 +201,7 @@
fn vmo_set_size() {
// Use a multiple of page size to match VMOs page aligned size
let start_size = 4096;
- let vmo = Vmo::create(start_size).unwrap();
+ let vmo = Vmo::create_with_opts(VmoOptions::RESIZABLE, start_size).unwrap();
assert_eq!(start_size, vmo.get_size().unwrap());
// Change the size and make sure the new size is reported
diff --git a/garnet/public/rust/mapped-vmo/src/lib.rs b/garnet/public/rust/mapped-vmo/src/lib.rs
index 893f5a5..20fe32f 100644
--- a/garnet/public/rust/mapped-vmo/src/lib.rs
+++ b/garnet/public/rust/mapped-vmo/src/lib.rs
@@ -130,7 +130,7 @@
let flags = zx::VmarFlags::PERM_READ | zx::VmarFlags::PERM_WRITE;
{
// Requires NON_RESIZEABLE
- let vmo = zx::Vmo::create(size as u64).unwrap();
+ let vmo = zx::Vmo::create_with_opts(zx::VmoOptions::RESIZABLE, size as u64).unwrap();
let status = Mapping::create_from_vmo(&vmo, size, flags).unwrap_err();
assert_eq!(status, zx::Status::NOT_SUPPORTED);
}
diff --git a/zircon/system/dev/block/ramdisk/ramdisk-controller.cpp b/zircon/system/dev/block/ramdisk/ramdisk-controller.cpp
index 9ddf16e..3e82b86 100644
--- a/zircon/system/dev/block/ramdisk/ramdisk-controller.cpp
+++ b/zircon/system/dev/block/ramdisk/ramdisk-controller.cpp
@@ -63,7 +63,7 @@
};
zx::vmo vmo;
- zx_status_t status = zx::vmo::create(block_size * block_count, 0, &vmo);
+ zx_status_t status = zx::vmo::create(block_size * block_count, ZX_VMO_RESIZABLE, &vmo);
if (status != ZX_OK) {
return failure_response(status);
}
diff --git a/zircon/system/ulib/bitmap/include/bitmap/storage.h b/zircon/system/ulib/bitmap/include/bitmap/storage.h
index 4e03bb1..4bde2c2 100644
--- a/zircon/system/ulib/bitmap/include/bitmap/storage.h
+++ b/zircon/system/ulib/bitmap/include/bitmap/storage.h
@@ -89,7 +89,7 @@
Release();
size_ = fbl::round_up(size, static_cast<size_t>(PAGE_SIZE));
zx_status_t status;
- if ((status = zx::vmo::create(size_, 0, &vmo_)) != ZX_OK) {
+ if ((status = zx::vmo::create(size_, ZX_VMO_RESIZABLE, &vmo_)) != ZX_OK) {
return status;
} else if ((status = zx_vmar_map(zx_vmar_root_self(),
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
diff --git a/zircon/system/ulib/fzl/include/lib/fzl/owned-vmo-mapper.h b/zircon/system/ulib/fzl/include/lib/fzl/owned-vmo-mapper.h
index 1c33b29..694e686 100644
--- a/zircon/system/ulib/fzl/include/lib/fzl/owned-vmo-mapper.h
+++ b/zircon/system/ulib/fzl/include/lib/fzl/owned-vmo-mapper.h
@@ -39,7 +39,8 @@
const char* name,
zx_vm_option_t map_options = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
fbl::RefPtr<VmarManager> vmar_manager = nullptr,
- uint32_t cache_policy = 0);
+ uint32_t cache_policy = 0,
+ uint32_t vmo_options = 0);
// See |VmoMapper::Map|.
zx_status_t Map(zx::vmo vmo,
diff --git a/zircon/system/ulib/fzl/include/lib/fzl/vmo-mapper.h b/zircon/system/ulib/fzl/include/lib/fzl/vmo-mapper.h
index 3130c6e..f7d70b5e 100644
--- a/zircon/system/ulib/fzl/include/lib/fzl/vmo-mapper.h
+++ b/zircon/system/ulib/fzl/include/lib/fzl/vmo-mapper.h
@@ -47,12 +47,14 @@
// to leave the default rights.
// cache_policy : When non-zero, indicates the cache policy to apply to the
// created VMO.
+ // vmo_options : The options to use when creating the VMO.
zx_status_t CreateAndMap(uint64_t size,
zx_vm_option_t map_flags,
fbl::RefPtr<VmarManager> vmar_manager = nullptr,
zx::vmo* vmo_out = nullptr,
zx_rights_t vmo_rights = ZX_RIGHT_SAME_RIGHTS,
- uint32_t cache_policy = 0);
+ uint32_t cache_policy = 0,
+ uint32_t vmo_options = 0);
// Map an existing VMO our address space using the provided map
// flags and optional target VMAR.
diff --git a/zircon/system/ulib/fzl/owned-vmo-mapper.cpp b/zircon/system/ulib/fzl/owned-vmo-mapper.cpp
index 9f08880..7c00c2f 100644
--- a/zircon/system/ulib/fzl/owned-vmo-mapper.cpp
+++ b/zircon/system/ulib/fzl/owned-vmo-mapper.cpp
@@ -15,14 +15,16 @@
const char* name,
zx_vm_option_t map_options,
fbl::RefPtr<VmarManager> vmar_manager,
- uint32_t cache_policy) {
+ uint32_t cache_policy,
+ uint32_t vmo_options) {
zx::vmo temp;
zx_status_t res = VmoMapper::CreateAndMap(size,
map_options,
std::move(vmar_manager),
&temp,
ZX_RIGHT_SAME_RIGHTS,
- cache_policy);
+ cache_policy,
+ vmo_options);
if (res == ZX_OK) {
temp.set_property(ZX_PROP_NAME, name, name ? strlen(name) : 0);
diff --git a/zircon/system/ulib/fzl/resizeable-vmo-mapper.cpp b/zircon/system/ulib/fzl/resizeable-vmo-mapper.cpp
index dacfdf1..13406e5 100644
--- a/zircon/system/ulib/fzl/resizeable-vmo-mapper.cpp
+++ b/zircon/system/ulib/fzl/resizeable-vmo-mapper.cpp
@@ -39,7 +39,7 @@
uint32_t cache_policy) {
zx::vmo temp;
zx_status_t res = OwnedVmoMapper::CreateAndMap(size, name, map_options, std::move(vmar_manager),
- cache_policy);
+ cache_policy, ZX_VMO_RESIZABLE);
if (res == ZX_OK) {
map_options_ = map_options;
}
diff --git a/zircon/system/ulib/fzl/vmo-mapper.cpp b/zircon/system/ulib/fzl/vmo-mapper.cpp
index 55d016f..42676af 100644
--- a/zircon/system/ulib/fzl/vmo-mapper.cpp
+++ b/zircon/system/ulib/fzl/vmo-mapper.cpp
@@ -15,7 +15,8 @@
fbl::RefPtr<VmarManager> vmar_manager,
zx::vmo* vmo_out,
zx_rights_t vmo_rights,
- uint32_t cache_policy) {
+ uint32_t cache_policy,
+ uint32_t vmo_options) {
if (size == 0) {
return ZX_ERR_INVALID_ARGS;
}
@@ -26,7 +27,7 @@
}
zx::vmo vmo;
- zx_status_t ret = zx::vmo::create(size, 0, &vmo);
+ zx_status_t ret = zx::vmo::create(size, vmo_options, &vmo);
if (ret != ZX_OK) {
return ret;
}
diff --git a/zircon/system/ulib/memfs/file.cpp b/zircon/system/ulib/memfs/file.cpp
index 6b5c0d9..145c9ba 100644
--- a/zircon/system/ulib/memfs/file.cpp
+++ b/zircon/system/ulib/memfs/file.cpp
@@ -102,7 +102,7 @@
zx_status_t status;
if (!vmo_.is_valid()) {
// First access to the file? Allocate it.
- if ((status = zx::vmo::create(0, 0, &vmo_)) != ZX_OK) {
+ if ((status = zx::vmo::create(0, ZX_VMO_RESIZABLE, &vmo_)) != ZX_OK) {
return status;
}
}
diff --git a/zircon/system/ulib/memfs/memfs.cpp b/zircon/system/ulib/memfs/memfs.cpp
index cd3a5b2..c5fd2d5 100644
--- a/zircon/system/ulib/memfs/memfs.cpp
+++ b/zircon/system/ulib/memfs/memfs.cpp
@@ -80,7 +80,7 @@
}
zx_status_t status;
if (!vmo.is_valid()) {
- if ((status = zx::vmo::create(aligned_len, 0, &vmo)) != ZX_OK) {
+ if ((status = zx::vmo::create(aligned_len, ZX_VMO_RESIZABLE, &vmo)) != ZX_OK) {
return status;
}
} else {
diff --git a/zircon/system/ulib/minfs/vnode.cpp b/zircon/system/ulib/minfs/vnode.cpp
index d8d0d1e..b938493 100644
--- a/zircon/system/ulib/minfs/vnode.cpp
+++ b/zircon/system/ulib/minfs/vnode.cpp
@@ -236,7 +236,7 @@
zx_status_t status;
const size_t vmo_size = fbl::round_up(GetSize(), kMinfsBlockSize);
- if ((status = zx::vmo::create(vmo_size, 0, &vmo_)) != ZX_OK) {
+ if ((status = zx::vmo::create(vmo_size, ZX_VMO_RESIZABLE, &vmo_)) != ZX_OK) {
FS_TRACE_ERROR("Failed to initialize vmo; error: %d\n", status);
return status;
}
diff --git a/zircon/system/ulib/zbi-bootfs/zbi-bootfs.cpp b/zircon/system/ulib/zbi-bootfs/zbi-bootfs.cpp
index abbd55d..56cbc2d 100644
--- a/zircon/system/ulib/zbi-bootfs/zbi-bootfs.cpp
+++ b/zircon/system/ulib/zbi-bootfs/zbi-bootfs.cpp
@@ -212,7 +212,7 @@
return ZX_ERR_BUFFER_TOO_SMALL;
}
- zx_status_t status = zx::vmo::create(buf_size, 0, &vmo);
+ zx_status_t status = zx::vmo::create(buf_size, ZX_VMO_RESIZABLE, &vmo);
if (status != ZX_OK) {
fprintf(stderr, "Error creating VMO\n");
diff --git a/zircon/system/utest/core/vmo/vmo-clone.cpp b/zircon/system/utest/core/vmo/vmo-clone.cpp
index 771ebc9..9379b24 100644
--- a/zircon/system/utest/core/vmo/vmo-clone.cpp
+++ b/zircon/system/utest/core/vmo/vmo-clone.cpp
@@ -176,7 +176,7 @@
// create a vmo
const size_t size = PAGE_SIZE * 4;
- EXPECT_EQ(ZX_OK, zx_vmo_create(size, ZX_VMO_RESIZABLE, &vmo), "vm_object_create");
+ EXPECT_EQ(ZX_OK, zx_vmo_create(size, 0, &vmo), "vm_object_create");
// map it
EXPECT_EQ(ZX_OK,
@@ -187,7 +187,8 @@
// clone it
clone_vmo[0] = ZX_HANDLE_INVALID;
- EXPECT_EQ(ZX_OK, zx_vmo_create_child(vmo, ZX_VMO_CHILD_COPY_ON_WRITE, 0, size, &clone_vmo[0]),"vm_clone");
+ EXPECT_EQ(ZX_OK, zx_vmo_create_child(vmo, ZX_VMO_CHILD_COPY_ON_WRITE | ZX_VMO_CHILD_RESIZABLE,
+ 0, size, &clone_vmo[0]),"vm_clone");
EXPECT_NE(ZX_HANDLE_INVALID, clone_vmo[0], "vm_clone_handle");
// Attempt a non-resizable map fails.
@@ -409,7 +410,8 @@
// create a clone that extends beyond the parent by one page
clone_vmo[0] = ZX_HANDLE_INVALID;
- EXPECT_EQ(ZX_OK, zx_vmo_create_child(vmo, ZX_VMO_CHILD_COPY_ON_WRITE, PAGE_SIZE, size, &clone_vmo[0]), "vm_clone");
+ EXPECT_EQ(ZX_OK, zx_vmo_create_child(vmo, ZX_VMO_CHILD_COPY_ON_WRITE | ZX_VMO_CHILD_RESIZABLE,
+ PAGE_SIZE, size, &clone_vmo[0]), "vm_clone");
// map the clone
EXPECT_EQ(ZX_OK,
diff --git a/zircon/system/utest/core/vmo/vmo-clone2.cpp b/zircon/system/utest/core/vmo/vmo-clone2.cpp
index ae1a185..880a42a 100644
--- a/zircon/system/utest/core/vmo/vmo-clone2.cpp
+++ b/zircon/system/utest/core/vmo/vmo-clone2.cpp
@@ -40,7 +40,7 @@
// Creates a vmo with |page_count| pages and writes (page_index + 1) to each page.
bool init_page_tagged_vmo(uint32_t page_count, zx::vmo* vmo) {
zx_status_t status;
- status = zx::vmo::create(page_count * ZX_PAGE_SIZE, 0, vmo);
+ status = zx::vmo::create(page_count * ZX_PAGE_SIZE, ZX_VMO_RESIZABLE, vmo);
if (status != ZX_OK) {
unittest_printf_critical(" create failed %d", status);
return false;
@@ -573,7 +573,8 @@
ASSERT_TRUE(init_page_tagged_vmo(4, &vmo));
zx::vmo clone;
- ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2, 0, 4 * ZX_PAGE_SIZE, &clone), ZX_OK);
+ ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2 | ZX_VMO_CHILD_RESIZABLE,
+ 0, 4 * ZX_PAGE_SIZE, &clone), ZX_OK);
// Write to one page in each vmo.
ASSERT_TRUE(vmo_write(vmo, 5, ZX_PAGE_SIZE));
@@ -626,7 +627,8 @@
ASSERT_TRUE(init_page_tagged_vmo(2, &vmo));
zx::vmo clone;
- ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2, 0, ZX_PAGE_SIZE, &clone), ZX_OK);
+ ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2 | ZX_VMO_CHILD_RESIZABLE,
+ 0, ZX_PAGE_SIZE, &clone), ZX_OK);
ASSERT_TRUE(vmo_check(clone, 1));
@@ -673,7 +675,7 @@
// Clone one clone for each page.
zx::vmo clones[3];
for (unsigned i = 0; i < 3; i++) {
- ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2,
+ ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2 | ZX_VMO_CHILD_RESIZABLE,
i * ZX_PAGE_SIZE, ZX_PAGE_SIZE, clones + i), ZX_OK);
ASSERT_TRUE(vmo_check(clones[i], i + 1));
}
@@ -703,7 +705,8 @@
// Clone the vmo and fork a page into both.
zx::vmo clone;
- ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2, 0, 2 * ZX_PAGE_SIZE, &clone), ZX_OK);
+ ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE2 | ZX_VMO_CHILD_RESIZABLE,
+ 0, 2 * ZX_PAGE_SIZE, &clone), ZX_OK);
ASSERT_TRUE(vmo_write(vmo, 4, 0 * ZX_PAGE_SIZE));
ASSERT_TRUE(vmo_write(clone, 5, 1 * ZX_PAGE_SIZE));
@@ -919,7 +922,7 @@
// Repeatedly clone the vmo while simultaniously changing it.
for (unsigned i = 1; i < kNumClones; i++) {
- ASSERT_EQ(vmos[0].create_child(ZX_VMO_CHILD_COPY_ON_WRITE2,
+ ASSERT_EQ(vmos[0].create_child(ZX_VMO_CHILD_COPY_ON_WRITE2 | ZX_VMO_CHILD_RESIZABLE,
0, kNumClones * ZX_PAGE_SIZE, vmos + i), ZX_OK);
ASSERT_TRUE(vmo_write(vmos[i], kNumClones + 2, i * ZX_PAGE_SIZE));
}
diff --git a/zircon/third_party/ulib/musl/ldso/dynlink.c b/zircon/third_party/ulib/musl/ldso/dynlink.c
index 1774fe5..8fa91810 100644
--- a/zircon/third_party/ulib/musl/ldso/dynlink.c
+++ b/zircon/third_party/ulib/musl/ldso/dynlink.c
@@ -1016,7 +1016,8 @@
}
} else {
// Get a writable (lazy) copy of the portion of the file VMO.
- status = _zx_vmo_create_child(vmo, ZX_VMO_CHILD_COPY_ON_WRITE,
+ status = _zx_vmo_create_child(vmo,
+ ZX_VMO_CHILD_COPY_ON_WRITE | ZX_VMO_CHILD_RESIZABLE,
off_start, data_size, &map_vmo);
if (status == ZX_OK && map_size > data_size) {
// Extend the writable VMO to cover the .bss pages too.
diff --git a/zircon/third_party/ulib/scudo/fuchsia.cc b/zircon/third_party/ulib/scudo/fuchsia.cc
index 22c3801..6c9f884 100644
--- a/zircon/third_party/ulib/scudo/fuchsia.cc
+++ b/zircon/third_party/ulib/scudo/fuchsia.cc
@@ -90,7 +90,7 @@
}
} else {
// Otherwise, create a Vmo and set its name.
- Status = _zx_vmo_create(Size, 0, &Vmo);
+ Status = _zx_vmo_create(Size, ZX_VMO_RESIZABLE, &Vmo);
if (Status != ZX_OK) {
if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem)
dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY);