lkml.org 
[lkml]   [2021]   [Dec]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 34/40] x86/sev: add SEV-SNP feature detection/setup
    Date
    From: Michael Roth <michael.roth@amd.com>

    Initial/preliminary detection of SEV-SNP is done via the Confidential
    Computing blob. Check for it prior to the normal SEV/SME feature
    initialization, and add some sanity checks to confirm it agrees with
    SEV-SNP CPUID/MSR bits.

    Signed-off-by: Michael Roth <michael.roth@amd.com>
    Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
    ---
    arch/x86/include/asm/sev.h | 3 +-
    arch/x86/kernel/sev-shared.c | 2 +-
    arch/x86/kernel/sev.c | 65 ++++++++++++++++++++++++++++++
    arch/x86/mm/mem_encrypt_identity.c | 8 ++++
    4 files changed, 76 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
    index 4fa7ca20d7c9..4d32af1348ed 100644
    --- a/arch/x86/include/asm/sev.h
    +++ b/arch/x86/include/asm/sev.h
    @@ -147,6 +147,7 @@ void snp_set_memory_shared(unsigned long vaddr, unsigned int npages);
    void snp_set_memory_private(unsigned long vaddr, unsigned int npages);
    void snp_set_wakeup_secondary_cpu(void);
    bool snp_init(struct boot_params *bp);
    +void snp_abort(void);
    /*
    * TODO: These are exported only temporarily while boot/compressed/sev.c is
    * the only user. This is to avoid unused function warnings for kernel/sev.c
    @@ -156,7 +157,6 @@ bool snp_init(struct boot_params *bp);
    * can be moved back to being statically-scoped to units that pull in
    * sev-shared.c via #include and these declarations can be dropped.
    */
    -struct cc_blob_sev_info *snp_find_cc_blob_setup_data(struct boot_params *bp);
    void snp_cpuid_info_create(const struct cc_blob_sev_info *cc_info);
    #else
    static inline void sev_es_ist_enter(struct pt_regs *regs) { }
    @@ -176,6 +176,7 @@ static inline void snp_set_memory_shared(unsigned long vaddr, unsigned int npage
    static inline void snp_set_memory_private(unsigned long vaddr, unsigned int npages) { }
    static inline void snp_set_wakeup_secondary_cpu(void) { }
    static inline bool snp_init(struct boot_params *bp) { return false; }
    +static inline void snp_abort(void) { }
    #endif

    #endif
    diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
    index 5cb8f87df4b3..72836abcdbe2 100644
    --- a/arch/x86/kernel/sev-shared.c
    +++ b/arch/x86/kernel/sev-shared.c
    @@ -974,7 +974,7 @@ static struct cc_setup_data *get_cc_setup_data(struct boot_params *bp)
    * Search for a Confidential Computing blob passed in as a setup_data entry
    * via the Linux Boot Protocol.
    */
    -struct cc_blob_sev_info *
    +static struct cc_blob_sev_info *
    snp_find_cc_blob_setup_data(struct boot_params *bp)
    {
    struct cc_setup_data *sd;
    diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
    index 32f60602ec29..0e5c45eacc77 100644
    --- a/arch/x86/kernel/sev.c
    +++ b/arch/x86/kernel/sev.c
    @@ -1949,3 +1949,68 @@ bool __init handle_vc_boot_ghcb(struct pt_regs *regs)
    while (true)
    halt();
    }
    +
    +/*
    + * Initial set up of SEV-SNP relies on information provided by the
    + * Confidential Computing blob, which can be passed to the kernel
    + * in the following ways, depending on how it is booted:
    + *
    + * - when booted via the boot/decompress kernel:
    + * - via boot_params
    + *
    + * - when booted directly by firmware/bootloader (e.g. CONFIG_PVH):
    + * - via a setup_data entry, as defined by the Linux Boot Protocol
    + *
    + * Scan for the blob in that order.
    + */
    +static struct cc_blob_sev_info *snp_find_cc_blob(struct boot_params *bp)
    +{
    + struct cc_blob_sev_info *cc_info;
    +
    + /* Boot kernel would have passed the CC blob via boot_params. */
    + if (bp->cc_blob_address) {
    + cc_info = (struct cc_blob_sev_info *)
    + (unsigned long)bp->cc_blob_address;
    + goto found_cc_info;
    + }
    +
    + /*
    + * If kernel was booted directly, without the use of the
    + * boot/decompression kernel, the CC blob may have been passed via
    + * setup_data instead.
    + */
    + cc_info = snp_find_cc_blob_setup_data(bp);
    + if (!cc_info)
    + return NULL;
    +
    +found_cc_info:
    + if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC)
    + sev_es_terminate(1, GHCB_SNP_UNSUPPORTED);
    +
    + return cc_info;
    +}
    +
    +bool __init snp_init(struct boot_params *bp)
    +{
    + struct cc_blob_sev_info *cc_info;
    +
    + if (!bp)
    + return false;
    +
    + cc_info = snp_find_cc_blob(bp);
    + if (!cc_info)
    + return false;
    +
    + /*
    + * The CC blob will be used later to access the secrets page. Cache
    + * it here like the boot kernel does.
    + */
    + bp->cc_blob_address = (u32)(unsigned long)cc_info;
    +
    + return true;
    +}
    +
    +void __init snp_abort(void)
    +{
    + sev_es_terminate(1, GHCB_SNP_UNSUPPORTED);
    +}
    diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
    index 3f0abb403340..2f723e106ed3 100644
    --- a/arch/x86/mm/mem_encrypt_identity.c
    +++ b/arch/x86/mm/mem_encrypt_identity.c
    @@ -44,6 +44,7 @@
    #include <asm/setup.h>
    #include <asm/sections.h>
    #include <asm/cmdline.h>
    +#include <asm/sev.h>

    #include "mm_internal.h"

    @@ -508,8 +509,11 @@ void __init sme_enable(struct boot_params *bp)
    bool active_by_default;
    unsigned long me_mask;
    char buffer[16];
    + bool snp;
    u64 msr;

    + snp = snp_init(bp);
    +
    /* Check for the SME/SEV support leaf */
    eax = 0x80000000;
    ecx = 0;
    @@ -541,6 +545,10 @@ void __init sme_enable(struct boot_params *bp)
    sev_status = __rdmsr(MSR_AMD64_SEV);
    feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;

    + /* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */
    + if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
    + snp_abort();
    +
    /* Check if memory encryption is enabled */
    if (feature_mask == AMD_SME_BIT) {
    /*
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-12-10 16:47    [W:4.325 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site