From: Xingui Yang yangxingui@huawei.com
mainline inclusion from mainline-v6.3-rc1 commit 26a02d972bad category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6V6I1 CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------------------------------------
If a controller has DIX is enabled and an attached disk is formatted using a protection type supported by the controller, a block integrity profile is registered to enable protected transfers.
If the disk is subsequently reformatted to disable PI, and the controller does not support DIX Type 0, this can lead to failures such as this:
[142829.032340] hisi_sas_v3_hw 0000:b4:04.0: erroneous completion iptt=2375 task=00000000bea0970c dev id=5 direct-attached phy4 addr=51c20dbaf642a000 CQ hdr: 0x1023 0x50947 0x0 0x20000 Error info: 0x0 0x0 0x4 0x0 [142829.073883] sas: Enter sas_scsi_recover_host busy: 1 failed: 1 [142829.079783] sas: sas_scsi_find_task: aborting task 0x00000000bea0970c [142829.102342] sas: Internal abort: task to dev 51c20dbaf642a000 response: 0x0 status 0x5 [142829.110319] sas: sas_eh_handle_sas_errors: task 0x00000000bea0970c is done [142829.117275] sd 7:0:5:0: [sdc] tag#2375 UNKNOWN(0x2003) Result: hostbyte=0x05 driverbyte=DRIVER_OK cmd_age=0s [142829.127171] sd 7:0:5:0: [sdc] tag#2375 CDB: opcode=0x2a 2a 00 00 00 00 00 00 00 08 00 [142829.135059] I/O error, dev sdc, sector 0 op 0x1:(WRITE) flags 0x18800 phys_seg 1 prio class 2
This is because the block layer integrity profile is currently only set up the first time a disk is discovered.
To address this, remove the first_scan check when configuring protection information during revalidate. Also unregister the block integrity profile if DIX is not supported with a given protection type.
[mkp: commit description + printk dedup]
Link: https://lore.kernel.org/r/20230221081026.24736-1-yangxingui@huawei.com Signed-off-by: Xingui Yang yangxingui@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: xiabing xiabing12@h-partners.com --- drivers/scsi/sd.c | 13 +++++-------- drivers/scsi/sd_dif.c | 10 ++++++---- 2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b3d14b4c5e67..b5bd2d3c0e87 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2311,23 +2311,20 @@ static void sd_config_protection(struct scsi_disk *sdkp) { struct scsi_device *sdp = sdkp->device;
- if (!sdkp->first_scan) - return; - sd_dif_config_host(sdkp);
if (!sdkp->protection_type) return;
if (!scsi_host_dif_capable(sdp->host, sdkp->protection_type)) { - sd_printk(KERN_NOTICE, sdkp, - "Disabling DIF Type %u protection\n", - sdkp->protection_type); + sd_first_printk(KERN_NOTICE, sdkp, + "Disabling DIF Type %u protection\n", + sdkp->protection_type); sdkp->protection_type = 0; }
- sd_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n", - sdkp->protection_type); + sd_first_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n", + sdkp->protection_type); }
static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index a07c3ad6d276..7dd57a5fd4eb 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c @@ -39,8 +39,10 @@ void sd_dif_config_host(struct scsi_disk *sdkp) dif = 0; dix = 1; }
- if (!dix) + if (!dix) { + blk_integrity_unregister(disk); return; + }
memset(&bi, 0, sizeof(bi));
@@ -72,9 +74,9 @@ void sd_dif_config_host(struct scsi_disk *sdkp) bi.tag_size = sizeof(u16); }
- sd_printk(KERN_NOTICE, sdkp, - "Enabling DIX %s, application tag size %u bytes\n", - bi.profile->name, bi.tag_size); + sd_first_printk(KERN_NOTICE, sdkp, + "Enabling DIX %s, application tag size %u bytes\n", + bi.profile->name, bi.tag_size); out: blk_integrity_register(disk, &bi); }