Beispiel #1
0
void kvmppc_vcpu_block(struct kvm_vcpu *vcpu)
{
	u64 now;
	unsigned long dec_nsec;

	now = get_tb();
	if (now >= vcpu->arch.dec_expires && !kvmppc_core_pending_dec(vcpu))
		kvmppc_core_queue_dec(vcpu);
	if (vcpu->arch.pending_exceptions)
		return;
	if (vcpu->arch.dec_expires != ~(u64)0) {
		dec_nsec = (vcpu->arch.dec_expires - now) * NSEC_PER_SEC /
			tb_ticks_per_sec;
		hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
			      HRTIMER_MODE_REL);
	}

	kvmppc_vcpu_blocked(vcpu);

	kvm_vcpu_block(vcpu);
	vcpu->stat.halt_wakeup++;

	if (vcpu->arch.dec_expires != ~(u64)0)
		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);

	kvmppc_vcpu_unblocked(vcpu);
}
Beispiel #2
0
static void update_timer_ints(struct kvm_vcpu *vcpu)
{
	if ((vcpu->arch.tcr & TCR_DIE) && (vcpu->arch.tsr & TSR_DIS))
		kvmppc_core_queue_dec(vcpu);
	else
		kvmppc_core_dequeue_dec(vcpu);
}
Beispiel #3
0
void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
{
	unsigned long dec_nsec;

	pr_debug("mtDEC: %x\n", vcpu->arch.dec);
#ifdef CONFIG_PPC_BOOK3S
	/* mtdec lowers the interrupt line when positive. */
	kvmppc_core_dequeue_dec(vcpu);

	/* POWER4+ triggers a dec interrupt if the value is < 0 */
	if (vcpu->arch.dec & 0x80000000) {
		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
		kvmppc_core_queue_dec(vcpu);
		return;
	}
#endif
	if (kvmppc_dec_enabled(vcpu)) {
		/* The decrementer ticks at the same rate as the timebase, so
		 * that's how we convert the guest DEC value to the number of
		 * host ticks. */

		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
		dec_nsec = vcpu->arch.dec;
		dec_nsec *= 1000;
		dec_nsec /= tb_ticks_per_usec;
		hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
			      HRTIMER_MODE_REL);
		vcpu->arch.dec_jiffies = get_tb();
	} else {
		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
	}
}
Beispiel #4
0
static void kvmppc_decrementer_func(unsigned long data)
{
	struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data;

	kvmppc_core_queue_dec(vcpu);

	if (waitqueue_active(&vcpu->wq)) {
		wake_up_interruptible(&vcpu->wq);
		vcpu->stat.halt_wakeup++;
	}
}
Beispiel #5
0
void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
{
    unsigned long dec_nsec;
    unsigned long long dec_time;

    pr_debug("mtDEC: %x\n", vcpu->arch.dec);
    hrtimer_try_to_cancel(&vcpu->arch.dec_timer);

#ifdef CONFIG_PPC_BOOK3S
    /* mtdec lowers the interrupt line when positive. */
    kvmppc_core_dequeue_dec(vcpu);

    /* POWER4+ triggers a dec interrupt if the value is < 0 */
    if (vcpu->arch.dec & 0x80000000) {
        kvmppc_core_queue_dec(vcpu);
        return;
    }
#endif

#ifdef CONFIG_BOOKE
    /* On BOOKE, DEC = 0 is as good as decrementer not enabled */
    if (vcpu->arch.dec == 0)
        return;
#endif

    /*
     * The decrementer ticks at the same rate as the timebase, so
     * that's how we convert the guest DEC value to the number of
     * host ticks.
     */

    dec_time = vcpu->arch.dec;
    /*
     * Guest timebase ticks at the same frequency as host decrementer.
     * So use the host decrementer calculations for decrementer emulation.
     */
    dec_time = dec_time << decrementer_clockevent.shift;
    do_div(dec_time, decrementer_clockevent.mult);
    dec_nsec = do_div(dec_time, NSEC_PER_SEC);
    hrtimer_start(&vcpu->arch.dec_timer,
                  ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
    vcpu->arch.dec_jiffies = get_tb();
}