-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
x86/boot: Add early boot support when running with SEV active
Early in the boot process, add checks to determine if the kernel is running with Secure Encrypted Virtualization (SEV) active. Checking for SEV requires checking that the kernel is running under a hypervisor (CPUID 0x00000001, bit 31), that the SEV feature is available (CPUID 0x8000001f, bit 1) and then checking a non-interceptable SEV MSR (0xc0010131, bit 0). This check is required so that during early compressed kernel booting the pagetables (both the boot pagetables and KASLR pagetables (if enabled) are updated to include the encryption mask so that when the kernel is decompressed into encrypted memory, it can boot properly. After the kernel is decompressed and continues booting the same logic is used to check if SEV is active and set a flag indicating so. This allows to distinguish between SME and SEV, each of which have unique differences in how certain things are handled: e.g. DMA (always bounce buffered with SEV) or EFI tables (always access decrypted with SME). Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Borislav Petkov <bp@suse.de> Tested-by: Borislav Petkov <bp@suse.de> Cc: Laura Abbott <labbott@redhat.com> Cc: Kees Cook <keescook@chromium.org> Cc: kvm@vger.kernel.org Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Radim Krčmář <rkrcmar@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Andy Lutomirski <luto@kernel.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Link: https://lkml.kernel.org/r/20171020143059.3291-13-brijesh.singh@amd.com
- Loading branch information
Tom Lendacky
authored and
Thomas Gleixner
committed
Nov 7, 2017
1 parent
d7b417f
commit 1958b5f
Showing
8 changed files
with
186 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* | ||
* AMD Memory Encryption Support | ||
* | ||
* Copyright (C) 2017 Advanced Micro Devices, Inc. | ||
* | ||
* Author: Tom Lendacky <thomas.lendacky@amd.com> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/linkage.h> | ||
|
||
#include <asm/processor-flags.h> | ||
#include <asm/msr.h> | ||
#include <asm/asm-offsets.h> | ||
|
||
.text | ||
.code32 | ||
ENTRY(get_sev_encryption_bit) | ||
xor %eax, %eax | ||
|
||
#ifdef CONFIG_AMD_MEM_ENCRYPT | ||
push %ebx | ||
push %ecx | ||
push %edx | ||
push %edi | ||
|
||
/* | ||
* RIP-relative addressing is needed to access the encryption bit | ||
* variable. Since we are running in 32-bit mode we need this call/pop | ||
* sequence to get the proper relative addressing. | ||
*/ | ||
call 1f | ||
1: popl %edi | ||
subl $1b, %edi | ||
|
||
movl enc_bit(%edi), %eax | ||
cmpl $0, %eax | ||
jge .Lsev_exit | ||
|
||
/* Check if running under a hypervisor */ | ||
movl $1, %eax | ||
cpuid | ||
bt $31, %ecx /* Check the hypervisor bit */ | ||
jnc .Lno_sev | ||
|
||
movl $0x80000000, %eax /* CPUID to check the highest leaf */ | ||
cpuid | ||
cmpl $0x8000001f, %eax /* See if 0x8000001f is available */ | ||
jb .Lno_sev | ||
|
||
/* | ||
* Check for the SEV feature: | ||
* CPUID Fn8000_001F[EAX] - Bit 1 | ||
* CPUID Fn8000_001F[EBX] - Bits 5:0 | ||
* Pagetable bit position used to indicate encryption | ||
*/ | ||
movl $0x8000001f, %eax | ||
cpuid | ||
bt $1, %eax /* Check if SEV is available */ | ||
jnc .Lno_sev | ||
|
||
movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ | ||
rdmsr | ||
bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */ | ||
jnc .Lno_sev | ||
|
||
movl %ebx, %eax | ||
andl $0x3f, %eax /* Return the encryption bit location */ | ||
movl %eax, enc_bit(%edi) | ||
jmp .Lsev_exit | ||
|
||
.Lno_sev: | ||
xor %eax, %eax | ||
movl %eax, enc_bit(%edi) | ||
|
||
.Lsev_exit: | ||
pop %edi | ||
pop %edx | ||
pop %ecx | ||
pop %ebx | ||
|
||
#endif /* CONFIG_AMD_MEM_ENCRYPT */ | ||
|
||
ret | ||
ENDPROC(get_sev_encryption_bit) | ||
|
||
.code64 | ||
ENTRY(get_sev_encryption_mask) | ||
xor %rax, %rax | ||
|
||
#ifdef CONFIG_AMD_MEM_ENCRYPT | ||
push %rbp | ||
push %rdx | ||
|
||
movq %rsp, %rbp /* Save current stack pointer */ | ||
|
||
call get_sev_encryption_bit /* Get the encryption bit position */ | ||
testl %eax, %eax | ||
jz .Lno_sev_mask | ||
|
||
xor %rdx, %rdx | ||
bts %rax, %rdx /* Create the encryption mask */ | ||
mov %rdx, %rax /* ... and return it */ | ||
|
||
.Lno_sev_mask: | ||
movq %rbp, %rsp /* Restore original stack pointer */ | ||
|
||
pop %rdx | ||
pop %rbp | ||
#endif | ||
|
||
ret | ||
ENDPROC(get_sev_encryption_mask) | ||
|
||
.data | ||
enc_bit: | ||
.int 0xffffffff |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,4 +109,6 @@ static inline void console_init(void) | |
{ } | ||
#endif | ||
|
||
unsigned long get_sev_encryption_mask(void); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters