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

Commit 0a1ad60d authored by Jan Beulich's avatar Jan Beulich Committed by Linus Torvalds
Browse files

[PATCH] x86_64: serialize assign_irq_vector() use of static variables



Since assign_irq_vector() can be called at runtime, its access of static
variables should be protected by a lock.

Signed-off-by: default avatarJan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a32073bf
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ atomic_t irq_mis_count;
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };

static DEFINE_SPINLOCK(ioapic_lock);
static DEFINE_SPINLOCK(vector_lock);

int timer_over_8254 __initdata = 1;

@@ -1161,10 +1162,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
int assign_irq_vector(int irq)
{
	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
	int vector;

	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);

	spin_lock(&vector_lock);

	BUG_ON(irq >= NR_IRQ_VECTORS);
	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
		spin_unlock(&vector_lock);
		return IO_APIC_VECTOR(irq);
	}
next:
	current_vector += 8;
	if (current_vector == SYSCALL_VECTOR)
@@ -1172,16 +1179,21 @@ int assign_irq_vector(int irq)

	if (current_vector >= FIRST_SYSTEM_VECTOR) {
		offset++;
		if (!(offset%8))
		if (!(offset%8)) {
			spin_unlock(&vector_lock);
			return -ENOSPC;
		}
		current_vector = FIRST_DEVICE_VECTOR + offset;
	}

	vector_irq[current_vector] = irq;
	vector = current_vector;
	vector_irq[vector] = irq;
	if (irq != AUTO_ASSIGN)
		IO_APIC_VECTOR(irq) = current_vector;
		IO_APIC_VECTOR(irq) = vector;

	spin_unlock(&vector_lock);

	return current_vector;
	return vector;
}

static struct hw_interrupt_type ioapic_level_type;
+14 −4
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ int timer_over_8254 __initdata = 0;
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };

static DEFINE_SPINLOCK(ioapic_lock);
static DEFINE_SPINLOCK(vector_lock);

/*
 * # of IRQ routing registers
@@ -834,10 +835,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
int assign_irq_vector(int irq)
{
	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
	int vector;

	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)

	spin_lock(&vector_lock);

	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
		spin_unlock(&vector_lock);
		return IO_APIC_VECTOR(irq);
	}
next:
	current_vector += 8;
	if (current_vector == IA32_SYSCALL_VECTOR)
@@ -849,11 +856,14 @@ int assign_irq_vector(int irq)
		current_vector = FIRST_DEVICE_VECTOR + offset;
	}

	vector_irq[current_vector] = irq;
	vector = current_vector;
	vector_irq[vector] = irq;
	if (irq != AUTO_ASSIGN)
		IO_APIC_VECTOR(irq) = current_vector;
		IO_APIC_VECTOR(irq) = vector;

	spin_unlock(&vector_lock);

	return current_vector;
	return vector;
}

extern void (*interrupt[NR_IRQS])(void);