[svsm-devel] [PATCH v3 07/14] x86/sev: Provide SVSM discovery support
Gupta, Pankaj
pankaj.gupta at amd.com
Mon Apr 15 18:12:44 CEST 2024
On 3/25/2024 11:26 PM, Tom Lendacky wrote:
> The SVSM specification documents an alternative method of discovery for
> the SVSM using a reserved CPUID bit and a reserved MSR.
>
> For the CPUID support, the SNP CPUID table is updated to set bit 28 of
> the EAX register of the 0x8000001f leaf when an SVSM is present. This bit
> has been reserved for use in this capacity.
>
> For the MSR support, a new reserved MSR 0xc001f000 has been defined. A #VC
> should be generated when accessing this MSR. The #VC handler is expected
> to ignore writes to this MSR and return the physical calling area address
> (CAA) on reads of this MSR.
>
> Signed-off-by: Tom Lendacky <thomas.lendacky at amd.com>
Reviewed-by: Pankaj Gupta <pankaj.gupta at amd.com>
> ---
> arch/x86/include/asm/cpufeatures.h | 1 +
> arch/x86/include/asm/msr-index.h | 2 ++
> arch/x86/kernel/sev-shared.c | 11 +++++++++++
> arch/x86/kernel/sev.c | 17 +++++++++++++++++
> 4 files changed, 31 insertions(+)
>
> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
> index a38f8f9ba657..51e7c879f057 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -446,6 +446,7 @@
> #define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* "" Virtual TSC_AUX */
> #define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */
> #define X86_FEATURE_DEBUG_SWAP (19*32+14) /* AMD SEV-ES full debug state swap support */
> +#define X86_FEATURE_SVSM_PRESENT (19*32+28) /* "" SNP SVSM is present */
>
> /* AMD-defined Extended Feature 2 EAX, CPUID level 0x80000021 (EAX), word 20 */
> #define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* "" No Nested Data Breakpoints */
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 05956bd8bacf..cc4de3379265 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -654,6 +654,8 @@
> #define MSR_AMD64_RMP_BASE 0xc0010132
> #define MSR_AMD64_RMP_END 0xc0010133
>
> +#define MSR_SVSM_CAA 0xc001f000
> +
> /* AMD Collaborative Processor Performance Control MSRs */
> #define MSR_AMD_CPPC_CAP1 0xc00102b0
> #define MSR_AMD_CPPC_ENABLE 0xc00102b1
> diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
> index e63c0a6eccd6..17eb42c4ae71 100644
> --- a/arch/x86/kernel/sev-shared.c
> +++ b/arch/x86/kernel/sev-shared.c
> @@ -1559,6 +1559,8 @@ static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt,
> static void __head setup_svsm_ca(const struct cc_blob_sev_info *cc_info)
> {
> struct snp_secrets_page_layout *secrets_page;
> + struct snp_cpuid_table *cpuid_table;
> + unsigned int i;
> u64 caa;
>
> BUILD_BUG_ON(sizeof(*secrets_page) != PAGE_SIZE);
> @@ -1596,4 +1598,13 @@ static void __head setup_svsm_ca(const struct cc_blob_sev_info *cc_info)
> */
> boot_svsm_caa = (struct svsm_ca *)caa;
> boot_svsm_caa_pa = caa;
> +
> + /* Advertise the SVSM presence via CPUID. */
> + cpuid_table = (struct snp_cpuid_table *)snp_cpuid_get_table();
> + for (i = 0; i < cpuid_table->count; i++) {
> + struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
> +
> + if (fn->eax_in == 0x8000001f)
> + fn->eax |= BIT(28);
> + }
> }
> diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
> index ea8b43a0f01b..7f399ea87a3c 100644
> --- a/arch/x86/kernel/sev.c
> +++ b/arch/x86/kernel/sev.c
> @@ -1347,12 +1347,29 @@ int __init sev_es_efi_map_ghcbs(pgd_t *pgd)
> return 0;
> }
>
> +static enum es_result vc_handle_svsm_caa_msr(struct es_em_ctxt *ctxt)
> +{
> + struct pt_regs *regs = ctxt->regs;
> +
> + /* Writes to the SVSM CAA msr are ignored */
> + if (ctxt->insn.opcode.bytes[1] == 0x30)
> + return ES_OK;
> +
> + regs->ax = lower_32_bits(this_cpu_read(svsm_caa_pa));
> + regs->dx = upper_32_bits(this_cpu_read(svsm_caa_pa));
> +
> + return ES_OK;
> +}
> +
> static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
> {
> struct pt_regs *regs = ctxt->regs;
> enum es_result ret;
> u64 exit_info_1;
>
> + if (regs->cx == MSR_SVSM_CAA)
> + return vc_handle_svsm_caa_msr(ctxt);
> +
> /* Is it a WRMSR? */
> exit_info_1 = (ctxt->insn.opcode.bytes[1] == 0x30) ? 1 : 0;
>
More information about the Svsm-devel
mailing list