[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] gdbstub: Various fixes.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1198760037 0
# Node ID 9bf8b152df9fb6b5fa6400927b0e0ad2e4813ea9
# Parent  d24f457fa1afd40112b66e64c180c4f8c5bda46b
gdbstub: Various fixes.

Highlights:
- Removed panics and smp stop calls in favour of an smp pause
  mechanism.
- Added x86_64 register mapping for gdb serial protocol support.

Signed-off-by: Dan Doucette <doucette.daniel@xxxxxxxxx>
---
 xen/arch/ia64/xen/gdbstub.c   |    7 +
 xen/arch/powerpc/gdbstub.c    |    8 ++
 xen/arch/x86/gdbstub.c        |   75 +++++---------------
 xen/arch/x86/traps.c          |   14 +--
 xen/arch/x86/x86_32/Makefile  |    2 
 xen/arch/x86/x86_32/gdbstub.c |   82 +++++++++++++++++++++
 xen/arch/x86/x86_64/Makefile  |    1 
 xen/arch/x86/x86_64/gdbstub.c |  151 ++++++++++++++++++++++++++++++++++++++++
 xen/common/gdbstub.c          |  157 ++++++++++++++++++++++++++++++++++--------
 xen/include/asm-x86/desc.h    |    1 
 xen/include/xen/gdbstub.h     |    3 
 11 files changed, 407 insertions(+), 94 deletions(-)

diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/ia64/xen/gdbstub.c
--- a/xen/arch/ia64/xen/gdbstub.c       Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/arch/ia64/xen/gdbstub.c       Thu Dec 27 12:53:57 2007 +0000
@@ -61,6 +61,13 @@ gdb_arch_read_reg_array(struct cpu_user_
     gdb_send_reply("", ctx);
 }
 
+void 
+gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
+                    struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    gdb_send_reply("", ctx);
+}
+ 
 void 
 gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
                          struct gdb_context *ctx)
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/powerpc/gdbstub.c
--- a/xen/arch/powerpc/gdbstub.c        Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/arch/powerpc/gdbstub.c        Thu Dec 27 12:53:57 2007 +0000
@@ -132,6 +132,14 @@ gdb_arch_read_reg_array(struct cpu_user_
     gdb_send_packet(ctx);
 }
 
+void 
+gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
+                    struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    unimplemented();
+    gdb_send_reply("", ctx);
+}
+ 
 void
 gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char *buf,
                          struct gdb_context *ctx)
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/x86/gdbstub.c
--- a/xen/arch/x86/gdbstub.c    Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/arch/x86/gdbstub.c    Thu Dec 27 12:53:57 2007 +0000
@@ -24,51 +24,7 @@ u16
 u16
 gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
 {
-    /* XXX */
-    return 1;
-}
-
-void 
-gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
-{
-#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
-    GDB_REG(regs->eax);
-    GDB_REG(regs->ecx);
-    GDB_REG(regs->edx);
-    GDB_REG(regs->ebx);
-    GDB_REG(regs->esp);
-    GDB_REG(regs->ebp);
-    GDB_REG(regs->esi);
-    GDB_REG(regs->edi);
-    GDB_REG(regs->eip);
-    GDB_REG(regs->eflags);
-#undef GDB_REG
-#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
-    /* sizeof(segment) = 16bit */
-    /* but gdb requires its return value as 32bit value */
-    GDB_SEG_REG(regs->cs);
-    GDB_SEG_REG(regs->ss);
-    GDB_SEG_REG(regs->ds);
-    GDB_SEG_REG(regs->es);
-    GDB_SEG_REG(regs->fs);
-    GDB_SEG_REG(regs->gs);
-#undef GDB_SEG_REG
-    gdb_send_packet(ctx);
-}
-
-void 
-gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
-                         struct gdb_context *ctx)
-{
-    /* XXX TODO */
-    gdb_send_reply("E02", ctx);
-}
-
-void 
-gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
-                  struct gdb_context *ctx)
-{
-    gdb_send_reply("", ctx);
+    return 5;   /* TRAP signal.  see include/gdb/signals.h */
 }
 
 /*
@@ -85,17 +41,6 @@ gdb_arch_copy_to_user(void *dest, const 
 gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
 {
     return __copy_to_user(dest, src, len);
-}
-
-void 
-gdb_arch_resume(struct cpu_user_regs *regs,
-                unsigned long addr, unsigned long type,
-                struct gdb_context *ctx)
-{
-    /* XXX */
-    if (type == GDB_STEP) {
-        gdb_send_reply("S01", ctx);
-    }
 }
 
 void
