mirror of
https://github.com/acidanthera/audk.git
synced 2025-08-18 08:08:09 +02:00
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 Intel's Trust Domain Extensions (Intel TDX) refers to an Intel technology that extends Virtual Machines Extensions (VMX) and Multi-Key Total Memory Encryption (MKTME) with a new kind of virutal machines guest called a Trust Domain (TD). A TD is desinged to run in a CPU mode that protects the confidentiality of TD memory contents and the TD's CPU state from other software, including the hosting Virtual-Machine Monitor (VMM), unless explicitly shared by the TD itself. Note: Intel TDX is only available on X64, so the Tdx related changes are in X64 path. In IA32 path, there may be null stub to make the build success. This patch includes below major changes. 1. Ia32/IntelTdx.asm IntelTdx.asm includes below routines used in ResetVector - IsTdx Check if the running system is Tdx guest. - InitTdxWorkarea It initialize the TDX_WORK_AREA. Because it is called by both BSP and APs and to avoid the race condition, only BSP can initialize the WORK_AREA. AP will wait until the field of TDX_WORK_AREA_PGTBL_READY is set. - ReloadFlat32 After reset all CPUs in TDX are initialized to 32-bit protected mode. But GDT register is not set. So this routine loads the GDT then jump to Flat 32 protected mode again. - InitTdx This routine wrap above 3 routines together to do Tdx initialization in ResetVector phase. - IsTdxEnabled It is a OneTimeCall to probe if TDX is enabled by checking the CC_WORK_AREA. - CheckTdxFeaturesBeforeBuildPagetables This routine is called to check if it is Non-TDX guest, TDX-Bsp or TDX-APs. Because in TDX guest all the initialization is done by BSP (including the page tables). APs should not build the tables. - TdxPostBuildPageTables It is called after Page Tables are built by BSP. byte[TDX_WORK_AREA_PGTBL_READY] is set by BSP to indicate APs can leave spin and go. 2. Ia32/PageTables64.asm As described above only the TDX BSP build the page tables. So PageTables64.asm is updated to make sure only TDX BSP build the PageTables. TDX APs will skip the page table building and set Cr3 directly. 3. Ia16/ResetVectorVtf0.asm In Tdx all CPUs "reset" to run on 32-bit protected mode with flat descriptor (paging disabled). But in Non-Td guest the initial state of CPUs is 16-bit real mode. To resolve this conflict, BITS 16/32 is used in the ResetVectorVtf0.asm. It checks the 32-bit protected mode or 16-bit real mode, then jump to the corresponding entry point. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Min Xu <min.m.xu@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
130 lines
4.1 KiB
NASM
130 lines
4.1 KiB
NASM
;------------------------------------------------------------------------------
|
|
; @file
|
|
; Transition from 32 bit flat protected mode into 64 bit flat protected mode
|
|
;
|
|
; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
; Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
|
|
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
BITS 32
|
|
|
|
;
|
|
; Modified: EAX, ECX, EDX
|
|
;
|
|
Transition32FlatTo64Flat:
|
|
|
|
OneTimeCall SetCr3ForPageTables64
|
|
|
|
mov eax, cr4
|
|
bts eax, 5 ; enable PAE
|
|
mov cr4, eax
|
|
|
|
;
|
|
; In TDX LME has already been set. So we're done and jump to enable
|
|
; paging directly if Tdx is enabled.
|
|
; EBX is cleared because in the later it will be used to check if
|
|
; the second step of the SEV-ES mitigation is to be performed.
|
|
;
|
|
xor ebx, ebx
|
|
OneTimeCall IsTdxEnabled
|
|
test eax, eax
|
|
jnz EnablePaging
|
|
|
|
mov ecx, 0xc0000080
|
|
rdmsr
|
|
bts eax, 8 ; set LME
|
|
wrmsr
|
|
|
|
;
|
|
; SEV-ES mitigation check support
|
|
;
|
|
xor ebx, ebx
|
|
|
|
cmp byte[SEV_ES_WORK_AREA], 0
|
|
jz EnablePaging
|
|
|
|
;
|
|
; SEV-ES is active, perform a quick sanity check against the reported
|
|
; encryption bit position. This is to help mitigate against attacks where
|
|
; the hypervisor reports an incorrect encryption bit position.
|
|
;
|
|
; This is the first step in a two step process. Before paging is enabled
|
|
; writes to memory are encrypted. Using the RDRAND instruction (available
|
|
; on all SEV capable processors), write 64-bits of random data to the
|
|
; SEV_ES_WORK_AREA and maintain the random data in registers (register
|
|
; state is protected under SEV-ES). This will be used in the second step.
|
|
;
|
|
RdRand1:
|
|
rdrand ecx
|
|
jnc RdRand1
|
|
mov dword[SEV_ES_WORK_AREA_RDRAND], ecx
|
|
RdRand2:
|
|
rdrand edx
|
|
jnc RdRand2
|
|
mov dword[SEV_ES_WORK_AREA_RDRAND + 4], edx
|
|
|
|
;
|
|
; Use EBX instead of the SEV_ES_WORK_AREA memory to determine whether to
|
|
; perform the second step.
|
|
;
|
|
mov ebx, 1
|
|
|
|
EnablePaging:
|
|
mov eax, cr0
|
|
bts eax, 31 ; set PG
|
|
mov cr0, eax ; enable paging
|
|
|
|
jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere)
|
|
BITS 64
|
|
jumpTo64BitAndLandHere:
|
|
|
|
;
|
|
; Check if the second step of the SEV-ES mitigation is to be performed.
|
|
;
|
|
test ebx, ebx
|
|
jz InsnCompare
|
|
|
|
;
|
|
; SEV-ES is active, perform the second step of the encryption bit postion
|
|
; mitigation check. The ECX and EDX register contain data from RDRAND that
|
|
; was stored to memory in encrypted form. If the encryption bit position is
|
|
; valid, the contents of ECX and EDX will match the memory location.
|
|
;
|
|
cmp dword[SEV_ES_WORK_AREA_RDRAND], ecx
|
|
jne SevEncBitHlt
|
|
cmp dword[SEV_ES_WORK_AREA_RDRAND + 4], edx
|
|
jne SevEncBitHlt
|
|
|
|
;
|
|
; If SEV or SEV-ES is active, perform a quick sanity check against
|
|
; the reported encryption bit position. This is to help mitigate
|
|
; against attacks where the hypervisor reports an incorrect encryption
|
|
; bit position. If SEV is not active, this check will always succeed.
|
|
;
|
|
; The cmp instruction compares the first four bytes of the cmp instruction
|
|
; itself (which will be read decrypted if SEV or SEV-ES is active and the
|
|
; encryption bit position is valid) against the immediate within the
|
|
; instruction (an instruction fetch is always decrypted correctly by
|
|
; hardware) based on RIP relative addressing.
|
|
;
|
|
InsnCompare:
|
|
cmp dword[rel InsnCompare], 0xFFF63D81
|
|
je GoodCompare
|
|
|
|
;
|
|
; The hypervisor provided an incorrect encryption bit position, do not
|
|
; proceed.
|
|
;
|
|
SevEncBitHlt:
|
|
cli
|
|
hlt
|
|
jmp SevEncBitHlt
|
|
|
|
GoodCompare:
|
|
debugShowPostCode POSTCODE_64BIT_MODE
|
|
|
|
OneTimeCallRet Transition32FlatTo64Flat
|
|
|