aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/compat_linux.c5
-rw-r--r--arch/s390/kernel/cpcmd.c83
-rw-r--r--arch/s390/kernel/ipl.c21
-rw-r--r--arch/s390/kernel/process.c5
-rw-r--r--arch/s390/kernel/semaphore.c22
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kernel/smp.c73
-rw-r--r--arch/s390/kernel/time.c10
-rw-r--r--arch/s390/kernel/traps.c3
9 files changed, 86 insertions, 138 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 91b2884fa5c4..c46e3d48e410 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -544,10 +544,7 @@ sys32_execve(struct pt_regs regs)
544 current->ptrace &= ~PT_DTRACE; 544 current->ptrace &= ~PT_DTRACE;
545 task_unlock(current); 545 task_unlock(current);
546 current->thread.fp_regs.fpc=0; 546 current->thread.fp_regs.fpc=0;
547 __asm__ __volatile__ 547 asm volatile("sfpc %0,0" : : "d" (0));
548 ("sr 0,0\n\t"
549 "sfpc 0,0\n\t"
550 : : :"0");
551 } 548 }
552 putname(filename); 549 putname(filename);
553out: 550out:
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index 4ef44e536b2c..1eae74e72f95 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -25,11 +25,8 @@ static char cpcmd_buf[241];
25 */ 25 */
26int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) 26int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
27{ 27{
28 const int mask = 0x40000000L; 28 unsigned long flags, cmdlen;
29 unsigned long flags; 29 int return_code, return_len;
30 int return_code;
31 int return_len;
32 int cmdlen;
33 30
34 spin_lock_irqsave(&cpcmd_lock, flags); 31 spin_lock_irqsave(&cpcmd_lock, flags);
35 cmdlen = strlen(cmd); 32 cmdlen = strlen(cmd);
@@ -38,64 +35,44 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
38 ASCEBC(cpcmd_buf, cmdlen); 35 ASCEBC(cpcmd_buf, cmdlen);
39 36
40 if (response != NULL && rlen > 0) { 37 if (response != NULL && rlen > 0) {
38 register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
39 register unsigned long reg3 asm ("3") = (addr_t) response;
40 register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L;
41 register unsigned long reg5 asm ("5") = rlen;
42
41 memset(response, 0, rlen); 43 memset(response, 0, rlen);
44 asm volatile(
42#ifndef CONFIG_64BIT 45#ifndef CONFIG_64BIT
43 asm volatile ( "lra 2,0(%2)\n" 46 " diag %2,%0,0x8\n"
44 "lr 4,%3\n" 47 " brc 8,1f\n"
45 "o 4,%6\n" 48 " ar %1,%4\n"
46 "lra 3,0(%4)\n"
47 "lr 5,%5\n"
48 "diag 2,4,0x8\n"
49 "brc 8, 1f\n"
50 "ar 5, %5\n"
51 "1: \n"
52 "lr %0,4\n"
53 "lr %1,5\n"
54 : "=d" (return_code), "=d" (return_len)
55 : "a" (cpcmd_buf), "d" (cmdlen),
56 "a" (response), "d" (rlen), "m" (mask)
57 : "cc", "2", "3", "4", "5" );
58#else /* CONFIG_64BIT */ 49#else /* CONFIG_64BIT */
59 asm volatile ( "lrag 2,0(%2)\n" 50 " sam31\n"
60 "lgr 4,%3\n" 51 " diag %2,%0,0x8\n"
61 "o 4,%6\n" 52 " sam64\n"
62 "lrag 3,0(%4)\n" 53 " brc 8,1f\n"
63 "lgr 5,%5\n" 54 " agr %1,%4\n"
64 "sam31\n"
65 "diag 2,4,0x8\n"
66 "sam64\n"
67 "brc 8, 1f\n"
68 "agr 5, %5\n"
69 "1: \n"
70 "lgr %0,4\n"
71 "lgr %1,5\n"
72 : "=d" (return_code), "=d" (return_len)
73 : "a" (cpcmd_buf), "d" (cmdlen),
74 "a" (response), "d" (rlen), "m" (mask)
75 : "cc", "2", "3", "4", "5" );
76#endif /* CONFIG_64BIT */ 55#endif /* CONFIG_64BIT */
56 "1:\n"
57 : "+d" (reg4), "+d" (reg5)
58 : "d" (reg2), "d" (reg3), "d" (rlen) : "cc");
59 return_code = (int) reg4;
60 return_len = (int) reg5;
77 EBCASC(response, rlen); 61 EBCASC(response, rlen);
78 } else { 62 } else {
63 register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
64 register unsigned long reg3 asm ("3") = cmdlen;
79 return_len = 0; 65 return_len = 0;
66 asm volatile(
80#ifndef CONFIG_64BIT 67#ifndef CONFIG_64BIT
81 asm volatile ( "lra 2,0(%1)\n" 68 " diag %1,%0,0x8\n"
82 "lr 3,%2\n"
83 "diag 2,3,0x8\n"
84 "lr %0,3\n"
85 : "=d" (return_code)
86 : "a" (cpcmd_buf), "d" (cmdlen)
87 : "2", "3" );
88#else /* CONFIG_64BIT */ 69#else /* CONFIG_64BIT */
89 asm volatile ( "lrag 2,0(%1)\n" 70 " sam31\n"
90 "lgr 3,%2\n" 71 " diag %1,%0,0x8\n"
91 "sam31\n" 72 " sam64\n"
92 "diag 2,3,0x8\n"
93 "sam64\n"
94 "lgr %0,3\n"
95 : "=d" (return_code)
96 : "a" (cpcmd_buf), "d" (cmdlen)
97 : "2", "3" );
98#endif /* CONFIG_64BIT */ 73#endif /* CONFIG_64BIT */
74 : "+d" (reg3) : "d" (reg2) : "cc");
75 return_code = (int) reg3;
99 } 76 }
100 spin_unlock_irqrestore(&cpcmd_lock, flags); 77 spin_unlock_irqrestore(&cpcmd_lock, flags);
101 if (response_code != NULL) 78 if (response_code != NULL)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 6555cc48e28f..1f5e782b3d05 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -120,24 +120,15 @@ static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
120 120
121static int diag308(unsigned long subcode, void *addr) 121static int diag308(unsigned long subcode, void *addr)
122{ 122{
123 register unsigned long _addr asm("0") = (unsigned long)addr; 123 register unsigned long _addr asm("0") = (unsigned long) addr;
124 register unsigned long _rc asm("1") = 0; 124 register unsigned long _rc asm("1") = 0;
125 125
126 asm volatile ( 126 asm volatile(
127 " diag %0,%2,0x308\n" 127 " diag %0,%2,0x308\n"
128 "0: \n" 128 "0:\n"
129 ".section __ex_table,\"a\"\n" 129 EX_TABLE(0b,0b)
130#ifdef CONFIG_64BIT
131 " .align 8\n"
132 " .quad 0b, 0b\n"
133#else
134 " .align 4\n"
135 " .long 0b, 0b\n"
136#endif
137 ".previous\n"
138 : "+d" (_addr), "+d" (_rc) 130 : "+d" (_addr), "+d" (_rc)
139 : "d" (subcode) : "cc", "memory" ); 131 : "d" (subcode) : "cc", "memory");
140
141 return _rc; 132 return _rc;
142} 133}
143 134
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index d3cbfa3005ec..6603fbb41d07 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -45,7 +45,7 @@
45#include <asm/irq.h> 45#include <asm/irq.h>
46#include <asm/timer.h> 46#include <asm/timer.h>
47 47
48asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 48asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
49 49
50/* 50/*
51 * Return saved PC of a blocked thread. used in kernel/sched. 51 * Return saved PC of a blocked thread. used in kernel/sched.
@@ -177,7 +177,8 @@ void show_regs(struct pt_regs *regs)
177 177
178extern void kernel_thread_starter(void); 178extern void kernel_thread_starter(void);
179 179
180__asm__(".align 4\n" 180asm(
181 ".align 4\n"
181 "kernel_thread_starter:\n" 182 "kernel_thread_starter:\n"
182 " la 2,0(10)\n" 183 " la 2,0(10)\n"
183 " basr 14,9\n" 184 " basr 14,9\n"
diff --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c
index 8dfb690c159f..191303f6c1d8 100644
--- a/arch/s390/kernel/semaphore.c
+++ b/arch/s390/kernel/semaphore.c
@@ -26,17 +26,17 @@ static inline int __sem_update_count(struct semaphore *sem, int incr)
26{ 26{
27 int old_val, new_val; 27 int old_val, new_val;
28 28
29 __asm__ __volatile__(" l %0,0(%3)\n" 29 asm volatile(
30 "0: ltr %1,%0\n" 30 " l %0,0(%3)\n"
31 " jhe 1f\n" 31 "0: ltr %1,%0\n"
32 " lhi %1,0\n" 32 " jhe 1f\n"
33 "1: ar %1,%4\n" 33 " lhi %1,0\n"
34 " cs %0,%1,0(%3)\n" 34 "1: ar %1,%4\n"
35 " jl 0b\n" 35 " cs %0,%1,0(%3)\n"
36 : "=&d" (old_val), "=&d" (new_val), 36 " jl 0b\n"
37 "=m" (sem->count) 37 : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count)
38 : "a" (&sem->count), "d" (incr), "m" (sem->count) 38 : "a" (&sem->count), "d" (incr), "m" (sem->count)
39 : "cc" ); 39 : "cc");
40 return old_val; 40 return old_val;
41} 41}
42 42
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index e3d9325f6022..a21cfbb9d97e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -101,7 +101,7 @@ void __devinit cpu_init (void)
101 /* 101 /*
102 * Store processor id in lowcore (used e.g. in timer_interrupt) 102 * Store processor id in lowcore (used e.g. in timer_interrupt)
103 */ 103 */
104 asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); 104 asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
105 S390_lowcore.cpu_data.cpu_addr = addr; 105 S390_lowcore.cpu_data.cpu_addr = addr;
106 106
107 /* 107 /*
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b2e6f4c8d382..a8e6199755d4 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -63,7 +63,7 @@ static void smp_ext_bitcall(int, ec_bit_sig);
63static void smp_ext_bitcall_others(ec_bit_sig); 63static void smp_ext_bitcall_others(ec_bit_sig);
64 64
65/* 65/*
66 * Structure and data for smp_call_function(). This is designed to minimise 665B * Structure and data for smp_call_function(). This is designed to minimise
67 * static memory requirements. It also looks cleaner. 67 * static memory requirements. It also looks cleaner.
68 */ 68 */
69static DEFINE_SPINLOCK(call_lock); 69static DEFINE_SPINLOCK(call_lock);
@@ -418,59 +418,49 @@ void smp_send_reschedule(int cpu)
418/* 418/*
419 * parameter area for the set/clear control bit callbacks 419 * parameter area for the set/clear control bit callbacks
420 */ 420 */
421typedef struct 421struct ec_creg_mask_parms {
422{
423 __u16 start_ctl;
424 __u16 end_ctl;
425 unsigned long orvals[16]; 422 unsigned long orvals[16];
426 unsigned long andvals[16]; 423 unsigned long andvals[16];
427} ec_creg_mask_parms; 424};
428 425
429/* 426/*
430 * callback for setting/clearing control bits 427 * callback for setting/clearing control bits
431 */ 428 */
432void smp_ctl_bit_callback(void *info) { 429void smp_ctl_bit_callback(void *info) {
433 ec_creg_mask_parms *pp; 430 struct ec_creg_mask_parms *pp = info;
434 unsigned long cregs[16]; 431 unsigned long cregs[16];
435 int i; 432 int i;
436 433
437 pp = (ec_creg_mask_parms *) info; 434 __ctl_store(cregs, 0, 15);
438 __ctl_store(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); 435 for (i = 0; i <= 15; i++)
439 for (i = pp->start_ctl; i <= pp->end_ctl; i++)
440 cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i]; 436 cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i];
441 __ctl_load(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); 437 __ctl_load(cregs, 0, 15);
442} 438}
443 439
444/* 440/*
445 * Set a bit in a control register of all cpus 441 * Set a bit in a control register of all cpus
446 */ 442 */
447void smp_ctl_set_bit(int cr, int bit) { 443void smp_ctl_set_bit(int cr, int bit)
448 ec_creg_mask_parms parms; 444{
445 struct ec_creg_mask_parms parms;
449 446
450 parms.start_ctl = cr; 447 memset(&parms.orvals, 0, sizeof(parms.orvals));
451 parms.end_ctl = cr; 448 memset(&parms.andvals, 0xff, sizeof(parms.andvals));
452 parms.orvals[cr] = 1 << bit; 449 parms.orvals[cr] = 1 << bit;
453 parms.andvals[cr] = -1L; 450 on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1);
454 preempt_disable();
455 smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
456 __ctl_set_bit(cr, bit);
457 preempt_enable();
458} 451}
459 452
460/* 453/*
461 * Clear a bit in a control register of all cpus 454 * Clear a bit in a control register of all cpus
462 */ 455 */
463void smp_ctl_clear_bit(int cr, int bit) { 456void smp_ctl_clear_bit(int cr, int bit)
464 ec_creg_mask_parms parms; 457{
458 struct ec_creg_mask_parms parms;
465 459
466 parms.start_ctl = cr; 460 memset(&parms.orvals, 0, sizeof(parms.orvals));
467 parms.end_ctl = cr; 461 memset(&parms.andvals, 0xff, sizeof(parms.andvals));
468 parms.orvals[cr] = 0;
469 parms.andvals[cr] = ~(1L << bit); 462 parms.andvals[cr] = ~(1L << bit);
470 preempt_disable(); 463 on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1);
471 smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
472 __ctl_clear_bit(cr, bit);
473 preempt_enable();
474} 464}
475 465
476/* 466/*
@@ -650,9 +640,9 @@ __cpu_up(unsigned int cpu)
650 sf->gprs[9] = (unsigned long) sf; 640 sf->gprs[9] = (unsigned long) sf;
651 cpu_lowcore->save_area[15] = (unsigned long) sf; 641 cpu_lowcore->save_area[15] = (unsigned long) sf;
652 __ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15); 642 __ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15);
653 __asm__ __volatile__("stam 0,15,0(%0)" 643 asm volatile(
654 : : "a" (&cpu_lowcore->access_regs_save_area) 644 " stam 0,15,0(%0)"
655 : "memory"); 645 : : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
656 cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; 646 cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
657 cpu_lowcore->current_task = (unsigned long) idle; 647 cpu_lowcore->current_task = (unsigned long) idle;
658 cpu_lowcore->cpu_data.cpu_nr = cpu; 648 cpu_lowcore->cpu_data.cpu_nr = cpu;
@@ -708,7 +698,7 @@ int
708__cpu_disable(void) 698__cpu_disable(void)
709{ 699{
710 unsigned long flags; 700 unsigned long flags;
711 ec_creg_mask_parms cr_parms; 701 struct ec_creg_mask_parms cr_parms;
712 int cpu = smp_processor_id(); 702 int cpu = smp_processor_id();
713 703
714 spin_lock_irqsave(&smp_reserve_lock, flags); 704 spin_lock_irqsave(&smp_reserve_lock, flags);
@@ -724,30 +714,21 @@ __cpu_disable(void)
724 pfault_fini(); 714 pfault_fini();
725#endif 715#endif
726 716
727 /* disable all external interrupts */ 717 memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals));
718 memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals));
728 719
729 cr_parms.start_ctl = 0; 720 /* disable all external interrupts */
730 cr_parms.end_ctl = 0;
731 cr_parms.orvals[0] = 0; 721 cr_parms.orvals[0] = 0;
732 cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 | 722 cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 |
733 1<<11 | 1<<10 | 1<< 6 | 1<< 4); 723 1<<11 | 1<<10 | 1<< 6 | 1<< 4);
734 smp_ctl_bit_callback(&cr_parms);
735
736 /* disable all I/O interrupts */ 724 /* disable all I/O interrupts */
737
738 cr_parms.start_ctl = 6;
739 cr_parms.end_ctl = 6;
740 cr_parms.orvals[6] = 0; 725 cr_parms.orvals[6] = 0;
741 cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 | 726 cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 |
742 1<<27 | 1<<26 | 1<<25 | 1<<24); 727 1<<27 | 1<<26 | 1<<25 | 1<<24);
743 smp_ctl_bit_callback(&cr_parms);
744
745 /* disable most machine checks */ 728 /* disable most machine checks */
746
747 cr_parms.start_ctl = 14;
748 cr_parms.end_ctl = 14;
749 cr_parms.orvals[14] = 0; 729 cr_parms.orvals[14] = 0;
750 cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24); 730 cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24);
731
751 smp_ctl_bit_callback(&cr_parms); 732 smp_ctl_bit_callback(&cr_parms);
752 733
753 spin_unlock_irqrestore(&smp_reserve_lock, flags); 734 spin_unlock_irqrestore(&smp_reserve_lock, flags);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 74e6178fbaf2..1981c6199fa2 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -351,10 +351,12 @@ void __init time_init(void)
351 int cc; 351 int cc;
352 352
353 /* kick the TOD clock */ 353 /* kick the TOD clock */
354 asm volatile ("STCK 0(%1)\n\t" 354 asm volatile(
355 "IPM %0\n\t" 355 " stck 0(%2)\n"
356 "SRL %0,28" : "=r" (cc) : "a" (&init_timer_cc) 356 " ipm %0\n"
357 : "memory", "cc"); 357 " srl %0,28"
358 : "=d" (cc), "=m" (init_timer_cc)
359 : "a" (&init_timer_cc) : "cc");
358 switch (cc) { 360 switch (cc) {
359 case 0: /* clock in set state: all is fine */ 361 case 0: /* clock in set state: all is fine */
360 break; 362 break;
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index c4982c963424..3eb4fab048b8 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -597,8 +597,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
597 local_irq_enable(); 597 local_irq_enable();
598 598
599 if (MACHINE_HAS_IEEE) 599 if (MACHINE_HAS_IEEE)
600 __asm__ volatile ("stfpc %0\n\t" 600 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
601 : "=m" (current->thread.fp_regs.fpc));
602 601
603#ifdef CONFIG_MATHEMU 602#ifdef CONFIG_MATHEMU
604 else if (regs->psw.mask & PSW_MASK_PSTATE) { 603 else if (regs->psw.mask & PSW_MASK_PSTATE) {