powerpc/book3s: Fix flush_tlb cpu_spec hook to take a generic argument.
Subsystems (2)
PATCH v3 1/1 powerpc/book3s: Fix flush_tlb cpu_spec hook to take a generic argument.
From: Mahesh Salgaonkar <[email protected]>
The flush_tlb hook in cpu_spec was introduced as a generic function hook to invalidate TLBs. But the current implementation of flush_tlb hook takes IS (invalidation selector) as an argument which is architecture dependent. Hence, It is not right to have a generic routine where caller has to pass non-generic argument.
This patch fixes this and makes flush_tlb hook as high level API.
---
Changes in V3:
- Changed TLB flush action #defines into enum.
Changes in V2:
- Moved TLB flush action #defines to cputable.h
- Added missing ptesyncs to before and after TLB flush.
- Moved switch case to flush_tlb_206() function as suggested by Michael Ellerman.
--- arch/powerpc/include/asm/cputable.h | 8 ++++- arch/powerpc/include/asm/mmu-hash64.h | 1 + arch/powerpc/kernel/cpu_setup_power.S | 10 +----- arch/powerpc/kernel/cputable.c | 4 +- arch/powerpc/kernel/mce_power.c | 53 ++++++++++++++++++++++++++++++++- arch/powerpc/kvm/book3s_hv_ras.c | 4 +- 6 files changed, 65 insertions(+), 15 deletions(-)
arch/powerpc/include/asm/cputable.h +7 -1
@@ -100,7 +100,7 @@ struct cpu_spec {/* * Processor specific routine to flush tlbs. */ -void (*flush_tlb)(unsigned long inval_selector); +void (*flush_tlb)(unsigned int action); };
@@ -114,6 +114,12 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,extern const char *powerpc_base_platform; +/* TLB flush actions. Used as argument to cpu_spec.flush_tlb() hook */ +enum { +TLB_INVAL_SCOPE_GLOBAL =0 ,/* invalidate all TLBs */ +TLB_INVAL_SCOPE_LPID =1 ,/* invalidate TLBs for current LPID */ +}; +#endif /* __ASSEMBLY__ */ /* CPU kernel features */
arch/powerpc/include/asm/mmu-hash64.h +1 -0
@@ -112,6 +112,7 @@#define TLBIEL_INVAL_SET_SHIFT 12#define POWER7_TLB_SETS 128/* # sets in POWER7 TLB */ +#define POWER8_TLB_SETS 512/* # sets in POWER8 TLB */ #ifndef __ASSEMBLY__
arch/powerpc/kernel/cpu_setup_power.S +2 -8
@@ -137,15 +137,11 @@ __init_HFSCR: /* * Clear the TLB using the specified IS form of tlbiel instruction * (invalidate by congruence class). P7 has 128 CCs., P8 has 512. - * - * r3 = IS field */ __init_tlb_power7: - li r3,0xc00 /* IS field = 0b11 */ -_GLOBAL(__flush_tlb_power7) li r6,128 mtctr r6 - mr r7,r3 /* IS field */ + li r7,0xc00 /* IS field = 0b11 */ ptesync 2: tlbiel r7 addi r7,r7,0x1000
@@ -154,11 +150,9 @@ _GLOBAL(__flush_tlb_power7) 1: blr __init_tlb_power8: - li r3,0xc00 /* IS field = 0b11 */ -_GLOBAL(__flush_tlb_power8) li r6,512 mtctr r6 - mr r7,r3 /* IS field */ + li r7,0xc00 /* IS field = 0b11 */ ptesync 2: tlbiel r7 addi r7,r7,0x1000
arch/powerpc/kernel/cputable.c +2 -2
@@ -71,8 +71,8 @@ extern void __restore_cpu_power7(void);extern void __setup_cpu_power8 (unsigned long offset,struct cpu_spec * spec);extern void __restore_cpu_power8 (void );extern void __restore_cpu_a2 (void ); -extern void __flush_tlb_power7 (unsigned long inval_selector); -extern void __flush_tlb_power8 (unsigned long inval_selector); +extern void __flush_tlb_power7 (unsigned int action); +extern void __flush_tlb_power8 (unsigned int action);extern long __machine_check_early_realmode_p7 (struct pt_regs *regs);extern long __machine_check_early_realmode_p8 (struct pt_regs *regs);#endif /* CONFIG_PPC64 */
arch/powerpc/kernel/mce_power.c +51 -2
71 lines not on this page · raw message
arch/powerpc/kvm/book3s_hv_ras.c +2 -2
@@ -84,7 +84,7 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) }if (dsisr &DSISR_MC_TLB_MULTI ) {if (cur_cpu_spec && cur_cpu_spec->flush_tlb) - cur_cpu_spec->flush_tlb (TLBIEL_INVAL_SET_LPID ); + cur_cpu_spec->flush_tlb (TLB_INVAL_SCOPE_LPID ); dsisr &= ~DSISR_MC_TLB_MULTI ; }/* Any other errors we don't understand? */
@@ -102,7 +102,7 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)break ;case SRR1_MC_IFETCH_TLBMULTI :if (cur_cpu_spec && cur_cpu_spec->flush_tlb) - cur_cpu_spec->flush_tlb (TLBIEL_INVAL_SET_LPID ); + cur_cpu_spec->flush_tlb (TLB_INVAL_SCOPE_LPID );break ;default : handled =0 ;