forked from mirrors/linux
		
	mm: add default definition of set_ptes()
Most architectures can just define set_pte() and PFN_PTE_SHIFT to use this definition. It's also a handy spot to document the guarantees provided by the MM. Link: https://lkml.kernel.org/r/20230802151406.3735276-7-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Suggested-by: Mike Rapoport (IBM) <rppt@kernel.org> Reviewed-by: Mike Rapoport (IBM) <rppt@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									29d26f1215
								
							
						
					
					
						commit
						bcc6cc8325
					
				
					 1 changed files with 60 additions and 21 deletions
				
			
		|  | @ -182,6 +182,66 @@ static inline int pmd_young(pmd_t pmd) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * A facility to provide lazy MMU batching.  This allows PTE updates and | ||||||
|  |  * page invalidations to be delayed until a call to leave lazy MMU mode | ||||||
|  |  * is issued.  Some architectures may benefit from doing this, and it is | ||||||
|  |  * beneficial for both shadow and direct mode hypervisors, which may batch | ||||||
|  |  * the PTE updates which happen during this window.  Note that using this | ||||||
|  |  * interface requires that read hazards be removed from the code.  A read | ||||||
|  |  * hazard could result in the direct mode hypervisor case, since the actual | ||||||
|  |  * write to the page tables may not yet have taken place, so reads though | ||||||
|  |  * a raw PTE pointer after it has been modified are not guaranteed to be | ||||||
|  |  * up to date.  This mode can only be entered and left under the protection of | ||||||
|  |  * the page table locks for all page tables which may be modified.  In the UP | ||||||
|  |  * case, this is required so that preemption is disabled, and in the SMP case, | ||||||
|  |  * it must synchronize the delayed page table writes properly on other CPUs. | ||||||
|  |  */ | ||||||
|  | #ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE | ||||||
|  | #define arch_enter_lazy_mmu_mode()	do {} while (0) | ||||||
|  | #define arch_leave_lazy_mmu_mode()	do {} while (0) | ||||||
|  | #define arch_flush_lazy_mmu_mode()	do {} while (0) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef set_ptes | ||||||
|  | #ifdef PFN_PTE_SHIFT | ||||||
|  | /**
 | ||||||
|  |  * set_ptes - Map consecutive pages to a contiguous range of addresses. | ||||||
|  |  * @mm: Address space to map the pages into. | ||||||
|  |  * @addr: Address to map the first page at. | ||||||
|  |  * @ptep: Page table pointer for the first entry. | ||||||
|  |  * @pte: Page table entry for the first page. | ||||||
|  |  * @nr: Number of pages to map. | ||||||
|  |  * | ||||||
|  |  * May be overridden by the architecture, or the architecture can define | ||||||
|  |  * set_pte() and PFN_PTE_SHIFT. | ||||||
|  |  * | ||||||
|  |  * Context: The caller holds the page table lock.  The pages all belong | ||||||
|  |  * to the same folio.  The PTEs are all in the same PMD. | ||||||
|  |  */ | ||||||
|  | static inline void set_ptes(struct mm_struct *mm, unsigned long addr, | ||||||
|  | 		pte_t *ptep, pte_t pte, unsigned int nr) | ||||||
|  | { | ||||||
|  | 	page_table_check_ptes_set(mm, ptep, pte, nr); | ||||||
|  | 
 | ||||||
|  | 	arch_enter_lazy_mmu_mode(); | ||||||
|  | 	for (;;) { | ||||||
|  | 		set_pte(ptep, pte); | ||||||
|  | 		if (--nr == 0) | ||||||
|  | 			break; | ||||||
|  | 		ptep++; | ||||||
|  | 		pte = __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT)); | ||||||
|  | 	} | ||||||
|  | 	arch_leave_lazy_mmu_mode(); | ||||||
|  | } | ||||||
|  | #ifndef set_pte_at | ||||||
|  | #define set_pte_at(mm, addr, ptep, pte) set_ptes(mm, addr, ptep, pte, 1) | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | #else | ||||||
|  | #define set_pte_at(mm, addr, ptep, pte) set_ptes(mm, addr, ptep, pte, 1) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS | #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS | ||||||
| extern int ptep_set_access_flags(struct vm_area_struct *vma, | extern int ptep_set_access_flags(struct vm_area_struct *vma, | ||||||
| 				 unsigned long address, pte_t *ptep, | 				 unsigned long address, pte_t *ptep, | ||||||
|  | @ -1051,27 +1111,6 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | ||||||
| #define pgprot_decrypted(prot)	(prot) | #define pgprot_decrypted(prot)	(prot) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * A facility to provide lazy MMU batching.  This allows PTE updates and |  | ||||||
|  * page invalidations to be delayed until a call to leave lazy MMU mode |  | ||||||
|  * is issued.  Some architectures may benefit from doing this, and it is |  | ||||||
|  * beneficial for both shadow and direct mode hypervisors, which may batch |  | ||||||
|  * the PTE updates which happen during this window.  Note that using this |  | ||||||
|  * interface requires that read hazards be removed from the code.  A read |  | ||||||
|  * hazard could result in the direct mode hypervisor case, since the actual |  | ||||||
|  * write to the page tables may not yet have taken place, so reads though |  | ||||||
|  * a raw PTE pointer after it has been modified are not guaranteed to be |  | ||||||
|  * up to date.  This mode can only be entered and left under the protection of |  | ||||||
|  * the page table locks for all page tables which may be modified.  In the UP |  | ||||||
|  * case, this is required so that preemption is disabled, and in the SMP case, |  | ||||||
|  * it must synchronize the delayed page table writes properly on other CPUs. |  | ||||||
|  */ |  | ||||||
| #ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE |  | ||||||
| #define arch_enter_lazy_mmu_mode()	do {} while (0) |  | ||||||
| #define arch_leave_lazy_mmu_mode()	do {} while (0) |  | ||||||
| #define arch_flush_lazy_mmu_mode()	do {} while (0) |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * A facility to provide batching of the reload of page tables and |  * A facility to provide batching of the reload of page tables and | ||||||
|  * other process state with the actual context switch code for |  * other process state with the actual context switch code for | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Matthew Wilcox (Oracle)
						Matthew Wilcox (Oracle)