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.

Instrument timer mediation paths for virtual counter drift

+12 -1
+4
core/vcpu.c
··· 137 137 uart_put_dec64(vcpu->stats.virtual_irqs_injected); 138 138 uart_puts(" virq_done="); 139 139 uart_put_dec64(vcpu->stats.virtual_irqs_completed); 140 + uart_puts(" timer_syncs="); 141 + uart_put_dec64(vcpu->stats.timer_syncs); 142 + uart_puts(" timer_delta="); 143 + uart_put_dec64(vcpu->stats.timer_last_delta); 140 144 uart_puts("\n"); 141 145 for (uint32_t i = 0; i < 31u; i++) { 142 146 uart_puts("x");
+6 -1
drivers/timer.c
··· 27 27 28 28 void timer_vcpu_sync(struct vcpu *vcpu) 29 29 { 30 + uint64_t now; 30 31 if (vcpu == (struct vcpu *)0) { 31 32 return; 32 33 } 33 34 35 + vcpu->stats.timer_syncs++; 36 + now = timer_now(); 34 37 uint64_t ctl = vcpu->sysregs.cntv_ctl_el0; 35 38 bool enabled = (ctl & 1u) != 0u; 36 39 bool masked = (ctl & 2u) != 0u; ··· 39 42 return; 40 43 } 41 44 42 - if (timer_now() >= vcpu->sysregs.cntv_cval_el0) { 45 + if (now >= vcpu->sysregs.cntv_cval_el0) { 46 + vcpu->stats.timer_last_delta = now - vcpu->sysregs.cntv_cval_el0; 43 47 vcpu->sysregs.cntv_ctl_el0 |= 4u; 44 48 vcpu_set_pending_irq(vcpu, CONFIG_VTIMER_IRQ); 45 49 } else { 50 + vcpu->stats.timer_last_delta = vcpu->sysregs.cntv_cval_el0 - now; 46 51 vcpu->sysregs.cntv_ctl_el0 &= ~4ull; 47 52 vcpu_clear_pending_irq(vcpu, CONFIG_VTIMER_IRQ); 48 53 }
+2
include/hv/vcpu.h
··· 46 46 uint64_t injected_undefs; 47 47 uint64_t virtual_irqs_injected; 48 48 uint64_t virtual_irqs_completed; 49 + uint64_t timer_syncs; 50 + uint64_t timer_last_delta; 49 51 }; 50 52 51 53 struct vcpu {