aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lguest
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-01 18:20:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-01 18:20:51 -0400
commit43af9872f52abfed5523b8346d98a5e283b38163 (patch)
treef50f52c5dfc47ed06972d10a20f01feeff7300d9 /arch/x86/lguest
parent17e6b00ac422b49d44a0b8d98402a211f726282d (diff)
parenta47d4576cd1c58157a2d8cfffa93aa7ca375eede (diff)
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic updates from Thomas Gleixner: "This udpate contains: - rework the irq vector array to store a pointer to the irq descriptor instead of the irq number to avoid a lookup of the irq descriptor in the irq entry path - lguest interrupt handling cleanups - conversion of the local apic timer to the new clockevent callbacks - preparatory changes for the irq argument removal of interrupt flow handlers" * 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/irq: Do not dereference irq descriptor before checking it tools/lguest: Clean up include dir tools/lguest: Fix redefinition of struct virtio_pci_cfg_cap x86/irq: Store irq descriptor in vector array genirq: Provide irq_desc_has_action x86/irq: Get rid of an indentation level x86/irq: Rename VECTOR_UNDEFINED to VECTOR_UNUSED x86/irq: Replace numeric constant x86/irq: Protect smp_cleanup_move x86/lguest: Do not setup unused irq vectors x86/lguest: Clean up lguest_setup_irq x86/apic: Drop local_irq_save/restore in timer callbacks x86/apic: Migrate apic timer to new set_state interface x86/irq: Use access helper irq_data_get_affinity_mask() x86/irq: Use accessor irq_data_get_irq_handler_data() x86/irq: Use accessor irq_data_get_node()
Diffstat (limited to 'arch/x86/lguest')
-rw-r--r--arch/x86/lguest/boot.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 433e5a7dd37f..161804de124a 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -835,16 +835,46 @@ static struct irq_chip lguest_irq_controller = {
835 .irq_unmask = enable_lguest_irq, 835 .irq_unmask = enable_lguest_irq,
836}; 836};
837 837
838/*
839 * Interrupt descriptors are allocated as-needed, but low-numbered ones are
840 * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it
841 * tells us the irq is already used: other errors (ie. ENOMEM) we take
842 * seriously.
843 */
844static int lguest_setup_irq(unsigned int irq)
845{
846 struct irq_desc *desc;
847 int err;
848
849 /* Returns -ve error or vector number. */
850 err = irq_alloc_desc_at(irq, 0);
851 if (err < 0 && err != -EEXIST)
852 return err;
853
854 /*
855 * Tell the Linux infrastructure that the interrupt is
856 * controlled by our level-based lguest interrupt controller.
857 */
858 irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
859 handle_level_irq, "level");
860
861 /* Some systems map "vectors" to interrupts weirdly. Not us! */
862 desc = irq_to_desc(irq);
863 __this_cpu_write(vector_irq[FIRST_EXTERNAL_VECTOR + irq], desc);
864 return 0;
865}
866
838static int lguest_enable_irq(struct pci_dev *dev) 867static int lguest_enable_irq(struct pci_dev *dev)
839{ 868{
869 int err;
840 u8 line = 0; 870 u8 line = 0;
841 871
842 /* We literally use the PCI interrupt line as the irq number. */ 872 /* We literally use the PCI interrupt line as the irq number. */
843 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); 873 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
844 irq_set_chip_and_handler_name(line, &lguest_irq_controller, 874 err = lguest_setup_irq(line);
845 handle_level_irq, "level"); 875 if (!err)
846 dev->irq = line; 876 dev->irq = line;
847 return 0; 877 return err;
848} 878}
849 879
850/* We don't do hotplug PCI, so this shouldn't be called. */ 880/* We don't do hotplug PCI, so this shouldn't be called. */
@@ -855,17 +885,13 @@ static void lguest_disable_irq(struct pci_dev *dev)
855 885
856/* 886/*
857 * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware 887 * This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
858 * interrupt (except 128, which is used for system calls), and then tells the 888 * interrupt (except 128, which is used for system calls).
859 * Linux infrastructure that each interrupt is controlled by our level-based
860 * lguest interrupt controller.
861 */ 889 */
862static void __init lguest_init_IRQ(void) 890static void __init lguest_init_IRQ(void)
863{ 891{
864 unsigned int i; 892 unsigned int i;
865 893
866 for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) { 894 for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) {
867 /* Some systems map "vectors" to interrupts weirdly. Not us! */
868 __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
869 if (i != IA32_SYSCALL_VECTOR) 895 if (i != IA32_SYSCALL_VECTOR)
870 set_intr_gate(i, irq_entries_start + 896 set_intr_gate(i, irq_entries_start +
871 8 * (i - FIRST_EXTERNAL_VECTOR)); 897 8 * (i - FIRST_EXTERNAL_VECTOR));
@@ -879,26 +905,6 @@ static void __init lguest_init_IRQ(void)
879} 905}
880 906
881/* 907/*
882 * Interrupt descriptors are allocated as-needed, but low-numbered ones are
883 * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it
884 * tells us the irq is already used: other errors (ie. ENOMEM) we take
885 * seriously.
886 */
887int lguest_setup_irq(unsigned int irq)
888{
889 int err;
890
891 /* Returns -ve error or vector number. */
892 err = irq_alloc_desc_at(irq, 0);
893 if (err < 0 && err != -EEXIST)
894 return err;
895
896 irq_set_chip_and_handler_name(irq, &lguest_irq_controller,
897 handle_level_irq, "level");
898 return 0;
899}
900
901/*
902 * Time. 908 * Time.
903 * 909 *
904 * It would be far better for everyone if the Guest had its own clock, but 910 * It would be far better for everyone if the Guest had its own clock, but
@@ -1028,7 +1034,8 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc)
1028static void lguest_time_init(void) 1034static void lguest_time_init(void)
1029{ 1035{
1030 /* Set up the timer interrupt (0) to go to our simple timer routine */ 1036 /* Set up the timer interrupt (0) to go to our simple timer routine */
1031 lguest_setup_irq(0); 1037 if (lguest_setup_irq(0) != 0)
1038 panic("Could not set up timer irq");
1032 irq_set_handler(0, lguest_time_irq); 1039 irq_set_handler(0, lguest_time_irq);
1033 1040
1034 clocksource_register_hz(&lguest_clock, NSEC_PER_SEC); 1041 clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);