Test/FrmPkg: Fix the boot failure if guest OS has kernel 4.12 or newer.

Kernel 4.12 reads MSR 0x140, MSR_XEON_PHI_MISC_FEATURE_ENABLES_REGISTER
and it causes CPU hang if CPU is in VMM mode.

Solution: Set MsrBitmap to 1 and set the corresponding bits in
mGuestContextCommon.MsrBitmap. Make VMM service the MSR read/write
requests only if the MSR handler is  defined in MsrHandler.c.

Testing: Verified pass with Minnowboard max.
This commit is contained in:
Tsung Ho Wu 2018-12-12 17:03:48 -08:00
parent 2696e3dc80
commit 5d982b52d3
2 changed files with 50 additions and 2 deletions

View File

@ -413,6 +413,47 @@ InitGuestVmcs (
return ; return ;
} }
#define MSR_READ 1
#define MSR_WRITE 2
VOID
EnableMsrInterception (
UINT8 *bitmap, UINT32 msr_arg, UINT8 mode
)
{
UINT8 *read_map;
UINT8 *write_map;
UINT32 msr = msr_arg;
UINT8 msr_bit;
UINT32 msr_index;
/* low MSR */
if (msr < 0x1FFFU) {
read_map = bitmap;
write_map = bitmap + 2048;
} else if ((msr >= 0xc0000000U) && (msr <= 0xc0001fffU)) {
read_map = bitmap + 1024;
write_map = bitmap + 3072;
} else {
return;
}
msr &= 0x1FFFU;
msr_bit = 1U << (msr & 0x7U);
msr_index = msr >> 3U;
if ((mode & MSR_READ) == MSR_READ) {
read_map[msr_index] |= msr_bit;
} else {
read_map[msr_index] &= ~msr_bit;
}
if ((mode & MSR_WRITE) == MSR_WRITE) {
write_map[msr_index] |= msr_bit;
} else {
write_map[msr_index] &= ~msr_bit;
}
}
/** /**
This function initialize guest common context. This function initialize guest common context.
@ -432,7 +473,14 @@ InitGuestContextCommon (
mGuestContextCommon.CompatiblePageTablePae = CreateCompatiblePageTablePae (); mGuestContextCommon.CompatiblePageTablePae = CreateCompatiblePageTablePae ();
mGuestContextCommon.MsrBitmap = (UINT64)(UINTN)AllocatePages (1); mGuestContextCommon.MsrBitmap = (UINT64)(UINTN)AllocatePages (1);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_EFER_MSR_INDEX, MSR_WRITE|MSR_READ);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_SYSENTER_CS_MSR_INDEX, MSR_WRITE|MSR_READ);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_SYSENTER_ESP_MSR_INDEX, MSR_WRITE|MSR_READ);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_SYSENTER_EIP_MSR_INDEX, MSR_WRITE|MSR_READ);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_FS_BASE_MSR_INDEX, MSR_WRITE|MSR_READ);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_GS_BASE_MSR_INDEX, MSR_WRITE|MSR_READ);
EnableMsrInterception( (UINT8*)mGuestContextCommon.MsrBitmap, IA32_BIOS_UPDT_TRIG_MSR_INDEX, MSR_WRITE);
EptInit (); EptInit ();
IoInit (); IoInit ();

View File

@ -84,7 +84,7 @@ SetVmcsControlField (
ProcessorBasedCtrls.Bits.InterruptWindow = 0; // interrupt window ProcessorBasedCtrls.Bits.InterruptWindow = 0; // interrupt window
ProcessorBasedCtrls.Bits.NmiWindow = 0; ProcessorBasedCtrls.Bits.NmiWindow = 0;
ProcessorBasedCtrls.Bits.IoBitmap = 1; ProcessorBasedCtrls.Bits.IoBitmap = 1;
ProcessorBasedCtrls.Bits.MsrBitmap = 0; ProcessorBasedCtrls.Bits.MsrBitmap = 1;
ProcessorBasedCtrls.Bits.SecondaryControl = 1; ProcessorBasedCtrls.Bits.SecondaryControl = 1;
Data64 = AsmReadMsr64 (IA32_VMX_PROCBASED_CTLS2_MSR_INDEX); Data64 = AsmReadMsr64 (IA32_VMX_PROCBASED_CTLS2_MSR_INDEX);