Skip to content

Commit a87af77

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 bugfixes from Martin Schwidefsky: "A collection a bug fixes. Most of them are minor but two of them are more severe. The linkage stack bug can be used by user space to force an oops, with panic_on_oops this is a denial-of-service. And the dump memory detection issue can cause incomplete memory dumps" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/cio: improve cio_commit_config s390: fix kernel crash due to linkage stack instructions s390/dump: Fix dump memory detection s390/appldata: restore missing init_virt_timer() s390/qdio: correct program-controlled interruption checking s390/qdio: for_each macro correctness
2 parents 16e5a2e + 1bc8927 commit a87af77

File tree

6 files changed

+37
-37
lines changed

6 files changed

+37
-37
lines changed

arch/s390/appldata/appldata_base.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ static int __init appldata_init(void)
529529
{
530530
int rc;
531531

532+
init_virt_timer(&appldata_timer);
532533
appldata_timer.function = appldata_timer_function;
533534
appldata_timer.data = (unsigned long) &appldata_work;
534535

arch/s390/kernel/head64.S

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,23 @@ ENTRY(startup_continue)
5959
.quad 0 # cr12: tracing off
6060
.quad 0 # cr13: home space segment table
6161
.quad 0xc0000000 # cr14: machine check handling off
62-
.quad 0 # cr15: linkage stack operations
62+
.quad .Llinkage_stack # cr15: linkage stack operations
6363
.Lpcmsk:.quad 0x0000000180000000
6464
.L4malign:.quad 0xffffffffffc00000
6565
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
6666
.Lnop: .long 0x07000700
6767
.Lparmaddr:
6868
.quad PARMAREA
6969
.align 64
70-
.Lduct: .long 0,0,0,0,.Lduald,0,0,0
70+
.Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0
7171
.long 0,0,0,0,0,0,0,0
72+
.Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0
7273
.align 128
7374
.Lduald:.rept 8
7475
.long 0x80000000,0,0,0 # invalid access-list entries
7576
.endr
77+
.Llinkage_stack:
78+
.long 0,0,0x89000000,0,0,0,0x8a000000,0
7679

7780
ENTRY(_ehead)
7881

arch/s390/mm/page-states.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <linux/mm.h>
1313
#include <linux/gfp.h>
1414
#include <linux/init.h>
15+
#include <asm/setup.h>
16+
#include <asm/ipl.h>
1517

1618
#define ESSA_SET_STABLE 1
1719
#define ESSA_SET_UNUSED 2
@@ -41,6 +43,14 @@ void __init cmma_init(void)
4143

4244
if (!cmma_flag)
4345
return;
46+
/*
47+
* Disable CMM for dump, otherwise the tprot based memory
48+
* detection can fail because of unstable pages.
49+
*/
50+
if (OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP) {
51+
cmma_flag = 0;
52+
return;
53+
}
4454
asm volatile(
4555
" .insn rrf,0xb9ab0000,%1,%1,0,0\n"
4656
"0: la %0,0\n"

drivers/s390/cio/cio.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,9 @@ static int cio_check_config(struct subchannel *sch, struct schib *schib)
342342
*/
343343
int cio_commit_config(struct subchannel *sch)
344344
{
345-
struct schib schib;
346345
int ccode, retry, ret = 0;
346+
struct schib schib;
347+
struct irb irb;
347348

348349
if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
349350
return -ENODEV;
@@ -367,7 +368,10 @@ int cio_commit_config(struct subchannel *sch)
367368
ret = -EAGAIN;
368369
break;
369370
case 1: /* status pending */
370-
return -EBUSY;
371+
ret = -EBUSY;
372+
if (tsch(sch->schid, &irb))
373+
return ret;
374+
break;
371375
case 2: /* busy */
372376
udelay(100); /* allow for recovery */
373377
ret = -EBUSY;
@@ -403,7 +407,6 @@ EXPORT_SYMBOL_GPL(cio_update_schib);
403407
*/
404408
int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
405409
{
406-
int retry;
407410
int ret;
408411

409412
CIO_TRACE_EVENT(2, "ensch");
@@ -418,20 +421,14 @@ int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
418421
sch->config.isc = sch->isc;
419422
sch->config.intparm = intparm;
420423

421-
for (retry = 0; retry < 3; retry++) {
424+
ret = cio_commit_config(sch);
425+
if (ret == -EIO) {
426+
/*
427+
* Got a program check in msch. Try without
428+
* the concurrent sense bit the next time.
429+
*/
430+
sch->config.csense = 0;
422431
ret = cio_commit_config(sch);
423-
if (ret == -EIO) {
424-
/*
425-
* Got a program check in msch. Try without
426-
* the concurrent sense bit the next time.
427-
*/
428-
sch->config.csense = 0;
429-
} else if (ret == -EBUSY) {
430-
struct irb irb;
431-
if (tsch(sch->schid, &irb) != 0)
432-
break;
433-
} else
434-
break;
435432
}
436433
CIO_HEX_EVENT(2, &ret, sizeof(ret));
437434
return ret;
@@ -444,7 +441,6 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel);
444441
*/
445442
int cio_disable_subchannel(struct subchannel *sch)
446443
{
447-
int retry;
448444
int ret;
449445

450446
CIO_TRACE_EVENT(2, "dissch");
@@ -456,16 +452,8 @@ int cio_disable_subchannel(struct subchannel *sch)
456452
return -ENODEV;
457453

458454
sch->config.ena = 0;
455+
ret = cio_commit_config(sch);
459456

460-
for (retry = 0; retry < 3; retry++) {
461-
ret = cio_commit_config(sch);
462-
if (ret == -EBUSY) {
463-
struct irb irb;
464-
if (tsch(sch->schid, &irb) != 0)
465-
break;
466-
} else
467-
break;
468-
}
469457
CIO_HEX_EVENT(2, &ret, sizeof(ret));
470458
return ret;
471459
}

drivers/s390/cio/qdio.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,12 @@ static inline int multicast_outbound(struct qdio_q *q)
359359
#define need_siga_sync_out_after_pci(q) \
360360
(unlikely(q->irq_ptr->siga_flag.sync_out_after_pci))
361361

362-
#define for_each_input_queue(irq_ptr, q, i) \
363-
for (i = 0, q = irq_ptr->input_qs[0]; \
364-
i < irq_ptr->nr_input_qs; \
365-
q = irq_ptr->input_qs[++i])
366-
#define for_each_output_queue(irq_ptr, q, i) \
367-
for (i = 0, q = irq_ptr->output_qs[0]; \
368-
i < irq_ptr->nr_output_qs; \
369-
q = irq_ptr->output_qs[++i])
362+
#define for_each_input_queue(irq_ptr, q, i) \
363+
for (i = 0; i < irq_ptr->nr_input_qs && \
364+
({ q = irq_ptr->input_qs[i]; 1; }); i++)
365+
#define for_each_output_queue(irq_ptr, q, i) \
366+
for (i = 0; i < irq_ptr->nr_output_qs && \
367+
({ q = irq_ptr->output_qs[i]; 1; }); i++)
370368

371369
#define prev_buf(bufnr) \
372370
((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK)

drivers/s390/cio/qdio_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
996996
}
997997
}
998998

999-
if (!pci_out_supported(q))
999+
if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED))
10001000
return;
10011001

10021002
for_each_output_queue(irq_ptr, q, i) {

0 commit comments

Comments
 (0)