summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2020-08-18 12:12:28 +0800
committerFelix Fietkau <nbd@nbd.name>2020-09-24 18:10:15 +0200
commitb496490886f919a08e946ca4cf8bdd375f54e77f (patch)
tree43962d09887f9e1601920214cf42815a245a2134 /drivers/net/wireless/mediatek
parent8b7c6e1cb2cb1d4e2ee94556695d80dde6ccdcc6 (diff)
mt76: mt7663s: fix unable to handle kernel paging request
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@mediatek.com> Signed-off-by: YN Chen <YN.Chen@mediatek.com> Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76.h1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio.c8
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7615/sdio_txrx.c18
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 166d8a172ba6..80f4ba998383 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -463,6 +463,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 66d8652c756a..79e02157da4d 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, NULL);
- 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);
}