Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/sclp: Fix SCCB present check

Tracing code called by the SCLP interrupt handler contains early exits
if the SCCB address associated with an interrupt is NULL. This check is
performed after physical to virtual address translation.

If the kernel identity mapping does not start at address zero, the
resulting virtual address is never zero, so that the NULL checks won't
work. Subsequently this may result in incorrect accesses to the first
page of the identity mapping.

Fix this by introducing a function that handles the NULL case before
address translation.

Fixes: ada1da31ce34 ("s390/sclp: sort out physical vs virtual pointers usage")
Cc: stable@vger.kernel.org
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>

authored by

Peter Oberparleiter and committed by
Alexander Gordeev
430fa710 fcc43a7e

+9 -2
+9 -2
drivers/s390/char/sclp.c
··· 77 77 /* The currently active SCLP command word. */ 78 78 static sclp_cmdw_t active_cmd; 79 79 80 + static inline struct sccb_header *sclpint_to_sccb(u32 sccb_int) 81 + { 82 + if (sccb_int) 83 + return __va(sccb_int); 84 + return NULL; 85 + } 86 + 80 87 static inline void sclp_trace(int prio, char *id, u32 a, u64 b, bool err) 81 88 { 82 89 struct sclp_trace_entry e; ··· 627 620 628 621 static bool ok_response(u32 sccb_int, sclp_cmdw_t cmd) 629 622 { 630 - struct sccb_header *sccb = (struct sccb_header *)__va(sccb_int); 623 + struct sccb_header *sccb = sclpint_to_sccb(sccb_int); 631 624 struct evbuf_header *evbuf; 632 625 u16 response; 633 626 ··· 666 659 667 660 /* INT: Interrupt received (a=intparm, b=cmd) */ 668 661 sclp_trace_sccb(0, "INT", param32, active_cmd, active_cmd, 669 - (struct sccb_header *)__va(finished_sccb), 662 + sclpint_to_sccb(finished_sccb), 670 663 !ok_response(finished_sccb, active_cmd)); 671 664 672 665 if (finished_sccb) {