aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Clément Tosi <ptosi@google.com>2022-04-06 21:44:40 +0100
committerPierre-Clément Tosi <ptosi@google.com>2022-05-16 07:51:05 +0100
commit6649866e3b01109ea23e7c2f524eea7b36d90b94 (patch)
tree2befabf9f63fa3e7a5e0938c081c6fe5342a17a0
parentfb382a51073c3a18275b6d37d4f551e88a9609da (diff)
downloadu-boot-6649866e3b01109ea23e7c2f524eea7b36d90b94.tar.gz
ANDROID: pvmfw: Support DICE & AVF in DT template
Make the DT template hold the relevant nodes and patch/remove them as necessary while producing the DT for the next stage, instead of injecting them once it has been produced. Bug: 224922775 Signed-off-by: Pierre-Clément Tosi <ptosi@google.com> Change-Id: I820fce2cf9da772363abfdf8f5dbf12b781a1fbf
-rw-r--r--board/android/pvmfw-arm64/boot.c155
-rw-r--r--board/android/pvmfw-arm64/generate_fdt.c19
-rw-r--r--board/android/pvmfw-arm64/generate_fdt.h3
-rw-r--r--board/android/pvmfw-arm64/platform.dts9
4 files changed, 50 insertions, 136 deletions
diff --git a/board/android/pvmfw-arm64/boot.c b/board/android/pvmfw-arm64/boot.c
index f0d52a74a2..7c3cb19326 100644
--- a/board/android/pvmfw-arm64/boot.c
+++ b/board/android/pvmfw-arm64/boot.c
@@ -4,6 +4,7 @@
*/
#include <asm/global_data.h>
+#include <asm/io.h>
#include <android_bootloader.h>
#include <android_image.h>
@@ -19,13 +20,6 @@
#include "avb_preloaded.h"
#include "generate_fdt.h"
-/* This assumes reserved-memory#address-cells/size-cells <= 2 */
-#define DICE_NODE_SIZE 96
-#define RSV_MEM_SIZE (DICE_NODE_SIZE + 128)
-#define COMPAT_DICE "google,open-dice"
-
-#define CHOSEN_MEM_SIZE 64
-
/* Taken from libavb/avb_slot_verify.c */
#define VBMETA_MAX_SIZE SZ_64K
@@ -46,116 +40,6 @@ static bool is_valid_ram_region(const void *ptr, size_t size)
return is_valid_ram(ptr) && (size <= gd->ram_top - (uintptr_t)ptr);
}
-static int alloc_subnode(void *fdt, int parentoffset, const char *name,
- size_t size)
-{
- int offset, res;
-
- offset = fdt_add_subnode(fdt, parentoffset, name);
- if (offset != -FDT_ERR_NOSPACE)
- return offset;
-
- res = fdt_increase_size(fdt, size);
- if (res)
- return res;
-
- return fdt_add_subnode(fdt, parentoffset, name);
-}
-
-static int find_or_alloc_subnode(void *fdt, int parentoffset, const char *name,
- size_t size)
-{
- int offset;
-
- offset = fdt_subnode_offset(fdt, parentoffset, name);
- if (offset != -FDT_ERR_NOTFOUND)
- return offset;
-
- return alloc_subnode(fdt, parentoffset, name, size);
-}
-
-static bool pvmfw_fdt_is_valid(const void *fdt)
-{
- int offset;
-
- if (fdt != (const void *)CONFIG_SYS_SDRAM_BASE)
- return false;
-
- if (fdt_totalsize(fdt) > FDT_MAX_SIZE)
- return false;
-
- /* Reject DICE-compatible DT nodes. */
- offset = fdt_node_offset_by_compatible(fdt, -1, COMPAT_DICE);
- if (offset != -FDT_ERR_NOTFOUND)
- return false;
-
- /* Reject "/reserved-memory/dice" nodes. */
- offset = fdt_subnode_offset(fdt, -1, "reserved-memory");
- if (offset >= 0)
- offset = fdt_subnode_offset(fdt, offset, "dice");
- if (offset != -FDT_ERR_NOTFOUND)
- return false;
-
- return true;
-}
-
-static int add_dice_fdt_mem_rsv(void *fdt, void *addr, size_t size)
-{
- int mem, dice, err;
-
- mem = find_or_alloc_subnode(fdt, 0, "reserved-memory", RSV_MEM_SIZE);
- if (mem < 0)
- return mem;
-
- dice = alloc_subnode(fdt, mem, "dice", DICE_NODE_SIZE);
- if (dice < 0)
- return dice;
-
- err = fdt_appendprop_addrrange(fdt, mem, dice, "reg",
- (uint64_t)addr, size);
- if (err)
- return err;
-
- err = fdt_appendprop(fdt, dice, "no-map", NULL, 0);
- if (err)
- return err;
-
- err = fdt_appendprop_string(fdt, dice, "compatible", COMPAT_DICE);
- if (err)
- return err;
-
- return dice;
-}
-
-static int add_avf_fdt_chosen_properties(void *fdt, bool new_instance)
-{
- int chosen, err;
-
- chosen = find_or_alloc_subnode(fdt, 0, "chosen", CHOSEN_MEM_SIZE);
- if (chosen < 0)
- return chosen;
-
- err = fdt_increase_size(fdt, CHOSEN_MEM_SIZE);
- if (err)
- return err;
-
- err = fdt_appendprop(fdt, chosen, "avf,strict-boot", NULL, 0);
- if (err)
- return err;
-
- if (new_instance) {
- err = fdt_appendprop(fdt, chosen, "avf,new-instance", NULL, 0);
- if (err)
- return err;
- } else {
- err = fdt_delprop(fdt, chosen, "avf,new-instance");
- if (err && err != -FDT_ERR_NOTFOUND)
- return err;
- }
-
- return 0;
-}
-
static struct AvbOps *alloc_avb_ops(void *image, size_t size)
{
int error;
@@ -195,8 +79,7 @@ free_ops:
return NULL;
}
-static int verify_image(void *image, size_t size, void* fdt,
- struct boot_config *cfg)
+static int verify_image(void *image, size_t size, struct boot_config *cfg)
{
const char *instance_uuid = "90d2174a-038a-4bc6-adf3-824848fc5825";
const char *iface_str = "virtio";
@@ -219,6 +102,8 @@ static int verify_image(void *image, size_t size, void* fdt,
goto err;
}
+ cfg->new_instance = false;
+
ret = bcc_vm_instance_handover(iface_str, devnum, instance_uuid,
/*must_exist=*/false, "vm_entry",
BCC_MODE_NORMAL, data, NULL,
@@ -226,11 +111,8 @@ static int verify_image(void *image, size_t size, void* fdt,
if (ret < 0)
goto err;
- ret = add_avf_fdt_chosen_properties(fdt, ret == BCC_VM_INSTANCE_CREATED);
- if (ret) {
- ret = -EIO;
- goto err;
- }
+ cfg->new_instance = (ret == BCC_VM_INSTANCE_CREATED);
+ ret = 0;
err:
if (data)
@@ -245,15 +127,23 @@ int pvmfw_boot_flow(void *fdt, size_t fdt_max_size, void *image, size_t size,
void *bcc, size_t bcc_size)
{
int ret;
- struct boot_config cfg;
+ struct boot_config cfg = {
+ .bcc_addr = virt_to_phys(bcc),
+ .bcc_size = bcc_size,
+ };
if (!size || !is_valid_ram_region(image, size)) {
ret = -EPERM;
goto err;
}
- if (!pvmfw_fdt_is_valid(fdt)) {
- ret = -EINVAL;
+ if (fdt != (const void *)CONFIG_SYS_SDRAM_BASE) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ if (fdt_totalsize(fdt) > fdt_max_size) {
+ ret = -E2BIG;
goto err;
}
@@ -263,18 +153,11 @@ int pvmfw_boot_flow(void *fdt, size_t fdt_max_size, void *image, size_t size,
if (ret)
goto err;
- /* Transferring template here so that verify_image() can update it */
- ret = transfer_fdt_template(fdt, fdt_max_size);
+ ret = verify_image(image, size, &cfg);
if (ret)
goto err;
- ret = add_dice_fdt_mem_rsv(fdt, bcc, bcc_size);
- if (ret < 0) {
- ret = -EIO;
- goto err;
- }
-
- ret = verify_image(image, size, fdt, &cfg);
+ ret = transfer_fdt_template(fdt, fdt_max_size);
if (ret)
goto err;
diff --git a/board/android/pvmfw-arm64/generate_fdt.c b/board/android/pvmfw-arm64/generate_fdt.c
index 022f11b77e..9c77fb7866 100644
--- a/board/android/pvmfw-arm64/generate_fdt.c
+++ b/board/android/pvmfw-arm64/generate_fdt.c
@@ -476,6 +476,21 @@ static int patch_chosen_node(void *fdt, const struct boot_config *cfg)
if (TRY_OPTIONAL(fdt_path_offset(fdt, path)) == -FDT_ERR_NOTFOUND)
TRY(fdt_nop_property(fdt, node, "stdout-path"));
+ if (!cfg->new_instance)
+ TRY(fdt_nop_property(fdt, node, "avf,new-instance"));
+
+ /* '/chosen/avf,strict-boot' is always set (from the base DT) */
+
+ return 0;
+}
+
+static int patch_resmem_node(void *fdt, const struct boot_config *cfg)
+{
+ int node = TRY(fdt_path_offset(fdt, "/reserved-memory/dice"));
+
+ TRY(fdt_setpair_inplace_u64(fdt, node, "reg", cfg->bcc_addr,
+ cfg->bcc_size));
+
return 0;
}
@@ -538,6 +553,10 @@ int patch_output_fdt(void *fdt, const struct boot_config *cfg)
if (err)
return err;
+ err = patch_resmem_node(fdt, cfg);
+ if (err)
+ return err;
+
/* Keep patch_chosen_node() last as it relies on other nodes. */
return patch_chosen_node(fdt, cfg);
}
diff --git a/board/android/pvmfw-arm64/generate_fdt.h b/board/android/pvmfw-arm64/generate_fdt.h
index dc7eef6db1..4cf0832edc 100644
--- a/board/android/pvmfw-arm64/generate_fdt.h
+++ b/board/android/pvmfw-arm64/generate_fdt.h
@@ -37,6 +37,9 @@ struct boot_config {
uint64_t serials[4];
uint64_t swiotlb_size;
uint64_t swiotlb_align;
+ uint64_t bcc_addr;
+ uint64_t bcc_size;
+ bool new_instance;
};
int parse_input_fdt(const void *fdt, struct boot_config *cfg);
diff --git a/board/android/pvmfw-arm64/platform.dts b/board/android/pvmfw-arm64/platform.dts
index c793022e29..ee48f22ec5 100644
--- a/board/android/pvmfw-arm64/platform.dts
+++ b/board/android/pvmfw-arm64/platform.dts
@@ -7,6 +7,7 @@
#define PLACEHOLDER 0xffffffff
#define PLACEHOLDER2 PLACEHOLDER PLACEHOLDER
+#define PLACEHOLDER4 PLACEHOLDER2 PLACEHOLDER2
/dts-v1/;
@@ -19,6 +20,8 @@
chosen {
stdout-path = "/uart@3f8";
linux,pci-probe-only = <1>;
+ avf,strict-boot;
+ avf,new-instance;
};
memory {
@@ -35,6 +38,12 @@
size = <PLACEHOLDER2>;
alignment = <PLACEHOLDER2>;
};
+
+ dice {
+ compatible = "google,open-dice";
+ no-map;
+ reg = <PLACEHOLDER4>;
+ };
};
cpus {