X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-sparc64%2Ftlbflush.h;h=8c70fdd037b60cacfcf02187f94fb575bc9b57bf;hb=2cf7311f007833d5818fc9241c09a372c0325a4a;hp=3ef9909ac3ac28110ca0b9c62c26397baff41402;hpb=a91482bdcc2e0f6035702e46f1b99043a0893346;p=linux-2.6.git diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h index 3ef9909ac..8c70fdd03 100644 --- a/include/asm-sparc64/tlbflush.h +++ b/include/asm-sparc64/tlbflush.h @@ -7,14 +7,11 @@ /* TLB flush operations. */ -extern void flush_tlb_pending(void); - -#define flush_tlb_range(vma,start,end) \ - do { (void)(start); flush_tlb_pending(); } while (0) -#define flush_tlb_page(vma,addr) flush_tlb_pending() -#define flush_tlb_mm(mm) flush_tlb_pending() - extern void __flush_tlb_all(void); +extern void __flush_tlb_mm(unsigned long context, unsigned long r); +extern void __flush_tlb_range(unsigned long context, unsigned long start, + unsigned long r, unsigned long end, + unsigned long pgsz, unsigned long size); extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); @@ -25,17 +22,89 @@ extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); #define flush_tlb_kernel_range(start,end) \ __flush_tlb_kernel_range(start,end) +#define flush_tlb_mm(__mm) \ +do { if (CTX_VALID((__mm)->context)) \ + __flush_tlb_mm(CTX_HWBITS((__mm)->context), SECONDARY_CONTEXT); \ +} while (0) + +#define flush_tlb_range(__vma, start, end) \ +do { if (CTX_VALID((__vma)->vm_mm->context)) { \ + unsigned long __start = (start)&PAGE_MASK; \ + unsigned long __end = PAGE_ALIGN(end); \ + __flush_tlb_range(CTX_HWBITS((__vma)->vm_mm->context), __start, \ + SECONDARY_CONTEXT, __end, PAGE_SIZE, \ + (__end - __start)); \ + } \ +} while (0) + +#define flush_tlb_vpte_range(__mm, start, end) \ +do { if (CTX_VALID((__mm)->context)) { \ + unsigned long __start = (start)&PAGE_MASK; \ + unsigned long __end = PAGE_ALIGN(end); \ + __flush_tlb_range(CTX_HWBITS((__mm)->context), __start, \ + SECONDARY_CONTEXT, __end, PAGE_SIZE, \ + (__end - __start)); \ + } \ +} while (0) + +#define flush_tlb_page(vma, page) \ +do { struct mm_struct *__mm = (vma)->vm_mm; \ + if (CTX_VALID(__mm->context)) \ + __flush_tlb_page(CTX_HWBITS(__mm->context), (page)&PAGE_MASK, \ + SECONDARY_CONTEXT); \ +} while (0) + +#define flush_tlb_vpte_page(mm, addr) \ +do { struct mm_struct *__mm = (mm); \ + if (CTX_VALID(__mm->context)) \ + __flush_tlb_page(CTX_HWBITS(__mm->context), (addr)&PAGE_MASK, \ + SECONDARY_CONTEXT); \ +} while (0) + #else /* CONFIG_SMP */ extern void smp_flush_tlb_all(void); +extern void smp_flush_tlb_mm(struct mm_struct *mm); +extern void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end); extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); +extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page); #define flush_tlb_all() smp_flush_tlb_all() +#define flush_tlb_mm(mm) smp_flush_tlb_mm(mm) +#define flush_tlb_range(vma, start, end) \ + smp_flush_tlb_range((vma)->vm_mm, start, end) +#define flush_tlb_vpte_range(mm, start, end) \ + smp_flush_tlb_range(mm, start, end) #define flush_tlb_kernel_range(start, end) \ smp_flush_tlb_kernel_range(start, end) +#define flush_tlb_page(vma, page) \ + smp_flush_tlb_page((vma)->vm_mm, page) +#define flush_tlb_vpte_page(mm, page) \ + smp_flush_tlb_page((mm), page) #endif /* ! CONFIG_SMP */ -extern void flush_tlb_pgtables(struct mm_struct *, unsigned long, unsigned long); +static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + /* Note the signed type. */ + long s = start, e = end, vpte_base; + /* Nobody should call us with start below VM hole and end above. + See if it is really true. */ + BUG_ON(s > e); +#if 0 + /* Currently free_pgtables guarantees this. */ + s &= PMD_MASK; + e = (e + PMD_SIZE - 1) & PMD_MASK; +#endif + vpte_base = (tlb_type == spitfire ? + VPTE_BASE_SPITFIRE : + VPTE_BASE_CHEETAH); + + flush_tlb_vpte_range(mm, + vpte_base + (s >> (PAGE_SHIFT - 3)), + vpte_base + (e >> (PAGE_SHIFT - 3))); +} #endif /* _SPARC64_TLBFLUSH_H */