2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
16 #include <linux/cpumask.h>
17 #include <linux/module.h>
18 #include <asm/tlbflush.h>
19 #include <asm/homecache.h>
20 #include <hv/hypervisor.h>
23 DEFINE_PER_CPU(int, current_asid
);
24 int min_asid
, max_asid
;
27 * Note that we flush the L1I (for VM_EXEC pages) as well as the TLB
28 * so that when we are unmapping an executable page, we also flush it.
29 * Combined with flushing the L1I at context switch time, this means
30 * we don't have to do any other icache flushes.
33 void flush_tlb_mm(struct mm_struct
*mm
)
35 HV_Remote_ASID asids
[NR_CPUS
];
37 for_each_cpu(cpu
, mm_cpumask(mm
)) {
38 HV_Remote_ASID
*asid
= &asids
[i
++];
39 asid
->y
= cpu
/ smp_topology
.width
;
40 asid
->x
= cpu
% smp_topology
.width
;
41 asid
->asid
= per_cpu(current_asid
, cpu
);
43 flush_remote(0, HV_FLUSH_EVICT_L1I
, mm_cpumask(mm
),
44 0, 0, 0, NULL
, asids
, i
);
47 void flush_tlb_current_task(void)
49 flush_tlb_mm(current
->mm
);
52 void flush_tlb_page_mm(const struct vm_area_struct
*vma
, struct mm_struct
*mm
,
55 unsigned long size
= hv_page_size(vma
);
56 int cache
= (vma
->vm_flags
& VM_EXEC
) ? HV_FLUSH_EVICT_L1I
: 0;
57 flush_remote(0, cache
, mm_cpumask(mm
),
58 va
, size
, size
, mm_cpumask(mm
), NULL
, 0);
61 void flush_tlb_page(const struct vm_area_struct
*vma
, unsigned long va
)
63 flush_tlb_page_mm(vma
, vma
->vm_mm
, va
);
65 EXPORT_SYMBOL(flush_tlb_page
);
67 void flush_tlb_range(const struct vm_area_struct
*vma
,
68 unsigned long start
, unsigned long end
)
70 unsigned long size
= hv_page_size(vma
);
71 struct mm_struct
*mm
= vma
->vm_mm
;
72 int cache
= (vma
->vm_flags
& VM_EXEC
) ? HV_FLUSH_EVICT_L1I
: 0;
73 flush_remote(0, cache
, mm_cpumask(mm
), start
, end
- start
, size
,
74 mm_cpumask(mm
), NULL
, 0);
77 void flush_tlb_all(void)
81 HV_VirtAddrRange r
= hv_inquire_virtual(i
);
84 flush_remote(0, HV_FLUSH_EVICT_L1I
, cpu_online_mask
,
85 r
.start
, r
.size
, PAGE_SIZE
, cpu_online_mask
,
87 flush_remote(0, 0, NULL
,
88 r
.start
, r
.size
, HPAGE_SIZE
, cpu_online_mask
,
93 void flush_tlb_kernel_range(unsigned long start
, unsigned long end
)
95 flush_remote(0, HV_FLUSH_EVICT_L1I
, cpu_online_mask
,
96 start
, end
- start
, PAGE_SIZE
, cpu_online_mask
, NULL
, 0);