|
|
26ba25 |
From cfa472eb467f8e5139a2a7d30aa85c9affbccd4f Mon Sep 17 00:00:00 2001
|
|
|
26ba25 |
From: Igor Mammedov <imammedo@redhat.com>
|
|
|
26ba25 |
Date: Fri, 5 Oct 2018 12:59:47 +0100
|
|
|
26ba25 |
Subject: [PATCH 6/6] memory: cleanup side effects of memory_region_init_foo()
|
|
|
26ba25 |
on failure
|
|
|
26ba25 |
|
|
|
26ba25 |
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
|
|
26ba25 |
Message-id: <1538744387-84898-1-git-send-email-imammedo@redhat.com>
|
|
|
26ba25 |
Patchwork-id: 82391
|
|
|
26ba25 |
O-Subject: [RHEL-8 qemu-kvm PATCH] memory: cleanup side effects of memory_region_init_foo() on failure
|
|
|
26ba25 |
Bugzilla: 1600365
|
|
|
26ba25 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
26ba25 |
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
26ba25 |
RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
|
|
|
26ba25 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
26ba25 |
|
|
|
26ba25 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1600365
|
|
|
26ba25 |
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=18658506
|
|
|
26ba25 |
|
|
|
26ba25 |
if MemoryRegion intialization fails it's left in semi-initialized state,
|
|
|
26ba25 |
where it's size is not 0 and attached as child to owner object.
|
|
|
26ba25 |
And this leds to crash in following use-case:
|
|
|
26ba25 |
(monitor) object_add memory-backend-file,id=mem1,size=99999G,mem-path=/tmp/foo,discard-data=yes
|
|
|
26ba25 |
memory.c:2083: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed
|
|
|
26ba25 |
Aborted (core dumped)
|
|
|
26ba25 |
it happens due to assumption that memory region is intialized when
|
|
|
26ba25 |
memory_region_size() != 0
|
|
|
26ba25 |
and therefore it's ok to access it in
|
|
|
26ba25 |
file_backend_unparent()
|
|
|
26ba25 |
if (memory_region_size() != 0)
|
|
|
26ba25 |
memory_region_get_ram_ptr()
|
|
|
26ba25 |
|
|
|
26ba25 |
which happens when object_add fails and unparents failed backend making
|
|
|
26ba25 |
file_backend_unparent() access invalid memory region.
|
|
|
26ba25 |
|
|
|
26ba25 |
Fix it by making sure that memory_region_init_foo() APIs cleanup externally
|
|
|
26ba25 |
visible side effects on failure (like set size to 0 and unparenting object)
|
|
|
26ba25 |
|
|
|
26ba25 |
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
26ba25 |
Message-Id: <1536064777-42312-1-git-send-email-imammedo@redhat.com>
|
|
|
26ba25 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
26ba25 |
(cherry picked from commit 1cd3d492624da399d66c4c3e6a5eabb8f96bb0a2)
|
|
|
26ba25 |
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
26ba25 |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
26ba25 |
|
|
|
26ba25 |
Conflicts:
|
|
|
26ba25 |
memory.c
|
|
|
26ba25 |
due missing (cbfc01710 "memory, exec: switch file ram allocation functions to 'flags' parameters")
|
|
|
26ba25 |
not related to the patch signature mismatch of
|
|
|
26ba25 |
qemu_ram_alloc_from_file()/qemu_ram_alloc_from_fd()
|
|
|
26ba25 |
---
|
|
|
26ba25 |
memory.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
|
|
|
26ba25 |
1 file changed, 42 insertions(+), 6 deletions(-)
|
|
|
26ba25 |
|
|
|
26ba25 |
diff --git a/memory.c b/memory.c
|
|
|
26ba25 |
index e70b64b..1a99b9c 100644
|
|
|
26ba25 |
--- a/memory.c
|
|
|
26ba25 |
+++ b/memory.c
|
|
|
26ba25 |
@@ -1519,12 +1519,18 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
|
|
|
26ba25 |
bool share,
|
|
|
26ba25 |
Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
+ Error *err = NULL;
|
|
|
26ba25 |
memory_region_init(mr, owner, name, size);
|
|
|
26ba25 |
mr->ram = true;
|
|
|
26ba25 |
mr->terminates = true;
|
|
|
26ba25 |
mr->destructor = memory_region_destructor_ram;
|
|
|
26ba25 |
- mr->ram_block = qemu_ram_alloc(size, share, mr, errp);
|
|
|
26ba25 |
+ mr->ram_block = qemu_ram_alloc(size, share, mr, &err;;
|
|
|
26ba25 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
26ba25 |
+ if (err) {
|
|
|
26ba25 |
+ mr->size = int128_zero();
|
|
|
26ba25 |
+ object_unparent(OBJECT(mr));
|
|
|
26ba25 |
+ error_propagate(errp, err);
|
|
|
26ba25 |
+ }
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
void memory_region_init_resizeable_ram(MemoryRegion *mr,
|
|
|
26ba25 |
@@ -1537,13 +1543,19 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
|
|
|
26ba25 |
void *host),
|
|
|
26ba25 |
Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
+ Error *err = NULL;
|
|
|
26ba25 |
memory_region_init(mr, owner, name, size);
|
|
|
26ba25 |
mr->ram = true;
|
|
|
26ba25 |
mr->terminates = true;
|
|
|
26ba25 |
mr->destructor = memory_region_destructor_ram;
|
|
|
26ba25 |
mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
|
|
|
26ba25 |
- mr, errp);
|
|
|
26ba25 |
+ mr, &err;;
|
|
|
26ba25 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
26ba25 |
+ if (err) {
|
|
|
26ba25 |
+ mr->size = int128_zero();
|
|
|
26ba25 |
+ object_unparent(OBJECT(mr));
|
|
|
26ba25 |
+ error_propagate(errp, err);
|
|
|
26ba25 |
+ }
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
#ifdef __linux__
|
|
|
26ba25 |
@@ -1556,13 +1568,19 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
|
|
26ba25 |
const char *path,
|
|
|
26ba25 |
Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
+ Error *err = NULL;
|
|
|
26ba25 |
memory_region_init(mr, owner, name, size);
|
|
|
26ba25 |
mr->ram = true;
|
|
|
26ba25 |
mr->terminates = true;
|
|
|
26ba25 |
mr->destructor = memory_region_destructor_ram;
|
|
|
26ba25 |
mr->align = align;
|
|
|
26ba25 |
- mr->ram_block = qemu_ram_alloc_from_file(size, mr, share, path, errp);
|
|
|
26ba25 |
+ mr->ram_block = qemu_ram_alloc_from_file(size, mr, share, path, &err;;
|
|
|
26ba25 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
26ba25 |
+ if (err) {
|
|
|
26ba25 |
+ mr->size = int128_zero();
|
|
|
26ba25 |
+ object_unparent(OBJECT(mr));
|
|
|
26ba25 |
+ error_propagate(errp, err);
|
|
|
26ba25 |
+ }
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
void memory_region_init_ram_from_fd(MemoryRegion *mr,
|
|
|
26ba25 |
@@ -1573,12 +1591,18 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
|
|
|
26ba25 |
int fd,
|
|
|
26ba25 |
Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
+ Error *err = NULL;
|
|
|
26ba25 |
memory_region_init(mr, owner, name, size);
|
|
|
26ba25 |
mr->ram = true;
|
|
|
26ba25 |
mr->terminates = true;
|
|
|
26ba25 |
mr->destructor = memory_region_destructor_ram;
|
|
|
26ba25 |
- mr->ram_block = qemu_ram_alloc_from_fd(size, mr, share, fd, errp);
|
|
|
26ba25 |
+ mr->ram_block = qemu_ram_alloc_from_fd(size, mr, share, fd, &err;;
|
|
|
26ba25 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
26ba25 |
+ if (err) {
|
|
|
26ba25 |
+ mr->size = int128_zero();
|
|
|
26ba25 |
+ object_unparent(OBJECT(mr));
|
|
|
26ba25 |
+ error_propagate(errp, err);
|
|
|
26ba25 |
+ }
|
|
|
26ba25 |
}
|
|
|
26ba25 |
#endif
|
|
|
26ba25 |
|
|
|
26ba25 |
@@ -1629,13 +1653,19 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr,
|
|
|
26ba25 |
uint64_t size,
|
|
|
26ba25 |
Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
+ Error *err = NULL;
|
|
|
26ba25 |
memory_region_init(mr, owner, name, size);
|
|
|
26ba25 |
mr->ram = true;
|
|
|
26ba25 |
mr->readonly = true;
|
|
|
26ba25 |
mr->terminates = true;
|
|
|
26ba25 |
mr->destructor = memory_region_destructor_ram;
|
|
|
26ba25 |
- mr->ram_block = qemu_ram_alloc(size, false, mr, errp);
|
|
|
26ba25 |
+ mr->ram_block = qemu_ram_alloc(size, false, mr, &err;;
|
|
|
26ba25 |
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
|
|
|
26ba25 |
+ if (err) {
|
|
|
26ba25 |
+ mr->size = int128_zero();
|
|
|
26ba25 |
+ object_unparent(OBJECT(mr));
|
|
|
26ba25 |
+ error_propagate(errp, err);
|
|
|
26ba25 |
+ }
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
|
|
26ba25 |
@@ -1646,6 +1676,7 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
|
|
26ba25 |
uint64_t size,
|
|
|
26ba25 |
Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
+ Error *err = NULL;
|
|
|
26ba25 |
assert(ops);
|
|
|
26ba25 |
memory_region_init(mr, owner, name, size);
|
|
|
26ba25 |
mr->ops = ops;
|
|
|
26ba25 |
@@ -1653,7 +1684,12 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
|
|
26ba25 |
mr->terminates = true;
|
|
|
26ba25 |
mr->rom_device = true;
|
|
|
26ba25 |
mr->destructor = memory_region_destructor_ram;
|
|
|
26ba25 |
- mr->ram_block = qemu_ram_alloc(size, false, mr, errp);
|
|
|
26ba25 |
+ mr->ram_block = qemu_ram_alloc(size, false, mr, &err;;
|
|
|
26ba25 |
+ if (err) {
|
|
|
26ba25 |
+ mr->size = int128_zero();
|
|
|
26ba25 |
+ object_unparent(OBJECT(mr));
|
|
|
26ba25 |
+ error_propagate(errp, err);
|
|
|
26ba25 |
+ }
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
void memory_region_init_iommu(void *_iommu_mr,
|
|
|
26ba25 |
--
|
|
|
26ba25 |
1.8.3.1
|
|
|
26ba25 |
|