AArch64 EL2 hypervisor for QEMU virt that boots at EL2
1

Configure Feed

Select the types of activity you want to include in your feed.

ariel / guest / main.c
3.1 kB 134 lines
1#include <stdint.h> 2#include <stddef.h> 3 4void guest_main(void); 5uint64_t guest_hvc_call(uint64_t num, uint64_t a1, uint64_t a2); 6 7static size_t guest_strlen(const char *s) 8{ 9 size_t n = 0; 10 while (s[n] != '\0') { 11 n++; 12 } 13 return n; 14} 15 16static uint64_t hvc_call(uint64_t num, uint64_t a1, uint64_t a2) 17{ 18 return guest_hvc_call(num, a1, a2); 19} 20 21static void console(const char *s) 22{ 23 (void)hvc_call(4u, (uint64_t)(uintptr_t)s, guest_strlen(s)); 24} 25 26static uint64_t read_midr(void) 27{ 28 uint64_t v; 29 __asm__ volatile("mrs %0, midr_el1" : "=r"(v)); 30 return v; 31} 32 33static uint64_t read_pfr0(void) 34{ 35 uint64_t v; 36 __asm__ volatile("mrs %0, id_aa64pfr0_el1" : "=r"(v)); 37 return v; 38} 39 40static uint64_t read_cntv_ctl(void) 41{ 42 uint64_t v; 43 __asm__ volatile("mrs %0, cntv_ctl_el0" : "=r"(v)); 44 return v; 45} 46 47static void write_sctlr(uint64_t v) 48{ 49 __asm__ volatile("msr sctlr_el1, %0" :: "r"(v) : "memory"); 50} 51 52static void write_vbar(uint64_t v) 53{ 54 __asm__ volatile("msr vbar_el1, %0" :: "r"(v) : "memory"); 55} 56 57static void write_ttbr0(uint64_t v) 58{ 59 __asm__ volatile("msr ttbr0_el1, %0" :: "r"(v) : "memory"); 60} 61 62static void write_tcr(uint64_t v) 63{ 64 __asm__ volatile("msr tcr_el1, %0" :: "r"(v) : "memory"); 65} 66 67static void write_actlr(uint64_t v) 68{ 69 __asm__ volatile("msr actlr_el1, %0" :: "r"(v) : "memory"); 70} 71 72static uint64_t attempt_hcr_el2_read(void) 73{ 74 uint64_t v; 75 __asm__ volatile("mrs %0, hcr_el2" : "=r"(v)); 76 return v; 77} 78 79static uint64_t read_unknown_sysreg(void) 80{ 81 uint64_t v; 82 __asm__ volatile("mrs %0, S3_7_C15_C15_7" : "=r"(v)); 83 return v; 84} 85 86void guest_main(void) 87{ 88 console("diagnostic guest: start"); 89 uint64_t midr = read_midr(); 90 (void)midr; 91 console("diagnostic guest: read midr_el1"); 92 93 uint64_t pfr0 = read_pfr0(); 94 (void)pfr0; 95 console("diagnostic guest: read id_aa64pfr0_el1"); 96 97 write_sctlr(0x30d00800u); 98 console("diagnostic guest: wrote sctlr_el1 shadow"); 99 100 write_vbar(0x40000800u); 101 console("diagnostic guest: wrote vbar_el1 vector base"); 102 103 write_ttbr0(0u); 104 console("diagnostic guest: wrote ttbr0_el1 shadow"); 105 106 write_tcr(0u); 107 console("diagnostic guest: wrote tcr_el1 shadow"); 108 109 uint64_t cntv = read_cntv_ctl(); 110 (void)cntv; 111 console("diagnostic guest: read cntv_ctl_el0"); 112 113 (void)hvc_call(0u, 0u, 0u); 114 console("diagnostic guest: requested hv id"); 115 116 (void)hvc_call(1u, 0u, 0u); 117 console("diagnostic guest: requested log dump"); 118 119 console("diagnostic guest: attempting denied hcr_el2 read"); 120 (void)attempt_hcr_el2_read(); 121 console("diagnostic guest: returned through guest undefined vector"); 122 123 __asm__ volatile("brk #0"); 124 console("diagnostic guest: returned through guest brk vector"); 125 126 console("diagnostic guest: attempting unknown sysreg read"); 127 (void)read_unknown_sysreg(); 128 console("diagnostic guest: returned from unknown sysreg read"); 129 130 console("diagnostic guest: attempting denied actlr_el1 write"); 131 write_actlr(1u); 132 console("diagnostic guest: unexpected return from denied actlr_el1"); 133 (void)hvc_call(3u, 0u, 0u); 134}