From: Martin Schwidefsky - Add console_unblank in machine_{restart,halt,power_off} to get all messages on the screen. - Set console_irq to -1 if condev= parameter is present. - Fix write_trylock for 64 bit. - Fix svc restarting. - System call number on 64 bit is an int. Fix compare in entry64.S. - Fix tlb flush problem. - Use the idte instruction to flush tlbs of a particular mm. - Fix ptrace. - Add fadvise64_64 system call wrapper. - Fix pfault handling. - Do not clobber _PAGE_INVALID_NONE pages in pte_wrprotect. - Fix siginfo_t size problem (needs to be 128 for s390x, not 136). - Avoid direct assignment to tsk->state, use __set_task_state. - Always make any pending restarted system call return -EINTR. - Add panic_on_oops. - Display symbol for psw address in show_trace. - Don't discard sections .exit.text, .exit.data and .eh_frame, otherwise stabs information for kerntypes will get lost. - Add memory clobber to assembler inline in ip_fast_checksum for gcc 3.3. - Fix softirq_pending calls for the current cpu (cpu == smp_processor_id()). - Remove BUG_ON in irq_enter. Two irq_enters are possible. --- 25-akpm/arch/s390/defconfig | 27 +++++++++++++++++++++--- 25-akpm/arch/s390/kernel/entry.S | 6 +++-- 25-akpm/arch/s390/kernel/entry64.S | 15 ++++++++----- 25-akpm/arch/s390/kernel/head.S | 14 ++++++++++++ 25-akpm/arch/s390/kernel/head64.S | 14 ++++++++++++ 25-akpm/arch/s390/kernel/ptrace.c | 37 ++++++++++++++++++++++++--------- 25-akpm/arch/s390/kernel/semaphore.c | 12 +++++----- 25-akpm/arch/s390/kernel/setup.c | 7 +++++- 25-akpm/arch/s390/kernel/signal.c | 3 ++ 25-akpm/arch/s390/kernel/sys_s390.c | 36 ++++++++++++++++++++++++++++++++ 25-akpm/arch/s390/kernel/syscalls.S | 5 ++-- 25-akpm/arch/s390/kernel/traps.c | 8 ++++++- 25-akpm/arch/s390/kernel/vmlinux.lds.S | 3 -- 25-akpm/arch/s390/mm/fault.c | 34 ++++++++---------------------- 25-akpm/include/asm-s390/bitops.h | 18 ++++++++-------- 25-akpm/include/asm-s390/bug.h | 2 + 25-akpm/include/asm-s390/byteorder.h | 12 +++++----- 25-akpm/include/asm-s390/checksum.h | 8 +++---- 25-akpm/include/asm-s390/hardirq.h | 15 +++++++++---- 25-akpm/include/asm-s390/ioctl.h | 16 +++++++++++--- 25-akpm/include/asm-s390/mmu_context.h | 2 - 25-akpm/include/asm-s390/pgalloc.h | 8 +++++-- 25-akpm/include/asm-s390/pgtable.h | 9 +++++--- 25-akpm/include/asm-s390/scatterlist.h | 6 ++++- 25-akpm/include/asm-s390/setup.h | 1 25-akpm/include/asm-s390/siginfo.h | 6 +++++ 25-akpm/include/asm-s390/spinlock.h | 2 - 25-akpm/include/asm-s390/tlbflush.h | 23 +++++++++++--------- 25-akpm/include/asm-s390/unistd.h | 4 ++- 29 files changed, 251 insertions(+), 102 deletions(-) diff -puN arch/s390/defconfig~s390-01-base arch/s390/defconfig --- 25/arch/s390/defconfig~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/defconfig Thu Jan 8 14:10:58 2004 @@ -29,6 +29,7 @@ CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # # Loadable module support @@ -109,8 +110,8 @@ CONFIG_SCSI_LOGGING=y # # SCSI low-level drivers # -# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_DEBUG is not set CONFIG_ZFCP=y @@ -318,6 +319,21 @@ CONFIG_QETH=y CONFIG_CCWGROUP=y # +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# # File systems # CONFIG_EXT2_FS=y @@ -358,8 +374,7 @@ CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLBFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -385,6 +400,7 @@ CONFIG_RAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y # CONFIG_NFSD_V4 is not set @@ -424,6 +440,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_EFI_PARTITION is not set # +# Native Language Support +# +# CONFIG_NLS is not set + +# # Kernel hacking # CONFIG_DEBUG_KERNEL=y diff -puN arch/s390/kernel/entry64.S~s390-01-base arch/s390/kernel/entry64.S --- 25/arch/s390/kernel/entry64.S~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/entry64.S Thu Jan 8 14:10:58 2004 @@ -169,9 +169,10 @@ system_call: slag %r7,%r7,2 # *4 and test for svc 0 jnz sysc_do_restart # svc 0: system call number in %r1 - clg %r1,.Lnr_syscalls-.Lconst(%r14) + cl %r1,.Lnr_syscalls-.Lconst(%r14) jnl sysc_do_restart - slag %r7,%r1,2 # svc 0: system call number in %r1 + lgfr %r7,%r1 # clear high word in r1 + slag %r7,%r7,2 # svc 0: system call number in %r1 sysc_do_restart: larl %r10,sys_call_table #ifdef CONFIG_S390_SUPPORT @@ -235,16 +236,18 @@ sysc_sigpending: sgr %r3,%r3 # clear *oldset brasl %r14,do_signal # call do_signal stnsm 48(%r15),0xfc # disable I/O and ext. interrupts + tm __TI_flags+7(%r9),_TIF_RESTART_SVC + jo sysc_restart j sysc_leave # out of here, do NOT recheck # # _TIF_RESTART_SVC is set, set up registers and restart svc # sysc_restart: - ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC + ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC stosm 48(%r15),0x03 # reenable interrupts lg %r7,SP_R2(%r15) # load new svc number - slag %r7,%r7,3 # *8 + slag %r7,%r7,2 # *4 mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument lmg %r2,%r6,SP_R2(%r15) # load svc arguments j sysc_do_restart # restart svc @@ -503,7 +506,7 @@ pgm_svcstd: larl %r10,sys_call_table_emu # use 31 bit emulation system calls pgm_svcper_noemu: #endif - tm __TI_flags+3(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE lgf %r8,0(%r7,%r10) # load address of system call routine jo pgm_tracesys basr %r14,%r8 # call sys_xxxx @@ -512,7 +515,7 @@ pgm_svcper_noemu: # changing anything here !! pgm_svcret: - tm __TI_flags+3(%r9),_TIF_SIGPENDING + tm __TI_flags+7(%r9),_TIF_SIGPENDING jo pgm_svcper_nosig la %r2,SP_PTREGS(%r15) # load pt_regs sgr %r3,%r3 # clear *oldset diff -puN arch/s390/kernel/entry.S~s390-01-base arch/s390/kernel/entry.S --- 25/arch/s390/kernel/entry.S~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/entry.S Thu Jan 8 14:10:58 2004 @@ -249,6 +249,8 @@ sysc_sigpending: l %r1,BASED(.Ldo_signal) basr %r14,%r1 # call do_signal stnsm 24(%r15),0xfc # disable I/O and ext. interrupts + tm __TI_flags+3(%r9),_TIF_RESTART_SVC + bo BASED(sysc_restart) b BASED(sysc_leave) # out of here, do NOT recheck # @@ -258,7 +260,7 @@ sysc_restart: ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC stosm 24(%r15),0x03 # reenable interrupts l %r7,SP_R2(%r15) # load new svc number - sla %r2,2 + sla %r7,2 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument lm %r2,%r6,SP_R2(%r15) # load svc arguments b BASED(sysc_do_restart) # restart svc @@ -541,7 +543,7 @@ io_preempt: io_resume_loop: tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bno BASED(io_leave) - mvc __TI_precount(4,%r9),.Lc_pactive + mvc __TI_precount(4,%r9),BASED(.Lc_pactive) # hmpf, we are on the async. stack but to call schedule # we have to move the interrupt frame to the process stack l %r1,SP_R15(%r15) diff -puN arch/s390/kernel/head64.S~s390-01-base arch/s390/kernel/head64.S --- 25/arch/s390/kernel/head64.S~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/head64.S Thu Jan 8 14:10:58 2004 @@ -582,6 +582,20 @@ startup:basr %r13,0 mvc __LC_DIAG44_OPCODE(8),.Ldiag44-.LPG1(%r13) 0: +# +# find out if we have the IDTE instruction +# + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + .long 0xb2b10000 # store facility list + tm 0xc8,0x08 # check bit for clearing-by-ASCE + bno 0f-.LPG1(%r13) + lhi %r1,2094 + lhi %r2,0 + .long 0xb98e2001 + oi 7(%r12),0x80 # set IDTE flag +0: + lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, # virtual and never return ... .align 16 diff -puN arch/s390/kernel/head.S~s390-01-base arch/s390/kernel/head.S --- 25/arch/s390/kernel/head.S~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/head.S Thu Jan 8 14:10:58 2004 @@ -569,6 +569,19 @@ startup:basr %r13,0 oi 3(%r12),16 # set MVPG flag .Lchkmvpg: +# +# find out if we have the IDTE instruction +# + mvc __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13) + .long 0xb2b10000 # store facility list + tm 0xc8,0x08 # check bit for clearing-by-ASCE + bno .Lchkidte-.LPG1(%r13) + lhi %r1,2094 + lhi %r2,0 + .long 0xb98e2001 + oi 3(%r12),0x80 # set IDTE flag +.Lchkidte: + lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, # virtual and never return ... .align 8 @@ -593,6 +606,7 @@ startup:basr %r13,0 .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg +.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte .Lmemsize:.long memory_size .Lmchunk:.long memory_chunk .Lmflags:.long machine_flags diff -puN arch/s390/kernel/ptrace.c~s390-01-base arch/s390/kernel/ptrace.c --- 25/arch/s390/kernel/ptrace.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/ptrace.c Thu Jan 8 14:10:58 2004 @@ -130,7 +130,11 @@ peek_user(struct task_struct *child, add struct user *dummy = NULL; addr_t offset, tmp; - if ((addr & __ADDR_MASK) || addr > sizeof(struct user) - __ADDR_MASK) + /* + * Stupid gdb peeks/pokes the access registers in 64 bit with + * an alignment of 4. Programmers from hell... + */ + if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; if (addr <= (addr_t) &dummy->regs.orig_gpr2) { @@ -138,6 +142,9 @@ peek_user(struct task_struct *child, add * psw, gprs, acrs and orig_gpr2 are stored on the stack */ tmp = *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr); + if (addr == (addr_t) &dummy->regs.psw.mask) + /* Remove per bit from user psw. */ + tmp &= ~PSW_MASK_PER; } else if (addr >= (addr_t) &dummy->regs.fp_regs && addr < (addr_t) (&dummy->regs.fp_regs + 1)) { @@ -173,7 +180,11 @@ poke_user(struct task_struct *child, add struct user *dummy = NULL; addr_t offset; - if ((addr & __ADDR_MASK) || addr > sizeof(struct user) - __ADDR_MASK) + /* + * Stupid gdb peeks/pokes the access registers in 64 bit with + * an alignment of 4. Programmers from hell indeed... + */ + if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; if (addr <= (addr_t) &dummy->regs.orig_gpr2) { @@ -258,7 +269,7 @@ do_ptrace_normal(struct task_struct *chi case PTRACE_PEEKUSR_AREA: case PTRACE_POKEUSR_AREA: - if (!copy_from_user(&parea, (void *) addr, sizeof(parea))) + if (copy_from_user(&parea, (void *) addr, sizeof(parea))) return -EFAULT; addr = parea.kernel_addr; data = parea.process_addr; @@ -266,8 +277,12 @@ do_ptrace_normal(struct task_struct *chi while (copied < parea.len) { if (request == PTRACE_PEEKUSR_AREA) ret = peek_user(child, addr, data); - else - ret = poke_user(child, addr, data); + else { + addr_t tmp; + if (get_user (tmp, (addr_t *) data)) + return -EFAULT; + ret = poke_user(child, addr, tmp); + } if (ret) return ret; addr += sizeof(unsigned long); @@ -390,7 +405,7 @@ poke_user_emu31(struct task_struct *chil if ((tmp & ~PSW32_MASK_CC) != PSW32_USER_BITS) /* Invalid psw mask. */ return -EINVAL; - __KSTK_PTREGS(child)->psw.mask = PSW_USER_BITS | + __KSTK_PTREGS(child)->psw.mask = PSW_USER32_BITS | ((tmp & PSW32_MASK_CC) << 32); } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Build a 64 bit psw address from 31 bit address. */ @@ -484,7 +499,7 @@ do_ptrace_emu31(struct task_struct *chil case PTRACE_PEEKUSR_AREA: case PTRACE_POKEUSR_AREA: - if (!copy_from_user(&parea, (void *) addr, sizeof(parea))) + if (copy_from_user(&parea, (void *) addr, sizeof(parea))) return -EFAULT; addr = parea.kernel_addr; data = parea.process_addr; @@ -492,8 +507,12 @@ do_ptrace_emu31(struct task_struct *chil while (copied < parea.len) { if (request == PTRACE_PEEKUSR_AREA) ret = peek_user_emu31(child, addr, data); - else - ret = poke_user_emu31(child, addr, data); + else { + __u32 tmp; + if (get_user (tmp, (__u32 *) data)) + return -EFAULT; + ret = poke_user_emu31(child, addr, tmp); + } if (ret) return ret; addr += sizeof(unsigned int); diff -puN arch/s390/kernel/semaphore.c~s390-01-base arch/s390/kernel/semaphore.c --- 25/arch/s390/kernel/semaphore.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/semaphore.c Thu Jan 8 14:10:58 2004 @@ -64,14 +64,14 @@ void __down(struct semaphore * sem) struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); while (__sem_update_count(sem, -1) <= 0) { schedule(); - tsk->state = TASK_UNINTERRUPTIBLE; + set_task_state(tsk, TASK_UNINTERRUPTIBLE); } remove_wait_queue(&sem->wait, &wait); - tsk->state = TASK_RUNNING; + __set_task_state(tsk, TASK_RUNNING); wake_up(&sem->wait); } @@ -87,7 +87,7 @@ int __down_interruptible(struct semaphor struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; + __set_task_state(tsk, TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); while (__sem_update_count(sem, -1) <= 0) { if (signal_pending(current)) { @@ -96,10 +96,10 @@ int __down_interruptible(struct semaphor break; } schedule(); - tsk->state = TASK_INTERRUPTIBLE; + set_task_state(tsk, TASK_INTERRUPTIBLE); } remove_wait_queue(&sem->wait, &wait); - tsk->state = TASK_RUNNING; + __set_task_state(tsk, TASK_RUNNING); wake_up(&sem->wait); return retval; } diff -puN arch/s390/kernel/setup.c~s390-01-base arch/s390/kernel/setup.c --- 25/arch/s390/kernel/setup.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/setup.c Thu Jan 8 14:10:58 2004 @@ -158,8 +158,10 @@ static int __init condev_setup(char *str int vdev; vdev = simple_strtoul(str, &str, 0); - if (vdev >= 0 && vdev < 65536) + if (vdev >= 0 && vdev < 65536) { console_device = vdev; + console_irq = -1; + } return 1; } @@ -287,6 +289,7 @@ void (*_machine_power_off)(void) = do_ma void machine_restart(char *command) { + console_unblank(); _machine_restart(command); } @@ -294,6 +297,7 @@ EXPORT_SYMBOL(machine_restart); void machine_halt(void) { + console_unblank(); _machine_halt(); } @@ -301,6 +305,7 @@ EXPORT_SYMBOL(machine_halt); void machine_power_off(void) { + console_unblank(); _machine_power_off(); } diff -puN arch/s390/kernel/signal.c~s390-01-base arch/s390/kernel/signal.c --- 25/arch/s390/kernel/signal.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/signal.c Thu Jan 8 14:10:58 2004 @@ -167,6 +167,9 @@ static int restore_sigregs(struct pt_reg { int err; + /* Alwys make any pending restarted system call return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common)); regs->psw.mask = PSW_USER_BITS | (regs->psw.mask & PSW_MASK_CC); regs->psw.addr |= PSW_ADDR_AMODE; diff -puN arch/s390/kernel/syscalls.S~s390-01-base arch/s390/kernel/syscalls.S --- 25/arch/s390/kernel/syscalls.S~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/syscalls.S Thu Jan 8 14:10:58 2004 @@ -15,7 +15,7 @@ SYSCALL(sys_read,sys_read,sys32_read_wra SYSCALL(sys_write,sys_write,sys32_write_wrapper) SYSCALL(sys_open,sys_open,sys32_open_wrapper) /* 5 */ SYSCALL(sys_close,sys_close,sys32_close_wrapper) -SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_ni_syscall) +SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_restart_syscall) SYSCALL(sys_creat,sys_creat,sys32_creat_wrapper) SYSCALL(sys_link,sys_link,sys32_link_wrapper) SYSCALL(sys_unlink,sys_unlink,sys32_unlink_wrapper) /* 10 */ @@ -261,7 +261,7 @@ SYSCALL(sys_epoll_create,sys_epoll_creat SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper) /* 250 */ SYSCALL(sys_epoll_wait,sys_epoll_wait,sys_epoll_wait_wrapper) SYSCALL(sys_set_tid_address,sys_set_tid_address,sys32_set_tid_address_wrapper) -SYSCALL(sys_fadvise64,sys_fadvise64,sys_ni_syscall) +SYSCALL(s390_fadvise64,sys_fadvise64_64,sys_ni_syscall) SYSCALL(sys_timer_create,sys_timer_create,sys_ni_syscall) SYSCALL(sys_timer_settime,sys_timer_settime,sys_ni_syscall) /* 255 */ SYSCALL(sys_timer_gettime,sys_timer_gettime,sys_ni_syscall) @@ -272,3 +272,4 @@ SYSCALL(sys_clock_gettime,sys_clock_gett SYSCALL(sys_clock_getres,sys_clock_getres,sys_ni_syscall) SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys_ni_syscall) NI_SYSCALL /* reserved for vserver */ +SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys_ni_syscall) diff -puN arch/s390/kernel/sys_s390.c~s390-01-base arch/s390/kernel/sys_s390.c --- 25/arch/s390/kernel/sys_s390.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/sys_s390.c Thu Jan 8 14:10:58 2004 @@ -325,3 +325,39 @@ asmlinkage int s390x_personality(unsigne return ret; } #endif /* CONFIG_ARCH_S390X */ + +/* + * Wrapper function for sys_fadvise64/fadvise64_64 + */ +#ifndef CONFIG_ARCH_S390X + +extern asmlinkage long sys_fadvise64(int, loff_t, size_t, int); + +asmlinkage long +s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice) +{ + return sys_fadvise64(fd, (u64) offset_high << 32 | offset_low, + len, advice); +} + +#endif + +extern asmlinkage long sys_fadvise64_64(int, loff_t, loff_t, int); + +struct fadvise64_64_args { + int fd; + long long offset; + long long len; + int advice; +}; + +asmlinkage long +s390_fadvise64_64(struct fadvise64_64_args *args) +{ + struct fadvise64_64_args a; + + if ( copy_from_user(&a, args, sizeof(a)) ) + return -EFAULT; + return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); +} + diff -puN arch/s390/kernel/traps.c~s390-01-base arch/s390/kernel/traps.c --- 25/arch/s390/kernel/traps.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/traps.c Thu Jan 8 14:10:58 2004 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -156,9 +157,10 @@ void show_registers(struct pt_regs *regs int i; mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; - printk("%s PSW : %p %p\n", + printk("%s PSW : %p %p", mode, (void *) regs->psw.mask, (void *) regs->psw.addr); + print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); printk("%s GPRS: " FOURLONG, mode, regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); printk(" " FOURLONG, @@ -250,6 +252,10 @@ void die(const char * str, struct pt_reg show_regs(regs); bust_spinlocks(0); spin_unlock_irq(&die_lock); + if (in_interrupt()) + panic("Fatal exception in interrupt"); + if (panic_on_oops) + panic("Fatal exception: panic_on_oops"); do_exit(SIGSEGV); } diff -puN arch/s390/kernel/vmlinux.lds.S~s390-01-base arch/s390/kernel/vmlinux.lds.S --- 25/arch/s390/kernel/vmlinux.lds.S~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/kernel/vmlinux.lds.S Thu Jan 8 14:10:58 2004 @@ -117,10 +117,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.text) - *(.exit.data) *(.exitcall.exit) - *(.eh_frame) } /* Stabs debugging sections. */ diff -puN arch/s390/mm/fault.c~s390-01-base arch/s390/mm/fault.c --- 25/arch/s390/mm/fault.c~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/arch/s390/mm/fault.c Thu Jan 8 14:10:58 2004 @@ -538,8 +538,6 @@ asmlinkage void pfault_interrupt(struct pt_regs *regs, __u16 error_code) { struct task_struct *tsk; - wait_queue_head_t queue; - wait_queue_head_t *qp; __u16 subcode; /* @@ -553,46 +551,34 @@ pfault_interrupt(struct pt_regs *regs, _ return; /* - * Get the token (= address of kernel stack of affected task). + * Get the token (= address of the task structure of the affected task). */ tsk = *(struct task_struct **) __LC_PFAULT_INTPARM; - /* - * We got all needed information from the lowcore and can - * now safely switch on interrupts. - */ - if (regs->psw.mask & PSW_MASK_PSTATE) - local_irq_enable(); - if (subcode & 0x0080) { /* signal bit is set -> a page has been swapped in by VM */ - qp = (wait_queue_head_t *) - xchg(&tsk->thread.pfault_wait, -1); - if (qp != NULL) { + if (xchg(&tsk->thread.pfault_wait, -1) != 0) { /* Initial interrupt was faster than the completion * interrupt. pfault_wait is valid. Set pfault_wait * back to zero and wake up the process. This can * safely be done because the task is still sleeping * and can't procude new pfaults. */ - tsk->thread.pfault_wait = 0ULL; - wake_up(qp); + tsk->thread.pfault_wait = 0; + wake_up_process(tsk); } } else { /* signal bit not set -> a real page is missing. */ - init_waitqueue_head (&queue); - qp = (wait_queue_head_t *) - xchg(&tsk->thread.pfault_wait, (addr_t) &queue); - if (qp != NULL) { + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + if (xchg(&tsk->thread.pfault_wait, 1) != 0) { /* Completion interrupt was faster than the initial * interrupt (swapped in a -1 for pfault_wait). Set * pfault_wait back to zero and exit. This can be * done safely because tsk is running in kernel * mode and can't produce new pfaults. */ - tsk->thread.pfault_wait = 0ULL; - } - - /* go to sleep */ - wait_event(queue, tsk->thread.pfault_wait == 0ULL); + tsk->thread.pfault_wait = 0; + set_task_state(tsk, TASK_RUNNING); + } else + set_tsk_need_resched(tsk); } } #endif diff -puN include/asm-s390/bitops.h~s390-01-base include/asm-s390/bitops.h --- 25/include/asm-s390/bitops.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/bitops.h Thu Jan 8 14:10:58 2004 @@ -526,10 +526,10 @@ __constant_test_bit(unsigned long nr, co * Find-bit routines.. */ static inline int -find_first_zero_bit(unsigned long * addr, unsigned size) +find_first_zero_bit(unsigned long * addr, unsigned int size) { unsigned long cmp, count; - int res; + unsigned int res; if (!size) return 0; @@ -565,10 +565,10 @@ find_first_zero_bit(unsigned long * addr } static inline int -find_first_bit(unsigned long * addr, unsigned size) +find_first_bit(unsigned long * addr, unsigned int size) { unsigned long cmp, count; - int res; + unsigned int res; if (!size) return 0; @@ -1022,7 +1022,7 @@ extern inline int ffs (int x) /* * fls: find last bit set. */ -extern __inline__ int fls(int x) +static __inline__ int fls(int x) { int r = 32; @@ -1095,10 +1095,10 @@ extern __inline__ int fls(int x) #ifndef __s390x__ static inline int -ext2_find_first_zero_bit(void *vaddr, unsigned size) +ext2_find_first_zero_bit(void *vaddr, unsigned int size) { unsigned long cmp, count; - int res; + unsigned int res; if (!size) return 0; @@ -1135,12 +1135,12 @@ ext2_find_first_zero_bit(void *vaddr, un } static inline int -ext2_find_next_zero_bit(void *vaddr, unsigned size, unsigned offset) +ext2_find_next_zero_bit(void *vaddr, unsigned int size, unsigned offset) { unsigned long *addr = vaddr; unsigned long *p = addr + (offset >> 5); unsigned long word, reg; - int bit = offset & 31UL, res; + unsigned int bit = offset & 31UL, res; if (offset >= size) return size; diff -puN include/asm-s390/bug.h~s390-01-base include/asm-s390/bug.h --- 25/include/asm-s390/bug.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/bug.h Thu Jan 8 14:10:58 2004 @@ -1,6 +1,8 @@ #ifndef _S390_BUG_H #define _S390_BUG_H +#include + #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ __asm__ __volatile__(".long 0"); \ diff -puN include/asm-s390/byteorder.h~s390-01-base include/asm-s390/byteorder.h --- 25/include/asm-s390/byteorder.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/byteorder.h Thu Jan 8 14:10:58 2004 @@ -14,7 +14,7 @@ #ifdef __GNUC__ #ifdef __s390x__ -static __inline__ __const__ __u64 ___arch__swab64p(__u64 *x) +static __inline__ __u64 ___arch__swab64p(__u64 *x) { __u64 result; @@ -24,7 +24,7 @@ static __inline__ __const__ __u64 ___arc return result; } -static __inline__ __const__ __u64 ___arch__swab64(__u64 x) +static __inline__ __u64 ___arch__swab64(__u64 x) { __u64 result; @@ -40,7 +40,7 @@ static __inline__ void ___arch__swab64s( } #endif /* __s390x__ */ -static __inline__ __const__ __u32 ___arch__swab32p(__u32 *x) +static __inline__ __u32 ___arch__swab32p(__u32 *x) { __u32 result; @@ -58,7 +58,7 @@ static __inline__ __const__ __u32 ___arc return result; } -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +static __inline__ __u32 ___arch__swab32(__u32 x) { #ifndef __s390x__ return ___arch__swab32p(&x); @@ -77,7 +77,7 @@ static __inline__ void ___arch__swab32s( *x = ___arch__swab32p(x); } -static __inline__ __const__ __u16 ___arch__swab16p(__u16 *x) +static __inline__ __u16 ___arch__swab16p(__u16 *x) { __u16 result; @@ -93,7 +93,7 @@ static __inline__ __const__ __u16 ___arc return result; } -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +static __inline__ __u16 ___arch__swab16(__u16 x) { return ___arch__swab16p(&x); } diff -puN include/asm-s390/checksum.h~s390-01-base include/asm-s390/checksum.h --- 25/include/asm-s390/checksum.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/checksum.h Thu Jan 8 14:10:58 2004 @@ -70,7 +70,7 @@ csum_partial_inline(const unsigned char __asm__ __volatile__ ( "0: cksm %0,%1\n" /* do checksum on longs */ " jo 0b\n" - : "+&d" (sum), "+&a" (rp) : : "cc" ); + : "+&d" (sum), "+&a" (rp) : : "cc", "memory" ); #else /* __s390x__ */ __asm__ __volatile__ ( " lgr 2,%1\n" /* address in gpr 2 */ @@ -79,7 +79,7 @@ csum_partial_inline(const unsigned char " jo 0b\n" : "+&d" (sum) : "d" (buff), "d" (len) - : "cc", "2", "3" ); + : "cc", "memory", "2", "3" ); #endif /* __s390x__ */ return sum; } @@ -165,7 +165,7 @@ ip_fast_csum(unsigned char *iph, unsigne " sr %0,%0\n" /* set sum to zero */ "0: cksm %0,%1\n" /* do checksum on longs */ " jo 0b\n" - : "=&d" (sum), "+&a" (rp) : : "cc" ); + : "=&d" (sum), "+&a" (rp) : : "cc", "memory" ); #else /* __s390x__ */ __asm__ __volatile__ ( " slgr %0,%0\n" /* set sum to zero */ @@ -175,7 +175,7 @@ ip_fast_csum(unsigned char *iph, unsigne " jo 0b\n" : "=&d" (sum) : "d" (iph), "d" (ihl*4) - : "cc", "2", "3" ); + : "cc", "memory", "2", "3" ); #endif /* __s390x__ */ return csum_fold(sum); } diff -puN include/asm-s390/hardirq.h~s390-01-base include/asm-s390/hardirq.h --- 25/include/asm-s390/hardirq.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/hardirq.h Thu Jan 8 14:10:58 2004 @@ -25,9 +25,17 @@ typedef struct { unsigned int __softirq_pending; } irq_cpustat_t; -#define softirq_pending(cpu) (lowcore_ptr[(cpu)]->softirq_pending) #define local_softirq_pending() (S390_lowcore.softirq_pending) +/* this is always called with cpu == smp_processor_id() at the moment */ +static inline __u32 +softirq_pending(unsigned int cpu) +{ + if (cpu == smp_processor_id()) + return local_softirq_pending(); + return lowcore_ptr[cpu]->softirq_pending; +} + #define __ARCH_IRQ_STAT /* @@ -42,12 +50,12 @@ typedef struct { * * PREEMPT_MASK: 0x000000ff * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00010000 + * HARDIRQ_MASK: 0x00ff0000 */ #define PREEMPT_BITS 8 #define SOFTIRQ_BITS 8 -#define HARDIRQ_BITS 1 +#define HARDIRQ_BITS 8 #define PREEMPT_SHIFT 0 #define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) @@ -81,7 +89,6 @@ typedef struct { #define irq_enter() \ do { \ - BUG_ON( hardirq_count() ); \ (preempt_count() += HARDIRQ_OFFSET); \ } while(0) diff -puN include/asm-s390/ioctl.h~s390-01-base include/asm-s390/ioctl.h --- 25/include/asm-s390/ioctl.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/ioctl.h Thu Jan 8 14:10:58 2004 @@ -55,11 +55,21 @@ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) +/* provoke compile error for invalid uses of size argument */ +extern unsigned long __invalid_size_argument_for_IOC; +#define _IOC_TYPECHECK(t) \ + ((sizeof(t) == sizeof(t[1]) && \ + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ + sizeof(t) : __invalid_size_argument_for_IOC) + /* used to create numbers */ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) /* used to decode ioctl numbers.. */ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) diff -puN include/asm-s390/mmu_context.h~s390-01-base include/asm-s390/mmu_context.h --- 25/include/asm-s390/mmu_context.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/mmu_context.h Thu Jan 8 14:10:58 2004 @@ -14,7 +14,7 @@ */ #define init_new_context(tsk,mm) 0 -#define destroy_context(mm) flush_tlb_mm(mm) +#define destroy_context(mm) do { } while (0) static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) diff -puN include/asm-s390/pgalloc.h~s390-01-base include/asm-s390/pgalloc.h --- 25/include/asm-s390/pgalloc.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/pgalloc.h Thu Jan 8 14:10:58 2004 @@ -84,7 +84,11 @@ static inline void pmd_free (pmd_t *pmd) free_pages((unsigned long) pmd, 2); } -#define __pmd_free_tlb(tlb,pmd) pmd_free(pmd) +#define __pmd_free_tlb(tlb,pmd) \ + do { \ + tlb_flush_mmu(tlb, 0, 0); \ + pmd_free(pmd); \ + } while (0) static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) { @@ -146,7 +150,7 @@ static inline void pte_free(struct page __free_page(pte); } -#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) +#define __pte_free_tlb(tlb,pte) tlb_remove_page(tlb,pte) /* * This establishes kernel virtual mappings (e.g., as a result of a diff -puN include/asm-s390/pgtable.h~s390-01-base include/asm-s390/pgtable.h --- 25/include/asm-s390/pgtable.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/pgtable.h Thu Jan 8 14:10:58 2004 @@ -29,6 +29,7 @@ * the S390 page table tree. */ #ifndef __ASSEMBLY__ +#include #include #include @@ -465,7 +466,9 @@ extern inline pte_t pte_modify(pte_t pte extern inline pte_t pte_wrprotect(pte_t pte) { - pte_val(pte) |= _PAGE_RO; + /* Do not clobber _PAGE_INVALID_NONE pages! */ + if (!(pte_val(pte) & _PAGE_INVALID)) + pte_val(pte) |= _PAGE_RO; return pte; } @@ -682,9 +685,9 @@ extern inline pte_t mk_swap_pte(unsigned pte_t pte; pte_val(pte) = (type << 1) | (offset << 12) | _PAGE_INVALID_SWAP; #ifndef __s390x__ - pte_val(pte) &= 0x7ffff6fe; /* better to be paranoid */ + BUG_ON((pte_val(pte) & 0x80000901) != 0); #else /* __s390x__ */ - pte_val(pte) &= 0xfffffffffffff6fe; /* better to be paranoid */ + BUG_ON((pte_val(pte) & 0x901) != 0); #endif /* __s390x__ */ return pte; } diff -puN include/asm-s390/scatterlist.h~s390-01-base include/asm-s390/scatterlist.h --- 25/include/asm-s390/scatterlist.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/scatterlist.h Thu Jan 8 14:10:58 2004 @@ -7,6 +7,10 @@ struct scatterlist { unsigned int length; }; -#define ISA_DMA_THRESHOLD (0xffffffffffffffff) +#ifdef __s390x__ +#define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) +#else +#define ISA_DMA_THRESHOLD (0xffffffffUL) +#endif #endif /* _ASMS390X_SCATTERLIST_H */ diff -puN include/asm-s390/setup.h~s390-01-base include/asm-s390/setup.h --- 25/include/asm-s390/setup.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/setup.h Thu Jan 8 14:10:58 2004 @@ -36,6 +36,7 @@ extern unsigned long machine_flags; #define MACHINE_HAS_MVPG (machine_flags & 16) #define MACHINE_HAS_DIAG44 (machine_flags & 32) #define MACHINE_NEW_STIDP (machine_flags & 64) +#define MACHINE_HAS_IDTE (machine_flags & 128) #ifndef __s390x__ #define MACHINE_HAS_IEEE (machine_flags & 2) diff -puN include/asm-s390/siginfo.h~s390-01-base include/asm-s390/siginfo.h --- 25/include/asm-s390/siginfo.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/siginfo.h Thu Jan 8 14:10:59 2004 @@ -14,6 +14,12 @@ #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) #endif +#ifdef CONFIG_ARCH_S390X +#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) +#else +#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) +#endif + #include /* diff -puN include/asm-s390/spinlock.h~s390-01-base include/asm-s390/spinlock.h --- 25/include/asm-s390/spinlock.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/spinlock.h Thu Jan 8 14:10:59 2004 @@ -217,7 +217,7 @@ typedef struct { extern inline int _raw_write_trylock(rwlock_t *rw) { - unsigned int result, reg; + unsigned long result, reg; __asm__ __volatile__( #ifndef __s390x__ diff -puN include/asm-s390/tlbflush.h~s390-01-base include/asm-s390/tlbflush.h --- 25/include/asm-s390/tlbflush.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/tlbflush.h Thu Jan 8 14:10:59 2004 @@ -99,17 +99,21 @@ static inline void global_flush_tlb(void static inline void __flush_tlb_mm(struct mm_struct * mm) { cpumask_t local_cpumask; + + if (unlikely(cpus_empty(mm->cpu_vm_mask))) + return; + if (MACHINE_HAS_IDTE) { + asm volatile (".insn rrf,0xb98e0000,0,%0,%1,0" + : : "a" (2048), + "a" (__pa(mm->pgd)&PAGE_MASK) : "cc" ); + return; + } preempt_disable(); local_cpumask = cpumask_of_cpu(smp_processor_id()); - if (cpus_equal(mm->cpu_vm_mask, local_cpumask)) { - /* mm was active on more than one cpu. */ - if (mm == current->active_mm && - atomic_read(&mm->mm_users) == 1) - /* this cpu is the only one using the mm. */ - mm->cpu_vm_mask = local_cpumask; - global_flush_tlb(); - } else + if (cpus_equal(mm->cpu_vm_mask, local_cpumask)) local_flush_tlb(); + else + global_flush_tlb(); preempt_enable(); } @@ -136,8 +140,7 @@ static inline void flush_tlb_range(struc __flush_tlb_mm(vma->vm_mm); } -#define flush_tlb_kernel_range(start, end) \ - __flush_tlb_mm(&init_mm) +#define flush_tlb_kernel_range(start, end) global_flush_tlb() #endif diff -puN include/asm-s390/unistd.h~s390-01-base include/asm-s390/unistd.h --- 25/include/asm-s390/unistd.h~s390-01-base Thu Jan 8 14:10:58 2004 +++ 25-akpm/include/asm-s390/unistd.h Thu Jan 8 14:10:59 2004 @@ -259,8 +259,9 @@ /* * Number 263 is reserved for vserver */ +#define __NR_fadvise64_64 264 -#define NR_syscalls 264 +#define NR_syscalls 265 /* * There are some system calls that are not present on 64 bit, some @@ -322,6 +323,7 @@ #undef __NR_getdents64 #undef __NR_fcntl64 #undef __NR_sendfile64 +#undef __NR_fadvise64_64 #define __NR_select 142 #define __NR_getrlimit 191 /* SuS compliant getrlimit */ _