Commit 4006f663 authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by David Mosberger

[PATCH] ia64: set_rte() should get iosapic_lock

Currently set_rte() changes RTE without iosapic_lock held. I guess it
assumes to be called only at the boot time. But set_rte() can be
called by PCI driver not only at the boot time. So I think set_rte()
should get iosapic_lock.

pci_enable_device(drivers/pci/pci.c)
|
+-> pci_enable_device_bars(drivers/pci/pci.c)
    |
    +-> pcibios_enable_device(arch/ia64/pci/pci.c)
        |
        +-> acpi_pci_irq_enable (drivers/acpi/pci_irq.c)
            |
            +-> iosapic_enable_intr (arch/ia64/kernel/iosapic.c)
                |
                +-> set_rte (arch_ia64/kernel/iosapic.c)

A following patch fixes this issue.
parent 57f668bf
......@@ -172,7 +172,7 @@ gsi_to_irq (unsigned int gsi)
static void
set_rte (unsigned int vector, unsigned int dest, int mask)
{
unsigned long pol, trigger, dmode;
unsigned long pol, trigger, dmode, flags;
u32 low32, high32;
char *addr;
int rte_index;
......@@ -211,11 +211,15 @@ set_rte (unsigned int vector, unsigned int dest, int mask)
/* dest contains both id and eid */
high32 = (dest << IOSAPIC_DEST_SHIFT);
writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
writel(high32, addr + IOSAPIC_WINDOW);
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
writel(low32, addr + IOSAPIC_WINDOW);
iosapic_intr_info[vector].low32 = low32;
spin_lock_irqsave(&iosapic_lock, flags);
{
writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
writel(high32, addr + IOSAPIC_WINDOW);
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
writel(low32, addr + IOSAPIC_WINDOW);
iosapic_intr_info[vector].low32 = low32;
}
spin_unlock_irqrestore(&iosapic_lock, flags);
}
static void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment