There are no restrictions in hardware to configure the delivery mode of
each interrupt individually. Also, certain interrupts need to be
configured with a specific delivery mode (e.g., non-maskable interrupts).
Add a new member, delivery_mode, to struct irq_cfg to this effect.

To keep the current behavior, use the delivery mode of the APIC driver when
allocating a vector for an interrupt in the root domain (i.e.,
x86_vector_domain).

Cc: Andi Kleen <a...@linux.intel.com>
Cc: "Ravi V. Shankar" <ravi.v.shan...@intel.com>
Cc: Stephane Eranian <eran...@google.com>
Cc: io...@lists.linux-foundation.org
Cc: linuxppc-dev@lists.ozlabs.org
Reviewed-by: Ashok Raj <ashok....@intel.com>
Reviewed-by: Tony Luck <tony.l...@intel.com>
Signed-off-by: Ricardo Neri <ricardo.neri-calde...@linux.intel.com>
---
Changes since v6:
 * Reworded the commit message to accurately state that the root domain
   allocates a vector for an interrupt, not an interrupt. (Thomas)
 * Removed stray newline. (Thomas)
 * Replaced 'irq' with 'interrupt' in the changelog and in the code.
  (Thomas).

Changes since v5:
 * Updated indentation of the existing members of struct irq_cfg.
 * Reworded the commit message.

Changes since v4:
 * Rebased to use new enumeration apic_delivery_modes.

Changes since v3:
 * None

Changes since v2:
 * Reduced scope to only add the interrupt delivery mode in
   struct irq_alloc_info.

Changes since v1:
 * Introduced this patch.
---
 arch/x86/include/asm/hw_irq.h | 5 +++--
 arch/x86/kernel/apic/vector.c | 6 ++++++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index d465ece58151..5ac5e6c603ee 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -88,8 +88,9 @@ struct irq_alloc_info {
 };
 
 struct irq_cfg {
-       unsigned int            dest_apicid;
-       unsigned int            vector;
+       unsigned int                    dest_apicid;
+       unsigned int                    vector;
+       enum apic_delivery_modes        delivery_mode;
 };
 
 extern struct irq_cfg *irq_cfg(unsigned int irq);
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index c1efebd27e6c..633b442c8f84 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -573,6 +573,12 @@ static int x86_vector_alloc_irqs(struct irq_domain 
*domain, unsigned int virq,
                /* Don't invoke affinity setter on deactivated interrupts */
                irqd_set_affinity_on_activate(irqd);
 
+               /*
+                * A delivery mode may be specified in the interrupt allocation
+                * info. If not, use the delivery mode of the APIC.
+                */
+               apicd->hw_irq_cfg.delivery_mode = apic->delivery_mode;
+
                /*
                 * Legacy vectors are already assigned when the IOAPIC
                 * takes them over. They stay on the same vector. This is
-- 
2.25.1

Reply via email to