diff mbox series

xen/events: Use chip data for storing per IRQ XEN data pointer

Message ID 87lfi2yckt.fsf@nanos.tec.linutronix.de (mailing list archive)
State Accepted
Commit c330fb1ddc0a922f044989492b7fcca77ee1db46
Headers show
Series xen/events: Use chip data for storing per IRQ XEN data pointer | expand

Commit Message

Thomas Gleixner Aug. 25, 2020, 3:22 p.m. UTC
XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt
XEN data pointer which contains XEN specific information.

handler data is meant for interrupt handlers and not for storing irq chip
specific information as some devices require handler data to store internal
per interrupt information, e.g. pinctrl/GPIO chained interrupt handlers.

This obviously creates a conflict of interests and crashes the machine
because the XEN pointer is overwritten by the driver pointer.

As the XEN data is not handler specific it should be stored in
irqdesc::irq_data::chip_data instead.

A simple sed s/irq_[sg]et_handler_data/irq_[sg]et_chip_data/ cures that.

Reported-by: Roman Shaposhnik <roman@zededa.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
Note: This probably wants a 'Cc: stable@' and a 'Fixes:' tag, but I
leave that as an exercise to the maintainers how far they want to move
that back.
---
 drivers/xen/events/events_base.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

Comments

Jürgen Groß Aug. 25, 2020, 3:43 p.m. UTC | #1
On 25.08.20 17:22, Thomas Gleixner wrote:
> XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt
> XEN data pointer which contains XEN specific information.
> 
> handler data is meant for interrupt handlers and not for storing irq chip
> specific information as some devices require handler data to store internal
> per interrupt information, e.g. pinctrl/GPIO chained interrupt handlers.
> 
> This obviously creates a conflict of interests and crashes the machine
> because the XEN pointer is overwritten by the driver pointer.
> 
> As the XEN data is not handler specific it should be stored in
> irqdesc::irq_data::chip_data instead.
> 
> A simple sed s/irq_[sg]et_handler_data/irq_[sg]et_chip_data/ cures that.
> 
> Reported-by: Roman Shaposhnik <roman@zededa.com>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Reviewed-by: Juergen Gross <jgross@suse.com>

> ---
> Note: This probably wants a 'Cc: stable@' and a 'Fixes:' tag, but I
> leave that as an exercise to the maintainers how far they want to move
> that back.

Will do. :-)

Thanks for the patch,


Juergen
Roman Shaposhnik Aug. 25, 2020, 10:04 p.m. UTC | #2
On Tue, Aug 25, 2020 at 8:43 AM Jürgen Groß <jgross@suse.com> wrote:
>
> On 25.08.20 17:22, Thomas Gleixner wrote:
> > XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt
> > XEN data pointer which contains XEN specific information.
> >
> > handler data is meant for interrupt handlers and not for storing irq chip
> > specific information as some devices require handler data to store internal
> > per interrupt information, e.g. pinctrl/GPIO chained interrupt handlers.
> >
> > This obviously creates a conflict of interests and crashes the machine
> > because the XEN pointer is overwritten by the driver pointer.
> >
> > As the XEN data is not handler specific it should be stored in
> > irqdesc::irq_data::chip_data instead.
> >
> > A simple sed s/irq_[sg]et_handler_data/irq_[sg]et_chip_data/ cures that.
> >
> > Reported-by: Roman Shaposhnik <roman@zededa.com>
> > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> Reviewed-by: Juergen Gross <jgross@suse.com>

Tested-by: Roman Shaposhnik <roman@zededa.com>

Thank you everyone for coming up with the fix so quickly! I tested it out
and it appears to be functional with and without Xen.

Thanks,
Roman.
diff mbox series

Patch

--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -156,7 +156,7 @@  int get_evtchn_to_irq(evtchn_port_t evtc
 /* Get info for IRQ */
 struct irq_info *info_for_irq(unsigned irq)
 {
-	return irq_get_handler_data(irq);
+	return irq_get_chip_data(irq);
 }
 
 /* Constructors for packed IRQ information. */
@@ -377,7 +377,7 @@  static void xen_irq_init(unsigned irq)
 	info->type = IRQT_UNBOUND;
 	info->refcnt = -1;
 
-	irq_set_handler_data(irq, info);
+	irq_set_chip_data(irq, info);
 
 	list_add_tail(&info->list, &xen_irq_list_head);
 }
@@ -426,14 +426,14 @@  static int __must_check xen_allocate_irq
 
 static void xen_free_irq(unsigned irq)
 {
-	struct irq_info *info = irq_get_handler_data(irq);
+	struct irq_info *info = irq_get_chip_data(irq);
 
 	if (WARN_ON(!info))
 		return;
 
 	list_del(&info->list);
 
-	irq_set_handler_data(irq, NULL);
+	irq_set_chip_data(irq, NULL);
 
 	WARN_ON(info->refcnt > 0);
 
@@ -603,7 +603,7 @@  EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
 static void __unbind_from_irq(unsigned int irq)
 {
 	evtchn_port_t evtchn = evtchn_from_irq(irq);
-	struct irq_info *info = irq_get_handler_data(irq);
+	struct irq_info *info = irq_get_chip_data(irq);
 
 	if (info->refcnt > 0) {
 		info->refcnt--;
@@ -1108,7 +1108,7 @@  int bind_ipi_to_irqhandler(enum ipi_vect
 
 void unbind_from_irqhandler(unsigned int irq, void *dev_id)
 {
-	struct irq_info *info = irq_get_handler_data(irq);
+	struct irq_info *info = irq_get_chip_data(irq);
 
 	if (WARN_ON(!info))
 		return;
@@ -1142,7 +1142,7 @@  int evtchn_make_refcounted(evtchn_port_t
 	if (irq == -1)
 		return -ENOENT;
 
-	info = irq_get_handler_data(irq);
+	info = irq_get_chip_data(irq);
 
 	if (!info)
 		return -ENOENT;
@@ -1170,7 +1170,7 @@  int evtchn_get(evtchn_port_t evtchn)
 	if (irq == -1)
 		goto done;
 
-	info = irq_get_handler_data(irq);
+	info = irq_get_chip_data(irq);
 
 	if (!info)
 		goto done;