WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] gdbstub: Various fixes.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Dec 2007 12:00:14 -0800
Delivery-date: Thu, 27 Dec 2007 12:00:34 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] gdbstub: Various fixes., Xen patchbot-unstable <=