Revision c821c2bd target-ppc/kvm.c
b/target-ppc/kvm.c | ||
---|---|---|
37 | 37 |
do { } while (0) |
38 | 38 |
#endif |
39 | 39 |
|
40 |
/* XXX For some odd reason we sometimes hang inside KVM forever. I'd guess it's
|
|
41 |
* a race condition where we actually have a level triggered interrupt, but
|
|
42 |
* the infrastructure can't expose that yet, so the guest ACKs it, goes to
|
|
43 |
* sleep and never gets notified that there's still an interrupt pending.
|
|
40 |
/* XXX We have a race condition where we actually have a level triggered
|
|
41 |
* interrupt, but the infrastructure can't expose that yet, so the guest
|
|
42 |
* takes but ignores it, goes to sleep and never gets notified that there's
|
|
43 |
* still an interrupt pending. |
|
44 | 44 |
* |
45 |
* As a quick workaround, let's just wake up every 500 ms. That way we can |
|
46 |
* assure that we're always reinjecting interrupts in time. |
|
45 |
* As a quick workaround, let's just wake up again 20 ms after we injected |
|
46 |
* an interrupt. That way we can assure that we're always reinjecting |
|
47 |
* interrupts in case the guest swallowed them. |
|
47 | 48 |
*/ |
48 | 49 |
static QEMUTimer *idle_timer; |
49 | 50 |
|
50 |
static void do_nothing(void *opaque)
|
|
51 |
static void kvm_kick_env(void *env)
|
|
51 | 52 |
{ |
52 |
qemu_mod_timer(idle_timer, qemu_get_clock(vm_clock) + |
|
53 |
(get_ticks_per_sec() / 2)); |
|
53 |
qemu_cpu_kick(env); |
|
54 | 54 |
} |
55 | 55 |
|
56 | 56 |
int kvm_arch_init(KVMState *s, int smp_cpus) |
... | ... | |
66 | 66 |
sregs.pvr = cenv->spr[SPR_PVR]; |
67 | 67 |
ret = kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs); |
68 | 68 |
|
69 |
idle_timer = qemu_new_timer(vm_clock, kvm_kick_env, cenv); |
|
70 |
|
|
69 | 71 |
return ret; |
70 | 72 |
} |
71 | 73 |
|
... | ... | |
189 | 191 |
int r; |
190 | 192 |
unsigned irq; |
191 | 193 |
|
192 |
if (!idle_timer) { |
|
193 |
idle_timer = qemu_new_timer(vm_clock, do_nothing, NULL); |
|
194 |
qemu_mod_timer(idle_timer, qemu_get_clock(vm_clock) + |
|
195 |
(get_ticks_per_sec() / 2)); |
|
196 |
} |
|
197 |
|
|
198 | 194 |
/* PowerPC Qemu tracks the various core input pins (interrupt, critical |
199 | 195 |
* interrupt, reset, etc) in PPC-specific env->irq_input_state. */ |
200 | 196 |
if (run->ready_for_interrupt_injection && |
... | ... | |
211 | 207 |
r = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &irq); |
212 | 208 |
if (r < 0) |
213 | 209 |
printf("cpu %d fail inject %x\n", env->cpu_index, irq); |
210 |
|
|
211 |
/* Always wake up soon in case the interrupt was level based */ |
|
212 |
qemu_mod_timer(idle_timer, qemu_get_clock(vm_clock) + |
|
213 |
(get_ticks_per_sec() / 50)); |
|
214 | 214 |
} |
215 | 215 |
|
216 | 216 |
/* We don't know if there are more interrupts pending after this. However, |
Also available in: Unified diff