Commit Graph

20 Commits

Author SHA1 Message Date
Kirkendall, Garrett bdafda8c45 UefiCpuPkg: PiSmmCpuDxeSmm skip MSR_IA32_MISC_ENABLE manipulation on AMD
AMD does not support MSR_IA32_MISC_ENABLE.  Accessing that register
causes and exception on AMD processors.  If Execution Disable is
supported, but if the processor is an AMD processor, skip manipulating
MSR_IA32_MISC_ENABLE[34] XD Disable bit.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Garrett Kirkendall <garrett.kirkendall@amd.com>
Message-Id: <20200622131825.1352-5-Garrett.Kirkendall@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2020-07-07 23:25:16 +00:00
Antoine Coeur ef62da4ff7 UefiCpuPkg/PiSmm: Fix various typos
Fix various typos in comments and documentation.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Antoine Coeur <coeur@gmx.fr>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com>
Message-Id: <20200207010831.9046-78-philmd@redhat.com>
2020-02-10 22:30:07 +00:00
Ray Ni 86ad762fa7 UefiCpuPkg/PiSmmCpu: Enable 5L paging only when phy addr line > 48
Today's behavior is to enable 5l paging when CPU supports it
(CPUID[7,0].ECX.BIT[16] is set).

The patch changes the behavior to enable 5l paging when two
conditions are both met:
1. CPU supports it;
2. The max physical address bits is bigger than 48.

Because 4-level paging can support to address physical address up to
2^48 - 1, there is no need to enable 5-level paging with max
physical address bits <= 48.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
2019-09-13 16:20:54 +08:00
Ray Ni 4eee0cc7cc UefiCpuPkg/PiSmmCpu: Enable 5 level paging when CPU supports
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1946

The patch changes SMM environment to use 5 level paging when CPU
supports it.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
(cherry picked from commit 7365eb2c8c)
2019-07-12 15:13:51 +08:00
Ray Ni 4e78c7bebb Revert "UefiCpuPkg/PiSmmCpu: Enable 5 level paging when CPU supports"
This reverts commit 7365eb2c8c.
Commit
7c5010c7f8 MdePkg/BaseLib.h: Update IA32_CR4 structure for 5-level paging
technically breaks the EDKII development process documented in
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Development-Process
and Maintainers.txt in EDKII repo root directory.

The voilation is commit 7c5010c7f8 doesn't have a Reviewed-by or
Acked-by from MdePkg maintainers.

In order to revert 7c5010c7f8, 7365eb2c8 needs to revert first otherwise
simply reverting 7c5010c7f8 will cause build break.

Signed-off-by: Ray Ni <ray.ni@intel.com>
2019-07-12 14:59:32 +08:00
Ray Ni 7365eb2c8c UefiCpuPkg/PiSmmCpu: Enable 5 level paging when CPU supports
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1946

The patch changes SMM environment to use 5 level paging when CPU
supports it.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2019-07-10 16:00:15 +08:00
Michael D Kinney 0acd869796 UefiCpuPkg: Replace BSD License with BSD+Patent License
https://bugzilla.tianocore.org/show_bug.cgi?id=1373

Replace BSD 2-Clause License with BSD+Patent License.  This change is
based on the following emails:

  https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html
  https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html

RFCs with detailed process for the license change:

  V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html
  V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html
  V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
2019-04-09 10:58:28 -07:00
Jiewen Yao 3eb69b081c UefiCpuPkg/PiSmmCpu: Add Shadow Stack Support for X86 SMM.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1521

We scan the SMM code with ROPgadget.
http://shell-storm.org/project/ROPgadget/
https://github.com/JonathanSalwan/ROPgadget/tree/master
This tool reports the gadget in SMM driver.

This patch enabled CET ShadowStack for X86 SMM.
If CET is supported, SMM will enable CET ShadowStack.
SMM CET will save the OS CET context at SmmEntry and
restore OS CET context at SmmExit.

