Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
sec/intel/txt: Add support for running SCLEAN in romstage
SCLEAN has specific requirements and needs to run in early romstage, since the DRAM would be locked when SCLEAN needs to be executed.
Change-Id: I77b237342e0c98eda974f87944f1948d197714db Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/security/intel/txt/Makefile.inc A src/security/intel/txt/getsec_sclean.S M src/security/intel/txt/txt_getsec.h 3 files changed, 187 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/07/46607/1
diff --git a/src/security/intel/txt/Makefile.inc b/src/security/intel/txt/Makefile.inc index 39c3ad1..64726cd 100644 --- a/src/security/intel/txt/Makefile.inc +++ b/src/security/intel/txt/Makefile.inc @@ -1,5 +1,7 @@ ifeq ($(CONFIG_INTEL_TXT),y)
+romstage-y += getsec_sclean.S + romstage-y += common.c romstage-$(CONFIG_INTEL_TXT_LOGGING) += logging.c
diff --git a/src/security/intel/txt/getsec_sclean.S b/src/security/intel/txt/getsec_sclean.S new file mode 100644 index 0000000..bf64215 --- /dev/null +++ b/src/security/intel/txt/getsec_sclean.S @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/x86/cr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/msr.h> + +#include "getsec_mtrr_setup.S" + +#define MTRR_HIGH_MASK $((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1) + +#define NO_EVICT_MODE 0x2e0 + +.align 4 +.text + +/* + * void getsec_sclean(const uint32_t acm_base, const uint32_t acm_size); + */ +.global getsec_sclean +getsec_sclean: + + /* + * At this point, it is certain that the BIOS ACM will be run. + * This requires tearing down CAR, which cannot be undone. + * + * From here onwards, the only way out is to reset the system. + */ + + /* Enable SMXE, SSE and debug extensions */ + movl %cr4, %eax + orl $(CR4_OSFXSR | CR4_DE | CR4_SMXE), %eax + movl %eax, %cr4 + + /* + * Save arguments into SSE registers. We need to tear down CAR + * before launching the BIOS ACM, which will destroy the stack. + */ + movd 8(%esp), %xmm2 /* acm_base */ + movd 12(%esp), %xmm3 /* acm_size */ + + /* Disable cache */ + movl %cr0, %eax + orl $(CR0_CD | CR0_NE), %eax + andl $(~(CR0_NW)), %eax + movl %eax, %cr0 + + /* Invalidate the cache */ + invd + + /* Disable MTRRs */ + movl $(MTRR_DEF_TYPE_MSR), %ecx + xorl %eax, %eax + xorl %edx, %edx + wrmsr + + /* Disable NEM, needs to be done in two steps */ + movl $NO_EVICT_MODE, %ecx + rdmsr + andl $~2, %eax /* Clear NEM Run bit */ + wrmsr + andl $~1, %eax /* Clear NEM Setup bit */ + wrmsr + + /* Invalidate the cache, again */ + invd + + /* + * Clear variable MTRRs + * Chapter 2.2.5.1 + * Intel TXT Software Development Guide (Document: 315168-015) + */ + movl $(MTRR_CAP_MSR), %ecx + rdmsr + andl $(0xff), %eax + movl %eax, %ebx + + xorl %eax, %eax + xorl %edx, %edx + + jmp cond_clear_var_mtrrs + +body_clear_var_mtrrs: + + decl %ebx + movl %ebx, %ecx + shll %ecx + addl $(MTRR_PHYS_BASE(0)), %ecx + wrmsr + incl %ecx /* MTRR_PHYS_MASK */ + wrmsr + +cond_clear_var_mtrrs: + + cmpl $0, %ebx + jnz body_clear_var_mtrrs + + /* + * Setup BIOS ACM as WB + * Chapter A.1.1 + * Intel TXT Software Development Guide (Document: 315168-015) + */ + + /* Determine size of AC module */ + movd %xmm2, %eax /* acm_base */ + movd %xmm3, %ebx /* acm_size */ + + /* Round up to page size */ + addl $(0xfff), %ebx + andl $(~0xfff), %ebx /* Aligned to a page (4 KiB) */ + + /* Use SSE registers to store local variables */ + movd %eax, %xmm0 + movd %ebx, %xmm1 + + /* + * Important note: The MTRRs must cache less than a page (4 KiB) + * of unused memory after the BIOS ACM. Failure to do so will + * result in a TXT reset with Class Code 5, Major Error Code 2. + * + * The caller must have checked that there are enough variable + * MTRRs to cache the ACM size prior to invoking this routine. + */ + SET_UP_MTRRS_FOR_BIOS_ACM + + /* Enable variable MTRRs */ + movl $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + orl $MTRR_DEF_TYPE_EN, %eax + wrmsr + + /* Enable cache - CR0_NW is and stays clear */ + movl %cr0, %eax + andl $~(CR0_CD), %eax + movl %eax, %cr0 + + /* + * Get function arguments. + * It's important to pass the exact ACM size as it's used by getsec to verify + * the integrity of ACM. Unlike the size for MTRR programming, which needs to + * be power of two. + * + * Note: Do not forget that CAR has been torn down, so the stack doesn't exist. + */ + movl $2, %eax /* GETSEC[ENTERACCS] */ + movd %xmm2, %ebx /* acm_base */ + movd %xmm3, %ecx /* acm_size */ + movl $0, %edx /* reserved, must be zero */ + movl $0, %edi /* must be zero */ + movl $0, %esi /* SCLEAN */ + + getsec + + /* + * The platform state after SCLEAN is undefined. The only sane + * thing to do afterwards is to reset the platform. Note that + * the BIOS ACM should already reset the platform, so this code + * may not always be reached, but keep it here just to be sure. + */ +#if 1 + movw $0xcf8, %dx + movl $0x8000F8AC, %eax + outl %eax, %dx + + movw $0xcfc, %dx + inl %dx, %eax + andl $~(1 << 20), %eax + outl %eax, %dx +#endif + + movw $0xcf9, %dx + movb $0, %al + outb %al, %dx + + movw $0xcf9, %dx + movb $0x0e, %al + outb %al, %dx + + cli + + hlt + + ret diff --git a/src/security/intel/txt/txt_getsec.h b/src/security/intel/txt/txt_getsec.h index 78171a7..f949c7d 100644 --- a/src/security/intel/txt/txt_getsec.h +++ b/src/security/intel/txt/txt_getsec.h @@ -20,4 +20,7 @@ const uint32_t acm_base, const uint32_t acm_size);
+void getsec_sclean(const uint32_t acm_base, + const uint32_t acm_size); + #endif /* SECURITY_INTEL_TXT_REGISTER_H_ */
Hello Philipp Deppenwiese, Patrick Georgi, Martin Roth, Patrick Rudolph, Christian Walter, Arthur Heymans,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/46607
to look at the new patch set (#2).
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
sec/intel/txt: Add support for running SCLEAN in romstage
SCLEAN has specific requirements and needs to run in early romstage, since the DRAM would be locked when SCLEAN needs to be executed.
Change-Id: I77b237342e0c98eda974f87944f1948d197714db Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/security/intel/txt/Makefile.inc A src/security/intel/txt/getsec_sclean.S M src/security/intel/txt/txt_getsec.h 3 files changed, 186 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/07/46607/2
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Patrick Rudolph, Christian Walter, Arthur Heymans,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/46607
to look at the new patch set (#3).
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
sec/intel/txt: Add support for running SCLEAN in romstage
SCLEAN has specific requirements and needs to run in early romstage, since the DRAM would be locked when SCLEAN needs to be executed.
Change-Id: I77b237342e0c98eda974f87944f1948d197714db Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/security/intel/txt/Makefile.inc A src/security/intel/txt/getsec_sclean.S M src/security/intel/txt/txt_getsec.h 3 files changed, 186 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/07/46607/3
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
Patch Set 3:
(1 comment)
https://review.coreboot.org/c/coreboot/+/46607/3/src/security/intel/txt/gets... File src/security/intel/txt/getsec_sclean.S:
https://review.coreboot.org/c/coreboot/+/46607/3/src/security/intel/txt/gets... PS3, Line 55: needs This code make platforms specific assumptions, which it shouldn't.
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
Patch Set 3:
(1 comment)
https://review.coreboot.org/c/coreboot/+/46607/3/src/security/intel/txt/gets... File src/security/intel/txt/getsec_sclean.S:
https://review.coreboot.org/c/coreboot/+/46607/3/src/security/intel/txt/gets... PS3, Line 55: needs
This code make platforms specific assumptions, which it shouldn't.
SNB, BYT, HSW, BDW, SKL, KBL all require this to be done in two separate steps, as per BWGs. Since this code is only necessary on LT-CX, I think it's a reasonable assumption.
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
Patch Set 5:
(1 comment)
https://review.coreboot.org/c/coreboot/+/46607/3/src/security/intel/txt/gets... File src/security/intel/txt/getsec_sclean.S:
https://review.coreboot.org/c/coreboot/+/46607/3/src/security/intel/txt/gets... PS3, Line 55: needs
SNB, BYT, HSW, BDW, SKL, KBL all require this to be done in two separate steps, as per BWGs. […]
Ack
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
Patch Set 5: Code-Review+2
(1 comment)
https://review.coreboot.org/c/coreboot/+/46607/5/src/security/intel/txt/gets... File src/security/intel/txt/getsec_sclean.S:
https://review.coreboot.org/c/coreboot/+/46607/5/src/security/intel/txt/gets... PS5, Line 117: Class Code 5, Major Error Code 2. Specify that this the case on at least Haswell?
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Patrick Rudolph, Christian Walter, Arthur Heymans,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/46607
to look at the new patch set (#6).
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
sec/intel/txt: Add support for running SCLEAN in romstage
SCLEAN has specific requirements and needs to run in early romstage, since the DRAM would be locked when SCLEAN needs to be executed.
Change-Id: I77b237342e0c98eda974f87944f1948d197714db Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/security/intel/txt/Makefile.inc A src/security/intel/txt/getsec_sclean.S M src/security/intel/txt/txt_getsec.h 3 files changed, 186 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/07/46607/6
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
Patch Set 6:
(1 comment)
https://review.coreboot.org/c/coreboot/+/46607/5/src/security/intel/txt/gets... File src/security/intel/txt/getsec_sclean.S:
https://review.coreboot.org/c/coreboot/+/46607/5/src/security/intel/txt/gets... PS5, Line 117: Class Code 5, Major Error Code 2.
Specify that this the case on at least Haswell?
Done
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
Patch Set 6: Code-Review+2
Angel Pons has submitted this change. ( https://review.coreboot.org/c/coreboot/+/46607 )
Change subject: sec/intel/txt: Add support for running SCLEAN in romstage ......................................................................
sec/intel/txt: Add support for running SCLEAN in romstage
SCLEAN has specific requirements and needs to run in early romstage, since the DRAM would be locked when SCLEAN needs to be executed.
Change-Id: I77b237342e0c98eda974f87944f1948d197714db Signed-off-by: Angel Pons th3fanbus@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/46607 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Arthur Heymans arthur@aheymans.xyz --- M src/security/intel/txt/Makefile.inc A src/security/intel/txt/getsec_sclean.S M src/security/intel/txt/txt_getsec.h 3 files changed, 186 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Arthur Heymans: Looks good to me, approved
diff --git a/src/security/intel/txt/Makefile.inc b/src/security/intel/txt/Makefile.inc index 712ab58..762256f 100644 --- a/src/security/intel/txt/Makefile.inc +++ b/src/security/intel/txt/Makefile.inc @@ -1,5 +1,7 @@ ifeq ($(CONFIG_INTEL_TXT),y)
+romstage-y += getsec_sclean.S + romstage-y += common.c romstage-$(CONFIG_INTEL_TXT_LOGGING) += logging.c
diff --git a/src/security/intel/txt/getsec_sclean.S b/src/security/intel/txt/getsec_sclean.S new file mode 100644 index 0000000..e240a2f --- /dev/null +++ b/src/security/intel/txt/getsec_sclean.S @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/x86/cr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/msr.h> + +#include "getsec_mtrr_setup.inc" + +#define MTRR_HIGH_MASK $((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1) + +#define NO_EVICT_MODE 0x2e0 + +.align 4 +.text + +/* + * void getsec_sclean(const uint32_t acm_base, const uint32_t acm_size); + */ +.global getsec_sclean +getsec_sclean: + /* + * At this point, it is certain that the BIOS ACM will be run. + * This requires tearing down CAR, which cannot be undone. + * + * From here onwards, the only way out is to reset the system. + */ + + /* Enable SMXE, SSE and debug extensions */ + movl %cr4, %eax + orl $(CR4_OSFXSR | CR4_DE | CR4_SMXE), %eax + movl %eax, %cr4 + + /* + * Save arguments into SSE registers. We need to tear down CAR + * before launching the BIOS ACM, which will destroy the stack. + */ + movd 4(%esp), %xmm2 /* acm_base */ + movd 8(%esp), %xmm3 /* acm_size */ + + /* Disable cache */ + movl %cr0, %eax + orl $(CR0_CD | CR0_NE), %eax + andl $(~(CR0_NW)), %eax + movl %eax, %cr0 + + /* Invalidate the cache */ + invd + + /* Disable MTRRs */ + movl $(MTRR_DEF_TYPE_MSR), %ecx + xorl %eax, %eax + xorl %edx, %edx + wrmsr + + /* Disable NEM, needs to be done in two steps */ + movl $NO_EVICT_MODE, %ecx + rdmsr + andl $~2, %eax /* Clear NEM Run bit */ + wrmsr + andl $~1, %eax /* Clear NEM Setup bit */ + wrmsr + + /* Invalidate the cache, again */ + invd + + /* + * Clear variable MTRRs + * Chapter 2.2.5.1 + * Intel TXT Software Development Guide (Document: 315168-015) + */ + movl $(MTRR_CAP_MSR), %ecx + rdmsr + andl $(0xff), %eax + movl %eax, %ebx + + xorl %eax, %eax + xorl %edx, %edx + + jmp cond_clear_var_mtrrs + +body_clear_var_mtrrs: + + decl %ebx + movl %ebx, %ecx + shll %ecx + addl $(MTRR_PHYS_BASE(0)), %ecx + wrmsr + incl %ecx /* MTRR_PHYS_MASK */ + wrmsr + +cond_clear_var_mtrrs: + + cmpl $0, %ebx + jnz body_clear_var_mtrrs + + /* + * Setup BIOS ACM as WB + * Chapter A.1.1 + * Intel TXT Software Development Guide (Document: 315168-015) + */ + + /* Determine size of AC module */ + movd %xmm2, %eax /* acm_base */ + movd %xmm3, %ebx /* acm_size */ + + /* Round up to page size */ + addl $(0xfff), %ebx + andl $(~0xfff), %ebx /* Aligned to a page (4 KiB) */ + + /* Use SSE registers to store local variables */ + movd %eax, %xmm0 + movd %ebx, %xmm1 + + /* + * Important note: The MTRRs must cache less than a page (4 KiB) + * of unused memory after the BIOS ACM. Not doing so on Haswell + * will cause a TXT reset with Class Code 5, Major Error Code 2. + * + * The caller must have checked that there are enough variable + * MTRRs to cache the ACM size prior to invoking this routine. + */ + SET_UP_MTRRS_FOR_BIOS_ACM + + /* Enable variable MTRRs */ + movl $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + orl $MTRR_DEF_TYPE_EN, %eax + wrmsr + + /* Enable cache - CR0_NW is and stays clear */ + movl %cr0, %eax + andl $~(CR0_CD), %eax + movl %eax, %cr0 + + /* + * Get function arguments. + * It's important to pass the exact ACM size as it's used by getsec to verify + * the integrity of ACM. Unlike the size for MTRR programming, which needs to + * be power of two. + * + * Note: Do not forget that CAR has been torn down, so the stack doesn't exist. + */ + movl $2, %eax /* GETSEC[ENTERACCS] */ + movd %xmm2, %ebx /* acm_base */ + movd %xmm3, %ecx /* acm_size */ + movl $0, %edx /* reserved, must be zero */ + movl $0, %edi /* must be zero */ + movl $0, %esi /* SCLEAN */ + + getsec + + /* + * The platform state after SCLEAN is undefined. The only sane + * thing to do afterwards is to reset the platform. Note that + * the BIOS ACM should already reset the platform, so this code + * may not always be reached, but keep it here just to be sure. + */ +#if 1 + movw $0xcf8, %dx + movl $0x8000F8AC, %eax + outl %eax, %dx + + movw $0xcfc, %dx + inl %dx, %eax + andl $~(1 << 20), %eax + outl %eax, %dx +#endif + + movw $0xcf9, %dx + movb $0, %al + outb %al, %dx + + movw $0xcf9, %dx + movb $0x0e, %al + outb %al, %dx + + cli + + hlt + + ret diff --git a/src/security/intel/txt/txt_getsec.h b/src/security/intel/txt/txt_getsec.h index 78171a7..f949c7d 100644 --- a/src/security/intel/txt/txt_getsec.h +++ b/src/security/intel/txt/txt_getsec.h @@ -20,4 +20,7 @@ const uint32_t acm_base, const uint32_t acm_size);
+void getsec_sclean(const uint32_t acm_base, + const uint32_t acm_size); + #endif /* SECURITY_INTEL_TXT_REGISTER_H_ */