diff options
Diffstat (limited to 'arch/x86/include/asm/pgtable.h')
| -rw-r--r-- | arch/x86/include/asm/pgtable.h | 44 | 
1 files changed, 35 insertions, 9 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index a34430b7af4a..62ab07e24aef 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -15,18 +15,14 @@  		     cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)))	\  	 : (prot)) -/* - * Macros to add or remove encryption attribute - */ -#define pgprot_encrypted(prot)	__pgprot(__sme_set(pgprot_val(prot))) -#define pgprot_decrypted(prot)	__pgprot(__sme_clr(pgprot_val(prot))) -  #ifndef __ASSEMBLY__  #include <linux/spinlock.h>  #include <asm/x86_init.h>  #include <asm/pkru.h>  #include <asm/fpu/api.h> +#include <asm/coco.h>  #include <asm-generic/pgtable_uffd.h> +#include <linux/page_table_check.h>  extern pgd_t early_top_pgt[PTRS_PER_PGD];  bool __init __early_make_pgtable(unsigned long address, pmdval_t pmd); @@ -37,6 +33,12 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,  void ptdump_walk_pgd_level_checkwx(void);  void ptdump_walk_user_pgd_level_checkwx(void); +/* + * Macros to add or remove encryption attribute + */ +#define pgprot_encrypted(prot)	__pgprot(cc_mkenc(pgprot_val(prot))) +#define pgprot_decrypted(prot)	__pgprot(cc_mkdec(pgprot_val(prot))) +  #ifdef CONFIG_DEBUG_WX  #define debug_checkwx()		ptdump_walk_pgd_level_checkwx()  #define debug_checkwx_user()	ptdump_walk_user_pgd_level_checkwx() @@ -753,7 +755,7 @@ static inline bool pte_accessible(struct mm_struct *mm, pte_t a)  		return true;  	if ((pte_flags(a) & _PAGE_PROTNONE) && -			mm_tlb_flush_pending(mm)) +			atomic_read(&mm->tlb_flush_pending))  		return true;  	return false; @@ -1007,18 +1009,21 @@ static inline pud_t native_local_pudp_get_and_clear(pud_t *pudp)  static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,  			      pte_t *ptep, pte_t pte)  { +	page_table_check_pte_set(mm, addr, ptep, pte);  	set_pte(ptep, pte);  }  static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,  			      pmd_t *pmdp, pmd_t pmd)  { +	page_table_check_pmd_set(mm, addr, pmdp, pmd);  	set_pmd(pmdp, pmd);  }  static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,  			      pud_t *pudp, pud_t pud)  { +	page_table_check_pud_set(mm, addr, pudp, pud);  	native_set_pud(pudp, pud);  } @@ -1049,6 +1054,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,  				       pte_t *ptep)  {  	pte_t pte = native_ptep_get_and_clear(ptep); +	page_table_check_pte_clear(mm, addr, pte);  	return pte;  } @@ -1064,12 +1070,23 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,  		 * care about updates and native needs no locking  		 */  		pte = native_local_ptep_get_and_clear(ptep); +		page_table_check_pte_clear(mm, addr, pte);  	} else {  		pte = ptep_get_and_clear(mm, addr, ptep);  	}  	return pte;  } +#define __HAVE_ARCH_PTEP_CLEAR +static inline void ptep_clear(struct mm_struct *mm, unsigned long addr, +			      pte_t *ptep) +{ +	if (IS_ENABLED(CONFIG_PAGE_TABLE_CHECK)) +		ptep_get_and_clear(mm, addr, ptep); +	else +		pte_clear(mm, addr, ptep); +} +  #define __HAVE_ARCH_PTEP_SET_WRPROTECT  static inline void ptep_set_wrprotect(struct mm_struct *mm,  				      unsigned long addr, pte_t *ptep) @@ -1110,14 +1127,22 @@ static inline int pmd_write(pmd_t pmd)  static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr,  				       pmd_t *pmdp)  { -	return native_pmdp_get_and_clear(pmdp); +	pmd_t pmd = native_pmdp_get_and_clear(pmdp); + +	page_table_check_pmd_clear(mm, addr, pmd); + +	return pmd;  }  #define __HAVE_ARCH_PUDP_HUGE_GET_AND_CLEAR  static inline pud_t pudp_huge_get_and_clear(struct mm_struct *mm,  					unsigned long addr, pud_t *pudp)  { -	return native_pudp_get_and_clear(pudp); +	pud_t pud = native_pudp_get_and_clear(pudp); + +	page_table_check_pud_clear(mm, addr, pud); + +	return pud;  }  #define __HAVE_ARCH_PMDP_SET_WRPROTECT @@ -1138,6 +1163,7 @@ static inline int pud_write(pud_t pud)  static inline pmd_t pmdp_establish(struct vm_area_struct *vma,  		unsigned long address, pmd_t *pmdp, pmd_t pmd)  { +	page_table_check_pmd_set(vma->vm_mm, address, pmdp, pmd);  	if (IS_ENABLED(CONFIG_SMP)) {  		return xchg(pmdp, pmd);  	} else {  |