mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-04-30 03:50:47 +00:00
add C program to get hardware capabilities from CPUID
Implement a C program that extracts AMD SEV hardware information such as reduced-phys-bios and cbitpos from CPUID, looks if SEV, SEV-ES & SEV-SNP are enabled, and outputs these details as JSON to /run/qemu-server/host-hw-capabilities.json This program can also be used to read and save other hardware information. Signed-off-by: Markus Frank <m.frank@proxmox.com> Co-authored-by: Thomas Lamprecht <t.lamprecht@proxmox.com> Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
parent
1ceb26e71e
commit
c9eee44b47
1
Makefile
1
Makefile
@ -65,6 +65,7 @@ install: $(PKGSOURCES)
|
|||||||
install -m 0644 -D bootsplash.jpg $(DESTDIR)/usr/share/$(PACKAGE)
|
install -m 0644 -D bootsplash.jpg $(DESTDIR)/usr/share/$(PACKAGE)
|
||||||
$(MAKE) -C PVE install
|
$(MAKE) -C PVE install
|
||||||
$(MAKE) -C qmeventd install
|
$(MAKE) -C qmeventd install
|
||||||
|
$(MAKE) -C query-machine-capabilities install
|
||||||
$(MAKE) -C qemu-configs install
|
$(MAKE) -C qemu-configs install
|
||||||
$(MAKE) -C vm-network-scripts install
|
$(MAKE) -C vm-network-scripts install
|
||||||
install -m 0755 qm $(DESTDIR)$(SBINDIR)
|
install -m 0755 qm $(DESTDIR)$(SBINDIR)
|
||||||
|
18
query-machine-capabilities/Makefile
Normal file
18
query-machine-capabilities/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
DESTDIR=
|
||||||
|
PREFIX=/usr
|
||||||
|
BINDIR=${PREFIX}/libexec/qemu-server
|
||||||
|
|
||||||
|
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}/${BINDIR}
|
||||||
|
install -m 0755 query-machine-capabilities ${DESTDIR}${BINDIR}
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f query-machine-capabilities
|
79
query-machine-capabilities/query-machine-capabilities.c
Normal file
79
query-machine-capabilities/query-machine-capabilities.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/stat.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 ret = stat(path, &statbuf);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (!S_ISDIR(statbuf.st_mode)) {
|
||||||
|
printf("Path %s is not a directory.\n", path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (errno == ENOENT) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 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"
|
||||||
|
);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Error writing to file %s: %s\n", path, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fclose(file);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("Error closing file %s: %s\n", path, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user