Skip to content

Commit dc0450f

Browse files
miczyg1SergiiDmytruk
authored andcommitted
soc/intel/lockdown: Allow locking down SPI and LPC in SMM
Heads payload uses APM_CNT_FINALIZE SMI to set and lock down the SPI controller with PR0 flash protection for pre-Skylake platforms. Add new option to skip LPC and FAST SPI lock down in coreboot and move it to APM_CNT_FINALIZE SMI handler. Reuse the INTEL_CHIPSET_LOCKDOWN option to prevent issuing APM_CNT_FINALIZE SMI on normal boot path, like it was done on pre-Skylake platforms. As the locking on modern SOCs became more complicated, separate the SPI and LPC locking into new modules to make linking to SMM easier. The expected configuration to leverage the feautre is to unselect INTEL_CHIPSET_LOCKDOWN and select SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM. Testing various microarchitectures happens on heads repository: linuxboot/heads#1818 TEST=Lock the SPI flash using APM_CNT_FINALIZE in heads on Alder Lake (Protectli VP66xx) and Comet Lake (Protectli VP46xx) platforms. Check if flash is unlocked in the heads recovery console. Check if flash is locked in the kexec'ed OS. Change-Id: Icbcc6fcde90e5b0a999aacb720e2e3dc2748c838 Signed-off-by: Michał Żygowski <[email protected]>
1 parent 10ce867 commit dc0450f

File tree

18 files changed

+125
-53
lines changed

18 files changed

+125
-53
lines changed

src/soc/intel/alderlake/finalize.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ static void soc_finalize(void *unused)
8585
printk(BIOS_DEBUG, "Finalizing chipset.\n");
8686

8787
pch_finalize();
88-
apm_control(APM_CNT_FINALIZE);
88+
if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3())
89+
apm_control(APM_CNT_FINALIZE);
90+
8991
tbt_finalize();
9092
if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) &&
9193
CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE))

src/soc/intel/cannonlake/finalize.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ static void soc_finalize(void *unused)
8787
printk(BIOS_DEBUG, "Finalizing chipset.\n");
8888

8989
pch_finalize();
90-
apm_control(APM_CNT_FINALIZE);
90+
if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3())
91+
apm_control(APM_CNT_FINALIZE);
92+
9193
if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT) &&
9294
CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PMC_IPC))
9395
heci1_disable();

src/soc/intel/common/block/lpc/Makefile.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c
55

66
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c
77
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc.c
8+
9+
ifeq ($(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM),y)
10+
smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c
11+
endif

src/soc/intel/common/block/smm/smihandler.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#include <device/pci_def.h>
1616
#include <device/pci_ops.h>
1717
#include <elog.h>
18+
#include <intelblocks/cfg.h>
1819
#include <intelblocks/fast_spi.h>
1920
#include <intelblocks/oc_wdt.h>
2021
#include <intelblocks/pmclib.h>
2122
#include <intelblocks/smihandler.h>
2223
#include <intelblocks/tco.h>
2324
#include <intelblocks/uart.h>
25+
#include <intelpch/lockdown.h>
2426
#include <smmstore.h>
2527
#include <soc/nvs.h>
2628
#include <soc/pci_devs.h>
@@ -347,6 +349,14 @@ static void finalize(void)
347349
}
348350
finalize_done = 1;
349351

352+
if (CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) {
353+
/* SPI lock down configuration */
354+
fast_spi_lockdown_bios(CHIPSET_LOCKDOWN_COREBOOT);
355+
356+
/* LPC/eSPI lock down configuration */
357+
lpc_lockdown_config(CHIPSET_LOCKDOWN_COREBOOT);
358+
}
359+
350360
if (CONFIG(SPI_FLASH_SMM))
351361
/* Re-init SPI driver to handle locked BAR */
352362
fast_spi_init();

src/soc/intel/common/pch/include/intelpch/lockdown.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ int get_lockdown_config(void);
2222
*/
2323
void soc_lockdown_config(int chipset_lockdown);
2424

25+
void fast_spi_lockdown_bios(int chipset_lockdown);
26+
void lpc_lockdown_config(int chipset_lockdown);
27+
2528
#endif /* SOC_INTEL_COMMON_PCH_LOCKDOWN_H */

src/soc/intel/common/pch/lockdown/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,22 @@
33
config SOC_INTEL_COMMON_PCH_LOCKDOWN
44
bool
55
default n
6+
select HAVE_INTEL_CHIPSET_LOCKDOWN
67
help
78
This option allows to have chipset lockdown for DMI, FAST_SPI and
89
soc_lockdown_config() to implement any additional lockdown as PMC,
910
LPC for supported PCH.
11+
12+
config SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM
13+
bool "Lock down SPI controller in SMM"
14+
default n
15+
depends on HAVE_SMI_HANDLER && !INTEL_CHIPSET_LOCKDOWN
16+
select SPI_FLASH_SMM
17+
help
18+
This option allows to have chipset lockdown for FAST_SPI and LPC for
19+
supported PCH. If selected, coreboot will skip locking down the SPI
20+
and LPC controller. The payload or OS is responsible for locking it
21+
using APM_CNT_FINALIZE SMI. Used by heads to set and lock PR0 flash
22+
protection.
23+
24+
If unsure, say N.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
## SPDX-License-Identifier: GPL-2.0-only
22
ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c
3+
ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_lpc.c
4+
ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_spi.c
5+
6+
smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_lpc.c
7+
smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_spi.c

