powerpc: Add SMP support to no-hash TLB handling v2
PATCH 1/1 powerpc: Add SMP support to no-hash TLB handling v2
This patch moves the whole no-hash TLB handling out of line into a new tlb_nohash.c file, and implements some basic SMP support using IPIs and/or broadcast tlbivax instructions.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
---
This variant fixes usage of linux/spinlock.h instead of asm/spinlock.h
arch/powerpc/include/asm/mmu.h | 3 arch/powerpc/include/asm/tlbflush.h | 63 +++------- arch/powerpc/kernel/misc_32.S | 20 +++ arch/powerpc/kernel/ppc_ksyms.c | 8 - arch/powerpc/mm/Makefile | 2 arch/powerpc/mm/tlb_hash32.c | 4 arch/powerpc/mm/tlb_nohash.c | 209 ++++++++++++++++++++++++++++++++++++ 7 files changed, 260 insertions(+), 49 deletions(-)
arch/powerpc/include/asm/tlbflush.h +22 -41
@@ -18,7 +18,7 @@*/ #ifdef __KERNEL__ -#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE ) +#ifdef CONFIG_PPC_MMU_NOHASH /* * TLB flushing for software loaded TLB chips *
@@ -35,6 +35,7 @@ extern void _tlbie(unsigned long addressextern void _tlbil_all (void );extern void _tlbil_pid (unsigned int pid);extern void _tlbil_va (unsigned long address,unsigned int pid); +extern void _tlbivax_bcast (unsigned long address,unsigned int pid);#if defined(CONFIG_40x) || defined(CONFIG_8xx)#define _tlbia () asm volatile ("tlbia; sync" : : : "memory")
@@ -42,48 +43,26 @@ extern void _tlbil_va(unsigned long addrextern void _tlbia (void );#endif -static inline void local_flush_tlb_mm (struct mm_struct *mm) -{ -_tlbil_pid (mm->context.id); -} - -static inline void flush_tlb_mm (struct mm_struct *mm) -{ -_tlbil_pid (mm->context.id); -} - -static inline void local_flush_tlb_page (unsigned long vmaddr) -{ -_tlbil_va (vmaddr,0 ); -} - -static inline void flush_tlb_page (struct vm_area_struct *vma, -unsigned long vmaddr) -{ -_tlbil_va (vmaddr, vma ? vma->vm_mm->context.id :0 ); -} +extern void flush_tlb_range (struct vm_area_struct *vma,unsigned long start, +unsigned long end); +extern void flush_tlb_kernel_range (unsigned long start,unsigned long end); -static inline void flush_tlb_page_nohash (struct vm_area_struct *vma, -unsigned long vmaddr) -{ -flush_tlb_page (vma, vmaddr); -} +extern void local_flush_tlb_mm (struct mm_struct *mm); +extern void local_flush_tlb_page (struct vm_area_struct *vma,unsigned long vmaddr); -static inline void flush_tlb_range (struct vm_area_struct *vma, -unsigned long start,unsigned long end) -{ -_tlbil_pid (vma->vm_mm->context.id); -} +#ifdef CONFIG_SMP +extern void flush_tlb_mm (struct mm_struct *mm); +extern void flush_tlb_page (struct vm_area_struct *vma,unsigned long vmaddr); +#else +#define flush_tlb_mm (mm) local_flush_tlb_mm(mm) +#define flush_tlb_page (vma,addr) local_flush_tlb_page(vma,addr) +#endif +#define flush_tlb_page_nohash (vma,addr) flush_tlb_page(vma,addr) -static inline void flush_tlb_kernel_range (unsigned long start, -unsigned long end) -{ -_tlbil_pid (0 ); -} +#elif defined(CONFIG_PPC_STD_MMU_32) -#elif defined(CONFIG_PPC32)/* -* TLB flushing for "classic" hash-MMMU 32-bit CPUs, 6xx, 7xx, 7xxx +* TLB flushing for "classic" hash-MMU 32-bit CPUs, 6xx, 7xx, 7xxx */ extern void _tlbie (unsigned long address);extern void _tlbia (void );
@@ -99,9 +78,10 @@ static inline void local_flush_tlb_page( flush_tlb_page(NULL, vmaddr); } -#else +#elif defined(CONFIG_PPC_STD_MMU_64) +/* -* TLB flushing for 64-bit has-MMU CPUs +* TLB flushing for 64-bit hash-MMU CPUs */ #include <linux/percpu.h>
@@ -183,7 +163,8 @@ static inline void flush_tlb_kernel_rangextern void __flush_hash_table_range (struct mm_struct *mm,unsigned long start,unsigned long end); - +#else +#error Unsupported MMU type#endif #endif /*__KERNEL__ */
arch/powerpc/mm/Makefile +1 -1
@@ -9,7 +9,7 @@ endif obj-y := fault.o mem.o pgtable.o \ init_$(CONFIG_WORD_SIZE).o \ pgtable_$(CONFIG_WORD_SIZE).o -obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o +obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o obj-$(CONFIG_PPC64) += hash_utils_64.o \ slb_low.o slb.o stab.o \
arch/powerpc/mm/tlb_nohash.c new file +209 -0
209 lines not on this page · raw message
arch/powerpc/kernel/misc_32.S +20 -0
@@ -29,6 +29,7 @@ #include <asm/asm-offsets.h> #include <asm/processor.h> #include <asm/kexec.h> +#include <asm/bug.h> .text
@@ -493,6 +494,25 @@ _GLOBAL(_tlbil_va) blr #endif /* CONFIG_FSL_BOOKE */ +_GLOBAL(_tlbivax_bcast) +#if defined(CONFIG_PPC_MMU_NOHASH) && defined(CONFIG_SMP) + mfmsr r10 + wrteei 0 + mtspr SPRN_MMUCR,r4 /* Set PID and all rest to 0 */ +/* tlbivax 0,r3 - use .long to avoid binutils deps */ + .long 0x7c000624 | (r3 << 11) + isync + eieio + tlbsync + sync +10: wrtee r10 + blr +#else +1: trap + EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; + blr +#endif + /* * Flush instruction cache.
arch/powerpc/kernel/ppc_ksyms.c +1 -7
@@ -116,15 +116,9 @@ EXPORT_SYMBOL(giveup_spe);#ifndef CONFIG_PPC64 EXPORT_SYMBOL (flush_instruction_cache); -EXPORT_SYMBOL (flush_tlb_kernel_range); -EXPORT_SYMBOL (flush_tlb_page); -EXPORT_SYMBOL (_tlbie); -#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE ) -EXPORT_SYMBOL (_tlbil_va); -#endif -#endif EXPORT_SYMBOL (__flush_icache_range);EXPORT_SYMBOL (flush_dcache_range); +#endif #ifdef CONFIG_SMP #ifdef CONFIG_PPC32
arch/powerpc/mm/tlb_hash32.c +4 -0
@@ -137,6 +137,7 @@ void flush_tlb_kernel_range(unsigned lonflush_range (&init_mm, start, end);FINISH_FLUSH ; } +EXPORT_SYMBOL (flush_tlb_kernel_range);/* * Flush all the (user) entries for the address space described by mm.
@@ -160,6 +161,7 @@ void flush_tlb_mm(struct mm_struct *mm)flush_range (mp->vm_mm, mp->vm_start, mp->vm_end);FINISH_FLUSH ; } +EXPORT_SYMBOL (flush_tlb_mm);void flush_tlb_page (struct vm_area_struct *vma,unsigned long vmaddr) {
@@ -176,6 +178,7 @@ void flush_tlb_page(struct vm_area_strucflush_hash_pages (mm->context.id, vmaddr,pmd_val (*pmd),1 );FINISH_FLUSH ; } +EXPORT_SYMBOL (flush_tlb_page);/* * For each address in the range, find the pte for the address
@@ -188,3 +191,4 @@ void flush_tlb_range(struct vm_area_struflush_range (vma->vm_mm, start, end);FINISH_FLUSH ; } +EXPORT_SYMBOL (flush_tlb_range);
arch/powerpc/include/asm/mmu.h +3 -0
@@ -15,6 +15,9 @@#define MMU_FTR_TYPE_FSL_E ASM_CONST(0x00000010)#define MMU_FTR_HAS_HIGH_BATS ASM_CONST(0x00010000)#define MMU_FTR_BIG_PHYS ASM_CONST(0x00020000) +#define MMU_FTR_HAS_TLBIVAX_BCAST ASM_CONST(0x00040000) +#define MMU_FTR_HAS_TLBILX_PID ASM_CONST(0x00080000) +#define MMU_FTR_TLBIVAX_NEED_LOCK ASM_CONST(0x00100000)#ifndef __ASSEMBLY__#include <asm/cputable.h>