Skip to content

Commit f7b32e4

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Martin Schwidefsky: - some cleanup for the hugetlbfs pte/pmd conversion functions - the code to check for the minimum CPU type is converted from assembler to C and an informational message is added in case the CPU is not new enough to run the kernel - bug fixes * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/ftrace/jprobes: Fix conflict between jprobes and function graph tracing s390: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO s390/zcrypt: fix possible memory leak in ap_module_init() s390/numa: only set possible nodes within node_possible_map s390/als: fix compile with gcov enabled s390/facilities: do not generate DWORDS define anymore s390/als: print missing facilities on facility mismatch s390/als: print machine type on facility mismatch s390/als: convert architecture level set code to C s390/sclp: move uninitialized data to data section s390/zcrypt: Fix zcrypt suspend/resume behavior s390/cio: fix premature wakeup during chp configure s390/cio: convert cfg_lock mutex to spinlock s390/mm: clean up pte/pmd encoding
2 parents 731c7d3 + e64a547 commit f7b32e4

File tree

20 files changed

+305
-99
lines changed

20 files changed

+305
-99
lines changed

arch/s390/boot/compressed/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
1818

1919
GCOV_PROFILE := n
2020

21-
OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
21+
OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o als.o)
2222
OBJECTS += $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o
2323

2424
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T

arch/s390/include/asm/elf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ do { \
225225
#define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL)
226226
#define STACK_RND_MASK MMAP_RND_MASK
227227

228+
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
228229
#define ARCH_DLINFO \
229230
do { \
230231
if (vdso_enabled) \

arch/s390/include/asm/pgtable.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ static inline int is_module_addr(void *addr)
242242
* swap .11..ttttt.0
243243
* prot-none, clean, old .11.xx0000.1
244244
* prot-none, clean, young .11.xx0001.1
245-
* prot-none, dirty, old .10.xx0010.1
246-
* prot-none, dirty, young .10.xx0011.1
245+
* prot-none, dirty, old .11.xx0010.1
246+
* prot-none, dirty, young .11.xx0011.1
247247
* read-only, clean, old .11.xx0100.1
248248
* read-only, clean, young .01.xx0101.1
249249
* read-only, dirty, old .11.xx0110.1
@@ -323,8 +323,8 @@ static inline int is_module_addr(void *addr)
323323
#define _SEGMENT_ENTRY_DIRTY 0x2000 /* SW segment dirty bit */
324324
#define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */
325325
#define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */
326-
#define _SEGMENT_ENTRY_READ 0x0002 /* SW segment read bit */
327-
#define _SEGMENT_ENTRY_WRITE 0x0001 /* SW segment write bit */
326+
#define _SEGMENT_ENTRY_WRITE 0x0002 /* SW segment write bit */
327+
#define _SEGMENT_ENTRY_READ 0x0001 /* SW segment read bit */
328328

329329
#ifdef CONFIG_MEM_SOFT_DIRTY
330330
#define _SEGMENT_ENTRY_SOFT_DIRTY 0x4000 /* SW segment soft dirty bit */
@@ -335,15 +335,15 @@ static inline int is_module_addr(void *addr)
335335
/*
336336
* Segment table and region3 table entry encoding
337337
* (R = read-only, I = invalid, y = young bit):
338-
* dy..R...I...rw
338+
* dy..R...I...wr
339339
* prot-none, clean, old 00..1...1...00
340340
* prot-none, clean, young 01..1...1...00
341341
* prot-none, dirty, old 10..1...1...00
342342
* prot-none, dirty, young 11..1...1...00
343-
* read-only, clean, old 00..1...1...10
344-
* read-only, clean, young 01..1...0...10
345-
* read-only, dirty, old 10..1...1...10
346-
* read-only, dirty, young 11..1...0...10
343+
* read-only, clean, old 00..1...1...01
344+
* read-only, clean, young 01..1...0...01
345+
* read-only, dirty, old 10..1...1...01
346+
* read-only, dirty, young 11..1...0...01
347347
* read-write, clean, old 00..1...1...11
348348
* read-write, clean, young 01..1...0...11
349349
* read-write, dirty, old 10..0...1...11
@@ -382,7 +382,7 @@ static inline int is_module_addr(void *addr)
382382
/*
383383
* Page protection definitions.
384384
*/
385-
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_INVALID)
385+
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_INVALID | _PAGE_PROTECT)
386386
#define PAGE_READ __pgprot(_PAGE_PRESENT | _PAGE_READ | \
387387
_PAGE_INVALID | _PAGE_PROTECT)
388388
#define PAGE_WRITE __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \

arch/s390/include/uapi/asm/auxvec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33

44
#define AT_SYSINFO_EHDR 33
55

6+
#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
7+
68
#endif

arch/s390/kernel/Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
KCOV_INSTRUMENT_early.o := n
66
KCOV_INSTRUMENT_sclp.o := n
7+
KCOV_INSTRUMENT_als.o := n
78

89
ifdef CONFIG_FUNCTION_TRACER
910
# Don't trace early setup code and tracing code
@@ -32,21 +33,25 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
3233
CFLAGS_sysinfo.o += -w
3334

3435
#
35-
# Use -march=z900 for sclp.c to be able to print an error message if
36-
# the kernel is started on a machine which is too old
36+
# Use -march=z900 for sclp.c and als.c to be able to print an error
37+
# message if the kernel is started on a machine which is too old
3738
#
3839
CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE)
40+
CFLAGS_REMOVE_als.o = $(CC_FLAGS_FTRACE)
3941
ifneq ($(CC_FLAGS_MARCH),-march=z900)
4042
CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH)
4143
CFLAGS_sclp.o += -march=z900
44+
CFLAGS_REMOVE_als.o += $(CC_FLAGS_MARCH)
45+
CFLAGS_als.o += -march=z900
4246
AFLAGS_REMOVE_head.o += $(CC_FLAGS_MARCH)
4347
AFLAGS_head.o += -march=z900
4448
endif
4549
GCOV_PROFILE_sclp.o := n
50+
GCOV_PROFILE_als.o := n
4651

4752
obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o
4853
obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
49-
obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o
54+
obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o als.o
5055
obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
5156
obj-y += runtime_instr.o cache.o fpu.o dumpstack.o
5257
obj-y += entry.o reipl.o relocate_kernel.o

arch/s390/kernel/als.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright IBM Corp. 2016
3+
*/
4+
#include <linux/kernel.h>
5+
#include <linux/init.h>
6+
#include <asm/processor.h>
7+
#include <asm/facility.h>
8+
#include <asm/lowcore.h>
9+
#include <asm/sclp.h>
10+
#include "entry.h"
11+
12+
/*
13+
* The code within this file will be called very early. It may _not_
14+
* access anything within the bss section, since that is not cleared
15+
* yet and may contain data (e.g. initrd) that must be saved by other
16+
* code.
17+
* For temporary objects the stack (16k) should be used.
18+
*/
19+
20+
static unsigned long als[] __initdata = { FACILITIES_ALS };
21+
22+
static void __init u16_to_hex(char *str, u16 val)
23+
{
24+
int i, num;
25+
26+
for (i = 1; i <= 4; i++) {
27+
num = (val >> (16 - 4 * i)) & 0xf;
28+
if (num >= 10)
29+
num += 7;
30+
*str++ = '0' + num;
31+
}
32+
*str = '\0';
33+
}
34+
35+
static void __init print_machine_type(void)
36+
{
37+
static char mach_str[80] __initdata = "Detected machine-type number: ";
38+
char type_str[5];
39+
struct cpuid id;
40+
41+
get_cpu_id(&id);
42+
u16_to_hex(type_str, id.machine);
43+
strcat(mach_str, type_str);
44+
_sclp_print_early(mach_str);
45+
}
46+
47+
static void __init u16_to_decimal(char *str, u16 val)
48+
{
49+
int div = 1;
50+
51+
while (div * 10 <= val)
52+
div *= 10;
53+
while (div) {
54+
*str++ = '0' + val / div;
55+
val %= div;
56+
div /= 10;
57+
}
58+
*str = '\0';
59+
}
60+
61+
static void __init print_missing_facilities(void)
62+
{
63+
static char als_str[80] __initdata = "Missing facilities: ";
64+
unsigned long val;
65+
char val_str[6];
66+
int i, j, first;
67+
68+
first = 1;
69+
for (i = 0; i < ARRAY_SIZE(als); i++) {
70+
val = ~S390_lowcore.stfle_fac_list[i] & als[i];
71+
for (j = 0; j < BITS_PER_LONG; j++) {
72+
if (!(val & (1UL << (BITS_PER_LONG - 1 - j))))
73+
continue;
74+
if (!first)
75+
strcat(als_str, ",");
76+
/*
77+
* Make sure we stay within one line. Consider that
78+
* each facility bit adds up to five characters and
79+
* z/VM adds a four character prefix.
80+
*/
81+
if (strlen(als_str) > 70) {
82+
_sclp_print_early(als_str);
83+
*als_str = '\0';
84+
}
85+
u16_to_decimal(val_str, i * BITS_PER_LONG + j);
86+
strcat(als_str, val_str);
87+
first = 0;
88+
}
89+
}
90+
_sclp_print_early(als_str);
91+
_sclp_print_early("See Principles of Operations for facility bits");
92+
}
93+
94+
static void __init facility_mismatch(void)
95+
{
96+
_sclp_print_early("The Linux kernel requires more recent processor hardware");
97+
print_machine_type();
98+
print_missing_facilities();
99+
disabled_wait(0x8badcccc);
100+
}
101+
102+
void __init verify_facilities(void)
103+
{
104+
int i;
105+
106+
for (i = 0; i < ARRAY_SIZE(S390_lowcore.stfle_fac_list); i++)
107+
S390_lowcore.stfle_fac_list[i] = 0;
108+
asm volatile(
109+
" stfl 0(0)\n"
110+
: "=m" (S390_lowcore.stfl_fac_list));
111+
S390_lowcore.stfle_fac_list[0] = (u64)S390_lowcore.stfl_fac_list << 32;
112+
if (S390_lowcore.stfl_fac_list & 0x01000000) {
113+
register unsigned long reg0 asm("0") = ARRAY_SIZE(als) - 1;
114+
115+
asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */
116+
: "+d" (reg0)
117+
: "a" (&S390_lowcore.stfle_fac_list)
118+
: "memory", "cc");
119+
}
120+
for (i = 0; i < ARRAY_SIZE(als); i++) {
121+
if ((S390_lowcore.stfle_fac_list[i] & als[i]) != als[i])
122+
facility_mismatch();
123+
}
124+
}

