aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-10-25 10:10:38 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:19 -0400
commitf6649a7e5a9ee99e9623878f4a5579cc2f6cdd51 (patch)
tree183438313c7593565980a1445f208e0ba30162cd /arch
parent1e54622e0403891b10f2105663e0f9dd595a1f17 (diff)
[S390] cleanup lowcore access from external interrupts
Read external interrupts parameters from the lowcore in the first level interrupt handler in entry[64].S. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/s390_ext.h2
-rw-r--r--arch/s390/kernel/asm-offsets.c2
-rw-r--r--arch/s390/kernel/entry.S3
-rw-r--r--arch/s390/kernel/entry.h2
-rw-r--r--arch/s390/kernel/entry64.S5
-rw-r--r--arch/s390/kernel/s390_ext.c9
-rw-r--r--arch/s390/kernel/smp.c3
-rw-r--r--arch/s390/kernel/time.c17
-rw-r--r--arch/s390/kernel/vtime.c3
-rw-r--r--arch/s390/mm/fault.c11
10 files changed, 35 insertions, 22 deletions
diff --git a/arch/s390/include/asm/s390_ext.h b/arch/s390/include/asm/s390_ext.h
index 2afc060266a2..1a9307e70842 100644
--- a/arch/s390/include/asm/s390_ext.h
+++ b/arch/s390/include/asm/s390_ext.h
@@ -12,7 +12,7 @@
12 12
13#include <linux/types.h> 13#include <linux/types.h>
14 14
15typedef void (*ext_int_handler_t)(__u16 code); 15typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
16 16
17typedef struct ext_int_info_t { 17typedef struct ext_int_info_t {
18 struct ext_int_info_t *next; 18 struct ext_int_info_t *next;
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 76328deb31f7..f3c1b823c9a8 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -143,10 +143,8 @@ int main(void)
143 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area)); 143 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
144 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area)); 144 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
145#ifdef CONFIG_32BIT 145#ifdef CONFIG_32BIT
146 DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params));
147 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr)); 146 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
148#else /* CONFIG_32BIT */ 147#else /* CONFIG_32BIT */
149 DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params2));
150 DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2)); 148 DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
151 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area)); 149 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
152 DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste)); 150 DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index adf25246f72e..736d7010629e 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -722,7 +722,8 @@ ext_no_vtime:
722 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 722 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
723 TRACE_IRQS_OFF 723 TRACE_IRQS_OFF
724 la %r2,SP_PTREGS(%r15) # address of register-save area 724 la %r2,SP_PTREGS(%r15) # address of register-save area
725 lh %r3,__LC_EXT_INT_CODE # get interruption code 725 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
726 l %r4,__LC_EXT_PARAMS # get external parameters
726 l %r1,BASED(.Ldo_extint) 727 l %r1,BASED(.Ldo_extint)
727 basr %r14,%r1 728 basr %r14,%r1
728 b BASED(io_return) 729 b BASED(io_return)
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 714ff2e57c6b..95c1dfc4ef31 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -19,7 +19,7 @@ void do_signal(struct pt_regs *regs);
19int handle_signal32(unsigned long sig, struct k_sigaction *ka, 19int handle_signal32(unsigned long sig, struct k_sigaction *ka,
20 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs); 20 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
21 21
22void do_extint(struct pt_regs *regs, unsigned short code); 22void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
23int __cpuinit start_secondary(void *cpuvoid); 23int __cpuinit start_secondary(void *cpuvoid);
24void __init startup_init(void); 24void __init startup_init(void);
25void die(const char * str, struct pt_regs * regs, long err); 25void die(const char * str, struct pt_regs * regs, long err);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 2d205e4e7bb6..e4038ea4dc57 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -727,8 +727,11 @@ ext_int_handler:
727ext_no_vtime: 727ext_no_vtime:
728 HANDLE_SIE_INTERCEPT 728 HANDLE_SIE_INTERCEPT
729 TRACE_IRQS_OFF 729 TRACE_IRQS_OFF
730 lghi %r1,4096
730 la %r2,SP_PTREGS(%r15) # address of register-save area 731 la %r2,SP_PTREGS(%r15) # address of register-save area
731 llgh %r3,__LC_EXT_INT_CODE # get interruption code 732 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
733 llgf %r4,__LC_EXT_PARAMS # get external parameter
734 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
732 brasl %r14,do_extint 735 brasl %r14,do_extint
733 j io_return 736 j io_return
734 737
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 9ce641b5291f..bd1db508e8af 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -113,12 +113,15 @@ int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
113 return 0; 113 return 0;
114} 114}
115 115
116void __irq_entry do_extint(struct pt_regs *regs, unsigned short code) 116void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
117 unsigned int param32, unsigned long param64)
117{ 118{
119 struct pt_regs *old_regs;
120 unsigned short code;
118 ext_int_info_t *p; 121 ext_int_info_t *p;
119 int index; 122 int index;
120 struct pt_regs *old_regs;
121 123
124 code = (unsigned short) ext_int_code;
122 old_regs = set_irq_regs(regs); 125 old_regs = set_irq_regs(regs);
123 s390_idle_check(regs, S390_lowcore.int_clock, 126 s390_idle_check(regs, S390_lowcore.int_clock,
124 S390_lowcore.async_enter_timer); 127 S390_lowcore.async_enter_timer);
@@ -132,7 +135,7 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
132 index = ext_hash(code); 135 index = ext_hash(code);
133 for (p = ext_int_hash[index]; p; p = p->next) { 136 for (p = ext_int_hash[index]; p; p = p->next) {
134 if (likely(p->code == code)) 137 if (likely(p->code == code))
135 p->handler(code); 138 p->handler(ext_int_code, param32, param64);
136 } 139 }
137 irq_exit(); 140 irq_exit();
138 set_irq_regs(old_regs); 141 set_irq_regs(old_regs);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8127ebd59c4d..354589d096b1 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -156,7 +156,8 @@ void smp_send_stop(void)
156 * cpus are handled. 156 * cpus are handled.
157 */ 157 */
158 158
159static void do_ext_call_interrupt(__u16 code) 159static void do_ext_call_interrupt(unsigned int ext_int_code,
160 unsigned int param32, unsigned long param64)
160{ 161{
161 unsigned long bits; 162 unsigned long bits;
162 163
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2896cac9c14a..f754a6dc4f94 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -155,7 +155,9 @@ void init_cpu_timer(void)
155 __ctl_set_bit(0, 4); 155 __ctl_set_bit(0, 4);
156} 156}
157 157
158static void clock_comparator_interrupt(__u16 code) 158static void clock_comparator_interrupt(unsigned int ext_int_code,
159 unsigned int param32,
160 unsigned long param64)
159{ 161{
160 if (S390_lowcore.clock_comparator == -1ULL) 162 if (S390_lowcore.clock_comparator == -1ULL)
161 set_clock_comparator(S390_lowcore.clock_comparator); 163 set_clock_comparator(S390_lowcore.clock_comparator);
@@ -164,14 +166,13 @@ static void clock_comparator_interrupt(__u16 code)
164static void etr_timing_alert(struct etr_irq_parm *); 166static void etr_timing_alert(struct etr_irq_parm *);
165static void stp_timing_alert(struct stp_irq_parm *); 167static void stp_timing_alert(struct stp_irq_parm *);
166 168
167static void timing_alert_interrupt(__u16 code) 169static void timing_alert_interrupt(unsigned int ext_int_code,
170 unsigned int param32, unsigned long param64)
168{ 171{
169 if (S390_lowcore.ext_params & 0x00c40000) 172 if (param32 & 0x00c40000)
170 etr_timing_alert((struct etr_irq_parm *) 173 etr_timing_alert((struct etr_irq_parm *) &param32);
171 &S390_lowcore.ext_params); 174 if (param32 & 0x00038000)
172 if (S390_lowcore.ext_params & 0x00038000) 175 stp_timing_alert((struct stp_irq_parm *) &param32);
173 stp_timing_alert((struct stp_irq_parm *)
174 &S390_lowcore.ext_params);
175} 176}
176 177
177static void etr_reset(void); 178static void etr_reset(void);
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 3479f1b0d4e0..56c8687b29b3 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -314,7 +314,8 @@ static void do_callbacks(struct list_head *cb_list)
314/* 314/*
315 * Handler for the virtual CPU timer. 315 * Handler for the virtual CPU timer.
316 */ 316 */
317static void do_cpu_timer_interrupt(__u16 error_code) 317static void do_cpu_timer_interrupt(unsigned int ext_int_code,
318 unsigned int param32, unsigned long param64)
318{ 319{
319 struct vtimer_queue *vq; 320 struct vtimer_queue *vq;
320 struct vtimer_list *event, *tmp; 321 struct vtimer_list *event, *tmp;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index b6570069b127..b4aad0c1f562 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -542,7 +542,8 @@ void pfault_fini(void)
542 : : "a" (&refbk), "m" (refbk) : "cc"); 542 : : "a" (&refbk), "m" (refbk) : "cc");
543} 543}
544 544
545static void pfault_interrupt(__u16 int_code) 545static void pfault_interrupt(unsigned int ext_int_code,
546 unsigned int param32, unsigned long param64)
546{ 547{
547 struct task_struct *tsk; 548 struct task_struct *tsk;
548 __u16 subcode; 549 __u16 subcode;
@@ -553,14 +554,18 @@ static void pfault_interrupt(__u16 int_code)
553 * in the 'cpu address' field associated with the 554 * in the 'cpu address' field associated with the
554 * external interrupt. 555 * external interrupt.
555 */ 556 */
556 subcode = S390_lowcore.cpu_addr; 557 subcode = ext_int_code >> 16;
557 if ((subcode & 0xff00) != __SUBCODE_MASK) 558 if ((subcode & 0xff00) != __SUBCODE_MASK)
558 return; 559 return;
559 560
560 /* 561 /*
561 * Get the token (= address of the task structure of the affected task). 562 * Get the token (= address of the task structure of the affected task).
562 */ 563 */
563 tsk = *(struct task_struct **) __LC_PFAULT_INTPARM; 564#ifdef CONFIG_64BIT
565 tsk = *(struct task_struct **) param64;
566#else
567 tsk = *(struct task_struct **) param32;
568#endif
564 569
565 if (subcode & 0x0080) { 570 if (subcode & 0x0080) {
566 /* signal bit is set -> a page has been swapped in by VM */ 571 /* signal bit is set -> a page has been swapped in by VM */