]> git.hungrycats.org Git - linux/commitdiff
[PATCH] s390: general update
authorAndrew Morton <akpm@osdl.org>
Mon, 19 Jan 2004 02:40:53 +0000 (18:40 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 19 Jan 2004 02:40:53 +0000 (18:40 -0800)
From: Martin Schwidefsky <schwidefsky@de.ibm.com>

 - 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.

29 files changed:
arch/s390/defconfig
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/head.S
arch/s390/kernel/head64.S
arch/s390/kernel/ptrace.c
arch/s390/kernel/semaphore.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/sys_s390.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/traps.c
arch/s390/kernel/vmlinux.lds.S
arch/s390/mm/fault.c
include/asm-s390/bitops.h
include/asm-s390/bug.h
include/asm-s390/byteorder.h
include/asm-s390/checksum.h
include/asm-s390/hardirq.h
include/asm-s390/ioctl.h
include/asm-s390/mmu_context.h
include/asm-s390/pgalloc.h
include/asm-s390/pgtable.h
include/asm-s390/scatterlist.h
include/asm-s390/setup.h
include/asm-s390/siginfo.h
include/asm-s390/spinlock.h
include/asm-s390/tlbflush.h
include/asm-s390/unistd.h

index a1e4e3d3e38c28227244bb5ba6222eb0fb2aca09..4182bc990d0a6238e9a262f81e839c1242e4f69d 100644 (file)
@@ -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
@@ -317,6 +318,21 @@ CONFIG_QETH=y
 # CONFIG_QETH_PERF_STATS is not set
 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
 #
@@ -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
@@ -423,6 +439,11 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
 #
 # Kernel hacking
 #
index 79f75d3383efb7735d5986cc49c2533bb197c294..bcfb5b6a95edcc74b15533efbcc284937dd1e624 100644 (file)
@@ -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)
index ebeec5dd463613139133d293b4f24b4a5f672cda..e1d69a0a96e74b53f5cd6d1e91f0f52428b4b301 100644 (file)
@@ -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
index cd625d2369aeeb3cebf1838a99c0e87855d69c31..229f4aff8aecd4bcfb1d838fdd9342fac029402d 100644 (file)
@@ -569,6 +569,19 @@ startup:basr  %r13,0                     # get base
        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                     # get base
 .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
index fda57350276d9532407d2ecd3eb255403e8e3802..c380e2b9cc8ec50b620d27293317cda10842d017 100644 (file)
@@ -582,6 +582,20 @@ startup:basr  %r13,0                     # get base
        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
index 73cb7e8136e306b9b8a5382be0ca23d1186268b3..3985767a8feb1d1c6b5bae84fc260e932872cd72 100644 (file)
@@ -130,7 +130,11 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
        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, addr_t addr, addr_t data)
                 * 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, addr_t addr, addr_t data)
        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 *child, long request, long addr, long data)
 
        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 *child, long request, long addr, long data)
                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 *child, addr_t addr, addr_t data)
                        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 *child, long request, long addr, long data)
 
        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 *child, long request, long addr, long data)
                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);
index 4ba2c084f35831f790dba200693a3111c313ad08..f6cfdd7c00a8ea98542efd6aee96f15c6710b4b5 100644 (file)
@@ -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 semaphore * sem)
        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 semaphore * sem)
                        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;
 }
index 315380bb914d39ddf658b684055d8c37ad532b75..fc703b1e363aeacf82aa829303d0bf69db119e2c 100644 (file)
@@ -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_machine_power_off_nonsmp;
 
 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();
 }
 
index 94696fca669db9a24adafb723b73fb25e68bf98b..43f2b7404fa5b432d1ea14b531502b4be5489202 100644 (file)
@@ -167,6 +167,9 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
 {
        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;
index 51038c69733f6d82cc47a29189ccbadf8737071b..b21c19b8ab68004c9d17277d00c16de647438f2d 100644 (file)
@@ -325,3 +325,39 @@ asmlinkage int s390x_personality(unsigned long personality)
        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);
+}
+
index d6786b2b214dda276e6f0ddd64c448b08a0c1080..df1e6320ce39741e111f8e62db3ed68ff3ae3bcf 100644 (file)
@@ -15,7 +15,7 @@ SYSCALL(sys_read,sys_read,sys32_read_wrapper)
 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_create,sys_epoll_create_wrapper)
 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_gettime,sys_ni_syscall) /* 260 */
 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)
index 6efb3cfa4d830139bf5b66c79d78fefec9da07c9..4031e1f6ede3f775a1e4fd71d10c35e8bb4ba3e6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
@@ -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_regs * regs, long err)
         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);
 }
 
index 1e44b7a8f90c35e44c8d8bcf51a077dd8ad82923..c9ca7a8e93b36f8d06c80467e52f63f617a78d50 100644 (file)
@@ -117,10 +117,7 @@ SECTIONS
 
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.exit.text)
-       *(.exit.data)
        *(.exitcall.exit)