Test:
1) test Intel internal platform (x64 only, CET enabled/disabled)
Boot test:
CET supported or not supported CPU
on CET supported platform
  CET enabled/disabled
  PcdCpuSmmCetEnable enabled/disabled
  Single core/Multiple core
  PcdCpuSmmStackGuard enabled/disabled
  PcdCpuSmmProfileEnable enabled/disabled
  PcdCpuSmmStaticPageTable enabled/disabled
CET exception test:
  #CF generated with PcdCpuSmmStackGuard enabled/disabled.
Other exception test:
  #PF for normal stack overflow
  #PF for NX protection
  #PF for RO protection
CET env test:
  Launch SMM in CET enabled/disabled environment (DXE) - no impact to DXE

The test case can be found at
https://github.com/jyao1/SecurityEx/tree/master/ControlFlowPkg

2) test ovmf (both IA32 and X64 SMM, CET disabled only)
test OvmfIa32/Ovmf3264, with -D SMM_REQUIRE.
  qemu-system-x86_64.exe -machine q35,smm=on -smp 4
    -serial file:serial.log
    -drive if=pflash,format=raw,unit=0,file=OVMF_CODE.fd,readonly=on
    -drive if=pflash,format=raw,unit=1,file=OVMF_VARS.fd
QEMU emulator version 3.1.0 (v3.1.0-11736-g7a30e7adb0-dirty)

3) not tested
IA32 CET enabled platform

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yao Jiewen <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2019-02-28 09:39:54 +08:00
Hao Wu ada4a003f9 UefiCpuPkg: Merge StuffRsb.inc files into one in UefiCpuPkg/Include
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1091

Previously, when compiling NASM source files, BaseTools did not support
including files outside of the NASM source file directory. As a result, we
duplicated multiple copies of "StuffRsb.inc" files in UefiCpuPkg. Those
INC files contain the common logic to stuff the Return Stack Buffer and
are identical.

After the fix of BZ 1085:
https://bugzilla.tianocore.org/show_bug.cgi?id=1085
The above support was introduced.

Thus, this commit will merge all the StuffRsb.inc files in UefiCpuPkg into
one file. The merged file will be named 'StuffRsbNasm.inc' and be placed
under folder UefiCpuPkg/Include/.

Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2019-01-02 09:45:29 +08:00
Liming Gao a364928195 UefiCpuPkg PiSmmCpuDxeSmm: Update SmiEntry function run the same position
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1191

Before commit e21e355e2c, jmp _SmiHandler
is commented. And below code, ASM_PFX(CpuSmmDebugEntry) is moved into rax,
then call it. But, this code doesn't work in XCODE5 tool chain. Because XCODE5
doesn't generated the absolute address in the EFI image. So, rax stores the
relative address. Once this logic is moved to another place, it will not work.
;   jmp     _SmiHandler                 ; instruction is not needed
...
    mov     rax, ASM_PFX(CpuSmmDebugEntry)
    call    rax

Commit e21e355e2c is to support XCODE5.
One tricky way is selected to fix it. Although SmiEntry logic is copied to
another place and run, but here jmp _SmiHandler is enabled to jmp the original
code place, then call ASM_PFX(CpuSmmDebugEntry) with the relative address.
    mov     rax, strict qword 0         ;   mov     rax, _SmiHandler
_SmiHandlerAbsAddr:
    jmp     rax
...
    call    ASM_PFX(CpuSmmDebugEntry)

Now, BZ 1191 raises the issue that SmiHandler should run in the copied address,
can't run in the common address. So, jmp _SmiHandler is required to be removed,
the code is kept to run in copied address. And, the relative address is
requried to be fixed up to the absolute address. The necessary changes should
not affect the behavior of platforms that already consume PiSmmCpuDxeSmm.
OVMF SMM boot to shell with VS2017, GCC5 and XCODE5 tool chain has been verified.
...
    mov     rax, strict qword 0         ;   call    ASM_PFX(CpuSmmDebugEntry)
CpuSmmDebugEntryAbsAddr:
    call    rax

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
2018-09-25 08:25:41 +08:00
Hao Wu 02f7fd158e UefiCpuPkg/PiSmmCpuDxeSmm: [CVE-2017-5715] Stuff RSB before RSM
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1093

