Commit f598181a authored by David Woodhouse's avatar David Woodhouse Committed by Thomas Gleixner
Browse files

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: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20201024213535.443185-10-dwmw2@infradead.org
parent 8c44963b
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -520,12 +520,10 @@ static inline void apic_smt_update(void) { }
#endif

struct msi_msg;
struct irq_cfg;

#ifdef CONFIG_PCI_MSI
void x86_vector_msi_compose_msg(struct irq_data *data, struct msi_msg *msg);
#else
# define x86_vector_msi_compose_msg NULL
#endif
extern void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg,
				  bool dmar);

extern void ioapic_zap_locks(void);

+32 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#include <asm/io_apic.h>
#include <asm/desc.h>
#include <asm/hpet.h>
#include <asm/msidef.h>
#include <asm/mtrr.h>
#include <asm/time.h>
#include <asm/smp.h>
@@ -2480,6 +2481,37 @@ int hard_smp_processor_id(void)
	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.
 * Only called during early boot when only one CPU is active and with
+0 −37
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#include <linux/hpet.h>
#include <linux/msi.h>
#include <asm/irqdomain.h>
#include <asm/msidef.h>
#include <asm/hpet.h>
#include <asm/hw_irq.h>
#include <asm/apic.h>
@@ -23,42 +22,6 @@

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)
{
	struct msi_msg msg[2] = { [1] = { }, };
+6 −0
Original line number Diff line number Diff line
@@ -818,6 +818,12 @@ void apic_ack_edge(struct irq_data *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 = {
	.name			= "APIC",
	.irq_ack		= apic_ack_edge,