Skip to content

Commit aca20d5

Browse files
tlendackyIngo Molnar
authored andcommitted
x86/mm: Add support to make use of Secure Memory Encryption
Add support to check if SME has been enabled and if memory encryption should be activated (checking of command line option based on the configuration of the default state). If memory encryption is to be activated, then the encryption mask is set and the kernel is encrypted "in place." Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Dave Young <dyoung@redhat.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Larry Woodman <lwoodman@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Radim Krčmář <rkrcmar@redhat.com> Cc: Rik van Riel <riel@redhat.com> Cc: Toshimitsu Kani <toshi.kani@hpe.com> Cc: kasan-dev@googlegroups.com Cc: kvm@vger.kernel.org Cc: linux-arch@vger.kernel.org Cc: linux-doc@vger.kernel.org Cc: linux-efi@vger.kernel.org Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/5f0da2fd4cce63f556117549e2c89c170072209f.1500319216.git.thomas.lendacky@amd.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 7375ae3 commit aca20d5

File tree

3 files changed

+83
-5
lines changed

3 files changed

+83
-5
lines changed

arch/x86/include/asm/mem_encrypt.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include <linux/init.h>
1919

20+
#include <asm/bootparam.h>
21+
2022
#ifdef CONFIG_AMD_MEM_ENCRYPT
2123

2224
extern unsigned long sme_me_mask;
@@ -38,7 +40,7 @@ void __init sme_unmap_bootdata(char *real_mode_data);
3840
void __init sme_early_init(void);
3941

4042
void __init sme_encrypt_kernel(void);
41-
void __init sme_enable(void);
43+
void __init sme_enable(struct boot_params *bp);
4244

4345
/* Architecture __weak replacement functions */
4446
void __init mem_encrypt_init(void);
@@ -60,7 +62,7 @@ static inline void __init sme_unmap_bootdata(char *real_mode_data) { }
6062
static inline void __init sme_early_init(void) { }
6163

6264
static inline void __init sme_encrypt_kernel(void) { }
63-
static inline void __init sme_enable(void) { }
65+
static inline void __init sme_enable(struct boot_params *bp) { }
6466

6567
#endif /* CONFIG_AMD_MEM_ENCRYPT */
6668

arch/x86/kernel/head64.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ static void __head *fixup_pointer(void *ptr, unsigned long physaddr)
4545
return ptr - (void *)_text + (void *)physaddr;
4646
}
4747

48-
unsigned long __head __startup_64(unsigned long physaddr)
48+
unsigned long __head __startup_64(unsigned long physaddr,
49+
struct boot_params *bp)
4950
{
5051
unsigned long load_delta, *p;
5152
unsigned long pgtable_flags;
@@ -70,7 +71,7 @@ unsigned long __head __startup_64(unsigned long physaddr)
7071
for (;;);
7172

7273
/* Activate Secure Memory Encryption (SME) if supported and enabled */
73-
sme_enable();
74+
sme_enable(bp);
7475

7576
/* Include the SME encryption mask in the fixup value */
7677
load_delta += sme_get_me_mask();

arch/x86/mm/mem_encrypt.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/mm.h>
1616
#include <linux/dma-mapping.h>
1717
#include <linux/swiotlb.h>
18+
#include <linux/mem_encrypt.h>
1819

1920
#include <asm/tlbflush.h>
2021
#include <asm/fixmap.h>
@@ -23,6 +24,13 @@
2324
#include <asm/set_memory.h>
2425
#include <asm/cacheflush.h>
2526
#include <asm/sections.h>
27+
#include <asm/processor-flags.h>
28+
#include <asm/msr.h>
29+
#include <asm/cmdline.h>
30+
31+
static char sme_cmdline_arg[] __initdata = "mem_encrypt";
32+
static char sme_cmdline_on[] __initdata = "on";
33+
static char sme_cmdline_off[] __initdata = "off";
2634

2735
/*
2836
* Since SME related variables are set early in the boot process they must
@@ -190,6 +198,8 @@ void __init mem_encrypt_init(void)
190198

191199
/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
192200
swiotlb_update_mem_attributes();
201+
202+
pr_info("AMD Secure Memory Encryption (SME) active\n");
193203
}
194204

195205
void swiotlb_set_mem_attributes(void *vaddr, unsigned long size)
@@ -513,6 +523,71 @@ void __init sme_encrypt_kernel(void)
513523
native_write_cr3(__native_read_cr3());
514524
}
515525

516-
void __init sme_enable(void)
526+
void __init __nostackprotector sme_enable(struct boot_params *bp)
517527
{
528+
const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off;
529+
unsigned int eax, ebx, ecx, edx;
530+
bool active_by_default;
531+
unsigned long me_mask;
532+
char buffer[16];
533+
u64 msr;
534+
535+
/* Check for the SME support leaf */
536+
eax = 0x80000000;
537+
ecx = 0;
538+
native_cpuid(&eax, &ebx, &ecx, &edx);
539+
if (eax < 0x8000001f)
540+
return;
541+
542+
/*
543+
* Check for the SME feature:
544+
* CPUID Fn8000_001F[EAX] - Bit 0
545+
* Secure Memory Encryption support
546+
* CPUID Fn8000_001F[EBX] - Bits 5:0
547+
* Pagetable bit position used to indicate encryption
548+
*/
549+
eax = 0x8000001f;
550+
ecx = 0;
551+
native_cpuid(&eax, &ebx, &ecx, &edx);
552+
if (!(eax & 1))
553+
return;
554+
555+
me_mask = 1UL << (ebx & 0x3f);
556+
557+
/* Check if SME is enabled */
558+
msr = __rdmsr(MSR_K8_SYSCFG);
559+
if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT))
560+
return;
561+
562+
/*
563+
* Fixups have not been applied to phys_base yet and we're running
564+
* identity mapped, so we must obtain the address to the SME command
565+
* line argument data using rip-relative addressing.
566+
*/
567+
asm ("lea sme_cmdline_arg(%%rip), %0"
568+
: "=r" (cmdline_arg)
569+
: "p" (sme_cmdline_arg));
570+
asm ("lea sme_cmdline_on(%%rip), %0"
571+
: "=r" (cmdline_on)
572+
: "p" (sme_cmdline_on));
573+
asm ("lea sme_cmdline_off(%%rip), %0"
574+
: "=r" (cmdline_off)
575+
: "p" (sme_cmdline_off));
576+
577+
if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT))
578+
active_by_default = true;
579+
else
580+
active_by_default = false;
581+
582+
cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
583+
((u64)bp->ext_cmd_line_ptr << 32));
584+
585+
cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer));
586+
587+
if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
588+
sme_me_mask = me_mask;
589+
else if (!strncmp(buffer, cmdline_off, sizeof(buffer)))
590+
sme_me_mask = 0;
591+
else
592+
sme_me_mask = active_by_default ? me_mask : 0;
518593
}

0 commit comments

Comments
 (0)