Return Stack Buffer (RSB) is used to predict the target of RET
instructions. When the RSB underflows, some processors may fall back to
using branch predictors. This might impact software using the retpoline
mitigation strategy on those processors.

This commit will add RSB stuffing logic before returning from SMM (the RSM
instruction) to avoid interfering with non-SMM usage of the retpoline
technique.

After the stuffing, RSB entries will contain a trap like:

@SpecTrap:
    pause
    lfence
    jmp     @SpecTrap

A more detailed explanation of the purpose of commit is under the
'Branch target injection mitigation' section of the below link:
https://software.intel.com/security-software-guidance/insights/host-firmware-speculative-execution-side-channel-mitigation

Please note that this commit requires further actions (BZ 1091) to remove
the duplicated 'StuffRsb.inc' files and merge them into one under a
UefiCpuPkg package-level directory (such as UefiCpuPkg/Include/).

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1091

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2018-08-21 16:10:42 +08:00
Laszlo Ersek d22c995a48 UefiCpuPkg/PiSmmCpuDxeSmm: use mnemonics for FXSAVE(64)/FXRSTOR(64)
NASM introduced FXSAVE / FXRSTOR support in commit 900fa5b26b8f ("NASM
0.98p3-hpa", 2002-04-30), which commit stands for the nasm-0.98p3-hpa
release.

NASM introduced FXSAVE64 / FXRSTOR64 support in commit 3a014348ca15
("insns: add FXSAVE64/FXRSTOR64, drop np prefix", 2010-07-07), which was
part of the "nasm-2.09" release.

Edk2 requires nasm-2.10 or later for use with the GCC toolchain family,
and nasm-2.12.01 or later for use with all other toolchain families.
Replace the binary encoding of the FXSAVE(64)/FXRSTOR(64) instructions
with mnemonics.

I verified that the "Ia32/SmiException.obj", "X64/SmiEntry.obj" and
"X64/SmiException.obj" files are rebuilt after this patch, without any
change in content.

This patch removes the last instructions encoded with DBs from
PiSmmCpuDxeSmm.

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>
2018-04-04 16:44:27 +02:00
Laszlo Ersek 3c5ce64f23 UefiCpuPkg/PiSmmCpuDxeSmm: patch "XdSupported" with PatchInstructionX86()
"mXdSupported" is a global BOOLEAN variable, initialized to TRUE. The
CheckFeatureSupported() function is executed on all processors (not
concurrently though), called from SmmInitHandler(). If XD support is found
to be missing on any CPU, then "mXdSupported" is set to FALSE, and further
processors omit the check. Afterwards, "mXdSupported" is read by several
assembly and C code locations.

The tricky part is *where* "mXdSupported" is allocated (defined):

- Before commit 717fb60443 ("UefiCpuPkg/PiSmmCpuDxeSmm: Add paging
  protection.", 2016-11-17), it used to be a normal global variable,
  defined (allocated) in "SmmProfile.c".

- With said commit, we moved the definition (allocation) of "mXdSupported"
  into "SmiEntry.nasm". The variable was defined over the last byte of a
  "mov al, 1" instruction, so that setting it to FALSE in
  CheckFeatureSupported() would patch the instruction to "mov al, 0". The
  subsequent conditional jump would change behavior, plus all further read
  references to "mXdSupported" (in C and assembly code) would read back
  the source (imm8) operand of the patched MOV instruction as data.

  This trick required that the MOV instruction be encoded with DB.

In order to get rid of the DB, we have to split both roles: we need a
label for the code patching, and "mXdSupported" has to be defined
(allocated) independently of the code patching. Of course, their values
must always remain in sync.

(1) Reinstate the "mXdSupported" definition and initialization in
    "SmmProfile.c" from before commit 717fb60443. Change the assembly
    language definition ("global") to a declaration ("extern").

(2) Define the "gPatchXdSupported" label (type X86_ASSEMBLY_PATCH_LABEL)
    in "SmiEntry.nasm", and add the C-language declaration to
    "SmmProfileInternal.h". Replace the DB with the MOV mnemonic (keeping
    the imm8 source operand with value 1).

(3) In CheckFeatureSupported(), whenever "mXdSupported" is set to FALSE,
    patch the assembly code in sync, with PatchInstructionX86().

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>
2018-04-04 16:44:08 +02:00
Laszlo Ersek c455687fd0 UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiCr3" with PatchInstructionX86()
Rename the variable to "gPatchSmiCr3" so that its association with
PatchInstructionX86() is clear from the declaration, change its type to
X86_ASSEMBLY_PATCH_LABEL, and patch it with PatchInstructionX86(). This
lets us remove the binary (DB) encoding of some instructions in
"SmiEntry.nasm".

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>
2018-04-04 16:44:06 +02:00
Laszlo Ersek fc504fdea7 UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" with PatchInstructionX86()
Rename the variable to "gPatchSmiStack" so that its association with
PatchInstructionX86() is clear from the declaration. Also change its type
to X86_ASSEMBLY_PATCH_LABEL.

Unlike "gSmbase" in the previous patch, "gSmiStack"'s patched value is
also de-referenced by C code (in other words, it is read back after
patching): the InstallSmiHandler() function stores "CpuIndex" to the given
CPU's SMI stack through "gSmiStack". Introduce the local variable
"CpuSmiStack" in InstallSmiHandler() for calculating the stack location
separately, then use this variable for both patching into the assembly
code, and for storing "CpuIndex" through it.

It's assumed that "volatile" stood in the declaration of "gSmiStack"
because we used to read "gSmiStack" back for de-referencing; with that use
gone, we can remove "volatile" too. (Note that the *target* of the pointer
was never volatile-qualified.)

Finally, replace the binary (DB) encoding of "mov esp, imm32" in
"SmiEntry.nasm".

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>
2018-04-04 16:44:04 +02:00
Laszlo Ersek 5a1bfda4bd UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmbase" with PatchInstructionX86()
Rename the variable to "gPatchSmbase" so that its association with
PatchInstructionX86() is clear from the declaration, change its type to
X86_ASSEMBLY_PATCH_LABEL, and patch it with PatchInstructionX86(). This
lets us remove the binary (DB) encoding of some instructions in
"SmiEntry.nasm".

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>
2018-04-04 16:44:02 +02:00
Liming Gao e21e355e2c UefiCpuPkg: Update PiSmmCpuDxeSmm pass XCODE5 tool chain
https://bugzilla.tianocore.org/show_bug.cgi?id=849

In V2, use "mov rax, strict qword 0" to replace the hard code db.

1. Use lea instruction to get the address instead of mov instruction.
2. Use the dummy address as jmp destination, and add the logic to fix up
the address to the absolute address at boot time.
3. On MpFuncs.nasm, use ExchangeInfo to record InitializeFloatingPointUnits.
This way is same to MpInitLib.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
2018-01-16 23:43:08 +08:00
Liming Gao 8764ed57b4 UefiCpuPkg: PiSmmCpuDxeSmm Add the missing ASM_PFX in nasm code
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
2017-12-08 13:29:42 +08:00
Jiewen Yao 717fb60443 UefiCpuPkg/PiSmmCpuDxeSmm: Add paging protection.
PiSmmCpuDxeSmm consumes SmmAttributesTable and setup page table:
1) Code region is marked as read-only and Data region is non-executable,
if the PE image is 4K aligned.
2) Important data structure is set to RO, such as GDT/IDT.
3) SmmSaveState is set to non-executable,
and SmmEntrypoint is set to read-only.
4) If static page is supported, page table is read-only.

We use page table to protect other components, and itself.

If we use dynamic paging, we can still provide *partial* protection.
And hope page table is not modified by other components.

The XD enabling code is moved to SmiEntry to let NX take effect.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
2016-11-17 16:30:07 +08:00
Liming Gao 9a36d4dc3f UefiCpuPkg PiSmmCpuDxeSmm: Convert X64/SmiEntry.asm to NASM
Manually convert X64/SmiEntry.asm to X64/SmiEntry.nasm

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
2016-06-28 09:52:17 +08:00