From: Sergiu Moga Date: Mon, 27 Mar 2023 10:00:30 +0000 (+0300) Subject: plat/kvm/arm: Enable the Unikernel to be built as an UEFI application X-Git-Tag: RELEASE-0.14.0~70 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=46d98734ca577da19459dd353567c8d1a66bec5a;p=unikraft%2Funikraft.git plat/kvm/arm: Enable the Unikernel to be built as an UEFI application If `CONFIG_EFI_STUB` is enabled, add to the build system the ARM UEFI entry stub and the ARM specific post-EFI stub that applies finishing touches to the platform initialization. Add a configuration entry `KVM_BOOT_QEMU_VIRT` to explicitly indicate that we are booting from the default `QEMU virt` environment. This will help us differentiate between UEFI and non-UEFI ARM builds. Signed-off-by: Sergiu Moga Reviewed-by: Michalis Pappas Approved-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Closes: #909 --- diff --git a/plat/kvm/Config.uk b/plat/kvm/Config.uk index de5fa22ca..5fa58e366 100644 --- a/plat/kvm/Config.uk +++ b/plat/kvm/Config.uk @@ -29,6 +29,12 @@ config KVM_BOOT_PROTO_LXBOOT help Linux 64-bit Boot Protocol +config KVM_BOOT_PROTOCOL_QEMU_VIRT + bool "QEMU virt" + depends on KVM_VMM_QEMU && !KVM_VMM_FIRECRACKER && ARCH_ARM_64 + help + Default QEMU virt environment + config KVM_BOOT_EFI_STUB bool "EFI stub" depends on KVM_VMM_QEMU && !KVM_VMM_FIRECRACKER diff --git a/plat/kvm/Linker.uk b/plat/kvm/Linker.uk index 35d53a60a..b2c5196b8 100644 --- a/plat/kvm/Linker.uk +++ b/plat/kvm/Linker.uk @@ -10,8 +10,15 @@ KVM_LDFLAGS-y += -Wl,--entry=uk_efi_entry64 KVM_LDFLAGS-y += -Wl,-m,elf_x86_64 endif else ifeq (arm64,$(CONFIG_UK_ARCH)) +ifeq ($(CONFIG_KVM_BOOT_PROTOCOL_QEMU_VIRT),y) +KVM_LDFLAGS-y += -Wl,--entry=_libkvmplat_entry KVM_LDFLAGS-y += -Wl,-m,aarch64elf KVM_LINK_LIBGCC_FLAG := -lgcc +else ifeq ($(CONFIG_KVM_BOOT_EFI_STUB),y) +KVM_LDFLAGS-y += -Wl,--entry=uk_efi_entry64 +KVM_LDFLAGS-y += -Wl,-m,aarch64elf +KVM_LINK_LIBGCC_FLAG := -lgcc +endif endif ## diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk index 98a4744ef..a33fc9a0e 100644 --- a/plat/kvm/Makefile.uk +++ b/plat/kvm/Makefile.uk @@ -114,7 +114,12 @@ ifeq ($(CONFIG_HAVE_SMP),y) LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/lcpu_start.S endif LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/bpt64.S|arm +ifeq ($(CONFIG_KVM_BOOT_EFI_STUB),y) +LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/efi_post.c +LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/efi_entry64.S|arm +else LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/entry64.S|isr +endif LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/exceptions.S|isr LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/pagetable64.S|isr LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/setup.c diff --git a/plat/kvm/arm/efi_arm.c b/plat/kvm/arm/efi_arm.c deleted file mode 100644 index e28beba0a..000000000 --- a/plat/kvm/arm/efi_arm.c +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. - * Licensed under the BSD-3-Clause License (the "License"). - * You may not use this file except in compliance with the License. - */ -#include -#include -#include -#include -#include - -extern void clean_and_invalidate_dcache_range(unsigned long, unsigned long); -extern void _ukplat_entry(void *) __noreturn; -extern __paddr_t vector_table; -extern void start_mmu(void); - -static __u8 __align(16) uk_efi_bootstack[__PAGE_SIZE]; - -/* We cannot set the system register directly */ -#define uk_efi_set_sp_el1(sp) \ - __asm__ __volatile__("mov sp, %0\n" ::"r" (sp)) - -void __noreturn uk_efi_jmp_to_kern(void) -{ - ukplat_lcpu_disable_irq(); - - /* Invalidate the image from the data cache */ - clean_and_invalidate_dcache_range(__BASE_ADDR, __END); - - SYSREG_WRITE64(sctlr_el1, SCTLR_SET_BITS); - SYSREG_WRITE64(contextidr_el1, 0); - SYSREG_WRITE64(VBAR_EL1, &vector_table); - SYSREG_WRITE64(spsr_el1, 0); - SYSREG_WRITE64(elr_el1, 0); - SYSREG_WRITE64(cntv_cval_el0, 0); - /* EDKII's backtrace and dump register code is written in C, so - * it requires a stack. If SP_EL1 is corrupted before an exception - * is taken, they rely on SP_EL0 which is set to a backup stack. - * Thus, reset it to 0 to avoid any back reference to firmware. - */ - SYSREG_WRITE64(sp_el0, 0); - SYSREG_WRITE64(tpidr_el0, 0); - - start_mmu(); - uk_efi_set_sp_el1(uk_efi_bootstack + __PAGE_SIZE); - _ukplat_entry(ukplat_bootinfo_get()); -} diff --git a/plat/kvm/arm/efi_post.c b/plat/kvm/arm/efi_post.c new file mode 100644 index 000000000..e28beba0a --- /dev/null +++ b/plat/kvm/arm/efi_post.c @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ +#include +#include +#include +#include +#include + +extern void clean_and_invalidate_dcache_range(unsigned long, unsigned long); +extern void _ukplat_entry(void *) __noreturn; +extern __paddr_t vector_table; +extern void start_mmu(void); + +static __u8 __align(16) uk_efi_bootstack[__PAGE_SIZE]; + +/* We cannot set the system register directly */ +#define uk_efi_set_sp_el1(sp) \ + __asm__ __volatile__("mov sp, %0\n" ::"r" (sp)) + +void __noreturn uk_efi_jmp_to_kern(void) +{ + ukplat_lcpu_disable_irq(); + + /* Invalidate the image from the data cache */ + clean_and_invalidate_dcache_range(__BASE_ADDR, __END); + + SYSREG_WRITE64(sctlr_el1, SCTLR_SET_BITS); + SYSREG_WRITE64(contextidr_el1, 0); + SYSREG_WRITE64(VBAR_EL1, &vector_table); + SYSREG_WRITE64(spsr_el1, 0); + SYSREG_WRITE64(elr_el1, 0); + SYSREG_WRITE64(cntv_cval_el0, 0); + /* EDKII's backtrace and dump register code is written in C, so + * it requires a stack. If SP_EL1 is corrupted before an exception + * is taken, they rely on SP_EL0 which is set to a backup stack. + * Thus, reset it to 0 to avoid any back reference to firmware. + */ + SYSREG_WRITE64(sp_el0, 0); + SYSREG_WRITE64(tpidr_el0, 0); + + start_mmu(); + uk_efi_set_sp_el1(uk_efi_bootstack + __PAGE_SIZE); + _ukplat_entry(ukplat_bootinfo_get()); +} diff --git a/plat/kvm/arm/link64.lds.S b/plat/kvm/arm/link64.lds.S index 8bff6ab62..07180eebf 100644 --- a/plat/kvm/arm/link64.lds.S +++ b/plat/kvm/arm/link64.lds.S @@ -40,7 +40,6 @@ OUTPUT_FORMAT("elf64-littleaarch64") OUTPUT_ARCH(aarch64) -ENTRY(_libkvmplat_entry) PHDRS {