hypcall.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  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. #include <linux/kernel.h>
  11. #include <linux/kvm_host.h>
  12. #include <linux/kvm_para.h>
  13. #define MAX_HYPCALL_ARGS 4
  14. enum emulation_result kvm_mips_emul_hypcall(struct kvm_vcpu *vcpu,
  15. union mips_instruction inst)
  16. {
  17. unsigned int code = (inst.co_format.code >> 5) & 0x3ff;
  18. kvm_debug("[%#lx] HYPCALL %#03x\n", vcpu->arch.pc, code);
  19. switch (code) {
  20. case 0:
  21. return EMULATE_HYPERCALL;
  22. default:
  23. return EMULATE_FAIL;
  24. };
  25. }
  26. static int kvm_mips_hypercall(struct kvm_vcpu *vcpu, unsigned long num,
  27. const unsigned long *args, unsigned long *hret)
  28. {
  29. /* Report unimplemented hypercall to guest */
  30. *hret = -KVM_ENOSYS;
  31. return RESUME_GUEST;
  32. }
  33. int kvm_mips_handle_hypcall(struct kvm_vcpu *vcpu)
  34. {
  35. unsigned long num, args[MAX_HYPCALL_ARGS];
  36. /* read hypcall number and arguments */
  37. num = vcpu->arch.gprs[2]; /* v0 */
  38. args[0] = vcpu->arch.gprs[4]; /* a0 */
  39. args[1] = vcpu->arch.gprs[5]; /* a1 */
  40. args[2] = vcpu->arch.gprs[6]; /* a2 */
  41. args[3] = vcpu->arch.gprs[7]; /* a3 */
  42. return kvm_mips_hypercall(vcpu, num,
  43. args, &vcpu->arch.gprs[2] /* v0 */);
  44. }