From: David Woodhouse Date: Wed, 7 Oct 2020 08:01:49 +0000 (+0100) Subject: x86/apic: Use physical mode for external interrupts even for x2apic_cluster X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=429f0c33f4f32cfdbb90a8d796ce5deee768af3e;p=users%2Fdwmw2%2Flinux.git x86/apic: Use physical mode for external interrupts even for x2apic_cluster Linux only ever uses dest_Fixed to target a single CPU with external IOAPIC/MSI interrupts; there's never any benefit to using logical mode for those. In logical mode, the destination APIC ID gratuitously requires more bits, making it less likely to fit into an IOAPIC/MSI destination ID field which may be limited to 8 bits without interrupt remapping. Linux has cases which force x2apic_phys mode just to work around this limitation of external interrupts, when it could perfectly happily be using cluster mode for IPI communication as long as the *external* interrupts use physical mode. There is a corner case where this bimodality doesn't work — when interrupt remapping is enabled, but there are devices which fall outside the scope of any remapping unit. Such devices would fall into the scope of the non-remapped MSI domain, limited to 8 bits of destination ID. As an alternative to this patch, it might be theoretically possible to make IOMMU drivers attempt to detect that case in advance, and manually set x2apic_phys if it is possible that an unremapped device could ever be hotplugged. For completeness, the other alternative I see is restricting the non-IR domains to those *logical* APIC IDs which fit in 8 bits. It's just that there are very few of those. About 8, in fact. Signed-off-by: David Woodhouse --- diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index b0889c48a2ac5..0f8cf9dcc4590 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -185,7 +185,7 @@ static struct apic apic_x2apic_cluster __ro_after_init = { .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed, - .irq_dest_mode = 1, /* logical */ + .irq_dest_mode = 0, /* physical */ .disable_esr = 0, .dest_logical = APIC_DEST_LOGICAL, @@ -203,7 +203,7 @@ static struct apic apic_x2apic_cluster __ro_after_init = { .get_apic_id = x2apic_get_apic_id, .set_apic_id = x2apic_set_apic_id, - .calc_dest_apicid = x2apic_calc_apicid, + .calc_dest_apicid = apic_default_calc_apicid, .send_IPI = x2apic_send_IPI, .send_IPI_mask = x2apic_send_IPI_mask,