Skip to content

Commit 740eaf7

Browse files
committed
Merge tag 's390-5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Vasily Gorbik: - Add clang 10 build support. - Fix BUG() implementation to contain precise bug address, which is relevant for kprobes. - Make ftraced function appear in a stacktrace. - Minor perf improvements and refactoring. - Possible deadlock and recovery fixes in pci code. * tag 's390-5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390: fix __EMIT_BUG() macro s390/ftrace: generate traced function stack frame s390: adjust -mpacked-stack support check for clang 10 s390/jump_label: use "i" constraint for clang s390/cpum_sf: Use DIV_ROUND_UP s390/cpum_sf: Use kzalloc and minor changes s390/cpum_sf: Convert debug trace to common layout s390/pci: Fix possible deadlock in recover_store() s390/pci: Recover handle in clp_set_pci_fn()
2 parents fad7bdc + 17248ea commit 740eaf7

File tree

13 files changed

+172
-93
lines changed

13 files changed

+172
-93
lines changed

arch/s390/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include
6969
#
7070
cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls
7171

72-
ifeq ($(call cc-option-yn,-mpacked-stack),y)
72+
ifeq ($(call cc-option-yn,-mpacked-stack -mbackchain -msoft-float),y)
7373
cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK
7474
aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK
7575
endif

arch/s390/boot/head.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ ENTRY(startup_kdump)
329329
.quad .Lduct # cr5: primary-aste origin
330330
.quad 0 # cr6: I/O interrupts
331331
.quad 0 # cr7: secondary space segment table
332-
.quad 0 # cr8: access registers translation
332+
.quad 0x0000000000008000 # cr8: access registers translation
333333
.quad 0 # cr9: tracing off
334334
.quad 0 # cr10: tracing off
335335
.quad 0 # cr11: tracing off

arch/s390/include/asm/bug.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010

1111
#define __EMIT_BUG(x) do { \
1212
asm_inline volatile( \
13-
"0: j 0b+2\n" \
14-
"1:\n" \
13+
"0: mc 0,0\n" \
1514
".section .rodata.str,\"aMS\",@progbits,1\n" \
16-
"2: .asciz \""__FILE__"\"\n" \
15+
"1: .asciz \""__FILE__"\"\n" \
1716
".previous\n" \
1817
".section __bug_table,\"awM\",@progbits,%2\n" \
19-
"3: .long 1b-3b,2b-3b\n" \
18+
"2: .long 0b-2b,1b-2b\n" \
2019
" .short %0,%1\n" \
21-
" .org 3b+%2\n" \
20+
" .org 2b+%2\n" \
2221
".previous\n" \
2322
: : "i" (__LINE__), \
2423
"i" (x), \
@@ -29,12 +28,11 @@
2928

3029
#define __EMIT_BUG(x) do { \
3130
asm_inline volatile( \
32-
"0: j 0b+2\n" \
33-
"1:\n" \
31+
"0: mc 0,0\n" \
3432
".section __bug_table,\"awM\",@progbits,%1\n" \
35-
"2: .long 1b-2b\n" \
33+
"1: .long 0b-1b\n" \
3634
" .short %0\n" \
37-
" .org 2b+%1\n" \
35+
" .org 1b+%1\n" \
3836
".previous\n" \
3937
: : "i" (x), \
4038
"i" (sizeof(struct bug_entry))); \

arch/s390/include/asm/jump_label.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
#define JUMP_LABEL_NOP_SIZE 6
1111
#define JUMP_LABEL_NOP_OFFSET 2
1212

13-
#if __GNUC__ < 9
13+
#ifdef CONFIG_CC_IS_CLANG
14+
#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
15+
#elif __GNUC__ < 9
1416
#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "X"
1517
#else
1618
#define JUMP_LABEL_STATIC_KEY_CONSTRAINT "jdd"

arch/s390/include/asm/pci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ void zpci_remove_reserved_devices(void);
180180
/* CLP */
181181
int clp_scan_pci_devices(void);
182182
int clp_rescan_pci_devices(void);
183-
int clp_rescan_pci_devices_simple(void);
183+
int clp_rescan_pci_devices_simple(u32 *fid);
184184
int clp_add_pci_device(u32, u32, int);
185185
int clp_enable_fh(struct zpci_dev *, u8);
186186
int clp_disable_fh(struct zpci_dev *);

arch/s390/kernel/entry.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ void specification_exception(struct pt_regs *regs);
4545
void transaction_exception(struct pt_regs *regs);
4646
void translation_exception(struct pt_regs *regs);
4747
void vector_exception(struct pt_regs *regs);
48+
void monitor_event_exception(struct pt_regs *regs);
4849

4950
void do_per_trap(struct pt_regs *regs);
5051
void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str);

