From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web12.21190.1628769444911593052 for ; Thu, 12 Aug 2021 04:57:44 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: min.m.xu@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10073"; a="215322209" X-IronPort-AV: E=Sophos;i="5.84,315,1620716400"; d="scan'208";a="215322209" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2021 04:57:43 -0700 X-IronPort-AV: E=Sophos;i="5.84,315,1620716400"; d="scan'208";a="517433665" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.175.248]) by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2021 04:57:41 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Eric Dong , Ray Ni , Rahul Kumar , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky Subject: [PATCH 08/23] UefiCpuPkg: Support TDX in BaseXApicX2ApicLib Date: Thu, 12 Aug 2021 19:56:47 +0800 Message-Id: <2285a62534d0ec4e19051d1ee9236fea7d87ed9e.1628767741.git.min.m.xu@intel.com> X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 MSR is accessed in BaseXApicX2ApicLib. In TDX some MSRs are accessed directly from/to CPU. Some should be accessed via explicit requests from the host VMM using TDCALL(TDG.VP.VMCALL). This is done by the help of TdxLib. Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Signed-off-by: Min Xu --- .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 172 +++++++++++++++++- .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf | 2 + UefiCpuPkg/UefiCpuPkg.dsc | 2 + 3 files changed, 168 insertions(+), 8 deletions(-) diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index cdcbca046191..793ea61b50fa 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -23,11 +23,166 @@ #include #include #include +#include +#include +#include // // Library internal functions // +/** + Some MSRs in TDX are directly read/write from/to CPU. + + @param MsrIndex Index of the MSR + @retval TRUE MSR direct read/write from/to CPU. + @retval FALSE MSR not direct read/write from/to CPU. + +**/ +BOOLEAN +EFIAPI +AccessMsrNative ( + IN UINT32 MsrIndex + ) +{ + switch (MsrIndex) { + case MSR_IA32_X2APIC_TPR: + case MSR_IA32_X2APIC_PPR: + case MSR_IA32_X2APIC_EOI: + case MSR_IA32_X2APIC_ISR0: + case MSR_IA32_X2APIC_ISR1: + case MSR_IA32_X2APIC_ISR2: + case MSR_IA32_X2APIC_ISR3: + case MSR_IA32_X2APIC_ISR4: + case MSR_IA32_X2APIC_ISR5: + case MSR_IA32_X2APIC_ISR6: + case MSR_IA32_X2APIC_ISR7: + case MSR_IA32_X2APIC_TMR0: + case MSR_IA32_X2APIC_TMR1: + case MSR_IA32_X2APIC_TMR2: + case MSR_IA32_X2APIC_TMR3: + case MSR_IA32_X2APIC_TMR4: + case MSR_IA32_X2APIC_TMR5: + case MSR_IA32_X2APIC_TMR6: + case MSR_IA32_X2APIC_TMR7: + case MSR_IA32_X2APIC_IRR0: + case MSR_IA32_X2APIC_IRR1: + case MSR_IA32_X2APIC_IRR2: + case MSR_IA32_X2APIC_IRR3: + case MSR_IA32_X2APIC_IRR4: + case MSR_IA32_X2APIC_IRR5: + case MSR_IA32_X2APIC_IRR6: + case MSR_IA32_X2APIC_IRR7: + return TRUE; + default: + break; + } + return FALSE; +} + +/** + Read MSR value. + + @param MsrIndex Index of the MSR to read + @retval 64-bit Value of MSR. + +**/ +UINT64 +EFIAPI +ReadMsrReg64 ( + IN UINT32 MsrIndex + ) +{ + UINT64 Val; + UINT64 Status; + if (!AccessMsrNative (MsrIndex) && TdxIsEnabled ()) { + Status = TdVmCall (TDVMCALL_RDMSR, (UINT64) MsrIndex, 0, 0, 0, &Val); + if (Status != 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + } else { + Val = AsmReadMsr64 (MsrIndex); + } + return Val; +} + +/** + Write to MSR. + + @param MsrIndex Index of the MSR to write to + @param Val Value to be written to the MSR + +**/ +VOID +EFIAPI +WriteMsrReg64 ( + IN UINT32 MsrIndex, + IN UINT64 Val + ) +{ + UINT64 Status; + if (!AccessMsrNative (MsrIndex) && TdxIsEnabled ()) { + Status = TdVmCall (TDVMCALL_WRMSR, (UINT64) MsrIndex, Val, 0, 0, 0); + if (Status != 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + } else { + AsmWriteMsr64 (MsrIndex, Val); + } +} + +/** + Read MSR value. + + @param MsrIndex Index of the MSR to read + @retval 32-bit Value of MSR. + +**/ +UINT32 +EFIAPI +ReadMsrReg32 ( + IN UINT32 MsrIndex + ) +{ + UINT64 Val; + UINT64 Status; + if (!AccessMsrNative (MsrIndex) && TdxIsEnabled ()) { + Status = TdVmCall (TDVMCALL_RDMSR, (UINT64) MsrIndex, 0, 0, 0, &Val); + if (Status != 0) { + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + } else { + Val = AsmReadMsr32 (MsrIndex); + } + return (UINT32)(UINTN) Val; +} + +/** + Write to MSR. + + @param MsrIndex Index of the MSR to write to + @param Val Value to be written to the MSR + +**/ +VOID +EFIAPI +WriteMsrReg32 ( + IN UINT32 MsrIndex, + IN UINT32 Val + ) +{ + UINT64 Status; + if (!AccessMsrNative (MsrIndex) && TdxIsEnabled ()) { + Status = TdVmCall (TDVMCALL_WRMSR, (UINT64) MsrIndex, (UINT64) Val, 0, 0, 0); + if (Status != 0) { + DEBUG((DEBUG_ERROR, "WriteMsrReg32 returned failure. Status=0x%llx\n", Status)); + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + } + } else { + AsmWriteMsr32 (MsrIndex, Val); + } +} + /** Determine if the CPU supports the Local APIC Base Address MSR. @@ -77,7 +232,7 @@ GetLocalApicBaseAddress ( return PcdGet32 (PcdCpuLocalApicBaseAddress); } - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Uint64 = ReadMsrReg64 (MSR_IA32_APIC_BASE); return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHi, 32)) + (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12); @@ -108,12 +263,12 @@ SetLocalApicBaseAddress ( return; } - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Uint64 = ReadMsrReg64 (MSR_IA32_APIC_BASE); ApicBaseMsr.Bits.ApicBase = (UINT32) (BaseAddress >> 12); ApicBaseMsr.Bits.ApicBaseHi = (UINT32) (RShiftU64((UINT64) BaseAddress, 32)); - AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + WriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); } /** @@ -153,7 +308,7 @@ ReadLocalApicReg ( ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET); MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS; - return AsmReadMsr32 (MsrIndex); + return ReadMsrReg32 (MsrIndex); } } @@ -202,7 +357,7 @@ WriteLocalApicReg ( // Use memory fence here to force the serializing semantics to be consisent with xAPIC mode. // MemoryFence (); - AsmWriteMsr32 (MsrIndex, Value); + WriteMsrReg32 (MsrIndex, Value); } } @@ -309,7 +464,7 @@ GetApicMode ( return LOCAL_APIC_MODE_XAPIC; } - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Uint64 = ReadMsrReg64 (MSR_IA32_APIC_BASE); // // Local APIC should have been enabled // @@ -350,13 +505,14 @@ SetApicMode ( CurrentMode = GetApicMode (); if (CurrentMode == LOCAL_APIC_MODE_XAPIC) { + switch (ApicMode) { case LOCAL_APIC_MODE_XAPIC: break; case LOCAL_APIC_MODE_X2APIC: - ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); + ApicBaseMsr.Uint64 = ReadMsrReg64 (MSR_IA32_APIC_BASE); ApicBaseMsr.Bits.EXTD = 1; - AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + WriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); break; default: ASSERT (FALSE); diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf index 1e2a4f8b790f..2367a3349008 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf @@ -39,6 +39,8 @@ IoLib PcdLib UefiCpuLib + TdxLib + TdxProbeLib [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 699c91626bd8..47768b10d5be 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -61,6 +61,8 @@ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf + TdxProbeLib|MdePkg/Library/TdxProbeLib/TdxProbeLib.inf + TdxLib|MdePkg/Library/TdxLib/TdxLib.inf [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf -- 2.29.2.windows.2