Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / mips / kvm / hypcall.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * KVM/MIPS: Hypercall handling.
7  *
8  * Copyright (C) 2015  Imagination Technologies Ltd.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/kvm_host.h>
13 #include <linux/kvm_para.h>
14
15 #define MAX_HYPCALL_ARGS        4
16
17 enum emulation_result kvm_mips_emul_hypcall(struct kvm_vcpu *vcpu,
18                                             union mips_instruction inst)
19 {
20         unsigned int code = (inst.co_format.code >> 5) & 0x3ff;
21
22         kvm_debug("[%#lx] HYPCALL %#03x\n", vcpu->arch.pc, code);
23
24         switch (code) {
25         case 0:
26                 return EMULATE_HYPERCALL;
27         default:
28                 return EMULATE_FAIL;
29         };
30 }
31
32 static int kvm_mips_hypercall(struct kvm_vcpu *vcpu, unsigned long num,
33                               const unsigned long *args, unsigned long *hret)
34 {
35         /* Report unimplemented hypercall to guest */
36         *hret = -KVM_ENOSYS;
37         return RESUME_GUEST;
38 }
39
40 int kvm_mips_handle_hypcall(struct kvm_vcpu *vcpu)
41 {
42         unsigned long num, args[MAX_HYPCALL_ARGS];
43
44         /* read hypcall number and arguments */
45         num = vcpu->arch.gprs[2];       /* v0 */
46         args[0] = vcpu->arch.gprs[4];   /* a0 */
47         args[1] = vcpu->arch.gprs[5];   /* a1 */
48         args[2] = vcpu->arch.gprs[6];   /* a2 */
49         args[3] = vcpu->arch.gprs[7];   /* a3 */
50
51         return kvm_mips_hypercall(vcpu, num,
52                                   args, &vcpu->arch.gprs[2] /* v0 */);
53 }