aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-ia64
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2007-10-16 04:25:44 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:59 -0400
commit954ffcb35f5aca428661d29b96c4eee82b3c19cd (patch)
tree2dd8aaf26a8ae81b461b6d5d824ae8744690e483 /include/asm-ia64
parent97ee052461446526e1de7236497e6f1b1ffedf8c (diff)
flush icache before set_pte() on ia64: flush icache at set_pte
Current ia64 kernel flushes icache by lazy_mmu_prot_update() *after* set_pte(). This is too late. This patch removes lazy_mmu_prot_update and add modfied set_pte() for flushing if necessary. This patch flush icache of a page when new pte has exec bit. && new pte has present bit && new pte is user's page. && (old *ptep is not present || new pte's pfn is not same to old *ptep's ptn) && new pte's page has no Pg_arch_1 bit. Pg_arch_1 is set when a page is cache consistent. I think this condition checks are much easier to understand than considering "Where sync_icache_dcache() should be inserted ?". pte_user() for ia64 was removed by http://lkml.org/lkml/2007/6/12/67 as clean-up. So, I added it again. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: Christoph Lameter <clameter@sgi.com> Cc: Hugh Dickins <hugh@veritas.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/asm-ia64')
-rw-r--r--include/asm-ia64/pgtable.h44
1 files changed, 31 insertions, 13 deletions
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 6b4216edbb9c..0971ec90807e 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -223,12 +223,6 @@ ia64_phys_addr_valid (unsigned long addr)
223 * page table. 223 * page table.
224 */ 224 */
225 225
226/*
227 * On some architectures, special things need to be done when setting
228 * the PTE in a page table. Nothing special needs to be on IA-64.
229 */
230#define set_pte(ptep, pteval) (*(ptep) = (pteval))
231#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
232 226
233#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL) 227#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL)
234#ifdef CONFIG_VIRTUAL_MEM_MAP 228#ifdef CONFIG_VIRTUAL_MEM_MAP
@@ -321,6 +315,36 @@ ia64_phys_addr_valid (unsigned long addr)
321#define pte_mkhuge(pte) (__pte(pte_val(pte))) 315#define pte_mkhuge(pte) (__pte(pte_val(pte)))
322 316
323/* 317/*
318 * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to
319 * sync icache and dcache when we insert *new* executable page.
320 * __ia64_sync_icache_dcache() check Pg_arch_1 bit and flush icache
321 * if necessary.
322 *
323 * set_pte() is also called by the kernel, but we can expect that the kernel
324 * flushes icache explicitly if necessary.
325 */
326#define pte_present_exec_user(pte)\
327 ((pte_val(pte) & (_PAGE_P | _PAGE_PL_MASK | _PAGE_AR_RX)) == \
328 (_PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX))
329
330extern void __ia64_sync_icache_dcache(pte_t pteval);
331static inline void set_pte(pte_t *ptep, pte_t pteval)
332{
333 /* page is present && page is user && page is executable
334 * && (page swapin or new page or page migraton
335 * || copy_on_write with page copying.)
336 */
337 if (pte_present_exec_user(pteval) &&
338 (!pte_present(*ptep) ||
339 pte_pfn(*ptep) != pte_pfn(pteval)))
340 /* load_module() calles flush_icache_range() explicitly*/
341 __ia64_sync_icache_dcache(pteval);
342 *ptep = pteval;
343}
344
345#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
346
347/*
324 * Make page protection values cacheable, uncacheable, or write- 348 * Make page protection values cacheable, uncacheable, or write-
325 * combining. Note that "protection" is really a misnomer here as the 349 * combining. Note that "protection" is really a misnomer here as the
326 * protection value contains the memory attribute bits, dirty bits, and 350 * protection value contains the memory attribute bits, dirty bits, and
@@ -489,12 +513,6 @@ extern struct page *zero_page_memmap_ptr;
489#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1)) 513#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1))
490#endif 514#endif
491 515
492/*
493 * IA-64 doesn't have any external MMU info: the page tables contain all the necessary
494 * information. However, we use this routine to take care of any (delayed) i-cache
495 * flushing that may be necessary.
496 */
497extern void lazy_mmu_prot_update (pte_t pte);
498 516
499#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS 517#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
500/* 518/*
@@ -584,7 +602,7 @@ extern void lazy_mmu_prot_update (pte_t pte);
584#define __HAVE_ARCH_PTEP_SET_WRPROTECT 602#define __HAVE_ARCH_PTEP_SET_WRPROTECT
585#define __HAVE_ARCH_PTE_SAME 603#define __HAVE_ARCH_PTE_SAME
586#define __HAVE_ARCH_PGD_OFFSET_GATE 604#define __HAVE_ARCH_PGD_OFFSET_GATE
587#define __HAVE_ARCH_LAZY_MMU_PROT_UPDATE 605
588 606
589#ifndef CONFIG_PGTABLE_4 607#ifndef CONFIG_PGTABLE_4
590#include <asm-generic/pgtable-nopud.h> 608#include <asm-generic/pgtable-nopud.h>