From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id CF19F1FF17A for ; Tue, 28 Oct 2025 13:55:33 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id BD8F91ABEA; Tue, 28 Oct 2025 13:55:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1761656132; x=1762260932; d=canarybit.eu; s=rsa1; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=rtschIccKTSrjVAGtpiZO1WAuoRyrvu9oxPAQYafjUw=; b=JTQTtQBBePBzZULVv4q0ljhucngkriD9H2j9DxO6A7qly1oaW5DrZTilyPh/ILpTJnuUkPQaPU0jl Pwxwa4JbZQdTmfYilf+icdQXuH60cxLCf6lBSbx1Ynn06i8DdhGQGIDaDP4bZWo2TBds4VV3m2uIwK i6Q3DLe0OamtPWttwHZMA5pgduYopD6nfiuoM+ks32ibSmDBFsYDiWfHYtCv3+rTgv8Z18xULzCdIR AbhdKqd5w78IxLrrdiaG4pVfd98htsb88p2MP0opobUm3rKX4GPw2FMnZw8CM3mkcTZmCqDlAigHrl wOajjqp9bvwZ+6kNNq3fIgxP4+FQRsw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1761656132; x=1762260932; d=canarybit.eu; s=ed1; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=rtschIccKTSrjVAGtpiZO1WAuoRyrvu9oxPAQYafjUw=; b=IVgVGZIUn/s2PAmtj/dJLp0ZQuUgR099kx3A1/8ozXQLK7MeKR7s/1nd7o0WHnpH49XawB7ojMJfV +9GNBW5Bw== X-HalOne-ID: 6293e5bd-b3fd-11f0-ada8-d510462faafc From: Anton Iacobaeus To: pve-devel@lists.proxmox.com Date: Tue, 28 Oct 2025 13:54:29 +0100 Message-ID: <20251028125459.287308-8-anton.iacobaeus@canarybit.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251028125459.287308-1-anton.iacobaeus@canarybit.eu> References: <20251028125459.287308-1-anton.iacobaeus@canarybit.eu> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.578 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_MISSING 0.1 Missing DMARC policy MIME_BASE64_TEXT 1.741 Message text disguised using base64 encoding RCVD_IN_DNSWL_NONE -0.0001 Sender listed at https://www.dnswl.org/, no trust SPF_HELO_PASS -0.001 SPF: HELO matches SPF record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [PATCH qemu-server v3 2/4] Add check for TDX support X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Cc: Philipp Giersfeld Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" From: Philipp Giersfeld Check whether TDX is enabled on this machine. Instead of using CPUID like AMD SEV, Intel TDX enablement can be verified by reading the MSR (https://cc-enabling.trustedservices.intel.com/intel-tdx-enabling-guide/05/host_os_setup/). Signed-off-by: Philipp Giersfeld Signed-off-by: Anton Iacobaeus --- .../query-machine-capabilities.c | 98 ++++++++++++++++--- src/usr/modules-load.conf | 1 + 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/src/query-machine-capabilities/query-machine-capabilities.c b/src/query-machine-capabilities/query-machine-capabilities.c index 0c522afc..33317aca 100644 --- a/src/query-machine-capabilities/query-machine-capabilities.c +++ b/src/query-machine-capabilities/query-machine-capabilities.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #define eprintf(...) fprintf(stderr, __VA_ARGS__) @@ -18,17 +20,56 @@ typedef struct { uint8_t cbitpos; uint8_t reduced_phys_bits; -} cpu_caps_t; +} cpu_caps_amd_sev_t; -void query_cpu_capabilities(cpu_caps_t *res) { +typedef struct { + bool tdx_support; +} cpu_caps_intel_tdx_t; + +int read_msr(uint32_t msr_index, uint64_t *value) { + uint64_t data; + char* msr_file_name = "/dev/cpu/0/msr"; + int fd; + + fd = open(msr_file_name, O_RDONLY); + if (fd < 0) { + if (errno == ENXIO) { + eprintf("rdmsr: No CPU 0\n"); + return -1; + } else if (errno == EIO) { + eprintf("rdmsr: CPU doesn't support MSRs\n"); + return -1; + } else { + perror("rdmsr: failed to open MSR"); + return -1; + } + } + + if (pread(fd, &data, sizeof(data), msr_index) != sizeof(data)) { + if (errno == EIO) { + eprintf("rdmsr: CPU cannot read MSR 0x%08x\n", msr_index); + return -1; + } else { + perror("rdmsr: pread"); + return -1; + } + } + + *value = data; + + close(fd); + return 0; +} + +void query_cpu_capabilities_sev(cpu_caps_amd_sev_t *res) { 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) + : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) + : "0"(query_function) ); res->sev_support = (eax & (1<<1)) != 0; @@ -39,6 +80,19 @@ void query_cpu_capabilities(cpu_caps_t *res) { res->reduced_phys_bits = (ebx >> 6) & 0x3f; } +int query_cpu_capabilities_tdx(cpu_caps_intel_tdx_t *res) { + uint64_t tme_value, sgx_value, tdx_value; + + if (read_msr(0x982, &tme_value) == 0 && read_msr(0xa0, &sgx_value) == 0 && + read_msr(0x1401, &tdx_value) == 0) { + res->tdx_support = ((tme_value >> 1) & 1ULL) & (!sgx_value) & ((tdx_value >> 11) & 1ULL); + } else { + eprintf("Intel TDX support undetermined\n"); + return -1; + } + return 0; +} + int prepare_output_directory() { // Check that the directory exists and create it if it does not. struct stat statbuf; @@ -65,8 +119,8 @@ int main() { return 1; } - cpu_caps_t caps; - query_cpu_capabilities(&caps); + cpu_caps_amd_sev_t caps_sev; + query_cpu_capabilities_sev(&caps_sev); FILE *file = fopen(OUTPUT_PATH, "w"); if (file == NULL) { @@ -82,18 +136,36 @@ int main() { " \"sev-support\": %s," " \"sev-support-es\": %s," " \"sev-support-snp\": %s" - " }" - " }\n", - caps.cbitpos, - caps.reduced_phys_bits, - caps.sev_support ? "true" : "false", - caps.sev_es_support ? "true" : "false", - caps.sev_snp_support ? "true" : "false" + " }", + caps_sev.cbitpos, + caps_sev.reduced_phys_bits, + caps_sev.sev_support ? "true" : "false", + caps_sev.sev_es_support ? "true" : "false", + caps_sev.sev_snp_support ? "true" : "false" ); if (ret < 0) { eprintf("Error writing to file '" OUTPUT_PATH "': %s\n", strerror(errno)); } + cpu_caps_intel_tdx_t caps_tdx; + if (query_cpu_capabilities_tdx(&caps_tdx) == 0) { + ret = fprintf(file, + "," + " \"intel-tdx\": {" + " \"tdx-support\": %s" + " }", + caps_tdx.tdx_support ? "true" : "false" + ); + if (ret < 0) { + eprintf("Error writing to file '" OUTPUT_PATH "': %s\n", strerror(errno)); + } + } + + ret = fprintf(file, " }\n"); + if (ret < 0) { + eprintf("Error writing to file '" OUTPUT_PATH "': %s\n", strerror(errno)); + } + ret = fclose(file); if (ret != 0) { eprintf("Error closing file '" OUTPUT_PATH "': %s\n", strerror(errno)); diff --git a/src/usr/modules-load.conf b/src/usr/modules-load.conf index aee7d42a..f45d256b 100644 --- a/src/usr/modules-load.conf +++ b/src/usr/modules-load.conf @@ -1 +1,2 @@ vhost_net +msr -- 2.43.0 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel