summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/compat_wrapper.S26
-rw-r--r--arch/s390/kernel/entry.S6
-rw-r--r--arch/s390/kernel/entry64.S6
-rw-r--r--arch/s390/kernel/head.S16
-rw-r--r--arch/s390/kernel/head64.S12
-rw-r--r--arch/s390/kernel/machine_kexec.c7
-rw-r--r--arch/s390/kernel/relocate_kernel.S41
-rw-r--r--arch/s390/kernel/relocate_kernel64.S45
-rw-r--r--arch/s390/kernel/s390_ext.c16
-rw-r--r--arch/s390/kernel/setup.c6
-rw-r--r--arch/s390/kernel/smp.c16
-rw-r--r--arch/s390/kernel/syscalls.S5
-rw-r--r--arch/s390/kernel/traps.c15
13 files changed, 183 insertions, 34 deletions
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 799a98eac92..23fe94e5868 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1449,3 +1449,29 @@ compat_sys_kexec_load_wrapper:
llgtr %r4,%r4 # struct kexec_segment *
llgfr %r5,%r5 # unsigned long
jg compat_sys_kexec_load
+
+ .globl sys_ioprio_set_wrapper
+sys_ioprio_set_wrapper:
+ lgfr %r2,%r2 # int
+ lgfr %r3,%r3 # int
+ lgfr %r4,%r4 # int
+ jg sys_ioprio_set
+
+ .globl sys_ioprio_get_wrapper
+sys_ioprio_get_wrapper:
+ lgfr %r2,%r2 # int
+ lgfr %r3,%r3 # int
+ jg sys_ioprio_get
+
+ .globl sys_inotify_add_watch_wrapper
+sys_inotify_add_watch_wrapper:
+ lgfr %r2,%r2 # int
+ llgtr %r3,%r3 # const char *
+ llgfr %r4,%r4 # u32
+ jg sys_inotify_add_watch
+
+ .globl sys_inotify_rm_watch_wrapper
+sys_inotify_rm_watch_wrapper:
+ lgfr %r2,%r2 # int
+ llgfr %r3,%r3 # u32
+ jg sys_inotify_rm_watch
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 5b262b5d869..1a271b16cb5 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 57ca75d0ad7..d9f22915008 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 fc8bf5e285f..2710e66fefb 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 f525c0c2125..9a8263a153c 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/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 2721c3a32b8..5aa71b05b8a 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -70,6 +70,8 @@ machine_kexec(struct kimage *image)
for (;;);
}
+extern void pfault_fini(void);
+
static void
kexec_halt_all_cpus(void *kernel_image)
{
@@ -78,6 +80,11 @@ kexec_halt_all_cpus(void *kernel_image)
struct kimage *image;
relocate_kernel_t data_mover;
+#ifdef CONFIG_PFAULT
+ if (MACHINE_IS_VM)
+ pfault_fini();
+#endif
+
if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
signal_processor(smp_processor_id(), sigp_stop);
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
index d5e4a62fbb7..2a25ec7147f 100644
--- a/arch/s390/kernel/relocate_kernel.S
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -4,6 +4,7 @@
* (C) Copyright IBM Corp. 2005
*
* Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
*
*/
@@ -25,8 +26,31 @@
relocate_kernel:
basr %r13,0 #base address
.base:
- spx zero64-.base(%r13) #absolute addressing mode
stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external)
+ spx zero64-.base(%r13) #absolute addressing mode
+ stctl %c0,%c15,ctlregs-.base(%r13)
+ stm %r0,%r15,gprregs-.base(%r13)
+ la %r1,load_psw-.base(%r13)
+ mvc 0(8,%r0),0(%r1)
+ la %r0,.back-.base(%r13)
+ st %r0,4(%r0)
+ oi 4(%r0),0x80
+ mvc 0x68(8,%r0),0(%r1)
+ la %r0,.back_pgm-.base(%r13)
+ st %r0,0x6c(%r0)
+ oi 0x6c(%r0),0x80
+ lhi %r0,0
+ diag %r0,%r0,0x308
+ .back:
+ basr %r13,0
+ .back_base:
+ oi have_diag308-.back_base(%r13),0x01
+ lctl %c0,%c15,ctlregs-.back_base(%r13)
+ lm %r0,%r15,gprregs-.back_base(%r13)
+ j .start_reloc
+ .back_pgm:
+ lm %r0,%r15,gprregs-.base(%r13)
+ .start_reloc:
lhi %r10,-1 #preparing the mask
sll %r10,12 #shift it such that it becomes 0xf000
.top:
@@ -63,6 +87,10 @@
o %r3,4(%r4) #or load address into psw
st %r3,4(%r4)
mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0
+ tm have_diag308-.base(%r13),0x01
+ jno .no_diag308
+ diag %r0,%r0,0x308
+ .no_diag308:
sr %r1,%r1 #clear %r1
sr %r2,%r2 #clear %r2
sigp %r1,%r2,0x12 #set cpuid to zero
@@ -75,6 +103,17 @@
.long 0x00080000,0x80000000
sys_msk:
.quad 0
+ ctlregs:
+ .rept 16
+ .long 0
+ .endr
+ gprregs:
+ .rept 16
+ .long 0
+ .endr
+ have_diag308:
+ .byte 0
+ .align 8
relocate_kernel_end:
.globl relocate_kernel_len
relocate_kernel_len:
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
index 96290cc4eb3..8cdb86e8911 100644
--- a/arch/s390/kernel/relocate_kernel64.S
+++ b/arch/s390/kernel/relocate_kernel64.S
@@ -4,6 +4,7 @@
* (C) Copyright IBM Corp. 2005
*
* Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
*
*/
@@ -26,8 +27,34 @@
relocate_kernel:
basr %r13,0 #base address
.base:
+ stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQs
spx zero64-.base(%r13) #absolute addressing mode
- stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external)
+ stctg %c0,%c15,ctlregs-.base(%r13)
+ stmg %r0,%r15,gprregs-.base(%r13)
+ lghi %r0,3
+ sllg %r0,%r0,31
+ stg %r0,0x1d0(%r0)
+ la %r0,.back_pgm-.base(%r13)
+ stg %r0,0x1d8(%r0)
+ la %r1,load_psw-.base(%r13)
+ mvc 0(8,%r0),0(%r1)
+ la %r0,.back-.base(%r13)
+ st %r0,4(%r0)
+ oi 4(%r0),0x80
+ lghi %r0,0
+ diag %r0,%r0,0x308
+ .back:
+ lhi %r1,1 #mode 1 = esame
+ sigp %r1,%r0,0x12 #switch to esame mode
+ sam64 #switch to 64 bit addressing mode
+ basr %r13,0
+ .back_base:
+ oi have_diag308-.back_base(%r13),0x01
+ lctlg %c0,%c15,ctlregs-.back_base(%r13)
+ lmg %r0,%r15,gprregs-.back_base(%r13)
+ j .top
+ .back_pgm:
+ lmg %r0,%r15,gprregs-.base(%r13)
.top:
lghi %r7,4096 #load PAGE_SIZE in r7
lghi %r9,4096 #load PAGE_SIZE in r9
@@ -62,6 +89,10 @@
o %r3,4(%r4) #or load address into psw
st %r3,4(%r4)
mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0
+ tm have_diag308-.base(%r13),0x01
+ jno .no_diag308
+ diag %r0,%r0,0x308
+ .no_diag308:
sam31 #31 bit mode
sr %r1,%r1 #erase register r1
sr %r2,%r2 #erase register r2
@@ -75,8 +106,18 @@
.long 0x00080000,0x80000000
sys_msk:
.quad 0
+ ctlregs:
+ .rept 16
+ .quad 0
+ .endr
+ gprregs:
+ .rept 16
+ .quad 0
+ .endr
+ have_diag308:
+ .byte 0
+ .align 8
relocate_kernel_end:
.globl relocate_kernel_len
relocate_kernel_len:
.quad relocate_kernel_end - relocate_kernel
-
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 3bdd38ec71d..207bc511a6e 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 a12183989a7..5ba5a5485da 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -431,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 642572a8e33..85222fee436 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);
}
}
@@ -537,7 +537,8 @@ int __devinit start_secondary(void *cpuvoid)
#endif
#ifdef CONFIG_PFAULT
/* Enable pfault pseudo page faults on this cpu. */
- pfault_init();
+ if (MACHINE_IS_VM)
+ pfault_init();
#endif
/* Mark this cpu as online */
cpu_set(smp_processor_id(), cpu_online_map);
@@ -690,7 +691,8 @@ __cpu_disable(void)
#ifdef CONFIG_PFAULT
/* Disable pfault pseudo page faults on this cpu. */
- pfault_fini();
+ if (MACHINE_IS_VM)
+ pfault_fini();
#endif
/* disable all external interrupts */
@@ -751,9 +753,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));
/*
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index a8668afb5f8..426d7cafdab 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -290,3 +290,8 @@ SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper)
SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper)
SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */
SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid_wrapper)
+SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper)
+SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper)
+SYSCALL(sys_inotify_init,sys_inotify_init,sys_inotify_init)
+SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper)
+SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,sys_inotify_rm_watch_wrapper)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index bc7b7be7acb..6b8703ec2ae 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/reboot.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -675,6 +676,19 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
panic("Corrupt kernel stack, can't continue.");
}
+#ifndef CONFIG_ARCH_S390X
+static int
+pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ if (MACHINE_IS_VM)
+ cpcmd("SET PAGEX OFF", NULL, 0, NULL);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block pagex_reboot_notifier = {
+ .notifier_call = &pagex_reboot_event,
+};
+#endif
/* init is done in lowcore.S and head.S */
@@ -735,6 +749,7 @@ void __init trap_init(void)
&ext_int_pfault);
#endif
#ifndef CONFIG_ARCH_S390X
+ register_reboot_notifier(&pagex_reboot_notifier);
cpcmd("SET PAGEX ON", NULL, 0, NULL);
#endif
}