|
|
383d26 |
From 2d02fc0e933a7d4a30e8bb7c665d898d00ac5e00 Mon Sep 17 00:00:00 2001
|
|
|
383d26 |
From: Igor Mammedov <imammedo@redhat.com>
|
|
|
383d26 |
Date: Fri, 23 Nov 2018 11:58:47 +0100
|
|
|
383d26 |
Subject: [PATCH 14/34] memory: cleanup side effects of
|
|
|
383d26 |
memory_region_init_foo() on failure
|
|
|
383d26 |
MIME-Version: 1.0
|
|
|
383d26 |
Content-Type: text/plain; charset=UTF-8
|
|
|
383d26 |
Content-Transfer-Encoding: 8bit
|
|
|
383d26 |
|
|
|
383d26 |
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
|
|
383d26 |
Message-id: <1542974327-165907-1-git-send-email-imammedo@redhat.com>
|
|
|
383d26 |
Patchwork-id: 83127
|
|
|
383d26 |
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH v2] memory: cleanup side effects of memory_region_init_foo() on failure
|
|
|
383d26 |
Bugzilla: 1585155
|
|
|
383d26 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
383d26 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
383d26 |
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
|
383d26 |
|
|
|
383d26 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1585155
|
|
|
383d26 |
Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=19261375
|
|
|
383d26 |
|
|
|
383d26 |
if MemoryRegion intialization fails it's left in semi-initialized state,
|
|
|
383d26 |
where it's size is not 0 and attached as child to owner object.
|
|
|
383d26 |
And this leds to crash in following use-case:
|
|
|
383d26 |
(monitor) object_add memory-backend-file,id=mem1,size=99999G,mem-path=/tmp/foo,discard-data=yes
|
|
|
383d26 |
memory.c:2083: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed
|
|
|
383d26 |
Aborted (core dumped)
|
|
|
383d26 |
it happens due to assumption that memory region is intialized when
|
|
|
383d26 |
memory_region_size() != 0
|
|
|
383d26 |
and therefore it's ok to access it in
|
|
|
383d26 |
file_backend_unparent()
|
|
|
383d26 |
if (memory_region_size() != 0)
|
|
|
383d26 |
memory_region_get_ram_ptr()
|
|
|
383d26 |
|
|
|
383d26 |
which happens when object_add fails and unparents failed backend making
|
|
|
383d26 |
file_backend_unparent() access invalid memory region.
|
|
|
383d26 |
|
|
|
383d26 |
Fix it by making sure that memory_region_init_foo() APIs cleanup externally
|
|
|
383d26 |
visible side effects on failure (like set size to 0 and unparenting object)
|
|
|
383d26 |
|
|
|
383d26 |
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
383d26 |
Message-Id: <1536064777-42312-1-git-send-email-imammedo@redhat.com>
|
|
|
383d26 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
383d26 |
(cherry picked from commit 1cd3d492624da399d66c4c3e6a5eabb8f96bb0a2)
|
|
|
383d26 |
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
383d26 |
---
|
|
|
383d26 |
v2:
|
|
|
383d26 |
- clean backport since dependency has been backported and merged as
|
|
|
383d26 |
(commit 754dd8f2 memory, exec: switch file ram allocation functions to 'flags' parameters)
|
|
|
383d26 |
|
|
|
383d26 |
enter the commit message for your changes. Lines starting
|
|
|
383d26 |
|
|
|
383d26 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
383d26 |
---
|
|
|
383d26 |
memory.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
|
|
|
383d26 |
1 file changed, 42 insertions(+), 6 deletions(-)
|
|
|
383d26 |
|
|
|
383d26 |
diff --git a/memory.c b/memory.c
|
|
|
383d26 |
index 7b47f53..4974f97 100644
|
|
|
383d26 |
--- a/memory.c
|
|
|
383d26 |
+++ b/memory.c
|
|
|
383d26 |
@@ -1519,12 +1519,18 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
|
|
|
383d26 |
bool share,
|
|
|
383d26 |
Error **errp)
|
|
|
383d26 |
{
|
|
|
383d26 |
+ Error *err = NULL;
|
|
|
383d26 |
memory_region_init(mr, owner, name, size);
|
|
|
383d26 |
mr->ram = true;
|
|
|
383d26 |
mr->terminates = true;
|
|
|
383d26 |
mr->destructor = memory_region_destructor_ram;
|
|
|
383d26 |
- mr->ram_block = qemu_ram_alloc(size, share, mr, errp);
|
|
|
383d26 |
+ mr->ram_block = qemu_ram_alloc(size, share, mr, &err;;
|
|
|
383d26 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
383d26 |
+ if (err) {
|
|
|
383d26 |
+ mr->size = int128_zero();
|
|
|
383d26 |
+ object_unparent(OBJECT(mr));
|
|
|
383d26 |
+ error_propagate(errp, err);
|
|
|
383d26 |
+ }
|
|
|
383d26 |
}
|
|
|
383d26 |
|
|
|
383d26 |
void memory_region_init_resizeable_ram(MemoryRegion *mr,
|
|
|
383d26 |
@@ -1537,13 +1543,19 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
|
|
|
383d26 |
void *host),
|
|
|
383d26 |
Error **errp)
|
|
|
383d26 |
{
|
|
|
383d26 |
+ Error *err = NULL;
|
|
|
383d26 |
memory_region_init(mr, owner, name, size);
|
|
|
383d26 |
mr->ram = true;
|
|
|
383d26 |
mr->terminates = true;
|
|
|
383d26 |
mr->destructor = memory_region_destructor_ram;
|
|
|
383d26 |
mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
|
|
|
383d26 |
- mr, errp);
|
|
|
383d26 |
+ mr, &err;;
|
|
|
383d26 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
383d26 |
+ if (err) {
|
|
|
383d26 |
+ mr->size = int128_zero();
|
|
|
383d26 |
+ object_unparent(OBJECT(mr));
|
|
|
383d26 |
+ error_propagate(errp, err);
|
|
|
383d26 |
+ }
|
|
|
383d26 |
}
|
|
|
383d26 |
|
|
|
383d26 |
#ifdef __linux__
|
|
|
383d26 |
@@ -1556,13 +1568,19 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
|
|
383d26 |
const char *path,
|
|
|
383d26 |
Error **errp)
|
|
|
383d26 |
{
|
|
|
383d26 |
+ Error *err = NULL;
|
|
|
383d26 |
memory_region_init(mr, owner, name, size);
|
|
|
383d26 |
mr->ram = true;
|
|
|
383d26 |
mr->terminates = true;
|
|
|
383d26 |
mr->destructor = memory_region_destructor_ram;
|
|
|
383d26 |
mr->align = align;
|
|
|
383d26 |
- mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, errp);
|
|
|
383d26 |
+ mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err;;
|
|
|
383d26 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
383d26 |
+ if (err) {
|
|
|
383d26 |
+ mr->size = int128_zero();
|
|
|
383d26 |
+ object_unparent(OBJECT(mr));
|
|
|
383d26 |
+ error_propagate(errp, err);
|
|
|
383d26 |
+ }
|
|
|
383d26 |
}
|
|
|
383d26 |
|
|
|
383d26 |
void memory_region_init_ram_from_fd(MemoryRegion *mr,
|
|
|
383d26 |
@@ -1573,14 +1591,20 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
|
|
|
383d26 |
int fd,
|
|
|
383d26 |
Error **errp)
|
|
|
383d26 |
{
|
|
|
383d26 |
+ Error *err = NULL;
|
|
|
383d26 |
memory_region_init(mr, owner, name, size);
|
|
|
383d26 |
mr->ram = true;
|
|
|
383d26 |
mr->terminates = true;
|
|
|
383d26 |
mr->destructor = memory_region_destructor_ram;
|
|
|
383d26 |
mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
|
|
|
383d26 |
share ? RAM_SHARED : 0,
|
|
|
383d26 |
- fd, errp);
|
|
|
383d26 |
+ fd, &err;;
|
|
|
383d26 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
383d26 |
+ if (err) {
|
|
|
383d26 |
+ mr->size = int128_zero();
|
|
|
383d26 |
+ object_unparent(OBJECT(mr));
|
|
|
383d26 |
+ error_propagate(errp, err);
|
|
|
383d26 |
+ }
|
|
|
383d26 |
}
|
|
|
383d26 |
#endif
|
|
|
383d26 |
|
|
|
383d26 |
@@ -1631,13 +1655,19 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr,
|
|
|
383d26 |
uint64_t size,
|
|
|
383d26 |
Error **errp)
|
|
|
383d26 |
{
|
|
|
383d26 |
+ Error *err = NULL;
|
|
|
383d26 |
memory_region_init(mr, owner, name, size);
|
|
|
383d26 |
mr->ram = true;
|
|
|
383d26 |
mr->readonly = true;
|
|
|
383d26 |
mr->terminates = true;
|
|
|
383d26 |
mr->destructor = memory_region_destructor_ram;
|
|
|
383d26 |
- mr->ram_block = qemu_ram_alloc(size, false, mr, errp);
|
|
|
383d26 |
+ mr->ram_block = qemu_ram_alloc(size, false, mr, &err;;
|
|
|
383d26 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
383d26 |
+ if (err) {
|
|
|
383d26 |
+ mr->size = int128_zero();
|
|
|
383d26 |
+ object_unparent(OBJECT(mr));
|
|
|
383d26 |
+ error_propagate(errp, err);
|
|
|
383d26 |
+ }
|
|
|
383d26 |
}
|
|
|
383d26 |
|
|
|
383d26 |
void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
|
|
383d26 |
@@ -1648,6 +1678,7 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
|
|
383d26 |
uint64_t size,
|
|
|
383d26 |
Error **errp)
|
|
|
383d26 |
{
|
|
|
383d26 |
+ Error *err = NULL;
|
|
|
383d26 |
assert(ops);
|
|
|
383d26 |
memory_region_init(mr, owner, name, size);
|
|
|
383d26 |
mr->ops = ops;
|
|
|
383d26 |
@@ -1655,7 +1686,12 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
|
|
383d26 |
mr->terminates = true;
|
|
|
383d26 |
mr->rom_device = true;
|
|
|
383d26 |
mr->destructor = memory_region_destructor_ram;
|
|
|
383d26 |
- mr->ram_block = qemu_ram_alloc(size, false, mr, errp);
|
|
|
383d26 |
+ mr->ram_block = qemu_ram_alloc(size, false, mr, &err;;
|
|
|
383d26 |
+ if (err) {
|
|
|
383d26 |
+ mr->size = int128_zero();
|
|
|
383d26 |
+ object_unparent(OBJECT(mr));
|
|
|
383d26 |
+ error_propagate(errp, err);
|
|
|
383d26 |
+ }
|
|
|
383d26 |
}
|
|
|
383d26 |
|
|
|
383d26 |
void memory_region_init_iommu(void *_iommu_mr,
|
|
|
383d26 |
--
|
|
|
383d26 |
1.8.3.1
|
|
|
383d26 |
|