Merge branches 'x86/alternatives', 'x86/cleanups', 'x86/commandline', 'x86/crashdump', 'x86/debug', 'x86/defconfig', 'x86/doc', 'x86/exports', 'x86/fpu', 'x86/gart', 'x86/idle', 'x86/mm', 'x86/mtrr', 'x86/nmi-watchdog', 'x86/oprofile', 'x86/paravirt', 'x86/reboot', 'x86/sparse-fixes', 'x86/tsc', 'x86/urgent' and 'x86/vmalloc' into x86-v28-for-linus-phase1
This commit is contained in:
		
					 90 changed files with 1305 additions and 774 deletions
				
			
		| 
						 | 
					@ -251,8 +251,6 @@ mono.txt
 | 
				
			||||||
	- how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
 | 
						- how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
 | 
				
			||||||
moxa-smartio
 | 
					moxa-smartio
 | 
				
			||||||
	- file with info on installing/using Moxa multiport serial driver.
 | 
						- file with info on installing/using Moxa multiport serial driver.
 | 
				
			||||||
mtrr.txt
 | 
					 | 
				
			||||||
	- how to use PPro Memory Type Range Registers to increase performance.
 | 
					 | 
				
			||||||
mutex-design.txt
 | 
					mutex-design.txt
 | 
				
			||||||
	- info on the generic mutex subsystem.
 | 
						- info on the generic mutex subsystem.
 | 
				
			||||||
namespaces/
 | 
					namespaces/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -463,12 +463,6 @@ and is between 256 and 4096 characters. It is defined in the file
 | 
				
			||||||
			Range: 0 - 8192
 | 
								Range: 0 - 8192
 | 
				
			||||||
			Default: 64
 | 
								Default: 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	disable_8254_timer
 | 
					 | 
				
			||||||
	enable_8254_timer
 | 
					 | 
				
			||||||
			[IA32/X86_64] Disable/Enable interrupt 0 timer routing
 | 
					 | 
				
			||||||
			over the 8254 in addition to over the IO-APIC. The
 | 
					 | 
				
			||||||
			kernel tries to set a sensible default.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hpet=		[X86-32,HPET] option to control HPET usage
 | 
						hpet=		[X86-32,HPET] option to control HPET usage
 | 
				
			||||||
			Format: { enable (default) | disable | force }
 | 
								Format: { enable (default) | disable | force }
 | 
				
			||||||
			disable: disable HPET and use PIT instead
 | 
								disable: disable HPET and use PIT instead
 | 
				
			||||||
| 
						 | 
					@ -1882,6 +1876,12 @@ and is between 256 and 4096 characters. It is defined in the file
 | 
				
			||||||
	shapers=	[NET]
 | 
						shapers=	[NET]
 | 
				
			||||||
			Maximal number of shapers.
 | 
								Maximal number of shapers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						show_msr=	[x86] show boot-time MSR settings
 | 
				
			||||||
 | 
								Format: { <integer> }
 | 
				
			||||||
 | 
								Show boot-time (BIOS-initialized) MSR settings.
 | 
				
			||||||
 | 
								The parameter means the number of CPUs to show,
 | 
				
			||||||
 | 
								for example 1 means boot CPU only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sim710=		[SCSI,HW]
 | 
						sim710=		[SCSI,HW]
 | 
				
			||||||
			See header of drivers/scsi/sim710.c.
 | 
								See header of drivers/scsi/sim710.c.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								Documentation/x86/00-INDEX
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Documentation/x86/00-INDEX
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					00-INDEX
 | 
				
			||||||
 | 
						- this file
 | 
				
			||||||
 | 
					mtrr.txt
 | 
				
			||||||
 | 
						- how to use x86 Memory Type Range Registers to increase performance
 | 
				
			||||||
| 
						 | 
					@ -308,7 +308,7 @@ Protocol:	2.00+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Field name:	start_sys
 | 
					Field name:	start_sys
 | 
				
			||||||
Type:		read
 | 
					Type:		read
 | 
				
			||||||
Offset/size:	0x20c/4
 | 
					Offset/size:	0x20c/2
 | 
				
			||||||
Protocol:	2.00+
 | 
					Protocol:	2.00+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  The load low segment (0x1000).  Obsolete.
 | 
					  The load low segment (0x1000).  Obsolete.
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ Richard Gooch
 | 
				
			||||||
  The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
 | 
					  The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
 | 
				
			||||||
  MTRRs. These are supported.  The AMD Athlon family provide 8 Intel
 | 
					  MTRRs. These are supported.  The AMD Athlon family provide 8 Intel
 | 
				
			||||||
  style MTRRs.
 | 
					  style MTRRs.
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
 | 
					  The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
 | 
				
			||||||
  are supported.
 | 
					  are supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ reg00: base=0x00000000 (   0MB), size=  64MB: write-back, count=1
 | 
				
			||||||
reg01: base=0xfb000000 (4016MB), size=  16MB: write-combining, count=1
 | 
					reg01: base=0xfb000000 (4016MB), size=  16MB: write-combining, count=1
 | 
				
			||||||
reg02: base=0xfb000000 (4016MB), size=   4kB: uncachable, count=1
 | 
					reg02: base=0xfb000000 (4016MB), size=   4kB: uncachable, count=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Some cards (especially Voodoo Graphics boards) need this 4 kB area 
 | 
					Some cards (especially Voodoo Graphics boards) need this 4 kB area
 | 
				
			||||||
excluded from the beginning of the region because it is used for
 | 
					excluded from the beginning of the region because it is used for
 | 
				
			||||||
registers.
 | 
					registers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,10 @@ PAT allows for different types of memory attributes. The most commonly used
 | 
				
			||||||
ones that will be supported at this time are Write-back, Uncached,
 | 
					ones that will be supported at this time are Write-back, Uncached,
 | 
				
			||||||
Write-combined and Uncached Minus.
 | 
					Write-combined and Uncached Minus.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PAT APIs
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are many different APIs in the kernel that allows setting of memory
 | 
					There are many different APIs in the kernel that allows setting of memory
 | 
				
			||||||
attributes at the page level. In order to avoid aliasing, these interfaces
 | 
					attributes at the page level. In order to avoid aliasing, these interfaces
 | 
				
			||||||
should be used thoughtfully. Below is a table of interfaces available,
 | 
					should be used thoughtfully. Below is a table of interfaces available,
 | 
				
			||||||
| 
						 | 
					@ -26,38 +30,38 @@ address range to avoid any aliasing.
 | 
				
			||||||
API                    |    RAM   |  ACPI,...  |  Reserved/Holes  |
 | 
					API                    |    RAM   |  ACPI,...  |  Reserved/Holes  |
 | 
				
			||||||
-----------------------|----------|------------|------------------|
 | 
					-----------------------|----------|------------|------------------|
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
ioremap                |    --    |    UC      |       UC         |
 | 
					ioremap                |    --    |    UC-     |       UC-        |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
ioremap_cache          |    --    |    WB      |       WB         |
 | 
					ioremap_cache          |    --    |    WB      |       WB         |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
ioremap_nocache        |    --    |    UC      |       UC         |
 | 
					ioremap_nocache        |    --    |    UC-     |       UC-        |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
ioremap_wc             |    --    |    --      |       WC         |
 | 
					ioremap_wc             |    --    |    --      |       WC         |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
set_memory_uc          |    UC    |    --      |       --         |
 | 
					set_memory_uc          |    UC-   |    --      |       --         |
 | 
				
			||||||
 set_memory_wb         |          |            |                  |
 | 
					 set_memory_wb         |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
set_memory_wc          |    WC    |    --      |       --         |
 | 
					set_memory_wc          |    WC    |    --      |       --         |
 | 
				
			||||||
 set_memory_wb         |          |            |                  |
 | 
					 set_memory_wb         |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
pci sysfs resource     |    --    |    --      |       UC         |
 | 
					pci sysfs resource     |    --    |    --      |       UC-        |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
pci sysfs resource_wc  |    --    |    --      |       WC         |
 | 
					pci sysfs resource_wc  |    --    |    --      |       WC         |
 | 
				
			||||||
 is IORESOURCE_PREFETCH|          |            |                  |
 | 
					 is IORESOURCE_PREFETCH|          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
pci proc               |    --    |    --      |       UC         |
 | 
					pci proc               |    --    |    --      |       UC-        |
 | 
				
			||||||
 !PCIIOC_WRITE_COMBINE |          |            |                  |
 | 
					 !PCIIOC_WRITE_COMBINE |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
pci proc               |    --    |    --      |       WC         |
 | 
					pci proc               |    --    |    --      |       WC         |
 | 
				
			||||||
 PCIIOC_WRITE_COMBINE  |          |            |                  |
 | 
					 PCIIOC_WRITE_COMBINE  |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
/dev/mem               |    --    |    UC      |       UC         |
 | 
					/dev/mem               |    --    |  WB/WC/UC- |    WB/WC/UC-     |
 | 
				
			||||||
 read-write            |          |            |                  |
 | 
					 read-write            |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
/dev/mem               |    --    |    UC      |       UC         |
 | 
					/dev/mem               |    --    |    UC-     |       UC-        |
 | 
				
			||||||
 mmap SYNC flag        |          |            |                  |
 | 
					 mmap SYNC flag        |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
/dev/mem               |    --    |  WB/WC/UC  |    WB/WC/UC      |
 | 
					/dev/mem               |    --    |  WB/WC/UC- |    WB/WC/UC-     |
 | 
				
			||||||
 mmap !SYNC flag       |          |(from exist-|  (from exist-    |
 | 
					 mmap !SYNC flag       |          |(from exist-|  (from exist-    |
 | 
				
			||||||
 and                   |          |  ing alias)|    ing alias)    |
 | 
					 and                   |          |  ing alias)|    ing alias)    |
 | 
				
			||||||
 any alias to this area|          |            |                  |
 | 
					 any alias to this area|          |            |                  |
 | 
				
			||||||
| 
						 | 
					@ -68,7 +72,7 @@ pci proc               |    --    |    --      |       WC         |
 | 
				
			||||||
 and                   |          |            |                  |
 | 
					 and                   |          |            |                  |
 | 
				
			||||||
 MTRR says WB          |          |            |                  |
 | 
					 MTRR says WB          |          |            |                  |
 | 
				
			||||||
                       |          |            |                  |
 | 
					                       |          |            |                  |
 | 
				
			||||||
/dev/mem               |    --    |    --      |    UC_MINUS      |
 | 
					/dev/mem               |    --    |    --      |       UC-        |
 | 
				
			||||||
 mmap !SYNC flag       |          |            |                  |
 | 
					 mmap !SYNC flag       |          |            |                  |
 | 
				
			||||||
 no alias to this area |          |            |                  |
 | 
					 no alias to this area |          |            |                  |
 | 
				
			||||||
 and                   |          |            |                  |
 | 
					 and                   |          |            |                  |
 | 
				
			||||||
| 
						 | 
					@ -98,3 +102,35 @@ types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Drivers should use set_memory_[uc|wc] to set access type for RAM ranges.
 | 
					Drivers should use set_memory_[uc|wc] to set access type for RAM ranges.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PAT debugging
 | 
				
			||||||
 | 
					-------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With CONFIG_DEBUG_FS enabled, PAT memtype list can be examined by
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# mount -t debugfs debugfs /sys/kernel/debug
 | 
				
			||||||
 | 
					# cat /sys/kernel/debug/x86/pat_memtype_list
 | 
				
			||||||
 | 
					PAT memtype list:
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fadf000-0x7fae0000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb19000-0x7fb1a000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb1a000-0x7fb1b000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb1b000-0x7fb1c000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb1c000-0x7fb1d000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb1d000-0x7fb1e000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb1e000-0x7fb25000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb25000-0x7fb26000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb26000-0x7fb27000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb27000-0x7fb28000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb28000-0x7fb2e000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb2e000-0x7fb2f000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb2f000-0x7fb30000
 | 
				
			||||||
 | 
					uncached-minus @ 0x7fb31000-0x7fb32000
 | 
				
			||||||
 | 
					uncached-minus @ 0x80000000-0x90000000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This list shows physical address ranges and various PAT settings used to
 | 
				
			||||||
 | 
					access those physical address ranges.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Another, more verbose way of getting PAT related debug messages is with
 | 
				
			||||||
 | 
					"debugpat" boot parameter. With this parameter, various debug messages are
 | 
				
			||||||
 | 
					printed to dmesg log.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,10 +54,6 @@ APICs
 | 
				
			||||||
		 apicmaintimer. Useful when your PIT timer is totally
 | 
							 apicmaintimer. Useful when your PIT timer is totally
 | 
				
			||||||
		 broken.
 | 
							 broken.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   disable_8254_timer / enable_8254_timer
 | 
					 | 
				
			||||||
		 Enable interrupt 0 timer routing over the 8254 in addition to over
 | 
					 | 
				
			||||||
	         the IO-APIC. The kernel tries to set a sensible default.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Early Console
 | 
					Early Console
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   syntax: earlyprintk=vga
 | 
					   syntax: earlyprintk=vga
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1021,7 +1021,7 @@ config HAVE_ARCH_ALLOC_REMAP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config ARCH_FLATMEM_ENABLE
 | 
					config ARCH_FLATMEM_ENABLE
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
	depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC && !NUMA
 | 
						depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && !NUMA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config ARCH_DISCONTIGMEM_ENABLE
 | 
					config ARCH_DISCONTIGMEM_ENABLE
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
| 
						 | 
					@ -1037,7 +1037,7 @@ config ARCH_SPARSEMEM_DEFAULT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config ARCH_SPARSEMEM_ENABLE
 | 
					config ARCH_SPARSEMEM_ENABLE
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
	depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC)
 | 
						depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC) || X86_GENERICARCH
 | 
				
			||||||
	select SPARSEMEM_STATIC if X86_32
 | 
						select SPARSEMEM_STATIC if X86_32
 | 
				
			||||||
	select SPARSEMEM_VMEMMAP_ENABLE if X86_64
 | 
						select SPARSEMEM_VMEMMAP_ENABLE if X86_64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1118,10 +1118,10 @@ config MTRR
 | 
				
			||||||
	  You can safely say Y even if your machine doesn't have MTRRs, you'll
 | 
						  You can safely say Y even if your machine doesn't have MTRRs, you'll
 | 
				
			||||||
	  just add about 9 KB to your kernel.
 | 
						  just add about 9 KB to your kernel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  See <file:Documentation/mtrr.txt> for more information.
 | 
						  See <file:Documentation/x86/mtrr.txt> for more information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config MTRR_SANITIZER
 | 
					config MTRR_SANITIZER
 | 
				
			||||||
	bool
 | 
						def_bool y
 | 
				
			||||||
	prompt "MTRR cleanup support"
 | 
						prompt "MTRR cleanup support"
 | 
				
			||||||
	depends on MTRR
 | 
						depends on MTRR
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
| 
						 | 
					@ -1132,7 +1132,7 @@ config MTRR_SANITIZER
 | 
				
			||||||
	  The largest mtrr entry size for a continous block can be set with
 | 
						  The largest mtrr entry size for a continous block can be set with
 | 
				
			||||||
	  mtrr_chunk_size.
 | 
						  mtrr_chunk_size.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  If unsure, say N.
 | 
						  If unsure, say Y.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config MTRR_SANITIZER_ENABLE_DEFAULT
 | 
					config MTRR_SANITIZER_ENABLE_DEFAULT
 | 
				
			||||||
	int "MTRR cleanup enable value (0-1)"
 | 
						int "MTRR cleanup enable value (0-1)"
 | 
				
			||||||
| 
						 | 
					@ -1192,7 +1192,6 @@ config IRQBALANCE
 | 
				
			||||||
config SECCOMP
 | 
					config SECCOMP
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
	prompt "Enable seccomp to safely compute untrusted bytecode"
 | 
						prompt "Enable seccomp to safely compute untrusted bytecode"
 | 
				
			||||||
	depends on PROC_FS
 | 
					 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  This kernel feature is useful for number crunching applications
 | 
						  This kernel feature is useful for number crunching applications
 | 
				
			||||||
	  that may need to compute untrusted bytecode during their
 | 
						  that may need to compute untrusted bytecode during their
 | 
				
			||||||
| 
						 | 
					@ -1200,7 +1199,7 @@ config SECCOMP
 | 
				
			||||||
	  the process as file descriptors supporting the read/write
 | 
						  the process as file descriptors supporting the read/write
 | 
				
			||||||
	  syscalls, it's possible to isolate those applications in
 | 
						  syscalls, it's possible to isolate those applications in
 | 
				
			||||||
	  their own address space using seccomp. Once seccomp is
 | 
						  their own address space using seccomp. Once seccomp is
 | 
				
			||||||
	  enabled via /proc/<pid>/seccomp, it cannot be disabled
 | 
						  enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
 | 
				
			||||||
	  and the task is only allowed to execute a few safe syscalls
 | 
						  and the task is only allowed to execute a few safe syscalls
 | 
				
			||||||
	  defined by each seccomp mode.
 | 
						  defined by each seccomp mode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1357,14 +1356,14 @@ config PHYSICAL_ALIGN
 | 
				
			||||||
	  Don't change this unless you know what you are doing.
 | 
						  Don't change this unless you know what you are doing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config HOTPLUG_CPU
 | 
					config HOTPLUG_CPU
 | 
				
			||||||
	bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
 | 
						bool "Support for hot-pluggable CPUs"
 | 
				
			||||||
	depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
 | 
						depends on SMP && HOTPLUG && !X86_VOYAGER
 | 
				
			||||||
	---help---
 | 
						---help---
 | 
				
			||||||
	  Say Y here to experiment with turning CPUs off and on, and to
 | 
						  Say Y here to allow turning CPUs off and on. CPUs can be
 | 
				
			||||||
	  enable suspend on SMP systems. CPUs can be controlled through
 | 
						  controlled through /sys/devices/system/cpu.
 | 
				
			||||||
	  /sys/devices/system/cpu.
 | 
						  ( Note: power management support will enable this option
 | 
				
			||||||
	  Say N if you want to disable CPU hotplug and don't need to
 | 
						    automatically on SMP systems. )
 | 
				
			||||||
	  suspend.
 | 
						  Say N if you want to disable CPU hotplug.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config COMPAT_VDSO
 | 
					config COMPAT_VDSO
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
| 
						 | 
					@ -1379,6 +1378,51 @@ config COMPAT_VDSO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  If unsure, say Y.
 | 
						  If unsure, say Y.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config CMDLINE_BOOL
 | 
				
			||||||
 | 
						bool "Built-in kernel command line"
 | 
				
			||||||
 | 
						default n
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Allow for specifying boot arguments to the kernel at
 | 
				
			||||||
 | 
						  build time.  On some systems (e.g. embedded ones), it is
 | 
				
			||||||
 | 
						  necessary or convenient to provide some or all of the
 | 
				
			||||||
 | 
						  kernel boot arguments with the kernel itself (that is,
 | 
				
			||||||
 | 
						  to not rely on the boot loader to provide them.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  To compile command line arguments into the kernel,
 | 
				
			||||||
 | 
						  set this option to 'Y', then fill in the
 | 
				
			||||||
 | 
						  the boot arguments in CONFIG_CMDLINE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  Systems with fully functional boot loaders (i.e. non-embedded)
 | 
				
			||||||
 | 
						  should leave this option set to 'N'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config CMDLINE
 | 
				
			||||||
 | 
						string "Built-in kernel command string"
 | 
				
			||||||
 | 
						depends on CMDLINE_BOOL
 | 
				
			||||||
 | 
						default ""
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Enter arguments here that should be compiled into the kernel
 | 
				
			||||||
 | 
						  image and used at boot time.  If the boot loader provides a
 | 
				
			||||||
 | 
						  command line at boot time, it is appended to this string to
 | 
				
			||||||
 | 
						  form the full kernel command line, when the system boots.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  However, you can use the CONFIG_CMDLINE_OVERRIDE option to
 | 
				
			||||||
 | 
						  change this behavior.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  In most cases, the command line (whether built-in or provided
 | 
				
			||||||
 | 
						  by the boot loader) should specify the device for the root
 | 
				
			||||||
 | 
						  file system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config CMDLINE_OVERRIDE
 | 
				
			||||||
 | 
						bool "Built-in command line overrides boot loader arguments"
 | 
				
			||||||
 | 
						default n
 | 
				
			||||||
 | 
						depends on CMDLINE_BOOL
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Set this option to 'Y' to have the kernel ignore the boot loader
 | 
				
			||||||
 | 
						  command line, and use ONLY the built-in command line.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  This is used to work around broken boot loaders.  This should
 | 
				
			||||||
 | 
						  be set to 'N' under normal conditions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endmenu
 | 
					endmenu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config ARCH_ENABLE_MEMORY_HOTPLUG
 | 
					config ARCH_ENABLE_MEMORY_HOTPLUG
 | 
				
			||||||
| 
						 | 
					@ -1774,7 +1818,7 @@ config COMPAT_FOR_U64_ALIGNMENT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SYSVIPC_COMPAT
 | 
					config SYSVIPC_COMPAT
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
	depends on X86_64 && COMPAT && SYSVIPC
 | 
						depends on COMPAT && SYSVIPC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endmenu
 | 
					endmenu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,14 +137,15 @@ relocated:
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
	movl output_len(%ebx), %eax
 | 
						movl output_len(%ebx), %eax
 | 
				
			||||||
	pushl %eax
 | 
						pushl %eax
 | 
				
			||||||
 | 
								# push arguments for decompress_kernel:
 | 
				
			||||||
	pushl %ebp	# output address
 | 
						pushl %ebp	# output address
 | 
				
			||||||
	movl input_len(%ebx), %eax
 | 
						movl input_len(%ebx), %eax
 | 
				
			||||||
	pushl %eax	# input_len
 | 
						pushl %eax	# input_len
 | 
				
			||||||
	leal input_data(%ebx), %eax
 | 
						leal input_data(%ebx), %eax
 | 
				
			||||||
	pushl %eax	# input_data
 | 
						pushl %eax	# input_data
 | 
				
			||||||
	leal boot_heap(%ebx), %eax
 | 
						leal boot_heap(%ebx), %eax
 | 
				
			||||||
	pushl %eax	# heap area as third argument
 | 
						pushl %eax	# heap area
 | 
				
			||||||
	pushl %esi	# real mode pointer as second arg
 | 
						pushl %esi	# real mode pointer
 | 
				
			||||||
	call decompress_kernel
 | 
						call decompress_kernel
 | 
				
			||||||
	addl $20, %esp
 | 
						addl $20, %esp
 | 
				
			||||||
	popl %ecx
 | 
						popl %ecx
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@
 | 
				
			||||||
#include <linux/linkage.h>
 | 
					#include <linux/linkage.h>
 | 
				
			||||||
#include <linux/screen_info.h>
 | 
					#include <linux/screen_info.h>
 | 
				
			||||||
#include <linux/elf.h>
 | 
					#include <linux/elf.h>
 | 
				
			||||||
#include <asm/io.h>
 | 
					#include <linux/io.h>
 | 
				
			||||||
#include <asm/page.h>
 | 
					#include <asm/page.h>
 | 
				
			||||||
#include <asm/boot.h>
 | 
					#include <asm/boot.h>
 | 
				
			||||||
#include <asm/bootparam.h>
 | 
					#include <asm/bootparam.h>
 | 
				
			||||||
| 
						 | 
					@ -251,7 +251,7 @@ static void __putstr(int error, const char *s)
 | 
				
			||||||
				y--;
 | 
									y--;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			vidmem [(x + cols * y) * 2] = c;
 | 
								vidmem[(x + cols * y) * 2] = c;
 | 
				
			||||||
			if (++x >= cols) {
 | 
								if (++x >= cols) {
 | 
				
			||||||
				x = 0;
 | 
									x = 0;
 | 
				
			||||||
				if (++y >= lines) {
 | 
									if (++y >= lines) {
 | 
				
			||||||
| 
						 | 
					@ -277,7 +277,8 @@ static void *memset(void *s, int c, unsigned n)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	char *ss = s;
 | 
						char *ss = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < n; i++) ss[i] = c;
 | 
						for (i = 0; i < n; i++)
 | 
				
			||||||
 | 
							ss[i] = c;
 | 
				
			||||||
	return s;
 | 
						return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -287,7 +288,8 @@ static void *memcpy(void *dest, const void *src, unsigned n)
 | 
				
			||||||
	const char *s = src;
 | 
						const char *s = src;
 | 
				
			||||||
	char *d = dest;
 | 
						char *d = dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < n; i++) d[i] = s[i];
 | 
						for (i = 0; i < n; i++)
 | 
				
			||||||
 | 
							d[i] = s[i];
 | 
				
			||||||
	return dest;
 | 
						return dest;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,6 @@ SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
 | 
				
			||||||
SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
 | 
					SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
 | 
				
			||||||
					/* to be loaded */
 | 
										/* to be loaded */
 | 
				
			||||||
ROOT_DEV	= 0			/* ROOT_DEV is now written by "build" */
 | 
					ROOT_DEV	= 0			/* ROOT_DEV is now written by "build" */
 | 
				
			||||||
SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef SVGA_MODE
 | 
					#ifndef SVGA_MODE
 | 
				
			||||||
#define SVGA_MODE ASK_VGA
 | 
					#define SVGA_MODE ASK_VGA
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Automatically generated make config: don't edit
 | 
					# Automatically generated make config: don't edit
 | 
				
			||||||
# Linux kernel version: 2.6.27-rc4
 | 
					# Linux kernel version: 2.6.27-rc5
 | 
				
			||||||
# Mon Aug 25 15:04:00 2008
 | 
					# Wed Sep  3 17:23:09 2008
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# CONFIG_64BIT is not set
 | 
					# CONFIG_64BIT is not set
 | 
				
			||||||
CONFIG_X86_32=y
 | 
					CONFIG_X86_32=y
 | 
				
			||||||
| 
						 | 
					@ -202,7 +202,7 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 | 
				
			||||||
# CONFIG_M586 is not set
 | 
					# CONFIG_M586 is not set
 | 
				
			||||||
# CONFIG_M586TSC is not set
 | 
					# CONFIG_M586TSC is not set
 | 
				
			||||||
# CONFIG_M586MMX is not set
 | 
					# CONFIG_M586MMX is not set
 | 
				
			||||||
# CONFIG_M686 is not set
 | 
					CONFIG_M686=y
 | 
				
			||||||
# CONFIG_MPENTIUMII is not set
 | 
					# CONFIG_MPENTIUMII is not set
 | 
				
			||||||
# CONFIG_MPENTIUMIII is not set
 | 
					# CONFIG_MPENTIUMIII is not set
 | 
				
			||||||
# CONFIG_MPENTIUMM is not set
 | 
					# CONFIG_MPENTIUMM is not set
 | 
				
			||||||
| 
						 | 
					@ -221,13 +221,14 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 | 
				
			||||||
# CONFIG_MVIAC3_2 is not set
 | 
					# CONFIG_MVIAC3_2 is not set
 | 
				
			||||||
# CONFIG_MVIAC7 is not set
 | 
					# CONFIG_MVIAC7 is not set
 | 
				
			||||||
# CONFIG_MPSC is not set
 | 
					# CONFIG_MPSC is not set
 | 
				
			||||||
CONFIG_MCORE2=y
 | 
					# CONFIG_MCORE2 is not set
 | 
				
			||||||
# CONFIG_GENERIC_CPU is not set
 | 
					# CONFIG_GENERIC_CPU is not set
 | 
				
			||||||
CONFIG_X86_GENERIC=y
 | 
					CONFIG_X86_GENERIC=y
 | 
				
			||||||
CONFIG_X86_CPU=y
 | 
					CONFIG_X86_CPU=y
 | 
				
			||||||
CONFIG_X86_CMPXCHG=y
 | 
					CONFIG_X86_CMPXCHG=y
 | 
				
			||||||
CONFIG_X86_L1_CACHE_SHIFT=7
 | 
					CONFIG_X86_L1_CACHE_SHIFT=7
 | 
				
			||||||
CONFIG_X86_XADD=y
 | 
					CONFIG_X86_XADD=y
 | 
				
			||||||
 | 
					# CONFIG_X86_PPRO_FENCE is not set
 | 
				
			||||||
CONFIG_X86_WP_WORKS_OK=y
 | 
					CONFIG_X86_WP_WORKS_OK=y
 | 
				
			||||||
CONFIG_X86_INVLPG=y
 | 
					CONFIG_X86_INVLPG=y
 | 
				
			||||||
CONFIG_X86_BSWAP=y
 | 
					CONFIG_X86_BSWAP=y
 | 
				
			||||||
| 
						 | 
					@ -235,14 +236,15 @@ CONFIG_X86_POPAD_OK=y
 | 
				
			||||||
CONFIG_X86_INTEL_USERCOPY=y
 | 
					CONFIG_X86_INTEL_USERCOPY=y
 | 
				
			||||||
CONFIG_X86_USE_PPRO_CHECKSUM=y
 | 
					CONFIG_X86_USE_PPRO_CHECKSUM=y
 | 
				
			||||||
CONFIG_X86_TSC=y
 | 
					CONFIG_X86_TSC=y
 | 
				
			||||||
 | 
					CONFIG_X86_CMOV=y
 | 
				
			||||||
CONFIG_X86_MINIMUM_CPU_FAMILY=4
 | 
					CONFIG_X86_MINIMUM_CPU_FAMILY=4
 | 
				
			||||||
CONFIG_X86_DEBUGCTLMSR=y
 | 
					CONFIG_X86_DEBUGCTLMSR=y
 | 
				
			||||||
CONFIG_HPET_TIMER=y
 | 
					CONFIG_HPET_TIMER=y
 | 
				
			||||||
CONFIG_HPET_EMULATE_RTC=y
 | 
					CONFIG_HPET_EMULATE_RTC=y
 | 
				
			||||||
CONFIG_DMI=y
 | 
					CONFIG_DMI=y
 | 
				
			||||||
# CONFIG_IOMMU_HELPER is not set
 | 
					# CONFIG_IOMMU_HELPER is not set
 | 
				
			||||||
CONFIG_NR_CPUS=4
 | 
					CONFIG_NR_CPUS=64
 | 
				
			||||||
# CONFIG_SCHED_SMT is not set
 | 
					CONFIG_SCHED_SMT=y
 | 
				
			||||||
CONFIG_SCHED_MC=y
 | 
					CONFIG_SCHED_MC=y
 | 
				
			||||||
# CONFIG_PREEMPT_NONE is not set
 | 
					# CONFIG_PREEMPT_NONE is not set
 | 
				
			||||||
CONFIG_PREEMPT_VOLUNTARY=y
 | 
					CONFIG_PREEMPT_VOLUNTARY=y
 | 
				
			||||||
| 
						 | 
					@ -254,7 +256,8 @@ CONFIG_VM86=y
 | 
				
			||||||
# CONFIG_TOSHIBA is not set
 | 
					# CONFIG_TOSHIBA is not set
 | 
				
			||||||
# CONFIG_I8K is not set
 | 
					# CONFIG_I8K is not set
 | 
				
			||||||
CONFIG_X86_REBOOTFIXUPS=y
 | 
					CONFIG_X86_REBOOTFIXUPS=y
 | 
				
			||||||
# CONFIG_MICROCODE is not set
 | 
					CONFIG_MICROCODE=y
 | 
				
			||||||
 | 
					CONFIG_MICROCODE_OLD_INTERFACE=y
 | 
				
			||||||
CONFIG_X86_MSR=y
 | 
					CONFIG_X86_MSR=y
 | 
				
			||||||
CONFIG_X86_CPUID=y
 | 
					CONFIG_X86_CPUID=y
 | 
				
			||||||
# CONFIG_NOHIGHMEM is not set
 | 
					# CONFIG_NOHIGHMEM is not set
 | 
				
			||||||
| 
						 | 
					@ -2115,7 +2118,7 @@ CONFIG_IO_DELAY_0X80=y
 | 
				
			||||||
CONFIG_DEFAULT_IO_DELAY_TYPE=0
 | 
					CONFIG_DEFAULT_IO_DELAY_TYPE=0
 | 
				
			||||||
CONFIG_DEBUG_BOOT_PARAMS=y
 | 
					CONFIG_DEBUG_BOOT_PARAMS=y
 | 
				
			||||||
# CONFIG_CPA_DEBUG is not set
 | 
					# CONFIG_CPA_DEBUG is not set
 | 
				
			||||||
# CONFIG_OPTIMIZE_INLINING is not set
 | 
					CONFIG_OPTIMIZE_INLINING=y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Security options
 | 
					# Security options
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Automatically generated make config: don't edit
 | 
					# Automatically generated make config: don't edit
 | 
				
			||||||
# Linux kernel version: 2.6.27-rc4
 | 
					# Linux kernel version: 2.6.27-rc5
 | 
				
			||||||
# Mon Aug 25 14:40:46 2008
 | 
					# Wed Sep  3 17:13:39 2008
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
CONFIG_64BIT=y
 | 
					CONFIG_64BIT=y
 | 
				
			||||||
# CONFIG_X86_32 is not set
 | 
					# CONFIG_X86_32 is not set
 | 
				
			||||||
| 
						 | 
					@ -218,17 +218,14 @@ CONFIG_X86_PC=y
 | 
				
			||||||
# CONFIG_MVIAC3_2 is not set
 | 
					# CONFIG_MVIAC3_2 is not set
 | 
				
			||||||
# CONFIG_MVIAC7 is not set
 | 
					# CONFIG_MVIAC7 is not set
 | 
				
			||||||
# CONFIG_MPSC is not set
 | 
					# CONFIG_MPSC is not set
 | 
				
			||||||
CONFIG_MCORE2=y
 | 
					# CONFIG_MCORE2 is not set
 | 
				
			||||||
# CONFIG_GENERIC_CPU is not set
 | 
					CONFIG_GENERIC_CPU=y
 | 
				
			||||||
CONFIG_X86_CPU=y
 | 
					CONFIG_X86_CPU=y
 | 
				
			||||||
CONFIG_X86_L1_CACHE_BYTES=64
 | 
					CONFIG_X86_L1_CACHE_BYTES=128
 | 
				
			||||||
CONFIG_X86_INTERNODE_CACHE_BYTES=64
 | 
					CONFIG_X86_INTERNODE_CACHE_BYTES=128
 | 
				
			||||||
CONFIG_X86_CMPXCHG=y
 | 
					CONFIG_X86_CMPXCHG=y
 | 
				
			||||||
CONFIG_X86_L1_CACHE_SHIFT=6
 | 
					CONFIG_X86_L1_CACHE_SHIFT=7
 | 
				
			||||||
CONFIG_X86_WP_WORKS_OK=y
 | 
					CONFIG_X86_WP_WORKS_OK=y
 | 
				
			||||||
CONFIG_X86_INTEL_USERCOPY=y
 | 
					 | 
				
			||||||
CONFIG_X86_USE_PPRO_CHECKSUM=y
 | 
					 | 
				
			||||||
CONFIG_X86_P6_NOP=y
 | 
					 | 
				
			||||||
CONFIG_X86_TSC=y
 | 
					CONFIG_X86_TSC=y
 | 
				
			||||||
CONFIG_X86_CMPXCHG64=y
 | 
					CONFIG_X86_CMPXCHG64=y
 | 
				
			||||||
CONFIG_X86_CMOV=y
 | 
					CONFIG_X86_CMOV=y
 | 
				
			||||||
| 
						 | 
					@ -243,9 +240,8 @@ CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
 | 
				
			||||||
CONFIG_AMD_IOMMU=y
 | 
					CONFIG_AMD_IOMMU=y
 | 
				
			||||||
CONFIG_SWIOTLB=y
 | 
					CONFIG_SWIOTLB=y
 | 
				
			||||||
CONFIG_IOMMU_HELPER=y
 | 
					CONFIG_IOMMU_HELPER=y
 | 
				
			||||||
# CONFIG_MAXSMP is not set
 | 
					CONFIG_NR_CPUS=64
 | 
				
			||||||
CONFIG_NR_CPUS=4
 | 
					CONFIG_SCHED_SMT=y
 | 
				
			||||||
# CONFIG_SCHED_SMT is not set
 | 
					 | 
				
			||||||
CONFIG_SCHED_MC=y
 | 
					CONFIG_SCHED_MC=y
 | 
				
			||||||
# CONFIG_PREEMPT_NONE is not set
 | 
					# CONFIG_PREEMPT_NONE is not set
 | 
				
			||||||
CONFIG_PREEMPT_VOLUNTARY=y
 | 
					CONFIG_PREEMPT_VOLUNTARY=y
 | 
				
			||||||
| 
						 | 
					@ -254,7 +250,8 @@ CONFIG_X86_LOCAL_APIC=y
 | 
				
			||||||
CONFIG_X86_IO_APIC=y
 | 
					CONFIG_X86_IO_APIC=y
 | 
				
			||||||
# CONFIG_X86_MCE is not set
 | 
					# CONFIG_X86_MCE is not set
 | 
				
			||||||
# CONFIG_I8K is not set
 | 
					# CONFIG_I8K is not set
 | 
				
			||||||
# CONFIG_MICROCODE is not set
 | 
					CONFIG_MICROCODE=y
 | 
				
			||||||
 | 
					CONFIG_MICROCODE_OLD_INTERFACE=y
 | 
				
			||||||
CONFIG_X86_MSR=y
 | 
					CONFIG_X86_MSR=y
 | 
				
			||||||
CONFIG_X86_CPUID=y
 | 
					CONFIG_X86_CPUID=y
 | 
				
			||||||
CONFIG_NUMA=y
 | 
					CONFIG_NUMA=y
 | 
				
			||||||
| 
						 | 
					@ -290,7 +287,7 @@ CONFIG_BOUNCE=y
 | 
				
			||||||
CONFIG_VIRT_TO_BUS=y
 | 
					CONFIG_VIRT_TO_BUS=y
 | 
				
			||||||
CONFIG_MTRR=y
 | 
					CONFIG_MTRR=y
 | 
				
			||||||
# CONFIG_MTRR_SANITIZER is not set
 | 
					# CONFIG_MTRR_SANITIZER is not set
 | 
				
			||||||
# CONFIG_X86_PAT is not set
 | 
					CONFIG_X86_PAT=y
 | 
				
			||||||
CONFIG_EFI=y
 | 
					CONFIG_EFI=y
 | 
				
			||||||
CONFIG_SECCOMP=y
 | 
					CONFIG_SECCOMP=y
 | 
				
			||||||
# CONFIG_HZ_100 is not set
 | 
					# CONFIG_HZ_100 is not set
 | 
				
			||||||
| 
						 | 
					@ -2089,7 +2086,7 @@ CONFIG_IO_DELAY_0X80=y
 | 
				
			||||||
CONFIG_DEFAULT_IO_DELAY_TYPE=0
 | 
					CONFIG_DEFAULT_IO_DELAY_TYPE=0
 | 
				
			||||||
CONFIG_DEBUG_BOOT_PARAMS=y
 | 
					CONFIG_DEBUG_BOOT_PARAMS=y
 | 
				
			||||||
# CONFIG_CPA_DEBUG is not set
 | 
					# CONFIG_CPA_DEBUG is not set
 | 
				
			||||||
# CONFIG_OPTIMIZE_INLINING is not set
 | 
					CONFIG_OPTIMIZE_INLINING=y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Security options
 | 
					# Security options
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,8 +85,10 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump)
 | 
				
			||||||
	dump->regs.ax = regs->ax;
 | 
						dump->regs.ax = regs->ax;
 | 
				
			||||||
	dump->regs.ds = current->thread.ds;
 | 
						dump->regs.ds = current->thread.ds;
 | 
				
			||||||
	dump->regs.es = current->thread.es;
 | 
						dump->regs.es = current->thread.es;
 | 
				
			||||||
	asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs;
 | 
						savesegment(fs, fs);
 | 
				
			||||||
	asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs;
 | 
						dump->regs.fs = fs;
 | 
				
			||||||
 | 
						savesegment(gs, gs);
 | 
				
			||||||
 | 
						dump->regs.gs = gs;
 | 
				
			||||||
	dump->regs.orig_ax = regs->orig_ax;
 | 
						dump->regs.orig_ax = regs->orig_ax;
 | 
				
			||||||
	dump->regs.ip = regs->ip;
 | 
						dump->regs.ip = regs->ip;
 | 
				
			||||||
	dump->regs.cs = regs->cs;
 | 
						dump->regs.cs = regs->cs;
 | 
				
			||||||
| 
						 | 
					@ -430,8 +432,9 @@ beyond_if:
 | 
				
			||||||
	current->mm->start_stack =
 | 
						current->mm->start_stack =
 | 
				
			||||||
		(unsigned long)create_aout_tables((char __user *)bprm->p, bprm);
 | 
							(unsigned long)create_aout_tables((char __user *)bprm->p, bprm);
 | 
				
			||||||
	/* start thread */
 | 
						/* start thread */
 | 
				
			||||||
	asm volatile("movl %0,%%fs" :: "r" (0)); \
 | 
						loadsegment(fs, 0);
 | 
				
			||||||
	asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS));
 | 
						loadsegment(ds, __USER32_DS);
 | 
				
			||||||
 | 
						loadsegment(es, __USER32_DS);
 | 
				
			||||||
	load_gs_index(0);
 | 
						load_gs_index(0);
 | 
				
			||||||
	(regs)->ip = ex.a_entry;
 | 
						(regs)->ip = ex.a_entry;
 | 
				
			||||||
	(regs)->sp = current->mm->start_stack;
 | 
						(regs)->sp = current->mm->start_stack;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -206,7 +206,7 @@ struct rt_sigframe
 | 
				
			||||||
	{ unsigned int cur;						\
 | 
						{ unsigned int cur;						\
 | 
				
			||||||
	  unsigned short pre;						\
 | 
						  unsigned short pre;						\
 | 
				
			||||||
	  err |= __get_user(pre, &sc->seg);				\
 | 
						  err |= __get_user(pre, &sc->seg);				\
 | 
				
			||||||
	  asm volatile("movl %%" #seg ",%0" : "=r" (cur));		\
 | 
						  savesegment(seg, cur);					\
 | 
				
			||||||
	  pre |= mask;							\
 | 
						  pre |= mask;							\
 | 
				
			||||||
	  if (pre != cur) loadsegment(seg, pre); }
 | 
						  if (pre != cur) loadsegment(seg, pre); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -235,7 +235,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	err |= __get_user(gs, &sc->gs);
 | 
						err |= __get_user(gs, &sc->gs);
 | 
				
			||||||
	gs |= 3;
 | 
						gs |= 3;
 | 
				
			||||||
	asm("movl %%gs,%0" : "=r" (oldgs));
 | 
						savesegment(gs, oldgs);
 | 
				
			||||||
	if (gs != oldgs)
 | 
						if (gs != oldgs)
 | 
				
			||||||
		load_gs_index(gs);
 | 
							load_gs_index(gs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -355,14 +355,13 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int tmp, err = 0;
 | 
						int tmp, err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tmp = 0;
 | 
						savesegment(gs, tmp);
 | 
				
			||||||
	__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
 | 
					 | 
				
			||||||
	err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
 | 
						err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
 | 
				
			||||||
	__asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
 | 
						savesegment(fs, tmp);
 | 
				
			||||||
	err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
 | 
						err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
 | 
				
			||||||
	__asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
 | 
						savesegment(ds, tmp);
 | 
				
			||||||
	err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
 | 
						err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
 | 
				
			||||||
	__asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
 | 
						savesegment(es, tmp);
 | 
				
			||||||
	err |= __put_user(tmp, (unsigned int __user *)&sc->es);
 | 
						err |= __put_user(tmp, (unsigned int __user *)&sc->es);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err |= __put_user((u32)regs->di, &sc->di);
 | 
						err |= __put_user((u32)regs->di, &sc->di);
 | 
				
			||||||
| 
						 | 
					@ -498,8 +497,8 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
 | 
				
			||||||
	regs->dx = 0;
 | 
						regs->dx = 0;
 | 
				
			||||||
	regs->cx = 0;
 | 
						regs->cx = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
 | 
						loadsegment(ds, __USER32_DS);
 | 
				
			||||||
	asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
 | 
						loadsegment(es, __USER32_DS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regs->cs = __USER32_CS;
 | 
						regs->cs = __USER32_CS;
 | 
				
			||||||
	regs->ss = __USER32_DS;
 | 
						regs->ss = __USER32_DS;
 | 
				
			||||||
| 
						 | 
					@ -591,8 +590,8 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
				
			||||||
	regs->dx = (unsigned long) &frame->info;
 | 
						regs->dx = (unsigned long) &frame->info;
 | 
				
			||||||
	regs->cx = (unsigned long) &frame->uc;
 | 
						regs->cx = (unsigned long) &frame->uc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
 | 
						loadsegment(ds, __USER32_DS);
 | 
				
			||||||
	asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
 | 
						loadsegment(es, __USER32_DS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regs->cs = __USER32_CS;
 | 
						regs->cs = __USER32_CS;
 | 
				
			||||||
	regs->ss = __USER32_DS;
 | 
						regs->ss = __USER32_DS;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -556,15 +556,6 @@ asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig,
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* These are here just in case some old ia32 binary calls it. */
 | 
					 | 
				
			||||||
asmlinkage long sys32_pause(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	current->state = TASK_INTERRUPTIBLE;
 | 
					 | 
				
			||||||
	schedule();
 | 
					 | 
				
			||||||
	return -ERESTARTNOHAND;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_SYSCTL_SYSCALL
 | 
					#ifdef CONFIG_SYSCTL_SYSCALL
 | 
				
			||||||
struct sysctl_ia32 {
 | 
					struct sysctl_ia32 {
 | 
				
			||||||
	unsigned int	name;
 | 
						unsigned int	name;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,6 @@ EXPORT_SYMBOL(acpi_disabled);
 | 
				
			||||||
#ifdef	CONFIG_X86_64
 | 
					#ifdef	CONFIG_X86_64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/proto.h>
 | 
					#include <asm/proto.h>
 | 
				
			||||||
#include <asm/genapic.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else				/* X86 */
 | 
					#else				/* X86 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,8 +96,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 | 
				
			||||||
#warning ACPI uses CMPXCHG, i486 and later hardware
 | 
					#warning ACPI uses CMPXCHG, i486 and later hardware
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* --------------------------------------------------------------------------
 | 
					/* --------------------------------------------------------------------------
 | 
				
			||||||
                              Boot-time Configuration
 | 
					                              Boot-time Configuration
 | 
				
			||||||
   -------------------------------------------------------------------------- */
 | 
					   -------------------------------------------------------------------------- */
 | 
				
			||||||
| 
						 | 
					@ -160,6 +157,8 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
 | 
				
			||||||
struct acpi_mcfg_allocation *pci_mmcfg_config;
 | 
					struct acpi_mcfg_allocation *pci_mmcfg_config;
 | 
				
			||||||
int pci_mmcfg_config_num;
 | 
					int pci_mmcfg_config_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
 | 
					static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!strcmp(mcfg->header.oem_id, "SGI"))
 | 
						if (!strcmp(mcfg->header.oem_id, "SGI"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -231,25 +231,25 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (*ptr > text_end)
 | 
							if (*ptr > text_end)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		text_poke(*ptr, ((unsigned char []){0xf0}), 1); /* add lock prefix */
 | 
							/* turn DS segment override prefix into lock prefix */
 | 
				
			||||||
 | 
							text_poke(*ptr, ((unsigned char []){0xf0}), 1);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
 | 
					static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 **ptr;
 | 
						u8 **ptr;
 | 
				
			||||||
	char insn[1];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (noreplace_smp)
 | 
						if (noreplace_smp)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	add_nops(insn, 1);
 | 
					 | 
				
			||||||
	for (ptr = start; ptr < end; ptr++) {
 | 
						for (ptr = start; ptr < end; ptr++) {
 | 
				
			||||||
		if (*ptr < text)
 | 
							if (*ptr < text)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (*ptr > text_end)
 | 
							if (*ptr > text_end)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		text_poke(*ptr, insn, 1);
 | 
							/* turn lock prefix into DS segment override prefix */
 | 
				
			||||||
 | 
							text_poke(*ptr, ((unsigned char []){0x3E}), 1);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,11 +455,11 @@ out:
 | 
				
			||||||
		   force_iommu ||
 | 
							   force_iommu ||
 | 
				
			||||||
		   valid_agp ||
 | 
							   valid_agp ||
 | 
				
			||||||
		   fallback_aper_force) {
 | 
							   fallback_aper_force) {
 | 
				
			||||||
		printk(KERN_ERR
 | 
							printk(KERN_INFO
 | 
				
			||||||
			"Your BIOS doesn't leave a aperture memory hole\n");
 | 
								"Your BIOS doesn't leave a aperture memory hole\n");
 | 
				
			||||||
		printk(KERN_ERR
 | 
							printk(KERN_INFO
 | 
				
			||||||
			"Please enable the IOMMU option in the BIOS setup\n");
 | 
								"Please enable the IOMMU option in the BIOS setup\n");
 | 
				
			||||||
		printk(KERN_ERR
 | 
							printk(KERN_INFO
 | 
				
			||||||
			"This costs you %d MB of RAM\n",
 | 
								"This costs you %d MB of RAM\n",
 | 
				
			||||||
				32 << fallback_aper_order);
 | 
									32 << fallback_aper_order);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -228,7 +228,6 @@
 | 
				
			||||||
#include <linux/suspend.h>
 | 
					#include <linux/suspend.h>
 | 
				
			||||||
#include <linux/kthread.h>
 | 
					#include <linux/kthread.h>
 | 
				
			||||||
#include <linux/jiffies.h>
 | 
					#include <linux/jiffies.h>
 | 
				
			||||||
#include <linux/smp_lock.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/system.h>
 | 
					#include <asm/system.h>
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					#include <asm/uaccess.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,11 +25,11 @@ x86_bios_strerror(long status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	switch (status) {
 | 
						switch (status) {
 | 
				
			||||||
	case  0: str = "Call completed without error"; break;
 | 
						case  0: str = "Call completed without error";	break;
 | 
				
			||||||
	case -1: str = "Not implemented"; break;
 | 
						case -1: str = "Not implemented";		break;
 | 
				
			||||||
	case -2: str = "Invalid argument"; break;
 | 
						case -2: str = "Invalid argument";		break;
 | 
				
			||||||
	case -3: str = "Call completed with error"; break;
 | 
						case -3: str = "Call completed with error";	break;
 | 
				
			||||||
	default: str = "Unknown BIOS status code"; break;
 | 
						default: str = "Unknown BIOS status code";	break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return str;
 | 
						return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -430,6 +430,49 @@ static __init int setup_noclflush(char *arg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
__setup("noclflush", setup_noclflush);
 | 
					__setup("noclflush", setup_noclflush);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct msr_range {
 | 
				
			||||||
 | 
						unsigned min;
 | 
				
			||||||
 | 
						unsigned max;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct msr_range msr_range_array[] __cpuinitdata = {
 | 
				
			||||||
 | 
						{ 0x00000000, 0x00000418},
 | 
				
			||||||
 | 
						{ 0xc0000000, 0xc000040b},
 | 
				
			||||||
 | 
						{ 0xc0010000, 0xc0010142},
 | 
				
			||||||
 | 
						{ 0xc0011000, 0xc001103b},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __cpuinit print_cpu_msr(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned index;
 | 
				
			||||||
 | 
						u64 val;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						unsigned index_min, index_max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) {
 | 
				
			||||||
 | 
							index_min = msr_range_array[i].min;
 | 
				
			||||||
 | 
							index_max = msr_range_array[i].max;
 | 
				
			||||||
 | 
							for (index = index_min; index < index_max; index++) {
 | 
				
			||||||
 | 
								if (rdmsrl_amd_safe(index, &val))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int show_msr __cpuinitdata;
 | 
				
			||||||
 | 
					static __init int setup_show_msr(char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get_option(&arg, &num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (num > 0)
 | 
				
			||||||
 | 
							show_msr = num;
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					__setup("show_msr=", setup_show_msr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 | 
					void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (c->x86_model_id[0])
 | 
						if (c->x86_model_id[0])
 | 
				
			||||||
| 
						 | 
					@ -439,6 +482,14 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 | 
				
			||||||
		printk(KERN_CONT " stepping %02x\n", c->x86_mask);
 | 
							printk(KERN_CONT " stepping %02x\n", c->x86_mask);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		printk(KERN_CONT "\n");
 | 
							printk(KERN_CONT "\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SMP
 | 
				
			||||||
 | 
						if (c->cpu_index < show_msr)
 | 
				
			||||||
 | 
							print_cpu_msr();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if (show_msr)
 | 
				
			||||||
 | 
							print_cpu_msr();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __init int setup_disablecpuid(char *arg)
 | 
					static __init int setup_disablecpuid(char *arg)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -401,12 +401,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
 | 
				
			||||||
		tmp |= ~((1<<(hi - 1)) - 1);
 | 
							tmp |= ~((1<<(hi - 1)) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (tmp != mask_lo) {
 | 
							if (tmp != mask_lo) {
 | 
				
			||||||
			static int once = 1;
 | 
								WARN_ONCE(1, KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (once) {
 | 
					 | 
				
			||||||
				printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
 | 
					 | 
				
			||||||
				once = 0;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			mask_lo = tmp;
 | 
								mask_lo = tmp;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,9 +405,9 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			/* RED-PEN: base can be > 32bit */ 
 | 
								/* RED-PEN: base can be > 32bit */ 
 | 
				
			||||||
			len += seq_printf(seq, 
 | 
								len += seq_printf(seq, 
 | 
				
			||||||
				   "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n",
 | 
									   "reg%02i: base=0x%06lx000 (%5luMB), size=%5lu%cB, count=%d: %s\n",
 | 
				
			||||||
			     i, base, base >> (20 - PAGE_SHIFT), size, factor,
 | 
								     i, base, base >> (20 - PAGE_SHIFT), size, factor,
 | 
				
			||||||
			     mtrr_attrib_to_str(type), mtrr_usage_table[i]);
 | 
								     mtrr_usage_table[i], mtrr_attrib_to_str(type));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -759,7 +759,8 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
 | 
				
			||||||
	/* take out UC ranges */
 | 
						/* take out UC ranges */
 | 
				
			||||||
	for (i = 0; i < num_var_ranges; i++) {
 | 
						for (i = 0; i < num_var_ranges; i++) {
 | 
				
			||||||
		type = range_state[i].type;
 | 
							type = range_state[i].type;
 | 
				
			||||||
		if (type != MTRR_TYPE_UNCACHABLE)
 | 
							if (type != MTRR_TYPE_UNCACHABLE &&
 | 
				
			||||||
 | 
							    type != MTRR_TYPE_WRPROT)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		size = range_state[i].size_pfn;
 | 
							size = range_state[i].size_pfn;
 | 
				
			||||||
		if (!size)
 | 
							if (!size)
 | 
				
			||||||
| 
						 | 
					@ -836,6 +837,13 @@ static int __init enable_mtrr_cleanup_setup(char *str)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
 | 
					early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __init mtrr_cleanup_debug_setup(char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						debug_print = 1;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct var_mtrr_state {
 | 
					struct var_mtrr_state {
 | 
				
			||||||
	unsigned long	range_startk;
 | 
						unsigned long	range_startk;
 | 
				
			||||||
	unsigned long	range_sizek;
 | 
						unsigned long	range_sizek;
 | 
				
			||||||
| 
						 | 
					@ -898,6 +906,27 @@ set_var_mtrr_all(unsigned int address_bits)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned long to_size_factor(unsigned long sizek, char *factorp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char factor;
 | 
				
			||||||
 | 
						unsigned long base = sizek;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (base & ((1<<10) - 1)) {
 | 
				
			||||||
 | 
							/* not MB alignment */
 | 
				
			||||||
 | 
							factor = 'K';
 | 
				
			||||||
 | 
						} else if (base & ((1<<20) - 1)){
 | 
				
			||||||
 | 
							factor = 'M';
 | 
				
			||||||
 | 
							base >>= 10;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							factor = 'G';
 | 
				
			||||||
 | 
							base >>= 20;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*factorp = factor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int __init
 | 
					static unsigned int __init
 | 
				
			||||||
range_to_mtrr(unsigned int reg, unsigned long range_startk,
 | 
					range_to_mtrr(unsigned int reg, unsigned long range_startk,
 | 
				
			||||||
	      unsigned long range_sizek, unsigned char type)
 | 
						      unsigned long range_sizek, unsigned char type)
 | 
				
			||||||
| 
						 | 
					@ -919,13 +948,21 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
 | 
				
			||||||
			align = max_align;
 | 
								align = max_align;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sizek = 1 << align;
 | 
							sizek = 1 << align;
 | 
				
			||||||
		if (debug_print)
 | 
							if (debug_print) {
 | 
				
			||||||
 | 
								char start_factor = 'K', size_factor = 'K';
 | 
				
			||||||
 | 
								unsigned long start_base, size_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								start_base = to_size_factor(range_startk, &start_factor),
 | 
				
			||||||
 | 
								size_base = to_size_factor(sizek, &size_factor),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			printk(KERN_DEBUG "Setting variable MTRR %d, "
 | 
								printk(KERN_DEBUG "Setting variable MTRR %d, "
 | 
				
			||||||
				"base: %ldMB, range: %ldMB, type %s\n",
 | 
									"base: %ld%cB, range: %ld%cB, type %s\n",
 | 
				
			||||||
				reg, range_startk >> 10, sizek >> 10,
 | 
									reg, start_base, start_factor,
 | 
				
			||||||
 | 
									size_base, size_factor,
 | 
				
			||||||
				(type == MTRR_TYPE_UNCACHABLE)?"UC":
 | 
									(type == MTRR_TYPE_UNCACHABLE)?"UC":
 | 
				
			||||||
				    ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
 | 
									    ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
 | 
				
			||||||
				);
 | 
									);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		save_var_mtrr(reg++, range_startk, sizek, type);
 | 
							save_var_mtrr(reg++, range_startk, sizek, type);
 | 
				
			||||||
		range_startk += sizek;
 | 
							range_startk += sizek;
 | 
				
			||||||
		range_sizek -= sizek;
 | 
							range_sizek -= sizek;
 | 
				
			||||||
| 
						 | 
					@ -970,6 +1007,8 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
 | 
				
			||||||
	/* try to append some small hole */
 | 
						/* try to append some small hole */
 | 
				
			||||||
	range0_basek = state->range_startk;
 | 
						range0_basek = state->range_startk;
 | 
				
			||||||
	range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
 | 
						range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* no increase */
 | 
				
			||||||
	if (range0_sizek == state->range_sizek) {
 | 
						if (range0_sizek == state->range_sizek) {
 | 
				
			||||||
		if (debug_print)
 | 
							if (debug_print)
 | 
				
			||||||
			printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
 | 
								printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
 | 
				
			||||||
| 
						 | 
					@ -980,13 +1019,40 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	range0_sizek -= chunk_sizek;
 | 
						/* only cut back, when it is not the last */
 | 
				
			||||||
	if (range0_sizek && sizek) {
 | 
						if (sizek) {
 | 
				
			||||||
	    while (range0_basek + range0_sizek > (basek + sizek)) {
 | 
							while (range0_basek + range0_sizek > (basek + sizek)) {
 | 
				
			||||||
		range0_sizek -= chunk_sizek;
 | 
								if (range0_sizek >= chunk_sizek)
 | 
				
			||||||
		if (!range0_sizek)
 | 
									range0_sizek -= chunk_sizek;
 | 
				
			||||||
			break;
 | 
								else
 | 
				
			||||||
	    }
 | 
									range0_sizek = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!range0_sizek)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					second_try:
 | 
				
			||||||
 | 
						range_basek = range0_basek + range0_sizek;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* one hole in the middle */
 | 
				
			||||||
 | 
						if (range_basek > basek && range_basek <= (basek + sizek))
 | 
				
			||||||
 | 
							second_sizek = range_basek - basek;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (range0_sizek > state->range_sizek) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* one hole in middle or at end */
 | 
				
			||||||
 | 
							hole_sizek = range0_sizek - state->range_sizek - second_sizek;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* hole size should be less than half of range0 size */
 | 
				
			||||||
 | 
							if (hole_sizek >= (range0_sizek >> 1) &&
 | 
				
			||||||
 | 
							    range0_sizek >= chunk_sizek) {
 | 
				
			||||||
 | 
								range0_sizek -= chunk_sizek;
 | 
				
			||||||
 | 
								second_sizek = 0;
 | 
				
			||||||
 | 
								hole_sizek = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								goto second_try;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (range0_sizek) {
 | 
						if (range0_sizek) {
 | 
				
			||||||
| 
						 | 
					@ -996,50 +1062,28 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
 | 
				
			||||||
				(range0_basek + range0_sizek)<<10);
 | 
									(range0_basek + range0_sizek)<<10);
 | 
				
			||||||
		state->reg = range_to_mtrr(state->reg, range0_basek,
 | 
							state->reg = range_to_mtrr(state->reg, range0_basek,
 | 
				
			||||||
				range0_sizek, MTRR_TYPE_WRBACK);
 | 
									range0_sizek, MTRR_TYPE_WRBACK);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	range_basek = range0_basek + range0_sizek;
 | 
						if (range0_sizek < state->range_sizek) {
 | 
				
			||||||
	range_sizek = chunk_sizek;
 | 
							/* need to handle left over */
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (range_basek + range_sizek > basek &&
 | 
					 | 
				
			||||||
	    range_basek + range_sizek <= (basek + sizek)) {
 | 
					 | 
				
			||||||
		/* one hole */
 | 
					 | 
				
			||||||
		second_basek = basek;
 | 
					 | 
				
			||||||
		second_sizek = range_basek + range_sizek - basek;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* if last piece, only could one hole near end */
 | 
					 | 
				
			||||||
	if ((second_basek || !basek) &&
 | 
					 | 
				
			||||||
	    range_sizek - (state->range_sizek - range0_sizek) - second_sizek <
 | 
					 | 
				
			||||||
	    (chunk_sizek >> 1)) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * one hole in middle (second_sizek is 0) or at end
 | 
					 | 
				
			||||||
		 * (second_sizek is 0 )
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		hole_sizek = range_sizek - (state->range_sizek - range0_sizek)
 | 
					 | 
				
			||||||
				 - second_sizek;
 | 
					 | 
				
			||||||
		hole_basek = range_basek + range_sizek - hole_sizek
 | 
					 | 
				
			||||||
				 - second_sizek;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		/* fallback for big hole, or several holes */
 | 
					 | 
				
			||||||
		range_sizek = state->range_sizek - range0_sizek;
 | 
							range_sizek = state->range_sizek - range0_sizek;
 | 
				
			||||||
		second_basek = 0;
 | 
					
 | 
				
			||||||
		second_sizek = 0;
 | 
							if (debug_print)
 | 
				
			||||||
 | 
								printk(KERN_DEBUG "range: %016lx - %016lx\n",
 | 
				
			||||||
 | 
									 range_basek<<10,
 | 
				
			||||||
 | 
									 (range_basek + range_sizek)<<10);
 | 
				
			||||||
 | 
							state->reg = range_to_mtrr(state->reg, range_basek,
 | 
				
			||||||
 | 
									 range_sizek, MTRR_TYPE_WRBACK);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (debug_print)
 | 
					 | 
				
			||||||
		printk(KERN_DEBUG "range: %016lx - %016lx\n", range_basek<<10,
 | 
					 | 
				
			||||||
			 (range_basek + range_sizek)<<10);
 | 
					 | 
				
			||||||
	state->reg = range_to_mtrr(state->reg, range_basek, range_sizek,
 | 
					 | 
				
			||||||
					 MTRR_TYPE_WRBACK);
 | 
					 | 
				
			||||||
	if (hole_sizek) {
 | 
						if (hole_sizek) {
 | 
				
			||||||
 | 
							hole_basek = range_basek - hole_sizek - second_sizek;
 | 
				
			||||||
		if (debug_print)
 | 
							if (debug_print)
 | 
				
			||||||
			printk(KERN_DEBUG "hole: %016lx - %016lx\n",
 | 
								printk(KERN_DEBUG "hole: %016lx - %016lx\n",
 | 
				
			||||||
				 hole_basek<<10, (hole_basek + hole_sizek)<<10);
 | 
									 hole_basek<<10,
 | 
				
			||||||
		state->reg = range_to_mtrr(state->reg, hole_basek, hole_sizek,
 | 
									 (hole_basek + hole_sizek)<<10);
 | 
				
			||||||
						 MTRR_TYPE_UNCACHABLE);
 | 
							state->reg = range_to_mtrr(state->reg, hole_basek,
 | 
				
			||||||
 | 
									 hole_sizek, MTRR_TYPE_UNCACHABLE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return second_sizek;
 | 
						return second_sizek;
 | 
				
			||||||
| 
						 | 
					@ -1154,11 +1198,11 @@ struct mtrr_cleanup_result {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * gran_size: 1M, 2M, ..., 2G
 | 
					 * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
 | 
				
			||||||
 * chunk size: gran_size, ..., 4G
 | 
					 * chunk size: gran_size, ..., 2G
 | 
				
			||||||
 * so we need (2+13)*6
 | 
					 * so we need (1+16)*8
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define NUM_RESULT	90
 | 
					#define NUM_RESULT	136
 | 
				
			||||||
#define PSHIFT		(PAGE_SHIFT - 10)
 | 
					#define PSHIFT		(PAGE_SHIFT - 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
 | 
					static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
 | 
				
			||||||
| 
						 | 
					@ -1168,13 +1212,14 @@ static unsigned long __initdata min_loss_pfn[RANGE_NUM];
 | 
				
			||||||
static int __init mtrr_cleanup(unsigned address_bits)
 | 
					static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long extra_remove_base, extra_remove_size;
 | 
						unsigned long extra_remove_base, extra_remove_size;
 | 
				
			||||||
	unsigned long i, base, size, def, dummy;
 | 
						unsigned long base, size, def, dummy;
 | 
				
			||||||
	mtrr_type type;
 | 
						mtrr_type type;
 | 
				
			||||||
	int nr_range, nr_range_new;
 | 
						int nr_range, nr_range_new;
 | 
				
			||||||
	u64 chunk_size, gran_size;
 | 
						u64 chunk_size, gran_size;
 | 
				
			||||||
	unsigned long range_sums, range_sums_new;
 | 
						unsigned long range_sums, range_sums_new;
 | 
				
			||||||
	int index_good;
 | 
						int index_good;
 | 
				
			||||||
	int num_reg_good;
 | 
						int num_reg_good;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* extra one for all 0 */
 | 
						/* extra one for all 0 */
 | 
				
			||||||
	int num[MTRR_NUM_TYPES + 1];
 | 
						int num[MTRR_NUM_TYPES + 1];
 | 
				
			||||||
| 
						 | 
					@ -1204,6 +1249,8 @@ static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (!size)
 | 
							if (!size)
 | 
				
			||||||
			type = MTRR_NUM_TYPES;
 | 
								type = MTRR_NUM_TYPES;
 | 
				
			||||||
 | 
							if (type == MTRR_TYPE_WRPROT)
 | 
				
			||||||
 | 
								type = MTRR_TYPE_UNCACHABLE;
 | 
				
			||||||
		num[type]++;
 | 
							num[type]++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1216,23 +1263,57 @@ static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
		num_var_ranges - num[MTRR_NUM_TYPES])
 | 
							num_var_ranges - num[MTRR_NUM_TYPES])
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* print original var MTRRs at first, for debugging: */
 | 
				
			||||||
 | 
						printk(KERN_DEBUG "original variable MTRRs\n");
 | 
				
			||||||
 | 
						for (i = 0; i < num_var_ranges; i++) {
 | 
				
			||||||
 | 
							char start_factor = 'K', size_factor = 'K';
 | 
				
			||||||
 | 
							unsigned long start_base, size_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
 | 
				
			||||||
 | 
							if (!size_base)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size_base = to_size_factor(size_base, &size_factor),
 | 
				
			||||||
 | 
							start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
 | 
				
			||||||
 | 
							start_base = to_size_factor(start_base, &start_factor),
 | 
				
			||||||
 | 
							type = range_state[i].type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
 | 
				
			||||||
 | 
								i, start_base, start_factor,
 | 
				
			||||||
 | 
								size_base, size_factor,
 | 
				
			||||||
 | 
								(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
 | 
				
			||||||
 | 
								    ((type == MTRR_TYPE_WRPROT) ? "WP" :
 | 
				
			||||||
 | 
								     ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(range, 0, sizeof(range));
 | 
						memset(range, 0, sizeof(range));
 | 
				
			||||||
	extra_remove_size = 0;
 | 
						extra_remove_size = 0;
 | 
				
			||||||
	if (mtrr_tom2) {
 | 
						extra_remove_base = 1 << (32 - PAGE_SHIFT);
 | 
				
			||||||
		extra_remove_base = 1 << (32 - PAGE_SHIFT);
 | 
						if (mtrr_tom2)
 | 
				
			||||||
		extra_remove_size =
 | 
							extra_remove_size =
 | 
				
			||||||
			(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
 | 
								(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
 | 
						nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
 | 
				
			||||||
					  extra_remove_size);
 | 
										  extra_remove_size);
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * [0, 1M) should always be coverred by var mtrr with WB
 | 
				
			||||||
 | 
						 * and fixed mtrrs should take effective before var mtrr for it
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						nr_range = add_range_with_merge(range, nr_range, 0,
 | 
				
			||||||
 | 
										(1ULL<<(20 - PAGE_SHIFT)) - 1);
 | 
				
			||||||
 | 
						/* sort the ranges */
 | 
				
			||||||
 | 
						sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	range_sums = sum_ranges(range, nr_range);
 | 
						range_sums = sum_ranges(range, nr_range);
 | 
				
			||||||
	printk(KERN_INFO "total RAM coverred: %ldM\n",
 | 
						printk(KERN_INFO "total RAM coverred: %ldM\n",
 | 
				
			||||||
	       range_sums >> (20 - PAGE_SHIFT));
 | 
						       range_sums >> (20 - PAGE_SHIFT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mtrr_chunk_size && mtrr_gran_size) {
 | 
						if (mtrr_chunk_size && mtrr_gran_size) {
 | 
				
			||||||
		int num_reg;
 | 
							int num_reg;
 | 
				
			||||||
 | 
							char gran_factor, chunk_factor, lose_factor;
 | 
				
			||||||
 | 
							unsigned long gran_base, chunk_base, lose_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		debug_print = 1;
 | 
							debug_print++;
 | 
				
			||||||
		/* convert ranges to var ranges state */
 | 
							/* convert ranges to var ranges state */
 | 
				
			||||||
		num_reg = x86_setup_var_mtrrs(range, nr_range, mtrr_chunk_size,
 | 
							num_reg = x86_setup_var_mtrrs(range, nr_range, mtrr_chunk_size,
 | 
				
			||||||
					      mtrr_gran_size);
 | 
										      mtrr_gran_size);
 | 
				
			||||||
| 
						 | 
					@ -1256,34 +1337,48 @@ static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
			result[i].lose_cover_sizek =
 | 
								result[i].lose_cover_sizek =
 | 
				
			||||||
				(range_sums - range_sums_new) << PSHIFT;
 | 
									(range_sums - range_sums_new) << PSHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t",
 | 
							gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
 | 
				
			||||||
			 result[i].bad?"*BAD*":" ", result[i].gran_sizek >> 10,
 | 
							chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
 | 
				
			||||||
			 result[i].chunk_sizek >> 10);
 | 
							lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
 | 
				
			||||||
		printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ldM \n",
 | 
							printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
 | 
				
			||||||
 | 
								 result[i].bad?"*BAD*":" ",
 | 
				
			||||||
 | 
								 gran_base, gran_factor, chunk_base, chunk_factor);
 | 
				
			||||||
 | 
							printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
 | 
				
			||||||
			 result[i].num_reg, result[i].bad?"-":"",
 | 
								 result[i].num_reg, result[i].bad?"-":"",
 | 
				
			||||||
			 result[i].lose_cover_sizek >> 10);
 | 
								 lose_base, lose_factor);
 | 
				
			||||||
		if (!result[i].bad) {
 | 
							if (!result[i].bad) {
 | 
				
			||||||
			set_var_mtrr_all(address_bits);
 | 
								set_var_mtrr_all(address_bits);
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
 | 
							printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
 | 
				
			||||||
		       "will find optimal one\n");
 | 
							       "will find optimal one\n");
 | 
				
			||||||
		debug_print = 0;
 | 
							debug_print--;
 | 
				
			||||||
		memset(result, 0, sizeof(result[0]));
 | 
							memset(result, 0, sizeof(result[0]));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i = 0;
 | 
						i = 0;
 | 
				
			||||||
	memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
 | 
						memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
 | 
				
			||||||
	memset(result, 0, sizeof(result));
 | 
						memset(result, 0, sizeof(result));
 | 
				
			||||||
	for (gran_size = (1ULL<<20); gran_size < (1ULL<<32); gran_size <<= 1) {
 | 
						for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
 | 
				
			||||||
		for (chunk_size = gran_size; chunk_size < (1ULL<<33);
 | 
							char gran_factor;
 | 
				
			||||||
 | 
							unsigned long gran_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (debug_print)
 | 
				
			||||||
 | 
								gran_base = to_size_factor(gran_size >> 10, &gran_factor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (chunk_size = gran_size; chunk_size < (1ULL<<32);
 | 
				
			||||||
		     chunk_size <<= 1) {
 | 
							     chunk_size <<= 1) {
 | 
				
			||||||
			int num_reg;
 | 
								int num_reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (debug_print)
 | 
								if (debug_print) {
 | 
				
			||||||
				printk(KERN_INFO
 | 
									char chunk_factor;
 | 
				
			||||||
			       "\ngran_size: %lldM   chunk_size_size: %lldM\n",
 | 
									unsigned long chunk_base;
 | 
				
			||||||
				       gran_size >> 20, chunk_size >> 20);
 | 
					
 | 
				
			||||||
 | 
									chunk_base = to_size_factor(chunk_size>>10, &chunk_factor),
 | 
				
			||||||
 | 
									printk(KERN_INFO "\n");
 | 
				
			||||||
 | 
									printk(KERN_INFO "gran_size: %ld%c   chunk_size: %ld%c \n",
 | 
				
			||||||
 | 
									       gran_base, gran_factor, chunk_base, chunk_factor);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if (i >= NUM_RESULT)
 | 
								if (i >= NUM_RESULT)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1326,12 +1421,18 @@ static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* print out all */
 | 
						/* print out all */
 | 
				
			||||||
	for (i = 0; i < NUM_RESULT; i++) {
 | 
						for (i = 0; i < NUM_RESULT; i++) {
 | 
				
			||||||
		printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t",
 | 
							char gran_factor, chunk_factor, lose_factor;
 | 
				
			||||||
		       result[i].bad?"*BAD* ":" ", result[i].gran_sizek >> 10,
 | 
							unsigned long gran_base, chunk_base, lose_base;
 | 
				
			||||||
		       result[i].chunk_sizek >> 10);
 | 
					
 | 
				
			||||||
		printk(KERN_CONT "num_reg: %d \tlose RAM: %s%ldM\n",
 | 
							gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
 | 
				
			||||||
		       result[i].num_reg, result[i].bad?"-":"",
 | 
							chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
 | 
				
			||||||
		       result[i].lose_cover_sizek >> 10);
 | 
							lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
 | 
				
			||||||
 | 
							printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
 | 
				
			||||||
 | 
								 result[i].bad?"*BAD*":" ",
 | 
				
			||||||
 | 
								 gran_base, gran_factor, chunk_base, chunk_factor);
 | 
				
			||||||
 | 
							printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
 | 
				
			||||||
 | 
								 result[i].num_reg, result[i].bad?"-":"",
 | 
				
			||||||
 | 
								 lose_base, lose_factor);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* try to find the optimal index */
 | 
						/* try to find the optimal index */
 | 
				
			||||||
| 
						 | 
					@ -1339,10 +1440,8 @@ static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
		nr_mtrr_spare_reg = num_var_ranges - 1;
 | 
							nr_mtrr_spare_reg = num_var_ranges - 1;
 | 
				
			||||||
	num_reg_good = -1;
 | 
						num_reg_good = -1;
 | 
				
			||||||
	for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
 | 
						for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
 | 
				
			||||||
		if (!min_loss_pfn[i]) {
 | 
							if (!min_loss_pfn[i])
 | 
				
			||||||
			num_reg_good = i;
 | 
								num_reg_good = i;
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	index_good = -1;
 | 
						index_good = -1;
 | 
				
			||||||
| 
						 | 
					@ -1358,21 +1457,26 @@ static int __init mtrr_cleanup(unsigned address_bits)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (index_good != -1) {
 | 
						if (index_good != -1) {
 | 
				
			||||||
 | 
							char gran_factor, chunk_factor, lose_factor;
 | 
				
			||||||
 | 
							unsigned long gran_base, chunk_base, lose_base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
 | 
							printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
 | 
				
			||||||
		i = index_good;
 | 
							i = index_good;
 | 
				
			||||||
		printk(KERN_INFO "gran_size: %ldM \tchunk_size: %ldM \t",
 | 
							gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
 | 
				
			||||||
				result[i].gran_sizek >> 10,
 | 
							chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
 | 
				
			||||||
				result[i].chunk_sizek >> 10);
 | 
							lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
 | 
				
			||||||
		printk(KERN_CONT "num_reg: %d \tlose RAM: %ldM\n",
 | 
							printk(KERN_INFO "gran_size: %ld%c \tchunk_size: %ld%c \t",
 | 
				
			||||||
				result[i].num_reg,
 | 
								 gran_base, gran_factor, chunk_base, chunk_factor);
 | 
				
			||||||
				result[i].lose_cover_sizek >> 10);
 | 
							printk(KERN_CONT "num_reg: %d  \tlose RAM: %ld%c\n",
 | 
				
			||||||
 | 
								 result[i].num_reg, lose_base, lose_factor);
 | 
				
			||||||
		/* convert ranges to var ranges state */
 | 
							/* convert ranges to var ranges state */
 | 
				
			||||||
		chunk_size = result[i].chunk_sizek;
 | 
							chunk_size = result[i].chunk_sizek;
 | 
				
			||||||
		chunk_size <<= 10;
 | 
							chunk_size <<= 10;
 | 
				
			||||||
		gran_size = result[i].gran_sizek;
 | 
							gran_size = result[i].gran_sizek;
 | 
				
			||||||
		gran_size <<= 10;
 | 
							gran_size <<= 10;
 | 
				
			||||||
		debug_print = 1;
 | 
							debug_print++;
 | 
				
			||||||
		x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
 | 
							x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
 | 
				
			||||||
 | 
							debug_print--;
 | 
				
			||||||
		set_var_mtrr_all(address_bits);
 | 
							set_var_mtrr_all(address_bits);
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,13 +295,19 @@ static int setup_k7_watchdog(unsigned nmi_hz)
 | 
				
			||||||
	/* setup the timer */
 | 
						/* setup the timer */
 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
	write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz);
 | 
						write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize the wd struct before enabling */
 | 
				
			||||||
 | 
						wd->perfctr_msr = perfctr_msr;
 | 
				
			||||||
 | 
						wd->evntsel_msr = evntsel_msr;
 | 
				
			||||||
 | 
						wd->cccr_msr = 0;  /* unused */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ok, everything is initialized, announce that we're set */
 | 
				
			||||||
 | 
						cpu_nmi_set_wd_enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
						apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
				
			||||||
	evntsel |= K7_EVNTSEL_ENABLE;
 | 
						evntsel |= K7_EVNTSEL_ENABLE;
 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wd->perfctr_msr = perfctr_msr;
 | 
					 | 
				
			||||||
	wd->evntsel_msr = evntsel_msr;
 | 
					 | 
				
			||||||
	wd->cccr_msr = 0;  /* unused */
 | 
					 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -379,13 +385,19 @@ static int setup_p6_watchdog(unsigned nmi_hz)
 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
	nmi_hz = adjust_for_32bit_ctr(nmi_hz);
 | 
						nmi_hz = adjust_for_32bit_ctr(nmi_hz);
 | 
				
			||||||
	write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz);
 | 
						write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* initialize the wd struct before enabling */
 | 
				
			||||||
 | 
						wd->perfctr_msr = perfctr_msr;
 | 
				
			||||||
 | 
						wd->evntsel_msr = evntsel_msr;
 | 
				
			||||||
 | 
						wd->cccr_msr = 0;  /* unused */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ok, everything is initialized, announce that we're set */
 | 
				
			||||||
 | 
						cpu_nmi_set_wd_enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
						apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
				
			||||||
	evntsel |= P6_EVNTSEL0_ENABLE;
 | 
						evntsel |= P6_EVNTSEL0_ENABLE;
 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wd->perfctr_msr = perfctr_msr;
 | 
					 | 
				
			||||||
	wd->evntsel_msr = evntsel_msr;
 | 
					 | 
				
			||||||
	wd->cccr_msr = 0;  /* unused */
 | 
					 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -432,6 +444,27 @@ static const struct wd_ops p6_wd_ops = {
 | 
				
			||||||
#define P4_CCCR_ENABLE		(1 << 12)
 | 
					#define P4_CCCR_ENABLE		(1 << 12)
 | 
				
			||||||
#define P4_CCCR_OVF 		(1 << 31)
 | 
					#define P4_CCCR_OVF 		(1 << 31)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define P4_CONTROLS 18
 | 
				
			||||||
 | 
					static unsigned int p4_controls[18] = {
 | 
				
			||||||
 | 
						MSR_P4_BPU_CCCR0,
 | 
				
			||||||
 | 
						MSR_P4_BPU_CCCR1,
 | 
				
			||||||
 | 
						MSR_P4_BPU_CCCR2,
 | 
				
			||||||
 | 
						MSR_P4_BPU_CCCR3,
 | 
				
			||||||
 | 
						MSR_P4_MS_CCCR0,
 | 
				
			||||||
 | 
						MSR_P4_MS_CCCR1,
 | 
				
			||||||
 | 
						MSR_P4_MS_CCCR2,
 | 
				
			||||||
 | 
						MSR_P4_MS_CCCR3,
 | 
				
			||||||
 | 
						MSR_P4_FLAME_CCCR0,
 | 
				
			||||||
 | 
						MSR_P4_FLAME_CCCR1,
 | 
				
			||||||
 | 
						MSR_P4_FLAME_CCCR2,
 | 
				
			||||||
 | 
						MSR_P4_FLAME_CCCR3,
 | 
				
			||||||
 | 
						MSR_P4_IQ_CCCR0,
 | 
				
			||||||
 | 
						MSR_P4_IQ_CCCR1,
 | 
				
			||||||
 | 
						MSR_P4_IQ_CCCR2,
 | 
				
			||||||
 | 
						MSR_P4_IQ_CCCR3,
 | 
				
			||||||
 | 
						MSR_P4_IQ_CCCR4,
 | 
				
			||||||
 | 
						MSR_P4_IQ_CCCR5,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
 | 
					 * Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
 | 
				
			||||||
 * CRU_ESCR0 (with any non-null event selector) through a complemented
 | 
					 * CRU_ESCR0 (with any non-null event selector) through a complemented
 | 
				
			||||||
| 
						 | 
					@ -473,6 +506,26 @@ static int setup_p4_watchdog(unsigned nmi_hz)
 | 
				
			||||||
		evntsel_msr = MSR_P4_CRU_ESCR0;
 | 
							evntsel_msr = MSR_P4_CRU_ESCR0;
 | 
				
			||||||
		cccr_msr = MSR_P4_IQ_CCCR0;
 | 
							cccr_msr = MSR_P4_IQ_CCCR0;
 | 
				
			||||||
		cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4);
 | 
							cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If we're on the kdump kernel or other situation, we may
 | 
				
			||||||
 | 
							 * still have other performance counter registers set to
 | 
				
			||||||
 | 
							 * interrupt and they'll keep interrupting forever because
 | 
				
			||||||
 | 
							 * of the P4_CCCR_OVF quirk. So we need to ACK all the
 | 
				
			||||||
 | 
							 * pending interrupts and disable all the registers here,
 | 
				
			||||||
 | 
							 * before reenabling the NMI delivery. Refer to p4_rearm()
 | 
				
			||||||
 | 
							 * about the P4_CCCR_OVF quirk.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (reset_devices) {
 | 
				
			||||||
 | 
								unsigned int low, high;
 | 
				
			||||||
 | 
								int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (i = 0; i < P4_CONTROLS; i++) {
 | 
				
			||||||
 | 
									rdmsr(p4_controls[i], low, high);
 | 
				
			||||||
 | 
									low &= ~(P4_CCCR_ENABLE | P4_CCCR_OVF);
 | 
				
			||||||
 | 
									wrmsr(p4_controls[i], low, high);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* logical cpu 1 */
 | 
							/* logical cpu 1 */
 | 
				
			||||||
		perfctr_msr = MSR_P4_IQ_PERFCTR1;
 | 
							perfctr_msr = MSR_P4_IQ_PERFCTR1;
 | 
				
			||||||
| 
						 | 
					@ -499,12 +552,17 @@ static int setup_p4_watchdog(unsigned nmi_hz)
 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
	wrmsr(cccr_msr, cccr_val, 0);
 | 
						wrmsr(cccr_msr, cccr_val, 0);
 | 
				
			||||||
	write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0", nmi_hz);
 | 
						write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0", nmi_hz);
 | 
				
			||||||
	apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
					
 | 
				
			||||||
	cccr_val |= P4_CCCR_ENABLE;
 | 
					 | 
				
			||||||
	wrmsr(cccr_msr, cccr_val, 0);
 | 
					 | 
				
			||||||
	wd->perfctr_msr = perfctr_msr;
 | 
						wd->perfctr_msr = perfctr_msr;
 | 
				
			||||||
	wd->evntsel_msr = evntsel_msr;
 | 
						wd->evntsel_msr = evntsel_msr;
 | 
				
			||||||
	wd->cccr_msr = cccr_msr;
 | 
						wd->cccr_msr = cccr_msr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ok, everything is initialized, announce that we're set */
 | 
				
			||||||
 | 
						cpu_nmi_set_wd_enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
				
			||||||
 | 
						cccr_val |= P4_CCCR_ENABLE;
 | 
				
			||||||
 | 
						wrmsr(cccr_msr, cccr_val, 0);
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -620,13 +678,17 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
	nmi_hz = adjust_for_32bit_ctr(nmi_hz);
 | 
						nmi_hz = adjust_for_32bit_ctr(nmi_hz);
 | 
				
			||||||
	write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0", nmi_hz);
 | 
						write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0", nmi_hz);
 | 
				
			||||||
	apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
					 | 
				
			||||||
	evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
 | 
					 | 
				
			||||||
	wrmsr(evntsel_msr, evntsel, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wd->perfctr_msr = perfctr_msr;
 | 
						wd->perfctr_msr = perfctr_msr;
 | 
				
			||||||
	wd->evntsel_msr = evntsel_msr;
 | 
						wd->evntsel_msr = evntsel_msr;
 | 
				
			||||||
	wd->cccr_msr = 0;  /* unused */
 | 
						wd->cccr_msr = 0;  /* unused */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ok, everything is initialized, announce that we're set */
 | 
				
			||||||
 | 
						cpu_nmi_set_wd_enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apic_write(APIC_LVTPC, APIC_DM_NMI);
 | 
				
			||||||
 | 
						evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
 | 
				
			||||||
 | 
						wrmsr(evntsel_msr, evntsel, 0);
 | 
				
			||||||
	intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
 | 
						intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,6 @@
 | 
				
			||||||
#include <linux/smp_lock.h>
 | 
					#include <linux/smp_lock.h>
 | 
				
			||||||
#include <linux/major.h>
 | 
					#include <linux/major.h>
 | 
				
			||||||
#include <linux/fs.h>
 | 
					#include <linux/fs.h>
 | 
				
			||||||
#include <linux/smp_lock.h>
 | 
					 | 
				
			||||||
#include <linux/device.h>
 | 
					#include <linux/device.h>
 | 
				
			||||||
#include <linux/cpu.h>
 | 
					#include <linux/cpu.h>
 | 
				
			||||||
#include <linux/notifier.h>
 | 
					#include <linux/notifier.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,9 +7,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/errno.h>
 | 
					#include <linux/errno.h>
 | 
				
			||||||
#include <linux/crash_dump.h>
 | 
					#include <linux/crash_dump.h>
 | 
				
			||||||
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					#include <linux/io.h>
 | 
				
			||||||
#include <asm/io.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * copy_oldmem_page - copy one page from "oldmem"
 | 
					 * copy_oldmem_page - copy one page from "oldmem"
 | 
				
			||||||
| 
						 | 
					@ -25,7 +24,7 @@
 | 
				
			||||||
 * in the current kernel. We stitch up a pte, similar to kmap_atomic.
 | 
					 * in the current kernel. We stitch up a pte, similar to kmap_atomic.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 | 
					ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 | 
				
			||||||
                               size_t csize, unsigned long offset, int userbuf)
 | 
							size_t csize, unsigned long offset, int userbuf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void  *vaddr;
 | 
						void  *vaddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,14 +32,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
 | 
						vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
 | 
				
			||||||
 | 
						if (!vaddr)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (userbuf) {
 | 
						if (userbuf) {
 | 
				
			||||||
		if (copy_to_user(buf, (vaddr + offset), csize)) {
 | 
							if (copy_to_user(buf, vaddr + offset, csize)) {
 | 
				
			||||||
			iounmap(vaddr);
 | 
								iounmap(vaddr);
 | 
				
			||||||
			return -EFAULT;
 | 
								return -EFAULT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
	memcpy(buf, (vaddr + offset), csize);
 | 
							memcpy(buf, vaddr + offset, csize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	iounmap(vaddr);
 | 
						iounmap(vaddr);
 | 
				
			||||||
	return csize;
 | 
						return csize;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -414,9 +414,11 @@ void __init efi_init(void)
 | 
				
			||||||
	if (memmap.map == NULL)
 | 
						if (memmap.map == NULL)
 | 
				
			||||||
		printk(KERN_ERR "Could not map the EFI memory map!\n");
 | 
							printk(KERN_ERR "Could not map the EFI memory map!\n");
 | 
				
			||||||
	memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
 | 
						memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (memmap.desc_size != sizeof(efi_memory_desc_t))
 | 
						if (memmap.desc_size != sizeof(efi_memory_desc_t))
 | 
				
			||||||
		printk(KERN_WARNING "Kernel-defined memdesc"
 | 
							printk(KERN_WARNING
 | 
				
			||||||
		       "doesn't match the one from EFI!\n");
 | 
							  "Kernel-defined memdesc doesn't match the one from EFI!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (add_efi_memmap)
 | 
						if (add_efi_memmap)
 | 
				
			||||||
		do_add_efi_memmap();
 | 
							do_add_efi_memmap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,9 +275,9 @@ ENTRY(native_usergs_sysret64)
 | 
				
			||||||
ENTRY(ret_from_fork)
 | 
					ENTRY(ret_from_fork)
 | 
				
			||||||
	CFI_DEFAULT_STACK
 | 
						CFI_DEFAULT_STACK
 | 
				
			||||||
	push kernel_eflags(%rip)
 | 
						push kernel_eflags(%rip)
 | 
				
			||||||
	CFI_ADJUST_CFA_OFFSET 4
 | 
						CFI_ADJUST_CFA_OFFSET 8
 | 
				
			||||||
	popf				# reset kernel eflags
 | 
						popf				# reset kernel eflags
 | 
				
			||||||
	CFI_ADJUST_CFA_OFFSET -4
 | 
						CFI_ADJUST_CFA_OFFSET -8
 | 
				
			||||||
	call schedule_tail
 | 
						call schedule_tail
 | 
				
			||||||
	GET_THREAD_INFO(%rcx)
 | 
						GET_THREAD_INFO(%rcx)
 | 
				
			||||||
	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%rcx)
 | 
						testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%rcx)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,12 +108,11 @@ void __init x86_64_start_kernel(char * real_mode_data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	load_idt((const struct desc_ptr *)&idt_descr);
 | 
						load_idt((const struct desc_ptr *)&idt_descr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	early_printk("Kernel alive\n");
 | 
						if (console_loglevel == 10)
 | 
				
			||||||
 | 
							early_printk("Kernel alive\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	x86_64_init_pda();
 | 
						x86_64_init_pda();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	early_printk("Kernel really alive\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	x86_64_start_reservations(real_mode_data);
 | 
						x86_64_start_reservations(real_mode_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -325,7 +325,7 @@ skip:
 | 
				
			||||||
		for_each_online_cpu(j)
 | 
							for_each_online_cpu(j)
 | 
				
			||||||
			seq_printf(p, "%10u ",
 | 
								seq_printf(p, "%10u ",
 | 
				
			||||||
				per_cpu(irq_stat,j).irq_call_count);
 | 
									per_cpu(irq_stat,j).irq_call_count);
 | 
				
			||||||
		seq_printf(p, "  function call interrupts\n");
 | 
							seq_printf(p, "  Function call interrupts\n");
 | 
				
			||||||
		seq_printf(p, "TLB: ");
 | 
							seq_printf(p, "TLB: ");
 | 
				
			||||||
		for_each_online_cpu(j)
 | 
							for_each_online_cpu(j)
 | 
				
			||||||
			seq_printf(p, "%10u ",
 | 
								seq_printf(p, "%10u ",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,7 +129,7 @@ skip:
 | 
				
			||||||
		seq_printf(p, "CAL: ");
 | 
							seq_printf(p, "CAL: ");
 | 
				
			||||||
		for_each_online_cpu(j)
 | 
							for_each_online_cpu(j)
 | 
				
			||||||
			seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count);
 | 
								seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count);
 | 
				
			||||||
		seq_printf(p, "  function call interrupts\n");
 | 
							seq_printf(p, "  Function call interrupts\n");
 | 
				
			||||||
		seq_printf(p, "TLB: ");
 | 
							seq_printf(p, "TLB: ");
 | 
				
			||||||
		for_each_online_cpu(j)
 | 
							for_each_online_cpu(j)
 | 
				
			||||||
			seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
 | 
								seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,7 +178,7 @@ static void kvm_flush_tlb(void)
 | 
				
			||||||
	kvm_deferred_mmu_op(&ftlb, sizeof ftlb);
 | 
						kvm_deferred_mmu_op(&ftlb, sizeof ftlb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void kvm_release_pt(u32 pfn)
 | 
					static void kvm_release_pt(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct kvm_mmu_op_release_pt rpt = {
 | 
						struct kvm_mmu_op_release_pt rpt = {
 | 
				
			||||||
		.header.op = KVM_MMU_OP_RELEASE_PT,
 | 
							.header.op = KVM_MMU_OP_RELEASE_PT,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -299,6 +299,15 @@ void acpi_nmi_disable(void)
 | 
				
			||||||
		on_each_cpu(__acpi_nmi_disable, NULL, 1);
 | 
							on_each_cpu(__acpi_nmi_disable, NULL, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This function is called as soon the LAPIC NMI watchdog driver has everything
 | 
				
			||||||
 | 
					 * in place and it's ready to check if the NMIs belong to the NMI watchdog
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void cpu_nmi_set_wd_enabled(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						__get_cpu_var(wd_enabled) = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup_apic_nmi_watchdog(void *unused)
 | 
					void setup_apic_nmi_watchdog(void *unused)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (__get_cpu_var(wd_enabled))
 | 
						if (__get_cpu_var(wd_enabled))
 | 
				
			||||||
| 
						 | 
					@ -311,8 +320,6 @@ void setup_apic_nmi_watchdog(void *unused)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (nmi_watchdog) {
 | 
						switch (nmi_watchdog) {
 | 
				
			||||||
	case NMI_LOCAL_APIC:
 | 
						case NMI_LOCAL_APIC:
 | 
				
			||||||
		 /* enable it before to avoid race with handler */
 | 
					 | 
				
			||||||
		__get_cpu_var(wd_enabled) = 1;
 | 
					 | 
				
			||||||
		if (lapic_watchdog_init(nmi_hz) < 0) {
 | 
							if (lapic_watchdog_init(nmi_hz) < 0) {
 | 
				
			||||||
			__get_cpu_var(wd_enabled) = 0;
 | 
								__get_cpu_var(wd_enabled) = 0;
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,12 +190,12 @@ EXPORT_SYMBOL_GPL(olpc_ec_cmd);
 | 
				
			||||||
static void __init platform_detect(void)
 | 
					static void __init platform_detect(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t propsize;
 | 
						size_t propsize;
 | 
				
			||||||
	u32 rev;
 | 
						__be32 rev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ofw("getprop", 4, 1, NULL, "board-revision-int", &rev, 4,
 | 
						if (ofw("getprop", 4, 1, NULL, "board-revision-int", &rev, 4,
 | 
				
			||||||
			&propsize) || propsize != 4) {
 | 
								&propsize) || propsize != 4) {
 | 
				
			||||||
		printk(KERN_ERR "ofw: getprop call failed!\n");
 | 
							printk(KERN_ERR "ofw: getprop call failed!\n");
 | 
				
			||||||
		rev = 0;
 | 
							rev = cpu_to_be32(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	olpc_platform_info.boardrev = be32_to_cpu(rev);
 | 
						olpc_platform_info.boardrev = be32_to_cpu(rev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -203,7 +203,7 @@ static void __init platform_detect(void)
 | 
				
			||||||
static void __init platform_detect(void)
 | 
					static void __init platform_detect(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* stopgap until OFW support is added to the kernel */
 | 
						/* stopgap until OFW support is added to the kernel */
 | 
				
			||||||
	olpc_platform_info.boardrev = be32_to_cpu(0xc2);
 | 
						olpc_platform_info.boardrev = 0xc2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,6 +330,7 @@ struct pv_cpu_ops pv_cpu_ops = {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	.wbinvd = native_wbinvd,
 | 
						.wbinvd = native_wbinvd,
 | 
				
			||||||
	.read_msr = native_read_msr_safe,
 | 
						.read_msr = native_read_msr_safe,
 | 
				
			||||||
 | 
						.read_msr_amd = native_read_msr_amd_safe,
 | 
				
			||||||
	.write_msr = native_write_msr_safe,
 | 
						.write_msr = native_write_msr_safe,
 | 
				
			||||||
	.read_tsc = native_read_tsc,
 | 
						.read_tsc = native_read_tsc,
 | 
				
			||||||
	.read_pmc = native_read_pmc,
 | 
						.read_pmc = native_read_pmc,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
 | 
				
			||||||
			start = start_##ops##_##x;		\
 | 
								start = start_##ops##_##x;		\
 | 
				
			||||||
			end = end_##ops##_##x;			\
 | 
								end = end_##ops##_##x;			\
 | 
				
			||||||
			goto patch_site
 | 
								goto patch_site
 | 
				
			||||||
	switch(type) {
 | 
						switch (type) {
 | 
				
			||||||
		PATCH_SITE(pv_irq_ops, irq_disable);
 | 
							PATCH_SITE(pv_irq_ops, irq_disable);
 | 
				
			||||||
		PATCH_SITE(pv_irq_ops, irq_enable);
 | 
							PATCH_SITE(pv_irq_ops, irq_enable);
 | 
				
			||||||
		PATCH_SITE(pv_irq_ops, restore_fl);
 | 
							PATCH_SITE(pv_irq_ops, restore_fl);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,7 @@ void __init dma32_reserve_bootmem(void)
 | 
				
			||||||
	 * using 512M as goal
 | 
						 * using 512M as goal
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	align = 64ULL<<20;
 | 
						align = 64ULL<<20;
 | 
				
			||||||
	size = round_up(dma32_bootmem_size, align);
 | 
						size = roundup(dma32_bootmem_size, align);
 | 
				
			||||||
	dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
 | 
						dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
 | 
				
			||||||
				 512ULL<<20);
 | 
									 512ULL<<20);
 | 
				
			||||||
	if (dma32_bootmem_ptr)
 | 
						if (dma32_bootmem_ptr)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,8 @@ AGPEXTERN __u32 *agp_gatt_table;
 | 
				
			||||||
static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
 | 
					static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
 | 
				
			||||||
static int need_flush;		/* global flush state. set for each gart wrap */
 | 
					static int need_flush;		/* global flush state. set for each gart wrap */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned long alloc_iommu(struct device *dev, int size)
 | 
					static unsigned long alloc_iommu(struct device *dev, int size,
 | 
				
			||||||
 | 
									 unsigned long align_mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long offset, flags;
 | 
						unsigned long offset, flags;
 | 
				
			||||||
	unsigned long boundary_size;
 | 
						unsigned long boundary_size;
 | 
				
			||||||
| 
						 | 
					@ -90,16 +91,17 @@ static unsigned long alloc_iommu(struct device *dev, int size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
 | 
						base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
 | 
				
			||||||
			   PAGE_SIZE) >> PAGE_SHIFT;
 | 
								   PAGE_SIZE) >> PAGE_SHIFT;
 | 
				
			||||||
	boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
 | 
						boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
 | 
				
			||||||
			      PAGE_SIZE) >> PAGE_SHIFT;
 | 
								      PAGE_SIZE) >> PAGE_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&iommu_bitmap_lock, flags);
 | 
						spin_lock_irqsave(&iommu_bitmap_lock, flags);
 | 
				
			||||||
	offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
 | 
						offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
 | 
				
			||||||
				  size, base_index, boundary_size, 0);
 | 
									  size, base_index, boundary_size, align_mask);
 | 
				
			||||||
	if (offset == -1) {
 | 
						if (offset == -1) {
 | 
				
			||||||
		need_flush = 1;
 | 
							need_flush = 1;
 | 
				
			||||||
		offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
 | 
							offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
 | 
				
			||||||
					  size, base_index, boundary_size, 0);
 | 
										  size, base_index, boundary_size,
 | 
				
			||||||
 | 
										  align_mask);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (offset != -1) {
 | 
						if (offset != -1) {
 | 
				
			||||||
		next_bit = offset+size;
 | 
							next_bit = offset+size;
 | 
				
			||||||
| 
						 | 
					@ -236,10 +238,10 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
 | 
				
			||||||
 * Caller needs to check if the iommu is needed and flush.
 | 
					 * Caller needs to check if the iommu is needed and flush.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
 | 
					static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
 | 
				
			||||||
				size_t size, int dir)
 | 
									size_t size, int dir, unsigned long align_mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long npages = iommu_num_pages(phys_mem, size);
 | 
						unsigned long npages = iommu_num_pages(phys_mem, size);
 | 
				
			||||||
	unsigned long iommu_page = alloc_iommu(dev, npages);
 | 
						unsigned long iommu_page = alloc_iommu(dev, npages, align_mask);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (iommu_page == -1) {
 | 
						if (iommu_page == -1) {
 | 
				
			||||||
| 
						 | 
					@ -262,7 +264,11 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
 | 
				
			||||||
static dma_addr_t
 | 
					static dma_addr_t
 | 
				
			||||||
gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir)
 | 
					gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dma_addr_t map = dma_map_area(dev, paddr, size, dir);
 | 
						dma_addr_t map;
 | 
				
			||||||
 | 
						unsigned long align_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						align_mask = (1UL << get_order(size)) - 1;
 | 
				
			||||||
 | 
						map = dma_map_area(dev, paddr, size, dir, align_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush_gart();
 | 
						flush_gart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,7 +287,8 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
 | 
				
			||||||
	if (!need_iommu(dev, paddr, size))
 | 
						if (!need_iommu(dev, paddr, size))
 | 
				
			||||||
		return paddr;
 | 
							return paddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bus = gart_map_simple(dev, paddr, size, dir);
 | 
						bus = dma_map_area(dev, paddr, size, dir, 0);
 | 
				
			||||||
 | 
						flush_gart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return bus;
 | 
						return bus;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -340,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 | 
				
			||||||
		unsigned long addr = sg_phys(s);
 | 
							unsigned long addr = sg_phys(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (nonforced_iommu(dev, addr, s->length)) {
 | 
							if (nonforced_iommu(dev, addr, s->length)) {
 | 
				
			||||||
			addr = dma_map_area(dev, addr, s->length, dir);
 | 
								addr = dma_map_area(dev, addr, s->length, dir, 0);
 | 
				
			||||||
			if (addr == bad_dma_address) {
 | 
								if (addr == bad_dma_address) {
 | 
				
			||||||
				if (i > 0)
 | 
									if (i > 0)
 | 
				
			||||||
					gart_unmap_sg(dev, sg, i, dir);
 | 
										gart_unmap_sg(dev, sg, i, dir);
 | 
				
			||||||
| 
						 | 
					@ -362,7 +369,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
 | 
				
			||||||
			  int nelems, struct scatterlist *sout,
 | 
								  int nelems, struct scatterlist *sout,
 | 
				
			||||||
			  unsigned long pages)
 | 
								  unsigned long pages)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long iommu_start = alloc_iommu(dev, pages);
 | 
						unsigned long iommu_start = alloc_iommu(dev, pages, 0);
 | 
				
			||||||
	unsigned long iommu_page = iommu_start;
 | 
						unsigned long iommu_page = iommu_start;
 | 
				
			||||||
	struct scatterlist *s;
 | 
						struct scatterlist *s;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -626,7 +633,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
 | 
				
			||||||
	struct pci_dev *dev;
 | 
						struct pci_dev *dev;
 | 
				
			||||||
	void *gatt;
 | 
						void *gatt;
 | 
				
			||||||
	int i, error;
 | 
						int i, error;
 | 
				
			||||||
	unsigned long start_pfn, end_pfn;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
 | 
						printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
 | 
				
			||||||
	aper_size = aper_base = info->aper_size = 0;
 | 
						aper_size = aper_base = info->aper_size = 0;
 | 
				
			||||||
| 
						 | 
					@ -672,12 +678,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
 | 
				
			||||||
	printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
 | 
						printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
 | 
				
			||||||
	       aper_base, aper_size>>10);
 | 
						       aper_base, aper_size>>10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* need to map that range */
 | 
					 | 
				
			||||||
	end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
 | 
					 | 
				
			||||||
	if (end_pfn > max_low_pfn_mapped) {
 | 
					 | 
				
			||||||
		start_pfn = (aper_base>>PAGE_SHIFT);
 | 
					 | 
				
			||||||
		init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 nommu:
 | 
					 nommu:
 | 
				
			||||||
| 
						 | 
					@ -727,7 +727,8 @@ void __init gart_iommu_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct agp_kern_info info;
 | 
						struct agp_kern_info info;
 | 
				
			||||||
	unsigned long iommu_start;
 | 
						unsigned long iommu_start;
 | 
				
			||||||
	unsigned long aper_size;
 | 
						unsigned long aper_base, aper_size;
 | 
				
			||||||
 | 
						unsigned long start_pfn, end_pfn;
 | 
				
			||||||
	unsigned long scratch;
 | 
						unsigned long scratch;
 | 
				
			||||||
	long i;
 | 
						long i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -765,8 +766,16 @@ void __init gart_iommu_init(void)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* need to map that range */
 | 
				
			||||||
 | 
						aper_size = info.aper_size << 20;
 | 
				
			||||||
 | 
						aper_base = info.aper_base;
 | 
				
			||||||
 | 
						end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
 | 
				
			||||||
 | 
						if (end_pfn > max_low_pfn_mapped) {
 | 
				
			||||||
 | 
							start_pfn = (aper_base>>PAGE_SHIFT);
 | 
				
			||||||
 | 
							init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
 | 
						printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
 | 
				
			||||||
	aper_size = info.aper_size * 1024 * 1024;
 | 
					 | 
				
			||||||
	iommu_size = check_iommu_size(info.aper_base, aper_size);
 | 
						iommu_size = check_iommu_size(info.aper_base, aper_size);
 | 
				
			||||||
	iommu_pages = iommu_size >> PAGE_SHIFT;
 | 
						iommu_pages = iommu_size >> PAGE_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,13 @@
 | 
				
			||||||
#include <linux/platform_device.h>
 | 
					#include <linux/platform_device.h>
 | 
				
			||||||
#include <linux/errno.h>
 | 
					#include <linux/err.h>
 | 
				
			||||||
#include <linux/init.h>
 | 
					#include <linux/init.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __init int add_pcspkr(void)
 | 
					static __init int add_pcspkr(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct platform_device *pd;
 | 
						struct platform_device *pd;
 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pd = platform_device_alloc("pcspkr", -1);
 | 
						pd = platform_device_register_simple("pcspkr", -1, NULL, 0);
 | 
				
			||||||
	if (!pd)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = platform_device_add(pd);
 | 
						return IS_ERR(pd) ? PTR_ERR(pd) : 0;
 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		platform_device_put(pd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
device_initcall(add_pcspkr);
 | 
					device_initcall(add_pcspkr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -185,7 +185,8 @@ static void mwait_idle(void)
 | 
				
			||||||
static void poll_idle(void)
 | 
					static void poll_idle(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local_irq_enable();
 | 
						local_irq_enable();
 | 
				
			||||||
	cpu_relax();
 | 
						while (!need_resched())
 | 
				
			||||||
 | 
							cpu_relax();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#include <linux/tick.h>
 | 
					#include <linux/tick.h>
 | 
				
			||||||
#include <linux/percpu.h>
 | 
					#include <linux/percpu.h>
 | 
				
			||||||
#include <linux/prctl.h>
 | 
					#include <linux/prctl.h>
 | 
				
			||||||
 | 
					#include <linux/dmi.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					#include <asm/uaccess.h>
 | 
				
			||||||
#include <asm/pgtable.h>
 | 
					#include <asm/pgtable.h>
 | 
				
			||||||
| 
						 | 
					@ -163,6 +164,7 @@ void __show_registers(struct pt_regs *regs, int all)
 | 
				
			||||||
	unsigned long d0, d1, d2, d3, d6, d7;
 | 
						unsigned long d0, d1, d2, d3, d6, d7;
 | 
				
			||||||
	unsigned long sp;
 | 
						unsigned long sp;
 | 
				
			||||||
	unsigned short ss, gs;
 | 
						unsigned short ss, gs;
 | 
				
			||||||
 | 
						const char *board;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (user_mode_vm(regs)) {
 | 
						if (user_mode_vm(regs)) {
 | 
				
			||||||
		sp = regs->sp;
 | 
							sp = regs->sp;
 | 
				
			||||||
| 
						 | 
					@ -175,11 +177,15 @@ void __show_registers(struct pt_regs *regs, int all)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk("\n");
 | 
						printk("\n");
 | 
				
			||||||
	printk("Pid: %d, comm: %s %s (%s %.*s)\n",
 | 
					
 | 
				
			||||||
 | 
						board = dmi_get_system_info(DMI_PRODUCT_NAME);
 | 
				
			||||||
 | 
						if (!board)
 | 
				
			||||||
 | 
							board = "";
 | 
				
			||||||
 | 
						printk("Pid: %d, comm: %s %s (%s %.*s) %s\n",
 | 
				
			||||||
			task_pid_nr(current), current->comm,
 | 
								task_pid_nr(current), current->comm,
 | 
				
			||||||
			print_tainted(), init_utsname()->release,
 | 
								print_tainted(), init_utsname()->release,
 | 
				
			||||||
			(int)strcspn(init_utsname()->version, " "),
 | 
								(int)strcspn(init_utsname()->version, " "),
 | 
				
			||||||
			init_utsname()->version);
 | 
								init_utsname()->version, board);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
 | 
						printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
 | 
				
			||||||
			(u16)regs->cs, regs->ip, regs->flags,
 | 
								(u16)regs->cs, regs->ip, regs->flags,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,11 +37,11 @@
 | 
				
			||||||
#include <linux/kdebug.h>
 | 
					#include <linux/kdebug.h>
 | 
				
			||||||
#include <linux/tick.h>
 | 
					#include <linux/tick.h>
 | 
				
			||||||
#include <linux/prctl.h>
 | 
					#include <linux/prctl.h>
 | 
				
			||||||
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
 | 
					#include <linux/io.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					 | 
				
			||||||
#include <asm/pgtable.h>
 | 
					#include <asm/pgtable.h>
 | 
				
			||||||
#include <asm/system.h>
 | 
					#include <asm/system.h>
 | 
				
			||||||
#include <asm/io.h>
 | 
					 | 
				
			||||||
#include <asm/processor.h>
 | 
					#include <asm/processor.h>
 | 
				
			||||||
#include <asm/i387.h>
 | 
					#include <asm/i387.h>
 | 
				
			||||||
#include <asm/mmu_context.h>
 | 
					#include <asm/mmu_context.h>
 | 
				
			||||||
| 
						 | 
					@ -89,7 +89,7 @@ void exit_idle(void)
 | 
				
			||||||
#ifdef CONFIG_HOTPLUG_CPU
 | 
					#ifdef CONFIG_HOTPLUG_CPU
 | 
				
			||||||
DECLARE_PER_CPU(int, cpu_state);
 | 
					DECLARE_PER_CPU(int, cpu_state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/nmi.h>
 | 
					#include <linux/nmi.h>
 | 
				
			||||||
/* We halt the CPU with physical CPU hotplug */
 | 
					/* We halt the CPU with physical CPU hotplug */
 | 
				
			||||||
static inline void play_dead(void)
 | 
					static inline void play_dead(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -154,7 +154,7 @@ void cpu_idle(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Prints also some state that isn't saved in the pt_regs */
 | 
					/* Prints also some state that isn't saved in the pt_regs */
 | 
				
			||||||
void __show_regs(struct pt_regs * regs)
 | 
					void __show_regs(struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
 | 
						unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
 | 
				
			||||||
	unsigned long d0, d1, d2, d3, d6, d7;
 | 
						unsigned long d0, d1, d2, d3, d6, d7;
 | 
				
			||||||
| 
						 | 
					@ -163,59 +163,61 @@ void __show_regs(struct pt_regs * regs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk("\n");
 | 
						printk("\n");
 | 
				
			||||||
	print_modules();
 | 
						print_modules();
 | 
				
			||||||
	printk("Pid: %d, comm: %.20s %s %s %.*s\n",
 | 
						printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n",
 | 
				
			||||||
		current->pid, current->comm, print_tainted(),
 | 
							current->pid, current->comm, print_tainted(),
 | 
				
			||||||
		init_utsname()->release,
 | 
							init_utsname()->release,
 | 
				
			||||||
		(int)strcspn(init_utsname()->version, " "),
 | 
							(int)strcspn(init_utsname()->version, " "),
 | 
				
			||||||
		init_utsname()->version);
 | 
							init_utsname()->version);
 | 
				
			||||||
	printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
 | 
						printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
 | 
				
			||||||
	printk_address(regs->ip, 1);
 | 
						printk_address(regs->ip, 1);
 | 
				
			||||||
	printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->sp,
 | 
						printk(KERN_INFO "RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss,
 | 
				
			||||||
		regs->flags);
 | 
								regs->sp, regs->flags);
 | 
				
			||||||
	printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
 | 
						printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
 | 
				
			||||||
	       regs->ax, regs->bx, regs->cx);
 | 
						       regs->ax, regs->bx, regs->cx);
 | 
				
			||||||
	printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
 | 
						printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n",
 | 
				
			||||||
	       regs->dx, regs->si, regs->di);
 | 
						       regs->dx, regs->si, regs->di);
 | 
				
			||||||
	printk("RBP: %016lx R08: %016lx R09: %016lx\n",
 | 
						printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
 | 
				
			||||||
	       regs->bp, regs->r8, regs->r9);
 | 
						       regs->bp, regs->r8, regs->r9);
 | 
				
			||||||
	printk("R10: %016lx R11: %016lx R12: %016lx\n",
 | 
						printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
 | 
				
			||||||
	       regs->r10, regs->r11, regs->r12); 
 | 
						       regs->r10, regs->r11, regs->r12);
 | 
				
			||||||
	printk("R13: %016lx R14: %016lx R15: %016lx\n",
 | 
						printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
 | 
				
			||||||
	       regs->r13, regs->r14, regs->r15); 
 | 
						       regs->r13, regs->r14, regs->r15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asm("movl %%ds,%0" : "=r" (ds)); 
 | 
						asm("movl %%ds,%0" : "=r" (ds));
 | 
				
			||||||
	asm("movl %%cs,%0" : "=r" (cs)); 
 | 
						asm("movl %%cs,%0" : "=r" (cs));
 | 
				
			||||||
	asm("movl %%es,%0" : "=r" (es)); 
 | 
						asm("movl %%es,%0" : "=r" (es));
 | 
				
			||||||
	asm("movl %%fs,%0" : "=r" (fsindex));
 | 
						asm("movl %%fs,%0" : "=r" (fsindex));
 | 
				
			||||||
	asm("movl %%gs,%0" : "=r" (gsindex));
 | 
						asm("movl %%gs,%0" : "=r" (gsindex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rdmsrl(MSR_FS_BASE, fs);
 | 
						rdmsrl(MSR_FS_BASE, fs);
 | 
				
			||||||
	rdmsrl(MSR_GS_BASE, gs); 
 | 
						rdmsrl(MSR_GS_BASE, gs);
 | 
				
			||||||
	rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 
 | 
						rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cr0 = read_cr0();
 | 
						cr0 = read_cr0();
 | 
				
			||||||
	cr2 = read_cr2();
 | 
						cr2 = read_cr2();
 | 
				
			||||||
	cr3 = read_cr3();
 | 
						cr3 = read_cr3();
 | 
				
			||||||
	cr4 = read_cr4();
 | 
						cr4 = read_cr4();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk("FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", 
 | 
						printk(KERN_INFO "FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
 | 
				
			||||||
	       fs,fsindex,gs,gsindex,shadowgs); 
 | 
						       fs, fsindex, gs, gsindex, shadowgs);
 | 
				
			||||||
	printk("CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); 
 | 
						printk(KERN_INFO "CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
 | 
				
			||||||
	printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
 | 
								es, cr0);
 | 
				
			||||||
 | 
						printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
 | 
				
			||||||
 | 
								cr4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	get_debugreg(d0, 0);
 | 
						get_debugreg(d0, 0);
 | 
				
			||||||
	get_debugreg(d1, 1);
 | 
						get_debugreg(d1, 1);
 | 
				
			||||||
	get_debugreg(d2, 2);
 | 
						get_debugreg(d2, 2);
 | 
				
			||||||
	printk("DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
 | 
						printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
 | 
				
			||||||
	get_debugreg(d3, 3);
 | 
						get_debugreg(d3, 3);
 | 
				
			||||||
	get_debugreg(d6, 6);
 | 
						get_debugreg(d6, 6);
 | 
				
			||||||
	get_debugreg(d7, 7);
 | 
						get_debugreg(d7, 7);
 | 
				
			||||||
	printk("DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
 | 
						printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void show_regs(struct pt_regs *regs)
 | 
					void show_regs(struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk("CPU %d:", smp_processor_id());
 | 
						printk(KERN_INFO "CPU %d:", smp_processor_id());
 | 
				
			||||||
	__show_regs(regs);
 | 
						__show_regs(regs);
 | 
				
			||||||
	show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
 | 
						show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -324,10 +326,10 @@ void prepare_to_copy(struct task_struct *tsk)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 | 
					int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 | 
				
			||||||
		unsigned long unused,
 | 
							unsigned long unused,
 | 
				
			||||||
	struct task_struct * p, struct pt_regs * regs)
 | 
						struct task_struct *p, struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	struct pt_regs * childregs;
 | 
						struct pt_regs *childregs;
 | 
				
			||||||
	struct task_struct *me = current;
 | 
						struct task_struct *me = current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	childregs = ((struct pt_regs *)
 | 
						childregs = ((struct pt_regs *)
 | 
				
			||||||
| 
						 | 
					@ -372,10 +374,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 | 
				
			||||||
		if (test_thread_flag(TIF_IA32))
 | 
							if (test_thread_flag(TIF_IA32))
 | 
				
			||||||
			err = do_set_thread_area(p, -1,
 | 
								err = do_set_thread_area(p, -1,
 | 
				
			||||||
				(struct user_desc __user *)childregs->si, 0);
 | 
									(struct user_desc __user *)childregs->si, 0);
 | 
				
			||||||
		else 			
 | 
							else
 | 
				
			||||||
#endif	 
 | 
					#endif
 | 
				
			||||||
			err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 
 | 
								err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
 | 
				
			||||||
		if (err) 
 | 
							if (err)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = 0;
 | 
						err = 0;
 | 
				
			||||||
| 
						 | 
					@ -568,7 +570,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 | 
				
			||||||
	unsigned fsindex, gsindex;
 | 
						unsigned fsindex, gsindex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* we're going to use this soon, after a few expensive things */
 | 
						/* we're going to use this soon, after a few expensive things */
 | 
				
			||||||
	if (next_p->fpu_counter>5)
 | 
						if (next_p->fpu_counter > 5)
 | 
				
			||||||
		prefetch(next->xstate);
 | 
							prefetch(next->xstate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -576,13 +578,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	load_sp0(tss, next);
 | 
						load_sp0(tss, next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* 
 | 
						/*
 | 
				
			||||||
	 * Switch DS and ES.
 | 
						 * Switch DS and ES.
 | 
				
			||||||
	 * This won't pick up thread selector changes, but I guess that is ok.
 | 
						 * This won't pick up thread selector changes, but I guess that is ok.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	savesegment(es, prev->es);
 | 
						savesegment(es, prev->es);
 | 
				
			||||||
	if (unlikely(next->es | prev->es))
 | 
						if (unlikely(next->es | prev->es))
 | 
				
			||||||
		loadsegment(es, next->es); 
 | 
							loadsegment(es, next->es);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	savesegment(ds, prev->ds);
 | 
						savesegment(ds, prev->ds);
 | 
				
			||||||
	if (unlikely(next->ds | prev->ds))
 | 
						if (unlikely(next->ds | prev->ds))
 | 
				
			||||||
| 
						 | 
					@ -608,7 +610,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	arch_leave_lazy_cpu_mode();
 | 
						arch_leave_lazy_cpu_mode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* 
 | 
						/*
 | 
				
			||||||
	 * Switch FS and GS.
 | 
						 * Switch FS and GS.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * Segment register != 0 always requires a reload.  Also
 | 
						 * Segment register != 0 always requires a reload.  Also
 | 
				
			||||||
| 
						 | 
					@ -617,13 +619,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (unlikely(fsindex | next->fsindex | prev->fs)) {
 | 
						if (unlikely(fsindex | next->fsindex | prev->fs)) {
 | 
				
			||||||
		loadsegment(fs, next->fsindex);
 | 
							loadsegment(fs, next->fsindex);
 | 
				
			||||||
		/* 
 | 
							/*
 | 
				
			||||||
		 * Check if the user used a selector != 0; if yes
 | 
							 * Check if the user used a selector != 0; if yes
 | 
				
			||||||
		 *  clear 64bit base, since overloaded base is always
 | 
							 *  clear 64bit base, since overloaded base is always
 | 
				
			||||||
		 *  mapped to the Null selector
 | 
							 *  mapped to the Null selector
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (fsindex)
 | 
							if (fsindex)
 | 
				
			||||||
			prev->fs = 0;				
 | 
								prev->fs = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* when next process has a 64bit base use it */
 | 
						/* when next process has a 64bit base use it */
 | 
				
			||||||
	if (next->fs)
 | 
						if (next->fs)
 | 
				
			||||||
| 
						 | 
					@ -633,7 +635,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 | 
				
			||||||
	if (unlikely(gsindex | next->gsindex | prev->gs)) {
 | 
						if (unlikely(gsindex | next->gsindex | prev->gs)) {
 | 
				
			||||||
		load_gs_index(next->gsindex);
 | 
							load_gs_index(next->gsindex);
 | 
				
			||||||
		if (gsindex)
 | 
							if (gsindex)
 | 
				
			||||||
			prev->gs = 0;				
 | 
								prev->gs = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (next->gs)
 | 
						if (next->gs)
 | 
				
			||||||
		wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
 | 
							wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
 | 
				
			||||||
| 
						 | 
					@ -642,12 +644,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 | 
				
			||||||
	/* Must be after DS reload */
 | 
						/* Must be after DS reload */
 | 
				
			||||||
	unlazy_fpu(prev_p);
 | 
						unlazy_fpu(prev_p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* 
 | 
						/*
 | 
				
			||||||
	 * Switch the PDA and FPU contexts.
 | 
						 * Switch the PDA and FPU contexts.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	prev->usersp = read_pda(oldrsp);
 | 
						prev->usersp = read_pda(oldrsp);
 | 
				
			||||||
	write_pda(oldrsp, next->usersp);
 | 
						write_pda(oldrsp, next->usersp);
 | 
				
			||||||
	write_pda(pcurrent, next_p); 
 | 
						write_pda(pcurrent, next_p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	write_pda(kernelstack,
 | 
						write_pda(kernelstack,
 | 
				
			||||||
		  (unsigned long)task_stack_page(next_p) +
 | 
							  (unsigned long)task_stack_page(next_p) +
 | 
				
			||||||
| 
						 | 
					@ -688,7 +690,7 @@ long sys_execve(char __user *name, char __user * __user *argv,
 | 
				
			||||||
		char __user * __user *envp, struct pt_regs *regs)
 | 
							char __user * __user *envp, struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	long error;
 | 
						long error;
 | 
				
			||||||
	char * filename;
 | 
						char *filename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	filename = getname(name);
 | 
						filename = getname(name);
 | 
				
			||||||
	error = PTR_ERR(filename);
 | 
						error = PTR_ERR(filename);
 | 
				
			||||||
| 
						 | 
					@ -746,55 +748,55 @@ asmlinkage long sys_vfork(struct pt_regs *regs)
 | 
				
			||||||
unsigned long get_wchan(struct task_struct *p)
 | 
					unsigned long get_wchan(struct task_struct *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long stack;
 | 
						unsigned long stack;
 | 
				
			||||||
	u64 fp,ip;
 | 
						u64 fp, ip;
 | 
				
			||||||
	int count = 0;
 | 
						int count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!p || p == current || p->state==TASK_RUNNING)
 | 
						if (!p || p == current || p->state == TASK_RUNNING)
 | 
				
			||||||
		return 0; 
 | 
							return 0;
 | 
				
			||||||
	stack = (unsigned long)task_stack_page(p);
 | 
						stack = (unsigned long)task_stack_page(p);
 | 
				
			||||||
	if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
 | 
						if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	fp = *(u64 *)(p->thread.sp);
 | 
						fp = *(u64 *)(p->thread.sp);
 | 
				
			||||||
	do { 
 | 
						do {
 | 
				
			||||||
		if (fp < (unsigned long)stack ||
 | 
							if (fp < (unsigned long)stack ||
 | 
				
			||||||
		    fp > (unsigned long)stack+THREAD_SIZE)
 | 
							    fp > (unsigned long)stack+THREAD_SIZE)
 | 
				
			||||||
			return 0; 
 | 
								return 0;
 | 
				
			||||||
		ip = *(u64 *)(fp+8);
 | 
							ip = *(u64 *)(fp+8);
 | 
				
			||||||
		if (!in_sched_functions(ip))
 | 
							if (!in_sched_functions(ip))
 | 
				
			||||||
			return ip;
 | 
								return ip;
 | 
				
			||||||
		fp = *(u64 *)fp; 
 | 
							fp = *(u64 *)fp;
 | 
				
			||||||
	} while (count++ < 16); 
 | 
						} while (count++ < 16);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 | 
					long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 | 
				
			||||||
{ 
 | 
					{
 | 
				
			||||||
	int ret = 0; 
 | 
						int ret = 0;
 | 
				
			||||||
	int doit = task == current;
 | 
						int doit = task == current;
 | 
				
			||||||
	int cpu;
 | 
						int cpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (code) { 
 | 
						switch (code) {
 | 
				
			||||||
	case ARCH_SET_GS:
 | 
						case ARCH_SET_GS:
 | 
				
			||||||
		if (addr >= TASK_SIZE_OF(task))
 | 
							if (addr >= TASK_SIZE_OF(task))
 | 
				
			||||||
			return -EPERM; 
 | 
								return -EPERM;
 | 
				
			||||||
		cpu = get_cpu();
 | 
							cpu = get_cpu();
 | 
				
			||||||
		/* handle small bases via the GDT because that's faster to 
 | 
							/* handle small bases via the GDT because that's faster to
 | 
				
			||||||
		   switch. */
 | 
							   switch. */
 | 
				
			||||||
		if (addr <= 0xffffffff) {  
 | 
							if (addr <= 0xffffffff) {
 | 
				
			||||||
			set_32bit_tls(task, GS_TLS, addr); 
 | 
								set_32bit_tls(task, GS_TLS, addr);
 | 
				
			||||||
			if (doit) { 
 | 
								if (doit) {
 | 
				
			||||||
				load_TLS(&task->thread, cpu);
 | 
									load_TLS(&task->thread, cpu);
 | 
				
			||||||
				load_gs_index(GS_TLS_SEL); 
 | 
									load_gs_index(GS_TLS_SEL);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			task->thread.gsindex = GS_TLS_SEL; 
 | 
								task->thread.gsindex = GS_TLS_SEL;
 | 
				
			||||||
			task->thread.gs = 0;
 | 
								task->thread.gs = 0;
 | 
				
			||||||
		} else { 
 | 
							} else {
 | 
				
			||||||
			task->thread.gsindex = 0;
 | 
								task->thread.gsindex = 0;
 | 
				
			||||||
			task->thread.gs = addr;
 | 
								task->thread.gs = addr;
 | 
				
			||||||
			if (doit) {
 | 
								if (doit) {
 | 
				
			||||||
				load_gs_index(0);
 | 
									load_gs_index(0);
 | 
				
			||||||
				ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
 | 
									ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
 | 
				
			||||||
			} 
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		put_cpu();
 | 
							put_cpu();
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -848,8 +850,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 | 
				
			||||||
				rdmsrl(MSR_KERNEL_GS_BASE, base);
 | 
									rdmsrl(MSR_KERNEL_GS_BASE, base);
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				base = task->thread.gs;
 | 
									base = task->thread.gs;
 | 
				
			||||||
		}
 | 
							} else
 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			base = task->thread.gs;
 | 
								base = task->thread.gs;
 | 
				
			||||||
		ret = put_user(base, (unsigned long __user *)addr);
 | 
							ret = put_user(base, (unsigned long __user *)addr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,11 @@ EXPORT_SYMBOL(pm_power_off);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct desc_ptr no_idt = {};
 | 
					static const struct desc_ptr no_idt = {};
 | 
				
			||||||
static int reboot_mode;
 | 
					static int reboot_mode;
 | 
				
			||||||
enum reboot_type reboot_type = BOOT_KBD;
 | 
					/*
 | 
				
			||||||
 | 
					 * Keyboard reset and triple fault may result in INIT, not RESET, which
 | 
				
			||||||
 | 
					 * doesn't work when we're in vmx root mode.  Try ACPI first.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum reboot_type reboot_type = BOOT_ACPI;
 | 
				
			||||||
int reboot_force;
 | 
					int reboot_force;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
 | 
					#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,6 +223,9 @@ unsigned long saved_video_mode;
 | 
				
			||||||
#define RAMDISK_LOAD_FLAG		0x4000
 | 
					#define RAMDISK_LOAD_FLAG		0x4000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char __initdata command_line[COMMAND_LINE_SIZE];
 | 
					static char __initdata command_line[COMMAND_LINE_SIZE];
 | 
				
			||||||
 | 
					#ifdef CONFIG_CMDLINE_BOOL
 | 
				
			||||||
 | 
					static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 | 
					#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 | 
				
			||||||
struct edd edd;
 | 
					struct edd edd;
 | 
				
			||||||
| 
						 | 
					@ -665,6 +668,19 @@ void __init setup_arch(char **cmdline_p)
 | 
				
			||||||
	bss_resource.start = virt_to_phys(&__bss_start);
 | 
						bss_resource.start = virt_to_phys(&__bss_start);
 | 
				
			||||||
	bss_resource.end = virt_to_phys(&__bss_stop)-1;
 | 
						bss_resource.end = virt_to_phys(&__bss_stop)-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_CMDLINE_BOOL
 | 
				
			||||||
 | 
					#ifdef CONFIG_CMDLINE_OVERRIDE
 | 
				
			||||||
 | 
						strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if (builtin_cmdline[0]) {
 | 
				
			||||||
 | 
							/* append boot loader cmdline to builtin */
 | 
				
			||||||
 | 
							strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
 | 
				
			||||||
 | 
							strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
 | 
				
			||||||
 | 
							strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 | 
						strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 | 
				
			||||||
	*cmdline_p = command_line;
 | 
						*cmdline_p = command_line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,9 +162,16 @@ void __init setup_per_cpu_areas(void)
 | 
				
			||||||
			printk(KERN_INFO
 | 
								printk(KERN_INFO
 | 
				
			||||||
			       "cpu %d has no node %d or node-local memory\n",
 | 
								       "cpu %d has no node %d or node-local memory\n",
 | 
				
			||||||
				cpu, node);
 | 
									cpu, node);
 | 
				
			||||||
 | 
								if (ptr)
 | 
				
			||||||
 | 
									printk(KERN_DEBUG "per cpu data for cpu%d at %016lx\n",
 | 
				
			||||||
 | 
										 cpu, __pa(ptr));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else {
 | 
				
			||||||
			ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
 | 
								ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
 | 
				
			||||||
 | 
								if (ptr)
 | 
				
			||||||
 | 
									printk(KERN_DEBUG "per cpu data for cpu%d on node%d at %016lx\n",
 | 
				
			||||||
 | 
										 cpu, node, __pa(ptr));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		per_cpu_offset(cpu) = ptr - __per_cpu_start;
 | 
							per_cpu_offset(cpu) = ptr - __per_cpu_start;
 | 
				
			||||||
		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
 | 
							memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,4 +24,9 @@ struct rt_sigframe {
 | 
				
			||||||
	struct ucontext uc;
 | 
						struct ucontext uc;
 | 
				
			||||||
	struct siginfo info;
 | 
						struct siginfo info;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
				
			||||||
 | 
							sigset_t *set, struct pt_regs *regs);
 | 
				
			||||||
 | 
					int ia32_setup_frame(int sig, struct k_sigaction *ka,
 | 
				
			||||||
 | 
							sigset_t *set, struct pt_regs *regs);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,9 +20,10 @@
 | 
				
			||||||
#include <linux/stddef.h>
 | 
					#include <linux/stddef.h>
 | 
				
			||||||
#include <linux/personality.h>
 | 
					#include <linux/personality.h>
 | 
				
			||||||
#include <linux/compiler.h>
 | 
					#include <linux/compiler.h>
 | 
				
			||||||
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/processor.h>
 | 
					#include <asm/processor.h>
 | 
				
			||||||
#include <asm/ucontext.h>
 | 
					#include <asm/ucontext.h>
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					 | 
				
			||||||
#include <asm/i387.h>
 | 
					#include <asm/i387.h>
 | 
				
			||||||
#include <asm/proto.h>
 | 
					#include <asm/proto.h>
 | 
				
			||||||
#include <asm/ia32_unistd.h>
 | 
					#include <asm/ia32_unistd.h>
 | 
				
			||||||
| 
						 | 
					@ -44,11 +45,6 @@
 | 
				
			||||||
# define FIX_EFLAGS	__FIX_EFLAGS
 | 
					# define FIX_EFLAGS	__FIX_EFLAGS
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
					 | 
				
			||||||
               sigset_t *set, struct pt_regs * regs); 
 | 
					 | 
				
			||||||
int ia32_setup_frame(int sig, struct k_sigaction *ka,
 | 
					 | 
				
			||||||
            sigset_t *set, struct pt_regs * regs); 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
asmlinkage long
 | 
					asmlinkage long
 | 
				
			||||||
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 | 
					sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 | 
				
			||||||
		struct pt_regs *regs)
 | 
							struct pt_regs *regs)
 | 
				
			||||||
| 
						 | 
					@ -131,7 +127,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
 | 
				
			||||||
	/* Always make any pending restarted system calls return -EINTR */
 | 
						/* Always make any pending restarted system calls return -EINTR */
 | 
				
			||||||
	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 | 
						current_thread_info()->restart_block.fn = do_no_restart_syscall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define COPY(x)		err |= __get_user(regs->x, &sc->x)
 | 
					#define COPY(x)		(err |= __get_user(regs->x, &sc->x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
 | 
						COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
 | 
				
			||||||
	COPY(dx); COPY(cx); COPY(ip);
 | 
						COPY(dx); COPY(cx); COPY(ip);
 | 
				
			||||||
| 
						 | 
					@ -161,7 +157,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct _fpstate __user * buf;
 | 
							struct _fpstate __user *buf;
 | 
				
			||||||
		err |= __get_user(buf, &sc->fpstate);
 | 
							err |= __get_user(buf, &sc->fpstate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (buf) {
 | 
							if (buf) {
 | 
				
			||||||
| 
						 | 
					@ -201,7 +197,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 | 
				
			||||||
	current->blocked = set;
 | 
						current->blocked = set;
 | 
				
			||||||
	recalc_sigpending();
 | 
						recalc_sigpending();
 | 
				
			||||||
	spin_unlock_irq(¤t->sighand->siglock);
 | 
						spin_unlock_irq(¤t->sighand->siglock);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
 | 
						if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
 | 
				
			||||||
		goto badframe;
 | 
							goto badframe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,16 +207,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 | 
				
			||||||
	return ax;
 | 
						return ax;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
badframe:
 | 
					badframe:
 | 
				
			||||||
	signal_fault(regs,frame,"sigreturn");
 | 
						signal_fault(regs, frame, "sigreturn");
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}	
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Set up a signal frame.
 | 
					 * Set up a signal frame.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int
 | 
					static inline int
 | 
				
			||||||
setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
 | 
					setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 | 
				
			||||||
 | 
							unsigned long mask, struct task_struct *me)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err = 0;
 | 
						int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,35 +273,35 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
					static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
				
			||||||
			   sigset_t *set, struct pt_regs * regs)
 | 
								   sigset_t *set, struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rt_sigframe __user *frame;
 | 
						struct rt_sigframe __user *frame;
 | 
				
			||||||
	struct _fpstate __user *fp = NULL; 
 | 
						struct _fpstate __user *fp = NULL;
 | 
				
			||||||
	int err = 0;
 | 
						int err = 0;
 | 
				
			||||||
	struct task_struct *me = current;
 | 
						struct task_struct *me = current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (used_math()) {
 | 
						if (used_math()) {
 | 
				
			||||||
		fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
 | 
							fp = get_stack(ka, regs, sizeof(struct _fpstate));
 | 
				
			||||||
		frame = (void __user *)round_down(
 | 
							frame = (void __user *)round_down(
 | 
				
			||||||
			(unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
 | 
								(unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
 | 
							if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
 | 
				
			||||||
			goto give_sigsegv;
 | 
								goto give_sigsegv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (save_i387(fp) < 0) 
 | 
							if (save_i387(fp) < 0)
 | 
				
			||||||
			err |= -1; 
 | 
								err |= -1;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
 | 
							frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 | 
						if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 | 
				
			||||||
		goto give_sigsegv;
 | 
							goto give_sigsegv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ka->sa.sa_flags & SA_SIGINFO) { 
 | 
						if (ka->sa.sa_flags & SA_SIGINFO) {
 | 
				
			||||||
		err |= copy_siginfo_to_user(&frame->info, info);
 | 
							err |= copy_siginfo_to_user(&frame->info, info);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			goto give_sigsegv;
 | 
								goto give_sigsegv;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
	/* Create the ucontext.  */
 | 
						/* Create the ucontext.  */
 | 
				
			||||||
	err |= __put_user(0, &frame->uc.uc_flags);
 | 
						err |= __put_user(0, &frame->uc.uc_flags);
 | 
				
			||||||
	err |= __put_user(0, &frame->uc.uc_link);
 | 
						err |= __put_user(0, &frame->uc.uc_link);
 | 
				
			||||||
| 
						 | 
					@ -314,9 +311,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
				
			||||||
	err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
 | 
						err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
 | 
				
			||||||
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
 | 
						err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
 | 
				
			||||||
	err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
 | 
						err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
 | 
				
			||||||
	if (sizeof(*set) == 16) { 
 | 
						if (sizeof(*set) == 16) {
 | 
				
			||||||
		__put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
 | 
							__put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
 | 
				
			||||||
		__put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 
 | 
							__put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 | 
							err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -327,7 +324,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
				
			||||||
		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
 | 
							err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* could use a vstub here */
 | 
							/* could use a vstub here */
 | 
				
			||||||
		goto give_sigsegv; 
 | 
							goto give_sigsegv;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
| 
						 | 
					@ -335,7 +332,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set up registers for signal handler */
 | 
						/* Set up registers for signal handler */
 | 
				
			||||||
	regs->di = sig;
 | 
						regs->di = sig;
 | 
				
			||||||
	/* In case the signal handler was declared without prototypes */ 
 | 
						/* In case the signal handler was declared without prototypes */
 | 
				
			||||||
	regs->ax = 0;
 | 
						regs->ax = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* This also works for non SA_SIGINFO handlers because they expect the
 | 
						/* This also works for non SA_SIGINFO handlers because they expect the
 | 
				
			||||||
| 
						 | 
					@ -359,7 +356,7 @@ give_sigsegv:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * OK, we're invoking a handler
 | 
					 * OK, we're invoking a handler
 | 
				
			||||||
 */	
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 | 
					handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 | 
				
			||||||
| 
						 | 
					@ -403,7 +400,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 | 
				
			||||||
			ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
 | 
								ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			ret = ia32_setup_frame(sig, ka, oldset, regs);
 | 
								ret = ia32_setup_frame(sig, ka, oldset, regs);
 | 
				
			||||||
	} else 
 | 
						} else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	ret = setup_rt_frame(sig, ka, info, oldset, regs);
 | 
						ret = setup_rt_frame(sig, ka, info, oldset, regs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -429,9 +426,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 | 
				
			||||||
		regs->flags &= ~X86_EFLAGS_TF;
 | 
							regs->flags &= ~X86_EFLAGS_TF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spin_lock_irq(¤t->sighand->siglock);
 | 
							spin_lock_irq(¤t->sighand->siglock);
 | 
				
			||||||
		sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
 | 
							sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
 | 
				
			||||||
		if (!(ka->sa.sa_flags & SA_NODEFER))
 | 
							if (!(ka->sa.sa_flags & SA_NODEFER))
 | 
				
			||||||
			sigaddset(¤t->blocked,sig);
 | 
								sigaddset(¤t->blocked, sig);
 | 
				
			||||||
		recalc_sigpending();
 | 
							recalc_sigpending();
 | 
				
			||||||
		spin_unlock_irq(¤t->sighand->siglock);
 | 
							spin_unlock_irq(¤t->sighand->siglock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -541,14 +538,15 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
 | 
					void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
 | 
				
			||||||
{ 
 | 
					{
 | 
				
			||||||
	struct task_struct *me = current; 
 | 
						struct task_struct *me = current;
 | 
				
			||||||
	if (show_unhandled_signals && printk_ratelimit()) {
 | 
						if (show_unhandled_signals && printk_ratelimit()) {
 | 
				
			||||||
		printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
 | 
							printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
 | 
				
			||||||
	       me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax);
 | 
						       me->comm, me->pid, where, frame, regs->ip,
 | 
				
			||||||
 | 
							   regs->sp, regs->orig_ax);
 | 
				
			||||||
		print_vma_addr(" in ", regs->ip);
 | 
							print_vma_addr(" in ", regs->ip);
 | 
				
			||||||
		printk("\n");
 | 
							printk("\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	force_sig(SIGSEGV, me); 
 | 
						force_sig(SIGSEGV, me);
 | 
				
			||||||
} 
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1313,16 +1313,13 @@ __init void prefill_possible_map(void)
 | 
				
			||||||
	if (!num_processors)
 | 
						if (!num_processors)
 | 
				
			||||||
		num_processors = 1;
 | 
							num_processors = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_HOTPLUG_CPU
 | 
					 | 
				
			||||||
	if (additional_cpus == -1) {
 | 
						if (additional_cpus == -1) {
 | 
				
			||||||
		if (disabled_cpus > 0)
 | 
							if (disabled_cpus > 0)
 | 
				
			||||||
			additional_cpus = disabled_cpus;
 | 
								additional_cpus = disabled_cpus;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			additional_cpus = 0;
 | 
								additional_cpus = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#else
 | 
					
 | 
				
			||||||
	additional_cpus = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	possible = num_processors + additional_cpus;
 | 
						possible = num_processors + additional_cpus;
 | 
				
			||||||
	if (possible > NR_CPUS)
 | 
						if (possible > NR_CPUS)
 | 
				
			||||||
		possible = NR_CPUS;
 | 
							possible = NR_CPUS;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,16 +13,17 @@
 | 
				
			||||||
#include <linux/utsname.h>
 | 
					#include <linux/utsname.h>
 | 
				
			||||||
#include <linux/personality.h>
 | 
					#include <linux/personality.h>
 | 
				
			||||||
#include <linux/random.h>
 | 
					#include <linux/random.h>
 | 
				
			||||||
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					 | 
				
			||||||
#include <asm/ia32.h>
 | 
					#include <asm/ia32.h>
 | 
				
			||||||
#include <asm/syscalls.h>
 | 
					#include <asm/syscalls.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
 | 
					asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
 | 
				
			||||||
	unsigned long fd, unsigned long off)
 | 
							unsigned long prot, unsigned long flags,
 | 
				
			||||||
 | 
							unsigned long fd, unsigned long off)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	long error;
 | 
						long error;
 | 
				
			||||||
	struct file * file;
 | 
						struct file *file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = -EINVAL;
 | 
						error = -EINVAL;
 | 
				
			||||||
	if (off & ~PAGE_MASK)
 | 
						if (off & ~PAGE_MASK)
 | 
				
			||||||
| 
						 | 
					@ -57,9 +58,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
 | 
				
			||||||
		   unmapped base down for this case. This can give
 | 
							   unmapped base down for this case. This can give
 | 
				
			||||||
		   conflicts with the heap, but we assume that glibc
 | 
							   conflicts with the heap, but we assume that glibc
 | 
				
			||||||
		   malloc knows how to fall back to mmap. Give it 1GB
 | 
							   malloc knows how to fall back to mmap. Give it 1GB
 | 
				
			||||||
		   of playground for now. -AK */ 
 | 
							   of playground for now. -AK */
 | 
				
			||||||
		*begin = 0x40000000; 
 | 
							*begin = 0x40000000;
 | 
				
			||||||
		*end = 0x80000000;		
 | 
							*end = 0x80000000;
 | 
				
			||||||
		if (current->flags & PF_RANDOMIZE) {
 | 
							if (current->flags & PF_RANDOMIZE) {
 | 
				
			||||||
			new_begin = randomize_range(*begin, *begin + 0x02000000, 0);
 | 
								new_begin = randomize_range(*begin, *begin + 0x02000000, 0);
 | 
				
			||||||
			if (new_begin)
 | 
								if (new_begin)
 | 
				
			||||||
| 
						 | 
					@ -67,9 +68,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		*begin = TASK_UNMAPPED_BASE;
 | 
							*begin = TASK_UNMAPPED_BASE;
 | 
				
			||||||
		*end = TASK_SIZE; 
 | 
							*end = TASK_SIZE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} 
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long
 | 
					unsigned long
 | 
				
			||||||
arch_get_unmapped_area(struct file *filp, unsigned long addr,
 | 
					arch_get_unmapped_area(struct file *filp, unsigned long addr,
 | 
				
			||||||
| 
						 | 
					@ -79,11 +80,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 | 
				
			||||||
	struct vm_area_struct *vma;
 | 
						struct vm_area_struct *vma;
 | 
				
			||||||
	unsigned long start_addr;
 | 
						unsigned long start_addr;
 | 
				
			||||||
	unsigned long begin, end;
 | 
						unsigned long begin, end;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if (flags & MAP_FIXED)
 | 
						if (flags & MAP_FIXED)
 | 
				
			||||||
		return addr;
 | 
							return addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	find_start_end(flags, &begin, &end); 
 | 
						find_start_end(flags, &begin, &end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (len > end)
 | 
						if (len > end)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
| 
						 | 
					@ -97,12 +98,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
 | 
						if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
 | 
				
			||||||
	    && len <= mm->cached_hole_size) {
 | 
						    && len <= mm->cached_hole_size) {
 | 
				
			||||||
	        mm->cached_hole_size = 0;
 | 
							mm->cached_hole_size = 0;
 | 
				
			||||||
		mm->free_area_cache = begin;
 | 
							mm->free_area_cache = begin;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	addr = mm->free_area_cache;
 | 
						addr = mm->free_area_cache;
 | 
				
			||||||
	if (addr < begin) 
 | 
						if (addr < begin)
 | 
				
			||||||
		addr = begin; 
 | 
							addr = begin;
 | 
				
			||||||
	start_addr = addr;
 | 
						start_addr = addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
full_search:
 | 
					full_search:
 | 
				
			||||||
| 
						 | 
					@ -128,7 +129,7 @@ full_search:
 | 
				
			||||||
			return addr;
 | 
								return addr;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (addr + mm->cached_hole_size < vma->vm_start)
 | 
							if (addr + mm->cached_hole_size < vma->vm_start)
 | 
				
			||||||
		        mm->cached_hole_size = vma->vm_start - addr;
 | 
								mm->cached_hole_size = vma->vm_start - addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		addr = vma->vm_end;
 | 
							addr = vma->vm_end;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -178,7 +179,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 | 
				
			||||||
		vma = find_vma(mm, addr-len);
 | 
							vma = find_vma(mm, addr-len);
 | 
				
			||||||
		if (!vma || addr <= vma->vm_start)
 | 
							if (!vma || addr <= vma->vm_start)
 | 
				
			||||||
			/* remember the address as a hint for next time */
 | 
								/* remember the address as a hint for next time */
 | 
				
			||||||
			return (mm->free_area_cache = addr-len);
 | 
								return mm->free_area_cache = addr-len;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mm->mmap_base < len)
 | 
						if (mm->mmap_base < len)
 | 
				
			||||||
| 
						 | 
					@ -195,7 +196,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 | 
				
			||||||
		vma = find_vma(mm, addr);
 | 
							vma = find_vma(mm, addr);
 | 
				
			||||||
		if (!vma || addr+len <= vma->vm_start)
 | 
							if (!vma || addr+len <= vma->vm_start)
 | 
				
			||||||
			/* remember the address as a hint for next time */
 | 
								/* remember the address as a hint for next time */
 | 
				
			||||||
			return (mm->free_area_cache = addr);
 | 
								return mm->free_area_cache = addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* remember the largest hole we saw so far */
 | 
							/* remember the largest hole we saw so far */
 | 
				
			||||||
		if (addr + mm->cached_hole_size < vma->vm_start)
 | 
							if (addr + mm->cached_hole_size < vma->vm_start)
 | 
				
			||||||
| 
						 | 
					@ -225,13 +226,13 @@ bottomup:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage long sys_uname(struct new_utsname __user * name)
 | 
					asmlinkage long sys_uname(struct new_utsname __user *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	down_read(&uts_sem);
 | 
						down_read(&uts_sem);
 | 
				
			||||||
	err = copy_to_user(name, utsname(), sizeof (*name));
 | 
						err = copy_to_user(name, utsname(), sizeof(*name));
 | 
				
			||||||
	up_read(&uts_sem);
 | 
						up_read(&uts_sem);
 | 
				
			||||||
	if (personality(current->personality) == PER_LINUX32) 
 | 
						if (personality(current->personality) == PER_LINUX32)
 | 
				
			||||||
		err |= copy_to_user(&name->machine, "i686", 5); 		
 | 
							err |= copy_to_user(&name->machine, "i686", 5);
 | 
				
			||||||
	return err ? -EFAULT : 0;
 | 
						return err ? -EFAULT : 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,8 @@
 | 
				
			||||||
#include <linux/bug.h>
 | 
					#include <linux/bug.h>
 | 
				
			||||||
#include <linux/nmi.h>
 | 
					#include <linux/nmi.h>
 | 
				
			||||||
#include <linux/mm.h>
 | 
					#include <linux/mm.h>
 | 
				
			||||||
 | 
					#include <linux/smp.h>
 | 
				
			||||||
 | 
					#include <linux/io.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_EDAC)
 | 
					#if defined(CONFIG_EDAC)
 | 
				
			||||||
#include <linux/edac.h>
 | 
					#include <linux/edac.h>
 | 
				
			||||||
| 
						 | 
					@ -45,9 +47,6 @@
 | 
				
			||||||
#include <asm/unwind.h>
 | 
					#include <asm/unwind.h>
 | 
				
			||||||
#include <asm/desc.h>
 | 
					#include <asm/desc.h>
 | 
				
			||||||
#include <asm/i387.h>
 | 
					#include <asm/i387.h>
 | 
				
			||||||
#include <asm/nmi.h>
 | 
					 | 
				
			||||||
#include <asm/smp.h>
 | 
					 | 
				
			||||||
#include <asm/io.h>
 | 
					 | 
				
			||||||
#include <asm/pgalloc.h>
 | 
					#include <asm/pgalloc.h>
 | 
				
			||||||
#include <asm/proto.h>
 | 
					#include <asm/proto.h>
 | 
				
			||||||
#include <asm/pda.h>
 | 
					#include <asm/pda.h>
 | 
				
			||||||
| 
						 | 
					@ -85,7 +84,8 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void printk_address(unsigned long address, int reliable)
 | 
					void printk_address(unsigned long address, int reliable)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address);
 | 
						printk(" [<%016lx>] %s%pS\n",
 | 
				
			||||||
 | 
								address, reliable ?	"" : "? ", (void *) address);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 | 
					static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 | 
				
			||||||
| 
						 | 
					@ -98,7 +98,8 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 | 
				
			||||||
		[STACKFAULT_STACK - 1] = "#SS",
 | 
							[STACKFAULT_STACK - 1] = "#SS",
 | 
				
			||||||
		[MCE_STACK - 1] = "#MC",
 | 
							[MCE_STACK - 1] = "#MC",
 | 
				
			||||||
#if DEBUG_STKSZ > EXCEPTION_STKSZ
 | 
					#if DEBUG_STKSZ > EXCEPTION_STKSZ
 | 
				
			||||||
		[N_EXCEPTION_STACKS ... N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
 | 
							[N_EXCEPTION_STACKS ...
 | 
				
			||||||
 | 
								N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	unsigned k;
 | 
						unsigned k;
 | 
				
			||||||
| 
						 | 
					@ -163,7 +164,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * x86-64 can have up to three kernel stacks: 
 | 
					 * x86-64 can have up to three kernel stacks:
 | 
				
			||||||
 * process stack
 | 
					 * process stack
 | 
				
			||||||
 * interrupt stack
 | 
					 * interrupt stack
 | 
				
			||||||
 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
 | 
					 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
 | 
				
			||||||
| 
						 | 
					@ -219,7 +220,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 | 
				
			||||||
		const struct stacktrace_ops *ops, void *data)
 | 
							const struct stacktrace_ops *ops, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const unsigned cpu = get_cpu();
 | 
						const unsigned cpu = get_cpu();
 | 
				
			||||||
	unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr;
 | 
						unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
 | 
				
			||||||
	unsigned used = 0;
 | 
						unsigned used = 0;
 | 
				
			||||||
	struct thread_info *tinfo;
 | 
						struct thread_info *tinfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,7 +238,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 | 
				
			||||||
	if (!bp) {
 | 
						if (!bp) {
 | 
				
			||||||
		if (task == current) {
 | 
							if (task == current) {
 | 
				
			||||||
			/* Grab bp right from our regs */
 | 
								/* Grab bp right from our regs */
 | 
				
			||||||
			asm("movq %%rbp, %0" : "=r" (bp) :);
 | 
								asm("movq %%rbp, %0" : "=r" (bp) : );
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* bp is the last reg pushed by switch_to */
 | 
								/* bp is the last reg pushed by switch_to */
 | 
				
			||||||
			bp = *(unsigned long *) task->thread.sp;
 | 
								bp = *(unsigned long *) task->thread.sp;
 | 
				
			||||||
| 
						 | 
					@ -339,9 +340,8 @@ static void
 | 
				
			||||||
show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
 | 
					show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
 | 
				
			||||||
		unsigned long *stack, unsigned long bp, char *log_lvl)
 | 
							unsigned long *stack, unsigned long bp, char *log_lvl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk("\nCall Trace:\n");
 | 
						printk("Call Trace:\n");
 | 
				
			||||||
	dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
 | 
						dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
 | 
				
			||||||
	printk("\n");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void show_trace(struct task_struct *task, struct pt_regs *regs,
 | 
					void show_trace(struct task_struct *task, struct pt_regs *regs,
 | 
				
			||||||
| 
						 | 
					@ -357,11 +357,15 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
 | 
				
			||||||
	unsigned long *stack;
 | 
						unsigned long *stack;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	const int cpu = smp_processor_id();
 | 
						const int cpu = smp_processor_id();
 | 
				
			||||||
	unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr);
 | 
						unsigned long *irqstack_end =
 | 
				
			||||||
	unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
 | 
							(unsigned long *) (cpu_pda(cpu)->irqstackptr);
 | 
				
			||||||
 | 
						unsigned long *irqstack =
 | 
				
			||||||
 | 
							(unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// debugging aid: "show_stack(NULL, NULL);" prints the
 | 
						/*
 | 
				
			||||||
	// back trace for this cpu.
 | 
						 * debugging aid: "show_stack(NULL, NULL);" prints the
 | 
				
			||||||
 | 
						 * back trace for this cpu.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sp == NULL) {
 | 
						if (sp == NULL) {
 | 
				
			||||||
		if (task)
 | 
							if (task)
 | 
				
			||||||
| 
						 | 
					@ -386,6 +390,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
 | 
				
			||||||
		printk(" %016lx", *stack++);
 | 
							printk(" %016lx", *stack++);
 | 
				
			||||||
		touch_nmi_watchdog();
 | 
							touch_nmi_watchdog();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						printk("\n");
 | 
				
			||||||
	show_trace_log_lvl(task, regs, sp, bp, log_lvl);
 | 
						show_trace_log_lvl(task, regs, sp, bp, log_lvl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -404,7 +409,7 @@ void dump_stack(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_FRAME_POINTER
 | 
					#ifdef CONFIG_FRAME_POINTER
 | 
				
			||||||
	if (!bp)
 | 
						if (!bp)
 | 
				
			||||||
		asm("movq %%rbp, %0" : "=r" (bp):);
 | 
							asm("movq %%rbp, %0" : "=r" (bp) : );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk("Pid: %d, comm: %.20s %s %s %.*s\n",
 | 
						printk("Pid: %d, comm: %.20s %s %s %.*s\n",
 | 
				
			||||||
| 
						 | 
					@ -414,7 +419,6 @@ void dump_stack(void)
 | 
				
			||||||
		init_utsname()->version);
 | 
							init_utsname()->version);
 | 
				
			||||||
	show_trace(NULL, NULL, &stack, bp);
 | 
						show_trace(NULL, NULL, &stack, bp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
EXPORT_SYMBOL(dump_stack);
 | 
					EXPORT_SYMBOL(dump_stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void show_registers(struct pt_regs *regs)
 | 
					void show_registers(struct pt_regs *regs)
 | 
				
			||||||
| 
						 | 
					@ -443,7 +447,6 @@ void show_registers(struct pt_regs *regs)
 | 
				
			||||||
		printk("Stack: ");
 | 
							printk("Stack: ");
 | 
				
			||||||
		show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
 | 
							show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
 | 
				
			||||||
				regs->bp, "");
 | 
									regs->bp, "");
 | 
				
			||||||
		printk("\n");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		printk(KERN_EMERG "Code: ");
 | 
							printk(KERN_EMERG "Code: ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -493,7 +496,7 @@ unsigned __kprobes long oops_begin(void)
 | 
				
			||||||
	raw_local_irq_save(flags);
 | 
						raw_local_irq_save(flags);
 | 
				
			||||||
	cpu = smp_processor_id();
 | 
						cpu = smp_processor_id();
 | 
				
			||||||
	if (!__raw_spin_trylock(&die_lock)) {
 | 
						if (!__raw_spin_trylock(&die_lock)) {
 | 
				
			||||||
		if (cpu == die_owner) 
 | 
							if (cpu == die_owner)
 | 
				
			||||||
			/* nested oops. should stop eventually */;
 | 
								/* nested oops. should stop eventually */;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			__raw_spin_lock(&die_lock);
 | 
								__raw_spin_lock(&die_lock);
 | 
				
			||||||
| 
						 | 
					@ -638,7 +641,7 @@ kernel_trap:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DO_ERROR(trapnr, signr, str, name) \
 | 
					#define DO_ERROR(trapnr, signr, str, name) \
 | 
				
			||||||
asmlinkage void do_##name(struct pt_regs * regs, long error_code)	\
 | 
					asmlinkage void do_##name(struct pt_regs *regs, long error_code)	\
 | 
				
			||||||
{									\
 | 
					{									\
 | 
				
			||||||
	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)	\
 | 
						if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)	\
 | 
				
			||||||
							== NOTIFY_STOP)	\
 | 
												== NOTIFY_STOP)	\
 | 
				
			||||||
| 
						 | 
					@ -648,7 +651,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code)	\
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr)		\
 | 
					#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr)		\
 | 
				
			||||||
asmlinkage void do_##name(struct pt_regs * regs, long error_code)	\
 | 
					asmlinkage void do_##name(struct pt_regs *regs, long error_code)	\
 | 
				
			||||||
{									\
 | 
					{									\
 | 
				
			||||||
	siginfo_t info;							\
 | 
						siginfo_t info;							\
 | 
				
			||||||
	info.si_signo = signr;						\
 | 
						info.si_signo = signr;						\
 | 
				
			||||||
| 
						 | 
					@ -683,7 +686,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
 | 
				
			||||||
	preempt_conditional_cli(regs);
 | 
						preempt_conditional_cli(regs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
 | 
					asmlinkage void do_double_fault(struct pt_regs *regs, long error_code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static const char str[] = "double fault";
 | 
						static const char str[] = "double fault";
 | 
				
			||||||
	struct task_struct *tsk = current;
 | 
						struct task_struct *tsk = current;
 | 
				
			||||||
| 
						 | 
					@ -778,9 +781,10 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static notrace __kprobes void
 | 
					static notrace __kprobes void
 | 
				
			||||||
unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 | 
					unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
 | 
						if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
 | 
				
			||||||
 | 
								NOTIFY_STOP)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
 | 
						printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
 | 
				
			||||||
		reason);
 | 
							reason);
 | 
				
			||||||
| 
						 | 
					@ -882,7 +886,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
 | 
				
			||||||
	else if (user_mode(eregs))
 | 
						else if (user_mode(eregs))
 | 
				
			||||||
		regs = task_pt_regs(current);
 | 
							regs = task_pt_regs(current);
 | 
				
			||||||
	/* Exception from kernel and interrupts are enabled. Move to
 | 
						/* Exception from kernel and interrupts are enabled. Move to
 | 
				
			||||||
 	   kernel process stack. */
 | 
						   kernel process stack. */
 | 
				
			||||||
	else if (eregs->flags & X86_EFLAGS_IF)
 | 
						else if (eregs->flags & X86_EFLAGS_IF)
 | 
				
			||||||
		regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
 | 
							regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
 | 
				
			||||||
	if (eregs != regs)
 | 
						if (eregs != regs)
 | 
				
			||||||
| 
						 | 
					@ -891,7 +895,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* runs on IST stack. */
 | 
					/* runs on IST stack. */
 | 
				
			||||||
asmlinkage void __kprobes do_debug(struct pt_regs * regs,
 | 
					asmlinkage void __kprobes do_debug(struct pt_regs *regs,
 | 
				
			||||||
				   unsigned long error_code)
 | 
									   unsigned long error_code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct task_struct *tsk = current;
 | 
						struct task_struct *tsk = current;
 | 
				
			||||||
| 
						 | 
					@ -1035,7 +1039,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage void bad_intr(void)
 | 
					asmlinkage void bad_intr(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk("bad interrupt"); 
 | 
						printk("bad interrupt");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
 | 
					asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
 | 
				
			||||||
| 
						 | 
					@ -1047,7 +1051,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	conditional_sti(regs);
 | 
						conditional_sti(regs);
 | 
				
			||||||
	if (!user_mode(regs) &&
 | 
						if (!user_mode(regs) &&
 | 
				
			||||||
        	kernel_math_error(regs, "kernel simd math error", 19))
 | 
								kernel_math_error(regs, "kernel simd math error", 19))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -1092,7 +1096,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
 | 
				
			||||||
	force_sig_info(SIGFPE, &info, task);
 | 
						force_sig_info(SIGFPE, &info, task);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
 | 
					asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1149,8 +1153,10 @@ void __init trap_init(void)
 | 
				
			||||||
	set_intr_gate(0, ÷_error);
 | 
						set_intr_gate(0, ÷_error);
 | 
				
			||||||
	set_intr_gate_ist(1, &debug, DEBUG_STACK);
 | 
						set_intr_gate_ist(1, &debug, DEBUG_STACK);
 | 
				
			||||||
	set_intr_gate_ist(2, &nmi, NMI_STACK);
 | 
						set_intr_gate_ist(2, &nmi, NMI_STACK);
 | 
				
			||||||
 	set_system_gate_ist(3, &int3, DEBUG_STACK); /* int3 can be called from all */
 | 
						/* int3 can be called from all */
 | 
				
			||||||
	set_system_gate(4, &overflow); /* int4 can be called from all */
 | 
						set_system_gate_ist(3, &int3, DEBUG_STACK);
 | 
				
			||||||
 | 
						/* int4 can be called from all */
 | 
				
			||||||
 | 
						set_system_gate(4, &overflow);
 | 
				
			||||||
	set_intr_gate(5, &bounds);
 | 
						set_intr_gate(5, &bounds);
 | 
				
			||||||
	set_intr_gate(6, &invalid_op);
 | 
						set_intr_gate(6, &invalid_op);
 | 
				
			||||||
	set_intr_gate(7, &device_not_available);
 | 
						set_intr_gate(7, &device_not_available);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,7 +104,7 @@ __setup("notsc", notsc_setup);
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Read TSC and the reference counters. Take care of SMI disturbance
 | 
					 * Read TSC and the reference counters. Take care of SMI disturbance
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static u64 tsc_read_refs(u64 *pm, u64 *hpet)
 | 
					static u64 tsc_read_refs(u64 *p, int hpet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 t1, t2;
 | 
						u64 t1, t2;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -112,9 +112,9 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
 | 
				
			||||||
	for (i = 0; i < MAX_RETRIES; i++) {
 | 
						for (i = 0; i < MAX_RETRIES; i++) {
 | 
				
			||||||
		t1 = get_cycles();
 | 
							t1 = get_cycles();
 | 
				
			||||||
		if (hpet)
 | 
							if (hpet)
 | 
				
			||||||
			*hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
 | 
								*p = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			*pm = acpi_pm_read_early();
 | 
								*p = acpi_pm_read_early();
 | 
				
			||||||
		t2 = get_cycles();
 | 
							t2 = get_cycles();
 | 
				
			||||||
		if ((t2 - t1) < SMI_TRESHOLD)
 | 
							if ((t2 - t1) < SMI_TRESHOLD)
 | 
				
			||||||
			return t2;
 | 
								return t2;
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,52 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
 | 
				
			||||||
	return ULLONG_MAX;
 | 
						return ULLONG_MAX;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Calculate the TSC frequency from HPET reference
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u64 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hpet2 < hpet1)
 | 
				
			||||||
 | 
							hpet2 += 0x100000000ULL;
 | 
				
			||||||
 | 
						hpet2 -= hpet1;
 | 
				
			||||||
 | 
						tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
 | 
				
			||||||
 | 
						do_div(tmp, 1000000);
 | 
				
			||||||
 | 
						do_div(deltatsc, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (unsigned long) deltatsc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Calculate the TSC frequency from PMTimer reference
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u64 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!pm1 && !pm2)
 | 
				
			||||||
 | 
							return ULONG_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pm2 < pm1)
 | 
				
			||||||
 | 
							pm2 += (u64)ACPI_PM_OVRRUN;
 | 
				
			||||||
 | 
						pm2 -= pm1;
 | 
				
			||||||
 | 
						tmp = pm2 * 1000000000LL;
 | 
				
			||||||
 | 
						do_div(tmp, PMTMR_TICKS_PER_SEC);
 | 
				
			||||||
 | 
						do_div(deltatsc, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (unsigned long) deltatsc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CAL_MS		10
 | 
				
			||||||
 | 
					#define CAL_LATCH	(CLOCK_TICK_RATE / (1000 / CAL_MS))
 | 
				
			||||||
 | 
					#define CAL_PIT_LOOPS	1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CAL2_MS		50
 | 
				
			||||||
 | 
					#define CAL2_LATCH	(CLOCK_TICK_RATE / (1000 / CAL2_MS))
 | 
				
			||||||
 | 
					#define CAL2_PIT_LOOPS	5000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Try to calibrate the TSC against the Programmable
 | 
					 * Try to calibrate the TSC against the Programmable
 | 
				
			||||||
 * Interrupt Timer and return the frequency of the TSC
 | 
					 * Interrupt Timer and return the frequency of the TSC
 | 
				
			||||||
| 
						 | 
					@ -129,7 +175,7 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Return ULONG_MAX on failure to calibrate.
 | 
					 * Return ULONG_MAX on failure to calibrate.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static unsigned long pit_calibrate_tsc(void)
 | 
					static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 tsc, t1, t2, delta;
 | 
						u64 tsc, t1, t2, delta;
 | 
				
			||||||
	unsigned long tscmin, tscmax;
 | 
						unsigned long tscmin, tscmax;
 | 
				
			||||||
| 
						 | 
					@ -144,8 +190,8 @@ static unsigned long pit_calibrate_tsc(void)
 | 
				
			||||||
	 * (LSB then MSB) to begin countdown.
 | 
						 * (LSB then MSB) to begin countdown.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	outb(0xb0, 0x43);
 | 
						outb(0xb0, 0x43);
 | 
				
			||||||
	outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
 | 
						outb(latch & 0xff, 0x42);
 | 
				
			||||||
	outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
 | 
						outb(latch >> 8, 0x42);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tsc = t1 = t2 = get_cycles();
 | 
						tsc = t1 = t2 = get_cycles();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,31 +212,154 @@ static unsigned long pit_calibrate_tsc(void)
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Sanity checks:
 | 
						 * Sanity checks:
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * If we were not able to read the PIT more than 5000
 | 
						 * If we were not able to read the PIT more than loopmin
 | 
				
			||||||
	 * times, then we have been hit by a massive SMI
 | 
						 * times, then we have been hit by a massive SMI
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * If the maximum is 10 times larger than the minimum,
 | 
						 * If the maximum is 10 times larger than the minimum,
 | 
				
			||||||
	 * then we got hit by an SMI as well.
 | 
						 * then we got hit by an SMI as well.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (pitcnt < 5000 || tscmax > 10 * tscmin)
 | 
						if (pitcnt < loopmin || tscmax > 10 * tscmin)
 | 
				
			||||||
		return ULONG_MAX;
 | 
							return ULONG_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Calculate the PIT value */
 | 
						/* Calculate the PIT value */
 | 
				
			||||||
	delta = t2 - t1;
 | 
						delta = t2 - t1;
 | 
				
			||||||
	do_div(delta, 50);
 | 
						do_div(delta, ms);
 | 
				
			||||||
	return delta;
 | 
						return delta;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This reads the current MSB of the PIT counter, and
 | 
				
			||||||
 | 
					 * checks if we are running on sufficiently fast and
 | 
				
			||||||
 | 
					 * non-virtualized hardware.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Our expectations are:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  - the PIT is running at roughly 1.19MHz
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  - each IO is going to take about 1us on real hardware,
 | 
				
			||||||
 | 
					 *    but we allow it to be much faster (by a factor of 10) or
 | 
				
			||||||
 | 
					 *    _slightly_ slower (ie we allow up to a 2us read+counter
 | 
				
			||||||
 | 
					 *    update - anything else implies a unacceptably slow CPU
 | 
				
			||||||
 | 
					 *    or PIT for the fast calibration to work.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  - with 256 PIT ticks to read the value, we have 214us to
 | 
				
			||||||
 | 
					 *    see the same MSB (and overhead like doing a single TSC
 | 
				
			||||||
 | 
					 *    read per MSB value etc).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  - We're doing 2 reads per loop (LSB, MSB), and we expect
 | 
				
			||||||
 | 
					 *    them each to take about a microsecond on real hardware.
 | 
				
			||||||
 | 
					 *    So we expect a count value of around 100. But we'll be
 | 
				
			||||||
 | 
					 *    generous, and accept anything over 50.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  - if the PIT is stuck, and we see *many* more reads, we
 | 
				
			||||||
 | 
					 *    return early (and the next caller of pit_expect_msb()
 | 
				
			||||||
 | 
					 *    then consider it a failure when they don't see the
 | 
				
			||||||
 | 
					 *    next expected value).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * These expectations mean that we know that we have seen the
 | 
				
			||||||
 | 
					 * transition from one expected value to another with a fairly
 | 
				
			||||||
 | 
					 * high accuracy, and we didn't miss any events. We can thus
 | 
				
			||||||
 | 
					 * use the TSC value at the transitions to calculate a pretty
 | 
				
			||||||
 | 
					 * good value for the TSC frequencty.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline int pit_expect_msb(unsigned char val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (count = 0; count < 50000; count++) {
 | 
				
			||||||
 | 
							/* Ignore LSB */
 | 
				
			||||||
 | 
							inb(0x42);
 | 
				
			||||||
 | 
							if (inb(0x42) != val)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return count > 50;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * How many MSB values do we want to see? We aim for a
 | 
				
			||||||
 | 
					 * 15ms calibration, which assuming a 2us counter read
 | 
				
			||||||
 | 
					 * error should give us roughly 150 ppm precision for
 | 
				
			||||||
 | 
					 * the calibration.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define QUICK_PIT_MS 15
 | 
				
			||||||
 | 
					#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned long quick_pit_calibrate(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Set the Gate high, disable speaker */
 | 
				
			||||||
 | 
						outb((inb(0x61) & ~0x02) | 0x01, 0x61);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Counter 2, mode 0 (one-shot), binary count
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * NOTE! Mode 2 decrements by two (and then the
 | 
				
			||||||
 | 
						 * output is flipped each time, giving the same
 | 
				
			||||||
 | 
						 * final output frequency as a decrement-by-one),
 | 
				
			||||||
 | 
						 * so mode 0 is much better when looking at the
 | 
				
			||||||
 | 
						 * individual counts.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						outb(0xb0, 0x43);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Start at 0xffff */
 | 
				
			||||||
 | 
						outb(0xff, 0x42);
 | 
				
			||||||
 | 
						outb(0xff, 0x42);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pit_expect_msb(0xff)) {
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
							u64 t1, t2, delta;
 | 
				
			||||||
 | 
							unsigned char expect = 0xfe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							t1 = get_cycles();
 | 
				
			||||||
 | 
							for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) {
 | 
				
			||||||
 | 
								if (!pit_expect_msb(expect))
 | 
				
			||||||
 | 
									goto failed;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t2 = get_cycles();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Make sure we can rely on the second TSC timestamp:
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (!pit_expect_msb(expect))
 | 
				
			||||||
 | 
								goto failed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Ok, if we get here, then we've seen the
 | 
				
			||||||
 | 
							 * MSB of the PIT decrement QUICK_PIT_ITERATIONS
 | 
				
			||||||
 | 
							 * times, and each MSB had many hits, so we never
 | 
				
			||||||
 | 
							 * had any sudden jumps.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * As a result, we can depend on there not being
 | 
				
			||||||
 | 
							 * any odd delays anywhere, and the TSC reads are
 | 
				
			||||||
 | 
							 * reliable.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * kHz = ticks / time-in-seconds / 1000;
 | 
				
			||||||
 | 
							 * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000
 | 
				
			||||||
 | 
							 * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000)
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							delta = (t2 - t1)*PIT_TICK_RATE;
 | 
				
			||||||
 | 
							do_div(delta, QUICK_PIT_ITERATIONS*256*1000);
 | 
				
			||||||
 | 
							printk("Fast TSC calibration using PIT\n");
 | 
				
			||||||
 | 
							return delta;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					failed:
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * native_calibrate_tsc - calibrate the tsc on boot
 | 
					 * native_calibrate_tsc - calibrate the tsc on boot
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
unsigned long native_calibrate_tsc(void)
 | 
					unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 tsc1, tsc2, delta, pm1, pm2, hpet1, hpet2;
 | 
						u64 tsc1, tsc2, delta, ref1, ref2;
 | 
				
			||||||
	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
 | 
						unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags, latch, ms, fast_calibrate;
 | 
				
			||||||
	int hpet = is_hpet_enabled(), i;
 | 
						int hpet = is_hpet_enabled(), i, loopmin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_irq_save(flags);
 | 
				
			||||||
 | 
						fast_calibrate = quick_pit_calibrate();
 | 
				
			||||||
 | 
						local_irq_restore(flags);
 | 
				
			||||||
 | 
						if (fast_calibrate)
 | 
				
			||||||
 | 
							return fast_calibrate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Run 5 calibration loops to get the lowest frequency value
 | 
						 * Run 5 calibration loops to get the lowest frequency value
 | 
				
			||||||
| 
						 | 
					@ -216,7 +385,13 @@ unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
	 * calibration delay loop as we have to wait for a certain
 | 
						 * calibration delay loop as we have to wait for a certain
 | 
				
			||||||
	 * amount of time anyway.
 | 
						 * amount of time anyway.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	for (i = 0; i < 5; i++) {
 | 
					
 | 
				
			||||||
 | 
						/* Preset PIT loop values */
 | 
				
			||||||
 | 
						latch = CAL_LATCH;
 | 
				
			||||||
 | 
						ms = CAL_MS;
 | 
				
			||||||
 | 
						loopmin = CAL_PIT_LOOPS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < 3; i++) {
 | 
				
			||||||
		unsigned long tsc_pit_khz;
 | 
							unsigned long tsc_pit_khz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -226,16 +401,16 @@ unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
		 * read the end value.
 | 
							 * read the end value.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		local_irq_save(flags);
 | 
							local_irq_save(flags);
 | 
				
			||||||
		tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
 | 
							tsc1 = tsc_read_refs(&ref1, hpet);
 | 
				
			||||||
		tsc_pit_khz = pit_calibrate_tsc();
 | 
							tsc_pit_khz = pit_calibrate_tsc(latch, ms, loopmin);
 | 
				
			||||||
		tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
 | 
							tsc2 = tsc_read_refs(&ref2, hpet);
 | 
				
			||||||
		local_irq_restore(flags);
 | 
							local_irq_restore(flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Pick the lowest PIT TSC calibration so far */
 | 
							/* Pick the lowest PIT TSC calibration so far */
 | 
				
			||||||
		tsc_pit_min = min(tsc_pit_min, tsc_pit_khz);
 | 
							tsc_pit_min = min(tsc_pit_min, tsc_pit_khz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* hpet or pmtimer available ? */
 | 
							/* hpet or pmtimer available ? */
 | 
				
			||||||
		if (!hpet && !pm1 && !pm2)
 | 
							if (!hpet && !ref1 && !ref2)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Check, whether the sampling was disturbed by an SMI */
 | 
							/* Check, whether the sampling was disturbed by an SMI */
 | 
				
			||||||
| 
						 | 
					@ -243,23 +418,41 @@ unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		tsc2 = (tsc2 - tsc1) * 1000000LL;
 | 
							tsc2 = (tsc2 - tsc1) * 1000000LL;
 | 
				
			||||||
 | 
							if (hpet)
 | 
				
			||||||
 | 
								tsc2 = calc_hpet_ref(tsc2, ref1, ref2);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (hpet) {
 | 
							tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
 | 
				
			||||||
			if (hpet2 < hpet1)
 | 
					
 | 
				
			||||||
				hpet2 += 0x100000000ULL;
 | 
							/* Check the reference deviation */
 | 
				
			||||||
			hpet2 -= hpet1;
 | 
							delta = ((u64) tsc_pit_min) * 100;
 | 
				
			||||||
			tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
 | 
							do_div(delta, tsc_ref_min);
 | 
				
			||||||
			do_div(tsc1, 1000000);
 | 
					
 | 
				
			||||||
		} else {
 | 
							/*
 | 
				
			||||||
			if (pm2 < pm1)
 | 
							 * If both calibration results are inside a 10% window
 | 
				
			||||||
				pm2 += (u64)ACPI_PM_OVRRUN;
 | 
							 * then we can be sure, that the calibration
 | 
				
			||||||
			pm2 -= pm1;
 | 
							 * succeeded. We break out of the loop right away. We
 | 
				
			||||||
			tsc1 = pm2 * 1000000000LL;
 | 
							 * use the reference value, as it is more precise.
 | 
				
			||||||
			do_div(tsc1, PMTMR_TICKS_PER_SEC);
 | 
							 */
 | 
				
			||||||
 | 
							if (delta >= 90 && delta <= 110) {
 | 
				
			||||||
 | 
								printk(KERN_INFO
 | 
				
			||||||
 | 
								       "TSC: PIT calibration matches %s. %d loops\n",
 | 
				
			||||||
 | 
								       hpet ? "HPET" : "PMTIMER", i + 1);
 | 
				
			||||||
 | 
								return tsc_ref_min;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		do_div(tsc2, tsc1);
 | 
							/*
 | 
				
			||||||
		tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
 | 
							 * Check whether PIT failed more than once. This
 | 
				
			||||||
 | 
							 * happens in virtualized environments. We need to
 | 
				
			||||||
 | 
							 * give the virtual PC a slightly longer timeframe for
 | 
				
			||||||
 | 
							 * the HPET/PMTIMER to make the result precise.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (i == 1 && tsc_pit_min == ULONG_MAX) {
 | 
				
			||||||
 | 
								latch = CAL2_LATCH;
 | 
				
			||||||
 | 
								ms = CAL2_MS;
 | 
				
			||||||
 | 
								loopmin = CAL2_PIT_LOOPS;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -270,7 +463,7 @@ unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
		printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n");
 | 
							printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* We don't have an alternative source, disable TSC */
 | 
							/* We don't have an alternative source, disable TSC */
 | 
				
			||||||
		if (!hpet && !pm1 && !pm2) {
 | 
							if (!hpet && !ref1 && !ref2) {
 | 
				
			||||||
			printk("TSC: No reference (HPET/PMTIMER) available\n");
 | 
								printk("TSC: No reference (HPET/PMTIMER) available\n");
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -278,7 +471,7 @@ unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
		/* The alternative source failed as well, disable TSC */
 | 
							/* The alternative source failed as well, disable TSC */
 | 
				
			||||||
		if (tsc_ref_min == ULONG_MAX) {
 | 
							if (tsc_ref_min == ULONG_MAX) {
 | 
				
			||||||
			printk(KERN_WARNING "TSC: HPET/PMTIMER calibration "
 | 
								printk(KERN_WARNING "TSC: HPET/PMTIMER calibration "
 | 
				
			||||||
			       "failed due to SMI disturbance.\n");
 | 
								       "failed.\n");
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -290,44 +483,25 @@ unsigned long native_calibrate_tsc(void)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We don't have an alternative source, use the PIT calibration value */
 | 
						/* We don't have an alternative source, use the PIT calibration value */
 | 
				
			||||||
	if (!hpet && !pm1 && !pm2) {
 | 
						if (!hpet && !ref1 && !ref2) {
 | 
				
			||||||
		printk(KERN_INFO "TSC: Using PIT calibration value\n");
 | 
							printk(KERN_INFO "TSC: Using PIT calibration value\n");
 | 
				
			||||||
		return tsc_pit_min;
 | 
							return tsc_pit_min;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* The alternative source failed, use the PIT calibration value */
 | 
						/* The alternative source failed, use the PIT calibration value */
 | 
				
			||||||
	if (tsc_ref_min == ULONG_MAX) {
 | 
						if (tsc_ref_min == ULONG_MAX) {
 | 
				
			||||||
		printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed due "
 | 
							printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. "
 | 
				
			||||||
		       "to SMI disturbance. Using PIT calibration\n");
 | 
							       "Using PIT calibration\n");
 | 
				
			||||||
		return tsc_pit_min;
 | 
							return tsc_pit_min;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check the reference deviation */
 | 
					 | 
				
			||||||
	delta = ((u64) tsc_pit_min) * 100;
 | 
					 | 
				
			||||||
	do_div(delta, tsc_ref_min);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * If both calibration results are inside a 5% window, the we
 | 
					 | 
				
			||||||
	 * use the lower frequency of those as it is probably the
 | 
					 | 
				
			||||||
	 * closest estimate.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (delta >= 95 && delta <= 105) {
 | 
					 | 
				
			||||||
		printk(KERN_INFO "TSC: PIT calibration confirmed by %s.\n",
 | 
					 | 
				
			||||||
		       hpet ? "HPET" : "PMTIMER");
 | 
					 | 
				
			||||||
		printk(KERN_INFO "TSC: using %s calibration value\n",
 | 
					 | 
				
			||||||
		       tsc_pit_min <= tsc_ref_min ? "PIT" :
 | 
					 | 
				
			||||||
		       hpet ? "HPET" : "PMTIMER");
 | 
					 | 
				
			||||||
		return tsc_pit_min <= tsc_ref_min ? tsc_pit_min : tsc_ref_min;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n",
 | 
					 | 
				
			||||||
	       hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * The calibration values differ too much. In doubt, we use
 | 
						 * The calibration values differ too much. In doubt, we use
 | 
				
			||||||
	 * the PIT value as we know that there are PMTIMERs around
 | 
						 * the PIT value as we know that there are PMTIMERs around
 | 
				
			||||||
	 * running at double speed.
 | 
						 * running at double speed. At least we let the user know:
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
						printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n",
 | 
				
			||||||
 | 
						       hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min);
 | 
				
			||||||
	printk(KERN_INFO "TSC: Using PIT calibration value\n");
 | 
						printk(KERN_INFO "TSC: Using PIT calibration value\n");
 | 
				
			||||||
	return tsc_pit_min;
 | 
						return tsc_pit_min;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,45 +25,31 @@
 | 
				
			||||||
#include <asm/visws/cobalt.h>
 | 
					#include <asm/visws/cobalt.h>
 | 
				
			||||||
#include <asm/visws/piix4.h>
 | 
					#include <asm/visws/piix4.h>
 | 
				
			||||||
#include <asm/arch_hooks.h>
 | 
					#include <asm/arch_hooks.h>
 | 
				
			||||||
 | 
					#include <asm/io_apic.h>
 | 
				
			||||||
#include <asm/fixmap.h>
 | 
					#include <asm/fixmap.h>
 | 
				
			||||||
#include <asm/reboot.h>
 | 
					#include <asm/reboot.h>
 | 
				
			||||||
#include <asm/setup.h>
 | 
					#include <asm/setup.h>
 | 
				
			||||||
#include <asm/e820.h>
 | 
					#include <asm/e820.h>
 | 
				
			||||||
#include <asm/smp.h>
 | 
					 | 
				
			||||||
#include <asm/io.h>
 | 
					#include <asm/io.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <mach_ipi.h>
 | 
					#include <mach_ipi.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mach_apic.h"
 | 
					#include "mach_apic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/init.h>
 | 
					 | 
				
			||||||
#include <linux/smp.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <linux/kernel_stat.h>
 | 
					#include <linux/kernel_stat.h>
 | 
				
			||||||
#include <linux/interrupt.h>
 | 
					 | 
				
			||||||
#include <linux/init.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/io.h>
 | 
					 | 
				
			||||||
#include <asm/apic.h>
 | 
					 | 
				
			||||||
#include <asm/i8259.h>
 | 
					#include <asm/i8259.h>
 | 
				
			||||||
#include <asm/irq_vectors.h>
 | 
					#include <asm/irq_vectors.h>
 | 
				
			||||||
#include <asm/visws/cobalt.h>
 | 
					 | 
				
			||||||
#include <asm/visws/lithium.h>
 | 
					#include <asm/visws/lithium.h>
 | 
				
			||||||
#include <asm/visws/piix4.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/sched.h>
 | 
					#include <linux/sched.h>
 | 
				
			||||||
#include <linux/kernel.h>
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
#include <linux/init.h>
 | 
					 | 
				
			||||||
#include <linux/pci.h>
 | 
					#include <linux/pci.h>
 | 
				
			||||||
#include <linux/pci_ids.h>
 | 
					#include <linux/pci_ids.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int no_broadcast;
 | 
					extern int no_broadcast;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/io.h>
 | 
					 | 
				
			||||||
#include <asm/apic.h>
 | 
					#include <asm/apic.h>
 | 
				
			||||||
#include <asm/arch_hooks.h>
 | 
					 | 
				
			||||||
#include <asm/visws/cobalt.h>
 | 
					 | 
				
			||||||
#include <asm/visws/lithium.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
char visws_board_type	= -1;
 | 
					char visws_board_type	= -1;
 | 
				
			||||||
char visws_board_rev	= -1;
 | 
					char visws_board_rev	= -1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -393,13 +393,13 @@ static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vmi_allocate_pte(struct mm_struct *mm, u32 pfn)
 | 
					static void vmi_allocate_pte(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	vmi_set_page_type(pfn, VMI_PAGE_L1);
 | 
						vmi_set_page_type(pfn, VMI_PAGE_L1);
 | 
				
			||||||
	vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0);
 | 
						vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vmi_allocate_pmd(struct mm_struct *mm, u32 pfn)
 | 
					static void vmi_allocate_pmd(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 	/*
 | 
					 	/*
 | 
				
			||||||
	 * This call comes in very early, before mem_map is setup.
 | 
						 * This call comes in very early, before mem_map is setup.
 | 
				
			||||||
| 
						 | 
					@ -410,20 +410,20 @@ static void vmi_allocate_pmd(struct mm_struct *mm, u32 pfn)
 | 
				
			||||||
	vmi_ops.allocate_page(pfn, VMI_PAGE_L2, 0, 0, 0);
 | 
						vmi_ops.allocate_page(pfn, VMI_PAGE_L2, 0, 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vmi_allocate_pmd_clone(u32 pfn, u32 clonepfn, u32 start, u32 count)
 | 
					static void vmi_allocate_pmd_clone(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 	vmi_set_page_type(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE);
 | 
					 	vmi_set_page_type(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE);
 | 
				
			||||||
	vmi_check_page_type(clonepfn, VMI_PAGE_L2);
 | 
						vmi_check_page_type(clonepfn, VMI_PAGE_L2);
 | 
				
			||||||
	vmi_ops.allocate_page(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE, clonepfn, start, count);
 | 
						vmi_ops.allocate_page(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE, clonepfn, start, count);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vmi_release_pte(u32 pfn)
 | 
					static void vmi_release_pte(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	vmi_ops.release_page(pfn, VMI_PAGE_L1);
 | 
						vmi_ops.release_page(pfn, VMI_PAGE_L1);
 | 
				
			||||||
	vmi_set_page_type(pfn, VMI_PAGE_NORMAL);
 | 
						vmi_set_page_type(pfn, VMI_PAGE_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vmi_release_pmd(u32 pfn)
 | 
					static void vmi_release_pmd(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	vmi_ops.release_page(pfn, VMI_PAGE_L2);
 | 
						vmi_ops.release_page(pfn, VMI_PAGE_L2);
 | 
				
			||||||
	vmi_set_page_type(pfn, VMI_PAGE_NORMAL);
 | 
						vmi_set_page_type(pfn, VMI_PAGE_NORMAL);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,37 +16,46 @@ static void __rdmsr_on_cpu(void *info)
 | 
				
			||||||
	rdmsr(rv->msr_no, rv->l, rv->h);
 | 
						rdmsr(rv->msr_no, rv->l, rv->h);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __rdmsr_safe_on_cpu(void *info)
 | 
					static void __wrmsr_on_cpu(void *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct msr_info *rv = info;
 | 
						struct msr_info *rv = info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
 | 
						wrmsr(rv->msr_no, rv->l, rv->h);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe)
 | 
					int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err = 0;
 | 
						int err;
 | 
				
			||||||
	struct msr_info rv;
 | 
						struct msr_info rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rv.msr_no = msr_no;
 | 
						rv.msr_no = msr_no;
 | 
				
			||||||
	if (safe) {
 | 
						err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
 | 
				
			||||||
		err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu,
 | 
					 | 
				
			||||||
					       &rv, 1);
 | 
					 | 
				
			||||||
		err = err ? err : rv.err;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*l = rv.l;
 | 
						*l = rv.l;
 | 
				
			||||||
	*h = rv.h;
 | 
						*h = rv.h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __wrmsr_on_cpu(void *info)
 | 
					int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
						struct msr_info rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rv.msr_no = msr_no;
 | 
				
			||||||
 | 
						rv.l = l;
 | 
				
			||||||
 | 
						rv.h = h;
 | 
				
			||||||
 | 
						err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* These "safe" variants are slower and should be used when the target MSR
 | 
				
			||||||
 | 
					   may not actually exist. */
 | 
				
			||||||
 | 
					static void __rdmsr_safe_on_cpu(void *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct msr_info *rv = info;
 | 
						struct msr_info *rv = info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wrmsr(rv->msr_no, rv->l, rv->h);
 | 
						rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __wrmsr_safe_on_cpu(void *info)
 | 
					static void __wrmsr_safe_on_cpu(void *info)
 | 
				
			||||||
| 
						 | 
					@ -56,45 +65,30 @@ static void __wrmsr_safe_on_cpu(void *info)
 | 
				
			||||||
	rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
 | 
						rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe)
 | 
					int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err = 0;
 | 
						int err;
 | 
				
			||||||
 | 
						struct msr_info rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rv.msr_no = msr_no;
 | 
				
			||||||
 | 
						err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
 | 
				
			||||||
 | 
						*l = rv.l;
 | 
				
			||||||
 | 
						*h = rv.h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err ? err : rv.err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
	struct msr_info rv;
 | 
						struct msr_info rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rv.msr_no = msr_no;
 | 
						rv.msr_no = msr_no;
 | 
				
			||||||
	rv.l = l;
 | 
						rv.l = l;
 | 
				
			||||||
	rv.h = h;
 | 
						rv.h = h;
 | 
				
			||||||
	if (safe) {
 | 
						err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
 | 
				
			||||||
		err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu,
 | 
					 | 
				
			||||||
					       &rv, 1);
 | 
					 | 
				
			||||||
		err = err ? err : rv.err;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err ? err : rv.err;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return _wrmsr_on_cpu(cpu, msr_no, l, h, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return _rdmsr_on_cpu(cpu, msr_no, l, h, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* These "safe" variants are slower and should be used when the target MSR
 | 
					 | 
				
			||||||
   may not actually exist. */
 | 
					 | 
				
			||||||
int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return _wrmsr_on_cpu(cpu, msr_no, l, h, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return _rdmsr_on_cpu(cpu, msr_no, l, h, 1);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPORT_SYMBOL(rdmsr_on_cpu);
 | 
					EXPORT_SYMBOL(rdmsr_on_cpu);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ char *strcpy(char *dest, const char *src)
 | 
				
			||||||
		"testb %%al,%%al\n\t"
 | 
							"testb %%al,%%al\n\t"
 | 
				
			||||||
		"jne 1b"
 | 
							"jne 1b"
 | 
				
			||||||
		: "=&S" (d0), "=&D" (d1), "=&a" (d2)
 | 
							: "=&S" (d0), "=&D" (d1), "=&a" (d2)
 | 
				
			||||||
		:"0" (src), "1" (dest) : "memory");
 | 
							: "0" (src), "1" (dest) : "memory");
 | 
				
			||||||
	return dest;
 | 
						return dest;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strcpy);
 | 
					EXPORT_SYMBOL(strcpy);
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ char *strncpy(char *dest, const char *src, size_t count)
 | 
				
			||||||
		"stosb\n"
 | 
							"stosb\n"
 | 
				
			||||||
		"2:"
 | 
							"2:"
 | 
				
			||||||
		: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
 | 
							: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
 | 
				
			||||||
		:"0" (src), "1" (dest), "2" (count) : "memory");
 | 
							: "0" (src), "1" (dest), "2" (count) : "memory");
 | 
				
			||||||
	return dest;
 | 
						return dest;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strncpy);
 | 
					EXPORT_SYMBOL(strncpy);
 | 
				
			||||||
| 
						 | 
					@ -60,7 +60,7 @@ char *strcat(char *dest, const char *src)
 | 
				
			||||||
		"testb %%al,%%al\n\t"
 | 
							"testb %%al,%%al\n\t"
 | 
				
			||||||
		"jne 1b"
 | 
							"jne 1b"
 | 
				
			||||||
		: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
 | 
							: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
 | 
				
			||||||
		: "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu): "memory");
 | 
							: "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu) : "memory");
 | 
				
			||||||
	return dest;
 | 
						return dest;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strcat);
 | 
					EXPORT_SYMBOL(strcat);
 | 
				
			||||||
| 
						 | 
					@ -105,9 +105,9 @@ int strcmp(const char *cs, const char *ct)
 | 
				
			||||||
		"2:\tsbbl %%eax,%%eax\n\t"
 | 
							"2:\tsbbl %%eax,%%eax\n\t"
 | 
				
			||||||
		"orb $1,%%al\n"
 | 
							"orb $1,%%al\n"
 | 
				
			||||||
		"3:"
 | 
							"3:"
 | 
				
			||||||
		:"=a" (res), "=&S" (d0), "=&D" (d1)
 | 
							: "=a" (res), "=&S" (d0), "=&D" (d1)
 | 
				
			||||||
		:"1" (cs), "2" (ct)
 | 
							: "1" (cs), "2" (ct)
 | 
				
			||||||
		:"memory");
 | 
							: "memory");
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strcmp);
 | 
					EXPORT_SYMBOL(strcmp);
 | 
				
			||||||
| 
						 | 
					@ -130,9 +130,9 @@ int strncmp(const char *cs, const char *ct, size_t count)
 | 
				
			||||||
		"3:\tsbbl %%eax,%%eax\n\t"
 | 
							"3:\tsbbl %%eax,%%eax\n\t"
 | 
				
			||||||
		"orb $1,%%al\n"
 | 
							"orb $1,%%al\n"
 | 
				
			||||||
		"4:"
 | 
							"4:"
 | 
				
			||||||
		:"=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
 | 
							: "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
 | 
				
			||||||
		:"1" (cs), "2" (ct), "3" (count)
 | 
							: "1" (cs), "2" (ct), "3" (count)
 | 
				
			||||||
		:"memory");
 | 
							: "memory");
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strncmp);
 | 
					EXPORT_SYMBOL(strncmp);
 | 
				
			||||||
| 
						 | 
					@ -152,9 +152,9 @@ char *strchr(const char *s, int c)
 | 
				
			||||||
		"movl $1,%1\n"
 | 
							"movl $1,%1\n"
 | 
				
			||||||
		"2:\tmovl %1,%0\n\t"
 | 
							"2:\tmovl %1,%0\n\t"
 | 
				
			||||||
		"decl %0"
 | 
							"decl %0"
 | 
				
			||||||
		:"=a" (res), "=&S" (d0)
 | 
							: "=a" (res), "=&S" (d0)
 | 
				
			||||||
		:"1" (s), "0" (c)
 | 
							: "1" (s), "0" (c)
 | 
				
			||||||
		:"memory");
 | 
							: "memory");
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strchr);
 | 
					EXPORT_SYMBOL(strchr);
 | 
				
			||||||
| 
						 | 
					@ -169,9 +169,9 @@ size_t strlen(const char *s)
 | 
				
			||||||
		"scasb\n\t"
 | 
							"scasb\n\t"
 | 
				
			||||||
		"notl %0\n\t"
 | 
							"notl %0\n\t"
 | 
				
			||||||
		"decl %0"
 | 
							"decl %0"
 | 
				
			||||||
		:"=c" (res), "=&D" (d0)
 | 
							: "=c" (res), "=&D" (d0)
 | 
				
			||||||
		:"1" (s), "a" (0), "0" (0xffffffffu)
 | 
							: "1" (s), "a" (0), "0" (0xffffffffu)
 | 
				
			||||||
		:"memory");
 | 
							: "memory");
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strlen);
 | 
					EXPORT_SYMBOL(strlen);
 | 
				
			||||||
| 
						 | 
					@ -189,9 +189,9 @@ void *memchr(const void *cs, int c, size_t count)
 | 
				
			||||||
		"je 1f\n\t"
 | 
							"je 1f\n\t"
 | 
				
			||||||
		"movl $1,%0\n"
 | 
							"movl $1,%0\n"
 | 
				
			||||||
		"1:\tdecl %0"
 | 
							"1:\tdecl %0"
 | 
				
			||||||
		:"=D" (res), "=&c" (d0)
 | 
							: "=D" (res), "=&c" (d0)
 | 
				
			||||||
		:"a" (c), "0" (cs), "1" (count)
 | 
							: "a" (c), "0" (cs), "1" (count)
 | 
				
			||||||
		:"memory");
 | 
							: "memory");
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(memchr);
 | 
					EXPORT_SYMBOL(memchr);
 | 
				
			||||||
| 
						 | 
					@ -228,9 +228,9 @@ size_t strnlen(const char *s, size_t count)
 | 
				
			||||||
		"cmpl $-1,%1\n\t"
 | 
							"cmpl $-1,%1\n\t"
 | 
				
			||||||
		"jne 1b\n"
 | 
							"jne 1b\n"
 | 
				
			||||||
		"3:\tsubl %2,%0"
 | 
							"3:\tsubl %2,%0"
 | 
				
			||||||
		:"=a" (res), "=&d" (d0)
 | 
							: "=a" (res), "=&d" (d0)
 | 
				
			||||||
		:"c" (s), "1" (count)
 | 
							: "c" (s), "1" (count)
 | 
				
			||||||
		:"memory");
 | 
							: "memory");
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(strnlen);
 | 
					EXPORT_SYMBOL(strnlen);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,9 +23,9 @@ __asm__ __volatile__(
 | 
				
			||||||
	"jne 1b\n\t"
 | 
						"jne 1b\n\t"
 | 
				
			||||||
	"xorl %%eax,%%eax\n\t"
 | 
						"xorl %%eax,%%eax\n\t"
 | 
				
			||||||
	"2:"
 | 
						"2:"
 | 
				
			||||||
	:"=a" (__res), "=&c" (d0), "=&S" (d1)
 | 
						: "=a" (__res), "=&c" (d0), "=&S" (d1)
 | 
				
			||||||
	:"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
 | 
						: "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
 | 
				
			||||||
	:"dx", "di");
 | 
						: "dx", "di");
 | 
				
			||||||
return __res;
 | 
					return __res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -328,7 +328,7 @@ void __init initmem_init(unsigned long start_pfn,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	get_memcfg_numa();
 | 
						get_memcfg_numa();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE);
 | 
						kva_pages = roundup(calculate_numa_remap_pages(), PTRS_PER_PTE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE);
 | 
						kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE);
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,8 +148,8 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 | 
				
			||||||
	 * we have now. "break" is either changing perms, levels or
 | 
						 * we have now. "break" is either changing perms, levels or
 | 
				
			||||||
	 * address space marker.
 | 
						 * address space marker.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	prot = pgprot_val(new_prot) & ~(PTE_PFN_MASK);
 | 
						prot = pgprot_val(new_prot) & PTE_FLAGS_MASK;
 | 
				
			||||||
	cur = pgprot_val(st->current_prot) & ~(PTE_PFN_MASK);
 | 
						cur = pgprot_val(st->current_prot) & PTE_FLAGS_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!st->level) {
 | 
						if (!st->level) {
 | 
				
			||||||
		/* First entry */
 | 
							/* First entry */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,7 +225,7 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
 | 
				
			||||||
void __init cleanup_highmap(void)
 | 
					void __init cleanup_highmap(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long vaddr = __START_KERNEL_map;
 | 
						unsigned long vaddr = __START_KERNEL_map;
 | 
				
			||||||
	unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1;
 | 
						unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1;
 | 
				
			||||||
	pmd_t *pmd = level2_kernel_pgt;
 | 
						pmd_t *pmd = level2_kernel_pgt;
 | 
				
			||||||
	pmd_t *last_pmd = pmd + PTRS_PER_PMD;
 | 
						pmd_t *last_pmd = pmd + PTRS_PER_PMD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -451,14 +451,14 @@ static void __init find_early_table_space(unsigned long end)
 | 
				
			||||||
	unsigned long puds, pmds, ptes, tables, start;
 | 
						unsigned long puds, pmds, ptes, tables, start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
 | 
						puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
 | 
				
			||||||
	tables = round_up(puds * sizeof(pud_t), PAGE_SIZE);
 | 
						tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
 | 
				
			||||||
	if (direct_gbpages) {
 | 
						if (direct_gbpages) {
 | 
				
			||||||
		unsigned long extra;
 | 
							unsigned long extra;
 | 
				
			||||||
		extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
 | 
							extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
 | 
				
			||||||
		pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
 | 
							pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
 | 
							pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
 | 
				
			||||||
	tables += round_up(pmds * sizeof(pmd_t), PAGE_SIZE);
 | 
						tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cpu_has_pse) {
 | 
						if (cpu_has_pse) {
 | 
				
			||||||
		unsigned long extra;
 | 
							unsigned long extra;
 | 
				
			||||||
| 
						 | 
					@ -466,7 +466,7 @@ static void __init find_early_table_space(unsigned long end)
 | 
				
			||||||
		ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
 | 
							ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
 | 
							ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
 | 
				
			||||||
	tables += round_up(ptes * sizeof(pte_t), PAGE_SIZE);
 | 
						tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * RED-PEN putting page tables only on node 0 could
 | 
						 * RED-PEN putting page tables only on node 0 could
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,7 @@ static int __init allocate_cachealigned_memnodemap(void)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr = 0x8000;
 | 
						addr = 0x8000;
 | 
				
			||||||
	nodemap_size = round_up(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES);
 | 
						nodemap_size = roundup(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES);
 | 
				
			||||||
	nodemap_addr = find_e820_area(addr, max_pfn<<PAGE_SHIFT,
 | 
						nodemap_addr = find_e820_area(addr, max_pfn<<PAGE_SHIFT,
 | 
				
			||||||
				      nodemap_size, L1_CACHE_BYTES);
 | 
									      nodemap_size, L1_CACHE_BYTES);
 | 
				
			||||||
	if (nodemap_addr == -1UL) {
 | 
						if (nodemap_addr == -1UL) {
 | 
				
			||||||
| 
						 | 
					@ -176,10 +176,10 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
 | 
				
			||||||
	unsigned long start_pfn, last_pfn, bootmap_pages, bootmap_size;
 | 
						unsigned long start_pfn, last_pfn, bootmap_pages, bootmap_size;
 | 
				
			||||||
	unsigned long bootmap_start, nodedata_phys;
 | 
						unsigned long bootmap_start, nodedata_phys;
 | 
				
			||||||
	void *bootmap;
 | 
						void *bootmap;
 | 
				
			||||||
	const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
 | 
						const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
 | 
				
			||||||
	int nid;
 | 
						int nid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	start = round_up(start, ZONE_ALIGN);
 | 
						start = roundup(start, ZONE_ALIGN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
 | 
						printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
 | 
				
			||||||
	       start, end);
 | 
						       start, end);
 | 
				
			||||||
| 
						 | 
					@ -210,9 +210,9 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
 | 
				
			||||||
	bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn);
 | 
						bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn);
 | 
				
			||||||
	nid = phys_to_nid(nodedata_phys);
 | 
						nid = phys_to_nid(nodedata_phys);
 | 
				
			||||||
	if (nid == nodeid)
 | 
						if (nid == nodeid)
 | 
				
			||||||
		bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
 | 
							bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		bootmap_start = round_up(start, PAGE_SIZE);
 | 
							bootmap_start = roundup(start, PAGE_SIZE);
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * SMP_CACHE_BYTES could be enough, but init_bootmem_node like
 | 
						 * SMP_CACHE_BYTES could be enough, but init_bootmem_node like
 | 
				
			||||||
	 * to use that to align to PAGE_SIZE
 | 
						 * to use that to align to PAGE_SIZE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,7 @@ static inline unsigned long highmap_start_pfn(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned long highmap_end_pfn(void)
 | 
					static inline unsigned long highmap_end_pfn(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
 | 
						return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -906,11 +906,13 @@ int set_memory_ro(unsigned long addr, int numpages)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
 | 
						return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(set_memory_ro);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int set_memory_rw(unsigned long addr, int numpages)
 | 
					int set_memory_rw(unsigned long addr, int numpages)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
 | 
						return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(set_memory_rw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int set_memory_np(unsigned long addr, int numpages)
 | 
					int set_memory_np(unsigned long addr, int numpages)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,10 +63,8 @@ static inline void pgd_list_del(pgd_t *pgd)
 | 
				
			||||||
#define UNSHARED_PTRS_PER_PGD				\
 | 
					#define UNSHARED_PTRS_PER_PGD				\
 | 
				
			||||||
	(SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
 | 
						(SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pgd_ctor(void *p)
 | 
					static void pgd_ctor(pgd_t *pgd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pgd_t *pgd = p;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* If the pgd points to a shared pagetable level (either the
 | 
						/* If the pgd points to a shared pagetable level (either the
 | 
				
			||||||
	   ptes in non-PAE, or shared PMD in PAE), then just copy the
 | 
						   ptes in non-PAE, or shared PMD in PAE), then just copy the
 | 
				
			||||||
	   references from swapper_pg_dir. */
 | 
						   references from swapper_pg_dir. */
 | 
				
			||||||
| 
						 | 
					@ -87,7 +85,7 @@ static void pgd_ctor(void *p)
 | 
				
			||||||
		pgd_list_add(pgd);
 | 
							pgd_list_add(pgd);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pgd_dtor(void *pgd)
 | 
					static void pgd_dtor(pgd_t *pgd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long flags; /* can be called from interrupt context */
 | 
						unsigned long flags; /* can be called from interrupt context */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,7 +123,8 @@ static int __init parse_vmalloc(char *arg)
 | 
				
			||||||
	if (!arg)
 | 
						if (!arg)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__VMALLOC_RESERVE = memparse(arg, &arg);
 | 
						/* Add VMALLOC_OFFSET to the parsed value due to vm area guard hole*/
 | 
				
			||||||
 | 
						__VMALLOC_RESERVE = memparse(arg, &arg) + VMALLOC_OFFSET;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
early_param("vmalloc", parse_vmalloc);
 | 
					early_param("vmalloc", parse_vmalloc);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,11 +10,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/oprofile.h>
 | 
					#include <linux/oprofile.h>
 | 
				
			||||||
#include <linux/smp.h>
 | 
					#include <linux/smp.h>
 | 
				
			||||||
 | 
					#include <linux/ptrace.h>
 | 
				
			||||||
 | 
					#include <linux/nmi.h>
 | 
				
			||||||
#include <asm/msr.h>
 | 
					#include <asm/msr.h>
 | 
				
			||||||
#include <asm/ptrace.h>
 | 
					 | 
				
			||||||
#include <asm/fixmap.h>
 | 
					#include <asm/fixmap.h>
 | 
				
			||||||
#include <asm/apic.h>
 | 
					#include <asm/apic.h>
 | 
				
			||||||
#include <asm/nmi.h>
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "op_x86_model.h"
 | 
					#include "op_x86_model.h"
 | 
				
			||||||
#include "op_counter.h"
 | 
					#include "op_counter.h"
 | 
				
			||||||
| 
						 | 
					@ -40,7 +41,7 @@ static unsigned int num_controls = NUM_CONTROLS_NON_HT;
 | 
				
			||||||
static inline void setup_num_counters(void)
 | 
					static inline void setup_num_counters(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_SMP
 | 
					#ifdef CONFIG_SMP
 | 
				
			||||||
	if (smp_num_siblings == 2){
 | 
						if (smp_num_siblings == 2) {
 | 
				
			||||||
		num_counters = NUM_COUNTERS_HT2;
 | 
							num_counters = NUM_COUNTERS_HT2;
 | 
				
			||||||
		num_controls = NUM_CONTROLS_HT2;
 | 
							num_controls = NUM_CONTROLS_HT2;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -86,7 +87,7 @@ struct p4_event_binding {
 | 
				
			||||||
#define CTR_FLAME_2    (1 << 6)
 | 
					#define CTR_FLAME_2    (1 << 6)
 | 
				
			||||||
#define CTR_IQ_5       (1 << 7)
 | 
					#define CTR_IQ_5       (1 << 7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = {
 | 
					static struct p4_counter_binding p4_counters[NUM_COUNTERS_NON_HT] = {
 | 
				
			||||||
	{ CTR_BPU_0,   MSR_P4_BPU_PERFCTR0,   MSR_P4_BPU_CCCR0 },
 | 
						{ CTR_BPU_0,   MSR_P4_BPU_PERFCTR0,   MSR_P4_BPU_CCCR0 },
 | 
				
			||||||
	{ CTR_MS_0,    MSR_P4_MS_PERFCTR0,    MSR_P4_MS_CCCR0 },
 | 
						{ CTR_MS_0,    MSR_P4_MS_PERFCTR0,    MSR_P4_MS_CCCR0 },
 | 
				
			||||||
	{ CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 },
 | 
						{ CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 },
 | 
				
			||||||
| 
						 | 
					@ -97,32 +98,32 @@ static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = {
 | 
				
			||||||
	{ CTR_IQ_5,    MSR_P4_IQ_PERFCTR5,    MSR_P4_IQ_CCCR5 }
 | 
						{ CTR_IQ_5,    MSR_P4_IQ_PERFCTR5,    MSR_P4_IQ_CCCR5 }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NUM_UNUSED_CCCRS	NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT
 | 
					#define NUM_UNUSED_CCCRS (NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* p4 event codes in libop/op_event.h are indices into this table. */
 | 
					/* p4 event codes in libop/op_event.h are indices into this table. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
					static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	{ /* BRANCH_RETIRED */
 | 
						{ /* BRANCH_RETIRED */
 | 
				
			||||||
		0x05, 0x06, 
 | 
							0x05, 0x06,
 | 
				
			||||||
		{ {CTR_IQ_4, MSR_P4_CRU_ESCR2},
 | 
							{ {CTR_IQ_4, MSR_P4_CRU_ESCR2},
 | 
				
			||||||
		  {CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 | 
							  {CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	{ /* MISPRED_BRANCH_RETIRED */
 | 
						{ /* MISPRED_BRANCH_RETIRED */
 | 
				
			||||||
		0x04, 0x03, 
 | 
							0x04, 0x03,
 | 
				
			||||||
		{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 | 
							{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 | 
				
			||||||
		  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 | 
							  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	{ /* TC_DELIVER_MODE */
 | 
						{ /* TC_DELIVER_MODE */
 | 
				
			||||||
		0x01, 0x01,
 | 
							0x01, 0x01,
 | 
				
			||||||
		{ { CTR_MS_0, MSR_P4_TC_ESCR0},  
 | 
							{ { CTR_MS_0, MSR_P4_TC_ESCR0},
 | 
				
			||||||
		  { CTR_MS_2, MSR_P4_TC_ESCR1} }
 | 
							  { CTR_MS_2, MSR_P4_TC_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	{ /* BPU_FETCH_REQUEST */
 | 
						{ /* BPU_FETCH_REQUEST */
 | 
				
			||||||
		0x00, 0x03, 
 | 
							0x00, 0x03,
 | 
				
			||||||
		{ { CTR_BPU_0, MSR_P4_BPU_ESCR0},
 | 
							{ { CTR_BPU_0, MSR_P4_BPU_ESCR0},
 | 
				
			||||||
		  { CTR_BPU_2, MSR_P4_BPU_ESCR1} }
 | 
							  { CTR_BPU_2, MSR_P4_BPU_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -146,7 +147,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* LOAD_PORT_REPLAY */
 | 
						{ /* LOAD_PORT_REPLAY */
 | 
				
			||||||
		0x02, 0x04, 
 | 
							0x02, 0x04,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -170,43 +171,43 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* BSQ_CACHE_REFERENCE */
 | 
						{ /* BSQ_CACHE_REFERENCE */
 | 
				
			||||||
		0x07, 0x0c, 
 | 
							0x07, 0x0c,
 | 
				
			||||||
		{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
 | 
							{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
 | 
				
			||||||
		  { CTR_BPU_2, MSR_P4_BSU_ESCR1} }
 | 
							  { CTR_BPU_2, MSR_P4_BSU_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* IOQ_ALLOCATION */
 | 
						{ /* IOQ_ALLOCATION */
 | 
				
			||||||
		0x06, 0x03, 
 | 
							0x06, 0x03,
 | 
				
			||||||
		{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 | 
							{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 | 
				
			||||||
		  { 0, 0 } }
 | 
							  { 0, 0 } }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* IOQ_ACTIVE_ENTRIES */
 | 
						{ /* IOQ_ACTIVE_ENTRIES */
 | 
				
			||||||
		0x06, 0x1a, 
 | 
							0x06, 0x1a,
 | 
				
			||||||
		{ { CTR_BPU_2, MSR_P4_FSB_ESCR1},
 | 
							{ { CTR_BPU_2, MSR_P4_FSB_ESCR1},
 | 
				
			||||||
		  { 0, 0 } }
 | 
							  { 0, 0 } }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* FSB_DATA_ACTIVITY */
 | 
						{ /* FSB_DATA_ACTIVITY */
 | 
				
			||||||
		0x06, 0x17, 
 | 
							0x06, 0x17,
 | 
				
			||||||
		{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 | 
							{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 | 
				
			||||||
		  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
 | 
							  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* BSQ_ALLOCATION */
 | 
						{ /* BSQ_ALLOCATION */
 | 
				
			||||||
		0x07, 0x05, 
 | 
							0x07, 0x05,
 | 
				
			||||||
		{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
 | 
							{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
 | 
				
			||||||
		  { 0, 0 } }
 | 
							  { 0, 0 } }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* BSQ_ACTIVE_ENTRIES */
 | 
						{ /* BSQ_ACTIVE_ENTRIES */
 | 
				
			||||||
		0x07, 0x06,
 | 
							0x07, 0x06,
 | 
				
			||||||
		{ { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},  
 | 
							{ { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},
 | 
				
			||||||
		  { 0, 0 } }
 | 
							  { 0, 0 } }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* X87_ASSIST */
 | 
						{ /* X87_ASSIST */
 | 
				
			||||||
		0x05, 0x03, 
 | 
							0x05, 0x03,
 | 
				
			||||||
		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 | 
							{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 | 
				
			||||||
		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 | 
							  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -216,21 +217,21 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
	{ /* PACKED_SP_UOP */
 | 
						{ /* PACKED_SP_UOP */
 | 
				
			||||||
		0x01, 0x08, 
 | 
							0x01, 0x08,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
	{ /* PACKED_DP_UOP */
 | 
						{ /* PACKED_DP_UOP */
 | 
				
			||||||
		0x01, 0x0c, 
 | 
							0x01, 0x0c,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* SCALAR_SP_UOP */
 | 
						{ /* SCALAR_SP_UOP */
 | 
				
			||||||
		0x01, 0x0a, 
 | 
							0x01, 0x0a,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -242,31 +243,31 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* 64BIT_MMX_UOP */
 | 
						{ /* 64BIT_MMX_UOP */
 | 
				
			||||||
		0x01, 0x02, 
 | 
							0x01, 0x02,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
	{ /* 128BIT_MMX_UOP */
 | 
						{ /* 128BIT_MMX_UOP */
 | 
				
			||||||
		0x01, 0x1a, 
 | 
							0x01, 0x1a,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* X87_FP_UOP */
 | 
						{ /* X87_FP_UOP */
 | 
				
			||||||
		0x01, 0x04, 
 | 
							0x01, 0x04,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
	{ /* X87_SIMD_MOVES_UOP */
 | 
						{ /* X87_SIMD_MOVES_UOP */
 | 
				
			||||||
		0x01, 0x2e, 
 | 
							0x01, 0x2e,
 | 
				
			||||||
		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
							{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 | 
				
			||||||
		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
							  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
	{ /* MACHINE_CLEAR */
 | 
						{ /* MACHINE_CLEAR */
 | 
				
			||||||
		0x05, 0x02, 
 | 
							0x05, 0x02,
 | 
				
			||||||
		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 | 
							{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 | 
				
			||||||
		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 | 
							  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -276,9 +277,9 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
		{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 | 
							{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 | 
				
			||||||
		  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
 | 
							  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
	{ /* TC_MS_XFER */
 | 
						{ /* TC_MS_XFER */
 | 
				
			||||||
		0x00, 0x05, 
 | 
							0x00, 0x05,
 | 
				
			||||||
		{ { CTR_MS_0, MSR_P4_MS_ESCR0},
 | 
							{ { CTR_MS_0, MSR_P4_MS_ESCR0},
 | 
				
			||||||
		  { CTR_MS_2, MSR_P4_MS_ESCR1} }
 | 
							  { CTR_MS_2, MSR_P4_MS_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -308,7 +309,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* INSTR_RETIRED */
 | 
						{ /* INSTR_RETIRED */
 | 
				
			||||||
		0x04, 0x02, 
 | 
							0x04, 0x02,
 | 
				
			||||||
		{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 | 
							{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 | 
				
			||||||
		  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 | 
							  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -319,14 +320,14 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
		  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 | 
							  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* UOP_TYPE */    
 | 
						{ /* UOP_TYPE */
 | 
				
			||||||
		0x02, 0x02, 
 | 
							0x02, 0x02,
 | 
				
			||||||
		{ { CTR_IQ_4, MSR_P4_RAT_ESCR0},
 | 
							{ { CTR_IQ_4, MSR_P4_RAT_ESCR0},
 | 
				
			||||||
		  { CTR_IQ_5, MSR_P4_RAT_ESCR1} }
 | 
							  { CTR_IQ_5, MSR_P4_RAT_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ /* RETIRED_MISPRED_BRANCH_TYPE */
 | 
						{ /* RETIRED_MISPRED_BRANCH_TYPE */
 | 
				
			||||||
		0x02, 0x05, 
 | 
							0x02, 0x05,
 | 
				
			||||||
		{ { CTR_MS_0, MSR_P4_TBPU_ESCR0},
 | 
							{ { CTR_MS_0, MSR_P4_TBPU_ESCR0},
 | 
				
			||||||
		  { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
 | 
							  { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -349,8 +350,8 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
 | 
					#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
 | 
				
			||||||
#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
 | 
					#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
 | 
				
			||||||
#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
 | 
					#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
 | 
				
			||||||
#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0)
 | 
					#define ESCR_READ(escr, high, ev, i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0)
 | 
				
			||||||
#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0)
 | 
					#define ESCR_WRITE(escr, high, ev, i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CCCR_RESERVED_BITS 0x38030FFF
 | 
					#define CCCR_RESERVED_BITS 0x38030FFF
 | 
				
			||||||
#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
 | 
					#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
 | 
				
			||||||
| 
						 | 
					@ -360,15 +361,15 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 | 
				
			||||||
#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
 | 
					#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
 | 
				
			||||||
#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
 | 
					#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
 | 
				
			||||||
#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
 | 
					#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
 | 
				
			||||||
#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high));} while (0)
 | 
					#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0)
 | 
				
			||||||
#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high));} while (0)
 | 
					#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0)
 | 
				
			||||||
#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
 | 
					#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
 | 
				
			||||||
#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
 | 
					#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0)
 | 
					#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
 | 
				
			||||||
#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0)
 | 
					#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
 | 
				
			||||||
#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0)
 | 
					#define CTR_READ(l, h, i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h)); } while (0)
 | 
				
			||||||
#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0)
 | 
					#define CTR_WRITE(l, i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1); } while (0)
 | 
				
			||||||
#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
 | 
					#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -380,7 +381,7 @@ static unsigned int get_stagger(void)
 | 
				
			||||||
#ifdef CONFIG_SMP
 | 
					#ifdef CONFIG_SMP
 | 
				
			||||||
	int cpu = smp_processor_id();
 | 
						int cpu = smp_processor_id();
 | 
				
			||||||
	return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
 | 
						return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
 | 
				
			||||||
#endif	
 | 
					#endif
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -395,25 +396,23 @@ static unsigned long reset_value[NUM_COUNTERS_NON_HT];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void p4_fill_in_addresses(struct op_msrs * const msrs)
 | 
					static void p4_fill_in_addresses(struct op_msrs * const msrs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int i; 
 | 
						unsigned int i;
 | 
				
			||||||
	unsigned int addr, cccraddr, stag;
 | 
						unsigned int addr, cccraddr, stag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setup_num_counters();
 | 
						setup_num_counters();
 | 
				
			||||||
	stag = get_stagger();
 | 
						stag = get_stagger();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initialize some registers */
 | 
						/* initialize some registers */
 | 
				
			||||||
	for (i = 0; i < num_counters; ++i) {
 | 
						for (i = 0; i < num_counters; ++i)
 | 
				
			||||||
		msrs->counters[i].addr = 0;
 | 
							msrs->counters[i].addr = 0;
 | 
				
			||||||
	}
 | 
						for (i = 0; i < num_controls; ++i)
 | 
				
			||||||
	for (i = 0; i < num_controls; ++i) {
 | 
					 | 
				
			||||||
		msrs->controls[i].addr = 0;
 | 
							msrs->controls[i].addr = 0;
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	/* the counter & cccr registers we pay attention to */
 | 
						/* the counter & cccr registers we pay attention to */
 | 
				
			||||||
	for (i = 0; i < num_counters; ++i) {
 | 
						for (i = 0; i < num_counters; ++i) {
 | 
				
			||||||
		addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
 | 
							addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
 | 
				
			||||||
		cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address;
 | 
							cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address;
 | 
				
			||||||
		if (reserve_perfctr_nmi(addr)){
 | 
							if (reserve_perfctr_nmi(addr)) {
 | 
				
			||||||
			msrs->counters[i].addr = addr;
 | 
								msrs->counters[i].addr = addr;
 | 
				
			||||||
			msrs->controls[i].addr = cccraddr;
 | 
								msrs->controls[i].addr = cccraddr;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -447,22 +446,22 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
 | 
				
			||||||
		if (reserve_evntsel_nmi(addr))
 | 
							if (reserve_evntsel_nmi(addr))
 | 
				
			||||||
			msrs->controls[i].addr = addr;
 | 
								msrs->controls[i].addr = addr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for (addr = MSR_P4_MS_ESCR0 + stag;
 | 
						for (addr = MSR_P4_MS_ESCR0 + stag;
 | 
				
			||||||
	     addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { 
 | 
						     addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) {
 | 
				
			||||||
		if (reserve_evntsel_nmi(addr))
 | 
							if (reserve_evntsel_nmi(addr))
 | 
				
			||||||
			msrs->controls[i].addr = addr;
 | 
								msrs->controls[i].addr = addr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for (addr = MSR_P4_IX_ESCR0 + stag;
 | 
						for (addr = MSR_P4_IX_ESCR0 + stag;
 | 
				
			||||||
	     addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { 
 | 
						     addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) {
 | 
				
			||||||
		if (reserve_evntsel_nmi(addr))
 | 
							if (reserve_evntsel_nmi(addr))
 | 
				
			||||||
			msrs->controls[i].addr = addr;
 | 
								msrs->controls[i].addr = addr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* there are 2 remaining non-contiguously located ESCRs */
 | 
						/* there are 2 remaining non-contiguously located ESCRs */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (num_counters == NUM_COUNTERS_NON_HT) {		
 | 
						if (num_counters == NUM_COUNTERS_NON_HT) {
 | 
				
			||||||
		/* standard non-HT CPUs handle both remaining ESCRs*/
 | 
							/* standard non-HT CPUs handle both remaining ESCRs*/
 | 
				
			||||||
		if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5))
 | 
							if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5))
 | 
				
			||||||
			msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
 | 
								msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
 | 
				
			||||||
| 
						 | 
					@ -498,20 +497,20 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
 | 
				
			||||||
	unsigned int stag;
 | 
						unsigned int stag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stag = get_stagger();
 | 
						stag = get_stagger();
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* convert from counter *number* to counter *bit* */
 | 
						/* convert from counter *number* to counter *bit* */
 | 
				
			||||||
	counter_bit = 1 << VIRT_CTR(stag, ctr);
 | 
						counter_bit = 1 << VIRT_CTR(stag, ctr);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	/* find our event binding structure. */
 | 
						/* find our event binding structure. */
 | 
				
			||||||
	if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) {
 | 
						if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) {
 | 
				
			||||||
		printk(KERN_ERR 
 | 
							printk(KERN_ERR
 | 
				
			||||||
		       "oprofile: P4 event code 0x%lx out of range\n", 
 | 
							       "oprofile: P4 event code 0x%lx out of range\n",
 | 
				
			||||||
		       counter_config[ctr].event);
 | 
							       counter_config[ctr].event);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	ev = &(p4_events[counter_config[ctr].event - 1]);
 | 
						ev = &(p4_events[counter_config[ctr].event - 1]);
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for (i = 0; i < maxbind; i++) {
 | 
						for (i = 0; i < maxbind; i++) {
 | 
				
			||||||
		if (ev->bindings[i].virt_counter & counter_bit) {
 | 
							if (ev->bindings[i].virt_counter & counter_bit) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -526,25 +525,24 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
 | 
				
			||||||
				ESCR_SET_OS_1(escr, counter_config[ctr].kernel);
 | 
									ESCR_SET_OS_1(escr, counter_config[ctr].kernel);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ESCR_SET_EVENT_SELECT(escr, ev->event_select);
 | 
								ESCR_SET_EVENT_SELECT(escr, ev->event_select);
 | 
				
			||||||
			ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);			
 | 
								ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);
 | 
				
			||||||
			ESCR_WRITE(escr, high, ev, i);
 | 
								ESCR_WRITE(escr, high, ev, i);
 | 
				
			||||||
		       
 | 
					
 | 
				
			||||||
			/* modify CCCR */
 | 
								/* modify CCCR */
 | 
				
			||||||
			CCCR_READ(cccr, high, VIRT_CTR(stag, ctr));
 | 
								CCCR_READ(cccr, high, VIRT_CTR(stag, ctr));
 | 
				
			||||||
			CCCR_CLEAR(cccr);
 | 
								CCCR_CLEAR(cccr);
 | 
				
			||||||
			CCCR_SET_REQUIRED_BITS(cccr);
 | 
								CCCR_SET_REQUIRED_BITS(cccr);
 | 
				
			||||||
			CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
 | 
								CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
 | 
				
			||||||
			if (stag == 0) {
 | 
								if (stag == 0)
 | 
				
			||||||
				CCCR_SET_PMI_OVF_0(cccr);
 | 
									CCCR_SET_PMI_OVF_0(cccr);
 | 
				
			||||||
			} else {
 | 
								else
 | 
				
			||||||
				CCCR_SET_PMI_OVF_1(cccr);
 | 
									CCCR_SET_PMI_OVF_1(cccr);
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr));
 | 
								CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr));
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_ERR 
 | 
						printk(KERN_ERR
 | 
				
			||||||
	       "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n",
 | 
						       "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n",
 | 
				
			||||||
	       counter_config[ctr].event, stag, ctr);
 | 
						       counter_config[ctr].event, stag, ctr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -559,14 +557,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
 | 
				
			||||||
	stag = get_stagger();
 | 
						stag = get_stagger();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rdmsr(MSR_IA32_MISC_ENABLE, low, high);
 | 
						rdmsr(MSR_IA32_MISC_ENABLE, low, high);
 | 
				
			||||||
	if (! MISC_PMC_ENABLED_P(low)) {
 | 
						if (!MISC_PMC_ENABLED_P(low)) {
 | 
				
			||||||
		printk(KERN_ERR "oprofile: P4 PMC not available\n");
 | 
							printk(KERN_ERR "oprofile: P4 PMC not available\n");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* clear the cccrs we will use */
 | 
						/* clear the cccrs we will use */
 | 
				
			||||||
	for (i = 0 ; i < num_counters ; i++) {
 | 
						for (i = 0 ; i < num_counters ; i++) {
 | 
				
			||||||
		if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
 | 
							if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 | 
							rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 | 
				
			||||||
		CCCR_CLEAR(low);
 | 
							CCCR_CLEAR(low);
 | 
				
			||||||
| 
						 | 
					@ -576,14 +574,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* clear all escrs (including those outside our concern) */
 | 
						/* clear all escrs (including those outside our concern) */
 | 
				
			||||||
	for (i = num_counters; i < num_controls; i++) {
 | 
						for (i = num_counters; i < num_controls; i++) {
 | 
				
			||||||
		if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
 | 
							if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		wrmsr(msrs->controls[i].addr, 0, 0);
 | 
							wrmsr(msrs->controls[i].addr, 0, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* setup all counters */
 | 
						/* setup all counters */
 | 
				
			||||||
	for (i = 0 ; i < num_counters ; ++i) {
 | 
						for (i = 0 ; i < num_counters ; ++i) {
 | 
				
			||||||
		if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs,i))) {
 | 
							if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs, i))) {
 | 
				
			||||||
			reset_value[i] = counter_config[i].count;
 | 
								reset_value[i] = counter_config[i].count;
 | 
				
			||||||
			pmc_setup_one_p4_counter(i);
 | 
								pmc_setup_one_p4_counter(i);
 | 
				
			||||||
			CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i));
 | 
								CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i));
 | 
				
			||||||
| 
						 | 
					@ -603,11 +601,11 @@ static int p4_check_ctrs(struct pt_regs * const regs,
 | 
				
			||||||
	stag = get_stagger();
 | 
						stag = get_stagger();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < num_counters; ++i) {
 | 
						for (i = 0; i < num_counters; ++i) {
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if (!reset_value[i]) 
 | 
							if (!reset_value[i])
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* 
 | 
							/*
 | 
				
			||||||
		 * there is some eccentricity in the hardware which
 | 
							 * there is some eccentricity in the hardware which
 | 
				
			||||||
		 * requires that we perform 2 extra corrections:
 | 
							 * requires that we perform 2 extra corrections:
 | 
				
			||||||
		 *
 | 
							 *
 | 
				
			||||||
| 
						 | 
					@ -616,24 +614,24 @@ static int p4_check_ctrs(struct pt_regs * const regs,
 | 
				
			||||||
		 *
 | 
							 *
 | 
				
			||||||
		 * - write the counter back twice to ensure it gets
 | 
							 * - write the counter back twice to ensure it gets
 | 
				
			||||||
		 *   updated properly.
 | 
							 *   updated properly.
 | 
				
			||||||
		 * 
 | 
							 *
 | 
				
			||||||
		 * the former seems to be related to extra NMIs happening
 | 
							 * the former seems to be related to extra NMIs happening
 | 
				
			||||||
		 * during the current NMI; the latter is reported as errata
 | 
							 * during the current NMI; the latter is reported as errata
 | 
				
			||||||
		 * N15 in intel doc 249199-029, pentium 4 specification
 | 
							 * N15 in intel doc 249199-029, pentium 4 specification
 | 
				
			||||||
		 * update, though their suggested work-around does not
 | 
							 * update, though their suggested work-around does not
 | 
				
			||||||
		 * appear to solve the problem.
 | 
							 * appear to solve the problem.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		real = VIRT_CTR(stag, i);
 | 
							real = VIRT_CTR(stag, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		CCCR_READ(low, high, real);
 | 
							CCCR_READ(low, high, real);
 | 
				
			||||||
 		CTR_READ(ctr, high, real);
 | 
							CTR_READ(ctr, high, real);
 | 
				
			||||||
		if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
 | 
							if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
 | 
				
			||||||
			oprofile_add_sample(regs, i);
 | 
								oprofile_add_sample(regs, i);
 | 
				
			||||||
 			CTR_WRITE(reset_value[i], real);
 | 
								CTR_WRITE(reset_value[i], real);
 | 
				
			||||||
			CCCR_CLEAR_OVF(low);
 | 
								CCCR_CLEAR_OVF(low);
 | 
				
			||||||
			CCCR_WRITE(low, high, real);
 | 
								CCCR_WRITE(low, high, real);
 | 
				
			||||||
 			CTR_WRITE(reset_value[i], real);
 | 
								CTR_WRITE(reset_value[i], real);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -683,15 +681,16 @@ static void p4_shutdown(struct op_msrs const * const msrs)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0 ; i < num_counters ; ++i) {
 | 
						for (i = 0 ; i < num_counters ; ++i) {
 | 
				
			||||||
		if (CTR_IS_RESERVED(msrs,i))
 | 
							if (CTR_IS_RESERVED(msrs, i))
 | 
				
			||||||
			release_perfctr_nmi(msrs->counters[i].addr);
 | 
								release_perfctr_nmi(msrs->counters[i].addr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* some of the control registers are specially reserved in
 | 
						/*
 | 
				
			||||||
 | 
						 * some of the control registers are specially reserved in
 | 
				
			||||||
	 * conjunction with the counter registers (hence the starting offset).
 | 
						 * conjunction with the counter registers (hence the starting offset).
 | 
				
			||||||
	 * This saves a few bits.
 | 
						 * This saves a few bits.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	for (i = num_counters ; i < num_controls ; ++i) {
 | 
						for (i = num_counters ; i < num_controls ; ++i) {
 | 
				
			||||||
		if (CTRL_IS_RESERVED(msrs,i))
 | 
							if (CTRL_IS_RESERVED(msrs, i))
 | 
				
			||||||
			release_evntsel_nmi(msrs->controls[i].addr);
 | 
								release_evntsel_nmi(msrs->controls[i].addr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -580,7 +580,7 @@ static int __cpuinit amd_cpu_notify(struct notifier_block *self,
 | 
				
			||||||
				    unsigned long action, void *hcpu)
 | 
									    unsigned long action, void *hcpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int cpu = (long)hcpu;
 | 
						int cpu = (long)hcpu;
 | 
				
			||||||
	switch(action) {
 | 
						switch (action) {
 | 
				
			||||||
	case CPU_ONLINE:
 | 
						case CPU_ONLINE:
 | 
				
			||||||
	case CPU_ONLINE_FROZEN:
 | 
						case CPU_ONLINE_FROZEN:
 | 
				
			||||||
		smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0);
 | 
							smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1043,35 +1043,44 @@ static void __init pcibios_fixup_irqs(void)
 | 
				
			||||||
		if (io_apic_assign_pci_irqs) {
 | 
							if (io_apic_assign_pci_irqs) {
 | 
				
			||||||
			int irq;
 | 
								int irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (pin) {
 | 
								if (!pin)
 | 
				
			||||||
				/*
 | 
									continue;
 | 
				
			||||||
				 * interrupt pins are numbered starting
 | 
					 | 
				
			||||||
				 * from 1
 | 
					 | 
				
			||||||
				 */
 | 
					 | 
				
			||||||
				pin--;
 | 
					 | 
				
			||||||
				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
 | 
					 | 
				
			||||||
					PCI_SLOT(dev->devfn), pin);
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Busses behind bridges are typically not listed in the MP-table.
 | 
					 | 
				
			||||||
	 * In this case we have to look up the IRQ based on the parent bus,
 | 
					 | 
				
			||||||
	 * parent slot, and pin number. The SMP code detects such bridged
 | 
					 | 
				
			||||||
	 * busses itself so we should get into this branch reliably.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
 | 
					 | 
				
			||||||
					struct pci_dev *bridge = dev->bus->self;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
 | 
								/*
 | 
				
			||||||
					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
 | 
								 * interrupt pins are numbered starting from 1
 | 
				
			||||||
							PCI_SLOT(bridge->devfn), pin);
 | 
								 */
 | 
				
			||||||
					if (irq >= 0)
 | 
								pin--;
 | 
				
			||||||
						dev_warn(&dev->dev, "using bridge %s INT %c to get IRQ %d\n",
 | 
								irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
 | 
				
			||||||
							 pci_name(bridge),
 | 
									PCI_SLOT(dev->devfn), pin);
 | 
				
			||||||
							 'A' + pin, irq);
 | 
								/*
 | 
				
			||||||
				}
 | 
								 * Busses behind bridges are typically not listed in the
 | 
				
			||||||
				if (irq >= 0) {
 | 
								 * MP-table.  In this case we have to look up the IRQ
 | 
				
			||||||
					dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c -> IRQ %d\n", 'A' + pin, irq);
 | 
								 * based on the parent bus, parent slot, and pin number.
 | 
				
			||||||
					dev->irq = irq;
 | 
								 * The SMP code detects such bridged busses itself so we
 | 
				
			||||||
				}
 | 
								 * should get into this branch reliably.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (irq < 0 && dev->bus->parent) {
 | 
				
			||||||
 | 
									/* go back to the bridge */
 | 
				
			||||||
 | 
									struct pci_dev *bridge = dev->bus->self;
 | 
				
			||||||
 | 
									int bus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									pin = (pin + PCI_SLOT(dev->devfn)) % 4;
 | 
				
			||||||
 | 
									bus = bridge->bus->number;
 | 
				
			||||||
 | 
									irq = IO_APIC_get_PCI_irq_vector(bus,
 | 
				
			||||||
 | 
											PCI_SLOT(bridge->devfn), pin);
 | 
				
			||||||
 | 
									if (irq >= 0)
 | 
				
			||||||
 | 
										dev_warn(&dev->dev,
 | 
				
			||||||
 | 
											"using bridge %s INT %c to "
 | 
				
			||||||
 | 
												"get IRQ %d\n",
 | 
				
			||||||
 | 
											 pci_name(bridge),
 | 
				
			||||||
 | 
											 'A' + pin, irq);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (irq >= 0) {
 | 
				
			||||||
 | 
									dev_info(&dev->dev,
 | 
				
			||||||
 | 
										"PCI->APIC IRQ transform: INT %c "
 | 
				
			||||||
 | 
											"-> IRQ %d\n",
 | 
				
			||||||
 | 
										'A' + pin, irq);
 | 
				
			||||||
 | 
									dev->irq = irq;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,3 @@
 | 
				
			||||||
.text
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This may not use any stack, nor any variable that is not "NoSave":
 | 
					 * This may not use any stack, nor any variable that is not "NoSave":
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -12,17 +10,18 @@
 | 
				
			||||||
#include <asm/segment.h>
 | 
					#include <asm/segment.h>
 | 
				
			||||||
#include <asm/page.h>
 | 
					#include <asm/page.h>
 | 
				
			||||||
#include <asm/asm-offsets.h>
 | 
					#include <asm/asm-offsets.h>
 | 
				
			||||||
 | 
					#include <asm/processor-flags.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.text
 | 
					.text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRY(swsusp_arch_suspend)
 | 
					ENTRY(swsusp_arch_suspend)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	movl %esp, saved_context_esp
 | 
						movl %esp, saved_context_esp
 | 
				
			||||||
	movl %ebx, saved_context_ebx
 | 
						movl %ebx, saved_context_ebx
 | 
				
			||||||
	movl %ebp, saved_context_ebp
 | 
						movl %ebp, saved_context_ebp
 | 
				
			||||||
	movl %esi, saved_context_esi
 | 
						movl %esi, saved_context_esi
 | 
				
			||||||
	movl %edi, saved_context_edi
 | 
						movl %edi, saved_context_edi
 | 
				
			||||||
	pushfl ; popl saved_context_eflags
 | 
						pushfl
 | 
				
			||||||
 | 
						popl saved_context_eflags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	call swsusp_save
 | 
						call swsusp_save
 | 
				
			||||||
	ret
 | 
						ret
 | 
				
			||||||
| 
						 | 
					@ -59,7 +58,7 @@ done:
 | 
				
			||||||
	movl	mmu_cr4_features, %ecx
 | 
						movl	mmu_cr4_features, %ecx
 | 
				
			||||||
	jecxz	1f	# cr4 Pentium and higher, skip if zero
 | 
						jecxz	1f	# cr4 Pentium and higher, skip if zero
 | 
				
			||||||
	movl	%ecx, %edx
 | 
						movl	%ecx, %edx
 | 
				
			||||||
	andl	$~(1<<7), %edx;  # PGE
 | 
						andl	$~(X86_CR4_PGE), %edx
 | 
				
			||||||
	movl	%edx, %cr4;  # turn off PGE
 | 
						movl	%edx, %cr4;  # turn off PGE
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
	movl	%cr3, %eax;  # flush TLB
 | 
						movl	%cr3, %eax;  # flush TLB
 | 
				
			||||||
| 
						 | 
					@ -74,7 +73,8 @@ done:
 | 
				
			||||||
	movl saved_context_esi, %esi
 | 
						movl saved_context_esi, %esi
 | 
				
			||||||
	movl saved_context_edi, %edi
 | 
						movl saved_context_edi, %edi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pushl saved_context_eflags ; popfl
 | 
						pushl saved_context_eflags
 | 
				
			||||||
 | 
						popfl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xorl	%eax, %eax
 | 
						xorl	%eax, %eax
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -812,7 +812,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Early in boot, while setting up the initial pagetable, assume
 | 
					/* Early in boot, while setting up the initial pagetable, assume
 | 
				
			||||||
   everything is pinned. */
 | 
					   everything is pinned. */
 | 
				
			||||||
static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
 | 
					static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_FLATMEM
 | 
					#ifdef CONFIG_FLATMEM
 | 
				
			||||||
	BUG_ON(mem_map);	/* should only be used early */
 | 
						BUG_ON(mem_map);	/* should only be used early */
 | 
				
			||||||
| 
						 | 
					@ -822,7 +822,7 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Early release_pte assumes that all pts are pinned, since there's
 | 
					/* Early release_pte assumes that all pts are pinned, since there's
 | 
				
			||||||
   only init_mm and anything attached to that is pinned. */
 | 
					   only init_mm and anything attached to that is pinned. */
 | 
				
			||||||
static void xen_release_pte_init(u32 pfn)
 | 
					static void xen_release_pte_init(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
 | 
						make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -838,7 +838,7 @@ static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This needs to make sure the new pte page is pinned iff its being
 | 
					/* This needs to make sure the new pte page is pinned iff its being
 | 
				
			||||||
   attached to a pinned pagetable. */
 | 
					   attached to a pinned pagetable. */
 | 
				
			||||||
static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
 | 
					static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned level)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct page *page = pfn_to_page(pfn);
 | 
						struct page *page = pfn_to_page(pfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -856,12 +856,12 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xen_alloc_pte(struct mm_struct *mm, u32 pfn)
 | 
					static void xen_alloc_pte(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xen_alloc_ptpage(mm, pfn, PT_PTE);
 | 
						xen_alloc_ptpage(mm, pfn, PT_PTE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xen_alloc_pmd(struct mm_struct *mm, u32 pfn)
 | 
					static void xen_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xen_alloc_ptpage(mm, pfn, PT_PMD);
 | 
						xen_alloc_ptpage(mm, pfn, PT_PMD);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -909,7 +909,7 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This should never happen until we're OK to use struct page */
 | 
					/* This should never happen until we're OK to use struct page */
 | 
				
			||||||
static void xen_release_ptpage(u32 pfn, unsigned level)
 | 
					static void xen_release_ptpage(unsigned long pfn, unsigned level)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct page *page = pfn_to_page(pfn);
 | 
						struct page *page = pfn_to_page(pfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -923,23 +923,23 @@ static void xen_release_ptpage(u32 pfn, unsigned level)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xen_release_pte(u32 pfn)
 | 
					static void xen_release_pte(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xen_release_ptpage(pfn, PT_PTE);
 | 
						xen_release_ptpage(pfn, PT_PTE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xen_release_pmd(u32 pfn)
 | 
					static void xen_release_pmd(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xen_release_ptpage(pfn, PT_PMD);
 | 
						xen_release_ptpage(pfn, PT_PMD);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if PAGETABLE_LEVELS == 4
 | 
					#if PAGETABLE_LEVELS == 4
 | 
				
			||||||
static void xen_alloc_pud(struct mm_struct *mm, u32 pfn)
 | 
					static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xen_alloc_ptpage(mm, pfn, PT_PUD);
 | 
						xen_alloc_ptpage(mm, pfn, PT_PUD);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xen_release_pud(u32 pfn)
 | 
					static void xen_release_pud(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xen_release_ptpage(pfn, PT_PUD);
 | 
						xen_release_ptpage(pfn, PT_PUD);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,9 +81,7 @@ extern int get_physical_broadcast(void);
 | 
				
			||||||
static inline void ack_APIC_irq(void)
 | 
					static inline void ack_APIC_irq(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * ack_APIC_irq() actually gets compiled as a single instruction:
 | 
						 * ack_APIC_irq() actually gets compiled as a single instruction
 | 
				
			||||||
	 * - a single rmw on Pentium/82489DX
 | 
					 | 
				
			||||||
	 * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC)
 | 
					 | 
				
			||||||
	 * ... yummie.
 | 
						 * ... yummie.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,17 +20,22 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _ASM_PTR	__ASM_SEL(.long, .quad)
 | 
					#define _ASM_PTR	__ASM_SEL(.long, .quad)
 | 
				
			||||||
#define _ASM_ALIGN	__ASM_SEL(.balign 4, .balign 8)
 | 
					#define _ASM_ALIGN	__ASM_SEL(.balign 4, .balign 8)
 | 
				
			||||||
#define _ASM_MOV_UL	__ASM_SIZE(mov)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _ASM_MOV	__ASM_SIZE(mov)
 | 
				
			||||||
#define _ASM_INC	__ASM_SIZE(inc)
 | 
					#define _ASM_INC	__ASM_SIZE(inc)
 | 
				
			||||||
#define _ASM_DEC	__ASM_SIZE(dec)
 | 
					#define _ASM_DEC	__ASM_SIZE(dec)
 | 
				
			||||||
#define _ASM_ADD	__ASM_SIZE(add)
 | 
					#define _ASM_ADD	__ASM_SIZE(add)
 | 
				
			||||||
#define _ASM_SUB	__ASM_SIZE(sub)
 | 
					#define _ASM_SUB	__ASM_SIZE(sub)
 | 
				
			||||||
#define _ASM_XADD	__ASM_SIZE(xadd)
 | 
					#define _ASM_XADD	__ASM_SIZE(xadd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _ASM_AX		__ASM_REG(ax)
 | 
					#define _ASM_AX		__ASM_REG(ax)
 | 
				
			||||||
#define _ASM_BX		__ASM_REG(bx)
 | 
					#define _ASM_BX		__ASM_REG(bx)
 | 
				
			||||||
#define _ASM_CX		__ASM_REG(cx)
 | 
					#define _ASM_CX		__ASM_REG(cx)
 | 
				
			||||||
#define _ASM_DX		__ASM_REG(dx)
 | 
					#define _ASM_DX		__ASM_REG(dx)
 | 
				
			||||||
 | 
					#define _ASM_SP		__ASM_REG(sp)
 | 
				
			||||||
 | 
					#define _ASM_BP		__ASM_REG(bp)
 | 
				
			||||||
 | 
					#define _ASM_SI		__ASM_REG(si)
 | 
				
			||||||
 | 
					#define _ASM_DI		__ASM_REG(di)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Exception table entry */
 | 
					/* Exception table entry */
 | 
				
			||||||
# define _ASM_EXTABLE(from,to) \
 | 
					# define _ASM_EXTABLE(from,to) \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,8 +148,9 @@ do {						\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
 | 
					static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	asm volatile("movl %0,%%fs" :: "r" (0));
 | 
						loadsegment(fs, 0);
 | 
				
			||||||
	asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS));
 | 
						loadsegment(ds, __USER32_DS);
 | 
				
			||||||
 | 
						loadsegment(es, __USER32_DS);
 | 
				
			||||||
	load_gs_index(0);
 | 
						load_gs_index(0);
 | 
				
			||||||
	regs->ip = ip;
 | 
						regs->ip = ip;
 | 
				
			||||||
	regs->sp = sp;
 | 
						regs->sp = sp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@
 | 
				
			||||||
	asm volatile("1:\tmovl	%2, %0\n"			\
 | 
						asm volatile("1:\tmovl	%2, %0\n"			\
 | 
				
			||||||
		     "\tmovl\t%0, %3\n"				\
 | 
							     "\tmovl\t%0, %3\n"				\
 | 
				
			||||||
		     "\t" insn "\n"				\
 | 
							     "\t" insn "\n"				\
 | 
				
			||||||
		     "2:\tlock; cmpxchgl %3, %2\n"		\
 | 
							     "2:\t" LOCK_PREFIX "cmpxchgl %3, %2\n"	\
 | 
				
			||||||
		     "\tjnz\t1b\n"				\
 | 
							     "\tjnz\t1b\n"				\
 | 
				
			||||||
		     "3:\t.section .fixup,\"ax\"\n"		\
 | 
							     "3:\t.section .fixup,\"ax\"\n"		\
 | 
				
			||||||
		     "4:\tmov\t%5, %1\n"			\
 | 
							     "4:\tmov\t%5, %1\n"			\
 | 
				
			||||||
| 
						 | 
					@ -64,7 +64,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
 | 
				
			||||||
		__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
 | 
							__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case FUTEX_OP_ADD:
 | 
						case FUTEX_OP_ADD:
 | 
				
			||||||
		__futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
 | 
							__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
 | 
				
			||||||
				   uaddr, oparg);
 | 
									   uaddr, oparg);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case FUTEX_OP_OR:
 | 
						case FUTEX_OP_OR:
 | 
				
			||||||
| 
						 | 
					@ -122,7 +122,7 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
 | 
				
			||||||
	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
 | 
						if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asm volatile("1:\tlock; cmpxchgl %3, %1\n"
 | 
						asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
 | 
				
			||||||
		     "2:\t.section .fixup, \"ax\"\n"
 | 
							     "2:\t.section .fixup, \"ax\"\n"
 | 
				
			||||||
		     "3:\tmov     %2, %0\n"
 | 
							     "3:\tmov     %2, %0\n"
 | 
				
			||||||
		     "\tjmp     2b\n"
 | 
							     "\tjmp     2b\n"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,15 +52,15 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (aper_base + aper_size > 0x100000000ULL) {
 | 
						if (aper_base + aper_size > 0x100000000ULL) {
 | 
				
			||||||
		printk(KERN_ERR "Aperture beyond 4GB. Ignoring.\n");
 | 
							printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
 | 
						if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
 | 
				
			||||||
		printk(KERN_ERR "Aperture pointing to e820 RAM. Ignoring.\n");
 | 
							printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (aper_size < min_size) {
 | 
						if (aper_size < min_size) {
 | 
				
			||||||
		printk(KERN_ERR "Aperture too small (%d MB) than (%d MB)\n",
 | 
							printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
 | 
				
			||||||
				 aper_size>>20, min_size>>20);
 | 
									 aper_size>>20, min_size>>20);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
#ifndef ASM_X86__MACH_RDC321X__GPIO_H
 | 
					#ifndef ASM_X86__MACH_RDC321X__GPIO_H
 | 
				
			||||||
#define ASM_X86__MACH_RDC321X__GPIO_H
 | 
					#define ASM_X86__MACH_RDC321X__GPIO_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int rdc_gpio_get_value(unsigned gpio);
 | 
					extern int rdc_gpio_get_value(unsigned gpio);
 | 
				
			||||||
extern void rdc_gpio_set_value(unsigned gpio, int value);
 | 
					extern void rdc_gpio_set_value(unsigned gpio, int value);
 | 
				
			||||||
extern int rdc_gpio_direction_input(unsigned gpio);
 | 
					extern int rdc_gpio_direction_input(unsigned gpio);
 | 
				
			||||||
| 
						 | 
					@ -18,6 +20,7 @@ static inline int gpio_request(unsigned gpio, const char *label)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gpio_free(unsigned gpio)
 | 
					static inline void gpio_free(unsigned gpio)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						might_sleep();
 | 
				
			||||||
	rdc_gpio_free(gpio);
 | 
						rdc_gpio_free(gpio);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,14 +7,9 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * The x86 doesn't have a mmu context, but
 | 
					 * The x86 doesn't have a mmu context, but
 | 
				
			||||||
 * we put the segment information here.
 | 
					 * we put the segment information here.
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * cpu_vm_mask is used to optimize ldt flushing.
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	void *ldt;
 | 
						void *ldt;
 | 
				
			||||||
#ifdef CONFIG_X86_64
 | 
					 | 
				
			||||||
	rwlock_t ldtlock;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	int size;
 | 
						int size;
 | 
				
			||||||
	struct mutex lock;
 | 
						struct mutex lock;
 | 
				
			||||||
	void *vdso;
 | 
						void *vdso;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,22 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 | 
				
			||||||
	return EAX_EDX_VAL(val, low, high);
 | 
						return EAX_EDX_VAL(val, low, high);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
 | 
				
			||||||
 | 
											      int *err)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DECLARE_ARGS(val, low, high);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						asm volatile("2: rdmsr ; xor %0,%0\n"
 | 
				
			||||||
 | 
							     "1:\n\t"
 | 
				
			||||||
 | 
							     ".section .fixup,\"ax\"\n\t"
 | 
				
			||||||
 | 
							     "3:  mov %3,%0 ; jmp 1b\n\t"
 | 
				
			||||||
 | 
							     ".previous\n\t"
 | 
				
			||||||
 | 
							     _ASM_EXTABLE(2b, 3b)
 | 
				
			||||||
 | 
							     : "=r" (*err), EAX_EDX_RET(val, low, high)
 | 
				
			||||||
 | 
							     : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
 | 
				
			||||||
 | 
						return EAX_EDX_VAL(val, low, high);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void native_write_msr(unsigned int msr,
 | 
					static inline void native_write_msr(unsigned int msr,
 | 
				
			||||||
				    unsigned low, unsigned high)
 | 
									    unsigned low, unsigned high)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -158,6 +174,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 | 
				
			||||||
	*p = native_read_msr_safe(msr, &err);
 | 
						*p = native_read_msr_safe(msr, &err);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*p = native_read_msr_amd_safe(msr, &err);
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define rdtscl(low)						\
 | 
					#define rdtscl(low)						\
 | 
				
			||||||
	((low) = (u32)native_read_tsc())
 | 
						((low) = (u32)native_read_tsc())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@ extern void stop_apic_nmi_watchdog(void *);
 | 
				
			||||||
extern void disable_timer_nmi_watchdog(void);
 | 
					extern void disable_timer_nmi_watchdog(void);
 | 
				
			||||||
extern void enable_timer_nmi_watchdog(void);
 | 
					extern void enable_timer_nmi_watchdog(void);
 | 
				
			||||||
extern int nmi_watchdog_tick(struct pt_regs *regs, unsigned reason);
 | 
					extern int nmi_watchdog_tick(struct pt_regs *regs, unsigned reason);
 | 
				
			||||||
 | 
					extern void cpu_nmi_set_wd_enabled(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern atomic_t nmi_active;
 | 
					extern atomic_t nmi_active;
 | 
				
			||||||
extern unsigned int nmi_watchdog;
 | 
					extern unsigned int nmi_watchdog;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,9 +89,6 @@ extern int nx_enabled;
 | 
				
			||||||
extern unsigned int __VMALLOC_RESERVE;
 | 
					extern unsigned int __VMALLOC_RESERVE;
 | 
				
			||||||
extern int sysctl_legacy_va_layout;
 | 
					extern int sysctl_legacy_va_layout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
 | 
					 | 
				
			||||||
#define MAXMEM			(-__PAGE_OFFSET - __VMALLOC_RESERVE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void find_low_pfn_range(void);
 | 
					extern void find_low_pfn_range(void);
 | 
				
			||||||
extern unsigned long init_memory_mapping(unsigned long start,
 | 
					extern unsigned long init_memory_mapping(unsigned long start,
 | 
				
			||||||
					 unsigned long end);
 | 
										 unsigned long end);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,6 +137,7 @@ struct pv_cpu_ops {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* MSR, PMC and TSR operations.
 | 
						/* MSR, PMC and TSR operations.
 | 
				
			||||||
	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
 | 
						   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
 | 
				
			||||||
 | 
						u64 (*read_msr_amd)(unsigned int msr, int *err);
 | 
				
			||||||
	u64 (*read_msr)(unsigned int msr, int *err);
 | 
						u64 (*read_msr)(unsigned int msr, int *err);
 | 
				
			||||||
	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
 | 
						int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -257,13 +258,13 @@ struct pv_mmu_ops {
 | 
				
			||||||
	 * Hooks for allocating/releasing pagetable pages when they're
 | 
						 * Hooks for allocating/releasing pagetable pages when they're
 | 
				
			||||||
	 * attached to a pagetable
 | 
						 * attached to a pagetable
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	void (*alloc_pte)(struct mm_struct *mm, u32 pfn);
 | 
						void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
 | 
				
			||||||
	void (*alloc_pmd)(struct mm_struct *mm, u32 pfn);
 | 
						void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
 | 
				
			||||||
	void (*alloc_pmd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count);
 | 
						void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
 | 
				
			||||||
	void (*alloc_pud)(struct mm_struct *mm, u32 pfn);
 | 
						void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
 | 
				
			||||||
	void (*release_pte)(u32 pfn);
 | 
						void (*release_pte)(unsigned long pfn);
 | 
				
			||||||
	void (*release_pmd)(u32 pfn);
 | 
						void (*release_pmd)(unsigned long pfn);
 | 
				
			||||||
	void (*release_pud)(u32 pfn);
 | 
						void (*release_pud)(unsigned long pfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Pagetable manipulation functions */
 | 
						/* Pagetable manipulation functions */
 | 
				
			||||||
	void (*set_pte)(pte_t *ptep, pte_t pteval);
 | 
						void (*set_pte)(pte_t *ptep, pte_t pteval);
 | 
				
			||||||
| 
						 | 
					@ -726,6 +727,10 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
 | 
						return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					static inline u64 paravirt_read_msr_amd(unsigned msr, int *err)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 | 
					static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
 | 
						return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
 | 
				
			||||||
| 
						 | 
					@ -771,6 +776,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 | 
				
			||||||
	*p = paravirt_read_msr(msr, &err);
 | 
						*p = paravirt_read_msr(msr, &err);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*p = paravirt_read_msr_amd(msr, &err);
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline u64 paravirt_read_tsc(void)
 | 
					static inline u64 paravirt_read_tsc(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -993,35 +1005,35 @@ static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd)
 | 
				
			||||||
	PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd);
 | 
						PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned pfn)
 | 
					static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn);
 | 
						PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static inline void paravirt_release_pte(unsigned pfn)
 | 
					static inline void paravirt_release_pte(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL1(pv_mmu_ops.release_pte, pfn);
 | 
						PVOP_VCALL1(pv_mmu_ops.release_pte, pfn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned pfn)
 | 
					static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn);
 | 
						PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void paravirt_alloc_pmd_clone(unsigned pfn, unsigned clonepfn,
 | 
					static inline void paravirt_alloc_pmd_clone(unsigned long pfn, unsigned long clonepfn,
 | 
				
			||||||
					    unsigned start, unsigned count)
 | 
										    unsigned long start, unsigned long count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL4(pv_mmu_ops.alloc_pmd_clone, pfn, clonepfn, start, count);
 | 
						PVOP_VCALL4(pv_mmu_ops.alloc_pmd_clone, pfn, clonepfn, start, count);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static inline void paravirt_release_pmd(unsigned pfn)
 | 
					static inline void paravirt_release_pmd(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn);
 | 
						PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned pfn)
 | 
					static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL2(pv_mmu_ops.alloc_pud, mm, pfn);
 | 
						PVOP_VCALL2(pv_mmu_ops.alloc_pud, mm, pfn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static inline void paravirt_release_pud(unsigned pfn)
 | 
					static inline void paravirt_release_pud(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PVOP_VCALL1(pv_mmu_ops.release_pud, pfn);
 | 
						PVOP_VCALL1(pv_mmu_ops.release_pud, pfn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,9 +53,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp)
 | 
				
			||||||
#define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
 | 
					#define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define pte_page(x)		pfn_to_page(pte_pfn(x))
 | 
					 | 
				
			||||||
#define pte_none(x)		(!(x).pte_low)
 | 
					#define pte_none(x)		(!(x).pte_low)
 | 
				
			||||||
#define pte_pfn(x)		(pte_val(x) >> PAGE_SHIFT)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Bits 0, 6 and 7 are taken, split up the 29 bits of offset
 | 
					 * Bits 0, 6 and 7 are taken, split up the 29 bits of offset
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,18 +151,11 @@ static inline int pte_same(pte_t a, pte_t b)
 | 
				
			||||||
	return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
 | 
						return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define pte_page(x)	pfn_to_page(pte_pfn(x))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int pte_none(pte_t pte)
 | 
					static inline int pte_none(pte_t pte)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return !pte.pte_low && !pte.pte_high;
 | 
						return !pte.pte_low && !pte.pte_high;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned long pte_pfn(pte_t pte)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Bits 0, 6 and 7 are taken in the low part of the pte,
 | 
					 * Bits 0, 6 and 7 are taken in the low part of the pte,
 | 
				
			||||||
 * put the 32 bits of offset into the high part.
 | 
					 * put the 32 bits of offset into the high part.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,6 +186,13 @@ static inline int pte_special(pte_t pte)
 | 
				
			||||||
	return pte_val(pte) & _PAGE_SPECIAL;
 | 
						return pte_val(pte) & _PAGE_SPECIAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned long pte_pfn(pte_t pte)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pte_page(pte)	pfn_to_page(pte_pfn(pte))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int pmd_large(pmd_t pte)
 | 
					static inline int pmd_large(pmd_t pte)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
 | 
						return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,8 +57,7 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
 | 
				
			||||||
 * area for the same reason. ;)
 | 
					 * area for the same reason. ;)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define VMALLOC_OFFSET	(8 * 1024 * 1024)
 | 
					#define VMALLOC_OFFSET	(8 * 1024 * 1024)
 | 
				
			||||||
#define VMALLOC_START	(((unsigned long)high_memory + 2 * VMALLOC_OFFSET - 1) \
 | 
					#define VMALLOC_START	((unsigned long)high_memory + VMALLOC_OFFSET)
 | 
				
			||||||
			 & ~(VMALLOC_OFFSET - 1))
 | 
					 | 
				
			||||||
#ifdef CONFIG_X86_PAE
 | 
					#ifdef CONFIG_X86_PAE
 | 
				
			||||||
#define LAST_PKMAP 512
 | 
					#define LAST_PKMAP 512
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -74,6 +73,8 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
 | 
				
			||||||
# define VMALLOC_END	(FIXADDR_START - 2 * PAGE_SIZE)
 | 
					# define VMALLOC_END	(FIXADDR_START - 2 * PAGE_SIZE)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAXMEM	(VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Define this if things work differently on an i386 and an i486:
 | 
					 * Define this if things work differently on an i386 and an i486:
 | 
				
			||||||
 * it will (on an i486) warn about kernel memory accesses that are
 | 
					 * it will (on an i486) warn about kernel memory accesses that are
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,8 +175,6 @@ static inline int pmd_bad(pmd_t pmd)
 | 
				
			||||||
#define pte_present(x)	(pte_val((x)) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 | 
					#define pte_present(x)	(pte_val((x)) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define pages_to_mb(x)	((x) >> (20 - PAGE_SHIFT))   /* FIXME: is this right? */
 | 
					#define pages_to_mb(x)	((x) >> (20 - PAGE_SHIFT))   /* FIXME: is this right? */
 | 
				
			||||||
#define pte_page(x)	pfn_to_page(pte_pfn((x)))
 | 
					 | 
				
			||||||
#define pte_pfn(x)	((pte_val((x)) & __PHYSICAL_MASK) >> PAGE_SHIFT)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Macro to mark a page protection value as "uncacheable".
 | 
					 * Macro to mark a page protection value as "uncacheable".
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@
 | 
				
			||||||
do {								\
 | 
					do {								\
 | 
				
			||||||
	if (pm_trace_enabled) {					\
 | 
						if (pm_trace_enabled) {					\
 | 
				
			||||||
		const void *tracedata;				\
 | 
							const void *tracedata;				\
 | 
				
			||||||
		asm volatile(_ASM_MOV_UL " $1f,%0\n"		\
 | 
							asm volatile(_ASM_MOV " $1f,%0\n"		\
 | 
				
			||||||
			     ".section .tracedata,\"a\"\n"	\
 | 
								     ".section .tracedata,\"a\"\n"	\
 | 
				
			||||||
			     "1:\t.word %c1\n\t"		\
 | 
								     "1:\t.word %c1\n\t"		\
 | 
				
			||||||
			     _ASM_PTR " %c2\n"			\
 | 
								     _ASM_PTR " %c2\n"			\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,7 +97,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
 | 
				
			||||||
		     "jne 1f\n\t"
 | 
							     "jne 1f\n\t"
 | 
				
			||||||
		     "movw %w0,%w1\n\t"
 | 
							     "movw %w0,%w1\n\t"
 | 
				
			||||||
		     "incb %h1\n\t"
 | 
							     "incb %h1\n\t"
 | 
				
			||||||
		     "lock ; cmpxchgw %w1,%2\n\t"
 | 
							     LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
 | 
				
			||||||
		     "1:"
 | 
							     "1:"
 | 
				
			||||||
		     "sete %b1\n\t"
 | 
							     "sete %b1\n\t"
 | 
				
			||||||
		     "movzbl %b1,%0\n\t"
 | 
							     "movzbl %b1,%0\n\t"
 | 
				
			||||||
| 
						 | 
					@ -135,7 +135,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
 | 
				
			||||||
	int inc = 0x00010000;
 | 
						int inc = 0x00010000;
 | 
				
			||||||
	int tmp;
 | 
						int tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asm volatile("lock ; xaddl %0, %1\n"
 | 
						asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
 | 
				
			||||||
		     "movzwl %w0, %2\n\t"
 | 
							     "movzwl %w0, %2\n\t"
 | 
				
			||||||
		     "shrl $16, %0\n\t"
 | 
							     "shrl $16, %0\n\t"
 | 
				
			||||||
		     "1:\t"
 | 
							     "1:\t"
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
 | 
				
			||||||
		     "cmpl %0,%1\n\t"
 | 
							     "cmpl %0,%1\n\t"
 | 
				
			||||||
		     "jne 1f\n\t"
 | 
							     "jne 1f\n\t"
 | 
				
			||||||
		     "addl $0x00010000, %1\n\t"
 | 
							     "addl $0x00010000, %1\n\t"
 | 
				
			||||||
		     "lock ; cmpxchgl %1,%2\n\t"
 | 
							     LOCK_PREFIX "cmpxchgl %1,%2\n\t"
 | 
				
			||||||
		     "1:"
 | 
							     "1:"
 | 
				
			||||||
		     "sete %b1\n\t"
 | 
							     "sete %b1\n\t"
 | 
				
			||||||
		     "movzbl %b1,%0\n\t"
 | 
							     "movzbl %b1,%0\n\t"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue