diff options
Diffstat (limited to 'arch/x86/include/asm/pgtable-2level.h')
| -rw-r--r-- | arch/x86/include/asm/pgtable-2level.h | 101 | 
1 files changed, 30 insertions, 71 deletions
diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index 3bf2dd0cf61..206a87fdd22 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h @@ -55,49 +55,12 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)  #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)  #endif -#ifdef CONFIG_MEM_SOFT_DIRTY - -/* - * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE, _PAGE_BIT_SOFT_DIRTY and - * _PAGE_BIT_PROTNONE are taken, split up the 28 bits of offset - * into this range. - */ -#define PTE_FILE_MAX_BITS	28 -#define PTE_FILE_SHIFT1		(_PAGE_BIT_PRESENT + 1) -#define PTE_FILE_SHIFT2		(_PAGE_BIT_FILE + 1) -#define PTE_FILE_SHIFT3		(_PAGE_BIT_PROTNONE + 1) -#define PTE_FILE_SHIFT4		(_PAGE_BIT_SOFT_DIRTY + 1) -#define PTE_FILE_BITS1		(PTE_FILE_SHIFT2 - PTE_FILE_SHIFT1 - 1) -#define PTE_FILE_BITS2		(PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1) -#define PTE_FILE_BITS3		(PTE_FILE_SHIFT4 - PTE_FILE_SHIFT3 - 1) - -#define pte_to_pgoff(pte)						\ -	((((pte).pte_low >> (PTE_FILE_SHIFT1))				\ -	  & ((1U << PTE_FILE_BITS1) - 1)))				\ -	+ ((((pte).pte_low >> (PTE_FILE_SHIFT2))			\ -	    & ((1U << PTE_FILE_BITS2) - 1))				\ -	   << (PTE_FILE_BITS1))						\ -	+ ((((pte).pte_low >> (PTE_FILE_SHIFT3))			\ -	    & ((1U << PTE_FILE_BITS3) - 1))				\ -	   << (PTE_FILE_BITS1 + PTE_FILE_BITS2))			\ -	+ ((((pte).pte_low >> (PTE_FILE_SHIFT4)))			\ -	    << (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)) - -#define pgoff_to_pte(off)						\ -	((pte_t) { .pte_low =						\ -	 ((((off)) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)	\ -	 + ((((off) >> PTE_FILE_BITS1)					\ -	     & ((1U << PTE_FILE_BITS2) - 1))				\ -	    << PTE_FILE_SHIFT2)						\ -	 + ((((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))		\ -	     & ((1U << PTE_FILE_BITS3) - 1))				\ -	    << PTE_FILE_SHIFT3)						\ -	 + ((((off) >>							\ -	      (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)))	\ -	    << PTE_FILE_SHIFT4)						\ -	 + _PAGE_FILE }) - -#else /* CONFIG_MEM_SOFT_DIRTY */ +/* Bit manipulation helper on pte/pgoff entry */ +static inline unsigned long pte_bitop(unsigned long value, unsigned int rightshift, +				      unsigned long mask, unsigned int leftshift) +{ +	return ((value >> rightshift) & mask) << leftshift; +}  /*   * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken, @@ -105,43 +68,39 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)   */  #define PTE_FILE_MAX_BITS	29  #define PTE_FILE_SHIFT1		(_PAGE_BIT_PRESENT + 1) -#if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE  #define PTE_FILE_SHIFT2		(_PAGE_BIT_FILE + 1)  #define PTE_FILE_SHIFT3		(_PAGE_BIT_PROTNONE + 1) -#else -#define PTE_FILE_SHIFT2		(_PAGE_BIT_PROTNONE + 1) -#define PTE_FILE_SHIFT3		(_PAGE_BIT_FILE + 1) -#endif  #define PTE_FILE_BITS1		(PTE_FILE_SHIFT2 - PTE_FILE_SHIFT1 - 1)  #define PTE_FILE_BITS2		(PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1) -#define pte_to_pgoff(pte)						\ -	((((pte).pte_low >> PTE_FILE_SHIFT1)				\ -	  & ((1U << PTE_FILE_BITS1) - 1))				\ -	 + ((((pte).pte_low >> PTE_FILE_SHIFT2)				\ -	     & ((1U << PTE_FILE_BITS2) - 1)) << PTE_FILE_BITS1)		\ -	 + (((pte).pte_low >> PTE_FILE_SHIFT3)				\ -	    << (PTE_FILE_BITS1 + PTE_FILE_BITS2))) - -#define pgoff_to_pte(off)						\ -	((pte_t) { .pte_low =						\ -	 (((off) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)	\ -	 + ((((off) >> PTE_FILE_BITS1) & ((1U << PTE_FILE_BITS2) - 1))	\ -	    << PTE_FILE_SHIFT2)						\ -	 + (((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))		\ -	    << PTE_FILE_SHIFT3)						\ -	 + _PAGE_FILE }) - -#endif /* CONFIG_MEM_SOFT_DIRTY */ +#define PTE_FILE_MASK1		((1U << PTE_FILE_BITS1) - 1) +#define PTE_FILE_MASK2		((1U << PTE_FILE_BITS2) - 1) + +#define PTE_FILE_LSHIFT2	(PTE_FILE_BITS1) +#define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2) + +static __always_inline pgoff_t pte_to_pgoff(pte_t pte) +{ +	return (pgoff_t) +		(pte_bitop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)		    + +		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) + +		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT3,           -1UL,  PTE_FILE_LSHIFT3)); +} + +static __always_inline pte_t pgoff_to_pte(pgoff_t off) +{ +	return (pte_t){ +		.pte_low = +			pte_bitop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) + +			pte_bitop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) + +			pte_bitop(off, PTE_FILE_LSHIFT3,           -1UL,  PTE_FILE_SHIFT3) + +			_PAGE_FILE, +	}; +}  /* Encode and de-code a swap entry */ -#if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE  #define SWP_TYPE_BITS (_PAGE_BIT_FILE - _PAGE_BIT_PRESENT - 1)  #define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1) -#else -#define SWP_TYPE_BITS (_PAGE_BIT_PROTNONE - _PAGE_BIT_PRESENT - 1) -#define SWP_OFFSET_SHIFT (_PAGE_BIT_FILE + 1) -#endif  #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)  | 
