From: Paolo Bonzini <pbonz...@redhat.com>

This adjusts the previously introduced state save map access functions, to
account for QEMU and KVM's 64-bit state save map following the AMD spec
rather than the Intel one.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
[ler...@redhat.com: reflow commit message, 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>
Reviewed-by: Michael Kinney <michael.d.kin...@intel.com>
---

Notes:
    v3:
    - new in v3

 OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf |   1 +
 OvmfPkg/Include/Register/QemuSmramSaveStateMap.h        | 184 
++++++++++++++++++++
 OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c   |  50 +++---
 3 files changed, 212 insertions(+), 23 deletions(-)

diff --git a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf 
b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
index 4b86deb..31edf3a 100644
--- a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+++ b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
@@ -27,6 +27,7 @@ [Sources]
 
 [Packages]
   MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
 
 [LibraryClasses]
diff --git a/OvmfPkg/Include/Register/QemuSmramSaveStateMap.h 
b/OvmfPkg/Include/Register/QemuSmramSaveStateMap.h
new file mode 100644
index 0000000..389428d
--- /dev/null
+++ b/OvmfPkg/Include/Register/QemuSmramSaveStateMap.h
@@ -0,0 +1,184 @@
+/** @file
+SMRAM Save State Map Definitions.
+
+SMRAM Save State Map definitions based on contents of the 
+Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+  Volume 3C, Section 34.4 SMRAM
+  Volume 3C, Section 34.5 SMI Handler Execution Environment
+  Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
+
+and the AMD64 Architecture Programmer's Manual
+  Volume 2, Section 10.2 SMM Resources
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Red Hat, Inc.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __QEMU_SMRAM_SAVE_STATE_MAP_H__
+#define __QEMU_SMRAM_SAVE_STATE_MAP_H__
+
+#pragma pack (1)
+
+///
+/// 32-bit SMRAM Save State Map
+///
+typedef struct {
+  UINT8   Reserved0[0x200]; // 7c00h
+  UINT8   Reserved1[0xf8];  // 7e00h
+  UINT32  SMBASE;           // 7ef8h
+  UINT32  SMMRevId;         // 7efch
+  UINT16  IORestart;        // 7f00h
+  UINT16  AutoHALTRestart;  // 7f02h
+  UINT8   Reserved2[0x9C];  // 7f08h
+  UINT32  IOMemAddr;        // 7fa0h
+  UINT32  IOMisc;           // 7fa4h
+  UINT32  _ES;              // 7fa8h
+  UINT32  _CS;              // 7fach
+  UINT32  _SS;              // 7fb0h
+  UINT32  _DS;              // 7fb4h
+  UINT32  _FS;              // 7fb8h
+  UINT32  _GS;              // 7fbch
+  UINT32  Reserved3;        // 7fc0h
+  UINT32  _TR;              // 7fc4h
+  UINT32  _DR7;             // 7fc8h
+  UINT32  _DR6;             // 7fcch
+  UINT32  _EAX;             // 7fd0h
+  UINT32  _ECX;             // 7fd4h
+  UINT32  _EDX;             // 7fd8h
+  UINT32  _EBX;             // 7fdch
+  UINT32  _ESP;             // 7fe0h
+  UINT32  _EBP;             // 7fe4h
+  UINT32  _ESI;             // 7fe8h
+  UINT32  _EDI;             // 7fech
+  UINT32  _EIP;             // 7ff0h
+  UINT32  _EFLAGS;          // 7ff4h
+  UINT32  _CR3;             // 7ff8h
+  UINT32  _CR0;             // 7ffch
+} QEMU_SMRAM_SAVE_STATE_MAP32;
+
+///
+/// 64-bit SMRAM Save State Map
+///
+typedef struct {
+  UINT8   Reserved0[0x200];  // 7c00h
+
+  UINT16  _ES;               // 7e00h
+  UINT16  _ESAccessRights;   // 7e02h
+  UINT32  _ESLimit;          // 7e04h
+  UINT64  _ESBase;           // 7e08h
+
+  UINT16  _CS;               // 7e10h
+  UINT16  _CSAccessRights;   // 7e12h
+  UINT32  _CSLimit;          // 7e14h
+  UINT64  _CSBase;           // 7e18h
+
+  UINT16  _SS;               // 7e20h
+  UINT16  _SSAccessRights;   // 7e22h
+  UINT32  _SSLimit;          // 7e24h
+  UINT64  _SSBase;           // 7e28h
+
+  UINT16  _DS;               // 7e30h
+  UINT16  _DSAccessRights;   // 7e32h
+  UINT32  _DSLimit;          // 7e34h
+  UINT64  _DSBase;           // 7e38h
+
+  UINT16  _FS;               // 7e40h
+  UINT16  _FSAccessRights;   // 7e42h
+  UINT32  _FSLimit;          // 7e44h
+  UINT64  _FSBase;           // 7e48h
+
+  UINT16  _GS;               // 7e50h
+  UINT16  _GSAccessRights;   // 7e52h
+  UINT32  _GSLimit;          // 7e54h
+  UINT64  _GSBase;           // 7e58h
+
+  UINT32  _GDTRReserved1;    // 7e60h
+  UINT16  _GDTRLimit;        // 7e64h
+  UINT16  _GDTRReserved2;    // 7e66h
+  UINT64  _GDTRBase;         // 7e68h
+
+  UINT16  _LDTR;             // 7e70h
+  UINT16  _LDTRAccessRights; // 7e72h
+  UINT32  _LDTRLimit;        // 7e74h
+  UINT64  _LDTRBase;         // 7e78h
+
+  UINT32  _IDTRReserved1;    // 7e80h
+  UINT16  _IDTRLimit;        // 7e84h
+  UINT16  _IDTRReserved2;    // 7e86h
+  UINT64  _IDTRBase;         // 7e88h
+
+  UINT16  _TR;               // 7e90h
+  UINT16  _TRAccessRights;   // 7e92h
+  UINT32  _TRLimit;          // 7e94h
+  UINT64  _TRBase;           // 7e98h
+
+  UINT64  IO_RIP;            // 7ea0h
+  UINT64  IO_RCX;            // 7ea8h
+  UINT64  IO_RSI;            // 7eb0h
+  UINT64  IO_RDI;            // 7eb8h
+  UINT32  IO_DWord;          // 7ec0h
+  UINT8   Reserved1[0x04];   // 7ec4h
+  UINT8   IORestart;         // 7ec8h
+  UINT8   AutoHALTRestart;   // 7ec9h
+  UINT8   Reserved2[0x06];   // 7ecah
+
+  UINT64  IA32_EFER;         // 7ed0h
+  UINT64  SVM_Guest;         // 7ed8h
+  UINT64  SVM_GuestVMCB;     // 7ee0h
+  UINT64  SVM_GuestVIntr;    // 7ee8h
+  UINT8   Reserved3[0x0c];   // 7ef0h
+
+  UINT32  SMMRevId;          // 7efch
+  UINT32  SMBASE;            // 7f00h
+
+  UINT8   Reserved4[0x1c];   // 7f04h
+  UINT64  SVM_GuestPAT;      // 7f20h
+  UINT64  SVM_HostIA32_EFER; // 7f28h
+  UINT64  SVM_HostCR4;       // 7f30h
+  UINT64  SVM_HostCR3;       // 7f38h
+  UINT64  SVM_HostCR0;       // 7f40h
+
+  UINT64  _CR4;              // 7f48h
+  UINT64  _CR3;              // 7f50h
+  UINT64  _CR0;              // 7f58h
+  UINT64  _DR7;              // 7f60h
+  UINT64  _DR6;              // 7f68h
+  UINT64  _RFLAGS;           // 7f70h
+  UINT64  _RIP;              // 7f78h
+  UINT64  _R15;              // 7f80h
+  UINT64  _R14;              // 7f88h
+  UINT64  _R13;              // 7f90h
+  UINT64  _R12;              // 7f98h
+  UINT64  _R11;              // 7fa0h
+  UINT64  _R10;              // 7fa8h
+  UINT64  _R9;               // 7fb0h
+  UINT64  _R8;               // 7fb8h
+  UINT64  _RDI;              // 7fc0h
+  UINT64  _RSI;              // 7fc8h
+  UINT64  _RBP;              // 7fd0h
+  UINT64  _RSP;              // 7fd8h
+  UINT64  _RBX;              // 7fe0h
+  UINT64  _RDX;              // 7fe8h
+  UINT64  _RCX;              // 7ff0h
+  UINT64  _RAX;              // 7ff8h
+} QEMU_SMRAM_SAVE_STATE_MAP64;
+
+///
+/// Union of 32-bit and 64-bit SMRAM Save State Maps
+///
+typedef union  {
+  QEMU_SMRAM_SAVE_STATE_MAP32  x86;
+  QEMU_SMRAM_SAVE_STATE_MAP64  x64;
+} QEMU_SMRAM_SAVE_STATE_MAP;
+
+#pragma pack ()
+
+#endif
diff --git a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c 
b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
index b3d0e3a..a307f64 100644
--- a/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
+++ b/OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include <Library/MemoryAllocationLib.h>
 #include <Library/SmmServicesTableLib.h>
 #include <Library/DebugLib.h>
-#include <Register/SmramSaveStateMap.h>
+#include <Register/QemuSmramSaveStateMap.h>
 
 //
 // EFER register LMA bit
@@ -82,13 +82,17 @@ SmmCpuFeaturesInitializeProcessor (
   IN CPU_HOT_PLUG_DATA          *CpuHotPlugData
   )
 {
-  SMRAM_SAVE_STATE_MAP  *CpuState;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuState;
 
   //
   // Configure SMBASE.
   //
-  CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + 
SMRAM_SAVE_STATE_MAP_OFFSET);
-  CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+  CpuState = (QEMU_SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + 
SMRAM_SAVE_STATE_MAP_OFFSET);
+  if ((CpuState->x86.SMMRevId & 0xFFFF) == 0) {
+    CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+  } else {
+    CpuState->x64.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+  }
 
   //
   // No need to program SMRRs on our virtual platform.
@@ -135,8 +139,8 @@ SmmCpuFeaturesHookReturnFromSmm (
   IN UINT64                NewInstructionPointer
   )
 {
-  UINT64                 OriginalInstructionPointer;
-  SMRAM_SAVE_STATE_MAP  *CpuSaveState = (SMRAM_SAVE_STATE_MAP *)CpuState;
+  UINT64                      OriginalInstructionPointer;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP 
*)CpuState;
 
   if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
     OriginalInstructionPointer = (UINT64)CpuSaveState->x86._EIP;
@@ -397,7 +401,7 @@ SmmCpuFeaturesSetSmmRegister (
 ///
 /// 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)
+#define SMM_CPU_OFFSET(Field) OFFSET_OF (QEMU_SMRAM_SAVE_STATE_MAP, Field)
 
 ///
 /// Macro used to simplify the lookup table entries of type 
CPU_SMM_SAVE_STATE_REGISTER_RANGE
@@ -450,13 +454,13 @@ static CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY 
mSmmCpuWidthOffset[] = {
   //
   // 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
+  {0, 8, 0                            , SMM_CPU_OFFSET (x64._GDTRBase) , 
SMM_CPU_OFFSET (x64._GDTRBase)  + 4, FALSE},  //  
EFI_SMM_SAVE_STATE_REGISTER_GDTBASE  = 4
+  {0, 8, 0                            , SMM_CPU_OFFSET (x64._IDTRBase) , 
SMM_CPU_OFFSET (x64._IDTRBase)  + 4, FALSE},  //  
EFI_SMM_SAVE_STATE_REGISTER_IDTBASE  = 5
+  {0, 8, 0                            , SMM_CPU_OFFSET (x64._LDTRBase) , 
SMM_CPU_OFFSET (x64._LDTRBase)  + 4, FALSE},  //  
EFI_SMM_SAVE_STATE_REGISTER_LDTBASE  = 6
+  {0, 0, 0                            , SMM_CPU_OFFSET (x64._GDTRLimit), 
SMM_CPU_OFFSET (x64._GDTRLimit) + 4, FALSE},  //  
EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7
+  {0, 0, 0                            , SMM_CPU_OFFSET (x64._IDTRLimit), 
SMM_CPU_OFFSET (x64._IDTRLimit) + 4, FALSE},  //  
EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8
+  {0, 0, 0                            , SMM_CPU_OFFSET (x64._LDTRLimit), 
SMM_CPU_OFFSET (x64._LDTRLimit) + 4, FALSE},  //  
EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9
+  {0, 0, 0                            , 0                              , 0     
                          + 4, 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
@@ -489,7 +493,7 @@ static CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY 
mSmmCpuWidthOffset[] = {
   {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
+  {0, 4, 0                            , SMM_CPU_OFFSET (x64._CR4)    , 
SMM_CPU_OFFSET (x64._CR4)    + 4, FALSE},  //  EFI_SMM_SAVE_STATE_REGISTER_CR4  
    = 54
 };
 
 //
@@ -548,9 +552,9 @@ ReadSaveStateRegisterByIndex (
   OUT VOID   *Buffer
   )
 {
-  SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
 
-  CpuSaveState = gSmst->CpuSaveState[CpuIndex];
+  CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
 
   if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
     //
@@ -628,8 +632,8 @@ SmmCpuFeaturesReadSaveStateRegister (
   OUT VOID                         *Buffer
   )
 {
-  UINTN                  RegisterIndex;
-  SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+  UINTN                       RegisterIndex;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
 
   //
   // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA
@@ -642,7 +646,7 @@ SmmCpuFeaturesReadSaveStateRegister (
       return EFI_INVALID_PARAMETER;
     }
 
-    CpuSaveState = gSmst->CpuSaveState[CpuIndex];
+    CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
 
     //
     // Check CPU mode
@@ -701,8 +705,8 @@ SmmCpuFeaturesWriteSaveStateRegister (
   IN CONST VOID                   *Buffer
   )
 {
-  UINTN                 RegisterIndex;
-  SMRAM_SAVE_STATE_MAP  *CpuSaveState;
+  UINTN                       RegisterIndex;
+  QEMU_SMRAM_SAVE_STATE_MAP  *CpuSaveState;
 
   //
   // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored
@@ -728,7 +732,7 @@ SmmCpuFeaturesWriteSaveStateRegister (
     return Register < EFI_SMM_SAVE_STATE_REGISTER_IO ? EFI_NOT_FOUND : 
EFI_UNSUPPORTED;
   }
 
-  CpuSaveState = gSmst->CpuSaveState[CpuIndex];
+  CpuSaveState = (QEMU_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
 
   //
   // Do not write non-writable SaveState, because it will cause exception.
-- 
1.8.3.1


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to