lkml.org 
[lkml]   [2021]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH v8 01/40] x86/compressed/64: detect/setup SEV/SME features earlier in boot
    From
    Date
    On 12/14/21 6:14 PM, Venu Busireddy wrote:
    > On 2021-12-14 20:10:16 +0100, Borislav Petkov wrote:
    >> On Tue, Dec 14, 2021 at 11:46:14AM -0600, Venu Busireddy wrote:
    >>> What I am suggesting should not have anything to do with the boot stage
    >>> of the kernel.
    >>
    >> I know exactly what you're suggesting.
    >>
    >>> For example, both these functions call native_cpuid(), which is declared
    >>> as an inline function. I am merely suggesting to do something similar
    >>> to avoid the code duplication.
    >>
    >> Try it yourself. If you can come up with something halfway readable and
    >> it builds, I'm willing to take a look.
    >
    > Patch (to be applied on top of sev-snp-v8 branch of
    > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Flinux.git&data=04%7C01%7Cthomas.lendacky%40amd.com%7Cbff83ee03b1147c39ea808d9bf5fe9d8%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637751240978266883%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=D8t%2FwXY%2FYIl8aJXN%2BU7%2Flubln8AbhtdgB0f4DCNWp4w%3D&reserved=0) is attached at the end.
    >
    > Here are a few things I did.
    >
    > 1. Moved all the common code that existed at the begining of
    > sme_enable() and sev_enable() to an inline function named
    > get_pagetable_bit_pos().
    > 2. sme_enable() was using AMD_SME_BIT and AMD_SEV_BIT, whereas
    > sev_enable() was dealing with raw bits. Moved those definitions to
    > sev.h, and changed sev_enable() to use those definitions.
    > 3. Make consistent use of BIT_ULL.
    >
    > Venu
    >
    >
    > diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
    > index c2bf99522e5e..b44d6b37796e 100644
    > --- a/arch/x86/boot/compressed/sev.c
    > +++ b/arch/x86/boot/compressed/sev.c
    > @@ -291,6 +291,7 @@ static void enforce_vmpl0(void)
    > void sev_enable(struct boot_params *bp)
    > {
    > unsigned int eax, ebx, ecx, edx;
    > + unsigned long pt_bit_pos; /* Pagetable bit position */
    > bool snp;
    >
    > /*
    > @@ -299,26 +300,8 @@ void sev_enable(struct boot_params *bp)
    > */
    > snp = snp_init(bp);
    >
    > - /* Check for the SME/SEV support leaf */
    > - eax = 0x80000000;
    > - ecx = 0;
    > - native_cpuid(&eax, &ebx, &ecx, &edx);
    > - if (eax < 0x8000001f)
    > - return;
    > -
    > - /*
    > - * Check for the SME/SEV feature:
    > - * CPUID Fn8000_001F[EAX]
    > - * - Bit 0 - Secure Memory Encryption support
    > - * - Bit 1 - Secure Encrypted Virtualization support
    > - * CPUID Fn8000_001F[EBX]
    > - * - Bits 5:0 - Pagetable bit position used to indicate encryption
    > - */
    > - eax = 0x8000001f;
    > - ecx = 0;
    > - native_cpuid(&eax, &ebx, &ecx, &edx);
    > - /* Check whether SEV is supported */
    > - if (!(eax & BIT(1))) {
    > + /* Get the pagetable bit position if SEV is supported */
    > + if ((get_pagetable_bit_pos(&pt_bit_pos, AMD_SEV_BIT)) < 0) {
    > if (snp)
    > error("SEV-SNP support indicated by CC blob, but not CPUID.");
    > return;
    > @@ -350,7 +333,7 @@ void sev_enable(struct boot_params *bp)
    > if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
    > error("SEV-SNP supported indicated by CC blob, but not SEV status MSR.");
    >
    > - sme_me_mask = BIT_ULL(ebx & 0x3f);
    > + sme_me_mask = BIT_ULL(pt_bit_pos);
    > }
    >
    > /* Search for Confidential Computing blob in the EFI config table. */
    > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
    > index 2c5f12ae7d04..41b096f28d02 100644
    > --- a/arch/x86/include/asm/processor.h
    > +++ b/arch/x86/include/asm/processor.h
    > @@ -224,6 +224,43 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
    > : "memory");
    > }
    >
    > +/*
    > + * Returns the pagetable bit position in pt_bit_pos,
    > + * iff the specified features are supported.
    > + */
    > +static inline int get_pagetable_bit_pos(unsigned long *pt_bit_pos,
    > + unsigned long features)

    I'm not a fan of this name. You are specifically returning the encryption
    bit position but using a very generic name of get_pagetable_bit_pos() in a
    very common header file. Maybe something more like get_me_bit() and move
    the function to an existing SEV header file.

    Also, this can probably just return an unsigned int that will be either 0
    or the bit position, right? Then the check above can be for a zero value,
    e.g.:

    me_bit = get_me_bit();
    if (!me_bit) {

    ...

    sme_me_mask = BIT_ULL(me_bit);

    That should work below, too, but you'll need to verify that.

    > +{
    > + unsigned int eax, ebx, ecx, edx;
    > +
    > + /* Check for the SME/SEV support leaf */
    > + eax = 0x80000000;
    > + ecx = 0;
    > + native_cpuid(&eax, &ebx, &ecx, &edx);
    > + if (eax < 0x8000001f)
    > + return -1;

    This can then be:

    return 0;

    > +
    > + eax = 0x8000001f;
    > + ecx = 0;
    > + native_cpuid(&eax, &ebx, &ecx, &edx);
    > +
    > + /* Check whether the specified features are supported.
    > + * SME/SEV features:
    > + * CPUID Fn8000_001F[EAX]
    > + * - Bit 0 - Secure Memory Encryption support
    > + * - Bit 1 - Secure Encrypted Virtualization support
    > + */
    > + if (!(eax & features))
    > + return -1;

    and this can be:

    return 0;

    > +
    > + /*
    > + * CPUID Fn8000_001F[EBX]
    > + * - Bits 5:0 - Pagetable bit position used to indicate encryption
    > + */
    > + *pt_bit_pos = (unsigned long)(ebx & 0x3f);

    and this can be:

    return ebx & 0x3f;

    > + return 0;
    > +}
    > +
    > #define native_cpuid_reg(reg) \
    > static inline unsigned int native_cpuid_##reg(unsigned int op) \
    > { \
    > diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
    > index 7a5934af9d47..1a2344362ec6 100644
    > --- a/arch/x86/include/asm/sev.h
    > +++ b/arch/x86/include/asm/sev.h
    > @@ -17,6 +17,9 @@
    > #define GHCB_PROTOCOL_MAX 2ULL
    > #define GHCB_DEFAULT_USAGE 0ULL
    >
    > +#define AMD_SME_BIT BIT(0)
    > +#define AMD_SEV_BIT BIT(1)
    > +

    Maybe this is where that new static inline function should go...

    > #define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); }
    >
    > enum es_result {
    > diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
    > index 2f723e106ed3..1ef50e969efd 100644
    > --- a/arch/x86/mm/mem_encrypt_identity.c
    > +++ b/arch/x86/mm/mem_encrypt_identity.c
    > @@ -508,38 +508,18 @@ void __init sme_enable(struct boot_params *bp)
    > unsigned long feature_mask;
    > bool active_by_default;
    > unsigned long me_mask;
    > + unsigned long pt_bit_pos; /* Pagetable bit position */

    unsigned int and me_bit or me_bit_pos.

    Thanks,
    Tom

    > char buffer[16];
    > bool snp;
    > u64 msr;
    >
    > snp = snp_init(bp);
    >
    > - /* Check for the SME/SEV support leaf */
    > - eax = 0x80000000;
    > - ecx = 0;
    > - native_cpuid(&eax, &ebx, &ecx, &edx);
    > - if (eax < 0x8000001f)
    > + /* Get the pagetable bit position if SEV or SME are supported */
    > + if ((get_pagetable_bit_pos(&pt_bit_pos, AMD_SEV_BIT | AMD_SME_BIT)) < 0)
    > return;
    >
    > -#define AMD_SME_BIT BIT(0)
    > -#define AMD_SEV_BIT BIT(1)
    > -
    > - /*
    > - * Check for the SME/SEV feature:
    > - * CPUID Fn8000_001F[EAX]
    > - * - Bit 0 - Secure Memory Encryption support
    > - * - Bit 1 - Secure Encrypted Virtualization support
    > - * CPUID Fn8000_001F[EBX]
    > - * - Bits 5:0 - Pagetable bit position used to indicate encryption
    > - */
    > - eax = 0x8000001f;
    > - ecx = 0;
    > - native_cpuid(&eax, &ebx, &ecx, &edx);
    > - /* Check whether SEV or SME is supported */
    > - if (!(eax & (AMD_SEV_BIT | AMD_SME_BIT)))
    > - return;
    > -
    > - me_mask = 1UL << (ebx & 0x3f);
    > + me_mask = BIT_ULL(pt_bit_pos);
    >
    > /* Check the SEV MSR whether SEV or SME is enabled */
    > sev_status = __rdmsr(MSR_AMD64_SEV);
    >

    \
     
     \ /
      Last update: 2021-12-15 15:44    [W:4.109 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site