s390/sclp: sort out physical vs virtual pointers usage
authorAlexander Gordeev <agordeev@linux.ibm.com>
Mon, 8 Feb 2021 15:01:17 +0000 (16:01 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 26 Oct 2021 13:21:28 +0000 (15:21 +0200)
Provide physical addresses whenever the hardware interface
expects it or a 32-bit value used for tracking.

Variable sclp_early_sccb gets initialized in the decompressor
and points to an address in physcal memory. Yet, it is used
as virtual memory pointer and therefore should be converted.

Note, the other two __bootdata variables sclp_info_sccb and
sclp_info_sccb_valid contain plain data, but no pointers and
do need any special care.

Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/sclp.h
arch/s390/kernel/early.c
drivers/s390/char/sclp.c
drivers/s390/char/sclp.h
drivers/s390/char/sclp_early.c
drivers/s390/char/sclp_sd.c

index e3ae937bef1c6e6bd6fcaeada43e652bdf774a5f..c68ea35de49861073ac765bd4e7a2609d0ddae31 100644 (file)
@@ -117,6 +117,7 @@ struct zpci_report_error_header {
 
 extern char *sclp_early_sccb;
 
+void sclp_early_adjust_va(void);
 void sclp_early_set_buffer(void *sccb);
 int sclp_early_read_info(void);
 int sclp_early_read_storage_info(void);
index 9857cb04672680c81c4ab81b82a380b8f1e2ba58..ba3ace5ac73c6ba8f36a3e445144e7bcd05a3a57 100644 (file)
@@ -296,6 +296,7 @@ static void __init check_image_bootable(void)
 
 void __init startup_init(void)
 {
+       sclp_early_adjust_va();
        reset_tod_clock();
        check_image_bootable();
        time_early_init();
index 2cf7fe131ecec412ff4f82c5d85df7beb264a389..f0763e36b86168d6f79663303dd281fd0ec12ad3 100644 (file)
@@ -163,7 +163,7 @@ static inline void sclp_trace_req(int prio, char *id, struct sclp_req *req,
        summary.timeout = (u16)req->queue_timeout;
        summary.start_count = (u16)req->start_count;
 
-       sclp_trace(prio, id, (u32)(addr_t)sccb, summary.b, err);
+       sclp_trace(prio, id, __pa(sccb), summary.b, err);
 }
 
 static inline void sclp_trace_register(int prio, char *id, u32 a, u64 b,
@@ -502,7 +502,7 @@ sclp_add_request(struct sclp_req *req)
        }
 
        /* RQAD: Request was added (a=sccb, b=caller) */
-       sclp_trace(2, "RQAD", (u32)(addr_t)req->sccb, _RET_IP_, false);
+       sclp_trace(2, "RQAD", __pa(req->sccb), _RET_IP_, false);
 
        req->status = SCLP_REQ_QUEUED;
        req->start_count = 0;
@@ -617,15 +617,15 @@ __sclp_find_req(u32 sccb)
 
        list_for_each(l, &sclp_req_queue) {
                req = list_entry(l, struct sclp_req, list);
-               if (sccb == (u32) (addr_t) req->sccb)
-                               return req;
+               if (sccb == __pa(req->sccb))
+                       return req;
        }
        return NULL;
 }
 
 static bool ok_response(u32 sccb_int, sclp_cmdw_t cmd)
 {
-       struct sccb_header *sccb = (struct sccb_header *)(addr_t)sccb_int;
+       struct sccb_header *sccb = (struct sccb_header *)__va(sccb_int);
        struct evbuf_header *evbuf;
        u16 response;
 
@@ -664,7 +664,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 *)(addr_t)finished_sccb,
+                       (struct sccb_header *)__va(finished_sccb),
                        !ok_response(finished_sccb, active_cmd));
 
        if (finished_sccb) {
@@ -1110,7 +1110,7 @@ static void sclp_check_handler(struct ext_code ext_code,
        /* Is this the interrupt we are waiting for? */
        if (finished_sccb == 0)
                return;
-       if (finished_sccb != (u32) (addr_t) sclp_init_sccb)
+       if (finished_sccb != __pa(sclp_init_sccb))
                panic("sclp: unsolicited interrupt for buffer at 0x%x\n",
                      finished_sccb);
        spin_lock(&sclp_lock);
index 5e434108aae6aa3d74e2ab2becf2830875e8ad29..8a30e77db46988eb6cfa42dcd6e4abd3b5e076f3 100644 (file)
@@ -333,7 +333,7 @@ static inline int sclp_service_call(sclp_cmdw_t command, void *sccb)
                "2:\n"
                EX_TABLE(0b, 2b)
                EX_TABLE(1b, 2b)
-               : "+&d" (cc) : "d" (command), "a" ((unsigned long)sccb)
+               : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
                : "cc", "memory");
        if (cc == 4)
                return -EINVAL;
index f3d5c7f4c13d29aa48be077cc9e03456316cdb1a..ab68684b5d83b2febff21099482459c1257859d4 100644 (file)
@@ -155,6 +155,11 @@ static void __init sclp_early_console_detect(struct init_sccb *sccb)
                sclp.has_linemode = 1;
 }
 
+void __init sclp_early_adjust_va(void)
+{
+       sclp_early_sccb = __va((unsigned long)sclp_early_sccb);
+}
+
 void __init sclp_early_detect(void)
 {
        void *sccb = sclp_early_sccb;
index a5dd4e9f5b1bffb5d2488ec9ee43fd4743ec595b..25c2d760f6e68d55461d811a1f04ab902c65a3b0 100644 (file)
@@ -194,7 +194,7 @@ static int sclp_sd_sync(unsigned long page, u8 eq, u8 di, u64 sat, u64 sa,
        struct sclp_sd_evbuf *evbuf;
        int rc;
 
-       sclp_sd_listener_init(&listener, (u32) (addr_t) sccb);
+       sclp_sd_listener_init(&listener, __pa(sccb));
        sclp_sd_listener_add(&listener);
 
        /* Prepare SCCB */