Skip to content

Commit

Permalink
XEN uses irqdesc::irq_data_common::handler_data to store a per interr…
Browse files Browse the repository at this point in the history
…upt XEN data pointer which contains XEN specific information.

commit c330fb1 upstream.

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.

Cc: stable@vger.kernel.org
Reported-by: Roman Shaposhnik <roman@zededa.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Roman Shaposhnik <roman@zededa.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/87lfi2yckt.fsf@nanos.tec.linutronix.de
Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Thomas Gleixner authored and gregkh committed Sep 3, 2020
1 parent 05ae7cf commit 2b32323
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions drivers/xen/events/events_base.c
Expand Up @@ -156,7 +156,7 @@ int get_evtchn_to_irq(evtchn_port_t evtchn)
/* 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. */
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -426,14 +426,14 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)

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);

Expand Down Expand Up @@ -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--;
Expand Down Expand Up @@ -1108,7 +1108,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,

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;
Expand Down Expand Up @@ -1142,7 +1142,7 @@ int evtchn_make_refcounted(evtchn_port_t evtchn)
if (irq == -1)
return -ENOENT;

info = irq_get_handler_data(irq);
info = irq_get_chip_data(irq);

if (!info)
return -ENOENT;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 2b32323

Please sign in to comment.