]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/PiSmmCpuDxeSmm: eliminate "gSmmJmpAddr" and related DBs
authorLaszlo Ersek <lersek@redhat.com>
Fri, 2 Feb 2018 03:12:51 +0000 (04:12 +0100)
committerLaszlo Ersek <lersek@redhat.com>
Wed, 4 Apr 2018 14:44:19 +0000 (16:44 +0200)
The IA32 version of "SmmInit.nasm" does not need "gSmmJmpAddr" at all (its
PiSmmCpuSmmInitFixupAddress() variant doesn't do anything either). We can
simply use the NASM syntax for the following Mixed-Size Jump:

> jmp PROTECT_MODE_CS : dword @32bit

The generated object code for the instruction is unchanged:

00000182  66EA5A0000000800  jmp dword 0x8:0x5a

(The NASM manual explains that putting the DWORD prefix after the colon
":" reflects the intent better, since it is the offset that is a DWORD.
Thus, that's what I used. However, both syntaxes are interchangeable,
hence the ndisasm output.)

The X64 version of "SmmInit.nasm" appears to require "gSmmJmpAddr";
however that's accidental, not inherent:

- Bring LONG_MODE_CODE_SEGMENT from
  "UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h" to "SmmInit.nasm" as
  LONG_MODE_CS, same as PROTECT_MODE_CODE_SEGMENT was brought to the IA32
  version as PROTECT_MODE_CS earlier.

- Apply the NASM-native Mixed-Size Jump syntax again, but jump to the
  fixed zero offset in LONG_MODE_CS. This will produce no relocation
  record at all. Add a label after the instruction.

- Modify PiSmmCpuSmmInitFixupAddress() to patch the jump target backwards
  from the label. Because we modify the DWORD offset with a DWORD access,
  the segment selector is unharmed in the instruction, and we need not set
  it from PiCpuSmmEntry().

According to "objdump --reloc", the X64 version undergoes only the
following relocations, after this patch:

> RELOCATION RECORDS FOR [.text]:
> OFFSET           TYPE              VALUE
0000000000000095 R_X86_64_PC32     SmmInitHandler-0x0000000000000004
00000000000000e0 R_X86_64_PC32     mRebasedFlag-0x0000000000000004
00000000000000ea R_X86_64_PC32     mSmmRelocationOriginalAddress-0x0000000000000004

Therefore the patch does not regress
<https://bugzilla.tianocore.org/show_bug.cgi?id=849> ("Enable XCODE5 tool
chain for UefiCpuPkg with nasm source code").

Cc: Eric Dong <eric.dong@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=866
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.nasm
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.nasm

index 0f62fe4487125c38532b6b7690cbee817d818b91..f59413d9d4a3cce37a77fb2405b954f48b599793 100644 (file)
@@ -25,7 +25,6 @@ extern ASM_PFX(mSmmRelocationOriginalAddress)
 global ASM_PFX(gPatchSmmCr3)\r
 global ASM_PFX(gPatchSmmCr4)\r
 global ASM_PFX(gPatchSmmCr0)\r
-global ASM_PFX(gSmmJmpAddr)\r
 global ASM_PFX(gSmmInitStack)\r
 global ASM_PFX(gcSmiInitGdtr)\r
 global ASM_PFX(gcSmmInitSize)\r
@@ -64,10 +63,7 @@ ASM_PFX(gPatchSmmCr4):
 ASM_PFX(gPatchSmmCr0):\r
     mov     di, PROTECT_MODE_DS\r
     mov     cr0, eax\r
-    DB      0x66, 0xea                  ; jmp far [ptr48]\r
-ASM_PFX(gSmmJmpAddr):\r
-    DD      @32bit\r
-    DW      PROTECT_MODE_CS\r
+    jmp     PROTECT_MODE_CS : dword @32bit\r
 \r
 BITS 32\r
 @32bit:\r
index f602d86d51a141252dc1651f0ea678b0a1606b22..0c8a4543d8651794fbeb7f38ff869b3670a71237 100755 (executable)
@@ -569,13 +569,6 @@ PiCpuSmmEntry (
     EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT\r
     );\r
 \r
-  //\r
-  // Fix segment address of the long-mode-switch jump\r
-  //\r
-  if (sizeof (UINTN) == sizeof (UINT64)) {\r
-    gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT;\r
-  }\r
-\r
   //\r
   // Find out SMRR Base and SMRR Size\r
   //\r
index 8344e0653a4800091c5c1869e3bdb7cab77e7305..d897d4353e104f4963fb2778dca23385b81535f8 100644 (file)
@@ -295,17 +295,6 @@ WriteSaveStateRegister (
   IN CONST VOID                   *Buffer\r
   );\r
 \r
-//\r
-//\r
-//\r
-typedef struct {\r
-  UINT32                            Offset;\r
-  UINT16                            Segment;\r
-  UINT16                            Reserved;\r
-} IA32_FAR_ADDRESS;\r
-\r
-extern IA32_FAR_ADDRESS             gSmmJmpAddr;\r
-\r
 extern CONST UINT8                  gcSmmInitTemplate[];\r
 extern CONST UINT16                 gcSmmInitSize;\r
 X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr0;\r
index 1a0667bd97bae95836b7f53cce06b3c9b9d54389..2460e1eb2dee91d2e0388ffe32044d7ebad0b471 100644 (file)
@@ -25,7 +25,6 @@ extern ASM_PFX(mSmmRelocationOriginalAddress)
 global ASM_PFX(gPatchSmmCr3)\r
 global ASM_PFX(gPatchSmmCr4)\r
 global ASM_PFX(gPatchSmmCr0)\r
-global ASM_PFX(gSmmJmpAddr)\r
 global ASM_PFX(gSmmInitStack)\r
 global ASM_PFX(gcSmiInitGdtr)\r
 global ASM_PFX(gcSmmInitSize)\r
@@ -33,6 +32,8 @@ global ASM_PFX(gcSmmInitTemplate)
 global ASM_PFX(mRebasedFlagAddr32)\r
 global ASM_PFX(mSmmRelocationOriginalAddressPtr32)\r
 \r
+%define LONG_MODE_CS 0x38\r
+\r
     DEFAULT REL\r
     SECTION .text\r
 \r
@@ -66,8 +67,8 @@ ASM_PFX(gPatchSmmCr4):
     mov     eax, strict dword 0         ; source operand will be patched\r
 ASM_PFX(gPatchSmmCr0):\r
     mov     cr0, eax                    ; enable protected mode & paging\r
-    DB      0x66, 0xea                   ; far jmp to long mode\r
-ASM_PFX(gSmmJmpAddr): DQ 0;@LongMode\r
+    jmp     LONG_MODE_CS : dword 0      ; offset will be patched to @LongMode\r
+@PatchLongModeOffset:\r
 \r
 BITS 64\r
 @LongMode:                              ; long-mode starts here\r
@@ -141,8 +142,8 @@ ASM_PFX(mSmmRelocationOriginalAddressPtr32): dd 0
 global ASM_PFX(PiSmmCpuSmmInitFixupAddress)\r
 ASM_PFX(PiSmmCpuSmmInitFixupAddress):\r
     lea    rax, [@LongMode]\r
-    lea    rcx, [ASM_PFX(gSmmJmpAddr)]\r
-    mov    qword [rcx], rax\r
+    lea    rcx, [@PatchLongModeOffset - 6]\r
+    mov    dword [rcx], eax\r
 \r
     lea    rax, [ASM_PFX(SmmStartup)]\r
     lea    rcx, [@L1]\r