From nobody Mon Feb 9 18:43:58 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+86808+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+86808+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1645324429; cv=none; d=zohomail.com; s=zohoarc; b=TXDbUUY/zmOYci+qs4HeU+CcU03VOorS+0eXJR8tQ7r3xAh0lO5hOejtTGJt2dN2VDklpt3Ydt5vXyk43mtNGh1zhFutolSvhVnlf4YOb9iGQJINGKQLq0KM0xUhYxMXkbIL2H532bT4CnxjqrP/oeVy9wJ3xISNQX0kceDFGys= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1645324429; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=7RKMg7mOwCrbcuRS/xDoTN/DSsuoj7FC1v22pLHi9/U=; b=HaEvvMzFiLaKW3mj+llJB/3UEO146jNWmuO3gcv3cS0yGEwdC7nHnqKgMih0yGxw5CksZq9ahRtokavm+vKPU9ZfdbEDA0wjIIdAZtaL5P1ekTYYy7mI1MyKs+WPMhfvxfFuLogxkSgnzpD1OWM0+KUjKK3dqkB7M7QcdG6tSh0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+86808+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 164532442913341.38569944611277; Sat, 19 Feb 2022 18:33:49 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id DAlkYY1788612x5gaWqAaRGj; Sat, 19 Feb 2022 18:33:48 -0800 X-Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web09.17717.1645324415382497262 for ; Sat, 19 Feb 2022 18:33:48 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10263"; a="231961733" X-IronPort-AV: E=Sophos;i="5.88,382,1635231600"; d="scan'208";a="231961733" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Feb 2022 18:33:47 -0800 X-IronPort-AV: E=Sophos;i="5.88,382,1635231600"; d="scan'208";a="705818727" X-Received: from wangz1-mobl.ccr.corp.intel.com (HELO mxu9-mobl1.ccr.corp.intel.com) ([10.255.31.171]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Feb 2022 18:33:45 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Michael D Kinney , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [edk2-devel] [PATCH V3 5/8] OvmfPkg/IntelTdx: Add Sec to bring up both Legacy and Tdx guest Date: Sun, 20 Feb 2022 10:33:16 +0800 Message-Id: <20220220023319.1495-6-min.m.xu@intel.com> In-Reply-To: <20220220023319.1495-1-min.m.xu@intel.com> References: <20220220023319.1495-1-min.m.xu@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: aimZkxg0fu6K5ntDaCx8abUbx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1645324428; bh=u0hBUNB7k8Qg7D/E5ddOSCNZ7crBjd0o3xvNyiOGwNo=; h=Cc:Date:From:Reply-To:Subject:To; b=shyTlegEMh2G3r3W5fVkmiDJYgFovDqp7Og5IRT0MKTMDD0sXjH9GimwRUxCgpC/SDg r/UL5vkbKHTHg1z42UE08NqzdVaZiqpgfOXj3G/rG0NRiGDjgxyX1jwDono2SuzPtZ9lL 497hAAyS5LN9XPPSpkCqh82FPpREX3t4EJE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1645324430392100002 Content-Type: text/plain; charset="utf-8" RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3429 OvmfPkg/IntelTdx/Sec is a simplied version of OvmfPkg/Sec. There are below differences between these 2 Sec - IntelTdx/Sec only supports Legacy guest and Tdx guest in X64. - IntelTdx/Sec calls TdxStartup () to jump from SEC to DXE directly. - IntelTdx/Sec uses MemoryAllocationLib / HobLib / PrePiLib in EmbeddedPkg. Cc: Michael D Kinney Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Signed-off-by: Min Xu Acked-by: Gerd Hoffmann --- OvmfPkg/IntelTdx/Sec/SecMain.c | 198 +++++++++++++++++++++++++ OvmfPkg/IntelTdx/Sec/SecMain.inf | 61 ++++++++ OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm | 151 +++++++++++++++++++ 3 files changed, 410 insertions(+) create mode 100644 OvmfPkg/IntelTdx/Sec/SecMain.c create mode 100644 OvmfPkg/IntelTdx/Sec/SecMain.inf create mode 100644 OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c new file mode 100644 index 000000000000..365d94d8620f --- /dev/null +++ b/OvmfPkg/IntelTdx/Sec/SecMain.c @@ -0,0 +1,198 @@ +/** @file + Main SEC phase code. Transitions to PEI. + + Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef struct _SEC_IDT_TABLE { + EFI_PEI_SERVICES *PeiService; + IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +// +// Template of an IDT entry pointing to 10:FFFFFFE4h. +// +IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate =3D { + { // Bits + 0xffe4, // OffsetLow + 0x10, // Selector + 0x0, // Reserved_0 + IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType + 0xffff // OffsetHigh + } +}; + +VOID +EFIAPI +SecCoreStartupWithStack ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, + IN VOID *TopOfCurrentStack + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + SEC_IDT_TABLE IdtTableInStack; + IA32_DESCRIPTOR IdtDescriptor; + UINT32 Index; + volatile UINT8 *Table; + + if (TdIsEnabled ()) { + // + // For Td guests, the memory map info is in TdHobLib. It should be pro= cessed + // first so that the memory is accepted. Otherwise access to the unacc= epted + // memory will trigger tripple fault. + // + if (ProcessTdxHobList () !=3D EFI_SUCCESS) { + CpuDeadLoop (); + } + } + + // + // To ensure SMM can't be compromised on S3 resume, we must force re-ini= t of + // the BaseExtractGuidedSectionLib. Since this is before library contruc= tors + // are called, we must use a loop rather than SetMem. + // + Table =3D (UINT8 *)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAdd= ress); + for (Index =3D 0; + Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize); + ++Index) + { + Table[Index] =3D 0; + } + + // + // Initialize IDT - Since this is before library constructors are called, + // we use a loop rather than CopyMem. + // + IdtTableInStack.PeiService =3D NULL; + + for (Index =3D 0; Index < SEC_IDT_ENTRY_COUNT; Index++) { + // + // Declare the local variables that actually move the data elements as + // volatile to prevent the optimizer from replacing this function with + // the intrinsic memcpy() + // + CONST UINT8 *Src; + volatile UINT8 *Dst; + UINTN Byte; + + Src =3D (CONST UINT8 *)&mIdtEntryTemplate; + Dst =3D (volatile UINT8 *)&IdtTableInStack.IdtTable[Index]; + + for (Byte =3D 0; Byte < sizeof (mIdtEntryTemplate); Byte++) { + Dst[Byte] =3D Src[Byte]; + } + } + + IdtDescriptor.Base =3D (UINTN)&IdtTableInStack.IdtTable; + IdtDescriptor.Limit =3D (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); + + ProcessLibraryConstructorList (NULL, NULL); + + // + // Load the IDTR. + // + AsmWriteIdtr (&IdtDescriptor); + + if (TdIsEnabled ()) { + // + // InitializeCpuExceptionHandlers () should be called in Td guests so = that + // #VE exceptions can be handled correctly. + // + InitializeCpuExceptionHandlers (NULL); + } + + DEBUG (( + DEBUG_INFO, + "SecCoreStartupWithStack(0x%x, 0x%x)\n", + (UINT32)(UINTN)BootFv, + (UINT32)(UINTN)TopOfCurrentStack + )); + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + // + // ASSERT that the Page Tables were set by the reset vector code to + // the address we expect. + // + ASSERT (AsmReadCr3 () =3D=3D (UINTN)PcdGet32 (PcdOvmfSecPageTablesBase)); + + // + // |-------------| <-- TopOfCurrentStack + // | Stack | 32k + // |-------------| + // | Heap | 32k + // |-------------| <-- SecCoreData.TemporaryRamBase + // + + ASSERT ( + (UINTN)(PcdGet32 (PcdOvmfSecPeiTempRamBase) + + PcdGet32 (PcdOvmfSecPeiTempRamSize)) =3D=3D + (UINTN)TopOfCurrentStack + ); + + // + // Initialize SEC hand-off state + // + SecCoreData.DataSize =3D sizeof (EFI_SEC_PEI_HAND_OFF); + + SecCoreData.TemporaryRamSize =3D (UINTN)PcdGet32 (PcdOvmfSecPeiTempRamSi= ze); + SecCoreData.TemporaryRamBase =3D (VOID *)((UINT8 *)TopOfCurrentStack - S= ecCoreData.TemporaryRamSize); + + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryRamBase + SecCor= eData.PeiTemporaryRamSize; + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >> 1; + + SecCoreData.BootFirmwareVolumeBase =3D BootFv; + SecCoreData.BootFirmwareVolumeSize =3D (UINTN)BootFv->FvLength; + + // + // Make sure the 8259 is masked before initializing the Debug Agent and = the debug timer is enabled + // + IoWrite8 (0x21, 0xff); + IoWrite8 (0xA1, 0xff); + + // + // Initialize Local APIC Timer hardware and disable Local APIC Timer + // interrupts before initializing the Debug Agent and the debug timer is + // enabled. + // + InitializeApicTimer (0, MAX_UINT32, TRUE, 5); + DisableApicTimerInterrupt (); + + TdxStartup (&SecCoreData); + + ASSERT (FALSE); + CpuDeadLoop (); +} diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.inf b/OvmfPkg/IntelTdx/Sec/SecMai= n.inf new file mode 100644 index 000000000000..d0441f869807 --- /dev/null +++ b/OvmfPkg/IntelTdx/Sec/SecMain.inf @@ -0,0 +1,61 @@ +## @file +# SEC Driver +# +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SecMain + FILE_GUID =3D 69d96630-eb64-4b33-8491-13a5cf023dcf + MODULE_TYPE =3D SEC + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D SecMain + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 +# + +[Sources] + SecMain.c + X64/SecEntry.nasm + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + OvmfPkg/OvmfPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + PcdLib + UefiCpuLib + DebugAgentLib + IoLib + PeCoffLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + ExtractGuidedSectionLib + LocalApicLib + MemEncryptSevLib + CpuExceptionHandlerLib + TdxStartupLib + PlatformInitLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress + gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase diff --git a/OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm b/OvmfPkg/IntelTdx/Sec/= X64/SecEntry.nasm new file mode 100644 index 000000000000..4528fec309a0 --- /dev/null +++ b/OvmfPkg/IntelTdx/Sec/X64/SecEntry.nasm @@ -0,0 +1,151 @@ +;-------------------------------------------------------------------------= ----- +;* +;* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+;* SPDX-License-Identifier: BSD-2-Clause-Patent +;* +;* CpuAsm.asm +;* +;* Abstract: +;* +;-------------------------------------------------------------------------= ----- + +#include +%include "TdxCommondefs.inc" + +DEFAULT REL +SECTION .text + +extern ASM_PFX(SecCoreStartupWithStack) + +%macro tdcall 0 + db 0x66, 0x0f, 0x01, 0xcc +%endmacro + +; +; SecCore Entry Point +; +; Processor is in flat protected mode +; +; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self= Test) +; @param[in] DI 'BP': boot-strap processor, or 'AP': application proce= ssor +; @param[in] RBP Pointer to the start of the Boot Firmware Volume +; @param[in] DS Selector allowing flat access to all addresses +; @param[in] ES Selector allowing flat access to all addresses +; @param[in] FS Selector allowing flat access to all addresses +; @param[in] GS Selector allowing flat access to all addresses +; @param[in] SS Selector allowing flat access to all addresses +; +; @return None This routine does not return +; +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + + ; + ; Guest type is stored in OVMF_WORK_AREA + ; + %define OVMF_WORK_AREA FixedPcdGet32 (PcdOvmfWorkAreaBase) + %define VM_GUEST_TYPE_TDX 2 + mov eax, OVMF_WORK_AREA + cmp byte[eax], VM_GUEST_TYPE_TDX + jne InitStack + + mov rax, TDCALL_TDINFO + tdcall + + ; + ; R8 [31:0] NUM_VCPUS + ; [63:32] MAX_VCPUS + ; R9 [31:0] VCPU_INDEX + ; Td Guest set the VCPU0 as the BSP, others are the APs + ; APs jump to spinloop and get released by DXE's MpInitLib + ; + mov rax, r9 + and rax, 0xffff + test rax, rax + jne ParkAp + +InitStack: + + ; + ; Fill the temporary RAM with the initial stack value. + ; The loop below will seed the heap as well, but that's harmless. + ; + mov rax, (FixedPcdGet32 (PcdInitValueInTempStack) << 32) | FixedPc= dGet32 (PcdInitValueInTempStack) + ; qword to s= tore + mov rdi, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) ; base addre= ss, + ; relative= to + ; ES + mov rcx, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) / 8 ; qword count + cld ; store from= base + ; up + rep stosq + + ; + ; Load temporary RAM stack based on PCDs + ; + %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + \ + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) + mov rsp, SEC_TOP_OF_STACK + nop + + ; + ; Setup parameters and call SecCoreStartupWithStack + ; rcx: BootFirmwareVolumePtr + ; rdx: TopOfCurrentStack + ; + mov rcx, rbp + mov rdx, rsp + sub rsp, 0x20 + call ASM_PFX(SecCoreStartupWithStack) + + ; + ; Note: BSP never gets here. APs will be unblocked by DXE + ; + ; R8 [31:0] NUM_VCPUS + ; [63:32] MAX_VCPUS + ; R9 [31:0] VCPU_INDEX + ; +ParkAp: + + mov rbp, r9 + +.do_wait_loop: + mov rsp, FixedPcdGet32 (PcdOvmfSecGhcbBackupBase) + + ; + ; register itself in [rsp + CpuArrivalOffset] + ; + mov rax, 1 + lock xadd dword [rsp + CpuArrivalOffset], eax + inc eax + +.check_arrival_cnt: + cmp eax, r8d + je .check_command + mov eax, dword[rsp + CpuArrivalOffset] + jmp .check_arrival_cnt + +.check_command: + mov eax, dword[rsp + CommandOffset] + cmp eax, MpProtectedModeWakeupCommandNoop + je .check_command + + cmp eax, MpProtectedModeWakeupCommandWakeup + je .do_wakeup + + ; Don't support this command, so ignore + jmp .check_command + +.do_wakeup: + ; + ; BSP sets these variables before unblocking APs + ; RAX: WakeupVectorOffset + ; RBX: Relocated mailbox address + ; RBP: vCpuId + ; + mov rax, 0 + mov eax, dword[rsp + WakeupVectorOffset] + mov rbx, [rsp + WakeupArgsRelocatedMailBox] + nop + jmp rax + jmp $ --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#86808): https://edk2.groups.io/g/devel/message/86808 Mute This Topic: https://groups.io/mt/89266119/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-