Skip to content

Commit aaac8f2

Browse files
suncepingmxu9
authored andcommitted
OvmfPkg: Add the ResetVector in TDX MailBox
Refer to the ACPI 6.6 changed, MADT table needs to provide the ResetVector address to OS and it should can make the AP to entry a state to check the mailbox. Signed-off-by: Ceping Sun <[email protected]> reviewed-by: Min Xu <[email protected]> tested-by: Kirill A. Shutemov <[email protected]>
1 parent 912c70b commit aaac8f2

File tree

5 files changed

+162
-5
lines changed

5 files changed

+162
-5
lines changed

OvmfPkg/Include/IndustryStandard/IntelTdx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct {
6161
typedef struct {
6262
UINT8 *RelocateApLoopFuncAddress;
6363
UINTN RelocateApLoopFuncSize;
64+
UINT8 *RelocateApResetVector;
6465
} MP_RELOCATION_MAP;
6566

6667
#pragma pack()

OvmfPkg/TdxDxe/TdxAcpiTable.c

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,46 @@
2828
#include <Uefi.h>
2929
#include <TdxAcpiTable.h>
3030

31+
32+
IA32_GDT mGdtEntries[] = {
33+
{
34+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
35+
}, /* 0x0: reserve */
36+
{
37+
{ 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }
38+
}, /* 0x8: compatibility mode */
39+
{
40+
{ 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0 }
41+
}, /* 0x10: for long mode */
42+
{
43+
{ 0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }
44+
}, /* 0x18: data */
45+
{
46+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
47+
}, /* 0x20: reserve */
48+
};
49+
50+
51+
/**
52+
At the beginning of ResetVector in OS, the GDT needs to be reloaded.
53+
**/
54+
VOID
55+
SetMailboxResetVectorGDT (
56+
VOID
57+
)
58+
{
59+
TDX_WORK_AREA *TdxWorkArea;
60+
61+
TdxWorkArea = (TDX_WORK_AREA *)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase);
62+
ASSERT (TdxWorkArea != NULL);
63+
ZeroMem ((VOID *)TdxWorkArea->MailboxGdt.Data, sizeof (TdxWorkArea->MailboxGdt.Data));
64+
65+
CopyMem((VOID *)TdxWorkArea->MailboxGdt.Data, (VOID *)mGdtEntries, sizeof(mGdtEntries));
66+
TdxWorkArea->MailboxGdt.Gdtr.Base = (UINTN)TdxWorkArea->MailboxGdt.Data;
67+
TdxWorkArea->MailboxGdt.Gdtr.Limit = sizeof (mGdtEntries) - 1;
68+
}
69+
70+
3171
/**
3272
At the beginning of system boot, a 4K-aligned, 4K-size memory (Td mailbox) is
3373
pre-allocated by host VMM. BSP & APs do the page accept together in that memory
@@ -37,12 +77,14 @@
3777
memory block which is allocated in the ACPI Nvs memory. APs are waken up and
3878
spin around the relocated mailbox for further command.
3979
80+
@param[in, out] ResetVector Pointer to the ResetVector
81+
4082
@return EFI_PHYSICAL_ADDRESS Address of the relocated mailbox
4183
**/
4284
EFI_PHYSICAL_ADDRESS
4385
EFIAPI
4486
RelocateMailbox (
45-
VOID
87+
EFI_PHYSICAL_ADDRESS *ResetVector
4688
)
4789
{
4890
EFI_PHYSICAL_ADDRESS Address;
@@ -92,6 +134,7 @@ RelocateMailbox (
92134
ApLoopFunc
93135
));
94136

137+
SetMailboxResetVectorGDT();
95138
//
96139
// Initialize mailbox
97140
//
@@ -115,6 +158,13 @@ RelocateMailbox (
115158
0
116159
);
117160

161+
*ResetVector = (UINT64)ApLoopFunc + (RelocationMap.RelocateApResetVector -
162+
RelocationMap.RelocateApLoopFuncAddress);
163+
DEBUG ((
164+
DEBUG_INFO,
165+
"Ap Relocation: reset_vector %llx\n",
166+
*ResetVector
167+
));
118168
return Address;
119169
}
120170

@@ -142,6 +192,7 @@ AlterAcpiTable (
142192
UINT8 *NewMadtTable;
143193
UINTN NewMadtTableLength;
144194
EFI_PHYSICAL_ADDRESS RelocateMailboxAddress;
195+
EFI_PHYSICAL_ADDRESS RelocateResetVector;
145196
EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE *MadtMpWk;
146197
EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader;
147198

@@ -155,7 +206,7 @@ AlterAcpiTable (
155206
return;
156207
}
157208

158-
RelocateMailboxAddress = RelocateMailbox ();
209+
RelocateMailboxAddress = RelocateMailbox (&RelocateResetVector);
159210
if (RelocateMailboxAddress == 0) {
160211
ASSERT (FALSE);
161212
DEBUG ((DEBUG_ERROR, "Failed to relocate Td mailbox\n"));
@@ -186,9 +237,10 @@ AlterAcpiTable (
186237
MadtMpWk = (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE *)(NewMadtTable + Table->Length);
187238
MadtMpWk->Type = EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP;
188239
MadtMpWk->Length = sizeof (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE);
189-
MadtMpWk->MailBoxVersion = 0;
240+
MadtMpWk->MailBoxVersion = 1;
190241
MadtMpWk->Reserved = 0;
191242
MadtMpWk->MailBoxAddress = RelocateMailboxAddress;
243+
MadtMpWk->ResetVector = RelocateResetVector;
192244

193245
Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, NewMadtTable, NewMadtTableLength, &NewTableKey);
194246
if (EFI_ERROR (Status)) {

OvmfPkg/TdxDxe/TdxAcpiTable.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <Library/UefiBootServicesTableLib.h>
1919
#include <Library/DebugLib.h>
2020
#include <Library/PcdLib.h>
21+
#include <WorkArea.h>
22+
2123
#include <IndustryStandard/IntelTdx.h>
2224
#include <IndustryStandard/Acpi.h>
2325

@@ -41,7 +43,7 @@ AsmGetRelocationMap (
4143
EFI_PHYSICAL_ADDRESS
4244
EFIAPI
4345
RelocateMailbox (
44-
VOID
46+
EFI_PHYSICAL_ADDRESS *ResetVector
4547
);
4648

4749
/**

OvmfPkg/TdxDxe/TdxDxe.inf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,7 @@
7171
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
7272
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
7373
gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
74+
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
75+
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
76+
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
77+
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize

OvmfPkg/TdxDxe/X64/ApRunLoop.nasm

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,18 @@
1616

1717
DEFAULT REL
1818

19+
SECTION .bss
20+
global STACK_BASE
21+
STACK_BASE:
22+
resb 1024
23+
STACK_TOP:
24+
1925
SECTION .text
2026

27+
%define TDX_WORK_AREA_MAILBOX_GDTR (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 128)
28+
29+
%define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
30+
2131
BITS 64
2232

2333
%define TDVMCALL_EXPOSE_REGS_MASK 0xffec
@@ -49,6 +59,7 @@ AsmRelocateApMailBoxLoopStart:
4959
test r10, r10
5060
jnz Panic
5161
mov r8, r15
62+
mov qword[rel mailbox_address], rbx
5263

5364
MailBoxLoop:
5465
; Spin until command set
@@ -81,6 +92,91 @@ MailBoxSleep:
8192
jmp $
8293
Panic:
8394
ud2
95+
96+
AsmRelocateApResetVector:
97+
98+
.prepareStack:
99+
; The stack can then be used to switch from long mode to compatibility mode
100+
mov rsp, STACK_TOP
101+
102+
.loadGDT:
103+
cli
104+
mov rax, TDX_WORK_AREA_MAILBOX_GDTR
105+
lgdt [rax]
106+
107+
.loadSwicthModeCode:
108+
mov rcx, dword 0x10 ; load long mode selector
109+
shl rcx, 32
110+
lea rdx, [LongMode] ; assume address < 4G
111+
or rcx, rdx
112+
push rcx
113+
114+
mov rcx, dword 0x08 ; load compatible mode selector
115+
shl rcx, 32
116+
lea rdx, [Compatible] ; assume address < 4G
117+
or rcx, rdx
118+
push rcx
119+
retf
120+
121+
BITS 32
122+
Compatible:
123+
mov eax, dword 0x18
124+
; ; reload DS/ES/SS to make sure they are correct referred to current GDT
125+
mov ds, ax
126+
mov es, ax
127+
mov ss, ax
128+
; reload the fs and gs
129+
mov fs, ax
130+
mov gs, ax
131+
132+
; Must clear the CR4.PCIDE before clearing paging
133+
mov ecx, cr4
134+
btc ecx, 17
135+
mov cr4, ecx
136+
;
137+
; Disable paging
138+
;
139+
mov ecx, cr0
140+
btc ecx, 31
141+
mov cr0, ecx
142+
;
143+
RestoreCr0:
144+
; Only enable PE(bit 0), NE(bit 5), ET(bit 4) 0x31
145+
mov eax, dword 0x31
146+
mov cr0, eax
147+
148+
149+
; Only Enable MCE(bit 6), VMXE(bit 13) 0x2040
150+
; TDX enforeced the VMXE = 1 and mask it in VMM, so not set it.
151+
RestoreCr4:
152+
mov eax, 0x40
153+
mov cr4, eax
154+
SetCr3:
155+
;
156+
; Can use the boot page tables since it's reserved
157+
158+
mov eax, PT_ADDR (0)
159+
mov cr3, eax
160+
161+
EnablePAE:
162+
mov eax, cr4
163+
bts eax, 5
164+
mov cr4, eax
165+
166+
EnablePaging:
167+
mov eax, cr0
168+
bts eax, 31 ; set PG
169+
mov cr0, eax ; enable paging
170+
; return to LongMode
171+
retf
172+
173+
BITS 64
174+
LongMode:
175+
mov rbx, qword[rel mailbox_address]
176+
jmp AsmRelocateApMailBoxLoopStart
177+
align 16
178+
mailbox_address:
179+
dq 0
84180
BITS 64
85181
AsmRelocateApMailBoxLoopEnd:
86182

@@ -89,8 +185,10 @@ AsmRelocateApMailBoxLoopEnd:
89185
;-------------------------------------------------------------------------------------
90186
global ASM_PFX(AsmGetRelocationMap)
91187
ASM_PFX(AsmGetRelocationMap):
188+
; mov byte[TDX_WORK_AREA_MB_PGTBL_READY], 0
92189
lea rax, [AsmRelocateApMailBoxLoopStart]
93190
mov qword [rcx], rax
94191
mov qword [rcx + 8h], AsmRelocateApMailBoxLoopEnd - AsmRelocateApMailBoxLoopStart
192+
lea rax, [AsmRelocateApResetVector]
193+
mov qword [rcx + 10h], rax
95194
ret
96-

0 commit comments

Comments
 (0)