From be5bfac2572c9ebc79a9b3627fb43fb7c61601a7 Mon Sep 17 00:00:00 2001 From: t30040867 Date: Thu, 30 May 2024 23:24:52 +0800 Subject: [PATCH] Support virtCCA feature libvirt support to create secure vm, also support virsh tool to inquire tmm memory info. Signed-off-by: tujipei --- ...tmm-memory-info-API-and-libvirtd-RPC.patch | 405 ++++++++++++++++++ libvirt-support-the-virtCCA-feature.patch | 189 ++++++++ libvirt.spec | 9 +- virsh-add-tmm-main-command-word.patch | 134 ++++++ 4 files changed, 736 insertions(+), 1 deletion(-) create mode 100644 libvirt-add-get-tmm-memory-info-API-and-libvirtd-RPC.patch create mode 100644 libvirt-support-the-virtCCA-feature.patch create mode 100644 virsh-add-tmm-main-command-word.patch diff --git a/libvirt-add-get-tmm-memory-info-API-and-libvirtd-RPC.patch b/libvirt-add-get-tmm-memory-info-API-and-libvirtd-RPC.patch new file mode 100644 index 0000000..d75efb2 --- /dev/null +++ b/libvirt-add-get-tmm-memory-info-API-and-libvirtd-RPC.patch @@ -0,0 +1,405 @@ +From cd0f3755bd04bb58089d756400f20c75550e54f2 Mon Sep 17 00:00:00 2001 +From: tujipei +Date: Wed, 12 Jun 2024 12:02:00 +0800 +Subject: [PATCH 2/3] libvirt: add get tmm memory info API and libvirtd RPC Add + the get tmm memory info API into libvirt-host. Also should add the RPC calls + into libvirtd for API calling. + +Signed-off-by: tujipei +--- + include/libvirt/libvirt-host.h | 2 + + scripts/apibuild.py | 1 + + scripts/check-aclrules.py | 1 + + src/driver-hypervisor.h | 5 + + src/libvirt-host.c | 35 +++++++ + src/libvirt_public.syms | 1 + + src/qemu/qemu_driver.c | 139 ++++++++++++++++++++++++++++ + src/remote/remote_daemon_dispatch.c | 23 +++++ + src/remote/remote_driver.c | 29 ++++++ + src/remote/remote_protocol.x | 16 +++- + 10 files changed, 251 insertions(+), 1 deletion(-) + +diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h +index 6972834175..e7272ccb20 100644 +--- a/include/libvirt/libvirt-host.h ++++ b/include/libvirt/libvirt-host.h +@@ -820,5 +820,7 @@ int virNodeAllocPages(virConnectPtr conn, + unsigned int cellCount, + unsigned int flags); + ++char *virConnectGetTmmMemoryInfo(virConnectPtr conn, ++ unsigned int detail); + + #endif /* LIBVIRT_HOST_H */ +diff --git a/scripts/apibuild.py b/scripts/apibuild.py +index c98bcf6091..9b78754e5d 100755 +--- a/scripts/apibuild.py ++++ b/scripts/apibuild.py +@@ -107,6 +107,7 @@ ignored_functions = { + "virDomainMigrateConfirm3Params": "private function for migration", + "virDomainMigratePrepareTunnel3Params": "private function for tunnelled migration", + "virErrorCopyNew": "private", ++ "virConnectGetTmmMemoryInfo": "private function for tmm", + } + + ignored_macros = { +diff --git a/scripts/check-aclrules.py b/scripts/check-aclrules.py +index e196f81de9..aa5a589c85 100755 +--- a/scripts/check-aclrules.py ++++ b/scripts/check-aclrules.py +@@ -54,6 +54,7 @@ whitelist = { + "localOnly": True, + "domainQemuAttach": True, + "domainHotpatchManage": True, ++ "connectGetTmmMemoryInfo": True, + } + + # XXX this vzDomainMigrateConfirm3Params looks +diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h +index 82f808905d..e48b701365 100644 +--- a/src/driver-hypervisor.h ++++ b/src/driver-hypervisor.h +@@ -1402,6 +1402,10 @@ typedef int + typedef struct _virHypervisorDriver virHypervisorDriver; + typedef virHypervisorDriver *virHypervisorDriverPtr; + ++typedef char * ++(*virDrvConnectGetTmmMemoryInfo)(virConnectPtr conn, ++ bool detail); ++ + /** + * _virHypervisorDriver: + * +@@ -1664,4 +1668,5 @@ struct _virHypervisorDriver { + virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc; + virDrvDomainHotpatchManage domainHotpatchManage; + virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc; ++ virDrvConnectGetTmmMemoryInfo connectGetTmmMemoryInfo; + }; +diff --git a/src/libvirt-host.c b/src/libvirt-host.c +index bc3d1d2803..d0750d28cc 100644 +--- a/src/libvirt-host.c ++++ b/src/libvirt-host.c +@@ -1754,3 +1754,38 @@ virNodeGetSEVInfo(virConnectPtr conn, + virDispatchError(conn); + return -1; + } ++ ++/* ++ * virConnectGetTmmMemoryInfo: ++ * @conn: pointer to the hypervisor connection ++ * @detail: whether libvirtd return detailed tmm memory information; ++ * the default value is 0 which means don't return detailed tmm memory information. ++ * ++ * If Tmm enable, then will fill the cotents of string buffer with tmm memory information. ++ * ++ * Returns string ptr in case of success, and NULL in case of failure. ++ */ ++char * ++virConnectGetTmmMemoryInfo(virConnectPtr conn, ++ unsigned int detail) ++{ ++ VIR_DEBUG("conn=%p", conn); ++ ++ virResetLastError(); ++ ++ virCheckConnectReturn(conn, NULL); ++ ++ if (conn->driver->connectGetTmmMemoryInfo) { ++ char *ret; ++ ret = conn->driver->connectGetTmmMemoryInfo(conn, detail); ++ if (!ret) ++ goto error; ++ return ret; ++ } ++ ++ virReportUnsupportedError(); ++ error: ++ virDispatchError(conn); ++ return NULL; ++} ++ +diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms +index f006516208..284b7f7873 100644 +--- a/src/libvirt_public.syms ++++ b/src/libvirt_public.syms +@@ -877,5 +877,6 @@ LIBVIRT_6.2.0 { + global: + virDomainHotpatchManage; + virDomainStartDirtyRateCalc; ++ virConnectGetTmmMemoryInfo; + } LIBVIRT_6.0.0; + # .... define new API here using predicted next version number .... +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 77a139c66b..1e3f63a39a 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -23385,6 +23385,144 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom, + return ret; + } + ++static int ++qemuConnectTmmInfoListAppend(char ***targetInfoStrList, ++ char **infoStrList, ++ int targetNumaNum, ++ int *startIndex, ++ int maxListSize) ++{ ++ char *numStart; ++ int numaNode, index, ret = 0; ++ ++ for (index = *startIndex; index < maxListSize; index++) { ++ if (strlen(infoStrList[index]) == 0) ++ break; ++ ++ numStart = strstr(infoStrList[index], "node "); ++ if (!numStart) ++ return -1; ++ ++ virSkipToDigit((const char **)(&numStart)); ++ ret = virStrToLong_i(numStart, &numStart, 10, &numaNode); ++ if (ret < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Failed to get current numa node")); ++ return ret; ++ } ++ ++ if (numaNode == targetNumaNum) { ++ ret = virStringListAdd(targetInfoStrList, infoStrList[index]); ++ if (ret < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s [%d]", ++ _("Failed to get add info list member"), index); ++ return ret; ++ } ++ } else { ++ break; ++ } ++ } ++ ++ *startIndex = index; ++ ++ return ret; ++} ++ ++static char * ++qemuConnectTmmDetailInfoFormat(char *baseMeminfo, ++ char *slabInfo) ++{ ++ int ret, i = 0, j = 0; ++ char *numStart, *numListStart, *format = NULL; ++ char **baseMeminfoSplits = virStringSplit(baseMeminfo, "\n", 0); ++ char **slabInfoSplits = virStringSplit(slabInfo, "\n", 0); ++ char **resultStrList = NULL; ++ int numaSize, numaIndex, headNumaNode; ++ ssize_t meminfoListSize = virStringListLength((const char * const *)baseMeminfoSplits); ++ ssize_t slabInfoSize = virStringListLength((const char * const *)slabInfoSplits); ++ ++ numStart = strchr(baseMeminfoSplits[i], ':'); ++ numListStart = strchr(baseMeminfoSplits[i], '('); ++ if (!numStart || !numListStart) ++ goto cleanup; ++ ++ virSkipToDigit((const char **)(&numStart)); ++ ret = virStrToLong_i(numStart, &numStart, 10, &numaSize); ++ if (ret < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Failed to get available numa size")); ++ goto cleanup; ++ } ++ ++ ret = virStringListAdd(&resultStrList, baseMeminfoSplits[i++]); ++ if (ret < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s [%d]", ++ _("Failed to get add base memory info list member"), (i - 1)); ++ goto cleanup; ++ } ++ ++ virSkipToDigit((const char **)(&numListStart)); ++ for (numaIndex = 0; *numListStart && numaIndex < numaSize; numaIndex++, numListStart++) { ++ ret = virStrToLong_i(numListStart, &numListStart, 10, &headNumaNode); ++ if (ret < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Failed to get current numa node")); ++ goto cleanup; ++ } ++ ++ ret = qemuConnectTmmInfoListAppend(&resultStrList, baseMeminfoSplits, headNumaNode, &i, meminfoListSize); ++ if (ret < 0) ++ goto cleanup; ++ ret = qemuConnectTmmInfoListAppend(&resultStrList, slabInfoSplits, headNumaNode, &j, slabInfoSize); ++ if (ret < 0) ++ goto cleanup; ++ } ++ ++ format = virStringListJoin((const char **)resultStrList, "\n"); ++ ++ cleanup: ++ virStringListFree(baseMeminfoSplits); ++ virStringListFree(slabInfoSplits); ++ virStringListFree(resultStrList); ++ return format; ++} ++ ++static char * ++qemuConnectGetTmmMemoryInfo(virConnectPtr conn G_GNUC_UNUSED, ++ bool detail) ++{ ++ int maxLen = 10 * 1024; ++ char *meminfo = NULL; ++ g_autofree char *formatInfo = NULL; ++ g_autofree char *baseMeminfo = NULL; ++ g_autofree char *slabInfo = NULL; ++ g_autofree char *buddyInfo = NULL; ++ ++ if (virFileReadAll("/sys/kernel/tmm/memory_info", maxLen, &baseMeminfo) < 0) ++ goto end; ++ if (detail && virFileReadAll("/sys/kernel/tmm/slab_info", maxLen, &slabInfo) < 0) ++ goto end; ++ if (detail && virFileReadAll("/sys/kernel/tmm/buddy_info", maxLen, &buddyInfo) < 0) ++ goto end; ++ ++ if (detail) { ++ if (!virStringIsEmpty(baseMeminfo) && !virStringIsEmpty(slabInfo)) { ++ formatInfo = qemuConnectTmmDetailInfoFormat(baseMeminfo, slabInfo); ++ if (formatInfo == NULL) ++ goto end; ++ } else { ++ formatInfo = g_strdup_printf(_("%s%s"), baseMeminfo, slabInfo); ++ } ++ ++ meminfo = g_strdup_printf(_("%s\n%s"), formatInfo, buddyInfo); ++ } else { ++ meminfo = g_steal_pointer(&baseMeminfo); ++ } ++ ++end: ++ return meminfo; ++} ++ + + static virHypervisorDriver qemuHypervisorDriver = { + .name = QEMU_DRIVER_NAME, +@@ -23627,6 +23765,7 @@ static virHypervisorDriver qemuHypervisorDriver = { + .domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */ + .domainHotpatchManage = qemuDomainHotpatchManage, /* 6.2.0 */ + .domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 6.2.0 */ ++ .connectGetTmmMemoryInfo = qemuConnectGetTmmMemoryInfo, /* 6.2.0 */ + }; + + +diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c +index 0bbcc05235..a9763cee7b 100644 +--- a/src/remote/remote_daemon_dispatch.c ++++ b/src/remote/remote_daemon_dispatch.c +@@ -7268,6 +7268,29 @@ remoteDispatchNetworkPortGetParameters(virNetServerPtr server G_GNUC_UNUSED, + return rv; + } + ++static int ++remoteDispatchConnectGetTmmMemoryInfo(virNetServerPtr server G_GNUC_UNUSED, ++ virNetServerClientPtr client, ++ virNetMessagePtr msg G_GNUC_UNUSED, ++ virNetMessageErrorPtr rerr, ++ remote_connect_get_tmm_memory_info_args *args, ++ remote_connect_get_tmm_memory_info_ret *ret) ++{ ++ int rv = -1; ++ char *meminfo = NULL; ++ virConnectPtr conn = remoteGetHypervisorConn(client); ++ ++ if (conn && (meminfo = virConnectGetTmmMemoryInfo(conn, args->detail))) { ++ rv = 0; ++ ret->meminfo = meminfo; ++ } ++ ++ if (rv < 0) ++ virNetMessageSaveError(rerr); ++ ++ return rv; ++} ++ + + /*----- Helpers. -----*/ + +diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c +index 9c272b4ff8..b597ae614c 100644 +--- a/src/remote/remote_driver.c ++++ b/src/remote/remote_driver.c +@@ -8253,6 +8253,34 @@ remoteDomainGetGuestInfo(virDomainPtr dom, + return rv; + } + ++static char * ++remoteConnectGetTmmMemoryInfo(virConnectPtr conn, ++ bool detail) ++{ ++ char *rv = NULL; ++ struct private_data *priv = conn->privateData; ++ remote_connect_get_tmm_memory_info_args args; ++ remote_connect_get_tmm_memory_info_ret ret; ++ ++ remoteDriverLock(priv); ++ ++ args.detail = detail; ++ ++ memset(&ret, 0, sizeof(ret)); ++ ++ if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_TMM_MEMORY_INFO, ++ (xdrproc_t)xdr_remote_connect_get_tmm_memory_info_args, (char *)&args, ++ (xdrproc_t)xdr_remote_connect_get_tmm_memory_info_ret, (char *)&ret) < 0) { ++ goto done; ++ } ++ ++ rv = ret.meminfo; ++ ++ done: ++ remoteDriverUnlock(priv); ++ return rv; ++} ++ + /* get_nonnull_domain and get_nonnull_network turn an on-wire + * (name, uuid) pair into virDomainPtr or virNetworkPtr object. + * These can return NULL if underlying memory allocations fail, +@@ -8686,6 +8714,7 @@ static virHypervisorDriver hypervisor_driver = { + .domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */ + .domainHotpatchManage = remoteDomainHotpatchManage, /* 6.2.0 */ + .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 6.2.0 */ ++ .connectGetTmmMemoryInfo = remoteConnectGetTmmMemoryInfo /* 6.2.0 */ + }; + + static virNetworkDriver network_driver = { +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index d89cc1a087..f37bd332a1 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -3789,6 +3789,14 @@ struct remote_domain_start_dirty_rate_calc_args { + unsigned int flags; + }; + ++struct remote_connect_get_tmm_memory_info_args { ++ unsigned int detail; ++}; ++ ++struct remote_connect_get_tmm_memory_info_ret { ++ remote_nonnull_string meminfo; ++}; ++ + /*----- Protocol. -----*/ + + /* Define the program number, protocol version and procedure numbers here. */ +@@ -6698,5 +6706,11 @@ enum remote_procedure { + * @generate: both + * @acl: domain:read + */ +- REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800 ++ REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800, ++ ++ /** ++ * @generate: none ++ * @acl: connect:read ++ */ ++ REMOTE_PROC_CONNECT_GET_TMM_MEMORY_INFO = 900 + }; +-- +2.31.1.windows.1 + diff --git a/libvirt-support-the-virtCCA-feature.patch b/libvirt-support-the-virtCCA-feature.patch new file mode 100644 index 0000000..4e54f68 --- /dev/null +++ b/libvirt-support-the-virtCCA-feature.patch @@ -0,0 +1,189 @@ +From a2b13dd8d6e0282d76a583f36965b3a00cdb7eea Mon Sep 17 00:00:00 2001 +From: liupingwei +Date: Wed, 12 Jun 2024 11:39:38 +0800 +Subject: [PATCH 1/3] libvirt: support the virtCCA feature Add cvm parameter + into the type of LaunchSecurity which is a optional filed for libvirt xml. + Its purpose is to pass the cvm parameter through to qemu. Also this patch + support virsh edit to save cvm parameter into libvirt temporary xml. + +Signed-off-by: tujipei +--- + docs/schemas/domaincommon.rng | 67 ++++++++++++++++++++--------------- + src/conf/domain_conf.c | 25 ++++++++++--- + src/conf/domain_conf.h | 3 ++ + src/qemu/qemu_command.c | 2 ++ + 4 files changed, 63 insertions(+), 34 deletions(-) + +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index e3b51d333c..a49842a9d0 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -460,35 +460,44 @@ + + + +- +- sev +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ sev ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ cvm ++ ++ ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index cf807c7747..9219d08753 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1273,6 +1273,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, + VIR_DOMAIN_LAUNCH_SECURITY_LAST, + "", + "sev", ++ "cvm", + ); + + static virClassPtr virDomainObjClass; +@@ -16823,6 +16824,7 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode, + def->sectype = virDomainLaunchSecurityTypeFromString(type); + switch ((virDomainLaunchSecurity) def->sectype) { + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: ++ case VIR_DOMAIN_LAUNCH_SECURITY_CVM: + break; + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: +@@ -22169,11 +22171,19 @@ virDomainDefParseXML(xmlDocPtr xml, + ctxt->node = node; + VIR_FREE(nodes); + +- /* Check for SEV feature */ ++ /* Check for CVM/SEV feature */ + if ((node = virXPathNode("./launchSecurity", ctxt)) != NULL) { +- def->sev = virDomainSEVDefParseXML(node, ctxt); +- if (!def->sev) +- goto error; ++ tmp = virXMLPropString(node, "type"); ++ if((virDomainLaunchSecurity)virDomainLaunchSecurityTypeFromString(tmp) == VIR_DOMAIN_LAUNCH_SECURITY_CVM) { ++ def->cvm = true; ++ } else { ++ def->sev = virDomainSEVDefParseXML(node, ctxt); ++ if(!def->sev) { ++ VIR_FREE(tmp); ++ goto error; ++ } ++ } ++ VIR_FREE(tmp); + } + + /* analysis of memory devices */ +@@ -29861,7 +29871,12 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + if (def->keywrap) + virDomainKeyWrapDefFormat(buf, def->keywrap); + +- virDomainSEVDefFormat(buf, def->sev); ++ if (def->cvm) { ++ virBufferAddLit(buf, "\n"); ++ virBufferAddLit(buf, "\n"); ++ } else { ++ virDomainSEVDefFormat(buf, def->sev); ++ } + + virBufferAdjustIndent(buf, -2); + virBufferAsprintf(buf, "\n", rootname); +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 7419bf8d7e..180975840c 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2373,6 +2373,7 @@ struct _virDomainKeyWrapDef { + typedef enum { + VIR_DOMAIN_LAUNCH_SECURITY_NONE, + VIR_DOMAIN_LAUNCH_SECURITY_SEV, ++ VIR_DOMAIN_LAUNCH_SECURITY_CVM, + + VIR_DOMAIN_LAUNCH_SECURITY_LAST, + } virDomainLaunchSecurity; +@@ -2586,6 +2587,8 @@ struct _virDomainDef { + + /* SEV-specific domain */ + virDomainSEVDefPtr sev; ++ /* CVM-specific domain */ ++ bool cvm; + + /* Application-specific custom metadata */ + xmlNodePtr metadata; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 9fcea9d46a..675a624919 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7266,6 +7266,8 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, + + if (def->sev) + virBufferAddLit(&buf, ",memory-encryption=sev0"); ++ if (def->cvm) ++ virBufferAddLit(&buf, ",kvm-type=cvm"); + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) { + if (priv->pflash0) +-- +2.31.1.windows.1 + diff --git a/libvirt.spec b/libvirt.spec index 5d238ff..f051f76 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 63 +Release: 64 License: LGPLv2+ URL: https://libvirt.org/ @@ -510,6 +510,9 @@ Patch0397: interface-fix-udev_device_get_sysattr_value-return-v.patch Patch0398: util-keep-track-of-full-GSource-object-not-source-ID.patch Patch0399: rpc-mark-source-returned-by-virEventGLibAddSocketWat.patch Patch0400: rpc-ensure-temporary-GSource-is-removed-from-client-.patch +Patch0401: libvirt-support-the-virtCCA-feature.patch +Patch0402: libvirt-add-get-tmm-memory-info-API-and-libvirtd-RPC.patch +Patch0403: virsh-add-tmm-main-command-word.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2246,6 +2249,10 @@ exit 0 %changelog +* Thu May 30 2024 tujipei - 6.2.0-64 +- libvirt: support virtCCA +- libvirt: support get secure memory information (add command line) + * Fri May 24 2024 jiangjiacheng - 6.2.0-63 - util: keep track of full GSource object not source ID number - rpc: mark source returned by virEventGLibAddSocketWatch as unused diff --git a/virsh-add-tmm-main-command-word.patch b/virsh-add-tmm-main-command-word.patch new file mode 100644 index 0000000..9a64965 --- /dev/null +++ b/virsh-add-tmm-main-command-word.patch @@ -0,0 +1,134 @@ +From d9599ee42db6a62cac6ae89c8d246c4c47574d5f Mon Sep 17 00:00:00 2001 +From: tujipei +Date: Wed, 12 Jun 2024 14:34:57 +0800 +Subject: [PATCH 3/3] virsh: add tmm main command word Add tmm command word + into virsh tool to call get tmm memory info API. It makes virsh can use tmm + main commmand to show tmm memory info on console. This command requires + specific kernel and a kernel driver to make sure its regular function. If + runnning environment missing the above reliance, this command will show error + result on console. + +Signed-off-by: tujipei +--- + tools/virsh-host.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 99 insertions(+) + +diff --git a/tools/virsh-host.c b/tools/virsh-host.c +index 67d5466be2..4f54cafec7 100644 +--- a/tools/virsh-host.c ++++ b/tools/virsh-host.c +@@ -1799,6 +1799,99 @@ cmdHypervisorCPUBaseline(vshControl *ctl, + return ret; + } + ++/* ++ * "securememinfo" command ++ */ ++ ++static const vshCmdInfo info_tmm[] = { ++ {.name = "help", ++ .data = N_("Interaction with the tmm") ++ }, ++ {.name = "desc", ++ .data = N_("Call the host kernel dev which is provided for virsh to use receiving tmm informations.") ++ }, ++ {.name = NULL} ++}; ++ ++static const vshCmdOptDef opts_tmm[] = { ++ {.name = "dev", ++ .type = VSH_OT_DATA, ++ .flags = VSH_OFLAG_REQ, ++ .help = N_("Device name of host kernel dev") ++ }, ++ {.name = "detail", ++ .type = VSH_OT_BOOL, ++ .help = N_("print detailed info if this option contained in cmd") ++ }, ++ {.name = NULL} ++}; ++ ++static bool ++virshGetTmmMemoryInfo(vshControl *ctl, ++ const vshCmd *cmd) ++{ ++ char *tmmMemoryInfo = NULL; ++ bool detail; ++ virshControlPtr priv = ctl->privData; ++ ++ detail = vshCommandOptBool(cmd, "detail"); ++ if (!(tmmMemoryInfo = virConnectGetTmmMemoryInfo(priv->conn, (unsigned int)detail))) { ++ vshError(ctl, _("Get tmm_memory_info failed")); ++ return false; ++ } ++ ++ vshPrintExtra(ctl, _("%s"), tmmMemoryInfo); ++ ++ VIR_FREE(tmmMemoryInfo); ++ return true; ++} ++ ++typedef bool ++(*virshTmmFunc)(vshControl *ctl, ++ const vshCmd *cmd); ++ ++struct _virshTmmFuncInfo { ++ const char *devName; ++ virshTmmFunc funcPtr; ++}; ++ ++typedef struct _virshTmmFuncInfo virshTmmFuncInfo; ++ ++static virshTmmFuncInfo virshTmmFuncMap[] = { ++ {"tmm_memory_info", virshGetTmmMemoryInfo}, ++}; ++ ++static bool ++virshTmmRunFunc(vshControl *ctl, ++ const char *devName, ++ const vshCmd *cmd) ++{ ++ int funcIndex; ++ ++ for (funcIndex = 0; funcIndex < sizeof(virshTmmFuncMap) / sizeof(virshTmmFuncInfo); funcIndex++) { ++ if (strcmp(devName, virshTmmFuncMap[funcIndex].devName) == 0) { ++ virshTmmFuncMap[funcIndex].funcPtr(ctl, cmd); ++ return true; ++ } ++ } ++ ++ vshError(ctl, _("Invalid dev name")); ++ return false; ++} ++ ++static bool ++cmdTmm(vshControl *ctl, const vshCmd *cmd) ++{ ++ const char *devName = NULL; ++ ++ if (vshCommandOptStringReq(ctl, cmd, "dev", &devName) < 0) ++ return false; ++ ++ if (!virshTmmRunFunc(ctl, devName, cmd)) ++ return false; ++ ++ return true; ++} + + const vshCmdDef hostAndHypervisorCmds[] = { + {.name = "allocpages", +@@ -1927,5 +2020,11 @@ const vshCmdDef hostAndHypervisorCmds[] = { + .info = info_version, + .flags = 0 + }, ++ {.name = "tmm", ++ .handler = cmdTmm, ++ .opts = opts_tmm, ++ .info = info_tmm, ++ .flags = 0 ++ }, + {.name = NULL} + }; +-- +2.31.1.windows.1 + -- Gitee