From 73e7ccc46bf165c90bc68c5f3320a087f7de4faf Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Thu, 27 Jun 2024 20:31:35 +0200 Subject: [PATCH] drivers/smmstore: add logic to disable capsule update handling code This adds a call to SMMSTORE that saves information about availability of capsules in SMM memory. This new call is ignored when run more than once, which means that there should be no way of enabling full flash handling after it was disabled and vice versa. The call should be always made by the firmware to lock further calls, otherwise OS could gain full flash access. This is done on entry to BS_POST_DEVICE, after capsules are obtained in BS_DEV_INIT. Change-Id: I3dc175ea313aae1edae304520595b82db7206cbb Signed-off-by: Krystian Hebel --- src/drivers/efi/capsules.c | 16 +++++++++++++++- src/drivers/smmstore/smi.c | 2 +- src/drivers/smmstore/store.c | 13 +++++++++++-- src/include/smmstore.h | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/drivers/efi/capsules.c b/src/drivers/efi/capsules.c index 3bb66414bc3..fdd7cdcaa00 100644 --- a/src/drivers/efi/capsules.c +++ b/src/drivers/efi/capsules.c @@ -9,9 +9,10 @@ #include #include #include +#include +#include #include #include -#include #include #include @@ -742,3 +743,16 @@ static void parse_capsules(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, parse_capsules, NULL); #endif + +static void enable_capsule_smi(void *unused) +{ + uint32_t ret; + + ret = call_smm(APM_CNT_SMMSTORE, SMMSTORE_CMD_USE_FULL_FLASH, + (void*)(uintptr_t)uefi_capsule_count); + + printk(BIOS_INFO, "%sabled capsule update SMI handler\n", + ret == SMMSTORE_RET_SUCCESS ? "En" : "Dis"); +} + +BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, enable_capsule_smi, NULL); diff --git a/src/drivers/smmstore/smi.c b/src/drivers/smmstore/smi.c index 0b1f4c8225a..230097c1749 100644 --- a/src/drivers/smmstore/smi.c +++ b/src/drivers/smmstore/smi.c @@ -143,7 +143,7 @@ static uint32_t smmstorev2_exec(uint8_t command, void *param) uint32_t smmstore_exec(uint8_t command, void *param) { - if (smmstore_preprocess_cmd(&command)) + if (smmstore_preprocess_cmd(&command, param)) return SMMSTORE_RET_SUCCESS; if (command != SMMSTORE_CMD_CLEAR && !param) diff --git a/src/drivers/smmstore/store.c b/src/drivers/smmstore/store.c index d6d1616017d..e8a0560294c 100644 --- a/src/drivers/smmstore/store.c +++ b/src/drivers/smmstore/store.c @@ -48,11 +48,20 @@ _Static_assert(SMM_BLOCK_SIZE <= FMAP_SECTION_SMMSTORE_SIZE, */ static int use_full_flash; +static int has_capsules = -1; -int smmstore_preprocess_cmd(uint8_t *cmd) +int smmstore_preprocess_cmd(uint8_t *cmd, void *param) { if (CONFIG(DRIVERS_EFI_UPDATE_CAPSULES)) { - if (*cmd & SMMSTORE_CMD_USE_FULL_FLASH) { + if (has_capsules == -1 && *cmd == SMMSTORE_CMD_USE_FULL_FLASH) { + has_capsules = !!(uintptr_t)param; + /* + * If we have capsules, return success, otherwise let smmstore_exec() + * fail on !param check, which will be 0 in that case. This informs + * the caller whether capsule handling was enabled or not. + */ + return has_capsules; + } else if (has_capsules == 1 && *cmd & SMMSTORE_CMD_USE_FULL_FLASH) { use_full_flash = 1; *cmd &= ~SMMSTORE_CMD_USE_FULL_FLASH; } else { diff --git a/src/include/smmstore.h b/src/include/smmstore.h index 4b5805acbbc..5b93a816b93 100644 --- a/src/include/smmstore.h +++ b/src/include/smmstore.h @@ -121,7 +121,7 @@ int smmstore_get_info(struct smmstore_params_info *info); struct region_device; int smmstore_lookup_region(struct region_device *rstore); /* Returns 0 if normal parsing should continue, 1 otherwise */ -int smmstore_preprocess_cmd(uint8_t *cmd); +int smmstore_preprocess_cmd(uint8_t *cmd, void *param); /* Advertise SMMSTORE v2 support */ struct lb_header;