1 Star 0 Fork 126

ganqx/src-qemu

forked from src-openEuler/qemu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
hw-misc-psp-Pin-the-hugepage-memory-specified-by-mem.patch 6.11 KB
一键复制 编辑 原始数据 按行查看 历史
Jiabo Feng 提交于 2024-12-12 17:01 . QEMU update to version 8.2.0-26:
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
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ganqx/src-qemu.git
git@gitee.com:ganqx/src-qemu.git
ganqx
src-qemu
src-qemu
master

搜索帮助