Re: [PATCH v2 fixed 13/16] numa: Teach ram block notifiers about resizable ram blocks

2020-02-13 Thread Paul Durrant
On Wed, 12 Feb 2020 at 14:44, David Hildenbrand  wrote:
>
> We want to actually resize ram blocks (make everything between
> used_length and max_length inaccessible) - however, not all ram block
> notifiers will support that. Let's teach the notifier that ram blocks
> are indeed resizable, but keep using max_size in the existing notifiers.
>
> Supply the max_size when adding and removing ram blocks. Also, notify on
> resizes. Introduce a way to detect if any registered notifier does not
> support resizes - ram_block_notifiers_support_resize() - which we can later
> use to fallback to legacy handling if a registered notifier (esp., SEV and
> HAX) does not support actual resizes.
>
> Cc: Richard Henderson 
> Cc: Paolo Bonzini 
> Cc: "Dr. David Alan Gilbert" 
> Cc: Eduardo Habkost 
> Cc: Marcel Apfelbaum 
> Cc: Stefano Stabellini 
> Cc: Anthony Perard 
> Cc: Paul Durrant 
> Cc: "Michael S. Tsirkin" 
> Cc: xen-de...@lists.xenproject.org
> Cc: Igor Mammedov 
> Signed-off-by: David Hildenbrand 

Xen parts...

Acked-by: Paul Durrant 



[PATCH v2 fixed 13/16] numa: Teach ram block notifiers about resizable ram blocks

2020-02-12 Thread David Hildenbrand
We want to actually resize ram blocks (make everything between
used_length and max_length inaccessible) - however, not all ram block
notifiers will support that. Let's teach the notifier that ram blocks
are indeed resizable, but keep using max_size in the existing notifiers.

Supply the max_size when adding and removing ram blocks. Also, notify on
resizes. Introduce a way to detect if any registered notifier does not
support resizes - ram_block_notifiers_support_resize() - which we can later
use to fallback to legacy handling if a registered notifier (esp., SEV and
HAX) does not support actual resizes.

Cc: Richard Henderson 
Cc: Paolo Bonzini 
Cc: "Dr. David Alan Gilbert" 
Cc: Eduardo Habkost 
Cc: Marcel Apfelbaum 
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: "Michael S. Tsirkin" 
Cc: xen-de...@lists.xenproject.org
Cc: Igor Mammedov 
Signed-off-by: David Hildenbrand 
---
 exec.c | 13 +++--
 hw/core/numa.c | 34 +-
 hw/i386/xen/xen-mapcache.c |  7 ---
 include/exec/ramlist.h | 14 ++
 target/i386/hax-mem.c  |  5 +++--
 target/i386/sev.c  | 18 ++
 util/vfio-helpers.c| 17 +
 7 files changed, 76 insertions(+), 32 deletions(-)

diff --git a/exec.c b/exec.c
index fc65c4f7ca..f2d30479b8 100644
--- a/exec.c
+++ b/exec.c
@@ -2139,6 +2139,8 @@ static void qemu_ram_apply_settings(void *host, size_t 
length)
  */
 int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
 {
+const ram_addr_t oldsize = block->used_length;
+
 assert(block);
 
 newsize = HOST_PAGE_ALIGN(newsize);
@@ -2167,6 +2169,11 @@ 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);
+
+if (block->host) {
+ram_block_notify_resized(block->host, oldsize, newsize);
+}
+
 memory_region_set_size(block->mr, newsize);
 if (block->resized) {
 block->resized(block->idstr, newsize, block->host);
@@ -2319,7 +2326,8 @@ static void ram_block_add(RAMBlock *new_block, Error 
**errp)
 
 if (new_block->host) {
 qemu_ram_apply_settings(new_block->host, new_block->max_length);
-ram_block_notify_add(new_block->host, new_block->max_length);
+ram_block_notify_add(new_block->host, new_block->used_length,
+ new_block->max_length);
 }
 }
 
@@ -2502,7 +2510,8 @@ void qemu_ram_free(RAMBlock *block)
 }
 
 if (block->host) {
-ram_block_notify_remove(block->host, block->max_length);
+ram_block_notify_remove(block->host, block->used_length,
+block->max_length);
 }
 
 qemu_mutex_lock_ramlist();
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 6599c69e05..5b20dc726d 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -902,11 +902,12 @@ void query_numa_node_mem(NumaNodeMem node_mem[], 
MachineState *ms)
 static int ram_block_notify_add_single(RAMBlock *rb, void *opaque)
 {
 const ram_addr_t max_size = qemu_ram_get_max_length(rb);
+const ram_addr_t size = qemu_ram_get_used_length(rb);
 void *host = qemu_ram_get_host_addr(rb);
 RAMBlockNotifier *notifier = opaque;
 
 if (host) {
-notifier->ram_block_added(notifier, host, max_size);
+notifier->ram_block_added(notifier, host, size, max_size);
 }
 return 0;
 }
@@ -923,20 +924,43 @@ void ram_block_notifier_remove(RAMBlockNotifier *n)
 QLIST_REMOVE(n, next);
 }
 
-void ram_block_notify_add(void *host, size_t size)
+void ram_block_notify_add(void *host, size_t size, size_t max_size)
 {
 RAMBlockNotifier *notifier;
 
 QLIST_FOREACH(notifier, _list.ramblock_notifiers, next) {
-notifier->ram_block_added(notifier, host, size);
+notifier->ram_block_added(notifier, host, size, max_size);
 }
 }
 
-void ram_block_notify_remove(void *host, size_t size)
+void ram_block_notify_remove(void *host, size_t size, size_t max_size)
 {
 RAMBlockNotifier *notifier;
 
 QLIST_FOREACH(notifier, _list.ramblock_notifiers, next) {
-notifier->ram_block_removed(notifier, host, size);
+notifier->ram_block_removed(notifier, host, size, max_size);
 }
 }
+
+void ram_block_notify_resized(void *host, size_t old_size, size_t new_size)
+{
+RAMBlockNotifier *notifier;
+
+QLIST_FOREACH(notifier, _list.ramblock_notifiers, next) {
+if (notifier->ram_block_resized) {
+notifier->ram_block_resized(notifier, host, old_size, new_size);
+}
+}
+}
+
+bool ram_block_notifiers_support_resize(void)
+{
+RAMBlockNotifier *notifier;
+
+QLIST_FOREACH(notifier, _list.ramblock_notifiers, next) {
+if (!notifier->ram_block_resized) {
+return false;
+}
+}
+return true;
+}
diff --git