UPSTREAM: cpu/x86/smm: Add sinkhole mitigation to relocatable smmstub

The sinkhole exploit exists in placing the lapic base such that it
messes with GDT. This can be mitigated by checking the lapic MSR
against the current program counter.

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37289
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Original-Change-Id: I49927c4f4218552b732bac8aae551d845ad7f079
GitOrigin-RevId: 95af254e116802490481c6293ae752f5b61e561b
Change-Id: Ia6f8fb8beac116b9ee9ba7dd0df30cbf5a598c03
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/3581091
Tested-by: CopyBot Service Account <copybot.service@gmail.com>
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Commit-Queue: Jack Rosenthal <jrosenth@chromium.org>
diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S
index c83839c..02532a4 100644
--- a/src/cpu/x86/smm/smm_stub.S
+++ b/src/cpu/x86/smm/smm_stub.S
@@ -45,10 +45,49 @@
 	(CR0_CD | CR0_NW | CR0_PG | CR0_AM | CR0_WP | \
 	 CR0_NE | CR0_TS | CR0_EM | CR0_MP)
 
+#define SMM_DEFAULT_SIZE 0x10000
+
 .text
 .code16
 .global _start
 _start:
+smm_handler_start:
+#if CONFIG(SMM_LAPIC_REMAP_MITIGATION)
+	/* Check if the LAPIC register block overlaps with the stub.
+	 * This block needs to work without data accesses because they
+	 * may be routed into the LAPIC register block.
+	 * Code accesses, on the other hand, are never routed to LAPIC,
+	 * which is what makes this work in the first place.
+	 */
+	mov	$LAPIC_BASE_MSR, %ecx
+	rdmsr
+	and	$(~0xfff), %eax
+	call	1f
+	/* Get the current program counter */
+1:
+	pop	%ebx
+	sub	%ebx, %eax
+	cmp	$(SMM_DEFAULT_SIZE), %eax
+	ja	untampered_lapic
+1:
+#if CONFIG(CONSOLE_SERIAL)
+	/* emit "Crash" on serial */
+	mov	$(CONFIG_TTYS0_BASE), %dx
+	mov	$'C', %al
+	out	%al, (%dx)
+	mov	$'r', %al
+	out	%al, (%dx)
+	mov	$'a', %al
+	out	%al, (%dx)
+	mov	$'s', %al
+	out	%al, (%dx)
+	mov	$'h', %al
+	out	%al, (%dx)
+#endif /* CONFIG_CONSOLE_SERIAL */
+	/* now crash for real */
+	ud2
+untampered_lapic:
+#endif
 	movl	$(smm_relocate_gdt), %ebx
 	lgdtl	(%ebx)