lkml.org 
[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCHv2 22/29] x86/tdx: Make pages shared in ioremap()
    Date
    In TDX guests, guest memory is protected from host access. If a guest
    performs I/O, it needs to explicitly share the I/O memory with the host.

    Make all ioremap()ed pages that are not backed by normal memory
    (IORES_DESC_NONE or IORES_DESC_RESERVED) mapped as shared.

    Since TDX memory encryption support is similar to AMD SEV architecture,
    reuse the infrastructure from AMD SEV code.

    Add tdx_shared_mask() interface to get the TDX guest shared bitmask.

    pgprot_decrypted() is used by drivers (i915, virtio_gpu, vfio). Export
    both pgprot_encrypted() and pgprot_decrypted().

    Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
    Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
    Reviewed-by: Andi Kleen <ak@linux.intel.com>
    Reviewed-by: Tony Luck <tony.luck@intel.com>
    Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
    ---
    arch/x86/include/asm/pgtable.h | 19 +++++++++++++------
    arch/x86/include/asm/tdx.h | 4 ++++
    arch/x86/kernel/cc_platform.c | 23 +++++++++++++++++++++++
    arch/x86/kernel/tdx.c | 9 +++++++++
    arch/x86/mm/ioremap.c | 5 +++++
    5 files changed, 54 insertions(+), 6 deletions(-)

    diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
    index 8a9432fb3802..40e22db48319 100644
    --- a/arch/x86/include/asm/pgtable.h
    +++ b/arch/x86/include/asm/pgtable.h
    @@ -15,12 +15,6 @@
    cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))) \
    : (prot))

    -/*
    - * Macros to add or remove encryption attribute
    - */
    -#define pgprot_encrypted(prot) __pgprot(__sme_set(pgprot_val(prot)))
    -#define pgprot_decrypted(prot) __pgprot(__sme_clr(pgprot_val(prot)))
    -
    #ifndef __ASSEMBLY__
    #include <linux/spinlock.h>
    #include <asm/x86_init.h>
    @@ -38,6 +32,19 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
    void ptdump_walk_pgd_level_checkwx(void);
    void ptdump_walk_user_pgd_level_checkwx(void);

    +/*
    + * Macros to add or remove encryption attribute
    + */
    +#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
    +pgprot_t pgprot_encrypted(pgprot_t prot);
    +pgprot_t pgprot_decrypted(pgprot_t prot);
    +#define pgprot_encrypted(prot) pgprot_encrypted(prot)
    +#define pgprot_decrypted(prot) pgprot_decrypted(prot)
    +#else
    +#define pgprot_encrypted(prot) (prot)
    +#define pgprot_decrypted(prot) (prot)
    +#endif
    +
    #ifdef CONFIG_DEBUG_WX
    #define debug_checkwx() ptdump_walk_pgd_level_checkwx()
    #define debug_checkwx_user() ptdump_walk_user_pgd_level_checkwx()
    diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
    index 4bcaadf21dc6..c6a279e67dff 100644
    --- a/arch/x86/include/asm/tdx.h
    +++ b/arch/x86/include/asm/tdx.h
    @@ -55,6 +55,8 @@ void tdx_safe_halt(void);

    bool tdx_early_handle_ve(struct pt_regs *regs);

    +phys_addr_t tdx_shared_mask(void);
    +
    #else

    static inline void tdx_early_init(void) { };
    @@ -63,6 +65,8 @@ static inline void tdx_safe_halt(void) { };

    static inline bool tdx_early_handle_ve(struct pt_regs *regs) { return false; }

    +static inline phys_addr_t tdx_shared_mask(void) { return 0; }
    +
    #endif /* CONFIG_INTEL_TDX_GUEST */

    #if defined(CONFIG_KVM_GUEST) && defined(CONFIG_INTEL_TDX_GUEST)
    diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c
    index dcb31d6a7554..be8722ad4792 100644
    --- a/arch/x86/kernel/cc_platform.c
    +++ b/arch/x86/kernel/cc_platform.c
    @@ -12,6 +12,7 @@
    #include <linux/mem_encrypt.h>

    #include <asm/mshyperv.h>
    +#include <asm/pgtable.h>
    #include <asm/processor.h>
    #include <asm/tdx.h>

    @@ -90,3 +91,25 @@ bool cc_platform_has(enum cc_attr attr)
    return false;
    }
    EXPORT_SYMBOL_GPL(cc_platform_has);
    +
    +pgprot_t pgprot_encrypted(pgprot_t prot)
    +{
    + if (sme_me_mask)
    + return __pgprot(__sme_set(pgprot_val(prot)));
    + else if (is_tdx_guest())
    + return __pgprot(pgprot_val(prot) & ~tdx_shared_mask());
    +
    + return prot;
    +}
    +EXPORT_SYMBOL_GPL(pgprot_encrypted);
    +
    +pgprot_t pgprot_decrypted(pgprot_t prot)
    +{
    + if (sme_me_mask)
    + return __pgprot(__sme_clr(pgprot_val(prot)));
    + else if (is_tdx_guest())
    + return __pgprot(pgprot_val(prot) | tdx_shared_mask());
    +
    + return prot;
    +}
    +EXPORT_SYMBOL_GPL(pgprot_decrypted);
    diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c
    index beeaf61934bc..3bf6621eae7d 100644
    --- a/arch/x86/kernel/tdx.c
    +++ b/arch/x86/kernel/tdx.c
    @@ -66,6 +66,15 @@ long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,
    EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
    #endif

    +/*
    + * The highest bit of a guest physical address is the "sharing" bit.
    + * Set it for shared pages and clear it for private pages.
    + */
    +phys_addr_t tdx_shared_mask(void)
    +{
    + return BIT_ULL(td_info.gpa_width - 1);
    +}
    +
    static void tdx_get_info(void)
    {
    struct tdx_module_output out;
    diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
    index 026031b3b782..a5d4ec1afca2 100644
    --- a/arch/x86/mm/ioremap.c
    +++ b/arch/x86/mm/ioremap.c
    @@ -242,10 +242,15 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size,
    * If the page being mapped is in memory and SEV is active then
    * make sure the memory encryption attribute is enabled in the
    * resulting mapping.
    + * In TDX guests, memory is marked private by default. If encryption
    + * is not requested (using encrypted), explicitly set decrypt
    + * attribute in all IOREMAPPED memory.
    */
    prot = PAGE_KERNEL_IO;
    if ((io_desc.flags & IORES_MAP_ENCRYPTED) || encrypted)
    prot = pgprot_encrypted(prot);
    + else
    + prot = pgprot_decrypted(prot);

    switch (pcm) {
    case _PAGE_CACHE_MODE_UC:
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-01-24 16:03    [W:5.231 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site