aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/Kconfig8
-rw-r--r--arch/s390/include/asm/atomic.h7
-rw-r--r--arch/s390/include/asm/kvm_host.h4
-rw-r--r--arch/s390/include/asm/perf_counter.h2
-rw-r--r--arch/s390/include/asm/thread_info.h2
-rw-r--r--arch/s390/kernel/ipl.c15
-rw-r--r--arch/s390/kvm/kvm-s390.c23
-rw-r--r--arch/s390/kvm/priv.c2
-rw-r--r--arch/s390/lib/Makefile2
-rw-r--r--arch/s390/lib/delay.c2
-rw-r--r--arch/s390/lib/ucmpdi2.c26
11 files changed, 81 insertions, 12 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index e577839f3073..2ae5d72f47ed 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -95,6 +95,11 @@ config S390
95 select HAVE_ARCH_TRACEHOOK 95 select HAVE_ARCH_TRACEHOOK
96 select INIT_ALL_POSSIBLE 96 select INIT_ALL_POSSIBLE
97 select HAVE_PERF_COUNTERS 97 select HAVE_PERF_COUNTERS
98 select GENERIC_ATOMIC64 if !64BIT
99
100config SCHED_OMIT_FRAME_POINTER
101 bool
102 default y
98 103
99source "init/Kconfig" 104source "init/Kconfig"
100 105
@@ -116,6 +121,9 @@ config 32BIT
116 bool 121 bool
117 default y if !64BIT 122 default y if !64BIT
118 123
124config KTIME_SCALAR
125 def_bool 32BIT
126
119config SMP 127config SMP
120 bool "Symmetric multi-processing support" 128 bool "Symmetric multi-processing support"
121 ---help--- 129 ---help---
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
index fca9dffcc669..c7d0abfb0f00 100644
--- a/arch/s390/include/asm/atomic.h
+++ b/arch/s390/include/asm/atomic.h
@@ -268,7 +268,12 @@ static __inline__ int atomic64_add_unless(atomic64_t *v,
268#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) 268#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
269 269
270#undef __CSG_LOOP 270#undef __CSG_LOOP
271#endif 271
272#else /* __s390x__ */
273
274#include <asm-generic/atomic64.h>
275
276#endif /* __s390x__ */
272 277
273#define smp_mb__before_atomic_dec() smp_mb() 278#define smp_mb__before_atomic_dec() smp_mb()
274#define smp_mb__after_atomic_dec() smp_mb() 279#define smp_mb__after_atomic_dec() smp_mb()
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index a27d0d5a6f86..1cd02f6073a0 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -99,7 +99,9 @@ struct kvm_s390_sie_block {
99 __u8 reservedd0[48]; /* 0x00d0 */ 99 __u8 reservedd0[48]; /* 0x00d0 */
100 __u64 gcr[16]; /* 0x0100 */ 100 __u64 gcr[16]; /* 0x0100 */
101 __u64 gbea; /* 0x0180 */ 101 __u64 gbea; /* 0x0180 */
102 __u8 reserved188[120]; /* 0x0188 */ 102 __u8 reserved188[24]; /* 0x0188 */
103 __u32 fac; /* 0x01a0 */
104 __u8 reserved1a4[92]; /* 0x01a4 */
103} __attribute__((packed)); 105} __attribute__((packed));
104 106
105struct kvm_vcpu_stat { 107struct kvm_vcpu_stat {
diff --git a/arch/s390/include/asm/perf_counter.h b/arch/s390/include/asm/perf_counter.h
index a7205a3828cb..7015188c2cc2 100644
--- a/arch/s390/include/asm/perf_counter.h
+++ b/arch/s390/include/asm/perf_counter.h
@@ -6,3 +6,5 @@
6 6
7static inline void set_perf_counter_pending(void) {} 7static inline void set_perf_counter_pending(void) {}
8static inline void clear_perf_counter_pending(void) {} 8static inline void clear_perf_counter_pending(void) {}
9
10#define PERF_COUNTER_INDEX_OFFSET 0
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 925bcc649035..ba1cab9fc1f9 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -61,7 +61,7 @@ struct thread_info {
61 .exec_domain = &default_exec_domain, \ 61 .exec_domain = &default_exec_domain, \
62 .flags = 0, \ 62 .flags = 0, \
63 .cpu = 0, \ 63 .cpu = 0, \
64 .preempt_count = 1, \ 64 .preempt_count = INIT_PREEMPT_COUNT, \
65 .restart_block = { \ 65 .restart_block = { \
66 .fn = do_no_restart_syscall, \ 66 .fn = do_no_restart_syscall, \
67 }, \ 67 }, \
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index b8bf4b140065..371a2d88f4ac 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -70,6 +70,7 @@ struct shutdown_action {
70 char *name; 70 char *name;
71 void (*fn) (struct shutdown_trigger *trigger); 71 void (*fn) (struct shutdown_trigger *trigger);
72 int (*init) (void); 72 int (*init) (void);
73 int init_rc;
73}; 74};
74 75
75static char *ipl_type_str(enum ipl_type type) 76static char *ipl_type_str(enum ipl_type type)
@@ -1486,11 +1487,13 @@ static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
1486 int i; 1487 int i;
1487 1488
1488 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { 1489 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1489 if (!shutdown_actions_list[i])
1490 continue;
1491 if (sysfs_streq(buf, shutdown_actions_list[i]->name)) { 1490 if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
1492 trigger->action = shutdown_actions_list[i]; 1491 if (shutdown_actions_list[i]->init_rc) {
1493 return len; 1492 return shutdown_actions_list[i]->init_rc;
1493 } else {
1494 trigger->action = shutdown_actions_list[i];
1495 return len;
1496 }
1494 } 1497 }
1495 } 1498 }
1496 return -EINVAL; 1499 return -EINVAL;
@@ -1640,8 +1643,8 @@ static void __init shutdown_actions_init(void)
1640 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { 1643 for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1641 if (!shutdown_actions_list[i]->init) 1644 if (!shutdown_actions_list[i]->init)
1642 continue; 1645 continue;
1643 if (shutdown_actions_list[i]->init()) 1646 shutdown_actions_list[i]->init_rc =
1644 shutdown_actions_list[i] = NULL; 1647 shutdown_actions_list[i]->init();
1645 } 1648 }
1646} 1649}
1647 1650
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index c18b21d6991c..90d9d1ba258b 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -25,6 +25,7 @@
25#include <asm/lowcore.h> 25#include <asm/lowcore.h>
26#include <asm/pgtable.h> 26#include <asm/pgtable.h>
27#include <asm/nmi.h> 27#include <asm/nmi.h>
28#include <asm/system.h>
28#include "kvm-s390.h" 29#include "kvm-s390.h"
29#include "gaccess.h" 30#include "gaccess.h"
30 31
@@ -69,6 +70,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
69 { NULL } 70 { NULL }
70}; 71};
71 72
73static unsigned long long *facilities;
72 74
73/* Section: not file related */ 75/* Section: not file related */
74void kvm_arch_hardware_enable(void *garbage) 76void kvm_arch_hardware_enable(void *garbage)
@@ -288,6 +290,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
288 vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; 290 vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
289 vcpu->arch.sie_block->ecb = 2; 291 vcpu->arch.sie_block->ecb = 2;
290 vcpu->arch.sie_block->eca = 0xC1002001U; 292 vcpu->arch.sie_block->eca = 0xC1002001U;
293 vcpu->arch.sie_block->fac = (int) (long) facilities;
291 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); 294 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
292 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, 295 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
293 (unsigned long) vcpu); 296 (unsigned long) vcpu);
@@ -739,11 +742,29 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
739 742
740static int __init kvm_s390_init(void) 743static int __init kvm_s390_init(void)
741{ 744{
742 return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); 745 int ret;
746 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
747 if (ret)
748 return ret;
749
750 /*
751 * guests can ask for up to 255+1 double words, we need a full page
752 * to hold the maximum amount of facilites. On the other hand, we
753 * only set facilities that are known to work in KVM.
754 */
755 facilities = (unsigned long long *) get_zeroed_page(GFP_DMA);
756 if (!facilities) {
757 kvm_exit();
758 return -ENOMEM;
759 }
760 stfle(facilities, 1);
761 facilities[0] &= 0xff00fff3f0700000ULL;
762 return 0;
743} 763}
744 764
745static void __exit kvm_s390_exit(void) 765static void __exit kvm_s390_exit(void)
746{ 766{
767 free_page((unsigned long) facilities);
747 kvm_exit(); 768 kvm_exit();
748} 769}
749 770
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 93ecd06e1a74..d426aac8095d 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -158,7 +158,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
158 158
159 vcpu->stat.instruction_stfl++; 159 vcpu->stat.instruction_stfl++;
160 /* only pass the facility bits, which we can handle */ 160 /* only pass the facility bits, which we can handle */
161 facility_list &= 0xfe00fff3; 161 facility_list &= 0xff00fff3;
162 162
163 rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), 163 rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
164 &facility_list, sizeof(facility_list)); 164 &facility_list, sizeof(facility_list));
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index ab6735df2d21..97975ec7a274 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o 5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
6obj-$(CONFIG_32BIT) += div64.o qrnnd.o 6obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
7lib-$(CONFIG_64BIT) += uaccess_mvcos.o 7lib-$(CONFIG_64BIT) += uaccess_mvcos.o
8lib-$(CONFIG_SMP) += spinlock.o 8lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index 3f5f680726ed..97c1eca83cc2 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -36,9 +36,11 @@ static void __udelay_disabled(unsigned long usecs)
36 cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; 36 cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
37 __ctl_load(cr0 , 0, 0); 37 __ctl_load(cr0 , 0, 0);
38 mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; 38 mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
39 lockdep_off();
39 trace_hardirqs_on(); 40 trace_hardirqs_on();
40 __load_psw_mask(mask); 41 __load_psw_mask(mask);
41 local_irq_disable(); 42 local_irq_disable();
43 lockdep_on();
42 __ctl_load(cr0_saved, 0, 0); 44 __ctl_load(cr0_saved, 0, 0);
43 local_tick_enable(clock_saved); 45 local_tick_enable(clock_saved);
44 set_clock_comparator(S390_lowcore.clock_comparator); 46 set_clock_comparator(S390_lowcore.clock_comparator);
diff --git a/arch/s390/lib/ucmpdi2.c b/arch/s390/lib/ucmpdi2.c
new file mode 100644
index 000000000000..3e05ff532582
--- /dev/null
+++ b/arch/s390/lib/ucmpdi2.c
@@ -0,0 +1,26 @@
1#include <linux/module.h>
2
3union ull_union {
4 unsigned long long ull;
5 struct {
6 unsigned int high;
7 unsigned int low;
8 } ui;
9};
10
11int __ucmpdi2(unsigned long long a, unsigned long long b)
12{
13 union ull_union au = {.ull = a};
14 union ull_union bu = {.ull = b};
15
16 if (au.ui.high < bu.ui.high)
17 return 0;
18 else if (au.ui.high > bu.ui.high)
19 return 2;
20 if (au.ui.low < bu.ui.low)
21 return 0;
22 else if (au.ui.low > bu.ui.low)
23 return 2;
24 return 1;
25}
26EXPORT_SYMBOL(__ucmpdi2);