]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - include/linux/irq.h
x86/apic/msi: Plug non-maskable MSI affinity race
[mirror_ubuntu-bionic-kernel.git] / include / linux / irq.h
index a0231e96a578348c21596a3c9d2d0cbe4a9a1249..65545b97d7813387dba246da1ce646fe339943aa 100644 (file)
@@ -213,6 +213,8 @@ struct irq_data {
  * IRQD_SINGLE_TARGET          - IRQ allows only a single affinity target
  * IRQD_DEFAULT_TRIGGER_SET    - Expected trigger already been set
  * IRQD_CAN_RESERVE            - Can use reservation mode
+ * IRQD_MSI_NOMASK_QUIRK       - Non-maskable MSI quirk for affinity change
+ *                               required
  */
 enum {
        IRQD_TRIGGER_MASK               = 0xf,
@@ -235,6 +237,7 @@ enum {
        IRQD_SINGLE_TARGET              = (1 << 24),
        IRQD_DEFAULT_TRIGGER_SET        = (1 << 25),
        IRQD_CAN_RESERVE                = (1 << 26),
+       IRQD_MSI_NOMASK_QUIRK           = (1 << 27),
 };
 
 #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
@@ -394,6 +397,21 @@ static inline bool irqd_can_reserve(struct irq_data *d)
        return __irqd_to_state(d) & IRQD_CAN_RESERVE;
 }
 
+static inline void irqd_set_msi_nomask_quirk(struct irq_data *d)
+{
+       __irqd_to_state(d) |= IRQD_MSI_NOMASK_QUIRK;
+}
+
+static inline void irqd_clr_msi_nomask_quirk(struct irq_data *d)
+{
+       __irqd_to_state(d) &= ~IRQD_MSI_NOMASK_QUIRK;
+}
+
+static inline bool irqd_msi_nomask_quirk(struct irq_data *d)
+{
+       return __irqd_to_state(d) & IRQD_MSI_NOMASK_QUIRK;
+}
+
 #undef __irqd_to_state
 
 static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
@@ -556,7 +574,12 @@ extern int irq_affinity_online_cpu(unsigned int cpu);
 #endif
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
-void irq_move_irq(struct irq_data *data);
+void __irq_move_irq(struct irq_data *data);
+static inline void irq_move_irq(struct irq_data *data)
+{
+       if (unlikely(irqd_is_setaffinity_pending(data)))
+               __irq_move_irq(data);
+}
 void irq_move_masked_irq(struct irq_data *data);
 void irq_force_complete_move(struct irq_desc *desc);
 #else
@@ -1149,7 +1172,8 @@ void irq_matrix_offline(struct irq_matrix *m);
 void irq_matrix_assign_system(struct irq_matrix *m, unsigned int bit, bool replace);
 int irq_matrix_reserve_managed(struct irq_matrix *m, const struct cpumask *msk);
 void irq_matrix_remove_managed(struct irq_matrix *m, const struct cpumask *msk);
-int irq_matrix_alloc_managed(struct irq_matrix *m, unsigned int cpu);
+int irq_matrix_alloc_managed(struct irq_matrix *m, const struct cpumask *msk,
+                               unsigned int *mapped_cpu);
 void irq_matrix_reserve(struct irq_matrix *m);
 void irq_matrix_remove_reserved(struct irq_matrix *m);
 int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,