@@ -116,6 +61,24 @@ gdb_arch_exit(struct cpu_user_regs *regs
     /* nothing */
 }
 
+void 
+gdb_arch_resume(struct cpu_user_regs *regs,
+                unsigned long addr, unsigned long type,
+                struct gdb_context *ctx)
+{
+    if ( addr != -1UL )
+        regs->eip = addr;
+
+    regs->eflags &= ~X86_EFLAGS_TF;
+
+    /* Set eflags.RF to ensure we do not re-enter. */
+    regs->eflags |= X86_EFLAGS_RF;
+
+    /* Set the trap flag if we are single stepping. */
+    if ( type == GDB_STEP )
+        regs->eflags |= X86_EFLAGS_TF;
+}
+
 /*
  * Local variables:
  * mode: C
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/arch/x86/traps.c      Thu Dec 27 12:53:57 2007 +0000
@@ -806,9 +806,8 @@ asmlinkage void do_int3(struct cpu_user_
 
     if ( !guest_mode(regs) )
     {
-        DEBUGGER_trap_fatal(TRAP_int3, regs);
-        show_execution_state(regs);
-        panic("FATAL TRAP: vector = 3 (Int3)\n");
+        debugger_trap_fatal(TRAP_int3, regs);
+        return;
     } 
 
     do_guest_trap(TRAP_int3, regs, 0);
@@ -2690,11 +2689,6 @@ void set_intr_gate(unsigned int n, void 
     _set_gate(&idt_table[n], 14, 0, addr);
 }
 
-void set_system_gate(unsigned int n, void *addr)
-{
-    _set_gate(idt_table+n,14,3,addr);
-}
-
 void set_tss_desc(unsigned int n, void *addr)
 {
     _set_tssldt_desc(
@@ -2759,8 +2753,8 @@ void __init trap_init(void)
     set_intr_gate(TRAP_divide_error,&divide_error);
     set_intr_gate(TRAP_debug,&debug);
     set_intr_gate(TRAP_nmi,&nmi);
-    set_system_gate(TRAP_int3,&int3);         /* usable from all privileges */
-    set_system_gate(TRAP_overflow,&overflow); /* usable from all privileges */
+    set_intr_gate(TRAP_int3,&int3);         /* usable from all privileges */
+    set_intr_gate(TRAP_overflow,&overflow); /* usable from all privileges */
     set_intr_gate(TRAP_bounds,&bounds);
     set_intr_gate(TRAP_invalid_op,&invalid_op);
     set_intr_gate(TRAP_no_device,&device_not_available);
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/x86/x86_32/Makefile
--- a/xen/arch/x86/x86_32/Makefile      Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/arch/x86/x86_32/Makefile      Thu Dec 27 12:53:57 2007 +0000
@@ -5,4 +5,6 @@ obj-y += seg_fixup.o
 obj-y += seg_fixup.o
 obj-y += traps.o
 
