forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.3 KiB
152 lines
3.3 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
#ifndef _ALPHA_TLBFLUSH_H |
|
#define _ALPHA_TLBFLUSH_H |
|
|
|
#include <linux/mm.h> |
|
#include <linux/sched.h> |
|
#include <asm/compiler.h> |
|
|
|
#ifndef __EXTERN_INLINE |
|
#define __EXTERN_INLINE extern inline |
|
#define __MMU_EXTERN_INLINE |
|
#endif |
|
|
|
extern void __load_new_mm_context(struct mm_struct *); |
|
|
|
|
|
/* Use a few helper functions to hide the ugly broken ASN |
|
numbers on early Alphas (ev4 and ev45). */ |
|
|
|
__EXTERN_INLINE void |
|
ev4_flush_tlb_current(struct mm_struct *mm) |
|
{ |
|
__load_new_mm_context(mm); |
|
tbiap(); |
|
} |
|
|
|
__EXTERN_INLINE void |
|
ev5_flush_tlb_current(struct mm_struct *mm) |
|
{ |
|
__load_new_mm_context(mm); |
|
} |
|
|
|
/* Flush just one page in the current TLB set. We need to be very |
|
careful about the icache here, there is no way to invalidate a |
|
specific icache page. */ |
|
|
|
__EXTERN_INLINE void |
|
ev4_flush_tlb_current_page(struct mm_struct * mm, |
|
struct vm_area_struct *vma, |
|
unsigned long addr) |
|
{ |
|
int tbi_flag = 2; |
|
if (vma->vm_flags & VM_EXEC) { |
|
__load_new_mm_context(mm); |
|
tbi_flag = 3; |
|
} |
|
tbi(tbi_flag, addr); |
|
} |
|
|
|
__EXTERN_INLINE void |
|
ev5_flush_tlb_current_page(struct mm_struct * mm, |
|
struct vm_area_struct *vma, |
|
unsigned long addr) |
|
{ |
|
if (vma->vm_flags & VM_EXEC) |
|
__load_new_mm_context(mm); |
|
else |
|
tbi(2, addr); |
|
} |
|
|
|
|
|
#ifdef CONFIG_ALPHA_GENERIC |
|
# define flush_tlb_current alpha_mv.mv_flush_tlb_current |
|
# define flush_tlb_current_page alpha_mv.mv_flush_tlb_current_page |
|
#else |
|
# ifdef CONFIG_ALPHA_EV4 |
|
# define flush_tlb_current ev4_flush_tlb_current |
|
# define flush_tlb_current_page ev4_flush_tlb_current_page |
|
# else |
|
# define flush_tlb_current ev5_flush_tlb_current |
|
# define flush_tlb_current_page ev5_flush_tlb_current_page |
|
# endif |
|
#endif |
|
|
|
#ifdef __MMU_EXTERN_INLINE |
|
#undef __EXTERN_INLINE |
|
#undef __MMU_EXTERN_INLINE |
|
#endif |
|
|
|
/* Flush current user mapping. */ |
|
static inline void |
|
flush_tlb(void) |
|
{ |
|
flush_tlb_current(current->active_mm); |
|
} |
|
|
|
/* Flush someone else's user mapping. */ |
|
static inline void |
|
flush_tlb_other(struct mm_struct *mm) |
|
{ |
|
unsigned long *mmc = &mm->context[smp_processor_id()]; |
|
/* Check it's not zero first to avoid cacheline ping pong |
|
when possible. */ |
|
if (*mmc) *mmc = 0; |
|
} |
|
|
|
#ifndef CONFIG_SMP |
|
/* Flush everything (kernel mapping may also have changed |
|
due to vmalloc/vfree). */ |
|
static inline void flush_tlb_all(void) |
|
{ |
|
tbia(); |
|
} |
|
|
|
/* Flush a specified user mapping. */ |
|
static inline void |
|
flush_tlb_mm(struct mm_struct *mm) |
|
{ |
|
if (mm == current->active_mm) |
|
flush_tlb_current(mm); |
|
else |
|
flush_tlb_other(mm); |
|
} |
|
|
|
/* Page-granular tlb flush. */ |
|
static inline void |
|
flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) |
|
{ |
|
struct mm_struct *mm = vma->vm_mm; |
|
|
|
if (mm == current->active_mm) |
|
flush_tlb_current_page(mm, vma, addr); |
|
else |
|
flush_tlb_other(mm); |
|
} |
|
|
|
/* Flush a specified range of user mapping. On the Alpha we flush |
|
the whole user tlb. */ |
|
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 */ |
|
|
|
extern void flush_tlb_all(void); |
|
extern void flush_tlb_mm(struct mm_struct *); |
|
extern void flush_tlb_page(struct vm_area_struct *, unsigned long); |
|
extern void flush_tlb_range(struct vm_area_struct *, unsigned long, |
|
unsigned long); |
|
|
|
#endif /* CONFIG_SMP */ |
|
|
|
static inline void flush_tlb_kernel_range(unsigned long start, |
|
unsigned long end) |
|
{ |
|
flush_tlb_all(); |
|
} |
|
|
|
#endif /* _ALPHA_TLBFLUSH_H */
|
|
|