lkml.org 
[lkml]   [2022]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/2] x86/sev: Add SNP-specific unaccepted memory support
    Date
    Add SNP-specific hooks to the unaccepted memory support in the boot
    path (__accept_memory()) and the core kernel (accept_memory()) in order
    to support booting SNP guests when unaccepted memory is present. Without
    this support, SNP guests will fail to boot and/or panic() when unaccepted
    memory is present in the EFI memory map.

    The process of accepting memory under SNP involves invoking the hypervisor
    to perform a page state change for the page to private memory and then
    issuing a PVALIDATE instruction to accept the page.

    Create the new header file arch/x86/boot/compressed/sev.h because adding
    the function declaration to any of the existing SEV related header files
    pulls in too many other header files, causing the build to fail.

    Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
    ---
    arch/x86/Kconfig | 1 +
    arch/x86/boot/compressed/mem.c | 3 +++
    arch/x86/boot/compressed/sev.c | 10 +++++++++-
    arch/x86/boot/compressed/sev.h | 23 +++++++++++++++++++++++
    arch/x86/include/asm/sev.h | 3 +++
    arch/x86/kernel/sev.c | 16 ++++++++++++++++
    arch/x86/mm/unaccepted_memory.c | 4 ++++
    7 files changed, 59 insertions(+), 1 deletion(-)
    create mode 100644 arch/x86/boot/compressed/sev.h

    diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
    index 34146ecc5bdd..0ad53c3533c2 100644
    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -1553,6 +1553,7 @@ config AMD_MEM_ENCRYPT
    select INSTRUCTION_DECODER
    select ARCH_HAS_CC_PLATFORM
    select X86_MEM_ENCRYPT
    + select UNACCEPTED_MEMORY
    help
    Say yes to enable support for the encryption of system memory.
    This requires an AMD processor that supports Secure Memory
    diff --git a/arch/x86/boot/compressed/mem.c b/arch/x86/boot/compressed/mem.c
    index 48e36e640da1..3e19dc0da0d7 100644
    --- a/arch/x86/boot/compressed/mem.c
    +++ b/arch/x86/boot/compressed/mem.c
    @@ -6,6 +6,7 @@
    #include "find.h"
    #include "math.h"
    #include "tdx.h"
    +#include "sev.h"
    #include <asm/shared/tdx.h>

    #define PMD_SHIFT 21
    @@ -39,6 +40,8 @@ static inline void __accept_memory(phys_addr_t start, phys_addr_t end)
    /* Platform-specific memory-acceptance call goes here */
    if (is_tdx_guest())
    tdx_accept_memory(start, end);
    + else if (sev_snp_enabled())
    + snp_accept_memory(start, end);
    else
    error("Cannot accept memory: unknown platform\n");
    }
    diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
    index 730c4677e9db..d4b06c862094 100644
    --- a/arch/x86/boot/compressed/sev.c
    +++ b/arch/x86/boot/compressed/sev.c
    @@ -115,7 +115,7 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
    /* Include code for early handlers */
    #include "../../kernel/sev-shared.c"

    -static inline bool sev_snp_enabled(void)
    +bool sev_snp_enabled(void)
    {
    return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
    }
    @@ -161,6 +161,14 @@ void snp_set_page_shared(unsigned long paddr)
    __page_state_change(paddr, SNP_PAGE_STATE_SHARED);
    }

    +void snp_accept_memory(phys_addr_t start, phys_addr_t end)
    +{
    + while (end > start) {
    + snp_set_page_private(start);
    + start += PAGE_SIZE;
    + }
    +}
    +
    static bool early_setup_ghcb(void)
    {
    if (set_page_decrypted((unsigned long)&boot_ghcb_page))
    diff --git a/arch/x86/boot/compressed/sev.h b/arch/x86/boot/compressed/sev.h
    new file mode 100644
    index 000000000000..fc725a981b09
    --- /dev/null
    +++ b/arch/x86/boot/compressed/sev.h
    @@ -0,0 +1,23 @@
    +/* SPDX-License-Identifier: GPL-2.0 */
    +/*
    + * AMD SEV header for early boot related functions.
    + *
    + * Author: Tom Lendacky <thomas.lendacky@amd.com>
    + */
    +
    +#ifndef BOOT_COMPRESSED_SEV_H
    +#define BOOT_COMPRESSED_SEV_H
    +
    +#ifdef CONFIG_AMD_MEM_ENCRYPT
    +
    +bool sev_snp_enabled(void);
    +void snp_accept_memory(phys_addr_t start, phys_addr_t end);
    +
    +#else
    +
    +static inline bool sev_snp_enabled(void) { return false; }
    +static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
    +
    +#endif
    +
    +#endif
    diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
    index 19514524f0f8..21db66bacefe 100644
    --- a/arch/x86/include/asm/sev.h
    +++ b/arch/x86/include/asm/sev.h
    @@ -202,6 +202,7 @@ void snp_set_wakeup_secondary_cpu(void);
    bool snp_init(struct boot_params *bp);
    void snp_abort(void);
    int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err);
    +void snp_accept_memory(phys_addr_t start, phys_addr_t end);
    #else
    static inline void sev_es_ist_enter(struct pt_regs *regs) { }
    static inline void sev_es_ist_exit(void) { }
    @@ -226,6 +227,8 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
    {
    return -ENOTTY;
    }
    +
    +static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
    #endif

    #endif
    diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
    index 275aa890611f..f64805fa5dcb 100644
    --- a/arch/x86/kernel/sev.c
    +++ b/arch/x86/kernel/sev.c
    @@ -916,6 +916,22 @@ void snp_set_memory_private(unsigned long vaddr, unsigned int npages)
    pvalidate_pages(vaddr, npages, true);
    }

    +void snp_accept_memory(phys_addr_t start, phys_addr_t end)
    +{
    + unsigned long vaddr;
    + unsigned int npages;
    +
    + if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
    + return;
    +
    + vaddr = (unsigned long)__va(start);
    + npages = (end - start) >> PAGE_SHIFT;
    +
    + set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE);
    +
    + pvalidate_pages(vaddr, npages, true);
    +}
    +
    static int snp_set_vmsa(void *va, bool vmsa)
    {
    u64 attrs;
    diff --git a/arch/x86/mm/unaccepted_memory.c b/arch/x86/mm/unaccepted_memory.c
    index 9ec2304272dc..b86ad6a8ddf5 100644
    --- a/arch/x86/mm/unaccepted_memory.c
    +++ b/arch/x86/mm/unaccepted_memory.c
    @@ -9,6 +9,7 @@
    #include <asm/setup.h>
    #include <asm/shared/tdx.h>
    #include <asm/unaccepted_memory.h>
    +#include <asm/sev.h>

    /* Protects unaccepted memory bitmap */
    static DEFINE_SPINLOCK(unaccepted_memory_lock);
    @@ -66,6 +67,9 @@ void accept_memory(phys_addr_t start, phys_addr_t end)
    if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
    tdx_accept_memory(range_start * PMD_SIZE,
    range_end * PMD_SIZE);
    + } else if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) {
    + snp_accept_memory(range_start * PMD_SIZE,
    + range_end * PMD_SIZE);
    } else {
    panic("Cannot accept memory: unknown platform\n");
    }
    --
    2.36.1
    \
     
     \ /
      Last update: 2022-08-08 19:17    [W:4.369 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site