+obj-$(crash_debug) += gdbstub.o
+
 obj-$(supervisor_mode_kernel) += supervisor_mode_kernel.o
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/x86/x86_32/gdbstub.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/x86_32/gdbstub.c     Thu Dec 27 12:53:57 2007 +0000
@@ -0,0 +1,82 @@
+/*
+ * x86-specific gdb stub routines
+ * based on x86 cdb(xen/arch/x86/cdb.c), but Extensively modified.
+ * 
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan. K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <asm/debugger.h>
+
+void 
+gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
+    GDB_REG(regs->eax);
+    GDB_REG(regs->ecx);
+    GDB_REG(regs->edx);
+    GDB_REG(regs->ebx);
+    GDB_REG(regs->esp);
+    GDB_REG(regs->ebp);
+    GDB_REG(regs->esi);
+    GDB_REG(regs->edi);
+    GDB_REG(regs->eip);
+    GDB_REG(regs->eflags);
+#undef GDB_REG
+#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
+    /* sizeof(segment) = 16bit */
+    /* but gdb requires its return value as 32bit value */
+    GDB_SEG_REG(regs->cs);
+    GDB_SEG_REG(regs->ss);
+    GDB_SEG_REG(regs->ds);
+    GDB_SEG_REG(regs->es);
+    GDB_SEG_REG(regs->fs);
+    GDB_SEG_REG(regs->gs);
+#undef GDB_SEG_REG
+    gdb_send_packet(ctx);
+}
+
+void
+gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
+                         struct gdb_context *ctx)
+{
+    /* XXX TODO */
+    gdb_send_reply("E02", ctx);
+}
+
+void
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+                  struct gdb_context *ctx)
+{
+    gdb_send_reply("", ctx);
+}
+
+void
+gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
+                    struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    gdb_send_reply("", ctx);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/x86/x86_64/Makefile
--- a/xen/arch/x86/x86_64/Makefile      Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/arch/x86/x86_64/Makefile      Thu Dec 27 12:53:57 2007 +0000
@@ -5,6 +5,7 @@ obj-y += mm.o
 obj-y += mm.o
 obj-y += traps.o
 
+obj-$(crash_debug)   += gdbstub.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_COMPAT) += compat_kexec.o
 obj-$(CONFIG_COMPAT) += domain.o
