[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH for-5.0 v2 3/3] exec: Fix for qemu_ram_resize() callback

From: Philippe Mathieu-Daudé
Subject: Re: [PATCH for-5.0 v2 3/3] exec: Fix for qemu_ram_resize() callback
Date: Fri, 3 Apr 2020 12:50:11 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0

On 4/3/20 12:18 PM, Shameer Kolothum wrote:
From: David Hildenbrand <address@hidden>

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 <address@hidden>
[Shameer: added commit log]
Signed-off-by: Shameer Kolothum <address@hidden>
Reviewed-by: Igor Mammedov <address@hidden>

Reviewed-by: Philippe Mathieu-Daudé <address@hidden>

Please find previous discussion here,
  exec.c | 16 ++++++++++++++--
  1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index de9d949902..2874bb5088 100644
--- a/exec.c
+++ b/exec.c
@@ -2074,11 +2074,23 @@ static int memory_try_enable_merging(void *addr, size_t 
  int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
+    const ram_addr_t unaligned_size = newsize;
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 (unaligned_size != memory_region_size(block->mr)) {
+            memory_region_set_size(block->mr, unaligned_size);
+            if (block->resized) {
+                block->resized(block->idstr, unaligned_size, block->host);
+            }
+        }
          return 0;
@@ -2102,9 +2114,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,
-    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;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]