mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-16 23:45:31 +08:00
A single fix targeting the MHI host stack:
- Since the commit1227d2a20c
("bus: mhi: host: Move IRQ allocation to controller registration phase"), the MHI context gets freed during mhi_unregister_controller(). But when the MHI IRQs are shared, the IRQ handler may get invoked during __free_irq() if CONFIG_DEBUG_SHIRQ is set. In that case, there will be a null pointer dereference because of trying to use the freed context struct. So for fixing the issue, let's check for the existence of the context struct at the start of the handler before handling the IRQ. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEZ6VDKoFIy9ikWCeXVZ8R5v6RzvUFAmMM85YACgkQVZ8R5v6R zvUAvAf+IHJBo3749kKBJ2YrD6+P1ZTXvcSD/UM2JUrAnRck6oUB1o75PJv0l+zJ LG1FY6JzBFYT7tsJnbKEe92cEaYe6G5cnG0DM9fd3d90bnAKF+0TykiPbYWVmMNp uv3ojQEd8q30SFF4xa83N51GFjlvyNEmy9gv+X6Ha3Wfa4LWLC5j5XNttz/052Zc RE3uQvbygmWy/K3WlFqlTHESzMqlXrKs5gWTs2wilvIP0OhipSZ6haU4/sQKal+u taEEOHz2ANQjInIbvohQTtnTnj5ZXS7S4tLz95RrZjh/VrG4O+HhQVwQUnxV4n1F 5CMLJXZgaMg+OJeBCkLWf+sFIHlgEQ== =Zd1d -----END PGP SIGNATURE----- Merge tag 'mhi-fixes-for-v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi into char-misc-linus Manivannan writes: "A single fix targeting the MHI host stack: - Since the commit1227d2a20c
("bus: mhi: host: Move IRQ allocation to controller registration phase"), the MHI context gets freed during mhi_unregister_controller(). But when the MHI IRQs are shared, the IRQ handler may get invoked during __free_irq() if CONFIG_DEBUG_SHIRQ is set. In that case, there will be a null pointer dereference because of trying to use the freed context struct. So for fixing the issue, let's check for the existence of the context struct at the start of the handler before handling the IRQ." * tag 'mhi-fixes-for-v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi: bus: mhi: host: Fix up null pointer access in mhi_irq_handler
This commit is contained in:
commit
5ef251b9b7
@ -430,12 +430,25 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev)
|
||||
{
|
||||
struct mhi_event *mhi_event = dev;
|
||||
struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl;
|
||||
struct mhi_event_ctxt *er_ctxt =
|
||||
&mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
|
||||
struct mhi_event_ctxt *er_ctxt;
|
||||
struct mhi_ring *ev_ring = &mhi_event->ring;
|
||||
dma_addr_t ptr = le64_to_cpu(er_ctxt->rp);
|
||||
dma_addr_t ptr;
|
||||
void *dev_rp;
|
||||
|
||||
/*
|
||||
* If CONFIG_DEBUG_SHIRQ is set, the IRQ handler will get invoked during __free_irq()
|
||||
* and by that time mhi_ctxt() would've freed. So check for the existence of mhi_ctxt
|
||||
* before handling the IRQs.
|
||||
*/
|
||||
if (!mhi_cntrl->mhi_ctxt) {
|
||||
dev_dbg(&mhi_cntrl->mhi_dev->dev,
|
||||
"mhi_ctxt has been freed\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
|
||||
ptr = le64_to_cpu(er_ctxt->rp);
|
||||
|
||||
if (!is_valid_ring_ptr(ev_ring, ptr)) {
|
||||
dev_err(&mhi_cntrl->mhi_dev->dev,
|
||||
"Event ring rp points outside of the event ring\n");
|
||||
|
Loading…
Reference in New Issue
Block a user