x86/mm: Decouple dynamic __PHYSICAL_MASK from AMD SME
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Fri, 18 May 2018 11:30:28 +0000 (14:30 +0300)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 6 Jun 2018 11:38:01 +0000 (13:38 +0200)
AMD SME claims one bit from physical address to indicate whether the
page is encrypted or not. To achieve that we clear out the bit from
__PHYSICAL_MASK.

The capability to adjust __PHYSICAL_MASK is required beyond AMD SME.
For instance for upcoming Intel Multi-Key Total Memory Encryption.

Factor it out into a separate feature with own Kconfig handle.

It also helps with overhead of AMD SME. It saves more than 3k in .text
on defconfig + AMD_MEM_ENCRYPT:

add/remove: 3/2 grow/shrink: 5/110 up/down: 189/-3753 (-3564)

We would need to return to this once we have infrastructure to patch
constants in code. That's good candidate for it.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Cc: linux-mm@kvack.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Link: https://lkml.kernel.org/r/20180518113028.79825-1-kirill.shutemov@linux.intel.com
arch/x86/Kconfig
arch/x86/boot/compressed/kaslr_64.c
arch/x86/include/asm/page_types.h
arch/x86/mm/mem_encrypt_identity.c
arch/x86/mm/pgtable.c

index c07f492..43a8fc4 100644 (file)
@@ -337,6 +337,9 @@ config ARCH_SUPPORTS_UPROBES
 config FIX_EARLYCON_MEM
        def_bool y
 
+config DYNAMIC_PHYSICAL_MASK
+       bool
+
 config PGTABLE_LEVELS
        int
        default 5 if X86_5LEVEL
@@ -1508,6 +1511,7 @@ config ARCH_HAS_MEM_ENCRYPT
 config AMD_MEM_ENCRYPT
        bool "AMD Secure Memory Encryption (SME) support"
        depends on X86_64 && CPU_SUP_AMD
+       select DYNAMIC_PHYSICAL_MASK
        ---help---
          Say yes to enable support for the encryption of system memory.
          This requires an AMD processor that supports Secure Memory
index 522d114..748456c 100644 (file)
@@ -69,6 +69,8 @@ static struct alloc_pgt_data pgt_data;
 /* The top level page table entry pointer. */
 static unsigned long top_level_pgt;
 
+phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
+
 /*
  * Mapping information structure passed to kernel_ident_mapping_init().
  * Due to relocation, pointers must be assigned at run time not build time.
@@ -81,6 +83,9 @@ void initialize_identity_maps(void)
        /* If running as an SEV guest, the encryption mask is required. */
        set_sev_encryption_mask();
 
+       /* Exclude the encryption mask from __PHYSICAL_MASK */
+       physical_mask &= ~sme_me_mask;
+
        /* Init mapping_info with run-time function/buffer pointers. */
        mapping_info.alloc_pgt_page = alloc_pgt_page;
        mapping_info.context = &pgt_data;
index 1e53560..c85e150 100644 (file)
@@ -17,7 +17,6 @@
 #define PUD_PAGE_SIZE          (_AC(1, UL) << PUD_SHIFT)
 #define PUD_PAGE_MASK          (~(PUD_PAGE_SIZE-1))
 
-#define __PHYSICAL_MASK                ((phys_addr_t)(__sme_clr((1ULL << __PHYSICAL_MASK_SHIFT) - 1)))
 #define __VIRTUAL_MASK         ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
 
 /* Cast *PAGE_MASK to a signed type so that it is sign-extended if
 
 #ifndef __ASSEMBLY__
 
+#ifdef CONFIG_DYNAMIC_PHYSICAL_MASK
+extern phys_addr_t physical_mask;
+#define __PHYSICAL_MASK                physical_mask
+#else
+#define __PHYSICAL_MASK                ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
+#endif
+
 extern int devmem_is_allowed(unsigned long pagenr);
 
 extern unsigned long max_low_pfn_mapped;
index 1b2197d..7ae3686 100644 (file)
@@ -527,6 +527,7 @@ void __init sme_enable(struct boot_params *bp)
                /* SEV state cannot be controlled by a command line option */
                sme_me_mask = me_mask;
                sev_enabled = true;
+               physical_mask &= ~sme_me_mask;
                return;
        }
 
@@ -561,4 +562,6 @@ void __init sme_enable(struct boot_params *bp)
                sme_me_mask = 0;
        else
                sme_me_mask = active_by_default ? me_mask : 0;
+
+       physical_mask &= ~sme_me_mask;
 }
index ffc8c13..3ca59cf 100644 (file)
@@ -8,6 +8,11 @@
 #include <asm/fixmap.h>
 #include <asm/mtrr.h>
 
+#ifdef CONFIG_DYNAMIC_PHYSICAL_MASK
+phys_addr_t physical_mask __ro_after_init = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
+EXPORT_SYMBOL(physical_mask);
+#endif
+
 #define PGALLOC_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
 
 #ifdef CONFIG_HIGHPTE