diff -r d24f457fa1af -r 9bf8b152df9f xen/arch/x86/x86_64/gdbstub.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/x86_64/gdbstub.c     Thu Dec 27 12:53:57 2007 +0000
@@ -0,0 +1,151 @@
+/*
+ * x86_64 -specific gdb stub routines
+ * 
+ * Copyright (C) 2007 Dan Doucette   ddoucette@xxxxxxxxxxxx
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <asm/debugger.h>
+
+#define GDB_REG64(r) gdb_write_to_packet_hex(r, sizeof(u64), ctx)
+#define GDB_REG32(r)  gdb_write_to_packet_hex(r, sizeof(u32), ctx)
+
+void 
+gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    GDB_REG64(regs->rax);
+    GDB_REG64(regs->rbx);
+    GDB_REG64(regs->rcx);
+    GDB_REG64(regs->rdx);
+    GDB_REG64(regs->rsi);
+    GDB_REG64(regs->rdi);
+    GDB_REG64(regs->rbp);
+    GDB_REG64(regs->rsp);
+
+    GDB_REG64(regs->r8);
+    GDB_REG64(regs->r9);
+    GDB_REG64(regs->r10);
+    GDB_REG64(regs->r11);
+    GDB_REG64(regs->r12);
+    GDB_REG64(regs->r13);
+    GDB_REG64(regs->r14);
+    GDB_REG64(regs->r15);
+
+    GDB_REG64(regs->rip);
+    GDB_REG32(regs->eflags);
+
+    GDB_REG32(regs->cs);
+    GDB_REG32(regs->ss);
+    GDB_REG32(regs->ds);
+    GDB_REG32(regs->es);
+    GDB_REG32(regs->fs);
+    GDB_REG32(regs->gs);
+
+    gdb_send_packet(ctx);
+}
+
+void 
+gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
+                         struct gdb_context *ctx)
+{
+    gdb_send_reply("", ctx);
+}
+
+void 
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+                  struct gdb_context *ctx)
+{
+    switch (regnum)
+    {
+        case 0: GDB_REG64(regs->rax); break;
+        case 1: GDB_REG64(regs->rbx); break;
+        case 2: GDB_REG64(regs->rcx); break;
+        case 3: GDB_REG64(regs->rdx); break;
+        case 4: GDB_REG64(regs->rsi); break;
+        case 5: GDB_REG64(regs->rdi); break;
+        case 6: GDB_REG64(regs->rbp); break;
+        case 7: GDB_REG64(regs->rsp); break;
+
+        case 8: GDB_REG64(regs->r8); break;
+        case 9: GDB_REG64(regs->r9); break;
+        case 10: GDB_REG64(regs->r10); break;
+        case 11: GDB_REG64(regs->r11); break;
+        case 12: GDB_REG64(regs->r12); break;
+        case 13: GDB_REG64(regs->r13); break;
+        case 14: GDB_REG64(regs->r14); break;
+        case 15: GDB_REG64(regs->r15); break;
+
+        case 16: GDB_REG64(regs->rip); break;
+        case 17: GDB_REG32(regs->rflags); break;
+        case 18: GDB_REG32(regs->cs); break;
+        case 19: GDB_REG32(regs->ss); break;
+        case 20: GDB_REG32(regs->ds); break;
+        case 21: GDB_REG32(regs->es); break;
+        case 22: GDB_REG32(regs->fs); break;
+        case 23: GDB_REG32(regs->gs); break;
+        default:
+            GDB_REG64(0xbaadf00ddeadbeef);
+            break;
+    }
+    gdb_send_packet(ctx);
+}
+
+void 
+gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
+                    struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    switch (regnum)
+    {
+        case 0: regs->rax = val; break;
+        case 1: regs->rbx = val; break;
+        case 2: regs->rcx = val; break;
+        case 3: regs->rdx = val; break;
+        case 4: regs->rsi = val; break;
+        case 5: regs->rdi = val; break;
+        case 6: regs->rbp = val; break;
+        case 7: regs->rsp = val; break;
+
+        case 8: regs->r8 = val; break;
+        case 9: regs->r9 = val; break;
+        case 10: regs->r10 = val; break;
+        case 11: regs->r11 = val; break;
+        case 12: regs->r12 = val; break;
+        case 13: regs->r13 = val; break;
+        case 14: regs->r14 = val; break;
+        case 15: regs->r15 = val; break;
+
+        case 16: regs->rip = val; break;
+        case 17: regs->rflags = (u32)val; break;
+        case 18: regs->cs = (u16)val; break;
+        case 19: regs->ss = (u16)val; break;
+        case 20: regs->ds = (u16)val; break;
+        case 21: regs->es = (u16)val; break;
+        case 22: regs->fs = (u16)val; break;
+        case 23: regs->gs = (u16)val; break;
+        default:
+            break;
+    }
+    gdb_send_reply("OK", ctx);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r d24f457fa1af -r 9bf8b152df9f xen/common/gdbstub.c
--- a/xen/common/gdbstub.c      Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/common/gdbstub.c      Thu Dec 27 12:53:57 2007 +0000
@@ -43,6 +43,7 @@
 #include <xen/smp.h>
 #include <xen/console.h>
 #include <xen/errno.h>
+#include <xen/delay.h>
 #include <asm/byteorder.h>
 
 /* Printk isn't particularly safe just after we've trapped to the
@@ -51,6 +52,18 @@
 /*#define dbg_printk(...)   printk(__VA_ARGS__)*/
 
 #define GDB_RETRY_MAX   10
+
+struct gdb_cpu_info
+{
+    atomic_t paused;
+    atomic_t ack;
+};
+
+static struct gdb_cpu_info gdb_cpu[NR_CPUS];
+static atomic_t gdb_smp_paused_count;
+
+static void gdb_smp_pause(void);
+static void gdb_smp_resume(void);
 
 static char opt_gdb[30] = "none";
 string_param("gdb", opt_gdb);
@@ -234,7 +247,7 @@ gdb_write_to_packet_hex(unsigned long x,
     }
 
 #ifdef __BIG_ENDIAN
