[pve-devel] [PATCH qemu-server v7 1/3] add C program to get AMD SEV hardware parameters from CPUID

Markus Frank m.frank at proxmox.com
Mon Apr 22 14:16:15 CEST 2024


Implement a systemd service that runs a C program that extracts AMD SEV
hardware parameters such as reduced-phys-bios and cbitpos from CPUID at boot
time, looks if SEV, SEV-ES & SEV-SNP are enabled, and outputs these details
as JSON to /run/qemu-server/hw-params.json.

This programm can also be used to read and save other hardware information
at boot time.

Signed-off-by: Markus Frank <m.frank at proxmox.com>
Co-authored-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
v7:
* renamed amd-sev-support to query-machine-params
* mv /run/amd-sev-params to /run/qemu-server/hw-params.json
* add "mkdir /run/qemu-server" to ensure that the directory exists
* moved json content to amd-sev property inside a bigger json
 so that other hardware parameters could also be read at boot time and
 included in this json file.

 Makefile                                      |  1 +
 query-machine-params/Makefile                 | 21 +++++++
 query-machine-params/query-machine-params.c   | 55 +++++++++++++++++++
 .../query-machine-params.service              | 12 ++++
 4 files changed, 89 insertions(+)
 create mode 100644 query-machine-params/Makefile
 create mode 100644 query-machine-params/query-machine-params.c
 create mode 100644 query-machine-params/query-machine-params.service

diff --git a/Makefile b/Makefile
index 133468d..de32036 100644
--- a/Makefile
+++ b/Makefile
@@ -65,6 +65,7 @@ install: $(PKGSOURCES)
 	install -m 0644 -D bootsplash.jpg $(DESTDIR)/usr/share/$(PACKAGE)
 	$(MAKE) -C PVE install
 	$(MAKE) -C qmeventd install
+	$(MAKE) -C query-machine-params install
 	$(MAKE) -C qemu-configs install
 	$(MAKE) -C vm-network-scripts install
 	install -m 0755 qm $(DESTDIR)$(SBINDIR)
diff --git a/query-machine-params/Makefile b/query-machine-params/Makefile
new file mode 100644
index 0000000..e657bd1
--- /dev/null
+++ b/query-machine-params/Makefile
@@ -0,0 +1,21 @@
+DESTDIR=
+PREFIX=/usr
+SBINDIR=${PREFIX}/libexec/qemu-server
+SERVICEDIR=/lib/systemd/system
+
+CC ?= gcc
+CFLAGS += -O2 -fanalyzer -Werror -Wall -Wextra -Wpedantic -Wtype-limits -Wl,-z,relro -std=gnu11
+
+query-machine-params: query-machine-params.c
+	$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
+
+.PHONY: install
+install: query-machine-params
+	install -d ${DESTDIR}/${SBINDIR}
+	install -d ${DESTDIR}${SERVICEDIR}
+	install -m 0644 query-machine-params.service ${DESTDIR}${SERVICEDIR}
+	install -m 0755 query-machine-params ${DESTDIR}${SBINDIR}
+
+.PHONY: clean
+clean:
+	rm -f query-machine-params
diff --git a/query-machine-params/query-machine-params.c b/query-machine-params/query-machine-params.c
new file mode 100644
index 0000000..9552347
--- /dev/null
+++ b/query-machine-params/query-machine-params.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int main() {
+    uint32_t eax, ebx, ecx, edx;
+
+    // query Encrypted Memory Capabilities, see:
+    // https://en.wikipedia.org/wiki/CPUID#EAX=8000001Fh:_Encrypted_Memory_Capabilities
+    uint32_t query_function = 0x8000001F;
+    asm volatile("cpuid"
+	 : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+	 : "0"(query_function)
+    );
+
+    bool sev_support = (eax & (1<<1)) != 0;
+    bool sev_es_support = (eax & (1<<3)) != 0;
+    bool sev_snp_support = (eax & (1<<4)) != 0;
+
+    uint8_t cbitpos = ebx & 0x3f;
+    uint8_t reduced_phys_bits = (ebx >> 6) & 0x3f;
+
+    FILE *file;
+    char filename[] = "/run/qemu-server/hw-params.json";
+
+    mkdir("/run/qemu-server/", 0755);
+
+    file = fopen(filename, "w");
+    if (file == NULL) {
+	perror("Error opening file");
+	return 1;
+    }
+
+    fprintf(file,
+	"{"
+	" \"amd-sev\": {"
+	" \"cbitpos\": %u,"
+	" \"reduced-phys-bits\": %u,"
+	" \"sev-support\": %s,"
+	" \"sev-support-es\": %s,"
+	" \"sev-support-snp\": %s"
+	" }"
+	" }\n",
+	cbitpos,
+	reduced_phys_bits,
+	sev_support ? "true" : "false",
+	sev_es_support ? "true" : "false",
+	sev_snp_support ? "true" : "false"
+    );
+
+    fclose(file);
+    return 0;
+}
diff --git a/query-machine-params/query-machine-params.service b/query-machine-params/query-machine-params.service
new file mode 100644
index 0000000..774fc7f
--- /dev/null
+++ b/query-machine-params/query-machine-params.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=read AMD SEV parameters
+RequiresMountsFor=/run
+Before=pve-ha-lrm.service
+Before=pve-guests.service
+
+[Service]
+ExecStart=/usr/libexec/qemu-server/query-machine-params
+Type=oneshot
+
+[Install]
+WantedBy=multi-user.target
-- 
2.39.2





More information about the pve-devel mailing list