From 038cef9dffdd0df89e50799826e521b1e26b3081 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Wed, 14 Oct 2020 17:58:36 +0200 Subject: sec/intel/txt: Bail if var MTRRs cannot snugly cache the BIOS ACM When caching the BIOS ACM, one must cache less than a page (4 KiB) of unused memory past the end of the BIOS ACM. Failure to do so on Haswell will result in a lovely TXT reset with Class Code 5, Major Error Code 2. The current approach uses a single variable MTRR to cache the whole BIOS ACM. Before fighting with the variable MTRRs in assembly code, ensure that enough variable MTRRs exist to cache the BIOS ACM's size. Since the code checks that the ACM base is aligned to its size, each `one` bit in the ACM size will require one variable MTRR to properly cache the ACM. One of the several BIOS ACMs for Haswell has a size of 101504 bytes. This is 0x18c80 in hexadecimal, and 0001 1000 1100 1000 0000 in binary. After aligning up the BIOS ACM size to a page boundary, the resulting size is 0x19000 in hexadecimal, and 0001 1001 0000 0000 0000 in binary. To successfully invoke said ACM, its base must be a multiple of 0x20000 and three variable MTRRs must be used to cache the ACM. The MTRR ranges must be contiguous and cover 0x10000, 0x8000, 0x1000 bytes, in order. The assembly code is updated in a follow-up, and relies on these checks. Change-Id: I480dc3e4a9e4a59fbb73d571fd62b0257abc65b3 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/46422 Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/security/intel/txt/common.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/security') diff --git a/src/security/intel/txt/common.c b/src/security/intel/txt/common.c index e73defb912..5f8a976946 100644 --- a/src/security/intel/txt/common.c +++ b/src/security/intel/txt/common.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -266,6 +267,17 @@ int intel_txt_run_bios_acm(const u8 input_params) return -1; } + /* + * When setting up the MTRRs to cache the BIOS ACM, one must cache less than + * a page (4 KiB) of unused memory after the BIOS ACM. On Haswell, failure + * to do so will cause a TXT reset with Class Code 5, Major Error Code 2. + */ + if (popcnt(ALIGN_UP(acm_len, 4096)) > get_var_mtrr_count()) { + printk(BIOS_ERR, "TEE-TXT: Not enough MTRRs to cache this BIOS ACM's size.\n"); + rdev_munmap(&acm, acm_data); + return -1; + } + if (CONFIG(INTEL_TXT_LOGGING)) txt_dump_acm_info(acm_data); -- cgit v1.2.3