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

x86: fix lguest used_vectors breakage, -v2



Impact: fix lguest, clean up

32-bit lguest used used_vectors to record vectors, but that model of
allocating vectors changed and got broken, after we changed vector
allocation to a per_cpu array.

Try enable that for 64bit, and the array is used for all vectors that
are not managed by vector_irq per_cpu array.

Also kill system_vectors[], that is now a duplication of the
used_vectors bitmap.

[ merged in cpus4096 due to io_apic.c cpumask changes. ]
[ -v2, fix build failure ]

Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent a7883dec
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -320,16 +320,14 @@ static inline void set_intr_gate(unsigned int n, void *addr)
	_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
}

#define SYS_VECTOR_FREE		0
#define SYS_VECTOR_ALLOCED	1

extern int first_system_vector;
extern char system_vectors[];
/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
extern unsigned long used_vectors[];

static inline void alloc_system_vector(int vector)
{
	if (system_vectors[vector] == SYS_VECTOR_FREE) {
		system_vectors[vector] = SYS_VECTOR_ALLOCED;
	if (!test_bit(vector, used_vectors)) {
		set_bit(vector, used_vectors);
		if (first_system_vector > vector)
			first_system_vector = vector;
	} else
+1 −0
Original line number Diff line number Diff line
@@ -46,5 +46,6 @@ extern void native_init_IRQ(void);

/* Interrupt vector management */
extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
extern int vector_used_by_percpu_irq(unsigned int vector);

#endif /* _ASM_X86_IRQ_H */
+0 −2
Original line number Diff line number Diff line
@@ -118,8 +118,6 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);

int first_system_vector = 0xfe;

char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};

/*
 * Debug level, exported for io_apic.c
 */
+3 −6
Original line number Diff line number Diff line
@@ -1326,13 +1326,10 @@ next:
		}
		if (unlikely(current_vector == vector))
			continue;
#ifdef CONFIG_X86_64
		if (vector == IA32_SYSCALL_VECTOR)
			goto next;
#else
		if (vector == SYSCALL_VECTOR)

		if (test_bit(vector, used_vectors))
			goto next;
#endif

		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
			if (per_cpu(vector_irq, new_cpu)[vector] != -1)
				goto next;
+15 −1
Original line number Diff line number Diff line
@@ -110,6 +110,18 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
	[IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
};

int vector_used_by_percpu_irq(unsigned int vector)
{
	int cpu;

	for_each_online_cpu(cpu) {
		if (per_cpu(vector_irq, cpu)[vector] != -1)
			return 1;
	}

	return 0;
}

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

@@ -146,10 +158,12 @@ void __init native_init_IRQ(void)
	alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);

	/* IPI for single call function */
	set_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt);
	alloc_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);
	set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
#endif

#ifdef CONFIG_X86_LOCAL_APIC
Loading