copy_from_user_nmi() is used in oprofile and perf. Moving it to other library functions like copy_from_user(). As this is x86 code for 32 and 64 bits, create a new file usercopy.c for unified code. Signed-off-by: Robert Richter <robert.richter@amd.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/20110607172413.GJ20052@erda.amd.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
		
			
				
	
	
		
			43 lines
		
	
	
	
		
			815 B
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			43 lines
		
	
	
	
		
			815 B
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * User address space access functions.
 | 
						|
 *
 | 
						|
 *  For licencing details see kernel-base/COPYING
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/highmem.h>
 | 
						|
#include <linux/module.h>
 | 
						|
 | 
						|
/*
 | 
						|
 * best effort, GUP based copy_from_user() that is NMI-safe
 | 
						|
 */
 | 
						|
unsigned long
 | 
						|
copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
 | 
						|
{
 | 
						|
	unsigned long offset, addr = (unsigned long)from;
 | 
						|
	unsigned long size, len = 0;
 | 
						|
	struct page *page;
 | 
						|
	void *map;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	do {
 | 
						|
		ret = __get_user_pages_fast(addr, 1, 0, &page);
 | 
						|
		if (!ret)
 | 
						|
			break;
 | 
						|
 | 
						|
		offset = addr & (PAGE_SIZE - 1);
 | 
						|
		size = min(PAGE_SIZE - offset, n - len);
 | 
						|
 | 
						|
		map = kmap_atomic(page);
 | 
						|
		memcpy(to, map+offset, size);
 | 
						|
		kunmap_atomic(map);
 | 
						|
		put_page(page);
 | 
						|
 | 
						|
		len  += size;
 | 
						|
		to   += size;
 | 
						|
		addr += size;
 | 
						|
 | 
						|
	} while (len < n);
 | 
						|
 | 
						|
	return len;
 | 
						|
}
 | 
						|
EXPORT_SYMBOL_GPL(copy_from_user_nmi);
 |