summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Oberparleiter <oberpar@linux.ibm.com>2025-08-18 12:21:52 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-08-28 16:34:36 +0200
commitbf83ae3537359af088d6577812ed93113dfbcb7b (patch)
treeca69e94c002723a022f41df22ccbd109a8291130
parent8ead139a8edef485cc36d3a792e2ae5dd538339a (diff)
s390/sclp: Fix SCCB present check
commit 430fa71027b6ac9bb0ce5532b8d0676777d4219a upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/s390/char/sclp.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 9a55e2d04e63..2ff1658bc93c 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -76,6 +76,13 @@ unsigned long sclp_console_full;
/* The currently active SCLP command word. */
static sclp_cmdw_t active_cmd;
+static inline struct sccb_header *sclpint_to_sccb(u32 sccb_int)
+{
+ if (sccb_int)
+ return __va(sccb_int);
+ return NULL;
+}
+
static inline void sclp_trace(int prio, char *id, u32 a, u64 b, bool err)
{
struct sclp_trace_entry e;
@@ -619,7 +626,7 @@ __sclp_find_req(u32 sccb)
static bool ok_response(u32 sccb_int, sclp_cmdw_t cmd)
{
- struct sccb_header *sccb = (struct sccb_header *)__va(sccb_int);
+ struct sccb_header *sccb = sclpint_to_sccb(sccb_int);
struct evbuf_header *evbuf;
u16 response;
@@ -658,7 +665,7 @@ static void sclp_interrupt_handler(struct ext_code ext_code,
/* INT: Interrupt received (a=intparm, b=cmd) */
sclp_trace_sccb(0, "INT", param32, active_cmd, active_cmd,
- (struct sccb_header *)__va(finished_sccb),
+ sclpint_to_sccb(finished_sccb),
!ok_response(finished_sccb, active_cmd));
if (finished_sccb) {