代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/qemu 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。