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

Commit 497c9a19 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86: make 32bit support per_cpu vector



so we can merge io_apic_32.c and io_apic_64.c

v2: Use cpu_online_map as target cpus for bigsmp, just like 64-bit is doing.

Also remove some unused TARGET_CPUS macro.

v3: need to check if desc is null in smp_irq_move_cleanup

also migration needs to reset vector too, so copy __target_IO_APIC_irq
from 64bit.

(the duplication will go away once the two files are unified.)

Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 199751d7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -629,7 +629,7 @@ ENTRY(interrupt)
ENTRY(irq_entries_start)
	RING0_INT_FRAME
vector=0
.rept NR_IRQS
.rept NR_VECTORS
	ALIGN
 .if vector
	CFI_ADJUST_CFA_OFFSET -4
+459 −260

File changed.

Preview size limit exceeded, changes collapsed.

+11 −7
Original line number Diff line number Diff line
@@ -223,21 +223,25 @@ unsigned int do_IRQ(struct pt_regs *regs)
{
	struct pt_regs *old_regs;
	/* high bit used in ret_from_ code */
	int overflow, irq = ~regs->orig_ax;
	int overflow;
	unsigned vector = ~regs->orig_ax;
	struct irq_desc *desc;
	unsigned irq;

	desc = irq_to_desc(irq);
	if (unlikely(!desc)) {
		printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
					__func__, irq);
		BUG();
	}

	old_regs = set_irq_regs(regs);
	irq_enter();
	irq = __get_cpu_var(vector_irq)[vector];

	overflow = check_stack_overflow();

	desc = irq_to_desc(irq);
	if (unlikely(!desc)) {
		printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x\n",
					__func__, irq, vector);
		BUG();
	}

	if (!execute_on_irq_stack(overflow, desc, irq)) {
		if (unlikely(overflow))
			print_stack_overflow();
+29 −12
Original line number Diff line number Diff line
@@ -90,6 +90,27 @@ static struct irqaction irq2 = {
	.name = "cascade",
};

DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
	[0 ... IRQ0_VECTOR - 1] = -1,
	[IRQ0_VECTOR] = 0,
	[IRQ1_VECTOR] = 1,
	[IRQ2_VECTOR] = 2,
	[IRQ3_VECTOR] = 3,
	[IRQ4_VECTOR] = 4,
	[IRQ5_VECTOR] = 5,
	[IRQ6_VECTOR] = 6,
	[IRQ7_VECTOR] = 7,
	[IRQ8_VECTOR] = 8,
	[IRQ9_VECTOR] = 9,
	[IRQ10_VECTOR] = 10,
	[IRQ11_VECTOR] = 11,
	[IRQ12_VECTOR] = 12,
	[IRQ13_VECTOR] = 13,
	[IRQ14_VECTOR] = 14,
	[IRQ15_VECTOR] = 15,
	[IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
};

/* Overridden in paravirt.c */
void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));

@@ -105,22 +126,14 @@ void __init native_init_IRQ(void)
	 * us. (some of these will be overridden and become
	 * 'special' SMP interrupts)
	 */
	for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
		int vector = FIRST_EXTERNAL_VECTOR + i;
		if (i >= nr_irqs)
			break;
	for (i =  FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
		/* SYSCALL_VECTOR was reserved in trap_init. */
		if (!test_bit(vector, used_vectors))
			set_intr_gate(vector, interrupt[i]);
		if (i != SYSCALL_VECTOR)
			set_intr_gate(i, interrupt[i]);
	}

#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
	/*
	 * IRQ0 must be given a fixed assignment and initialized,
	 * because it's used before the IO-APIC is set up.
	 */
	set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);

#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
	/*
	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
	 * IPI, driven by wakeup.
@@ -135,6 +148,9 @@ void __init native_init_IRQ(void)

	/* IPI for single call function */
	set_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt);

	/* Low priority IPI to cleanup after moving an irq */
	set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
#endif

#ifdef CONFIG_X86_LOCAL_APIC
@@ -168,3 +184,4 @@ void __init native_init_IRQ(void)

	irq_ctx_init(smp_processor_id());
}
+1 −1
Original line number Diff line number Diff line
@@ -582,7 +582,7 @@ static void __init lguest_init_IRQ(void)
	for (i = 0; i < LGUEST_IRQS; i++) {
		int vector = FIRST_EXTERNAL_VECTOR + i;
		if (vector != SYSCALL_VECTOR) {
			set_intr_gate(vector, interrupt[i]);
			set_intr_gate(vector, interrupt[vector]);
			set_irq_chip_and_handler_name(i, &lguest_irq_controller,
						      handle_level_irq,
						      "level");
Loading