Commit be6a14aa authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86-64 update

Add accumulated bug fixes for x86-64 and some minor cleanups.

 - Add ptep_set_access_flags from i386
 - Change memory text mapping to 10MB from 40MB to make alias window
   smaller
 - Disable change_page_attr for kernel mapoing for now (wrong, but the
   other code also doesn't work)
 - Add .bss.page_aligned and align interrupt/exception stacks (idea from
   Matt Mackall)
 - Protect sysenter MSR setup against missing registers. 
 - Set mce tolerance level to 1 (panic instead of deadlock)
 - Fix cross 4GB bug in find_first_bit (Michael Matz)
 - Add missing memory clobbers in bitops.h (Suresh B.  Siddha)
 - Check kernel size at boot up
 - Set boot cpu online at boot to fix early printk
 - Fix EFER bit definitions (Dave Jones)
 - Fix comments in 32bit syscall table.
 - Quieten all 32bit syscalls that are unimplemented in 32bit. 
 - Various MCE fixes suggested by Eric Morton, David Boles et.al.
   More to come.
 - Quieten some printks
 - Fix cpu online check in msr driver
 - Lower polling interval for machine checks to 5 minutes to avoid
   overrunning the registers. 
 - Make memcpy_{from,to}io more compatible with i386 (Roland Dreier)
parent 95d9dbbd
...@@ -306,7 +306,6 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs regs) ...@@ -306,7 +306,6 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
{ {
struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4); struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
sigset_t set; sigset_t set;
stack_t st;
unsigned int eax; unsigned int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
...@@ -323,8 +322,8 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs regs) ...@@ -323,8 +322,8 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
if (ia32_restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax)) if (ia32_restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax))
goto badframe; goto badframe;
if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, regs) == -EFAULT) if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, regs) == -EFAULT)
goto badframe; goto badframe;
return eax; return eax;
......
...@@ -322,7 +322,7 @@ ia32_sys_call_table: ...@@ -322,7 +322,7 @@ ia32_sys_call_table:
.quad sys_mknod .quad sys_mknod
.quad sys_chmod /* 15 */ .quad sys_chmod /* 15 */
.quad sys_lchown16 .quad sys_lchown16
.quad ni_syscall /* old break syscall holder */ .quad quiet_ni_syscall /* old break syscall holder */
.quad sys_stat .quad sys_stat
.quad sys32_lseek .quad sys32_lseek
.quad sys_getpid /* 20 */ .quad sys_getpid /* 20 */
...@@ -336,11 +336,11 @@ ia32_sys_call_table: ...@@ -336,11 +336,11 @@ ia32_sys_call_table:
.quad sys_fstat /* (old)fstat */ .quad sys_fstat /* (old)fstat */
.quad sys_pause .quad sys_pause
.quad compat_sys_utime /* 30 */ .quad compat_sys_utime /* 30 */
.quad ni_syscall /* old stty syscall holder */ .quad quiet_ni_syscall /* old stty syscall holder */
.quad ni_syscall /* old gtty syscall holder */ .quad quiet_ni_syscall /* old gtty syscall holder */
.quad sys_access .quad sys_access
.quad sys_nice .quad sys_nice
.quad ni_syscall /* 35 */ /* old ftime syscall holder */ .quad quiet_ni_syscall /* 35 */ /* old ftime syscall holder */
.quad sys_sync .quad sys_sync
.quad sys32_kill .quad sys32_kill
.quad sys_rename .quad sys_rename
...@@ -349,7 +349,7 @@ ia32_sys_call_table: ...@@ -349,7 +349,7 @@ ia32_sys_call_table:
.quad sys_dup .quad sys_dup
.quad sys32_pipe .quad sys32_pipe
.quad compat_sys_times .quad compat_sys_times
.quad ni_syscall /* old prof syscall holder */ .quad quiet_ni_syscall /* old prof syscall holder */
.quad sys_brk /* 45 */ .quad sys_brk /* 45 */
.quad sys_setgid16 .quad sys_setgid16
.quad sys_getgid16 .quad sys_getgid16
...@@ -358,12 +358,12 @@ ia32_sys_call_table: ...@@ -358,12 +358,12 @@ ia32_sys_call_table:
.quad sys_getegid16 /* 50 */ .quad sys_getegid16 /* 50 */
.quad sys_acct .quad sys_acct
.quad sys_umount /* new_umount */ .quad sys_umount /* new_umount */
.quad ni_syscall /* old lock syscall holder */ .quad quiet_ni_syscall /* old lock syscall holder */
.quad compat_sys_ioctl .quad compat_sys_ioctl
.quad compat_sys_fcntl64 /* 55 */ .quad compat_sys_fcntl64 /* 55 */
.quad ni_syscall /* old mpx syscall holder */ .quad quiet_ni_syscall /* old mpx syscall holder */
.quad sys_setpgid .quad sys_setpgid
.quad ni_syscall /* old ulimit syscall holder */ .quad quiet_ni_syscall /* old ulimit syscall holder */
.quad sys32_olduname .quad sys32_olduname
.quad sys_umask /* 60 */ .quad sys_umask /* 60 */
.quad sys_chroot .quad sys_chroot
...@@ -403,7 +403,7 @@ ia32_sys_call_table: ...@@ -403,7 +403,7 @@ ia32_sys_call_table:
.quad sys_fchown16 /* 95 */ .quad sys_fchown16 /* 95 */
.quad sys_getpriority .quad sys_getpriority
.quad sys_setpriority .quad sys_setpriority
.quad ni_syscall /* old profil syscall holder */ .quad quiet_ni_syscall /* old profil syscall holder */
.quad compat_sys_statfs .quad compat_sys_statfs
.quad compat_sys_fstatfs /* 100 */ .quad compat_sys_fstatfs /* 100 */
.quad sys_ioperm .quad sys_ioperm
...@@ -417,7 +417,7 @@ ia32_sys_call_table: ...@@ -417,7 +417,7 @@ ia32_sys_call_table:
.quad sys32_uname .quad sys32_uname
.quad stub32_iopl /* 110 */ .quad stub32_iopl /* 110 */
.quad sys_vhangup .quad sys_vhangup
.quad ni_syscall /* old "idle" system call */ .quad quiet_ni_syscall /* old "idle" system call */
.quad sys32_vm86_warning /* vm86old */ .quad sys32_vm86_warning /* vm86old */
.quad compat_sys_wait4 .quad compat_sys_wait4
.quad sys_swapoff /* 115 */ .quad sys_swapoff /* 115 */
...@@ -442,7 +442,7 @@ ia32_sys_call_table: ...@@ -442,7 +442,7 @@ ia32_sys_call_table:
.quad quiet_ni_syscall /* bdflush */ .quad quiet_ni_syscall /* bdflush */
.quad sys_sysfs /* 135 */ .quad sys_sysfs /* 135 */
.quad sys_personality .quad sys_personality
.quad ni_syscall /* for afs_syscall */ .quad quiet_ni_syscall /* for afs_syscall */
.quad sys_setfsuid16 .quad sys_setfsuid16
.quad sys_setfsgid16 .quad sys_setfsgid16
.quad sys_llseek /* 140 */ .quad sys_llseek /* 140 */
...@@ -493,8 +493,8 @@ ia32_sys_call_table: ...@@ -493,8 +493,8 @@ ia32_sys_call_table:
.quad sys_capset .quad sys_capset
.quad stub32_sigaltstack .quad stub32_sigaltstack
.quad sys32_sendfile .quad sys32_sendfile
.quad ni_syscall /* streams1 */ .quad quiet_ni_syscall /* streams1 */
.quad ni_syscall /* streams2 */ .quad quiet_ni_syscall /* streams2 */
.quad stub32_vfork /* 190 */ .quad stub32_vfork /* 190 */
.quad compat_sys_getrlimit .quad compat_sys_getrlimit
.quad sys32_mmap2 .quad sys32_mmap2
...@@ -543,51 +543,52 @@ ia32_sys_call_table: ...@@ -543,51 +543,52 @@ ia32_sys_call_table:
.quad sys_removexattr /* 235 */ .quad sys_removexattr /* 235 */
.quad sys_lremovexattr .quad sys_lremovexattr
.quad sys_fremovexattr .quad sys_fremovexattr
.quad sys_tkill /* 238 */ .quad sys_tkill
.quad sys_sendfile64 .quad sys_sendfile64
.quad compat_sys_futex /* 240 */ .quad compat_sys_futex /* 240 */
.quad compat_sys_sched_setaffinity .quad compat_sys_sched_setaffinity
.quad compat_sys_sched_getaffinity .quad compat_sys_sched_getaffinity
.quad sys32_set_thread_area .quad sys32_set_thread_area
.quad sys32_get_thread_area .quad sys32_get_thread_area
.quad sys32_io_setup .quad sys32_io_setup /* 245 */
.quad sys_io_destroy .quad sys_io_destroy
.quad sys32_io_getevents .quad sys32_io_getevents
.quad sys32_io_submit .quad sys32_io_submit
.quad sys_io_cancel .quad sys_io_cancel
.quad sys_fadvise64 .quad sys_fadvise64 /* 250 */
.quad quiet_ni_syscall /* free_huge_pages */ .quad quiet_ni_syscall /* free_huge_pages */
.quad sys_exit_group /* exit_group */ .quad sys_exit_group
.quad sys_lookup_dcookie .quad sys_lookup_dcookie
.quad sys_epoll_create .quad sys_epoll_create
.quad sys_epoll_ctl .quad sys_epoll_ctl /* 255 */
.quad sys_epoll_wait .quad sys_epoll_wait
.quad sys_remap_file_pages .quad sys_remap_file_pages
.quad sys_set_tid_address .quad sys_set_tid_address
.quad sys32_timer_create .quad sys32_timer_create
.quad compat_timer_settime .quad compat_timer_settime /* 260 */
.quad compat_timer_gettime .quad compat_timer_gettime
.quad sys_timer_getoverrun .quad sys_timer_getoverrun
.quad sys_timer_delete .quad sys_timer_delete
.quad compat_clock_settime .quad compat_clock_settime
.quad compat_clock_gettime .quad compat_clock_gettime /* 265 */
.quad compat_clock_getres .quad compat_clock_getres
.quad compat_clock_nanosleep .quad compat_clock_nanosleep
.quad compat_statfs64 /* statfs64 */ .quad compat_statfs64
.quad compat_fstatfs64 /* fstatfs64 */ .quad compat_fstatfs64
.quad sys_tgkill .quad sys_tgkill /* 270 */
.quad compat_sys_utimes .quad compat_sys_utimes
.quad sys32_fadvise64_64 .quad sys32_fadvise64_64
.quad sys_ni_syscall /* sys_vserver */ .quad quiet_ni_syscall /* sys_vserver */
.quad sys_ni_syscall /* sys_mbind */ .quad sys_mbind
.quad sys_ni_syscall /* 275 sys_get_mempolicy */ .quad compat_get_mempolicy /* 275 */
.quad sys_ni_syscall /* sys_set_mempolicy */ .quad sys_set_mempolicy
.quad compat_sys_mq_open .quad compat_sys_mq_open
.quad sys_mq_unlink .quad sys_mq_unlink
.quad compat_sys_mq_timedsend .quad compat_sys_mq_timedsend
.quad compat_sys_mq_timedreceive /* 280 */ .quad compat_sys_mq_timedreceive /* 280 */
.quad compat_sys_mq_notify .quad compat_sys_mq_notify
.quad compat_sys_mq_getsetattr .quad compat_sys_mq_getsetattr
.quad quiet_ni_syscall /* reserved for kexec */
/* don't forget to change IA32_NR_syscalls */ /* don't forget to change IA32_NR_syscalls */
ia32_syscall_end: ia32_syscall_end:
.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
......
...@@ -83,9 +83,9 @@ void __init syscall32_cpu_init(void) ...@@ -83,9 +83,9 @@ void __init syscall32_cpu_init(void)
/* Load these always in case some future AMD CPU supports /* Load these always in case some future AMD CPU supports
SYSENTER from compat mode too. */ SYSENTER from compat mode too. */
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
wrmsr(MSR_IA32_SYSENTER_ESP, 0, 0); checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
wrmsrl(MSR_IA32_SYSENTER_EIP, ia32_sysenter_target); checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
wrmsrl(MSR_CSTAR, ia32_cstar_target); wrmsrl(MSR_CSTAR, ia32_cstar_target);
} }
#
# Makefile for the linux kernel.
#
extra-y := head.o head64.o init_task.o vmlinux.lds.s
EXTRA_AFLAGS := -traditional
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
x8664_ksyms.o i387.o syscall.o vsyscall.o \
setup64.o bootflag.o e820.o reboot.o warmreboot.o
obj-y += mce.o
obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/
obj-$(CONFIG_ACPI_BOOT) += acpi/
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o
obj-$(CONFIG_PM) += suspend.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
obj-$(CONFIG_SWIOTLB) += swiotlb.o
obj-$(CONFIG_SCHED_SMT) += domain.o
obj-$(CONFIG_MODULES) += module.o
obj-y += topology.o
bootflag-y += ../../i386/kernel/bootflag.o
cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
topology-y += ../../i386/mach-default/topology.o
swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o
microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
...@@ -114,7 +114,7 @@ void __init acpi_reserve_bootmem(void) ...@@ -114,7 +114,7 @@ void __init acpi_reserve_bootmem(void)
acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); Dprintk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
} }
static int __init acpi_sleep_setup(char *str) static int __init acpi_sleep_setup(char *str)
......
...@@ -255,7 +255,7 @@ temp_boot_pmds: ...@@ -255,7 +255,7 @@ temp_boot_pmds:
.org 0x5000 .org 0x5000
ENTRY(level2_kernel_pgt) ENTRY(level2_kernel_pgt)
/* 40MB kernel mapping. The kernel code cannot be bigger than that. /* 10MB kernel mapping. The kernel code cannot be bigger than that.
When you change this change KERNEL_TEXT_SIZE in page.h too. */ When you change this change KERNEL_TEXT_SIZE in page.h too. */
/* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */
.quad 0x0000000000000183 .quad 0x0000000000000183
...@@ -263,21 +263,8 @@ ENTRY(level2_kernel_pgt) ...@@ -263,21 +263,8 @@ ENTRY(level2_kernel_pgt)
.quad 0x0000000000400183 .quad 0x0000000000400183
.quad 0x0000000000600183 .quad 0x0000000000600183
.quad 0x0000000000800183 .quad 0x0000000000800183
.quad 0x0000000000A00183 /* 10MB mapping for now to decrease the aliasing window */
.quad 0x0000000000C00183 .fill 15,8,0
.quad 0x0000000000E00183
.quad 0x0000000001000183
.quad 0x0000000001200183
.quad 0x0000000001400183
.quad 0x0000000001600183
.quad 0x0000000001800183
.quad 0x0000000001A00183
.quad 0x0000000001C00183
.quad 0x0000000001E00183
.quad 0x0000000002000183
.quad 0x0000000002200183
.quad 0x0000000002400183
.quad 0x0000000002600183
/* Module mapping starts here */ /* Module mapping starts here */
.fill 492,8,0 .fill 492,8,0
......
...@@ -73,6 +73,8 @@ static void __init setup_boot_cpu_data(void) ...@@ -73,6 +73,8 @@ static void __init setup_boot_cpu_data(void)
boot_cpu_data.x86_mask = eax & 0xf; boot_cpu_data.x86_mask = eax & 0xf;
} }
extern char _end[];
void __init x86_64_start_kernel(char * real_mode_data) void __init x86_64_start_kernel(char * real_mode_data)
{ {
char *s; char *s;
...@@ -80,6 +82,9 @@ void __init x86_64_start_kernel(char * real_mode_data) ...@@ -80,6 +82,9 @@ void __init x86_64_start_kernel(char * real_mode_data)
clear_bss(); clear_bss();
pda_init(0); pda_init(0);
copy_bootdata(real_mode_data); copy_bootdata(real_mode_data);
#ifdef CONFIG_SMP
cpu_set(0, cpu_online_map);
#endif
/* default console: */ /* default console: */
if (!strstr(saved_command_line, "console=")) if (!strstr(saved_command_line, "console="))
strcat(saved_command_line, " console=tty0"); strcat(saved_command_line, " console=tty0");
...@@ -95,6 +100,10 @@ void __init x86_64_start_kernel(char * real_mode_data) ...@@ -95,6 +100,10 @@ void __init x86_64_start_kernel(char * real_mode_data)
if (strstr(saved_command_line, "disableapic")) if (strstr(saved_command_line, "disableapic"))
disable_apic = 1; disable_apic = 1;
#endif #endif
/* You need early console to see that */
if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
panic("Kernel too big for kernel mapping\n");
setup_boot_cpu_data(); setup_boot_cpu_data();
start_kernel(); start_kernel();
} }
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
static int mce_disabled __initdata; static int mce_disabled __initdata;
/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic */ /* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic */
static int tolerant = 2; static int tolerant = 1;
static int banks; static int banks;
static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
...@@ -96,7 +96,8 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start) ...@@ -96,7 +96,8 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start)
int i; int i;
oops_begin(); oops_begin();
for (i = 0; i < MCE_LOG_LEN; i++) { for (i = 0; i < MCE_LOG_LEN; i++) {
if (mcelog.entry[i].tsc < start) unsigned long tsc = mcelog.entry[i].tsc;
if (time_before(tsc, start))
continue; continue;
print_mce(&mcelog.entry[i]); print_mce(&mcelog.entry[i]);
if (mcelog.entry[i].tsc == backup->tsc) if (mcelog.entry[i].tsc == backup->tsc)
...@@ -120,8 +121,8 @@ static int mce_available(struct cpuinfo_x86 *c) ...@@ -120,8 +121,8 @@ static int mce_available(struct cpuinfo_x86 *c)
void do_machine_check(struct pt_regs * regs, long error_code) void do_machine_check(struct pt_regs * regs, long error_code)
{ {
struct mce m; struct mce m, panicm;
int nowayout = 0; int nowayout = (tolerant < 1);
int kill_it = 0; int kill_it = 0;
u64 mcestart; u64 mcestart;
int i; int i;
...@@ -149,12 +150,23 @@ void do_machine_check(struct pt_regs * regs, long error_code) ...@@ -149,12 +150,23 @@ void do_machine_check(struct pt_regs * regs, long error_code)
for (i = 0; i < banks; i++) { for (i = 0; i < banks; i++) {
if (!bank[i]) if (!bank[i])
continue; continue;
/* Did this bank cause the exception? */
/* XXX: check more flags */
if ((m.status & MCI_STATUS_PCC)) {
panicm = m;
} else {
m.rip = 0;
m.cs = 0;
}
m.misc = 0;
m.addr = 0;
rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status);
if ((m.status & MCI_STATUS_VAL) == 0) if ((m.status & MCI_STATUS_VAL) == 0)
continue; continue;
nowayout |= (tolerant < 1);
nowayout |= !!(m.status & (MCI_STATUS_OVER|MCI_STATUS_PCC)); nowayout |= !!(m.status & (MCI_STATUS_OVER|MCI_STATUS_PCC));
kill_it |= !!(m.status & MCI_STATUS_UC); kill_it |= !!(m.status & MCI_STATUS_UC);
m.bank = i; m.bank = i;
...@@ -176,7 +188,10 @@ void do_machine_check(struct pt_regs * regs, long error_code) ...@@ -176,7 +188,10 @@ void do_machine_check(struct pt_regs * regs, long error_code)
if (nowayout) if (nowayout)
mce_panic("Machine check", &m, mcestart); mce_panic("Machine check", &m, mcestart);
if (kill_it) { if (kill_it) {
int user_space = (m.rip && (m.cs & 3)); int user_space = 0;
if (m.mcgstatus & MCG_STATUS_RIPV)
user_space = m.rip && (m.cs & 3);
/* When the machine was in user space and the CPU didn't get /* When the machine was in user space and the CPU didn't get
confused it's normally not necessary to panic, unless you confused it's normally not necessary to panic, unless you
...@@ -187,7 +202,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) ...@@ -187,7 +202,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
it is best to just halt the machine. */ it is best to just halt the machine. */
if ((!user_space && (panic_on_oops || tolerant < 2)) || if ((!user_space && (panic_on_oops || tolerant < 2)) ||
(unsigned)current->pid <= 1) (unsigned)current->pid <= 1)
mce_panic("Uncorrected machine check", &m, mcestart); mce_panic("Uncorrected machine check", &panicm, mcestart);
/* do_exit takes an awful lot of locks and has as slight risk /* do_exit takes an awful lot of locks and has as slight risk
of deadlocking. If you don't want that don't set tolerant >= 2 */ of deadlocking. If you don't want that don't set tolerant >= 2 */
...@@ -207,7 +222,7 @@ static void mce_clear_all(void) ...@@ -207,7 +222,7 @@ static void mce_clear_all(void)
* Periodic polling timer for "silent" machine check errors. * Periodic polling timer for "silent" machine check errors.
*/ */
static int check_interval = 3600; /* one hour */ static int check_interval = 5 * 60; /* 5 minutes */
static void mcheck_timer(void *data); static void mcheck_timer(void *data);
static DECLARE_WORK(mcheck_work, mcheck_timer, NULL); static DECLARE_WORK(mcheck_work, mcheck_timer, NULL);
......
...@@ -575,6 +575,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) ...@@ -575,6 +575,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
extern void __bad_mpf_size(void); extern void __bad_mpf_size(void);
unsigned int *bp = phys_to_virt(base); unsigned int *bp = phys_to_virt(base);
struct intel_mp_floating *mpf; struct intel_mp_floating *mpf;
static int printed __initdata;
Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length); Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
if (sizeof(*mpf) != 16) if (sizeof(*mpf) != 16)
...@@ -598,7 +599,10 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) ...@@ -598,7 +599,10 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
bp += 4; bp += 4;
length -= 16; length -= 16;
} }
printk(KERN_INFO "No mptable found.\n"); if (!printed) {
printk(KERN_INFO "No mptable found.\n");
printed = 1;
}
return 0; return 0;
} }
......
...@@ -241,7 +241,7 @@ static int msr_open(struct inode *inode, struct file *file) ...@@ -241,7 +241,7 @@ static int msr_open(struct inode *inode, struct file *file)
int cpu = iminor(file->f_dentry->d_inode); int cpu = iminor(file->f_dentry->d_inode);
struct cpuinfo_x86 *c = &(cpu_data)[cpu]; struct cpuinfo_x86 *c = &(cpu_data)[cpu];
if (!cpu_online(cpu)) if (cpu >= NR_CPUS || !cpu_online(cpu))
return -ENXIO; /* No such CPU */ return -ENXIO; /* No such CPU */
if ( !cpu_has(c, X86_FEATURE_MSR) ) if ( !cpu_has(c, X86_FEATURE_MSR) )
return -EIO; /* MSR not supported */ return -EIO; /* MSR not supported */
......
...@@ -909,7 +909,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) ...@@ -909,7 +909,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
c->x86_model += ((tfms >> 16) & 0xF) << 4; c->x86_model += ((tfms >> 16) & 0xF) << 4;
} }
if (c->x86_capability[0] & (1<<19)) if (c->x86_capability[0] & (1<<19))
c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
} else { } else {
/* Have CPUID level 0 only - unheard of */ /* Have CPUID level 0 only - unheard of */
c->x86 = 4; c->x86 = 4;
...@@ -967,7 +967,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) ...@@ -967,7 +967,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
display_cacheinfo(c); display_cacheinfo(c);
break; break;
} }
select_idle_routine(c); select_idle_routine(c);
detect_ht(c); detect_ht(c);
......
...@@ -39,7 +39,7 @@ extern unsigned char __per_cpu_start[], __per_cpu_end[]; ...@@ -39,7 +39,7 @@ extern unsigned char __per_cpu_start[], __per_cpu_end[];
extern struct desc_ptr cpu_gdt_descr[]; extern struct desc_ptr cpu_gdt_descr[];
struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table };
char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned; char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
unsigned long __supported_pte_mask = ~0UL; unsigned long __supported_pte_mask = ~0UL;
static int do_not_nx __initdata = 0; static int do_not_nx __initdata = 0;
...@@ -190,7 +190,8 @@ void pda_init(int cpu) ...@@ -190,7 +190,8 @@ void pda_init(int cpu)
pda->irqstackptr += IRQSTACKSIZE-64; pda->irqstackptr += IRQSTACKSIZE-64;
} }
char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ]; char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ]
__attribute__((section(".bss.page_aligned")));
void __init syscall_init(void) void __init syscall_init(void)
{ {
......
...@@ -895,15 +895,17 @@ static void __init smp_boot_cpus(unsigned int max_cpus) ...@@ -895,15 +895,17 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpu_set(i, cpu_sibling_map[cpu]); cpu_set(i, cpu_sibling_map[cpu]);
} }
} }
} else { } else {
siblings++; siblings++;
cpu_set(cpu, cpu_sibling_map[cpu]); cpu_set(cpu, cpu_sibling_map[cpu]);
} }
if (siblings != smp_num_siblings) if (siblings != smp_num_siblings) {
printk(KERN_WARNING printk(KERN_WARNING
"WARNING: %d siblings found for CPU%d, should be %d\n", "WARNING: %d siblings found for CPU%d, should be %d\n",
siblings, cpu, smp_num_siblings); siblings, cpu, smp_num_siblings);
smp_num_siblings = siblings;
}
} }
Dprintk("Boot done.\n"); Dprintk("Boot done.\n");
......
...@@ -39,6 +39,7 @@ SECTIONS ...@@ -39,6 +39,7 @@ SECTIONS
__bss_start = .; /* BSS */ __bss_start = .; /* BSS */
.bss : { .bss : {
*(.bss.page_aligned)
*(.bss) *(.bss)
} }
__bss_end = .; __bss_end = .;
...@@ -75,8 +76,8 @@ SECTIONS ...@@ -75,8 +76,8 @@ SECTIONS
. = ALIGN(8192); /* init_task */ . = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) } .data.init_task : { *(.data.init_task) }
. = ALIGN(4096); . = ALIGN(4096);
.data.boot_pgt : { *(.data.boot_pgt) } .data.page_aligned : { *(.data.page_aligned) }
. = ALIGN(4096); /* Init code and data */ . = ALIGN(4096); /* Init code and data */
__init_begin = .; __init_begin = .;
......
...@@ -219,6 +219,3 @@ EXPORT_SYMBOL_GPL(flush_tlb_all); ...@@ -219,6 +219,3 @@ EXPORT_SYMBOL_GPL(flush_tlb_all);
#endif #endif
EXPORT_SYMBOL(sys_ioctl); EXPORT_SYMBOL(sys_ioctl);
EXPORT_SYMBOL(memcpy_toio);
EXPORT_SYMBOL(memcpy_fromio);
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
CFLAGS_csum-partial.o := -funroll-loops CFLAGS_csum-partial.o := -funroll-loops
obj-y := io.o
lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
usercopy.o getuser.o putuser.o \ usercopy.o getuser.o putuser.o \
thunk.o io.o clear_page.o copy_page.o bitstr.o thunk.o clear_page.o copy_page.o bitstr.o
lib-y += memcpy.o memmove.o memset.o copy_user.o lib-y += memcpy.o memmove.o memset.o copy_user.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
#include <asm/io.h> #include <asm/io.h>
#include <linux/module.h> #include <linux/module.h>
void *memcpy_toio(void *dst,const void*src,unsigned len) void *__memcpy_toio(unsigned long dst,const void*src,unsigned len)
{ {
return __inline_memcpy(dst,src,len); return __inline_memcpy((void *) dst,src,len);
} }
EXPORT_SYMBOL(__memcpy_toio);
void *memcpy_fromio(void *dst,const void*src,unsigned len) void *__memcpy_fromio(void *dst,unsigned long src,unsigned len)
{ {
return __inline_memcpy(dst,src,len); return __inline_memcpy(dst,(const void *) src,len);
} }
EXPORT_SYMBOL(__memcpy_fromio);
...@@ -512,9 +512,7 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) ...@@ -512,9 +512,7 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
/* Should check here against the e820 map to avoid double free */ /* Should check here against the e820 map to avoid double free */
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
int nid = phys_to_nid(phys); int nid = phys_to_nid(phys);
if (phys < HIGH_MEMORY && nid) reserve_bootmem_node(NODE_DATA(nid), phys, len);
panic("reserve of %lx at node %d", phys, nid);
reserve_bootmem_node(NODE_DATA(nid), phys, len);
#else #else
reserve_bootmem(phys, len); reserve_bootmem(phys, len);
#endif #endif
......
...@@ -96,8 +96,7 @@ static inline void save_page(unsigned long address, struct page *fpage) ...@@ -96,8 +96,7 @@ static inline void save_page(unsigned long address, struct page *fpage)
* No more special protections in this 2/4MB area - revert to a * No more special protections in this 2/4MB area - revert to a
* large page again. * large page again.
*/ */
static void revert_page(struct page *kpte_page, unsigned long address, static void revert_page(unsigned long address, pgprot_t ref_prot)
pgprot_t ref_prot)
{ {
pgd_t *pgd; pgd_t *pgd;
pmd_t *pmd; pmd_t *pmd;
...@@ -145,7 +144,7 @@ __change_page_attr(unsigned long address, struct page *page, pgprot_t prot, ...@@ -145,7 +144,7 @@ __change_page_attr(unsigned long address, struct page *page, pgprot_t prot,
if (page_count(kpte_page) == 1) { if (page_count(kpte_page) == 1) {
save_page(address, kpte_page); save_page(address, kpte_page);
revert_page(kpte_page, address, ref_prot); revert_page(address, ref_prot);
} }
return 0; return 0;
} }
...@@ -176,9 +175,11 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) ...@@ -176,9 +175,11 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot)
break; break;
/* Handle kernel mapping too which aliases part of the /* Handle kernel mapping too which aliases part of the
* lowmem */ * lowmem */
if (page_to_phys(page) < KERNEL_TEXT_SIZE) { /* Disabled right now. Fixme */
if (0 && page_to_phys(page) < KERNEL_TEXT_SIZE) {
unsigned long addr2; unsigned long addr2;
addr2 = __START_KERNEL_map + page_to_phys(page); addr2 = __START_KERNEL_map + page_to_phys(page);
__pgprot(prot) &= ~_PAGE_NX;
err = __change_page_attr(addr2, page, prot, err = __change_page_attr(addr2, page, prot,
PAGE_KERNEL_EXECUTABLE); PAGE_KERNEL_EXECUTABLE);
} }
......
...@@ -337,16 +337,15 @@ static __inline__ int find_first_bit(const unsigned long * addr, unsigned size) ...@@ -337,16 +337,15 @@ static __inline__ int find_first_bit(const unsigned long * addr, unsigned size)
"repe; scasl\n\t" "repe; scasl\n\t"
"jz 1f\n\t" "jz 1f\n\t"
"leaq -4(%%rdi),%%rdi\n\t" "leaq -4(%%rdi),%%rdi\n\t"
"bsfq (%%rdi),%%rax\n" "bsfl (%%rdi),%%eax\n"
"1:\tsubl %%ebx,%%edi\n\t" "1:\tsubq %%rbx,%%rdi\n\t"
"shll $3,%%edi\n\t" "shll $3,%%edi\n\t"
"addl %%edi,%%eax" "addl %%edi,%%eax"
:"=a" (res), "=&c" (d0), "=&D" (d1) :"=a" (res), "=&c" (d0), "=&D" (d1)
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
return res; return res;
} }
/** /**
* find_next_bit - find the first set bit in a memory region * find_next_bit - find the first set bit in a memory region
* @addr: The address to base the search on * @addr: The address to base the search on
......
...@@ -288,7 +288,8 @@ ...@@ -288,7 +288,8 @@
#define __NR_ia32_mq_timedreceive (__NR_ia32_mq_open+3) #define __NR_ia32_mq_timedreceive (__NR_ia32_mq_open+3)
#define __NR_ia32_mq_notify (__NR_ia32_mq_open+4) #define __NR_ia32_mq_notify (__NR_ia32_mq_open+4)
#define __NR_ia32_mq_getsetattr (__NR_ia32_mq_open+5) #define __NR_ia32_mq_getsetattr (__NR_ia32_mq_open+5)
#define __NR_ia32_kexec 283
#define IA32_NR_syscalls 285 /* must be > than biggest syscall! */ #define IA32_NR_syscalls 287 /* must be > than biggest syscall! */
#endif /* _ASM_X86_64_IA32_UNISTD_H_ */ #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
...@@ -195,8 +195,13 @@ extern void iounmap(void *addr); ...@@ -195,8 +195,13 @@ extern void iounmap(void *addr);
#define __raw_writel writel #define __raw_writel writel
#define __raw_writeq writeq #define __raw_writeq writeq
void *memcpy_fromio(void*,const void*,unsigned); void *__memcpy_fromio(void*,unsigned long,unsigned);
void *memcpy_toio(void*,const void*,unsigned); void *__memcpy_toio(unsigned long,const void*,unsigned);
#define memcpy_fromio(to,from,len) \
__memcpy_fromio((to),(unsigned long)(from),(len))
#define memcpy_toio(to,from,len) \
__memcpy_toio((unsigned long)(to),(from),(len))
#define memset_io(a,b,c) memset((void *)(a),(b),(c)) #define memset_io(a,b,c) memset((void *)(a),(b),(c))
/* /*
......
...@@ -143,8 +143,8 @@ extern inline unsigned int cpuid_edx(unsigned int op) ...@@ -143,8 +143,8 @@ extern inline unsigned int cpuid_edx(unsigned int op)
#define _EFER_NX 11 /* No execute enable */ #define _EFER_NX 11 /* No execute enable */
#define EFER_SCE (1<<_EFER_SCE) #define EFER_SCE (1<<_EFER_SCE)
#define EFER_LME (1<<EFER_LME) #define EFER_LME (1<<_EFER_LME)
#define EFER_LMA (1<<EFER_LMA) #define EFER_LMA (1<<_EFER_LMA)
#define EFER_NX (1<<_EFER_NX) #define EFER_NX (1<<_EFER_NX)
/* Intel MSRs. Some also available on other CPUs */ /* Intel MSRs. Some also available on other CPUs */
......
...@@ -79,7 +79,7 @@ extern unsigned long vm_force_exec32; ...@@ -79,7 +79,7 @@ extern unsigned long vm_force_exec32;
#define __VIRTUAL_MASK_SHIFT 48 #define __VIRTUAL_MASK_SHIFT 48
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
#define KERNEL_TEXT_SIZE (40UL*1024*1024) #define KERNEL_TEXT_SIZE (10UL*1024*1024)
#define KERNEL_TEXT_START 0xffffffff80000000UL #define KERNEL_TEXT_START 0xffffffff80000000UL
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
...@@ -383,6 +383,20 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ...@@ -383,6 +383,20 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define update_mmu_cache(vma,address,pte) do { } while (0) #define update_mmu_cache(vma,address,pte) do { } while (0)
/* We only update the dirty/accessed state if we set
* the dirty bit by hand in the kernel, since the hardware
* will do the accessed bit for us, and we don't want to
* race with other CPU's that might be updating the dirty
* bit at the same time. */
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
do { \
if (__dirty) { \
set_pte(__ptep, __entry); \
flush_tlb_page(__vma, __address); \
} \
} while (0)
/* Encode and de-code a swap entry */ /* Encode and de-code a swap entry */
#define __swp_type(x) (((x).val >> 1) & 0x3f) #define __swp_type(x) (((x).val >> 1) & 0x3f)
#define __swp_offset(x) ((x).val >> 8) #define __swp_offset(x) ((x).val >> 8)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment