[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 fixed 13/16] numa: Teach ram block notifiers about resizable r
From: |
David Hildenbrand |
Subject: |
[PATCH v2 fixed 13/16] numa: Teach ram block notifiers about resizable ram blocks |
Date: |
Wed, 12 Feb 2020 14:42:51 +0100 |
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 <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Cc: "Dr. David Alan Gilbert" <address@hidden>
Cc: Eduardo Habkost <address@hidden>
Cc: Marcel Apfelbaum <address@hidden>
Cc: Stefano Stabellini <address@hidden>
Cc: Anthony Perard <address@hidden>
Cc: Paul Durrant <address@hidden>
Cc: "Michael S. Tsirkin" <address@hidden>
Cc: address@hidden
Cc: Igor Mammedov <address@hidden>
Signed-off-by: David Hildenbrand <address@hidden>
---
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, &ram_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, &ram_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, &ram_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, &ram_list.ramblock_notifiers, next) {
+ if (!notifier->ram_block_resized) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 5b120ed44b..d6dcea65d1 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -169,7 +169,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
if (entry->vaddr_base != NULL) {
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
- ram_block_notify_remove(entry->vaddr_base, entry->size);
+ ram_block_notify_remove(entry->vaddr_base, entry->size,
+ entry->size);
}
if (munmap(entry->vaddr_base, entry->size) != 0) {
perror("unmap fails");
@@ -211,7 +212,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
}
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
- ram_block_notify_add(vaddr_base, size);
+ ram_block_notify_add(vaddr_base, size, size);
}
entry->vaddr_base = vaddr_base;
@@ -452,7 +453,7 @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t
*buffer)
}
pentry->next = entry->next;
- ram_block_notify_remove(entry->vaddr_base, entry->size);
+ ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
if (munmap(entry->vaddr_base, entry->size) != 0) {
perror("unmap fails");
exit(-1);
diff --git a/include/exec/ramlist.h b/include/exec/ramlist.h
index bc4faa1b00..92e548461e 100644
--- a/include/exec/ramlist.h
+++ b/include/exec/ramlist.h
@@ -65,15 +65,21 @@ void qemu_mutex_lock_ramlist(void);
void qemu_mutex_unlock_ramlist(void);
struct RAMBlockNotifier {
- void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size);
- void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size);
+ void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size);
+ void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size);
+ void (*ram_block_resized)(RAMBlockNotifier *n, void *host, size_t old_size,
+ size_t new_size);
QLIST_ENTRY(RAMBlockNotifier) next;
};
void ram_block_notifier_add(RAMBlockNotifier *n);
void ram_block_notifier_remove(RAMBlockNotifier *n);
-void ram_block_notify_add(void *host, size_t size);
-void ram_block_notify_remove(void *host, size_t size);
+void ram_block_notify_add(void *host, size_t size, size_t max_size);
+void ram_block_notify_remove(void *host, size_t size, size_t max_size);
+void ram_block_notify_resized(void *host, size_t old_size, size_t new_size);
+bool ram_block_notifiers_support_resize(void);
void ram_block_dump(Monitor *mon);
diff --git a/target/i386/hax-mem.c b/target/i386/hax-mem.c
index 6bb5a24917..454d7fb212 100644
--- a/target/i386/hax-mem.c
+++ b/target/i386/hax-mem.c
@@ -293,7 +293,8 @@ static MemoryListener hax_memory_listener = {
.priority = 10,
};
-static void hax_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
+static void hax_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
{
/*
* We must register each RAM block with the HAXM kernel module, or
@@ -304,7 +305,7 @@ static void hax_ram_block_added(RAMBlockNotifier *n, void
*host, size_t size)
* host physical pages for the RAM block as part of this registration
* process, hence the name hax_populate_ram().
*/
- if (hax_populate_ram((uint64_t)(uintptr_t)host, size) < 0) {
+ if (hax_populate_ram((uint64_t)(uintptr_t)host, max_size) < 0) {
fprintf(stderr, "HAX failed to populate RAM\n");
abort();
}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 024bb24e51..6b4cee24a2 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -129,7 +129,8 @@ sev_set_guest_state(SevState new_state)
}
static void
-sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
+sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
{
int r;
struct kvm_enc_region range;
@@ -146,19 +147,20 @@ sev_ram_block_added(RAMBlockNotifier *n, void *host,
size_t size)
}
range.addr = (__u64)(unsigned long)host;
- range.size = size;
+ range.size = max_size;
- trace_kvm_memcrypt_register_region(host, size);
+ trace_kvm_memcrypt_register_region(host, max_size);
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
if (r) {
error_report("%s: failed to register region (%p+%#zx) error '%s'",
- __func__, host, size, strerror(errno));
+ __func__, host, max_size, strerror(errno));
exit(1);
}
}
static void
-sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
+sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
{
int r;
struct kvm_enc_region range;
@@ -175,13 +177,13 @@ sev_ram_block_removed(RAMBlockNotifier *n, void *host,
size_t size)
}
range.addr = (__u64)(unsigned long)host;
- range.size = size;
+ range.size = max_size;
- trace_kvm_memcrypt_unregister_region(host, size);
+ trace_kvm_memcrypt_unregister_region(host, max_size);
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
if (r) {
error_report("%s: failed to unregister region (%p+%#zx)",
- __func__, host, size);
+ __func__, host, max_size);
}
}
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
index b3adc328db..3db6aa49f4 100644
--- a/util/vfio-helpers.c
+++ b/util/vfio-helpers.c
@@ -372,25 +372,26 @@ fail_container:
return ret;
}
-static void qemu_vfio_ram_block_added(RAMBlockNotifier *n,
- void *host, size_t size)
+static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, void *host,
+ size_t size, size_t max_size)
{
QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier);
int ret;
- trace_qemu_vfio_ram_block_added(s, host, size);
- ret = qemu_vfio_dma_map(s, host, size, false, NULL);
+ trace_qemu_vfio_ram_block_added(s, host, max_size);
+ ret = qemu_vfio_dma_map(s, host, max_size, false, NULL);
if (ret) {
- error_report("qemu_vfio_dma_map(%p, %zu) failed: %d", host, size, ret);
+ error_report("qemu_vfio_dma_map(%p, %zu) failed: %d", host,
+ max_size, ret);
}
}
-static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n,
- void *host, size_t size)
+static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n, void *host,
+ size_t size, size_t max_size)
{
QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier);
if (host) {
- trace_qemu_vfio_ram_block_removed(s, host, size);
+ trace_qemu_vfio_ram_block_removed(s, host, max_size);
qemu_vfio_dma_unmap(s, host);
}
}
--
2.24.1
- [PATCH v2 fixed 03/16] util: vfio-helpers: Remove Error parameter from qemu_vfio_undo_mapping(), (continued)
- [PATCH v2 fixed 03/16] util: vfio-helpers: Remove Error parameter from qemu_vfio_undo_mapping(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 04/16] util: vfio-helpers: Factor out removal from qemu_vfio_undo_mapping(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 06/16] exec: Reuse qemu_ram_apply_settings() in qemu_ram_remap(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 05/16] exec: Factor out setting ram settings (madvise ...) into qemu_ram_apply_settings(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 07/16] exec: Drop "shared" parameter from ram_block_add(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 08/16] util/mmap-alloc: Factor out calculation of pagesize to mmap_pagesize(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 09/16] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 10/16] util/mmap-alloc: Factor out populating of memory to mmap_populate(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 11/16] util/mmap-alloc: Prepare for resizable mmaps, David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 12/16] util/mmap-alloc: Implement resizable mmaps, David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 13/16] numa: Teach ram block notifiers about resizable ram blocks,
David Hildenbrand <=
- [PATCH v2 fixed 14/16] util: vfio-helpers: Implement ram_block_resized(), David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 15/16] util: oslib: Resizable anonymous allocations under POSIX, David Hildenbrand, 2020/02/12
- [PATCH v2 fixed 16/16] exec: Ram blocks with resizable anonymous allocations under POSIX, David Hildenbrand, 2020/02/12
- Re: [PATCH v2 fixed 00/16] Ram blocks with resizable anonymous allocations under POSIX, David Hildenbrand, 2020/02/12