diff options
author | Johnny Lin <johnny_lin@wiwynn.com> | 2022-03-29 22:44:47 +0800 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-12-20 19:53:42 +0000 |
commit | 161d090d22f9f687a328a9582b264bec734d042b (patch) | |
tree | f5ebedc716183f71884cd1414ff1e7ae4ba47e6c /src/soc/intel | |
parent | 57789db4d218c7eee4e745ec46c2228eadb57846 (diff) |
soc/intel/xeon_sp: Set IA32_SMRR_PHYSMASK lock bit
smm_relocation_handler is run for each thread but IA32_SMRR_PHYS_BASE
and IA32_SMRR_PHYS_MASK are core scope, need to avoid writing the
same MSR that has been locked by another thread.
Tested=On OCP Crater Lake, rdmsr -a 0x1f3 can see all cores set the lock
bit.
Change-Id: I9cf5a6761c9a9e1578c6132ef83e288540d41176
Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/70870
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Jonathan Zhang <jonzhang@fb.com>
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/xeon_sp/smmrelocate.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/soc/intel/xeon_sp/smmrelocate.c b/src/soc/intel/xeon_sp/smmrelocate.c index f44fc62d3e..f9d100a600 100644 --- a/src/soc/intel/xeon_sp/smmrelocate.c +++ b/src/soc/intel/xeon_sp/smmrelocate.c @@ -113,7 +113,7 @@ static void update_save_state(int cpu, uintptr_t curr_smbase, void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase) { - msr_t mtrr_cap; + msr_t mtrr_cap, msr; struct smm_relocation_params *relo_params = &smm_reloc_params; printk(BIOS_DEBUG, "%s : CPU %d\n", __func__, cpu); @@ -123,6 +123,17 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, /* 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) { + msr = rdmsr(IA32_SMRR_PHYS_MASK); + /* Don't write the same core scope MSR if another thread has locked it, + otherwise system would hang. */ + if (msr.lo & SMRR_PHYS_MASK_LOCK) + return; + relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK; + } + if (mtrr_cap.lo & SMRR_SUPPORTED) write_smrr(relo_params); } |