From ff1941c93567beb4eda324a1af0b0bd4182bc1d9 Mon Sep 17 00:00:00 2001 From: zhenwei pi Date: Tue, 17 Jan 2023 09:46:53 +0800 Subject: [PATCH] qemu: command: support crypto device Support virtio-crypto device, also support cryptodev types: - builtin - lkcf Finally, we can launch a VM(QEMU) with one or more crypto devices by libvirt. Signed-off-by: zhenwei pi Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- src/qemu/qemu_command.c | 100 +++++++++++++++++- .../crypto-builtin.x86_64-latest.args | 40 +++++++ tests/qemuxml2argvtest.c | 2 + 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/crypto-builtin.x86_64-latest.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bb7031f66d..4ba978f3e6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -926,6 +926,12 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, } break; + case VIR_DOMAIN_DEVICE_CRYPTO: { + *baseName = "virtio-crypto"; + *virtioOptions = device->data.crypto->virtio; + break; + } + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_WATCHDOG: @@ -942,7 +948,6 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device, case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: - case VIR_DOMAIN_DEVICE_CRYPTO: case VIR_DOMAIN_DEVICE_LAST: default: break; @@ -9894,6 +9899,96 @@ qemuBuildVsockCommandLine(virCommand *cmd, } +VIR_ENUM_DECL(qemuCryptoBackend); +VIR_ENUM_IMPL(qemuCryptoBackend, + VIR_DOMAIN_CRYPTO_BACKEND_LAST, + "cryptodev-backend-builtin", + "cryptodev-backend-lkcf", +); + + +static int +qemuBuildCryptoBackendProps(virDomainCryptoDef *crypto, + virJSONValue **props) +{ + g_autofree char *objAlias = NULL; + + objAlias = g_strdup_printf("obj%s", crypto->info.alias); + + if (qemuMonitorCreateObjectProps(props, + qemuCryptoBackendTypeToString(crypto->backend), + objAlias, + "p:queues", crypto->queues, + NULL) < 0) + return -1; + + return 0; +} + + +static virJSONValue * +qemuBuildCryptoDevProps(const virDomainDef *def, + virDomainCryptoDef *dev, + virQEMUCaps *qemuCaps) +{ + g_autoptr(virJSONValue) props = NULL; + g_autofree char *crypto = g_strdup_printf("obj%s", dev->info.alias); + + if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_CRYPTO, dev, qemuCaps))) + return NULL; + + if (virJSONValueObjectAdd(&props, + "s:cryptodev", crypto, + "s:id", dev->info.alias, + NULL) < 0) + return NULL; + + if (qemuBuildDeviceAddressProps(props, def, &dev->info) < 0) + return NULL; + + return g_steal_pointer(&props); +} + + +static int +qemuBuildCryptoCommandLine(virCommand *cmd, + const virDomainDef *def, + virQEMUCaps *qemuCaps) +{ + size_t i; + + for (i = 0; i < def->ncryptos; i++) { + g_autoptr(virJSONValue) props = NULL; + virDomainCryptoDef *crypto = def->cryptos[i]; + g_autoptr(virJSONValue) devprops = NULL; + + if (!crypto->info.alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Crypto device is missing alias")); + return -1; + } + + if (qemuBuildCryptoBackendProps(crypto, &props) < 0) + return -1; + + if (qemuBuildObjectCommandlineFromJSON(cmd, props, qemuCaps) < 0) + return -1; + + /* add the device */ + if (qemuCommandAddExtDevice(cmd, &crypto->info, def, qemuCaps) < 0) + return -1; + + if (!(devprops = qemuBuildCryptoDevProps(def, crypto, qemuCaps))) + return -1; + + if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, def, qemuCaps) < 0) + return -1; + } + + return 0; +} + + typedef enum { QEMU_COMMAND_DEPRECATION_BEHAVIOR_NONE = 0, QEMU_COMMAND_DEPRECATION_BEHAVIOR_OMIT, @@ -10246,6 +10341,9 @@ qemuBuildCommandLine(virDomainObj *vm, qemuBuildVsockCommandLine(cmd, def, def->vsock, qemuCaps) < 0) return NULL; + if (qemuBuildCryptoCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + if (cfg->logTimestamp) virCommandAddArgList(cmd, "-msg", "timestamp=on", NULL); diff --git a/tests/qemuxml2argvdata/crypto-builtin.x86_64-latest.args b/tests/qemuxml2argvdata/crypto-builtin.x86_64-latest.args new file mode 100644 index 0000000000..1fafea9e4e --- /dev/null +++ b/tests/qemuxml2argvdata/crypto-builtin.x86_64-latest.args @@ -0,0 +1,40 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc-q35-7.0,usb=off,dump-guest-core=off \ +-accel tcg \ +-cpu qemu64 \ +-m size=1048576k,slots=16,maxmem=1130496k \ +-overcommit mem-lock=off \ +-smp 2,sockets=2,cores=1,threads=1 \ +-object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":536870912}' \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +-object '{"qom-type":"memory-backend-ram","id":"ram-node1","size":536870912}' \ +-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.1","addr":"0x0"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-object '{"qom-type":"cryptodev-backend-builtin","id":"objcrypto0","queues":1}' \ +-device '{"driver":"virtio-crypto-pci","cryptodev":"objcrypto0","id":"crypto0","bus":"pcie.0","addr":"0xa"}' \ +-msg timestamp=on diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 8c52feb83c..3e58a73e41 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2983,6 +2983,8 @@ mymain(void) DO_TEST_CAPS_VER("sgx-epc", "7.0.0"); + DO_TEST_CAPS_LATEST("crypto-builtin"); + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir);