diff options
Diffstat (limited to 'arch/s390/include/asm/pgtable.h')
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 105 | 
1 files changed, 49 insertions, 56 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 4a2930844d4..b4622915bd1 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -57,6 +57,10 @@ extern unsigned long zero_page_mask;  	 (((unsigned long)(vaddr)) &zero_page_mask))))  #define __HAVE_COLOR_ZERO_PAGE +/* TODO: s390 cannot support io_remap_pfn_range... */ +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) 	       \ +	remap_pfn_range(vma, vaddr, pfn, size, prot) +  #endif /* !__ASSEMBLY__ */  /* @@ -344,6 +348,7 @@ extern unsigned long MODULES_END;  #define _REGION3_ENTRY_CO	0x100	/* change-recording override	    */  /* Bits in the segment table entry */ +#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address	    */  #define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL/* segment table origin		    */  #define _SEGMENT_ENTRY_RO	0x200	/* page protection bit		    */  #define _SEGMENT_ENTRY_INV	0x20	/* invalid segment table entry	    */ @@ -419,6 +424,13 @@ extern unsigned long MODULES_END;  #define __S110	PAGE_RW  #define __S111	PAGE_RW +/* + * Segment entry (large page) protection definitions. + */ +#define SEGMENT_NONE	__pgprot(_HPAGE_TYPE_NONE) +#define SEGMENT_RO	__pgprot(_HPAGE_TYPE_RO) +#define SEGMENT_RW	__pgprot(_HPAGE_TYPE_RW) +  static inline int mm_exclusive(struct mm_struct *mm)  {  	return likely(mm == current->active_mm && @@ -759,6 +771,8 @@ void gmap_disable(struct gmap *gmap);  int gmap_map_segment(struct gmap *gmap, unsigned long from,  		     unsigned long to, unsigned long length);  int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len); +unsigned long __gmap_translate(unsigned long address, struct gmap *); +unsigned long gmap_translate(unsigned long address, struct gmap *);  unsigned long __gmap_fault(unsigned long address, struct gmap *);  unsigned long gmap_fault(unsigned long address, struct gmap *);  void gmap_discard(unsigned long from, unsigned long to, struct gmap *); @@ -907,26 +921,6 @@ static inline pte_t pte_mkspecial(pte_t pte)  #ifdef CONFIG_HUGETLB_PAGE  static inline pte_t pte_mkhuge(pte_t pte)  { -	/* -	 * PROT_NONE needs to be remapped from the pte type to the ste type. -	 * The HW invalid bit is also different for pte and ste. The pte -	 * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE -	 * bit, so we don't have to clear it. -	 */ -	if (pte_val(pte) & _PAGE_INVALID) { -		if (pte_val(pte) & _PAGE_SWT) -			pte_val(pte) |= _HPAGE_TYPE_NONE; -		pte_val(pte) |= _SEGMENT_ENTRY_INV; -	} -	/* -	 * Clear SW pte bits, there are no SW bits in a segment table entry. -	 */ -	pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX | _PAGE_SWC | -			  _PAGE_SWR | _PAGE_SWW); -	/* -	 * Also set the change-override bit because we don't need dirty bit -	 * tracking for hugetlbfs pages. -	 */  	pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO);  	return pte;  } @@ -1271,31 +1265,7 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)  	}  } -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - -#define SEGMENT_NONE	__pgprot(_HPAGE_TYPE_NONE) -#define SEGMENT_RO	__pgprot(_HPAGE_TYPE_RO) -#define SEGMENT_RW	__pgprot(_HPAGE_TYPE_RW) - -#define __HAVE_ARCH_PGTABLE_DEPOSIT -extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); - -#define __HAVE_ARCH_PGTABLE_WITHDRAW -extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); - -static inline int pmd_trans_splitting(pmd_t pmd) -{ -	return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; -} - -static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, -			      pmd_t *pmdp, pmd_t entry) -{ -	if (!(pmd_val(entry) & _SEGMENT_ENTRY_INV) && MACHINE_HAS_EDAT1) -		pmd_val(entry) |= _SEGMENT_ENTRY_CO; -	*pmdp = entry; -} - +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)  static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)  {  	/* @@ -1316,10 +1286,11 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)  	return pmd;  } -static inline pmd_t pmd_mkhuge(pmd_t pmd) +static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)  { -	pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; -	return pmd; +	pmd_t __pmd; +	pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); +	return __pmd;  }  static inline pmd_t pmd_mkwrite(pmd_t pmd) @@ -1329,6 +1300,34 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd)  		pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;  	return pmd;  } +#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + +#define __HAVE_ARCH_PGTABLE_DEPOSIT +extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); + +#define __HAVE_ARCH_PGTABLE_WITHDRAW +extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); + +static inline int pmd_trans_splitting(pmd_t pmd) +{ +	return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; +} + +static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, +			      pmd_t *pmdp, pmd_t entry) +{ +	if (!(pmd_val(entry) & _SEGMENT_ENTRY_INV) && MACHINE_HAS_EDAT1) +		pmd_val(entry) |= _SEGMENT_ENTRY_CO; +	*pmdp = entry; +} + +static inline pmd_t pmd_mkhuge(pmd_t pmd) +{ +	pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; +	return pmd; +}  static inline pmd_t pmd_wrprotect(pmd_t pmd)  { @@ -1425,13 +1424,6 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,  	}  } -static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot) -{ -	pmd_t __pmd; -	pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); -	return __pmd; -} -  #define pfn_pmd(pfn, pgprot)	mk_pmd_phys(__pa((pfn) << PAGE_SHIFT), (pgprot))  #define mk_pmd(page, pgprot)	pfn_pmd(page_to_pfn(page), (pgprot)) @@ -1531,7 +1523,8 @@ extern int s390_enable_sie(void);  /*   * No page table caches to initialise   */ -#define pgtable_cache_init()	do { } while (0) +static inline void pgtable_cache_init(void) { } +static inline void check_pgt_cache(void) { }  #include <asm-generic/pgtable.h>  |