arch/s390/kernel/entry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,6 @@ long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t);
7979

8080
DECLARE_PER_CPU(u64, mt_cycles[8]);
8181

82+
void verify_facilities(void);
83+
8284
#endif /* _ENTRY_H */

arch/s390/kernel/head.S

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -306,49 +306,14 @@ ENTRY(startup_kdump)
306306
stck __LC_LAST_UPDATE_CLOCK
307307
spt 6f-.LPG0(%r13)
308308
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
309-
stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST
310-
mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
311-
tm __LC_STFLE_FAC_LIST,0x01 # stfle available ?
312-
jz 0f
313-
lghi %r0,FACILITIES_ALS_DWORDS-1
314-
.insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
315-
# verify if all required facilities are supported by the machine
316-
0: la %r1,__LC_STFLE_FAC_LIST
317-
la %r2,3f+8-.LPG0(%r13)
318-
lhi %r3,FACILITIES_ALS_DWORDS
319-
1: lg %r0,0(%r1)
320-
ng %r0,0(%r2)
321-
clg %r0,0(%r2)
322-
jne 2f
323-
la %r1,8(%r1)
324-
la %r2,8(%r2)
325-
ahi %r3,-1
326-
jnz 1b
327-
j 4f
328-
2: l %r15,.Lstack-.LPG0(%r13)
309+
l %r15,.Lstack-.LPG0(%r13)
329310
ahi %r15,-STACK_FRAME_OVERHEAD
330-
la %r2,.Lals_string-.LPG0(%r13)
331-
l %r3,.Lsclp_print-.LPG0(%r13)
332-
basr %r14,%r3
333-
lpsw 3f-.LPG0(%r13) # machine type not good enough, crash
334-
.Lals_string:
335-
.asciz "The Linux kernel requires more recent processor hardware"
336-
.Lsclp_print:
337-
.long _sclp_print_early
338-
.Lstack:
339-
.long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
340-
.align 16
341-
3: .long 0x000a0000,0x8badcccc
342-
343-
# List of facilities that are required. If not all facilities are present
344-
# the kernel will crash.
345-
346-
.quad FACILITIES_ALS
347-
348-
4:
311+
brasl %r14,verify_facilities
349312
/* Continue with startup code in head64.S */
350313
jg startup_continue
351314

315+
.Lstack:
316+
.long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
352317
.align 8
353318
6: .long 0x7fffffff,0xffffffff
354319

arch/s390/kernel/kprobes.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
690690
stack = (unsigned long) regs->gprs[15];
691691

692692
memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack));
693+
694+
/*
695+
* jprobes use jprobe_return() which skips the normal return
696+
* path of the function, and this messes up the accounting of the
697+
* function graph tracer to get messed up.
698+
*
699+
* Pause function graph tracing while performing the jprobe function.
700+
*/
701+
pause_graph_tracing();
693702
return 1;
694703
}
695704
NOKPROBE_SYMBOL(setjmp_pre_handler);
@@ -705,6 +714,9 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
705714
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
706715
unsigned long stack;
707716

717+
/* It's OK to start function graph tracing again */
718+
unpause_graph_tracing();
719+
708720
stack = (unsigned long) kcb->jprobe_saved_regs.gprs[15];
709721

710722
/* Put the regs back */

arch/s390/kernel/sclp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
#define EVTYP_VT220MSG_MASK 0x00000040
1313
#define EVTYP_MSG_MASK 0x40000000
1414

15-
static char _sclp_work_area[4096] __aligned(PAGE_SIZE);
16-
static bool have_vt220, have_linemode;
15+
static char _sclp_work_area[4096] __aligned(PAGE_SIZE) __section(data);
16+
static bool have_vt220 __section(data);
17+
static bool have_linemode __section(data);
1718

1819
static void _sclp_wait_int(void)
1920
{

0 commit comments

Comments
 (0)