All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <jbeulich@novell.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] linux: prevent invalid or unsupportable PIRQs from being used
Date: Wed, 05 Nov 2008 14:13:55 +0000	[thread overview]
Message-ID: <4911B833.76E4.0078.0@novell.com> (raw)

By keeping the respective irq_desc[] entries pointing to no_irq_type,
setup_irq() (and thus request_irq()) will fail for such IRQs. This
matches native behavior, which also only installs ioapic_*_type out of
ioapic_register_intr().

At the same time, make assign_irq_vector() fail not only when Xen
doesn't support the PIRQ, but also if the IRQ requested doesn't fall
in the kernel's PIRQ space.

As usual, written and tested on 2.6.27.4 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

Index: head-2008-11-04/arch/i386/kernel/io_apic-xen.c
===================================================================
--- head-2008-11-04.orig/arch/i386/kernel/io_apic-xen.c	2008-11-04 13:45:24.000000000 +0100
+++ head-2008-11-04/arch/i386/kernel/io_apic-xen.c	2008-11-05 12:09:47.000000000 +0100
@@ -1229,6 +1229,9 @@ static int __assign_irq_vector(int irq)
 
 	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
 
+	if (irq < PIRQ_BASE || irq - PIRQ_BASE > NR_PIRQS)
+		return -EINVAL;
+
 	spin_lock_irqsave(&vector_lock, flags);
 
 	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
Index: head-2008-11-04/arch/x86_64/kernel/io_apic-xen.c
===================================================================
--- head-2008-11-04.orig/arch/x86_64/kernel/io_apic-xen.c	2008-11-04 13:45:24.000000000 +0100
+++ head-2008-11-04/arch/x86_64/kernel/io_apic-xen.c	2008-11-05 12:10:12.000000000 +0100
@@ -855,6 +855,9 @@ static int __assign_irq_vector(int irq, 
   
   	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
 
+	if (irq < PIRQ_BASE || irq - PIRQ_BASE > NR_PIRQS)
+		return -EINVAL;
+
 	spin_lock_irqsave(&vector_lock, flags);
 
   	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
Index: head-2008-11-04/drivers/xen/core/evtchn.c
===================================================================
--- head-2008-11-04.orig/drivers/xen/core/evtchn.c	2008-10-29 11:35:18.000000000 +0100
+++ head-2008-11-04/drivers/xen/core/evtchn.c	2008-11-05 13:56:23.000000000 +0100
@@ -784,71 +784,6 @@ static struct irq_chip dynirq_chip = {
 	.retrigger = resend_irq_on_evtchn,
 };
 
-void evtchn_register_pirq(int irq)
-{
-	struct irq_desc *desc;
-	unsigned long flags;
-
-	irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, 0);
-
-	/* Cannot call set_irq_probe(), as that's marked __init. */
-	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock, flags);
-	desc->status &= ~IRQ_NOPROBE;
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-#if defined(CONFIG_X86_IO_APIC)
-#define identity_mapped_irq(irq) (!IO_APIC_IRQ((irq) - PIRQ_BASE))
-#elif defined(CONFIG_X86)
-#define identity_mapped_irq(irq) (((irq) - PIRQ_BASE) < 16)
-#else
-#define identity_mapped_irq(irq) (1)
-#endif
-
-int evtchn_map_pirq(int irq, int xen_pirq)
-{
-	if (irq < 0) {
-		static DEFINE_SPINLOCK(irq_alloc_lock);
-
-		irq = PIRQ_BASE + NR_PIRQS - 1;
-		spin_lock(&irq_alloc_lock);
-		do {
-			if (identity_mapped_irq(irq))
-				continue;
-			if (!index_from_irq(irq)) {
-				BUG_ON(type_from_irq(irq) != IRQT_UNBOUND);
-				irq_info[irq] = mk_irq_info(IRQT_PIRQ,
-							    xen_pirq, 0);
-				break;
-			}
-		} while (--irq >= PIRQ_BASE);
-		spin_unlock(&irq_alloc_lock);
-		if (irq < PIRQ_BASE)
-			return -ENOSPC;
-	} else if (!xen_pirq) {
-		if (unlikely(type_from_irq(irq) != IRQT_PIRQ))
-			return -EINVAL;
-		irq_info[irq] = IRQ_UNBOUND;
-		return 0;
-	} else if (type_from_irq(irq) != IRQT_PIRQ
-		   || index_from_irq(irq) != xen_pirq) {
-		printk(KERN_ERR "IRQ#%d is already mapped to %d:%u - "
-				"cannot map to PIRQ#%u\n",
-		       irq, type_from_irq(irq), index_from_irq(irq), xen_pirq);
-		return -EINVAL;
-	}
-	return index_from_irq(irq) ? irq : -EINVAL;
-}
-
-int evtchn_get_xen_pirq(int irq)
-{
-	if (identity_mapped_irq(irq))
-		return irq;
-	BUG_ON(type_from_irq(irq) != IRQT_PIRQ);
-	return index_from_irq(irq);
-}
-
 static inline void pirq_unmask_notify(int irq)
 {
 	struct physdev_eoi eoi = { .irq = evtchn_get_xen_pirq(irq) };
@@ -1161,6 +1096,68 @@ void irq_resume(void)
 
 }
 
