aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMihai Caraman <mihai.caraman@freescale.com>2013-04-10 20:03:10 -0400
committerAlexander Graf <agraf@suse.de>2013-04-26 14:27:07 -0400
commit307d9008ed4f28920e0e78719e10d0f407341e00 (patch)
treefeb54a2bb563bd85e6b56126dc8079c3abadb923
parent8893a188b13160ee4b228fab02d802cf4f0a3e78 (diff)
KVM: PPC: e500: Add support for TLBnPS registers
Add support for TLBnPS registers available in MMU Architecture Version (MAV) 2.0. Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--Documentation/virtual/kvm/api.txt4
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h4
-rw-r--r--arch/powerpc/kvm/e500.h18
-rw-r--r--arch/powerpc/kvm/e500_emulate.c10
-rw-r--r--arch/powerpc/kvm/e500_mmu.c22
6 files changed, 59 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 1a766637ac21..f045377ae5a0 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1803,6 +1803,10 @@ registers, find a list below:
1803 PPC | KVM_REG_PPC_TLB1CFG | 32 1803 PPC | KVM_REG_PPC_TLB1CFG | 32
1804 PPC | KVM_REG_PPC_TLB2CFG | 32 1804 PPC | KVM_REG_PPC_TLB2CFG | 32
1805 PPC | KVM_REG_PPC_TLB3CFG | 32 1805 PPC | KVM_REG_PPC_TLB3CFG | 32
1806 PPC | KVM_REG_PPC_TLB0PS | 32
1807 PPC | KVM_REG_PPC_TLB1PS | 32
1808 PPC | KVM_REG_PPC_TLB2PS | 32
1809 PPC | KVM_REG_PPC_TLB3PS | 32
1806 1810
1807ARM registers are mapped using the lower 32 bits. The upper 16 of that 1811ARM registers are mapped using the lower 32 bits. The upper 16 of that
1808is the register group type, or coprocessor number: 1812is the register group type, or coprocessor number:
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index e34f8fee9080..3b6cee3e33a8 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -502,6 +502,7 @@ struct kvm_vcpu_arch {
502 spinlock_t wdt_lock; 502 spinlock_t wdt_lock;
503 struct timer_list wdt_timer; 503 struct timer_list wdt_timer;
504 u32 tlbcfg[4]; 504 u32 tlbcfg[4];
505 u32 tlbps[4];
505 u32 mmucfg; 506 u32 mmucfg;
506 u32 epr; 507 u32 epr;
507 u32 crit_save; 508 u32 crit_save;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 0c5cffb6a58e..4dd36c399842 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -465,5 +465,9 @@ struct kvm_get_htab_header {
465#define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94) 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) 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) 467#define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
468#define KVM_REG_PPC_TLB0PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
469#define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
470#define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
471#define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
468 472
469#endif /* __LINUX_KVM_POWERPC_H */ 473#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index b73ca7a1c09f..c2e5e98453a6 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -23,6 +23,10 @@
23#include <asm/mmu-book3e.h> 23#include <asm/mmu-book3e.h>
24#include <asm/tlb.h> 24#include <asm/tlb.h>
25 25
26enum vcpu_ftr {
27 VCPU_FTR_MMU_V2
28};
29
26#define E500_PID_NUM 3 30#define E500_PID_NUM 3
27#define E500_TLB_NUM 2 31#define E500_TLB_NUM 2
28 32
@@ -299,4 +303,18 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
299#define get_tlb_sts(gtlbe) (MAS1_TS) 303#define get_tlb_sts(gtlbe) (MAS1_TS)
300#endif /* !BOOKE_HV */ 304#endif /* !BOOKE_HV */
301 305
306static inline bool has_feature(const struct kvm_vcpu *vcpu,
307 enum vcpu_ftr ftr)
308{
309 bool has_ftr;
310 switch (ftr) {
311 case VCPU_FTR_MMU_V2:
312 has_ftr = ((vcpu->arch.mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2);
313 break;
314 default:
315 return false;
316 }
317 return has_ftr;
318}
319
302#endif /* KVM_E500_H */ 320#endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e78f353a836a..12b8de2f91ed 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -284,6 +284,16 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
284 case SPRN_TLB1CFG: 284 case SPRN_TLB1CFG:
285 *spr_val = vcpu->arch.tlbcfg[1]; 285 *spr_val = vcpu->arch.tlbcfg[1];
286 break; 286 break;
287 case SPRN_TLB0PS:
288 if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
289 return EMULATE_FAIL;
290 *spr_val = vcpu->arch.tlbps[0];
291 break;
292 case SPRN_TLB1PS:
293 if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
294 return EMULATE_FAIL;
295 *spr_val = vcpu->arch.tlbps[1];
296 break;
287 case SPRN_L1CSR0: 297 case SPRN_L1CSR0:
288 *spr_val = vcpu_e500->l1csr0; 298 *spr_val = vcpu_e500->l1csr0;
289 break; 299 break;
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
index 08a5b0d296fa..a863dc1791eb 100644
--- a/arch/powerpc/kvm/e500_mmu.c
+++ b/arch/powerpc/kvm/e500_mmu.c
@@ -631,6 +631,13 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
631 i = id - KVM_REG_PPC_TLB0CFG; 631 i = id - KVM_REG_PPC_TLB0CFG;
632 *val = get_reg_val(id, vcpu->arch.tlbcfg[i]); 632 *val = get_reg_val(id, vcpu->arch.tlbcfg[i]);
633 break; 633 break;
634 case KVM_REG_PPC_TLB0PS:
635 case KVM_REG_PPC_TLB1PS:
636 case KVM_REG_PPC_TLB2PS:
637 case KVM_REG_PPC_TLB3PS:
638 i = id - KVM_REG_PPC_TLB0PS;
639 *val = get_reg_val(id, vcpu->arch.tlbps[i]);
640 break;
634 default: 641 default:
635 r = -EINVAL; 642 r = -EINVAL;
636 break; 643 break;
@@ -682,6 +689,16 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
682 r = -EINVAL; 689 r = -EINVAL;
683 break; 690 break;
684 } 691 }
692 case KVM_REG_PPC_TLB0PS:
693 case KVM_REG_PPC_TLB1PS:
694 case KVM_REG_PPC_TLB2PS:
695 case KVM_REG_PPC_TLB3PS: {
696 u32 reg = set_reg_val(id, *val);
697 i = id - KVM_REG_PPC_TLB0PS;
698 if (reg != vcpu->arch.tlbps[i])
699 r = -EINVAL;
700 break;
701 }
685 default: 702 default:
686 r = -EINVAL; 703 r = -EINVAL;
687 break; 704 break;
@@ -855,6 +872,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
855 vcpu->arch.tlbcfg[1] |= params[1].entries; 872 vcpu->arch.tlbcfg[1] |= params[1].entries;
856 vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT; 873 vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT;
857 874
875 if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
876 vcpu->arch.tlbps[0] = mfspr(SPRN_TLB0PS);
877 vcpu->arch.tlbps[1] = mfspr(SPRN_TLB1PS);
878 }
879
858 return 0; 880 return 0;
859} 881}
860 882