![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 /* 0003 * sev_verify_cbit.S - Code for verification of the C-bit position reported 0004 * by the Hypervisor when running with SEV enabled. 0005 * 0006 * Copyright (c) 2020 Joerg Roedel (jroedel@suse.de) 0007 * 0008 * sev_verify_cbit() is called before switching to a new long-mode page-table 0009 * at boot. 0010 * 0011 * Verify that the C-bit position is correct by writing a random value to 0012 * an encrypted memory location while on the current page-table. Then it 0013 * switches to the new page-table to verify the memory content is still the 0014 * same. After that it switches back to the current page-table and when the 0015 * check succeeded it returns. If the check failed the code invalidates the 0016 * stack pointer and goes into a hlt loop. The stack-pointer is invalidated to 0017 * make sure no interrupt or exception can get the CPU out of the hlt loop. 0018 * 0019 * New page-table pointer is expected in %rdi (first parameter) 0020 * 0021 */ 0022 SYM_FUNC_START(sev_verify_cbit) 0023 #ifdef CONFIG_AMD_MEM_ENCRYPT 0024 /* First check if a C-bit was detected */ 0025 movq sme_me_mask(%rip), %rsi 0026 testq %rsi, %rsi 0027 jz 3f 0028 0029 /* sme_me_mask != 0 could mean SME or SEV - Check also for SEV */ 0030 movq sev_status(%rip), %rsi 0031 testq %rsi, %rsi 0032 jz 3f 0033 0034 /* Save CR4 in %rsi */ 0035 movq %cr4, %rsi 0036 0037 /* Disable Global Pages */ 0038 movq %rsi, %rdx 0039 andq $(~X86_CR4_PGE), %rdx 0040 movq %rdx, %cr4 0041 0042 /* 0043 * Verified that running under SEV - now get a random value using 0044 * RDRAND. This instruction is mandatory when running as an SEV guest. 0045 * 0046 * Don't bail out of the loop if RDRAND returns errors. It is better to 0047 * prevent forward progress than to work with a non-random value here. 0048 */ 0049 1: rdrand %rdx 0050 jnc 1b 0051 0052 /* Store value to memory and keep it in %rdx */ 0053 movq %rdx, sev_check_data(%rip) 0054 0055 /* Backup current %cr3 value to restore it later */ 0056 movq %cr3, %rcx 0057 0058 /* Switch to new %cr3 - This might unmap the stack */ 0059 movq %rdi, %cr3 0060 0061 /* 0062 * Compare value in %rdx with memory location. If C-bit is incorrect 0063 * this would read the encrypted data and make the check fail. 0064 */ 0065 cmpq %rdx, sev_check_data(%rip) 0066 0067 /* Restore old %cr3 */ 0068 movq %rcx, %cr3 0069 0070 /* Restore previous CR4 */ 0071 movq %rsi, %cr4 0072 0073 /* Check CMPQ result */ 0074 je 3f 0075 0076 /* 0077 * The check failed, prevent any forward progress to prevent ROP 0078 * attacks, invalidate the stack and go into a hlt loop. 0079 */ 0080 xorq %rsp, %rsp 0081 subq $0x1000, %rsp 0082 2: hlt 0083 jmp 2b 0084 3: 0085 #endif 0086 /* Return page-table pointer */ 0087 movq %rdi, %rax 0088 RET 0089 SYM_FUNC_END(sev_verify_cbit)
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |