]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
x86/irq: Limit IOAPIC and MSI domains' affinity without IR
authorDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 5 Oct 2020 08:37:53 +0000 (09:37 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 7 Oct 2020 10:28:36 +0000 (11:28 +0100)
When interrupt remapping isn't enabled, the non-remapped IOAPIC and MSI
IRQ domains can only target CPUs with APIC IDs below 256 (or 32768 in
some virtual environments). Set the appropriate max affinity for
the non-IR IRQ domains accordingly.

Note that the IOAPIC and HPET code paths touched in this patch are
used by both IR and non-IR and thus need to conditionally apply the
limit, while native_create_pci_msi_domain() is only for the non-IR
case and it doesn't need to be conditional there.

This also fixes the case where interrupt remapping is enabled but some
devices are not within the scope of any active IOMMU so they still fall
into the non-IR IRQ domain and require the same affinity limit.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/msi.c

index aa9a3b54a96cde5ee42f73112554a28d8c3086d5..526d89a68e8738ee69647ee5f623087560d93179 100644 (file)
@@ -2330,6 +2330,8 @@ static int mp_irqdomain_create(int ioapic)
        }
 
        ip->irqdomain->parent = parent;
+       if (parent == x86_vector_domain)
+               irq_domain_set_affinity(ip->irqdomain, &x86_non_ir_cpumask);
 
        if (cfg->type == IOAPIC_DOMAIN_LEGACY ||
            cfg->type == IOAPIC_DOMAIN_STRICT)
index 85206f971284a64928c051fee2219ec1d1975e0e..68d44c728c7da8926bb31c89a468cb2033a4217f 100644 (file)
@@ -259,6 +259,7 @@ struct irq_domain * __init native_create_pci_msi_domain(void)
                pr_warn("Failed to initialize PCI-MSI irqdomain.\n");
        } else {
                d->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
+               irq_domain_set_affinity(d, &x86_non_ir_cpumask);
        }
        return d;
 }
@@ -479,6 +480,8 @@ struct irq_domain *hpet_create_irq_domain(int hpet_id)
                irq_domain_free_fwnode(fn);
                kfree(domain_info);
        }
+       if (parent == x86_vector_domain)
+               irq_domain_set_affinity(d, &x86_non_ir_cpumask);
        return d;
 }