On Wed, 11 Mar 2020 17:20:07 +0000 Shameer Kolothum <shameerali.kolothum.th...@huawei.com> wrote:
> From: David Hildenbrand <da...@redhat.com> > > 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 <da...@redhat.com> > [Shameer: added commit log] > Signed-off-by: Shameer Kolothum <shameerali.kolothum.th...@huawei.com> Reviewed-by: Igor Mammedov <imamm...@redhat.com> > --- > Please find the discussion here, > https://patchwork.kernel.org/patch/11339591/ > --- > exec.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/exec.c b/exec.c > index 0cc500d53a..f8974cd303 100644 > --- a/exec.c > +++ b/exec.c > @@ -2073,11 +2073,21 @@ static int memory_try_enable_merging(void *addr, > size_t len) > */ > int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp) > { > + const ram_addr_t unaligned_size = newsize; > + > assert(block); > > newsize = HOST_PAGE_ALIGN(newsize); > > if (block->used_length == newsize) { > + /* > + * We don't have to resize the ram block (which only knows aligned > + * sizes), however, we have to notify if the unaligned size changed. > + */ > + if (block->resized && unaligned_size != > memory_region_size(block->mr)) { > + block->resized(block->idstr, unaligned_size, block->host); > + memory_region_set_size(block->mr, unaligned_size); > + } > return 0; > } > > @@ -2101,9 +2111,9 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t > newsize, Error **errp) > block->used_length = newsize; > cpu_physical_memory_set_dirty_range(block->offset, block->used_length, > DIRTY_CLIENTS_ALL); > - memory_region_set_size(block->mr, newsize); > + memory_region_set_size(block->mr, unaligned_size); > if (block->resized) { > - block->resized(block->idstr, newsize, block->host); > + block->resized(block->idstr, unaligned_size, block->host); > } > return 0; > }