* [RESEND-PATCH] cxl: Avoid double free_irq() for psl,slice interrupts
@ 2017-06-02 9:35 Vaibhav Jain
2017-06-02 15:30 ` Frederic Barrat
0 siblings, 1 reply; 4+ messages in thread
From: Vaibhav Jain @ 2017-06-02 9:35 UTC (permalink / raw)
To: Frederic Barrat, Philippe Bergheaud
Cc: Vaibhav Jain, linuxppc-dev, Andrew Donnellan, Ian Munsie,
Christophe Lombard, Greg Kurz, Alastair D'Silva, stable
During an eeh call to cxl_remove can result in double free_irq of
psl,slice interrupts. This can happen if perst_reloads_same_image == 1
and call to cxl_configure_adapter() fails during slot_reset
callback. In such a case we see a kernel oops with following back-trace:
Oops: Kernel access of bad area, sig: 11 [#1]
Call Trace:
free_irq+0x88/0xd0 (unreliable)
cxl_unmap_irq+0x20/0x40 [cxl]
cxl_native_release_psl_irq+0x78/0xd8 [cxl]
pci_deconfigure_afu+0xac/0x110 [cxl]
cxl_remove+0x104/0x210 [cxl]
pci_device_remove+0x6c/0x110
device_release_driver_internal+0x204/0x2e0
pci_stop_bus_device+0xa0/0xd0
pci_stop_and_remove_bus_device+0x28/0x40
pci_hp_remove_devices+0xb0/0x150
pci_hp_remove_devices+0x68/0x150
eeh_handle_normal_event+0x140/0x580
eeh_handle_event+0x174/0x360
eeh_event_handler+0x1e8/0x1f0
This patch fixes the issue of double free_irq by checking that
variables that hold the virqs (err_hwirq, serr_hwirq, psl_virq) are
not '0' before un-mapping and resetting these variables to '0' when
they are un-mapped.
Cc: stable@vger.kernel.org
Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
---
Re-send:
- Added stable to recipients
---
drivers/misc/cxl/native.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 871a2f0..3ed2254 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -1302,13 +1302,16 @@ int cxl_native_register_psl_err_irq(struct cxl *adapter)
void cxl_native_release_psl_err_irq(struct cxl *adapter)
{
- if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq))
+ if (adapter->native->err_virq == 0 ||
+ adapter->native->err_virq !=
+ irq_find_mapping(NULL, adapter->native->err_hwirq))
return;
cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
cxl_unmap_irq(adapter->native->err_virq, adapter);
cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);
kfree(adapter->irq_name);
+ adapter->native->err_virq = 0;
}
int cxl_native_register_serr_irq(struct cxl_afu *afu)
@@ -1346,13 +1349,15 @@ int cxl_native_register_serr_irq(struct cxl_afu *afu)
void cxl_native_release_serr_irq(struct cxl_afu *afu)
{
- if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
+ if (afu->serr_virq == 0 ||
+ afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
return;
cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
cxl_unmap_irq(afu->serr_virq, afu);
cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
kfree(afu->err_irq_name);
+ afu->serr_virq = 0;
}
int cxl_native_register_psl_irq(struct cxl_afu *afu)
@@ -1375,12 +1380,15 @@ int cxl_native_register_psl_irq(struct cxl_afu *afu)
void cxl_native_release_psl_irq(struct cxl_afu *afu)
{
- if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq))
+ if (afu->native->psl_virq == 0 ||
+ afu->native->psl_virq !=
+ irq_find_mapping(NULL, afu->native->psl_virq))
return;
cxl_unmap_irq(afu->native->psl_virq, afu);
cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);
kfree(afu->psl_irq_name);
+ afu->native->psl_virq = 0;
}
static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
--
2.9.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [RESEND-PATCH] cxl: Avoid double free_irq() for psl,slice interrupts
2017-06-02 9:35 [RESEND-PATCH] cxl: Avoid double free_irq() for psl,slice interrupts Vaibhav Jain
@ 2017-06-02 15:30 ` Frederic Barrat
2017-06-02 16:58 ` [RESEND-PATCH] cxl: Avoid double free_irq() for psl, slice interrupts Vaibhav Jain
0 siblings, 1 reply; 4+ messages in thread
From: Frederic Barrat @ 2017-06-02 15:30 UTC (permalink / raw)
To: Vaibhav Jain, Philippe Bergheaud
Cc: linuxppc-dev, Andrew Donnellan, Ian Munsie, Christophe Lombard,
Greg Kurz, Alastair D'Silva, stable
Le 02/06/2017 à 11:35, Vaibhav Jain a écrit :
> During an eeh call to cxl_remove can result in double free_irq of
> psl,slice interrupts. This can happen if perst_reloads_same_image == 1
> and call to cxl_configure_adapter() fails during slot_reset
> callback. In such a case we see a kernel oops with following back-trace:
>
> Oops: Kernel access of bad area, sig: 11 [#1]
> Call Trace:
> free_irq+0x88/0xd0 (unreliable)
> cxl_unmap_irq+0x20/0x40 [cxl]
> cxl_native_release_psl_irq+0x78/0xd8 [cxl]
> pci_deconfigure_afu+0xac/0x110 [cxl]
> cxl_remove+0x104/0x210 [cxl]
> pci_device_remove+0x6c/0x110
> device_release_driver_internal+0x204/0x2e0
> pci_stop_bus_device+0xa0/0xd0
> pci_stop_and_remove_bus_device+0x28/0x40
> pci_hp_remove_devices+0xb0/0x150
> pci_hp_remove_devices+0x68/0x150
> eeh_handle_normal_event+0x140/0x580
> eeh_handle_event+0x174/0x360
> eeh_event_handler+0x1e8/0x1f0
>
> This patch fixes the issue of double free_irq by checking that
> variables that hold the virqs (err_hwirq, serr_hwirq, psl_virq) are
> not '0' before un-mapping and resetting these variables to '0' when
> they are un-mapped.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>
> ---
> Re-send:
> - Added stable to recipients
> ---
> drivers/misc/cxl/native.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
> index 871a2f0..3ed2254 100644
> --- a/drivers/misc/cxl/native.c
> +++ b/drivers/misc/cxl/native.c
> @@ -1302,13 +1302,16 @@ int cxl_native_register_psl_err_irq(struct cxl *adapter)
>
> void cxl_native_release_psl_err_irq(struct cxl *adapter)
> {
> - if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq))
> + if (adapter->native->err_virq == 0 ||
> + adapter->native->err_virq !=
> + irq_find_mapping(NULL, adapter->native->err_hwirq))
> return;
>
> cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
> cxl_unmap_irq(adapter->native->err_virq, adapter);
> cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq);
> kfree(adapter->irq_name);
> + adapter->native->err_virq = 0;
> }
>
> int cxl_native_register_serr_irq(struct cxl_afu *afu)
> @@ -1346,13 +1349,15 @@ int cxl_native_register_serr_irq(struct cxl_afu *afu)
>
> void cxl_native_release_serr_irq(struct cxl_afu *afu)
> {
> - if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
> + if (afu->serr_virq == 0 ||
> + afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
> return;
>
> cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
> cxl_unmap_irq(afu->serr_virq, afu);
> cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
> kfree(afu->err_irq_name);
> + afu->serr_virq = 0;
> }
>
> int cxl_native_register_psl_irq(struct cxl_afu *afu)
> @@ -1375,12 +1380,15 @@ int cxl_native_register_psl_irq(struct cxl_afu *afu)
>
> void cxl_native_release_psl_irq(struct cxl_afu *afu)
> {
> - if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq))
> + if (afu->native->psl_virq == 0 ||
> + afu->native->psl_virq !=
> + irq_find_mapping(NULL, afu->native->psl_virq))
^^^
Shouldn't it be psl_hwirq?
Fred
> return;
>
> cxl_unmap_irq(afu->native->psl_virq, afu);
> cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq);
> kfree(afu->psl_irq_name);
> + afu->native->psl_virq = 0;
> }
>
> static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RESEND-PATCH] cxl: Avoid double free_irq() for psl,slice interrupts
2017-06-02 15:30 ` Frederic Barrat
@ 2017-06-02 16:58 ` Vaibhav Jain
0 siblings, 0 replies; 4+ messages in thread
From: Vaibhav Jain @ 2017-06-02 16:58 UTC (permalink / raw)
To: Frederic Barrat, Philippe Bergheaud
Cc: linuxppc-dev, Andrew Donnellan, Ian Munsie, Christophe Lombard,
Greg Kurz, Alastair D'Silva, stable
Frederic Barrat <fbarrat@linux.vnet.ibm.com> writes:
>> + irq_find_mapping(NULL, afu->native->psl_virq))
>
> ^^^
> Shouldn't it be psl_hwirq?
>
Thanks for catching this Fred. I have sent a v2 patch fixing this.
--
Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Linux Technology Center, IBM India Pvt. Ltd.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RESEND-PATCH] cxl: Avoid double free_irq() for psl, slice interrupts
@ 2017-06-02 16:58 ` Vaibhav Jain
0 siblings, 0 replies; 4+ messages in thread
From: Vaibhav Jain @ 2017-06-02 16:58 UTC (permalink / raw)
To: Frederic Barrat, Philippe Bergheaud
Cc: linuxppc-dev, Andrew Donnellan, Ian Munsie, Christophe Lombard,
Greg Kurz, Alastair D'Silva, stable
Frederic Barrat <fbarrat@linux.vnet.ibm.com> writes:
>> + irq_find_mapping(NULL, afu->native->psl_virq))
>
> ^^^
> Shouldn't it be psl_hwirq?
>
Thanks for catching this Fred. I have sent a v2 patch fixing this.
--
Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Linux Technology Center, IBM India Pvt. Ltd.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-06-02 16:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-02 9:35 [RESEND-PATCH] cxl: Avoid double free_irq() for psl,slice interrupts Vaibhav Jain
2017-06-02 15:30 ` Frederic Barrat
2017-06-02 16:58 ` Vaibhav Jain
2017-06-02 16:58 ` [RESEND-PATCH] cxl: Avoid double free_irq() for psl, slice interrupts Vaibhav Jain
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.