aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 21:47:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 21:47:00 -0400
commit1ee07ef6b5db7235b133ee257a3adf507697e6b3 (patch)
tree9c7a00cf98462c2a70610da9d09770c835ef8fcd /arch/s390/include
parent77654908ff1a58cee4886298968b5262884aff0b (diff)
parent0cccdda8d1512af4d3f6913044e8c8e58e15ef37 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "This patch set contains the main portion of the changes for 3.18 in regard to the s390 architecture. It is a bit bigger than usual, mainly because of a new driver and the vector extension patches. The interesting bits are: - Quite a bit of work on the tracing front. Uprobes is enabled and the ftrace code is reworked to get some of the lost performance back if CONFIG_FTRACE is enabled. - To improve boot time with CONFIG_DEBIG_PAGEALLOC, support for the IPTE range facility is added. - The rwlock code is re-factored to improve writer fairness and to be able to use the interlocked-access instructions. - The kernel part for the support of the vector extension is added. - The device driver to access the CD/DVD on the HMC is added, this will hopefully come in handy to improve the installation process. - Add support for control-unit initiated reconfiguration. - The crypto device driver is enhanced to enable the additional AP domains and to allow the new crypto hardware to be used. - Bug fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (39 commits) s390/ftrace: simplify enabling/disabling of ftrace_graph_caller s390/ftrace: remove 31 bit ftrace support s390/kdump: add support for vector extension s390/disassembler: add vector instructions s390: add support for vector extension s390/zcrypt: Toleration of new crypto hardware s390/idle: consolidate idle functions and definitions s390/nohz: use a per-cpu flag for arch_needs_cpu s390/vtime: do not reset idle data on CPU hotplug s390/dasd: add support for control unit initiated reconfiguration s390/dasd: fix infinite loop during format s390/mm: make use of ipte range facility s390/setup: correct 4-level kernel page table detection s390/topology: call set_sched_topology early s390/uprobes: architecture backend for uprobes s390/uprobes: common library for kprobes and uprobes s390/rwlock: use the interlocked-access facility 1 instructions s390/rwlock: improve writer fairness s390/rwlock: remove interrupt-enabling rwlock variant. s390/mm: remove change bit override support ...
Diffstat (limited to 'arch/s390/include')
-rw-r--r--arch/s390/include/asm/barrier.h6
-rw-r--r--arch/s390/include/asm/cputime.h26
-rw-r--r--arch/s390/include/asm/dis.h13
-rw-r--r--arch/s390/include/asm/elf.h3
-rw-r--r--arch/s390/include/asm/ftrace.h9
-rw-r--r--arch/s390/include/asm/idle.h26
-rw-r--r--arch/s390/include/asm/ipl.h4
-rw-r--r--arch/s390/include/asm/irq.h1
-rw-r--r--arch/s390/include/asm/kprobes.h4
-rw-r--r--arch/s390/include/asm/lowcore.h21
-rw-r--r--arch/s390/include/asm/nmi.h2
-rw-r--r--arch/s390/include/asm/pgtable.h25
-rw-r--r--arch/s390/include/asm/processor.h12
-rw-r--r--arch/s390/include/asm/ptrace.h6
-rw-r--r--arch/s390/include/asm/setup.h6
-rw-r--r--arch/s390/include/asm/sigp.h6
-rw-r--r--arch/s390/include/asm/smp.h2
-rw-r--r--arch/s390/include/asm/spinlock.h135
-rw-r--r--arch/s390/include/asm/spinlock_types.h1
-rw-r--r--arch/s390/include/asm/switch_to.h61
-rw-r--r--arch/s390/include/asm/thread_info.h3
-rw-r--r--arch/s390/include/asm/uprobes.h42
-rw-r--r--arch/s390/include/asm/vdso.h18
-rw-r--r--arch/s390/include/asm/vtimer.h2
-rw-r--r--arch/s390/include/uapi/asm/sigcontext.h20
-rw-r--r--arch/s390/include/uapi/asm/types.h4
-rw-r--r--arch/s390/include/uapi/asm/ucontext.h15
27 files changed, 368 insertions, 105 deletions
diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
index 19ff956b752b..b5dce6544d76 100644
--- a/arch/s390/include/asm/barrier.h
+++ b/arch/s390/include/asm/barrier.h
@@ -15,11 +15,13 @@
15 15
16#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES 16#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
17/* Fast-BCR without checkpoint synchronization */ 17/* Fast-BCR without checkpoint synchronization */
18#define mb() do { asm volatile("bcr 14,0" : : : "memory"); } while (0) 18#define __ASM_BARRIER "bcr 14,0\n"
19#else 19#else
20#define mb() do { asm volatile("bcr 15,0" : : : "memory"); } while (0) 20#define __ASM_BARRIER "bcr 15,0\n"
21#endif 21#endif
22 22
23#define mb() do { asm volatile(__ASM_BARRIER : : : "memory"); } while (0)
24
23#define rmb() mb() 25#define rmb() mb()
24#define wmb() mb() 26#define wmb() mb()
25#define read_barrier_depends() do { } while(0) 27#define read_barrier_depends() do { } while(0)
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index 3001887f94b7..f8c196984853 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -8,8 +8,6 @@
8#define _S390_CPUTIME_H 8#define _S390_CPUTIME_H
9 9
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/percpu.h>
12#include <linux/spinlock.h>
13#include <asm/div64.h> 11#include <asm/div64.h>
14 12
15 13
@@ -167,28 +165,8 @@ static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
167 return clock; 165 return clock;
168} 166}
169 167
170struct s390_idle_data { 168cputime64_t arch_cpu_idle_time(int cpu);
171 int nohz_delay;
172 unsigned int sequence;
173 unsigned long long idle_count;
174 unsigned long long idle_time;
175 unsigned long long clock_idle_enter;
176 unsigned long long clock_idle_exit;
177 unsigned long long timer_idle_enter;
178 unsigned long long timer_idle_exit;
179};
180 169
181DECLARE_PER_CPU(struct s390_idle_data, s390_idle); 170#define arch_idle_time(cpu) arch_cpu_idle_time(cpu)
182
183cputime64_t s390_get_idle_time(int cpu);
184
185#define arch_idle_time(cpu) s390_get_idle_time(cpu)
186
187static inline int s390_nohz_delay(int cpu)
188{
189 return __get_cpu_var(s390_idle).nohz_delay != 0;
190}
191
192#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)
193 171
194#endif /* _S390_CPUTIME_H */ 172#endif /* _S390_CPUTIME_H */
diff --git a/arch/s390/include/asm/dis.h b/arch/s390/include/asm/dis.h
index 04a83f5773cd..60323c21938b 100644
--- a/arch/s390/include/asm/dis.h
+++ b/arch/s390/include/asm/dis.h
@@ -13,12 +13,13 @@
13#define OPERAND_FPR 0x2 /* Operand printed as %fx */ 13#define OPERAND_FPR 0x2 /* Operand printed as %fx */
14#define OPERAND_AR 0x4 /* Operand printed as %ax */ 14#define OPERAND_AR 0x4 /* Operand printed as %ax */
15#define OPERAND_CR 0x8 /* Operand printed as %cx */ 15#define OPERAND_CR 0x8 /* Operand printed as %cx */
16#define OPERAND_DISP 0x10 /* Operand printed as displacement */ 16#define OPERAND_VR 0x10 /* Operand printed as %vx */
17#define OPERAND_BASE 0x20 /* Operand printed as base register */ 17#define OPERAND_DISP 0x20 /* Operand printed as displacement */
18#define OPERAND_INDEX 0x40 /* Operand printed as index register */ 18#define OPERAND_BASE 0x40 /* Operand printed as base register */
19#define OPERAND_PCREL 0x80 /* Operand printed as pc-relative symbol */ 19#define OPERAND_INDEX 0x80 /* Operand printed as index register */
20#define OPERAND_SIGNED 0x100 /* Operand printed as signed value */ 20#define OPERAND_PCREL 0x100 /* Operand printed as pc-relative symbol */
21#define OPERAND_LENGTH 0x200 /* Operand printed as length (+1) */ 21#define OPERAND_SIGNED 0x200 /* Operand printed as signed value */
22#define OPERAND_LENGTH 0x400 /* Operand printed as length (+1) */
22 23
23 24
24struct s390_operand { 25struct s390_operand {
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 78f4f8711d58..f6e43d39e3d8 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -102,6 +102,7 @@
102#define HWCAP_S390_ETF3EH 256 102#define HWCAP_S390_ETF3EH 256
103#define HWCAP_S390_HIGH_GPRS 512 103#define HWCAP_S390_HIGH_GPRS 512
104#define HWCAP_S390_TE 1024 104#define HWCAP_S390_TE 1024
105#define HWCAP_S390_VXRS 2048
105 106
106/* 107/*
107 * These are used to set parameters in the core dumps. 108 * These are used to set parameters in the core dumps.
@@ -225,6 +226,6 @@ int arch_setup_additional_pages(struct linux_binprm *, int);
225extern unsigned long arch_randomize_brk(struct mm_struct *mm); 226extern unsigned long arch_randomize_brk(struct mm_struct *mm);
226#define arch_randomize_brk arch_randomize_brk 227#define arch_randomize_brk arch_randomize_brk
227 228
228void *fill_cpu_elf_notes(void *ptr, struct save_area *sa); 229void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vxrs);
229 230
230#endif 231#endif
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
index bf246dae1367..3aef8afec336 100644
--- a/arch/s390/include/asm/ftrace.h
+++ b/arch/s390/include/asm/ftrace.h
@@ -4,6 +4,7 @@
4#ifndef __ASSEMBLY__ 4#ifndef __ASSEMBLY__
5 5
6extern void _mcount(void); 6extern void _mcount(void);
7extern char ftrace_graph_caller_end;
7 8
8struct dyn_arch_ftrace { }; 9struct dyn_arch_ftrace { };
9 10
@@ -17,10 +18,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
17 18
18#endif /* __ASSEMBLY__ */ 19#endif /* __ASSEMBLY__ */
19 20
20#ifdef CONFIG_64BIT 21#define MCOUNT_INSN_SIZE 18
21#define MCOUNT_INSN_SIZE 12 22
22#else 23#define ARCH_SUPPORTS_FTRACE_OPS 1
23#define MCOUNT_INSN_SIZE 22
24#endif
25 24
26#endif /* _ASM_S390_FTRACE_H */ 25#endif /* _ASM_S390_FTRACE_H */
diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h
new file mode 100644
index 000000000000..6af037f574b8
--- /dev/null
+++ b/arch/s390/include/asm/idle.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright IBM Corp. 2014
3 *
4 * Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
5 */
6
7#ifndef _S390_IDLE_H
8#define _S390_IDLE_H
9
10#include <linux/types.h>
11#include <linux/device.h>
12
13struct s390_idle_data {
14 unsigned int sequence;
15 unsigned long long idle_count;
16 unsigned long long idle_time;
17 unsigned long long clock_idle_enter;
18 unsigned long long clock_idle_exit;
19 unsigned long long timer_idle_enter;
20 unsigned long long timer_idle_exit;
21};
22
23extern struct device_attribute dev_attr_idle_count;
24extern struct device_attribute dev_attr_idle_time_us;
25
26#endif /* _S390_IDLE_H */
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index c81661e756a0..ece606c2ee86 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -89,12 +89,12 @@ extern u32 ipl_flags;
89extern u32 dump_prefix_page; 89extern u32 dump_prefix_page;
90 90
91struct dump_save_areas { 91struct dump_save_areas {
92 struct save_area **areas; 92 struct save_area_ext **areas;
93 int count; 93 int count;
94}; 94};
95 95
96extern struct dump_save_areas dump_save_areas; 96extern struct dump_save_areas dump_save_areas;
97struct save_area *dump_save_area_create(int cpu); 97struct save_area_ext *dump_save_area_create(int cpu);
98 98
99extern void do_reipl(void); 99extern void do_reipl(void);
100extern void do_halt(void); 100extern void do_halt(void);
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index c4dd400a2791..e787cc1bff8f 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -51,6 +51,7 @@ enum interruption_class {
51 IRQEXT_CMS, 51 IRQEXT_CMS,
52 IRQEXT_CMC, 52 IRQEXT_CMC,
53 IRQEXT_CMR, 53 IRQEXT_CMR,
54 IRQEXT_FTP,
54 IRQIO_CIO, 55 IRQIO_CIO,
55 IRQIO_QAI, 56 IRQIO_QAI,
56 IRQIO_DAS, 57 IRQIO_DAS,
diff --git a/arch/s390/include/asm/kprobes.h b/arch/s390/include/asm/kprobes.h
index 4176dfe0fba1..98629173ce3b 100644
--- a/arch/s390/include/asm/kprobes.h
+++ b/arch/s390/include/asm/kprobes.h
@@ -84,6 +84,10 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
84int kprobe_exceptions_notify(struct notifier_block *self, 84int kprobe_exceptions_notify(struct notifier_block *self,
85 unsigned long val, void *data); 85 unsigned long val, void *data);
86 86
87int probe_is_prohibited_opcode(u16 *insn);
88int probe_get_fixup_type(u16 *insn);
89int probe_is_insn_relative_long(u16 *insn);
90
87#define flush_insn_slot(p) do { } while (0) 91#define flush_insn_slot(p) do { } while (0)
88 92
89#endif /* _ASM_S390_KPROBES_H */ 93#endif /* _ASM_S390_KPROBES_H */
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 4349197ab9df..6cc51fe84410 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -11,6 +11,7 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <asm/ptrace.h> 12#include <asm/ptrace.h>
13#include <asm/cpu.h> 13#include <asm/cpu.h>
14#include <asm/types.h>
14 15
15#ifdef CONFIG_32BIT 16#ifdef CONFIG_32BIT
16 17
@@ -31,6 +32,11 @@ struct save_area {
31 u32 ctrl_regs[16]; 32 u32 ctrl_regs[16];
32} __packed; 33} __packed;
33 34
35struct save_area_ext {
36 struct save_area sa;
37 __vector128 vx_regs[32];
38};
39
34struct _lowcore { 40struct _lowcore {
35 psw_t restart_psw; /* 0x0000 */ 41 psw_t restart_psw; /* 0x0000 */
36 psw_t restart_old_psw; /* 0x0008 */ 42 psw_t restart_old_psw; /* 0x0008 */
@@ -183,6 +189,11 @@ struct save_area {
183 u64 ctrl_regs[16]; 189 u64 ctrl_regs[16];
184} __packed; 190} __packed;
185 191
192struct save_area_ext {
193 struct save_area sa;
194 __vector128 vx_regs[32];
195};
196
186struct _lowcore { 197struct _lowcore {
187 __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */ 198 __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */
188 __u32 ipl_parmblock_ptr; /* 0x0014 */ 199 __u32 ipl_parmblock_ptr; /* 0x0014 */
@@ -310,7 +321,10 @@ struct _lowcore {
310 321
311 /* Extended facility list */ 322 /* Extended facility list */
312 __u64 stfle_fac_list[32]; /* 0x0f00 */ 323 __u64 stfle_fac_list[32]; /* 0x0f00 */
313 __u8 pad_0x1000[0x11b8-0x1000]; /* 0x1000 */ 324 __u8 pad_0x1000[0x11b0-0x1000]; /* 0x1000 */
325
326 /* Pointer to vector register save area */
327 __u64 vector_save_area_addr; /* 0x11b0 */
314 328
315 /* 64 bit extparam used for pfault/diag 250: defined by architecture */ 329 /* 64 bit extparam used for pfault/diag 250: defined by architecture */
316 __u64 ext_params2; /* 0x11B8 */ 330 __u64 ext_params2; /* 0x11B8 */
@@ -334,9 +348,10 @@ struct _lowcore {
334 348
335 /* Transaction abort diagnostic block */ 349 /* Transaction abort diagnostic block */
336 __u8 pgm_tdb[256]; /* 0x1800 */ 350 __u8 pgm_tdb[256]; /* 0x1800 */
351 __u8 pad_0x1900[0x1c00-0x1900]; /* 0x1900 */
337 352
338 /* align to the top of the prefix area */ 353 /* Software defined save area for vector registers */
339 __u8 pad_0x1900[0x2000-0x1900]; /* 0x1900 */ 354 __u8 vector_save_area[1024]; /* 0x1c00 */
340} __packed; 355} __packed;
341 356
342#endif /* CONFIG_32BIT */ 357#endif /* CONFIG_32BIT */
diff --git a/arch/s390/include/asm/nmi.h b/arch/s390/include/asm/nmi.h
index 35f8ec185616..3027a5a72b74 100644
--- a/arch/s390/include/asm/nmi.h
+++ b/arch/s390/include/asm/nmi.h
@@ -38,7 +38,7 @@ struct mci {
38 __u32 pm : 1; /* 22 psw program mask and cc validity */ 38 __u32 pm : 1; /* 22 psw program mask and cc validity */
39 __u32 ia : 1; /* 23 psw instruction address validity */ 39 __u32 ia : 1; /* 23 psw instruction address validity */
40 __u32 fa : 1; /* 24 failing storage address validity */ 40 __u32 fa : 1; /* 24 failing storage address validity */
41 __u32 : 1; /* 25 */ 41 __u32 vr : 1; /* 25 vector register validity */
42 __u32 ec : 1; /* 26 external damage code validity */ 42 __u32 ec : 1; /* 26 external damage code validity */
43 __u32 fp : 1; /* 27 floating point register validity */ 43 __u32 fp : 1; /* 27 floating point register validity */
44 __u32 gr : 1; /* 28 general register validity */ 44 __u32 gr : 1; /* 28 general register validity */
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index b7054356cc98..57c882761dea 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -217,7 +217,6 @@ extern unsigned long MODULES_END;
217 */ 217 */
218 218
219/* Hardware bits in the page table entry */ 219/* Hardware bits in the page table entry */
220#define _PAGE_CO 0x100 /* HW Change-bit override */
221#define _PAGE_PROTECT 0x200 /* HW read-only bit */ 220#define _PAGE_PROTECT 0x200 /* HW read-only bit */
222#define _PAGE_INVALID 0x400 /* HW invalid bit */ 221#define _PAGE_INVALID 0x400 /* HW invalid bit */
223#define _PAGE_LARGE 0x800 /* Bit to mark a large pte */ 222#define _PAGE_LARGE 0x800 /* Bit to mark a large pte */
@@ -234,8 +233,8 @@ extern unsigned long MODULES_END;
234#define __HAVE_ARCH_PTE_SPECIAL 233#define __HAVE_ARCH_PTE_SPECIAL
235 234
236/* Set of bits not changed in pte_modify */ 235/* Set of bits not changed in pte_modify */
237#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL | _PAGE_CO | \ 236#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL | _PAGE_DIRTY | \
238 _PAGE_DIRTY | _PAGE_YOUNG) 237 _PAGE_YOUNG)
239 238
240/* 239/*
241 * handle_pte_fault uses pte_present, pte_none and pte_file to find out the 240 * handle_pte_fault uses pte_present, pte_none and pte_file to find out the
@@ -354,7 +353,6 @@ extern unsigned long MODULES_END;
354 353
355#define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ 354#define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */
356#define _REGION3_ENTRY_RO 0x200 /* page protection bit */ 355#define _REGION3_ENTRY_RO 0x200 /* page protection bit */
357#define _REGION3_ENTRY_CO 0x100 /* change-recording override */
358 356
359/* Bits in the segment table entry */ 357/* Bits in the segment table entry */
360#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL 358#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL
@@ -371,7 +369,6 @@ extern unsigned long MODULES_END;
371#define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */ 369#define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */
372#define _SEGMENT_ENTRY_SPLIT 0x0800 /* THP splitting bit */ 370#define _SEGMENT_ENTRY_SPLIT 0x0800 /* THP splitting bit */
373#define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */ 371#define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */
374#define _SEGMENT_ENTRY_CO 0x0100 /* change-recording override */
375#define _SEGMENT_ENTRY_READ 0x0002 /* SW segment read bit */ 372#define _SEGMENT_ENTRY_READ 0x0002 /* SW segment read bit */
376#define _SEGMENT_ENTRY_WRITE 0x0001 /* SW segment write bit */ 373#define _SEGMENT_ENTRY_WRITE 0x0001 /* SW segment write bit */
377 374
@@ -873,8 +870,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
873 pgste = pgste_set_pte(ptep, pgste, entry); 870 pgste = pgste_set_pte(ptep, pgste, entry);
874 pgste_set_unlock(ptep, pgste); 871 pgste_set_unlock(ptep, pgste);
875 } else { 872 } else {
876 if (!(pte_val(entry) & _PAGE_INVALID) && MACHINE_HAS_EDAT1)
877 pte_val(entry) |= _PAGE_CO;
878 *ptep = entry; 873 *ptep = entry;
879 } 874 }
880} 875}
@@ -1044,6 +1039,22 @@ static inline void __ptep_ipte_local(unsigned long address, pte_t *ptep)
1044 : "=m" (*ptep) : "m" (*ptep), "a" (pto), "a" (address)); 1039 : "=m" (*ptep) : "m" (*ptep), "a" (pto), "a" (address));
1045} 1040}
1046 1041
1042static inline void __ptep_ipte_range(unsigned long address, int nr, pte_t *ptep)
1043{
1044 unsigned long pto = (unsigned long) ptep;
1045
1046#ifndef CONFIG_64BIT
1047 /* pto in ESA mode must point to the start of the segment table */
1048 pto &= 0x7ffffc00;
1049#endif
1050 /* Invalidate a range of ptes + global TLB flush of the ptes */
1051 do {
1052 asm volatile(
1053 " .insn rrf,0xb2210000,%2,%0,%1,0"
1054 : "+a" (address), "+a" (nr) : "a" (pto) : "memory");
1055 } while (nr != 255);
1056}
1057
1047static inline void ptep_flush_direct(struct mm_struct *mm, 1058static inline void ptep_flush_direct(struct mm_struct *mm,
1048 unsigned long address, pte_t *ptep) 1059 unsigned long address, pte_t *ptep)
1049{ 1060{
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index e568fc8a7250..d559bdb03d18 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -13,9 +13,11 @@
13 13
14#define CIF_MCCK_PENDING 0 /* machine check handling is pending */ 14#define CIF_MCCK_PENDING 0 /* machine check handling is pending */
15#define CIF_ASCE 1 /* user asce needs fixup / uaccess */ 15#define CIF_ASCE 1 /* user asce needs fixup / uaccess */
16#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
16 17
17#define _CIF_MCCK_PENDING (1<<CIF_MCCK_PENDING) 18#define _CIF_MCCK_PENDING (1<<CIF_MCCK_PENDING)
18#define _CIF_ASCE (1<<CIF_ASCE) 19#define _CIF_ASCE (1<<CIF_ASCE)
20#define _CIF_NOHZ_DELAY (1<<CIF_NOHZ_DELAY)
19 21
20 22
21#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
@@ -43,6 +45,8 @@ static inline int test_cpu_flag(int flag)
43 return !!(S390_lowcore.cpu_flags & (1U << flag)); 45 return !!(S390_lowcore.cpu_flags & (1U << flag));
44} 46}
45 47
48#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
49
46/* 50/*
47 * Default implementation of macro that returns current 51 * Default implementation of macro that returns current
48 * instruction pointer ("program counter"). 52 * instruction pointer ("program counter").
@@ -113,6 +117,7 @@ struct thread_struct {
113 int ri_signum; 117 int ri_signum;
114#ifdef CONFIG_64BIT 118#ifdef CONFIG_64BIT
115 unsigned char trap_tdb[256]; /* Transaction abort diagnose block */ 119 unsigned char trap_tdb[256]; /* Transaction abort diagnose block */
120 __vector128 *vxrs; /* Vector register save area */
116#endif 121#endif
117}; 122};
118 123
@@ -285,7 +290,12 @@ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
285 return (psw.addr - ilc) & mask; 290 return (psw.addr - ilc) & mask;
286#endif 291#endif
287} 292}
288 293
294/*
295 * Function to stop a processor until the next interrupt occurs
296 */
297void enabled_wait(void);
298
289/* 299/*
290 * Function to drop a processor into disabled wait state 300 * Function to drop a processor into disabled wait state
291 */ 301 */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index 55d69dd7473c..be317feff7ac 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -161,6 +161,12 @@ static inline long regs_return_value(struct pt_regs *regs)
161 return regs->gprs[2]; 161 return regs->gprs[2];
162} 162}
163 163
164static inline void instruction_pointer_set(struct pt_regs *regs,
165 unsigned long val)
166{
167 regs->psw.addr = val | PSW_ADDR_AMODE;
168}
169
164int regs_query_register_offset(const char *name); 170int regs_query_register_offset(const char *name);
165const char *regs_query_register_name(unsigned int offset); 171const char *regs_query_register_name(unsigned int offset);
166unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset); 172unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset);
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 089a49814c50..7736fdd72595 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -55,8 +55,8 @@ extern void detect_memory_memblock(void);
55#define MACHINE_FLAG_LPP (1UL << 13) 55#define MACHINE_FLAG_LPP (1UL << 13)
56#define MACHINE_FLAG_TOPOLOGY (1UL << 14) 56#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
57#define MACHINE_FLAG_TE (1UL << 15) 57#define MACHINE_FLAG_TE (1UL << 15)
58#define MACHINE_FLAG_RRBM (1UL << 16)
59#define MACHINE_FLAG_TLB_LC (1UL << 17) 58#define MACHINE_FLAG_TLB_LC (1UL << 17)
59#define MACHINE_FLAG_VX (1UL << 18)
60 60
61#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) 61#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
62#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) 62#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
@@ -78,8 +78,8 @@ extern void detect_memory_memblock(void);
78#define MACHINE_HAS_LPP (0) 78#define MACHINE_HAS_LPP (0)
79#define MACHINE_HAS_TOPOLOGY (0) 79#define MACHINE_HAS_TOPOLOGY (0)
80#define MACHINE_HAS_TE (0) 80#define MACHINE_HAS_TE (0)
81#define MACHINE_HAS_RRBM (0)
82#define MACHINE_HAS_TLB_LC (0) 81#define MACHINE_HAS_TLB_LC (0)
82#define MACHINE_HAS_VX (0)
83#else /* CONFIG_64BIT */ 83#else /* CONFIG_64BIT */
84#define MACHINE_HAS_IEEE (1) 84#define MACHINE_HAS_IEEE (1)
85#define MACHINE_HAS_CSP (1) 85#define MACHINE_HAS_CSP (1)
@@ -91,8 +91,8 @@ extern void detect_memory_memblock(void);
91#define MACHINE_HAS_LPP (S390_lowcore.machine_flags & MACHINE_FLAG_LPP) 91#define MACHINE_HAS_LPP (S390_lowcore.machine_flags & MACHINE_FLAG_LPP)
92#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) 92#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
93#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) 93#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
94#define MACHINE_HAS_RRBM (S390_lowcore.machine_flags & MACHINE_FLAG_RRBM)
95#define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) 94#define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC)
95#define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX)
96#endif /* CONFIG_64BIT */ 96#endif /* CONFIG_64BIT */
97 97
98/* 98/*
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index bf9c823d4020..49576115dbb7 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -15,6 +15,7 @@
15#define SIGP_SET_ARCHITECTURE 18 15#define SIGP_SET_ARCHITECTURE 18
16#define SIGP_COND_EMERGENCY_SIGNAL 19 16#define SIGP_COND_EMERGENCY_SIGNAL 19
17#define SIGP_SENSE_RUNNING 21 17#define SIGP_SENSE_RUNNING 21
18#define SIGP_STORE_ADDITIONAL_STATUS 23
18 19
19/* SIGP condition codes */ 20/* SIGP condition codes */
20#define SIGP_CC_ORDER_CODE_ACCEPTED 0 21#define SIGP_CC_ORDER_CODE_ACCEPTED 0
@@ -33,9 +34,10 @@
33 34
34#ifndef __ASSEMBLY__ 35#ifndef __ASSEMBLY__
35 36
36static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status) 37static inline int __pcpu_sigp(u16 addr, u8 order, unsigned long parm,
38 u32 *status)
37{ 39{
38 register unsigned int reg1 asm ("1") = parm; 40 register unsigned long reg1 asm ("1") = parm;
39 int cc; 41 int cc;
40 42
41 asm volatile( 43 asm volatile(
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 4f1307962a95..762d4f88af5a 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -29,7 +29,6 @@ extern int smp_find_processor_id(u16 address);
29extern int smp_store_status(int cpu); 29extern int smp_store_status(int cpu);
30extern int smp_vcpu_scheduled(int cpu); 30extern int smp_vcpu_scheduled(int cpu);
31extern void smp_yield_cpu(int cpu); 31extern void smp_yield_cpu(int cpu);
32extern void smp_yield(void);
33extern void smp_cpu_set_polarization(int cpu, int val); 32extern void smp_cpu_set_polarization(int cpu, int val);
34extern int smp_cpu_get_polarization(int cpu); 33extern int smp_cpu_get_polarization(int cpu);
35extern void smp_fill_possible_mask(void); 34extern void smp_fill_possible_mask(void);
@@ -50,7 +49,6 @@ static inline int smp_find_processor_id(u16 address) { return 0; }
50static inline int smp_store_status(int cpu) { return 0; } 49static inline int smp_store_status(int cpu) { return 0; }
51static inline int smp_vcpu_scheduled(int cpu) { return 1; } 50static inline int smp_vcpu_scheduled(int cpu) { return 1; }
52static inline void smp_yield_cpu(int cpu) { } 51static inline void smp_yield_cpu(int cpu) { }
53static inline void smp_yield(void) { }
54static inline void smp_fill_possible_mask(void) { } 52static inline void smp_fill_possible_mask(void) { }
55 53
56#endif /* CONFIG_SMP */ 54#endif /* CONFIG_SMP */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index 96879f7ad6da..d6bdf906caa5 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -37,11 +37,17 @@ _raw_compare_and_swap(unsigned int *lock, unsigned int old, unsigned int new)
37 * (the type definitions are in asm/spinlock_types.h) 37 * (the type definitions are in asm/spinlock_types.h)
38 */ 38 */
39 39
40void arch_lock_relax(unsigned int cpu);
41
40void arch_spin_lock_wait(arch_spinlock_t *); 42void arch_spin_lock_wait(arch_spinlock_t *);
41int arch_spin_trylock_retry(arch_spinlock_t *); 43int arch_spin_trylock_retry(arch_spinlock_t *);
42void arch_spin_relax(arch_spinlock_t *);
43void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); 44void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags);
44 45
46static inline void arch_spin_relax(arch_spinlock_t *lock)
47{
48 arch_lock_relax(lock->lock);
49}
50
45static inline u32 arch_spin_lockval(int cpu) 51static inline u32 arch_spin_lockval(int cpu)
46{ 52{
47 return ~cpu; 53 return ~cpu;
@@ -64,11 +70,6 @@ static inline int arch_spin_trylock_once(arch_spinlock_t *lp)
64 _raw_compare_and_swap(&lp->lock, 0, SPINLOCK_LOCKVAL)); 70 _raw_compare_and_swap(&lp->lock, 0, SPINLOCK_LOCKVAL));
65} 71}
66 72
67static inline int arch_spin_tryrelease_once(arch_spinlock_t *lp)
68{
69 return _raw_compare_and_swap(&lp->lock, SPINLOCK_LOCKVAL, 0);
70}
71
72static inline void arch_spin_lock(arch_spinlock_t *lp) 73static inline void arch_spin_lock(arch_spinlock_t *lp)
73{ 74{
74 if (!arch_spin_trylock_once(lp)) 75 if (!arch_spin_trylock_once(lp))
@@ -91,7 +92,13 @@ static inline int arch_spin_trylock(arch_spinlock_t *lp)
91 92
92static inline void arch_spin_unlock(arch_spinlock_t *lp) 93static inline void arch_spin_unlock(arch_spinlock_t *lp)
93{ 94{
94 arch_spin_tryrelease_once(lp); 95 typecheck(unsigned int, lp->lock);
96 asm volatile(
97 __ASM_BARRIER
98 "st %1,%0\n"
99 : "+Q" (lp->lock)
100 : "d" (0)
101 : "cc", "memory");
95} 102}
96 103
97static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) 104static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
@@ -123,13 +130,12 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
123 */ 130 */
124#define arch_write_can_lock(x) ((x)->lock == 0) 131#define arch_write_can_lock(x) ((x)->lock == 0)
125 132
126extern void _raw_read_lock_wait(arch_rwlock_t *lp);
127extern void _raw_read_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags);
128extern int _raw_read_trylock_retry(arch_rwlock_t *lp); 133extern int _raw_read_trylock_retry(arch_rwlock_t *lp);
129extern void _raw_write_lock_wait(arch_rwlock_t *lp);
130extern void _raw_write_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags);
131extern int _raw_write_trylock_retry(arch_rwlock_t *lp); 134extern int _raw_write_trylock_retry(arch_rwlock_t *lp);
132 135
136#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
137#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
138
133static inline int arch_read_trylock_once(arch_rwlock_t *rw) 139static inline int arch_read_trylock_once(arch_rwlock_t *rw)
134{ 140{
135 unsigned int old = ACCESS_ONCE(rw->lock); 141 unsigned int old = ACCESS_ONCE(rw->lock);
@@ -144,16 +150,82 @@ static inline int arch_write_trylock_once(arch_rwlock_t *rw)
144 _raw_compare_and_swap(&rw->lock, 0, 0x80000000)); 150 _raw_compare_and_swap(&rw->lock, 0, 0x80000000));
145} 151}
146 152
153#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
154
155#define __RAW_OP_OR "lao"
156#define __RAW_OP_AND "lan"
157#define __RAW_OP_ADD "laa"
158
159#define __RAW_LOCK(ptr, op_val, op_string) \
160({ \
161 unsigned int old_val; \
162 \
163 typecheck(unsigned int *, ptr); \
164 asm volatile( \
165 op_string " %0,%2,%1\n" \
166 "bcr 14,0\n" \
167 : "=d" (old_val), "+Q" (*ptr) \
168 : "d" (op_val) \
169 : "cc", "memory"); \
170 old_val; \
171})
172
173#define __RAW_UNLOCK(ptr, op_val, op_string) \
174({ \
175 unsigned int old_val; \
176 \
177 typecheck(unsigned int *, ptr); \
178 asm volatile( \
179 "bcr 14,0\n" \
180 op_string " %0,%2,%1\n" \
181 : "=d" (old_val), "+Q" (*ptr) \
182 : "d" (op_val) \
183 : "cc", "memory"); \
184 old_val; \
185})
186
187extern void _raw_read_lock_wait(arch_rwlock_t *lp);
188extern void _raw_write_lock_wait(arch_rwlock_t *lp, unsigned int prev);
189
147static inline void arch_read_lock(arch_rwlock_t *rw) 190static inline void arch_read_lock(arch_rwlock_t *rw)
148{ 191{
149 if (!arch_read_trylock_once(rw)) 192 unsigned int old;
193
194 old = __RAW_LOCK(&rw->lock, 1, __RAW_OP_ADD);
195 if ((int) old < 0)
150 _raw_read_lock_wait(rw); 196 _raw_read_lock_wait(rw);
151} 197}
152 198
153static inline void arch_read_lock_flags(arch_rwlock_t *rw, unsigned long flags) 199static inline void arch_read_unlock(arch_rwlock_t *rw)
200{
201 __RAW_UNLOCK(&rw->lock, -1, __RAW_OP_ADD);
202}
203
204static inline void arch_write_lock(arch_rwlock_t *rw)
205{
206 unsigned int old;
207
208 old = __RAW_LOCK(&rw->lock, 0x80000000, __RAW_OP_OR);
209 if (old != 0)
210 _raw_write_lock_wait(rw, old);
211 rw->owner = SPINLOCK_LOCKVAL;
212}
213
214static inline void arch_write_unlock(arch_rwlock_t *rw)
215{
216 rw->owner = 0;
217 __RAW_UNLOCK(&rw->lock, 0x7fffffff, __RAW_OP_AND);
218}
219
220#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
221
222extern void _raw_read_lock_wait(arch_rwlock_t *lp);
223extern void _raw_write_lock_wait(arch_rwlock_t *lp);
224
225static inline void arch_read_lock(arch_rwlock_t *rw)
154{ 226{
155 if (!arch_read_trylock_once(rw)) 227 if (!arch_read_trylock_once(rw))
156 _raw_read_lock_wait_flags(rw, flags); 228 _raw_read_lock_wait(rw);
157} 229}
158 230
159static inline void arch_read_unlock(arch_rwlock_t *rw) 231static inline void arch_read_unlock(arch_rwlock_t *rw)
@@ -169,19 +241,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
169{ 241{
170 if (!arch_write_trylock_once(rw)) 242 if (!arch_write_trylock_once(rw))
171 _raw_write_lock_wait(rw); 243 _raw_write_lock_wait(rw);
172} 244 rw->owner = SPINLOCK_LOCKVAL;
173
174static inline void arch_write_lock_flags(arch_rwlock_t *rw, unsigned long flags)
175{
176 if (!arch_write_trylock_once(rw))
177 _raw_write_lock_wait_flags(rw, flags);
178} 245}
179 246
180static inline void arch_write_unlock(arch_rwlock_t *rw) 247static inline void arch_write_unlock(arch_rwlock_t *rw)
181{ 248{
182 _raw_compare_and_swap(&rw->lock, 0x80000000, 0); 249 typecheck(unsigned int, rw->lock);
250
251 rw->owner = 0;
252 asm volatile(
253 __ASM_BARRIER
254 "st %1,%0\n"
255 : "+Q" (rw->lock)
256 : "d" (0)
257 : "cc", "memory");
183} 258}
184 259
260#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
261
185static inline int arch_read_trylock(arch_rwlock_t *rw) 262static inline int arch_read_trylock(arch_rwlock_t *rw)
186{ 263{
187 if (!arch_read_trylock_once(rw)) 264 if (!arch_read_trylock_once(rw))
@@ -191,12 +268,20 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
191 268
192static inline int arch_write_trylock(arch_rwlock_t *rw) 269static inline int arch_write_trylock(arch_rwlock_t *rw)
193{ 270{
194 if (!arch_write_trylock_once(rw)) 271 if (!arch_write_trylock_once(rw) && !_raw_write_trylock_retry(rw))
195 return _raw_write_trylock_retry(rw); 272 return 0;
273 rw->owner = SPINLOCK_LOCKVAL;
196 return 1; 274 return 1;
197} 275}
198 276
199#define arch_read_relax(lock) cpu_relax() 277static inline void arch_read_relax(arch_rwlock_t *rw)
200#define arch_write_relax(lock) cpu_relax() 278{
279 arch_lock_relax(rw->owner);
280}
281
282static inline void arch_write_relax(arch_rwlock_t *rw)
283{
284 arch_lock_relax(rw->owner);
285}
201 286
202#endif /* __ASM_SPINLOCK_H */ 287#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h
index b2cd6ff7c2c5..d84b6939237c 100644
--- a/arch/s390/include/asm/spinlock_types.h
+++ b/arch/s390/include/asm/spinlock_types.h
@@ -13,6 +13,7 @@ typedef struct {
13 13
14typedef struct { 14typedef struct {
15 unsigned int lock; 15 unsigned int lock;
16 unsigned int owner;
16} arch_rwlock_t; 17} arch_rwlock_t;
17 18
18#define __ARCH_RW_LOCK_UNLOCKED { 0 } 19#define __ARCH_RW_LOCK_UNLOCKED { 0 }
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h
index 18ea9e3f8142..2542a7e4c8b4 100644
--- a/arch/s390/include/asm/switch_to.h
+++ b/arch/s390/include/asm/switch_to.h
@@ -103,6 +103,61 @@ static inline void restore_fp_regs(freg_t *fprs)
103 asm volatile("ld 15,%0" : : "Q" (fprs[15])); 103 asm volatile("ld 15,%0" : : "Q" (fprs[15]));
104} 104}
105 105
106static inline void save_vx_regs(__vector128 *vxrs)
107{
108 typedef struct { __vector128 _[__NUM_VXRS]; } addrtype;
109
110 asm volatile(
111 " la 1,%0\n"
112 " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */
113 " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */
114 : "=Q" (*(addrtype *) vxrs) : : "1");
115}
116
117static inline void save_vx_regs_safe(__vector128 *vxrs)
118{
119 unsigned long cr0, flags;
120
121 flags = arch_local_irq_save();
122 __ctl_store(cr0, 0, 0);
123 __ctl_set_bit(0, 17);
124 __ctl_set_bit(0, 18);
125 save_vx_regs(vxrs);
126 __ctl_load(cr0, 0, 0);
127 arch_local_irq_restore(flags);
128}
129
130static inline void restore_vx_regs(__vector128 *vxrs)
131{
132 typedef struct { __vector128 _[__NUM_VXRS]; } addrtype;
133
134 asm volatile(
135 " la 1,%0\n"
136 " .word 0xe70f,0x1000,0x0036\n" /* vlm 0,15,0(1) */
137 " .word 0xe70f,0x1100,0x0c36\n" /* vlm 16,31,256(1) */
138 : : "Q" (*(addrtype *) vxrs) : "1");
139}
140
141static inline void save_fp_vx_regs(struct task_struct *task)
142{
143#ifdef CONFIG_64BIT
144 if (task->thread.vxrs)
145 save_vx_regs(task->thread.vxrs);
146 else
147#endif
148 save_fp_regs(task->thread.fp_regs.fprs);
149}
150
151static inline void restore_fp_vx_regs(struct task_struct *task)
152{
153#ifdef CONFIG_64BIT
154 if (task->thread.vxrs)
155 restore_vx_regs(task->thread.vxrs);
156 else
157#endif
158 restore_fp_regs(task->thread.fp_regs.fprs);
159}
160
106static inline void save_access_regs(unsigned int *acrs) 161static inline void save_access_regs(unsigned int *acrs)
107{ 162{
108 typedef struct { int _[NUM_ACRS]; } acrstype; 163 typedef struct { int _[NUM_ACRS]; } acrstype;
@@ -120,16 +175,16 @@ static inline void restore_access_regs(unsigned int *acrs)
120#define switch_to(prev,next,last) do { \ 175#define switch_to(prev,next,last) do { \
121 if (prev->mm) { \ 176 if (prev->mm) { \
122 save_fp_ctl(&prev->thread.fp_regs.fpc); \ 177 save_fp_ctl(&prev->thread.fp_regs.fpc); \
123 save_fp_regs(prev->thread.fp_regs.fprs); \ 178 save_fp_vx_regs(prev); \
124 save_access_regs(&prev->thread.acrs[0]); \ 179 save_access_regs(&prev->thread.acrs[0]); \
125 save_ri_cb(prev->thread.ri_cb); \ 180 save_ri_cb(prev->thread.ri_cb); \
126 } \ 181 } \
127 if (next->mm) { \ 182 if (next->mm) { \
183 update_cr_regs(next); \
128 restore_fp_ctl(&next->thread.fp_regs.fpc); \ 184 restore_fp_ctl(&next->thread.fp_regs.fpc); \
129 restore_fp_regs(next->thread.fp_regs.fprs); \ 185 restore_fp_vx_regs(next); \
130 restore_access_regs(&next->thread.acrs[0]); \ 186 restore_access_regs(&next->thread.acrs[0]); \
131 restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \ 187 restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
132 update_cr_regs(next); \
133 } \ 188 } \
134 prev = __switch_to(prev,next); \ 189 prev = __switch_to(prev,next); \
135} while (0) 190} while (0)
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index b833e9c0bfbf..4d62fd5b56e5 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -84,11 +84,13 @@ static inline struct thread_info *current_thread_info(void)
84#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ 84#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
85#define TIF_SECCOMP 5 /* secure computing */ 85#define TIF_SECCOMP 5 /* secure computing */
86#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ 86#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
87#define TIF_UPROBE 7 /* breakpointed or single-stepping */
87#define TIF_31BIT 16 /* 32bit process */ 88#define TIF_31BIT 16 /* 32bit process */
88#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ 89#define TIF_MEMDIE 17 /* is terminating due to OOM killer */
89#define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal() */ 90#define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal() */
90#define TIF_SINGLE_STEP 19 /* This task is single stepped */ 91#define TIF_SINGLE_STEP 19 /* This task is single stepped */
91#define TIF_BLOCK_STEP 20 /* This task is block stepped */ 92#define TIF_BLOCK_STEP 20 /* This task is block stepped */
93#define TIF_UPROBE_SINGLESTEP 21 /* This task is uprobe single stepped */
92 94
93#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 95#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
94#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) 96#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
@@ -97,6 +99,7 @@ static inline struct thread_info *current_thread_info(void)
97#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 99#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
98#define _TIF_SECCOMP (1<<TIF_SECCOMP) 100#define _TIF_SECCOMP (1<<TIF_SECCOMP)
99#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) 101#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
102#define _TIF_UPROBE (1<<TIF_UPROBE)
100#define _TIF_31BIT (1<<TIF_31BIT) 103#define _TIF_31BIT (1<<TIF_31BIT)
101#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) 104#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
102 105
diff --git a/arch/s390/include/asm/uprobes.h b/arch/s390/include/asm/uprobes.h
new file mode 100644
index 000000000000..1411dff7fea7
--- /dev/null
+++ b/arch/s390/include/asm/uprobes.h
@@ -0,0 +1,42 @@
1/*
2 * User-space Probes (UProbes) for s390
3 *
4 * Copyright IBM Corp. 2014
5 * Author(s): Jan Willeke,
6 */
7
8#ifndef _ASM_UPROBES_H
9#define _ASM_UPROBES_H
10
11#include <linux/notifier.h>
12
13typedef u16 uprobe_opcode_t;
14
15#define UPROBE_XOL_SLOT_BYTES 256 /* cache aligned */
16
17#define UPROBE_SWBP_INSN 0x0002
18#define UPROBE_SWBP_INSN_SIZE 2
19
20struct arch_uprobe {
21 union{
22 uprobe_opcode_t insn[3];
23 uprobe_opcode_t ixol[3];
24 };
25 unsigned int saved_per : 1;
26 unsigned int saved_int_code;
27};
28
29struct arch_uprobe_task {
30};
31
32int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm,
33 unsigned long addr);
34int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
35int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
36bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
37int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val,
38 void *data);
39void arch_uprobe_abort_xol(struct arch_uprobe *ap, struct pt_regs *regs);
40unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline,
41 struct pt_regs *regs);
42#endif /* _ASM_UPROBES_H */
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h
index bc9746a7d47c..a62526d09201 100644
--- a/arch/s390/include/asm/vdso.h
+++ b/arch/s390/include/asm/vdso.h
@@ -22,13 +22,17 @@ struct vdso_data {
22 __u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */ 22 __u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */
23 __u64 xtime_clock_sec; /* Kernel time 0x10 */ 23 __u64 xtime_clock_sec; /* Kernel time 0x10 */
24 __u64 xtime_clock_nsec; /* 0x18 */ 24 __u64 xtime_clock_nsec; /* 0x18 */
25 __u64 wtom_clock_sec; /* Wall to monotonic clock 0x20 */ 25 __u64 xtime_coarse_sec; /* Coarse kernel time 0x20 */
26 __u64 wtom_clock_nsec; /* 0x28 */ 26 __u64 xtime_coarse_nsec; /* 0x28 */
27 __u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */ 27 __u64 wtom_clock_sec; /* Wall to monotonic clock 0x30 */
28 __u32 tz_dsttime; /* Type of dst correction 0x34 */ 28 __u64 wtom_clock_nsec; /* 0x38 */
29 __u32 ectg_available; /* ECTG instruction present 0x38 */ 29 __u64 wtom_coarse_sec; /* Coarse wall to monotonic 0x40 */
30 __u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */ 30 __u64 wtom_coarse_nsec; /* 0x48 */
31 __u32 tk_shift; /* Shift used for xtime_nsec 0x40 */ 31 __u32 tz_minuteswest; /* Minutes west of Greenwich 0x50 */
32 __u32 tz_dsttime; /* Type of dst correction 0x54 */
33 __u32 ectg_available; /* ECTG instruction present 0x58 */
34 __u32 tk_mult; /* Mult. used for xtime_nsec 0x5c */
35 __u32 tk_shift; /* Shift used for xtime_nsec 0x60 */
32}; 36};
33 37
34struct vdso_per_cpu_data { 38struct vdso_per_cpu_data {
diff --git a/arch/s390/include/asm/vtimer.h b/arch/s390/include/asm/vtimer.h
index bfe25d513ad2..10a179af62d8 100644
--- a/arch/s390/include/asm/vtimer.h
+++ b/arch/s390/include/asm/vtimer.h
@@ -28,6 +28,4 @@ extern int del_virt_timer(struct vtimer_list *timer);
28extern void init_cpu_vtimer(void); 28extern void init_cpu_vtimer(void);
29extern void vtime_init(void); 29extern void vtime_init(void);
30 30
31extern void vtime_stop_cpu(void);
32
33#endif /* _ASM_S390_TIMER_H */ 31#endif /* _ASM_S390_TIMER_H */
diff --git a/arch/s390/include/uapi/asm/sigcontext.h b/arch/s390/include/uapi/asm/sigcontext.h
index b30de9c01bbe..5f0b8d7ddb0b 100644
--- a/arch/s390/include/uapi/asm/sigcontext.h
+++ b/arch/s390/include/uapi/asm/sigcontext.h
@@ -7,10 +7,14 @@
7#define _ASM_S390_SIGCONTEXT_H 7#define _ASM_S390_SIGCONTEXT_H
8 8
9#include <linux/compiler.h> 9#include <linux/compiler.h>
10#include <linux/types.h>
10 11
11#define __NUM_GPRS 16 12#define __NUM_GPRS 16
12#define __NUM_FPRS 16 13#define __NUM_FPRS 16
13#define __NUM_ACRS 16 14#define __NUM_ACRS 16
15#define __NUM_VXRS 32
16#define __NUM_VXRS_LOW 16
17#define __NUM_VXRS_HIGH 16
14 18
15#ifndef __s390x__ 19#ifndef __s390x__
16 20
@@ -59,6 +63,16 @@ typedef struct
59 _s390_fp_regs fpregs; 63 _s390_fp_regs fpregs;
60} _sigregs; 64} _sigregs;
61 65
66typedef struct
67{
68#ifndef __s390x__
69 unsigned long gprs_high[__NUM_GPRS];
70#endif
71 unsigned long long vxrs_low[__NUM_VXRS_LOW];
72 __vector128 vxrs_high[__NUM_VXRS_HIGH];
73 unsigned char __reserved[128];
74} _sigregs_ext;
75
62struct sigcontext 76struct sigcontext
63{ 77{
64 unsigned long oldmask[_SIGCONTEXT_NSIG_WORDS]; 78 unsigned long oldmask[_SIGCONTEXT_NSIG_WORDS];
diff --git a/arch/s390/include/uapi/asm/types.h b/arch/s390/include/uapi/asm/types.h
index 038f2b9178a4..3c3951e3415b 100644
--- a/arch/s390/include/uapi/asm/types.h
+++ b/arch/s390/include/uapi/asm/types.h
@@ -17,6 +17,10 @@
17typedef unsigned long addr_t; 17typedef unsigned long addr_t;
18typedef __signed__ long saddr_t; 18typedef __signed__ long saddr_t;
19 19
20typedef struct {
21 __u32 u[4];
22} __vector128;
23
20#endif /* __ASSEMBLY__ */ 24#endif /* __ASSEMBLY__ */
21 25
22#endif /* _UAPI_S390_TYPES_H */ 26#endif /* _UAPI_S390_TYPES_H */
diff --git a/arch/s390/include/uapi/asm/ucontext.h b/arch/s390/include/uapi/asm/ucontext.h
index 3e077b2a4705..64a69aa5dde0 100644
--- a/arch/s390/include/uapi/asm/ucontext.h
+++ b/arch/s390/include/uapi/asm/ucontext.h
@@ -7,10 +7,15 @@
7#ifndef _ASM_S390_UCONTEXT_H 7#ifndef _ASM_S390_UCONTEXT_H
8#define _ASM_S390_UCONTEXT_H 8#define _ASM_S390_UCONTEXT_H
9 9
10#define UC_EXTENDED 0x00000001 10#define UC_GPRS_HIGH 1 /* uc_mcontext_ext has valid high gprs */
11 11#define UC_VXRS 2 /* uc_mcontext_ext has valid vector regs */
12#ifndef __s390x__
13 12
13/*
14 * The struct ucontext_extended describes how the registers are stored
15 * on a rt signal frame. Please note that the structure is not fixed,
16 * if new CPU registers are added to the user state the size of the
17 * struct ucontext_extended will increase.
18 */
14struct ucontext_extended { 19struct ucontext_extended {
15 unsigned long uc_flags; 20 unsigned long uc_flags;
16 struct ucontext *uc_link; 21 struct ucontext *uc_link;
@@ -19,11 +24,9 @@ struct ucontext_extended {
19 sigset_t uc_sigmask; 24 sigset_t uc_sigmask;
20 /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */ 25 /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
21 unsigned char __unused[128 - sizeof(sigset_t)]; 26 unsigned char __unused[128 - sizeof(sigset_t)];
22 unsigned long uc_gprs_high[16]; 27 _sigregs_ext uc_mcontext_ext;
23}; 28};
24 29
25#endif
26
27struct ucontext { 30struct ucontext {
28 unsigned long uc_flags; 31 unsigned long uc_flags;
29 struct ucontext *uc_link; 32 struct ucontext *uc_link;