Skip to content

Commit 0891fb3

Browse files
committed
xen/events: don't use chip_data for legacy IRQs
Since commit c330fb1 ("XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN data pointer which contains XEN specific information.") Xen is using the chip_data pointer for storing IRQ specific data. When running as a HVM domain this can result in problems for legacy IRQs, as those might use chip_data for their own purposes. Use a local array for this purpose in case of legacy IRQs, avoiding the double use. Cc: [email protected] Fixes: c330fb1 ("XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN data pointer which contains XEN specific information.") Signed-off-by: Juergen Gross <[email protected]> Tested-by: Stefan Bader <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Juergen Gross <[email protected]>
1 parent a1b8638 commit 0891fb3

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

drivers/xen/events/events_base.c

+21-8
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ static bool (*pirq_needs_eoi)(unsigned irq);
9292
/* Xen will never allocate port zero for any purpose. */
9393
#define VALID_EVTCHN(chn) ((chn) != 0)
9494

95+
static struct irq_info *legacy_info_ptrs[NR_IRQS_LEGACY];
96+
9597
static struct irq_chip xen_dynamic_chip;
9698
static struct irq_chip xen_percpu_chip;
9799
static struct irq_chip xen_pirq_chip;
@@ -156,7 +158,18 @@ int get_evtchn_to_irq(evtchn_port_t evtchn)
156158
/* Get info for IRQ */
157159
struct irq_info *info_for_irq(unsigned irq)
158160
{
159-
return irq_get_chip_data(irq);
161+
if (irq < nr_legacy_irqs())
162+
return legacy_info_ptrs[irq];
163+
else
164+
return irq_get_chip_data(irq);
165+
}
166+
167+
static void set_info_for_irq(unsigned int irq, struct irq_info *info)
168+
{
169+
if (irq < nr_legacy_irqs())
170+
legacy_info_ptrs[irq] = info;
171+
else
172+
irq_set_chip_data(irq, info);
160173
}
161174

162175
/* Constructors for packed IRQ information. */
@@ -377,7 +390,7 @@ static void xen_irq_init(unsigned irq)
377390
info->type = IRQT_UNBOUND;
378391
info->refcnt = -1;
379392

380-
irq_set_chip_data(irq, info);
393+
set_info_for_irq(irq, info);
381394

382395
list_add_tail(&info->list, &xen_irq_list_head);
383396
}
@@ -426,14 +439,14 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
426439

427440
static void xen_free_irq(unsigned irq)
428441
{
429-
struct irq_info *info = irq_get_chip_data(irq);
442+
struct irq_info *info = info_for_irq(irq);
430443

431444
if (WARN_ON(!info))
432445
return;
433446

434447
list_del(&info->list);
435448

436-
irq_set_chip_data(irq, NULL);
449+
set_info_for_irq(irq, NULL);
437450

438451
WARN_ON(info->refcnt > 0);
439452

@@ -603,7 +616,7 @@ EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
603616
static void __unbind_from_irq(unsigned int irq)
604617
{
605618
evtchn_port_t evtchn = evtchn_from_irq(irq);
606-
struct irq_info *info = irq_get_chip_data(irq);
619+
struct irq_info *info = info_for_irq(irq);
607620

608621
if (info->refcnt > 0) {
609622
info->refcnt--;
@@ -1108,7 +1121,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
11081121

11091122
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
11101123
{
1111-
struct irq_info *info = irq_get_chip_data(irq);
1124+
struct irq_info *info = info_for_irq(irq);
11121125

11131126
if (WARN_ON(!info))
11141127
return;
@@ -1142,7 +1155,7 @@ int evtchn_make_refcounted(evtchn_port_t evtchn)
11421155
if (irq == -1)
11431156
return -ENOENT;
11441157

1145-
info = irq_get_chip_data(irq);
1158+
info = info_for_irq(irq);
11461159

11471160
if (!info)
11481161
return -ENOENT;
@@ -1170,7 +1183,7 @@ int evtchn_get(evtchn_port_t evtchn)
11701183
if (irq == -1)
11711184
goto done;
11721185

1173-
info = irq_get_chip_data(irq);
1186+
info = info_for_irq(irq);
11741187

11751188
if (!info)
11761189
goto done;

0 commit comments

Comments
 (0)