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.c280
1 files changed, 259 insertions, 21 deletions
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
index e0dad0289797..d934b017f479 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,223 @@ 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 KVM_REG_MIPS_CP0_INDEX (0x10000 + 8 * 0 + 0)
489#define KVM_REG_MIPS_CP0_ENTRYLO0 (0x10000 + 8 * 2 + 0)
490#define KVM_REG_MIPS_CP0_ENTRYLO1 (0x10000 + 8 * 3 + 0)
491#define KVM_REG_MIPS_CP0_CONTEXT (0x10000 + 8 * 4 + 0)
492#define KVM_REG_MIPS_CP0_USERLOCAL (0x10000 + 8 * 4 + 2)
493#define KVM_REG_MIPS_CP0_PAGEMASK (0x10000 + 8 * 5 + 0)
494#define KVM_REG_MIPS_CP0_PAGEGRAIN (0x10000 + 8 * 5 + 1)
495#define KVM_REG_MIPS_CP0_WIRED (0x10000 + 8 * 6 + 0)
496#define KVM_REG_MIPS_CP0_HWRENA (0x10000 + 8 * 7 + 0)
497#define KVM_REG_MIPS_CP0_BADVADDR (0x10000 + 8 * 8 + 0)
498#define KVM_REG_MIPS_CP0_COUNT (0x10000 + 8 * 9 + 0)
499#define KVM_REG_MIPS_CP0_ENTRYHI (0x10000 + 8 * 10 + 0)
500#define KVM_REG_MIPS_CP0_COMPARE (0x10000 + 8 * 11 + 0)
501#define KVM_REG_MIPS_CP0_STATUS (0x10000 + 8 * 12 + 0)
502#define KVM_REG_MIPS_CP0_CAUSE (0x10000 + 8 * 13 + 0)
503#define KVM_REG_MIPS_CP0_EBASE (0x10000 + 8 * 15 + 1)
504#define KVM_REG_MIPS_CP0_CONFIG (0x10000 + 8 * 16 + 0)
505#define KVM_REG_MIPS_CP0_CONFIG1 (0x10000 + 8 * 16 + 1)
506#define KVM_REG_MIPS_CP0_CONFIG2 (0x10000 + 8 * 16 + 2)
507#define KVM_REG_MIPS_CP0_CONFIG3 (0x10000 + 8 * 16 + 3)
508#define KVM_REG_MIPS_CP0_CONFIG7 (0x10000 + 8 * 16 + 7)
509#define KVM_REG_MIPS_CP0_XCONTEXT (0x10000 + 8 * 20 + 0)
510#define KVM_REG_MIPS_CP0_ERROREPC (0x10000 + 8 * 30 + 0)
511
512static u64 kvm_mips_get_one_regs[] = {
513 KVM_REG_MIPS_R0,
514 KVM_REG_MIPS_R1,
515 KVM_REG_MIPS_R2,
516 KVM_REG_MIPS_R3,
517 KVM_REG_MIPS_R4,
518 KVM_REG_MIPS_R5,
519 KVM_REG_MIPS_R6,
520 KVM_REG_MIPS_R7,
521 KVM_REG_MIPS_R8,
522 KVM_REG_MIPS_R9,
523 KVM_REG_MIPS_R10,
524 KVM_REG_MIPS_R11,
525 KVM_REG_MIPS_R12,
526 KVM_REG_MIPS_R13,
527 KVM_REG_MIPS_R14,
528 KVM_REG_MIPS_R15,
529 KVM_REG_MIPS_R16,
530 KVM_REG_MIPS_R17,
531 KVM_REG_MIPS_R18,
532 KVM_REG_MIPS_R19,
533 KVM_REG_MIPS_R20,
534 KVM_REG_MIPS_R21,
535 KVM_REG_MIPS_R22,
536 KVM_REG_MIPS_R23,
537 KVM_REG_MIPS_R24,
538 KVM_REG_MIPS_R25,
539 KVM_REG_MIPS_R26,
540 KVM_REG_MIPS_R27,
541 KVM_REG_MIPS_R28,
542 KVM_REG_MIPS_R29,
543 KVM_REG_MIPS_R30,
544 KVM_REG_MIPS_R31,
545
546 KVM_REG_MIPS_HI,
547 KVM_REG_MIPS_LO,
548 KVM_REG_MIPS_PC,
549
550 KVM_REG_MIPS_CP0_INDEX,
551 KVM_REG_MIPS_CP0_CONTEXT,
552 KVM_REG_MIPS_CP0_PAGEMASK,
553 KVM_REG_MIPS_CP0_WIRED,
554 KVM_REG_MIPS_CP0_BADVADDR,
555 KVM_REG_MIPS_CP0_ENTRYHI,
556 KVM_REG_MIPS_CP0_STATUS,
557 KVM_REG_MIPS_CP0_CAUSE,
558 /* EPC set via kvm_regs, et al. */
559 KVM_REG_MIPS_CP0_CONFIG,
560 KVM_REG_MIPS_CP0_CONFIG1,
561 KVM_REG_MIPS_CP0_CONFIG2,
562 KVM_REG_MIPS_CP0_CONFIG3,
563 KVM_REG_MIPS_CP0_CONFIG7,
564 KVM_REG_MIPS_CP0_ERROREPC
565};
566
567static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
568 const struct kvm_one_reg *reg)
569{
570 u64 __user *uaddr = (u64 __user *)(long)reg->addr;
571
572 struct mips_coproc *cop0 = vcpu->arch.cop0;
573 s64 v;
574
575 switch (reg->id) {
576 case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31:
577 v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0];
578 break;
579 case KVM_REG_MIPS_HI:
580 v = (long)vcpu->arch.hi;
581 break;
582 case KVM_REG_MIPS_LO:
583 v = (long)vcpu->arch.lo;
584 break;
585 case KVM_REG_MIPS_PC:
586 v = (long)vcpu->arch.pc;
587 break;
588
589 case KVM_REG_MIPS_CP0_INDEX:
590 v = (long)kvm_read_c0_guest_index(cop0);
591 break;
592 case KVM_REG_MIPS_CP0_CONTEXT:
593 v = (long)kvm_read_c0_guest_context(cop0);
594 break;
595 case KVM_REG_MIPS_CP0_PAGEMASK:
596 v = (long)kvm_read_c0_guest_pagemask(cop0);
597 break;
598 case KVM_REG_MIPS_CP0_WIRED:
599 v = (long)kvm_read_c0_guest_wired(cop0);
600 break;
601 case KVM_REG_MIPS_CP0_BADVADDR:
602 v = (long)kvm_read_c0_guest_badvaddr(cop0);
603 break;
604 case KVM_REG_MIPS_CP0_ENTRYHI:
605 v = (long)kvm_read_c0_guest_entryhi(cop0);
606 break;
607 case KVM_REG_MIPS_CP0_STATUS:
608 v = (long)kvm_read_c0_guest_status(cop0);
609 break;
610 case KVM_REG_MIPS_CP0_CAUSE:
611 v = (long)kvm_read_c0_guest_cause(cop0);
612 break;
613 case KVM_REG_MIPS_CP0_ERROREPC:
614 v = (long)kvm_read_c0_guest_errorepc(cop0);
615 break;
616 case KVM_REG_MIPS_CP0_CONFIG:
617 v = (long)kvm_read_c0_guest_config(cop0);
618 break;
619 case KVM_REG_MIPS_CP0_CONFIG1:
620 v = (long)kvm_read_c0_guest_config1(cop0);
621 break;
622 case KVM_REG_MIPS_CP0_CONFIG2:
623 v = (long)kvm_read_c0_guest_config2(cop0);
624 break;
625 case KVM_REG_MIPS_CP0_CONFIG3:
626 v = (long)kvm_read_c0_guest_config3(cop0);
627 break;
628 case KVM_REG_MIPS_CP0_CONFIG7:
629 v = (long)kvm_read_c0_guest_config7(cop0);
630 break;
631 default:
632 return -EINVAL;
633 }
634 return put_user(v, uaddr);
635}
636
637static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
638 const struct kvm_one_reg *reg)
639{
640 u64 __user *uaddr = (u64 __user *)(long)reg->addr;
641 struct mips_coproc *cop0 = vcpu->arch.cop0;
642 u64 v;
643
644 if (get_user(v, uaddr) != 0)
645 return -EFAULT;
646
647 switch (reg->id) {
648 case KVM_REG_MIPS_R0:
649 /* Silently ignore requests to set $0 */
650 break;
651 case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31:
652 vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v;
653 break;
654 case KVM_REG_MIPS_HI:
655 vcpu->arch.hi = v;
656 break;
657 case KVM_REG_MIPS_LO:
658 vcpu->arch.lo = v;
659 break;
660 case KVM_REG_MIPS_PC:
661 vcpu->arch.pc = v;
662 break;
663
664 case KVM_REG_MIPS_CP0_INDEX:
665 kvm_write_c0_guest_index(cop0, v);
666 break;
667 case KVM_REG_MIPS_CP0_CONTEXT:
668 kvm_write_c0_guest_context(cop0, v);
669 break;
670 case KVM_REG_MIPS_CP0_PAGEMASK:
671 kvm_write_c0_guest_pagemask(cop0, v);
672 break;
673 case KVM_REG_MIPS_CP0_WIRED:
674 kvm_write_c0_guest_wired(cop0, v);
675 break;
676 case KVM_REG_MIPS_CP0_BADVADDR:
677 kvm_write_c0_guest_badvaddr(cop0, v);
678 break;
679 case KVM_REG_MIPS_CP0_ENTRYHI:
680 kvm_write_c0_guest_entryhi(cop0, v);
681 break;
682 case KVM_REG_MIPS_CP0_STATUS:
683 kvm_write_c0_guest_status(cop0, v);
684 break;
685 case KVM_REG_MIPS_CP0_CAUSE:
686 kvm_write_c0_guest_cause(cop0, v);
687 break;
688 case KVM_REG_MIPS_CP0_ERROREPC:
689 kvm_write_c0_guest_errorepc(cop0, v);
690 break;
691 default:
692 return -EINVAL;
693 }
694 return 0;
486} 695}
487 696
488long 697long
@@ -491,9 +700,38 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
491 struct kvm_vcpu *vcpu = filp->private_data; 700 struct kvm_vcpu *vcpu = filp->private_data;
492 void __user *argp = (void __user *)arg; 701 void __user *argp = (void __user *)arg;
493 long r; 702 long r;
494 int intr;
495 703
496 switch (ioctl) { 704 switch (ioctl) {
705 case KVM_SET_ONE_REG:
706 case KVM_GET_ONE_REG: {
707 struct kvm_one_reg reg;
708 if (copy_from_user(&reg, argp, sizeof(reg)))
709 return -EFAULT;
710 if (ioctl == KVM_SET_ONE_REG)
711 return kvm_mips_set_reg(vcpu, &reg);
712 else
713 return kvm_mips_get_reg(vcpu, &reg);
714 }
715 case KVM_GET_REG_LIST: {
716 struct kvm_reg_list __user *user_list = argp;
717 u64 __user *reg_dest;
718 struct kvm_reg_list reg_list;
719 unsigned n;
720
721 if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
722 return -EFAULT;
723 n = reg_list.n;
724 reg_list.n = ARRAY_SIZE(kvm_mips_get_one_regs);
725 if (copy_to_user(user_list, &reg_list, sizeof(reg_list)))
726 return -EFAULT;
727 if (n < reg_list.n)
728 return -E2BIG;
729 reg_dest = user_list->reg;
730 if (copy_to_user(reg_dest, kvm_mips_get_one_regs,
731 sizeof(kvm_mips_get_one_regs)))
732 return -EFAULT;
733 return 0;
734 }
497 case KVM_NMI: 735 case KVM_NMI:
498 /* Treat the NMI as a CPU reset */ 736 /* Treat the NMI as a CPU reset */
499 r = kvm_mips_reset_vcpu(vcpu); 737 r = kvm_mips_reset_vcpu(vcpu);
@@ -505,8 +743,6 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
505 if (copy_from_user(&irq, argp, sizeof(irq))) 743 if (copy_from_user(&irq, argp, sizeof(irq)))
506 goto out; 744 goto out;
507 745
508 intr = (int)irq.irq;
509
510 kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__, 746 kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__,
511 irq.irq); 747 irq.irq);
512 748
@@ -514,7 +750,7 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
514 break; 750 break;
515 } 751 }
516 default: 752 default:
517 r = -EINVAL; 753 r = -ENOIOCTLCMD;
518 } 754 }
519 755
520out: 756out:
@@ -565,7 +801,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
565 801
566 switch (ioctl) { 802 switch (ioctl) {
567 default: 803 default:
568 r = -EINVAL; 804 r = -ENOIOCTLCMD;
569 } 805 }
570 806
571 return r; 807 return r;
@@ -593,13 +829,13 @@ void kvm_arch_exit(void)
593int 829int
594kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 830kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
595{ 831{
596 return -ENOTSUPP; 832 return -ENOIOCTLCMD;
597} 833}
598 834
599int 835int
600kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 836kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
601{ 837{
602 return -ENOTSUPP; 838 return -ENOIOCTLCMD;
603} 839}
604 840
605int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) 841int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
@@ -609,12 +845,12 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
609 845
610int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 846int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
611{ 847{
612 return -ENOTSUPP; 848 return -ENOIOCTLCMD;
613} 849}
614 850
615int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 851int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
616{ 852{
617 return -ENOTSUPP; 853 return -ENOIOCTLCMD;
618} 854}
619 855
620int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) 856int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
@@ -627,6 +863,9 @@ int kvm_dev_ioctl_check_extension(long ext)
627 int r; 863 int r;
628 864
629 switch (ext) { 865 switch (ext) {
866 case KVM_CAP_ONE_REG:
867 r = 1;
868 break;
630 case KVM_CAP_COALESCED_MMIO: 869 case KVM_CAP_COALESCED_MMIO:
631 r = KVM_COALESCED_MMIO_PAGE_OFFSET; 870 r = KVM_COALESCED_MMIO_PAGE_OFFSET;
632 break; 871 break;
@@ -635,7 +874,6 @@ int kvm_dev_ioctl_check_extension(long ext)
635 break; 874 break;
636 } 875 }
637 return r; 876 return r;
638
639} 877}
640 878
641int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 879int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -677,28 +915,28 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
677{ 915{
678 int i; 916 int i;
679 917
680 for (i = 0; i < 32; i++) 918 for (i = 1; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
681 vcpu->arch.gprs[i] = regs->gprs[i]; 919 vcpu->arch.gprs[i] = regs->gpr[i];
682 920 vcpu->arch.gprs[0] = 0; /* zero is special, and cannot be set. */
683 vcpu->arch.hi = regs->hi; 921 vcpu->arch.hi = regs->hi;
684 vcpu->arch.lo = regs->lo; 922 vcpu->arch.lo = regs->lo;
685 vcpu->arch.pc = regs->pc; 923 vcpu->arch.pc = regs->pc;
686 924
687 return kvm_mips_callbacks->vcpu_ioctl_set_regs(vcpu, regs); 925 return 0;
688} 926}
689 927
690int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 928int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
691{ 929{
692 int i; 930 int i;
693 931
694 for (i = 0; i < 32; i++) 932 for (i = 0; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
695 regs->gprs[i] = vcpu->arch.gprs[i]; 933 regs->gpr[i] = vcpu->arch.gprs[i];
696 934
697 regs->hi = vcpu->arch.hi; 935 regs->hi = vcpu->arch.hi;
698 regs->lo = vcpu->arch.lo; 936 regs->lo = vcpu->arch.lo;
699 regs->pc = vcpu->arch.pc; 937 regs->pc = vcpu->arch.pc;
700 938
701 return kvm_mips_callbacks->vcpu_ioctl_get_regs(vcpu, regs); 939 return 0;
702} 940}
703 941
704void kvm_mips_comparecount_func(unsigned long data) 942void kvm_mips_comparecount_func(unsigned long data)