ia64/xen-unstable

changeset 16667:9bf8b152df9f

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@gmail.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Dec 27 12:53:57 2007 +0000 (2007-12-27)
parents d24f457fa1af
children 50bd5d2c15cf
files xen/arch/ia64/xen/gdbstub.c xen/arch/powerpc/gdbstub.c xen/arch/x86/gdbstub.c xen/arch/x86/traps.c xen/arch/x86/x86_32/Makefile xen/arch/x86/x86_32/gdbstub.c xen/arch/x86/x86_64/Makefile xen/arch/x86/x86_64/gdbstub.c xen/common/gdbstub.c xen/include/asm-x86/desc.h xen/include/xen/gdbstub.h
line diff
     1.1 --- a/xen/arch/ia64/xen/gdbstub.c	Thu Dec 27 12:30:44 2007 +0000
     1.2 +++ b/xen/arch/ia64/xen/gdbstub.c	Thu Dec 27 12:53:57 2007 +0000
     1.3 @@ -62,6 +62,13 @@ gdb_arch_read_reg_array(struct cpu_user_
     1.4  }
     1.5  
     1.6  void 
     1.7 +gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
     1.8 +                    struct cpu_user_regs *regs, struct gdb_context *ctx)
     1.9 +{
    1.10 +    gdb_send_reply("", ctx);
    1.11 +}
    1.12 + 
    1.13 +void 
    1.14  gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
    1.15                           struct gdb_context *ctx)
    1.16  {
     2.1 --- a/xen/arch/powerpc/gdbstub.c	Thu Dec 27 12:30:44 2007 +0000
     2.2 +++ b/xen/arch/powerpc/gdbstub.c	Thu Dec 27 12:53:57 2007 +0000
     2.3 @@ -132,6 +132,14 @@ gdb_arch_read_reg_array(struct cpu_user_
     2.4      gdb_send_packet(ctx);
     2.5  }
     2.6  
     2.7 +void 
     2.8 +gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
     2.9 +                    struct cpu_user_regs *regs, struct gdb_context *ctx)
    2.10 +{
    2.11 +    unimplemented();
    2.12 +    gdb_send_reply("", ctx);
    2.13 +}
    2.14 + 
    2.15  void
    2.16  gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char *buf,
    2.17                           struct gdb_context *ctx)
     3.1 --- a/xen/arch/x86/gdbstub.c	Thu Dec 27 12:30:44 2007 +0000
     3.2 +++ b/xen/arch/x86/gdbstub.c	Thu Dec 27 12:53:57 2007 +0000
     3.3 @@ -24,51 +24,7 @@
     3.4  u16
     3.5  gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
     3.6  {
     3.7 -    /* XXX */
     3.8 -    return 1;
     3.9 -}
    3.10 -
    3.11 -void 
    3.12 -gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
    3.13 -{
    3.14 -#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
    3.15 -    GDB_REG(regs->eax);
    3.16 -    GDB_REG(regs->ecx);
    3.17 -    GDB_REG(regs->edx);
    3.18 -    GDB_REG(regs->ebx);
    3.19 -    GDB_REG(regs->esp);
    3.20 -    GDB_REG(regs->ebp);
    3.21 -    GDB_REG(regs->esi);
    3.22 -    GDB_REG(regs->edi);
    3.23 -    GDB_REG(regs->eip);
    3.24 -    GDB_REG(regs->eflags);
    3.25 -#undef GDB_REG
    3.26 -#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
    3.27 -    /* sizeof(segment) = 16bit */
    3.28 -    /* but gdb requires its return value as 32bit value */
    3.29 -    GDB_SEG_REG(regs->cs);
    3.30 -    GDB_SEG_REG(regs->ss);
    3.31 -    GDB_SEG_REG(regs->ds);
    3.32 -    GDB_SEG_REG(regs->es);
    3.33 -    GDB_SEG_REG(regs->fs);
    3.34 -    GDB_SEG_REG(regs->gs);
    3.35 -#undef GDB_SEG_REG
    3.36 -    gdb_send_packet(ctx);
    3.37 -}
    3.38 -
    3.39 -void 
    3.40 -gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
    3.41 -                         struct gdb_context *ctx)
    3.42 -{
    3.43 -    /* XXX TODO */
    3.44 -    gdb_send_reply("E02", ctx);
    3.45 -}
    3.46 -
    3.47 -void 
    3.48 -gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
    3.49 -                  struct gdb_context *ctx)
    3.50 -{
    3.51 -    gdb_send_reply("", ctx);
    3.52 +    return 5;   /* TRAP signal.  see include/gdb/signals.h */
    3.53  }
    3.54  
    3.55  /*
    3.56 @@ -87,17 +43,6 @@ gdb_arch_copy_to_user(void *dest, const 
    3.57      return __copy_to_user(dest, src, len);
    3.58  }
    3.59  
    3.60 -void 
    3.61 -gdb_arch_resume(struct cpu_user_regs *regs,
    3.62 -                unsigned long addr, unsigned long type,
    3.63 -                struct gdb_context *ctx)
    3.64 -{
    3.65 -    /* XXX */
    3.66 -    if (type == GDB_STEP) {
    3.67 -        gdb_send_reply("S01", ctx);
    3.68 -    }
    3.69 -}
    3.70 -
    3.71  void
    3.72  gdb_arch_print_state(struct cpu_user_regs *regs)
    3.73  {
    3.74 @@ -116,6 +61,24 @@ gdb_arch_exit(struct cpu_user_regs *regs
    3.75      /* nothing */
    3.76  }
    3.77  
    3.78 +void 
    3.79 +gdb_arch_resume(struct cpu_user_regs *regs,
    3.80 +                unsigned long addr, unsigned long type,
    3.81 +                struct gdb_context *ctx)
    3.82 +{
    3.83 +    if ( addr != -1UL )
    3.84 +        regs->eip = addr;
    3.85 +
    3.86 +    regs->eflags &= ~X86_EFLAGS_TF;
    3.87 +
    3.88 +    /* Set eflags.RF to ensure we do not re-enter. */
    3.89 +    regs->eflags |= X86_EFLAGS_RF;
    3.90 +
    3.91 +    /* Set the trap flag if we are single stepping. */
    3.92 +    if ( type == GDB_STEP )
    3.93 +        regs->eflags |= X86_EFLAGS_TF;
    3.94 +}
    3.95 +
    3.96  /*
    3.97   * Local variables:
    3.98   * mode: C
     4.1 --- a/xen/arch/x86/traps.c	Thu Dec 27 12:30:44 2007 +0000
     4.2 +++ b/xen/arch/x86/traps.c	Thu Dec 27 12:53:57 2007 +0000
     4.3 @@ -806,9 +806,8 @@ asmlinkage void do_int3(struct cpu_user_
     4.4  
     4.5      if ( !guest_mode(regs) )
     4.6      {
     4.7 -        DEBUGGER_trap_fatal(TRAP_int3, regs);
     4.8 -        show_execution_state(regs);
     4.9 -        panic("FATAL TRAP: vector = 3 (Int3)\n");
    4.10 +        debugger_trap_fatal(TRAP_int3, regs);
    4.11 +        return;
    4.12      } 
    4.13  
    4.14      do_guest_trap(TRAP_int3, regs, 0);
    4.15 @@ -2690,11 +2689,6 @@ void set_intr_gate(unsigned int n, void 
    4.16      _set_gate(&idt_table[n], 14, 0, addr);
    4.17  }
    4.18  
    4.19 -void set_system_gate(unsigned int n, void *addr)
    4.20 -{
    4.21 -    _set_gate(idt_table+n,14,3,addr);
    4.22 -}
    4.23 -
    4.24  void set_tss_desc(unsigned int n, void *addr)
    4.25  {
    4.26      _set_tssldt_desc(
    4.27 @@ -2759,8 +2753,8 @@ void __init trap_init(void)
    4.28      set_intr_gate(TRAP_divide_error,&divide_error);
    4.29      set_intr_gate(TRAP_debug,&debug);
    4.30      set_intr_gate(TRAP_nmi,&nmi);
    4.31 -    set_system_gate(TRAP_int3,&int3);         /* usable from all privileges */
    4.32 -    set_system_gate(TRAP_overflow,&overflow); /* usable from all privileges */
    4.33 +    set_intr_gate(TRAP_int3,&int3);         /* usable from all privileges */
    4.34 +    set_intr_gate(TRAP_overflow,&overflow); /* usable from all privileges */
    4.35      set_intr_gate(TRAP_bounds,&bounds);
    4.36      set_intr_gate(TRAP_invalid_op,&invalid_op);
    4.37      set_intr_gate(TRAP_no_device,&device_not_available);
     5.1 --- a/xen/arch/x86/x86_32/Makefile	Thu Dec 27 12:30:44 2007 +0000
     5.2 +++ b/xen/arch/x86/x86_32/Makefile	Thu Dec 27 12:53:57 2007 +0000
     5.3 @@ -5,4 +5,6 @@ obj-y += mm.o
     5.4  obj-y += seg_fixup.o
     5.5  obj-y += traps.o
     5.6  
     5.7 +obj-$(crash_debug) += gdbstub.o
     5.8 +
     5.9  obj-$(supervisor_mode_kernel) += supervisor_mode_kernel.o
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/arch/x86/x86_32/gdbstub.c	Thu Dec 27 12:53:57 2007 +0000
     6.3 @@ -0,0 +1,82 @@
     6.4 +/*
     6.5 + * x86-specific gdb stub routines
     6.6 + * based on x86 cdb(xen/arch/x86/cdb.c), but Extensively modified.
     6.7 + * 
     6.8 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
     6.9 + *                    VA Linux Systems Japan. K.K.
    6.10 + *
    6.11 + * This program is free software; you can redistribute it and/or modify
    6.12 + * it under the terms of the GNU General Public License as published by
    6.13 + * the Free Software Foundation; either version 2 of the License, or
    6.14 + * (at your option) any later version.
    6.15 + * 
    6.16 + * This program is distributed in the hope that it will be useful,
    6.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.19 + * GNU General Public License for more details.
    6.20 + * 
    6.21 + * You should have received a copy of the GNU General Public License
    6.22 + * along with this program; if not, write to the Free Software
    6.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    6.24 + */
    6.25 +
    6.26 +#include <asm/debugger.h>
    6.27 +
    6.28 +void 
    6.29 +gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
    6.30 +{
    6.31 +#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
    6.32 +    GDB_REG(regs->eax);
    6.33 +    GDB_REG(regs->ecx);
    6.34 +    GDB_REG(regs->edx);
    6.35 +    GDB_REG(regs->ebx);
    6.36 +    GDB_REG(regs->esp);
    6.37 +    GDB_REG(regs->ebp);
    6.38 +    GDB_REG(regs->esi);
    6.39 +    GDB_REG(regs->edi);
    6.40 +    GDB_REG(regs->eip);
    6.41 +    GDB_REG(regs->eflags);
    6.42 +#undef GDB_REG
    6.43 +#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
    6.44 +    /* sizeof(segment) = 16bit */
    6.45 +    /* but gdb requires its return value as 32bit value */
    6.46 +    GDB_SEG_REG(regs->cs);
    6.47 +    GDB_SEG_REG(regs->ss);
    6.48 +    GDB_SEG_REG(regs->ds);
    6.49 +    GDB_SEG_REG(regs->es);
    6.50 +    GDB_SEG_REG(regs->fs);
    6.51 +    GDB_SEG_REG(regs->gs);
    6.52 +#undef GDB_SEG_REG
    6.53 +    gdb_send_packet(ctx);
    6.54 +}
    6.55 +
    6.56 +void
    6.57 +gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
    6.58 +                         struct gdb_context *ctx)
    6.59 +{
    6.60 +    /* XXX TODO */
    6.61 +    gdb_send_reply("E02", ctx);
    6.62 +}
    6.63 +
    6.64 +void
    6.65 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
    6.66 +                  struct gdb_context *ctx)
    6.67 +{
    6.68 +    gdb_send_reply("", ctx);
    6.69 +}
    6.70 +
    6.71 +void
    6.72 +gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
    6.73 +                    struct cpu_user_regs *regs, struct gdb_context *ctx)
    6.74 +{
    6.75 +    gdb_send_reply("", ctx);
    6.76 +}
    6.77 +
    6.78 +/*
    6.79 + * Local variables:
    6.80 + * mode: C
    6.81 + * c-set-style: "BSD"
    6.82 + * c-basic-offset: 4
    6.83 + * tab-width: 4
    6.84 + * End:
    6.85 + */
     7.1 --- a/xen/arch/x86/x86_64/Makefile	Thu Dec 27 12:30:44 2007 +0000
     7.2 +++ b/xen/arch/x86/x86_64/Makefile	Thu Dec 27 12:53:57 2007 +0000
     7.3 @@ -5,6 +5,7 @@ obj-y += gpr_switch.o
     7.4  obj-y += mm.o
     7.5  obj-y += traps.o
     7.6  
     7.7 +obj-$(crash_debug)   += gdbstub.o
     7.8  obj-$(CONFIG_COMPAT) += compat.o
     7.9  obj-$(CONFIG_COMPAT) += compat_kexec.o
    7.10  obj-$(CONFIG_COMPAT) += domain.o
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/arch/x86/x86_64/gdbstub.c	Thu Dec 27 12:53:57 2007 +0000
     8.3 @@ -0,0 +1,151 @@
     8.4 +/*
     8.5 + * x86_64 -specific gdb stub routines
     8.6 + * 
     8.7 + * Copyright (C) 2007 Dan Doucette   ddoucette@teradici.com
     8.8 + *
     8.9 + * This program is free software; you can redistribute it and/or modify
    8.10 + * it under the terms of the GNU General Public License as published by
    8.11 + * the Free Software Foundation; either version 2 of the License, or
    8.12 + * (at your option) any later version.
    8.13 + * 
    8.14 + * This program is distributed in the hope that it will be useful,
    8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.17 + * GNU General Public License for more details.
    8.18 + * 
    8.19 + * You should have received a copy of the GNU General Public License
    8.20 + * along with this program; if not, write to the Free Software
    8.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    8.22 + */
    8.23 +
    8.24 +#include <asm/debugger.h>
    8.25 +
    8.26 +#define GDB_REG64(r) gdb_write_to_packet_hex(r, sizeof(u64), ctx)
    8.27 +#define GDB_REG32(r)  gdb_write_to_packet_hex(r, sizeof(u32), ctx)
    8.28 +
    8.29 +void 
    8.30 +gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
    8.31 +{
    8.32 +    GDB_REG64(regs->rax);
    8.33 +    GDB_REG64(regs->rbx);
    8.34 +    GDB_REG64(regs->rcx);
    8.35 +    GDB_REG64(regs->rdx);
    8.36 +    GDB_REG64(regs->rsi);
    8.37 +    GDB_REG64(regs->rdi);
    8.38 +    GDB_REG64(regs->rbp);
    8.39 +    GDB_REG64(regs->rsp);
    8.40 +
    8.41 +    GDB_REG64(regs->r8);
    8.42 +    GDB_REG64(regs->r9);
    8.43 +    GDB_REG64(regs->r10);
    8.44 +    GDB_REG64(regs->r11);
    8.45 +    GDB_REG64(regs->r12);
    8.46 +    GDB_REG64(regs->r13);
    8.47 +    GDB_REG64(regs->r14);
    8.48 +    GDB_REG64(regs->r15);
    8.49 +
    8.50 +    GDB_REG64(regs->rip);
    8.51 +    GDB_REG32(regs->eflags);
    8.52 +
    8.53 +    GDB_REG32(regs->cs);
    8.54 +    GDB_REG32(regs->ss);
    8.55 +    GDB_REG32(regs->ds);
    8.56 +    GDB_REG32(regs->es);
    8.57 +    GDB_REG32(regs->fs);
    8.58 +    GDB_REG32(regs->gs);
    8.59 +
    8.60 +    gdb_send_packet(ctx);
    8.61 +}
    8.62 +
    8.63 +void 
    8.64 +gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
    8.65 +                         struct gdb_context *ctx)
    8.66 +{
    8.67 +    gdb_send_reply("", ctx);
    8.68 +}
    8.69 +
    8.70 +void 
    8.71 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
    8.72 +                  struct gdb_context *ctx)
    8.73 +{
    8.74 +    switch (regnum)
    8.75 +    {
    8.76 +        case 0: GDB_REG64(regs->rax); break;
    8.77 +        case 1: GDB_REG64(regs->rbx); break;
    8.78 +        case 2: GDB_REG64(regs->rcx); break;
    8.79 +        case 3: GDB_REG64(regs->rdx); break;
    8.80 +        case 4: GDB_REG64(regs->rsi); break;
    8.81 +        case 5: GDB_REG64(regs->rdi); break;
    8.82 +        case 6: GDB_REG64(regs->rbp); break;
    8.83 +        case 7: GDB_REG64(regs->rsp); break;
    8.84 +
    8.85 +        case 8: GDB_REG64(regs->r8); break;
    8.86 +        case 9: GDB_REG64(regs->r9); break;
    8.87 +        case 10: GDB_REG64(regs->r10); break;
    8.88 +        case 11: GDB_REG64(regs->r11); break;
    8.89 +        case 12: GDB_REG64(regs->r12); break;
    8.90 +        case 13: GDB_REG64(regs->r13); break;
    8.91 +        case 14: GDB_REG64(regs->r14); break;
    8.92 +        case 15: GDB_REG64(regs->r15); break;
    8.93 +
    8.94 +        case 16: GDB_REG64(regs->rip); break;
    8.95 +        case 17: GDB_REG32(regs->rflags); break;
    8.96 +        case 18: GDB_REG32(regs->cs); break;
    8.97 +        case 19: GDB_REG32(regs->ss); break;
    8.98 +        case 20: GDB_REG32(regs->ds); break;
    8.99 +        case 21: GDB_REG32(regs->es); break;
   8.100 +        case 22: GDB_REG32(regs->fs); break;
   8.101 +        case 23: GDB_REG32(regs->gs); break;
   8.102 +        default:
   8.103 +            GDB_REG64(0xbaadf00ddeadbeef);
   8.104 +            break;
   8.105 +    }
   8.106 +    gdb_send_packet(ctx);
   8.107 +}
   8.108 +
   8.109 +void 
   8.110 +gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
   8.111 +                    struct cpu_user_regs *regs, struct gdb_context *ctx)
   8.112 +{
   8.113 +    switch (regnum)
   8.114 +    {
   8.115 +        case 0: regs->rax = val; break;
   8.116 +        case 1: regs->rbx = val; break;
   8.117 +        case 2: regs->rcx = val; break;
   8.118 +        case 3: regs->rdx = val; break;
   8.119 +        case 4: regs->rsi = val; break;
   8.120 +        case 5: regs->rdi = val; break;
   8.121 +        case 6: regs->rbp = val; break;
   8.122 +        case 7: regs->rsp = val; break;
   8.123 +
   8.124 +        case 8: regs->r8 = val; break;
   8.125 +        case 9: regs->r9 = val; break;
   8.126 +        case 10: regs->r10 = val; break;
   8.127 +        case 11: regs->r11 = val; break;
   8.128 +        case 12: regs->r12 = val; break;
   8.129 +        case 13: regs->r13 = val; break;
   8.130 +        case 14: regs->r14 = val; break;
   8.131 +        case 15: regs->r15 = val; break;
   8.132 +
   8.133 +        case 16: regs->rip = val; break;
   8.134 +        case 17: regs->rflags = (u32)val; break;
   8.135 +        case 18: regs->cs = (u16)val; break;
   8.136 +        case 19: regs->ss = (u16)val; break;
   8.137 +        case 20: regs->ds = (u16)val; break;
   8.138 +        case 21: regs->es = (u16)val; break;
   8.139 +        case 22: regs->fs = (u16)val; break;
   8.140 +        case 23: regs->gs = (u16)val; break;
   8.141 +        default:
   8.142 +            break;
   8.143 +    }
   8.144 +    gdb_send_reply("OK", ctx);
   8.145 +}
   8.146 +
   8.147 +/*
   8.148 + * Local variables:
   8.149 + * mode: C
   8.150 + * c-set-style: "BSD"
   8.151 + * c-basic-offset: 4
   8.152 + * tab-width: 4
   8.153 + * End:
   8.154 + */
     9.1 --- a/xen/common/gdbstub.c	Thu Dec 27 12:30:44 2007 +0000
     9.2 +++ b/xen/common/gdbstub.c	Thu Dec 27 12:53:57 2007 +0000
     9.3 @@ -43,6 +43,7 @@
     9.4  #include <xen/smp.h>
     9.5  #include <xen/console.h>
     9.6  #include <xen/errno.h>
     9.7 +#include <xen/delay.h>
     9.8  #include <asm/byteorder.h>
     9.9  
    9.10  /* Printk isn't particularly safe just after we've trapped to the
    9.11 @@ -52,6 +53,18 @@
    9.12  
    9.13  #define GDB_RETRY_MAX   10
    9.14  
    9.15 +struct gdb_cpu_info
    9.16 +{
    9.17 +    atomic_t paused;
    9.18 +    atomic_t ack;
    9.19 +};
    9.20 +
    9.21 +static struct gdb_cpu_info gdb_cpu[NR_CPUS];
    9.22 +static atomic_t gdb_smp_paused_count;
    9.23 +
    9.24 +static void gdb_smp_pause(void);
    9.25 +static void gdb_smp_resume(void);
    9.26 +
    9.27  static char opt_gdb[30] = "none";
    9.28  string_param("gdb", opt_gdb);
    9.29  
    9.30 @@ -234,7 +247,7 @@ gdb_write_to_packet_hex(unsigned long x,
    9.31      }
    9.32  
    9.33  #ifdef __BIG_ENDIAN
    9.34 -	i = sizeof(unsigned long) * 2
    9.35 +    i = sizeof(unsigned long) * 2
    9.36      do {
    9.37          buf[--i] = hex2char(x & 15);
    9.38          x >>= 4;
    9.39 @@ -245,13 +258,14 @@ gdb_write_to_packet_hex(unsigned long x,
    9.40  
    9.41      gdb_write_to_packet(&buf[i], width, ctx);
    9.42  #elif defined(__LITTLE_ENDIAN)
    9.43 -	i = 0;
    9.44 -	while (i < width) {
    9.45 -		buf[i++] = hex2char(x>>4);
    9.46 -		buf[i++] = hex2char(x);
    9.47 -		x >>= 8;
    9.48 -	}
    9.49 -	gdb_write_to_packet(buf, width, ctx);
    9.50 +    i = 0;
    9.51 +    while ( i < width )
    9.52 +    {
    9.53 +        buf[i++] = hex2char(x>>4);
    9.54 +        buf[i++] = hex2char(x);
    9.55 +        x >>= 8;
    9.56 +    }
    9.57 +    gdb_write_to_packet(buf, width, ctx);
    9.58  #else
    9.59  # error unknown endian
    9.60  #endif
    9.61 @@ -396,8 +410,9 @@ static int
    9.62  process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
    9.63  {
    9.64      const char *ptr;
    9.65 -    unsigned long addr, length;
    9.66 +    unsigned long addr, length, val;
    9.67      int resume = 0;
    9.68 +    unsigned long type = GDB_CONTINUE;
    9.69  
    9.70      /* XXX check ctx->in_bytes >= 2 or similar. */
    9.71  
    9.72 @@ -460,30 +475,40 @@ process_command(struct cpu_user_regs *re
    9.73          }
    9.74          gdb_arch_read_reg(addr, regs, ctx);
    9.75          break;
    9.76 +    case 'P': /* write register */
    9.77 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
    9.78 +        if ( ptr == (ctx->in_buf + 1) )
    9.79 +        {
    9.80 +            gdb_send_reply("E03", ctx);
    9.81 +            return 0;
    9.82 +        }
    9.83 +        if ( ptr[0] != '=' )
    9.84 +        {
    9.85 +            gdb_send_reply("E04", ctx);
    9.86 +            return 0;
    9.87 +        }
    9.88 +        ptr++;
    9.89 +        val = str2ulong(ptr, sizeof(unsigned long));
    9.90 +        gdb_arch_write_reg(addr, val, regs, ctx);
    9.91 +        break;
    9.92      case 'D':
    9.93 +    case 'k':
    9.94          gdbstub_detach(ctx);
    9.95          gdb_send_reply("OK", ctx);
    9.96 -        /* fall through */
    9.97 -    case 'k':
    9.98          ctx->connected = 0;
    9.99 -        /* fall through */
   9.100 +        resume = 1;
   9.101 +        break;
   9.102      case 's': /* Single step */
   9.103 +        type = GDB_STEP;
   9.104      case 'c': /* Resume at current address */
   9.105 -    {
   9.106 -        unsigned long addr = ~((unsigned long)0);
   9.107 -        unsigned long type = GDB_CONTINUE;
   9.108 -        if ( ctx->in_buf[0] == 's' )
   9.109 -            type = GDB_STEP;
   9.110 -        if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
   9.111 -             ctx->in_buf[1] )
   9.112 +        addr = ~((unsigned long)0);
   9.113 +
   9.114 +        if ( ctx->in_buf[1] )
   9.115              addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
   9.116 -        if ( ctx->in_buf[0] != 'D' )
   9.117 -            gdbstub_attach(ctx);
   9.118 +        gdbstub_attach(ctx);
   9.119          resume = 1;
   9.120          gdb_arch_resume(regs, addr, type, ctx);
   9.121          break;
   9.122 -    }
   9.123 -
   9.124      default:
   9.125          gdb_send_reply("", ctx);
   9.126          break;
   9.127 @@ -555,10 +580,8 @@ int
   9.128          gdb_ctx->connected = 1;
   9.129      }
   9.130  
   9.131 -    smp_send_stop();
   9.132 +    gdb_smp_pause();
   9.133  
   9.134 -    /* Try to make things a little more stable by disabling
   9.135 -       interrupts while we're here. */
   9.136      local_irq_save(flags);
   9.137  
   9.138      watchdog_disable();
   9.139 @@ -587,6 +610,8 @@ int
   9.140          }
   9.141      } while ( process_command(regs, gdb_ctx) == 0 );
   9.142  
   9.143 +    gdb_smp_resume();
   9.144 +
   9.145      gdb_arch_exit(regs);
   9.146      console_end_sync();
   9.147      watchdog_enable();
   9.148 @@ -606,6 +631,84 @@ initialise_gdb(void)
   9.149      serial_start_sync(gdb_ctx->serhnd);
   9.150  }
   9.151  
   9.152 +static void gdb_pause_this_cpu(void *unused)
   9.153 +{
   9.154 +    unsigned long flags;
   9.155 +
   9.156 +    local_irq_save(flags);
   9.157 +
   9.158 +    atomic_set(&gdb_cpu[smp_processor_id()].ack, 1);
   9.159 +    atomic_inc(&gdb_smp_paused_count);
   9.160 +
   9.161 +    while ( atomic_read(&gdb_cpu[smp_processor_id()].paused) )
   9.162 +        mdelay(1);
   9.163 +
   9.164 +    atomic_dec(&gdb_smp_paused_count);
   9.165 +    atomic_set(&gdb_cpu[smp_processor_id()].ack, 0);
   9.166 +
   9.167 +    /* Restore interrupts */
   9.168 +    local_irq_restore(flags);
   9.169 +}
   9.170 +
   9.171 +static void gdb_smp_pause(void)
   9.172 +{
   9.173 +    int timeout = 100;
   9.174 +    int cpu;
   9.175 +
   9.176 +    for_each_online_cpu(cpu)
   9.177 +    {
   9.178 +        atomic_set(&gdb_cpu[cpu].ack, 0);
   9.179 +        atomic_set(&gdb_cpu[cpu].paused, 1);
   9.180 +    }
   9.181 +
   9.182 +    atomic_set(&gdb_smp_paused_count, 0);
   9.183 +
   9.184 +    smp_call_function(gdb_pause_this_cpu, NULL, /* dont wait! */0, 0);
   9.185 +
   9.186 +    /* Wait 100ms for all other CPUs to enter pause loop */
   9.187 +    while ( (atomic_read(&gdb_smp_paused_count) < (num_online_cpus() - 1)) 
   9.188 +            && (timeout-- > 0) )
   9.189 +        mdelay(1);
   9.190 +
   9.191 +    if ( atomic_read(&gdb_smp_paused_count) < (num_online_cpus() - 1) )
   9.192 +    {
   9.193 +        printk("GDB: Not all CPUs have paused, missing CPUs ");
   9.194 +        for_each_online_cpu(cpu)
   9.195 +        {
   9.196 +            if ( (cpu != smp_processor_id()) &&
   9.197 +                 !atomic_read(&gdb_cpu[cpu].ack) )
   9.198 +                printk("%d ", cpu);
   9.199 +        }
   9.200 +        printk("\n");
   9.201 +    }
   9.202 +}
   9.203 +
   9.204 +static void gdb_smp_resume(void)
   9.205 +{
   9.206 +    int cpu;
   9.207 +    int timeout = 100;
   9.208 +
   9.209 +    for_each_online_cpu(cpu)
   9.210 +        atomic_set(&gdb_cpu[cpu].paused, 0);
   9.211 +
   9.212 +    /* Make sure all CPUs resume */
   9.213 +    while ( (atomic_read(&gdb_smp_paused_count) > 0)
   9.214 +            && (timeout-- > 0) )
   9.215 +        mdelay(1);
   9.216 +
   9.217 +    if ( atomic_read(&gdb_smp_paused_count) > 0 )
   9.218 +    {
   9.219 +        printk("GDB: Not all CPUs have resumed execution, missing CPUs ");
   9.220 +        for_each_online_cpu(cpu)
   9.221 +        {
   9.222 +            if ( (cpu != smp_processor_id()) &&
   9.223 +                 atomic_read(&gdb_cpu[cpu].ack) )
   9.224 +                printk("%d ", cpu);
   9.225 +        }
   9.226 +        printk("\n");
   9.227 +    }
   9.228 +}
   9.229 +
   9.230  /*
   9.231   * Local variables:
   9.232   * mode: C
    10.1 --- a/xen/include/asm-x86/desc.h	Thu Dec 27 12:30:44 2007 +0000
    10.2 +++ b/xen/include/asm-x86/desc.h	Thu Dec 27 12:53:57 2007 +0000
    10.3 @@ -213,7 +213,6 @@ extern struct desc_struct compat_gdt_tab
    10.4  #endif
    10.5  
    10.6  extern void set_intr_gate(unsigned int irq, void * addr);
    10.7 -extern void set_system_gate(unsigned int n, void *addr);
    10.8  extern void set_tss_desc(unsigned int n, void *addr);
    10.9  
   10.10  #endif /* !__ASSEMBLY__ */
    11.1 --- a/xen/include/xen/gdbstub.h	Thu Dec 27 12:30:44 2007 +0000
    11.2 +++ b/xen/include/xen/gdbstub.h	Thu Dec 27 12:53:57 2007 +0000
    11.3 @@ -69,6 +69,9 @@ void gdb_arch_write_reg_array(
    11.4      struct cpu_user_regs *regs, const char* buf, struct gdb_context *ctx);
    11.5  void gdb_arch_read_reg(
    11.6      unsigned long regnum, struct cpu_user_regs *regs, struct gdb_context *ctx);
    11.7 +void gdb_arch_write_reg(
    11.8 +    unsigned long regnum, unsigned long val, struct cpu_user_regs *regs, 
    11.9 +    struct gdb_context *ctx);
   11.10  unsigned int gdb_arch_copy_from_user(
   11.11      void *dest, const void *src, unsigned len);
   11.12  unsigned int gdb_arch_copy_to_user(