Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d0ae2db authored by Weidong Han's avatar Weidong Han Committed by Ingo Molnar
Browse files

x86, intr-remap: fix ack for interrupt remapping



Shouldn't call ack_apic_edge() in ir_ack_apic_edge(), because
ack_apic_edge() does more than just ack: it also does irq migration
in the non-interrupt-remapping case. But there is no such need for
interrupt-remapping case, as irq migration is done in the process
context.

Similarly, ir_ack_apic_level() shouldn't call ack_apic_level, and
instead should do the local cpu's EOI + directed EOI to the io-apic.

ack_x2APIC_irq() is not neccessary, because ack_APIC_irq() will use MSR
write for x2apic, and uncached write for non-x2apic.

[ Impact: simplify/standardize intr-remap IRQ acking, fix on !x2apic ]

Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarWeidong Han <weidong.han@intel.com>
Acked-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
Cc: iommu@lists.linux-foundation.org
Cc: allen.m.kay@intel.com
Cc: fenghua.yu@intel.com
LKML-Reference: <1239957736-6161-3-git-send-email-weidong.han@intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 2b2fd87a
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -204,14 +204,6 @@ static inline int x2apic_enabled(void)

extern int get_physical_broadcast(void);

#ifdef CONFIG_X86_X2APIC
static inline void ack_x2APIC_irq(void)
{
	/* Docs say use 0 for future compatibility */
	native_apic_msr_write(APIC_EOI, 0);
}
#endif

extern void apic_disable(void);
extern int lapic_get_maxlvt(void);
extern void clear_local_APIC(void);
+5 −27
Original line number Diff line number Diff line
@@ -2552,20 +2552,6 @@ eoi_ioapic_irq(struct irq_desc *desc)
	spin_unlock_irqrestore(&ioapic_lock, flags);
}

#ifdef CONFIG_X86_X2APIC
static void ack_x2apic_level(unsigned int irq)
{
	struct irq_desc *desc = irq_to_desc(irq);
	ack_x2APIC_irq();
	eoi_ioapic_irq(desc);
}

static void ack_x2apic_edge(unsigned int irq)
{
	ack_x2APIC_irq();
}
#endif

static void ack_apic_edge(unsigned int irq)
{
	struct irq_desc *desc = irq_to_desc(irq);
@@ -2629,9 +2615,6 @@ static void ack_apic_level(unsigned int irq)
	 */
	ack_APIC_irq();

	if (irq_remapped(irq))
		eoi_ioapic_irq(desc);

	/* Now we can move and renable the irq */
	if (unlikely(do_unmask_irq)) {
		/* Only migrate the irq if the ack has been received.
@@ -2680,20 +2663,15 @@ static void ack_apic_level(unsigned int irq)
#ifdef CONFIG_INTR_REMAP
static void ir_ack_apic_edge(unsigned int irq)
{
#ifdef CONFIG_X86_X2APIC
       if (x2apic_enabled())
               return ack_x2apic_edge(irq);
#endif
       return ack_apic_edge(irq);
	ack_APIC_irq();
}

static void ir_ack_apic_level(unsigned int irq)
{
#ifdef CONFIG_X86_X2APIC
       if (x2apic_enabled())
               return ack_x2apic_level(irq);
#endif
       return ack_apic_level(irq);
	struct irq_desc *desc = irq_to_desc(irq);

	ack_APIC_irq();
	eoi_ioapic_irq(desc);
}
#endif /* CONFIG_INTR_REMAP */