diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2021-01-04 17:13:18 +0000 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2021-02-01 17:07:34 -0500 |
commit | 369d6dc4de45b8e5e35a851f5719e7fd59a0462f (patch) | |
tree | 9b7bf91786c4866c63bab05090e83964a7bbbf33 /util | |
parent | 74208cd252c5da9d867270a178799abd802b9338 (diff) |
memory: add readonly support to memory_region_init_ram_from_file()
There is currently no way to open(O_RDONLY) and mmap(PROT_READ) when
creating a memory region from a file. This functionality is needed since
the underlying host file may not allow writing.
Add a bool readonly argument to memory_region_init_ram_from_file() and
the APIs it calls.
Extend memory_region_init_ram_from_file() rather than introducing a
memory_region_init_rom_from_file() API so that callers can easily make a
choice between read/write and read-only at runtime without calling
different APIs.
No new RAMBlock flag is introduced for read-only because it's unclear
whether RAMBlocks need to know that they are read-only. Pass a bool
readonly argument instead.
Both of these design decisions can be changed in the future. It just
seemed like the simplest approach to me.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20210104171320.575838-2-stefanha@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'util')
-rw-r--r-- | util/mmap-alloc.c | 10 | ||||
-rw-r--r-- | util/oslib-posix.c | 2 |
2 files changed, 7 insertions, 5 deletions
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 27dcccd8ec..890fda6a35 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -85,9 +85,11 @@ size_t qemu_mempath_getpagesize(const char *mem_path) void *qemu_ram_mmap(int fd, size_t size, size_t align, + bool readonly, bool shared, bool is_pmem) { + int prot; int flags; int map_sync_flags = 0; int guardfd; @@ -146,8 +148,9 @@ void *qemu_ram_mmap(int fd, offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr; - ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags | map_sync_flags, fd, 0); + prot = PROT_READ | (readonly ? 0 : PROT_WRITE); + + ptr = mmap(guardptr + offset, size, prot, flags | map_sync_flags, fd, 0); if (ptr == MAP_FAILED && map_sync_flags) { if (errno == ENOTSUP) { @@ -171,8 +174,7 @@ void *qemu_ram_mmap(int fd, * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC, * we will remove these flags to handle compatibility. */ - ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags, fd, 0); + ptr = mmap(guardptr + offset, size, prot, flags, fd, 0); } if (ptr == MAP_FAILED) { diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 359c52df12..bf57d3b030 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -230,7 +230,7 @@ void *qemu_memalign(size_t alignment, size_t size) void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared) { size_t align = QEMU_VMALLOC_ALIGN; - void *ptr = qemu_ram_mmap(-1, size, align, shared, false); + void *ptr = qemu_ram_mmap(-1, size, align, false, shared, false); if (ptr == MAP_FAILED) { return NULL; |