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 */ }
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; }
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); }
/* 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; }