summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorEugene Myers <edmyers@tycho.nsa.gov>2020-01-21 17:01:47 -0500
committerPatrick Georgi <pgeorgi@google.com>2020-02-05 18:49:27 +0000
commitae438be57856e994774ec0e2521d49f1ad09bd6f (patch)
treeb174c6b496de3524bca2dd027c686fa5c9b5bd8b /src/cpu
parentd498e52c3f024971f342da9029fd7f11668c0a3d (diff)
downloadcoreboot-ae438be57856e994774ec0e2521d49f1ad09bd6f.tar.xz
security/intel/stm: Add STM support
This update is a combination of all four of the patches so that the commit can be done without breaking parts of coreboot. This possible breakage is because of the cross-dependencies between the original separate patches would cause failure because of data structure changes. security/intel/stm This directory contains the functions that check and move the STM to the MSEG, create its page tables, and create the BIOS resource list. The STM page tables is a six page region located in the MSEG and are pointed to by the CR3 Offset field in the MSEG header. The initial page tables will identity map all memory between 0-4G. The STM starts in IA32e mode, which requires page tables to exist at startup. The BIOS resource list defines the resources that the SMI Handler is allowed to access. This includes the SMM memory area where the SMI handler resides and other resources such as I/O devices. The STM uses the BIOS resource list to restrict the SMI handler's accesses. The BIOS resource list is currently located in the same area as the SMI handler. This location is shown in the comment section before smm_load_module in smm_module_loader.c Note: The files within security/intel/stm come directly from their Tianocore counterparts. Unnecessary code has been removed and the remaining code has been converted to meet coreboot coding requirements. For more information see: SMI Transfer Monitor (STM) User Guide, Intel Corp., August 2015, Rev 1.0, can be found at firmware.intel.com include/cpu/x86: Addtions to include/cpu/x86 for STM support. cpu/x86: STM Set up - The STM needs to be loaded into the MSEG during BIOS initialization and the SMM Monitor Control MSR be set to indicate that an STM is in the system. cpu/x86/smm: SMI module loader modifications needed to set up the SMM descriptors used by the STM during its initialization Change-Id: If4adcd92c341162630ce1ec357ffcf8a135785ec Signed-off-by: Eugene D. Myers <edmyers@tycho.nsa.gov> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33234 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com> Reviewed-by: ron minnich <rminnich@gmail.com>
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/x86/mp_init.c34
-rw-r--r--src/cpu/x86/smm/smm_module_loader.c19
-rw-r--r--src/cpu/x86/smm/smm_stub.S13
3 files changed, 65 insertions, 1 deletions
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c
index b093be7003..331f3b552a 100644
--- a/src/cpu/x86/mp_init.c
+++ b/src/cpu/x86/mp_init.c
@@ -38,6 +38,8 @@
#include <timer.h>
#include <thread.h>
+#include <security/intel/stm/SmmStm.h>
+
#define MAX_APIC_IDS 256
struct mp_callback {
@@ -743,6 +745,23 @@ static void asmlinkage smm_do_relocation(void *arg)
/* Setup code checks this callback for validity. */
mp_state.ops.relocation_handler(cpu, curr_smbase, perm_smbase);
+
+ if (CONFIG(STM)) {
+ if (is_smm_enabled()) {
+ uintptr_t mseg;
+
+ mseg = mp_state.perm_smbase +
+ (mp_state.perm_smsize - CONFIG_MSEG_SIZE);
+
+ stm_setup(mseg, p->cpu, runtime->num_cpus,
+ perm_smbase,
+ mp_state.perm_smbase,
+ runtime->start32_offset);
+ } else {
+ printk(BIOS_DEBUG,
+ "STM not loaded because SMM is not enabled!\n");
+ }
+ }
}
static void adjust_smm_apic_id_map(struct smm_loader_params *smm_params)
@@ -1023,6 +1042,21 @@ static void fill_mp_state(struct mp_state *state, const struct mp_ops *ops)
&state->smm_save_state_size);
/*
+ * Make sure there is enough room for the SMM descriptor
+ */
+ if (CONFIG(STM))
+ state->smm_save_state_size +=
+ sizeof(TXT_PROCESSOR_SMM_DESCRIPTOR);
+
+ /* Currently, the CPU SMM save state size is based on a simplistic
+ * algorithm. (align on 4K)
+ * note: In the future, this will need to handle newer x86 processors
+ * that require alignment of the save state on 32K boundaries.
+ */
+ state->smm_save_state_size =
+ ALIGN_UP(state->smm_save_state_size, 0x1000);
+
+ /*
* Default to smm_initiate_relocation() if trigger callback isn't
* provided.
*/
diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c
index c6c6b38737..a421436893 100644
--- a/src/cpu/x86/smm/smm_module_loader.c
+++ b/src/cpu/x86/smm/smm_module_loader.c
@@ -17,6 +17,7 @@
#include <cpu/x86/cache.h>
#include <commonlib/helpers.h>
#include <console/console.h>
+#include <security/intel/stm/SmmStm.h>
#define FXSAVE_SIZE 512
@@ -267,6 +268,7 @@ static int smm_module_setup_stub(void *smbase, struct smm_loader_params *params,
stub_params->fxsave_area_size = FXSAVE_SIZE;
stub_params->runtime.smbase = (uintptr_t)smbase;
stub_params->runtime.save_state_size = params->per_cpu_save_state_size;
+ stub_params->runtime.num_cpus = params->num_concurrent_stacks;
/* Initialize the APIC id to CPU number table to be 1:1 */
for (i = 0; i < params->num_concurrent_stacks; i++)
@@ -313,6 +315,11 @@ int smm_setup_relocation_handler(struct smm_loader_params *params)
* +-----------------+ <- smram + size
* | stacks |
* +-----------------+ <- smram + size - total_stack_size
+ * | fxsave area |
+ * +-----------------+ <- smram + size - total_stack_size - fxsave_size
+ * | BIOS resource |
+ * | list (STM) |
+ * +-----------------+ <- .. - CONFIG_BIOS_RESOURCE_LIST_SIZE
* | ... |
* +-----------------+ <- smram + handler_size + SMM_DEFAULT_SIZE
* | handler |
@@ -353,7 +360,12 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
/* Stacks start at the top of the region. */
base = smram;
- base += size;
+
+ if (CONFIG(STM))
+ base += size - CONFIG_MSEG_SIZE; // take out the mseg
+ else
+ base += size;
+
params->stack_top = base;
/* SMM module starts at offset SMM_DEFAULT_SIZE with the load alignment
@@ -382,6 +394,11 @@ int smm_load_module(void *smram, size_t size, struct smm_loader_params *params)
/* Does the required amount of memory exceed the SMRAM region size? */
total_size = total_stack_size + handler_size;
total_size += fxsave_size + SMM_DEFAULT_SIZE;
+
+ // account for the bios resource list
+ if (CONFIG(STM))
+ total_size += CONFIG_BIOS_RESOURCE_LIST_SIZE;
+
if (total_size > size)
return -1;
diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S
index f0e55f9a18..8207d233a0 100644
--- a/src/cpu/x86/smm/smm_stub.S
+++ b/src/cpu/x86/smm/smm_stub.S
@@ -44,6 +44,11 @@ smbase:
.long 0
save_state_size:
.long 0
+num_cpus:
+.long 0
+/* allows the STM to bring up SMM in 32-bit mode */
+start32_offset:
+.long smm_trampoline32 - _start
/* apic_to_cpu_num is a table mapping the default APIC id to CPU num. If the
* APIC id is found at the given index, the contiguous CPU number is index
* into the table. */
@@ -90,6 +95,14 @@ smm_relocate_gdt:
/* gdt selector 0x10, flat data segment */
.word 0xffff, 0x0000
.byte 0x00, 0x93, 0xcf, 0x00
+
+ /* gdt selector 0x18, flat code segment (64-bit) */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x9b, 0xcf, 0x00
+
+ /* gdt selector 0x20 tss segment */
+ .word 0xffff, 0x0000
+ .byte 0x00, 0x8b, 0x80, 0x00
smm_relocate_gdt_end:
.align 4