src/soc/intel/common/pch/lockdown/lockdown.c

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0-only */
22

33
#include <bootstate.h>
4-
#include <dasharo/options.h>
54
#include <intelblocks/cfg.h>
65
#include <intelblocks/fast_spi.h>
76
#include <intelblocks/lpc_lib.h>
@@ -61,56 +60,17 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown)
6160
/* Set FAST_SPI opcode menu */
6261
fast_spi_set_opcode_menu();
6362

64-
/* Discrete Lock Flash PR registers */
65-
fast_spi_pr_dlock();
66-
6763
/* Check if SPI transaction is pending */
6864
fast_spi_cycle_in_progress();
6965

7066
/* Clear any outstanding status bits like AEL, FCERR, FDONE, SAF etc. */
7167
fast_spi_clear_outstanding_status();
7268

73-
/* Lock FAST_SPIBAR */
74-
fast_spi_lock_bar();
75-
7669
/* Set Vendor Component Lock (VCL) */
7770
fast_spi_vscc0_lock();
7871

79-
/* Set BIOS Interface Lock, BIOS Lock */
80-
if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {
81-
/* BIOS Interface Lock */
82-
fast_spi_set_bios_interface_lock_down();
83-
84-
/* Only allow writes in SMM */
85-
if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) {
86-
fast_spi_set_eiss();
87-
fast_spi_enable_wp();
88-
}
89-
90-
/* BIOS Lock */
91-
fast_spi_set_lock_enable();
92-
93-
/* EXT BIOS Lock */
94-
fast_spi_set_ext_bios_lock_enable();
95-
}
96-
}
97-
98-
static void lpc_lockdown_config(int chipset_lockdown)
99-
{
100-
/* Set BIOS Interface Lock, BIOS Lock */
101-
if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {
102-
/* BIOS Interface Lock */
103-
lpc_set_bios_interface_lock_down();
104-
105-
/* Only allow writes in SMM */
106-
if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) {
107-
lpc_set_eiss();
108-
lpc_enable_wp();
109-
}
110-
111-
/* BIOS Lock */
112-
lpc_set_lock_enable();
113-
}
72+
if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM))
73+
fast_spi_lockdown_bios(chipset_lockdown);
11474
}
11575

11676
static void sa_lockdown_config(int chipset_lockdown)
@@ -136,8 +96,9 @@ static void platform_lockdown_config(void *unused)
13696
/* SPI lock down configuration */
13797
fast_spi_lockdown_cfg(chipset_lockdown);
13898

139-
/* LPC/eSPI lock down configuration */
140-
lpc_lockdown_config(chipset_lockdown);
99+
if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM))
100+
/* LPC/eSPI lock down configuration */
101+
lpc_lockdown_config(chipset_lockdown);
141102

142103
/* GPMR lock down configuration */
143104
gpmr_lockdown_cfg();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#include <dasharo/options.h>
4+
#include <intelblocks/cfg.h>
5+
#include <intelblocks/lpc_lib.h>
6+
#include <intelpch/lockdown.h>
7+
8+
void lpc_lockdown_config(int chipset_lockdown)
9+
{
10+
/* Set BIOS Interface Lock, BIOS Lock */
11+
if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {
12+
/* BIOS Interface Lock */
13+
lpc_set_bios_interface_lock_down();
14+
15+
/* Only allow writes in SMM */
16+
if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) {
17+
lpc_set_eiss();
18+
lpc_enable_wp();
19+
}
20+
21+
/* BIOS Lock */
22+
lpc_set_lock_enable();
23+
}
24+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#include <dasharo/options.h>
4+
#include <intelblocks/cfg.h>
5+
#include <intelblocks/fast_spi.h>
6+
#include <intelpch/lockdown.h>
7+
8+
void fast_spi_lockdown_bios(int chipset_lockdown)
9+
{
10+
/* Discrete Lock Flash PR registers */
11+
fast_spi_pr_dlock();
12+
13+
/* Lock FAST_SPIBAR */
14+
fast_spi_lock_bar();
15+
16+
/* Set BIOS Interface Lock, BIOS Lock */
17+
if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {
18+
/* BIOS Interface Lock */
19+
fast_spi_set_bios_interface_lock_down();
20+
21+
/* Only allow writes in SMM */
22+
if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) {
23+
fast_spi_set_eiss();
24+
fast_spi_enable_wp();
25+
}
26+
27+
/* BIOS Lock */
28+
fast_spi_set_lock_enable();
29+
30+
/* EXT BIOS Lock */
31+
fast_spi_set_ext_bios_lock_enable();
32+
}
33+
}

0 commit comments

Comments
 (0)