drivers/smmstore: allow full flash access for capsule updates
With DRIVERS_EFI_UPDATE_CAPSULES enabled and when at least one capsule was found, SMMSTORE SMI handler can use commands with the highest bit (0x80) set to access the whole flash instead of just the SMMSTORE region. The rest of the interface is identical to regular SMMSTORE v2 except for a new call to control full flash access. The added call saves information about the availability of capsules in SMM memory. The call is ignored when run more than once, meaning there should be no way of enabling full flash handling after it was disabled and vice versa. The call should always be made by the firmware to lock further calls, so that an OS could not gain full flash access. This is done on entry to BS_POST_DEVICE after capsules are obtained in BS_DEV_INIT. Change-Id: I7f3dbfa965b9dcbade8b2f06a5bd2ac1345c7972 Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com> Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/83424 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Michał Żygowski <michal.zygowski@3mdeb.com>
This commit is contained in:
parent
7814b8a6be
commit
0cc0e6996c
5 changed files with 104 additions and 1 deletions
|
|
@ -10,9 +10,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>
|
||||
|
|
@ -786,3 +787,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);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ static uint32_t smmstorev2_exec(uint8_t command, void *param)
|
|||
|
||||
uint32_t smmstore_exec(uint8_t command, void *param)
|
||||
{
|
||||
if (smmstore_preprocess_cmd(&command, param))
|
||||
return SMMSTORE_RET_SUCCESS;
|
||||
|
||||
if (command != SMMSTORE_CMD_CLEAR && !param)
|
||||
return SMMSTORE_RET_FAILURE;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,43 @@ _Static_assert(SMM_BLOCK_SIZE <= FMAP_SECTION_SMMSTORE_SIZE,
|
|||
* crash/reboot could clear out all variables.
|
||||
*/
|
||||
|
||||
static int smmstore_use_full_flash;
|
||||
static int has_capsules = -1;
|
||||
|
||||
int smmstore_preprocess_cmd(uint8_t *cmd, void *param)
|
||||
{
|
||||
if (CONFIG(DRIVERS_EFI_UPDATE_CAPSULES)) {
|
||||
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) {
|
||||
smmstore_use_full_flash = 1;
|
||||
*cmd &= ~SMMSTORE_CMD_USE_FULL_FLASH;
|
||||
} else {
|
||||
smmstore_use_full_flash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum cb_err lookup_store_region(struct region *region)
|
||||
{
|
||||
if (CONFIG(DRIVERS_EFI_UPDATE_CAPSULES) && smmstore_use_full_flash) {
|
||||
const struct region_device *rdev = boot_device_rw();
|
||||
|
||||
if (rdev == NULL)
|
||||
return CB_ERR;
|
||||
|
||||
*region = *region_device_region(rdev);
|
||||
return CB_SUCCESS;
|
||||
}
|
||||
|
||||
if (fmap_locate_area(SMMSTORE_REGION, region)) {
|
||||
printk(BIOS_WARNING,
|
||||
"smm store: Unable to find SMM store FMAP region '%s'\n",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue