x86/apic: Always provide irq_compose_msi_msg() method for vector domain
This shouldn't be dependent on PCI_MSI. HPET and I/O-APIC can deliver interrupts through MSI without having any PCI in the system at all. Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20201024213535.443185-10-dwmw2@infradead.org
This commit is contained in:
committed by
Thomas Gleixner
parent
8c44963b60
commit
f598181acf
@@ -520,12 +520,10 @@ static inline void apic_smt_update(void) { }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct msi_msg;
|
struct msi_msg;
|
||||||
|
struct irq_cfg;
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_MSI
|
extern void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg,
|
||||||
void x86_vector_msi_compose_msg(struct irq_data *data, struct msi_msg *msg);
|
bool dmar);
|
||||||
#else
|
|
||||||
# define x86_vector_msi_compose_msg NULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void ioapic_zap_locks(void);
|
extern void ioapic_zap_locks(void);
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include <asm/io_apic.h>
|
#include <asm/io_apic.h>
|
||||||
#include <asm/desc.h>
|
#include <asm/desc.h>
|
||||||
#include <asm/hpet.h>
|
#include <asm/hpet.h>
|
||||||
|
#include <asm/msidef.h>
|
||||||
#include <asm/mtrr.h>
|
#include <asm/mtrr.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
@@ -2480,6 +2481,37 @@ int hard_smp_processor_id(void)
|
|||||||
return read_apic_id();
|
return read_apic_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg,
|
||||||
|
bool dmar)
|
||||||
|
{
|
||||||
|
msg->address_hi = MSI_ADDR_BASE_HI;
|
||||||
|
|
||||||
|
msg->address_lo =
|
||||||
|
MSI_ADDR_BASE_LO |
|
||||||
|
(apic->dest_mode_logical ?
|
||||||
|
MSI_ADDR_DEST_MODE_LOGICAL :
|
||||||
|
MSI_ADDR_DEST_MODE_PHYSICAL) |
|
||||||
|
MSI_ADDR_REDIRECTION_CPU |
|
||||||
|
MSI_ADDR_DEST_ID(cfg->dest_apicid);
|
||||||
|
|
||||||
|
msg->data =
|
||||||
|
MSI_DATA_TRIGGER_EDGE |
|
||||||
|
MSI_DATA_LEVEL_ASSERT |
|
||||||
|
MSI_DATA_DELIVERY_FIXED |
|
||||||
|
MSI_DATA_VECTOR(cfg->vector);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only the IOMMU itself can use the trick of putting destination
|
||||||
|
* APIC ID into the high bits of the address. Anything else would
|
||||||
|
* just be writing to memory if it tried that, and needs IR to
|
||||||
|
* address higher APIC IDs.
|
||||||
|
*/
|
||||||
|
if (dmar)
|
||||||
|
msg->address_hi |= MSI_ADDR_EXT_DEST_ID(cfg->dest_apicid);
|
||||||
|
else
|
||||||
|
WARN_ON_ONCE(MSI_ADDR_EXT_DEST_ID(cfg->dest_apicid));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override the generic EOI implementation with an optimized version.
|
* Override the generic EOI implementation with an optimized version.
|
||||||
* Only called during early boot when only one CPU is active and with
|
* Only called during early boot when only one CPU is active and with
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <linux/hpet.h>
|
#include <linux/hpet.h>
|
||||||
#include <linux/msi.h>
|
#include <linux/msi.h>
|
||||||
#include <asm/irqdomain.h>
|
#include <asm/irqdomain.h>
|
||||||
#include <asm/msidef.h>
|
|
||||||
#include <asm/hpet.h>
|
#include <asm/hpet.h>
|
||||||
#include <asm/hw_irq.h>
|
#include <asm/hw_irq.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
@@ -23,42 +22,6 @@
|
|||||||
|
|
||||||
struct irq_domain *x86_pci_msi_default_domain __ro_after_init;
|
struct irq_domain *x86_pci_msi_default_domain __ro_after_init;
|
||||||
|
|
||||||
static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg,
|
|
||||||
bool dmar)
|
|
||||||
{
|
|
||||||
msg->address_hi = MSI_ADDR_BASE_HI;
|
|
||||||
|
|
||||||
msg->address_lo =
|
|
||||||
MSI_ADDR_BASE_LO |
|
|
||||||
(apic->dest_mode_logical ?
|
|
||||||
MSI_ADDR_DEST_MODE_LOGICAL :
|
|
||||||
MSI_ADDR_DEST_MODE_PHYSICAL) |
|
|
||||||
MSI_ADDR_REDIRECTION_CPU |
|
|
||||||
MSI_ADDR_DEST_ID(cfg->dest_apicid);
|
|
||||||
|
|
||||||
msg->data =
|
|
||||||
MSI_DATA_TRIGGER_EDGE |
|
|
||||||
MSI_DATA_LEVEL_ASSERT |
|
|
||||||
MSI_DATA_DELIVERY_FIXED |
|
|
||||||
MSI_DATA_VECTOR(cfg->vector);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only the IOMMU itself can use the trick of putting destination
|
|
||||||
* APIC ID into the high bits of the address. Anything else would
|
|
||||||
* just be writing to memory if it tried that, and needs IR to
|
|
||||||
* address higher APIC IDs.
|
|
||||||
*/
|
|
||||||
if (dmar)
|
|
||||||
msg->address_hi |= MSI_ADDR_EXT_DEST_ID(cfg->dest_apicid);
|
|
||||||
else
|
|
||||||
WARN_ON_ONCE(MSI_ADDR_EXT_DEST_ID(cfg->dest_apicid));
|
|
||||||
}
|
|
||||||
|
|
||||||
void x86_vector_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
|
|
||||||
{
|
|
||||||
__irq_msi_compose_msg(irqd_cfg(data), msg, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void irq_msi_update_msg(struct irq_data *irqd, struct irq_cfg *cfg)
|
static void irq_msi_update_msg(struct irq_data *irqd, struct irq_cfg *cfg)
|
||||||
{
|
{
|
||||||
struct msi_msg msg[2] = { [1] = { }, };
|
struct msi_msg msg[2] = { [1] = { }, };
|
||||||
|
|||||||
@@ -818,6 +818,12 @@ void apic_ack_edge(struct irq_data *irqd)
|
|||||||
apic_ack_irq(irqd);
|
apic_ack_irq(irqd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void x86_vector_msi_compose_msg(struct irq_data *data,
|
||||||
|
struct msi_msg *msg)
|
||||||
|
{
|
||||||
|
__irq_msi_compose_msg(irqd_cfg(data), msg, false);
|
||||||
|
}
|
||||||
|
|
||||||
static struct irq_chip lapic_controller = {
|
static struct irq_chip lapic_controller = {
|
||||||
.name = "APIC",
|
.name = "APIC",
|
||||||
.irq_ack = apic_ack_edge,
|
.irq_ack = apic_ack_edge,
|
||||||
|
|||||||
Reference in New Issue
Block a user