-       i = sizeof(unsigned long) * 2
+    i = sizeof(unsigned long) * 2
     do {
         buf[--i] = hex2char(x & 15);
         x >>= 4;
@@ -245,13 +258,14 @@ gdb_write_to_packet_hex(unsigned long x,
 
     gdb_write_to_packet(&buf[i], width, ctx);
 #elif defined(__LITTLE_ENDIAN)
-       i = 0;
-       while (i < width) {
-               buf[i++] = hex2char(x>>4);
-               buf[i++] = hex2char(x);
-               x >>= 8;
-       }
-       gdb_write_to_packet(buf, width, ctx);
+    i = 0;
+    while ( i < width )
+    {
+        buf[i++] = hex2char(x>>4);
+        buf[i++] = hex2char(x);
+        x >>= 8;
+    }
+    gdb_write_to_packet(buf, width, ctx);
 #else
 # error unknown endian
 #endif
@@ -396,8 +410,9 @@ process_command(struct cpu_user_regs *re
 process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
 {
     const char *ptr;
-    unsigned long addr, length;
+    unsigned long addr, length, val;
     int resume = 0;
+    unsigned long type = GDB_CONTINUE;
 
     /* XXX check ctx->in_bytes >= 2 or similar. */
 
@@ -460,30 +475,40 @@ process_command(struct cpu_user_regs *re
         }
         gdb_arch_read_reg(addr, regs, ctx);
         break;
+    case 'P': /* write register */
+        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+        if ( ptr == (ctx->in_buf + 1) )
+        {
+            gdb_send_reply("E03", ctx);
+            return 0;
+        }
+        if ( ptr[0] != '=' )
+        {
+            gdb_send_reply("E04", ctx);
+            return 0;
+        }
+        ptr++;
+        val = str2ulong(ptr, sizeof(unsigned long));
+        gdb_arch_write_reg(addr, val, regs, ctx);
+        break;
     case 'D':
+    case 'k':
         gdbstub_detach(ctx);
         gdb_send_reply("OK", ctx);
-        /* fall through */
-    case 'k':
         ctx->connected = 0;
-        /* fall through */
+        resume = 1;
+        break;
     case 's': /* Single step */
+        type = GDB_STEP;
     case 'c': /* Resume at current address */
-    {
-        unsigned long addr = ~((unsigned long)0);
-        unsigned long type = GDB_CONTINUE;
-        if ( ctx->in_buf[0] == 's' )
-            type = GDB_STEP;
-        if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
-             ctx->in_buf[1] )
+        addr = ~((unsigned long)0);
+
+        if ( ctx->in_buf[1] )
             addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
-        if ( ctx->in_buf[0] != 'D' )
-            gdbstub_attach(ctx);
+        gdbstub_attach(ctx);
         resume = 1;
         gdb_arch_resume(regs, addr, type, ctx);
         break;
-    }
-
     default:
         gdb_send_reply("", ctx);
         break;
@@ -555,10 +580,8 @@ __trap_to_gdb(struct cpu_user_regs *regs
         gdb_ctx->connected = 1;
     }
 
-    smp_send_stop();
-
-    /* Try to make things a little more stable by disabling
-       interrupts while we're here. */
+    gdb_smp_pause();
+
     local_irq_save(flags);
 
     watchdog_disable();
@@ -586,6 +609,8 @@ __trap_to_gdb(struct cpu_user_regs *regs
             break;
         }
     } while ( process_command(regs, gdb_ctx) == 0 );
+
+    gdb_smp_resume();
 
     gdb_arch_exit(regs);
     console_end_sync();
@@ -604,6 +629,84 @@ initialise_gdb(void)
     if ( gdb_ctx->serhnd != -1 )
         printk("GDB stub initialised.\n");
     serial_start_sync(gdb_ctx->serhnd);
+}
+
+static void gdb_pause_this_cpu(void *unused)
+{
+    unsigned long flags;
+
+    local_irq_save(flags);
+
+    atomic_set(&gdb_cpu[smp_processor_id()].ack, 1);
+    atomic_inc(&gdb_smp_paused_count);
+
+    while ( atomic_read(&gdb_cpu[smp_processor_id()].paused) )
+        mdelay(1);
+
+    atomic_dec(&gdb_smp_paused_count);
+    atomic_set(&gdb_cpu[smp_processor_id()].ack, 0);
+
+    /* Restore interrupts */
+    local_irq_restore(flags);
+}
+
+static void gdb_smp_pause(void)
+{
+    int timeout = 100;
+    int cpu;
+
+    for_each_online_cpu(cpu)
+    {
+        atomic_set(&gdb_cpu[cpu].ack, 0);
+        atomic_set(&gdb_cpu[cpu].paused, 1);
+    }
+
+    atomic_set(&gdb_smp_paused_count, 0);
+
+    smp_call_function(gdb_pause_this_cpu, NULL, /* dont wait! */0, 0);
+
+    /* Wait 100ms for all other CPUs to enter pause loop */
+    while ( (atomic_read(&gdb_smp_paused_count) < (num_online_cpus() - 1)) 
+            && (timeout-- > 0) )
+        mdelay(1);
+
+    if ( atomic_read(&gdb_smp_paused_count) < (num_online_cpus() - 1) )
+    {
+        printk("GDB: Not all CPUs have paused, missing CPUs ");
+        for_each_online_cpu(cpu)
+        {
+            if ( (cpu != smp_processor_id()) &&
+                 !atomic_read(&gdb_cpu[cpu].ack) )
+                printk("%d ", cpu);
+        }
+        printk("\n");
+    }
+}
+
+static void gdb_smp_resume(void)
+{
+    int cpu;
+    int timeout = 100;
+
+    for_each_online_cpu(cpu)
+        atomic_set(&gdb_cpu[cpu].paused, 0);
+
+    /* Make sure all CPUs resume */
+    while ( (atomic_read(&gdb_smp_paused_count) > 0)
+            && (timeout-- > 0) )
+        mdelay(1);
+
+    if ( atomic_read(&gdb_smp_paused_count) > 0 )
+    {
+        printk("GDB: Not all CPUs have resumed execution, missing CPUs ");
+        for_each_online_cpu(cpu)
+        {
+            if ( (cpu != smp_processor_id()) &&
+                 atomic_read(&gdb_cpu[cpu].ack) )
+                printk("%d ", cpu);
+        }
+        printk("\n");
+    }
 }
 
 /*
diff -r d24f457fa1af -r 9bf8b152df9f xen/include/asm-x86/desc.h
--- a/xen/include/asm-x86/desc.h        Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/include/asm-x86/desc.h        Thu Dec 27 12:53:57 2007 +0000
@@ -213,7 +213,6 @@ extern struct desc_struct compat_gdt_tab
 #endif
 
 extern void set_intr_gate(unsigned int irq, void * addr);
-extern void set_system_gate(unsigned int n, void *addr);
 extern void set_tss_desc(unsigned int n, void *addr);
 
 #endif /* !__ASSEMBLY__ */
diff -r d24f457fa1af -r 9bf8b152df9f xen/include/xen/gdbstub.h
--- a/xen/include/xen/gdbstub.h Thu Dec 27 12:30:44 2007 +0000
+++ b/xen/include/xen/gdbstub.h Thu Dec 27 12:53:57 2007 +0000
@@ -69,6 +69,9 @@ void gdb_arch_write_reg_array(
     struct cpu_user_regs *regs, const char* buf, struct gdb_context *ctx);
 void gdb_arch_read_reg(
     unsigned long regnum, struct cpu_user_regs *regs, struct gdb_context *ctx);
+void gdb_arch_write_reg(
+    unsigned long regnum, unsigned long val, struct cpu_user_regs *regs, 
+    struct gdb_context *ctx);
 unsigned int gdb_arch_copy_from_user(
     void *dest, const void *src, unsigned len);
 unsigned int gdb_arch_copy_to_user(

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.