+#if defined(CONFIG_X86_IO_APIC)
+#define identity_mapped_irq(irq) (!IO_APIC_IRQ((irq) - PIRQ_BASE))
+#elif defined(CONFIG_X86)
+#define identity_mapped_irq(irq) (((irq) - PIRQ_BASE) < 16)
+#else
+#define identity_mapped_irq(irq) (1)
+#endif
+
+void evtchn_register_pirq(int irq)
+{
+	BUG_ON(irq < PIRQ_BASE || irq - PIRQ_BASE > NR_PIRQS);
+	if (identity_mapped_irq(irq))
+		return;
+	irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, 0);
+	set_irq_chip_and_handler_name(irq, &pirq_chip, handle_level_irq, "level");
+}
+
+int evtchn_map_pirq(int irq, int xen_pirq)
+{
+	if (irq < 0) {
+		static DEFINE_SPINLOCK(irq_alloc_lock);
+
+		irq = PIRQ_BASE + NR_PIRQS - 1;
+		spin_lock(&irq_alloc_lock);
+		do {
+			if (identity_mapped_irq(irq))
+				continue;
+			if (!index_from_irq(irq)) {
+				BUG_ON(type_from_irq(irq) != IRQT_UNBOUND);
+				irq_info[irq] = mk_irq_info(IRQT_PIRQ,
+							    xen_pirq, 0);
+				break;
+			}
+		} while (--irq >= PIRQ_BASE);
+		spin_unlock(&irq_alloc_lock);
+		if (irq < PIRQ_BASE)
+			return -ENOSPC;
+		irq_desc[irq].chip = &pirq_type;
+	} else if (!xen_pirq) {
+		if (unlikely(type_from_irq(irq) != IRQT_PIRQ))
+			return -EINVAL;
+		irq_desc[irq].chip = &no_irq_type;
+		irq_info[irq] = IRQ_UNBOUND;
+		return 0;
+	} else if (type_from_irq(irq) != IRQT_PIRQ
+		   || index_from_irq(irq) != xen_pirq) {
+		printk(KERN_ERR "IRQ#%d is already mapped to %d:%u - "
+				"cannot map to PIRQ#%u\n",
+		       irq, type_from_irq(irq), index_from_irq(irq), xen_pirq);
+		return -EINVAL;
+	}
+	return index_from_irq(irq) ? irq : -EINVAL;
+}
+
+int evtchn_get_xen_pirq(int irq)
+{
+	if (identity_mapped_irq(irq))
+		return irq;
+	BUG_ON(type_from_irq(irq) != IRQT_PIRQ);
+	return index_from_irq(irq);
+}
+
 void __init xen_init_IRQ(void)
 {
 	unsigned int i;
@@ -1197,16 +1195,16 @@ void __init xen_init_IRQ(void)
 	for (i = PIRQ_BASE; i < (PIRQ_BASE + NR_PIRQS); i++) {
 		irq_bindcount[i] = 1;
 
+		if (!identity_mapped_irq(i))
+			continue;
+
 #ifdef RTC_IRQ
 		/* If not domain 0, force our RTC driver to fail its probe. */
-		if (identity_mapped_irq(i) && ((i - PIRQ_BASE) == RTC_IRQ)
-		    && !is_initial_xendomain())
+		if (i - PIRQ_BASE == RTC_IRQ && !is_initial_xendomain())
 			continue;
 #endif
 
 		irq_desc[i].status = IRQ_DISABLED;
-		if (!identity_mapped_irq(i))
-			irq_desc[i].status |= IRQ_NOPROBE;
 		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 1;
 		irq_desc[i].chip = &pirq_type;

             reply	other threads:[~2008-11-05 14:13 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-05 14:13 Jan Beulich [this message]
2008-11-05 14:54 ` [PATCH] linux: prevent invalid or unsupportable PIRQs from being used Keir Fraser
2008-11-05 15:27   ` [PATCH] linux: prevent invalid or unsupportablePIRQs " Jan Beulich
2008-11-05 15:20 ` [PATCH] linux: prevent invalid or unsupportable PIRQsfrom " Jan Beulich
2008-11-05 15:26   ` Keir Fraser
2008-11-05 15:30     ` [PATCH] linux: prevent invalid or unsupportablePIRQsfrom " Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4911B833.76E4.0078.0@novell.com \
    --to=jbeulich@novell.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.