drivers/scsi/scsi.c | 39 +++++++++++++++++++++----------------- include/scsi/scsi_device.h | 12 ++++++++++++ 2 files changed, 34 insertions(+), 17 deletions(-)
When the vpd_buf->data[i] is expected to be processed, stop other
judgments.
Signed-off-by: Chaohai Chen <wdhh6@aliyun.com>
---
v1: https://lore.kernel.org/all/20250226065802.234144-1-wdhh6@aliyun.com/
v1->v2:
* Modify this function so that there is no code duplication
---
---
drivers/scsi/scsi.c | 39 +++++++++++++++++++++-----------------
include/scsi/scsi_device.h | 12 ++++++++++++
2 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a77e0499b738..e840616d4deb 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -498,8 +498,18 @@ static void scsi_update_vpd_page(struct scsi_device *sdev, u8 page,
*/
void scsi_attach_vpd(struct scsi_device *sdev)
{
- int i;
+ int i, j;
struct scsi_vpd *vpd_buf;
+ static const struct vpd_page_info cached_page[] = {
+ VPD_PAGE_INFO(0),
+ VPD_PAGE_INFO(80),
+ VPD_PAGE_INFO(83),
+ VPD_PAGE_INFO(89),
+ VPD_PAGE_INFO(b0),
+ VPD_PAGE_INFO(b1),
+ VPD_PAGE_INFO(b2),
+ VPD_PAGE_INFO(b7),
+ };
if (!scsi_device_supports_vpd(sdev))
return;
@@ -510,22 +520,17 @@ void scsi_attach_vpd(struct scsi_device *sdev)
return;
for (i = 4; i < vpd_buf->len; i++) {
- if (vpd_buf->data[i] == 0x0)
- scsi_update_vpd_page(sdev, 0x0, &sdev->vpd_pg0);
- if (vpd_buf->data[i] == 0x80)
- scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80);
- if (vpd_buf->data[i] == 0x83)
- scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83);
- if (vpd_buf->data[i] == 0x89)
- scsi_update_vpd_page(sdev, 0x89, &sdev->vpd_pg89);
- if (vpd_buf->data[i] == 0xb0)
- scsi_update_vpd_page(sdev, 0xb0, &sdev->vpd_pgb0);
- if (vpd_buf->data[i] == 0xb1)
- scsi_update_vpd_page(sdev, 0xb1, &sdev->vpd_pgb1);
- if (vpd_buf->data[i] == 0xb2)
- scsi_update_vpd_page(sdev, 0xb2, &sdev->vpd_pgb2);
- if (vpd_buf->data[i] == 0xb7)
- scsi_update_vpd_page(sdev, 0xb7, &sdev->vpd_pgb7);
+ for (j = 0; j < ARRAY_SIZE(cached_page); j++) {
+ const u8 page_code = cached_page[j].page_code;
+ const u16 offset = cached_page[j].offset;
+ struct scsi_vpd __rcu **vpd_data =
+ (void *)&sdev + offset;
+
+ if (vpd_buf->data[i] == page_code) {
+ scsi_update_vpd_page(sdev, page_code, vpd_data);
+ break;
+ }
+ }
}
kfree(vpd_buf);
}
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 7acd0ec82bb0..46f17875b758 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -284,6 +284,18 @@ struct scsi_device {
unsigned long sdev_data[];
} __attribute__((aligned(sizeof(unsigned long))));
+struct vpd_page_info {
+ u8 page_code;
+ u16 offset; /* offset in struct scsi_device of vpd_pg... member */
+};
+
+#define SCSI_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - sizeof(char))
+
+#define VPD_PAGE_INFO(vpd_page) \
+ { 0x##vpd_page, offsetof(struct scsi_device, vpd_pg##vpd_page) + \
+ SCSI_BUILD_BUG_ON(!__same_type(&((struct scsi_device *)NULL)->vpd_pg##vpd_page, \
+ struct scsi_vpd __rcu **))} \
+
#define to_scsi_device(d) \
container_of(d, struct scsi_device, sdev_gendev)
#define class_to_sdev(d) \
--
2.34.1
Hello,
kernel test robot noticed "BUG:unable_to_handle_page_fault_for_address" on:
commit: 8e44a5176a631b6b5ba7efa557d8b1895eb56d85 ("[PATCH v2] scsi: stop judging after finding a VPD page expected to be processed.")
url: https://github.com/intel-lab-lkp/linux/commits/Chaohai-Chen/scsi-stop-judging-after-finding-a-VPD-page-expected-to-be-processed/20250227-140720
base: https://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git for-next
patch link: https://lore.kernel.org/all/20250227060618.15787-1-wdhh6@aliyun.com/
patch subject: [PATCH v2] scsi: stop judging after finding a VPD page expected to be processed.
in testcase: boot
config: x86_64-rhel-9.4
compiler: gcc-12
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G
(please refer to attached dmesg/kmsg for entire log/backtrace)
+---------------------------------------------+------------+------------+
| | 5d51aea463 | 8e44a5176a |
+---------------------------------------------+------------+------------+
| boot_successes | 12 | 0 |
| boot_failures | 0 | 14 |
| BUG:unable_to_handle_page_fault_for_address | 0 | 14 |
| Oops | 0 | 14 |
| RIP:build_detached_freelist | 0 | 14 |
| Kernel_panic-not_syncing:Fatal_exception | 0 | 14 |
+---------------------------------------------+------------+------------+
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202503041036.ad427cb-lkp@intel.com
[ 14.245211][ T124] BUG: unable to handle page fault for address: ffffdeda9e000008
[ 14.245852][ T124] #PF: supervisor read access in kernel mode
[ 14.246293][ T124] #PF: error_code(0x0000) - not-present page
[ 14.246740][ T124] PGD 0 P4D 0
[ 14.247003][ T124] Oops: Oops: 0000 [#1] SMP PTI
[ 14.247375][ T124] CPU: 1 UID: 0 PID: 124 Comm: kworker/u8:3 Not tainted 6.14.0-rc1-00076-g8e44a5176a63 #1
[ 14.248100][ T124] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[ 14.248837][ T124] Workqueue: events_unbound kfree_rcu_work
[ 14.249283][ T124] RIP: 0010:build_detached_freelist (include/linux/page-flags.h:243 include/linux/mm.h:1297 mm/slab.h:211 mm/slub.c:4941)
[ 14.250299][ T124] Code: 8b 03 48 89 ca 48 01 c2 0f 82 ed 01 00 00 4d 89 d3 4c 2b 1d 74 b4 57 01 4c 01 da 48 c1 ea 0c 48 c1 e2 06 48 03 15 52 b4 57 01 <4c> 8b 6a 08 49 89 d3 41 f6 c5 01 0f 85 dd 00 00 00 0f 1f 44 00 00
All code
========
0: 8b 03 mov (%rbx),%eax
2: 48 89 ca mov %rcx,%rdx
5: 48 01 c2 add %rax,%rdx
8: 0f 82 ed 01 00 00 jb 0x1fb
e: 4d 89 d3 mov %r10,%r11
11: 4c 2b 1d 74 b4 57 01 sub 0x157b474(%rip),%r11 # 0x157b48c
18: 4c 01 da add %r11,%rdx
1b: 48 c1 ea 0c shr $0xc,%rdx
1f: 48 c1 e2 06 shl $0x6,%rdx
23: 48 03 15 52 b4 57 01 add 0x157b452(%rip),%rdx # 0x157b47c
2a:* 4c 8b 6a 08 mov 0x8(%rdx),%r13 <-- trapping instruction
2e: 49 89 d3 mov %rdx,%r11
31: 41 f6 c5 01 test $0x1,%r13b
35: 0f 85 dd 00 00 00 jne 0x118
3b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Code starting with the faulting instruction
===========================================
0: 4c 8b 6a 08 mov 0x8(%rdx),%r13
4: 49 89 d3 mov %rdx,%r11
7: 41 f6 c5 01 test $0x1,%r13b
b: 0f 85 dd 00 00 00 jne 0xee
11: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
[ 14.252909][ T124] RSP: 0000:ffffa8e5004ebcd0 EFLAGS: 00010286
[ 14.253973][ T124] RAX: 0000000080000000 RBX: ffffa8e5004ebd50 RCX: 0000000000000003
[ 14.255143][ T124] RDX: ffffdeda9e000000 RSI: 0000000000000177 RDI: 0000000000000002
[ 14.256313][ T124] RBP: ffff95f9e637b028 R08: ffffdd3284e15900 R09: 0000000000000000
[ 14.257464][ T124] R10: ffffffff80000000 R11: 00006a0700000000 R12: 0000000000000178
[ 14.258661][ T124] R13: 504d56b8f995ffff R14: ffff95f980042200 R15: 000000000000017d
[ 14.259806][ T124] FS: 0000000000000000(0000) GS:ffff95fcafd00000(0000) knlGS:0000000000000000
[ 14.261074][ T124] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 14.262173][ T124] CR2: ffffdeda9e000008 CR3: 0000000167df6000 CR4: 00000000000406f0
[ 14.263363][ T124] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 14.264575][ T124] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 14.265747][ T124] Call Trace:
[ 14.266530][ T124] <TASK>
[ 14.267349][ T124] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434)
[ 14.268182][ T124] ? page_fault_oops (arch/x86/mm/fault.c:714)
[ 14.269105][ T124] ? exc_page_fault (arch/x86/mm/fault.c:1478 arch/x86/mm/fault.c:1538)
[ 14.269972][ T124] ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:623)
[ 14.270888][ T124] ? build_detached_freelist (include/linux/page-flags.h:243 include/linux/mm.h:1297 mm/slab.h:211 mm/slub.c:4941)
[ 14.271810][ T124] kmem_cache_free_bulk (mm/slub.c:4706)
[ 14.272840][ T124] ? dequeue_entity (kernel/sched/fair.c:5488)
[ 14.273683][ T124] ? kvfree_rcu_bulk (include/linux/slab.h:791 mm/slab_common.c:1498)
[ 14.274542][ T124] kvfree_rcu_bulk (include/linux/slab.h:791 mm/slab_common.c:1498)
[ 14.275389][ T124] kfree_rcu_work (mm/slab_common.c:1576)
[ 14.276255][ T124] ? finish_task_switch+0x85/0x2b0
[ 14.277161][ T124] process_one_work (kernel/workqueue.c:3241)
[ 14.277998][ T124] worker_thread (kernel/workqueue.c:3311 kernel/workqueue.c:3398)
[ 14.278830][ T124] ? __pfx_worker_thread (kernel/workqueue.c:3344)
[ 14.279670][ T124] kthread (kernel/kthread.c:464)
[ 14.280456][ T124] ? __pfx_kthread (kernel/kthread.c:413)
[ 14.281263][ T124] ret_from_fork (arch/x86/kernel/process.c:154)
[ 14.282106][ T124] ? __pfx_kthread (kernel/kthread.c:413)
[ 14.282915][ T124] ret_from_fork_asm (arch/x86/entry/entry_64.S:257)
[ 14.283726][ T124] </TASK>
[ 14.284397][ T124] Modules linked in: ipmi_devintf ipmi_msghandler sr_mod cdrom sg snd_pcm intel_rapl_msr ata_generic intel_rapl_common snd_timer ghash_clmulni_intel ppdev rapl snd bochs drm_client_lib drm_shmem_helper soundcore i2c_piix4 ata_piix i2c_smbus drm_kms_helper joydev pcspkr parport_pc libata serio_raw parport fuse drm ip_tables
[ 14.287967][ T124] CR2: ffffdeda9e000008
[ 14.288794][ T124] ---[ end trace 0000000000000000 ]---
[ 14.289744][ T124] RIP: 0010:build_detached_freelist (include/linux/page-flags.h:243 include/linux/mm.h:1297 mm/slab.h:211 mm/slub.c:4941)
[ 14.290724][ T124] Code: 8b 03 48 89 ca 48 01 c2 0f 82 ed 01 00 00 4d 89 d3 4c 2b 1d 74 b4 57 01 4c 01 da 48 c1 ea 0c 48 c1 e2 06 48 03 15 52 b4 57 01 <4c> 8b 6a 08 49 89 d3 41 f6 c5 01 0f 85 dd 00 00 00 0f 1f 44 00 00
All code
========
0: 8b 03 mov (%rbx),%eax
2: 48 89 ca mov %rcx,%rdx
5: 48 01 c2 add %rax,%rdx
8: 0f 82 ed 01 00 00 jb 0x1fb
e: 4d 89 d3 mov %r10,%r11
11: 4c 2b 1d 74 b4 57 01 sub 0x157b474(%rip),%r11 # 0x157b48c
18: 4c 01 da add %r11,%rdx
1b: 48 c1 ea 0c shr $0xc,%rdx
1f: 48 c1 e2 06 shl $0x6,%rdx
23: 48 03 15 52 b4 57 01 add 0x157b452(%rip),%rdx # 0x157b47c
2a:* 4c 8b 6a 08 mov 0x8(%rdx),%r13 <-- trapping instruction
2e: 49 89 d3 mov %rdx,%r11
31: 41 f6 c5 01 test $0x1,%r13b
35: 0f 85 dd 00 00 00 jne 0x118
3b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Code starting with the faulting instruction
===========================================
0: 4c 8b 6a 08 mov 0x8(%rdx),%r13
4: 49 89 d3 mov %rdx,%r11
7: 41 f6 c5 01 test $0x1,%r13b
b: 0f 85 dd 00 00 00 jne 0xee
11: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20250304/202503041036.ad427cb-lkp@intel.com
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On 27/02/2025 06:06, Chaohai Chen wrote:
> +#define SCSI_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - sizeof(char))
> +
> +#define VPD_PAGE_INFO(vpd_page) \
> + { 0x##vpd_page, offsetof(struct scsi_device, vpd_pg##vpd_page) + \
> + SCSI_BUILD_BUG_ON(!__same_type(&((struct scsi_device *)NULL)->vpd_pg##vpd_page, \
> + struct scsi_vpd __rcu **))} \
> +
> #define to_scsi_device(d) \
That's unreadable....
© 2016 - 2025 Red Hat, Inc.