[RFC PATCH 4/7] qemu: add support to launch TDX guest

Zhenzhong Duan zhenzhong.duan at intel.com
Fri Jun 18 08:50:49 UTC 2021


QEMU will provides 'tdx-guest' object which is used to launch encrypted
VMs on Intel platform using TDX feature. The tag <TrustDomain> can be
used to launch a TDX guest. A typical TDX guest launch command line
looks like:

$QEMU ... \
  -object tdx-guest,id=tdx0,debug=on \
  -machine q35, confidential-guest-support=tdx0,kvm-type=tdx,pic=no,kernel_irqchip=split

Signed-off-by: Zhenzhong Duan <zhenzhong.duan at intel.com>
---
 src/qemu/qemu_command.c                       |  31 +++++++++++++++
 .../.trust-domain-tdx.xml.swo                 | Bin 0 -> 12288 bytes
 tests/qemuxml2argvdata/trust-domain-tdx.args  |  32 ++++++++++++++++
 tests/qemuxml2argvdata/trust-domain-tdx.xml   |  36 ++++++++++++++++++
 tests/qemuxml2argvtest.c                      |   3 ++
 5 files changed, 102 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo
 create mode 100644 tests/qemuxml2argvdata/trust-domain-tdx.args
 create mode 100644 tests/qemuxml2argvdata/trust-domain-tdx.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ea513693f7..1e14c95a49 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6974,6 +6974,9 @@ qemuBuildMachineCommandLine(virCommand *cmd,
         }
     }
 
+    if (def->tdx)
+        virBufferAddLit(&buf, ",confidential-guest-support=tdx0,kvm-type=tdx");
+
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
         if (priv->pflash0)
             virBufferAsprintf(&buf, ",pflash0=%s", priv->pflash0->nodeformat);
@@ -9860,6 +9863,31 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd,
     return 0;
 }
 
+static int
+qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd,
+                        virDomainTDXDef *tdx)
+{
+    g_autoptr(virJSONValue) props = NULL;
+    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+    qemuDomainObjPrivate *priv = vm->privateData;
+
+    if (!tdx)
+        return 0;
+
+    VIR_DEBUG("policy=0x%x", tdx->policy);
+
+    if (qemuMonitorCreateObjectProps(&props, "tdx-guest", "tdx0",
+                                     "B:debug", !!(tdx->policy & 1)) < 0)
+        return -1;
+
+    if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0)
+        return -1;
+
+    virCommandAddArg(cmd, "-object");
+    virCommandAddArgBuffer(cmd, &buf);
+    return 0;
+}
+
 static int
 qemuBuildVMCoreInfoCommandLine(virCommand *cmd,
                                const virDomainDef *def)
@@ -10562,6 +10590,9 @@ qemuBuildCommandLine(virQEMUDriver *driver,
     if (qemuBuildSEVCommandLine(vm, cmd, def->sev) < 0)
         return NULL;
 
+    if (qemuBuildTDXCommandLine(vm, cmd, def->tdx) < 0)
+        return NULL;
+
     if (snapshot)
         virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
 
diff --git a/tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo b/tests/qemuxml2argvdata/.trust-domain-tdx.xml.swo
new file mode 100644
index 0000000000000000000000000000000000000000..2835d4a14342651d239657fb1531318de3eff8e8
GIT binary patch
literal 12288
zcmeI2zmMER6vrpfAcgR=Ok<8>D&N?f+~!X5x<KKQ2%P{axq{{x&&*~=XM4=dc(Ysa
z4<J#~&=4dF#J>Rasc7k;p+lmDH)HSK<#Gt6jChv5^7+kop5J_CeA4M&l^x$ZO7?ei
z0 at oXa+$f)X`sOEB$#-AALaZ at 9g#YW3J#SM{Yt{Pn!_MoEYPCvlW&7EMiA=3JV?C>N
zwba(1^d0lcdB;9eO}}dD3AYcIl6%g)?VV4hX}E4vFIT%TdLbD;A^{}uoCL0s8<RYK
zmhbMolf3=bgXf%&b|ioVkN^@u0!RP}AOR$R1YTqUzPmy`hXuSeE at EfAU%7A}AMu6+
zkN^@u0!RP}AOR$R1dsp{Kmter3A}&=xP+pw67m=n{{O%E`~Q#E3Hb%|HE0bw1nq#X
zgMNRFke at -{gC2vv06hd9f+*-Z=(lTx`~><6RD<q<{(hB^KS57G-+~&@J<ty5Wzb(x
z!>^zpK|g>(P2Yg<LIOwt2_OL^fCP{L5<mj~Cjtc<I$=waBn7)4dSh?L*4Pk$P-ki_
z)@8QJvMevy_!!LRyoq0TYDS@%mJWHOT56%(n4?im#p~LbHffAh^^CTrRg{gxy6t*D
zrZ`pW%5W=bQuS^|J2$!1)|lR at OFY7~-kQ2rcFflaO%vTpwVKh4Ze9=3G&CS at b3Zdr
zOGv++x2g0QTkon%Y)oo*IxG%2aVf2GZY)Szy at b?fnPOdWu~46fE at kCosBd-rVSG0v
z8U_<!JEIH9$K{7g&pgibR;a<lz{&0!=a28OkKaFfaHofc==_{H)?$;EH?Vo3PZ|n{
z8)^BYjjaf48N*d=#3>EQVRL6RjKuwh+F)|cy|E?hon at 77W8Zb^*3PRYUF}a#rZ)?=
zb%pbD?u-<sJrS0>MJb^~Yt{wZMuHU{tg2wcN+1asd>kJ`qoFg8lr{7DQz^E=U=pGH
z1S~Ef?!6e+2)Q-~HN0ZOcMG64Tq;;t$NhqN!|vZcKHQzlf{g=^8j=Ta3AbV~qr+<9
zuyL`_Er9Aon(t<`Tr8V{1!Me3hPM_=(e+7JbD<jOai39GpVxwx at UexVXcfJ+FnFXI
zW7o-WGCt7n(Q=X><XKj*rwnlld~^Te9Y&(5 at 3kz&ExtFGl}wf7^Yq~6-d=hznetRl
l_e4IGRlc7c6f9Z;#c*26v*T2-7$C*)Yh*krr^^OT#y{J at p5y=k

literal 0
HcmV?d00001

diff --git a/tests/qemuxml2argvdata/trust-domain-tdx.args b/tests/qemuxml2argvdata/trust-domain-tdx.args
new file mode 100644
index 0000000000..45c8ed595f
--- /dev/null
+++ b/tests/qemuxml2argvdata/trust-domain-tdx.args
@@ -0,0 +1,32 @@
+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 \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name QEMUGuest1 \
+-S \
+-machine pc-q35-3.0,accel=kvm,usb=off,dump-guest-core=off,confidential-guest-support=tdx0,\
+kvm-type=tdx,pic=no,kernel_irqchip=split \
+-device loader,file=/path/to/TDVF.fd,id=fd0 \
+-m 214 \
+-realtime mlock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
+-object tdx-guest,policy=0x1,id=tdx0
diff --git a/tests/qemuxml2argvdata/trust-domain-tdx.xml b/tests/qemuxml2argvdata/trust-domain-tdx.xml
new file mode 100644
index 0000000000..e0f0b77866
--- /dev/null
+++ b/tests/qemuxml2argvdata/trust-domain-tdx.xml
@@ -0,0 +1,36 @@
+<domain type='kvm'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-q35-3.0'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <ioapic driver='qemu'/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+  <TrustDomain type='tdx'>
+    <policy>0x0001</policy>
+  </TrustDomain>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 7fed871c9e..ac5dc6b40b 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -3456,6 +3456,9 @@ mymain(void)
     DO_TEST_CAPS_VER("launch-security-sev", "2.12.0");
     DO_TEST_CAPS_VER("launch-security-sev", "6.0.0");
     DO_TEST_CAPS_VER("launch-security-sev-missing-platform-info", "2.12.0");
+    DO_TEST("trust-domain-tdx",
+            QEMU_CAPS_KVM,
+            QEMU_CAPS_TDX_GUEST);
 
     DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");
     DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");
-- 
2.25.1




More information about the libvir-list mailing list