From f35e44e7645edbb08e35b111c10c2fc57e2905c7 Mon Sep 17 00:00:00 2001 From: Alex Bennée Date: Fri, 21 Oct 2016 16:34:18 +0100 Subject: exec.c: ensure all AddressSpaceDispatch updates under RCU The memory_dispatch field is meant to be protected by RCU so we should use the correct primitives when accessing it. This race was flagged up by the ThreadSanitizer. Signed-off-by: Alex Bennée Message-Id: <20161021153418.21571-1-alex.bennee@linaro.org> Signed-off-by: Paolo Bonzini --- exec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 4d085812ca..a19ed21bff 100644 --- a/exec.c +++ b/exec.c @@ -493,7 +493,7 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, hwaddr *xlat, hwaddr *plen) { MemoryRegionSection *section; - AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch; + AddressSpaceDispatch *d = atomic_rcu_read(&cpu->cpu_ases[asidx].memory_dispatch); section = address_space_translate_internal(d, addr, xlat, plen, false); @@ -2376,7 +2376,7 @@ static void tcg_commit(MemoryListener *listener) * may have split the RCU critical section. */ d = atomic_rcu_read(&cpuas->as->dispatch); - cpuas->memory_dispatch = d; + atomic_rcu_set(&cpuas->memory_dispatch, d); tlb_flush(cpuas->cpu, 1); } -- cgit v1.2.3-55-g7522 From d6af99c9f8d577927a52d00af3fa8e6ec0b2a4e2 Mon Sep 17 00:00:00 2001 From: Haozhong Zhang Date: Thu, 27 Oct 2016 12:22:58 +0800 Subject: exec.c: do not truncate non-empty memory backend file For '-object memory-backend-file,mem-path=foo,size=xyz', if the size of file 'foo' does not match the given size 'xyz', the current QEMU will truncate the file to the given size, which may corrupt the existing data in that file. To avoid such data corruption, this patch disables truncating non-empty backend files. Signed-off-by: Haozhong Zhang Message-Id: <20161027042300.5929-2-haozhong.zhang@intel.com> Signed-off-by: Paolo Bonzini --- exec.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index a19ed21bff..f471e7377a 100644 --- a/exec.c +++ b/exec.c @@ -1229,6 +1229,15 @@ void qemu_mutex_unlock_ramlist(void) } #ifdef __linux__ +static int64_t get_file_size(int fd) +{ + int64_t size = lseek(fd, 0, SEEK_END); + if (size < 0) { + return -errno; + } + return size; +} + static void *file_ram_alloc(RAMBlock *block, ram_addr_t memory, const char *path, @@ -1240,6 +1249,7 @@ static void *file_ram_alloc(RAMBlock *block, char *c; void *area = MAP_FAILED; int fd = -1; + int64_t file_size; if (kvm_enabled() && !kvm_has_sync_mmu()) { error_setg(errp, @@ -1302,6 +1312,8 @@ static void *file_ram_alloc(RAMBlock *block, } #endif + file_size = get_file_size(fd); + if (memory < block->page_size) { error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to " "or larger than page size 0x%zx", @@ -1316,8 +1328,16 @@ static void *file_ram_alloc(RAMBlock *block, * hosts, so don't bother bailing out on errors. * If anything goes wrong with it under other filesystems, * mmap will fail. + * + * Do not truncate the non-empty backend file to avoid corrupting + * the existing data in the file. Disabling shrinking is not + * enough. For example, the current vNVDIMM implementation stores + * the guest NVDIMM labels at the end of the backend file. If the + * backend file is later extended, QEMU will not be able to find + * those labels. Therefore, extending the non-empty backend file + * is disabled as well. */ - if (ftruncate(fd, memory)) { + if (!file_size && ftruncate(fd, memory)) { perror("ftruncate"); } -- cgit v1.2.3-55-g7522 From 1775f111eaf7f49efcec30152db44a184c1e2222 Mon Sep 17 00:00:00 2001 From: Haozhong Zhang Date: Wed, 2 Nov 2016 09:05:51 +0800 Subject: exec.c: check memory backend file size with 'size' option If the memory backend file is not large enough to hold the required 'size', Qemu will report error and exit. Signed-off-by: Haozhong Zhang Message-Id: <20161027042300.5929-3-haozhong.zhang@intel.com> Reviewed-by: Eduardo Habkost Message-Id: <20161102010551.2723-1-haozhong.zhang@intel.com> Signed-off-by: Paolo Bonzini --- exec.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'exec.c') diff --git a/exec.c b/exec.c index f471e7377a..f3c2770d54 100644 --- a/exec.c +++ b/exec.c @@ -1321,6 +1321,13 @@ static void *file_ram_alloc(RAMBlock *block, goto error; } + if (file_size > 0 && file_size < memory) { + error_setg(errp, "backing store %s size 0x%" PRIx64 + " does not match 'size' option 0x" RAM_ADDR_FMT, + path, file_size, memory); + goto error; + } + memory = ROUND_UP(memory, block->page_size); /* -- cgit v1.2.3-55-g7522