Laszlo, Reviewed-by: Michael Kinney <michael.d.kin...@intel.com>
Mike > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Laszlo > Ersek > Sent: Tuesday, November 3, 2015 1:01 PM > To: edk2-de...@ml01.01.org > Cc: Paolo Bonzini <pbonz...@redhat.com> > Subject: [edk2] [PATCH v4 22/41] OvmfPkg: SmmCpuFeaturesLib: implement SMRAM > state save map access > > From: Paolo Bonzini <pbonz...@redhat.com> > > This implementation copies SMRAM state save map access from the > PiSmmCpuDxeSmm module. > > The most notable change is: > > - dropping support for EFI_SMM_SAVE_STATE_REGISTER_IO > > - changing the implementation of EFI_SMM_SAVE_STATE_REGISTER_LMA to use > the SMM revision id instead of a local variable (which > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c initializes from CPUID's LM > bit). This accounts for QEMU's implementation of x86_64, which always > uses revision 0x20064 even if the LM bit is zero. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > [ler...@redhat.com: reflow commit message & fix typo, convert patch to > CRLF] > Cc: Paolo Bonzini <pbonz...@redhat.com> > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Laszlo Ersek <ler...@redhat.com> > --- > > Notes: > v3: > - new in v3 > > OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | 2 + > OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c | 377 > +++++++++++++++++++- > 2 files changed, 376 insertions(+), 3 deletions(-) > > diff --git a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf > b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf > index 656dd08..594d85b 100644 > --- a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf > +++ b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf > @@ -31,5 +31,7 @@ [Packages] > > [LibraryClasses] > BaseLib > + BaseMemoryLib > PcdLib > DebugLib > + SmmServicesTableLib > diff --git a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c > b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c > index 078ea96..bd825b4 100644 > --- a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c > +++ b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c > @@ -15,11 +15,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > #include <PiSmm.h> > #include <Library/SmmCpuFeaturesLib.h> > #include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > #include <Library/PcdLib.h> > #include <Library/MemoryAllocationLib.h> > +#include <Library/SmmServicesTableLib.h> > #include <Library/DebugLib.h> > #include <Register/SmramSaveStateMap.h> > > +// > +// EFER register LMA bit > +// > +#define LMA BIT10 > + > /** > The constructor function > > @@ -125,7 +132,35 @@ SmmCpuFeaturesHookReturnFromSmm ( > IN UINT64 NewInstructionPointer > ) > { > - return 0; > + UINT64 OriginalInstructionPointer; > + SMRAM_SAVE_STATE_MAP *CpuSaveState = (SMRAM_SAVE_STATE_MAP *)CpuState; > + > + if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) { > + OriginalInstructionPointer = (UINT64)CpuSaveState->x86._EIP; > + CpuSaveState->x86._EIP = (UINT32)NewInstructionPointer; > + // > + // Clear the auto HALT restart flag so the RSM instruction returns > + // program control to the instruction following the HLT instruction. > + // > + if ((CpuSaveState->x86.AutoHALTRestart & BIT0) != 0) { > + CpuSaveState->x86.AutoHALTRestart &= ~BIT0; > + } > + } else { > + OriginalInstructionPointer = CpuSaveState->x64._RIP; > + if ((CpuSaveState->x64.IA32_EFER & LMA) == 0) { > + CpuSaveState->x64._RIP = (UINT32)NewInstructionPointer32; > + } else { > + CpuSaveState->x64._RIP = (UINT32)NewInstructionPointer; > + } > + // > + // Clear the auto HALT restart flag so the RSM instruction returns > + // program control to the instruction following the HLT instruction. > + // > + if ((CpuSaveState->x64.AutoHALTRestart & BIT0) != 0) { > + CpuSaveState->x64.AutoHALTRestart &= ~BIT0; > + } > + } > + return OriginalInstructionPointer; > } > > /** > @@ -356,6 +391,213 @@ SmmCpuFeaturesSetSmmRegister ( > ASSERT (FALSE); > } > > +/// > +/// Macro used to simplify the lookup table entries of type > CPU_SMM_SAVE_STATE_LOOKUP_ENTRY > +/// > +#define SMM_CPU_OFFSET(Field) OFFSET_OF (SMRAM_SAVE_STATE_MAP, Field) > + > +/// > +/// Macro used to simplify the lookup table entries of type > CPU_SMM_SAVE_STATE_REGISTER_RANGE > +/// > +#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1 } > + > +/// > +/// Structure used to describe a range of registers > +/// > +typedef struct { > + EFI_SMM_SAVE_STATE_REGISTER Start; > + EFI_SMM_SAVE_STATE_REGISTER End; > + UINTN Length; > +} CPU_SMM_SAVE_STATE_REGISTER_RANGE; > + > +/// > +/// Structure used to build a lookup table to retrieve the widths and offsets > +/// associated with each supported EFI_SMM_SAVE_STATE_REGISTER value > +/// > + > +#define SMM_SAVE_STATE_REGISTER_FIRST_INDEX 1 > + > +typedef struct { > + UINT8 Width32; > + UINT8 Width64; > + UINT16 Offset32; > + UINT16 Offset64Lo; > + UINT16 Offset64Hi; > + BOOLEAN Writeable; > +} CPU_SMM_SAVE_STATE_LOOKUP_ENTRY; > + > +/// > +/// Table used by GetRegisterIndex() to convert an > EFI_SMM_SAVE_STATE_REGISTER > +/// value to an index into a table of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY > +/// > +static CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmCpuRegisterRanges[] = { > + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE, > EFI_SMM_SAVE_STATE_REGISTER_LDTINFO), > + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES, > EFI_SMM_SAVE_STATE_REGISTER_RIP), > + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, > EFI_SMM_SAVE_STATE_REGISTER_CR4), > + { (EFI_SMM_SAVE_STATE_REGISTER)0, (EFI_SMM_SAVE_STATE_REGISTER)0, 0 } > +}; > + > +/// > +/// Lookup table used to retrieve the widths and offsets associated with each > +/// supported EFI_SMM_SAVE_STATE_REGISTER value > +/// > +static CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmCpuWidthOffset[] = { > + {0, 0, 0, 0, 0, FALSE}, > // Reserved > + > + // > + // CPU Save State registers defined in PI SMM CPU Protocol. > + // > + {0, 8, 0 , SMM_CPU_OFFSET (x64.GdtBaseLoDword) > , SMM_CPU_OFFSET (x64.GdtBaseHiDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_GDTBASE = 4 > + {0, 8, 0 , SMM_CPU_OFFSET (x64.IdtBaseLoDword) > , SMM_CPU_OFFSET (x64.IdtBaseHiDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_IDTBASE = 5 > + {0, 8, 0 , SMM_CPU_OFFSET (x64.LdtBaseLoDword) > , SMM_CPU_OFFSET (x64.LdtBaseHiDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_LDTBASE = 6 > + {0, 0, 0 , 0 > , 0 , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7 > + {0, 0, 0 , 0 > , 0 , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8 > + {0, 0, 0 , 0 > , 0 , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9 > + {0, 0, 0 , 0 > , 0 , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_LDTINFO = 10 > + > + {4, 4, SMM_CPU_OFFSET (x86._ES) , SMM_CPU_OFFSET (x64._ES) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_ES = 20 > + {4, 4, SMM_CPU_OFFSET (x86._CS) , SMM_CPU_OFFSET (x64._CS) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_CS = 21 > + {4, 4, SMM_CPU_OFFSET (x86._SS) , SMM_CPU_OFFSET (x64._SS) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_SS = 22 > + {4, 4, SMM_CPU_OFFSET (x86._DS) , SMM_CPU_OFFSET (x64._DS) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_DS = 23 > + {4, 4, SMM_CPU_OFFSET (x86._FS) , SMM_CPU_OFFSET (x64._FS) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_FS = 24 > + {4, 4, SMM_CPU_OFFSET (x86._GS) , SMM_CPU_OFFSET (x64._GS) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_GS = 25 > + {0, 4, 0 , SMM_CPU_OFFSET (x64._LDTR) , 0 > , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL > = 26 > + {4, 4, SMM_CPU_OFFSET (x86._TR) , SMM_CPU_OFFSET (x64._TR) , 0 > , FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_TR_SEL = 27 > + {4, 8, SMM_CPU_OFFSET (x86._DR7) , SMM_CPU_OFFSET (x64._DR7) , > SMM_CPU_OFFSET (x64._DR7) + 4, FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_DR7 = 28 > + {4, 8, SMM_CPU_OFFSET (x86._DR6) , SMM_CPU_OFFSET (x64._DR6) , > SMM_CPU_OFFSET (x64._DR6) + 4, FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_DR6 = 29 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R8) , > SMM_CPU_OFFSET (x64._R8) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R8 = 30 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R9) , > SMM_CPU_OFFSET (x64._R9) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R9 = 31 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R10) , > SMM_CPU_OFFSET (x64._R10) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R10 = 32 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R11) , > SMM_CPU_OFFSET (x64._R11) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R11 = 33 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R12) , > SMM_CPU_OFFSET (x64._R12) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R12 = 34 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R13) , > SMM_CPU_OFFSET (x64._R13) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R13 = 35 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R14) , > SMM_CPU_OFFSET (x64._R14) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R14 = 36 > + {0, 8, 0 , SMM_CPU_OFFSET (x64._R15) , > SMM_CPU_OFFSET (x64._R15) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_R15 = 37 > + {4, 8, SMM_CPU_OFFSET (x86._EAX) , SMM_CPU_OFFSET (x64._RAX) , > SMM_CPU_OFFSET (x64._RAX) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RAX = 38 > + {4, 8, SMM_CPU_OFFSET (x86._EBX) , SMM_CPU_OFFSET (x64._RBX) , > SMM_CPU_OFFSET (x64._RBX) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RBX = 39 > + {4, 8, SMM_CPU_OFFSET (x86._ECX) , SMM_CPU_OFFSET (x64._RCX) , > SMM_CPU_OFFSET (x64._RCX) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RCX = 40 > + {4, 8, SMM_CPU_OFFSET (x86._EDX) , SMM_CPU_OFFSET (x64._RDX) , > SMM_CPU_OFFSET (x64._RDX) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RDX = 41 > + {4, 8, SMM_CPU_OFFSET (x86._ESP) , SMM_CPU_OFFSET (x64._RSP) , > SMM_CPU_OFFSET (x64._RSP) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RSP = 42 > + {4, 8, SMM_CPU_OFFSET (x86._EBP) , SMM_CPU_OFFSET (x64._RBP) , > SMM_CPU_OFFSET (x64._RBP) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RBP = 43 > + {4, 8, SMM_CPU_OFFSET (x86._ESI) , SMM_CPU_OFFSET (x64._RSI) , > SMM_CPU_OFFSET (x64._RSI) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RSI = 44 > + {4, 8, SMM_CPU_OFFSET (x86._EDI) , SMM_CPU_OFFSET (x64._RDI) , > SMM_CPU_OFFSET (x64._RDI) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RDI = 45 > + {4, 8, SMM_CPU_OFFSET (x86._EIP) , SMM_CPU_OFFSET (x64._RIP) , > SMM_CPU_OFFSET (x64._RIP) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RIP = 46 > + > + {4, 8, SMM_CPU_OFFSET (x86._EFLAGS) , SMM_CPU_OFFSET (x64._RFLAGS) , > SMM_CPU_OFFSET (x64._RFLAGS) + 4, TRUE }, // > EFI_SMM_SAVE_STATE_REGISTER_RFLAGS = 51 > + {4, 8, SMM_CPU_OFFSET (x86._CR0) , SMM_CPU_OFFSET (x64._CR0) , > SMM_CPU_OFFSET (x64._CR0) + 4, FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_CR0 = 52 > + {4, 8, SMM_CPU_OFFSET (x86._CR3) , SMM_CPU_OFFSET (x64._CR3) , > SMM_CPU_OFFSET (x64._CR3) + 4, FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_CR3 = 53 > + {0, 4, 0 , SMM_CPU_OFFSET (x64._CR4) , 0 > , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR4 > = 54 > +}; > + > +// > +// No support for I/O restart > +// > + > +/** > + Read information from the CPU save state. > + > + @param Register Specifies the CPU register to read form the save state. > + > + @retval 0 Register is not valid > + @retval >0 Index into mSmmCpuWidthOffset[] associated with Register > + > +**/ > +static UINTN > +GetRegisterIndex ( > + IN EFI_SMM_SAVE_STATE_REGISTER Register > + ) > +{ > + UINTN Index; > + UINTN Offset; > + > + for (Index = 0, Offset = SMM_SAVE_STATE_REGISTER_FIRST_INDEX; > mSmmCpuRegisterRanges[Index].Length != 0; Index++) { > + if (Register >= mSmmCpuRegisterRanges[Index].Start && Register <= > mSmmCpuRegisterRanges[Index].End) { > + return Register - mSmmCpuRegisterRanges[Index].Start + Offset; > + } > + Offset += mSmmCpuRegisterRanges[Index].Length; > + } > + return 0; > +} > + > +/** > + Read a CPU Save State register on the target processor. > + > + This function abstracts the differences that whether the CPU Save State > register is in the > + IA32 CPU Save State Map or X64 CPU Save State Map. > + > + This function supports reading a CPU Save State register in SMBase > relocation handler. > + > + @param[in] CpuIndex Specifies the zero-based index of the CPU save > state. > + @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table. > + @param[in] Width The number of bytes to read from the CPU save > state. > + @param[out] Buffer Upon return, this holds the CPU register value > read from the save state. > + > + @retval EFI_SUCCESS The register was read from Save State. > + @retval EFI_NOT_FOUND The register is not defined for the Save > State of Processor. > + @retval EFI_INVALID_PARAMTER This or Buffer is NULL. > + > +**/ > +static EFI_STATUS > +ReadSaveStateRegisterByIndex ( > + IN UINTN CpuIndex, > + IN UINTN RegisterIndex, > + IN UINTN Width, > + OUT VOID *Buffer > + ) > +{ > + SMRAM_SAVE_STATE_MAP *CpuSaveState; > + > + CpuSaveState = gSmst->CpuSaveState[CpuIndex]; > + > + if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) { > + // > + // If 32-bit mode width is zero, then the specified register can not be > accessed > + // > + if (mSmmCpuWidthOffset[RegisterIndex].Width32 == 0) { > + return EFI_NOT_FOUND; > + } > + > + // > + // If Width is bigger than the 32-bit mode width, then the specified > register can not be accessed > + // > + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width32) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Write return buffer > + // > + ASSERT(CpuSaveState != NULL); > + CopyMem(Buffer, (UINT8 *)CpuSaveState + > mSmmCpuWidthOffset[RegisterIndex].Offset32, Width); > + } else { > + // > + // If 64-bit mode width is zero, then the specified register can not be > accessed > + // > + if (mSmmCpuWidthOffset[RegisterIndex].Width64 == 0) { > + return EFI_NOT_FOUND; > + } > + > + // > + // If Width is bigger than the 64-bit mode width, then the specified > register can not be accessed > + // > + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width64) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Write lower 32-bits of return buffer > + // > + CopyMem(Buffer, (UINT8 *)CpuSaveState + > mSmmCpuWidthOffset[RegisterIndex].Offset64Lo, MIN(4, Width)); > + if (Width >= 4) { > + // > + // Write upper 32-bits of return buffer > + // > + CopyMem((UINT8 *)Buffer + 4, (UINT8 *)CpuSaveState + > mSmmCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4); > + } > + } > + return EFI_SUCCESS; > +} > + > /** > Read an SMM Save State register on the target processor. If this function > returns EFI_UNSUPPORTED, then the caller is responsible for reading the > @@ -383,7 +625,52 @@ SmmCpuFeaturesReadSaveStateRegister ( > OUT VOID *Buffer > ) > { > - return EFI_UNSUPPORTED; > + UINTN RegisterIndex; > + SMRAM_SAVE_STATE_MAP *CpuSaveState; > + > + // > + // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA > + // > + if (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) { > + // > + // Only byte access is supported for this register > + // > + if (Width != 1) { > + return EFI_INVALID_PARAMETER; > + } > + > + CpuSaveState = gSmst->CpuSaveState[CpuIndex]; > + > + // > + // Check CPU mode > + // > + if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) { > + *(UINT8 *)Buffer = 32; > + } else { > + *(UINT8 *)Buffer = 64; > + } > + > + return EFI_SUCCESS; > + } > + > + // > + // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO > + // > + if (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) { > + return EFI_NOT_FOUND; > + } > + > + // > + // Convert Register to a register lookup table index. Let > + // PiSmmCpuDxeSmm implement other special registers (currently > + // there is only EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID). > + // > + RegisterIndex = GetRegisterIndex (Register); > + if (RegisterIndex == 0) { > + return Register < EFI_SMM_SAVE_STATE_REGISTER_IO ? EFI_NOT_FOUND : > EFI_UNSUPPORTED; > + } > + > + return ReadSaveStateRegisterByIndex (CpuIndex, RegisterIndex, Width, > Buffer); > } > > /** > @@ -411,5 +698,89 @@ SmmCpuFeaturesWriteSaveStateRegister ( > IN CONST VOID *Buffer > ) > { > - return EFI_UNSUPPORTED; > + UINTN RegisterIndex; > + SMRAM_SAVE_STATE_MAP *CpuSaveState; > + > + // > + // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored > + // > + if (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) { > + return EFI_SUCCESS; > + } > + > + // > + // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported > + // > + if (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) { > + return EFI_NOT_FOUND; > + } > + > + // > + // Convert Register to a register lookup table index. Let > + // PiSmmCpuDxeSmm implement other special registers (currently > + // there is only EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID). > + // > + RegisterIndex = GetRegisterIndex (Register); > + if (RegisterIndex == 0) { > + return Register < EFI_SMM_SAVE_STATE_REGISTER_IO ? EFI_NOT_FOUND : > EFI_UNSUPPORTED; > + } > + > + CpuSaveState = gSmst->CpuSaveState[CpuIndex]; > + > + // > + // Do not write non-writable SaveState, because it will cause exception. > + // > + if (!mSmmCpuWidthOffset[RegisterIndex].Writeable) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Check CPU mode > + // > + if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) { > + // > + // If 32-bit mode width is zero, then the specified register can not be > accessed > + // > + if (mSmmCpuWidthOffset[RegisterIndex].Width32 == 0) { > + return EFI_NOT_FOUND; > + } > + > + // > + // If Width is bigger than the 32-bit mode width, then the specified > register can not be accessed > + // > + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width32) { > + return EFI_INVALID_PARAMETER; > + } > + // > + // Write SMM State register > + // > + ASSERT (CpuSaveState != NULL); > + CopyMem((UINT8 *)CpuSaveState + > mSmmCpuWidthOffset[RegisterIndex].Offset32, Buffer, Width); > + } else { > + // > + // If 64-bit mode width is zero, then the specified register can not be > accessed > + // > + if (mSmmCpuWidthOffset[RegisterIndex].Width64 == 0) { > + return EFI_NOT_FOUND; > + } > + > + // > + // If Width is bigger than the 64-bit mode width, then the specified > register can not be accessed > + // > + if (Width > mSmmCpuWidthOffset[RegisterIndex].Width64) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Write lower 32-bits of SMM State register > + // > + CopyMem((UINT8 *)CpuSaveState + > mSmmCpuWidthOffset[RegisterIndex].Offset64Lo, Buffer, MIN (4, Width)); > + if (Width >= 4) { > + // > + // Write upper 32-bits of SMM State register > + // > + CopyMem((UINT8 *)CpuSaveState + > mSmmCpuWidthOffset[RegisterIndex].Offset64Hi, (UINT8 *)Buffer + 4, Width - 4); > + } > + } > + return EFI_SUCCESS; > } > -- > 1.8.3.1 > > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel