/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * KVM/MIPS: Hypercall handling. * * Copyright (C) 2015 Imagination Technologies Ltd. */ #include <linux/kernel.h> #include <linux/kvm_host.h> #include <linux/kvm_para.h> #define MAX_HYPCALL_ARGS 4 enum emulation_result kvm_mips_emul_hypcall(struct kvm_vcpu *vcpu, union mips_instruction inst) { unsigned int code = (inst.co_format.code >> 5) & 0x3ff; kvm_debug("[%#lx] HYPCALL %#03x\n", vcpu->arch.pc, code); switch (code) { case 0: return EMULATE_HYPERCALL; default: return EMULATE_FAIL; }; } static int kvm_mips_hypercall(struct kvm_vcpu *vcpu, unsigned long num, const unsigned long *args, unsigned long *hret) { /* Report unimplemented hypercall to guest */ *hret = -KVM_ENOSYS; return RESUME_GUEST; } int kvm_mips_handle_hypcall(struct kvm_vcpu *vcpu) { unsigned long num, args[MAX_HYPCALL_ARGS]; /* read hypcall number and arguments */ num = vcpu->arch.gprs[2]; /* v0 */ args[0] = vcpu->arch.gprs[4]; /* a0 */ args[1] = vcpu->arch.gprs[5]; /* a1 */ args[2] = vcpu->arch.gprs[6]; /* a2 */ args[3] = vcpu->arch.gprs[7]; /* a3 */ return kvm_mips_hypercall(vcpu, num, args, &vcpu->arch.gprs[2] /* v0 */); }