]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg: Support TDX in BaseXApicX2ApicLib
authorMin Xu <min.m.xu@intel.com>
Mon, 19 Jul 2021 05:50:40 +0000 (13:50 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 2 Apr 2022 08:15:12 +0000 (08:15 +0000)
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.

Please refer to [TDX] Section 18.1
TDX: https://software.intel.com/content/dam/develop/external/us/en/
documents/tdx-module-1.0-public-spec-v0.931.pdf

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.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>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c

index aaa42ff8450b575e541a30ed373007aae9169196..2d17177df12b189600a3ebe3102c76d2d2f0804d 100644 (file)
 #include <Library/TimerLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/UefiCpuLib.h>\r
+#include <IndustryStandard/Tdx.h>\r
 \r
 //\r
 // Library internal functions\r
 //\r
 \r
+/**\r
+  Some MSRs in TDX are accessed via TdCall.\r
+  Some are directly read/write from/to CPU.\r
+\r
+  @param  MsrIndex  Index of the MSR\r
+  @retval TRUE      MSR accessed via TdCall.\r
+  @retval FALSE     MSR accessed not via TdCall.\r
+\r
+**/\r
+BOOLEAN\r
+AccessMsrTdxCall (\r
+  IN UINT32  MsrIndex\r
+  )\r
+{\r
+  if (!TdIsEnabled ()) {\r
+    return FALSE;\r
+  }\r
+\r
+  switch (MsrIndex) {\r
+    case MSR_IA32_X2APIC_TPR:\r
+    case MSR_IA32_X2APIC_PPR:\r
+    case MSR_IA32_X2APIC_EOI:\r
+    case MSR_IA32_X2APIC_ISR0:\r
+    case MSR_IA32_X2APIC_ISR1:\r
+    case MSR_IA32_X2APIC_ISR2:\r
+    case MSR_IA32_X2APIC_ISR3:\r
+    case MSR_IA32_X2APIC_ISR4:\r
+    case MSR_IA32_X2APIC_ISR5:\r
+    case MSR_IA32_X2APIC_ISR6:\r
+    case MSR_IA32_X2APIC_ISR7:\r
+    case MSR_IA32_X2APIC_TMR0:\r
+    case MSR_IA32_X2APIC_TMR1:\r
+    case MSR_IA32_X2APIC_TMR2:\r
+    case MSR_IA32_X2APIC_TMR3:\r
+    case MSR_IA32_X2APIC_TMR4:\r
+    case MSR_IA32_X2APIC_TMR5:\r
+    case MSR_IA32_X2APIC_TMR6:\r
+    case MSR_IA32_X2APIC_TMR7:\r
+    case MSR_IA32_X2APIC_IRR0:\r
+    case MSR_IA32_X2APIC_IRR1:\r
+    case MSR_IA32_X2APIC_IRR2:\r
+    case MSR_IA32_X2APIC_IRR3:\r
+    case MSR_IA32_X2APIC_IRR4:\r
+    case MSR_IA32_X2APIC_IRR5:\r
+    case MSR_IA32_X2APIC_IRR6:\r
+    case MSR_IA32_X2APIC_IRR7:\r
+      return FALSE;\r
+    default:\r
+      break;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Read MSR value.\r
+\r
+  @param  MsrIndex  Index of the MSR to read\r
+  @retval 64-bit    Value of MSR.\r
+\r
+**/\r
+UINT64\r
+LocalApicReadMsrReg64 (\r
+  IN UINT32  MsrIndex\r
+  )\r
+{\r
+  UINT64  Val;\r
+  UINT64  Status;\r
+\r
+  if (AccessMsrTdxCall (MsrIndex)) {\r
+    Status = TdVmCall (TDVMCALL_RDMSR, (UINT64)MsrIndex, 0, 0, 0, &Val);\r
+    if (Status != 0) {\r
+      TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);\r
+    }\r
+  } else {\r
+    Val = AsmReadMsr64 (MsrIndex);\r
+  }\r
+\r
+  return Val;\r
+}\r
+\r
+/**\r
+  Write to MSR.\r
+\r
+  @param  MsrIndex  Index of the MSR to write to\r
+  @param  Value     Value to be written to the MSR\r
+\r
+  @return Value\r
+\r
+**/\r
+UINT64\r
+LocalApicWriteMsrReg64 (\r
+  IN UINT32  MsrIndex,\r
+  IN UINT64  Value\r
+  )\r
+{\r
+  UINT64  Status;\r
+\r
+  if (AccessMsrTdxCall (MsrIndex)) {\r
+    Status = TdVmCall (TDVMCALL_WRMSR, (UINT64)MsrIndex, Value, 0, 0, 0);\r
+    if (Status != 0) {\r
+      TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);\r
+    }\r
+  } else {\r
+    AsmWriteMsr64 (MsrIndex, Value);\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+/**\r
+  Read MSR value.\r
+\r
+  @param  MsrIndex  Index of the MSR to read\r
+  @retval 32-bit    Value of MSR.\r
+\r
+**/\r
+UINT32\r
+LocalApicReadMsrReg32 (\r
+  IN UINT32  MsrIndex\r
+  )\r
+{\r
+  return (UINT32)LocalApicReadMsrReg64 (MsrIndex);\r
+}\r
+\r
+/**\r
+  Write to MSR.\r
+\r
+  @param  MsrIndex  Index of the MSR to write to\r
+  @param  Value     Value to be written to the MSR\r
+\r
+  @return Value\r
+\r
+**/\r
+UINT32\r
+LocalApicWriteMsrReg32 (\r
+  IN UINT32  MsrIndex,\r
+  IN UINT32  Value\r
+  )\r
+{\r
+  return (UINT32)LocalApicWriteMsrReg64 (MsrIndex, Value);\r
+}\r
+\r
 /**\r
   Determine if the CPU supports the Local APIC Base Address MSR.\r
 \r
@@ -78,7 +222,7 @@ GetLocalApicBaseAddress (
     return PcdGet32 (PcdCpuLocalApicBaseAddress);\r
   }\r
 \r
-  ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+  ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
 \r
   return (UINTN)(LShiftU64 ((UINT64)ApicBaseMsr.Bits.ApicBaseHi, 32)) +\r
          (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);\r
@@ -109,12 +253,12 @@ SetLocalApicBaseAddress (
     return;\r
   }\r
 \r
-  ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+  ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
 \r
   ApicBaseMsr.Bits.ApicBase   = (UINT32)(BaseAddress >> 12);\r
   ApicBaseMsr.Bits.ApicBaseHi = (UINT32)(RShiftU64 ((UINT64)BaseAddress, 32));\r
 \r
-  AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
+  LocalApicWriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
 }\r
 \r
 /**\r
@@ -154,7 +298,7 @@ ReadLocalApicReg (
     ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);\r
 \r
     MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;\r
-    return AsmReadMsr32 (MsrIndex);\r
+    return LocalApicReadMsrReg32 (MsrIndex);\r
   }\r
 }\r
 \r
@@ -203,7 +347,7 @@ WriteLocalApicReg (
     // Use memory fence here to force the serializing semantics to be consisent with xAPIC mode.\r
     //\r
     MemoryFence ();\r
-    AsmWriteMsr32 (MsrIndex, Value);\r
+    LocalApicWriteMsrReg32 (MsrIndex, Value);\r
   }\r
 }\r
 \r
@@ -309,7 +453,7 @@ GetApicMode (
     return LOCAL_APIC_MODE_XAPIC;\r
   }\r
 \r
-  ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+  ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
   //\r
   // Local APIC should have been enabled\r
   //\r
@@ -354,9 +498,9 @@ SetApicMode (
       case LOCAL_APIC_MODE_XAPIC:\r
         break;\r
       case LOCAL_APIC_MODE_X2APIC:\r
-        ApicBaseMsr.Uint64    = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+        ApicBaseMsr.Uint64    = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);\r
         ApicBaseMsr.Bits.EXTD = 1;\r
-        AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
+        LocalApicWriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
         break;\r
       default:\r
         ASSERT (FALSE);\r