blob: 4e2404ef4e36adfec617c3a8ab24e55839d8b28e [file] [log] [blame]
#ifndef _ASM_IA64_TLBFLUSH_H
#define _ASM_IA64_TLBFLUSH_H
/*
* Copyright (C) 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <asm/mmu_context.h>
#include <asm/page.h>
/*
* Now for some TLB flushing routines. This is the kind of stuff that
* can be very expensive, so try to avoid them whenever possible.
*/
/*
* Flush everything (kernel mapping may also have changed due to
* vmalloc/vfree).
*/
extern void __flush_tlb_all (void);
#ifdef CONFIG_SMP
extern void smp_flush_tlb_all (void);
# define flush_tlb_all() smp_flush_tlb_all()
#else
# define flush_tlb_all() __flush_tlb_all()
#endif
/*
* Flush a specified user mapping
*/
static inline void
flush_tlb_mm (struct mm_struct *mm)
{
if (mm) {
mm->context = 0;
if (mm == current->active_mm) {
/* This is called, e.g., as a result of exec(). */
get_new_mmu_context(mm);
reload_context(mm);
}
}
}
extern void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end);
/*
* Page-granular tlb flush.
*/
static inline void
flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
{
#ifdef CONFIG_SMP
flush_tlb_range(vma, (addr & PAGE_MASK), (addr & PAGE_MASK) + PAGE_SIZE);
#else
if (vma->vm_mm == current->active_mm)
asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(PAGE_SHIFT << 2) : "memory");
#endif
}
/*
* Flush the TLB entries mapping the virtually mapped linear page
* table corresponding to address range [START-END).
*/
static inline void
flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end)
{
struct vm_area_struct vma;
if (REGION_NUMBER(start) != REGION_NUMBER(end))
printk("flush_tlb_pgtables: can't flush across regions!!\n");
vma.vm_mm = mm;
flush_tlb_range(&vma, ia64_thash(start), ia64_thash(end));
}
#define flush_tlb_kernel_range(start, end) flush_tlb_all() /* XXX fix me */
#endif /* _ASM_IA64_TLBFLUSH_H */