arch/s390/kernel/mcount.S

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ ENDPROC(ftrace_stub)
2626
#define STACK_PTREGS (STACK_FRAME_OVERHEAD)
2727
#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
2828
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
29+
#ifdef __PACK_STACK
30+
/* allocate just enough for r14, r15 and backchain */
31+
#define TRACED_FUNC_FRAME_SIZE 24
32+
#else
33+
#define TRACED_FUNC_FRAME_SIZE STACK_FRAME_OVERHEAD
34+
#endif
2935

3036
ENTRY(_mcount)
3137
BR_EX %r14
@@ -40,9 +46,16 @@ ENTRY(ftrace_caller)
4046
#if !(defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT))
4147
aghi %r0,MCOUNT_RETURN_FIXUP
4248
#endif
43-
aghi %r15,-STACK_FRAME_SIZE
49+
# allocate stack frame for ftrace_caller to contain traced function
50+
aghi %r15,-TRACED_FUNC_FRAME_SIZE
4451
stg %r1,__SF_BACKCHAIN(%r15)
52+
stg %r0,(__SF_GPRS+8*8)(%r15)
53+
stg %r15,(__SF_GPRS+9*8)(%r15)
54+
# allocate pt_regs and stack frame for ftrace_trace_function
55+
aghi %r15,-STACK_FRAME_SIZE
4556
stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15)
57+
aghi %r1,-TRACED_FUNC_FRAME_SIZE
58+
stg %r1,__SF_BACKCHAIN(%r15)
4659
stg %r0,(STACK_PTREGS_PSW+8)(%r15)
4760
stmg %r2,%r14,(STACK_PTREGS_GPRS+2*8)(%r15)
4861
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES

arch/s390/kernel/perf_cpum_sf.c

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,8 @@ static void aux_output_end(struct perf_output_handle *handle)
13831383
te = aux_sdb_trailer(aux, aux->alert_mark);
13841384
te->flags &= ~SDB_TE_ALERT_REQ_MASK;
13851385

1386-
debug_sprintf_event(sfdbg, 6, "%s: collect %#lx SDBs\n", __func__, i);
1386+
debug_sprintf_event(sfdbg, 6, "%s: SDBs %ld range %ld head %ld\n",
1387+
__func__, i, range_scan, aux->head);
13871388
}
13881389

13891390
/*
@@ -1416,13 +1417,17 @@ static int aux_output_begin(struct perf_output_handle *handle,
14161417
* SDBs between aux->head and aux->empty_mark are already ready
14171418
* for new data. range_scan is num of SDBs not within them.
14181419
*/
1420+
debug_sprintf_event(sfdbg, 6,
1421+
"%s: range %ld head %ld alert %ld empty %ld\n",
1422+
__func__, range, aux->head, aux->alert_mark,
1423+
aux->empty_mark);
14191424
if (range > AUX_SDB_NUM_EMPTY(aux)) {
14201425
range_scan = range - AUX_SDB_NUM_EMPTY(aux);
14211426
idx = aux->empty_mark + 1;
14221427
for (i = 0; i < range_scan; i++, idx++) {
14231428
te = aux_sdb_trailer(aux, idx);
1424-
te->flags = te->flags & ~SDB_TE_BUFFER_FULL_MASK;
1425-
te->flags = te->flags & ~SDB_TE_ALERT_REQ_MASK;
1429+
te->flags &= ~(SDB_TE_BUFFER_FULL_MASK |
1430+
SDB_TE_ALERT_REQ_MASK);
14261431
te->overflow = 0;
14271432
}
14281433
/* Save the position of empty SDBs */
@@ -1441,15 +1446,11 @@ static int aux_output_begin(struct perf_output_handle *handle,
14411446
cpuhw->lsctl.tear = base + offset * sizeof(unsigned long);
14421447
cpuhw->lsctl.dear = aux->sdb_index[head];
14431448

1444-
debug_sprintf_event(sfdbg, 6, "%s: "
1445-
"head->alert_mark->empty_mark (num_alert, range)"
1446-
"[%#lx -> %#lx -> %#lx] (%#lx, %#lx) "
1447-
"tear index %#lx, tear %#lx dear %#lx\n", __func__,
1449+
debug_sprintf_event(sfdbg, 6, "%s: head %ld alert %ld empty %ld "
1450+
"index %ld tear %#lx dear %#lx\n", __func__,
14481451
aux->head, aux->alert_mark, aux->empty_mark,
1449-
AUX_SDB_NUM_ALERT(aux), range,
14501452
head / CPUM_SF_SDB_PER_TABLE,
1451-
cpuhw->lsctl.tear,
1452-
cpuhw->lsctl.dear);
1453+
cpuhw->lsctl.tear, cpuhw->lsctl.dear);
14531454

14541455
return 0;
14551456
}
@@ -1469,8 +1470,7 @@ static bool aux_set_alert(struct aux_buffer *aux, unsigned long alert_index,
14691470
te = aux_sdb_trailer(aux, alert_index);
14701471
do {
14711472
orig_flags = te->flags;
1472-
orig_overflow = te->overflow;
1473-
*overflow = orig_overflow;
1473+
*overflow = orig_overflow = te->overflow;
14741474
if (orig_flags & SDB_TE_BUFFER_FULL_MASK) {
14751475
/*
14761476
* SDB is already set by hardware.
@@ -1512,9 +1512,12 @@ static bool aux_reset_buffer(struct aux_buffer *aux, unsigned long range,
15121512
unsigned long long *overflow)
15131513
{
15141514
unsigned long long orig_overflow, orig_flags, new_flags;
1515-
unsigned long i, range_scan, idx;
1515+
unsigned long i, range_scan, idx, idx_old;
15161516
struct hws_trailer_entry *te;
15171517

1518+
debug_sprintf_event(sfdbg, 6, "%s: range %ld head %ld alert %ld "
1519+
"empty %ld\n", __func__, range, aux->head,
1520+
aux->alert_mark, aux->empty_mark);
15181521
if (range <= AUX_SDB_NUM_EMPTY(aux))
15191522
/*
15201523
* No need to scan. All SDBs in range are marked as empty.
@@ -1537,7 +1540,7 @@ static bool aux_reset_buffer(struct aux_buffer *aux, unsigned long range,
15371540
* indicator fall into this range, set it.
15381541
*/
15391542
range_scan = range - AUX_SDB_NUM_EMPTY(aux);
1540-
idx = aux->empty_mark + 1;
1543+
idx_old = idx = aux->empty_mark + 1;
15411544
for (i = 0; i < range_scan; i++, idx++) {
15421545
te = aux_sdb_trailer(aux, idx);
15431546
do {
@@ -1557,6 +1560,9 @@ static bool aux_reset_buffer(struct aux_buffer *aux, unsigned long range,
15571560
/* Update empty_mark to new position */
15581561
aux->empty_mark = aux->head + range - 1;
15591562

1563+
debug_sprintf_event(sfdbg, 6, "%s: range_scan %ld idx %ld..%ld "
1564+
"empty %ld\n", __func__, range_scan, idx_old,
1565+
idx - 1, aux->empty_mark);
15601566
return true;
15611567
}
15621568

@@ -1570,24 +1576,24 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
15701576
unsigned long range = 0, size;
15711577
unsigned long long overflow = 0;
15721578
struct perf_output_handle *handle = &cpuhw->handle;
1573-
unsigned long num_sdb;
15741579

15751580
aux = perf_get_aux(handle);
15761581
if (WARN_ON_ONCE(!aux))
15771582
return;
15781583

15791584
/* Inform user space new data arrived */
15801585
size = AUX_SDB_NUM_ALERT(aux) << PAGE_SHIFT;
1586+
debug_sprintf_event(sfdbg, 6, "%s: #alert %ld\n", __func__,
1587+
size >> PAGE_SHIFT);
15811588
perf_aux_output_end(handle, size);
1582-
num_sdb = aux->sfb.num_sdb;
15831589

15841590
while (!done) {
15851591
/* Get an output handle */
15861592
aux = perf_aux_output_begin(handle, cpuhw->event);
15871593
if (handle->size == 0) {
15881594
pr_err("The AUX buffer with %lu pages for the "
15891595
"diagnostic-sampling mode is full\n",
1590-
num_sdb);
1596+
aux->sfb.num_sdb);
15911597
debug_sprintf_event(sfdbg, 1,
15921598
"%s: AUX buffer used up\n",
15931599
__func__);
@@ -1612,26 +1618,24 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
16121618
size = range << PAGE_SHIFT;
16131619
perf_aux_output_end(&cpuhw->handle, size);
16141620
pr_err("Sample data caused the AUX buffer with %lu "
1615-
"pages to overflow\n", num_sdb);
1616-
debug_sprintf_event(sfdbg, 1, "%s: head %#lx range %#lx "
1617-
"overflow %#llx\n", __func__,
1621+
"pages to overflow\n", aux->sfb.num_sdb);
1622+
debug_sprintf_event(sfdbg, 1, "%s: head %ld range %ld "
1623+
"overflow %lld\n", __func__,
16181624
aux->head, range, overflow);
16191625
} else {
16201626
size = AUX_SDB_NUM_ALERT(aux) << PAGE_SHIFT;
16211627
perf_aux_output_end(&cpuhw->handle, size);
1622-
debug_sprintf_event(sfdbg, 6, "%s: head %#lx alert %#lx "
1628+
debug_sprintf_event(sfdbg, 6, "%s: head %ld alert %ld "
16231629
"already full, try another\n",
16241630
__func__,
16251631
aux->head, aux->alert_mark);
16261632
}
16271633
}
16281634

16291635
if (done)
1630-
debug_sprintf_event(sfdbg, 6, "%s: aux_reset_buffer "
1631-
"[%#lx -> %#lx -> %#lx] (%#lx, %#lx)\n",
1632-
__func__, aux->head, aux->alert_mark,
1633-
aux->empty_mark, AUX_SDB_NUM_ALERT(aux),
1634-
range);
1636+
debug_sprintf_event(sfdbg, 6, "%s: head %ld alert %ld "
1637+
"empty %ld\n", __func__, aux->head,
1638+
aux->alert_mark, aux->empty_mark);
16351639
}
16361640

16371641
/*
@@ -1654,8 +1658,7 @@ static void aux_buffer_free(void *data)
16541658
kfree(aux->sdb_index);
16551659
kfree(aux);
16561660

1657-
debug_sprintf_event(sfdbg, 4, "%s: free "
1658-
"%lu SDBTs\n", __func__, num_sdbt);
1661+
debug_sprintf_event(sfdbg, 4, "%s: SDBTs %lu\n", __func__, num_sdbt);
16591662
}
16601663

16611664
static void aux_sdb_init(unsigned long sdb)
@@ -1707,13 +1710,13 @@ static void *aux_buffer_setup(struct perf_event *event, void **pages,
17071710
}
17081711

17091712
/* Allocate aux_buffer struct for the event */
1710-
aux = kmalloc(sizeof(struct aux_buffer), GFP_KERNEL);
1713+
aux = kzalloc(sizeof(struct aux_buffer), GFP_KERNEL);
17111714
if (!aux)
17121715
goto no_aux;
17131716
sfb = &aux->sfb;
17141717

17151718
/* Allocate sdbt_index for fast reference */
1716-
n_sdbt = (nr_pages + CPUM_SF_SDB_PER_TABLE - 1) / CPUM_SF_SDB_PER_TABLE;
1719+
n_sdbt = DIV_ROUND_UP(nr_pages, CPUM_SF_SDB_PER_TABLE);
17171720
aux->sdbt_index = kmalloc_array(n_sdbt, sizeof(void *), GFP_KERNEL);
17181721
if (!aux->sdbt_index)
17191722
goto no_sdbt_index;
@@ -1763,8 +1766,8 @@ static void *aux_buffer_setup(struct perf_event *event, void **pages,
17631766
*/
17641767
aux->empty_mark = sfb->num_sdb - 1;
17651768

1766-
debug_sprintf_event(sfdbg, 4, "%s: setup %lu SDBTs and %lu SDBs\n",
1767-
__func__, sfb->num_sdbt, sfb->num_sdb);
1769+
debug_sprintf_event(sfdbg, 4, "%s: SDBTs %lu SDBs %lu\n", __func__,
1770+
sfb->num_sdbt, sfb->num_sdb);
17681771

17691772
return aux;
17701773

arch/s390/kernel/pgm_check.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ PGM_CHECK_DEFAULT /* 3c */
8181
PGM_CHECK_DEFAULT /* 3d */
8282
PGM_CHECK_DEFAULT /* 3e */
8383
PGM_CHECK_DEFAULT /* 3f */
84-
PGM_CHECK_DEFAULT /* 40 */
84+
PGM_CHECK(monitor_event_exception) /* 40 */
8585
PGM_CHECK_DEFAULT /* 41 */
8686
PGM_CHECK_DEFAULT /* 42 */
8787
PGM_CHECK_DEFAULT /* 43 */

arch/s390/kernel/traps.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
5353
if (fixup)
5454
regs->psw.addr = extable_fixup(fixup);
5555
else {
56-
enum bug_trap_type btt;
57-
58-
btt = report_bug(regs->psw.addr, regs);
59-
if (btt == BUG_TRAP_TYPE_WARN)
60-
return;
6156
die(regs, str);
6257
}
6358
}
@@ -245,6 +240,27 @@ void space_switch_exception(struct pt_regs *regs)
245240
do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
246241
}
247242

243+
void monitor_event_exception(struct pt_regs *regs)
244+
{
245+
const struct exception_table_entry *fixup;
246+
247+
if (user_mode(regs))
248+
return;
249+
250+
switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) {
251+
case BUG_TRAP_TYPE_NONE:
252+
fixup = s390_search_extables(regs->psw.addr);
253+
if (fixup)
254+
regs->psw.addr = extable_fixup(fixup);
255+
break;
256+
case BUG_TRAP_TYPE_WARN:
257+
break;
258+
case BUG_TRAP_TYPE_BUG:
259+
die(regs, "monitor event");
260+
break;
261+
}
262+
}
263+
248264
void kernel_stack_overflow(struct pt_regs *regs)
249265
{
250266
bust_spinlocks(1);
@@ -255,8 +271,23 @@ void kernel_stack_overflow(struct pt_regs *regs)
255271
}
256272
NOKPROBE_SYMBOL(kernel_stack_overflow);
257273

274+
static void test_monitor_call(void)
275+
{
276+
int val = 1;
277+
278+
asm volatile(
279+
" mc 0,0\n"
280+
"0: xgr %0,%0\n"
281+
"1:\n"
282+
EX_TABLE(0b,1b)
283+
: "+d" (val));
284+
if (!val)
285+
panic("Monitor call doesn't work!\n");
286+
}
287+
258288
void __init trap_init(void)
259289
{
260290
sort_extable(__start_dma_ex_table, __stop_dma_ex_table);
261291
local_mcck_enable();
292+
test_monitor_call();
262293
}

0 commit comments

Comments
 (0)