|
15 | 15 | #include <linux/mm.h>
|
16 | 16 | #include <linux/dma-mapping.h>
|
17 | 17 | #include <linux/swiotlb.h>
|
| 18 | +#include <linux/mem_encrypt.h> |
18 | 19 |
|
19 | 20 | #include <asm/tlbflush.h>
|
20 | 21 | #include <asm/fixmap.h>
|
|
23 | 24 | #include <asm/set_memory.h>
|
24 | 25 | #include <asm/cacheflush.h>
|
25 | 26 | #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"; |
26 | 34 |
|
27 | 35 | /*
|
28 | 36 | * Since SME related variables are set early in the boot process they must
|
@@ -190,6 +198,8 @@ void __init mem_encrypt_init(void)
|
190 | 198 |
|
191 | 199 | /* Call into SWIOTLB to update the SWIOTLB DMA buffers */
|
192 | 200 | swiotlb_update_mem_attributes();
|
| 201 | + |
| 202 | + pr_info("AMD Secure Memory Encryption (SME) active\n"); |
193 | 203 | }
|
194 | 204 |
|
195 | 205 | void swiotlb_set_mem_attributes(void *vaddr, unsigned long size)
|
@@ -513,6 +523,71 @@ void __init sme_encrypt_kernel(void)
|
513 | 523 | native_write_cr3(__native_read_cr3());
|
514 | 524 | }
|
515 | 525 |
|
516 |
| -void __init sme_enable(void) |
| 526 | +void __init __nostackprotector sme_enable(struct boot_params *bp) |
517 | 527 | {
|
| 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; |
518 | 593 | }
|
0 commit comments