aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMihai Caraman <mihai.caraman@freescale.com>2013-04-10 20:03:08 -0400
committerAlexander Graf <agraf@suse.de>2013-04-26 14:27:06 -0400
commita85d2aa23e51a9460e034e283da2513930b4f183 (patch)
tree51f61cd107326edbd835c9ec24efea0d7ca3025a
parent35b299e279eb5bc4622ec883b5f388c3224cbd61 (diff)
KVM: PPC: e500: Expose MMU registers via ONE_REG
MMU registers were exposed to user-space using sregs interface. Add them to ONE_REG interface using kvmppc_get_one_reg/kvmppc_set_one_reg delegation mechanism. Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--Documentation/virtual/kvm/api.txt11
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h17
-rw-r--r--arch/powerpc/kvm/e500.c6
-rw-r--r--arch/powerpc/kvm/e500.h4
-rw-r--r--arch/powerpc/kvm/e500_mmu.c94
-rw-r--r--arch/powerpc/kvm/e500mc.c6
6 files changed, 134 insertions, 4 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 976eb650e7ef..1a766637ac21 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1792,6 +1792,17 @@ registers, find a list below:
1792 PPC | KVM_REG_PPC_TSR | 32 1792 PPC | KVM_REG_PPC_TSR | 32
1793 PPC | KVM_REG_PPC_OR_TSR | 32 1793 PPC | KVM_REG_PPC_OR_TSR | 32
1794 PPC | KVM_REG_PPC_CLEAR_TSR | 32 1794 PPC | KVM_REG_PPC_CLEAR_TSR | 32
1795 PPC | KVM_REG_PPC_MAS0 | 32
1796 PPC | KVM_REG_PPC_MAS1 | 32
1797 PPC | KVM_REG_PPC_MAS2 | 64
1798 PPC | KVM_REG_PPC_MAS7_3 | 64
1799 PPC | KVM_REG_PPC_MAS4 | 32
1800 PPC | KVM_REG_PPC_MAS6 | 32
1801 PPC | KVM_REG_PPC_MMUCFG | 32
1802 PPC | KVM_REG_PPC_TLB0CFG | 32
1803 PPC | KVM_REG_PPC_TLB1CFG | 32
1804 PPC | KVM_REG_PPC_TLB2CFG | 32
1805 PPC | KVM_REG_PPC_TLB3CFG | 32
1795 1806
1796ARM registers are mapped using the lower 32 bits. The upper 16 of that 1807ARM registers are mapped using the lower 32 bits. The upper 16 of that
1797is the register group type, or coprocessor number: 1808is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index c0c38ed9c97d..0c5cffb6a58e 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -449,4 +449,21 @@ struct kvm_get_htab_header {
449/* Debugging: Special instruction for software breakpoint */ 449/* Debugging: Special instruction for software breakpoint */
450#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b) 450#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
451 451
452/* MMU registers */
453#define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
454#define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d)
455#define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
456#define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8f)
457#define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
458#define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
459#define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
460/*
461 * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
462 * KVM_CAP_SW_TLB ioctl
463 */
464#define KVM_REG_PPC_TLB0CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
465#define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
466#define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
467#define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
468
452#endif /* __LINUX_KVM_POWERPC_H */ 469#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 576010f6c27d..ce6b73c29612 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -428,13 +428,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
428int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, 428int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
429 union kvmppc_one_reg *val) 429 union kvmppc_one_reg *val)
430{ 430{
431 return -EINVAL; 431 int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
432 return r;
432} 433}
433 434
434int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, 435int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
435 union kvmppc_one_reg *val) 436 union kvmppc_one_reg *val)
436{ 437{
437 return -EINVAL; 438 int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
439 return r;
438} 440}
439 441
440struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 442struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 33db48a8ce24..b73ca7a1c09f 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
131void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); 131void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
132int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); 132int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
133 133
134int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
135 union kvmppc_one_reg *val);
136int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
137 union kvmppc_one_reg *val);
134 138
135#ifdef CONFIG_KVM_E500V2 139#ifdef CONFIG_KVM_E500V2
136unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, 140unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 5c4475983f78..44f7762694ba 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -596,6 +596,100 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
596 return 0; 596 return 0;
597} 597}
598 598
599int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
600 union kvmppc_one_reg *val)
601{
602 int r = 0;
603 long int i;
604
605 switch (id) {
606 case KVM_REG_PPC_MAS0:
607 *val = get_reg_val(id, vcpu->arch.shared->mas0);
608 break;
609 case KVM_REG_PPC_MAS1:
610 *val = get_reg_val(id, vcpu->arch.shared->mas1);
611 break;
612 case KVM_REG_PPC_MAS2:
613 *val = get_reg_val(id, vcpu->arch.shared->mas2);
614 break;
615 case KVM_REG_PPC_MAS7_3:
616 *val = get_reg_val(id, vcpu->arch.shared->mas7_3);
617 break;
618 case KVM_REG_PPC_MAS4:
619 *val = get_reg_val(id, vcpu->arch.shared->mas4);
620 break;
621 case KVM_REG_PPC_MAS6:
622 *val = get_reg_val(id, vcpu->arch.shared->mas6);
623 break;
624 case KVM_REG_PPC_MMUCFG:
625 *val = get_reg_val(id, vcpu->arch.mmucfg);
626 break;
627 case KVM_REG_PPC_TLB0CFG:
628 case KVM_REG_PPC_TLB1CFG:
629 case KVM_REG_PPC_TLB2CFG:
630 case KVM_REG_PPC_TLB3CFG:
631 i = id - KVM_REG_PPC_TLB0CFG;
632 *val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
633 break;
634 default:
635 r = -EINVAL;
636 break;
637 }
638
639 return r;
640}
641
642int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
643 union kvmppc_one_reg *val)
644{
645 int r = 0;
646 long int i;
647
648 switch (id) {
649 case KVM_REG_PPC_MAS0:
650 vcpu->arch.shared->mas0 = set_reg_val(id, *val);
651 break;
652 case KVM_REG_PPC_MAS1:
653 vcpu->arch.shared->mas1 = set_reg_val(id, *val);
654 break;
655 case KVM_REG_PPC_MAS2:
656 vcpu->arch.shared->mas2 = set_reg_val(id, *val);
657 break;
658 case KVM_REG_PPC_MAS7_3:
659 vcpu->arch.shared->mas7_3 = set_reg_val(id, *val);
660 break;
661 case KVM_REG_PPC_MAS4:
662 vcpu->arch.shared->mas4 = set_reg_val(id, *val);
663 break;
664 case KVM_REG_PPC_MAS6:
665 vcpu->arch.shared->mas6 = set_reg_val(id, *val);
666 break;
667 /* Only allow MMU registers to be set to the config supported by KVM */
668 case KVM_REG_PPC_MMUCFG: {
669 u32 reg = set_reg_val(id, *val);
670 if (reg != vcpu->arch.mmucfg)
671 r = -EINVAL;
672 break;
673 }
674 case KVM_REG_PPC_TLB0CFG:
675 case KVM_REG_PPC_TLB1CFG:
676 case KVM_REG_PPC_TLB2CFG:
677 case KVM_REG_PPC_TLB3CFG: {
678 /* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */
679 u32 reg = set_reg_val(id, *val);
680 i = id - KVM_REG_PPC_TLB0CFG;
681 if (reg != vcpu->arch.tlbcfg[i])
682 r = -EINVAL;
683 break;
684 }
685 default:
686 r = -EINVAL;
687 break;
688 }
689
690 return r;
691}
692
599int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, 693int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
600 struct kvm_config_tlb *cfg) 694 struct kvm_config_tlb *cfg)
601{ 695{
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index b071bdcbe37d..ab073a80cd45 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -258,13 +258,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
258int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, 258int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
259 union kvmppc_one_reg *val) 259 union kvmppc_one_reg *val)
260{ 260{
261 return -EINVAL; 261 int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
262 return r;
262} 263}
263 264
264int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, 265int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
265 union kvmppc_one_reg *val) 266 union kvmppc_one_reg *val)
266{ 267{
267 return -EINVAL; 268 int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
269 return r;
268} 270}
269 271
270struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 272struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)