mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	mm: simplify compat_sys_move_pages
The compat move_pages() implementation uses compat_alloc_user_space() for converting the pointer array. Moving the compat handling into the function itself is a bit simpler and lets us avoid the compat_alloc_user_space() call. Link: https://lkml.kernel.org/r/20210727144859.4150043-4-arnd@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Biederman <ebiederm@xmission.com> Cc: Feng Tang <feng.tang@intel.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Helge Deller <deller@gmx.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Paul Mackerras <paulus@samba.org> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									5d700a0fd7
								
							
						
					
					
						commit
						5b1b561ba7
					
				
					 1 changed files with 30 additions and 15 deletions
				
			
		
							
								
								
									
										45
									
								
								mm/migrate.c
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								mm/migrate.c
									
									
									
									
									
								
							|  | @ -1900,6 +1900,23 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, | ||||||
| 	mmap_read_unlock(mm); | 	mmap_read_unlock(mm); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int get_compat_pages_array(const void __user *chunk_pages[], | ||||||
|  | 				  const void __user * __user *pages, | ||||||
|  | 				  unsigned long chunk_nr) | ||||||
|  | { | ||||||
|  | 	compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages; | ||||||
|  | 	compat_uptr_t p; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < chunk_nr; i++) { | ||||||
|  | 		if (get_user(p, pages32 + i)) | ||||||
|  | 			return -EFAULT; | ||||||
|  | 		chunk_pages[i] = compat_ptr(p); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Determine the nodes of a user array of pages and store it in |  * Determine the nodes of a user array of pages and store it in | ||||||
|  * a user array of status. |  * a user array of status. | ||||||
|  | @ -1919,8 +1936,15 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages, | ||||||
| 		if (chunk_nr > DO_PAGES_STAT_CHUNK_NR) | 		if (chunk_nr > DO_PAGES_STAT_CHUNK_NR) | ||||||
| 			chunk_nr = DO_PAGES_STAT_CHUNK_NR; | 			chunk_nr = DO_PAGES_STAT_CHUNK_NR; | ||||||
| 
 | 
 | ||||||
| 		if (copy_from_user(chunk_pages, pages, chunk_nr * sizeof(*chunk_pages))) | 		if (in_compat_syscall()) { | ||||||
| 			break; | 			if (get_compat_pages_array(chunk_pages, pages, | ||||||
|  | 						   chunk_nr)) | ||||||
|  | 				break; | ||||||
|  | 		} else { | ||||||
|  | 			if (copy_from_user(chunk_pages, pages, | ||||||
|  | 				      chunk_nr * sizeof(*chunk_pages))) | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); | 		do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); | ||||||
| 
 | 
 | ||||||
|  | @ -2025,23 +2049,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_COMPAT | #ifdef CONFIG_COMPAT | ||||||
| COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages, | COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages, | ||||||
| 		       compat_uptr_t __user *, pages32, | 		       compat_uptr_t __user *, pages, | ||||||
| 		       const int __user *, nodes, | 		       const int __user *, nodes, | ||||||
| 		       int __user *, status, | 		       int __user *, status, | ||||||
| 		       int, flags) | 		       int, flags) | ||||||
| { | { | ||||||
| 	const void __user * __user *pages; | 	return kernel_move_pages(pid, nr_pages, | ||||||
| 	int i; | 				 (const void __user *__user *)pages, | ||||||
| 
 | 				 nodes, status, flags); | ||||||
| 	pages = compat_alloc_user_space(nr_pages * sizeof(void *)); |  | ||||||
| 	for (i = 0; i < nr_pages; i++) { |  | ||||||
| 		compat_uptr_t p; |  | ||||||
| 
 |  | ||||||
| 		if (get_user(p, pages32 + i) || |  | ||||||
| 			put_user(compat_ptr(p), pages + i)) |  | ||||||
| 			return -EFAULT; |  | ||||||
| 	} |  | ||||||
| 	return kernel_move_pages(pid, nr_pages, pages, nodes, status, flags); |  | ||||||
| } | } | ||||||
| #endif /* CONFIG_COMPAT */ | #endif /* CONFIG_COMPAT */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Arnd Bergmann
						Arnd Bergmann