From nobody Tue Apr 7 01:05:26 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1773752121; cv=none; d=zohomail.com; s=zohoarc; b=G7TRHWjJmG2XgJYcXPOdxYlBlf3V3V6mXG/zJa1Uhpu5YuvLIHcpy3gnzmth709O4bnGuSa6Y7CAAEgXDlnjo9+AHrXi6PgxpkI/ZjFECK6anpFH5+PDxDm51Jfof4kxNSoVfVn3tADU3bQ6NmeKZmYRo3xpbNvyGoQ0lkRrOhw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773752121; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bY4KGqTqEcM2o4+nGwsRQwEX89TAOhW7Y8KDW5BEpQ4=; b=eAaA41ZSN531q0zPBs7pIuFcsKBAQ+A6bZr5j2BRfbQYNcuV5rGtw0FCVCxMRSPN5n6JNTrhSVPdC/Jesk7A2Q9SQ3x/lIaRD2iRmTm4L7bmbarR1gHJHzQ4ce7Qb7p9WowjsUvPa+IeBBlb7f5TVi2mNGzbeMxYe39GG1otwzY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1773752121291622.6401160956228; Tue, 17 Mar 2026 05:55:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w2TwV-0008Vp-Vs; Tue, 17 Mar 2026 08:54:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w2Sl2-0003Sr-6p for qemu-devel@nongnu.org; Tue, 17 Mar 2026 07:38:46 -0400 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1w2Skx-0007sG-7K for qemu-devel@nongnu.org; Tue, 17 Mar 2026 07:38:43 -0400 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-48535a0ef86so47057755e9.1 for ; Tue, 17 Mar 2026 04:38:38 -0700 (PDT) Received: from DesktopTC.localdomain (host-87-27-45-215.business.telecomitalia.it. [87.27.45.215]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4856eaee04fsm62721365e9.13.2026.03.17.04.38.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Mar 2026 04:38:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773747517; x=1774352317; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bY4KGqTqEcM2o4+nGwsRQwEX89TAOhW7Y8KDW5BEpQ4=; b=ajqP3Rdr2tuI0IfzmuiUwD5Q1CvtVU7N9P0zatn8x9hoI9Pq7oEGr+CdWs1PmvM7HN ifO/aMEuulGnbDR7YNjJfhspegEp37vRxMMkimC85RArojMibbb2JIBJAAS2Pg1wMjY8 YVUZRjovvZIvWB4Ga0sSfLRymPHlw1LNKs5yFmVxmsu1prUaxTNePmPD5F06PDDKpq6P dRYnhwi4qFoRPvNQ1zxpnofTf5QQ7SXpGdVEC1JUyd6VWw7wbFikQkdTfai4D7hFfPr9 zm/U7H63XxwG1TKKoeRCRFnoI5A9mV3pc+MJNDlreEpCikJnvcQSSb4Fz3m/u1PG+d3k qsyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773747517; x=1774352317; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=bY4KGqTqEcM2o4+nGwsRQwEX89TAOhW7Y8KDW5BEpQ4=; b=ErzLOoVVMWwZieTbsBcPD65rqgTPgmmNdG/g7rLPb9sC557arAcZt5auTwCWFgJBLU 5R7Q/2mCQ9E6uwjY+Jeufp66/ozoKFFly0tdAroa73a0WWxK8ujE4VDiA/Rra7bYNRhL GOLFkxarroZI2Yszt19LM+MDkf8jydT15fAw4+F0Tl0jdmkpaqnu4WgQaKCjvAgJORvE 7fmj93kx4PMy+Sw69jn4zUz5QjSFU9recA6asA+aUCtMqmBUsDWtB9SHH/pO/CnX2jm4 wF+KVsioXVDSMWXsJoy4SaiI6HxmEYPddSbaPi4gaQtfkfl2DhsXegF2AwvGjXDJXlbd Y2wg== X-Gm-Message-State: AOJu0YwOj6ZQGakP3mkk4UdEdSX59wapstMzR66zgrSkUHxyuVqsVHbj a2NHepGXEoaODfsnZ5iPf79QAPw2WxiMKqanEJsjEKGEfGCZXK73O5pPAAZwE303 X-Gm-Gg: ATEYQzzhQDAnk3R9g3jiS9TMR89zNEZHR17Q6fjOKnA2ea4tr6BCfQrtj6end3bpJyU ure2O6Yn4+Od9Xrkfh87yur7/DGeloKeHbAwMhxAeFz6ok3wvEUtiD2+mnQ81x/3j+2IKJ94h2c +KGJeL2soVmVGIh2afOTysWam9veR7PBbQ/TBmUDGzwRWDdsYjihm35nwaxCkC0zRPpvYY6lZp9 /jO540HvSaqHPsulWW4r3wuAcMs5HaW8nSJsa3uxV0Wb2ap6XAc1X/gtJyuw6uwmG6UoBhegQ/v EM5rYj98VouINfKP59vS+Kkr+IJRa+VXWwDrxWInJA82l2fVQxhb/6J/rt5HaCma+FOAp+cVtI6 qMWW3zuXmYbzokpudfxrp0XCXOXNYSabRLwUurR6Bc3cvw+GtLGR8j67z28ZB2kITmz9RGwkgXP +JShUJJf9DkjPzLxuj7roJGPZQ3rfzbl0tgYlXeE8BZDZfPVPCIIFK9wxla5VY4eFn7i7X2BWvu z1EMkuuc56SVSrPgocL X-Received: by 2002:a05:600c:a09:b0:483:9139:4c1d with SMTP id 5b1f17b1804b1-485566e1a4cmr296742155e9.14.1773747516835; Tue, 17 Mar 2026 04:38:36 -0700 (PDT) From: Tommaso Califano To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Eduardo Habkost , Markus Armbruster , Zhao Liu , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Marcelo Tosatti , Eric Blake , Oliver Steffen , Stefano Garzarella , Giuseppe Lettieri , Paolo Bonzini , Luigi Leonardi , Richard Henderson , Tommaso Califano Subject: [PATCH 2/5] target/i386: Add MSR SEV support and C-bit reset on TCG Date: Tue, 17 Mar 2026 12:38:37 +0100 Message-ID: <20260317113840.33017-3-califano.tommaso@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260317113840.33017-1-califano.tommaso@gmail.com> References: <20260317113840.33017-1-califano.tommaso@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=califano.tommaso@gmail.com; helo=mail-wm1-x332.google.com X-Spam_score_int: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, MIME_BASE64_TEXT=1.741, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Tue, 17 Mar 2026 08:54:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1773752121989158500 Content-Type: text/plain; charset="utf-8" Exposing SEV CPUID leaf informs the guest of SEV support, but activation of the features requires setting bit 0 in the SEV MSR (0xc0010131). sev_emulated_enable() is implemented to enable the MSR only when emulation is active. This is invoked from helper_rdmsr() to control MSR write behavior. SEV MSR activation prompts OVMF to use C-bits in PTEs, altering paging. To address this, C-bits are reset in all PTEs and CR3 via sev_emulated_convert_pte(). This change enables the features of the guest adding to QEMU arguments: -cpu "EPYC-Milan" \ -accel tcg \ -object sev-emulated,id=3Dsev0,cbitpos=3D47,reduced-phys-bits=3D1 \ -machine memory-encryption=3Dsev0 A SEV capable cpu profile must be selected to enable the emulation. Signed-off-by: Tommaso Califano --- target/i386/cpu.h | 2 ++ target/i386/sev.c | 18 ++++++++++++++++ target/i386/sev.h | 3 +++ target/i386/tcg/system/excp_helper.c | 31 ++++++++++++++++++++++++++++ target/i386/tcg/system/misc_helper.c | 13 ++++++++++++ 5 files changed, 67 insertions(+) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 0b539155c4..dc2f82837f 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -659,6 +659,8 @@ typedef enum X86Seg { #define ESA_FEATURE_ALIGN64_MASK (1U << ESA_FEATURE_ALIGN64_BIT) #define ESA_FEATURE_XFD_MASK (1U << ESA_FEATURE_XFD_BIT) =20 +/* AMD SEV MSR */ +#define MSR_AMD64_SEV 0xc0010131 =20 /* CPUID feature bits available in XCR0 */ #define CPUID_XSTATE_XCR0_MASK (XSTATE_FP_MASK | XSTATE_SSE_MASK | \ diff --git a/target/i386/sev.c b/target/i386/sev.c index 2502e860e2..cdadd83ab5 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -690,6 +690,14 @@ static int sev_set_cpu_context(uint16_t cpu_index, con= st void *ctx, return 0; } =20 +bool +sev_emulated_enabled(void) +{ + ConfidentialGuestSupport *cgs =3D MACHINE(qdev_get_machine())->cgs; + + return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_EMULATED); +} + bool sev_enabled(void) { @@ -731,6 +739,16 @@ sev_get_reduced_phys_bits(void) return sev_common ? sev_common->reduced_phys_bits : 0; } =20 +uint64_t +sev_emulated_convert_pte(uint64_t pte) +{ + if (unlikely(sev_emulated_enabled())) { + pte &=3D ~(1ULL << sev_get_cbit_position()); + } + + return pte; +} + static SevInfo *sev_get_info(void) { SevInfo *info; diff --git a/target/i386/sev.h b/target/i386/sev.h index 839656e2be..d69275d40f 100644 --- a/target/i386/sev.h +++ b/target/i386/sev.h @@ -24,10 +24,12 @@ #define sev_enabled() 0 #define sev_es_enabled() 0 #define sev_snp_enabled() 0 +#define sev_emulated_enabled() 0 #else bool sev_enabled(void); bool sev_es_enabled(void); bool sev_snp_enabled(void); +bool sev_emulated_enabled(void); #endif =20 #if !defined(CONFIG_USER_ONLY) @@ -197,5 +199,6 @@ void pc_system_parse_sev_metadata(uint8_t *flash_ptr, s= ize_t flash_size); =20 uint32_t sev_get_cbit_position(void); uint32_t sev_get_reduced_phys_bits(void); +uint64_t sev_emulated_convert_pte(uint64_t); =20 #endif diff --git a/target/i386/tcg/system/excp_helper.c b/target/i386/tcg/system/= excp_helper.c index d7ea77c855..307a4a7e6b 100644 --- a/target/i386/tcg/system/excp_helper.c +++ b/target/i386/tcg/system/excp_helper.c @@ -26,6 +26,7 @@ #include "exec/target_page.h" #include "exec/tlb-flags.h" #include "tcg/helper-tcg.h" +#include "sev.h" =20 typedef struct TranslateParams { target_ulong addr; @@ -160,7 +161,13 @@ static bool mmu_translate(CPUX86State *env, const Tran= slateParams *in, int prot; =20 restart_all: +#ifdef CONFIG_SEV + rsvd_mask =3D ~MAKE_64BIT_MASK(0, + env_archcpu(env)->phys_bits - sev_get_reduced_phys_bits()); + rsvd_mask =3D sev_emulated_convert_pte(rsvd_mask); +#else rsvd_mask =3D ~MAKE_64BIT_MASK(0, env_archcpu(env)->phys_bits); +#endif rsvd_mask &=3D PG_ADDRESS_MASK; if (!(pg_mode & PG_MODE_NXE)) { rsvd_mask |=3D PG_NX_MASK; @@ -179,6 +186,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, } restart_5: pte =3D ptw_ldq(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -203,6 +213,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, } restart_4: pte =3D ptw_ldq(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -223,6 +236,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, } restart_3_lma: pte =3D ptw_ldq(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -251,6 +267,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, rsvd_mask |=3D PG_HI_USER_MASK; restart_3_nolma: pte =3D ptw_ldq(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -272,6 +291,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, } restart_2_pae: pte =3D ptw_ldq(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -297,6 +319,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, return false; } pte =3D ptw_ldq(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -316,6 +341,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, } restart_2_nopae: pte =3D ptw_ldl(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } @@ -344,6 +372,9 @@ static bool mmu_translate(CPUX86State *env, const Trans= lateParams *in, return false; } pte =3D ptw_ldl(&pte_trans, ra); + #ifdef CONFIG_SEV + pte =3D sev_emulated_convert_pte(pte); + #endif if (!(pte & PG_PRESENT_MASK)) { goto do_fault; } diff --git a/target/i386/tcg/system/misc_helper.c b/target/i386/tcg/system/= misc_helper.c index bb79d4e470..aa6ed5cda1 100644 --- a/target/i386/tcg/system/misc_helper.c +++ b/target/i386/tcg/system/misc_helper.c @@ -27,6 +27,7 @@ #include "exec/cputlb.h" #include "tcg/helper-tcg.h" #include "hw/i386/apic.h" +#include "target/i386/sev.h" =20 void helper_outb(CPUX86State *env, uint32_t port, uint32_t data) { @@ -89,6 +90,10 @@ void helper_write_crN(CPUX86State *env, int reg, target_= ulong t0) cpu_x86_update_cr0(env, t0); break; case 3: + #ifdef CONFIG_SEV + /* If SEV emulation is active, reset the C-bit */ + t0 =3D sev_emulated_convert_pte(t0); + #endif if ((env->efer & MSR_EFER_LMA) && (t0 & ((~0ULL) << env_archcpu(env)->phys_bits))) { cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC()); @@ -468,6 +473,14 @@ void helper_rdmsr(CPUX86State *env) case MSR_IA32_UCODE_REV: val =3D x86_cpu->ucode_rev; break; + case MSR_AMD64_SEV: + if (sev_emulated_enabled()) { + val =3D 1; + } else { + /* XXX: exception? */ + val =3D 0; + } + break; case MSR_CORE_THREAD_COUNT: { val =3D cpu_x86_get_msr_core_thread_count(x86_cpu); break; --=20 2.53.0