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.

Use EL2 exception telemetry to expose guest trap behaviour through the UART monitor

+53
+53
core/vcpu.c
··· 2 2 #include "hv/arch.h" 3 3 #include "hv/panic.h" 4 4 #include "hv/string.h" 5 + #include "hv/sysreg.h" 5 6 #include "hv/uart.h" 6 7 #include "hv/vcpu.h" 7 8 ··· 111 112 g_current_vcpu = vcpu; 112 113 } 113 114 115 + static void vcpu_dump_exception_telemetry(const struct vcpu *vcpu) 116 + { 117 + uart_puts("trap_ec ec="); 118 + uart_put_hex64(ESR_EC_HVC64); 119 + uart_puts(" name="); 120 + uart_puts(esr_ec_name(ESR_EC_HVC64)); 121 + uart_puts(" count="); 122 + uart_put_dec64(vcpu->stats.hvc_calls); 123 + uart_puts("\ntrap_ec ec="); 124 + uart_put_hex64(ESR_EC_SYSREG); 125 + uart_puts(" name="); 126 + uart_puts(esr_ec_name(ESR_EC_SYSREG)); 127 + uart_puts(" count="); 128 + uart_put_dec64(vcpu->stats.sysreg_traps); 129 + uart_puts("\ntrap_ec ec="); 130 + uart_put_hex64(ESR_EC_SMC64); 131 + uart_puts(" name="); 132 + uart_puts(esr_ec_name(ESR_EC_SMC64)); 133 + uart_puts(" denied="); 134 + uart_put_dec64(vcpu->stats.smc_denied); 135 + uart_puts("\ntrap_ec ec="); 136 + uart_put_hex64(ESR_EC_WFI_WFE); 137 + uart_puts(" name="); 138 + uart_puts(esr_ec_name(ESR_EC_WFI_WFE)); 139 + uart_puts(" count="); 140 + uart_put_dec64(vcpu->stats.wfx_traps); 141 + uart_puts("\ntrap_ec ec="); 142 + uart_put_hex64(ESR_EC_IABT_LOWER); 143 + uart_puts(" name="); 144 + uart_puts(esr_ec_name(ESR_EC_IABT_LOWER)); 145 + uart_puts(" count="); 146 + uart_put_dec64(vcpu->stats.instruction_aborts); 147 + uart_puts("\ntrap_ec ec="); 148 + uart_put_hex64(ESR_EC_DABT_LOWER); 149 + uart_puts(" name="); 150 + uart_puts(esr_ec_name(ESR_EC_DABT_LOWER)); 151 + uart_puts(" count="); 152 + uart_put_dec64(vcpu->stats.data_aborts); 153 + uart_puts("\ntrap_ec ec="); 154 + uart_put_hex64(ESR_EC_UNKNOWN); 155 + uart_puts(" name="); 156 + uart_puts(esr_ec_name(ESR_EC_UNKNOWN)); 157 + uart_puts(" count="); 158 + uart_put_dec64(vcpu->stats.unknown_exceptions); 159 + uart_puts("\n"); 160 + } 161 + 114 162 void vcpu_dump(const struct vcpu *vcpu) 115 163 { 116 164 if (vcpu == (const struct vcpu *)0) { ··· 129 177 uart_put_hex64(vcpu->sp_el1); 130 178 uart_puts(" traps="); 131 179 uart_put_dec64(vcpu->stats.traps); 180 + uart_puts(" last_ec="); 181 + uart_put_hex64(esr_ec(vcpu->last_esr)); 182 + uart_puts(" last_ecname="); 183 + uart_puts(esr_ec_name(esr_ec(vcpu->last_esr))); 132 184 uart_puts(" injected_undefs="); 133 185 uart_put_dec64(vcpu->stats.injected_undefs); 134 186 uart_puts(" pending_irq="); ··· 142 194 uart_puts(" timer_delta="); 143 195 uart_put_dec64(vcpu->stats.timer_last_delta); 144 196 uart_puts("\n"); 197 + vcpu_dump_exception_telemetry(vcpu); 145 198 for (uint32_t i = 0; i < 31u; i++) { 146 199 uart_puts("x"); 147 200 uart_put_dec64(i);