diff options
author | Mihai Caraman <mihai.caraman@freescale.com> | 2013-04-10 20:03:10 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-04-26 14:27:07 -0400 |
commit | 307d9008ed4f28920e0e78719e10d0f407341e00 (patch) | |
tree | feb54a2bb563bd85e6b56126dc8079c3abadb923 /arch | |
parent | 8893a188b13160ee4b228fab02d802cf4f0a3e78 (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.h | 1 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/kvm.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500.h | 18 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_mmu.c | 22 |
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 | ||
26 | enum 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 | ||
306 | static 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 | ||