Merge patch series "Add support for secure falcon mode: disable fallback"
Anshul Dalal <anshuld@ti.com> says: Continuing from the last series[1], this patch series addresses the requirement of allowing no fallbacks in secure falcon mode. To do this in a clean way, all the falcon mode logic for each boot media was refactored to a corresponding *_load_image_os function whereas the regular boot is implemented in *_load_image, this allows us to easily return early in case the *_load_image_os function fails with secure mode enabled. The series also introduces the new SPL_OS_BOOT_SECURE config symbol which enables secure falcon boot flow. The generic flow after the patch series looks as follows: static int spl_<bootmedia>_load_image(...) { if (CONFIG_IS_ENABLED(OS_BOOT)) { ret = spl_<bootmedia>_load_image_os(...); puts("Failcon mode failed\n"); if (CONFIG_IS_ENABLED(OS_BOOT_SECURE)) { puts("no fallback allowed!\n"); return ret; } puts("Falling back to U-Boot\n"); } /* Regular boot flow */ } [1]: https://lore.kernel.org/u-boot/20250923124639.667718-1-anshuld@ti.com/ Link: https://lore.kernel.org/r/20251017193318.4124997-1-anshuld@ti.com
This commit is contained in:
@@ -1207,6 +1207,14 @@ config SPL_OS_BOOT
|
||||
Enable booting directly to an OS from SPL.
|
||||
for more info read doc/README.falcon
|
||||
|
||||
config SPL_OS_BOOT_SECURE
|
||||
bool "Allow Falcon Mode on secure devices"
|
||||
depends on SPL_OS_BOOT
|
||||
help
|
||||
This allows for secure devices with signature verification capabilities
|
||||
to use falcon mode by disabling certain inherently non-securable options
|
||||
in the SPL boot flow.
|
||||
|
||||
config SPL_PAYLOAD_ARGS_ADDR
|
||||
hex "Address in memory to load 'args' file for Falcon Mode to"
|
||||
depends on SPL_OS_BOOT || SPL_LOAD_FIT_OPENSBI_OS_BOOT
|
||||
|
||||
+54
-30
@@ -194,6 +194,46 @@ int spl_start_uboot(void)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_MMCSD_FS_BOOT
|
||||
static int spl_mmc_fs_load_os(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
struct blk_desc *blk_dev, int part)
|
||||
{
|
||||
int err = -ENOSYS;
|
||||
|
||||
if (CONFIG_IS_ENABLED(FS_FAT)) {
|
||||
err = spl_load_image_fat_os(spl_image, bootdev, blk_dev, part);
|
||||
if (!err)
|
||||
return 0;
|
||||
}
|
||||
if (CONFIG_IS_ENABLED(FS_EXT4)) {
|
||||
err = spl_load_image_ext_os(spl_image, bootdev, blk_dev, part);
|
||||
if (!err)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __maybe_unused spl_mmc_fs_load(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
struct blk_desc *blk_dev, int part, const char *file)
|
||||
{
|
||||
int err = -ENOENT;
|
||||
|
||||
if (CONFIG_IS_ENABLED(FS_FAT)) {
|
||||
err = spl_load_image_fat(spl_image, bootdev, blk_dev, part, file);
|
||||
if (!err)
|
||||
return 0;
|
||||
}
|
||||
if (CONFIG_IS_ENABLED(FS_EXT4)) {
|
||||
err = spl_load_image_ext(spl_image, bootdev, blk_dev, part, file);
|
||||
if (!err)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
struct mmc *mmc,
|
||||
@@ -225,42 +265,24 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_FS_FAT
|
||||
if (!spl_start_uboot()) {
|
||||
ret = spl_load_image_fat_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
|
||||
partition);
|
||||
ret = spl_mmc_fs_load_os(spl_image, bootdev,
|
||||
mmc_get_blk_desc(mmc), partition);
|
||||
if (!ret)
|
||||
return 0;
|
||||
printf("%s, Failed to load falcon payload: %d\n", __func__,
|
||||
ret);
|
||||
if (IS_ENABLED(CONFIG_SPL_OS_BOOT_SECURE))
|
||||
return ret;
|
||||
printf("Fallback to U-Boot\n");
|
||||
}
|
||||
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
|
||||
ret = spl_load_image_fat(spl_image, bootdev, mmc_get_blk_desc(mmc),
|
||||
partition,
|
||||
filename);
|
||||
if (!ret)
|
||||
return ret;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_SPL_FS_EXT4
|
||||
if (!spl_start_uboot()) {
|
||||
ret = spl_load_image_ext_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
|
||||
partition);
|
||||
if (!ret)
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
|
||||
ret = spl_load_image_ext(spl_image, bootdev, mmc_get_blk_desc(mmc),
|
||||
partition,
|
||||
filename);
|
||||
if (!ret)
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
|
||||
ret = -ENOENT;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
|
||||
return spl_mmc_fs_load(spl_image, bootdev, mmc_get_blk_desc(mmc),
|
||||
partition, filename);
|
||||
#else
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -392,6 +414,8 @@ int spl_mmc_load(struct spl_image_info *spl_image,
|
||||
ret = mmc_load_image_raw_os(spl_image, bootdev, mmc);
|
||||
if (!ret)
|
||||
return 0;
|
||||
if (IS_ENABLED(CONFIG_SPL_OS_BOOT_SECURE))
|
||||
return ret;
|
||||
}
|
||||
|
||||
raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
|
||||
|
||||
+53
-42
@@ -75,6 +75,52 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
|
||||
return spl_load(spl_image, bootdev, &load, 0, offset);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPL_OS_BOOT)
|
||||
static int spl_nand_load_image_os(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
int *src, *dst, err;
|
||||
struct legacy_img_hdr *header = spl_get_load_buffer(0, sizeof(*header));
|
||||
|
||||
/* load linux */
|
||||
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, sizeof(*header),
|
||||
(void *)header);
|
||||
err = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (header->ih_os != IH_OS_LINUX)
|
||||
return -EINVAL;
|
||||
|
||||
/* happy - was a linux */
|
||||
err = nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
|
||||
spl_image->size,
|
||||
(void *)spl_image->load_addr);
|
||||
nand_deselect();
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* load parameter image load to temp position since nand_spl_load_image
|
||||
* reads a whole block which is typically larger than
|
||||
* CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite following sections
|
||||
* like BSS
|
||||
*/
|
||||
nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, CONFIG_CMD_SPL_WRITE_SIZE,
|
||||
(void *)CONFIG_TEXT_BASE);
|
||||
/* copy to destintion */
|
||||
for (dst = (int *)CONFIG_SPL_PAYLOAD_ARGS_ADDR,
|
||||
src = (int *)CONFIG_TEXT_BASE;
|
||||
src < (int *)(CONFIG_TEXT_BASE + CONFIG_CMD_SPL_WRITE_SIZE);
|
||||
src++, dst++) {
|
||||
writel(readl(src), dst);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int spl_nand_load_image(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
@@ -89,51 +135,16 @@ static int spl_nand_load_image(struct spl_image_info *spl_image,
|
||||
|
||||
#if CONFIG_IS_ENABLED(OS_BOOT)
|
||||
if (!spl_start_uboot()) {
|
||||
int *src, *dst;
|
||||
struct legacy_img_hdr *header =
|
||||
spl_get_load_buffer(0, sizeof(*header));
|
||||
|
||||
/*
|
||||
* load parameter image
|
||||
* load to temp position since nand_spl_load_image reads
|
||||
* a whole block which is typically larger than
|
||||
* CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite
|
||||
* following sections like BSS
|
||||
*/
|
||||
nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
|
||||
CONFIG_CMD_SPL_WRITE_SIZE,
|
||||
(void *)CONFIG_TEXT_BASE);
|
||||
/* copy to destintion */
|
||||
for (dst = (int *)CONFIG_SPL_PAYLOAD_ARGS_ADDR,
|
||||
src = (int *)CONFIG_TEXT_BASE;
|
||||
src < (int *)(CONFIG_TEXT_BASE +
|
||||
CONFIG_CMD_SPL_WRITE_SIZE);
|
||||
src++, dst++) {
|
||||
writel(readl(src), dst);
|
||||
}
|
||||
|
||||
/* load linux */
|
||||
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
|
||||
sizeof(*header), (void *)header);
|
||||
err = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (err)
|
||||
err = spl_nand_load_image_os(spl_image, bootdev);
|
||||
if (!err)
|
||||
return 0;
|
||||
printf("%s: Failed in falcon boot: %d", __func__, err);
|
||||
if (IS_ENABLED(CONFIG_SPL_OS_BOOT_SECURE))
|
||||
return err;
|
||||
if (header->ih_os == IH_OS_LINUX) {
|
||||
/* happy - was a linux */
|
||||
err = nand_spl_load_image(
|
||||
CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
|
||||
spl_image->size,
|
||||
(void *)spl_image->load_addr);
|
||||
nand_deselect();
|
||||
return err;
|
||||
} else {
|
||||
puts("The Expected Linux image was not "
|
||||
"found. Please check your NAND "
|
||||
"configuration.\n");
|
||||
puts("Trying to start u-boot now...\n");
|
||||
}
|
||||
printf("Fallback to U-Boot\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NAND_ENV_DST
|
||||
spl_nand_load_element(spl_image, bootdev, CONFIG_ENV_OFFSET);
|
||||
#ifdef CONFIG_ENV_OFFSET_REDUND
|
||||
|
||||
+62
-47
@@ -25,6 +25,58 @@ unsigned long __weak spl_nor_get_uboot_base(void)
|
||||
return CFG_SYS_UBOOT_BASE;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPL_OS_BOOT)
|
||||
static int spl_nor_load_image_os(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
/*
|
||||
* Load Linux from its location in NOR flash to its defined
|
||||
* location in SDRAM
|
||||
*/
|
||||
const struct legacy_img_hdr *header =
|
||||
(const struct legacy_img_hdr *)CONFIG_SYS_OS_BASE;
|
||||
struct spl_load_info load;
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
if (image_get_magic(header) == FDT_MAGIC) {
|
||||
int ret;
|
||||
|
||||
debug("Found FIT\n");
|
||||
spl_load_init(&load, spl_nor_load_read, NULL, 1);
|
||||
|
||||
ret = spl_load_simple_fit(spl_image, &load, CONFIG_SYS_OS_BASE,
|
||||
(void *)header);
|
||||
|
||||
#if defined CONFIG_SPL_PAYLOAD_ARGS_ADDR && defined CONFIG_CMD_SPL_NOR_OFS
|
||||
memcpy((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR,
|
||||
(void *)CONFIG_CMD_SPL_NOR_OFS,
|
||||
CONFIG_CMD_SPL_WRITE_SIZE);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
if (image_get_os(header) != IH_OS_LINUX)
|
||||
return -EINVAL;
|
||||
|
||||
/* happy - was a Linux */
|
||||
int ret;
|
||||
|
||||
ret = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy((void *)spl_image->load_addr,
|
||||
(void *)(CONFIG_SYS_OS_BASE + sizeof(struct legacy_img_hdr)),
|
||||
spl_image->size);
|
||||
|
||||
#ifdef CONFIG_SPL_PAYLOAD_ARGS_ADDR
|
||||
spl_image->arg = (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int spl_nor_load_image(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
@@ -36,55 +88,18 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
|
||||
*/
|
||||
spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;
|
||||
|
||||
#if CONFIG_IS_ENABLED(OS_BOOT)
|
||||
#if IS_ENABLED(CONFIG_SPL_OS_BOOT)
|
||||
int err;
|
||||
|
||||
if (!spl_start_uboot()) {
|
||||
/*
|
||||
* Load Linux from its location in NOR flash to its defined
|
||||
* location in SDRAM
|
||||
*/
|
||||
const struct legacy_img_hdr *header =
|
||||
(const struct legacy_img_hdr *)CONFIG_SYS_OS_BASE;
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
if (image_get_magic(header) == FDT_MAGIC) {
|
||||
int ret;
|
||||
|
||||
debug("Found FIT\n");
|
||||
spl_load_init(&load, spl_nor_load_read, NULL, 1);
|
||||
|
||||
ret = spl_load_simple_fit(spl_image, &load,
|
||||
CONFIG_SYS_OS_BASE,
|
||||
(void *)header);
|
||||
|
||||
#if defined CONFIG_SPL_PAYLOAD_ARGS_ADDR && defined CONFIG_CMD_SPL_NOR_OFS
|
||||
memcpy((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR,
|
||||
(void *)CONFIG_CMD_SPL_NOR_OFS,
|
||||
CONFIG_CMD_SPL_WRITE_SIZE);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
if (image_get_os(header) == IH_OS_LINUX) {
|
||||
/* happy - was a Linux */
|
||||
int ret;
|
||||
|
||||
ret = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy((void *)spl_image->load_addr,
|
||||
(void *)(CONFIG_SYS_OS_BASE +
|
||||
sizeof(struct legacy_img_hdr)),
|
||||
spl_image->size);
|
||||
#ifdef CONFIG_SPL_PAYLOAD_ARGS_ADDR
|
||||
spl_image->arg = (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR;
|
||||
#endif
|
||||
|
||||
err = spl_nor_load_image_os(spl_image, bootdev);
|
||||
if (!err)
|
||||
return 0;
|
||||
} else {
|
||||
puts("The Expected Linux image was not found.\n"
|
||||
"Please check your NOR configuration.\n"
|
||||
"Trying to start u-boot now...\n");
|
||||
}
|
||||
|
||||
printf("%s: Failed in falcon boot: %d", __func__, err);
|
||||
if (IS_ENABLED(CONFIG_SPL_OS_BOOT_SECURE))
|
||||
return err;
|
||||
printf("Fallback to U-Boot\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+26
-7
@@ -49,6 +49,25 @@ u32 __weak spl_spi_boot_cs(void)
|
||||
return CONFIG_SF_DEFAULT_CS;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPL_OS_BOOT)
|
||||
static int spl_spi_load_image_os(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
struct spi_flash *flash,
|
||||
struct spl_load_info *load)
|
||||
{
|
||||
int err = spl_load(spl_image, bootdev, load, 0,
|
||||
CONFIG_SYS_SPI_KERNEL_OFFS);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Read device tree. */
|
||||
return spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
|
||||
CONFIG_SYS_SPI_ARGS_SIZE,
|
||||
(void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The main entry for SPI booting. It's necessary that SDRAM is already
|
||||
* configured and available since this code loads the main U-Boot image
|
||||
@@ -81,15 +100,15 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
|
||||
|
||||
#if CONFIG_IS_ENABLED(OS_BOOT)
|
||||
if (!spl_start_uboot()) {
|
||||
int err = spl_load(spl_image, bootdev, &load, 0,
|
||||
CONFIG_SYS_SPI_KERNEL_OFFS);
|
||||
err = spl_spi_load_image_os(spl_image, bootdev, flash, &load);
|
||||
|
||||
if (!err)
|
||||
/* Read device tree. */
|
||||
return spi_flash_read(
|
||||
flash, CONFIG_SYS_SPI_ARGS_OFFS,
|
||||
CONFIG_SYS_SPI_ARGS_SIZE,
|
||||
(void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR);
|
||||
return 0;
|
||||
|
||||
printf("%s: Failed in falcon boot: %d", __func__, err);
|
||||
if (IS_ENABLED(CONFIG_SPL_OS_BOOT_SECURE))
|
||||
return err;
|
||||
printf("Fallback to U-Boot\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+34
-12
@@ -11,6 +11,32 @@
|
||||
#include <ubispl.h>
|
||||
#include <spl.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SPL_OS_BOOT)
|
||||
int spl_ubi_load_image_os(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
struct ubispl_info *info)
|
||||
{
|
||||
struct legacy_img_hdr *header;
|
||||
struct ubispl_load volumes[2];
|
||||
int err;
|
||||
|
||||
volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID;
|
||||
volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR;
|
||||
volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID;
|
||||
volumes[1].load_addr = (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR;
|
||||
|
||||
err = ubispl_load_volumes(info, volumes, 2);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
header = (struct legacy_img_hdr *)volumes[0].load_addr;
|
||||
spl_parse_image_header(spl_image, bootdev, header);
|
||||
puts("Linux loaded.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int spl_ubi_load_image(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
@@ -46,21 +72,17 @@ int spl_ubi_load_image(struct spl_image_info *spl_image,
|
||||
|
||||
#if CONFIG_IS_ENABLED(OS_BOOT)
|
||||
if (!spl_start_uboot()) {
|
||||
volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID;
|
||||
volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR;
|
||||
volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID;
|
||||
volumes[1].load_addr = (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR;
|
||||
ret = spl_ubi_load_image_os(spl_image, bootdev, &info);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
ret = ubispl_load_volumes(&info, volumes, 2);
|
||||
if (!ret) {
|
||||
header = (struct legacy_img_hdr *)volumes[0].load_addr;
|
||||
spl_parse_image_header(spl_image, bootdev, header);
|
||||
puts("Linux loaded.\n");
|
||||
goto out;
|
||||
}
|
||||
puts("Loading Linux failed, falling back to U-Boot.\n");
|
||||
printf("%s: Failed in falcon boot: %d", __func__, ret);
|
||||
if (IS_ENABLED(CONFIG_SPL_OS_BOOT_SECURE))
|
||||
return ret;
|
||||
printf("Fallback to U-Boot\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
header = spl_get_load_buffer(-sizeof(*header), sizeof(header));
|
||||
#ifdef CONFIG_SPL_UBI_LOAD_BY_VOLNAME
|
||||
volumes[0].vol_id = -1;
|
||||
|
||||
Reference in New Issue
Block a user