diff options
-rw-r--r-- | src/northbridge/intel/haswell/memmap.c | 10 | ||||
-rw-r--r-- | src/security/intel/txt/ramstage.c | 41 | ||||
-rw-r--r-- | src/security/intel/txt/txt_platform.h | 12 | ||||
-rw-r--r-- | src/soc/intel/common/block/systemagent/systemagent_early.c | 7 |
4 files changed, 60 insertions, 10 deletions
diff --git a/src/northbridge/intel/haswell/memmap.c b/src/northbridge/intel/haswell/memmap.c index ac36e25999..02d120b119 100644 --- a/src/northbridge/intel/haswell/memmap.c +++ b/src/northbridge/intel/haswell/memmap.c @@ -9,6 +9,7 @@ #include <cpu/x86/smm.h> #include <device/pci_ops.h> #include <cbmem.h> +#include <security/intel/txt/txt_platform.h> #include <security/intel/txt/txt_register.h> #include "haswell.h" @@ -23,6 +24,11 @@ static size_t northbridge_get_tseg_size(void) return CONFIG_SMM_TSEG_SIZE; } +union dpr_register txt_get_chipset_dpr(void) +{ + return (union dpr_register) { .raw = pci_read_config32(HOST_BRIDGE, DPR) }; +} + /* * Return the topmost memory address below 4 GiB available for general * use, from software's view of memory. Do not confuse this with TOLUD, @@ -39,9 +45,7 @@ static uintptr_t top_of_low_usable_memory(void) */ uintptr_t tolum = northbridge_get_tseg_base(); - const union dpr_register dpr = { - .raw = pci_read_config32(HOST_BRIDGE, DPR), - }; + const union dpr_register dpr = txt_get_chipset_dpr(); /* Subtract DMA Protected Range size if enabled */ if (dpr.epm) diff --git a/src/security/intel/txt/ramstage.c b/src/security/intel/txt/ramstage.c index 263bc9daa6..f532a2fbd8 100644 --- a/src/security/intel/txt/ramstage.c +++ b/src/security/intel/txt/ramstage.c @@ -13,6 +13,7 @@ #include <types.h> #include "txt.h" +#include "txt_platform.h" #include "txt_register.h" #include "txt_getsec.h" @@ -233,16 +234,42 @@ static void lockdown_intel_txt(void *unused) printk(BIOS_INFO, "TEE-TXT: DPR capable %x\n", dpr_capable); if (dpr_capable) { - /* Protect 3 MiB below TSEG and lock register */ - union dpr_register dpr = { - .lock = 1, - .size = 3, - .top = tseg_base / MiB, - }; - write64((void *)TXT_DPR, dpr.raw); + /* Verify the DPR settings on the MCH and mirror them to TXT public space */ + union dpr_register dpr = txt_get_chipset_dpr(); + + printk(BIOS_DEBUG, "TEE-TXT: MCH DPR 0x%08x\n", dpr.raw); + + printk(BIOS_DEBUG, "TEE-TXT: MCH DPR base @ 0x%08x size %u MiB\n", + (dpr.top - dpr.size) * MiB, dpr.size); // DPR TODO: implement SA_ENABLE_DPR in the intelblocks + if (!dpr.lock) { + printk(BIOS_ERR, "TEE-TXT: MCH DPR not locked.\n"); + return; + } + + if (!dpr.epm || !dpr.prs) { + printk(BIOS_ERR, "TEE-TXT: MCH DPR protection not active.\n"); + return; + } + + if (dpr.size < 3) { + printk(BIOS_ERR, "TEE-TXT: MCH DPR configured size is too small.\n"); + return; + } + + if (dpr.top * MiB != tseg_base) { + printk(BIOS_ERR, "TEE-TXT: MCH DPR top does not equal TSEG base.\n"); + return; + } + + /* Clear reserved bits */ + dpr.prs = 0; + dpr.epm = 0; + + write64((void *)TXT_DPR, dpr.raw); + printk(BIOS_INFO, "TEE-TXT: TXT.DPR 0x%08x\n", read32((void *)TXT_DPR)); } diff --git a/src/security/intel/txt/txt_platform.h b/src/security/intel/txt/txt_platform.h new file mode 100644 index 0000000000..8881cab331 --- /dev/null +++ b/src/security/intel/txt/txt_platform.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SECURITY_INTEL_TXT_PLATFORM_H__ +#define __SECURITY_INTEL_TXT_PLATFORM_H__ + +#include <types.h> +#include "txt_register.h" + +/* Prototypes to be defined in chipset code */ +union dpr_register txt_get_chipset_dpr(void); + +#endif /* __SECURITY_INTEL_TXT_PLATFORM_H__ */ diff --git a/src/soc/intel/common/block/systemagent/systemagent_early.c b/src/soc/intel/common/block/systemagent/systemagent_early.c index ffb6404aa2..53d6077e5f 100644 --- a/src/soc/intel/common/block/systemagent/systemagent_early.c +++ b/src/soc/intel/common/block/systemagent/systemagent_early.c @@ -7,6 +7,8 @@ #include <device/device.h> #include <device/pci.h> #include <intelblocks/systemagent.h> +#include <security/intel/txt/txt_platform.h> +#include <security/intel/txt/txt_register.h> #include <soc/iomap.h> #include <soc/pci_devs.h> #include <soc/systemagent.h> @@ -145,3 +147,8 @@ size_t sa_get_tseg_size(void) { return sa_get_gsm_base() - sa_get_tseg_base(); } + +union dpr_register txt_get_chipset_dpr(void) +{ + return (union dpr_register) { .raw = pci_read_config32(SA_DEV_ROOT, DPR) }; +} |