diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:47:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:47:00 -0400 |
commit | 1ee07ef6b5db7235b133ee257a3adf507697e6b3 (patch) | |
tree | 9c7a00cf98462c2a70610da9d09770c835ef8fcd /arch/s390/include | |
parent | 77654908ff1a58cee4886298968b5262884aff0b (diff) | |
parent | 0cccdda8d1512af4d3f6913044e8c8e58e15ef37 (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')
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 | ||
170 | struct s390_idle_data { | 168 | cputime64_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 | ||
181 | DECLARE_PER_CPU(struct s390_idle_data, s390_idle); | 170 | #define arch_idle_time(cpu) arch_cpu_idle_time(cpu) |
182 | |||
183 | cputime64_t s390_get_idle_time(int cpu); | ||
184 | |||
185 | #define arch_idle_time(cpu) s390_get_idle_time(cpu) | ||
186 | |||
187 | static 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 | ||
24 | struct s390_operand { | 25 | struct 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); | |||
225 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | 226 | extern 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 | ||
228 | void *fill_cpu_elf_notes(void *ptr, struct save_area *sa); | 229 | void *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 | ||
6 | extern void _mcount(void); | 6 | extern void _mcount(void); |
7 | extern char ftrace_graph_caller_end; | ||
7 | 8 | ||
8 | struct dyn_arch_ftrace { }; | 9 | struct 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 | |||
13 | struct 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 | |||
23 | extern struct device_attribute dev_attr_idle_count; | ||
24 | extern 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; | |||
89 | extern u32 dump_prefix_page; | 89 | extern u32 dump_prefix_page; |
90 | 90 | ||
91 | struct dump_save_areas { | 91 | struct dump_save_areas { |
92 | struct save_area **areas; | 92 | struct save_area_ext **areas; |
93 | int count; | 93 | int count; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | extern struct dump_save_areas dump_save_areas; | 96 | extern struct dump_save_areas dump_save_areas; |
97 | struct save_area *dump_save_area_create(int cpu); | 97 | struct save_area_ext *dump_save_area_create(int cpu); |
98 | 98 | ||
99 | extern void do_reipl(void); | 99 | extern void do_reipl(void); |
100 | extern void do_halt(void); | 100 | extern 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); | |||
84 | int kprobe_exceptions_notify(struct notifier_block *self, | 84 | int kprobe_exceptions_notify(struct notifier_block *self, |
85 | unsigned long val, void *data); | 85 | unsigned long val, void *data); |
86 | 86 | ||
87 | int probe_is_prohibited_opcode(u16 *insn); | ||
88 | int probe_get_fixup_type(u16 *insn); | ||
89 | int 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 | ||
35 | struct save_area_ext { | ||
36 | struct save_area sa; | ||
37 | __vector128 vx_regs[32]; | ||
38 | }; | ||
39 | |||
34 | struct _lowcore { | 40 | struct _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 | ||
192 | struct save_area_ext { | ||
193 | struct save_area sa; | ||
194 | __vector128 vx_regs[32]; | ||
195 | }; | ||
196 | |||
186 | struct _lowcore { | 197 | struct _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 | ||
1042 | static 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 | |||
1047 | static inline void ptep_flush_direct(struct mm_struct *mm, | 1058 | static 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 | */ | ||
297 | void 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 | ||
164 | static inline void instruction_pointer_set(struct pt_regs *regs, | ||
165 | unsigned long val) | ||
166 | { | ||
167 | regs->psw.addr = val | PSW_ADDR_AMODE; | ||
168 | } | ||
169 | |||
164 | int regs_query_register_offset(const char *name); | 170 | int regs_query_register_offset(const char *name); |
165 | const char *regs_query_register_name(unsigned int offset); | 171 | const char *regs_query_register_name(unsigned int offset); |
166 | unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset); | 172 | unsigned 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 | ||
36 | static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status) | 37 | static 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); | |||
29 | extern int smp_store_status(int cpu); | 29 | extern int smp_store_status(int cpu); |
30 | extern int smp_vcpu_scheduled(int cpu); | 30 | extern int smp_vcpu_scheduled(int cpu); |
31 | extern void smp_yield_cpu(int cpu); | 31 | extern void smp_yield_cpu(int cpu); |
32 | extern void smp_yield(void); | ||
33 | extern void smp_cpu_set_polarization(int cpu, int val); | 32 | extern void smp_cpu_set_polarization(int cpu, int val); |
34 | extern int smp_cpu_get_polarization(int cpu); | 33 | extern int smp_cpu_get_polarization(int cpu); |
35 | extern void smp_fill_possible_mask(void); | 34 | extern void smp_fill_possible_mask(void); |
@@ -50,7 +49,6 @@ static inline int smp_find_processor_id(u16 address) { return 0; } | |||
50 | static inline int smp_store_status(int cpu) { return 0; } | 49 | static inline int smp_store_status(int cpu) { return 0; } |
51 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } | 50 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } |
52 | static inline void smp_yield_cpu(int cpu) { } | 51 | static inline void smp_yield_cpu(int cpu) { } |
53 | static inline void smp_yield(void) { } | ||
54 | static inline void smp_fill_possible_mask(void) { } | 52 | static 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 | ||
40 | void arch_lock_relax(unsigned int cpu); | ||
41 | |||
40 | void arch_spin_lock_wait(arch_spinlock_t *); | 42 | void arch_spin_lock_wait(arch_spinlock_t *); |
41 | int arch_spin_trylock_retry(arch_spinlock_t *); | 43 | int arch_spin_trylock_retry(arch_spinlock_t *); |
42 | void arch_spin_relax(arch_spinlock_t *); | ||
43 | void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); | 44 | void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); |
44 | 45 | ||
46 | static inline void arch_spin_relax(arch_spinlock_t *lock) | ||
47 | { | ||
48 | arch_lock_relax(lock->lock); | ||
49 | } | ||
50 | |||
45 | static inline u32 arch_spin_lockval(int cpu) | 51 | static 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 | ||
67 | static inline int arch_spin_tryrelease_once(arch_spinlock_t *lp) | ||
68 | { | ||
69 | return _raw_compare_and_swap(&lp->lock, SPINLOCK_LOCKVAL, 0); | ||
70 | } | ||
71 | |||
72 | static inline void arch_spin_lock(arch_spinlock_t *lp) | 73 | static 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 | ||
92 | static inline void arch_spin_unlock(arch_spinlock_t *lp) | 93 | static 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 | ||
97 | static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) | 104 | static 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 | ||
126 | extern void _raw_read_lock_wait(arch_rwlock_t *lp); | ||
127 | extern void _raw_read_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags); | ||
128 | extern int _raw_read_trylock_retry(arch_rwlock_t *lp); | 133 | extern int _raw_read_trylock_retry(arch_rwlock_t *lp); |
129 | extern void _raw_write_lock_wait(arch_rwlock_t *lp); | ||
130 | extern void _raw_write_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags); | ||
131 | extern int _raw_write_trylock_retry(arch_rwlock_t *lp); | 134 | extern 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 | |||
133 | static inline int arch_read_trylock_once(arch_rwlock_t *rw) | 139 | static 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 | |||
187 | extern void _raw_read_lock_wait(arch_rwlock_t *lp); | ||
188 | extern void _raw_write_lock_wait(arch_rwlock_t *lp, unsigned int prev); | ||
189 | |||
147 | static inline void arch_read_lock(arch_rwlock_t *rw) | 190 | static 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 | ||
153 | static inline void arch_read_lock_flags(arch_rwlock_t *rw, unsigned long flags) | 199 | static inline void arch_read_unlock(arch_rwlock_t *rw) |
200 | { | ||
201 | __RAW_UNLOCK(&rw->lock, -1, __RAW_OP_ADD); | ||
202 | } | ||
203 | |||
204 | static 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 | |||
214 | static 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 | |||
222 | extern void _raw_read_lock_wait(arch_rwlock_t *lp); | ||
223 | extern void _raw_write_lock_wait(arch_rwlock_t *lp); | ||
224 | |||
225 | static 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 | ||
159 | static inline void arch_read_unlock(arch_rwlock_t *rw) | 231 | static 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 | |||
174 | static 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 | ||
180 | static inline void arch_write_unlock(arch_rwlock_t *rw) | 247 | static 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 | |||
185 | static inline int arch_read_trylock(arch_rwlock_t *rw) | 262 | static 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 | ||
192 | static inline int arch_write_trylock(arch_rwlock_t *rw) | 269 | static 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() | 277 | static 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 | |||
282 | static 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 | ||
14 | typedef struct { | 14 | typedef 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 | ||
106 | static 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 | |||
117 | static 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 | |||
130 | static 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 | |||
141 | static 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 | |||
151 | static 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 | |||
106 | static inline void save_access_regs(unsigned int *acrs) | 161 | static 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 | |||
13 | typedef 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 | |||
20 | struct 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 | |||
29 | struct arch_uprobe_task { | ||
30 | }; | ||
31 | |||
32 | int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, | ||
33 | unsigned long addr); | ||
34 | int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); | ||
35 | int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); | ||
36 | bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); | ||
37 | int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, | ||
38 | void *data); | ||
39 | void arch_uprobe_abort_xol(struct arch_uprobe *ap, struct pt_regs *regs); | ||
40 | unsigned 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 | ||
34 | struct vdso_per_cpu_data { | 38 | struct 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); | |||
28 | extern void init_cpu_vtimer(void); | 28 | extern void init_cpu_vtimer(void); |
29 | extern void vtime_init(void); | 29 | extern void vtime_init(void); |
30 | 30 | ||
31 | extern 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 | ||
66 | typedef 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 | |||
62 | struct sigcontext | 76 | struct 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 @@ | |||
17 | typedef unsigned long addr_t; | 17 | typedef unsigned long addr_t; |
18 | typedef __signed__ long saddr_t; | 18 | typedef __signed__ long saddr_t; |
19 | 19 | ||
20 | typedef 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 | */ | ||
14 | struct ucontext_extended { | 19 | struct 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 | |||
27 | struct ucontext { | 30 | struct ucontext { |
28 | unsigned long uc_flags; | 31 | unsigned long uc_flags; |
29 | struct ucontext *uc_link; | 32 | struct ucontext *uc_link; |