Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 148930
b: refs/heads/master
c: 4ef702c
h: refs/heads/master
v: v3
  • Loading branch information
Andi Kleen authored and H. Peter Anvin committed Jun 3, 2009
1 parent d06ab6f commit 7e8b37b
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4611a6fa4b37cf6b8b6066ed0d605c994c62a1a0
refs/heads/master: 4ef702c10b5df18ab04921fc252c26421d4d6c75
1 change: 1 addition & 0 deletions trunk/arch/x86/include/asm/entry_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR)

BUILD_INTERRUPT3(invalidate_interrupt0,INVALIDATE_TLB_VECTOR_START+0,
smp_invalidate_interrupt)
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/x86/include/asm/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extern void invalidate_interrupt6(void);
extern void invalidate_interrupt7(void);

extern void irq_move_cleanup_interrupt(void);
extern void reboot_interrupt(void);
extern void threshold_interrupt(void);

extern void call_function_interrupt(void);
Expand Down
9 changes: 3 additions & 6 deletions trunk/arch/x86/include/asm/irq_vectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,7 @@
#define CALL_FUNCTION_SINGLE_VECTOR 0xfb
#define THERMAL_APIC_VECTOR 0xfa
#define THRESHOLD_APIC_VECTOR 0xf9

#ifdef CONFIG_X86_32
/* 0xf8 : free */
#else
# define UV_BAU_MESSAGE 0xf8
#endif
#define REBOOT_VECTOR 0xf8

/* f0-f7 used for spreading out TLB flushes: */
#define INVALIDATE_TLB_VECTOR_END 0xf7
Expand All @@ -117,6 +112,8 @@
*/
#define GENERIC_INTERRUPT_VECTOR 0xed

#define UV_BAU_MESSAGE 0xec

/*
* Self IPI vector for machine checks
*/
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,8 @@ END(\sym)
#ifdef CONFIG_SMP
apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \
irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt
apicinterrupt REBOOT_VECTOR \
reboot_interrupt smp_reboot_interrupt
#endif

#ifdef CONFIG_X86_UV
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/x86/kernel/irqinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ static void __init smp_intr_init(void)
/* 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);

/* IPI used for rebooting/stopping */
alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt);
#endif
#endif /* CONFIG_SMP */
}
Expand Down
28 changes: 27 additions & 1 deletion trunk/arch/x86/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,40 @@ void native_send_call_func_ipi(const struct cpumask *mask)
* this function calls the 'stop' function on all other CPUs in the system.
*/

asmlinkage void smp_reboot_interrupt(void)
{
ack_APIC_irq();
irq_enter();
stop_this_cpu(NULL);
irq_exit();
}

static void native_smp_send_stop(void)
{
unsigned long flags;
unsigned long wait;

if (reboot_force)
return;

smp_call_function(stop_this_cpu, NULL, 0);
/*
* Use an own vector here because smp_call_function
* does lots of things not suitable in a panic situation.
* On most systems we could also use an NMI here,
* but there are a few systems around where NMI
* is problematic so stay with an non NMI for now
* (this implies we cannot stop CPUs spinning with irq off
* currently)
*/
if (num_online_cpus() > 1) {
apic->send_IPI_allbutself(REBOOT_VECTOR);

/* Don't wait longer than a second */
wait = USEC_PER_SEC;
while (num_online_cpus() > 1 && wait--)
udelay(1);
}

local_irq_save(flags);
disable_local_APIC();
local_irq_restore(flags);
Expand Down

0 comments on commit 7e8b37b

Please sign in to comment.