From b29111067843a06ad4a8d05f92ec894b037eebe9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 11 Apr 2024 09:28:53 +0200 Subject: [PATCH] 6.1-stable patches added patches: revert-scsi-core-add-struct-for-args-to-execution-functions.patch revert-scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch --- ...ruct-for-args-to-execution-functions.patch | 193 ++++++++++++++++++ ...-prior-to-querying-device-properties.patch | 114 +++++++++++ ...-prior-to-querying-device-properties.patch | 145 +++++++++++++ queue-6.1/series | 3 + 4 files changed, 455 insertions(+) create mode 100644 queue-6.1/revert-scsi-core-add-struct-for-args-to-execution-functions.patch create mode 100644 queue-6.1/revert-scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch create mode 100644 queue-6.1/scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch diff --git a/queue-6.1/revert-scsi-core-add-struct-for-args-to-execution-functions.patch b/queue-6.1/revert-scsi-core-add-struct-for-args-to-execution-functions.patch new file mode 100644 index 00000000000..6853a9ef68c --- /dev/null +++ b/queue-6.1/revert-scsi-core-add-struct-for-args-to-execution-functions.patch @@ -0,0 +1,193 @@ +From d6977a0ba5a198fc0da04748e4d748dd7ffcc188 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 11 Apr 2024 09:26:49 +0200 +Subject: Revert "scsi: core: Add struct for args to execution functions" + +From: Greg Kroah-Hartman + +This reverts commit cf33e6ca12d814e1be2263cb76960d0019d7fb94 which is +commit d0949565811f0896c1c7e781ab2ad99d34273fdf upstream. + +It is known to cause problems and has asked to be dropped. + +Link: https://lore.kernel.org/r/yq1frvvpymp.fsf@ca-mkp.ca.oracle.com +Cc: Tasos Sahanidis +Cc: Ewan D. Milne +Cc: Bart Van Assche +Cc: Tasos Sahanidis +Cc: Martin K. Petersen +Cc: James Bottomley +Cc: Sasha Levin +Reported-by: John David Anglin +Reported-by: Cyril Brulebois +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_lib.c | 52 +++++++++++++++++++++++---------------------- + include/scsi/scsi_device.h | 51 ++++++++++++-------------------------------- + 2 files changed, 41 insertions(+), 62 deletions(-) + +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -185,37 +185,39 @@ void scsi_queue_insert(struct scsi_cmnd + __scsi_queue_insert(cmd, reason, true); + } + ++ + /** +- * scsi_execute_cmd - insert request and wait for the result +- * @sdev: scsi_device ++ * __scsi_execute - insert request and wait for the result ++ * @sdev: scsi device + * @cmd: scsi command +- * @opf: block layer request cmd_flags ++ * @data_direction: data direction + * @buffer: data buffer + * @bufflen: len of buffer ++ * @sense: optional sense buffer ++ * @sshdr: optional decoded sense header + * @timeout: request timeout in HZ + * @retries: number of times to retry request +- * @args: Optional args. See struct definition for field descriptions ++ * @flags: flags for ->cmd_flags ++ * @rq_flags: flags for ->rq_flags ++ * @resid: optional residual length + * + * Returns the scsi_cmnd result field if a command was executed, or a negative + * Linux error code if we didn't get that far. + */ +-int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, +- blk_opf_t opf, void *buffer, unsigned int bufflen, +- int timeout, int retries, +- const struct scsi_exec_args *args) ++int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, ++ int data_direction, void *buffer, unsigned bufflen, ++ unsigned char *sense, struct scsi_sense_hdr *sshdr, ++ int timeout, int retries, blk_opf_t flags, ++ req_flags_t rq_flags, int *resid) + { +- static const struct scsi_exec_args default_args; + struct request *req; + struct scsi_cmnd *scmd; + int ret; + +- if (!args) +- args = &default_args; +- else if (WARN_ON_ONCE(args->sense && +- args->sense_len != SCSI_SENSE_BUFFERSIZE)) +- return -EINVAL; +- +- req = scsi_alloc_request(sdev->request_queue, opf, args->req_flags); ++ req = scsi_alloc_request(sdev->request_queue, ++ data_direction == DMA_TO_DEVICE ? ++ REQ_OP_DRV_OUT : REQ_OP_DRV_IN, ++ rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); + if (IS_ERR(req)) + return PTR_ERR(req); + +@@ -230,7 +232,8 @@ int scsi_execute_cmd(struct scsi_device + memcpy(scmd->cmnd, cmd, scmd->cmd_len); + scmd->allowed = retries; + req->timeout = timeout; +- req->rq_flags |= RQF_QUIET; ++ req->cmd_flags |= flags; ++ req->rq_flags |= rq_flags | RQF_QUIET; + + /* + * head injection *required* here otherwise quiesce won't work +@@ -246,21 +249,20 @@ int scsi_execute_cmd(struct scsi_device + if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen)) + memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len); + +- if (args->resid) +- *args->resid = scmd->resid_len; +- if (args->sense) +- memcpy(args->sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); +- if (args->sshdr) ++ if (resid) ++ *resid = scmd->resid_len; ++ if (sense && scmd->sense_len) ++ memcpy(sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); ++ if (sshdr) + scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len, +- args->sshdr); +- ++ sshdr); + ret = scmd->result; + out: + blk_mq_free_request(req); + + return ret; + } +-EXPORT_SYMBOL(scsi_execute_cmd); ++EXPORT_SYMBOL(__scsi_execute); + + /* + * Wake up the error handler if necessary. Avoid as follows that the error +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -479,51 +479,28 @@ extern const char *scsi_device_state_nam + extern int scsi_is_sdev_device(const struct device *); + extern int scsi_is_target_device(const struct device *); + extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); +- +-/* Optional arguments to scsi_execute_cmd */ +-struct scsi_exec_args { +- unsigned char *sense; /* sense buffer */ +- unsigned int sense_len; /* sense buffer len */ +- struct scsi_sense_hdr *sshdr; /* decoded sense header */ +- blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */ +- int *resid; /* residual length */ +-}; +- +-int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, +- blk_opf_t opf, void *buffer, unsigned int bufflen, +- int timeout, int retries, +- const struct scsi_exec_args *args); +- ++extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, ++ int data_direction, void *buffer, unsigned bufflen, ++ unsigned char *sense, struct scsi_sense_hdr *sshdr, ++ int timeout, int retries, blk_opf_t flags, ++ req_flags_t rq_flags, int *resid); + /* Make sure any sense buffer is the correct size. */ +-#define scsi_execute(_sdev, _cmd, _data_dir, _buffer, _bufflen, _sense, \ +- _sshdr, _timeout, _retries, _flags, _rq_flags, \ +- _resid) \ ++#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \ ++ sshdr, timeout, retries, flags, rq_flags, resid) \ + ({ \ +- scsi_execute_cmd(_sdev, _cmd, (_data_dir == DMA_TO_DEVICE ? \ +- REQ_OP_DRV_OUT : REQ_OP_DRV_IN) | _flags, \ +- _buffer, _bufflen, _timeout, _retries, \ +- &(struct scsi_exec_args) { \ +- .sense = _sense, \ +- .sshdr = _sshdr, \ +- .req_flags = _rq_flags & RQF_PM ? \ +- BLK_MQ_REQ_PM : 0, \ +- .resid = _resid, \ +- }); \ ++ BUILD_BUG_ON((sense) != NULL && \ ++ sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \ ++ __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \ ++ sense, sshdr, timeout, retries, flags, rq_flags, \ ++ resid); \ + }) +- + static inline int scsi_execute_req(struct scsi_device *sdev, + const unsigned char *cmd, int data_direction, void *buffer, + unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, + int retries, int *resid) + { +- return scsi_execute_cmd(sdev, cmd, +- data_direction == DMA_TO_DEVICE ? +- REQ_OP_DRV_OUT : REQ_OP_DRV_IN, buffer, +- bufflen, timeout, retries, +- &(struct scsi_exec_args) { +- .sshdr = sshdr, +- .resid = resid, +- }); ++ return scsi_execute(sdev, cmd, data_direction, buffer, ++ bufflen, NULL, sshdr, timeout, retries, 0, 0, resid); + } + extern void sdev_disable_disk_events(struct scsi_device *sdev); + extern void sdev_enable_disk_events(struct scsi_device *sdev); diff --git a/queue-6.1/revert-scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch b/queue-6.1/revert-scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch new file mode 100644 index 00000000000..acc1865e357 --- /dev/null +++ b/queue-6.1/revert-scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch @@ -0,0 +1,114 @@ +From 9050061d7acde071fee4c2c2c76196da873684a8 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 11 Apr 2024 09:24:48 +0200 +Subject: Revert "scsi: sd: usb_storage: uas: Access media prior to querying device properties" + +From: Greg Kroah-Hartman + +This reverts commit b73dd5f9997279715cd450ee8ca599aaff2eabb9 which is +commit 321da3dc1f3c92a12e3c5da934090d2992a8814c upstream. + +It is known to cause problems and has asked to be dropped. + +Link: https://lore.kernel.org/r/yq1frvvpymp.fsf@ca-mkp.ca.oracle.com +Cc: Tasos Sahanidis +Cc: Ewan D. Milne +Cc: Bart Van Assche +Cc: Tasos Sahanidis +Cc: Martin K. Petersen +Cc: James Bottomley +Cc: Sasha Levin +Reported-by: John David Anglin +Reported-by: Cyril Brulebois +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sd.c | 26 +------------------------- + drivers/usb/storage/scsiglue.c | 7 ------- + drivers/usb/storage/uas.c | 7 ------- + include/scsi/scsi_device.h | 1 - + 4 files changed, 1 insertion(+), 40 deletions(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3286,24 +3286,6 @@ static bool sd_validate_opt_xfer_size(st + return true; + } + +-static void sd_read_block_zero(struct scsi_disk *sdkp) +-{ +- unsigned int buf_len = sdkp->device->sector_size; +- char *buffer, cmd[10] = { }; +- +- buffer = kmalloc(buf_len, GFP_KERNEL); +- if (!buffer) +- return; +- +- cmd[0] = READ_10; +- put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */ +- put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */ +- +- scsi_execute_cmd(sdkp->device, cmd, REQ_OP_DRV_IN, buffer, buf_len, +- SD_TIMEOUT, sdkp->max_retries, NULL); +- kfree(buffer); +-} +- + /** + * sd_revalidate_disk - called the first time a new disk is seen, + * performs disk spin up, read_capacity, etc. +@@ -3343,13 +3325,7 @@ static int sd_revalidate_disk(struct gen + */ + if (sdkp->media_present) { + sd_read_capacity(sdkp, buffer); +- /* +- * Some USB/UAS devices return generic values for mode pages +- * until the media has been accessed. Trigger a READ operation +- * to force the device to populate mode pages. +- */ +- if (sdp->read_before_ms) +- sd_read_block_zero(sdkp); ++ + /* + * set the default to rotational. All non-rotational devices + * support the block characteristics VPD page, which will +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -180,13 +180,6 @@ static int slave_configure(struct scsi_d + sdev->use_192_bytes_for_3f = 1; + + /* +- * Some devices report generic values until the media has been +- * accessed. Force a READ(10) prior to querying device +- * characteristics. +- */ +- sdev->read_before_ms = 1; +- +- /* + * Some devices don't like MODE SENSE with page=0x3f, + * which is the command used for checking if a device + * is write-protected. Now that we tell the sd driver +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -877,13 +877,6 @@ static int uas_slave_configure(struct sc + sdev->guess_capacity = 1; + + /* +- * Some devices report generic values until the media has been +- * accessed. Force a READ(10) prior to querying device +- * characteristics. +- */ +- sdev->read_before_ms = 1; +- +- /* + * Some devices don't like MODE SENSE with page=0x3f, + * which is the command used for checking if a device + * is write-protected. Now that we tell the sd driver +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -204,7 +204,6 @@ struct scsi_device { + unsigned use_10_for_rw:1; /* first try 10-byte read / write */ + unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */ +- unsigned read_before_ms:1; /* perform a READ before MODE SENSE */ + unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ + unsigned no_write_same:1; /* no WRITE SAME command */ + unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ diff --git a/queue-6.1/scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch b/queue-6.1/scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch new file mode 100644 index 00000000000..28480ed8102 --- /dev/null +++ b/queue-6.1/scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch @@ -0,0 +1,145 @@ +From c037c501860ddaa2625b08dc8806d4b491bb6bd7 Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Tue, 13 Feb 2024 09:33:06 -0500 +Subject: scsi: sd: usb_storage: uas: Access media prior to querying device properties + +From: "Martin K. Petersen" + +[ Upstream commit 321da3dc1f3c92a12e3c5da934090d2992a8814c ] + +It has been observed that some USB/UAS devices return generic properties +hardcoded in firmware for mode pages for a period of time after a device +has been discovered. The reported properties are either garbage or they do +not accurately reflect the characteristics of the physical storage device +attached in the case of a bridge. + +Prior to commit 1e029397d12f ("scsi: sd: Reorganize DIF/DIX code to +avoid calling revalidate twice") we would call revalidate several +times during device discovery. As a result, incorrect values would +eventually get replaced with ones accurately describing the attached +storage. When we did away with the redundant revalidate pass, several +cases were reported where devices reported nonsensical values or would +end up in write-protected state. + +An initial attempt at addressing this issue involved introducing a +delayed second revalidate invocation. However, this approach still +left some devices reporting incorrect characteristics. + +Tasos Sahanidis debugged the problem further and identified that +introducing a READ operation prior to MODE SENSE fixed the problem and that +it wasn't a timing issue. Issuing a READ appears to cause the devices to +update their state to reflect the actual properties of the storage +media. Device properties like vendor, model, and storage capacity appear to +be correctly reported from the get-go. It is unclear why these devices +defer populating the remaining characteristics. + +Match the behavior of a well known commercial operating system and +trigger a READ operation prior to querying device characteristics to +force the device to populate the mode pages. + +The additional READ is triggered by a flag set in the USB storage and +UAS drivers. We avoid issuing the READ for other transport classes +since some storage devices identify Linux through our particular +discovery command sequence. + +Link: https://lore.kernel.org/r/20240213143306.2194237-1-martin.petersen@oracle.com +Fixes: 1e029397d12f ("scsi: sd: Reorganize DIF/DIX code to avoid calling revalidate twice") +Cc: stable@vger.kernel.org +Reported-by: Tasos Sahanidis +Reviewed-by: Ewan D. Milne +Reviewed-by: Bart Van Assche +Tested-by: Tasos Sahanidis +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sd.c | 26 +++++++++++++++++++++++++- + drivers/usb/storage/scsiglue.c | 7 +++++++ + drivers/usb/storage/uas.c | 7 +++++++ + include/scsi/scsi_device.h | 1 + + 4 files changed, 40 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -3286,6 +3286,24 @@ static bool sd_validate_opt_xfer_size(st + return true; + } + ++static void sd_read_block_zero(struct scsi_disk *sdkp) ++{ ++ unsigned int buf_len = sdkp->device->sector_size; ++ char *buffer, cmd[10] = { }; ++ ++ buffer = kmalloc(buf_len, GFP_KERNEL); ++ if (!buffer) ++ return; ++ ++ cmd[0] = READ_10; ++ put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */ ++ put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */ ++ ++ scsi_execute_req(sdkp->device, cmd, DMA_FROM_DEVICE, buffer, buf_len, ++ NULL, SD_TIMEOUT, sdkp->max_retries, NULL); ++ kfree(buffer); ++} ++ + /** + * sd_revalidate_disk - called the first time a new disk is seen, + * performs disk spin up, read_capacity, etc. +@@ -3325,7 +3343,13 @@ static int sd_revalidate_disk(struct gen + */ + if (sdkp->media_present) { + sd_read_capacity(sdkp, buffer); +- ++ /* ++ * Some USB/UAS devices return generic values for mode pages ++ * until the media has been accessed. Trigger a READ operation ++ * to force the device to populate mode pages. ++ */ ++ if (sdp->read_before_ms) ++ sd_read_block_zero(sdkp); + /* + * set the default to rotational. All non-rotational devices + * support the block characteristics VPD page, which will +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -180,6 +180,13 @@ static int slave_configure(struct scsi_d + sdev->use_192_bytes_for_3f = 1; + + /* ++ * Some devices report generic values until the media has been ++ * accessed. Force a READ(10) prior to querying device ++ * characteristics. ++ */ ++ sdev->read_before_ms = 1; ++ ++ /* + * Some devices don't like MODE SENSE with page=0x3f, + * which is the command used for checking if a device + * is write-protected. Now that we tell the sd driver +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -877,6 +877,13 @@ static int uas_slave_configure(struct sc + sdev->guess_capacity = 1; + + /* ++ * Some devices report generic values until the media has been ++ * accessed. Force a READ(10) prior to querying device ++ * characteristics. ++ */ ++ sdev->read_before_ms = 1; ++ ++ /* + * Some devices don't like MODE SENSE with page=0x3f, + * which is the command used for checking if a device + * is write-protected. Now that we tell the sd driver +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -204,6 +204,7 @@ struct scsi_device { + unsigned use_10_for_rw:1; /* first try 10-byte read / write */ + unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */ ++ unsigned read_before_ms:1; /* perform a READ before MODE SENSE */ + unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ + unsigned no_write_same:1; /* no WRITE SAME command */ + unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ diff --git a/queue-6.1/series b/queue-6.1/series index aeab49c4be2..9aecfe73a60 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -71,3 +71,6 @@ netfilter-nf_tables-release-mutex-after-nft_gc_seq_e.patch netfilter-nf_tables-discard-table-flag-update-with-p.patch tty-n_gsm-require-cap_net_admin-to-attach-n_gsm0710-ldisc.patch gcc-plugins-stackleak-avoid-.head.text-section.patch +revert-scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch +revert-scsi-core-add-struct-for-args-to-execution-functions.patch +scsi-sd-usb_storage-uas-access-media-prior-to-querying-device-properties.patch -- 2.39.5