]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: cxlflash: Avoid clobbering context control register value
authorMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Mon, 26 Mar 2018 16:30:22 +0000 (11:30 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 Aug 2018 05:50:41 +0000 (07:50 +0200)
[ Upstream commit 465891fe9237b02f8d0fd26448f733fae7236f4a ]

The SISLite specification originally defined the context control register with
a single field of bits to represent the LISN and also stipulated that the
register reset value be 0. The cxlflash driver took advantage of this when
programming the LISN for the master contexts via an unconditional write - no
other bits were preserved.

When unmap support was added, SISLite was updated to define bit 0 of the
context control register as a way for the AFU to notify the context owner that
unmap operations were supported. Thus the assumptions under which the register
is setup changed and the existing unconditional write is clobbering the unmap
state for master contexts. This is presently not an issue due to the order in
which the context control register is programmed in relation to the unmap bit
being queried but should be addressed to avoid a future regression in the
event this code is moved elsewhere.

To remedy this issue, preserve the bits when programming the LISN field in the
context control register. Since the LISN will now be programmed using a read
value, assert that the initial state of the LISN field is as described in
SISLite (0).

Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/cxlflash/main.c
drivers/scsi/cxlflash/sislite.h

index 12faf7f6c8aca8c04ae522cd268cb7e7a64c3629..737314cac8d84fa5640b036503fae866b06c64d6 100644 (file)
@@ -1303,7 +1303,10 @@ static void afu_err_intr_init(struct afu *afu)
        for (i = 0; i < afu->num_hwqs; i++) {
                hwq = get_hwq(afu, i);
 
-               writeq_be(SISL_MSI_SYNC_ERROR, &hwq->host_map->ctx_ctrl);
+               reg = readq_be(&hwq->host_map->ctx_ctrl);
+               WARN_ON((reg & SISL_CTX_CTRL_LISN_MASK) != 0);
+               reg |= SISL_MSI_SYNC_ERROR;
+               writeq_be(reg, &hwq->host_map->ctx_ctrl);
                writeq_be(SISL_ISTATUS_MASK, &hwq->host_map->intr_mask);
        }
 }
index 09daa86670fcbb412ddb8f4ea01aefd707798c9e..0892fb1f0a1ee35afc4d452e130d1a42f2ad9f77 100644 (file)
@@ -284,6 +284,7 @@ struct sisl_host_map {
        __be64 cmd_room;
        __be64 ctx_ctrl;        /* least significant byte or b56:63 is LISN# */
 #define SISL_CTX_CTRL_UNMAP_SECTOR     0x8000000000000000ULL /* b0 */
+#define SISL_CTX_CTRL_LISN_MASK                (0xFFULL)
        __be64 mbox_w;          /* restricted use */
        __be64 sq_start;        /* Submission Queue (R/W): write sequence and */
        __be64 sq_end;          /* inclusion semantics are the same as RRQ    */