aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kvm/kvm_mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kvm/kvm_mips.c')
-rw-r--r--arch/mips/kvm/kvm_mips.c305
1 files changed, 284 insertions, 21 deletions
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
index e0dad0289797..dd203e59e6fd 100644
--- a/arch/mips/kvm/kvm_mips.c
+++ b/arch/mips/kvm/kvm_mips.c
@@ -195,7 +195,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
195long 195long
196kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) 196kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
197{ 197{
198 return -EINVAL; 198 return -ENOIOCTLCMD;
199} 199}
200 200
201void kvm_arch_free_memslot(struct kvm_memory_slot *free, 201void kvm_arch_free_memslot(struct kvm_memory_slot *free,
@@ -401,7 +401,7 @@ int
401kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, 401kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
402 struct kvm_guest_debug *dbg) 402 struct kvm_guest_debug *dbg)
403{ 403{
404 return -EINVAL; 404 return -ENOIOCTLCMD;
405} 405}
406 406
407int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) 407int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
@@ -475,14 +475,248 @@ int
475kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, 475kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
476 struct kvm_mp_state *mp_state) 476 struct kvm_mp_state *mp_state)
477{ 477{
478 return -EINVAL; 478 return -ENOIOCTLCMD;
479} 479}
480 480
481int 481int
482kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, 482kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
483 struct kvm_mp_state *mp_state) 483 struct kvm_mp_state *mp_state)
484{ 484{
485 return -EINVAL; 485 return -ENOIOCTLCMD;
486}
487
488#define MIPS_CP0_32(_R, _S) \
489 (KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x10000 | (8 * (_R) + (_S)))
490
491#define MIPS_CP0_64(_R, _S) \
492 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x10000 | (8 * (_R) + (_S)))
493
494#define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0)
495#define KVM_REG_MIPS_CP0_ENTRYLO0 MIPS_CP0_64(2, 0)
496#define KVM_REG_MIPS_CP0_ENTRYLO1 MIPS_CP0_64(3, 0)
497#define KVM_REG_MIPS_CP0_CONTEXT MIPS_CP0_64(4, 0)
498#define KVM_REG_MIPS_CP0_USERLOCAL MIPS_CP0_64(4, 2)
499#define KVM_REG_MIPS_CP0_PAGEMASK MIPS_CP0_32(5, 0)
500#define KVM_REG_MIPS_CP0_PAGEGRAIN MIPS_CP0_32(5, 1)
501#define KVM_REG_MIPS_CP0_WIRED MIPS_CP0_32(6, 0)
502#define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
503#define KVM_REG_MIPS_CP0_BADVADDR MIPS_CP0_64(8, 0)
504#define KVM_REG_MIPS_CP0_COUNT MIPS_CP0_32(9, 0)
505#define KVM_REG_MIPS_CP0_ENTRYHI MIPS_CP0_64(10, 0)
506#define KVM_REG_MIPS_CP0_COMPARE MIPS_CP0_32(11, 0)
507#define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0)
508#define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0)
509#define KVM_REG_MIPS_CP0_EBASE MIPS_CP0_64(15, 1)
510#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
511#define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1)
512#define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2)
513#define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3)
514#define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7)
515#define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0)
516#define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0)
517
518static u64 kvm_mips_get_one_regs[] = {
519 KVM_REG_MIPS_R0,
520 KVM_REG_MIPS_R1,
521 KVM_REG_MIPS_R2,
522 KVM_REG_MIPS_R3,
523 KVM_REG_MIPS_R4,
524 KVM_REG_MIPS_R5,
525 KVM_REG_MIPS_R6,
526 KVM_REG_MIPS_R7,
527 KVM_REG_MIPS_R8,
528 KVM_REG_MIPS_R9,
529 KVM_REG_MIPS_R10,
530 KVM_REG_MIPS_R11,
531 KVM_REG_MIPS_R12,
532 KVM_REG_MIPS_R13,
533 KVM_REG_MIPS_R14,
534 KVM_REG_MIPS_R15,
535 KVM_REG_MIPS_R16,
536 KVM_REG_MIPS_R17,
537 KVM_REG_MIPS_R18,
538 KVM_REG_MIPS_R19,
539 KVM_REG_MIPS_R20,
540 KVM_REG_MIPS_R21,
541 KVM_REG_MIPS_R22,
542 KVM_REG_MIPS_R23,
543 KVM_REG_MIPS_R24,
544 KVM_REG_MIPS_R25,
545 KVM_REG_MIPS_R26,
546 KVM_REG_MIPS_R27,
547 KVM_REG_MIPS_R28,
548 KVM_REG_MIPS_R29,
549 KVM_REG_MIPS_R30,
550 KVM_REG_MIPS_R31,
551
552 KVM_REG_MIPS_HI,
553 KVM_REG_MIPS_LO,
554 KVM_REG_MIPS_PC,
555
556 KVM_REG_MIPS_CP0_INDEX,
557 KVM_REG_MIPS_CP0_CONTEXT,
558 KVM_REG_MIPS_CP0_PAGEMASK,
559 KVM_REG_MIPS_CP0_WIRED,
560 KVM_REG_MIPS_CP0_BADVADDR,
561 KVM_REG_MIPS_CP0_ENTRYHI,
562 KVM_REG_MIPS_CP0_STATUS,
563 KVM_REG_MIPS_CP0_CAUSE,
564 /* EPC set via kvm_regs, et al. */
565 KVM_REG_MIPS_CP0_CONFIG,
566 KVM_REG_MIPS_CP0_CONFIG1,
567 KVM_REG_MIPS_CP0_CONFIG2,
568 KVM_REG_MIPS_CP0_CONFIG3,
569 KVM_REG_MIPS_CP0_CONFIG7,
570 KVM_REG_MIPS_CP0_ERROREPC
571};
572
573static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
574 const struct kvm_one_reg *reg)
575{
576 struct mips_coproc *cop0 = vcpu->arch.cop0;
577 s64 v;
578
579 switch (reg->id) {
580 case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31:
581 v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0];
582 break;
583 case KVM_REG_MIPS_HI:
584 v = (long)vcpu->arch.hi;
585 break;
586 case KVM_REG_MIPS_LO:
587 v = (long)vcpu->arch.lo;
588 break;
589 case KVM_REG_MIPS_PC:
590 v = (long)vcpu->arch.pc;
591 break;
592
593 case KVM_REG_MIPS_CP0_INDEX:
594 v = (long)kvm_read_c0_guest_index(cop0);
595 break;
596 case KVM_REG_MIPS_CP0_CONTEXT:
597 v = (long)kvm_read_c0_guest_context(cop0);
598 break;
599 case KVM_REG_MIPS_CP0_PAGEMASK:
600 v = (long)kvm_read_c0_guest_pagemask(cop0);
601 break;
602 case KVM_REG_MIPS_CP0_WIRED:
603 v = (long)kvm_read_c0_guest_wired(cop0);
604 break;
605 case KVM_REG_MIPS_CP0_BADVADDR:
606 v = (long)kvm_read_c0_guest_badvaddr(cop0);
607 break;
608 case KVM_REG_MIPS_CP0_ENTRYHI:
609 v = (long)kvm_read_c0_guest_entryhi(cop0);
610 break;
611 case KVM_REG_MIPS_CP0_STATUS:
612 v = (long)kvm_read_c0_guest_status(cop0);
613 break;
614 case KVM_REG_MIPS_CP0_CAUSE:
615 v = (long)kvm_read_c0_guest_cause(cop0);
616 break;
617 case KVM_REG_MIPS_CP0_ERROREPC:
618 v = (long)kvm_read_c0_guest_errorepc(cop0);
619 break;
620 case KVM_REG_MIPS_CP0_CONFIG:
621 v = (long)kvm_read_c0_guest_config(cop0);
622 break;
623 case KVM_REG_MIPS_CP0_CONFIG1:
624 v = (long)kvm_read_c0_guest_config1(cop0);
625 break;
626 case KVM_REG_MIPS_CP0_CONFIG2:
627 v = (long)kvm_read_c0_guest_config2(cop0);
628 break;
629 case KVM_REG_MIPS_CP0_CONFIG3:
630 v = (long)kvm_read_c0_guest_config3(cop0);
631 break;
632 case KVM_REG_MIPS_CP0_CONFIG7:
633 v = (long)kvm_read_c0_guest_config7(cop0);
634 break;
635 default:
636 return -EINVAL;
637 }
638 if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) {
639 u64 __user *uaddr64 = (u64 __user *)(long)reg->addr;
640 return put_user(v, uaddr64);
641 } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
642 u32 __user *uaddr32 = (u32 __user *)(long)reg->addr;
643 u32 v32 = (u32)v;
644 return put_user(v32, uaddr32);
645 } else {
646 return -EINVAL;
647 }
648}
649
650static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
651 const struct kvm_one_reg *reg)
652{
653 struct mips_coproc *cop0 = vcpu->arch.cop0;
654 u64 v;
655
656 if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) {
657 u64 __user *uaddr64 = (u64 __user *)(long)reg->addr;
658
659 if (get_user(v, uaddr64) != 0)
660 return -EFAULT;
661 } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
662 u32 __user *uaddr32 = (u32 __user *)(long)reg->addr;
663 s32 v32;
664
665 if (get_user(v32, uaddr32) != 0)
666 return -EFAULT;
667 v = (s64)v32;
668 } else {
669 return -EINVAL;
670 }
671
672 switch (reg->id) {
673 case KVM_REG_MIPS_R0:
674 /* Silently ignore requests to set $0 */
675 break;
676 case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31:
677 vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v;
678 break;
679 case KVM_REG_MIPS_HI:
680 vcpu->arch.hi = v;
681 break;
682 case KVM_REG_MIPS_LO:
683 vcpu->arch.lo = v;
684 break;
685 case KVM_REG_MIPS_PC:
686 vcpu->arch.pc = v;
687 break;
688
689 case KVM_REG_MIPS_CP0_INDEX:
690 kvm_write_c0_guest_index(cop0, v);
691 break;
692 case KVM_REG_MIPS_CP0_CONTEXT:
693 kvm_write_c0_guest_context(cop0, v);
694 break;
695 case KVM_REG_MIPS_CP0_PAGEMASK:
696 kvm_write_c0_guest_pagemask(cop0, v);
697 break;
698 case KVM_REG_MIPS_CP0_WIRED:
699 kvm_write_c0_guest_wired(cop0, v);
700 break;
701 case KVM_REG_MIPS_CP0_BADVADDR:
702 kvm_write_c0_guest_badvaddr(cop0, v);
703 break;
704 case KVM_REG_MIPS_CP0_ENTRYHI:
705 kvm_write_c0_guest_entryhi(cop0, v);
706 break;
707 case KVM_REG_MIPS_CP0_STATUS:
708 kvm_write_c0_guest_status(cop0, v);
709 break;
710 case KVM_REG_MIPS_CP0_CAUSE:
711 kvm_write_c0_guest_cause(cop0, v);
712 break;
713 case KVM_REG_MIPS_CP0_ERROREPC:
714 kvm_write_c0_guest_errorepc(cop0, v);
715 break;
716 default:
717 return -EINVAL;
718 }
719 return 0;
486} 720}
487 721
488long 722long
@@ -491,9 +725,38 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
491 struct kvm_vcpu *vcpu = filp->private_data; 725 struct kvm_vcpu *vcpu = filp->private_data;
492 void __user *argp = (void __user *)arg; 726 void __user *argp = (void __user *)arg;
493 long r; 727 long r;
494 int intr;
495 728
496 switch (ioctl) { 729 switch (ioctl) {
730 case KVM_SET_ONE_REG:
731 case KVM_GET_ONE_REG: {
732 struct kvm_one_reg reg;
733 if (copy_from_user(&reg, argp, sizeof(reg)))
734 return -EFAULT;
735 if (ioctl == KVM_SET_ONE_REG)
736 return kvm_mips_set_reg(vcpu, &reg);
737 else
738 return kvm_mips_get_reg(vcpu, &reg);
739 }
740 case KVM_GET_REG_LIST: {
741 struct kvm_reg_list __user *user_list = argp;
742 u64 __user *reg_dest;
743 struct kvm_reg_list reg_list;
744 unsigned n;
745
746 if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
747 return -EFAULT;
748 n = reg_list.n;
749 reg_list.n = ARRAY_SIZE(kvm_mips_get_one_regs);
750 if (copy_to_user(user_list, &reg_list, sizeof(reg_list)))
751 return -EFAULT;
752 if (n < reg_list.n)
753 return -E2BIG;
754 reg_dest = user_list->reg;
755 if (copy_to_user(reg_dest, kvm_mips_get_one_regs,
756 sizeof(kvm_mips_get_one_regs)))
757 return -EFAULT;
758 return 0;
759 }
497 case KVM_NMI: 760 case KVM_NMI:
498 /* Treat the NMI as a CPU reset */ 761 /* Treat the NMI as a CPU reset */
499 r = kvm_mips_reset_vcpu(vcpu); 762 r = kvm_mips_reset_vcpu(vcpu);
@@ -505,8 +768,6 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
505 if (copy_from_user(&irq, argp, sizeof(irq))) 768 if (copy_from_user(&irq, argp, sizeof(irq)))
506 goto out; 769 goto out;
507 770
508 intr = (int)irq.irq;
509
510 kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__, 771 kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__,
511 irq.irq); 772 irq.irq);
512 773
@@ -514,7 +775,7 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
514 break; 775 break;
515 } 776 }
516 default: 777 default:
517 r = -EINVAL; 778 r = -ENOIOCTLCMD;
518 } 779 }
519 780
520out: 781out:
@@ -565,7 +826,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
565 826
566 switch (ioctl) { 827 switch (ioctl) {
567 default: 828 default:
568 r = -EINVAL; 829 r = -ENOIOCTLCMD;
569 } 830 }
570 831
571 return r; 832 return r;
@@ -593,13 +854,13 @@ void kvm_arch_exit(void)
593int 854int
594kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 855kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
595{ 856{
596 return -ENOTSUPP; 857 return -ENOIOCTLCMD;
597} 858}
598 859
599int 860int
600kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 861kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
601{ 862{
602 return -ENOTSUPP; 863 return -ENOIOCTLCMD;
603} 864}
604 865
605int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) 866int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
@@ -609,12 +870,12 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
609 870
610int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 871int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
611{ 872{
612 return -ENOTSUPP; 873 return -ENOIOCTLCMD;
613} 874}
614 875
615int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 876int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
616{ 877{
617 return -ENOTSUPP; 878 return -ENOIOCTLCMD;
618} 879}
619 880
620int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) 881int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
@@ -627,6 +888,9 @@ int kvm_dev_ioctl_check_extension(long ext)
627 int r; 888 int r;
628 889
629 switch (ext) { 890 switch (ext) {
891 case KVM_CAP_ONE_REG:
892 r = 1;
893 break;
630 case KVM_CAP_COALESCED_MMIO: 894 case KVM_CAP_COALESCED_MMIO:
631 r = KVM_COALESCED_MMIO_PAGE_OFFSET; 895 r = KVM_COALESCED_MMIO_PAGE_OFFSET;
632 break; 896 break;
@@ -635,7 +899,6 @@ int kvm_dev_ioctl_check_extension(long ext)
635 break; 899 break;
636 } 900 }
637 return r; 901 return r;
638
639} 902}
640 903
641int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 904int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -677,28 +940,28 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
677{ 940{
678 int i; 941 int i;
679 942
680 for (i = 0; i < 32; i++) 943 for (i = 1; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
681 vcpu->arch.gprs[i] = regs->gprs[i]; 944 vcpu->arch.gprs[i] = regs->gpr[i];
682 945 vcpu->arch.gprs[0] = 0; /* zero is special, and cannot be set. */
683 vcpu->arch.hi = regs->hi; 946 vcpu->arch.hi = regs->hi;
684 vcpu->arch.lo = regs->lo; 947 vcpu->arch.lo = regs->lo;
685 vcpu->arch.pc = regs->pc; 948 vcpu->arch.pc = regs->pc;
686 949
687 return kvm_mips_callbacks->vcpu_ioctl_set_regs(vcpu, regs); 950 return 0;
688} 951}
689 952
690int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 953int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
691{ 954{
692 int i; 955 int i;
693 956
694 for (i = 0; i < 32; i++) 957 for (i = 0; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
695 regs->gprs[i] = vcpu->arch.gprs[i]; 958 regs->gpr[i] = vcpu->arch.gprs[i];
696 959
697 regs->hi = vcpu->arch.hi; 960 regs->hi = vcpu->arch.hi;
698 regs->lo = vcpu->arch.lo; 961 regs->lo = vcpu->arch.lo;
699 regs->pc = vcpu->arch.pc; 962 regs->pc = vcpu->arch.pc;
700 963
701 return kvm_mips_callbacks->vcpu_ioctl_get_regs(vcpu, regs); 964 return 0;
702} 965}
703 966
704void kvm_mips_comparecount_func(unsigned long data) 967void kvm_mips_comparecount_func(unsigned long data)