Exemplo n.º 1
0
static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
	/* SVC called from Hyp mode should never get here */
	kvm_debug("SVC called from Hyp mode shouldn't go here\n");
	BUG();
	return -EINVAL; /* Squash warning */
}
Exemplo n.º 2
0
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
{
	if (atomic_inc_return(&kvm_mips_instance) == 1) {
		kvm_debug("%s: 1st KVM instance, setup host TLB parameters\n",
			  __func__);
		on_each_cpu(kvm_mips_init_vm_percpu, kvm, 1);
	}

	return 0;
}
Exemplo n.º 3
0
static int handle_debug(CPUState *env)
{
#ifdef KVM_CAP_SET_GUEST_DEBUG
    struct kvm_run *run = env->kvm_run;

    return kvm_debug(env, &run->debug.arch);
#else
    return 0;
#endif
}
static void kvm_mips_init_tlbs(struct kvm *kvm)
{
	unsigned long wired;

	/* Add a wired entry to the TLB, it is used to map the commpage to the Guest kernel */
	wired = read_c0_wired();
	write_c0_wired(wired + 1);
	mtc0_tlbw_hazard();
	kvm->arch.commpage_tlb = wired;

	kvm_debug("[%d] commpage TLB: %d\n", smp_processor_id(),
		  kvm->arch.commpage_tlb);
}
Exemplo n.º 5
0
/* Deliver the interrupt of the corresponding priority, if possible. */
int
kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
			uint32_t cause)
{
	int allowed = 0;
	uint32_t exccode;

	struct kvm_vcpu_arch *arch = &vcpu->arch;
	struct kvm_mips_vcpu_te *vcpu_te = vcpu->arch.impl;
	struct mips_coproc *cop0 = vcpu_te->cop0;

	switch (priority) {
	case MIPS_EXC_INT_TIMER:
		if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
			allowed = 1;
			exccode = T_INT;
		}
		break;

	case MIPS_EXC_INT_IO:
		if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
			allowed = 1;
			exccode = T_INT;
		}
		break;

	case MIPS_EXC_INT_IPI_1:
		if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
			allowed = 1;
			exccode = T_INT;
		}
		break;

	case MIPS_EXC_INT_IPI_2:
		if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
			allowed = 1;
			exccode = T_INT;
		}
		break;

	default:
		break;
	}

	/* Are we allowed to deliver the interrupt ??? */
	if (allowed) {

		if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
			/* save old pc */
			kvm_write_c0_guest_epc(cop0, arch->epc);
			kvm_set_c0_guest_status(cop0, ST0_EXL);

			if (cause & CAUSEF_BD)
				kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
			else
				kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

			kvm_debug("Delivering INT @ pc %#lx\n", arch->epc);

		} else
			kvm_err("Trying to deliver interrupt when EXL is already set\n");

		kvm_change_c0_guest_cause(cop0, CAUSEF_EXCCODE,
					  (exccode << CAUSEB_EXCCODE));

		/* XXXSL Set PC to the interrupt exception entry point */
		if (kvm_read_c0_guest_cause(cop0) & CAUSEF_IV)
			arch->epc = KVM_GUEST_KSEG0 + 0x200;
		else
			arch->epc = KVM_GUEST_KSEG0 + 0x180;

		clear_bit(priority, &vcpu_te->pending_exceptions);
	}

	return allowed;
}