mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 12:39:23 +00:00 
			
		
		
		
	 27ac792ca0
			
		
	
	
		27ac792ca0
		
	
	
	
	
		
			
			On 32-bit architectures PAGE_ALIGN() truncates 64-bit values to the 32-bit boundary. For example: u64 val = PAGE_ALIGN(size); always returns a value < 4GB even if size is greater than 4GB. The problem resides in PAGE_MASK definition (from include/asm-x86/page.h for example): #define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) ... #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary. Using the ALIGN() macro seems to be the right way, because it uses typeof(addr) for the mask. Also move the PAGE_ALIGN() definitions out of include/asm-*/page.h in include/linux/mm.h. See also lkml discussion: http://lkml.org/lkml/2008/6/11/237 [akpm@linux-foundation.org: fix drivers/media/video/uvc/uvc_queue.c] [akpm@linux-foundation.org: fix v850] [akpm@linux-foundation.org: fix powerpc] [akpm@linux-foundation.org: fix arm] [akpm@linux-foundation.org: fix mips] [akpm@linux-foundation.org: fix drivers/media/video/pvrusb2/pvrusb2-dvb.c] [akpm@linux-foundation.org: fix drivers/mtd/maps/uclinux.c] [akpm@linux-foundation.org: fix powerpc] Signed-off-by: Andrea Righi <righi.andrea@gmail.com> Cc: <linux-arch@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
		
			
				
	
	
		
			26 lines
		
	
	
		
			643 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			26 lines
		
	
	
		
			643 B
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Suspend support specific for power.
 | |
|  *
 | |
|  * Distribute under GPLv2
 | |
|  *
 | |
|  * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
 | |
|  * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
 | |
|  */
 | |
| 
 | |
| #include <linux/mm.h>
 | |
| #include <asm/page.h>
 | |
| 
 | |
| /* References to section boundaries */
 | |
| extern const void __nosave_begin, __nosave_end;
 | |
| 
 | |
| /*
 | |
|  *	pfn_is_nosave - check if given pfn is in the 'nosave' section
 | |
|  */
 | |
| 
 | |
| int pfn_is_nosave(unsigned long pfn)
 | |
| {
 | |
| 	unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
 | |
| 	unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
 | |
| 	return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
 | |
| }
 |