soc/intel/tigerlake: Add SMRR Locking support

The SMRR MSRs can be locked, so that a further write to them will cause
a #GP.  This patch adds that functionality, but since the MSR is a
core-level register, it must only be done once per core; if the SoC has
hyperthreading enabled, then attempting to write the SMRR Lock bit on
the primary thread will cause a #GP when the secondary (sibling) thread
attempts to also write to this MSR.

BUG=b:164489598
TEST=Boot into OS, verify using `iotools rdmsr` that all threads have
the Lock bit set.

Signed-off-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Change-Id: I4ae7c7f703bdf090144637d071eb810617d9e309
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45013
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kane Chen <kane.chen@intel.com>
Reviewed-by: Caveh Jalali <caveh@chromium.org>
Reviewed-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Tim Wawrzynczak 2020-09-01 16:11:48 -06:00 committed by Patrick Georgi
parent 4cba419676
commit 0cded1f116
2 changed files with 18 additions and 0 deletions

View File

@ -16,6 +16,7 @@ config CPU_SPECIFIC_OPTIONS
select BOOT_DEVICE_SUPPORTS_WRITES
select CACHE_MRC_SETTINGS
select CPU_INTEL_COMMON
select CPU_INTEL_COMMON_HYPERTHREADING
select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
select FSP_COMPRESS_FSP_S_LZ4
select FSP_M_XIP

View File

@ -9,6 +9,7 @@
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <cpu/intel/common/common.h>
#include <cpu/intel/em64t101_save_state.h>
#include <cpu/intel/smm_reloc.h>
#include <console/console.h>
@ -137,8 +138,24 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
/* Make appropriate changes to the save state map. */
update_save_state(cpu, curr_smbase, staggered_smbase, relo_params);
/*
* The SMRR MSRs are core-level registers, so if two threads that share
* a core try to both set the lock bit (in the same physical register),
* a #GP will be raised on the second write to that register (which is
* exactly what the lock is supposed to do), therefore secondary threads
* should exit here.
*/
if (intel_ht_sibling())
return;
/* Write SMRR MSRs based on indicated support. */
mtrr_cap = rdmsr(MTRR_CAP_MSR);
/* Set Lock bit if supported */
if (mtrr_cap.lo & SMRR_LOCK_SUPPORTED)
relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK;
/* Write SMRRs if supported */
if (mtrr_cap.lo & SMRR_SUPPORTED)
write_smrr(relo_params);
}