Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
intel/txt: Add `txt_get_chipset_dpr` function
Due to platform-specific constraints, it is not possible to enable DPR by programming the MCH's DPR register in ramstage. Instead, assume it has been programmed earlier and check that its value is valid. If it is, then simply configure DPR in TXT public base with the same parameters. Note that some bits only exist on MCH DPR, and thus need to be cleared.
Implement this function on most client platforms. For Skylake and newer, place it in common System Agent code. Also implement it for Haswell, for which the rest of Intel TXT support will be added in subsequent commits.
Do not error out if DPR is larger than expected. On some platforms, such as Haswell, MRC decides the size of DPR, and cannot be changed easily. Reimplementing MRC is easier than working around its limitations anyway.
Change-Id: I391383fb03bd6636063964ff249c75028e0644cf Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/northbridge/intel/haswell/memmap.c M src/security/intel/txt/ramstage.c A src/security/intel/txt/txt_platform.h M src/soc/intel/common/block/systemagent/systemagent_early.c 4 files changed, 60 insertions(+), 10 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/90/46490/1
diff --git a/src/northbridge/intel/haswell/memmap.c b/src/northbridge/intel/haswell/memmap.c index ac36e25..02d120b 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 @@ 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 @@ */ 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 263bc9d..f532a2f 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 @@ 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 0000000..8881cab --- /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 ffb6404..53d6077 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 @@ { 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) }; +}
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
Patch Set 1: Code-Review+2
(2 comments)
https://review.coreboot.org/c/coreboot/+/46490/1/src/security/intel/txt/rams... File src/security/intel/txt/ramstage.c:
https://review.coreboot.org/c/coreboot/+/46490/1/src/security/intel/txt/rams... PS1, Line 237: MCH SA?
https://review.coreboot.org/c/coreboot/+/46490/1/src/soc/intel/common/block/... File src/soc/intel/common/block/systemagent/systemagent_early.c:
https://review.coreboot.org/c/coreboot/+/46490/1/src/soc/intel/common/block/... PS1, Line 153: SA_DEV_ROOT On xeon_sp you have multiple SA (not sure on the terminology but they call it IIOs), on different PCI busses. Maybe add a TODO/NOTE comment?
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/c/coreboot/+/46490/1/src/security/intel/txt/rams... File src/security/intel/txt/ramstage.c:
https://review.coreboot.org/c/coreboot/+/46490/1/src/security/intel/txt/rams... PS1, Line 237: MCH
SA?
x4x supports TXT (or can support, at least) and doesn't have a SA.
https://review.coreboot.org/c/coreboot/+/46490/1/src/soc/intel/common/block/... File src/soc/intel/common/block/systemagent/systemagent_early.c:
https://review.coreboot.org/c/coreboot/+/46490/1/src/soc/intel/common/block/... PS1, Line 153: SA_DEV_ROOT
On xeon_sp you have multiple SA (not sure on the terminology but they call it IIOs), on different PC […]
Do any of the registers above apply to Xeon-SP? I doubt this works for anything but client platforms.
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/c/coreboot/+/46490/1/src/soc/intel/common/block/... File src/soc/intel/common/block/systemagent/systemagent_early.c:
https://review.coreboot.org/c/coreboot/+/46490/1/src/soc/intel/common/block/... PS1, Line 153: SA_DEV_ROOT
Do any of the registers above apply to Xeon-SP? I doubt this works for anything but client platforms.
No it's on xx:05.0 reg 0x290. The semantics of the DPR reg seem to be the same.
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/c/coreboot/+/46490/1/src/security/intel/txt/rams... File src/security/intel/txt/ramstage.c:
https://review.coreboot.org/c/coreboot/+/46490/1/src/security/intel/txt/rams... PS1, Line 237: MCH
x4x supports TXT (or can support, at least) and doesn't have a SA.
Done
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
Patch Set 1: Code-Review+2
Philipp Deppenwiese has submitted this change. ( https://review.coreboot.org/c/coreboot/+/46490 )
Change subject: intel/txt: Add `txt_get_chipset_dpr` function ......................................................................
intel/txt: Add `txt_get_chipset_dpr` function
Due to platform-specific constraints, it is not possible to enable DPR by programming the MCH's DPR register in ramstage. Instead, assume it has been programmed earlier and check that its value is valid. If it is, then simply configure DPR in TXT public base with the same parameters. Note that some bits only exist on MCH DPR, and thus need to be cleared.
Implement this function on most client platforms. For Skylake and newer, place it in common System Agent code. Also implement it for Haswell, for which the rest of Intel TXT support will be added in subsequent commits.
Do not error out if DPR is larger than expected. On some platforms, such as Haswell, MRC decides the size of DPR, and cannot be changed easily. Reimplementing MRC is easier than working around its limitations anyway.
Change-Id: I391383fb03bd6636063964ff249c75028e0644cf Signed-off-by: Angel Pons th3fanbus@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/46490 Reviewed-by: Arthur Heymans arthur@aheymans.xyz Reviewed-by: Patrick Rudolph siro@das-labor.org Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/northbridge/intel/haswell/memmap.c M src/security/intel/txt/ramstage.c A src/security/intel/txt/txt_platform.h M src/soc/intel/common/block/systemagent/systemagent_early.c 4 files changed, 60 insertions(+), 10 deletions(-)
Approvals: build bot (Jenkins): Verified Patrick Rudolph: Looks good to me, approved Arthur Heymans: Looks good to me, approved
diff --git a/src/northbridge/intel/haswell/memmap.c b/src/northbridge/intel/haswell/memmap.c index ac36e25..02d120b 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 @@ 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 @@ */ 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 263bc9d..f532a2f 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 @@ 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 0000000..8881cab --- /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 ffb6404..53d6077 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 @@ { 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) }; +}