From 27a6f41c1a20a3339f456647a21e45fca5b82b62 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 4 Aug 2015 14:02:55 +0930 Subject: x86/lguest: Clean up lguest_setup_irq We make it static and hoist it higher in the file for the next patch. We also give a nice panic if it fails during boot. Signed-off-by: Rusty Russell Link: http://lkml.kernel.org/r/1438662776-4823-1-git-send-email-rusty@rustcorp.com.au Signed-off-by: Thomas Gleixner --- arch/x86/lguest/boot.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'arch/x86/lguest') diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index f2dc08c..d933a11 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -835,6 +835,26 @@ static struct irq_chip lguest_irq_controller = { .irq_unmask = enable_lguest_irq, }; +/* + * Interrupt descriptors are allocated as-needed, but low-numbered ones are + * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it + * tells us the irq is already used: other errors (ie. ENOMEM) we take + * seriously. + */ +static int lguest_setup_irq(unsigned int irq) +{ + int err; + + /* Returns -ve error or vector number. */ + err = irq_alloc_desc_at(irq, 0); + if (err < 0 && err != -EEXIST) + return err; + + irq_set_chip_and_handler_name(irq, &lguest_irq_controller, + handle_level_irq, "level"); + return 0; +} + static int lguest_enable_irq(struct pci_dev *dev) { u8 line = 0; @@ -879,26 +899,6 @@ static void __init lguest_init_IRQ(void) } /* - * Interrupt descriptors are allocated as-needed, but low-numbered ones are - * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it - * tells us the irq is already used: other errors (ie. ENOMEM) we take - * seriously. - */ -int lguest_setup_irq(unsigned int irq) -{ - int err; - - /* Returns -ve error or vector number. */ - err = irq_alloc_desc_at(irq, 0); - if (err < 0 && err != -EEXIST) - return err; - - irq_set_chip_and_handler_name(irq, &lguest_irq_controller, - handle_level_irq, "level"); - return 0; -} - -/* * Time. * * It would be far better for everyone if the Guest had its own clock, but @@ -1040,7 +1040,8 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc) static void lguest_time_init(void) { /* Set up the timer interrupt (0) to go to our simple timer routine */ - lguest_setup_irq(0); + if (lguest_setup_irq(0) != 0) + panic("Could not set up timer irq"); irq_set_handler(0, lguest_time_irq); clocksource_register_hz(&lguest_clock, NSEC_PER_SEC); -- cgit v1.1 From ad3f8d5afe503faa78d61a50a1f6eec3afa7c787 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Aug 2015 14:02:56 +0930 Subject: x86/lguest: Do not setup unused irq vectors No point in assigning the interrupt vectors if there is no interrupt chip installed. Move it to lguest_setup_irq() and call it from lguest_enable_irq. [ rusty: Typo fix and error handling ] Signed-off-by: Thomas Gleixner Signed-off-by: Rusty Russell Link: http://lkml.kernel.org/r/1438662776-4823-2-git-send-email-rusty@rustcorp.com.au Signed-off-by: Thomas Gleixner --- arch/x86/lguest/boot.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'arch/x86/lguest') diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index d933a11..2165f45 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -850,21 +850,29 @@ static int lguest_setup_irq(unsigned int irq) if (err < 0 && err != -EEXIST) return err; + /* + * Tell the Linux infrastructure that the interrupt is + * controlled by our level-based lguest interrupt controller. + */ irq_set_chip_and_handler_name(irq, &lguest_irq_controller, handle_level_irq, "level"); + + /* Some systems map "vectors" to interrupts weirdly. Not us! */ + __this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], irq); return 0; } static int lguest_enable_irq(struct pci_dev *dev) { + int err; u8 line = 0; /* We literally use the PCI interrupt line as the irq number. */ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); - irq_set_chip_and_handler_name(line, &lguest_irq_controller, - handle_level_irq, "level"); - dev->irq = line; - return 0; + err = lguest_setup_irq(line); + if (!err) + dev->irq = line; + return err; } /* We don't do hotplug PCI, so this shouldn't be called. */ @@ -875,17 +883,13 @@ static void lguest_disable_irq(struct pci_dev *dev) /* * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware - * interrupt (except 128, which is used for system calls), and then tells the - * Linux infrastructure that each interrupt is controlled by our level-based - * lguest interrupt controller. + * interrupt (except 128, which is used for system calls). */ static void __init lguest_init_IRQ(void) { unsigned int i; for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) { - /* Some systems map "vectors" to interrupts weirdly. Not us! */ - __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR); if (i != IA32_SYSCALL_VECTOR) set_intr_gate(i, irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR)); -- cgit v1.1 From a782a7e46bb50822fabfeb7271605762a59c86df Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 2 Aug 2015 20:38:27 +0000 Subject: x86/irq: Store irq descriptor in vector array We can spare the irq_desc lookup in the interrupt entry code if we store the descriptor pointer in the vector array instead the interrupt number. Signed-off-by: Thomas Gleixner Cc: Jiang Liu Cc: Peter Zijlstra Cc: Rusty Russell Cc: Bjorn Helgaas Link: http://lkml.kernel.org/r/20150802203609.717724106@linutronix.de Signed-off-by: Thomas Gleixner --- arch/x86/lguest/boot.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/x86/lguest') diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 2165f45..47071a0 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -843,6 +843,7 @@ static struct irq_chip lguest_irq_controller = { */ static int lguest_setup_irq(unsigned int irq) { + struct irq_desc *desc; int err; /* Returns -ve error or vector number. */ @@ -858,7 +859,8 @@ static int lguest_setup_irq(unsigned int irq) handle_level_irq, "level"); /* Some systems map "vectors" to interrupts weirdly. Not us! */ - __this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], irq); + desc = irq_to_desc(irq); + __this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], desc); return 0; } -- cgit v1.1