Error while loading dw-i3c-master: UBSAN: shift-out-of-bounds in drivers/i3c/master/dw-i3c-master.c:885:12
Louis Sautier
louis.sautier at ovhcloud.com
Tue Dec 9 11:52:46 PST 2025
On 12/9/25 18:24, Frank Li wrote:
> On Tue, Dec 09, 2025 at 04:36:30PM +0100, Louis Sautier wrote:
>> On 12/9/25 13:48, Alexandre Belloni wrote:
>>> On 09/12/2025 12:37:12+0100, Louis Sautier wrote:
>>>> On 12/8/25 21:58, Alexandre Belloni wrote:
>>>>> Hello Louis,
>>>>>
>>>>> On 02/12/2025 21:17:31+0100, Louis Sautier wrote:
>>>>>> Hello,
>>>>>>
>>>>>> I'm running into a bug when loading the dw-i3c-master module on kernel 6.18
>>>>>> on one specific server. I suspect it has to do with the large number of
>>>>>> CPUs on the machine (768 threads, from 2 AMD EPYC 9965 processors) but I am
>>>>>> not sure.
>>>>>>
>>>>>> The system is on Ubuntu 25.10 and a 6.18 kernel with https://gist.githubusercontent.com/sbraz/a6f37fafbcf9354bbe4eace9e9eb48cb/raw/115da594dc9d7ea99b06754847571e6fd76d9da5/config
>>>>>> (basically Ubuntu's).
>>>>> Just to be sure, does this also happen with v6.17?
>>>>>
>>>>> The only change is the shutdown handling so I would guess yes.
>>>>>
>>>> Hello,
>>>>
>>>> It does happen with 6.17. I initially discovered this while running Ubuntu
>>>> 25.10's stock kernel (6.17.0).
>>>>
>>>>> What is the behavior when you build the dw-i3c-master as a static driver?
>>>> I'll try CONFIG_DW_I3C_MASTER=y and report back.
>>>>
>>>> Someone also suggested (they didn't reply to the list though) that I add a
>>>> printk to see what the value of maxdevs is. I'll provide the log as soon as
>>>> I have rebuilt with:
>>>>
>>>> --- linux-6.18.orig/drivers/i3c/master/dw-i3c-master.c 2025-11-30 22:42:10.000000000 +0000
>>>> +++ linux-6.18/drivers/i3c/master/dw-i3c-master.c 2025-12-08 18:17:33.151567225 +0000
>>>> @@ -1588,6 +1588,7 @@
>>>> ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
>>>> master->datstartaddr = ret;
>>>> master->maxdevs = ret >> 16;
>>>> + printk("maxdevs: %d\n", master->maxdevs);
>>>> master->free_pos = GENMASK(master->maxdevs - 1, 0);
>>>> master->quirks = (unsigned long)device_get_match_data(&pdev->dev);
>>>>
>>> Yes, that was going to be my suggestion.
>>>
>> I haven't tried with the driver built-in yet. This is what the printk shows:
>> dw-i3c-master AMDI0015:00: probe with driver dw-i3c-master failed with error
>> -110
>> maxdevs: 65535
> Maybe ret is bigger 0x8000_0000, and ret is sign int. so >>16 because -1.
>
> unsigned int val = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
>
> master->maxdevs = val >> 16;
>
> Frank
I tried this and CONFIG_DW_I3C_MASTER=y:
--- linux-6.18.orig/drivers/i3c/master/dw-i3c-master.c 2025-11-30
22:42:10.000000000 +0000
+++ linux-6.18/drivers/i3c/master/dw-i3c-master.c 2025-12-09
19:21:52.735366616 +0000
@@ -1585,9 +1585,10 @@
ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL);
master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret);
- ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
- master->datstartaddr = ret;
- master->maxdevs = ret >> 16;
+ unsigned int val = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
+ master->datstartaddr = val;
+ master->maxdevs = val >> 16;
+ printk("maxdevs (unsigned): %d\n", master->maxdevs);
master->free_pos = GENMASK(master->maxdevs - 1, 0);
master->quirks = (unsigned long)device_get_match_data(&pdev->dev);
And I get this log, so no change, really. I assume there's only one
"maxdevs" log because there is only one attempt to load the built-in driver?
maxdevs (unsigned): 65535
------------[ cut here ]------------
UBSAN: shift-out-of-bounds in drivers/i3c/master/dw-i3c-master.c:1592:21
usb 1-1: new high-speed USB device number 2 using xhci_hcd
shift exponent 18446744073709486145 is too large for 64-bit type 'long
unsigned int'
CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0 #4
PREEMPT(voluntary)
Hardware name: Giga Computing MZ73-LM2-000/MZ73-LM2-000, BIOS R23_F43
11/28/2025
Call Trace:
<TASK>
dump_stack_lvl+0x5f/0x90
dump_stack+0x10/0x18
ubsan_epilogue+0x9/0x39
__ubsan_handle_shift_out_of_bounds.cold+0xdd/0x1c9
dw_i3c_common_probe.cold+0x16/0x1b
dw_i3c_probe+0x30/0x50
platform_probe+0x42/0xc0
? driver_sysfs_add+0x63/0xd0
really_probe+0xf9/0x370
? pm_runtime_barrier+0x56/0xa0
__driver_probe_device+0x8b/0x160
driver_probe_device+0x24/0xd0
? __pfx___driver_attach+0x10/0x10
__driver_attach+0xef/0x220
? __pfx_dw_i3c_driver_init+0x10/0x10
bus_for_each_dev+0x8a/0xe0
driver_attach+0x1e/0x30
bus_add_driver+0x13e/0x230
? __pfx_dw_i3c_driver_init+0x10/0x10
driver_register+0x75/0xf0
__platform_driver_register+0x1e/0x30
dw_i3c_driver_init+0x17/0x30
do_one_initcall+0x59/0x330
kernel_init_freeable+0x2bd/0x340
? __pfx_kernel_init+0x10/0x10
kernel_init+0x1b/0x160
? __pfx_kernel_init+0x10/0x10
ret_from_fork+0x202/0x230
? __pfx_kernel_init+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
---[ end trace ]---
More information about the linux-i3c
mailing list