direct-io.hg

changeset 1255:0d13d6c5ab80

bitkeeper revision 1.825.3.15 (406841d8eNNPD7qwknDved9Q5NHVCw)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/local/scratch/ach61/xeno-clone/xeno.bk
author ach61@labyrinth.cl.cam.ac.uk
date Mon Mar 29 15:33:44 2004 +0000 (2004-03-29)
parents 34aaad33c28d 139a29901573
children 128166f77232
files xen/arch/i386/pdb-stub.c xen/arch/i386/traps.c xen/common/debug-linux.c xen/include/asm-i386/pdb.h
line diff
     1.1 --- a/xen/arch/i386/pdb-stub.c	Mon Mar 29 14:45:20 2004 +0000
     1.2 +++ b/xen/arch/i386/pdb-stub.c	Mon Mar 29 15:33:44 2004 +0000
     1.3 @@ -1,10 +1,13 @@
     1.4  
     1.5  /*
     1.6   * pervasive debugger
     1.7 + * www.cl.cam.ac.uk/netos/pdb
     1.8   *
     1.9   * alex ho
    1.10   * 2004
    1.11   * university of cambridge computer laboratory
    1.12 + *
    1.13 + * code adapted originally from kgdb & nemesis
    1.14   */
    1.15  
    1.16  #include <xen/lib.h>
    1.17 @@ -32,9 +35,7 @@
    1.18  
    1.19  #define BUFMAX 400
    1.20  
    1.21 -#define PDB_ID_OFFSET 2        /* all threads & domains are positive numbers */
    1.22 -
    1.23 -static const char hexchars[]="0123456789abcdef";
    1.24 +static const char hexchars[] = "0123456789abcdef";
    1.25  
    1.26  static int remote_debug;
    1.27  
    1.28 @@ -46,22 +47,29 @@ static int  pdb_in_buffer_ptr;
    1.29  static unsigned char  pdb_in_checksum;
    1.30  static unsigned char  pdb_xmit_checksum;
    1.31  
    1.32 -struct pdb_ctx_element
    1.33 +/* function pointers in the near future... */
    1.34 +unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid);
    1.35 +void pdb_linux_get_values(char *buffer, int length, unsigned long address,
    1.36 +			  int pid, unsigned long cr3);
    1.37 +
    1.38 +struct pdb_context
    1.39  {
    1.40 -    int ctrl;
    1.41 -    int info;
    1.42 -    unsigned long ctrl_cr3;
    1.43 -    unsigned long info_cr3;
    1.44 +    int valid;
    1.45 +    int domain;
    1.46 +    int process;
    1.47 +    unsigned long ptbr;                   /* cached page table base register */
    1.48  };
    1.49 +struct pdb_context pdb_ctx;
    1.50  
    1.51 -#define pdb_ctx_count 3
    1.52 -enum pdb_levels {PDB_LVL_XEN = 0, PDB_LVL_GUESTOS, PDB_LVL_PROCESS};
    1.53 -struct pdb_ctx_element pdb_ctx[pdb_ctx_count];
    1.54 -int pdb_level = PDB_LVL_XEN;
    1.55 +int pdb_continue_thread = 0;
    1.56 +int pdb_general_thread = 0;
    1.57  
    1.58  void pdb_put_packet (unsigned char *buffer, int ack);
    1.59  
    1.60  int pdb_initialized = 0;
    1.61 +int pdb_page_fault_possible = 0;
    1.62 +int pdb_page_fault_scratch = 0;                     /* just a handy variable */
    1.63 +int pdb_page_fault = 0;
    1.64  static int pdb_serhnd = -1;
    1.65  static int pdb_stepping = 0;
    1.66  
    1.67 @@ -75,16 +83,6 @@ static inline unsigned char pdb_get_char
    1.68      return serial_getc(pdb_serhnd);
    1.69  }
    1.70  
    1.71 -static volatile int mem_err = 0;
    1.72 -void set_mem_err (void)                                   /* NOT USED YET... */
    1.73 -{
    1.74 -    mem_err = 1;
    1.75 -}
    1.76 -
    1.77 -/* These are separate functions so that they are so short and sweet
    1.78 -   that the compiler won't save any registers (if there is a fault
    1.79 -   to mem_fault, they won't get restored, so there better not be any
    1.80 -   saved).  */
    1.81  int
    1.82  get_char (char *addr)
    1.83  {
    1.84 @@ -106,38 +104,17 @@ pdb_process_query (char *ptr)
    1.85      }
    1.86      else if (strcmp(ptr, "fThreadInfo") == 0)
    1.87      {
    1.88 +#ifdef PDB_PAST
    1.89          struct task_struct *p;
    1.90          u_long flags;
    1.91 -	int buf_idx = 0;
    1.92 -
    1.93 -	{                                                /* case pdb_lvl_xen */
    1.94 -	    int count = 0;
    1.95 +#endif /* PDB_PAST */
    1.96  
    1.97 -	    read_lock_irqsave (&tasklist_lock, flags);
    1.98 -
    1.99 -	    pdb_out_buffer[buf_idx++] = 'm';
   1.100 -	    for_each_domain ( p )
   1.101 -	    {
   1.102 -	        domid_t domain = p->domain + PDB_ID_OFFSET;
   1.103 +        int buf_idx = 0;
   1.104  
   1.105 -		if (count > 0)
   1.106 -		{
   1.107 -		    pdb_out_buffer[buf_idx++] = ',';
   1.108 -		}
   1.109 -		if (domain > 15)
   1.110 -		{
   1.111 -		    pdb_out_buffer[buf_idx++] = hexchars[domain >> 4];
   1.112 -		}
   1.113 -		pdb_out_buffer[buf_idx++] = hexchars[domain % 16];
   1.114 -		count++;
   1.115 -	    }
   1.116 -	    pdb_out_buffer[buf_idx++] = 0;
   1.117 +	pdb_out_buffer[buf_idx++] = 'l';
   1.118 +	pdb_out_buffer[buf_idx++] = 0;
   1.119  
   1.120 -	    read_unlock_irqrestore(&tasklist_lock, flags);
   1.121 -	}
   1.122 -
   1.123 -#ifdef PDB_FUTURE
   1.124 -
   1.125 +#ifdef PDB_PAST
   1.126  	switch (pdb_level)
   1.127  	{
   1.128  	case PDB_LVL_XEN:                        /* return a list of domains */
   1.129 @@ -172,7 +149,7 @@ pdb_process_query (char *ptr)
   1.130  	    int foobar[20];
   1.131  	    int loop, total;
   1.132  
   1.133 -	    /* *** BUG: this cr3 is wrong wrong wrong */
   1.134 +                                                       /* this cr3 is wrong! */
   1.135  	    total = pdb_linux_process_list(pdb_ctx[pdb_level].info_cr3,
   1.136  					   foobar, 20);
   1.137  
   1.138 @@ -201,8 +178,7 @@ pdb_process_query (char *ptr)
   1.139  	default:
   1.140  	    break;
   1.141  	}
   1.142 -
   1.143 -#endif /* PDB_FUTURE */
   1.144 +#endif /* PDB_PAST */
   1.145  
   1.146      }
   1.147      else if (strcmp(ptr, "sThreadInfo") == 0)
   1.148 @@ -215,6 +191,16 @@ pdb_process_query (char *ptr)
   1.149      else if (strncmp(ptr, "ThreadExtraInfo,", 16) == 0)
   1.150      {
   1.151          int thread = 0;
   1.152 +	char *message = "foobar ?";
   1.153 +
   1.154 +	ptr += 16;
   1.155 +        if (hexToInt (&ptr, &thread))
   1.156 +	{
   1.157 +            mem2hex (message, pdb_out_buffer, strlen(message) + 1);
   1.158 +	}
   1.159 +
   1.160 +#ifdef PDB_PAST
   1.161 +        int thread = 0;
   1.162  	char message[16];
   1.163  	struct task_struct *p;
   1.164  
   1.165 @@ -227,6 +213,7 @@ pdb_process_query (char *ptr)
   1.166  	{
   1.167              mem2hex ((char *)message, pdb_out_buffer, strlen(message) + 1);
   1.168  	}
   1.169 +#endif /* PDB_PAST */
   1.170  
   1.171  #ifdef PDB_FUTURE
   1.172        {
   1.173 @@ -249,7 +236,7 @@ pdb_process_query (char *ptr)
   1.174      }
   1.175      else
   1.176      {
   1.177 -        printk("pdb_process_query: unknown query [%s]\n", ptr);
   1.178 +        printk("pdb: error, unknown query [%s]\n", ptr);
   1.179      }
   1.180  }
   1.181  
   1.182 @@ -341,36 +328,48 @@ pdb_process_command (char *ptr, struct p
   1.183  
   1.184      pdb_out_buffer[0] = 0;
   1.185  
   1.186 -    if (pdb_ctx[pdb_level].ctrl_cr3 == 0 &&
   1.187 -	pdb_ctx[pdb_level].ctrl >= 0)
   1.188 +    if (pdb_ctx.valid == 1)
   1.189      {
   1.190 -        struct task_struct *p;
   1.191 +        if (pdb_ctx.domain == -1)                        /* pdb context: xen */
   1.192 +	{
   1.193 +	    struct task_struct *p;
   1.194  
   1.195 -	p = find_domain_by_id(pdb_ctx[pdb_level].ctrl);
   1.196 -	if (p->mm.shadow_mode)
   1.197 -	  pdb_ctx[pdb_level].ctrl_cr3 = pagetable_val(p->mm.shadow_table);
   1.198 -	else
   1.199 -	  pdb_ctx[pdb_level].ctrl_cr3 = pagetable_val(p->mm.pagetable);
   1.200 -	put_task_struct(p);
   1.201 +	    p = &idle0_task;
   1.202 +	    if (p->mm.shadow_mode)
   1.203 +	        pdb_ctx.ptbr = pagetable_val(p->mm.shadow_table);
   1.204 +	    else
   1.205 +	        pdb_ctx.ptbr = pagetable_val(p->mm.pagetable);
   1.206 +	}
   1.207 +	else if (pdb_ctx.process == -1)             /* pdb context: guest os */
   1.208 +	{
   1.209 +	    struct task_struct *p;
   1.210  
   1.211 -	TRC(printk ("PROCESS: PDB SET CONTROL DOMAIN TO 0x%lx 0x%x\n",
   1.212 -		pdb_ctx[pdb_level].ctrl_cr3, 
   1.213 -		pdb_ctx[pdb_level].ctrl));
   1.214 -    }
   1.215 -    if (pdb_ctx[pdb_level].info_cr3 == 0 &&
   1.216 -	pdb_ctx[pdb_level].info >= 0)
   1.217 -    {
   1.218 -        struct task_struct *p;
   1.219 +	    p = find_domain_by_id(pdb_ctx.domain);
   1.220 +	    if (p->mm.shadow_mode)
   1.221 +	        pdb_ctx.ptbr = pagetable_val(p->mm.shadow_table);
   1.222 +	    else
   1.223 +	        pdb_ctx.ptbr = pagetable_val(p->mm.pagetable);
   1.224 +	    put_task_struct(p);
   1.225 +	}
   1.226 +	else                                         /* pdb context: process */
   1.227 +	{
   1.228 +	    struct task_struct *p;
   1.229 +	    unsigned long domain_ptbr;
   1.230  
   1.231 -	p = find_domain_by_id(pdb_ctx[pdb_level].info);
   1.232 -	if (p->mm.shadow_mode)
   1.233 -	  pdb_ctx[pdb_level].info_cr3 = pagetable_val(p->mm.shadow_table);
   1.234 -	else
   1.235 -	  pdb_ctx[pdb_level].info_cr3 = pagetable_val(p->mm.pagetable);
   1.236 -	put_task_struct(p);
   1.237 -	TRC(printk ("PROCESS: PDB SET INFO DOMAIN TO 0x%lx 0x%x\n",
   1.238 -		pdb_ctx[pdb_level].info_cr3, 
   1.239 -		pdb_ctx[pdb_level].info));
   1.240 +	    p = find_domain_by_id(pdb_ctx.domain);
   1.241 +	    if (p->mm.shadow_mode)
   1.242 +	        domain_ptbr = pagetable_val(p->mm.shadow_table);
   1.243 +	    else
   1.244 +	        domain_ptbr = pagetable_val(p->mm.pagetable);
   1.245 +	    put_task_struct(p);
   1.246 +
   1.247 +	    pdb_ctx.ptbr = domain_ptbr;
   1.248 +	    /* pdb_ctx.ptbr = pdb_linux_pid_ptbr(domain_ptbr, pdb_ctx.process); */
   1.249 +	}
   1.250 +
   1.251 +	pdb_ctx.valid = 0;
   1.252 +	TRC(printk ("pdb change context (dom:%d, proc:%d) now 0x%lx\n",
   1.253 +		    pdb_ctx.domain, pdb_ctx.process, pdb_ctx.ptbr));
   1.254      }
   1.255  
   1.256      switch (*ptr++)
   1.257 @@ -458,48 +457,20 @@ pdb_process_command (char *ptr, struct p
   1.258  
   1.259          if (hexToInt (&next, &thread))
   1.260          {
   1.261 -            if (thread > 0)
   1.262 -            {
   1.263 -                thread = thread - PDB_ID_OFFSET;
   1.264 -            }
   1.265              if (*ptr == 'c')
   1.266              {
   1.267 -	        pdb_ctx[pdb_level].ctrl = thread;
   1.268 -
   1.269 -		if (thread > 0)
   1.270 -		{
   1.271 -		    struct task_struct *p = find_domain_by_id(thread);
   1.272 -		    if (p->mm.shadow_mode)
   1.273 -		      pdb_ctx[pdb_level].ctrl_cr3 = pagetable_val(p->mm.shadow_table);
   1.274 -		    else
   1.275 -		      pdb_ctx[pdb_level].ctrl_cr3 = pagetable_val(p->mm.pagetable);
   1.276 -		    put_task_struct(p);
   1.277 -		    TRC(printk ("PDB SET CONTROL DOMAIN TO 0x%lx 0x%x\n",
   1.278 -			    pdb_ctx[pdb_level].ctrl_cr3,
   1.279 -			    pdb_ctx[pdb_level].ctrl));
   1.280 -		}
   1.281 +	        pdb_continue_thread = thread;
   1.282              }
   1.283              else if (*ptr == 'g')
   1.284              {
   1.285 -	        pdb_ctx[pdb_level].info = thread;
   1.286 -
   1.287 -		if (thread > 0)
   1.288 -		{
   1.289 -		    struct task_struct *p = find_domain_by_id(thread);
   1.290 -		    if (p->mm.shadow_mode)
   1.291 -		      pdb_ctx[pdb_level].info_cr3 = pagetable_val(p->mm.shadow_table);
   1.292 -		    else
   1.293 -		      pdb_ctx[pdb_level].info_cr3 = pagetable_val(p->mm.pagetable);
   1.294 -		    put_task_struct(p);
   1.295 -		    TRC(printk ("PDB SET INFO DOMAIN TO 0x%lx 0x%x\n",
   1.296 -			    pdb_ctx[pdb_level].info_cr3,
   1.297 -			    pdb_ctx[pdb_level].info));
   1.298 -		}
   1.299 +	        pdb_general_thread = thread;
   1.300              }
   1.301              else
   1.302              {
   1.303 -                printk ("ack, unknown command %c (thread: %d)\n", 
   1.304 +                printk ("pdb error: unknown set thread command %c (%d)\n", 
   1.305                          *ptr, thread);
   1.306 +		strcpy (pdb_out_buffer, "E00");
   1.307 +		break;
   1.308              }
   1.309          }
   1.310          strcpy (pdb_out_buffer, "OK");
   1.311 @@ -528,20 +499,31 @@ pdb_process_command (char *ptr, struct p
   1.312                  if (hexToInt (&ptr, &length))
   1.313                  {
   1.314                      ptr = 0;
   1.315 -                    mem_err = 0;
   1.316  
   1.317 -                    if (pdb_ctx[pdb_level].info >= 0)
   1.318 +		    pdb_page_fault_possible = 1;
   1.319 +		    pdb_page_fault = 0;
   1.320 +		    if (addr >= PAGE_OFFSET)
   1.321 +		    {
   1.322 +                        mem2hex ((char *) addr, pdb_out_buffer, length); 
   1.323 +		    }
   1.324 +		    else if (pdb_ctx.process != -1)
   1.325 +		    {
   1.326 +		        pdb_linux_get_values(pdb_buffer, length, addr, 
   1.327 +					     pdb_ctx.process, pdb_ctx.ptbr);
   1.328 +                        mem2hex (pdb_buffer, pdb_out_buffer, length); 
   1.329 +		    }
   1.330 +                    else
   1.331                      {
   1.332 -		        pdb_get_values(pdb_buffer, length,
   1.333 -				       pdb_ctx[pdb_level].info_cr3, addr);
   1.334 +		        pdb_get_values (pdb_buffer, length, 
   1.335 +					pdb_ctx.ptbr, addr);
   1.336                          mem2hex (pdb_buffer, pdb_out_buffer, length);
   1.337                      }
   1.338 -                    else
   1.339 -                        mem2hex ((char *) addr, pdb_out_buffer, length); 
   1.340 -                    if (mem_err)
   1.341 -                    {
   1.342 +
   1.343 +		    pdb_page_fault_possible = 0;
   1.344 +		    if (pdb_page_fault)
   1.345 +		    {
   1.346                          strcpy (pdb_out_buffer, "E03");
   1.347 -                    }
   1.348 +		    }
   1.349                  }
   1.350  	    
   1.351          if (ptr)
   1.352 @@ -560,13 +542,20 @@ pdb_process_command (char *ptr, struct p
   1.353                  if (hexToInt (&ptr, &length))
   1.354                      if (*(ptr++) == ':')
   1.355                      {
   1.356 -                        mem_err = 0;
   1.357  
   1.358 -                        /* pdb_set_values(ptr, length, cr3, addr); */
   1.359 -                        pdb_set_values(ptr, length, 
   1.360 -				       pdb_ctx[pdb_level].info_cr3, addr);
   1.361 -
   1.362 -                        if (mem_err)
   1.363 +		        pdb_page_fault_possible = 1;
   1.364 +			pdb_page_fault = 0;
   1.365 +			if (addr >= PAGE_OFFSET)
   1.366 +			{
   1.367 +			    hex2mem (ptr, (char *)addr, length);
   1.368 +			}
   1.369 +			else
   1.370 +			{
   1.371 +			    pdb_set_values (ptr, length,
   1.372 +					    pdb_ctx.ptbr, addr);
   1.373 +			}
   1.374 +			pdb_page_fault_possible = 0;
   1.375 +                        if (pdb_page_fault)
   1.376                          {
   1.377                              strcpy (pdb_out_buffer, "E03");
   1.378                          }
   1.379 @@ -589,17 +578,9 @@ pdb_process_command (char *ptr, struct p
   1.380  
   1.381          if (hexToInt (&ptr, &id))
   1.382          {
   1.383 -	        {                                        /* case pdb_lvl_xen */
   1.384 -		    struct task_struct *p;
   1.385 -		    id -= PDB_ID_OFFSET;
   1.386 -		    if ( (p = find_domain_by_id(id)) == NULL)
   1.387 -		        strcpy (pdb_out_buffer, "E00");
   1.388 -		    else
   1.389 -		        strcpy (pdb_out_buffer, "OK");
   1.390 -		    put_task_struct(p);
   1.391 -		}
   1.392 +	    strcpy (pdb_out_buffer, "E00");
   1.393  
   1.394 -#ifdef PDB_FUTURE
   1.395 +#ifdef PDB_PAST
   1.396  
   1.397  	    switch (pdb_level)                             /* previous level */
   1.398  	    {
   1.399 @@ -647,7 +628,7 @@ pdb_process_command (char *ptr, struct p
   1.400  		}
   1.401  	    }
   1.402  
   1.403 -#endif /* PDB_FUTURE */
   1.404 +#endif /* PDB_PAST */
   1.405          }
   1.406          break;
   1.407      }
   1.408 @@ -981,14 +962,21 @@ int pdb_change_values_one_page(u_char *b
   1.409      l2_table += l2_table_offset(addr);
   1.410      if (!(l2_pgentry_val(*l2_table) & _PAGE_PRESENT)) 
   1.411      {
   1.412 -        struct task_struct *p = find_domain_by_id(0);
   1.413 -	printk ("pdb error: cr3: 0x%lx    dom0cr3:  0x%lx\n",  cr3,
   1.414 -		p->mm.shadow_mode ? pagetable_val(p->mm.shadow_table)
   1.415 -		                  : pagetable_val(p->mm.pagetable));
   1.416 -	put_task_struct(p);
   1.417 -
   1.418 -	printk ("pdb error: L2:0x%p (0x%lx) \n", 
   1.419 -		l2_table, l2_pgentry_val(*l2_table));
   1.420 +	if (pdb_page_fault_possible == 1)
   1.421 +	{
   1.422 +	    pdb_page_fault = 1;
   1.423 +	    TRC(printk("pdb: L2 error (0x%lx)\n", addr));
   1.424 +	}
   1.425 +	else
   1.426 +	{
   1.427 +	    struct task_struct *p = find_domain_by_id(0);
   1.428 +	    printk ("pdb error: cr3: 0x%lx    dom0cr3:  0x%lx\n",  cr3,
   1.429 +		    p->mm.shadow_mode ? pagetable_val(p->mm.shadow_table)
   1.430 +		    : pagetable_val(p->mm.pagetable));
   1.431 +	    put_task_struct(p);
   1.432 +	    printk ("pdb error: L2:0x%p (0x%lx)\n", 
   1.433 +		    l2_table, l2_pgentry_val(*l2_table));
   1.434 +	}
   1.435  	goto exit2;
   1.436      }
   1.437  
   1.438 @@ -1012,9 +1000,17 @@ int pdb_change_values_one_page(u_char *b
   1.439  	l1_table += l1_table_offset(addr); 
   1.440  	if (!(l1_pgentry_val(*l1_table) & _PAGE_PRESENT))
   1.441  	{
   1.442 -	    printk ("L2:0x%p (0x%lx) L1:0x%p (0x%lx)\n", 
   1.443 -		    l2_table, l2_pgentry_val(*l2_table),
   1.444 -		    l1_table, l1_pgentry_val(*l1_table));
   1.445 +	    if (pdb_page_fault_possible == 1)
   1.446 +	    {
   1.447 +	        pdb_page_fault = 1;
   1.448 +		TRC(printk ("pdb: L1 error (0x%lx)\n", addr));
   1.449 +	    }
   1.450 +	    else
   1.451 +	    {
   1.452 +	        printk ("L2:0x%p (0x%lx) L1:0x%p (0x%lx)\n", 
   1.453 +			l2_table, l2_pgentry_val(*l2_table),
   1.454 +			l1_table, l1_pgentry_val(*l1_table));
   1.455 +	    }
   1.456  	    goto exit1;
   1.457  	}
   1.458  
   1.459 @@ -1028,11 +1024,11 @@ int pdb_change_values_one_page(u_char *b
   1.460          memcpy (buffer, page, length);
   1.461  	bytes = length;
   1.462  	break;
   1.463 -    case __PDB_SET_VAL:                                         /* write */
   1.464 +    case __PDB_SET_VAL:                                             /* write */
   1.465          hex2mem (buffer, page, length);
   1.466  	bytes = length;
   1.467  	break;
   1.468 -    default:                                                  /* unknown */
   1.469 +    default:                                                      /* unknown */
   1.470          printk ("error: unknown RW flag: %d\n", rw);
   1.471  	return 0;
   1.472      }
   1.473 @@ -1178,9 +1174,6 @@ int pdb_handle_exception(int exceptionVe
   1.474          xen_regs->eip--;
   1.475      }
   1.476  
   1.477 -    watchdog_save = watchdog_on;
   1.478 -    watchdog_on = 0;
   1.479 -
   1.480      /* Generate a signal for GDB. */
   1.481      switch ( exceptionVector )
   1.482      {
   1.483 @@ -1202,6 +1195,9 @@ int pdb_handle_exception(int exceptionVe
   1.484      pdb_out_buffer[3] = 0;
   1.485      pdb_put_packet(pdb_out_buffer, 1);
   1.486  
   1.487 +    watchdog_save = watchdog_on;
   1.488 +    watchdog_on = 0;
   1.489 +
   1.490      do {
   1.491          pdb_out_buffer[0] = 0;
   1.492  	pdb_get_packet(pdb_in_buffer);
   1.493 @@ -1222,7 +1218,6 @@ void pdb_key_pressed(u_char key, void *d
   1.494  void initialize_pdb()
   1.495  {
   1.496      extern char opt_pdb[];
   1.497 -    int loop;
   1.498  
   1.499      /* Certain state must be initialised even when PDB will not be used. */
   1.500      memset((void *) &breakpoints, 0, sizeof(breakpoints));
   1.501 @@ -1238,15 +1233,13 @@ void initialize_pdb()
   1.502          return;
   1.503      }
   1.504  
   1.505 -    for (loop = 0; loop < pdb_ctx_count; loop++)
   1.506 -    {
   1.507 -        pdb_ctx[loop].ctrl = -1;
   1.508 -	pdb_ctx[loop].info = -1;
   1.509 -        pdb_ctx[loop].ctrl_cr3 = 0;
   1.510 -	pdb_ctx[loop].info_cr3 = 0;
   1.511 -    }
   1.512 +    pdb_ctx.valid = 1;
   1.513 +    pdb_ctx.domain = -1;
   1.514 +    pdb_ctx.process = -1;
   1.515 +    pdb_ctx.ptbr = 0;
   1.516  
   1.517 -    printk("Initialized pervasive debugger (PDB) on port %s\n", opt_pdb);
   1.518 +    printk("pdb: pervasive debugger (%s)   www.cl.cam.ac.uk/netos/pdb\n", 
   1.519 +	   opt_pdb);
   1.520  
   1.521      /* Acknowledge any spurious GDB packets. */
   1.522      pdb_put_char('+');
     2.1 --- a/xen/arch/i386/traps.c	Mon Mar 29 14:45:20 2004 +0000
     2.2 +++ b/xen/arch/i386/traps.c	Mon Mar 29 15:33:44 2004 +0000
     2.3 @@ -386,6 +386,15 @@ asmlinkage void do_page_fault(struct pt_
     2.4  #endif
     2.5      }
     2.6  
     2.7 +    if (pdb_page_fault_possible)
     2.8 +    {
     2.9 +        pdb_page_fault = 1;
    2.10 +	/* make eax & edx valid to complete the instruction */
    2.11 +	regs->eax = (long)&pdb_page_fault_scratch;
    2.12 +	regs->edx = (long)&pdb_page_fault_scratch;
    2.13 +	return;
    2.14 +    }
    2.15 +
    2.16      show_registers(regs);
    2.17      panic("CPU%d FATAL PAGE FAULT\n"
    2.18            "[error_code=%08x]\n"
     3.1 --- a/xen/common/debug-linux.c	Mon Mar 29 14:45:20 2004 +0000
     3.2 +++ b/xen/common/debug-linux.c	Mon Mar 29 15:33:44 2004 +0000
     3.3 @@ -1,13 +1,21 @@
     3.4 +
     3.5 +/*
     3.6 + * pervasive debugger
     3.7 + * www.cl.cam.ac.uk/netos/pdb
     3.8 + *
     3.9 + * alex ho
    3.10 + * 2004
    3.11 + * university of cambridge computer laboratory
    3.12 + *
    3.13 + * linux specific pdb stuff 
    3.14 + */
    3.15 +
    3.16  #include <xen/config.h>
    3.17  #include <xen/types.h>
    3.18  #include <xen/lib.h>
    3.19  #include <hypervisor-ifs/dom0_ops.h>
    3.20  #include <asm/pdb.h>
    3.21  
    3.22 -/* 
    3.23 - * linux specific pdb stuff 
    3.24 - */
    3.25 -
    3.26  /* from linux/sched.h */
    3.27  #define PIDHASH_SZ (4096 >> 2)
    3.28  #define pid_hashfn(x)	((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
    3.29 @@ -30,10 +38,8 @@
    3.30  #define ENTRIES_PER_L1_PAGETABLE 1024
    3.31  #define L1_PAGE_BITS ( (ENTRIES_PER_L1_PAGETABLE - 1) << PAGE_SHIFT )
    3.32  
    3.33 -
    3.34  void pdb_linux_process_details (unsigned long cr3, int pid, char *buffer);
    3.35  
    3.36 -
    3.37  /* adapted from asm-xen/page.h */
    3.38  static inline unsigned long machine_to_phys(unsigned long cr3,
    3.39                                              unsigned long machine)
    3.40 @@ -46,9 +52,8 @@ static inline unsigned long machine_to_p
    3.41    return phys;
    3.42  }
    3.43  
    3.44 -
    3.45 -#define pidhash_addr         0xc01971e0UL
    3.46 -#define init_task_union_addr 0xc0182000UL
    3.47 +unsigned long pdb_pidhash_addr         = 0xc01971e0UL;
    3.48 +unsigned long pdb_init_task_union_addr = 0xc0182000UL;
    3.49  
    3.50  #define task_struct_mm_offset        0x2c
    3.51  #define task_struct_next_task_offset 0x48
    3.52 @@ -59,16 +64,18 @@ static inline unsigned long machine_to_p
    3.53  
    3.54  #define mm_struct_pgd_offset         0x0c
    3.55  
    3.56 -/* read a byte from a process */
    3.57 -u_char pdb_linux_get_value(int pid, unsigned long cr3, unsigned long addr)
    3.58 +/*
    3.59 + * find the task structure of a process (pid)
    3.60 + * given the cr3 of the guest os.
    3.61 + */
    3.62 +unsigned long pdb_linux_pid_task_struct (unsigned long cr3, int pid)
    3.63  {
    3.64 -  u_char result = 0;
    3.65 -  unsigned long task_struct_p, mm_p, pgd, task_struct_pid;
    3.66 -  unsigned long l2tab, page;
    3.67 +  unsigned long task_struct_p = (unsigned long) NULL;
    3.68 +  unsigned long task_struct_pid;
    3.69  
    3.70    /* find the task_struct of the given process */
    3.71    pdb_get_values((u_char *) &task_struct_p, sizeof(task_struct_p),
    3.72 -		 cr3, pidhash_addr + pid_hashfn(pid) * 4);
    3.73 +		 cr3, pdb_pidhash_addr + pid_hashfn(pid) * 4);
    3.74  
    3.75    /* find the correct task struct */
    3.76    while (task_struct_p != (unsigned long)NULL)
    3.77 @@ -79,15 +86,32 @@ u_char pdb_linux_get_value(int pid, unsi
    3.78      {
    3.79        break;
    3.80      }
    3.81 -    
    3.82 +
    3.83      pdb_get_values((u_char *) &task_struct_p, sizeof(task_struct_p),
    3.84  		   cr3, task_struct_p + task_struct_pidhash_next_offset);
    3.85    }
    3.86 -  if (task_struct_p == (unsigned long)NULL)
    3.87 +  if (task_struct_p == (unsigned long) NULL)
    3.88    {
    3.89      /* oops */
    3.90 -    printk ("error: pdb couldn't find process 0x%x\n", pid);
    3.91 -    return 0;
    3.92 +    printk ("pdb error: couldn't find process 0x%x (0x%lx)\n", pid, cr3);
    3.93 +  }
    3.94 +
    3.95 +  return task_struct_p;
    3.96 +}
    3.97 +
    3.98 +/*
    3.99 + * find the ptbr of a process (pid)
   3.100 + * given the cr3 of the guest os.
   3.101 + */
   3.102 +unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid)
   3.103 +{
   3.104 +  unsigned long task_struct_p;
   3.105 +  unsigned long mm_p, pgd;
   3.106 +
   3.107 +  task_struct_p = pdb_linux_pid_task_struct(cr3, pid);
   3.108 +  if (task_struct_p == (unsigned long) NULL)
   3.109 +  {
   3.110 +    return (unsigned long) NULL;
   3.111    }
   3.112  
   3.113    /* get the mm_struct within the task_struct */
   3.114 @@ -97,6 +121,27 @@ u_char pdb_linux_get_value(int pid, unsi
   3.115    pdb_get_values((u_char *) &pgd, sizeof(pgd),
   3.116  		 cr3, mm_p + mm_struct_pgd_offset);
   3.117  
   3.118 +  return pgd;
   3.119 +}
   3.120 +
   3.121 +
   3.122 +
   3.123 +/* read a byte from a process 
   3.124 + *
   3.125 + * in: pid: process id
   3.126 + *     cr3: ptbr for the process' domain
   3.127 + *     addr: address to read
   3.128 + */
   3.129 +
   3.130 +u_char pdb_linux_get_value(int pid, unsigned long cr3, unsigned long addr)
   3.131 +{
   3.132 +  u_char result = 0;
   3.133 +  unsigned long pgd;
   3.134 +  unsigned long l2tab, page;
   3.135 +
   3.136 +  /* get the process' pgd */
   3.137 +  pgd = pdb_linux_pid_ptbr(cr3, pid);
   3.138 +
   3.139    /* get the l2 table entry */
   3.140    pdb_get_values((u_char *) &l2tab, sizeof(l2tab),
   3.141  		 cr3, pgd + (addr >> PGDIR_SHIFT) * 4);
   3.142 @@ -114,8 +159,22 @@ u_char pdb_linux_get_value(int pid, unsi
   3.143    return result;
   3.144  }
   3.145  
   3.146 -/* return 1 if is the virtual address is in the operating system's
   3.147 -   address space, else 0 */
   3.148 +void pdb_linux_get_values(char *buffer, int length, unsigned long address,
   3.149 +			  int pid, unsigned long cr3)
   3.150 +{
   3.151 +    int loop;
   3.152 +
   3.153 +    /* yes, this can be optimized... a lot */
   3.154 +    for (loop = 0; loop < length; loop++)
   3.155 +    {
   3.156 +        buffer[loop] = pdb_linux_get_value(pid, cr3, address + loop);
   3.157 +    }
   3.158 +}
   3.159 +
   3.160 +/*
   3.161 + * return 1 if is the virtual address is in the operating system's
   3.162 + * address space, else 0 
   3.163 + */
   3.164  int pdb_linux_address_space (unsigned long addr)
   3.165  {
   3.166      return (addr > PAGE_OFFSET);
   3.167 @@ -135,9 +194,9 @@ int pdb_linux_process_list (unsigned lon
   3.168  
   3.169    /* task_p = init_task->next_task  */
   3.170    pdb_get_values((u_char *) &task_p, sizeof(task_p),
   3.171 -		 cr3, init_task_union_addr + task_struct_next_task_offset);
   3.172 +		 cr3, pdb_init_task_union_addr + task_struct_next_task_offset);
   3.173    
   3.174 -  while (task_p != init_task_union_addr)
   3.175 +  while (task_p != pdb_init_task_union_addr)
   3.176    {
   3.177        pdb_get_values((u_char *) &pid, sizeof(pid),
   3.178  		     cr3, task_p + task_struct_pid_offset);
   3.179 @@ -153,35 +212,14 @@ int pdb_linux_process_list (unsigned lon
   3.180    return count;
   3.181  }
   3.182  
   3.183 -/* get additional details about a particular process:
   3.184 +/*
   3.185 + * get additional details about a particular process
   3.186   */
   3.187  void pdb_linux_process_details (unsigned long cr3, int pid, char *buffer)
   3.188  {
   3.189 -  unsigned long task_struct_p, task_struct_pid;
   3.190 -
   3.191 -  /* find the task_struct of the given process */
   3.192 -  pdb_get_values((u_char *) &task_struct_p, sizeof(task_struct_p),
   3.193 -		 cr3, pidhash_addr + pid_hashfn(pid) * 4);
   3.194 +  unsigned long task_struct_p;
   3.195  
   3.196 -  /* find the correct task struct */
   3.197 -  while (task_struct_p != (unsigned long)NULL)
   3.198 -  {
   3.199 -    pdb_get_values((u_char *) &task_struct_pid, sizeof(task_struct_pid),
   3.200 -		   cr3, task_struct_p + task_struct_pid_offset);
   3.201 -    if (task_struct_pid == pid)
   3.202 -    {
   3.203 -      break;
   3.204 -    }
   3.205 -
   3.206 -    pdb_get_values((u_char *) &task_struct_p, sizeof(task_struct_p),
   3.207 -		   cr3, task_struct_p + task_struct_pidhash_next_offset);
   3.208 -  }
   3.209 -  if (task_struct_p == (unsigned long)NULL)
   3.210 -  {
   3.211 -    /* oops */
   3.212 -    printk ("error: pdb couldn't find process 0x%x\n", pid);
   3.213 -    return;
   3.214 -  }
   3.215 +  task_struct_p = pdb_linux_pid_task_struct(cr3, pid);
   3.216  
   3.217    pdb_get_values((u_char *) buffer, task_struct_comm_length,
   3.218  		 cr3, task_struct_p + task_struct_comm_offset);
     4.1 --- a/xen/include/asm-i386/pdb.h	Mon Mar 29 14:45:20 2004 +0000
     4.2 +++ b/xen/include/asm-i386/pdb.h	Mon Mar 29 15:33:44 2004 +0000
     4.3 @@ -1,6 +1,7 @@
     4.4  
     4.5  /*
     4.6   * pervasive debugger
     4.7 + * www.cl.cam.ac.uk/netos/pdb
     4.8   *
     4.9   * alex ho
    4.10   * 2004
    4.11 @@ -18,6 +19,9 @@
    4.12  extern int pdb_initialized;
    4.13  extern int pdb_com_port;
    4.14  extern int pdb_high_bit;
    4.15 +extern int pdb_page_fault_possible;
    4.16 +extern int pdb_page_fault_scratch;
    4.17 +extern int pdb_page_fault;
    4.18  
    4.19  extern void initialize_pdb(void);
    4.20