aboutsummaryrefslogtreecommitdiff
path: root/src/security
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2019-12-11 17:09:39 -0800
committerPhilipp Deppenwiese <zaolin.daisuki@gmail.com>2020-11-21 10:43:53 +0000
commit1e37c9ca465a14d55adeacb332354771543437b5 (patch)
tree6b38606a32261cb99a4518b925278e97c8f120a6 /src/security
parent7d11513ab3281ef3bee83b4b523219b683d3ddc1 (diff)
cbfs: Add metadata cache
This patch adds a new CBFS "mcache" (metadata cache) -- a memory buffer that stores the headers of all CBFS files. Similar to the existing FMAP cache, this cache should reduce the amount of SPI accesses we need to do every boot: rather than having to re-read all CBFS headers from SPI flash every time we're looking for a file, we can just walk the same list in this in-memory copy and finally use it to directly access the flash at the right position for the file data. This patch adds the code to support the cache but doesn't enable it on any platform. The next one will turn it on by default. Change-Id: I5b1084bfdad1c6ab0ee1b143ed8dd796827f4c65 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/38423 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/security')
-rw-r--r--src/security/vboot/vboot_common.h8
-rw-r--r--src/security/vboot/vboot_loader.c40
2 files changed, 39 insertions, 9 deletions
diff --git a/src/security/vboot/vboot_common.h b/src/security/vboot/vboot_common.h
index e64f6632a7..512da0e91f 100644
--- a/src/security/vboot/vboot_common.h
+++ b/src/security/vboot/vboot_common.h
@@ -3,6 +3,7 @@
#define __VBOOT_VBOOT_COMMON_H__
#include <commonlib/region.h>
+#include <cbfs.h>
#include <vb2_api.h>
/*
@@ -50,14 +51,17 @@ int vboot_developer_mode_enabled(void);
int vboot_recovery_mode_enabled(void);
int vboot_can_enable_udc(void);
void vboot_run_logic(void);
-int vboot_locate_cbfs(struct region_device *rdev);
+const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void);
#else /* !CONFIG_VBOOT */
static inline int vboot_developer_mode_enabled(void) { return 0; }
static inline int vboot_recovery_mode_enabled(void) { return 0; }
/* If VBOOT is not enabled, we are okay enabling USB device controller (UDC). */
static inline int vboot_can_enable_udc(void) { return 1; }
static inline void vboot_run_logic(void) {}
-static inline int vboot_locate_cbfs(struct region_device *rdev) { return -1; }
+static inline const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void)
+{
+ return NULL;
+}
#endif
void vboot_save_data(struct vb2_context *ctx);
diff --git a/src/security/vboot/vboot_loader.c b/src/security/vboot/vboot_loader.c
index bca4c3e3b7..9c6e56e9af 100644
--- a/src/security/vboot/vboot_loader.c
+++ b/src/security/vboot/vboot_loader.c
@@ -1,6 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <boot_device.h>
#include <cbfs.h>
+#include <cbmem.h>
+#include <commonlib/bsd/cbfs_private.h>
#include <console/console.h>
#include <ec/google/chromeec/ec.h>
#include <rmodule.h>
@@ -22,12 +25,27 @@ _Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE) ||
int vboot_executed;
+static void build_rw_mcache(void)
+{
+ if (CONFIG(NO_CBFS_MCACHE))
+ return;
+
+ const struct cbfs_boot_device *cbd = vboot_get_cbfs_boot_device();
+ if (!cbd) /* Don't build RW mcache in recovery mode. */
+ return;
+ cb_err_t err = cbfs_mcache_build(&cbd->rdev, cbd->mcache,
+ cbd->mcache_size, NULL);
+ if (err && err != CB_CBFS_CACHE_FULL)
+ die("Failed to build RW mcache."); /* TODO: -> recovery? */
+}
+
void vboot_run_logic(void)
{
if (verification_should_run()) {
/* Note: this path is not used for VBOOT_RETURN_FROM_VERSTAGE */
verstage_main();
vboot_executed = 1;
+ build_rw_mcache();
} else if (verstage_should_load()) {
struct cbfsf file;
struct prog verstage =
@@ -55,21 +73,29 @@ void vboot_run_logic(void)
return;
vboot_executed = 1;
+ build_rw_mcache();
}
}
-int vboot_locate_cbfs(struct region_device *rdev)
+const struct cbfs_boot_device *vboot_get_cbfs_boot_device(void)
{
- struct vb2_context *ctx;
-
/* Don't honor vboot results until the vboot logic has run. */
if (!vboot_logic_executed())
- return -1;
+ return NULL;
- ctx = vboot_get_context();
+ static struct cbfs_boot_device cbd;
+ if (region_device_sz(&cbd.rdev))
+ return &cbd;
+ struct vb2_context *ctx = vboot_get_context();
if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
- return -1;
+ return NULL;
+
+ boot_device_init();
+ if (vboot_locate_firmware(ctx, &cbd.rdev))
+ return NULL;
+
+ cbfs_boot_device_find_mcache(&cbd, CBMEM_ID_CBFS_RW_MCACHE);
- return vboot_locate_firmware(ctx, rdev);
+ return &cbd;
}