Skip to content

Commit b3e336d

Browse files
Andre-ARMgregkh
authored andcommitted
KVM: arm/arm64: Fix reference to uninitialised VGIC
commit b3aff6c upstream. Commit 4b4b451 ("arm/arm64: KVM: Rework the arch timer to use level-triggered semantics") brought the virtual architected timer closer to the VGIC. There is one occasion were we don't properly check for the VGIC actually having been initialized before, but instead go on to check the active state of some IRQ number. If userland hasn't instantiated a virtual GIC, we end up with a kernel NULL pointer dereference: ========= Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = ffffffc9745c5000 [00000000] *pgd=00000009f631e003, *pud=00000009f631e003, *pmd=0000000000000000 Internal error: Oops: 96000006 [#2] PREEMPT SMP Modules linked in: CPU: 0 PID: 2144 Comm: kvm_simplest-ar Tainted: G D 4.5.0-rc2+ #1300 Hardware name: ARM Juno development board (r1) (DT) task: ffffffc976da8000 ti: ffffffc976e28000 task.ti: ffffffc976e28000 PC is at vgic_bitmap_get_irq_val+0x78/0x90 LR is at kvm_vgic_map_is_active+0xac/0xc8 pc : [<ffffffc0000b7e28>] lr : [<ffffffc0000b972c>] pstate: 20000145 .... ========= Fix this by bailing out early of kvm_timer_flush_hwstate() if we don't have a VGIC at all. Reported-by: Cosmin Gorgovan <[email protected]> Acked-by: Marc Zyngier <[email protected]> Signed-off-by: Andre Przywara <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 593337c commit b3e336d

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

virt/kvm/arm/arch_timer.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
143143
* Check if there was a change in the timer state (should we raise or lower
144144
* the line level to the GIC).
145145
*/
146-
static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
146+
static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
147147
{
148148
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
149149

@@ -154,10 +154,12 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
154154
* until we call this function from kvm_timer_flush_hwstate.
155155
*/
156156
if (!vgic_initialized(vcpu->kvm))
157-
return;
157+
return -ENODEV;
158158

159159
if (kvm_timer_should_fire(vcpu) != timer->irq.level)
160160
kvm_timer_update_irq(vcpu, !timer->irq.level);
161+
162+
return 0;
161163
}
162164

163165
/*
@@ -218,7 +220,8 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
218220
bool phys_active;
219221
int ret;
220222

221-
kvm_timer_update_state(vcpu);
223+
if (kvm_timer_update_state(vcpu))
224+
return;
222225

223226
/*
224227
* If we enter the guest with the virtual input level to the VGIC

0 commit comments

Comments
 (0)