- target/i386: csv: Support inject secret for CSV3 guest only if the extension is enabled
- target/i386: csv: Support load kernel hashes for CSV3 guest only if the extension is enabled
- target/i386: csv: Request to set private memory of CSV3 guest if the extension is enabled
- target/i386: kvm: Support to get and enable extensions for Hygon CoCo guest
- qapi/qom,target/i386: csv-guest: Introduce secret-header-file=str and secret-file=str options
- bakcend: VirtCCA:resolve hugepage memory waste issue in vhost-user scenario
- parallels: fix ext_off assertion failure due to overflow
- backends/cryptodev-vhost-user: Fix local_error leaks
- hw/usb/hcd-ehci: Fix debug printf format string
- target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess
- target/riscv/vector_helper.c: optimize loops in ldst helpers
- target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX()
- target/hexagon: don't look for static glib
- virtio-net: Fix network stall at the host side waiting for kick
- Add if condition to avoid assertion failed error in blockdev_init
- target/arm: Use float_status copy in sme_fmopa_s
- target/arm: take HSTR traps of cp15 accesses to EL2, not EL1
- target/arm: Reinstate "vfp" property on AArch32 CPUs
- target/i386/cpu: Fix notes for CPU models
- target/arm: LDAPR should honour SCTLR_ELx.nAA
- target/riscv: Avoid bad shift in riscv_cpu_do_interrupt()
- hvf: remove unused but set variable
- hw/misc/nrf51_rng: Don't use BIT_MASK() when we mean BIT()
- Avoid taking address of out-of-bounds array index
- target/arm: Fix VCMLA Dd, Dn, Dm[idx]
- target/arm: Fix UMOPA/UMOPS of 16-bit values
- target/arm: Fix SVE/SME gross MTE suppression checks
- target/arm: Fix nregs computation in do_{ld,st}_zpa
- crypto: fix error check on gcry_md_open
- Change vmstate_cpuhp_sts vmstateDescription version_id
- hw/pci: Remove unused pci_irq_pulse() method
- hw/intc: Don't clear pending bits on IRQ lowering
- target/arm: Drop user-only special case in sve_stN_r
- migration: Ensure vmstate_save() sets errp
- target/i386: fix hang when using slow path for ptw_setl
- contrib/plugins: add compat for g_memdup2
- hw/audio/hda: fix memory leak on audio setup
- crypto: perform runtime check for hash/hmac support in gcrypt
- target/arm: Fix incorrect aa64_tidcp1 feature check
- target/arm: fix exception syndrome for AArch32 bkpt insn
- target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
- linux-user: Print tid not pid with strace
- target/arm: Fix A64 scalar SQSHRN and SQRSHRN
- target/arm: Don't assert for 128-bit tile accesses when SVL is 128
- hw/timer/exynos4210_mct: fix possible int overflow
- target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl()
- hw/audio/virtio-snd: Always use little endian audio format
- target/riscv: Fix vcompress with rvv_ta_all_1s
- usb-hub: Fix handling port power control messages
Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit d4a20b24ff377fd07fcbf2b72eecaf07a3ac4cc0)
321 lines
11 KiB
Diff
321 lines
11 KiB
Diff
From da6ee14de85b4e619eedfbe3a6cac3f09d948589 Mon Sep 17 00:00:00 2001
|
|
From: nonce <2774337358@qq.com>
|
|
Date: Thu, 23 Jan 2025 21:03:10 +0800
|
|
Subject: [PATCH] bakcend: VirtCCA:resolve hugepage memory waste issue in
|
|
vhost-user scenario
|
|
|
|
VirtCCA is based on SWIOTLB to implement virtio and will only allocate
|
|
Bounce Buffer in the lower address range below 4GB. Therefore, the
|
|
backend hugepages memory allocated above 4GB will not be used, resulting
|
|
in significant waste.
|
|
|
|
New address space and memory region are added to manage the backend
|
|
hugepages memory corresponding to the GPA below 4GB, and there are
|
|
shared with the vhostuser backend.
|
|
|
|
Signed-off-by: nonce0_0 <2774337358@qq.com>
|
|
---
|
|
backends/hostmem-file.c | 85 +++++++++++++++++++++++++++++++++++
|
|
hw/core/numa.c | 20 +++++++++
|
|
hw/virtio/vhost.c | 8 +++-
|
|
include/exec/address-spaces.h | 3 ++
|
|
include/exec/cpu-common.h | 1 +
|
|
include/exec/memory.h | 11 +++++
|
|
system/physmem.c | 17 +++++++
|
|
system/vl.c | 9 ++++
|
|
8 files changed, 153 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
|
|
index 361d4a8103..891fe4ac4a 100644
|
|
--- a/backends/hostmem-file.c
|
|
+++ b/backends/hostmem-file.c
|
|
@@ -20,9 +20,13 @@
|
|
#include "qom/object.h"
|
|
#include "qapi/visitor.h"
|
|
#include "qapi/qapi-visit-common.h"
|
|
+#include "sysemu/kvm.h"
|
|
+#include "exec/address-spaces.h"
|
|
|
|
OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE)
|
|
|
|
+bool virtcca_shared_hugepage_mapped = false;
|
|
+uint64_t virtcca_cvm_ram_size = 0;
|
|
|
|
struct HostMemoryBackendFile {
|
|
HostMemoryBackend parent_obj;
|
|
@@ -36,6 +40,83 @@ struct HostMemoryBackendFile {
|
|
OnOffAuto rom;
|
|
};
|
|
|
|
+/* Parse the path of the hugepages memory file used for memory sharing */
|
|
+static int virtcca_parse_share_mem_path(char *src, char *dst)
|
|
+{
|
|
+ int ret = 0;
|
|
+ char src_copy[PATH_MAX];
|
|
+ char *token = NULL;
|
|
+ char *last_dir = NULL;
|
|
+ char *second_last_dir = NULL;
|
|
+ static const char delimiter[] = "/";
|
|
+
|
|
+ if (src == NULL || dst == NULL ||
|
|
+ strlen(src) == 0 || strlen(src) > PATH_MAX - 1) {
|
|
+ error_report("Invalid input: NULL pointer or invalid string length.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ strcpy(src_copy, src);
|
|
+ token = strtok(src_copy, delimiter);
|
|
+
|
|
+ /* Iterate over the path segments to find the second-to-last directory */
|
|
+ while (token != NULL) {
|
|
+ second_last_dir = last_dir;
|
|
+ last_dir = token;
|
|
+ token = strtok(NULL, delimiter);
|
|
+ }
|
|
+
|
|
+ /* Check if the second-to-last directory is found */
|
|
+ if (second_last_dir == NULL) {
|
|
+ error_report("Invalid path: second-to-last directory not found.");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Construct the share memory path by appending the extracted domain name
|
|
+ * to the hugepages memory filesystem prefix
|
|
+ */
|
|
+ ret = snprintf(dst, PATH_MAX, "/dev/hugepages/libvirt/qemu/%s",
|
|
+ second_last_dir);
|
|
+
|
|
+ if (ret < 0 || ret >= PATH_MAX) {
|
|
+ error_report("Error: snprintf failed to construct the share mem path");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Create a hugepage memory region in the virtcca scenario
|
|
+ * for sharing with process like vhost-user and others.
|
|
+ */
|
|
+static void
|
|
+virtcca_shared_backend_memory_alloc(char *mem_path, uint32_t ram_flags, Error **errp)
|
|
+{
|
|
+ char dst[PATH_MAX];
|
|
+ uint64_t size = virtcca_cvm_ram_size;
|
|
+
|
|
+ if (virtcca_parse_share_mem_path(mem_path, dst)) {
|
|
+ error_report("parse virtcca share memory path failed");
|
|
+ exit(1);
|
|
+ }
|
|
+ if (virtcca_cvm_ram_size >= VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE) {
|
|
+ size = VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE;
|
|
+ }
|
|
+
|
|
+ virtcca_shared_hugepage = g_new(MemoryRegion, 1);
|
|
+ memory_region_init_ram_from_file(virtcca_shared_hugepage, NULL,
|
|
+ "virtcca_shared_hugepage", size,
|
|
+ VIRTCCA_SHARED_HUGEPAGE_ALIGN,
|
|
+ ram_flags, dst, 0, errp);
|
|
+ if (*errp) {
|
|
+ error_reportf_err(*errp, "cannot init RamBlock for virtcca_shared_hugepage: ");
|
|
+ exit(1);
|
|
+ }
|
|
+ virtcca_shared_hugepage_mapped = true;
|
|
+}
|
|
+
|
|
static void
|
|
file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|
{
|
|
@@ -90,6 +171,10 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|
backend->size, fb->align, ram_flags,
|
|
fb->mem_path, fb->offset, errp);
|
|
g_free(name);
|
|
+
|
|
+ if (virtcca_cvm_enabled() && backend->share && !virtcca_shared_hugepage_mapped) {
|
|
+ virtcca_shared_backend_memory_alloc(fb->mem_path, ram_flags, errp);
|
|
+ }
|
|
#endif
|
|
}
|
|
|
|
diff --git a/hw/core/numa.c b/hw/core/numa.c
|
|
index f08956ddb0..e7c48dab61 100644
|
|
--- a/hw/core/numa.c
|
|
+++ b/hw/core/numa.c
|
|
@@ -42,6 +42,8 @@
|
|
#include "qemu/option.h"
|
|
#include "qemu/config-file.h"
|
|
#include "qemu/cutils.h"
|
|
+#include "exec/address-spaces.h"
|
|
+#include "sysemu/kvm.h"
|
|
|
|
QemuOptsList qemu_numa_opts = {
|
|
.name = "numa",
|
|
@@ -641,6 +643,21 @@ static void numa_init_memdev_container(MachineState *ms, MemoryRegion *ram)
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * Add virtcca_shared_hugepage as a sub-MR to the root MR of address space
|
|
+ * address_space_memory and address_space_virtcca_shared_memory.
|
|
+ */
|
|
+static void virtcca_shared_memory_configuration(MachineState *ms)
|
|
+{
|
|
+ MemoryRegion *alias_mr = g_new(MemoryRegion, 1);
|
|
+
|
|
+ memory_region_add_subregion_overlap(ms->ram, 0, virtcca_shared_hugepage, 1);
|
|
+ memory_region_init_alias(alias_mr, NULL, "alias-mr", virtcca_shared_hugepage,
|
|
+ 0, int128_get64(virtcca_shared_hugepage->size));
|
|
+ memory_region_add_subregion(address_space_virtcca_shared_memory.root,
|
|
+ VIRTCCA_GPA_START, alias_mr);
|
|
+}
|
|
+
|
|
void numa_complete_configuration(MachineState *ms)
|
|
{
|
|
int i;
|
|
@@ -711,6 +728,9 @@ void numa_complete_configuration(MachineState *ms)
|
|
memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id,
|
|
ms->ram_size);
|
|
numa_init_memdev_container(ms, ms->ram);
|
|
+ if (virtcca_cvm_enabled() && virtcca_shared_hugepage->ram_block) {
|
|
+ virtcca_shared_memory_configuration(ms);
|
|
+ }
|
|
}
|
|
/* QEMU needs at least all unique node pair distances to build
|
|
* the whole NUMA distance table. QEMU treats the distance table
|
|
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
|
|
index d29075aa04..8b95558013 100644
|
|
--- a/hw/virtio/vhost.c
|
|
+++ b/hw/virtio/vhost.c
|
|
@@ -30,6 +30,7 @@
|
|
#include "sysemu/dma.h"
|
|
#include "trace.h"
|
|
#include "qapi/qapi-commands-migration.h"
|
|
+#include "sysemu/kvm.h"
|
|
|
|
/* enabled until disconnected backend stabilizes */
|
|
#define _VHOST_DEBUG 1
|
|
@@ -1616,7 +1617,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
|
hdev->log_size = 0;
|
|
hdev->log_enabled = false;
|
|
hdev->started = false;
|
|
- memory_listener_register(&hdev->memory_listener, &address_space_memory);
|
|
+ if (virtcca_cvm_enabled()) {
|
|
+ memory_listener_register(&hdev->memory_listener,
|
|
+ &address_space_virtcca_shared_memory);
|
|
+ } else {
|
|
+ memory_listener_register(&hdev->memory_listener, &address_space_memory);
|
|
+ }
|
|
QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
|
|
|
|
/*
|
|
diff --git a/include/exec/address-spaces.h b/include/exec/address-spaces.h
|
|
index 0d0aa61d68..4518b5da86 100644
|
|
--- a/include/exec/address-spaces.h
|
|
+++ b/include/exec/address-spaces.h
|
|
@@ -33,6 +33,9 @@ MemoryRegion *get_system_io(void);
|
|
|
|
extern AddressSpace address_space_memory;
|
|
extern AddressSpace address_space_io;
|
|
+extern AddressSpace address_space_virtcca_shared_memory;
|
|
+
|
|
+extern MemoryRegion *virtcca_shared_hugepage;
|
|
|
|
#endif
|
|
|
|
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
|
|
index c7fd30d5b9..d21d9990ad 100644
|
|
--- a/include/exec/cpu-common.h
|
|
+++ b/include/exec/cpu-common.h
|
|
@@ -28,6 +28,7 @@ typedef uint64_t vaddr;
|
|
|
|
void cpu_exec_init_all(void);
|
|
void cpu_exec_step_atomic(CPUState *cpu);
|
|
+void virtcca_shared_memory_address_space_init(void);
|
|
|
|
/* Using intptr_t ensures that qemu_*_page_mask is sign-extended even
|
|
* when intptr_t is 32-bit and we are aligning a long long.
|
|
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
|
index 542c9da918..33778f5c64 100644
|
|
--- a/include/exec/memory.h
|
|
+++ b/include/exec/memory.h
|
|
@@ -243,6 +243,17 @@ typedef struct IOMMUTLBEvent {
|
|
/* RAM FD is opened read-only */
|
|
#define RAM_READONLY_FD (1 << 11)
|
|
|
|
+/* The GPA range of the VirtCCA bounce buffer is from 1GB to 4GB. */
|
|
+#define VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE 0xc0000000ULL
|
|
+
|
|
+/* The VirtCCA shared hugepage memory granularity is 1GB */
|
|
+#define VIRTCCA_SHARED_HUGEPAGE_ALIGN 0x40000000ULL
|
|
+
|
|
+/* The GPA starting address of the VirtCCA CVM is 1GB */
|
|
+#define VIRTCCA_GPA_START 0x40000000ULL
|
|
+
|
|
+extern uint64_t virtcca_cvm_ram_size;
|
|
+
|
|
static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
|
|
IOMMUNotifierFlag flags,
|
|
hwaddr start, hwaddr end,
|
|
diff --git a/system/physmem.c b/system/physmem.c
|
|
index 250f315bc8..8f4be2d131 100644
|
|
--- a/system/physmem.c
|
|
+++ b/system/physmem.c
|
|
@@ -89,9 +89,17 @@ RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
|
|
|
|
static MemoryRegion *system_memory;
|
|
static MemoryRegion *system_io;
|
|
+static MemoryRegion *virtcca_shared_memory;
|
|
+
|
|
+/*
|
|
+ * Serves as the sub-MR of the root MR (virtcca_shared_memory)
|
|
+ * and is associated with the RAMBlock.
|
|
+ */
|
|
+MemoryRegion *virtcca_shared_hugepage;
|
|
|
|
AddressSpace address_space_io;
|
|
AddressSpace address_space_memory;
|
|
+AddressSpace address_space_virtcca_shared_memory;
|
|
|
|
static MemoryRegion io_mem_unassigned;
|
|
|
|
@@ -2586,6 +2594,15 @@ static void memory_map_init(void)
|
|
address_space_init(&address_space_io, system_io, "I/O");
|
|
}
|
|
|
|
+void virtcca_shared_memory_address_space_init(void)
|
|
+{
|
|
+ virtcca_shared_memory = g_malloc(sizeof(*virtcca_shared_memory));
|
|
+ memory_region_init(virtcca_shared_memory, NULL,
|
|
+ "virtcca_shared_memory", UINT64_MAX);
|
|
+ address_space_init(&address_space_virtcca_shared_memory,
|
|
+ virtcca_shared_memory, "virtcca_shared_memory");
|
|
+}
|
|
+
|
|
MemoryRegion *get_system_memory(void)
|
|
{
|
|
return system_memory;
|
|
diff --git a/system/vl.c b/system/vl.c
|
|
index a1e5e68773..7c10cd1337 100644
|
|
--- a/system/vl.c
|
|
+++ b/system/vl.c
|
|
@@ -3784,6 +3784,15 @@ void qemu_init(int argc, char **argv)
|
|
configure_accelerators(argv[0]);
|
|
phase_advance(PHASE_ACCEL_CREATED);
|
|
|
|
+ /*
|
|
+ * Must run after kvm_init completes, as virtcca_cvm_enabled()
|
|
+ * depends on initialization performed in kvm_init.
|
|
+ */
|
|
+ if (virtcca_cvm_enabled()) {
|
|
+ virtcca_cvm_ram_size = current_machine->ram_size;
|
|
+ virtcca_shared_memory_address_space_init();
|
|
+ }
|
|
+
|
|
/*
|
|
* Beware, QOM objects created before this point miss global and
|
|
* compat properties.
|
|
--
|
|
2.41.0.windows.1
|
|
|