diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-09-13 17:29:49 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-09-25 14:52:01 -0400 |
commit | 90ad9e2d91067983f3328e21b306323877e5f48a (patch) | |
tree | 95a903954b148672ca97384165b3bde1ce412bd5 | |
parent | 5ba204a1817ba95a7b24dbe8ef2c7ddd4cea886e (diff) |
x86/io_apic: Reevaluate vector configuration on activate()
With the upcoming reservation/management scheme, early activation will
assign a special vector. The final activation at request_irq() assigns a
real vector, which needs to be updated in the ioapic.
Split out the reconfiguration code in set_affinity and use it for
reactivation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Juergen Gross <jgross@suse.com>
Tested-by: Yu Chen <yu.c.chen@intel.com>
Acked-by: Juergen Gross <jgross@suse.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Alok Kataria <akataria@vmware.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Rui Zhang <rui.zhang@intel.com>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Len Brown <lenb@kernel.org>
Link: https://lkml.kernel.org/r/20170913213156.025232175@linutronix.de
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a4b0c60ab8e1..18c6a4861586 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1862,26 +1862,36 @@ static void ioapic_ir_ack_level(struct irq_data *irq_data) | |||
1862 | eoi_ioapic_pin(data->entry.vector, data); | 1862 | eoi_ioapic_pin(data->entry.vector, data); |
1863 | } | 1863 | } |
1864 | 1864 | ||
1865 | static void ioapic_configure_entry(struct irq_data *irqd) | ||
1866 | { | ||
1867 | struct mp_chip_data *mpd = irqd->chip_data; | ||
1868 | struct irq_cfg *cfg = irqd_cfg(irqd); | ||
1869 | struct irq_pin_list *entry; | ||
1870 | |||
1871 | /* | ||
1872 | * Only update when the parent is the vector domain, don't touch it | ||
1873 | * if the parent is the remapping domain. Check the installed | ||
1874 | * ioapic chip to verify that. | ||
1875 | */ | ||
1876 | if (irqd->chip == &ioapic_chip) { | ||
1877 | mpd->entry.dest = cfg->dest_apicid; | ||
1878 | mpd->entry.vector = cfg->vector; | ||
1879 | } | ||
1880 | for_each_irq_pin(entry, mpd->irq_2_pin) | ||
1881 | __ioapic_write_entry(entry->apic, entry->pin, mpd->entry); | ||
1882 | } | ||
1883 | |||
1865 | static int ioapic_set_affinity(struct irq_data *irq_data, | 1884 | static int ioapic_set_affinity(struct irq_data *irq_data, |
1866 | const struct cpumask *mask, bool force) | 1885 | const struct cpumask *mask, bool force) |
1867 | { | 1886 | { |
1868 | struct irq_data *parent = irq_data->parent_data; | 1887 | struct irq_data *parent = irq_data->parent_data; |
1869 | struct mp_chip_data *data = irq_data->chip_data; | ||
1870 | struct irq_pin_list *entry; | ||
1871 | struct irq_cfg *cfg; | ||
1872 | unsigned long flags; | 1888 | unsigned long flags; |
1873 | int ret; | 1889 | int ret; |
1874 | 1890 | ||
1875 | ret = parent->chip->irq_set_affinity(parent, mask, force); | 1891 | ret = parent->chip->irq_set_affinity(parent, mask, force); |
1876 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 1892 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
1877 | if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE) { | 1893 | if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE) |
1878 | cfg = irqd_cfg(irq_data); | 1894 | ioapic_configure_entry(irq_data); |
1879 | data->entry.dest = cfg->dest_apicid; | ||
1880 | data->entry.vector = cfg->vector; | ||
1881 | for_each_irq_pin(entry, data->irq_2_pin) | ||
1882 | __ioapic_write_entry(entry->apic, entry->pin, | ||
1883 | data->entry); | ||
1884 | } | ||
1885 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1895 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
1886 | 1896 | ||
1887 | return ret; | 1897 | return ret; |
@@ -2980,12 +2990,9 @@ int mp_irqdomain_activate(struct irq_domain *domain, | |||
2980 | struct irq_data *irq_data, bool early) | 2990 | struct irq_data *irq_data, bool early) |
2981 | { | 2991 | { |
2982 | unsigned long flags; | 2992 | unsigned long flags; |
2983 | struct irq_pin_list *entry; | ||
2984 | struct mp_chip_data *data = irq_data->chip_data; | ||
2985 | 2993 | ||
2986 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2994 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2987 | for_each_irq_pin(entry, data->irq_2_pin) | 2995 | ioapic_configure_entry(irq_data); |
2988 | __ioapic_write_entry(entry->apic, entry->pin, data->entry); | ||
2989 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2996 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
2990 | return 0; | 2997 | return 0; |
2991 | } | 2998 | } |