Skip to content

Commit a316877

Browse files
committed
Merge tag 'scmi-fixes-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
Arm SCMI fixes for v6.2 Few fixes addressing: 1. Possible compromise with the shorter message size from a misbheaving SCMI platform firmware. The shmem accesses are now hardened to handle the same in fetch_notification and fetch_response. 2. Possible unsafe locking scenario which is solved by calling virtio_break_device() before getting hold of vioch->lock. 3. Possible stale error status reported from a previous message being used again as it is not cleared. * tag 'scmi-fixes-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: Fix virtio channels cleanup on shutdown firmware: arm_scmi: Harden shared memory access in fetch_notification firmware: arm_scmi: Harden shared memory access in fetch_response firmware: arm_scmi: Clear stale xfer->hdr.status Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents dc43354 + e325285 commit a316877

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

drivers/firmware/arm_scmi/driver.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
910910
xfer->hdr.protocol_id, xfer->hdr.seq,
911911
xfer->hdr.poll_completion);
912912

913+
/* Clear any stale status */
914+
xfer->hdr.status = SCMI_SUCCESS;
913915
xfer->state = SCMI_XFER_SENT_OK;
914916
/*
915917
* Even though spinlocking is not needed here since no race is possible

drivers/firmware/arm_scmi/shmem.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,11 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem)
8181
void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
8282
struct scmi_xfer *xfer)
8383
{
84+
size_t len = ioread32(&shmem->length);
85+
8486
xfer->hdr.status = ioread32(shmem->msg_payload);
8587
/* Skip the length of header and status in shmem area i.e 8 bytes */
86-
xfer->rx.len = min_t(size_t, xfer->rx.len,
87-
ioread32(&shmem->length) - 8);
88+
xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0);
8889

8990
/* Take a copy to the rx buffer.. */
9091
memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len);
@@ -93,8 +94,10 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
9394
void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem,
9495
size_t max_len, struct scmi_xfer *xfer)
9596
{
97+
size_t len = ioread32(&shmem->length);
98+
9699
/* Skip only the length of header in shmem area i.e 4 bytes */
97-
xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4);
100+
xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0);
98101

99102
/* Take a copy to the rx buffer.. */
100103
memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len);

drivers/firmware/arm_scmi/virtio.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
160160
}
161161

162162
vioch->shutdown_done = &vioch_shutdown_done;
163-
virtio_break_device(vioch->vqueue->vdev);
164163
if (!vioch->is_rx && vioch->deferred_tx_wq)
165164
/* Cannot be kicked anymore after this...*/
166165
vioch->deferred_tx_wq = NULL;
@@ -482,6 +481,12 @@ static int virtio_chan_free(int id, void *p, void *data)
482481
struct scmi_chan_info *cinfo = p;
483482
struct scmi_vio_channel *vioch = cinfo->transport_info;
484483

484+
/*
485+
* Break device to inhibit further traffic flowing while shutting down
486+
* the channels: doing it later holding vioch->lock creates unsafe
487+
* locking dependency chains as reported by LOCKDEP.
488+
*/
489+
virtio_break_device(vioch->vqueue->vdev);
485490
scmi_vio_channel_cleanup_sync(vioch);
486491

487492
scmi_free_channel(cinfo, data, id);

0 commit comments

Comments
 (0)