diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2018-05-18 07:30:28 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-06-06 07:38:01 -0400 |
commit | 94d49eb30e854c84d1319095b5dd0405a7da9362 (patch) | |
tree | 0c2c2a712fae357f64de8e330c4956bda1215255 | |
parent | 046c0dbec0238c25b7526c26c9a9687664229ce2 (diff) |
x86/mm: Decouple dynamic __PHYSICAL_MASK from AMD SME
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
-rw-r--r-- | arch/x86/Kconfig | 4 | ||||
-rw-r--r-- | arch/x86/boot/compressed/kaslr_64.c | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/page_types.h | 8 | ||||
-rw-r--r-- | arch/x86/mm/mem_encrypt_identity.c | 3 | ||||
-rw-r--r-- | arch/x86/mm/pgtable.c | 5 |
5 files changed, 24 insertions, 1 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c07f492b871a..43a8fc476296 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -337,6 +337,9 @@ config ARCH_SUPPORTS_UPROBES | |||
337 | config FIX_EARLYCON_MEM | 337 | config FIX_EARLYCON_MEM |
338 | def_bool y | 338 | def_bool y |
339 | 339 | ||
340 | config DYNAMIC_PHYSICAL_MASK | ||
341 | bool | ||
342 | |||
340 | config PGTABLE_LEVELS | 343 | config PGTABLE_LEVELS |
341 | int | 344 | int |
342 | default 5 if X86_5LEVEL | 345 | default 5 if X86_5LEVEL |
@@ -1508,6 +1511,7 @@ config ARCH_HAS_MEM_ENCRYPT | |||
1508 | config AMD_MEM_ENCRYPT | 1511 | config AMD_MEM_ENCRYPT |
1509 | bool "AMD Secure Memory Encryption (SME) support" | 1512 | bool "AMD Secure Memory Encryption (SME) support" |
1510 | depends on X86_64 && CPU_SUP_AMD | 1513 | depends on X86_64 && CPU_SUP_AMD |
1514 | select DYNAMIC_PHYSICAL_MASK | ||
1511 | ---help--- | 1515 | ---help--- |
1512 | Say yes to enable support for the encryption of system memory. | 1516 | Say yes to enable support for the encryption of system memory. |
1513 | This requires an AMD processor that supports Secure Memory | 1517 | This requires an AMD processor that supports Secure Memory |
diff --git a/arch/x86/boot/compressed/kaslr_64.c b/arch/x86/boot/compressed/kaslr_64.c index 522d11431433..748456c365f4 100644 --- a/arch/x86/boot/compressed/kaslr_64.c +++ b/arch/x86/boot/compressed/kaslr_64.c | |||
@@ -69,6 +69,8 @@ static struct alloc_pgt_data pgt_data; | |||
69 | /* The top level page table entry pointer. */ | 69 | /* The top level page table entry pointer. */ |
70 | static unsigned long top_level_pgt; | 70 | static unsigned long top_level_pgt; |
71 | 71 | ||
72 | phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; | ||
73 | |||
72 | /* | 74 | /* |
73 | * Mapping information structure passed to kernel_ident_mapping_init(). | 75 | * Mapping information structure passed to kernel_ident_mapping_init(). |
74 | * Due to relocation, pointers must be assigned at run time not build time. | 76 | * Due to relocation, pointers must be assigned at run time not build time. |
@@ -81,6 +83,9 @@ void initialize_identity_maps(void) | |||
81 | /* If running as an SEV guest, the encryption mask is required. */ | 83 | /* If running as an SEV guest, the encryption mask is required. */ |
82 | set_sev_encryption_mask(); | 84 | set_sev_encryption_mask(); |
83 | 85 | ||
86 | /* Exclude the encryption mask from __PHYSICAL_MASK */ | ||
87 | physical_mask &= ~sme_me_mask; | ||
88 | |||
84 | /* Init mapping_info with run-time function/buffer pointers. */ | 89 | /* Init mapping_info with run-time function/buffer pointers. */ |
85 | mapping_info.alloc_pgt_page = alloc_pgt_page; | 90 | mapping_info.alloc_pgt_page = alloc_pgt_page; |
86 | mapping_info.context = &pgt_data; | 91 | mapping_info.context = &pgt_data; |
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 1e53560a84bb..c85e15010f48 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) | 17 | #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) |
18 | #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) | 18 | #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) |
19 | 19 | ||
20 | #define __PHYSICAL_MASK ((phys_addr_t)(__sme_clr((1ULL << __PHYSICAL_MASK_SHIFT) - 1))) | ||
21 | #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) | 20 | #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) |
22 | 21 | ||
23 | /* Cast *PAGE_MASK to a signed type so that it is sign-extended if | 22 | /* Cast *PAGE_MASK to a signed type so that it is sign-extended if |
@@ -55,6 +54,13 @@ | |||
55 | 54 | ||
56 | #ifndef __ASSEMBLY__ | 55 | #ifndef __ASSEMBLY__ |
57 | 56 | ||
57 | #ifdef CONFIG_DYNAMIC_PHYSICAL_MASK | ||
58 | extern phys_addr_t physical_mask; | ||
59 | #define __PHYSICAL_MASK physical_mask | ||
60 | #else | ||
61 | #define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1)) | ||
62 | #endif | ||
63 | |||
58 | extern int devmem_is_allowed(unsigned long pagenr); | 64 | extern int devmem_is_allowed(unsigned long pagenr); |
59 | 65 | ||
60 | extern unsigned long max_low_pfn_mapped; | 66 | extern unsigned long max_low_pfn_mapped; |
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index 1b2197d13832..7ae36868aed2 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c | |||
@@ -527,6 +527,7 @@ void __init sme_enable(struct boot_params *bp) | |||
527 | /* SEV state cannot be controlled by a command line option */ | 527 | /* SEV state cannot be controlled by a command line option */ |
528 | sme_me_mask = me_mask; | 528 | sme_me_mask = me_mask; |
529 | sev_enabled = true; | 529 | sev_enabled = true; |
530 | physical_mask &= ~sme_me_mask; | ||
530 | return; | 531 | return; |
531 | } | 532 | } |
532 | 533 | ||
@@ -561,4 +562,6 @@ void __init sme_enable(struct boot_params *bp) | |||
561 | sme_me_mask = 0; | 562 | sme_me_mask = 0; |
562 | else | 563 | else |
563 | sme_me_mask = active_by_default ? me_mask : 0; | 564 | sme_me_mask = active_by_default ? me_mask : 0; |
565 | |||
566 | physical_mask &= ~sme_me_mask; | ||
564 | } | 567 | } |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index ffc8c13c50e4..3ca59cf7a7f9 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
@@ -8,6 +8,11 @@ | |||
8 | #include <asm/fixmap.h> | 8 | #include <asm/fixmap.h> |
9 | #include <asm/mtrr.h> | 9 | #include <asm/mtrr.h> |
10 | 10 | ||
11 | #ifdef CONFIG_DYNAMIC_PHYSICAL_MASK | ||
12 | phys_addr_t physical_mask __ro_after_init = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; | ||
13 | EXPORT_SYMBOL(physical_mask); | ||
14 | #endif | ||
15 | |||
11 | #define PGALLOC_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO) | 16 | #define PGALLOC_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO) |
12 | 17 | ||
13 | #ifdef CONFIG_HIGHPTE | 18 | #ifdef CONFIG_HIGHPTE |