Revision c821c2bd

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