[edk2-devel] [PATCH V2 4/4] OvmfPkg/ResetVector: Update ResetVector to support Tdx
Lendacky, Thomas via groups.io
thomas.lendacky=amd.com at groups.io
Thu Jul 22 17:07:49 UTC 2021
On 7/22/21 12:52 AM, Min Xu wrote:
> RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429
>
> 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 very beginning of ResetVector. It will check the 32-bit protected
> mode or 16-bit real mode, then jump to the corresponding entry point.
> This is done in OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm.
>
> ReloadFlat32.asm load the GDT and set the CR0, then jump to Flat-32 mode.
>
> InitTdx.asm is called to record the Tdx signature ('TDXG') and other tdx
> information in a TDX_WORK_AREA which can be used by the other routines in
> ResetVector.
>
> Init32.asm is 32-bit initialization code in OvmfPkg. It puts above
> ReloadFlat32 and InitTdx together to do the initializaiton for Tdx.
>
> After that Tdx jumps to 64-bit long mode by doing following tasks:
> 1. SetCr3ForPageTables64
> For OVMF, some initial page tables is built at:
> PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000)
> This page table supports the 4-level page table.
> But Tdx support 4-level and 5-level page table based on the CPU GPA width.
> 48bit is 4-level paging, 52-bit is 5-level paging.
> If 5-level page table is supported (GPAW is 52), then a top level
> page directory pointers (1 * 256TB entry) is generated in the
> TdxPageTable.
> 2. Set Cr4
> Enable PAE.
> 3. Adjust Cr3
> If GPAW is 48, then Cr3 is PT_ADDR (0). If GPAW is 52, then Cr3 is
> TDX_PT_ADDR (0).
>
> Tdx MailBox [0x10, 0x800] is reserved for OS. So we initialize piece of this
> area ([0x10, 0x20]) to record the Tdx flag ('TDXG') and other Tdx info so that
> they can be used in the following flow.
>
> After all above is successfully done, Tdx jump to SecEntry.
>
> Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
> Cc: Brijesh Singh <brijesh.singh at amd.com>
> Cc: Erdem Aktas <erdemaktas at google.com>
> Cc: James Bottomley <jejb at linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao at intel.com>
> Cc: Tom Lendacky <thomas.lendacky at amd.com>
> Signed-off-by: Min Xu <min.m.xu at intel.com>
> ---
> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 21 ++++++++
> OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 47 ++++++++++++++++
> OvmfPkg/ResetVector/Ia32/Init32.asm | 34 ++++++++++++
> OvmfPkg/ResetVector/Ia32/InitTdx.asm | 57 ++++++++++++++++++++
> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 41 ++++++++++++++
> OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm | 44 +++++++++++++++
> OvmfPkg/ResetVector/ResetVector.nasmb | 18 +++++++
> 7 files changed, 262 insertions(+)
> create mode 100644 OvmfPkg/ResetVector/Ia32/Init32.asm
> create mode 100644 OvmfPkg/ResetVector/Ia32/InitTdx.asm
> create mode 100644 OvmfPkg/ResetVector/Ia32/ReloadFlat32.asm
>
> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> index ac86ce69ebe8..a390ed81d021 100644
> --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> @@ -155,10 +155,31 @@ resetVector:
> ;
> ; This is where the processor will begin execution
> ;
> +; In IA32 we follow the standard reset vector flow. While in X64, Td guest
> +; may be supported. Td guest requires the startup mode to be 32-bit
> +; protected mode but the legacy VM startup mode is 16-bit real mode.
> +; To make NASM generate such shared entry code that behaves correctly in
> +; both 16-bit and 32-bit mode, more BITS directives are added.
> +;
> +%ifdef ARCH_IA32
> +
> nop
> nop
> jmp EarlyBspInitReal16
>
> +%else
> +
> + smsw ax
> + test al, 1
> + jz .Real
> +BITS 32
> + jmp Main32
> +BITS 16
> +.Real:
> + jmp EarlyBspInitReal16
> +
> +%endif
> +
> ALIGN 16
>
> fourGigabytes:
> diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm
> index c6d0d898bcd1..2206ca719593 100644
> --- a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm
> +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm
> @@ -17,6 +17,9 @@ Transition32FlatTo64Flat:
>
> OneTimeCall SetCr3ForPageTables64
>
> + cmp dword[TDX_WORK_AREA], 0x47584454 ; 'TDXG'
> + jz TdxTransition32FlatTo64Flat
> +
Is the memory area guaranteed to be zeroed for legacy guests? Hopefully,
this won't trip up a non-TDX guest with a false match (highly unlikely,
though).
> mov eax, cr4
> bts eax, 5 ; enable PAE
> mov cr4, eax
> @@ -65,10 +68,54 @@ EnablePaging:
> bts eax, 31 ; set PG
> mov cr0, eax ; enable paging
>
> + jmp _jumpTo64Bit
> +
> +;
> +; Tdx Transition from 32Flat to 64Flat
> +;
> +TdxTransition32FlatTo64Flat:
> +
> + mov eax, cr4
> + bts eax, 5 ; enable PAE
> +
> + ;
> + ; byte[TDX_WORK_AREA_PAGELEVEL5] holds the indicator whether 52bit is supported.
> + ; if it is the case, need to set LA57 and use 5-level paging
> + ;
> + cmp byte[TDX_WORK_AREA_PAGELEVEL5], 0
> + jz .set_cr4
> + bts eax, 12
> +.set_cr4:
> + mov cr4, eax
> + mov ebx, cr3
> +
> + ;
> + ; if la57 is not set, we are ok
> + ; if using 5-level paging, adjust top-level page directory
> + ;
> + bt eax, 12
> + jnc .set_cr3
> + mov ebx, TDX_PT_ADDR (0)
> +.set_cr3:
> + mov cr3, ebx
> +
> + mov eax, cr0
> + bts eax, 31 ; set PG
> + mov cr0, eax ; enable paging
If you clear ebx here...
> +
> +_jumpTo64Bit:
> jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere)
> +
> BITS 64
> jumpTo64BitAndLandHere:
>
> + ;
> + ; For Td guest we are done and jump to the end
> + ;
> + mov eax, TDX_WORK_AREA
> + cmp dword [eax], 0x47584454 ; 'TDXG'
> + jz GoodCompare
> +
... you can remove these instructions. You'll jump to InsnCompare and that
check should succeed, right?
Thanks,
Tom
> ;
> ; Check if the second step of the SEV-ES mitigation is to be performed.
> ;
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#78104): https://edk2.groups.io/g/devel/message/78104
Mute This Topic: https://groups.io/mt/84373830/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list