From 27fb05d4ef5c8c661324ba2740d090880e06c0e4 Mon Sep 17 00:00:00 2001 From: xiongmengbiao Date: Thu, 13 Feb 2025 17:14:15 +0800 Subject: [PATCH] [Feature] Support Hygon TKM run on CSV Guest ANBZ: #13343 Signed-off-by: xiongmengbiao --- ...ure-hw-i386-add-mem2-option-for-qemu.patch | 330 ++++++++++++++++++ ...misc-psp-support-tkm-use-mem2-memory.patch | 124 +++++++ ...sc-psp-Pin-the-hugepage-memory-speci.patch | 213 +++++++++++ qemu-kvm.spec | 11 +- 4 files changed, 677 insertions(+), 1 deletion(-) create mode 100644 1130-newfeature-hw-i386-add-mem2-option-for-qemu.patch create mode 100644 1131-newfeature-hw-misc-psp-support-tkm-use-mem2-memory.patch create mode 100644 1132-newfeature-hw-misc-psp-Pin-the-hugepage-memory-speci.patch diff --git a/1130-newfeature-hw-i386-add-mem2-option-for-qemu.patch b/1130-newfeature-hw-i386-add-mem2-option-for-qemu.patch new file mode 100644 index 0000000..3f33746 --- /dev/null +++ b/1130-newfeature-hw-i386-add-mem2-option-for-qemu.patch @@ -0,0 +1,330 @@ +From 76a47a90f9ecee19f86039fdea992c7d5c1f4d22 Mon Sep 17 00:00:00 2001 +From: xiongmengbiao +Date: Wed, 29 May 2024 00:05:44 +0800 +Subject: [PATCH 1/3] [newfeature]: hw/i386: add mem2 option for qemu + +The '-mem2' option is used to create a set of hugepages +of memory and map them to a fixed address range of the guest. + +This allows some devices to easily obtain continuous host +physical address ranges for performing DMA operations. + +Change-Id: I9740405d5cd70b0bb399495128ffcffa0b1311c4 +Signed-off-by: xiongmengbiao +--- + hw/i386/pc.c | 129 ++++++++++++++++++++++++++++++++++++++++++++ + include/hw/boards.h | 2 + + qemu-options.hx | 12 +++++ + softmmu/vl.c | 71 ++++++++++++++++++++++++ + 4 files changed, 214 insertions(+) + +diff --git a/hw/i386/pc.c b/hw/i386/pc.c +index a2ef40ecbc..a29c7e5b4a 100644 +--- a/hw/i386/pc.c ++++ b/hw/i386/pc.c +@@ -790,6 +790,119 @@ void xen_load_linux(PCMachineState *pcms) + x86ms->fw_cfg = fw_cfg; + } + ++static int try_create_2MB_page(uint32_t page_num) ++{ ++ char nr_hp_num_s[256] = {0}; ++ char free_hp_num_s[256] = {0}; ++ const char *nr_hugepages_dir = "/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"; ++ const char *free_hugepages_dir = "/sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages"; ++ int nr_hp_num = -1, free_hp_num = -1, ret = -1; ++ int nr_fd = qemu_open_old(nr_hugepages_dir, O_RDWR); ++ int free_fd = qemu_open_old(free_hugepages_dir, O_RDONLY); ++ ++ if (nr_fd < 0 || free_fd < 0) { ++ error_report("%s: qemu_open failed: %s\n", __func__, strerror(errno)); ++ goto end; ++ } ++ ++ if (read(nr_fd, nr_hp_num_s, 256) < 0) ++ goto end; ++ if (read(free_fd, free_hp_num_s, 256) < 0) ++ goto end; ++ ++ nr_hp_num = atoi(nr_hp_num_s); ++ free_hp_num = atoi(free_hp_num_s); ++ if (nr_hp_num < 0 || free_hp_num < 0) ++ goto end; ++ ++ if (page_num <= free_hp_num) { ++ ret = 0; ++ goto end; ++ } ++ ++ nr_hp_num += (page_num - free_hp_num); ++ snprintf (nr_hp_num_s, 256, "%d", nr_hp_num); ++ if (write(nr_fd, nr_hp_num_s, strlen(nr_hp_num_s)) < 0) ++ goto end; ++ ++ ret = 0; ++end: ++ if (nr_fd >= 0) ++ qemu_close(nr_fd); ++ if (free_fd >= 0) ++ qemu_close(free_fd); ++ return ret; ++} ++ ++#define HUGEPAGE_NUM_MAX 128 ++#define HUGEPAGE_SIZE (1024*1024*2) ++static void mem2_init(MachineState *ms, MemoryRegion *system_memory) ++{ ++ MemoryRegion *mem2_mr[HUGEPAGE_NUM_MAX] = {NULL}; ++ char mr_name[128] = {0}; ++ void *ram = NULL; ++ int ret = 0, lock_fd = 0; ++ const char *lock_file = "/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"; ++ uint32_t page_num = ms->ram2_size / HUGEPAGE_SIZE, i; ++ ++ if (HUGEPAGE_NUM_MAX < page_num) { ++ error_report("\"-mem2 'size='\" needs to Less than %dM\n", ++ (HUGEPAGE_SIZE * HUGEPAGE_NUM_MAX) / (1024 * 1024)); ++ exit(EXIT_FAILURE); ++ } ++ ++ // Apply for hugepages from OS and use them, which needs to be synchronized ++ lock_fd = qemu_open_old(lock_file, O_WRONLY); ++ if (lock_fd < 0) { ++ error_report("%s: open %s failed: %s\n", __func__, lock_file, strerror(errno)); ++ exit(EXIT_FAILURE); ++ } ++ ++ // Non-blocking ++ while (qemu_lock_fd(lock_fd, 0, 0, true)) { ++ if (errno != EACCES && errno != EAGAIN) { ++ error_report("qemu_lock_fd failed: %s\n", strerror(errno)); ++ exit(EXIT_FAILURE); ++ } ++ } ++ ++ /** try to create hugepage. ++ * If there are enough free hugepages, then do nothing. ++ */ ++ ret = try_create_2MB_page(page_num); ++ if (ret) { ++ error_report("%s: Failed to allocate hugepage\n", __func__); ++ goto unlock; ++ } ++ ++ for (i = 0; i < page_num; ++i) { ++ mem2_mr[i] = g_malloc(sizeof(MemoryRegion)); ++ ram = mmap(NULL, HUGEPAGE_SIZE, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_HUGETLB, -1, 0); ++ if (ram == MAP_FAILED) { ++ error_report("%s: mmap failed: %s", __func__, strerror(errno)); ++ goto unlock; ++ } ++ ++ sprintf(mr_name, "mem2-%d", i); ++ memory_region_init_ram_ptr(mem2_mr[i], NULL, mr_name, HUGEPAGE_SIZE, ram); ++ memory_region_add_subregion(system_memory, ms->ram2_base + (i * HUGEPAGE_SIZE), mem2_mr[i]); ++ } ++ ++ ret = 0; ++unlock: ++ qemu_unlock_fd(lock_fd, 0, 0); ++ qemu_close(lock_fd); ++ ++ if (ret) { ++ for (i = 0; i < page_num; ++i) { ++ if (mem2_mr[i]) ++ g_free(mem2_mr[i]); ++ } ++ exit(EXIT_FAILURE); ++ } ++} ++ + #define PC_ROM_MIN_VGA 0xc0000 + #define PC_ROM_MIN_OPTION 0xc8000 + #define PC_ROM_MAX 0xe0000 +@@ -836,6 +949,22 @@ void pc_memory_init(PCMachineState *pcms, + e820_add_entry(0x100000000ULL, x86ms->above_4g_mem_size, E820_RAM); + } + ++ if (machine->ram2_size && machine->ram2_base) { ++ if (0x100000000ULL + x86ms->above_4g_mem_size > machine->ram2_base) { ++ error_report("\"-mem2 'base'\" needs to greater 0x%llx\n", ++ 0x100000000ULL + x86ms->above_4g_mem_size); ++ exit(EXIT_FAILURE); ++ } ++ if (machine->ram2_base & (HUGEPAGE_SIZE - 1) || ++ machine->ram2_size & (HUGEPAGE_SIZE - 1)) { ++ error_report("\"-mem2 'base|size'\" needs to aligned to 0x%x\n", HUGEPAGE_SIZE); ++ exit(EXIT_FAILURE); ++ } ++ ++ mem2_init(machine, system_memory); ++ e820_add_entry(machine->ram2_base, machine->ram2_size, E820_RAM); ++ } ++ + if (pcms->sgx_epc.size != 0) { + e820_add_entry(pcms->sgx_epc.base, pcms->sgx_epc.size, E820_RESERVED); + } +diff --git a/include/hw/boards.h b/include/hw/boards.h +index 9c1c190104..01b0cf816e 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -344,6 +344,8 @@ struct MachineState { + + ram_addr_t ram_size; + ram_addr_t maxram_size; ++ ram_addr_t ram2_base; ++ ram_addr_t ram2_size; + uint64_t ram_slots; + const char *boot_order; + const char *boot_once; +diff --git a/qemu-options.hx b/qemu-options.hx +index ae2c6dbbfc..014739c622 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -5397,6 +5397,18 @@ SRST + (qemu) qom-set /objects/iothread1 poll-max-ns 100000 + ERST + ++DEF("mem2", HAS_ARG, QEMU_OPTION_mem2, ++ "-mem2 base=addr[G],size=n[MG]\n" ++ " Map guest memory using host hugepages\n" ++ " base: starting position of guest physical address\n" ++ " size: the size of mmaped memory\n" ++ "NOTE: Both `base` and `size` need to be aligned according to 2MB\n", ++ QEMU_ARCH_I386) ++SRST ++``-mem2 base=addr[G],size=n[MG]`` ++ Map the host's large page memory at the specified guest address ++ so that some devices can use larger contiguous physical memory. ++ERST + + HXCOMM This is the last statement. Insert new options before this line! + +diff --git a/softmmu/vl.c b/softmmu/vl.c +index 620a1f1367..6951eaa023 100644 +--- a/softmmu/vl.c ++++ b/softmmu/vl.c +@@ -168,6 +168,8 @@ static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); + static bool nographic = false; + static int mem_prealloc; /* force preallocation of physical target memory */ + static ram_addr_t ram_size; ++static ram_addr_t ram2_base; ++static ram_addr_t ram2_size; + static const char *vga_model = NULL; + static DisplayOptions dpy; + static int num_serial_hds; +@@ -496,6 +498,23 @@ static QemuOptsList qemu_action_opts = { + }, + }; + ++static QemuOptsList qemu_mem2_opts = { ++ .name = "mem2", ++ .merge_lists = true, ++ .head = QTAILQ_HEAD_INITIALIZER(qemu_mem2_opts.head), ++ .desc = { ++ { ++ .name = "base", ++ .type = QEMU_OPT_SIZE, ++ }, ++ { ++ .name = "size", ++ .type = QEMU_OPT_SIZE, ++ }, ++ { /* end of list */ } ++ }, ++}; ++ + const char *qemu_get_vm_name(void) + { + return qemu_name; +@@ -1884,6 +1903,9 @@ static void qemu_apply_machine_options(QDict *qdict) + current_machine->maxram_size = maxram_size; + current_machine->ram_slots = ram_slots; + ++ current_machine->ram2_size = ram2_size; ++ current_machine->ram2_base = ram2_base; ++ + opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL); + if (opts) { + boot_order = qemu_opt_get(opts, "order"); +@@ -2137,6 +2159,45 @@ static void set_memory_options(MachineClass *mc) + loc_pop(&loc); + } + ++static void set_mem2_options(void) ++{ ++ uint64_t sz, base; ++ const char *sz_str = NULL, *base_str = NULL; ++ QemuOpts *opts = qemu_find_opts_singleton("mem2"); ++ Location loc; ++ ++ loc_push_none(&loc); ++ qemu_opts_loc_restore(opts); ++ ++ base_str = qemu_opt_get(opts, "base"); ++ sz_str = qemu_opt_get(opts, "size"); ++ ++ if (!base_str && !sz_str) ++ return; ++ ++ if ((!base_str || !*base_str) ++ || (!sz_str || !*sz_str)) { ++ error_report("missing 'base' or 'size' argument for -mem2 option"); ++ exit(EXIT_FAILURE); ++ } ++ ++ base = qemu_opt_get_size(opts, "base", ram2_base); ++ if (!base) { ++ error_report("invalid 'base' value\n"); ++ exit(EXIT_FAILURE); ++ } ++ ram2_base = base; ++ ++ sz = qemu_opt_get_size(opts, "size", ram2_size); ++ if (!sz) { ++ error_report("invalid 'size' value\n"); ++ exit(EXIT_FAILURE); ++ } ++ ram2_size = sz; ++ ++ loc_pop(&loc); ++} ++ + static void qemu_create_machine(QDict *qdict) + { + MachineClass *machine_class = select_machine(qdict, &error_fatal); +@@ -2144,6 +2205,8 @@ static void qemu_create_machine(QDict *qdict) + + set_memory_options(machine_class); + ++ set_mem2_options(); ++ + current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class))); + object_property_add_child(object_get_root(), "machine", + OBJECT(current_machine)); +@@ -2804,6 +2867,7 @@ void qemu_init(int argc, char **argv, char **envp) + qemu_add_opts(&qemu_semihosting_config_opts); + qemu_add_opts(&qemu_fw_cfg_opts); + qemu_add_opts(&qemu_action_opts); ++ qemu_add_opts(&qemu_mem2_opts); + module_call_init(MODULE_INIT_OPTS); + + error_init(argv[0]); +@@ -3657,6 +3721,13 @@ void qemu_init(int argc, char **argv, char **envp) + case QEMU_OPTION_nouserconfig: + /* Nothing to be parsed here. Especially, do not error out below. */ + break; ++ case QEMU_OPTION_mem2: ++ opts = qemu_opts_parse_noisily(qemu_find_opts("mem2"), ++ optarg, false); ++ if (!opts) { ++ exit(EXIT_FAILURE); ++ } ++ break; + default: + if (os_parse_cmd_args(popt->index, optarg)) { + error_report("Option not supported in this build"); +-- +2.36.6 + diff --git a/1131-newfeature-hw-misc-psp-support-tkm-use-mem2-memory.patch b/1131-newfeature-hw-misc-psp-support-tkm-use-mem2-memory.patch new file mode 100644 index 0000000..f755a40 --- /dev/null +++ b/1131-newfeature-hw-misc-psp-support-tkm-use-mem2-memory.patch @@ -0,0 +1,124 @@ +From c5b9286549f37f14e8ddbfb7831a6b7d125b1f65 Mon Sep 17 00:00:00 2001 +From: xiongmengbiao +Date: Wed, 29 May 2024 15:18:55 +0800 +Subject: [PATCH 2/3] [newfeature]: hw/misc/psp: support tkm use mem2 memory + +Change-Id: I04c76eb27eb7c097922d61b893a47b18f55bcd66 +Signed-off-by: xiongmengbiao +--- + hw/misc/psp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 63 insertions(+), 1 deletion(-) + +diff --git a/hw/misc/psp.c b/hw/misc/psp.c +index a876ca2c94..b71b2ab619 100644 +--- a/hw/misc/psp.c ++++ b/hw/misc/psp.c +@@ -15,6 +15,9 @@ + #include "migration/vmstate.h" + #include "hw/qdev-properties.h" + #include "sysemu/runstate.h" ++#include "exec/memory.h" ++#include "exec/address-spaces.h" ++#include "hw/i386/e820_memory_layout.h" + #include + + #define TYPE_PSP_DEV "psp" +@@ -46,14 +49,24 @@ struct PSPDevState { + enum VPSP_DEV_CTRL_OPCODE { + VPSP_OP_VID_ADD, + VPSP_OP_VID_DEL, ++ VPSP_OP_SET_DEFAULT_VID_PERMISSION, ++ VPSP_OP_GET_DEFAULT_VID_PERMISSION, ++ VPSP_OP_SET_GPA, + }; + + struct psp_dev_ctrl { + unsigned char op; ++ unsigned char resv[3]; + union { + unsigned int vid; ++ // Set or check the permissions for the default VID ++ unsigned int def_vid_perm; ++ struct { ++ uint64_t gpa_start; ++ uint64_t gpa_end; ++ } gpa; + unsigned char reserved[128]; +- } data; ++ } __attribute__ ((packed)) data; + }; + + static void psp_dev_destroy(PSPDevState *state) +@@ -86,10 +99,32 @@ 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; ++ char mr_name[128] = {0}; + struct psp_dev_ctrl ctrl = { 0 }; + PSPDevState *state = PSP_DEV(dev); ++ MemoryRegion *root_mr = get_system_memory(); ++ MemoryRegion *find_mr = NULL; ++ uint64_t ram2_start = 0, ram2_end = 0; + + state->dev_fd = qemu_open_old(PSP_DEV_PATH, O_RDWR); + if (state->dev_fd < 0) { +@@ -104,9 +139,36 @@ static void psp_dev_realize(DeviceState *dev, Error **errp) + goto end; + } + ++ for (i = 0 ;; ++i) { ++ sprintf(mr_name, "mem2-%d", i); ++ find_mr = find_memory_region_by_name(root_mr, mr_name); ++ if (!find_mr) ++ break; ++ ++ if (!ram2_start) ++ ram2_start = find_mr->addr; ++ ram2_end = find_mr->addr + find_mr->size - 1; ++ } ++ ++ if (ram2_start != ram2_end) { ++ ctrl.op = VPSP_OP_SET_GPA; ++ ctrl.data.gpa.gpa_start = ram2_start; ++ ctrl.data.gpa.gpa_end = ram2_end; ++ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { ++ error_setg(errp, "psp_dev_realize VPSP_OP_SET_GPA (start 0x%lx, end 0x%lx), return %d", ++ ram2_start, ram2_end, -errno); ++ goto del_vid; ++ } ++ } ++ + state->enabled = true; + state->shutdown_notifier.notify = psp_dev_shutdown_notify; + qemu_register_shutdown_notifier(&state->shutdown_notifier); ++ ++ return; ++del_vid: ++ ctrl.op = VPSP_OP_VID_DEL; ++ ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl); + end: + return; + } +-- +2.36.6 + diff --git a/1132-newfeature-hw-misc-psp-Pin-the-hugepage-memory-speci.patch b/1132-newfeature-hw-misc-psp-Pin-the-hugepage-memory-speci.patch new file mode 100644 index 0000000..eada3a1 --- /dev/null +++ b/1132-newfeature-hw-misc-psp-Pin-the-hugepage-memory-speci.patch @@ -0,0 +1,213 @@ +From da768933bfcec318425f788524b792e58bdf51ad Mon Sep 17 00:00:00 2001 +From: niuyongwen +Date: Sun, 29 Sep 2024 09:45:15 +0800 +Subject: [PATCH 3/3] [newfeature]: hw/misc/psp: Pin the hugepage memory + specified by mem2 during use for psp + +Change-Id: I3ada4a3f9d12361dc11318c56c1601dfdc4b2ed7 +Signed-off-by: niuyongwen +--- + 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 b71b2ab619..3caa446162 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 + +@@ -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.36.6 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index b18cb67..ac5d471 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.4 +%define anolis_release .0.5 %global SLOF_gittagdate 20191022 %global SLOF_gittagcommit 899d9883 @@ -1035,6 +1035,9 @@ Patch1126: 1126-target-i386-sev-Return-0-if-sev_send_get_packet_len-.patch Patch1127: 1127-target-i386-csv-The-CSV2-guest-running-on-the-recipi.patch Patch1128: 1128-virtio-net-Fix-network-stall-at-the-host-side-waitin.patch Patch1129: 1129-Enable-CONFIG_PSP_DEV-for-x86_64.patch +Patch1130: 1130-newfeature-hw-i386-add-mem2-option-for-qemu.patch +Patch1131: 1131-newfeature-hw-misc-psp-support-tkm-use-mem2-memory.patch +Patch1132: 1132-newfeature-hw-misc-psp-Pin-the-hugepage-memory-speci.patch BuildRequires: wget BuildRequires: rpm-build @@ -2273,6 +2276,12 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %endif %changelog +* Thu Feb 13 2025 xiongmengbiao - 6.2.0-53.0.1.5 +- Support Hygon TKM run on CSV Guest +- 1130-newfeature-hw-i386-add-mem2-option-for-qemu.patch +- 1131-newfeature-hw-misc-psp-support-tkm-use-mem2-memory.patch +- 1132-newfeature-hw-misc-psp-Pin-the-hugepage-memory-speci.patch + * Wed Jan 22 2025 xiongmengbiao - 6.2.0-53.0.1.4 - fix psp device is not enabled - 1129-Enable-CONFIG_PSP_DEV-for-x86_64.patch -- Gitee