AArch64 EL2 hypervisor for QEMU virt that boots at EL2
1#include "hv/allocator.h"
2#include "hv/arch.h"
3#include "hv/config.h"
4#include "hv/el2_mmu.h"
5#include "hv/log.h"
6#include "hv/panic.h"
7#include "hv/policy.h"
8#include "hv/platform.h"
9#include "hv/selftest.h"
10#include "hv/stage2.h"
11#include "hv/sysreg.h"
12#include "hv/vcpu.h"
13
14static void require(bool ok, const char *name)
15{
16 if (!ok) {
17 panic(name);
18 }
19 log_simple(LOG_SELFTEST, 0u, (uint64_t)(uintptr_t)name, 0u);
20}
21
22void selftests_run_or_panic(void)
23{
24 require(hv_is_aligned_u64((uint64_t)(uintptr_t)__vectors_el2, 2048u), "selftest vectors alignment");
25 require(stage2_selftest(), "selftest stage2 descriptors");
26 require(el2_mmu_selftest(), "selftest el2 mmu plan");
27 require(CONFIG_GUEST_RAM_SIZE != 0u && hv_is_aligned_u64(CONFIG_GUEST_RAM_BASE, CONFIG_PAGE_SIZE),
28 "selftest guest memory bounds");
29 require(platform_selftest(), "selftest qemu virt invariants");
30 require(policy_selftest(), "selftest policy table");
31 require(sysreg_selftest(), "selftest sysreg decoder");
32 require(vcpu_frame_selftest(), "selftest vcpu frame serialisation");
33 require(log_selftest(), "selftest log wraparound");
34 require(allocator_selftest(), "selftest allocator");
35
36 uint64_t hcr;
37 uint64_t sctlr;
38 uint64_t vttbr;
39 __asm__ volatile("mrs %0, hcr_el2" : "=r"(hcr));
40 __asm__ volatile("mrs %0, sctlr_el2" : "=r"(sctlr));
41 __asm__ volatile("mrs %0, vttbr_el2" : "=r"(vttbr));
42 require((hcr & HV_BIT(0)) != 0u && (hcr & HV_BIT(31)) != 0u, "selftest hcr trap sanity");
43 require((sctlr & (HV_BIT(0) | HV_BIT(2) | HV_BIT(12))) ==
44 (HV_BIT(0) | HV_BIT(2) | HV_BIT(12)), "selftest sctlr el2 mmu enabled");
45 require((vttbr & 0x0000fffffffff000ull) == stage2_vttbr(), "selftest vttbr root");
46}