summaryrefslogtreecommitdiff
path: root/src/cpu/x86/smm
diff options
context:
space:
mode:
authorRobert Zieba <robertzieba@google.com>2022-09-07 16:25:15 -0600
committerMartin L Roth <gaumless@gmail.com>2023-03-05 15:31:07 +0000
commitac8c378777d861000d82eea1c7439f16dcd45797 (patch)
tree58dafb5dd844410cec91e56c6f7ec5c8defd8fd5 /src/cpu/x86/smm
parentf1a4cffc88d8a5490c444f41b60eaaf544399998 (diff)
cpu/x86/smm: Add PCI resource store functionality
In certain cases data within protected memmory areas like SMRAM could be leaked or modified if an attacker remaps PCI BARs to point within that area. Add support to the existing SMM runtime to allow storing PCI resources in SMRAM and then later retrieving them. BRANCH=guybrush BUG=b:186792595 TEST=builds Signed-off-by: Robert Zieba <robertzieba@google.com> Change-Id: I23fb1e935dd1b89f1cc5c834cc2025f0fe5fda37 Reviewed-on: https://review.coreboot.org/c/coreboot/+/67931 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
Diffstat (limited to 'src/cpu/x86/smm')
-rw-r--r--src/cpu/x86/smm/Makefile.inc3
-rw-r--r--src/cpu/x86/smm/pci_resource_store.c73
-rw-r--r--src/cpu/x86/smm/smm_module_handler.c7
-rw-r--r--src/cpu/x86/smm/smm_module_loader.c3
4 files changed, 86 insertions, 0 deletions
diff --git a/src/cpu/x86/smm/Makefile.inc b/src/cpu/x86/smm/Makefile.inc
index 327b6c6720..dbe9c75262 100644
--- a/src/cpu/x86/smm/Makefile.inc
+++ b/src/cpu/x86/smm/Makefile.inc
@@ -1,6 +1,9 @@
## SPDX-License-Identifier: GPL-2.0-only
ramstage-y += smm_module_loader.c
+ramstage-$(CONFIG_SMM_PCI_RESOURCE_STORE) += pci_resource_store.c
+
+smm-$(CONFIG_SMM_PCI_RESOURCE_STORE) += pci_resource_store.c
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
$(eval $(call create_class_compiler,smm,x86_32))
diff --git a/src/cpu/x86/smm/pci_resource_store.c b/src/cpu/x86/smm/pci_resource_store.c
new file mode 100644
index 0000000000..56bb766cc3
--- /dev/null
+++ b/src/cpu/x86/smm/pci_resource_store.c
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cpu/x86/smm.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+
+void smm_pci_get_stored_resources(const volatile struct smm_pci_resource_info **out_slots,
+ size_t *out_size)
+{
+ *out_slots = smm_get_pci_resource_store();
+ *out_size = CONFIG_SMM_PCI_RESOURCE_STORE_NUM_SLOTS;
+}
+
+bool smm_pci_resource_store_fill_resources(struct smm_pci_resource_info *slots, size_t num_slots,
+ const struct device **devices, size_t num_devices)
+{
+ size_t i_slot = 0;
+
+ for (size_t i_dev = 0; i_dev < num_devices; i_dev++) {
+ if (i_slot >= num_slots) {
+ printk(BIOS_ERR, "Failed to store all PCI resources, number of devices exceeds %zd slots\n",
+ num_slots);
+ return false;
+ }
+
+ if (!is_pci(devices[i_dev])) {
+ printk(BIOS_WARNING, "Skipping storing PCI resources for device at index %zd, not a PCI device\n",
+ i_dev);
+ continue;
+ }
+
+ pci_devfn_t pci_addr = PCI_BDF(devices[i_dev]);
+ slots[i_slot].pci_addr = pci_addr;
+ slots[i_slot].class_device = PCI_CLASS_GET_DEVICE(devices[i_dev]->class);
+ slots[i_slot].class_prog = PCI_CLASS_GET_PROG(devices[i_dev]->class);
+
+ /* Use the resource list to get our BARs. */
+ if (!devices[i_dev]->resource_list)
+ continue;
+
+ size_t i_res = 0;
+ for (const struct resource *res = devices[i_dev]->resource_list; res != NULL;
+ res = res->next) {
+ slots[i_slot].resources[i_res] = *res;
+ slots[i_slot].resources[i_res].next = NULL;
+
+ if (i_res > 0)
+ slots[i_slot].resources[i_res - 1].next = (struct resource *)&slots[i_slot].resources[i_res];
+
+ if (++i_res >= SMM_PCI_RESOURCE_STORE_NUM_RESOURCES) {
+ if (res->next)
+ printk(BIOS_WARNING, "Number of PCI resources exceeds supported storage count\n");
+ break;
+ }
+ }
+
+ i_slot++;
+ }
+
+ return true;
+}
+
+void __weak smm_mainboard_pci_resource_store_init(struct smm_pci_resource_info *slots,
+ size_t size)
+{
+}
+
+void smm_pci_resource_store_init(struct smm_runtime *smm_runtime)
+{
+ smm_mainboard_pci_resource_store_init(&smm_runtime->pci_resources[0],
+ CONFIG_SMM_PCI_RESOURCE_STORE_NUM_SLOTS);
+}
diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c
index 1b3c93b780..3415b02842 100644
--- a/src/cpu/x86/smm/smm_module_handler.c
+++ b/src/cpu/x86/smm/smm_module_handler.c
@@ -195,6 +195,13 @@ asmlinkage void smm_handler_start(void *arg)
southbridge_smi_set_eos();
}
+#if CONFIG(SMM_PCI_RESOURCE_STORE)
+const volatile struct smm_pci_resource_info *smm_get_pci_resource_store(void)
+{
+ return &smm_runtime.pci_resources[0];
+}
+#endif
+
RMODULE_ENTRY(smm_handler_start);
/* Provide a default implementation for all weak handlers so that relocation
diff --git a/src/cpu/x86/smm/smm_module_loader.c b/src/cpu/x86/smm/smm_module_loader.c
index 1b04e8894d..6452707f75 100644
--- a/src/cpu/x86/smm/smm_module_loader.c
+++ b/src/cpu/x86/smm/smm_module_loader.c
@@ -343,6 +343,9 @@ static void setup_smihandler_params(struct smm_runtime *mod_params,
mod_params->smm_log_level = mainboard_set_smm_log_level();
else
mod_params->smm_log_level = 0;
+
+ if (CONFIG(SMM_PCI_RESOURCE_STORE))
+ smm_pci_resource_store_init(mod_params);
}
static void print_region(const char *name, const struct region region)