diff options
author | Akira Takeuchi <takeuchi.akr@jp.panasonic.com> | 2010-10-27 18:28:51 +0200 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2010-10-27 18:28:51 +0200 |
commit | 965ea4bbb9ae926358273368144ba838c561bc38 (patch) | |
tree | c6ee08f2f2970bb500ccc7cf58de6beea870e4f8 /arch/mn10300/include | |
parent | MN10300: Use the [ID]PTEL2 registers rather than [ID]PTEL for TLB control (diff) | |
download | linux-965ea4bbb9ae926358273368144ba838c561bc38.tar.xz linux-965ea4bbb9ae926358273368144ba838c561bc38.zip |
MN10300: SMP TLB flushing
Implement global TLB flushing for MN10300. This will be used by the AM34 which
is SMP capable.
Signed-off-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com>
Signed-off-by: Kiyoshi Owada <owada.kiyoshi@jp.panasonic.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'arch/mn10300/include')
-rw-r--r-- | arch/mn10300/include/asm/mmu_context.h | 22 | ||||
-rw-r--r-- | arch/mn10300/include/asm/tlbflush.h | 81 |
2 files changed, 74 insertions, 29 deletions
diff --git a/arch/mn10300/include/asm/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h index 5fb3648968ae..c8f6c82672ad 100644 --- a/arch/mn10300/include/asm/mmu_context.h +++ b/arch/mn10300/include/asm/mmu_context.h @@ -36,6 +36,22 @@ #define enter_lazy_tlb(mm, tsk) do {} while (0) +static inline void cpu_ran_vm(int cpu, struct mm_struct *mm) +{ +#ifdef CONFIG_SMP + cpumask_set_cpu(cpu, mm_cpumask(mm)); +#endif +} + +static inline bool cpu_maybe_ran_vm(int cpu, struct mm_struct *mm) +{ +#ifdef CONFIG_SMP + return cpumask_test_and_set_cpu(cpu, mm_cpumask(mm)); +#else + return true; +#endif +} + #ifdef CONFIG_MN10300_TLB_USE_PIDR extern unsigned long mmu_context_cache[NR_CPUS]; #define mm_context(mm) (mm->context.tlbpid[smp_processor_id()]) @@ -127,7 +143,13 @@ static inline void activate_context(struct mm_struct *mm) static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { + int cpu = smp_processor_id(); + if (prev != next) { +#ifdef CONFIG_SMP + per_cpu(cpu_tlbstate, cpu).active_mm = next; +#endif + cpu_ran_vm(cpu, next); PTBR = (unsigned long) next->pgd; activate_context(next); } diff --git a/arch/mn10300/include/asm/tlbflush.h b/arch/mn10300/include/asm/tlbflush.h index c3c194d4031e..efddd6e1adea 100644 --- a/arch/mn10300/include/asm/tlbflush.h +++ b/arch/mn10300/include/asm/tlbflush.h @@ -11,6 +11,7 @@ #ifndef _ASM_TLBFLUSH_H #define _ASM_TLBFLUSH_H +#include <linux/mm.h> #include <asm/processor.h> struct tlb_state { @@ -93,39 +94,61 @@ void local_flush_tlb_page(struct mm_struct *mm, unsigned long addr) * - flush_tlb_range(mm, start, end) flushes a range of pages * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ -#define flush_tlb_all() \ -do { \ - preempt_disable(); \ - local_flush_tlb_all(); \ - preempt_enable(); \ -} while (0) - -#define flush_tlb_mm(mm) \ -do { \ - preempt_disable(); \ - local_flush_tlb_all(); \ - preempt_enable(); \ -} while (0) - -#define flush_tlb_range(vma, start, end) \ -do { \ - unsigned long __s __attribute__((unused)) = (start); \ - unsigned long __e __attribute__((unused)) = (end); \ - preempt_disable(); \ - local_flush_tlb_all(); \ - preempt_enable(); \ -} while (0) +#ifdef CONFIG_SMP + +#include <asm/smp.h> + +extern void flush_tlb_all(void); +extern void flush_tlb_current_task(void); +extern void flush_tlb_mm(struct mm_struct *); +extern void flush_tlb_page(struct vm_area_struct *, unsigned long); + +#define flush_tlb() flush_tlb_current_task() + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + flush_tlb_mm(vma->vm_mm); +} + +#else /* CONFIG_SMP */ + +static inline void flush_tlb_all(void) +{ + preempt_disable(); + local_flush_tlb_all(); + preempt_enable(); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + preempt_disable(); + local_flush_tlb_all(); + preempt_enable(); +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + preempt_disable(); + local_flush_tlb_all(); + preempt_enable(); +} #define flush_tlb_page(vma, addr) local_flush_tlb_page((vma)->vm_mm, addr) #define flush_tlb() flush_tlb_all() -#define flush_tlb_kernel_range(start, end) \ -do { \ - unsigned long __s __attribute__((unused)) = (start); \ - unsigned long __e __attribute__((unused)) = (end); \ - flush_tlb_all(); \ -} while (0) +#endif /* CONFIG_SMP */ -#define flush_tlb_pgtables(mm, start, end) do {} while (0) +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ + flush_tlb_all(); +} + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} #endif /* _ASM_TLBFLUSH_H */ |