-- Attached file included as plaintext by Ecartis --
-- File: [PATCH] KDB: commandeer vector 0xfe for KDB_VECTOR.eml
Return-Path: <[EMAIL PROTECTED]>
Received: from cthulhu.engr.sgi.com (cthulhu.engr.sgi.com [192.26.80.2])
by kluge.engr.sgi.com (SGI-8.12.5/8.12.5) with ESMTP id m97Fn8CD2681370
for <[EMAIL PROTECTED]>; Tue, 7 Oct 2008 08:49:08 -0700 (PDT)
Received: from relay.sgi.com (relay2.corp.sgi.com [192.26.58.22])
by cthulhu.engr.sgi.com (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id
m97FmiPc002614
for <[EMAIL PROTECTED]>; Tue, 7 Oct 2008 08:48:44 -0700
Received: from estes.americas.sgi.com (estes.americas.sgi.com [128.162.236.10])
by relay2.corp.sgi.com (Postfix) with ESMTP id 930F530419E
for <[EMAIL PROTECTED]>; Tue, 7 Oct 2008 08:48:41 -0700 (PDT)
Received: by estes.americas.sgi.com (Postfix)
id 551F370001C8; Tue, 7 Oct 2008 10:48:41 -0500 (CDT)
Delivered-To: [EMAIL PROTECTED]
Received: from eag09.americas.sgi.com (eag09.americas.sgi.com [128.162.232.15])
by estes.americas.sgi.com (Postfix) with ESMTP id 4CCF37000103;
Tue, 7 Oct 2008 10:48:41 -0500 (CDT)
Received: from cpw by eag09.americas.sgi.com with local (Exim 4.69)
(envelope-from <[EMAIL PROTECTED]>)
id 1KnEnv-0000bk-E7; Tue, 07 Oct 2008 10:48:55 -0500
To: [EMAIL PROTECTED]
Subject: [PATCH] KDB: commandeer vector 0xfe for KDB_VECTOR
Cc: [EMAIL PROTECTED]
Message-Id: <[EMAIL PROTECTED]>
From: Cliff Wickman <[EMAIL PROTECTED]>
Date: Tue, 07 Oct 2008 10:48:55 -0500
From: Cliff Wickman <[EMAIL PROTECTED]>
Hi Jay,
Remember the conflict over interrupt vector 0xf8 between KDB and
UV TLB shootdown?
There didn't seem to be any clean way to resolve that. The dynamic
interrupt vector scheme that's going into the kernel does not allow
assigning the same vector to all cpu's, or specifying a vector priority.
And KDB needs to be higher priority than the timer interrupt, and UV TLB
shootdown should be too.
But since KDB only needs KDB_VECTOR to ping other cpu's it seems that
it can use one of the system vectors temporarily (not the UV TLB shootdown's
however, as it might be in-progress during the entry to KDB). Dimitri
suggested this approach.
So I tried commandeering 0xfe (ERROR_APIC_VECTOR).
According to arch/x86/kernel/apic_64.c:
"This interrupt should never happen with our APIC/SMP architecture"
When a cpu enters kdb, this patch causes it to commandeer that vector,
send the IPI's, and wait till all other cpu's enter kdb. Then restore
the IDT to its previous state.
It seems to work. I tested on x86_64 and ia32.
What do you think?
Diffed against 2.6.27-rc8
Signed-off-by: Cliff Wickman <[EMAIL PROTECTED]>
---
arch/x86/kdb/kdbasupport_32.c | 36 ++++++++++++++++++++++++++++++++----
arch/x86/kdb/kdbasupport_64.c | 37 +++++++++++++++++++++++++++++++++----
include/asm-x86/irq_vectors.h | 11 ++++++-----
3 files changed, 71 insertions(+), 13 deletions(-)
Index: 081002.linus/arch/x86/kdb/kdbasupport_32.c
===================================================================
--- 081002.linus.orig/arch/x86/kdb/kdbasupport_32.c
+++ 081002.linus/arch/x86/kdb/kdbasupport_32.c
@@ -883,9 +883,6 @@ kdba_cpu_up(void)
static int __init
kdba_arch_init(void)
{
-#ifdef CONFIG_SMP
- set_intr_gate(KDB_VECTOR, kdb_interrupt);
-#endif
set_intr_gate(KDBENTER_VECTOR, kdb_call);
return 0;
}
@@ -1027,14 +1024,45 @@ kdba_verify_rw(unsigned long addr, size_
#include <mach_ipi.h>
+gate_desc save_idt[NR_VECTORS];
+
+void kdb_takeover_vector(int vector)
+{
+ memcpy(&save_idt[vector], &idt_table[vector], sizeof(gate_desc));
+ set_intr_gate(KDB_VECTOR, kdb_interrupt);
+ return;
+}
+
+void kdb_giveback_vector(int vector)
+{
+ native_write_idt_entry(idt_table, vector, &save_idt[vector]);
+ return;
+}
+
/* When first entering KDB, try a normal IPI. That reduces backtrace problems
* on the other cpus.
*/
void
smp_kdb_stop(void)
{
- if (!KDB_FLAG(NOIPI))
+ int count;
+ int cpu;
+
+ if (!KDB_FLAG(NOIPI)) {
+ kdb_takeover_vector(KDB_VECTOR);
send_IPI_allbutself(KDB_VECTOR);
+ do {
+ count = 0;
+ for_each_possible_cpu(cpu) {
+ if (cpu_isset(cpu, cpu_online_map)) {
+ if (!KDB_STATE_CPU(KDB,cpu))
+ /* count any cpus NOT in kdb */
+ count++;
+ }
+ }
+ } while (count != 0);
+ kdb_giveback_vector(KDB_VECTOR);
+ }
}
/* The normal KDB IPI handler */
Index: 081002.linus/arch/x86/kdb/kdbasupport_64.c
===================================================================
--- 081002.linus.orig/arch/x86/kdb/kdbasupport_64.c
+++ 081002.linus/arch/x86/kdb/kdbasupport_64.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kdebug.h>
+#include <linux/cpumask.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
@@ -900,9 +901,6 @@ kdba_cpu_up(void)
static int __init
kdba_arch_init(void)
{
-#ifdef CONFIG_SMP
- set_intr_gate(KDB_VECTOR, kdb_interrupt);
-#endif
set_intr_gate(KDBENTER_VECTOR, kdb_call);
return 0;
}
@@ -976,14 +974,45 @@ kdba_set_current_task(const struct task_
#include <mach_ipi.h>
+gate_desc save_idt[NR_VECTORS];
+
+void kdb_takeover_vector(int vector)
+{
+ memcpy(&save_idt[vector], &idt_table[vector], sizeof(gate_desc));
+ set_intr_gate(KDB_VECTOR, kdb_interrupt);
+ return;
+}
+
+void kdb_giveback_vector(int vector)
+{
+ native_write_idt_entry(idt_table, vector, &save_idt[vector]);
+ return;
+}
+
/* When first entering KDB, try a normal IPI. That reduces backtrace problems
* on the other cpus.
*/
void
smp_kdb_stop(void)
{
- if (!KDB_FLAG(NOIPI))
+ int count;
+ int cpu;
+
+ if (!KDB_FLAG(NOIPI)) {
+ kdb_takeover_vector(KDB_VECTOR);
send_IPI_allbutself(KDB_VECTOR);
+ do {
+ count = 0;
+ for_each_possible_cpu(cpu) {
+ if (cpu_isset(cpu, cpu_online_map)) {
+ if (!KDB_STATE_CPU(KDB,cpu))
+ /* count any cpus NOT in kdb */
+ count++;
+ }
+ }
+ } while (count != 0);
+ kdb_giveback_vector(KDB_VECTOR);
+ }
}
/* The normal KDB IPI handler */
Index: 081002.linus/include/asm-x86/irq_vectors.h
===================================================================
--- 081002.linus.orig/include/asm-x86/irq_vectors.h
+++ 081002.linus/include/asm-x86/irq_vectors.h
@@ -66,7 +66,6 @@
# define RESCHEDULE_VECTOR 0xfc
# define CALL_FUNCTION_VECTOR 0xfb
# define CALL_FUNCTION_SINGLE_VECTOR 0xfa
-#define KDB_VECTOR 0xf9
# define THERMAL_APIC_VECTOR 0xf0
#else
@@ -79,10 +78,6 @@
#define THERMAL_APIC_VECTOR 0xfa
#define THRESHOLD_APIC_VECTOR 0xf9
#define UV_BAU_MESSAGE 0xf8
-/* Overload KDB_VECTOR with UV_BAU_MESSAGE. By the time the UV hardware is
- * ready, we should have moved to a dynamically allocated vector scheme.
- */
-#define KDB_VECTOR 0xf8
#define INVALIDATE_TLB_VECTOR_END 0xf7
#define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */
@@ -91,6 +86,12 @@
#endif
/*
+ * KDB_VECTOR will take over vector 0xfe when it is needed, as in theory
+ * it should not be used anyway.
+ */
+#define KDB_VECTOR 0xfe
+
+/*
* Local APIC timer IRQ vector is on a different priority level,
* to work around the 'lost local interrupt if more than 2 IRQ
* sources per level' errata.
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.