platform: generic-arm64: Map MMIO addresses with GUARD This change adds mapping of MMIO regions of GIC and UART registers using MMIO GUARD. MMIO Guard is enforced when pvmfw is in use. Without mapping those regions the pKVM issues a data aborts on each write and read to mmio. This patch addresses this for GIC and UART. Bug: 375584439 Test: boot trusty with pvmfw and verify that it boots and UART works Change-Id: I92d8bc1c56c6d07c152917ce985ac503aa4ea1b1 Signed-off-by: Bartłomiej Grzesik <bgrzesik@google.com>
diff --git a/platform/generic-arm64/debug.c b/platform/generic-arm64/debug.c index 514791b..84edf82 100644 --- a/platform/generic-arm64/debug.c +++ b/platform/generic-arm64/debug.c
@@ -27,6 +27,10 @@ #include <lk/reg.h> #include <lk/types.h> #include <platform/debug.h> +#if MMIO_GUARD_ENABLED +#include <err.h> +#include <lib/libhypervisor/libhypervisor.h> +#endif #include "debug.h" @@ -62,6 +66,19 @@ if (ret) { return; } + +#if MMIO_GUARD_ENABLED + /* + * MMIO Guard map UART registers. Ignore not supported which implies that + * guard is not used. + */ + ret = hypervisor_mmio_map_region(reg_pbase, PAGE_SIZE); + if (ret != NO_ERROR && ret != ERR_NOT_SUPPORTED) { + dprintf(CRITICAL, "failed to mmio guard map uart. error=%d\n", ret); + return; + } +#endif + uart_type = new_uart_type; uart_base = (uint8_t*)page_vaddr + (reg_paddr - reg_pbase); }
diff --git a/platform/generic-arm64/platform.c b/platform/generic-arm64/platform.c index 16568a3..93ce40d 100644 --- a/platform/generic-arm64/platform.c +++ b/platform/generic-arm64/platform.c
@@ -33,6 +33,9 @@ #include <sys/types.h> #if ARM64_BOOT_PROTOCOL_X0_DTB #include <vsock/vsock.h> +#if MMIO_GUARD_ENABLED +#include <lib/libhypervisor/libhypervisor.h> +#endif #endif #include "debug.h" @@ -246,6 +249,25 @@ GICR_SIZE); return; } + +#if MMIO_GUARD_ENABLED + /* + * MMIO Guard map GIC addresses. Ignore not supported which implies that + * guard is not used. + */ + ret = hypervisor_mmio_map_region(gicc, GICC_SIZE); + if (ret != NO_ERROR && ret != ERR_NOT_SUPPORTED) { + dprintf(CRITICAL, "failed to mmio guard map gicc. error=%d\n", ret); + } + ret = hypervisor_mmio_map_region(gicd, GICD_SIZE); + if (ret != NO_ERROR && ret != ERR_NOT_SUPPORTED) { + dprintf(CRITICAL, "failed to mmio guard map gicd. error=%d\n", ret); + } + ret = hypervisor_mmio_map_region(gicr, GICR_SIZE); + if (ret != NO_ERROR && ret != ERR_NOT_SUPPORTED) { + dprintf(CRITICAL, "failed to mmio guard map gicr. error=%d\n", ret); + } +#endif #else #error "Unknown ARM64_BOOT_PROTOCOL" #endif
diff --git a/platform/generic-arm64/rules.mk b/platform/generic-arm64/rules.mk index 02a82ec..3f2d878 100644 --- a/platform/generic-arm64/rules.mk +++ b/platform/generic-arm64/rules.mk
@@ -106,4 +106,13 @@ MODULE_DEPS += trusty/kernel/lib/arm_ffa endif +# MMIO Guard support +MMIO_GUARD_ENABLED ?= false +ifeq (true,$(call TOBOOL,$(MMIO_GUARD_ENABLED))) +MODULE_DEPS += \ + $(LKROOT)/lib/libhypervisor + +MODULE_DEFINES += MMIO_GUARD_ENABLED=1 +endif + include make/module.mk