Commit 307d9008ed4f28920e0e78719e10d0f407341e00
Committed by
Alexander Graf
1 parent
8893a188b1
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 6 changed files with 59 additions and 0 deletions Side-by-side Diff
Documentation/virtual/kvm/api.txt
... | ... | @@ -1803,6 +1803,10 @@ |
1803 | 1803 | PPC | KVM_REG_PPC_TLB1CFG | 32 |
1804 | 1804 | PPC | KVM_REG_PPC_TLB2CFG | 32 |
1805 | 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 | |
1807 | 1811 | ARM registers are mapped using the lower 32 bits. The upper 16 of that |
1808 | 1812 | is the register group type, or coprocessor number: |
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/uapi/asm/kvm.h
... | ... | @@ -465,6 +465,10 @@ |
465 | 465 | #define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94) |
466 | 466 | #define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95) |
467 | 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 | 473 | #endif /* __LINUX_KVM_POWERPC_H */ |
arch/powerpc/kvm/e500.h
... | ... | @@ -23,6 +23,10 @@ |
23 | 23 | #include <asm/mmu-book3e.h> |
24 | 24 | #include <asm/tlb.h> |
25 | 25 | |
26 | +enum vcpu_ftr { | |
27 | + VCPU_FTR_MMU_V2 | |
28 | +}; | |
29 | + | |
26 | 30 | #define E500_PID_NUM 3 |
27 | 31 | #define E500_TLB_NUM 2 |
28 | 32 | |
... | ... | @@ -298,6 +302,20 @@ |
298 | 302 | /* Force TS=1 for all guest mappings. */ |
299 | 303 | #define get_tlb_sts(gtlbe) (MAS1_TS) |
300 | 304 | #endif /* !BOOKE_HV */ |
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 | +} | |
301 | 319 | |
302 | 320 | #endif /* KVM_E500_H */ |
arch/powerpc/kvm/e500_emulate.c
... | ... | @@ -284,6 +284,16 @@ |
284 | 284 | case SPRN_TLB1CFG: |
285 | 285 | *spr_val = vcpu->arch.tlbcfg[1]; |
286 | 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 | 297 | case SPRN_L1CSR0: |
288 | 298 | *spr_val = vcpu_e500->l1csr0; |
289 | 299 | break; |
arch/powerpc/kvm/e500_mmu.c
... | ... | @@ -631,6 +631,13 @@ |
631 | 631 | i = id - KVM_REG_PPC_TLB0CFG; |
632 | 632 | *val = get_reg_val(id, vcpu->arch.tlbcfg[i]); |
633 | 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 | 641 | default: |
635 | 642 | r = -EINVAL; |
636 | 643 | break; |
... | ... | @@ -682,6 +689,16 @@ |
682 | 689 | r = -EINVAL; |
683 | 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 | 702 | default: |
686 | 703 | r = -EINVAL; |
687 | 704 | break; |
... | ... | @@ -854,6 +871,11 @@ |
854 | 871 | ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); |
855 | 872 | vcpu->arch.tlbcfg[1] |= params[1].entries; |
856 | 873 | vcpu->arch.tlbcfg[1] |= params[1].ways << TLBnCFG_ASSOC_SHIFT; |
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 | + } | |
857 | 879 | |
858 | 880 | return 0; |
859 | 881 | } |