mirror of https://gitee.com/openkylin/linux.git
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:
|
@ -251,8 +251,6 @@ mono.txt
|
|||
- how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
|
||||
moxa-smartio
|
||||
- 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
|
||||
- info on the generic mutex subsystem.
|
||||
namespaces/
|
||||
|
|
|
@ -463,12 +463,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
Range: 0 - 8192
|
||||
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
|
||||
Format: { enable (default) | disable | force }
|
||||
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]
|
||||
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]
|
||||
See header of drivers/scsi/sim710.c.
|
||||
|
||||
|
|
|
@ -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
|
||||
Type: read
|
||||
Offset/size: 0x20c/4
|
||||
Offset/size: 0x20c/2
|
||||
Protocol: 2.00+
|
||||
|
||||
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
|
||||
MTRRs. These are supported. The AMD Athlon family provide 8 Intel
|
||||
style MTRRs.
|
||||
|
||||
|
||||
The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
|
||||
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
|
||||
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
|
||||
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,
|
||||
Write-combined and Uncached Minus.
|
||||
|
||||
|
||||
PAT APIs
|
||||
--------
|
||||
|
||||
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
|
||||
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 |
|
||||
-----------------------|----------|------------|------------------|
|
||||
| | | |
|
||||
ioremap | -- | UC | UC |
|
||||
ioremap | -- | UC- | UC- |
|
||||
| | | |
|
||||
ioremap_cache | -- | WB | WB |
|
||||
| | | |
|
||||
ioremap_nocache | -- | UC | UC |
|
||||
ioremap_nocache | -- | UC- | UC- |
|
||||
| | | |
|
||||
ioremap_wc | -- | -- | WC |
|
||||
| | | |
|
||||
set_memory_uc | UC | -- | -- |
|
||||
set_memory_uc | UC- | -- | -- |
|
||||
set_memory_wb | | | |
|
||||
| | | |
|
||||
set_memory_wc | WC | -- | -- |
|
||||
set_memory_wb | | | |
|
||||
| | | |
|
||||
pci sysfs resource | -- | -- | UC |
|
||||
pci sysfs resource | -- | -- | UC- |
|
||||
| | | |
|
||||
pci sysfs resource_wc | -- | -- | WC |
|
||||
is IORESOURCE_PREFETCH| | | |
|
||||
| | | |
|
||||
pci proc | -- | -- | UC |
|
||||
pci proc | -- | -- | UC- |
|
||||
!PCIIOC_WRITE_COMBINE | | | |
|
||||
| | | |
|
||||
pci proc | -- | -- | WC |
|
||||
PCIIOC_WRITE_COMBINE | | | |
|
||||
| | | |
|
||||
/dev/mem | -- | UC | UC |
|
||||
/dev/mem | -- | WB/WC/UC- | WB/WC/UC- |
|
||||
read-write | | | |
|
||||
| | | |
|
||||
/dev/mem | -- | UC | UC |
|
||||
/dev/mem | -- | UC- | UC- |
|
||||
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- |
|
||||
and | | ing alias)| ing alias) |
|
||||
any alias to this area| | | |
|
||||
|
@ -68,7 +72,7 @@ pci proc | -- | -- | WC |
|
|||
and | | | |
|
||||
MTRR says WB | | | |
|
||||
| | | |
|
||||
/dev/mem | -- | -- | UC_MINUS |
|
||||
/dev/mem | -- | -- | UC- |
|
||||
mmap !SYNC flag | | | |
|
||||
no alias to this area | | | |
|
||||
and | | | |
|
||||
|
@ -98,3 +102,35 @@ types.
|
|||
|
||||
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
|
||||
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
|
||||
|
||||
syntax: earlyprintk=vga
|
||||
|
|
|
@ -1021,7 +1021,7 @@ config HAVE_ARCH_ALLOC_REMAP
|
|||
|
||||
config ARCH_FLATMEM_ENABLE
|
||||
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
|
||||
def_bool y
|
||||
|
@ -1037,7 +1037,7 @@ config ARCH_SPARSEMEM_DEFAULT
|
|||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
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_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
|
||||
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
|
||||
bool
|
||||
def_bool y
|
||||
prompt "MTRR cleanup support"
|
||||
depends on MTRR
|
||||
help
|
||||
|
@ -1132,7 +1132,7 @@ config MTRR_SANITIZER
|
|||
The largest mtrr entry size for a continous block can be set with
|
||||
mtrr_chunk_size.
|
||||
|
||||
If unsure, say N.
|
||||
If unsure, say Y.
|
||||
|
||||
config MTRR_SANITIZER_ENABLE_DEFAULT
|
||||
int "MTRR cleanup enable value (0-1)"
|
||||
|
@ -1192,7 +1192,6 @@ config IRQBALANCE
|
|||
config SECCOMP
|
||||
def_bool y
|
||||
prompt "Enable seccomp to safely compute untrusted bytecode"
|
||||
depends on PROC_FS
|
||||
help
|
||||
This kernel feature is useful for number crunching applications
|
||||
that may need to compute untrusted bytecode during their
|
||||
|
@ -1200,7 +1199,7 @@ config SECCOMP
|
|||
the process as file descriptors supporting the read/write
|
||||
syscalls, it's possible to isolate those applications in
|
||||
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
|
||||
defined by each seccomp mode.
|
||||
|
||||
|
@ -1357,14 +1356,14 @@ config PHYSICAL_ALIGN
|
|||
Don't change this unless you know what you are doing.
|
||||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
|
||||
depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SMP && HOTPLUG && !X86_VOYAGER
|
||||
---help---
|
||||
Say Y here to experiment with turning CPUs off and on, and to
|
||||
enable suspend on SMP systems. CPUs can be controlled through
|
||||
/sys/devices/system/cpu.
|
||||
Say N if you want to disable CPU hotplug and don't need to
|
||||
suspend.
|
||||
Say Y here to allow turning CPUs off and on. CPUs can be
|
||||
controlled through /sys/devices/system/cpu.
|
||||
( Note: power management support will enable this option
|
||||
automatically on SMP systems. )
|
||||
Say N if you want to disable CPU hotplug.
|
||||
|
||||
config COMPAT_VDSO
|
||||
def_bool y
|
||||
|
@ -1379,6 +1378,51 @@ config COMPAT_VDSO
|
|||
|
||||
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
|
||||
|
||||
config ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
|
@ -1774,7 +1818,7 @@ config COMPAT_FOR_U64_ALIGNMENT
|
|||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on X86_64 && COMPAT && SYSVIPC
|
||||
depends on COMPAT && SYSVIPC
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -137,14 +137,15 @@ relocated:
|
|||
*/
|
||||
movl output_len(%ebx), %eax
|
||||
pushl %eax
|
||||
# push arguments for decompress_kernel:
|
||||
pushl %ebp # output address
|
||||
movl input_len(%ebx), %eax
|
||||
pushl %eax # input_len
|
||||
leal input_data(%ebx), %eax
|
||||
pushl %eax # input_data
|
||||
leal boot_heap(%ebx), %eax
|
||||
pushl %eax # heap area as third argument
|
||||
pushl %esi # real mode pointer as second arg
|
||||
pushl %eax # heap area
|
||||
pushl %esi # real mode pointer
|
||||
call decompress_kernel
|
||||
addl $20, %esp
|
||||
popl %ecx
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/elf.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/boot.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
@ -251,7 +251,7 @@ static void __putstr(int error, const char *s)
|
|||
y--;
|
||||
}
|
||||
} else {
|
||||
vidmem [(x + cols * y) * 2] = c;
|
||||
vidmem[(x + cols * y) * 2] = c;
|
||||
if (++x >= cols) {
|
||||
x = 0;
|
||||
if (++y >= lines) {
|
||||
|
@ -277,7 +277,8 @@ static void *memset(void *s, int c, unsigned n)
|
|||
int i;
|
||||
char *ss = s;
|
||||
|
||||
for (i = 0; i < n; i++) ss[i] = c;
|
||||
for (i = 0; i < n; i++)
|
||||
ss[i] = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -287,7 +288,8 @@ static void *memcpy(void *dest, const void *src, unsigned n)
|
|||
const char *s = src;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
|
|||
SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
|
||||
/* to be loaded */
|
||||
ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
|
||||
SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
|
||||
|
||||
#ifndef SVGA_MODE
|
||||
#define SVGA_MODE ASK_VGA
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.27-rc4
|
||||
# Mon Aug 25 15:04:00 2008
|
||||
# Linux kernel version: 2.6.27-rc5
|
||||
# Wed Sep 3 17:23:09 2008
|
||||
#
|
||||
# CONFIG_64BIT is not set
|
||||
CONFIG_X86_32=y
|
||||
|
@ -202,7 +202,7 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
|
|||
# CONFIG_M586 is not set
|
||||
# CONFIG_M586TSC is not set
|
||||
# CONFIG_M586MMX is not set
|
||||
# CONFIG_M686 is not set
|
||||
CONFIG_M686=y
|
||||
# CONFIG_MPENTIUMII is not set
|
||||
# CONFIG_MPENTIUMIII 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_MVIAC7 is not set
|
||||
# CONFIG_MPSC is not set
|
||||
CONFIG_MCORE2=y
|
||||
# CONFIG_MCORE2 is not set
|
||||
# CONFIG_GENERIC_CPU is not set
|
||||
CONFIG_X86_GENERIC=y
|
||||
CONFIG_X86_CPU=y
|
||||
CONFIG_X86_CMPXCHG=y
|
||||
CONFIG_X86_L1_CACHE_SHIFT=7
|
||||
CONFIG_X86_XADD=y
|
||||
# CONFIG_X86_PPRO_FENCE is not set
|
||||
CONFIG_X86_WP_WORKS_OK=y
|
||||
CONFIG_X86_INVLPG=y
|
||||
CONFIG_X86_BSWAP=y
|
||||
|
@ -235,14 +236,15 @@ CONFIG_X86_POPAD_OK=y
|
|||
CONFIG_X86_INTEL_USERCOPY=y
|
||||
CONFIG_X86_USE_PPRO_CHECKSUM=y
|
||||
CONFIG_X86_TSC=y
|
||||
CONFIG_X86_CMOV=y
|
||||
CONFIG_X86_MINIMUM_CPU_FAMILY=4
|
||||
CONFIG_X86_DEBUGCTLMSR=y
|
||||
CONFIG_HPET_TIMER=y
|
||||
CONFIG_HPET_EMULATE_RTC=y
|
||||
CONFIG_DMI=y
|
||||
# CONFIG_IOMMU_HELPER is not set
|
||||
CONFIG_NR_CPUS=4
|
||||
# CONFIG_SCHED_SMT is not set
|
||||
CONFIG_NR_CPUS=64
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_SCHED_MC=y
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
|
@ -254,7 +256,8 @@ CONFIG_VM86=y
|
|||
# CONFIG_TOSHIBA is not set
|
||||
# CONFIG_I8K is not set
|
||||
CONFIG_X86_REBOOTFIXUPS=y
|
||||
# CONFIG_MICROCODE is not set
|
||||
CONFIG_MICROCODE=y
|
||||
CONFIG_MICROCODE_OLD_INTERFACE=y
|
||||
CONFIG_X86_MSR=y
|
||||
CONFIG_X86_CPUID=y
|
||||
# CONFIG_NOHIGHMEM is not set
|
||||
|
@ -2115,7 +2118,7 @@ CONFIG_IO_DELAY_0X80=y
|
|||
CONFIG_DEFAULT_IO_DELAY_TYPE=0
|
||||
CONFIG_DEBUG_BOOT_PARAMS=y
|
||||
# CONFIG_CPA_DEBUG is not set
|
||||
# CONFIG_OPTIMIZE_INLINING is not set
|
||||
CONFIG_OPTIMIZE_INLINING=y
|
||||
|
||||
#
|
||||
# Security options
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.27-rc4
|
||||
# Mon Aug 25 14:40:46 2008
|
||||
# Linux kernel version: 2.6.27-rc5
|
||||
# Wed Sep 3 17:13:39 2008
|
||||
#
|
||||
CONFIG_64BIT=y
|
||||
# CONFIG_X86_32 is not set
|
||||
|
@ -218,17 +218,14 @@ CONFIG_X86_PC=y
|
|||
# CONFIG_MVIAC3_2 is not set
|
||||
# CONFIG_MVIAC7 is not set
|
||||
# CONFIG_MPSC is not set
|
||||
CONFIG_MCORE2=y
|
||||
# CONFIG_GENERIC_CPU is not set
|
||||
# CONFIG_MCORE2 is not set
|
||||
CONFIG_GENERIC_CPU=y
|
||||
CONFIG_X86_CPU=y
|
||||
CONFIG_X86_L1_CACHE_BYTES=64
|
||||
CONFIG_X86_INTERNODE_CACHE_BYTES=64
|
||||
CONFIG_X86_L1_CACHE_BYTES=128
|
||||
CONFIG_X86_INTERNODE_CACHE_BYTES=128
|
||||
CONFIG_X86_CMPXCHG=y
|
||||
CONFIG_X86_L1_CACHE_SHIFT=6
|
||||
CONFIG_X86_L1_CACHE_SHIFT=7
|
||||
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_CMPXCHG64=y
|
||||
CONFIG_X86_CMOV=y
|
||||
|
@ -243,9 +240,8 @@ CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
|
|||
CONFIG_AMD_IOMMU=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_IOMMU_HELPER=y
|
||||
# CONFIG_MAXSMP is not set
|
||||
CONFIG_NR_CPUS=4
|
||||
# CONFIG_SCHED_SMT is not set
|
||||
CONFIG_NR_CPUS=64
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_SCHED_MC=y
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
|
@ -254,7 +250,8 @@ CONFIG_X86_LOCAL_APIC=y
|
|||
CONFIG_X86_IO_APIC=y
|
||||
# CONFIG_X86_MCE 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_CPUID=y
|
||||
CONFIG_NUMA=y
|
||||
|
@ -290,7 +287,7 @@ CONFIG_BOUNCE=y
|
|||
CONFIG_VIRT_TO_BUS=y
|
||||
CONFIG_MTRR=y
|
||||
# CONFIG_MTRR_SANITIZER is not set
|
||||
# CONFIG_X86_PAT is not set
|
||||
CONFIG_X86_PAT=y
|
||||
CONFIG_EFI=y
|
||||
CONFIG_SECCOMP=y
|
||||
# CONFIG_HZ_100 is not set
|
||||
|
@ -2089,7 +2086,7 @@ CONFIG_IO_DELAY_0X80=y
|
|||
CONFIG_DEFAULT_IO_DELAY_TYPE=0
|
||||
CONFIG_DEBUG_BOOT_PARAMS=y
|
||||
# CONFIG_CPA_DEBUG is not set
|
||||
# CONFIG_OPTIMIZE_INLINING is not set
|
||||
CONFIG_OPTIMIZE_INLINING=y
|
||||
|
||||
#
|
||||
# Security options
|
||||
|
|
|
@ -85,8 +85,10 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump)
|
|||
dump->regs.ax = regs->ax;
|
||||
dump->regs.ds = current->thread.ds;
|
||||
dump->regs.es = current->thread.es;
|
||||
asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs;
|
||||
asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs;
|
||||
savesegment(fs, fs);
|
||||
dump->regs.fs = fs;
|
||||
savesegment(gs, gs);
|
||||
dump->regs.gs = gs;
|
||||
dump->regs.orig_ax = regs->orig_ax;
|
||||
dump->regs.ip = regs->ip;
|
||||
dump->regs.cs = regs->cs;
|
||||
|
@ -430,8 +432,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
|||
current->mm->start_stack =
|
||||
(unsigned long)create_aout_tables((char __user *)bprm->p, bprm);
|
||||
/* start thread */
|
||||
asm volatile("movl %0,%%fs" :: "r" (0)); \
|
||||
asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS));
|
||||
loadsegment(fs, 0);
|
||||
loadsegment(ds, __USER32_DS);
|
||||
loadsegment(es, __USER32_DS);
|
||||
load_gs_index(0);
|
||||
(regs)->ip = ex.a_entry;
|
||||
(regs)->sp = current->mm->start_stack;
|
||||
|
|
|
@ -206,7 +206,7 @@ struct rt_sigframe
|
|||
{ unsigned int cur; \
|
||||
unsigned short pre; \
|
||||
err |= __get_user(pre, &sc->seg); \
|
||||
asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
|
||||
savesegment(seg, cur); \
|
||||
pre |= mask; \
|
||||
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);
|
||||
gs |= 3;
|
||||
asm("movl %%gs,%0" : "=r" (oldgs));
|
||||
savesegment(gs, oldgs);
|
||||
if (gs != oldgs)
|
||||
load_gs_index(gs);
|
||||
|
||||
|
@ -355,14 +355,13 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
|
|||
{
|
||||
int tmp, err = 0;
|
||||
|
||||
tmp = 0;
|
||||
__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
|
||||
savesegment(gs, tmp);
|
||||
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);
|
||||
__asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
|
||||
savesegment(ds, tmp);
|
||||
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((u32)regs->di, &sc->di);
|
||||
|
@ -498,8 +497,8 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
|
|||
regs->dx = 0;
|
||||
regs->cx = 0;
|
||||
|
||||
asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
|
||||
asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
|
||||
loadsegment(ds, __USER32_DS);
|
||||
loadsegment(es, __USER32_DS);
|
||||
|
||||
regs->cs = __USER32_CS;
|
||||
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->cx = (unsigned long) &frame->uc;
|
||||
|
||||
asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
|
||||
asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
|
||||
loadsegment(ds, __USER32_DS);
|
||||
loadsegment(es, __USER32_DS);
|
||||
|
||||
regs->cs = __USER32_CS;
|
||||
regs->ss = __USER32_DS;
|
||||
|
|
|
@ -556,15 +556,6 @@ asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig,
|
|||
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
|
||||
struct sysctl_ia32 {
|
||||
unsigned int name;
|
||||
|
|
|
@ -58,7 +58,6 @@ EXPORT_SYMBOL(acpi_disabled);
|
|||
#ifdef CONFIG_X86_64
|
||||
|
||||
#include <asm/proto.h>
|
||||
#include <asm/genapic.h>
|
||||
|
||||
#else /* X86 */
|
||||
|
||||
|
@ -97,8 +96,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
|
|||
#warning ACPI uses CMPXCHG, i486 and later hardware
|
||||
#endif
|
||||
|
||||
static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (*ptr > text_end)
|
||||
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)
|
||||
{
|
||||
u8 **ptr;
|
||||
char insn[1];
|
||||
|
||||
if (noreplace_smp)
|
||||
return;
|
||||
|
||||
add_nops(insn, 1);
|
||||
for (ptr = start; ptr < end; ptr++) {
|
||||
if (*ptr < text)
|
||||
continue;
|
||||
if (*ptr > text_end)
|
||||
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 @@ void __init gart_iommu_hole_init(void)
|
|||
force_iommu ||
|
||||
valid_agp ||
|
||||
fallback_aper_force) {
|
||||
printk(KERN_ERR
|
||||
printk(KERN_INFO
|
||||
"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");
|
||||
printk(KERN_ERR
|
||||
printk(KERN_INFO
|
||||
"This costs you %d MB of RAM\n",
|
||||
32 << fallback_aper_order);
|
||||
|
||||
|
|
|
@ -228,7 +228,6 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/smp_lock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
|
|
@ -25,11 +25,11 @@ x86_bios_strerror(long status)
|
|||
{
|
||||
const char *str;
|
||||
switch (status) {
|
||||
case 0: str = "Call completed without error"; break;
|
||||
case -1: str = "Not implemented"; break;
|
||||
case -2: str = "Invalid argument"; break;
|
||||
case -3: str = "Call completed with error"; break;
|
||||
default: str = "Unknown BIOS status code"; break;
|
||||
case 0: str = "Call completed without error"; break;
|
||||
case -1: str = "Not implemented"; break;
|
||||
case -2: str = "Invalid argument"; break;
|
||||
case -3: str = "Call completed with error"; break;
|
||||
default: str = "Unknown BIOS status code"; break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -430,6 +430,49 @@ static __init int setup_noclflush(char *arg)
|
|||
}
|
||||
__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)
|
||||
{
|
||||
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);
|
||||
else
|
||||
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)
|
||||
|
|
|
@ -401,12 +401,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
|
|||
tmp |= ~((1<<(hi - 1)) - 1);
|
||||
|
||||
if (tmp != mask_lo) {
|
||||
static int once = 1;
|
||||
|
||||
if (once) {
|
||||
printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
|
||||
once = 0;
|
||||
}
|
||||
WARN_ONCE(1, KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
|
||||
mask_lo = tmp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,9 +405,9 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
|
|||
}
|
||||
/* RED-PEN: base can be > 32bit */
|
||||
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,
|
||||
mtrr_attrib_to_str(type), mtrr_usage_table[i]);
|
||||
mtrr_usage_table[i], mtrr_attrib_to_str(type));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -759,7 +759,8 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
|
|||
/* take out UC ranges */
|
||||
for (i = 0; i < num_var_ranges; i++) {
|
||||
type = range_state[i].type;
|
||||
if (type != MTRR_TYPE_UNCACHABLE)
|
||||
if (type != MTRR_TYPE_UNCACHABLE &&
|
||||
type != MTRR_TYPE_WRPROT)
|
||||
continue;
|
||||
size = range_state[i].size_pfn;
|
||||
if (!size)
|
||||
|
@ -836,6 +837,13 @@ static int __init enable_mtrr_cleanup_setup(char *str)
|
|||
}
|
||||
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 {
|
||||
unsigned long range_startk;
|
||||
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
|
||||
range_to_mtrr(unsigned int reg, unsigned long range_startk,
|
||||
unsigned long range_sizek, unsigned char type)
|
||||
|
@ -919,13 +948,21 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
|
|||
align = max_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, "
|
||||
"base: %ldMB, range: %ldMB, type %s\n",
|
||||
reg, range_startk >> 10, sizek >> 10,
|
||||
"base: %ld%cB, range: %ld%cB, type %s\n",
|
||||
reg, start_base, start_factor,
|
||||
size_base, size_factor,
|
||||
(type == MTRR_TYPE_UNCACHABLE)?"UC":
|
||||
((type == MTRR_TYPE_WRBACK)?"WB":"Other")
|
||||
);
|
||||
}
|
||||
save_var_mtrr(reg++, range_startk, sizek, type);
|
||||
range_startk += 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 */
|
||||
range0_basek = state->range_startk;
|
||||
range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
|
||||
|
||||
/* no increase */
|
||||
if (range0_sizek == state->range_sizek) {
|
||||
if (debug_print)
|
||||
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;
|
||||
}
|
||||
|
||||
range0_sizek -= chunk_sizek;
|
||||
if (range0_sizek && sizek) {
|
||||
while (range0_basek + range0_sizek > (basek + sizek)) {
|
||||
range0_sizek -= chunk_sizek;
|
||||
if (!range0_sizek)
|
||||
break;
|
||||
}
|
||||
/* only cut back, when it is not the last */
|
||||
if (sizek) {
|
||||
while (range0_basek + range0_sizek > (basek + sizek)) {
|
||||
if (range0_sizek >= chunk_sizek)
|
||||
range0_sizek -= chunk_sizek;
|
||||
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) {
|
||||
|
@ -996,50 +1062,28 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
|
|||
(range0_basek + range0_sizek)<<10);
|
||||
state->reg = range_to_mtrr(state->reg, range0_basek,
|
||||
range0_sizek, MTRR_TYPE_WRBACK);
|
||||
|
||||
}
|
||||
|
||||
range_basek = range0_basek + range0_sizek;
|
||||
range_sizek = chunk_sizek;
|
||||
|
||||
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 */
|
||||
if (range0_sizek < state->range_sizek) {
|
||||
/* need to handle left over */
|
||||
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) {
|
||||
hole_basek = range_basek - hole_sizek - second_sizek;
|
||||
if (debug_print)
|
||||
printk(KERN_DEBUG "hole: %016lx - %016lx\n",
|
||||
hole_basek<<10, (hole_basek + hole_sizek)<<10);
|
||||
state->reg = range_to_mtrr(state->reg, hole_basek, hole_sizek,
|
||||
MTRR_TYPE_UNCACHABLE);
|
||||
|
||||
hole_basek<<10,
|
||||
(hole_basek + hole_sizek)<<10);
|
||||
state->reg = range_to_mtrr(state->reg, hole_basek,
|
||||
hole_sizek, MTRR_TYPE_UNCACHABLE);
|
||||
}
|
||||
|
||||
return second_sizek;
|
||||
|
@ -1154,11 +1198,11 @@ struct mtrr_cleanup_result {
|
|||
};
|
||||
|
||||
/*
|
||||
* gran_size: 1M, 2M, ..., 2G
|
||||
* chunk size: gran_size, ..., 4G
|
||||
* so we need (2+13)*6
|
||||
* gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
|
||||
* chunk size: gran_size, ..., 2G
|
||||
* so we need (1+16)*8
|
||||
*/
|
||||
#define NUM_RESULT 90
|
||||
#define NUM_RESULT 136
|
||||
#define PSHIFT (PAGE_SHIFT - 10)
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned long extra_remove_base, extra_remove_size;
|
||||
unsigned long i, base, size, def, dummy;
|
||||
unsigned long base, size, def, dummy;
|
||||
mtrr_type type;
|
||||
int nr_range, nr_range_new;
|
||||
u64 chunk_size, gran_size;
|
||||
unsigned long range_sums, range_sums_new;
|
||||
int index_good;
|
||||
int num_reg_good;
|
||||
int i;
|
||||
|
||||
/* extra one for all 0 */
|
||||
int num[MTRR_NUM_TYPES + 1];
|
||||
|
@ -1204,6 +1249,8 @@ static int __init mtrr_cleanup(unsigned address_bits)
|
|||
continue;
|
||||
if (!size)
|
||||
type = MTRR_NUM_TYPES;
|
||||
if (type == MTRR_TYPE_WRPROT)
|
||||
type = MTRR_TYPE_UNCACHABLE;
|
||||
num[type]++;
|
||||
}
|
||||
|
||||
|
@ -1216,23 +1263,57 @@ static int __init mtrr_cleanup(unsigned address_bits)
|
|||
num_var_ranges - num[MTRR_NUM_TYPES])
|
||||
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));
|
||||
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 =
|
||||
(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
|
||||
}
|
||||
nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
|
||||
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);
|
||||
printk(KERN_INFO "total RAM coverred: %ldM\n",
|
||||
range_sums >> (20 - PAGE_SHIFT));
|
||||
|
||||
if (mtrr_chunk_size && mtrr_gran_size) {
|
||||
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 */
|
||||
num_reg = x86_setup_var_mtrrs(range, nr_range, mtrr_chunk_size,
|
||||
mtrr_gran_size);
|
||||
|
@ -1256,34 +1337,48 @@ static int __init mtrr_cleanup(unsigned address_bits)
|
|||
result[i].lose_cover_sizek =
|
||||
(range_sums - range_sums_new) << PSHIFT;
|
||||
|
||||
printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t",
|
||||
result[i].bad?"*BAD*":" ", result[i].gran_sizek >> 10,
|
||||
result[i].chunk_sizek >> 10);
|
||||
printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ldM \n",
|
||||
gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
|
||||
chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
|
||||
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?"-":"",
|
||||
result[i].lose_cover_sizek >> 10);
|
||||
lose_base, lose_factor);
|
||||
if (!result[i].bad) {
|
||||
set_var_mtrr_all(address_bits);
|
||||
return 1;
|
||||
}
|
||||
printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
|
||||
"will find optimal one\n");
|
||||
debug_print = 0;
|
||||
debug_print--;
|
||||
memset(result, 0, sizeof(result[0]));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
|
||||
memset(result, 0, sizeof(result));
|
||||
for (gran_size = (1ULL<<20); gran_size < (1ULL<<32); gran_size <<= 1) {
|
||||
for (chunk_size = gran_size; chunk_size < (1ULL<<33);
|
||||
for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
|
||||
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) {
|
||||
int num_reg;
|
||||
|
||||
if (debug_print)
|
||||
printk(KERN_INFO
|
||||
"\ngran_size: %lldM chunk_size_size: %lldM\n",
|
||||
gran_size >> 20, chunk_size >> 20);
|
||||
if (debug_print) {
|
||||
char chunk_factor;
|
||||
unsigned long chunk_base;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
@ -1326,12 +1421,18 @@ static int __init mtrr_cleanup(unsigned address_bits)
|
|||
|
||||
/* print out all */
|
||||
for (i = 0; i < NUM_RESULT; i++) {
|
||||
printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t",
|
||||
result[i].bad?"*BAD* ":" ", result[i].gran_sizek >> 10,
|
||||
result[i].chunk_sizek >> 10);
|
||||
printk(KERN_CONT "num_reg: %d \tlose RAM: %s%ldM\n",
|
||||
result[i].num_reg, result[i].bad?"-":"",
|
||||
result[i].lose_cover_sizek >> 10);
|
||||
char gran_factor, chunk_factor, lose_factor;
|
||||
unsigned long gran_base, chunk_base, lose_base;
|
||||
|
||||
gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
|
||||
chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
|
||||
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 */
|
||||
|
@ -1339,10 +1440,8 @@ static int __init mtrr_cleanup(unsigned address_bits)
|
|||
nr_mtrr_spare_reg = num_var_ranges - 1;
|
||||
num_reg_good = -1;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index_good = -1;
|
||||
|
@ -1358,21 +1457,26 @@ static int __init mtrr_cleanup(unsigned address_bits)
|
|||
}
|
||||
|
||||
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");
|
||||
i = index_good;
|
||||
printk(KERN_INFO "gran_size: %ldM \tchunk_size: %ldM \t",
|
||||
result[i].gran_sizek >> 10,
|
||||
result[i].chunk_sizek >> 10);
|
||||
printk(KERN_CONT "num_reg: %d \tlose RAM: %ldM\n",
|
||||
result[i].num_reg,
|
||||
result[i].lose_cover_sizek >> 10);
|
||||
gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
|
||||
chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
|
||||
lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
|
||||
printk(KERN_INFO "gran_size: %ld%c \tchunk_size: %ld%c \t",
|
||||
gran_base, gran_factor, chunk_base, chunk_factor);
|
||||
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 */
|
||||
chunk_size = result[i].chunk_sizek;
|
||||
chunk_size <<= 10;
|
||||
gran_size = result[i].gran_sizek;
|
||||
gran_size <<= 10;
|
||||
debug_print = 1;
|
||||
debug_print++;
|
||||
x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
|
||||
debug_print--;
|
||||
set_var_mtrr_all(address_bits);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -295,13 +295,19 @@ static int setup_k7_watchdog(unsigned nmi_hz)
|
|||
/* setup the timer */
|
||||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
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);
|
||||
evntsel |= K7_EVNTSEL_ENABLE;
|
||||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
|
||||
wd->perfctr_msr = perfctr_msr;
|
||||
wd->evntsel_msr = evntsel_msr;
|
||||
wd->cccr_msr = 0; /* unused */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -379,13 +385,19 @@ static int setup_p6_watchdog(unsigned nmi_hz)
|
|||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
nmi_hz = adjust_for_32bit_ctr(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);
|
||||
evntsel |= P6_EVNTSEL0_ENABLE;
|
||||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
|
||||
wd->perfctr_msr = perfctr_msr;
|
||||
wd->evntsel_msr = evntsel_msr;
|
||||
wd->cccr_msr = 0; /* unused */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -432,6 +444,27 @@ static const struct wd_ops p6_wd_ops = {
|
|||
#define P4_CCCR_ENABLE (1 << 12)
|
||||
#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
|
||||
* 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;
|
||||
cccr_msr = MSR_P4_IQ_CCCR0;
|
||||
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 {
|
||||
/* logical cpu 1 */
|
||||
perfctr_msr = MSR_P4_IQ_PERFCTR1;
|
||||
|
@ -499,12 +552,17 @@ static int setup_p4_watchdog(unsigned nmi_hz)
|
|||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
wrmsr(cccr_msr, cccr_val, 0);
|
||||
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->evntsel_msr = evntsel_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;
|
||||
}
|
||||
|
||||
|
@ -620,13 +678,17 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
|
|||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
nmi_hz = adjust_for_32bit_ctr(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->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);
|
||||
evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
|
||||
wrmsr(evntsel_msr, evntsel, 0);
|
||||
intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <linux/smp_lock.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/notifier.h>
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/crash_dump.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -33,14 +32,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
|
|||
return 0;
|
||||
|
||||
vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
|
||||
if (!vaddr)
|
||||
return -ENOMEM;
|
||||
|
||||
if (userbuf) {
|
||||
if (copy_to_user(buf, (vaddr + offset), csize)) {
|
||||
if (copy_to_user(buf, vaddr + offset, csize)) {
|
||||
iounmap(vaddr);
|
||||
return -EFAULT;
|
||||
}
|
||||
} else
|
||||
memcpy(buf, (vaddr + offset), csize);
|
||||
memcpy(buf, vaddr + offset, csize);
|
||||
|
||||
iounmap(vaddr);
|
||||
return csize;
|
||||
|
|
|
@ -414,9 +414,11 @@ void __init efi_init(void)
|
|||
if (memmap.map == NULL)
|
||||
printk(KERN_ERR "Could not map the EFI memory map!\n");
|
||||
memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
|
||||
|
||||
if (memmap.desc_size != sizeof(efi_memory_desc_t))
|
||||
printk(KERN_WARNING "Kernel-defined memdesc"
|
||||
"doesn't match the one from EFI!\n");
|
||||
printk(KERN_WARNING
|
||||
"Kernel-defined memdesc doesn't match the one from EFI!\n");
|
||||
|
||||
if (add_efi_memmap)
|
||||
do_add_efi_memmap();
|
||||
|
||||
|
|
|
@ -275,9 +275,9 @@ ENTRY(native_usergs_sysret64)
|
|||
ENTRY(ret_from_fork)
|
||||
CFI_DEFAULT_STACK
|
||||
push kernel_eflags(%rip)
|
||||
CFI_ADJUST_CFA_OFFSET 4
|
||||
CFI_ADJUST_CFA_OFFSET 8
|
||||
popf # reset kernel eflags
|
||||
CFI_ADJUST_CFA_OFFSET -4
|
||||
CFI_ADJUST_CFA_OFFSET -8
|
||||
call schedule_tail
|
||||
GET_THREAD_INFO(%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);
|
||||
|
||||
early_printk("Kernel alive\n");
|
||||
if (console_loglevel == 10)
|
||||
early_printk("Kernel alive\n");
|
||||
|
||||
x86_64_init_pda();
|
||||
|
||||
early_printk("Kernel really alive\n");
|
||||
|
||||
x86_64_start_reservations(real_mode_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@ int show_interrupts(struct seq_file *p, void *v)
|
|||
for_each_online_cpu(j)
|
||||
seq_printf(p, "%10u ",
|
||||
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: ");
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "%10u ",
|
||||
|
|
|
@ -129,7 +129,7 @@ int show_interrupts(struct seq_file *p, void *v)
|
|||
seq_printf(p, "CAL: ");
|
||||
for_each_online_cpu(j)
|
||||
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: ");
|
||||
for_each_online_cpu(j)
|
||||
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);
|
||||
}
|
||||
|
||||
static void kvm_release_pt(u32 pfn)
|
||||
static void kvm_release_pt(unsigned long pfn)
|
||||
{
|
||||
struct kvm_mmu_op_release_pt rpt = {
|
||||
.header.op = KVM_MMU_OP_RELEASE_PT,
|
||||
|
|
|
@ -299,6 +299,15 @@ void acpi_nmi_disable(void)
|
|||
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)
|
||||
{
|
||||
if (__get_cpu_var(wd_enabled))
|
||||
|
@ -311,8 +320,6 @@ void setup_apic_nmi_watchdog(void *unused)
|
|||
|
||||
switch (nmi_watchdog) {
|
||||
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) {
|
||||
__get_cpu_var(wd_enabled) = 0;
|
||||
return;
|
||||
|
|
|
@ -190,12 +190,12 @@ EXPORT_SYMBOL_GPL(olpc_ec_cmd);
|
|||
static void __init platform_detect(void)
|
||||
{
|
||||
size_t propsize;
|
||||
u32 rev;
|
||||
__be32 rev;
|
||||
|
||||
if (ofw("getprop", 4, 1, NULL, "board-revision-int", &rev, 4,
|
||||
&propsize) || propsize != 4) {
|
||||
printk(KERN_ERR "ofw: getprop call failed!\n");
|
||||
rev = 0;
|
||||
rev = cpu_to_be32(0);
|
||||
}
|
||||
olpc_platform_info.boardrev = be32_to_cpu(rev);
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ static void __init platform_detect(void)
|
|||
static void __init platform_detect(void)
|
||||
{
|
||||
/* stopgap until OFW support is added to the kernel */
|
||||
olpc_platform_info.boardrev = be32_to_cpu(0xc2);
|
||||
olpc_platform_info.boardrev = 0xc2;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -330,6 +330,7 @@ struct pv_cpu_ops pv_cpu_ops = {
|
|||
#endif
|
||||
.wbinvd = native_wbinvd,
|
||||
.read_msr = native_read_msr_safe,
|
||||
.read_msr_amd = native_read_msr_amd_safe,
|
||||
.write_msr = native_write_msr_safe,
|
||||
.read_tsc = native_read_tsc,
|
||||
.read_pmc = native_read_pmc,
|
||||
|
|
|
@ -23,7 +23,7 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
|
|||
start = start_##ops##_##x; \
|
||||
end = end_##ops##_##x; \
|
||||
goto patch_site
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
PATCH_SITE(pv_irq_ops, irq_disable);
|
||||
PATCH_SITE(pv_irq_ops, irq_enable);
|
||||
PATCH_SITE(pv_irq_ops, restore_fl);
|
||||
|
|
|
@ -82,7 +82,7 @@ void __init dma32_reserve_bootmem(void)
|
|||
* using 512M as goal
|
||||
*/
|
||||
align = 64ULL<<20;
|
||||
size = round_up(dma32_bootmem_size, align);
|
||||
size = roundup(dma32_bootmem_size, align);
|
||||
dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
|
||||
512ULL<<20);
|
||||
if (dma32_bootmem_ptr)
|
||||
|
|
|
@ -82,7 +82,8 @@ AGPEXTERN __u32 *agp_gatt_table;
|
|||
static unsigned long next_bit; /* protected by iommu_bitmap_lock */
|
||||
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 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),
|
||||
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;
|
||||
|
||||
spin_lock_irqsave(&iommu_bitmap_lock, flags);
|
||||
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) {
|
||||
need_flush = 1;
|
||||
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) {
|
||||
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.
|
||||
*/
|
||||
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 iommu_page = alloc_iommu(dev, npages);
|
||||
unsigned long iommu_page = alloc_iommu(dev, npages, align_mask);
|
||||
int i;
|
||||
|
||||
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
|
||||
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();
|
||||
|
||||
|
@ -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))
|
||||
return paddr;
|
||||
|
||||
bus = gart_map_simple(dev, paddr, size, dir);
|
||||
bus = dma_map_area(dev, paddr, size, dir, 0);
|
||||
flush_gart();
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
@ -340,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
|
|||
unsigned long addr = sg_phys(s);
|
||||
|
||||
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 (i > 0)
|
||||
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,
|
||||
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;
|
||||
struct scatterlist *s;
|
||||
int i;
|
||||
|
@ -626,7 +633,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
|
|||
struct pci_dev *dev;
|
||||
void *gatt;
|
||||
int i, error;
|
||||
unsigned long start_pfn, end_pfn;
|
||||
|
||||
printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
|
||||
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",
|
||||
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;
|
||||
|
||||
nommu:
|
||||
|
@ -727,7 +727,8 @@ void __init gart_iommu_init(void)
|
|||
{
|
||||
struct agp_kern_info info;
|
||||
unsigned long iommu_start;
|
||||
unsigned long aper_size;
|
||||
unsigned long aper_base, aper_size;
|
||||
unsigned long start_pfn, end_pfn;
|
||||
unsigned long scratch;
|
||||
long i;
|
||||
|
||||
|
@ -765,8 +766,16 @@ void __init gart_iommu_init(void)
|
|||
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");
|
||||
aper_size = info.aper_size * 1024 * 1024;
|
||||
iommu_size = check_iommu_size(info.aper_base, aper_size);
|
||||
iommu_pages = iommu_size >> PAGE_SHIFT;
|
||||
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
static __init int add_pcspkr(void)
|
||||
{
|
||||
struct platform_device *pd;
|
||||
int ret;
|
||||
|
||||
pd = platform_device_alloc("pcspkr", -1);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
pd = platform_device_register_simple("pcspkr", -1, NULL, 0);
|
||||
|
||||
ret = platform_device_add(pd);
|
||||
if (ret)
|
||||
platform_device_put(pd);
|
||||
|
||||
return ret;
|
||||
return IS_ERR(pd) ? PTR_ERR(pd) : 0;
|
||||
}
|
||||
device_initcall(add_pcspkr);
|
||||
|
|
|
@ -185,7 +185,8 @@ static void mwait_idle(void)
|
|||
static void poll_idle(void)
|
||||
{
|
||||
local_irq_enable();
|
||||
cpu_relax();
|
||||
while (!need_resched())
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <linux/tick.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include <asm/uaccess.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 sp;
|
||||
unsigned short ss, gs;
|
||||
const char *board;
|
||||
|
||||
if (user_mode_vm(regs)) {
|
||||
sp = regs->sp;
|
||||
|
@ -175,11 +177,15 @@ void __show_registers(struct pt_regs *regs, int all)
|
|||
}
|
||||
|
||||
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,
|
||||
print_tainted(), init_utsname()->release,
|
||||
(int)strcspn(init_utsname()->version, " "),
|
||||
init_utsname()->version);
|
||||
init_utsname()->version, board);
|
||||
|
||||
printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
|
||||
(u16)regs->cs, regs->ip, regs->flags,
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
#include <linux/kdebug.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
@ -89,7 +89,7 @@ void exit_idle(void)
|
|||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
DECLARE_PER_CPU(int, cpu_state);
|
||||
|
||||
#include <asm/nmi.h>
|
||||
#include <linux/nmi.h>
|
||||
/* We halt the CPU with physical CPU hotplug */
|
||||
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 */
|
||||
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 d0, d1, d2, d3, d6, d7;
|
||||
|
@ -163,59 +163,61 @@ void __show_regs(struct pt_regs * regs)
|
|||
|
||||
printk("\n");
|
||||
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(),
|
||||
init_utsname()->release,
|
||||
(int)strcspn(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("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp,
|
||||
regs->flags);
|
||||
printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
|
||||
printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss,
|
||||
regs->sp, regs->flags);
|
||||
printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
|
||||
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);
|
||||
printk("RBP: %016lx R08: %016lx R09: %016lx\n",
|
||||
printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
|
||||
regs->bp, regs->r8, regs->r9);
|
||||
printk("R10: %016lx R11: %016lx R12: %016lx\n",
|
||||
regs->r10, regs->r11, regs->r12);
|
||||
printk("R13: %016lx R14: %016lx R15: %016lx\n",
|
||||
regs->r13, regs->r14, regs->r15);
|
||||
printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
|
||||
regs->r10, regs->r11, regs->r12);
|
||||
printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
|
||||
regs->r13, regs->r14, regs->r15);
|
||||
|
||||
asm("movl %%ds,%0" : "=r" (ds));
|
||||
asm("movl %%cs,%0" : "=r" (cs));
|
||||
asm("movl %%es,%0" : "=r" (es));
|
||||
asm("movl %%ds,%0" : "=r" (ds));
|
||||
asm("movl %%cs,%0" : "=r" (cs));
|
||||
asm("movl %%es,%0" : "=r" (es));
|
||||
asm("movl %%fs,%0" : "=r" (fsindex));
|
||||
asm("movl %%gs,%0" : "=r" (gsindex));
|
||||
|
||||
rdmsrl(MSR_FS_BASE, fs);
|
||||
rdmsrl(MSR_GS_BASE, gs);
|
||||
rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
|
||||
rdmsrl(MSR_GS_BASE, gs);
|
||||
rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
|
||||
|
||||
cr0 = read_cr0();
|
||||
cr2 = read_cr2();
|
||||
cr3 = read_cr3();
|
||||
cr4 = read_cr4();
|
||||
|
||||
printk("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
|
||||
fs,fsindex,gs,gsindex,shadowgs);
|
||||
printk("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0);
|
||||
printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
|
||||
printk(KERN_INFO "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
|
||||
fs, fsindex, gs, gsindex, shadowgs);
|
||||
printk(KERN_INFO "CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
|
||||
es, cr0);
|
||||
printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
|
||||
cr4);
|
||||
|
||||
get_debugreg(d0, 0);
|
||||
get_debugreg(d1, 1);
|
||||
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(d6, 6);
|
||||
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)
|
||||
{
|
||||
printk("CPU %d:", smp_processor_id());
|
||||
printk(KERN_INFO "CPU %d:", smp_processor_id());
|
||||
__show_regs(regs);
|
||||
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,
|
||||
unsigned long unused,
|
||||
struct task_struct * p, struct pt_regs * regs)
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
{
|
||||
int err;
|
||||
struct pt_regs * childregs;
|
||||
struct pt_regs *childregs;
|
||||
struct task_struct *me = current;
|
||||
|
||||
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))
|
||||
err = do_set_thread_area(p, -1,
|
||||
(struct user_desc __user *)childregs->si, 0);
|
||||
else
|
||||
#endif
|
||||
err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
|
||||
if (err)
|
||||
else
|
||||
#endif
|
||||
err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
err = 0;
|
||||
|
@ -568,7 +570,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
|||
unsigned fsindex, gsindex;
|
||||
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
|
@ -576,13 +578,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
|||
*/
|
||||
load_sp0(tss, next);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Switch DS and ES.
|
||||
* This won't pick up thread selector changes, but I guess that is ok.
|
||||
*/
|
||||
savesegment(es, prev->es);
|
||||
if (unlikely(next->es | prev->es))
|
||||
loadsegment(es, next->es);
|
||||
loadsegment(es, next->es);
|
||||
|
||||
savesegment(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();
|
||||
|
||||
/*
|
||||
/*
|
||||
* Switch FS and GS.
|
||||
*
|
||||
* 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)) {
|
||||
loadsegment(fs, next->fsindex);
|
||||
/*
|
||||
/*
|
||||
* Check if the user used a selector != 0; if yes
|
||||
* clear 64bit base, since overloaded base is always
|
||||
* mapped to the Null selector
|
||||
*/
|
||||
if (fsindex)
|
||||
prev->fs = 0;
|
||||
prev->fs = 0;
|
||||
}
|
||||
/* when next process has a 64bit base use it */
|
||||
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)) {
|
||||
load_gs_index(next->gsindex);
|
||||
if (gsindex)
|
||||
prev->gs = 0;
|
||||
prev->gs = 0;
|
||||
}
|
||||
if (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 */
|
||||
unlazy_fpu(prev_p);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Switch the PDA and FPU contexts.
|
||||
*/
|
||||
prev->usersp = read_pda(oldrsp);
|
||||
write_pda(oldrsp, next->usersp);
|
||||
write_pda(pcurrent, next_p);
|
||||
write_pda(pcurrent, next_p);
|
||||
|
||||
write_pda(kernelstack,
|
||||
(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)
|
||||
{
|
||||
long error;
|
||||
char * filename;
|
||||
char *filename;
|
||||
|
||||
filename = getname(name);
|
||||
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 stack;
|
||||
u64 fp,ip;
|
||||
u64 fp, ip;
|
||||
int count = 0;
|
||||
|
||||
if (!p || p == current || p->state==TASK_RUNNING)
|
||||
return 0;
|
||||
if (!p || p == current || p->state == TASK_RUNNING)
|
||||
return 0;
|
||||
stack = (unsigned long)task_stack_page(p);
|
||||
if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
|
||||
return 0;
|
||||
fp = *(u64 *)(p->thread.sp);
|
||||
do {
|
||||
do {
|
||||
if (fp < (unsigned long)stack ||
|
||||
fp > (unsigned long)stack+THREAD_SIZE)
|
||||
return 0;
|
||||
return 0;
|
||||
ip = *(u64 *)(fp+8);
|
||||
if (!in_sched_functions(ip))
|
||||
return ip;
|
||||
fp = *(u64 *)fp;
|
||||
} while (count++ < 16);
|
||||
fp = *(u64 *)fp;
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
|
||||
{
|
||||
int ret = 0;
|
||||
{
|
||||
int ret = 0;
|
||||
int doit = task == current;
|
||||
int cpu;
|
||||
|
||||
switch (code) {
|
||||
switch (code) {
|
||||
case ARCH_SET_GS:
|
||||
if (addr >= TASK_SIZE_OF(task))
|
||||
return -EPERM;
|
||||
return -EPERM;
|
||||
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. */
|
||||
if (addr <= 0xffffffff) {
|
||||
set_32bit_tls(task, GS_TLS, addr);
|
||||
if (doit) {
|
||||
if (addr <= 0xffffffff) {
|
||||
set_32bit_tls(task, GS_TLS, addr);
|
||||
if (doit) {
|
||||
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;
|
||||
} else {
|
||||
} else {
|
||||
task->thread.gsindex = 0;
|
||||
task->thread.gs = addr;
|
||||
if (doit) {
|
||||
load_gs_index(0);
|
||||
ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
put_cpu();
|
||||
break;
|
||||
|
@ -848,8 +850,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
|
|||
rdmsrl(MSR_KERNEL_GS_BASE, base);
|
||||
else
|
||||
base = task->thread.gs;
|
||||
}
|
||||
else
|
||||
} else
|
||||
base = task->thread.gs;
|
||||
ret = put_user(base, (unsigned long __user *)addr);
|
||||
break;
|
||||
|
|
|
@ -29,7 +29,11 @@ EXPORT_SYMBOL(pm_power_off);
|
|||
|
||||
static const struct desc_ptr no_idt = {};
|
||||
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;
|
||||
|
||||
#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
|
||||
|
|
|
@ -223,6 +223,9 @@ unsigned long saved_video_mode;
|
|||
#define RAMDISK_LOAD_FLAG 0x4000
|
||||
|
||||
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)
|
||||
struct edd edd;
|
||||
|
@ -665,6 +668,19 @@ void __init setup_arch(char **cmdline_p)
|
|||
bss_resource.start = virt_to_phys(&__bss_start);
|
||||
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);
|
||||
*cmdline_p = command_line;
|
||||
|
||||
|
|
|
@ -162,9 +162,16 @@ void __init setup_per_cpu_areas(void)
|
|||
printk(KERN_INFO
|
||||
"cpu %d has no node %d or node-local memory\n",
|
||||
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);
|
||||
if (ptr)
|
||||
printk(KERN_DEBUG "per cpu data for cpu%d on node%d at %016lx\n",
|
||||
cpu, node, __pa(ptr));
|
||||
}
|
||||
#endif
|
||||
per_cpu_offset(cpu) = ptr - __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 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
|
||||
|
|
|
@ -20,9 +20,10 @@
|
|||
#include <linux/stddef.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/proto.h>
|
||||
#include <asm/ia32_unistd.h>
|
||||
|
@ -44,11 +45,6 @@
|
|||
# define FIX_EFLAGS __FIX_EFLAGS
|
||||
#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
|
||||
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
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 */
|
||||
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(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);
|
||||
|
||||
if (buf) {
|
||||
|
@ -201,7 +197,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
|||
current->blocked = set;
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
|
||||
goto badframe;
|
||||
|
||||
|
@ -211,16 +207,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
|||
return ax;
|
||||
|
||||
badframe:
|
||||
signal_fault(regs,frame,"sigreturn");
|
||||
signal_fault(regs, frame, "sigreturn");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a signal frame.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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,
|
||||
sigset_t *set, struct pt_regs * regs)
|
||||
sigset_t *set, struct pt_regs *regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
struct _fpstate __user *fp = NULL;
|
||||
struct _fpstate __user *fp = NULL;
|
||||
int err = 0;
|
||||
struct task_struct *me = current;
|
||||
|
||||
if (used_math()) {
|
||||
fp = get_stack(ka, regs, sizeof(struct _fpstate));
|
||||
fp = get_stack(ka, regs, sizeof(struct _fpstate));
|
||||
frame = (void __user *)round_down(
|
||||
(unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
|
||||
goto give_sigsegv;
|
||||
|
||||
if (save_i387(fp) < 0)
|
||||
err |= -1;
|
||||
if (save_i387(fp) < 0)
|
||||
err |= -1;
|
||||
} else
|
||||
frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
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);
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
|
||||
/* Create the ucontext. */
|
||||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
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 |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
|
||||
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[1], &frame->uc.uc_sigmask.sig[1]);
|
||||
__put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
|
||||
} else
|
||||
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);
|
||||
} else {
|
||||
/* could use a vstub here */
|
||||
goto give_sigsegv;
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
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 */
|
||||
regs->di = sig;
|
||||
/* In case the signal handler was declared without prototypes */
|
||||
/* In case the signal handler was declared without prototypes */
|
||||
regs->ax = 0;
|
||||
|
||||
/* This also works for non SA_SIGINFO handlers because they expect the
|
||||
|
@ -359,7 +356,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
|
||||
/*
|
||||
* OK, we're invoking a handler
|
||||
*/
|
||||
*/
|
||||
|
||||
static int
|
||||
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);
|
||||
else
|
||||
ret = ia32_setup_frame(sig, ka, oldset, regs);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
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;
|
||||
|
||||
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))
|
||||
sigaddset(¤t->blocked,sig);
|
||||
sigaddset(¤t->blocked, sig);
|
||||
recalc_sigpending();
|
||||
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)
|
||||
{
|
||||
struct task_struct *me = current;
|
||||
{
|
||||
struct task_struct *me = current;
|
||||
if (show_unhandled_signals && printk_ratelimit()) {
|
||||
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);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
force_sig(SIGSEGV, me);
|
||||
}
|
||||
force_sig(SIGSEGV, me);
|
||||
}
|
||||
|
|
|
@ -1313,16 +1313,13 @@ __init void prefill_possible_map(void)
|
|||
if (!num_processors)
|
||||
num_processors = 1;
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
if (additional_cpus == -1) {
|
||||
if (disabled_cpus > 0)
|
||||
additional_cpus = disabled_cpus;
|
||||
else
|
||||
additional_cpus = 0;
|
||||
}
|
||||
#else
|
||||
additional_cpus = 0;
|
||||
#endif
|
||||
|
||||
possible = num_processors + additional_cpus;
|
||||
if (possible > NR_CPUS)
|
||||
possible = NR_CPUS;
|
||||
|
|
|
@ -13,16 +13,17 @@
|
|||
#include <linux/utsname.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/ia32.h>
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long off)
|
||||
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long off)
|
||||
{
|
||||
long error;
|
||||
struct file * file;
|
||||
struct file *file;
|
||||
|
||||
error = -EINVAL;
|
||||
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
|
||||
conflicts with the heap, but we assume that glibc
|
||||
malloc knows how to fall back to mmap. Give it 1GB
|
||||
of playground for now. -AK */
|
||||
*begin = 0x40000000;
|
||||
*end = 0x80000000;
|
||||
of playground for now. -AK */
|
||||
*begin = 0x40000000;
|
||||
*end = 0x80000000;
|
||||
if (current->flags & PF_RANDOMIZE) {
|
||||
new_begin = randomize_range(*begin, *begin + 0x02000000, 0);
|
||||
if (new_begin)
|
||||
|
@ -67,9 +68,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
|
|||
}
|
||||
} else {
|
||||
*begin = TASK_UNMAPPED_BASE;
|
||||
*end = TASK_SIZE;
|
||||
*end = TASK_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long
|
||||
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;
|
||||
unsigned long start_addr;
|
||||
unsigned long begin, end;
|
||||
|
||||
|
||||
if (flags & MAP_FIXED)
|
||||
return addr;
|
||||
|
||||
find_start_end(flags, &begin, &end);
|
||||
find_start_end(flags, &begin, &end);
|
||||
|
||||
if (len > end)
|
||||
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))
|
||||
&& len <= mm->cached_hole_size) {
|
||||
mm->cached_hole_size = 0;
|
||||
mm->cached_hole_size = 0;
|
||||
mm->free_area_cache = begin;
|
||||
}
|
||||
addr = mm->free_area_cache;
|
||||
if (addr < begin)
|
||||
addr = begin;
|
||||
if (addr < begin)
|
||||
addr = begin;
|
||||
start_addr = addr;
|
||||
|
||||
full_search:
|
||||
|
@ -128,7 +129,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
|||
return addr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -178,7 +179,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
vma = find_vma(mm, addr-len);
|
||||
if (!vma || addr <= vma->vm_start)
|
||||
/* 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)
|
||||
|
@ -195,7 +196,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
vma = find_vma(mm, addr);
|
||||
if (!vma || addr+len <= vma->vm_start)
|
||||
/* 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 */
|
||||
if (addr + mm->cached_hole_size < vma->vm_start)
|
||||
|
@ -225,13 +226,13 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
}
|
||||
|
||||
|
||||
asmlinkage long sys_uname(struct new_utsname __user * name)
|
||||
asmlinkage long sys_uname(struct new_utsname __user *name)
|
||||
{
|
||||
int err;
|
||||
down_read(&uts_sem);
|
||||
err = copy_to_user(name, utsname(), sizeof (*name));
|
||||
err = copy_to_user(name, utsname(), sizeof(*name));
|
||||
up_read(&uts_sem);
|
||||
if (personality(current->personality) == PER_LINUX32)
|
||||
err |= copy_to_user(&name->machine, "i686", 5);
|
||||
if (personality(current->personality) == PER_LINUX32)
|
||||
err |= copy_to_user(&name->machine, "i686", 5);
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <linux/bug.h>
|
||||
#include <linux/nmi.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#if defined(CONFIG_EDAC)
|
||||
#include <linux/edac.h>
|
||||
|
@ -45,9 +47,6 @@
|
|||
#include <asm/unwind.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/proto.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)
|
||||
{
|
||||
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,
|
||||
|
@ -98,7 +98,8 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
|
|||
[STACKFAULT_STACK - 1] = "#SS",
|
||||
[MCE_STACK - 1] = "#MC",
|
||||
#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
|
||||
};
|
||||
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
|
||||
* interrupt 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 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;
|
||||
struct thread_info *tinfo;
|
||||
|
||||
|
@ -237,7 +238,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
|||
if (!bp) {
|
||||
if (task == current) {
|
||||
/* Grab bp right from our regs */
|
||||
asm("movq %%rbp, %0" : "=r" (bp) :);
|
||||
asm("movq %%rbp, %0" : "=r" (bp) : );
|
||||
} else {
|
||||
/* bp is the last reg pushed by switch_to */
|
||||
bp = *(unsigned long *) task->thread.sp;
|
||||
|
@ -339,9 +340,8 @@ static void
|
|||
show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
||||
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);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
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;
|
||||
int i;
|
||||
const int cpu = smp_processor_id();
|
||||
unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr);
|
||||
unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
|
||||
unsigned long *irqstack_end =
|
||||
(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 (task)
|
||||
|
@ -386,6 +390,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
|||
printk(" %016lx", *stack++);
|
||||
touch_nmi_watchdog();
|
||||
}
|
||||
printk("\n");
|
||||
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
|
||||
}
|
||||
|
||||
|
@ -404,7 +409,7 @@ void dump_stack(void)
|
|||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
if (!bp)
|
||||
asm("movq %%rbp, %0" : "=r" (bp):);
|
||||
asm("movq %%rbp, %0" : "=r" (bp) : );
|
||||
#endif
|
||||
|
||||
printk("Pid: %d, comm: %.20s %s %s %.*s\n",
|
||||
|
@ -414,7 +419,6 @@ void dump_stack(void)
|
|||
init_utsname()->version);
|
||||
show_trace(NULL, NULL, &stack, bp);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
|
||||
void show_registers(struct pt_regs *regs)
|
||||
|
@ -443,7 +447,6 @@ void show_registers(struct pt_regs *regs)
|
|||
printk("Stack: ");
|
||||
show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
|
||||
regs->bp, "");
|
||||
printk("\n");
|
||||
|
||||
printk(KERN_EMERG "Code: ");
|
||||
|
||||
|
@ -493,7 +496,7 @@ unsigned __kprobes long oops_begin(void)
|
|||
raw_local_irq_save(flags);
|
||||
cpu = smp_processor_id();
|
||||
if (!__raw_spin_trylock(&die_lock)) {
|
||||
if (cpu == die_owner)
|
||||
if (cpu == die_owner)
|
||||
/* nested oops. should stop eventually */;
|
||||
else
|
||||
__raw_spin_lock(&die_lock);
|
||||
|
@ -638,7 +641,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
|
|||
}
|
||||
|
||||
#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) \
|
||||
== 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) \
|
||||
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; \
|
||||
info.si_signo = signr; \
|
||||
|
@ -683,7 +686,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
|
|||
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";
|
||||
struct task_struct *tsk = current;
|
||||
|
@ -778,9 +781,10 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
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;
|
||||
printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
|
||||
reason);
|
||||
|
@ -882,7 +886,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
|||
else if (user_mode(eregs))
|
||||
regs = task_pt_regs(current);
|
||||
/* Exception from kernel and interrupts are enabled. Move to
|
||||
kernel process stack. */
|
||||
kernel process stack. */
|
||||
else if (eregs->flags & X86_EFLAGS_IF)
|
||||
regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
|
||||
if (eregs != regs)
|
||||
|
@ -891,7 +895,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
@ -1035,7 +1039,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
|
|||
|
||||
asmlinkage void bad_intr(void)
|
||||
{
|
||||
printk("bad interrupt");
|
||||
printk("bad interrupt");
|
||||
}
|
||||
|
||||
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);
|
||||
if (!user_mode(regs) &&
|
||||
kernel_math_error(regs, "kernel simd math error", 19))
|
||||
kernel_math_error(regs, "kernel simd math error", 19))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -1092,7 +1096,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
|
|||
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_ist(1, &debug, DEBUG_STACK);
|
||||
set_intr_gate_ist(2, &nmi, NMI_STACK);
|
||||
set_system_gate_ist(3, &int3, DEBUG_STACK); /* int3 can be called from all */
|
||||
set_system_gate(4, &overflow); /* int4 can be called from all */
|
||||
/* int3 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(6, &invalid_op);
|
||||
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
|
||||
*/
|
||||
static u64 tsc_read_refs(u64 *pm, u64 *hpet)
|
||||
static u64 tsc_read_refs(u64 *p, int hpet)
|
||||
{
|
||||
u64 t1, t2;
|
||||
int i;
|
||||
|
@ -112,9 +112,9 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
|
|||
for (i = 0; i < MAX_RETRIES; i++) {
|
||||
t1 = get_cycles();
|
||||
if (hpet)
|
||||
*hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
|
||||
*p = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
|
||||
else
|
||||
*pm = acpi_pm_read_early();
|
||||
*p = acpi_pm_read_early();
|
||||
t2 = get_cycles();
|
||||
if ((t2 - t1) < SMI_TRESHOLD)
|
||||
return t2;
|
||||
|
@ -122,6 +122,52 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
|
|||
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
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
unsigned long tscmin, tscmax;
|
||||
|
@ -144,8 +190,8 @@ static unsigned long pit_calibrate_tsc(void)
|
|||
* (LSB then MSB) to begin countdown.
|
||||
*/
|
||||
outb(0xb0, 0x43);
|
||||
outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
|
||||
outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
|
||||
outb(latch & 0xff, 0x42);
|
||||
outb(latch >> 8, 0x42);
|
||||
|
||||
tsc = t1 = t2 = get_cycles();
|
||||
|
||||
|
@ -166,31 +212,154 @@ static unsigned long pit_calibrate_tsc(void)
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* If the maximum is 10 times larger than the minimum,
|
||||
* then we got hit by an SMI as well.
|
||||
*/
|
||||
if (pitcnt < 5000 || tscmax > 10 * tscmin)
|
||||
if (pitcnt < loopmin || tscmax > 10 * tscmin)
|
||||
return ULONG_MAX;
|
||||
|
||||
/* Calculate the PIT value */
|
||||
delta = t2 - t1;
|
||||
do_div(delta, 50);
|
||||
do_div(delta, ms);
|
||||
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
|
||||
*/
|
||||
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 flags;
|
||||
int hpet = is_hpet_enabled(), i;
|
||||
unsigned long flags, latch, ms, fast_calibrate;
|
||||
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
|
||||
|
@ -216,7 +385,13 @@ unsigned long native_calibrate_tsc(void)
|
|||
* calibration delay loop as we have to wait for a certain
|
||||
* 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;
|
||||
|
||||
/*
|
||||
|
@ -226,16 +401,16 @@ unsigned long native_calibrate_tsc(void)
|
|||
* read the end value.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
|
||||
tsc_pit_khz = pit_calibrate_tsc();
|
||||
tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
|
||||
tsc1 = tsc_read_refs(&ref1, hpet);
|
||||
tsc_pit_khz = pit_calibrate_tsc(latch, ms, loopmin);
|
||||
tsc2 = tsc_read_refs(&ref2, hpet);
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* Pick the lowest PIT TSC calibration so far */
|
||||
tsc_pit_min = min(tsc_pit_min, tsc_pit_khz);
|
||||
|
||||
/* hpet or pmtimer available ? */
|
||||
if (!hpet && !pm1 && !pm2)
|
||||
if (!hpet && !ref1 && !ref2)
|
||||
continue;
|
||||
|
||||
/* Check, whether the sampling was disturbed by an SMI */
|
||||
|
@ -243,23 +418,41 @@ unsigned long native_calibrate_tsc(void)
|
|||
continue;
|
||||
|
||||
tsc2 = (tsc2 - tsc1) * 1000000LL;
|
||||
if (hpet)
|
||||
tsc2 = calc_hpet_ref(tsc2, ref1, ref2);
|
||||
else
|
||||
tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2);
|
||||
|
||||
if (hpet) {
|
||||
if (hpet2 < hpet1)
|
||||
hpet2 += 0x100000000ULL;
|
||||
hpet2 -= hpet1;
|
||||
tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
|
||||
do_div(tsc1, 1000000);
|
||||
} else {
|
||||
if (pm2 < pm1)
|
||||
pm2 += (u64)ACPI_PM_OVRRUN;
|
||||
pm2 -= pm1;
|
||||
tsc1 = pm2 * 1000000000LL;
|
||||
do_div(tsc1, PMTMR_TICKS_PER_SEC);
|
||||
tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
|
||||
|
||||
/* Check the reference deviation */
|
||||
delta = ((u64) tsc_pit_min) * 100;
|
||||
do_div(delta, tsc_ref_min);
|
||||
|
||||
/*
|
||||
* If both calibration results are inside a 10% window
|
||||
* then we can be sure, that the calibration
|
||||
* succeeded. We break out of the loop right away. We
|
||||
* use the reference value, as it is more precise.
|
||||
*/
|
||||
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");
|
||||
|
||||
/* 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");
|
||||
return 0;
|
||||
}
|
||||
|
@ -278,7 +471,7 @@ unsigned long native_calibrate_tsc(void)
|
|||
/* The alternative source failed as well, disable TSC */
|
||||
if (tsc_ref_min == ULONG_MAX) {
|
||||
printk(KERN_WARNING "TSC: HPET/PMTIMER calibration "
|
||||
"failed due to SMI disturbance.\n");
|
||||
"failed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -290,44 +483,25 @@ unsigned long native_calibrate_tsc(void)
|
|||
}
|
||||
|
||||
/* 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");
|
||||
return tsc_pit_min;
|
||||
}
|
||||
|
||||
/* The alternative source failed, use the PIT calibration value */
|
||||
if (tsc_ref_min == ULONG_MAX) {
|
||||
printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed due "
|
||||
"to SMI disturbance. Using PIT calibration\n");
|
||||
printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. "
|
||||
"Using PIT calibration\n");
|
||||
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 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");
|
||||
return tsc_pit_min;
|
||||
}
|
||||
|
|
|
@ -25,45 +25,31 @@
|
|||
#include <asm/visws/cobalt.h>
|
||||
#include <asm/visws/piix4.h>
|
||||
#include <asm/arch_hooks.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <mach_ipi.h>
|
||||
|
||||
#include "mach_apic.h"
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.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/irq_vectors.h>
|
||||
#include <asm/visws/cobalt.h>
|
||||
#include <asm/visws/lithium.h>
|
||||
#include <asm/visws/piix4.h>
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
|
||||
extern int no_broadcast;
|
||||
|
||||
#include <asm/io.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_rev = -1;
|
||||
|
|
|
@ -393,13 +393,13 @@ static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type)
|
|||
}
|
||||
#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_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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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_check_page_type(clonepfn, VMI_PAGE_L2);
|
||||
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_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_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);
|
||||
}
|
||||
|
||||
static void __rdmsr_safe_on_cpu(void *info)
|
||||
static void __wrmsr_on_cpu(void *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;
|
||||
|
||||
rv.msr_no = msr_no;
|
||||
if (safe) {
|
||||
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);
|
||||
}
|
||||
err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
|
||||
*l = rv.l;
|
||||
*h = rv.h;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
|
@ -56,45 +65,30 @@ static void __wrmsr_safe_on_cpu(void *info)
|
|||
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;
|
||||
|
||||
rv.msr_no = msr_no;
|
||||
rv.l = l;
|
||||
rv.h = h;
|
||||
if (safe) {
|
||||
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);
|
||||
}
|
||||
err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
|
||||
|
||||
return 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);
|
||||
return err ? err : rv.err;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(rdmsr_on_cpu);
|
||||
|
|
|
@ -22,7 +22,7 @@ char *strcpy(char *dest, const char *src)
|
|||
"testb %%al,%%al\n\t"
|
||||
"jne 1b"
|
||||
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
|
||||
:"0" (src), "1" (dest) : "memory");
|
||||
: "0" (src), "1" (dest) : "memory");
|
||||
return dest;
|
||||
}
|
||||
EXPORT_SYMBOL(strcpy);
|
||||
|
@ -42,7 +42,7 @@ char *strncpy(char *dest, const char *src, size_t count)
|
|||
"stosb\n"
|
||||
"2:"
|
||||
: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
|
||||
:"0" (src), "1" (dest), "2" (count) : "memory");
|
||||
: "0" (src), "1" (dest), "2" (count) : "memory");
|
||||
return dest;
|
||||
}
|
||||
EXPORT_SYMBOL(strncpy);
|
||||
|
@ -60,7 +60,7 @@ char *strcat(char *dest, const char *src)
|
|||
"testb %%al,%%al\n\t"
|
||||
"jne 1b"
|
||||
: "=&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;
|
||||
}
|
||||
EXPORT_SYMBOL(strcat);
|
||||
|
@ -105,9 +105,9 @@ int strcmp(const char *cs, const char *ct)
|
|||
"2:\tsbbl %%eax,%%eax\n\t"
|
||||
"orb $1,%%al\n"
|
||||
"3:"
|
||||
:"=a" (res), "=&S" (d0), "=&D" (d1)
|
||||
:"1" (cs), "2" (ct)
|
||||
:"memory");
|
||||
: "=a" (res), "=&S" (d0), "=&D" (d1)
|
||||
: "1" (cs), "2" (ct)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(strcmp);
|
||||
|
@ -130,9 +130,9 @@ int strncmp(const char *cs, const char *ct, size_t count)
|
|||
"3:\tsbbl %%eax,%%eax\n\t"
|
||||
"orb $1,%%al\n"
|
||||
"4:"
|
||||
:"=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
|
||||
:"1" (cs), "2" (ct), "3" (count)
|
||||
:"memory");
|
||||
: "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
|
||||
: "1" (cs), "2" (ct), "3" (count)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(strncmp);
|
||||
|
@ -152,9 +152,9 @@ char *strchr(const char *s, int c)
|
|||
"movl $1,%1\n"
|
||||
"2:\tmovl %1,%0\n\t"
|
||||
"decl %0"
|
||||
:"=a" (res), "=&S" (d0)
|
||||
:"1" (s), "0" (c)
|
||||
:"memory");
|
||||
: "=a" (res), "=&S" (d0)
|
||||
: "1" (s), "0" (c)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(strchr);
|
||||
|
@ -169,9 +169,9 @@ size_t strlen(const char *s)
|
|||
"scasb\n\t"
|
||||
"notl %0\n\t"
|
||||
"decl %0"
|
||||
:"=c" (res), "=&D" (d0)
|
||||
:"1" (s), "a" (0), "0" (0xffffffffu)
|
||||
:"memory");
|
||||
: "=c" (res), "=&D" (d0)
|
||||
: "1" (s), "a" (0), "0" (0xffffffffu)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(strlen);
|
||||
|
@ -189,9 +189,9 @@ void *memchr(const void *cs, int c, size_t count)
|
|||
"je 1f\n\t"
|
||||
"movl $1,%0\n"
|
||||
"1:\tdecl %0"
|
||||
:"=D" (res), "=&c" (d0)
|
||||
:"a" (c), "0" (cs), "1" (count)
|
||||
:"memory");
|
||||
: "=D" (res), "=&c" (d0)
|
||||
: "a" (c), "0" (cs), "1" (count)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(memchr);
|
||||
|
@ -228,9 +228,9 @@ size_t strnlen(const char *s, size_t count)
|
|||
"cmpl $-1,%1\n\t"
|
||||
"jne 1b\n"
|
||||
"3:\tsubl %2,%0"
|
||||
:"=a" (res), "=&d" (d0)
|
||||
:"c" (s), "1" (count)
|
||||
:"memory");
|
||||
: "=a" (res), "=&d" (d0)
|
||||
: "c" (s), "1" (count)
|
||||
: "memory");
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
|
|
|
@ -23,9 +23,9 @@ __asm__ __volatile__(
|
|||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"2:"
|
||||
:"=a" (__res), "=&c" (d0), "=&S" (d1)
|
||||
:"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
|
||||
:"dx", "di");
|
||||
: "=a" (__res), "=&c" (d0), "=&S" (d1)
|
||||
: "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
|
||||
: "dx", "di");
|
||||
return __res;
|
||||
}
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ void __init initmem_init(unsigned long start_pfn,
|
|||
|
||||
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);
|
||||
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
|
||||
* address space marker.
|
||||
*/
|
||||
prot = pgprot_val(new_prot) & ~(PTE_PFN_MASK);
|
||||
cur = pgprot_val(st->current_prot) & ~(PTE_PFN_MASK);
|
||||
prot = pgprot_val(new_prot) & PTE_FLAGS_MASK;
|
||||
cur = pgprot_val(st->current_prot) & PTE_FLAGS_MASK;
|
||||
|
||||
if (!st->level) {
|
||||
/* First entry */
|
||||
|
|
|
@ -225,7 +225,7 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
|
|||
void __init cleanup_highmap(void)
|
||||
{
|
||||
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 *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;
|
||||
|
||||
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) {
|
||||
unsigned long extra;
|
||||
extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
|
||||
pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
|
||||
} else
|
||||
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) {
|
||||
unsigned long extra;
|
||||
|
@ -466,7 +466,7 @@ static void __init find_early_table_space(unsigned long end)
|
|||
ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
} else
|
||||
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
|
||||
|
|
|
@ -79,7 +79,7 @@ static int __init allocate_cachealigned_memnodemap(void)
|
|||
return 0;
|
||||
|
||||
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_size, L1_CACHE_BYTES);
|
||||
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 bootmap_start, nodedata_phys;
|
||||
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;
|
||||
|
||||
start = round_up(start, ZONE_ALIGN);
|
||||
start = roundup(start, ZONE_ALIGN);
|
||||
|
||||
printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
|
||||
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);
|
||||
nid = phys_to_nid(nodedata_phys);
|
||||
if (nid == nodeid)
|
||||
bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
|
||||
bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
|
||||
return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -906,11 +906,13 @@ int set_memory_ro(unsigned long addr, int numpages)
|
|||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -63,10 +63,8 @@ static inline void pgd_list_del(pgd_t *pgd)
|
|||
#define UNSHARED_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
|
||||
ptes in non-PAE, or shared PMD in PAE), then just copy the
|
||||
references from swapper_pg_dir. */
|
||||
|
@ -87,7 +85,7 @@ static void pgd_ctor(void *p)
|
|||
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 */
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@ static int __init parse_vmalloc(char *arg)
|
|||
if (!arg)
|
||||
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;
|
||||
}
|
||||
early_param("vmalloc", parse_vmalloc);
|
||||
|
|
|
@ -10,11 +10,12 @@
|
|||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/nmi.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/nmi.h>
|
||||
|
||||
|
||||
#include "op_x86_model.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)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (smp_num_siblings == 2){
|
||||
if (smp_num_siblings == 2) {
|
||||
num_counters = NUM_COUNTERS_HT2;
|
||||
num_controls = NUM_CONTROLS_HT2;
|
||||
}
|
||||
|
@ -86,7 +87,7 @@ struct p4_event_binding {
|
|||
#define CTR_FLAME_2 (1 << 6)
|
||||
#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_MS_0, MSR_P4_MS_PERFCTR0, MSR_P4_MS_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 }
|
||||
};
|
||||
|
||||
#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. */
|
||||
|
||||
static struct p4_event_binding p4_events[NUM_EVENTS] = {
|
||||
|
||||
|
||||
{ /* BRANCH_RETIRED */
|
||||
0x05, 0x06,
|
||||
0x05, 0x06,
|
||||
{ {CTR_IQ_4, MSR_P4_CRU_ESCR2},
|
||||
{CTR_IQ_5, MSR_P4_CRU_ESCR3} }
|
||||
},
|
||||
|
||||
|
||||
{ /* MISPRED_BRANCH_RETIRED */
|
||||
0x04, 0x03,
|
||||
0x04, 0x03,
|
||||
{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
|
||||
{ CTR_IQ_5, MSR_P4_CRU_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* TC_DELIVER_MODE */
|
||||
0x01, 0x01,
|
||||
{ { CTR_MS_0, MSR_P4_TC_ESCR0},
|
||||
{ { CTR_MS_0, MSR_P4_TC_ESCR0},
|
||||
{ CTR_MS_2, MSR_P4_TC_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* BPU_FETCH_REQUEST */
|
||||
0x00, 0x03,
|
||||
0x00, 0x03,
|
||||
{ { CTR_BPU_0, MSR_P4_BPU_ESCR0},
|
||||
{ CTR_BPU_2, MSR_P4_BPU_ESCR1} }
|
||||
},
|
||||
|
@ -146,7 +147,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
|
|||
},
|
||||
|
||||
{ /* LOAD_PORT_REPLAY */
|
||||
0x02, 0x04,
|
||||
0x02, 0x04,
|
||||
{ { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
|
||||
},
|
||||
|
@ -170,43 +171,43 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
|
|||
},
|
||||
|
||||
{ /* BSQ_CACHE_REFERENCE */
|
||||
0x07, 0x0c,
|
||||
0x07, 0x0c,
|
||||
{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
|
||||
{ CTR_BPU_2, MSR_P4_BSU_ESCR1} }
|
||||
},
|
||||
|
||||
{ /* IOQ_ALLOCATION */
|
||||
0x06, 0x03,
|
||||
0x06, 0x03,
|
||||
{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
|
||||
{ 0, 0 } }
|
||||
},
|
||||
|
||||
{ /* IOQ_ACTIVE_ENTRIES */
|
||||
0x06, 0x1a,
|
||||
0x06, 0x1a,
|
||||
{ { CTR_BPU_2, MSR_P4_FSB_ESCR1},
|
||||
{ 0, 0 } }
|
||||
},
|
||||
|
||||
{ /* FSB_DATA_ACTIVITY */
|
||||
0x06, 0x17,
|
||||
0x06, 0x17,
|
||||
{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
|
||||
{ CTR_BPU_2, MSR_P4_FSB_ESCR1} }
|
||||
},
|
||||
|
||||
{ /* BSQ_ALLOCATION */
|
||||
0x07, 0x05,
|
||||
0x07, 0x05,
|
||||
{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
|
||||
{ 0, 0 } }
|
||||
},
|
||||
|
||||
{ /* BSQ_ACTIVE_ENTRIES */
|
||||
0x07, 0x06,
|
||||
{ { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},
|
||||
{ { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},
|
||||
{ 0, 0 } }
|
||||
},
|
||||
|
||||
{ /* X87_ASSIST */
|
||||
0x05, 0x03,
|
||||
0x05, 0x03,
|
||||
{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
|
||||
{ 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_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* PACKED_SP_UOP */
|
||||
0x01, 0x08,
|
||||
0x01, 0x08,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* PACKED_DP_UOP */
|
||||
0x01, 0x0c,
|
||||
0x01, 0x0c,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
{ /* SCALAR_SP_UOP */
|
||||
0x01, 0x0a,
|
||||
0x01, 0x0a,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
@ -242,31 +243,31 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
|
|||
},
|
||||
|
||||
{ /* 64BIT_MMX_UOP */
|
||||
0x01, 0x02,
|
||||
0x01, 0x02,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* 128BIT_MMX_UOP */
|
||||
0x01, 0x1a,
|
||||
0x01, 0x1a,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
{ /* X87_FP_UOP */
|
||||
0x01, 0x04,
|
||||
0x01, 0x04,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* X87_SIMD_MOVES_UOP */
|
||||
0x01, 0x2e,
|
||||
0x01, 0x2e,
|
||||
{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
|
||||
{ CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* MACHINE_CLEAR */
|
||||
0x05, 0x02,
|
||||
0x05, 0x02,
|
||||
{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
|
||||
{ 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_2, MSR_P4_FSB_ESCR1} }
|
||||
},
|
||||
|
||||
|
||||
{ /* TC_MS_XFER */
|
||||
0x00, 0x05,
|
||||
0x00, 0x05,
|
||||
{ { CTR_MS_0, MSR_P4_MS_ESCR0},
|
||||
{ CTR_MS_2, MSR_P4_MS_ESCR1} }
|
||||
},
|
||||
|
@ -308,7 +309,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
|
|||
},
|
||||
|
||||
{ /* INSTR_RETIRED */
|
||||
0x04, 0x02,
|
||||
0x04, 0x02,
|
||||
{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
|
||||
{ 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} }
|
||||
},
|
||||
|
||||
{ /* UOP_TYPE */
|
||||
0x02, 0x02,
|
||||
{ /* UOP_TYPE */
|
||||
0x02, 0x02,
|
||||
{ { CTR_IQ_4, MSR_P4_RAT_ESCR0},
|
||||
{ CTR_IQ_5, MSR_P4_RAT_ESCR1} }
|
||||
},
|
||||
|
||||
{ /* RETIRED_MISPRED_BRANCH_TYPE */
|
||||
0x02, 0x05,
|
||||
0x02, 0x05,
|
||||
{ { CTR_MS_0, MSR_P4_TBPU_ESCR0},
|
||||
{ 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_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
|
||||
#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_WRITE(escr,high,ev,i) do {wrmsr(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 CCCR_RESERVED_BITS 0x38030FFF
|
||||
#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_ENABLE(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_WRITE(low, high, i) do {wrmsr(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_OVF_P(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 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_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (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_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_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
|
||||
|
||||
|
||||
|
@ -380,7 +381,7 @@ static unsigned int get_stagger(void)
|
|||
#ifdef CONFIG_SMP
|
||||
int cpu = smp_processor_id();
|
||||
return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
|
||||
#endif
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
unsigned int addr, cccraddr, stag;
|
||||
|
||||
setup_num_counters();
|
||||
stag = get_stagger();
|
||||
|
||||
/* initialize some registers */
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
for (i = 0; i < num_counters; ++i)
|
||||
msrs->counters[i].addr = 0;
|
||||
}
|
||||
for (i = 0; i < num_controls; ++i) {
|
||||
for (i = 0; i < num_controls; ++i)
|
||||
msrs->controls[i].addr = 0;
|
||||
}
|
||||
|
||||
|
||||
/* the counter & cccr registers we pay attention to */
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
addr = p4_counters[VIRT_CTR(stag, i)].counter_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->controls[i].addr = cccraddr;
|
||||
}
|
||||
|
@ -447,22 +446,22 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
|
|||
if (reserve_evntsel_nmi(addr))
|
||||
msrs->controls[i].addr = addr;
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
msrs->controls[i].addr = addr;
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
msrs->controls[i].addr = addr;
|
||||
}
|
||||
|
||||
/* 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*/
|
||||
if (reserve_evntsel_nmi(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;
|
||||
|
||||
stag = get_stagger();
|
||||
|
||||
|
||||
/* convert from counter *number* to counter *bit* */
|
||||
counter_bit = 1 << VIRT_CTR(stag, ctr);
|
||||
|
||||
|
||||
/* find our event binding structure. */
|
||||
if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) {
|
||||
printk(KERN_ERR
|
||||
"oprofile: P4 event code 0x%lx out of range\n",
|
||||
printk(KERN_ERR
|
||||
"oprofile: P4 event code 0x%lx out of range\n",
|
||||
counter_config[ctr].event);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ev = &(p4_events[counter_config[ctr].event - 1]);
|
||||
|
||||
|
||||
for (i = 0; i < maxbind; i++) {
|
||||
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_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);
|
||||
|
||||
|
||||
/* modify CCCR */
|
||||
CCCR_READ(cccr, high, VIRT_CTR(stag, ctr));
|
||||
CCCR_CLEAR(cccr);
|
||||
CCCR_SET_REQUIRED_BITS(cccr);
|
||||
CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
|
||||
if (stag == 0) {
|
||||
if (stag == 0)
|
||||
CCCR_SET_PMI_OVF_0(cccr);
|
||||
} else {
|
||||
else
|
||||
CCCR_SET_PMI_OVF_1(cccr);
|
||||
}
|
||||
CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_ERR
|
||||
printk(KERN_ERR
|
||||
"oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n",
|
||||
counter_config[ctr].event, stag, ctr);
|
||||
}
|
||||
|
@ -559,14 +557,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
|
|||
stag = get_stagger();
|
||||
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
/* clear the cccrs we will use */
|
||||
for (i = 0 ; i < num_counters ; i++) {
|
||||
if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
|
||||
if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
|
||||
continue;
|
||||
rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
|
||||
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) */
|
||||
for (i = num_counters; i < num_controls; i++) {
|
||||
if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
|
||||
if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
|
||||
continue;
|
||||
wrmsr(msrs->controls[i].addr, 0, 0);
|
||||
}
|
||||
|
||||
/* setup all counters */
|
||||
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;
|
||||
pmc_setup_one_p4_counter(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();
|
||||
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
|
||||
if (!reset_value[i])
|
||||
|
||||
if (!reset_value[i])
|
||||
continue;
|
||||
|
||||
/*
|
||||
/*
|
||||
* there is some eccentricity in the hardware which
|
||||
* 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
|
||||
* updated properly.
|
||||
*
|
||||
*
|
||||
* the former seems to be related to extra NMIs happening
|
||||
* during the current NMI; the latter is reported as errata
|
||||
* N15 in intel doc 249199-029, pentium 4 specification
|
||||
* update, though their suggested work-around does not
|
||||
* appear to solve the problem.
|
||||
*/
|
||||
|
||||
|
||||
real = VIRT_CTR(stag, i);
|
||||
|
||||
CCCR_READ(low, high, real);
|
||||
CTR_READ(ctr, high, real);
|
||||
CTR_READ(ctr, high, real);
|
||||
if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
|
||||
oprofile_add_sample(regs, i);
|
||||
CTR_WRITE(reset_value[i], real);
|
||||
CTR_WRITE(reset_value[i], real);
|
||||
CCCR_CLEAR_OVF(low);
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
/* 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).
|
||||
* This saves a few bits.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -580,7 +580,7 @@ static int __cpuinit amd_cpu_notify(struct notifier_block *self,
|
|||
unsigned long action, void *hcpu)
|
||||
{
|
||||
int cpu = (long)hcpu;
|
||||
switch(action) {
|
||||
switch (action) {
|
||||
case CPU_ONLINE:
|
||||
case CPU_ONLINE_FROZEN:
|
||||
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) {
|
||||
int irq;
|
||||
|
||||
if (pin) {
|
||||
/*
|
||||
* 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;
|
||||
if (!pin)
|
||||
continue;
|
||||
|
||||
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
|
||||
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
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
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
.text
|
||||
|
||||
/*
|
||||
* This may not use any stack, nor any variable that is not "NoSave":
|
||||
*
|
||||
|
@ -12,17 +10,18 @@
|
|||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/processor-flags.h>
|
||||
|
||||
.text
|
||||
.text
|
||||
|
||||
ENTRY(swsusp_arch_suspend)
|
||||
|
||||
movl %esp, saved_context_esp
|
||||
movl %ebx, saved_context_ebx
|
||||
movl %ebp, saved_context_ebp
|
||||
movl %esi, saved_context_esi
|
||||
movl %edi, saved_context_edi
|
||||
pushfl ; popl saved_context_eflags
|
||||
pushfl
|
||||
popl saved_context_eflags
|
||||
|
||||
call swsusp_save
|
||||
ret
|
||||
|
@ -59,7 +58,7 @@ done:
|
|||
movl mmu_cr4_features, %ecx
|
||||
jecxz 1f # cr4 Pentium and higher, skip if zero
|
||||
movl %ecx, %edx
|
||||
andl $~(1<<7), %edx; # PGE
|
||||
andl $~(X86_CR4_PGE), %edx
|
||||
movl %edx, %cr4; # turn off PGE
|
||||
1:
|
||||
movl %cr3, %eax; # flush TLB
|
||||
|
@ -74,7 +73,8 @@ done:
|
|||
movl saved_context_esi, %esi
|
||||
movl saved_context_edi, %edi
|
||||
|
||||
pushl saved_context_eflags ; popfl
|
||||
pushl saved_context_eflags
|
||||
popfl
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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)));
|
||||
}
|
||||
|
@ -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
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
static void xen_release_pmd(u32 pfn)
|
||||
static void xen_release_pmd(unsigned long pfn)
|
||||
{
|
||||
xen_release_ptpage(pfn, PT_PMD);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
static void xen_release_pud(u32 pfn)
|
||||
static void xen_release_pud(unsigned long pfn)
|
||||
{
|
||||
xen_release_ptpage(pfn, PT_PUD);
|
||||
}
|
||||
|
|
|
@ -81,9 +81,7 @@ extern int get_physical_broadcast(void);
|
|||
static inline void ack_APIC_irq(void)
|
||||
{
|
||||
/*
|
||||
* 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)
|
||||
* ack_APIC_irq() actually gets compiled as a single instruction
|
||||
* ... yummie.
|
||||
*/
|
||||
|
||||
|
|
|
@ -20,17 +20,22 @@
|
|||
|
||||
#define _ASM_PTR __ASM_SEL(.long, .quad)
|
||||
#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_DEC __ASM_SIZE(dec)
|
||||
#define _ASM_ADD __ASM_SIZE(add)
|
||||
#define _ASM_SUB __ASM_SIZE(sub)
|
||||
#define _ASM_XADD __ASM_SIZE(xadd)
|
||||
|
||||
#define _ASM_AX __ASM_REG(ax)
|
||||
#define _ASM_BX __ASM_REG(bx)
|
||||
#define _ASM_CX __ASM_REG(cx)
|
||||
#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 */
|
||||
# define _ASM_EXTABLE(from,to) \
|
||||
|
|
|
@ -148,8 +148,9 @@ do { \
|
|||
|
||||
static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
|
||||
{
|
||||
asm volatile("movl %0,%%fs" :: "r" (0));
|
||||
asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS));
|
||||
loadsegment(fs, 0);
|
||||
loadsegment(ds, __USER32_DS);
|
||||
loadsegment(es, __USER32_DS);
|
||||
load_gs_index(0);
|
||||
regs->ip = ip;
|
||||
regs->sp = sp;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
asm volatile("1:\tmovl %2, %0\n" \
|
||||
"\tmovl\t%0, %3\n" \
|
||||
"\t" insn "\n" \
|
||||
"2:\tlock; cmpxchgl %3, %2\n" \
|
||||
"2:\t" LOCK_PREFIX "cmpxchgl %3, %2\n" \
|
||||
"\tjnz\t1b\n" \
|
||||
"3:\t.section .fixup,\"ax\"\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);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
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)))
|
||||
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"
|
||||
"3:\tmov %2, %0\n"
|
||||
"\tjmp 2b\n"
|
||||
|
|
|
@ -52,15 +52,15 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
|
|||
return 0;
|
||||
|
||||
if (aper_base + aper_size > 0x100000000ULL) {
|
||||
printk(KERN_ERR "Aperture beyond 4GB. Ignoring.\n");
|
||||
printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef 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 void rdc_gpio_set_value(unsigned gpio, int value);
|
||||
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)
|
||||
{
|
||||
might_sleep();
|
||||
rdc_gpio_free(gpio);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,14 +7,9 @@
|
|||
/*
|
||||
* The x86 doesn't have a mmu context, but
|
||||
* we put the segment information here.
|
||||
*
|
||||
* cpu_vm_mask is used to optimize ldt flushing.
|
||||
*/
|
||||
typedef struct {
|
||||
void *ldt;
|
||||
#ifdef CONFIG_X86_64
|
||||
rwlock_t ldtlock;
|
||||
#endif
|
||||
int size;
|
||||
struct mutex lock;
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
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) \
|
||||
((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 enable_timer_nmi_watchdog(void);
|
||||
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 unsigned int nmi_watchdog;
|
||||
|
|
|
@ -89,9 +89,6 @@ extern int nx_enabled;
|
|||
extern unsigned int __VMALLOC_RESERVE;
|
||||
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 unsigned long init_memory_mapping(unsigned long start,
|
||||
unsigned long end);
|
||||
|
|
|
@ -137,6 +137,7 @@ struct pv_cpu_ops {
|
|||
|
||||
/* MSR, PMC and TSR operations.
|
||||
err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
|
||||
u64 (*read_msr_amd)(unsigned int msr, int *err);
|
||||
u64 (*read_msr)(unsigned int msr, int *err);
|
||||
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
|
||||
* attached to a pagetable
|
||||
*/
|
||||
void (*alloc_pte)(struct mm_struct *mm, u32 pfn);
|
||||
void (*alloc_pmd)(struct mm_struct *mm, u32 pfn);
|
||||
void (*alloc_pmd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count);
|
||||
void (*alloc_pud)(struct mm_struct *mm, u32 pfn);
|
||||
void (*release_pte)(u32 pfn);
|
||||
void (*release_pmd)(u32 pfn);
|
||||
void (*release_pud)(u32 pfn);
|
||||
void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
|
||||
void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
|
||||
void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
|
||||
void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
|
||||
void (*release_pte)(unsigned long pfn);
|
||||
void (*release_pmd)(unsigned long pfn);
|
||||
void (*release_pud)(unsigned long pfn);
|
||||
|
||||
/* Pagetable manipulation functions */
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static inline void paravirt_alloc_pmd_clone(unsigned pfn, unsigned clonepfn,
|
||||
unsigned start, unsigned count)
|
||||
static inline void paravirt_alloc_pmd_clone(unsigned long pfn, unsigned long clonepfn,
|
||||
unsigned long start, unsigned long 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
#endif
|
||||
|
||||
#define pte_page(x) pfn_to_page(pte_pfn(x))
|
||||
#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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
#define pte_page(x) pfn_to_page(pte_pfn(x))
|
||||
|
||||
static inline int pte_none(pte_t pte)
|
||||
{
|
||||
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,
|
||||
* 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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. ;)
|
||||
*/
|
||||
#define VMALLOC_OFFSET (8 * 1024 * 1024)
|
||||
#define VMALLOC_START (((unsigned long)high_memory + 2 * VMALLOC_OFFSET - 1) \
|
||||
& ~(VMALLOC_OFFSET - 1))
|
||||
#define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET)
|
||||
#ifdef CONFIG_X86_PAE
|
||||
#define LAST_PKMAP 512
|
||||
#else
|
||||
|
@ -74,6 +73,8 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
|
|||
# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
|
||||
#endif
|
||||
|
||||
#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
|
||||
|
||||
/*
|
||||
* Define this if things work differently on an i386 and an i486:
|
||||
* 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 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".
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
do { \
|
||||
if (pm_trace_enabled) { \
|
||||
const void *tracedata; \
|
||||
asm volatile(_ASM_MOV_UL " $1f,%0\n" \
|
||||
asm volatile(_ASM_MOV " $1f,%0\n" \
|
||||
".section .tracedata,\"a\"\n" \
|
||||
"1:\t.word %c1\n\t" \
|
||||
_ASM_PTR " %c2\n" \
|
||||
|
|
|
@ -97,7 +97,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
|
|||
"jne 1f\n\t"
|
||||
"movw %w0,%w1\n\t"
|
||||
"incb %h1\n\t"
|
||||
"lock ; cmpxchgw %w1,%2\n\t"
|
||||
LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
|
||||
"1:"
|
||||
"sete %b1\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 tmp;
|
||||
|
||||
asm volatile("lock ; xaddl %0, %1\n"
|
||||
asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
|
||||
"movzwl %w0, %2\n\t"
|
||||
"shrl $16, %0\n\t"
|
||||
"1:\t"
|
||||
|
@ -162,7 +162,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
|
|||
"cmpl %0,%1\n\t"
|
||||
"jne 1f\n\t"
|
||||
"addl $0x00010000, %1\n\t"
|
||||
"lock ; cmpxchgl %1,%2\n\t"
|
||||
LOCK_PREFIX "cmpxchgl %1,%2\n\t"
|
||||
"1:"
|
||||
"sete %b1\n\t"
|
||||
"movzbl %b1,%0\n\t"
|
||||
|
|
Loading…
Reference in New Issue