-       *(.eh_frame)
        }
 
   /* Stabs debugging sections.  */
index 4826b7971d3e4cd1f887dc0839a4f6dcabc8e5c2..84e41c9c4b85d4e8a02b50a3257fa46b09a94bf7 100644 (file)
@@ -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, __u16 error_code)
                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
index d68d059e91184c82455e915ce1117e9dc223fbbd..8de69aa8ec354de5e991717a539d4c9ae9b9a306 100644 (file)
@@ -526,10 +526,10 @@ __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
  * 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, unsigned size)
 }
 
 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, unsigned size)
 }
 
 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;
index c5cff3670d009727ddfcbfde721b0186d8ff45ef..d59639386f7cd14dcfe4bded1cf09e289db8c862 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _S390_BUG_H
 #define _S390_BUG_H
 
+#include <linux/kernel.h>
+
 #define BUG() do { \
         printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
         __asm__ __volatile__(".long 0"); \
index b13fe4b3b31a0d6c5d38302e18f6d21abce3cba8..afa7332e6d30dfaa766efa8b40d3feddb546dc5c 100644 (file)
@@ -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 ___arch__swab64p(__u64 *x)
        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(__u64 *x)
 }
 #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 ___arch__swab32p(__u32 *x)
        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(__u32 *x)
        *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 ___arch__swab16p(__u16 *x)
        return result;
 }
 
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+static __inline__ __u16 ___arch__swab16(__u16 x)
 {
        return ___arch__swab16p(&x);
 }
index f4790809353bb510db88da020e33f168d1747e8a..fc5c512aed0403743b4baef3aacb42ee00133e1b 100644 (file)
@@ -70,7 +70,7 @@ csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
        __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 * buff, int len, unsigned int sum)
                "    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, unsigned int ihl)
                "    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, unsigned int ihl)
                 "    jo   0b\n"
                 : "=&d" (sum)
                 : "d" (iph), "d" (ihl*4)
-                : "cc", "2", "3" );
+                : "cc", "memory", "2", "3" );
 #endif /* __s390x__ */
         return csum_fold(sum);
 }
index e7bd21c229b787b2beab56f40bdd266bbd3bbc00..1092143b8b975cac375bf048228d1a31c03de7e2 100644 (file)
@@ -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)
        
index 35b4821e8d22163ed6e0ed091b035b4c43c34814..df7394345ac40131b7bc8348c11e2fb265c06906 100644 (file)
         ((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)
index 9bf56465a196a9833c53fa471c1fef879d4b2aa4..b361c423a06685e42c150ddc89286a8cacfc5a45 100644 (file)
@@ -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)
index e4729fb912fd9e9311e2fa37fbc4a2edae2bd8ba..ac2aba7a92995c60cc271c3f02cc51f63a32f097 100644 (file)
@@ -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 *pte)
         __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
index 002a4ed74b41294a0aa740b5c25e4b49f9224af0..776e2b1c887b30ec1ac45fbf0fe156a27ce0585f 100644 (file)
@@ -29,6 +29,7 @@
  * the S390 page table tree.
  */
 #ifndef __ASSEMBLY__
+#include <asm/bug.h>
 #include <asm/processor.h>
 #include <linux/threads.h>
 
@@ -465,7 +466,9 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 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 long type, unsigned long offset)
        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;
 }
index 2ca4ea9ede18ba5f6431d3daa110d0a432649ecb..a43b3afc5e2da6bc919290f692bb44e50db9b44a 100644 (file)
@@ -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 */
index 21e9c4a643b4bd0d34c170f98667850a1039ffd1..c5b19f08c363f731787bbff3b465cdcb6660f594 100644 (file)
@@ -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)
index e2dcb1074155c850b5f17ac092c1e3766ec4bf3c..446fa8cf2a00a6cf8190650314e71c7f12c9d637 100644 (file)
 #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 <asm-generic/siginfo.h>
 
 /*
index fd79284aca7e553e08b2d01d821b9a5179479fbb..2d4d6e75469ed54996cdb67507651da0a2638f83 100644 (file)
@@ -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__
index 71908df445b76fd3ac1f1afa307c99f13fe15f9b..2b76fa728abb7413ec1e0b980491228921bb015d 100644 (file)
@@ -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(struct vm_area_struct *vma,
        __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
 
index f71b3b352ce8c80b8f256beb7d228e34c3c441ab..93c829f071072076f4cada4f90ab9fab138297da 100644 (file)
 /*
  * 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
 #undef  __NR_getdents64
 #undef  __NR_fcntl64
 #undef  __NR_sendfile64
+#undef  __NR_fadvise64_64
 
 #define __NR_select            142
 #define __NR_getrlimit         191     /* SuS compliant getrlimit */