diff options
author | Mihai Caraman <mihai.caraman@freescale.com> | 2014-08-20 09:36:24 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-09-22 04:11:33 -0400 |
commit | 8a41ea53b32ffbe7524e3424cf0403fa3b4c73fb (patch) | |
tree | 39056b5a6c18f3c7cdbabf6a9f8ab0845167a478 /arch/powerpc/kvm | |
parent | 95d80a294b1eec83eb58c57e101b05828d97a851 (diff) |
KVM: PPC: Make ONE_REG powerpc generic
Make ONE_REG generic for server and embedded architectures by moving
kvm_vcpu_ioctl_get_one_reg() and kvm_vcpu_ioctl_set_one_reg() functions
to powerpc layer.
Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r-- | arch/powerpc/kvm/book3s.c | 121 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 91 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 55 |
3 files changed, 138 insertions, 129 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index dd03f6b299ba..26868e207ff0 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -535,33 +535,28 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
535 | return -ENOTSUPP; | 535 | return -ENOTSUPP; |
536 | } | 536 | } |
537 | 537 | ||
538 | int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | 538 | int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, |
539 | union kvmppc_one_reg *val) | ||
539 | { | 540 | { |
540 | int r; | 541 | int r = 0; |
541 | union kvmppc_one_reg val; | ||
542 | int size; | ||
543 | long int i; | 542 | long int i; |
544 | 543 | ||
545 | size = one_reg_size(reg->id); | 544 | r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val); |
546 | if (size > sizeof(val)) | ||
547 | return -EINVAL; | ||
548 | |||
549 | r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val); | ||
550 | if (r == -EINVAL) { | 545 | if (r == -EINVAL) { |
551 | r = 0; | 546 | r = 0; |
552 | switch (reg->id) { | 547 | switch (id) { |
553 | case KVM_REG_PPC_DAR: | 548 | case KVM_REG_PPC_DAR: |
554 | val = get_reg_val(reg->id, kvmppc_get_dar(vcpu)); | 549 | *val = get_reg_val(id, kvmppc_get_dar(vcpu)); |
555 | break; | 550 | break; |
556 | case KVM_REG_PPC_DSISR: | 551 | case KVM_REG_PPC_DSISR: |
557 | val = get_reg_val(reg->id, kvmppc_get_dsisr(vcpu)); | 552 | *val = get_reg_val(id, kvmppc_get_dsisr(vcpu)); |
558 | break; | 553 | break; |
559 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: | 554 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: |
560 | i = reg->id - KVM_REG_PPC_FPR0; | 555 | i = id - KVM_REG_PPC_FPR0; |
561 | val = get_reg_val(reg->id, VCPU_FPR(vcpu, i)); | 556 | *val = get_reg_val(id, VCPU_FPR(vcpu, i)); |
562 | break; | 557 | break; |
563 | case KVM_REG_PPC_FPSCR: | 558 | case KVM_REG_PPC_FPSCR: |
564 | val = get_reg_val(reg->id, vcpu->arch.fp.fpscr); | 559 | *val = get_reg_val(id, vcpu->arch.fp.fpscr); |
565 | break; | 560 | break; |
566 | #ifdef CONFIG_ALTIVEC | 561 | #ifdef CONFIG_ALTIVEC |
567 | case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31: | 562 | case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31: |
@@ -569,110 +564,94 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
569 | r = -ENXIO; | 564 | r = -ENXIO; |
570 | break; | 565 | break; |
571 | } | 566 | } |
572 | val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0]; | 567 | val->vval = vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0]; |
573 | break; | 568 | break; |
574 | case KVM_REG_PPC_VSCR: | 569 | case KVM_REG_PPC_VSCR: |
575 | if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { | 570 | if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { |
576 | r = -ENXIO; | 571 | r = -ENXIO; |
577 | break; | 572 | break; |
578 | } | 573 | } |
579 | val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]); | 574 | *val = get_reg_val(id, vcpu->arch.vr.vscr.u[3]); |
580 | break; | 575 | break; |
581 | case KVM_REG_PPC_VRSAVE: | 576 | case KVM_REG_PPC_VRSAVE: |
582 | val = get_reg_val(reg->id, vcpu->arch.vrsave); | 577 | *val = get_reg_val(id, vcpu->arch.vrsave); |
583 | break; | 578 | break; |
584 | #endif /* CONFIG_ALTIVEC */ | 579 | #endif /* CONFIG_ALTIVEC */ |
585 | #ifdef CONFIG_VSX | 580 | #ifdef CONFIG_VSX |
586 | case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: | 581 | case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: |
587 | if (cpu_has_feature(CPU_FTR_VSX)) { | 582 | if (cpu_has_feature(CPU_FTR_VSX)) { |
588 | long int i = reg->id - KVM_REG_PPC_VSR0; | 583 | i = id - KVM_REG_PPC_VSR0; |
589 | val.vsxval[0] = vcpu->arch.fp.fpr[i][0]; | 584 | val->vsxval[0] = vcpu->arch.fp.fpr[i][0]; |
590 | val.vsxval[1] = vcpu->arch.fp.fpr[i][1]; | 585 | val->vsxval[1] = vcpu->arch.fp.fpr[i][1]; |
591 | } else { | 586 | } else { |
592 | r = -ENXIO; | 587 | r = -ENXIO; |
593 | } | 588 | } |
594 | break; | 589 | break; |
595 | #endif /* CONFIG_VSX */ | 590 | #endif /* CONFIG_VSX */ |
596 | case KVM_REG_PPC_DEBUG_INST: { | 591 | case KVM_REG_PPC_DEBUG_INST: |
597 | u32 opcode = INS_TW; | 592 | *val = get_reg_val(id, INS_TW); |
598 | r = copy_to_user((u32 __user *)(long)reg->addr, | ||
599 | &opcode, sizeof(u32)); | ||
600 | break; | 593 | break; |
601 | } | ||
602 | #ifdef CONFIG_KVM_XICS | 594 | #ifdef CONFIG_KVM_XICS |
603 | case KVM_REG_PPC_ICP_STATE: | 595 | case KVM_REG_PPC_ICP_STATE: |
604 | if (!vcpu->arch.icp) { | 596 | if (!vcpu->arch.icp) { |
605 | r = -ENXIO; | 597 | r = -ENXIO; |
606 | break; | 598 | break; |
607 | } | 599 | } |
608 | val = get_reg_val(reg->id, kvmppc_xics_get_icp(vcpu)); | 600 | *val = get_reg_val(id, kvmppc_xics_get_icp(vcpu)); |
609 | break; | 601 | break; |
610 | #endif /* CONFIG_KVM_XICS */ | 602 | #endif /* CONFIG_KVM_XICS */ |
611 | case KVM_REG_PPC_FSCR: | 603 | case KVM_REG_PPC_FSCR: |
612 | val = get_reg_val(reg->id, vcpu->arch.fscr); | 604 | *val = get_reg_val(id, vcpu->arch.fscr); |
613 | break; | 605 | break; |
614 | case KVM_REG_PPC_TAR: | 606 | case KVM_REG_PPC_TAR: |
615 | val = get_reg_val(reg->id, vcpu->arch.tar); | 607 | *val = get_reg_val(id, vcpu->arch.tar); |
616 | break; | 608 | break; |
617 | case KVM_REG_PPC_EBBHR: | 609 | case KVM_REG_PPC_EBBHR: |
618 | val = get_reg_val(reg->id, vcpu->arch.ebbhr); | 610 | *val = get_reg_val(id, vcpu->arch.ebbhr); |
619 | break; | 611 | break; |
620 | case KVM_REG_PPC_EBBRR: | 612 | case KVM_REG_PPC_EBBRR: |
621 | val = get_reg_val(reg->id, vcpu->arch.ebbrr); | 613 | *val = get_reg_val(id, vcpu->arch.ebbrr); |
622 | break; | 614 | break; |
623 | case KVM_REG_PPC_BESCR: | 615 | case KVM_REG_PPC_BESCR: |
624 | val = get_reg_val(reg->id, vcpu->arch.bescr); | 616 | *val = get_reg_val(id, vcpu->arch.bescr); |
625 | break; | 617 | break; |
626 | case KVM_REG_PPC_VTB: | 618 | case KVM_REG_PPC_VTB: |
627 | val = get_reg_val(reg->id, vcpu->arch.vtb); | 619 | *val = get_reg_val(id, vcpu->arch.vtb); |
628 | break; | 620 | break; |
629 | case KVM_REG_PPC_IC: | 621 | case KVM_REG_PPC_IC: |
630 | val = get_reg_val(reg->id, vcpu->arch.ic); | 622 | *val = get_reg_val(id, vcpu->arch.ic); |
631 | break; | 623 | break; |
632 | default: | 624 | default: |
633 | r = -EINVAL; | 625 | r = -EINVAL; |
634 | break; | 626 | break; |
635 | } | 627 | } |
636 | } | 628 | } |
637 | if (r) | ||
638 | return r; | ||
639 | |||
640 | if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size)) | ||
641 | r = -EFAULT; | ||
642 | 629 | ||
643 | return r; | 630 | return r; |
644 | } | 631 | } |
645 | 632 | ||
646 | int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | 633 | int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, |
634 | union kvmppc_one_reg *val) | ||
647 | { | 635 | { |
648 | int r; | 636 | int r = 0; |
649 | union kvmppc_one_reg val; | ||
650 | int size; | ||
651 | long int i; | 637 | long int i; |
652 | 638 | ||
653 | size = one_reg_size(reg->id); | 639 | r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val); |
654 | if (size > sizeof(val)) | ||
655 | return -EINVAL; | ||
656 | |||
657 | if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size)) | ||
658 | return -EFAULT; | ||
659 | |||
660 | r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val); | ||
661 | if (r == -EINVAL) { | 640 | if (r == -EINVAL) { |
662 | r = 0; | 641 | r = 0; |
663 | switch (reg->id) { | 642 | switch (id) { |
664 | case KVM_REG_PPC_DAR: | 643 | case KVM_REG_PPC_DAR: |
665 | kvmppc_set_dar(vcpu, set_reg_val(reg->id, val)); | 644 | kvmppc_set_dar(vcpu, set_reg_val(id, *val)); |
666 | break; | 645 | break; |
667 | case KVM_REG_PPC_DSISR: | 646 | case KVM_REG_PPC_DSISR: |
668 | kvmppc_set_dsisr(vcpu, set_reg_val(reg->id, val)); | 647 | kvmppc_set_dsisr(vcpu, set_reg_val(id, *val)); |
669 | break; | 648 | break; |
670 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: | 649 | case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: |
671 | i = reg->id - KVM_REG_PPC_FPR0; | 650 | i = id - KVM_REG_PPC_FPR0; |
672 | VCPU_FPR(vcpu, i) = set_reg_val(reg->id, val); | 651 | VCPU_FPR(vcpu, i) = set_reg_val(id, *val); |
673 | break; | 652 | break; |
674 | case KVM_REG_PPC_FPSCR: | 653 | case KVM_REG_PPC_FPSCR: |
675 | vcpu->arch.fp.fpscr = set_reg_val(reg->id, val); | 654 | vcpu->arch.fp.fpscr = set_reg_val(id, *val); |
676 | break; | 655 | break; |
677 | #ifdef CONFIG_ALTIVEC | 656 | #ifdef CONFIG_ALTIVEC |
678 | case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31: | 657 | case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31: |
@@ -680,29 +659,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
680 | r = -ENXIO; | 659 | r = -ENXIO; |
681 | break; | 660 | break; |
682 | } | 661 | } |
683 | vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0] = val.vval; | 662 | vcpu->arch.vr.vr[id - KVM_REG_PPC_VR0] = val->vval; |
684 | break; | 663 | break; |
685 | case KVM_REG_PPC_VSCR: | 664 | case KVM_REG_PPC_VSCR: |
686 | if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { | 665 | if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { |
687 | r = -ENXIO; | 666 | r = -ENXIO; |
688 | break; | 667 | break; |
689 | } | 668 | } |
690 | vcpu->arch.vr.vscr.u[3] = set_reg_val(reg->id, val); | 669 | vcpu->arch.vr.vscr.u[3] = set_reg_val(id, *val); |
691 | break; | 670 | break; |
692 | case KVM_REG_PPC_VRSAVE: | 671 | case KVM_REG_PPC_VRSAVE: |
693 | if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { | 672 | if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { |
694 | r = -ENXIO; | 673 | r = -ENXIO; |
695 | break; | 674 | break; |
696 | } | 675 | } |
697 | vcpu->arch.vrsave = set_reg_val(reg->id, val); | 676 | vcpu->arch.vrsave = set_reg_val(id, *val); |
698 | break; | 677 | break; |
699 | #endif /* CONFIG_ALTIVEC */ | 678 | #endif /* CONFIG_ALTIVEC */ |
700 | #ifdef CONFIG_VSX | 679 | #ifdef CONFIG_VSX |
701 | case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: | 680 | case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: |
702 | if (cpu_has_feature(CPU_FTR_VSX)) { | 681 | if (cpu_has_feature(CPU_FTR_VSX)) { |
703 | long int i = reg->id - KVM_REG_PPC_VSR0; | 682 | i = id - KVM_REG_PPC_VSR0; |
704 | vcpu->arch.fp.fpr[i][0] = val.vsxval[0]; | 683 | vcpu->arch.fp.fpr[i][0] = val->vsxval[0]; |
705 | vcpu->arch.fp.fpr[i][1] = val.vsxval[1]; | 684 | vcpu->arch.fp.fpr[i][1] = val->vsxval[1]; |
706 | } else { | 685 | } else { |
707 | r = -ENXIO; | 686 | r = -ENXIO; |
708 | } | 687 | } |
@@ -715,29 +694,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | |||
715 | break; | 694 | break; |
716 | } | 695 | } |
717 | r = kvmppc_xics_set_icp(vcpu, | 696 | r = kvmppc_xics_set_icp(vcpu, |
718 | set_reg_val(reg->id, val)); | 697 | set_reg_val(id, *val)); |
719 | break; | 698 | break; |
720 | #endif /* CONFIG_KVM_XICS */ | 699 | #endif /* CONFIG_KVM_XICS */ |
721 | case KVM_REG_PPC_FSCR: | 700 | case KVM_REG_PPC_FSCR: |
722 | vcpu->arch.fscr = set_reg_val(reg->id, val); | 701 | vcpu->arch.fscr = set_reg_val(id, *val); |
723 | break; | 702 | break; |
724 | case KVM_REG_PPC_TAR: | 703 | case KVM_REG_PPC_TAR: |
725 | vcpu->arch.tar = set_reg_val(reg->id, val); | 704 | vcpu->arch.tar = set_reg_val(id, *val); |
726 | break; | 705 | break; |
727 | case KVM_REG_PPC_EBBHR: | 706 | case KVM_REG_PPC_EBBHR: |
728 | vcpu->arch.ebbhr = set_reg_val(reg->id, val); | 707 | vcpu->arch.ebbhr = set_reg_val(id, *val); |
729 | break; | 708 | break; |
730 | case KVM_REG_PPC_EBBRR: | 709 | case KVM_REG_PPC_EBBRR: |
731 | vcpu->arch.ebbrr = set_reg_val(reg->id, val); | 710 | vcpu->arch.ebbrr = set_reg_val(id, *val); |
732 | break; | 711 | break; |
733 | case KVM_REG_PPC_BESCR: | 712 | case KVM_REG_PPC_BESCR: |
734 | vcpu->arch.bescr = set_reg_val(reg->id, val); | 713 | vcpu->arch.bescr = set_reg_val(id, *val); |
735 | break; | 714 | break; |
736 | case KVM_REG_PPC_VTB: | 715 | case KVM_REG_PPC_VTB: |
737 | vcpu->arch.vtb = set_reg_val(reg->id, val); | 716 | vcpu->arch.vtb = set_reg_val(id, *val); |
738 | break; | 717 | break; |
739 | case KVM_REG_PPC_IC: | 718 | case KVM_REG_PPC_IC: |
740 | vcpu->arch.ic = set_reg_val(reg->id, val); | 719 | vcpu->arch.ic = set_reg_val(id, *val); |
741 | break; | 720 | break; |
742 | default: | 721 | default: |
743 | r = -EINVAL; | 722 | r = -EINVAL; |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 8ace6120ef9b..831c1b433b09 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -1564,150 +1564,125 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
1564 | return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs); | 1564 | return vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs); |
1565 | } | 1565 | } |
1566 | 1566 | ||
1567 | int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | 1567 | int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, |
1568 | union kvmppc_one_reg *val) | ||
1568 | { | 1569 | { |
1569 | int r = 0; | 1570 | int r = 0; |
1570 | union kvmppc_one_reg val; | ||
1571 | int size; | ||
1572 | 1571 | ||
1573 | size = one_reg_size(reg->id); | 1572 | switch (id) { |
1574 | if (size > sizeof(val)) | ||
1575 | return -EINVAL; | ||
1576 | |||
1577 | switch (reg->id) { | ||
1578 | case KVM_REG_PPC_IAC1: | 1573 | case KVM_REG_PPC_IAC1: |
1579 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac1); | 1574 | *val = get_reg_val(id, vcpu->arch.dbg_reg.iac1); |
1580 | break; | 1575 | break; |
1581 | case KVM_REG_PPC_IAC2: | 1576 | case KVM_REG_PPC_IAC2: |
1582 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac2); | 1577 | *val = get_reg_val(id, vcpu->arch.dbg_reg.iac2); |
1583 | break; | 1578 | break; |
1584 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 1579 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
1585 | case KVM_REG_PPC_IAC3: | 1580 | case KVM_REG_PPC_IAC3: |
1586 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac3); | 1581 | *val = get_reg_val(id, vcpu->arch.dbg_reg.iac3); |
1587 | break; | 1582 | break; |
1588 | case KVM_REG_PPC_IAC4: | 1583 | case KVM_REG_PPC_IAC4: |
1589 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac4); | 1584 | *val = get_reg_val(id, vcpu->arch.dbg_reg.iac4); |
1590 | break; | 1585 | break; |
1591 | #endif | 1586 | #endif |
1592 | case KVM_REG_PPC_DAC1: | 1587 | case KVM_REG_PPC_DAC1: |
1593 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac1); | 1588 | *val = get_reg_val(id, vcpu->arch.dbg_reg.dac1); |
1594 | break; | 1589 | break; |
1595 | case KVM_REG_PPC_DAC2: | 1590 | case KVM_REG_PPC_DAC2: |
1596 | val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2); | 1591 | *val = get_reg_val(id, vcpu->arch.dbg_reg.dac2); |
1597 | break; | ||
1598 | case KVM_REG_PPC_DBSR: | ||
1599 | val = get_reg_val(reg->id, vcpu->arch.dbsr); | ||
1600 | break; | 1592 | break; |
1601 | case KVM_REG_PPC_EPR: { | 1593 | case KVM_REG_PPC_EPR: { |
1602 | u32 epr = kvmppc_get_epr(vcpu); | 1594 | u32 epr = kvmppc_get_epr(vcpu); |
1603 | val = get_reg_val(reg->id, epr); | 1595 | *val = get_reg_val(id, epr); |
1604 | break; | 1596 | break; |
1605 | } | 1597 | } |
1606 | #if defined(CONFIG_64BIT) | 1598 | #if defined(CONFIG_64BIT) |
1607 | case KVM_REG_PPC_EPCR: | 1599 | case KVM_REG_PPC_EPCR: |
1608 | val = get_reg_val(reg->id, vcpu->arch.epcr); | 1600 | *val = get_reg_val(id, vcpu->arch.epcr); |
1609 | break; | 1601 | break; |
1610 | #endif | 1602 | #endif |
1611 | case KVM_REG_PPC_TCR: | 1603 | case KVM_REG_PPC_TCR: |
1612 | val = get_reg_val(reg->id, vcpu->arch.tcr); | 1604 | *val = get_reg_val(id, vcpu->arch.tcr); |
1613 | break; | 1605 | break; |
1614 | case KVM_REG_PPC_TSR: | 1606 | case KVM_REG_PPC_TSR: |
1615 | val = get_reg_val(reg->id, vcpu->arch.tsr); | 1607 | *val = get_reg_val(id, vcpu->arch.tsr); |
1616 | break; | 1608 | break; |
1617 | case KVM_REG_PPC_DEBUG_INST: | 1609 | case KVM_REG_PPC_DEBUG_INST: |
1618 | val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV_DEBUG); | 1610 | *val = get_reg_val(id, KVMPPC_INST_EHPRIV_DEBUG); |
1619 | break; | 1611 | break; |
1620 | case KVM_REG_PPC_VRSAVE: | 1612 | case KVM_REG_PPC_VRSAVE: |
1621 | val = get_reg_val(reg->id, vcpu->arch.vrsave); | 1613 | *val = get_reg_val(id, vcpu->arch.vrsave); |
1622 | break; | 1614 | break; |
1623 | default: | 1615 | default: |
1624 | r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, reg->id, &val); | 1616 | r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val); |
1625 | break; | 1617 | break; |
1626 | } | 1618 | } |
1627 | 1619 | ||
1628 | if (r) | ||
1629 | return r; | ||
1630 | |||
1631 | if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size)) | ||
1632 | r = -EFAULT; | ||
1633 | |||
1634 | return r; | 1620 | return r; |
1635 | } | 1621 | } |
1636 | 1622 | ||
1637 | int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | 1623 | int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, |
1624 | union kvmppc_one_reg *val) | ||
1638 | { | 1625 | { |
1639 | int r = 0; | 1626 | int r = 0; |
1640 | union kvmppc_one_reg val; | ||
1641 | int size; | ||
1642 | 1627 | ||
1643 | size = one_reg_size(reg->id); | 1628 | switch (id) { |
1644 | if (size > sizeof(val)) | ||
1645 | return -EINVAL; | ||
1646 | |||
1647 | if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size)) | ||
1648 | return -EFAULT; | ||
1649 | |||
1650 | switch (reg->id) { | ||
1651 | case KVM_REG_PPC_IAC1: | 1629 | case KVM_REG_PPC_IAC1: |
1652 | vcpu->arch.dbg_reg.iac1 = set_reg_val(reg->id, val); | 1630 | vcpu->arch.dbg_reg.iac1 = set_reg_val(id, *val); |
1653 | break; | 1631 | break; |
1654 | case KVM_REG_PPC_IAC2: | 1632 | case KVM_REG_PPC_IAC2: |
1655 | vcpu->arch.dbg_reg.iac2 = set_reg_val(reg->id, val); | 1633 | vcpu->arch.dbg_reg.iac2 = set_reg_val(id, *val); |
1656 | break; | 1634 | break; |
1657 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 1635 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
1658 | case KVM_REG_PPC_IAC3: | 1636 | case KVM_REG_PPC_IAC3: |
1659 | vcpu->arch.dbg_reg.iac3 = set_reg_val(reg->id, val); | 1637 | vcpu->arch.dbg_reg.iac3 = set_reg_val(id, *val); |
1660 | break; | 1638 | break; |
1661 | case KVM_REG_PPC_IAC4: | 1639 | case KVM_REG_PPC_IAC4: |
1662 | vcpu->arch.dbg_reg.iac4 = set_reg_val(reg->id, val); | 1640 | vcpu->arch.dbg_reg.iac4 = set_reg_val(id, *val); |
1663 | break; | 1641 | break; |
1664 | #endif | 1642 | #endif |
1665 | case KVM_REG_PPC_DAC1: | 1643 | case KVM_REG_PPC_DAC1: |
1666 | vcpu->arch.dbg_reg.dac1 = set_reg_val(reg->id, val); | 1644 | vcpu->arch.dbg_reg.dac1 = set_reg_val(id, *val); |
1667 | break; | 1645 | break; |
1668 | case KVM_REG_PPC_DAC2: | 1646 | case KVM_REG_PPC_DAC2: |
1669 | vcpu->arch.dbg_reg.dac2 = set_reg_val(reg->id, val); | 1647 | vcpu->arch.dbg_reg.dac2 = set_reg_val(id, *val); |
1670 | break; | ||
1671 | case KVM_REG_PPC_DBSR: | ||
1672 | vcpu->arch.dbsr = set_reg_val(reg->id, val); | ||
1673 | break; | 1648 | break; |
1674 | case KVM_REG_PPC_EPR: { | 1649 | case KVM_REG_PPC_EPR: { |
1675 | u32 new_epr = set_reg_val(reg->id, val); | 1650 | u32 new_epr = set_reg_val(id, *val); |
1676 | kvmppc_set_epr(vcpu, new_epr); | 1651 | kvmppc_set_epr(vcpu, new_epr); |
1677 | break; | 1652 | break; |
1678 | } | 1653 | } |
1679 | #if defined(CONFIG_64BIT) | 1654 | #if defined(CONFIG_64BIT) |
1680 | case KVM_REG_PPC_EPCR: { | 1655 | case KVM_REG_PPC_EPCR: { |
1681 | u32 new_epcr = set_reg_val(reg->id, val); | 1656 | u32 new_epcr = set_reg_val(id, *val); |
1682 | kvmppc_set_epcr(vcpu, new_epcr); | 1657 | kvmppc_set_epcr(vcpu, new_epcr); |
1683 | break; | 1658 | break; |
1684 | } | 1659 | } |
1685 | #endif | 1660 | #endif |
1686 | case KVM_REG_PPC_OR_TSR: { | 1661 | case KVM_REG_PPC_OR_TSR: { |
1687 | u32 tsr_bits = set_reg_val(reg->id, val); | 1662 | u32 tsr_bits = set_reg_val(id, *val); |
1688 | kvmppc_set_tsr_bits(vcpu, tsr_bits); | 1663 | kvmppc_set_tsr_bits(vcpu, tsr_bits); |
1689 | break; | 1664 | break; |
1690 | } | 1665 | } |
1691 | case KVM_REG_PPC_CLEAR_TSR: { | 1666 | case KVM_REG_PPC_CLEAR_TSR: { |
1692 | u32 tsr_bits = set_reg_val(reg->id, val); | 1667 | u32 tsr_bits = set_reg_val(id, *val); |
1693 | kvmppc_clr_tsr_bits(vcpu, tsr_bits); | 1668 | kvmppc_clr_tsr_bits(vcpu, tsr_bits); |
1694 | break; | 1669 | break; |
1695 | } | 1670 | } |
1696 | case KVM_REG_PPC_TSR: { | 1671 | case KVM_REG_PPC_TSR: { |
1697 | u32 tsr = set_reg_val(reg->id, val); | 1672 | u32 tsr = set_reg_val(id, *val); |
1698 | kvmppc_set_tsr(vcpu, tsr); | 1673 | kvmppc_set_tsr(vcpu, tsr); |
1699 | break; | 1674 | break; |
1700 | } | 1675 | } |
1701 | case KVM_REG_PPC_TCR: { | 1676 | case KVM_REG_PPC_TCR: { |
1702 | u32 tcr = set_reg_val(reg->id, val); | 1677 | u32 tcr = set_reg_val(id, *val); |
1703 | kvmppc_set_tcr(vcpu, tcr); | 1678 | kvmppc_set_tcr(vcpu, tcr); |
1704 | break; | 1679 | break; |
1705 | } | 1680 | } |
1706 | case KVM_REG_PPC_VRSAVE: | 1681 | case KVM_REG_PPC_VRSAVE: |
1707 | vcpu->arch.vrsave = set_reg_val(reg->id, val); | 1682 | vcpu->arch.vrsave = set_reg_val(id, *val); |
1708 | break; | 1683 | break; |
1709 | default: | 1684 | default: |
1710 | r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, reg->id, &val); | 1685 | r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val); |
1711 | break; | 1686 | break; |
1712 | } | 1687 | } |
1713 | 1688 | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index da505237a664..8a26126db482 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -907,6 +907,61 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
907 | } | 907 | } |
908 | EXPORT_SYMBOL_GPL(kvmppc_handle_store); | 908 | EXPORT_SYMBOL_GPL(kvmppc_handle_store); |
909 | 909 | ||
910 | int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | ||
911 | { | ||
912 | int r = 0; | ||
913 | union kvmppc_one_reg val; | ||
914 | int size; | ||
915 | |||
916 | size = one_reg_size(reg->id); | ||
917 | if (size > sizeof(val)) | ||
918 | return -EINVAL; | ||
919 | |||
920 | r = kvmppc_get_one_reg(vcpu, reg->id, &val); | ||
921 | if (r == -EINVAL) { | ||
922 | r = 0; | ||
923 | switch (reg->id) { | ||
924 | default: | ||
925 | r = -EINVAL; | ||
926 | break; | ||
927 | } | ||
928 | } | ||
929 | |||
930 | if (r) | ||
931 | return r; | ||
932 | |||
933 | if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, size)) | ||
934 | r = -EFAULT; | ||
935 | |||
936 | return r; | ||
937 | } | ||
938 | |||
939 | int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) | ||
940 | { | ||
941 | int r; | ||
942 | union kvmppc_one_reg val; | ||
943 | int size; | ||
944 | |||
945 | size = one_reg_size(reg->id); | ||
946 | if (size > sizeof(val)) | ||
947 | return -EINVAL; | ||
948 | |||
949 | if (copy_from_user(&val, (char __user *)(unsigned long)reg->addr, size)) | ||
950 | return -EFAULT; | ||
951 | |||
952 | r = kvmppc_set_one_reg(vcpu, reg->id, &val); | ||
953 | if (r == -EINVAL) { | ||
954 | r = 0; | ||
955 | switch (reg->id) { | ||
956 | default: | ||
957 | r = -EINVAL; | ||
958 | break; | ||
959 | } | ||
960 | } | ||
961 | |||
962 | return r; | ||
963 | } | ||
964 | |||
910 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | 965 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) |
911 | { | 966 | { |
912 | int r; | 967 | int r; |