1f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#ifndef _ASM_POWERPC_PGTABLE_PPC64_H_
2f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define _ASM_POWERPC_PGTABLE_PPC64_H_
3f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
4f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * This file contains the functions and defines necessary to modify and use
5f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * the ppc64 hashed page table.
6f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
7f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
8f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#ifdef CONFIG_PPC_64K_PAGES
9c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#include <asm/pgtable-ppc64-64k.h>
10f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#else
11c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#include <asm/pgtable-ppc64-4k.h>
12f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#endif
13074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#include <asm/barrier.h>
14f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
15f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define FIRST_USER_ADDRESS	0
16f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
17f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
18f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * Size of EA range mapped by our pagetables.
19f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
20f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
21f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson                	    PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
223d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
23f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
24f940f5289873af2ad2c4e73f88c24ad2b8fe3f87Aneesh Kumar K.V#ifdef CONFIG_TRANSPARENT_HUGEPAGE
25f940f5289873af2ad2c4e73f88c24ad2b8fe3f87Aneesh Kumar K.V#define PMD_CACHE_INDEX	(PMD_INDEX_SIZE + 1)
26f940f5289873af2ad2c4e73f88c24ad2b8fe3f87Aneesh Kumar K.V#else
27f940f5289873af2ad2c4e73f88c24ad2b8fe3f87Aneesh Kumar K.V#define PMD_CACHE_INDEX	PMD_INDEX_SIZE
28f940f5289873af2ad2c4e73f88c24ad2b8fe3f87Aneesh Kumar K.V#endif
29f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
3057e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * Define the address range of the kernel non-linear virtual area
31f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
3257e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt
3357e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E
3457e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define KERN_VIRT_START ASM_CONST(0x8000000000000000)
3557e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#else
3657e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define KERN_VIRT_START ASM_CONST(0xD000000000000000)
3757e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#endif
3867550080b8288ee9b61e132e8ebc87d563f9c516Aneesh Kumar K.V#define KERN_VIRT_SIZE	ASM_CONST(0x0000100000000000)
39f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
40f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
4157e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * The vmalloc space starts at the beginning of that region, and
4257e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * occupies half of it on hash CPUs and a quarter of it on Book3E
4332a74949b7337726e76d69f51c48715431126c6cBenjamin Herrenschmidt * (we keep a quarter for the virtual memmap)
4457e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt */
4557e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define VMALLOC_START	KERN_VIRT_START
4657e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E
4757e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define VMALLOC_SIZE	(KERN_VIRT_SIZE >> 2)
4857e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#else
4957e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define VMALLOC_SIZE	(KERN_VIRT_SIZE >> 1)
5057e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#endif
5157e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
5257e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt
5357e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt/*
5457e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * The second half of the kernel virtual space is used for IO mappings,
5557e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * it's itself carved into the PIO region (ISA and PHB IO space) and
5657e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * the ioremap space
573d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt *
5857e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt *  ISA_IO_BASE = KERN_IO_START, 64K reserved area
593d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt *  PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces
603d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE
61f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
6257e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define KERN_IO_START	(KERN_VIRT_START + (KERN_VIRT_SIZE >> 1))
633d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt#define FULL_IO_SIZE	0x80000000ul
6457e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define  ISA_IO_BASE	(KERN_IO_START)
6557e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define  ISA_IO_END	(KERN_IO_START + 0x10000ul)
663d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt#define  PHB_IO_BASE	(ISA_IO_END)
6757e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define  PHB_IO_END	(KERN_IO_START + FULL_IO_SIZE)
683d5134ee8341bffc4f539049abb9e90d469b448dBenjamin Herrenschmidt#define IOREMAP_BASE	(PHB_IO_END)
6957e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define IOREMAP_END	(KERN_VIRT_START + KERN_VIRT_SIZE)
7057e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt
71f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
72f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
73f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * Region IDs
74f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
75f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define REGION_SHIFT		60UL
76f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define REGION_MASK		(0xfUL << REGION_SHIFT)
77f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define REGION_ID(ea)		(((unsigned long)(ea)) >> REGION_SHIFT)
78f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
79f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define VMALLOC_REGION_ID	(REGION_ID(VMALLOC_START))
80f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define KERNEL_REGION_ID	(REGION_ID(PAGE_OFFSET))
8132a74949b7337726e76d69f51c48715431126c6cBenjamin Herrenschmidt#define VMEMMAP_REGION_ID	(0xfUL)	/* Server only */
82f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define USER_REGION_ID		(0UL)
83f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
84f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
8557e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * Defines the address of the vmemap area, in its own region on
8657e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt * hash table CPUs and after the vmalloc space on Book3E
87d29eff7bca60c9ee401d691d4562a4abca8de543Andy Whitcroft */
8857e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E
8957e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define VMEMMAP_BASE		VMALLOC_END
9057e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#define VMEMMAP_END		KERN_IO_START
9157e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#else
92cec08e7a948326b01555be6311480aa08e637de2Benjamin Herrenschmidt#define VMEMMAP_BASE		(VMEMMAP_REGION_ID << REGION_SHIFT)
9357e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#endif
94cec08e7a948326b01555be6311480aa08e637de2Benjamin Herrenschmidt#define vmemmap			((struct page *)VMEMMAP_BASE)
95cec08e7a948326b01555be6311480aa08e637de2Benjamin Herrenschmidt
96d29eff7bca60c9ee401d691d4562a4abca8de543Andy Whitcroft
97d29eff7bca60c9ee401d691d4562a4abca8de543Andy Whitcroft/*
98c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt * Include the PTE bits definitions
99f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
10057e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3S
101c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#include <asm/pte-hash64.h>
10257e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#else
10357e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#include <asm/pte-book3e.h>
10457e2a99f74b0d3720c97a6aadb57ae6aad3c61eaBenjamin Herrenschmidt#endif
10571087002cf807e25056dba4e4028a9f204dc9ffdBenjamin Herrenschmidt#include <asm/pte-common.h>
106c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
10794ee815c05c9387931e549d83312d30009ed86e9Benjamin Herrenschmidt#ifdef CONFIG_PPC_MM_SLICES
108f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define HAVE_ARCH_UNMAPPED_AREA
109f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
11094ee815c05c9387931e549d83312d30009ed86e9Benjamin Herrenschmidt#endif /* CONFIG_PPC_MM_SLICES */
111f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
112f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#ifndef __ASSEMBLY__
113f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
114f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
115c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt * This is the default implementation of various PTE accessors, it's
116c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt * used in all cases except Book3S with 64K pages where we have a
117c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt * concept of sub-pages
118c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt */
119c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#ifndef __real_pte
120c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
121c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#ifdef STRICT_MM_TYPECHECKS
122c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define __real_pte(e,p)		((real_pte_t){(e)})
123c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define __rpte_to_pte(r)	((r).pte)
124c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#else
125c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define __real_pte(e,p)		(e)
126c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define __rpte_to_pte(r)	(__pte(r))
127c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#endif
128c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define __rpte_to_hidx(r,index)	(pte_val(__rpte_to_pte(r)) >> 12)
129c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
130c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)       \
131c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt	do {							         \
132c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt		index = 0;					         \
133c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt		shift = mmu_psize_defs[psize].shift;		         \
134c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
135c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define pte_iterate_hashed_end() } while(0)
136c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
137c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#ifdef CONFIG_PPC_HAS_HASH_64K
138c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define pte_pagesize_index(mm, addr, pte)	get_slice_psize(mm, addr)
139c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#else
140c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#define pte_pagesize_index(mm, addr, pte)	MMU_PAGE_4K
141c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#endif
142c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
143c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt#endif /* __real_pte */
144c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
145c605782b1c3f1c18a55dc1a75b19ed0288f61ac3Benjamin Herrenschmidt
146f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/* pte_clear moved to later in this file */
147f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
148f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define PMD_BAD_BITS		(PTE_TABLE_SIZE-1)
149f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define PUD_BAD_BITS		(PMD_TABLE_SIZE-1)
150f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
151f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pmd_set(pmdp, pmdval) 	(pmd_val(*(pmdp)) = (pmdval))
152f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pmd_none(pmd)		(!pmd_val(pmd))
153f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define	pmd_bad(pmd)		(!is_kernel_addr(pmd_val(pmd)) \
154f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				 || (pmd_val(pmd) & PMD_BAD_BITS))
155f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define	pmd_present(pmd)	(pmd_val(pmd) != 0)
156f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define	pmd_clear(pmdp)		(pmd_val(*(pmdp)) = 0)
157f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pmd_page_vaddr(pmd)	(pmd_val(pmd) & ~PMD_MASKED_BITS)
158074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern struct page *pmd_page(pmd_t pmd);
159f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
160f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pud_set(pudp, pudval)	(pud_val(*(pudp)) = (pudval))
161f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pud_none(pud)		(!pud_val(pud))
162f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define	pud_bad(pud)		(!is_kernel_addr(pud_val(pud)) \
163f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				 || (pud_val(pud) & PUD_BAD_BITS))
164f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pud_present(pud)	(pud_val(pud) != 0)
165f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pud_clear(pudp)		(pud_val(*(pudp)) = 0)
166f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pud_page_vaddr(pud)	(pud_val(pud) & ~PUD_MASKED_BITS)
167f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pud_page(pud)		virt_to_page(pud_page_vaddr(pud))
168f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
169f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pgd_set(pgdp, pudp)	({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
170f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
171f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
172f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * Find an entry in a page-table-directory.  We combine the address region
173f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * (the high order N bits) and the pgd portion of the address.
174f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
1750e5f35d0e4a8179cdfac115023f418126419e659Aneesh Kumar K.V#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
176f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
177f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pgd_offset(mm, address)	 ((mm)->pgd + pgd_index(address))
178f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
179f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pmd_offset(pudp,addr) \
180f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson  (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
181f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
182f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pte_offset_kernel(dir,addr) \
183f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson  (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
184f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
185f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pte_offset_map(dir,addr)	pte_offset_kernel((dir), (addr))
186f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pte_unmap(pte)			do { } while(0)
187f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
188f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/* to find an entry in a kernel page-table-directory */
189f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/* This now only contains the vmalloc pages */
190f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pgd_offset_k(address) pgd_offset(&init_mm, address)
19178f1dbde9fd020419313c2a0c3b602ea2427118fAneesh Kumar K.Vextern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
19278f1dbde9fd020419313c2a0c3b602ea2427118fAneesh Kumar K.V			    pte_t *ptep, unsigned long pte, int huge);
193f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
194f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/* Atomic PTE updates */
195f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibsonstatic inline unsigned long pte_update(struct mm_struct *mm,
196f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				       unsigned long addr,
197f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				       pte_t *ptep, unsigned long clr,
19888247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V				       unsigned long set,
199f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				       int huge)
200f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson{
201a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt#ifdef PTE_ATOMIC_UPDATES
202f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	unsigned long old, tmp;
203f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
204f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	__asm__ __volatile__(
205f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	"1:	ldarx	%0,0,%3		# pte_update\n\
206f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	andi.	%1,%0,%6\n\
207f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	bne-	1b \n\
208f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	andc	%1,%0,%4 \n\
20988247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	or	%1,%1,%7\n\
210f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	stdcx.	%1,0,%3 \n\
211f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	bne-	1b"
212f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	: "=&r" (old), "=&r" (tmp), "=m" (*ptep)
21388247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	: "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY), "r" (set)
214f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	: "cc" );
215a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt#else
216a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt	unsigned long old = pte_val(*ptep);
21788247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	*ptep = __pte((old & ~clr) | set);
218a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt#endif
2198d30c14cab30d405a05f2aaceda1e9ad57800f36Benjamin Herrenschmidt	/* huge pages use the old page table lock */
2208d30c14cab30d405a05f2aaceda1e9ad57800f36Benjamin Herrenschmidt	if (!huge)
2218d30c14cab30d405a05f2aaceda1e9ad57800f36Benjamin Herrenschmidt		assert_pte_locked(mm, addr);
2228d30c14cab30d405a05f2aaceda1e9ad57800f36Benjamin Herrenschmidt
223944916858a430a0627e483657d4cfa2cd2dfb4f7Benjamin Herrenschmidt#ifdef CONFIG_PPC_STD_MMU_64
224f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	if (old & _PAGE_HASHPTE)
225f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		hpte_need_flush(mm, addr, ptep, old, huge);
226944916858a430a0627e483657d4cfa2cd2dfb4f7Benjamin Herrenschmidt#endif
227944916858a430a0627e483657d4cfa2cd2dfb4f7Benjamin Herrenschmidt
228f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	return old;
229f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson}
230f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
231f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibsonstatic inline int __ptep_test_and_clear_young(struct mm_struct *mm,
232f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson					      unsigned long addr, pte_t *ptep)
233f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson{
234f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	unsigned long old;
235f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
23688247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
237f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		return 0;
23888247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
239f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	return (old & _PAGE_ACCESSED) != 0;
240f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson}
241f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
242f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define ptep_test_and_clear_young(__vma, __addr, __ptep)		   \
243f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson({									   \
244f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	int __r;							   \
245f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	__r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
246f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	__r;								   \
247f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson})
248f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
249f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __HAVE_ARCH_PTEP_SET_WRPROTECT
250f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibsonstatic inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
251f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				      pte_t *ptep)
252f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson{
253f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
2542a2c29c1a581319f4485af55e8d628d89e8f2583Stratos Psomadakis	if ((pte_val(*ptep) & _PAGE_RW) == 0)
2552a2c29c1a581319f4485af55e8d628d89e8f2583Stratos Psomadakis		return;
2562a2c29c1a581319f4485af55e8d628d89e8f2583Stratos Psomadakis
25788247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
258f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson}
259f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
260016b33c4958681c24056abed8ec95844a0da80a3Andy Whitcroftstatic inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
261016b33c4958681c24056abed8ec95844a0da80a3Andy Whitcroft					   unsigned long addr, pte_t *ptep)
262016b33c4958681c24056abed8ec95844a0da80a3Andy Whitcroft{
26386df86424939d316b1f6cfac1b6204f0c7dee317David Gibson	if ((pte_val(*ptep) & _PAGE_RW) == 0)
26486df86424939d316b1f6cfac1b6204f0c7dee317David Gibson		return;
2652a2c29c1a581319f4485af55e8d628d89e8f2583Stratos Psomadakis
26688247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	pte_update(mm, addr, ptep, _PAGE_RW, 0, 1);
267016b33c4958681c24056abed8ec95844a0da80a3Andy Whitcroft}
268f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
269f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/*
270f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * We currently remove entries from the hashtable regardless of whether
271f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * the entry was young or dirty. The generic routines only flush if the
272f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * entry was young or dirty which is not good enough.
273f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson *
274f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * We should be more intelligent about this but for the moment we override
275f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * these functions and force a tlb flush unconditionally
276f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
277f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
278f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define ptep_clear_flush_young(__vma, __address, __ptep)		\
279f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson({									\
280f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
281f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson						  __ptep);		\
282f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	__young;							\
283f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson})
284f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
285f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
286f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibsonstatic inline pte_t ptep_get_and_clear(struct mm_struct *mm,
287f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson				       unsigned long addr, pte_t *ptep)
288f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson{
28988247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0, 0);
290f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	return __pte(old);
291f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson}
292f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
293f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibsonstatic inline void pte_clear(struct mm_struct *mm, unsigned long addr,
294f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson			     pte_t * ptep)
295f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson{
29688247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	pte_update(mm, addr, ptep, ~0UL, 0, 0);
297f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson}
298f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
299f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
300f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/* Set the dirty and/or accessed bits atomically in a linux PTE, this
301f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson * function doesn't need to flush the hash entry
302f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson */
3038d30c14cab30d405a05f2aaceda1e9ad57800f36Benjamin Herrenschmidtstatic inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
304f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson{
305f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	unsigned long bits = pte_val(entry) &
306ea3cc330ac0cd521ff07c7cd432a1848c19a7e92Benjamin Herrenschmidt		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
307a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt
308a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt#ifdef PTE_ATOMIC_UPDATES
309f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	unsigned long old, tmp;
310f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
311f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	__asm__ __volatile__(
312f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	"1:	ldarx	%0,0,%4\n\
313f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		andi.	%1,%0,%6\n\
314f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		bne-	1b \n\
315f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		or	%0,%3,%0\n\
316f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		stdcx.	%0,0,%4\n\
317f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson		bne-	1b"
318f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	:"=&r" (old), "=&r" (tmp), "=m" (*ptep)
319f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	:"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
320f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson	:"cc");
321a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt#else
322a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt	unsigned long old = pte_val(*ptep);
323a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt	*ptep = __pte(old | bits);
324a033a487f8ae79800a15774cb6565cbbca685fc6Benjamin Herrenschmidt#endif
325f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson}
326f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
327f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __HAVE_ARCH_PTE_SAME
328f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
329f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
330f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pte_ERROR(e) \
331a7696b36c01316308f2b9f2009ce38cb01fd7a3fAnton Blanchard	pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
332f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pmd_ERROR(e) \
333a7696b36c01316308f2b9f2009ce38cb01fd7a3fAnton Blanchard	pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
334f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pgd_ERROR(e) \
335a7696b36c01316308f2b9f2009ce38cb01fd7a3fAnton Blanchard	pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
336f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
337f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson/* Encode and de-code a swap entry */
338f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __swp_type(entry)	(((entry).val >> 1) & 0x3f)
339f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __swp_offset(entry)	((entry).val >> 8)
340f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
341f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __pte_to_swp_entry(pte)	((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
342f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define __swp_entry_to_pte(x)	((pte_t) { (x).val << PTE_RPN_SHIFT })
343f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pte_to_pgoff(pte)	(pte_val(pte) >> PTE_RPN_SHIFT)
344f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define pgoff_to_pte(off)	((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
345f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#define PTE_FILE_MAX_BITS	(BITS_PER_LONG - PTE_RPN_SHIFT)
346f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
347a0668cdc154e54bf0c85182e0535eea237d53146David Gibsonvoid pgtable_cache_add(unsigned shift, void (*ctor)(void *));
348f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibsonvoid pgtable_cache_init(void);
349f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#endif /* __ASSEMBLY__ */
350f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson
351074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V/*
352074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * THP pages can't be special. So use the _PAGE_SPECIAL
353074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V */
354074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define _PAGE_SPLITTING _PAGE_SPECIAL
355074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
356074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V/*
357074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * We need to differentiate between explicit huge page and THP huge
358074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * page, since THP huge page also need to track real subpage details
359074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V */
360074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define _PAGE_THP_HUGE  _PAGE_4K_PFN
361074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
362074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V/*
363074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * set of bits not changed in pmd_modify.
364074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V */
365074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS |		\
366074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V			 _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \
367074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V			 _PAGE_THP_HUGE)
368074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
369074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#ifndef __ASSEMBLY__
370074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V/*
371074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * The linux hugepage PMD now include the pmd entries followed by the address
372074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits.
373074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per
374074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and
375074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t.
376074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V *
377074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * The last three bits are intentionally left to zero. This memory location
378074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * are also used as normal page PTE pointers. So if we have any pointers
379074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * left around while we collapse a hugepage, we need to make sure
380074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V * _PAGE_PRESENT and _PAGE_FILE bits of that are zero when we look at them
381074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V */
382074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
383074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
384074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return (hpte_slot_array[index] >> 3) & 0x1;
385074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
386074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
387074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array,
388074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V					   int index)
389074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
390074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return hpte_slot_array[index] >> 4;
391074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
392074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
393074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
394074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V					unsigned int index, unsigned int hidx)
395074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
396074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	hpte_slot_array[index] = hidx << 4 | 0x1 << 3;
397074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
398074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
3998e0861fa3c4edfc2f30dd4cf4d58d3929f7c1b23Alexey Kardashevskiystruct page *realmode_pfn_to_page(unsigned long pfn);
4008e0861fa3c4edfc2f30dd4cf4d58d3929f7c1b23Alexey Kardashevskiy
401074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline char *get_hpte_slot_array(pmd_t *pmdp)
402074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
403074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	/*
404074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 * The hpte hindex is stored in the pgtable whose address is in the
405074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 * second half of the PMD
406074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 *
407074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 * Order this load with the test for pmd_trans_huge in the caller
408074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 */
409074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	smp_rmb();
410074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return *(char **)(pmdp + PTRS_PER_PMD);
411074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
412074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
413074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
414074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
415074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
416fc0479557572375100ef16c71170b29a98e0d69aAneesh Kumar K.V				   pmd_t *pmdp, unsigned long old_pmd);
417074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#ifdef CONFIG_TRANSPARENT_HUGEPAGE
418074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot);
419074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
420074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
421074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
422074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V		       pmd_t *pmdp, pmd_t pmd);
423074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
424074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				 pmd_t *pmd);
425074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
426074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline int pmd_trans_huge(pmd_t pmd)
427074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
428074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	/*
429074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 * leaf pte for huge page, bottom two bits != 00
430074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 */
431074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE);
432074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
433074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
434074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline int pmd_large(pmd_t pmd)
435074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
436074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	/*
437074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 * leaf pte for huge page, bottom two bits != 00
438074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	 */
439074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	if (pmd_trans_huge(pmd))
440074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V		return pmd_val(pmd) & _PAGE_PRESENT;
441074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return 0;
442074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
443074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
444074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline int pmd_trans_splitting(pmd_t pmd)
445074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
446074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	if (pmd_trans_huge(pmd))
447074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V		return pmd_val(pmd) & _PAGE_SPLITTING;
448074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return 0;
449074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
450074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
451437d496457a30ce9ccccb94b2373c201b2558392Aneesh Kumar K.Vextern int has_transparent_hugepage(void);
452074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
453074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
454074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline pte_t pmd_pte(pmd_t pmd)
455074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
456074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return __pte(pmd_val(pmd));
457074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
458074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
459074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline pmd_t pte_pmd(pte_t pte)
460074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
461074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return __pmd(pte_val(pte));
462074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
463074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
464074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline pte_t *pmdp_ptep(pmd_t *pmd)
465074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
466074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return (pte_t *)pmd;
467074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
468074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
469074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_pfn(pmd)		pte_pfn(pmd_pte(pmd))
470074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_young(pmd)		pte_young(pmd_pte(pmd))
471074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_mkold(pmd)		pte_pmd(pte_mkold(pmd_pte(pmd)))
472074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_wrprotect(pmd)	pte_pmd(pte_wrprotect(pmd_pte(pmd)))
473074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_mkdirty(pmd)	pte_pmd(pte_mkdirty(pmd_pte(pmd)))
474074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_mkyoung(pmd)	pte_pmd(pte_mkyoung(pmd_pte(pmd)))
475074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_mkwrite(pmd)	pte_pmd(pte_mkwrite(pmd_pte(pmd)))
476074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
477074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMD_WRITE
478074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define pmd_write(pmd)		pte_write(pmd_pte(pmd))
479074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
480074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline pmd_t pmd_mkhuge(pmd_t pmd)
481074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
482074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	/* Do nothing, mk_pmd() does this part.  */
483074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return pmd;
484074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
485074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
486074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline pmd_t pmd_mknotpresent(pmd_t pmd)
487074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
488074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	pmd_val(pmd) &= ~_PAGE_PRESENT;
489074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return pmd;
490074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
491074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
492074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline pmd_t pmd_mksplitting(pmd_t pmd)
493074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
494074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	pmd_val(pmd) |= _PAGE_SPLITTING;
495074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return pmd;
496074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
497074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
498074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMD_SAME
499074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
500074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
501074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0);
502074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
503074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
504074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
505074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern int pmdp_set_access_flags(struct vm_area_struct *vma,
506074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				 unsigned long address, pmd_t *pmdp,
507074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				 pmd_t entry, int dirty);
508074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
509074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern unsigned long pmd_hugepage_update(struct mm_struct *mm,
510074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V					 unsigned long addr,
51188247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V					 pmd_t *pmdp,
51288247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V					 unsigned long clr,
51388247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V					 unsigned long set);
514074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
515074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
516074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V					      unsigned long addr, pmd_t *pmdp)
517074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
518074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	unsigned long old;
519074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
520074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
521074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V		return 0;
52288247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED, 0);
523074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	return ((old & _PAGE_ACCESSED) != 0);
524074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
525074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
526074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
527074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern int pmdp_test_and_clear_young(struct vm_area_struct *vma,
528074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				     unsigned long address, pmd_t *pmdp);
529074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
530074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern int pmdp_clear_flush_young(struct vm_area_struct *vma,
531074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				  unsigned long address, pmd_t *pmdp);
532074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
533074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
534074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern pmd_t pmdp_get_and_clear(struct mm_struct *mm,
535074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				unsigned long addr, pmd_t *pmdp);
536074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
537074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_CLEAR_FLUSH
538074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern pmd_t pmdp_clear_flush(struct vm_area_struct *vma, unsigned long address,
539074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V			      pmd_t *pmdp);
540074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
541074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_SET_WRPROTECT
542074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vstatic inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
543074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				      pmd_t *pmdp)
544074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V{
545074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
546074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V	if ((pmd_val(*pmdp) & _PAGE_RW) == 0)
547074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V		return;
548074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
54988247e8d7ba6639f2c199e147ebbc91f7673150cAneesh Kumar K.V	pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW, 0);
550074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V}
551074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
552074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
553074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern void pmdp_splitting_flush(struct vm_area_struct *vma,
554074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				 unsigned long address, pmd_t *pmdp);
555074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
556074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PGTABLE_DEPOSIT
557074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
558074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V				       pgtable_t pgtable);
559074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PGTABLE_WITHDRAW
560074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
561074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V
562074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#define __HAVE_ARCH_PMDP_INVALIDATE
563074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.Vextern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
564074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V			    pmd_t *pmdp);
565b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V
566b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V#define pmd_move_must_withdraw pmd_move_must_withdraw
567fd120dc2e205d2318a8b47d6d8098b789e3af67dLi Zhongstruct spinlock;
568fd120dc2e205d2318a8b47d6d8098b789e3af67dLi Zhongstatic inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
569fd120dc2e205d2318a8b47d6d8098b789e3af67dLi Zhong					 struct spinlock *old_pmd_ptl)
570b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V{
571b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V	/*
572b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V	 * Archs like ppc64 use pgtable to store per pmd
573b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V	 * specific information. So when we switch the pmd,
574b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V	 * we should also withdraw and deposit the pgtable
575b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V	 */
576b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V	return true;
577b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V}
578b3084f4db3aeb991c507ca774337c7e7893ed04fAneesh Kumar K.V
579074c2eae3e9b66c03a17a12df8f2cd19382b68abAneesh Kumar K.V#endif /* __ASSEMBLY__ */
580f88df14b1f15cdeffa060580a40c1ce3e13bb79eDavid Gibson#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
581