diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c index 5ad553e93..8c7518d1d 100644 --- a/plat/qemu/common/qemu_bl2_setup.c +++ b/plat/qemu/common/qemu_bl2_setup.c @@ -24,6 +24,9 @@ #endif #include #include +#if ENABLE_RME +#include +#endif #include "qemu_private.h" @@ -151,6 +154,53 @@ void qemu_bl2_sync_transfer_list(void) #endif } +#if ENABLE_RME +static void bl2_plat_gpt_setup(void) +{ + /* + * The GPT library might modify the gpt regions structure to optimize + * the layout, so the array cannot be constant. + */ + pas_region_t pas_regions[] = { + QEMU_PAS_ROOT, + QEMU_PAS_SECURE, + QEMU_PAS_GPTS, + QEMU_PAS_NS0, + QEMU_PAS_REALM, + QEMU_PAS_NS1, + }; + + /* + * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry + * covering 1GB (currently the only supported option), then covering + * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the + * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA). + */ + if (gpt_init_l0_tables(GPCCR_PPS_1TB, PLAT_QEMU_L0_GPT_BASE, + PLAT_QEMU_L0_GPT_SIZE) < 0) { + ERROR("gpt_init_l0_tables() failed!\n"); + panic(); + } + + /* Carve out defined PAS ranges. */ + if (gpt_init_pas_l1_tables(GPCCR_PGS_4K, + PLAT_QEMU_L1_GPT_BASE, + PLAT_QEMU_L1_GPT_SIZE, + pas_regions, + (unsigned int)(sizeof(pas_regions) / + sizeof(pas_region_t))) < 0) { + ERROR("gpt_init_pas_l1_tables() failed!\n"); + panic(); + } + + INFO("Enabling Granule Protection Checks\n"); + if (gpt_enable() < 0) { + ERROR("gpt_enable() failed!\n"); + panic(); + } +} +#endif + void bl2_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { @@ -173,6 +223,9 @@ void bl2_plat_arch_setup(void) /* BL2 runs in EL3 when RME enabled. */ assert(get_armv9_2_feat_rme_support() != 0U); enable_mmu_el3(0); + + /* Initialise and enable granule protection after MMU. */ + bl2_plat_gpt_setup(); #else /* ENABLE_RME */ #ifdef __aarch64__ diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c index 0fe399397..228aff551 100644 --- a/plat/qemu/common/qemu_bl31_setup.c +++ b/plat/qemu/common/qemu_bl31_setup.c @@ -8,6 +8,7 @@ #include #include +#include #include #include "qemu_private.h" @@ -108,6 +109,20 @@ void bl31_plat_arch_setup(void) setup_page_tables(bl_regions, plat_qemu_get_mmap()); enable_mmu_el3(0); + +#if ENABLE_RME + /* + * Initialise Granule Protection library and enable GPC for the primary + * processor. The tables have already been initialized by a previous BL + * stage, so there is no need to provide any PAS here. This function + * sets up pointers to those tables. + */ + if (gpt_runtime_init() < 0) { + ERROR("gpt_runtime_init() failed!\n"); + panic(); + } +#endif /* ENABLE_RME */ + } static void qemu_gpio_init(void)