diff options
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 38 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 6 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 6 | ||||
-rw-r--r-- | arch/s390/kernel/head.S | 16 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 12 | ||||
-rw-r--r-- | arch/s390/kernel/s390_ext.c | 16 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 10 |
9 files changed, 83 insertions, 37 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 614056222875..18610cea03a2 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -58,6 +58,7 @@ #include <linux/compat.h> #include <linux/vfs.h> #include <linux/ptrace.h> +#include <linux/fadvise.h> #include <asm/types.h> #include <asm/ipc.h> @@ -1043,3 +1044,40 @@ sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32, return ret; } + +/* + * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. + * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} + * because the 31 bit values differ from the 64 bit values. + */ + +asmlinkage long +sys32_fadvise64(int fd, loff_t offset, size_t len, int advise) +{ + if (advise == 4) + advise = POSIX_FADV_DONTNEED; + else if (advise == 5) + advise = POSIX_FADV_NOREUSE; + return sys_fadvise64(fd, offset, len, advise); +} + +struct fadvise64_64_args { + int fd; + long long offset; + long long len; + int advice; +}; + +asmlinkage long +sys32_fadvise64_64(struct fadvise64_64_args __user *args) +{ + struct fadvise64_64_args a; + + if ( copy_from_user(&a, args, sizeof(a)) ) + return -EFAULT; + if (a.advice == 4) + a.advice = POSIX_FADV_DONTNEED; + else if (a.advice == 5) + a.advice = POSIX_FADV_NOREUSE; + return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); +} diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index bf529739c8ab..799a98eac92d 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1251,12 +1251,12 @@ sys32_fadvise64_wrapper: or %r3,%r4 # get low word of 64bit loff_t llgfr %r4,%r5 # size_t (unsigned long) lgfr %r5,%r6 # int - jg sys_fadvise64 + jg sys32_fadvise64 .globl sys32_fadvise64_64_wrapper sys32_fadvise64_64_wrapper: llgtr %r2,%r2 # struct fadvise64_64_args * - jg s390_fadvise64_64 + jg sys32_fadvise64_64 .globl sys32_clock_settime_wrapper sys32_clock_settime_wrapper: diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 5b262b5d869f..1a271b16cb5c 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -690,9 +690,9 @@ mcck_int_handler: bo BASED(0f) spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 0: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 57ca75d0ad7f..d9f22915008c 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -727,9 +727,9 @@ mcck_int_handler: jo 0f spt __LC_LAST_UPDATE_TIMER #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER - mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 0: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? jno mcck_no_vtime # no -> no timer update tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index fc8bf5e285f6..2710e66fefba 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -346,6 +346,13 @@ iplstart: la %r2,.Lreset lhi %r3,26 diag %r2,%r3,8 + la %r5,.Lirb + stsch 0(%r5) # check if irq is pending + tm 30(%r5),0x0f # by verifying if any of the + bnz .Lwaitforirq # activity or status control + tm 31(%r5),0xff # bits is set in the schib + bz .Lnoreset +.Lwaitforirq: mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw .Lwaitrdrirq: lpsw .Lrdrwaitpsw @@ -535,8 +542,13 @@ startup:basr %r13,0 # get base lhi %r1,0 icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 jnz .Lscnd - l %r1,.Lscpincr2-PARMAREA+4(%r4) # otherwise use this one + lhi %r1,0x800 # otherwise report 2GB .Lscnd: + lhi %r3,0x800 # limit reported memory size to 2GB + cr %r1,%r3 + jl .Lno2gb + lr %r1,%r3 +.Lno2gb: xr %r3,%r3 # same logic ic %r3,.Lscpa1-PARMAREA(%r4) chi %r3,0x00 @@ -765,7 +777,7 @@ _stext: basr %r13,0 # get base # check control registers stctl %c0,%c15,0(%r15) - oi 2(%r15),0x20 # enable sigp external interrupts + oi 2(%r15),0x40 # enable sigp emergency signal oi 0(%r15),0x10 # switch on low address protection lctl %c0,%c15,0(%r15) diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index f525c0c21250..9a8263a153cb 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -345,6 +345,13 @@ iplstart: la %r2,.Lreset lhi %r3,26 diag %r2,%r3,8 + la %r5,.Lirb + stsch 0(%r5) # check if irq is pending + tm 30(%r5),0x0f # by verifying if any of the + bnz .Lwaitforirq # activity or status control + tm 31(%r5),0xff # bits is set in the schib + bz .Lnoreset +.Lwaitforirq: mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw .Lwaitrdrirq: lpsw .Lrdrwaitpsw @@ -658,10 +665,8 @@ startup:basr %r13,0 # get base # la %r1,0f-.LPG1(%r13) # set program check address stg %r1,__LC_PGM_NEW_PSW+8 - mvc __LC_DIAG44_OPCODE(8),.Lnop-.LPG1(%r13) diag 0,0,0x44 # test diag 0x44 oi 7(%r12),32 # set diag44 flag - mvc __LC_DIAG44_OPCODE(8),.Ldiag44-.LPG1(%r13) 0: # @@ -702,7 +707,6 @@ startup:basr %r13,0 # get base .L4malign:.quad 0xffffffffffc00000 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lnop: .long 0x07000700 -.Ldiag44:.long 0x83000044 .org PARMAREA-64 .Lduct: .long 0,0,0,0,0,0,0,0 @@ -765,7 +769,7 @@ _stext: basr %r13,0 # get base # check control registers stctg %c0,%c15,0(%r15) - oi 6(%r15),0x20 # enable sigp external interrupts + oi 6(%r15),0x40 # enable sigp emergency signal oi 4(%r15),0x10 # switch on low address proctection lctlg %c0,%c15,0(%r15) diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c index 3bdd38ec71da..207bc511a6e3 100644 --- a/arch/s390/kernel/s390_ext.c +++ b/arch/s390/kernel/s390_ext.c @@ -19,7 +19,6 @@ #include <asm/irq.h> /* - * Simple hash strategy: index = code & 0xff; * ext_int_hash[index] is the start of the list for all external interrupts * that hash to this index. With the current set of external interrupts * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000 @@ -27,6 +26,11 @@ */ ext_int_info_t *ext_int_hash[256] = { 0, }; +static inline int ext_hash(__u16 code) +{ + return (code + (code >> 9)) & 0xff; +} + int register_external_interrupt(__u16 code, ext_int_handler_t handler) { ext_int_info_t *p; @@ -37,7 +41,7 @@ int register_external_interrupt(__u16 code, ext_int_handler_t handler) return -ENOMEM; p->code = code; p->handler = handler; - index = code & 0xff; + index = ext_hash(code); p->next = ext_int_hash[index]; ext_int_hash[index] = p; return 0; @@ -52,7 +56,7 @@ int register_early_external_interrupt(__u16 code, ext_int_handler_t handler, return -EINVAL; p->code = code; p->handler = handler; - index = code & 0xff; + index = ext_hash(code); p->next = ext_int_hash[index]; ext_int_hash[index] = p; return 0; @@ -63,7 +67,7 @@ int unregister_external_interrupt(__u16 code, ext_int_handler_t handler) ext_int_info_t *p, *q; int index; - index = code & 0xff; + index = ext_hash(code); q = NULL; p = ext_int_hash[index]; while (p != NULL) { @@ -90,7 +94,7 @@ int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler, if (p == NULL || p->code != code || p->handler != handler) return -EINVAL; - index = code & 0xff; + index = ext_hash(code); q = ext_int_hash[index]; if (p != q) { while (q != NULL) { @@ -120,7 +124,7 @@ void do_extint(struct pt_regs *regs, unsigned short code) */ account_ticks(regs); kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; - index = code & 0xff; + index = ext_hash(code); for (p = ext_int_hash[index]; p; p = p->next) { if (likely(p->code == code)) { if (likely(p->handler)) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b6d740ac0e6e..5ba5a5485da9 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -299,24 +299,18 @@ void machine_restart(char *command) _machine_restart(command); } -EXPORT_SYMBOL(machine_restart); - void machine_halt(void) { console_unblank(); _machine_halt(); } -EXPORT_SYMBOL(machine_halt); - void machine_power_off(void) { console_unblank(); _machine_power_off(); } -EXPORT_SYMBOL(machine_power_off); - static void __init add_memory_hole(unsigned long start, unsigned long end) { @@ -437,12 +431,6 @@ setup_lowcore(void) ctl_set_bit(14, 29); } #endif -#ifdef CONFIG_ARCH_S390X - if (MACHINE_HAS_DIAG44) - lc->diag44_opcode = 0x83000044; - else - lc->diag44_opcode = 0x07000700; -#endif /* CONFIG_ARCH_S390X */ set_prefix((u32)(unsigned long) lc); } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 642572a8e334..da77f001af8d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -375,7 +375,7 @@ static void smp_ext_bitcall(int cpu, ec_bit_sig sig) * Set signaling bit in lowcore of target cpu and kick it */ set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); - while(signal_processor(cpu, sigp_external_call) == sigp_busy) + while(signal_processor(cpu, sigp_emergency_signal) == sigp_busy) udelay(10); } @@ -394,7 +394,7 @@ static void smp_ext_bitcall_others(ec_bit_sig sig) * Set signaling bit in lowcore of target cpu and kick it */ set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); - while (signal_processor(cpu, sigp_external_call) == sigp_busy) + while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) udelay(10); } } @@ -751,9 +751,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) unsigned int cpu; int i; - /* request the 0x1202 external interrupt */ - if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0) - panic("Couldn't request external interrupt 0x1202"); + /* request the 0x1201 emergency signal external interrupt */ + if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) + panic("Couldn't request external interrupt 0x1201"); smp_check_cpus(max_cpus); memset(lowcore_ptr,0,sizeof(lowcore_ptr)); /* |