- vdpa-dev: Fix initialisation order to restore VDUSE compatibility - tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc() - migration: fix-possible-int-overflow - target/m68k: Map FPU exceptions to FPSR register - qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo - hvf: arm: Fix encodings for ID_AA64PFR1_EL1 and debug System registers - hw/intc/arm_gic: Fix handling of NS view of GICC_APR<n> - qio: Inherit follow_coroutine_ctx across TLS - target/riscv: Fix the element agnostic function problem - accel/tcg: Fix typo causing tb->page_addr[1] to not be recorded - tcg/loongarch64: Fix tcg_out_movi vs some pcrel pointers - migration: Fix file migration with fdset - ui/vnc: don't return an empty SASL mechlist to the client - target/arm: Fix FJCVTZS vs flush-to-zero - hw/ppc/e500: Prefer QOM cast - sphinx/qapidoc: Fix to generate doc for explicit, unboxed arguments - hw/ppc/e500: Remove unused "irqs" parameter - hw/ppc/e500: Add missing device tree properties to i2c controller node - hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb() - hw/arm/mps2-tz.c: fix RX/TX interrupts order - target/i386: csv: Add support to migrate the incoming context for CSV3 guest - target/i386: csv: Add support to migrate the outgoing context for CSV3 guest - target/i386: csv: Add support to migrate the incoming page for CSV3 guest - target/i386: csv: Add support to migrate the outgoing page for CSV3 guest - linux-headers: update kernel headers to include CSV3 migration cmds - vfio: Only map shared region for CSV3 virtual machine - vga: Force full update for CSV3 guest - target/i386: csv: Load initial image to private memory for CSV3 guest - target/i386: csv: Do not register/unregister guest secure memory for CSV3 guest - target/i386: cpu: Populate CPUID 0x8000_001F when CSV3 is active - target/i386: csv: Add command to load vmcb to CSV3 guest memory - target/i386: csv: Add command to load data to CSV3 guest memory - target/i386: csv: Add command to initialize CSV3 context - target/i386: csv: Add CSV3 context - next-kbd: convert to use qemu_input_handler_register() - qemu/bswap: Undefine CPU_CONVERT() once done - exec/memop: Remove unused memop_big_endian() helper - hw/nvme: fix handling of over-committed queues - 9pfs: fix crash on 'Treaddir' request - hw/misc/psp: Pin the hugepage memory specified by mem2 during use for psp - hw/misc: support tkm use mem2 memory - hw/i386: add mem2 option for qemu - kvm: add support for guest physical bits - target/i386: add guest-phys-bits cpu property Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit f45f35e88509a4ffa9f62332ee9601e9fe1f8d09)
213 lines
6.1 KiB
Diff
213 lines
6.1 KiB
Diff
From ddaa38853d386e5b9f9fa1c3813048872c8ad687 Mon Sep 17 00:00:00 2001
|
|
From: niuyongwen <niuyongwen@hygon.cn>
|
|
Date: Sun, 29 Sep 2024 09:45:15 +0800
|
|
Subject: [PATCH] hw/misc/psp: Pin the hugepage memory specified by mem2 during
|
|
use for psp
|
|
|
|
Signed-off-by: niuyongwen <niuyongwen@hygon.cn>
|
|
---
|
|
hw/misc/psp.c | 138 +++++++++++++++++++++++++++++++++++++++++++-------
|
|
1 file changed, 121 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/hw/misc/psp.c b/hw/misc/psp.c
|
|
index 4eb5ca0e0b..03e8663027 100644
|
|
--- a/hw/misc/psp.c
|
|
+++ b/hw/misc/psp.c
|
|
@@ -17,6 +17,7 @@
|
|
#include "sysemu/runstate.h"
|
|
#include "exec/memory.h"
|
|
#include "exec/address-spaces.h"
|
|
+#include "exec/ramblock.h"
|
|
#include "hw/i386/e820_memory_layout.h"
|
|
#include <sys/ioctl.h>
|
|
|
|
@@ -38,6 +39,8 @@ struct PSPDevState {
|
|
* the TKM module uses different key spaces based on different vids.
|
|
*/
|
|
uint32_t vid;
|
|
+ /* pinned hugepage numbers */
|
|
+ int hp_num;
|
|
};
|
|
|
|
#define PSP_DEV_PATH "/dev/hygon_psp_config"
|
|
@@ -45,6 +48,8 @@ struct PSPDevState {
|
|
#define PSP_IOC_MUTEX_ENABLE _IOWR(HYGON_PSP_IOC_TYPE, 1, NULL)
|
|
#define PSP_IOC_MUTEX_DISABLE _IOWR(HYGON_PSP_IOC_TYPE, 2, NULL)
|
|
#define PSP_IOC_VPSP_OPT _IOWR(HYGON_PSP_IOC_TYPE, 3, NULL)
|
|
+#define PSP_IOC_PIN_USER_PAGE _IOWR(HYGON_PSP_IOC_TYPE, 4, NULL)
|
|
+#define PSP_IOC_UNPIN_USER_PAGE _IOWR(HYGON_PSP_IOC_TYPE, 5, NULL)
|
|
|
|
enum VPSP_DEV_CTRL_OPCODE {
|
|
VPSP_OP_VID_ADD,
|
|
@@ -69,6 +74,109 @@ struct psp_dev_ctrl {
|
|
} __attribute__ ((packed)) data;
|
|
};
|
|
|
|
+static MemoryRegion *find_memory_region_by_name(MemoryRegion *root, const char *name) {
|
|
+ MemoryRegion *subregion;
|
|
+ MemoryRegion *result;
|
|
+
|
|
+ if (strcmp(root->name, name) == 0)
|
|
+ return root;
|
|
+
|
|
+ QTAILQ_FOREACH(subregion, &root->subregions, subregions_link) {
|
|
+ result = find_memory_region_by_name(subregion, name);
|
|
+ if (result) {
|
|
+ return result;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static int pin_user_hugepage(int fd, uint64_t vaddr)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = ioctl(fd, PSP_IOC_PIN_USER_PAGE, vaddr);
|
|
+ /* 22: Invalid argument, some old kernel doesn't support this ioctl command */
|
|
+ if (ret != 0 && errno == EINVAL) {
|
|
+ ret = 0;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int unpin_user_hugepage(int fd, uint64_t vaddr)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = ioctl(fd, PSP_IOC_UNPIN_USER_PAGE, vaddr);
|
|
+ /* 22: Invalid argument, some old kernel doesn't support this ioctl command */
|
|
+ if (ret != 0 && errno == EINVAL) {
|
|
+ ret = 0;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int pin_psp_user_hugepages(struct PSPDevState *state, MemoryRegion *root)
|
|
+{
|
|
+ int ret = 0;
|
|
+ char mr_name[128] = {0};
|
|
+ int i, pinned_num;
|
|
+ MemoryRegion *find_mr = NULL;
|
|
+
|
|
+ for (i = 0 ; i < state->hp_num; ++i) {
|
|
+ sprintf(mr_name, "mem2-%d", i);
|
|
+ find_mr = find_memory_region_by_name(root, mr_name);
|
|
+ if (!find_mr) {
|
|
+ error_report("fail to find memory region by name %s.", mr_name);
|
|
+ ret = -ENOMEM;
|
|
+ goto end;
|
|
+ }
|
|
+
|
|
+ ret = pin_user_hugepage(state->dev_fd, (uint64_t)find_mr->ram_block->host);
|
|
+ if (ret) {
|
|
+ error_report("fail to pin_user_hugepage, ret: %d.", ret);
|
|
+ goto end;
|
|
+ }
|
|
+ }
|
|
+end:
|
|
+ if (ret) {
|
|
+ pinned_num = i;
|
|
+ for (i = 0 ; i < pinned_num; ++i) {
|
|
+ sprintf(mr_name, "mem2-%d", i);
|
|
+ find_mr = find_memory_region_by_name(root, mr_name);
|
|
+ if (!find_mr) {
|
|
+ continue;
|
|
+ }
|
|
+ unpin_user_hugepage(state->dev_fd, (uint64_t)find_mr->ram_block->host);
|
|
+ }
|
|
+
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int unpin_psp_user_hugepages(struct PSPDevState *state, MemoryRegion *root)
|
|
+{
|
|
+ int ret = 0;
|
|
+ char mr_name[128] = {0};
|
|
+ int i;
|
|
+ MemoryRegion *find_mr = NULL;
|
|
+
|
|
+ for (i = 0 ; i < state->hp_num; ++i) {
|
|
+ sprintf(mr_name, "mem2-%d", i);
|
|
+ find_mr = find_memory_region_by_name(root, mr_name);
|
|
+ if (!find_mr) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ ret = unpin_user_hugepage(state->dev_fd, (uint64_t)find_mr->ram_block->host);
|
|
+ if (ret) {
|
|
+ error_report("fail to unpin_user_hugepage, ret: %d.", ret);
|
|
+ goto end;
|
|
+ }
|
|
+ }
|
|
+end:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static void psp_dev_destroy(PSPDevState *state)
|
|
{
|
|
struct psp_dev_ctrl ctrl = { 0 };
|
|
@@ -77,6 +185,11 @@ static void psp_dev_destroy(PSPDevState *state)
|
|
ctrl.op = VPSP_OP_VID_DEL;
|
|
if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) {
|
|
error_report("VPSP_OP_VID_DEL: %d", -errno);
|
|
+ }
|
|
+
|
|
+ /* Unpin hugepage memory */
|
|
+ if (unpin_psp_user_hugepages(state, get_system_memory())) {
|
|
+ error_report("unpin_psp_user_hugepages failed");
|
|
} else {
|
|
state->enabled = false;
|
|
}
|
|
@@ -99,23 +212,6 @@ static void psp_dev_shutdown_notify(Notifier *notifier, void *data)
|
|
psp_dev_destroy(state);
|
|
}
|
|
|
|
-static MemoryRegion *find_memory_region_by_name(MemoryRegion *root, const char *name) {
|
|
- MemoryRegion *subregion;
|
|
- MemoryRegion *result;
|
|
-
|
|
- if (strcmp(root->name, name) == 0)
|
|
- return root;
|
|
-
|
|
- QTAILQ_FOREACH(subregion, &root->subregions, subregions_link) {
|
|
- result = find_memory_region_by_name(subregion, name);
|
|
- if (result) {
|
|
- return result;
|
|
- }
|
|
- }
|
|
-
|
|
- return NULL;
|
|
-}
|
|
-
|
|
static void psp_dev_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
int i;
|
|
@@ -150,6 +246,8 @@ static void psp_dev_realize(DeviceState *dev, Error **errp)
|
|
ram2_end = find_mr->addr + find_mr->size - 1;
|
|
}
|
|
|
|
+ state->hp_num = i;
|
|
+
|
|
if (ram2_start != ram2_end) {
|
|
ctrl.op = VPSP_OP_SET_GPA;
|
|
ctrl.data.gpa.gpa_start = ram2_start;
|
|
@@ -159,6 +257,12 @@ static void psp_dev_realize(DeviceState *dev, Error **errp)
|
|
ram2_start, ram2_end, -errno);
|
|
goto del_vid;
|
|
}
|
|
+
|
|
+ /* Pin hugepage memory */
|
|
+ if(pin_psp_user_hugepages(state, root_mr)) {
|
|
+ error_setg(errp, "pin_psp_user_hugepages failed.");
|
|
+ goto del_vid;
|
|
+ }
|
|
}
|
|
|
|
state->enabled = true;
|
|
--
|
|
2.41.0.windows.1
|
|
|