lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250424121333.417372-1-Raju.Rangoju@amd.com>
Date: Thu, 24 Apr 2025 17:43:33 +0530
From: Raju Rangoju <Raju.Rangoju@....com>
To: <broonie@...nel.org>
CC: <linux-spi@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<miquel.raynal@...tlin.com>, Raju Rangoju <Raju.Rangoju@....com>,
	Krishnamoorthi M <krishnamoorthi.m@....com>, Akshata MukundShetty
	<akshata.mukundshetty@....com>
Subject: [PATCH] spi: spi-mem: Add fix to avoid divide error

For some SPI flash memory operations, dummy bytes are not mandatory. For
example, in Winbond SPINAND flash memory devices, the `write_cache` and
`update_cache` operation variants have zero dummy bytes. Calculating the
duration for SPI memory operations with zero dummy bytes causes
a divide error when `ncycles` is calculated in the
spi_mem_calc_op_duration().

Add changes to skip the 'ncylcles' calculation for zero dummy bytes.

Following divide error is fixed by this change:

 Oops: divide error: 0000 [#1] PREEMPT SMP NOPTI
 CPU: 15 UID: 0 PID: 1872 Comm: modprobe Not tainted 6.14.0-rc7-zero-day-+ #7
 Hardware name: AMD FOX/Lilac-RMB, BIOS RFE1007A_SPI2_11112024. 10/17/2024
 RIP: 0010:spi_mem_calc_op_duration+0x56/0xb0
 Code: 47 08 0f b6 7f 09 c1 e0 03 99 f7 ff 0f b6 51 0a 83 e2 01 8d 7a 01 99 f7 ff 0f b6 79 19 48 98 48 01 c6 0f b6 41 18 c1 e0 03 99 <f7> ff 0f b6 51 1a 83 e2 01 8d 7a 01 99 f7 ff 0f b6 79 20 31 d2 48
 RSP: 0018:ffffb6638416b3d0 EFLAGS: 00010256
 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffb6638416b3f0
 RDX: 0000000000000000 RSI: 0000000000000018 RDI: 0000000000000000
 RBP: ffffb6638416b460 R08: 0000000000000000 R09: 0000000000000000
 R10: 0000000000000000 R11: 0000000000000000 R12: ffff9d98d476b828
 R13: 0000000000000000 R14: 0000000000000040 R15: ffffffffc0f5a3b0
 FS:  00007ed599a0dc40(0000) GS:ffff9d9c25180000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007d798ce9cff0 CR3: 0000000111506000 CR4: 0000000000750ef0
 PKRU: 55555554
 Call Trace:
  <TASK>
  ? show_regs+0x71/0x90
  ? die+0x38/0xa0
  ? do_trap+0xdb/0x100
  ? do_error_trap+0x75/0xb0
  ? spi_mem_calc_op_duration+0x56/0xb0
  ? exc_divide_error+0x3b/0x70
  ? spi_mem_calc_op_duration+0x56/0xb0
  ? asm_exc_divide_error+0x1b/0x20
  ? spi_mem_calc_op_duration+0x56/0xb0
  ? spinand_select_op_variant+0xee/0x190 [spinand]
  spinand_match_and_init+0x13e/0x1a0 [spinand]
  spinand_manufacturer_match+0x6e/0xa0 [spinand]
  spinand_probe+0x357/0x7f0 [spinand]
  ? kernfs_activate+0x87/0xd0
  spi_mem_probe+0x7a/0xb0
  spi_probe+0x7d/0x130
  ? driver_sysfs_add+0x66/0xd0
  really_probe+0xf7/0x3b0
  __driver_probe_device+0x8a/0x180
  driver_probe_device+0x23/0xd0
  __device_attach_driver+0xc5/0x160
  ? __pfx___device_attach_driver+0x10/0x10
  bus_for_each_drv+0x89/0xf0
  __device_attach+0xc1/0x200
  device_initial_probe+0x13/0x20
  bus_probe_device+0x9f/0xb0
  device_add+0x64f/0x870
  __spi_add_device+0x187/0x390
  spi_new_device+0x13a/0x1f0
  spinand_drv_init+0xe4/0xff0 [spinand]
  ? __pfx_spinand_drv_init+0x10/0x10 [spinand]
  do_one_initcall+0x49/0x330
  do_init_module+0x6a/0x290
  load_module+0x2522/0x2620
  init_module_from_file+0x9c/0xf0
  ? init_module_from_file+0x9c/0xf0
  idempotent_init_module+0x178/0x270
  __x64_sys_finit_module+0x77/0x100
  x64_sys_call+0x1f0b/0x26f0
  do_syscall_64+0x70/0x130
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? mmap_region+0x67/0xe0
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? do_mmap+0x52b/0x650
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? vm_mmap_pgoff+0x152/0x200
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? ksys_mmap_pgoff+0x191/0x250
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? syscall_exit_to_user_mode+0x53/0x1c0
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? do_syscall_64+0x7c/0x130
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? syscall_exit_to_user_mode+0x18c/0x1c0
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? do_syscall_64+0x7c/0x130
  entry_SYSCALL_64_after_hwframe+0x76/0x7e
 RIP: 0033:0x7ed59911e88d
 Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 b5 0f 00 f7 d8 64 89 01 48
 RSP: 002b:00007ffd5c54e7f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
 RAX: ffffffffffffffda RBX: 000060eff3d62f50 RCX: 00007ed59911e88d
 RDX: 0000000000000000 RSI: 000060efdbd38cd2 RDI: 0000000000000006
 RBP: 0000000000040000 R08: 0000000000000000 R09: 0000000000000002
 R10: 0000000000000006 R11: 0000000000000246 R12: 000060efdbd38cd2
 R13: 000060eff3d63080 R14: 000060eff3d629e0 R15: 000060eff3d63780
  </TASK>

Fixes: 226d6cb3cb79 ("spi: spi-mem: Estimate the time taken by operations")
Suggested-by: Krishnamoorthi M <krishnamoorthi.m@....com>
Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@....com>
Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@....com>
Signed-off-by: Raju Rangoju <Raju.Rangoju@....com>
---
 drivers/spi/spi-mem.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index a31a1db07aa4..5db0639d3b01 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -596,7 +596,11 @@ u64 spi_mem_calc_op_duration(struct spi_mem_op *op)
 	ns_per_cycles = 1000000000 / op->max_freq;
 	ncycles += ((op->cmd.nbytes * 8) / op->cmd.buswidth) / (op->cmd.dtr ? 2 : 1);
 	ncycles += ((op->addr.nbytes * 8) / op->addr.buswidth) / (op->addr.dtr ? 2 : 1);
-	ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
+
+	/* Dummy bytes are optional for some SPI flash memory operations */
+	if (op->dummy.nbytes)
+		ncycles += ((op->dummy.nbytes * 8) / op->dummy.buswidth) / (op->dummy.dtr ? 2 : 1);
+
 	ncycles += ((op->data.nbytes * 8) / op->data.buswidth) / (op->data.dtr ? 2 : 1);
 
 	return ncycles * ns_per_cycles;
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