Re: [PATCH v5 1/1] pinctrl: mediatek: Add EINT support for multiple addresses
From: Uwe Kleine-König
Date: Mon Apr 14 2025 - 11:13:12 EST
Hello,
this patch became commit 3ef9f710efcb in v6.15-rc1. It breaks booting a
mt8365-evk.
With earlycon it's possible to see a null pointer exception:
[ 0.072938] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000002
[ 0.074101] Mem abort info:
[ 0.074468] ESR = 0x0000000096000004
[ 0.074984] EC = 0x25: DABT (current EL), IL = 32 bits
[ 0.075681] SET = 0, FnV = 0
[ 0.076083] EA = 0, S1PTW = 0
[ 0.076495] FSC = 0x04: level 0 translation fault
[ 0.077134] Data abort info:
[ 0.077511] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[ 0.078229] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 0.078891] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 0.079593] [0000000000000002] user address but active_mm is swapper
[ 0.080426] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[ 0.081248] Modules linked in:
[ 0.081656] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.14.0-rc3-00113-g3ef9f710efcb #18
[ 0.082796] Hardware name: MediaTek MT8365 Open Platform EVK (DT)
[ 0.083594] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.084507] pc : mtk_eint_do_init+0x470/0x580
[ 0.085088] lr : mtk_eint_do_init+0x37c/0x580
[ 0.085663] sp : ffff80008160b7e0
[ 0.086098] x29: ffff80008160b850 x28: 0000000000000000 x27: ffff8000812600b0
[ 0.087040] x26: ffff0000bf9b7a80 x25: ffff0000bf9baac8 x24: ffff0000bf9baac8
[ 0.087981] x23: 0000000000000000 x22: ffff8000800cebe0 x21: ffff80008147e418
[ 0.088922] x20: 0000000000000000 x19: ffff0000021be780 x18: 00000000ffffffff
[ 0.089863] x17: 0000000000000003 x16: ffff000001832b00 x15: ffff0000021b70e0
[ 0.090804] x14: 0000000000000001 x13: ffff0000021b70e3 x12: ffff000001832c00
[ 0.091744] x11: 0000000000000000 x10: ffff800080f11cc0 x9 : ffff80008160b780
[ 0.092685] x8 : ffff80008160b780 x7 : 0000000000000000 x6 : 00000000ffffffff
[ 0.093626] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800080d0dbb0
[ 0.094567] x2 : 0000000000000000 x1 : ffff800080d53100 x0 : 0000000000000000
[ 0.095509] Call trace:
[ 0.095831] mtk_eint_do_init+0x470/0x580 (P)
[ 0.096408] mtk_pctrl_init+0x464/0x4fc
[ 0.096917] mtk_pctrl_common_probe+0x30/0x60
[ 0.097494] platform_probe+0x68/0xdc
[ 0.097981] really_probe+0xbc/0x2c0
[ 0.098457] __driver_probe_device+0xcc/0x120
[ 0.099035] driver_probe_device+0x3c/0x154
[ 0.099590] __device_attach_driver+0xb8/0x140
[ 0.100179] bus_for_each_drv+0x88/0xe8
[ 0.100688] __device_attach+0xa0/0x190
[ 0.101197] device_initial_probe+0x14/0x20
[ 0.101752] bus_probe_device+0xb4/0xc0
[ 0.102261] device_add+0x554/0x72c
[ 0.102724] of_device_add+0x54/0x64
[ 0.103201] of_platform_device_create_pdata+0x8c/0x118
[ 0.103891] of_platform_bus_create+0x190/0x38c
[ 0.104491] of_platform_bus_create+0x1d8/0x38c
[ 0.105091] of_platform_populate+0x74/0x108
[ 0.105656] of_platform_default_populate_init+0xe8/0x10c
[ 0.106369] do_one_initcall+0x60/0x1d4
[ 0.106879] kernel_init_freeable+0x210/0x274
[ 0.107456] kernel_init+0x20/0x140
[ 0.107921] ret_from_fork+0x10/0x20
[ 0.108400] Code: 14000002 39404265 f9403260 8b170000 (39400802)
[ 0.109199] ---[ end trace 0000000000000000 ]---
[ 0.109821] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[ 0.110824] SMP: stopping secondary CPUs
[ 0.111345] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
The problem is that ...
On Sat, Mar 22, 2025 at 11:52:28AM +0800, Hao Chang wrote:
> int mtk_eint_do_init(struct mtk_eint *eint)
> {
> - int i;
> + unsigned int size, i, port, inst = 0;
> + struct mtk_pinctrl *hw = (struct mtk_pinctrl *)eint->pctl;
>
> /* If clients don't assign a specific regs, let's use generic one */
> if (!eint->regs)
> eint->regs = &mtk_generic_eint_regs;
>
> - eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
> - sizeof(*eint->wake_mask), GFP_KERNEL);
> - if (!eint->wake_mask)
> + eint->base_pin_num = devm_kmalloc_array(eint->dev, eint->nbase, sizeof(u16),
> + GFP_KERNEL | __GFP_ZERO);
> + if (!eint->base_pin_num)
> return -ENOMEM;
>
> - eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
> - sizeof(*eint->cur_mask), GFP_KERNEL);
> - if (!eint->cur_mask)
> - return -ENOMEM;
> + if (eint->nbase == 1) {
> + size = eint->hw->ap_num * sizeof(struct mtk_eint_pin);
> + eint->pins = devm_kmalloc(eint->dev, size, GFP_KERNEL);
> + if (!eint->pins)
> + goto err_pins;
> +
> + eint->base_pin_num[inst] = eint->hw->ap_num;
> + for (i = 0; i < eint->hw->ap_num; i++) {
> + eint->pins[i].instance = inst;
> + eint->pins[i].index = i;
> + eint->pins[i].debounce = (i < eint->hw->db_cnt) ? 1 : 0;
> + }
> + }
>
> - eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
> - sizeof(int), GFP_KERNEL);
> - if (!eint->dual_edge)
> - return -ENOMEM;
> + if (hw && hw->soc && hw->soc->eint_pin) {
> + eint->pins = hw->soc->eint_pin;
> + for (i = 0; i < eint->hw->ap_num; i++) {
> + inst = eint->pins[i].instance;
> + if (inst >= eint->nbase)
> + continue;
> + eint->base_pin_num[inst]++;
> + }
> + }
> +
> + eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL);
> + if (!eint->pin_list)
> + goto err_pin_list;
> +
> + eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
> + if (!eint->wake_mask)
> + goto err_wake_mask;
> +
> + eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
> + if (!eint->cur_mask)
> + goto err_cur_mask;
> +
> + for (i = 0; i < eint->nbase; i++) {
> + eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16),
> + GFP_KERNEL);
> + port = DIV_ROUND_UP(eint->base_pin_num[i], 32);
> + eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
> + eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
> + if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i])
> + goto err_eint;
> + }
>
> eint->domain = irq_domain_add_linear(eint->dev->of_node,
> eint->hw->ap_num,
> &irq_domain_simple_ops, NULL);
> if (!eint->domain)
> - return -ENOMEM;
> + goto err_eint;
>
> if (eint->hw->db_time) {
> for (i = 0; i < MTK_EINT_DBNC_MAX; i++)
> @@ -523,8 +580,11 @@ int mtk_eint_do_init(struct mtk_eint *eint)
>
> mtk_eint_hw_init(eint);
> for (i = 0; i < eint->hw->ap_num; i++) {
> + inst = eint->pins[i].instance;
... here eint->pins is NULL.
> + if (inst >= eint->nbase)
> + continue;
> + eint->pin_list[inst][eint->pins[i].index] = i;
> int virq = irq_create_mapping(eint->domain, i);
> -
> irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
> handle_level_irq);
> irq_set_chip_data(virq, eint);
> @@ -534,6 +594,27 @@ int mtk_eint_do_init(struct mtk_eint *eint)
> eint);
>
> return 0;
> +
> +err_eint:
> + for (i = 0; i < eint->nbase; i++) {
> + if (eint->cur_mask[i])
> + devm_kfree(eint->dev, eint->cur_mask[i]);
> + if (eint->wake_mask[i])
> + devm_kfree(eint->dev, eint->wake_mask[i]);
> + if (eint->pin_list[i])
> + devm_kfree(eint->dev, eint->pin_list[i]);
> + }
> + devm_kfree(eint->dev, eint->cur_mask);
> +err_cur_mask:
> + devm_kfree(eint->dev, eint->wake_mask);
> +err_wake_mask:
> + devm_kfree(eint->dev, eint->pin_list);
> +err_pin_list:
> + if (eint->nbase == 1)
> + devm_kfree(eint->dev, eint->pins);
> +err_pins:
> + devm_kfree(eint->dev, eint->base_pin_num);
> + return -ENOMEM;
> }
> EXPORT_SYMBOL_GPL(mtk_eint_do_init);
That commit can be cleanly reverted on top of v6.15-rc2 which makes my
machine boot again.
Best regards
Uwe
#regzbot introduced: 3ef9f710efcb
Attachment:
signature.asc
Description: PGP signature