Beispiel #1
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 #2
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 #3
0
int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
{
	u64 now;

	if (signal_pending(current)) {
		run->exit_reason = KVM_EXIT_INTR;
		return -EINTR;
	}

	flush_fp_to_thread(current);
	flush_altivec_to_thread(current);
	flush_vsx_to_thread(current);
	preempt_disable();

	/*
	 * Make sure we are running on thread 0, and that
	 * secondary threads are offline.
	 * XXX we should also block attempts to bring any
	 * secondary threads online.
	 */
	if (threads_per_core > 1) {
		int cpu = smp_processor_id();
		int thr = cpu_thread_in_core(cpu);

		if (thr)
			goto out;
		while (++thr < threads_per_core)
			if (cpu_online(cpu + thr))
				goto out;
	}

	kvm_guest_enter();

	__kvmppc_vcore_entry(NULL, vcpu);

	kvm_guest_exit();

	preempt_enable();
	kvm_resched(vcpu);

	now = get_tb();
	/* cancel pending dec exception if dec is positive */
	if (now < vcpu->arch.dec_expires && kvmppc_core_pending_dec(vcpu))
		kvmppc_core_dequeue_dec(vcpu);

	return kvmppc_handle_exit(run, vcpu, current);

 out:
	preempt_enable();
	return -EBUSY;
}
Beispiel #4
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();
}