From: Sean Wang <sean.wang@xxxxxxxxxxxx> Use buffer allocated with kmalloc instead of with stack to fix kernel crash due to Unable to handle kernel paging request at virtual address ffffffc0095cbce8. [ 156.977349] Unable to handle kernel paging request at virtual address ffffffc0095cbce8 [ 156.985270] Mem abort info: [ 156.988059] ESR = 0x96000045 [ 156.991104] Exception class = DABT (current EL), IL = 32 bits [ 156.997013] SET = 0, FnV = 0 [ 157.000057] EA = 0, S1PTW = 0 [ 157.003190] Data abort info: [ 157.006061] ISV = 0, ISS = 0x00000045 [ 157.009887] CM = 0, WnR = 1 [ 157.012850] swapper pgtable: 4k pages, 39-bit VAs, pgdp = 0000000042adcba2 [ 157.019715] [ffffffc0095cbce8] pgd=0000000000000000, pud=0000000000000000 [ 157.026499] Internal error: Oops: 96000045 [#1] PREEMPT SMP [ 157.032065] Modules linked in: mt7663s mt7663_usb_sdio_common mt7615_common ... [ 157.073007] Process CompositorTileW (pid: 1625, stack limit = 0x000000003f2389fc) [ 157.080484] CPU: 0 PID: 1625 Comm: CompositorTileW Not tainted 4.19.137 #36 [ 157.092219] pstate: 80000085 (Nzcv daIf -PAN -UAO) [ 157.097012] pc : __memcpy+0xc0/0x180 [ 157.100585] lr : swiotlb_tbl_unmap_single+0x84/0x14c [ 157.105540] sp : ffffff8008003cb0 [ 157.108845] x29: ffffff8008003cb0 x28: ffffff9c1a211f60 [ 157.114149] x27: ffffff9c19ecc018 x26: 0000000000001000 [ 157.119452] x25: ffffff9c1a378000 x24: 0000000000000001 [ 157.124755] x23: ffffff9c1a378000 x22: 00000000000001ff [ 157.130058] x21: 0000000000000000 x20: 00000000fbefe800 [ 157.135360] x19: 0000000000000070 x18: 0000000000000000 [ 157.140663] x17: 0000000000000000 x16: 0000000000000000 [ 157.145965] x15: 0000000000000000 x14: 0000000000000000 [ 157.151267] x13: 0000000000000000 x12: 000000000000000d [ 157.156569] x11: 000000000000000c x10: 0000000a7befe800 [ 157.161873] x9 : fffffff680000000 x8 : 0000000000000000 [ 157.167175] x7 : 0000000100000003 x6 : ffffffc0095cbce8 [ 157.172479] x5 : 0000000000000000 x4 : 0000000000000000 [ 157.177781] x3 : 0000000000000002 x2 : fffffffffffffff0 [ 157.183085] x1 : ffffffca7befe810 x0 : ffffffc0095cbce8 [ 157.188389] Call trace: [ 157.190832] __memcpy+0xc0/0x180 [ 157.194053] swiotlb_unmap_sg_attrs+0xa8/0xb0 [ 157.198406] __swiotlb_unmap_sg_attrs+0x8c/0xa4 [ 157.202931] msdc_unprepare_data+0x6c/0x84 [ 157.207019] msdc_request_done+0x58/0x98 [ 157.210934] msdc_data_xfer_done+0x1a8/0x1d0 [ 157.215195] msdc_irq+0x12c/0x17c [ 157.218505] __handle_irq_event_percpu+0xd8/0x298 [ 157.223202] handle_irq_event+0x60/0xdc [ 157.227031] handle_fasteoi_irq+0xa4/0x1d4 [ 157.231120] __handle_domain_irq+0x84/0xc4 [ 157.235210] gic_handle_irq+0x124/0x1a4 [ 157.239038] el0_irq_naked+0x4c/0x54 [ 157.242608] Code: 14000028 f1020042 5400024a a8c12027 (a88120c7) [ 157.248693] ---[ end trace 28b8090135b0a2e1 ]--- [ 157.265589] Kernel panic - not syncing: Fatal exception in interrupt [ 157.271944] SMP: stopping secondary CPUs [ 157.275865] Kernel Offset: 0x1c10e00000 from 0xffffff8008000000 [ 157.281779] CPU features: 0x0,2188200c [ 157.285519] Memory Limit: none Fixes: a66cbdd6573d ("mt76: mt7615: introduce mt7663s support") Co-developed-by: YN Chen <YN.Chen@xxxxxxxxxxxx> Signed-off-by: YN Chen <YN.Chen@xxxxxxxxxxxx> Signed-off-by: Sean Wang <sean.wang@xxxxxxxxxxxx> --- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt7615/sdio.c | 8 ++++++++ .../wireless/mediatek/mt76/mt7615/sdio_txrx.c | 18 +++++++++--------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 3d5037afd5ea..94fa835e9134 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -464,6 +464,7 @@ struct mt76_sdio { struct work_struct stat_work; struct sdio_func *func; + void *intr_data; struct { struct mutex lock; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c index 56f65345d048..e0603e82e33d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c @@ -379,6 +379,14 @@ static int mt7663s_probe(struct sdio_func *func, (mt76_rr(dev, MT_HW_REV) & 0xff); dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); + mdev->sdio.intr_data = devm_kmalloc(mdev->dev, + sizeof(struct mt76s_intr), + GFP_KERNEL); + if (!mdev->sdio.intr_data) { + ret = -ENOMEM; + goto err_deinit; + } + ret = mt76s_alloc_queues(&dev->mt76); if (ret) goto err_deinit; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c index c945b4e0320d..a589fd5535db 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c @@ -221,35 +221,35 @@ void mt7663s_rx_work(struct work_struct *work) struct mt76_sdio *sdio = container_of(work, struct mt76_sdio, rx.recv_work); struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio); - struct mt76s_intr intr; + struct mt76s_intr *intr = sdio->intr_data; int nframes = 0, ret; /* disable interrupt */ sdio_claim_host(sdio->func); sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, 0); - sdio_readsb(sdio->func, &intr, MCR_WHISR, sizeof(struct mt76s_intr)); + sdio_readsb(sdio->func, intr, MCR_WHISR, sizeof(struct mt76s_intr)); sdio_release_host(sdio->func); - trace_dev_irq(dev, intr.isr, 0); + trace_dev_irq(dev, intr->isr, 0); - if (intr.isr & WHIER_RX0_DONE_INT_EN) { - ret = mt7663s_rx_run_queue(dev, 0, &intr); + if (intr->isr & WHIER_RX0_DONE_INT_EN) { + ret = mt7663s_rx_run_queue(dev, 0, intr); if (ret > 0) { queue_work(sdio->txrx_wq, &sdio->rx.net_work); nframes += ret; } } - if (intr.isr & WHIER_RX1_DONE_INT_EN) { - ret = mt7663s_rx_run_queue(dev, 1, &intr); + if (intr->isr & WHIER_RX1_DONE_INT_EN) { + ret = mt7663s_rx_run_queue(dev, 1, intr); if (ret > 0) { queue_work(sdio->txrx_wq, &sdio->rx.net_work); nframes += ret; } } - if (intr.isr & WHIER_TX_DONE_INT_EN) { - mt7663s_refill_sched_quota(dev, intr.tx.wtqcr); + if (intr->isr & WHIER_TX_DONE_INT_EN) { + mt7663s_refill_sched_quota(dev, intr->tx.wtqcr); queue_work(sdio->txrx_wq, &sdio->tx.xmit_work); } -- 2.25.1