aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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 /arch
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>
Diffstat (limited to 'arch')
-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
5 files changed, 55 insertions, 0 deletions
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