Skip to content

Commit ce4adc0

Browse files
davidhildenbrandmstsirkin
authored andcommitted
exec: Fix for qemu_ram_resize() callback
Summarizing the issue: 1. Memory regions contain ram blocks with a different size, if the size is not properly aligned. While memory regions can have an unaligned size, ram blocks can't. This is true when creating resizable memory region with an unaligned size. 2. When resizing a ram block/memory region, the size of the memory region is set to the aligned size. The callback is called with the aligned size. The unaligned piece is lost. Because of the above, if ACPI blob length modifications happens after the initial virt_acpi_build() call, and the changed blob length is within the PAGE size boundary, then the revised size is not seen by the firmware on Guest reboot. Hence make sure callback is called if memory region size is changed, irrespective of aligned or not. Signed-off-by: David Hildenbrand <[email protected]> [Shameer: added commit log] Signed-off-by: Shameer Kolothum <[email protected]> Reviewed-by: Igor Mammedov <[email protected]> Message-Id: <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
1 parent 394f0f7 commit ce4adc0

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

exec.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,11 +2074,23 @@ static int memory_try_enable_merging(void *addr, size_t len)
20742074
*/
20752075
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
20762076
{
2077+
const ram_addr_t unaligned_size = newsize;
2078+
20772079
assert(block);
20782080

20792081
newsize = HOST_PAGE_ALIGN(newsize);
20802082

20812083
if (block->used_length == newsize) {
2084+
/*
2085+
* We don't have to resize the ram block (which only knows aligned
2086+
* sizes), however, we have to notify if the unaligned size changed.
2087+
*/
2088+
if (unaligned_size != memory_region_size(block->mr)) {
2089+
memory_region_set_size(block->mr, unaligned_size);
2090+
if (block->resized) {
2091+
block->resized(block->idstr, unaligned_size, block->host);
2092+
}
2093+
}
20822094
return 0;
20832095
}
20842096

@@ -2102,9 +2114,9 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
21022114
block->used_length = newsize;
21032115
cpu_physical_memory_set_dirty_range(block->offset, block->used_length,
21042116
DIRTY_CLIENTS_ALL);
2105-
memory_region_set_size(block->mr, newsize);
2117+
memory_region_set_size(block->mr, unaligned_size);
21062118
if (block->resized) {
2107-
block->resized(block->idstr, newsize, block->host);
2119+
block->resized(block->idstr, unaligned_size, block->host);
21082120
}
21092121
return 0;
21102122
}

0 commit comments

Comments
 (0)