cpu/x86/smm: add OPAL S3 CBMEM scratch
Provide an optional, coreboot-managed CBMEM scratch buffer for SMM code. CBMEM is reserved from the OS via the memory map and persists across S3, so it is suitable for firmware-owned DMA buffers used during resume. SMRAM is not device DMA-accessible, so this scratch buffer must live outside SMRAM. Pass the base/size to SMM via smm_runtime so SMM code can validate placement and avoid relying on untrusted pointers. The CBMEM region size is configurable via SMM_OPAL_S3_SCRATCH_SIZE, defaulting to 16 KiB as a safe value. TEST=tested with rest of patch train Change-Id: I79ae5327f27e574b151b7cf456761fa0d7038f2f Signed-off-by: Sean Rhodes <sean@starlabs.systems> Reviewed-on: https://review.coreboot.org/c/coreboot/+/91042 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com>
This commit is contained in:
parent
513899c3c8
commit
deb510afeb
5 changed files with 55 additions and 0 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#define CBMEM_ID_ACPI_BERT 0x42455254
|
||||
#define CBMEM_ID_ACPI_CNVS 0x434e5653
|
||||
#define CBMEM_ID_ACPI_GNVS 0x474e5653
|
||||
#define CBMEM_ID_OPAL_S3_SCRATCH 0x3353504f /* 'OPS3' */
|
||||
#define CBMEM_ID_ACPI_HEST 0x48455354
|
||||
#define CBMEM_ID_ACPI_UCSI 0x55435349
|
||||
#define CBMEM_ID_AFTER_CAR 0xc4787a93
|
||||
|
|
@ -100,6 +101,7 @@
|
|||
{ CBMEM_ID_ACPI_BERT, "ACPI BERT " }, \
|
||||
{ CBMEM_ID_ACPI_CNVS, "CHROMEOS NVS" }, \
|
||||
{ CBMEM_ID_ACPI_GNVS, "ACPI GNVS " }, \
|
||||
{ CBMEM_ID_OPAL_S3_SCRATCH, "OPAL S3 SCR" }, \
|
||||
{ CBMEM_ID_ACPI_HEST, "ACPI HEST " }, \
|
||||
{ CBMEM_ID_ACPI_UCSI, "ACPI UCSI " }, \
|
||||
{ CBMEM_ID_AGESA_RUNTIME, "AGESA RSVD " }, \
|
||||
|
|
|
|||
|
|
@ -196,6 +196,24 @@ config SMM_MODULE_STACK_SIZE
|
|||
This option determines the size of the stack within the SMM handler
|
||||
modules.
|
||||
|
||||
config SMM_OPAL_S3_SCRATCH_CBMEM
|
||||
bool
|
||||
depends on HAVE_ACPI_RESUME
|
||||
default n
|
||||
help
|
||||
Allocate a coreboot-managed CBMEM region that can be used as a
|
||||
persistent (across S3) scratch buffer by SMM code performing OPAL/NVMe
|
||||
unlock on resume. The region is in CBMEM and therefore reserved from
|
||||
the OS via the memory map.
|
||||
|
||||
config SMM_OPAL_S3_SCRATCH_SIZE
|
||||
hex "OPAL S3 scratch size (bytes)"
|
||||
depends on SMM_OPAL_S3_SCRATCH_CBMEM
|
||||
default 0x4000
|
||||
help
|
||||
Size of the CBMEM scratch buffer provided to the OPAL S3 unlock SMM
|
||||
handler. This buffer must be DMA-safe and persistent across S3.
|
||||
|
||||
endif
|
||||
|
||||
config SMM_LAPIC_REMAP_MITIGATION
|
||||
|
|
|
|||
|
|
@ -66,6 +66,14 @@ void smm_get_smmstore_com_buffer(uintptr_t *base, size_t *size)
|
|||
*size = smm_runtime.smmstore_com_buffer_size;
|
||||
}
|
||||
|
||||
#if CONFIG(SMM_OPAL_S3_SCRATCH_CBMEM)
|
||||
void smm_get_opal_s3_scratch_buffer(uintptr_t *base, size_t *size)
|
||||
{
|
||||
*base = smm_runtime.opal_s3_scratch_base;
|
||||
*size = smm_runtime.opal_s3_scratch_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
void smm_get_cbmemc_buffer(void **buffer_out, size_t *size_out)
|
||||
{
|
||||
*buffer_out = smm_runtime.cbmemc;
|
||||
|
|
|
|||
|
|
@ -366,6 +366,26 @@ static void setup_smihandler_params(struct smm_runtime *mod_params,
|
|||
mod_params->smmstore_com_buffer_base = (uintptr_t)ptr;
|
||||
mod_params->smmstore_com_buffer_size = info.block_size;
|
||||
}
|
||||
|
||||
#if CONFIG(SMM_OPAL_S3_SCRATCH_CBMEM)
|
||||
/*
|
||||
* Provide a small, coreboot-managed CBMEM scratch region for SMM code.
|
||||
* CBMEM is reserved in the memory map, and persists across S3, making
|
||||
* it suitable for firmware-owned DMA buffers on resume. SMRAM is not
|
||||
* accessible to devices for DMA, so this scratch buffer must live
|
||||
* outside SMRAM.
|
||||
*/
|
||||
const size_t opal_s3_scratch_size = CONFIG_SMM_OPAL_S3_SCRATCH_SIZE;
|
||||
void *scratch = cbmem_add(CBMEM_ID_OPAL_S3_SCRATCH, opal_s3_scratch_size);
|
||||
if (!scratch) {
|
||||
printk(BIOS_ERR, "SMM: Failed to allocate OPAL S3 scratch\n");
|
||||
mod_params->opal_s3_scratch_base = 0;
|
||||
mod_params->opal_s3_scratch_size = 0;
|
||||
} else {
|
||||
mod_params->opal_s3_scratch_base = (uintptr_t)scratch;
|
||||
mod_params->opal_s3_scratch_size = opal_s3_scratch_size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_region(const char *name, const struct region region)
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@ struct smm_runtime {
|
|||
int smm_log_level;
|
||||
uintptr_t smmstore_com_buffer_base;
|
||||
size_t smmstore_com_buffer_size;
|
||||
#if CONFIG(SMM_OPAL_S3_SCRATCH_CBMEM)
|
||||
uintptr_t opal_s3_scratch_base;
|
||||
size_t opal_s3_scratch_size;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
struct smm_module_params {
|
||||
|
|
@ -238,5 +242,8 @@ bool smm_pci_resource_store_fill_resources(struct smm_pci_resource_info *slots,
|
|||
void smm_pci_resource_store_init(struct smm_runtime *smm_runtime);
|
||||
|
||||
void smm_get_smmstore_com_buffer(uintptr_t *base, size_t *size);
|
||||
#if CONFIG(SMM_OPAL_S3_SCRATCH_CBMEM)
|
||||
void smm_get_opal_s3_scratch_buffer(uintptr_t *base, size_t *size);
|
||||
#endif
|
||||
|
||||
#endif /* CPU_X86_SMM_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue