~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/kernel/sev_verify_cbit.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  *      sev_verify_cbit.S - Code for verification of the C-bit position reported
  4  *                          by the Hypervisor when running with SEV enabled.
  5  *
  6  *      Copyright (c) 2020  Joerg Roedel (jroedel@suse.de)
  7  *
  8  * sev_verify_cbit() is called before switching to a new long-mode page-table
  9  * at boot.
 10  *
 11  * Verify that the C-bit position is correct by writing a random value to
 12  * an encrypted memory location while on the current page-table. Then it
 13  * switches to the new page-table to verify the memory content is still the
 14  * same. After that it switches back to the current page-table and when the
 15  * check succeeded it returns. If the check failed the code invalidates the
 16  * stack pointer and goes into a hlt loop. The stack-pointer is invalidated to
 17  * make sure no interrupt or exception can get the CPU out of the hlt loop.
 18  *
 19  * New page-table pointer is expected in %rdi (first parameter)
 20  *
 21  */
 22 SYM_FUNC_START(sev_verify_cbit)
 23 #ifdef CONFIG_AMD_MEM_ENCRYPT
 24         /* First check if a C-bit was detected */
 25         movq    sme_me_mask(%rip), %rsi
 26         testq   %rsi, %rsi
 27         jz      3f
 28 
 29         /* sme_me_mask != 0 could mean SME or SEV - Check also for SEV */
 30         movq    sev_status(%rip), %rsi
 31         testq   %rsi, %rsi
 32         jz      3f
 33 
 34         /* Save CR4 in %rsi */
 35         movq    %cr4, %rsi
 36 
 37         /* Disable Global Pages */
 38         movq    %rsi, %rdx
 39         andq    $(~X86_CR4_PGE), %rdx
 40         movq    %rdx, %cr4
 41 
 42         /*
 43          * Verified that running under SEV - now get a random value using
 44          * RDRAND. This instruction is mandatory when running as an SEV guest.
 45          *
 46          * Don't bail out of the loop if RDRAND returns errors. It is better to
 47          * prevent forward progress than to work with a non-random value here.
 48          */
 49 1:      rdrand  %rdx
 50         jnc     1b
 51 
 52         /* Store value to memory and keep it in %rdx */
 53         movq    %rdx, sev_check_data(%rip)
 54 
 55         /* Backup current %cr3 value to restore it later */
 56         movq    %cr3, %rcx
 57 
 58         /* Switch to new %cr3 - This might unmap the stack */
 59         movq    %rdi, %cr3
 60 
 61         /*
 62          * Compare value in %rdx with memory location. If C-bit is incorrect
 63          * this would read the encrypted data and make the check fail.
 64          */
 65         cmpq    %rdx, sev_check_data(%rip)
 66 
 67         /* Restore old %cr3 */
 68         movq    %rcx, %cr3
 69 
 70         /* Restore previous CR4 */
 71         movq    %rsi, %cr4
 72 
 73         /* Check CMPQ result */
 74         je      3f
 75 
 76         /*
 77          * The check failed, prevent any forward progress to prevent ROP
 78          * attacks, invalidate the stack and go into a hlt loop.
 79          */
 80         xorl    %esp, %esp
 81         subq    $0x1000, %rsp
 82 2:      hlt
 83         jmp 2b
 84 3:
 85 #endif
 86         /* Return page-table pointer */
 87         movq    %rdi, %rax
 88         RET
 89 SYM_FUNC_END(sev_verify_cbit)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php