vmspawn: allow TDX guest to connect to host QGS

To query a TD quote, the TDX guest must connect to the Quote Generation
Service (QGS), a SGX enclave running on the host. We check if the
service is exposed via a well-known unix socket, then pass that socket
or a fallback well-known vsock address to QEMU.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
This commit is contained in:
Paul Meyer
2026-07-01 14:36:45 +02:00
parent a78afc1616
commit 0a9f7b5487
2 changed files with 42 additions and 1 deletions
+5 -1
View File
@@ -379,7 +379,11 @@
measured individually by <command>systemd-stub</command> into RTMR 2. For direct linux boot,
firmware measures the kernel PE into RTMR 1, and the Linux EFI stub measures initrd and
command line into RTMR 2. A vTPM, if attached via <option>--tpm=</option>, must be treated
as untrusted by the guest.
as untrusted by the guest. To obtain TD Quotes for remote attestation, the guest is wired
to the host's local TDX Quote Generation Service automatically: the unix socket
up <filename>/run/tdx-qgs/qgs.socket</filename> is used if it exists, otherwise vsock port 4050
on the host (cid 2). If the QGS is listening on neither channel, the guest's quote requests will
fail.
<xi:include href="version-info.xml" xpointer="v262"/></para>
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
+37
View File
@@ -105,6 +105,13 @@
#define DISK_SERIAL_MAX_LEN_NVME 20
#define DISK_SERIAL_MAX_LEN_VIRTIO_BLK 20
/* Well-known endpoints for the host's TDX Quote Generation Service (qgsd), auto-discovered so the
* guest can obtain TD Quotes. The Intel reference qgsd listens on a unix socket; the common
* deployment listens on vsock port 4050 (cid 2 = host). */
#define TDX_QGS_UNIX_SOCKET_PATH "/run/tdx-qgs/qgs.socket"
#define TDX_QGS_VSOCK_CID "2"
#define TDX_QGS_VSOCK_PORT "4050"
/* First and one-past-last pcie.0 device-numbers used for multifunction-packed
* pcie-root-ports. Sits above the auto-assigned virtio devices (0x01-0x03) and
* below 0x1f, which q35 reserves for ICH9 LPC at 0x1f.0 (single-function). */
@@ -2936,6 +2943,36 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
"qom-type", "tdx-guest");
if (r < 0)
return r;
/* The guest needs a connection to the TDX Quote Generation Service (QGS) running on
* the host to obtain TD Quotes (e.g. via the systemd-report-sign-tsm). There are two
* well-known interfaces for QGS: a well-known unix socket, or vsock port 4050. QEMU
* only connects on a GetQuote request, and pointing at an absent QGS is harmless,
* the request just fails and the guest gets no quote. */
r = is_socket(TDX_QGS_UNIX_SOCKET_PATH);
if (r < 0)
log_debug_errno(r, "Failed to check for QGS socket '%s', falling back to vsock: %m", TDX_QGS_UNIX_SOCKET_PATH);
if (r > 0) {
r = qemu_config_key(config_file, "quote-generation-socket.type", "unix");
if (r < 0)
return r;
r = qemu_config_key(config_file, "quote-generation-socket.path", TDX_QGS_UNIX_SOCKET_PATH);
if (r < 0)
return r;
log_debug("Using TDX Quote Generation Service at unix socket %s.", TDX_QGS_UNIX_SOCKET_PATH);
} else {
r = qemu_config_key(config_file, "quote-generation-socket.type", "vsock");
if (r < 0)
return r;
r = qemu_config_key(config_file, "quote-generation-socket.cid", TDX_QGS_VSOCK_CID);
if (r < 0)
return r;
r = qemu_config_key(config_file, "quote-generation-socket.port", TDX_QGS_VSOCK_PORT);
if (r < 0)
return r;
log_debug("No QGS unix socket found, pointing TDX quote generation at vsock %s:%s.",
TDX_QGS_VSOCK_CID, TDX_QGS_VSOCK_PORT);
}
}
unsigned child_cid = arg_vsock_cid;