mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg: Support TDX in BaseXApicX2ApicLib
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>
This commit is contained in:
parent
3571fc906f
commit
7bed7ae6c5
|
@ -23,11 +23,155 @@
|
||||||
#include <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/UefiCpuLib.h>
|
#include <Library/UefiCpuLib.h>
|
||||||
|
#include <IndustryStandard/Tdx.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Library internal functions
|
// Library internal functions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
Some MSRs in TDX are accessed via TdCall.
|
||||||
|
Some are directly read/write from/to CPU.
|
||||||
|
|
||||||
|
@param MsrIndex Index of the MSR
|
||||||
|
@retval TRUE MSR accessed via TdCall.
|
||||||
|
@retval FALSE MSR accessed not via TdCall.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
AccessMsrTdxCall (
|
||||||
|
IN UINT32 MsrIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!TdIsEnabled ()) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 FALSE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read MSR value.
|
||||||
|
|
||||||
|
@param MsrIndex Index of the MSR to read
|
||||||
|
@retval 64-bit Value of MSR.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
LocalApicReadMsrReg64 (
|
||||||
|
IN UINT32 MsrIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 Val;
|
||||||
|
UINT64 Status;
|
||||||
|
|
||||||
|
if (AccessMsrTdxCall (MsrIndex)) {
|
||||||
|
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 Value Value to be written to the MSR
|
||||||
|
|
||||||
|
@return Value
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
LocalApicWriteMsrReg64 (
|
||||||
|
IN UINT32 MsrIndex,
|
||||||
|
IN UINT64 Value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 Status;
|
||||||
|
|
||||||
|
if (AccessMsrTdxCall (MsrIndex)) {
|
||||||
|
Status = TdVmCall (TDVMCALL_WRMSR, (UINT64)MsrIndex, Value, 0, 0, 0);
|
||||||
|
if (Status != 0) {
|
||||||
|
TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AsmWriteMsr64 (MsrIndex, Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read MSR value.
|
||||||
|
|
||||||
|
@param MsrIndex Index of the MSR to read
|
||||||
|
@retval 32-bit Value of MSR.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT32
|
||||||
|
LocalApicReadMsrReg32 (
|
||||||
|
IN UINT32 MsrIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (UINT32)LocalApicReadMsrReg64 (MsrIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write to MSR.
|
||||||
|
|
||||||
|
@param MsrIndex Index of the MSR to write to
|
||||||
|
@param Value Value to be written to the MSR
|
||||||
|
|
||||||
|
@return Value
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT32
|
||||||
|
LocalApicWriteMsrReg32 (
|
||||||
|
IN UINT32 MsrIndex,
|
||||||
|
IN UINT32 Value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (UINT32)LocalApicWriteMsrReg64 (MsrIndex, Value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Determine if the CPU supports the Local APIC Base Address MSR.
|
Determine if the CPU supports the Local APIC Base Address MSR.
|
||||||
|
|
||||||
|
@ -78,7 +222,7 @@ GetLocalApicBaseAddress (
|
||||||
return PcdGet32 (PcdCpuLocalApicBaseAddress);
|
return PcdGet32 (PcdCpuLocalApicBaseAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
|
ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);
|
||||||
|
|
||||||
return (UINTN)(LShiftU64 ((UINT64)ApicBaseMsr.Bits.ApicBaseHi, 32)) +
|
return (UINTN)(LShiftU64 ((UINT64)ApicBaseMsr.Bits.ApicBaseHi, 32)) +
|
||||||
(((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);
|
(((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);
|
||||||
|
@ -109,12 +253,12 @@ SetLocalApicBaseAddress (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
|
ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);
|
||||||
|
|
||||||
ApicBaseMsr.Bits.ApicBase = (UINT32)(BaseAddress >> 12);
|
ApicBaseMsr.Bits.ApicBase = (UINT32)(BaseAddress >> 12);
|
||||||
ApicBaseMsr.Bits.ApicBaseHi = (UINT32)(RShiftU64 ((UINT64)BaseAddress, 32));
|
ApicBaseMsr.Bits.ApicBaseHi = (UINT32)(RShiftU64 ((UINT64)BaseAddress, 32));
|
||||||
|
|
||||||
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
|
LocalApicWriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +298,7 @@ ReadLocalApicReg (
|
||||||
ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);
|
ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);
|
||||||
|
|
||||||
MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;
|
MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;
|
||||||
return AsmReadMsr32 (MsrIndex);
|
return LocalApicReadMsrReg32 (MsrIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +347,7 @@ WriteLocalApicReg (
|
||||||
// Use memory fence here to force the serializing semantics to be consisent with xAPIC mode.
|
// Use memory fence here to force the serializing semantics to be consisent with xAPIC mode.
|
||||||
//
|
//
|
||||||
MemoryFence ();
|
MemoryFence ();
|
||||||
AsmWriteMsr32 (MsrIndex, Value);
|
LocalApicWriteMsrReg32 (MsrIndex, Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +453,7 @@ GetApicMode (
|
||||||
return LOCAL_APIC_MODE_XAPIC;
|
return LOCAL_APIC_MODE_XAPIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
|
ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);
|
||||||
//
|
//
|
||||||
// Local APIC should have been enabled
|
// Local APIC should have been enabled
|
||||||
//
|
//
|
||||||
|
@ -354,9 +498,9 @@ SetApicMode (
|
||||||
case LOCAL_APIC_MODE_XAPIC:
|
case LOCAL_APIC_MODE_XAPIC:
|
||||||
break;
|
break;
|
||||||
case LOCAL_APIC_MODE_X2APIC:
|
case LOCAL_APIC_MODE_X2APIC:
|
||||||
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
|
ApicBaseMsr.Uint64 = LocalApicReadMsrReg64 (MSR_IA32_APIC_BASE);
|
||||||
ApicBaseMsr.Bits.EXTD = 1;
|
ApicBaseMsr.Bits.EXTD = 1;
|
||||||
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
|
LocalApicWriteMsrReg64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
|
|
Loading…
Reference in New Issue