Ran this on an Intel(R) Core(TM) i7-7700K CPU at Markus' request to see how this behaves on an Intel processor. This results in the following being written to /run/qemu-server/host-hw-capabilities.json:
{ "amd-sev": { "cbitpos": 0, "reduced-phys-bits": 0, "sev-support": false, "sev-support-es": false, "sev-support-snp": false } }
PS: The sys/types.h include can be omitted. Otherwise the code looks fine to me. On 26/04/2024 11:58, Markus Frank wrote:
Implement a systemd service that runs a C program that extracts AMD SEV hardware information 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.fr...@proxmox.com> Co-authored-by: Thomas Lamprecht <t.lampre...@proxmox.com> --- v9: * added directory existance check * print error messages v8: * renamed query-machine-params to query-machine-capabilities 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-capabilities/Makefile | 21 ++++++ .../query-machine-capabilities.c | 71 +++++++++++++++++++ .../query-machine-capabilities.service | 12 ++++ 4 files changed, 105 insertions(+) create mode 100644 query-machine-capabilities/Makefile create mode 100644 query-machine-capabilities/query-machine-capabilities.c create mode 100644 query-machine-capabilities/query-machine-capabilities.service diff --git a/Makefile b/Makefile index 133468d..ed67fe0 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-capabilities install $(MAKE) -C qemu-configs install $(MAKE) -C vm-network-scripts install install -m 0755 qm $(DESTDIR)$(SBINDIR) diff --git a/query-machine-capabilities/Makefile b/query-machine-capabilities/Makefile new file mode 100644 index 0000000..c5f6348 --- /dev/null +++ b/query-machine-capabilities/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-capabilities: query-machine-capabilities.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +.PHONY: install +install: query-machine-capabilities + install -d ${DESTDIR}/${SBINDIR} + install -d ${DESTDIR}${SERVICEDIR} + install -m 0644 query-machine-capabilities.service ${DESTDIR}${SERVICEDIR} + install -m 0755 query-machine-capabilities ${DESTDIR}${SBINDIR} + +.PHONY: clean +clean: + rm -f query-machine-capabilities diff --git a/query-machine-capabilities/query-machine-capabilities.c b/query-machine-capabilities/query-machine-capabilities.c new file mode 100644 index 0000000..7b8c59f --- /dev/null +++ b/query-machine-capabilities/query-machine-capabilities.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <string.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; + + const char *path = "/run/qemu-server/"; + // Check that the directory exists and create it if it does not. + struct stat statbuf; + int stats = stat(path, &statbuf); + if (stats == 0 && S_ISDIR(statbuf.st_mode)) { + printf("Directory %s already exists.\n", path); + } else if (errno == ENOENT) { + printf("%s does not exist. Creating directory.\n", path); + if (mkdir(path, 0755) != 0) { + printf("Error creating directory %s: %s\n", path, strerror(errno)); + return 1; + } + } else { + printf("Error checking path %s: %s\n", path, strerror(errno)); + return 1; + } + + FILE *file; + const char *filename = "/run/qemu-server/host-hw-capabilities.json"; + 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-capabilities/query-machine-capabilities.service b/query-machine-capabilities/query-machine-capabilities.service new file mode 100644 index 0000000..f926074 --- /dev/null +++ b/query-machine-capabilities/query-machine-capabilities.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-capabilities +Type=oneshot + +[Install] +WantedBy=multi-user.target
_______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel