Skip to content

Commit

Permalink
drivers/smmstore: add logic to disable capsule update handling code
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
krystian-hebel committed Jun 28, 2024
1 parent 623abec commit 73e7ccc
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
16 changes: 15 additions & 1 deletion src/drivers/efi/capsules.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
#include <drivers/efi/efivars.h>
#include <drivers/efi/capsules.h>
#include <memrange.h>
#include <smm_call.h>
#include <smmstore.h>
#include <string.h>
#include <stdio.h>
#include <smmstore.h>
#include <types.h>

#include <Uefi/UefiSpec.h>
Expand Down Expand Up @@ -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);
2 changes: 1 addition & 1 deletion src/drivers/smmstore/smi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 11 additions & 2 deletions src/drivers/smmstore/store.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/include/smmstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 73e7ccc

Please sign in to comment.