ia64/xen-unstable

changeset 2195:5de156da549c

bitkeeper revision 1.1159.1.38 (411b1fd12fB3Leya1WmeLEasVngdig)

Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
author xenbk@gandalf.hpl.hp.com
date Thu Aug 12 07:44:17 2004 +0000 (2004-08-12)
parents 0c7d6ab95324 d67491ea6dcd
children 443ede9ad110
files linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c linux-2.6.7-xen-sparse/drivers/char/mem.c linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c tools/misc/xen-clone xen/arch/x86/memory.c xen/common/kernel.c xen/common/memory.c xen/include/asm-x86/mm.h xen/include/hypervisor-ifs/hypervisor-if.h
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c	Wed Aug 11 10:19:26 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c	Thu Aug 12 07:44:17 2004 +0000
     1.3 @@ -60,6 +60,34 @@ static int           sg_operation = -1;
     1.4  static unsigned long sg_next_sect;
     1.5  #define DISABLE_SCATTERGATHER() (sg_operation = -1)
     1.6  
     1.7 +
     1.8 +inline void translate_req_to_pfn( blkif_request_t * xreq, blkif_request_t * req)
     1.9 +{
    1.10 +    int i;
    1.11 +    
    1.12 +    *xreq=*req; 
    1.13 +    for ( i=0; i<req->nr_segments; i++ )
    1.14 +    {	
    1.15 +	xreq->frame_and_sects[i] = (req->frame_and_sects[i] & ~PAGE_MASK) |
    1.16 +	    (machine_to_phys_mapping[req->frame_and_sects[i]>>PAGE_SHIFT]<<PAGE_SHIFT);	
    1.17 +    }
    1.18 +    return xreq;
    1.19 +}
    1.20 +
    1.21 +inline void translate_req_to_mfn( blkif_request_t * xreq, blkif_request_t * req)
    1.22 +{
    1.23 +    int i;
    1.24 +
    1.25 +    *xreq=*req; 
    1.26 +    for ( i=0; i<req->nr_segments; i++ )
    1.27 +    {	
    1.28 +	xreq->frame_and_sects[i] = (req->frame_and_sects[i] & ~PAGE_MASK) |
    1.29 +	    (phys_to_machine_mapping[req->frame_and_sects[i]>>PAGE_SHIFT]<<PAGE_SHIFT);
    1.30 +    }
    1.31 +    return xreq;
    1.32 +}
    1.33 +
    1.34 +
    1.35  static inline void flush_requests(void)
    1.36  {
    1.37      DISABLE_SCATTERGATHER();
    1.38 @@ -364,8 +392,8 @@ static int blkif_queue_request(unsigned 
    1.39                  DISABLE_SCATTERGATHER();
    1.40  
    1.41              /* Update the copy of the request in the recovery ring. */
    1.42 -            blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod - 1)].req
    1.43 -                = *req;
    1.44 +	    translate_req_to_pfn(&blk_ring_rec->ring[
    1.45 +		MASK_BLKIF_IDX(blk_ring_rec->req_prod - 1)].req, req);
    1.46  
    1.47              return 0;
    1.48          }
    1.49 @@ -395,8 +423,9 @@ static int blkif_queue_request(unsigned 
    1.50      req->frame_and_sects[0] = buffer_ma | (fsect<<3) | lsect;
    1.51      req_prod++;
    1.52  
    1.53 -    /* Keep a private copy so we can reissue requests when recovering. */
    1.54 -    blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod)].req = *req;
    1.55 +    /* Keep a private copy so we can reissue requests when recovering. */    
    1.56 +    translate_req_to_pfn(&blk_ring_rec->ring[
    1.57 +	MASK_BLKIF_IDX(blk_ring_rec->req_prod)].req, req);
    1.58      blk_ring_rec->req_prod++;
    1.59  
    1.60      return 0;
    1.61 @@ -570,9 +599,11 @@ void blkif_control_send(blkif_request_t 
    1.62      }
    1.63  
    1.64      DISABLE_SCATTERGATHER();
    1.65 -    memcpy(&blk_ring->ring[MASK_BLKIF_IDX(req_prod)].req, req, sizeof(*req));
    1.66 -    memcpy(&blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod++)].req,
    1.67 -           req, sizeof(*req));
    1.68 +    blk_ring->ring[MASK_BLKIF_IDX(req_prod)].req = *req;
    1.69 +    
    1.70 +    translate_req_to_pfn(&blk_ring_rec->ring[
    1.71 +	MASK_BLKIF_IDX(blk_ring_rec->req_prod++)].req,req);
    1.72 +
    1.73      req_prod++;
    1.74      flush_requests();
    1.75  
    1.76 @@ -660,7 +691,7 @@ static void blkif_status_change(blkif_fe
    1.77  
    1.78          if ( recovery )
    1.79          {
    1.80 -            int i;
    1.81 +            int i,j;
    1.82  
    1.83  	    /* Shouldn't need the io_request_lock here - the device is
    1.84  	     * plugged and the recovery flag prevents the interrupt handler
    1.85 @@ -670,18 +701,24 @@ static void blkif_status_change(blkif_fe
    1.86              for ( i = 0;
    1.87  		  resp_cons_rec < blk_ring_rec->req_prod;
    1.88                    resp_cons_rec++, i++ )
    1.89 -            {
    1.90 -                blk_ring->ring[i].req
    1.91 -                    = blk_ring_rec->ring[MASK_BLKIF_IDX(resp_cons_rec)].req;
    1.92 +            {                
    1.93 +                translate_req_to_mfn(&blk_ring->ring[i].req,
    1.94 +				     &blk_ring_rec->ring[
    1.95 +					 MASK_BLKIF_IDX(resp_cons_rec)].req);
    1.96              }
    1.97  
    1.98 -            /* Reset the private block ring to match the new ring. */
    1.99 -            memcpy(blk_ring_rec, blk_ring, sizeof(*blk_ring));
   1.100 +            /* Reset the private block ring to match the new ring. */	    
   1.101 +	    for( j=0; j<i; j++ )
   1.102 +	    {		
   1.103 +		translate_req_to_pfn(
   1.104 +		    &blk_ring_rec->ring[j].req,
   1.105 +		    &blk_ring->ring[j].req);
   1.106 +	    }
   1.107 +
   1.108              resp_cons_rec = 0;
   1.109  
   1.110              /* blk_ring->req_prod will be set when we flush_requests().*/
   1.111              blk_ring_rec->req_prod = req_prod = i;
   1.112 -
   1.113              wmb();
   1.114  
   1.115              /* Switch off recovery mode, using a memory barrier to ensure that
   1.116 @@ -806,8 +843,7 @@ void blkdev_suspend(void)
   1.117  void blkdev_resume(void)
   1.118  {
   1.119      ctrl_msg_t                       cmsg;
   1.120 -    blkif_fe_driver_status_changed_t st;
   1.121 -    
   1.122 +    blkif_fe_driver_status_changed_t st;    
   1.123  
   1.124      /* Send a driver-UP notification to the domain controller. */
   1.125      cmsg.type      = CMSG_BLKIF_FE;
     2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Wed Aug 11 10:19:26 2004 +0000
     2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Thu Aug 12 07:44:17 2004 +0000
     2.3 @@ -1197,11 +1197,12 @@ static int shutting_down = -1;
     2.4  
     2.5  static void __do_suspend(void)
     2.6  {
     2.7 +    int i,j;
     2.8      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
     2.9      extern void blkdev_suspend(void);
    2.10      extern void blkdev_resume(void);
    2.11 -    extern void netif_resume(void);
    2.12 -    
    2.13 +    extern void netif_suspend(void);
    2.14 +    extern void netif_resume(void);    
    2.15      extern void time_suspend(void);
    2.16      extern void time_resume(void);
    2.17  
    2.18 @@ -1213,10 +1214,11 @@ static void __do_suspend(void)
    2.19  
    2.20      suspend_record->nr_pfns = max_pfn; /* final number of pfns */
    2.21  
    2.22 -    //netdev_suspend();
    2.23 -    //blkdev_suspend();
    2.24 +    __cli();
    2.25  
    2.26 -    __cli();
    2.27 +    netif_suspend();
    2.28 +
    2.29 +    blkdev_suspend();
    2.30  
    2.31      time_suspend();
    2.32  
    2.33 @@ -1241,16 +1243,27 @@ static void __do_suspend(void)
    2.34  
    2.35      memset(empty_zero_page, 0, PAGE_SIZE);
    2.36  
    2.37 +    for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    2.38 +    {	
    2.39 +        pfn_to_mfn_frame_list[j] = 
    2.40 +            virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
    2.41 +    }
    2.42 +    HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
    2.43 +	virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
    2.44 +
    2.45 +
    2.46      irq_resume();
    2.47  
    2.48      ctrl_if_resume();
    2.49  
    2.50      time_resume();
    2.51  
    2.52 +    blkdev_resume();
    2.53 +
    2.54 +    netif_resume();
    2.55 +
    2.56      __sti();
    2.57  
    2.58 -    blkdev_resume();
    2.59 -    netif_resume();
    2.60  
    2.61   out:
    2.62      if ( suspend_record != NULL )
     3.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Wed Aug 11 10:19:26 2004 +0000
     3.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Thu Aug 12 07:44:17 2004 +0000
     3.3 @@ -32,7 +32,7 @@
     3.4  #include <asm/pgtable.h>
     3.5  #include <asm/uaccess.h>
     3.6  
     3.7 -#if 1
     3.8 +#if 0
     3.9  #define ASSERT(_p) \
    3.10      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    3.11      __LINE__, __FILE__); *(int*)0=0; }
    3.12 @@ -44,14 +44,13 @@
    3.13  #define DPRINTK(_f, _a...) ((void)0)
    3.14  #endif
    3.15  
    3.16 -static char            *fixup_buf;
    3.17 +static unsigned char *fixup_buf;
    3.18  #define FIXUP_BUF_USER  PAGE_SIZE
    3.19  #define FIXUP_BUF_ORDER 1
    3.20  #define FIXUP_BUF_SIZE  (PAGE_SIZE<<FIXUP_BUF_ORDER)
    3.21  #define PATCH_LEN       5
    3.22  
    3.23  struct fixup_entry {
    3.24 -    unsigned long  patch_addr; /* XXX */
    3.25      unsigned char  patched_code[20];
    3.26      unsigned short patched_code_len;
    3.27      unsigned short fixup_idx;
    3.28 @@ -77,9 +76,9 @@ static inline int FIXUP_HASH(char *b)
    3.29  
    3.30  /* Helpful codes for the main decode routine. */
    3.31  #define CODE_MASK         (3<<6)
    3.32 -#define PUSH              (0<<6) /* PUSH onto stack */
    3.33 -#define POP               (1<<6) /* POP from stack */
    3.34 -#define JMP               (2<<6) /* 8-bit relative JMP */
    3.35 +#define PUSH              (1<<6) /* PUSH onto stack */
    3.36 +#define POP               (2<<6) /* POP from stack */
    3.37 +#define JMP               (3<<6) /* 8-bit relative JMP */
    3.38  
    3.39  /* Short forms for the table. */
    3.40  #define X  0 /* invalid for some random reason */
    3.41 @@ -117,7 +116,7 @@ static unsigned char insn_decode[256] = 
    3.42      O|M|1, O|M|4, O|M|1, O|M|1, O|M, O|M, O|M, O|M,
    3.43      O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M|POP, 
    3.44      /* 0x90 - 0x9F */
    3.45 -    O, O, O, O, O, O, O, O,
    3.46 +    O, O, O, O, S, O, O, O,
    3.47      O, O, X, O, O, O, O, O,
    3.48      /* 0xA0 - 0xAF */
    3.49      O|1, O|4, O|1, O|4, O, O, O, O,
    3.50 @@ -139,9 +138,9 @@ static unsigned char insn_decode[256] = 
    3.51      O, O, O, O, O, O, O|M, X
    3.52  };
    3.53  
    3.54 -static unsigned int get_insn_len(unsigned char *insn, 
    3.55 -                                 unsigned char *p_opcode,
    3.56 -                                 unsigned char *p_decode)
    3.57 +static unsigned int parse_insn(unsigned char *insn, 
    3.58 +                               unsigned char *p_opcode,
    3.59 +                               unsigned char *p_decode)
    3.60  {
    3.61      unsigned char b, d, *pb, mod, rm;
    3.62  
    3.63 @@ -159,10 +158,7 @@ static unsigned int get_insn_len(unsigne
    3.64  
    3.65      /* 2. Ensure we have a valid opcode byte. */
    3.66      if ( !(d & OPCODE_BYTE) )
    3.67 -    {
    3.68 -        printk(KERN_ALERT " *** %02x %02x %02x\n", pb[0], pb[1], pb[2]);
    3.69          return 0;
    3.70 -    }
    3.71  
    3.72      /* 3. Process Mod/RM if there is one. */
    3.73      if ( d & HAS_MODRM )
    3.74 @@ -188,10 +184,11 @@ static unsigned int get_insn_len(unsigne
    3.75          }
    3.76      }
    3.77  
    3.78 -    /* 4. All done. Result is all byte sstepped over, plus any immediates. */
    3.79 +    /* 4. All done. Result is all bytes stepped over, plus any immediates. */
    3.80      return ((pb - insn) + 1 + (d & INSN_SUFFIX_BYTES));
    3.81  }
    3.82  
    3.83 +/* Bitmap of faulting instructions that we can handle. */
    3.84  static unsigned char handleable_code[32] = {
    3.85      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    3.86      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    3.87 @@ -201,13 +198,25 @@ static unsigned char handleable_code[32]
    3.88      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    3.89  };
    3.90  
    3.91 +/* Bitmap of opcodes that use a register operand specified by Mod/RM. */
    3.92 +static unsigned char opcode_uses_reg[32] = {
    3.93 +    /* 0x00 - 0x3F */
    3.94 +    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
    3.95 +    /* 0x40 - 0x7F */
    3.96 +    0x00, 0x00, 0x00, 0x00, 0x0C, 0x0A, 0x00, 0x00,
    3.97 +    /* 0x80 - 0xBF */
    3.98 +    0xF0, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    3.99 +    /* 0xC0 - 0xFF */
   3.100 +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   3.101 +};
   3.102 +
   3.103  asmlinkage void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
   3.104  {
   3.105      static unsigned int fixup_idx = 0;
   3.106      unsigned int fi;
   3.107 -    int save_indirect_reg, hash;
   3.108 +    int save_indirect_reg, hash, i;
   3.109      unsigned int insn_len = (unsigned int)error_code, new_insn_len;
   3.110 -    unsigned char b[20], modrm, mod, reg, rm, patch[PATCH_LEN], opcode, decode;
   3.111 +    unsigned char b[20], modrm, mod, reg, rm, sib, patch[20], opcode, decode;
   3.112      unsigned long eip = regs->eip - insn_len;
   3.113      struct fixup_entry *fe;
   3.114      pte_t *pte;
   3.115 @@ -227,20 +236,14 @@ asmlinkage void do_fixup_4gb_segment(str
   3.116          DPRINTK("User executing out of kernel space?!");
   3.117          return;
   3.118      }
   3.119 -    
   3.120 -    if ( unlikely(((eip ^ (eip+PATCH_LEN)) & PAGE_MASK) != 0) )
   3.121 -    {
   3.122 -        DPRINTK("Patch instruction would straddle a page boundary.");
   3.123 -        return;
   3.124 -    }
   3.125  
   3.126      /*
   3.127 -     * Check that the page to be patched is part of a read-only VMA. This 
   3.128 +     * Check that the page to be patched is part of a private VMA. This 
   3.129       * means that our patch will never erroneously get flushed to disc.
   3.130       */
   3.131      if ( eip > (FIXUP_BUF_USER + FIXUP_BUF_SIZE) ) /* don't check fixup area */
   3.132      {
   3.133 -        /* [SMP] Need to the mmap_sem semaphore. */
   3.134 +        /* [SMP] Need to grab the mmap_sem semaphore. */
   3.135          struct vm_area_struct *vma = find_vma(current->mm, eip);
   3.136          if ( (vma == NULL) || (vma->vm_flags & VM_MAYSHARE) )
   3.137          {
   3.138 @@ -255,19 +258,16 @@ asmlinkage void do_fixup_4gb_segment(str
   3.139          return;
   3.140      }
   3.141  
   3.142 -    /* Already created a fixup for this address and code sequence? */
   3.143 +    /* Already created a fixup for this code sequence? */
   3.144      hash = FIXUP_HASH(b);
   3.145 -    for ( fe = fixup_hash[hash];
   3.146 -          fe != NULL; fe = fe->next )
   3.147 +    for ( fe = fixup_hash[hash]; fe != NULL; fe = fe->next )
   3.148      {
   3.149 -        if ( eip != fe->patch_addr )
   3.150 -            continue; /* XXX */
   3.151          if ( memcmp(fe->patched_code, b, fe->patched_code_len) == 0 )
   3.152              goto do_the_patch;
   3.153      }
   3.154  
   3.155      /* Guaranteed enough room to patch? */
   3.156 -    if ( unlikely((fi = fixup_idx) > (FIXUP_BUF_SIZE-32)) )
   3.157 +    if ( unlikely((fi = fixup_idx) > (FIXUP_BUF_SIZE-64)) )
   3.158      {
   3.159          static int printed = 0;
   3.160          if ( !printed )
   3.161 @@ -324,6 +324,9 @@ asmlinkage void do_fixup_4gb_segment(str
   3.162      if ( save_indirect_reg )
   3.163          fixup_buf[fi++] = 0x50 + rm;
   3.164  
   3.165 +    /* pushf */
   3.166 +    fixup_buf[fi++] = 0x9c;
   3.167 +
   3.168      /* add %gs:0,<r32> */
   3.169      fixup_buf[fi++] = 0x65;
   3.170      fixup_buf[fi++] = 0x03;
   3.171 @@ -331,6 +334,9 @@ asmlinkage void do_fixup_4gb_segment(str
   3.172      *(unsigned long *)&fixup_buf[fi] = 0;
   3.173      fi += 4;
   3.174  
   3.175 +    /* popf */
   3.176 +    fixup_buf[fi++] = 0x9d;
   3.177 +
   3.178      /* Relocate the faulting instruction, minus the GS override. */
   3.179      memcpy(&fixup_buf[fi], &b[1], error_code - 1);
   3.180      fi += error_code - 1;
   3.181 @@ -350,7 +356,7 @@ asmlinkage void do_fixup_4gb_segment(str
   3.182  
   3.183          /* Bail if can't decode the following instruction. */
   3.184          if ( unlikely((new_insn_len =
   3.185 -                       get_insn_len(&b[insn_len], &opcode, &decode)) == 0) )
   3.186 +                       parse_insn(&b[insn_len], &opcode, &decode)) == 0) )
   3.187          {
   3.188              DPRINTK("Could not decode following instruction.");
   3.189              return;
   3.190 @@ -358,63 +364,183 @@ asmlinkage void do_fixup_4gb_segment(str
   3.191  
   3.192          if ( (decode & CODE_MASK) == JMP )
   3.193          {
   3.194 -            return;
   3.195 +            long off;
   3.196  
   3.197              memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 1);
   3.198              fi += new_insn_len - 1;
   3.199              
   3.200              /* Patch the 8-bit relative offset. */
   3.201              fixup_buf[fi++] = 1;
   3.202 -
   3.203 +            
   3.204              insn_len += new_insn_len;
   3.205              ASSERT(insn_len >= PATCH_LEN);
   3.206          
   3.207              /* ret */
   3.208              fixup_buf[fi++] = 0xc3;
   3.209  
   3.210 -            /* jmp <rel32> */
   3.211 -            fixup_buf[fi++] = 0xe9;
   3.212 -            fi += 4;
   3.213 -            *(unsigned long *)&fixup_buf[fi-4] = 
   3.214 -                (eip + insn_len + (long)(char)b[insn_len-1]) - 
   3.215 -                (FIXUP_BUF_USER + fi);
   3.216 -            
   3.217 +            /* pushf */
   3.218 +            fixup_buf[fi++] = 0x9c;
   3.219 +
   3.220 +            off = (insn_len - PATCH_LEN) + (long)(char)b[insn_len-1];
   3.221 +            if ( unlikely(off > 127) )
   3.222 +            {
   3.223 +                /* add <imm32>,4(%esp) */
   3.224 +                fixup_buf[fi++] = 0x81;
   3.225 +                fixup_buf[fi++] = 0x44;
   3.226 +                fixup_buf[fi++] = 0x24;
   3.227 +                fixup_buf[fi++] = 0x04;
   3.228 +                fi += 4;
   3.229 +                *(long *)&fixup_buf[fi-4] = off;
   3.230 +            }
   3.231 +            else
   3.232 +            {
   3.233 +                /* add <imm8>,4(%esp) [sign-extended] */
   3.234 +                fixup_buf[fi++] = 0x83;
   3.235 +                fixup_buf[fi++] = 0x44;
   3.236 +                fixup_buf[fi++] = 0x24;
   3.237 +                fixup_buf[fi++] = 0x04;
   3.238 +                fixup_buf[fi++] = (char)(off & 0xff);
   3.239 +            }
   3.240 +
   3.241 +            /* popf */
   3.242 +            fixup_buf[fi++] = 0x9d;
   3.243 +
   3.244 +            /* ret */
   3.245 +            fixup_buf[fi++] = 0xc3;
   3.246 +
   3.247              break;
   3.248          }
   3.249 -        else if ( opcode == 0xe9 )
   3.250 +        else if ( opcode == 0xe9 ) /* jmp <rel32> */
   3.251          {
   3.252 -            return;
   3.253 -
   3.254 -            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 4);
   3.255 -            fi += new_insn_len - 4;
   3.256 -            
   3.257              insn_len += new_insn_len;
   3.258              ASSERT(insn_len >= PATCH_LEN);
   3.259          
   3.260 -            /* Patch the 32-bit relative offset. */
   3.261 +            /* pushf */
   3.262 +            fixup_buf[fi++] = 0x9c;
   3.263 +
   3.264 +            /* add <imm32>,4(%esp) */
   3.265 +            fixup_buf[fi++] = 0x81;
   3.266 +            fixup_buf[fi++] = 0x44;
   3.267 +            fixup_buf[fi++] = 0x24;
   3.268 +            fixup_buf[fi++] = 0x04;
   3.269              fi += 4;
   3.270 -            *(unsigned long *)&fixup_buf[fi-4] = 
   3.271 -                (eip + insn_len + *(long *)&b[insn_len-4]) - 
   3.272 -                (FIXUP_BUF_USER + fi);
   3.273 +            *(long *)&fixup_buf[fi-4] = 
   3.274 +                (insn_len - PATCH_LEN) + *(long *)&b[insn_len-4];
   3.275 +
   3.276 +            /* popf */
   3.277 +            fixup_buf[fi++] = 0x9d;
   3.278  
   3.279              /* ret */
   3.280              fixup_buf[fi++] = 0xc3;
   3.281  
   3.282              break;
   3.283          }
   3.284 -        else if ( (decode & CODE_MASK) == PUSH )
   3.285 +        else if ( opcode == 0xc3 ) /* ret */
   3.286          {
   3.287 -            return;
   3.288 -        }
   3.289 -        else if ( (decode & CODE_MASK) == POP )
   3.290 -        {
   3.291 -            return;
   3.292 +            /* pop -4(%esp) [doesn't affect EFLAGS] */
   3.293 +            fixup_buf[fi++] = 0x8f;
   3.294 +            fixup_buf[fi++] = 0x44;
   3.295 +            fixup_buf[fi++] = 0x24;
   3.296 +            fixup_buf[fi++] = 0xfc;
   3.297          }
   3.298          else
   3.299          {
   3.300 -            /* Relocate the instruction verbatim. */
   3.301 -            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len);
   3.302 -            fi += new_insn_len;
   3.303 +            int stack_addon = 4;
   3.304 +
   3.305 +            if ( (decode & CODE_MASK) == PUSH )
   3.306 +            {
   3.307 +                stack_addon = 8;
   3.308 +                /* push (%esp) */
   3.309 +                fixup_buf[fi++] = 0xff;
   3.310 +                fixup_buf[fi++] = 0x34;
   3.311 +                fixup_buf[fi++] = 0x24;
   3.312 +            }
   3.313 +            else if ( (decode & CODE_MASK) == POP )
   3.314 +            {
   3.315 +                stack_addon = 8;
   3.316 +                /* push 4(%esp) */
   3.317 +                fixup_buf[fi++] = 0xff;
   3.318 +                fixup_buf[fi++] = 0x74;
   3.319 +                fixup_buf[fi++] = 0x24;
   3.320 +                fixup_buf[fi++] = 0x04;
   3.321 +            }
   3.322 +
   3.323 +            /* Check for EA calculations involving ESP, and skip return addr */
   3.324 +            if ( decode & HAS_MODRM )
   3.325 +            {
   3.326 +                do { new_insn_len--; }
   3.327 +                while ( (fixup_buf[fi++] = b[insn_len++]) != opcode );
   3.328 +
   3.329 +                modrm = fixup_buf[fi++] = b[insn_len++];
   3.330 +                new_insn_len--;
   3.331 +                mod   = (modrm >> 6) & 3;
   3.332 +                reg   = (modrm >> 3) & 7;
   3.333 +                rm    = (modrm >> 0) & 7;
   3.334 +
   3.335 +                if ( (reg == 4) &&
   3.336 +                     test_bit(opcode, (unsigned long *)opcode_uses_reg) )
   3.337 +                {
   3.338 +                    DPRINTK("Data movement to ESP unsupported.");
   3.339 +                    return;
   3.340 +                }
   3.341 +
   3.342 +                if ( rm == 4 )
   3.343 +                {
   3.344 +                    if ( mod == 3 )
   3.345 +                    {
   3.346 +                        DPRINTK("Data movement to ESP is unsupported.");
   3.347 +                        return;
   3.348 +                    }
   3.349 +
   3.350 +                    sib = fixup_buf[fi++] = b[insn_len++];
   3.351 +                    new_insn_len--;
   3.352 +                    if ( (sib & 7) == 4 )
   3.353 +                    {
   3.354 +                        switch ( mod )
   3.355 +                        {
   3.356 +                        case 0:
   3.357 +                            mod = 1;
   3.358 +                            fixup_buf[fi-2] |= 0x40;
   3.359 +                            fixup_buf[fi++] = stack_addon;
   3.360 +                            break;
   3.361 +                        case 1:
   3.362 +                            fixup_buf[fi++] = b[insn_len++] + stack_addon;
   3.363 +                            new_insn_len--;
   3.364 +                            break;
   3.365 +                        case 2:
   3.366 +                            *(long *)&fixup_buf[fi] = 
   3.367 +                                *(long *)&b[insn_len] + stack_addon;
   3.368 +                            fi += 4;
   3.369 +                            insn_len += 4;
   3.370 +                            new_insn_len -= 4;
   3.371 +                            break;
   3.372 +                        }
   3.373 +                    }
   3.374 +                }
   3.375 +            }
   3.376 +
   3.377 +            /* Relocate the (remainder of) the instruction. */
   3.378 +            if ( new_insn_len != 0 )
   3.379 +            {
   3.380 +                memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len);
   3.381 +                fi += new_insn_len;
   3.382 +            }
   3.383 +
   3.384 +            if ( (decode & CODE_MASK) == PUSH )
   3.385 +            {
   3.386 +                /* pop 4(%esp) */
   3.387 +                fixup_buf[fi++] = 0x8f;
   3.388 +                fixup_buf[fi++] = 0x44;
   3.389 +                fixup_buf[fi++] = 0x24;
   3.390 +                fixup_buf[fi++] = 0x04;
   3.391 +            }
   3.392 +            else if ( (decode & CODE_MASK) == POP )
   3.393 +            {
   3.394 +                /* pop (%esp) */
   3.395 +                fixup_buf[fi++] = 0x8f;
   3.396 +                fixup_buf[fi++] = 0x04;
   3.397 +                fixup_buf[fi++] = 0x24;
   3.398 +            }
   3.399          }
   3.400  
   3.401          if ( (insn_len += new_insn_len) > 20 )
   3.402 @@ -424,7 +550,7 @@ asmlinkage void do_fixup_4gb_segment(str
   3.403          }
   3.404  
   3.405          /* Can't have a RET in the middle of a patch sequence. */
   3.406 -        if ( (opcode == 0xc4) && (insn_len < PATCH_LEN) )
   3.407 +        if ( (opcode == 0xc3) && (insn_len < PATCH_LEN) )
   3.408          {
   3.409              DPRINTK("RET in middle of patch seq!\n");
   3.410              return;
   3.411 @@ -438,12 +564,11 @@ asmlinkage void do_fixup_4gb_segment(str
   3.412          DPRINTK("Not enough memory to allocate a fixup_entry.");
   3.413          return;
   3.414      }
   3.415 -    fe->patch_addr = eip; /* XXX */
   3.416      fe->patched_code_len = insn_len;
   3.417      memcpy(fe->patched_code, b, insn_len);
   3.418      fe->fixup_idx = fixup_idx;
   3.419      fe->return_idx = 
   3.420 -        fixup_idx + error_code + 6 + 4/**/ + (save_indirect_reg ? 2 : 0);
   3.421 +        fixup_idx + error_code + (save_indirect_reg ? 14 : 12);
   3.422      fe->next = fixup_hash[hash];
   3.423      fixup_hash[hash] = fe;
   3.424  
   3.425 @@ -451,39 +576,22 @@ asmlinkage void do_fixup_4gb_segment(str
   3.426      fixup_idx = fi;
   3.427  
   3.428   do_the_patch:
   3.429 -#if 1
   3.430 -    /* Create the patching instruction in a temporary buffer. */
   3.431 +
   3.432 +    if ( unlikely(((eip ^ (eip + fe->patched_code_len)) & PAGE_MASK) != 0) )
   3.433 +    {
   3.434 +        DPRINTK("Patch instruction would straddle a page boundary.");
   3.435 +        return;
   3.436 +    }
   3.437 +
   3.438 +    /* Create the patching instructions in a temporary buffer. */
   3.439      patch[0] = 0x67;
   3.440      patch[1] = 0xff;
   3.441      patch[2] = 0x16; /* call <r/m16> */
   3.442      *(u16 *)&patch[3] = FIXUP_BUF_USER + fe->fixup_idx;
   3.443 -#else
   3.444 -    patch[0] = 0x9a;
   3.445 -    *(u32 *)&patch[1] = FIXUP_BUF_USER + fe->fixup_idx + 4;
   3.446 -    *(u16 *)&patch[5] = __USER_CS;
   3.447 -#endif
   3.448 +    for ( i = 5; i < fe->patched_code_len; i++ )
   3.449 +        patch[i] = 0x90; /* nop */
   3.450  
   3.451 -#if 1
   3.452 -    {
   3.453 -        int iii;
   3.454 -        printk(KERN_ALERT "EIP == %08lx; USER_EIP == %08lx\n",
   3.455 -               eip, FIXUP_BUF_USER + fe->fixup_idx);
   3.456 -        printk(KERN_ALERT " .byte ");
   3.457 -        for ( iii = 0; iii < insn_len; iii++ )
   3.458 -            printk("0x%02x,", b[iii]);
   3.459 -        printk("!!\n");
   3.460 -        printk(KERN_ALERT " .byte ");
   3.461 -        for ( iii = fe->fixup_idx; iii < fi; iii++ )
   3.462 -            printk("0x%02x,", (unsigned char)fixup_buf[iii]);
   3.463 -        printk("!!\n");
   3.464 -        printk(KERN_ALERT " .byte ");
   3.465 -        for ( iii = 0; iii < 7; iii++ )
   3.466 -            printk("0x%02x,", (unsigned char)patch[iii]);
   3.467 -        printk("!!\n");
   3.468 -    }
   3.469 -#endif
   3.470 -
   3.471 -    if ( put_user(eip + insn_len, (unsigned long *)regs->esp - 1) != 0 )
   3.472 +    if ( put_user(eip + PATCH_LEN, (unsigned long *)regs->esp - 1) != 0 )
   3.473      {
   3.474          DPRINTK("Failed to place return address on user stack.");
   3.475          return;
   3.476 @@ -498,7 +606,7 @@ asmlinkage void do_fixup_4gb_segment(str
   3.477      pmd = pmd_offset(pgd, eip);
   3.478      pte = pte_offset_kernel(pmd, eip);
   3.479      veip = kmap(pte_page(*pte));
   3.480 -    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, PATCH_LEN);
   3.481 +    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, fe->patched_code_len);
   3.482      kunmap(pte_page(*pte));
   3.483  
   3.484      return;
   3.485 @@ -512,7 +620,7 @@ static int __init fixup_init(void)
   3.486      struct page *_pages[1<<FIXUP_BUF_ORDER], **pages=_pages;
   3.487      int i;
   3.488  
   3.489 -    /*if ( nosegfixup )*/
   3.490 +    if ( nosegfixup )
   3.491          return 0;
   3.492  
   3.493      HYPERVISOR_vm_assist(VMASST_CMD_enable,
     4.1 --- a/linux-2.6.7-xen-sparse/drivers/char/mem.c	Wed Aug 11 10:19:26 2004 +0000
     4.2 +++ b/linux-2.6.7-xen-sparse/drivers/char/mem.c	Thu Aug 12 07:44:17 2004 +0000
     4.3 @@ -252,7 +252,7 @@ static int mmap_mem(struct file * file, 
     4.4  	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
     4.5  	if (direct_remap_area_pages(vma->vm_mm, vma->vm_start, offset, 
     4.6  				vma->vm_end-vma->vm_start, vma->vm_page_prot,
     4.7 -				(domid_t)file->private_data))
     4.8 +				(domid_t)(unsigned long)file->private_data))
     4.9  		return -EAGAIN;
    4.10  	return 0;
    4.11  }
     5.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c	Wed Aug 11 10:19:26 2004 +0000
     5.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkfront/blkfront.c	Thu Aug 12 07:44:17 2004 +0000
     5.3 @@ -50,6 +50,32 @@ static int recovery = 0;           /* "R
     5.4  static request_queue_t *pending_queues[MAX_PENDING];
     5.5  static int nr_pending;
     5.6  
     5.7 +inline void translate_req_to_pfn( blkif_request_t * xreq, blkif_request_t * req)
     5.8 +{
     5.9 +    int i;
    5.10 +    
    5.11 +    *xreq=*req; 
    5.12 +    for ( i=0; i<req->nr_segments; i++ )
    5.13 +    {	
    5.14 +	xreq->frame_and_sects[i] = (req->frame_and_sects[i] & ~PAGE_MASK) |
    5.15 +	    (machine_to_phys_mapping[req->frame_and_sects[i]>>PAGE_SHIFT]<<PAGE_SHIFT);	
    5.16 +    }
    5.17 +    return xreq;
    5.18 +}
    5.19 +
    5.20 +inline void translate_req_to_mfn( blkif_request_t * xreq, blkif_request_t * req)
    5.21 +{
    5.22 +    int i;
    5.23 +
    5.24 +    *xreq=*req; 
    5.25 +    for ( i=0; i<req->nr_segments; i++ )
    5.26 +    {	
    5.27 +	xreq->frame_and_sects[i] = (req->frame_and_sects[i] & ~PAGE_MASK) |
    5.28 +	    (phys_to_machine_mapping[req->frame_and_sects[i]>>PAGE_SHIFT]<<PAGE_SHIFT);
    5.29 +    }
    5.30 +    return xreq;
    5.31 +}
    5.32 +
    5.33  static inline void flush_requests(void)
    5.34  {
    5.35  
    5.36 @@ -243,8 +269,10 @@ static int blkif_queue_request(struct re
    5.37  	req_prod++;
    5.38  
    5.39          /* Keep a private copy so we can reissue requests when recovering. */
    5.40 -        blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod)].req =
    5.41 -                *ring_req;
    5.42 +        translate_req_to_pfn(
    5.43 +	    &blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod)].req,
    5.44 +            ring_req);
    5.45 +
    5.46          blk_ring_rec->req_prod++;
    5.47  
    5.48          return 0;
    5.49 @@ -407,9 +435,10 @@ void blkif_control_send(blkif_request_t 
    5.50          goto retry;
    5.51      }
    5.52  
    5.53 -    memcpy(&blk_ring->ring[MASK_BLKIF_IDX(req_prod)].req, req, sizeof(*req));
    5.54 -    memcpy(&blk_ring_rec->ring[MASK_BLKIF_IDX(blk_ring_rec->req_prod++)].req,
    5.55 -           req, sizeof(*req));
    5.56 +    blk_ring->ring[MASK_BLKIF_IDX(req_prod)].req = *req;    
    5.57 +    translate_req_to_pfn(&blk_ring_rec->ring[
    5.58 +	MASK_BLKIF_IDX(blk_ring_rec->req_prod++)].req,req);
    5.59 +
    5.60      req_prod++;
    5.61      flush_requests();
    5.62  
    5.63 @@ -497,9 +526,9 @@ static void blkif_status_change(blkif_fe
    5.64  
    5.65          if ( recovery )
    5.66          {
    5.67 -            int i;
    5.68 +            int i,j;
    5.69  
    5.70 -	    /* Shouldn't need the blkif_io_lock here - the device is
    5.71 +	    /* Shouldn't need the io_request_lock here - the device is
    5.72  	     * plugged and the recovery flag prevents the interrupt handler
    5.73  	     * changing anything. */
    5.74  
    5.75 @@ -507,18 +536,24 @@ static void blkif_status_change(blkif_fe
    5.76              for ( i = 0;
    5.77  		  resp_cons_rec < blk_ring_rec->req_prod;
    5.78                    resp_cons_rec++, i++ )
    5.79 -            {
    5.80 -                blk_ring->ring[i].req
    5.81 -                    = blk_ring_rec->ring[MASK_BLKIF_IDX(resp_cons_rec)].req;
    5.82 +            {                
    5.83 +                translate_req_to_mfn(&blk_ring->ring[i].req,
    5.84 +				     &blk_ring_rec->ring[
    5.85 +					 MASK_BLKIF_IDX(resp_cons_rec)].req);
    5.86              }
    5.87  
    5.88 -            /* Reset the private block ring to match the new ring. */
    5.89 -            memcpy(blk_ring_rec, blk_ring, sizeof(*blk_ring));
    5.90 +            /* Reset the private block ring to match the new ring. */	    
    5.91 +	    for( j=0; j<i; j++ )
    5.92 +	    {		
    5.93 +		translate_req_to_pfn(
    5.94 +		    &blk_ring_rec->ring[j].req,
    5.95 +		    &blk_ring->ring[j].req);
    5.96 +	    }
    5.97 +
    5.98              resp_cons_rec = 0;
    5.99  
   5.100              /* blk_ring->req_prod will be set when we flush_requests().*/
   5.101              blk_ring_rec->req_prod = req_prod = i;
   5.102 -
   5.103              wmb();
   5.104  
   5.105              /* Switch off recovery mode, using a memory barrier to ensure that
   5.106 @@ -677,4 +712,14 @@ void blkdev_suspend(void)
   5.107  
   5.108  void blkdev_resume(void)
   5.109  {
   5.110 +    ctrl_msg_t                       cmsg;
   5.111 +    blkif_fe_driver_status_changed_t st;    
   5.112 +
   5.113 +    /* Send a driver-UP notification to the domain controller. */
   5.114 +    cmsg.type      = CMSG_BLKIF_FE;
   5.115 +    cmsg.subtype   = CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED;
   5.116 +    cmsg.length    = sizeof(blkif_fe_driver_status_changed_t);
   5.117 +    st.status      = BLKIF_DRIVER_STATUS_UP;
   5.118 +    memcpy(cmsg.msg, &st, sizeof(st));
   5.119 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   5.120  }
     6.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c	Wed Aug 11 10:19:26 2004 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c	Thu Aug 12 07:44:17 2004 +0000
     6.3 @@ -241,6 +241,8 @@ void netif_connect(netif_be_connect_t *c
     6.4      netif->status         = CONNECTED;
     6.5      netif_get(netif);
     6.6  
     6.7 +    netif->tx->resp_prod = netif->rx->resp_prod = 0;
     6.8 +
     6.9      rtnl_lock();
    6.10      (void)dev_open(netif->dev);
    6.11      rtnl_unlock();
     7.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c	Wed Aug 11 10:19:26 2004 +0000
     7.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c	Thu Aug 12 07:44:17 2004 +0000
     7.3 @@ -546,7 +546,7 @@ static void network_connect(struct net_d
     7.4  
     7.5      /* Step 1: Reinitialise variables. */
     7.6      np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
     7.7 -    np->rx->event = 1;
     7.8 +    np->rx->event = np->tx->event = 1;
     7.9  
    7.10      /* Step 2: Rebuild the RX and TX ring contents.
    7.11       * NB. We could just free the queued TX packets now but we hope
    7.12 @@ -776,12 +776,13 @@ static int create_netdev(int handle, str
    7.13   * Initialize the network control interface. Set the number of network devices
    7.14   * and create them.
    7.15   */
    7.16 +
    7.17  static void netif_driver_status_change(
    7.18      netif_fe_driver_status_changed_t *status)
    7.19  {
    7.20      int err = 0;
    7.21      int i;
    7.22 -    
    7.23 +
    7.24      netctrl.interface_n = status->nr_interfaces;
    7.25      netctrl.connected_n = 0;
    7.26  
    7.27 @@ -874,11 +875,75 @@ static int __init netif_init(void)
    7.28      return err;
    7.29  }
    7.30  
    7.31 +void netif_suspend(void)
    7.32 +{
    7.33 +#if 1 /* XXX THIS IS TEMPORARY */
    7.34 +    struct net_device *dev = NULL;
    7.35 +    struct net_private *np = NULL;
    7.36 +    int i;
    7.37 +
    7.38 +/* avoid having tx/rx stuff happen until we're ready */
    7.39 +
    7.40 +    for(i=0;i<netctrl.interface_n;i++)
    7.41 +    {
    7.42 +	char name[32];
    7.43 +
    7.44 +	sprintf(name,"eth%d",i);
    7.45 +	dev = __dev_get_by_name(name);
    7.46 +
    7.47 +	if ( dev && (dev->flags & IFF_UP) )
    7.48 +	{
    7.49 +	    np  = dev->priv;
    7.50 +
    7.51 +	    free_irq(np->irq, dev);
    7.52 +            unbind_evtchn_from_irq(np->evtchn);
    7.53 +	}    
    7.54 +    }
    7.55 +#endif
    7.56 +}
    7.57 +
    7.58  void netif_resume(void)
    7.59  {
    7.60      ctrl_msg_t                       cmsg;
    7.61 -    netif_fe_driver_status_changed_t st;
    7.62 +    netif_fe_interface_connect_t     up;
    7.63 +//    netif_fe_driver_status_changed_t   st;
    7.64 +    struct net_device *dev = NULL;
    7.65 +    struct net_private *np = NULL;
    7.66 +    int i;
    7.67 +
    7.68 +#if 1
    7.69 +    /* XXX THIS IS TEMPORARY */
    7.70 +
    7.71 +    for(i=0;i<netctrl.interface_n;i++)    
    7.72 +    {
    7.73 +	char name[32];
    7.74 +
    7.75 +	sprintf(name,"eth%d",i);
    7.76 +	dev = __dev_get_by_name(name);
    7.77 +
    7.78 +	if ( dev ) // connect regardless of whether IFF_UP flag set
    7.79 +	{
    7.80 +	    np  = dev->priv;
    7.81  
    7.82 +	    // stop bad things from happening until we're back up
    7.83 +	    np->backend_state = BEST_DISCONNECTED;
    7.84 +
    7.85 +	    cmsg.type      = CMSG_NETIF_FE;
    7.86 +	    cmsg.subtype   = CMSG_NETIF_FE_INTERFACE_CONNECT;
    7.87 +	    cmsg.length    = sizeof(netif_fe_interface_connect_t);
    7.88 +	    up.handle      = np->handle;
    7.89 +	    up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
    7.90 +	    up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
    7.91 +	    memcpy(cmsg.msg, &up, sizeof(up));
    7.92 +
    7.93 +	    /* Tell the controller to bring up the interface. */
    7.94 +	    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    7.95 +	}
    7.96 +    }
    7.97 +#endif	    
    7.98 +
    7.99 +
   7.100 +#if 0
   7.101      /* Send a driver-UP notification to the domain controller. */
   7.102      cmsg.type      = CMSG_NETIF_FE;
   7.103      cmsg.subtype   = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED;
   7.104 @@ -887,6 +952,8 @@ void netif_resume(void)
   7.105      st.nr_interfaces = 0;
   7.106      memcpy(cmsg.msg, &st, sizeof(st));
   7.107      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   7.108 +#endif
   7.109 +
   7.110  
   7.111  }
   7.112  
     8.1 --- a/tools/misc/xen-clone	Wed Aug 11 10:19:26 2004 +0000
     8.2 +++ b/tools/misc/xen-clone	Thu Aug 12 07:44:17 2004 +0000
     8.3 @@ -17,7 +17,7 @@ UCCL)
     8.4  *)
     8.5  	BK_REP=${1:-bk://xen.bkbits.net/xeno-1.0.bk}
     8.6  	# BK_REP=${1:-ssh://xen@xen.bkbits.net/xeno-1.0.bk}
     8.7 -	LINUX_DIR=${3:-..}
     8.8 +	LINUX_DIR=${3:-.:..}
     8.9  ;;
    8.10  esac
    8.11  
    8.12 @@ -65,19 +65,14 @@ if [ -d ${DEST_BK_REP}/linux-2.4.*-xen-s
    8.13  then
    8.14   # this is a new style Xen repository so building is dead easy
    8.15  
    8.16 - LINUX_VER=`( /bin/ls -ld ${DEST_BK_REP}/*linux-2.4.*-xen-sparse ) 2>/dev/null | sed -e 's!^.*linux-\(.\+\)-xen-sparse!\1!'`
    8.17 -
    8.18 - if [ -e ${LINUX_DIR}/linux-${LINUX_VER}.tar.gz ] 
    8.19 - then
    8.20 -  export LINUX_SRC=${LINUX_DIR}/linux-${LINUX_VER}.tar.gz
    8.21 - fi
    8.22 + export LINUX_SRC_PATH=${LINUX_DIR}
    8.23  
    8.24   cd ${DEST_BK_REP} 
    8.25   ln -sf ../install install
    8.26   make -j4 world
    8.27   make -j4 linux26
    8.28   cd ../install/boot
    8.29 - [ -r vmlinuz-${LINUX_VER}-xen0 ] && ln -s vmlinuz-${LINUX_VER}-xen0 xenolinux.gz
    8.30 + [ -r vmlinuz-2.4.*-xen0 ] && ln -s vmlinuz-2.4.*-xen0 xenolinux.gz
    8.31    
    8.32  else
    8.33   # old style repository without 'make world'
     9.1 --- a/xen/arch/x86/memory.c	Wed Aug 11 10:19:26 2004 +0000
     9.2 +++ b/xen/arch/x86/memory.c	Thu Aug 12 07:44:17 2004 +0000
     9.3 @@ -136,9 +136,14 @@ static struct {
     9.4  #define GPS (percpu_info[smp_processor_id()].gps ? : current)
     9.5  
     9.6  
     9.7 -void init_percpu_info(void)
     9.8 +void ptwr_init_backpointers(void);
     9.9 +
    9.10 +void arch_init_memory(void)
    9.11  {
    9.12      memset(percpu_info, 0, sizeof(percpu_info));
    9.13 +
    9.14 +    vm_assist_info[VMASST_TYPE_writeable_pagetables].enable =
    9.15 +        ptwr_init_backpointers;
    9.16  }
    9.17  
    9.18  static void __invalidate_shadow_ldt(struct domain *d)
    9.19 @@ -255,6 +260,17 @@ static int get_page_and_type_from_pagenr
    9.20  }
    9.21  
    9.22  
    9.23 +static inline void set_l1_page_va(unsigned long pfn,
    9.24 +                                  unsigned long va_idx)
    9.25 +{
    9.26 +    struct pfn_info *page;
    9.27 +    
    9.28 +    page = &frame_table[pfn];
    9.29 +    page->u.inuse.type_info &= ~PGT_va_mask;
    9.30 +    page->u.inuse.type_info |= va_idx << PGT_va_shift;
    9.31 +}
    9.32 +
    9.33 +
    9.34  /*
    9.35   * We allow an L2 tables to map each other (a.k.a. linear page tables). It
    9.36   * needs some special care with reference counst and access permissions:
    9.37 @@ -413,9 +429,11 @@ static int alloc_l2_table(struct pfn_inf
    9.38     
    9.39      pl2e = map_domain_mem(page_nr << PAGE_SHIFT);
    9.40  
    9.41 -    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
    9.42 +    for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) {
    9.43          if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
    9.44              goto fail;
    9.45 +        set_l1_page_va(l2_pgentry_val(pl2e[i]) >> PAGE_SHIFT, i);
    9.46 +    }
    9.47      
    9.48  #if defined(__i386__)
    9.49      /* Now we add our private high mappings. */
    9.50 @@ -509,17 +527,6 @@ static inline int update_l2e(l2_pgentry_
    9.51  }
    9.52  
    9.53  
    9.54 -static inline void set_l1_page_va(unsigned long pfn,
    9.55 -                                  unsigned long va_idx)
    9.56 -{
    9.57 -    struct pfn_info *page;
    9.58 -    
    9.59 -    page = &frame_table[pfn];
    9.60 -    page->u.inuse.type_info &= ~PGT_va_mask;
    9.61 -    page->u.inuse.type_info |= va_idx << PGT_va_shift;
    9.62 -}
    9.63 -
    9.64 -
    9.65  /* Update the L2 entry at pl2e to new value nl2e. pl2e is within frame pfn. */
    9.66  static int mod_l2_entry(l2_pgentry_t *pl2e, 
    9.67                          l2_pgentry_t nl2e, 
    9.68 @@ -1266,32 +1273,33 @@ void ptwr_reconnect_disconnected(unsigne
    9.69      l1_pgentry_t *pl1e;
    9.70      int cpu = smp_processor_id();
    9.71      int i;
    9.72 +    unsigned long *writable_pte = (unsigned long *)&linear_pg_table
    9.73 +        [ptwr_info[cpu].writable_l1>>PAGE_SHIFT];
    9.74  
    9.75  #ifdef PTWR_TRACK_DOMAIN
    9.76      if (ptwr_domain[cpu] != get_current()->domain)
    9.77          printk("ptwr_reconnect_disconnected domain mismatch %d != %d\n",
    9.78                 ptwr_domain[cpu], get_current()->domain);
    9.79  #endif
    9.80 -    PTWR_PRINTK(("page fault in disconnected space: addr %08lx space %08lx\n",
    9.81 -		 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
    9.82 +    PTWR_PRINTK(("[A] page fault in disconnected space: addr %08lx space %08lx\n",
    9.83 +                 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
    9.84      pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
    9.85  
    9.86 -    if (__get_user(pte, ptwr_info[cpu].writable_l1))
    9.87 +    if (__get_user(pte, writable_pte))
    9.88          BUG();
    9.89      pfn = pte >> PAGE_SHIFT;
    9.90      page = &frame_table[pfn];
    9.91  
    9.92      /* reconnect l1 page */
    9.93 -    PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
    9.94 -		 l2_pgentry_val(*pl2e),
    9.95 -		 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
    9.96 -						PAGE_SHIFT]) >> PAGE_SHIFT,
    9.97 -		 frame_table[pfn].u.inuse.type_info,
    9.98 -		 frame_table[pfn].u.inuse.count_info,
    9.99 -		 frame_table[pfn].u.inuse.domain->domain));
   9.100 +    PTWR_PRINTK(("[A]     pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n",
   9.101 +                 pl2e, l2_pgentry_val(*pl2e),
   9.102 +                 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   9.103 +                                                PAGE_SHIFT]) >> PAGE_SHIFT,
   9.104 +                 frame_table[pfn].u.inuse.type_info,
   9.105 +                 frame_table[pfn].u.inuse.count_info,
   9.106 +                 frame_table[pfn].u.inuse.domain->domain));
   9.107  
   9.108 -    nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~0x800) |
   9.109 -                         _PAGE_PRESENT);
   9.110 +    nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
   9.111      pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) << PAGE_SHIFT);
   9.112      for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   9.113          l1_pgentry_t ol1e, nl1e;
   9.114 @@ -1312,22 +1320,23 @@ void ptwr_reconnect_disconnected(unsigne
   9.115      unmap_domain_mem(pl1e);
   9.116      update_l2e(pl2e, *pl2e, nl2e);
   9.117  
   9.118 -    PTWR_PRINTK(("now pl2e %p l2e %08lx              taf %08x/%08x/%u\n", pl2e,
   9.119 -		 l2_pgentry_val(*pl2e),
   9.120 -		 frame_table[pfn].u.inuse.type_info,
   9.121 -		 frame_table[pfn].u.inuse.count_info,
   9.122 -		 frame_table[pfn].u.inuse.domain->domain));
   9.123 +    PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              taf %08x/%08x/%u\n",
   9.124 +                 pl2e, l2_pgentry_val(*pl2e),
   9.125 +                 frame_table[pfn].u.inuse.type_info,
   9.126 +                 frame_table[pfn].u.inuse.count_info,
   9.127 +                 frame_table[pfn].u.inuse.domain->domain));
   9.128      ptwr_info[cpu].disconnected = ENTRIES_PER_L2_PAGETABLE;
   9.129      /* make pt page write protected */
   9.130 -    if (__get_user(pte, ptwr_info[cpu].writable_l1))
   9.131 +    if (__get_user(pte, writable_pte))
   9.132          BUG();
   9.133 -    PTWR_PRINTK(("writable_l1 at %p is %08lx\n", ptwr_info[cpu].writable_l1,
   9.134 -		 pte));
   9.135 +    PTWR_PRINTK(("[A] writable_l1 at %p is %08lx\n",
   9.136 +                 writable_pte, pte));
   9.137      pte &= ~_PAGE_RW;
   9.138 -    if (__put_user(pte, ptwr_info[cpu].writable_l1))
   9.139 +    if (__put_user(pte, writable_pte))
   9.140          BUG();
   9.141 -    PTWR_PRINTK(("writable_l1 at %p now %08lx\n", ptwr_info[cpu].writable_l1,
   9.142 -		 pte));
   9.143 +    __flush_tlb_one(ptwr_info[cpu].writable_l1);
   9.144 +    PTWR_PRINTK(("[A] writable_l1 at %p now %08lx\n",
   9.145 +                 writable_pte, pte));
   9.146      /* and try again */
   9.147      return;
   9.148  }
   9.149 @@ -1355,11 +1364,13 @@ void ptwr_flush_inactive(void)
   9.150      }
   9.151  #endif
   9.152      for (idx = 0; idx < ptwr_info[cpu].writable_idx; idx++) {
   9.153 -        if (__get_user(pte, ptwr_info[cpu].writables[idx]))
   9.154 +        unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   9.155 +            [ptwr_info[cpu].writables[idx]>>PAGE_SHIFT];
   9.156 +        if (__get_user(pte, writable_pte))
   9.157              BUG();
   9.158          pfn = pte >> PAGE_SHIFT;
   9.159          page = &frame_table[pfn];
   9.160 -        PTWR_PRINTK(("alloc l1 page %p\n", page));
   9.161 +        PTWR_PRINTK(("[I] alloc l1 page %p\n", page));
   9.162  
   9.163          pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   9.164          for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
   9.165 @@ -1376,13 +1387,14 @@ void ptwr_flush_inactive(void)
   9.166          unmap_domain_mem(pl1e);
   9.167  
   9.168          /* make pt page writable */
   9.169 -        PTWR_PRINTK(("writable_l1 at %p is %08lx\n",
   9.170 -		     ptwr_info[cpu].writables[idx], pte));
   9.171 +        PTWR_PRINTK(("[I] writable_l1 at %p is %08lx\n",
   9.172 +                     writable_pte, pte));
   9.173          pte &= ~_PAGE_RW;
   9.174 -        if (__put_user(pte, ptwr_info[cpu].writables[idx]))
   9.175 +        if (__put_user(pte, writable_pte))
   9.176              BUG();
   9.177 -        PTWR_PRINTK(("writable_l1 at %p now %08lx\n",
   9.178 -		     ptwr_info[cpu].writables[idx], pte));
   9.179 +        __flush_tlb_one(ptwr_info[cpu].writables[idx]);
   9.180 +        PTWR_PRINTK(("[I] writable_l1 at %p now %08lx\n",
   9.181 +                     writable_pte, pte));
   9.182      }
   9.183      ptwr_info[cpu].writable_idx = 0;
   9.184  }
   9.185 @@ -1398,7 +1410,7 @@ int ptwr_do_page_fault(unsigned long add
   9.186  
   9.187  #if 0
   9.188      PTWR_PRINTK(("get user %p for va %08lx\n",
   9.189 -		 &linear_pg_table[addr>>PAGE_SHIFT], addr));
   9.190 +                 &linear_pg_table[addr>>PAGE_SHIFT], addr));
   9.191  #endif
   9.192      if (l2_pgentry_val(linear_l2_table[addr >> L2_PAGETABLE_SHIFT]) &
   9.193          _PAGE_PRESENT &&
   9.194 @@ -1407,7 +1419,7 @@ int ptwr_do_page_fault(unsigned long add
   9.195          pfn = pte >> PAGE_SHIFT;
   9.196  #if 0
   9.197          PTWR_PRINTK(("check pte %08lx = pfn %08lx for va %08lx\n", pte, pfn,
   9.198 -		     addr));
   9.199 +                     addr));
   9.200  #endif
   9.201          page = &frame_table[pfn];
   9.202          if ((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table) {
   9.203 @@ -1419,22 +1431,21 @@ int ptwr_do_page_fault(unsigned long add
   9.204              pl2e = &linear_l2_table[(page->u.inuse.type_info &
   9.205                                       PGT_va_mask) >> PGT_va_shift];
   9.206              PTWR_PRINTK(("page_fault on l1 pt at va %08lx, pt for %08x, "
   9.207 -			 "pfn %08lx\n", addr,
   9.208 -			 ((page->u.inuse.type_info & PGT_va_mask) >>
   9.209 -			  PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   9.210 +                         "pfn %08lx\n", addr,
   9.211 +                         ((page->u.inuse.type_info & PGT_va_mask) >>
   9.212 +                          PGT_va_shift) << L2_PAGETABLE_SHIFT, pfn));
   9.213              if (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) {
   9.214                  l1_pgentry_t *pl1e;
   9.215 -                PTWR_PRINTK(("freeing l1 page %p taf %08x/%08x\n", page,
   9.216 -			     page->u.inuse.type_info,
   9.217 -			     page->u.inuse.count_info));
   9.218 +                PTWR_PRINTK(("[I] freeing l1 page %p taf %08x/%08x\n", page,
   9.219 +                             page->u.inuse.type_info,
   9.220 +                             page->u.inuse.count_info));
   9.221                  if (ptwr_info[cpu].writable_idx == PTWR_NR_WRITABLES)
   9.222                      ptwr_flush_inactive();
   9.223 -                ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] =
   9.224 -		    (unsigned long *)&linear_pg_table[addr>>PAGE_SHIFT];
   9.225 +                ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] = addr;
   9.226  
   9.227                  pl1e = map_domain_mem(pfn << PAGE_SHIFT);
   9.228                  memcpy(&ptwr_info[cpu].writable_page[
   9.229 -			   ptwr_info[cpu].writable_idx][0],
   9.230 +                           ptwr_info[cpu].writable_idx][0],
   9.231                         pl1e, ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t));
   9.232                  unmap_domain_mem(pl1e);
   9.233  
   9.234 @@ -1444,28 +1455,26 @@ int ptwr_do_page_fault(unsigned long add
   9.235                  l1_pgentry_t *pl1e;
   9.236                  if (ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE)
   9.237                      ptwr_reconnect_disconnected(addr);
   9.238 -                PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx "
   9.239 -			     "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   9.240 -			     l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   9.241 -							    >> PAGE_SHIFT]) >>
   9.242 -			     PAGE_SHIFT,
   9.243 -			     frame_table[pfn].u.inuse.type_info,
   9.244 -			     frame_table[pfn].u.inuse.count_info,
   9.245 -			     frame_table[pfn].u.inuse.domain->domain));
   9.246 +                PTWR_PRINTK(("[A]    pl2e %p l2e %08lx pfn %08lx "
   9.247 +                             "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   9.248 +                             l1_pgentry_val(linear_pg_table[(unsigned long)pl2e
   9.249 +                                                            >> PAGE_SHIFT]) >>
   9.250 +                             PAGE_SHIFT,
   9.251 +                             frame_table[pfn].u.inuse.type_info,
   9.252 +                             frame_table[pfn].u.inuse.count_info,
   9.253 +                             frame_table[pfn].u.inuse.domain->domain));
   9.254                  /* disconnect l1 page */
   9.255 -                nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) &
   9.256 -                                      ~_PAGE_PRESENT) | 0x800);
   9.257 +                nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT));
   9.258                  update_l2e(pl2e, *pl2e, nl2e);
   9.259  
   9.260                  ptwr_info[cpu].disconnected =
   9.261 -		    (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   9.262 -                PTWR_PRINTK(("now pl2e %p l2e %08lx              "
   9.263 -			     "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   9.264 -			     frame_table[pfn].u.inuse.type_info,
   9.265 -			     frame_table[pfn].u.inuse.count_info,
   9.266 -			     frame_table[pfn].u.inuse.domain->domain));
   9.267 -                ptwr_info[cpu].writable_l1 =
   9.268 -		    (unsigned long *)&linear_pg_table[addr>>PAGE_SHIFT];
   9.269 +                    (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift;
   9.270 +                PTWR_PRINTK(("[A] now pl2e %p l2e %08lx              "
   9.271 +                             "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e),
   9.272 +                             frame_table[pfn].u.inuse.type_info,
   9.273 +                             frame_table[pfn].u.inuse.count_info,
   9.274 +                             frame_table[pfn].u.inuse.domain->domain));
   9.275 +                ptwr_info[cpu].writable_l1 = addr;
   9.276                  pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) <<
   9.277                                        PAGE_SHIFT);
   9.278                  memcpy(&ptwr_info[cpu].disconnected_page[0], pl1e,
   9.279 @@ -1475,7 +1484,7 @@ int ptwr_do_page_fault(unsigned long add
   9.280              /* make pt page writable */
   9.281              pte |= _PAGE_RW;
   9.282              PTWR_PRINTK(("update %p pte to %08lx\n",
   9.283 -			 &linear_pg_table[addr>>PAGE_SHIFT], pte));
   9.284 +                         &linear_pg_table[addr>>PAGE_SHIFT], pte));
   9.285              if (__put_user(pte, (unsigned long *)
   9.286                             &linear_pg_table[addr>>PAGE_SHIFT]))
   9.287                  BUG();
   9.288 @@ -1485,6 +1494,28 @@ int ptwr_do_page_fault(unsigned long add
   9.289      return 0;
   9.290  }
   9.291  
   9.292 +void ptwr_init_backpointers(void)
   9.293 +{
   9.294 +    struct pfn_info *page;
   9.295 +    unsigned long pde, pfn;
   9.296 +    int va_idx;
   9.297 +
   9.298 +    for (va_idx = 0; va_idx < DOMAIN_ENTRIES_PER_L2_PAGETABLE; va_idx++) {
   9.299 +        /* check if entry valid */
   9.300 +        pde = l2_pgentry_val(linear_l2_table[va_idx]);
   9.301 +        if ((pde & _PAGE_PRESENT) == 0)
   9.302 +            continue;
   9.303 +        pfn = pde >> PAGE_SHIFT;
   9.304 +        page = &frame_table[pfn];
   9.305 +        /* assert that page is an l1_page_table   XXXcl maybe l2? */
   9.306 +        if ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) {
   9.307 +            BUG();
   9.308 +        }
   9.309 +        page->u.inuse.type_info &= ~PGT_va_mask;
   9.310 +        page->u.inuse.type_info |= va_idx << PGT_va_shift;
   9.311 +    }
   9.312 +}
   9.313 +
   9.314  #ifndef NDEBUG
   9.315  void ptwr_status(void)
   9.316  {
   9.317 @@ -1495,14 +1526,16 @@ void ptwr_status(void)
   9.318      int cpu = smp_processor_id();
   9.319  
   9.320      for (i = 0; i < ptwr_info[cpu].writable_idx; i++) {
   9.321 -        if (__get_user(pte, ptwr_info[cpu].writables[i]))
   9.322 +        unsigned long *writable_pte = (unsigned long *)&linear_pg_table
   9.323 +            [ptwr_info[cpu].writables[i]>>PAGE_SHIFT];
   9.324 +        if (__get_user(pte, writable_pte))
   9.325              BUG();
   9.326          pfn = pte >> PAGE_SHIFT;
   9.327          page = &frame_table[pfn];
   9.328          printk("need to alloc l1 page %p\n", page);
   9.329          /* make pt page writable */
   9.330          printk("need to make read-only l1-page at %p is %08lx\n",
   9.331 -               ptwr_info[cpu].writables[i], pte);
   9.332 +               writable_pte, pte);
   9.333      }
   9.334  
   9.335      if (ptwr_info[cpu].disconnected == ENTRIES_PER_L2_PAGETABLE)
   9.336 @@ -1518,11 +1551,11 @@ void ptwr_status(void)
   9.337      page = &frame_table[pfn];
   9.338  
   9.339      PTWR_PRINTK(("    pl2e %p l2e %08lx pfn %08lx taf %08x/%08x/%u\n", pl2e,
   9.340 -		 l2_pgentry_val(*pl2e),
   9.341 -		 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   9.342 -						PAGE_SHIFT]) >> PAGE_SHIFT,
   9.343 -		 frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   9.344 -		 frame_table[pfn].u.inuse.type_info,
   9.345 -		 frame_table[pfn].u.inuse.domain->domain));
   9.346 +                 l2_pgentry_val(*pl2e),
   9.347 +                 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e >>
   9.348 +                                                PAGE_SHIFT]) >> PAGE_SHIFT,
   9.349 +                 frame_table[l2_pgentry_to_pagenr(*pl2e)].u.inuse.type_info,
   9.350 +                 frame_table[pfn].u.inuse.type_info,
   9.351 +                 frame_table[pfn].u.inuse.domain->domain));
   9.352  }
   9.353  #endif
    10.1 --- a/xen/common/kernel.c	Wed Aug 11 10:19:26 2004 +0000
    10.2 +++ b/xen/common/kernel.c	Thu Aug 12 07:44:17 2004 +0000
    10.3 @@ -30,6 +30,8 @@ unsigned long xenheap_phys_end;
    10.4  
    10.5  xmem_cache_t *domain_struct_cachep;
    10.6  
    10.7 +vm_assist_info_t vm_assist_info[MAX_VMASST_TYPE + 1];
    10.8 +
    10.9  struct e820entry {
   10.10      unsigned long addr_lo, addr_hi;        /* start of memory segment */
   10.11      unsigned long size_lo, size_hi;        /* size of memory segment */
   10.12 @@ -353,16 +355,20 @@ long do_xen_version(int cmd)
   10.13  
   10.14  long do_vm_assist(unsigned int cmd, unsigned int type)
   10.15  {
   10.16 -    if ( type > (sizeof(unsigned long) * 8) )
   10.17 +    if ( type > MAX_VMASST_TYPE )
   10.18          return -EINVAL;
   10.19  
   10.20      switch ( cmd )
   10.21      {
   10.22      case VMASST_CMD_enable:
   10.23          set_bit(type, &current->vm_assist);
   10.24 +        if (vm_assist_info[type].enable)
   10.25 +            (*vm_assist_info[type].enable)();
   10.26          return 0;
   10.27      case VMASST_CMD_disable:
   10.28          clear_bit(type, &current->vm_assist);
   10.29 +        if (vm_assist_info[type].disable)
   10.30 +            (*vm_assist_info[type].disable)();
   10.31          return 0;
   10.32      }
   10.33  
    11.1 --- a/xen/common/memory.c	Wed Aug 11 10:19:26 2004 +0000
    11.2 +++ b/xen/common/memory.c	Thu Aug 12 07:44:17 2004 +0000
    11.3 @@ -37,13 +37,13 @@ struct pfn_info *frame_table;
    11.4  unsigned long frame_table_size;
    11.5  unsigned long max_page;
    11.6  
    11.7 -extern void init_percpu_info(void);
    11.8 +extern void arch_init_memory(void);
    11.9  
   11.10  void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
   11.11  {
   11.12      unsigned long mfn;
   11.13  
   11.14 -    init_percpu_info();
   11.15 +    arch_init_memory();
   11.16  
   11.17      max_page = nr_pages;
   11.18      frame_table_size = nr_pages * sizeof(struct pfn_info);
    12.1 --- a/xen/include/asm-x86/mm.h	Wed Aug 11 10:19:26 2004 +0000
    12.2 +++ b/xen/include/asm-x86/mm.h	Thu Aug 12 07:44:17 2004 +0000
    12.3 @@ -330,13 +330,20 @@ int memguard_is_guarded(void *p);
    12.4  #endif
    12.5  
    12.6  
    12.7 +typedef struct {
    12.8 +    void	(*enable)(void);
    12.9 +    void	(*disable)(void);
   12.10 +} vm_assist_info_t;
   12.11 +extern vm_assist_info_t vm_assist_info[];
   12.12 +
   12.13 +
   12.14  /* Writable Pagetables */
   12.15  #define	PTWR_NR_WRITABLES 1
   12.16  typedef struct {
   12.17      unsigned long disconnected;
   12.18      l1_pgentry_t disconnected_page[ENTRIES_PER_L1_PAGETABLE];
   12.19 -    unsigned long *writable_l1;
   12.20 -    unsigned long *writables[PTWR_NR_WRITABLES];
   12.21 +    unsigned long writable_l1;
   12.22 +    unsigned long writables[PTWR_NR_WRITABLES];
   12.23      int writable_idx;
   12.24      l1_pgentry_t writable_page[PTWR_NR_WRITABLES][ENTRIES_PER_L1_PAGETABLE];
   12.25  #ifdef PTWR_TRACK_DOMAIN
    13.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Aug 11 10:19:26 2004 +0000
    13.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Thu Aug 12 07:44:17 2004 +0000
    13.3 @@ -190,6 +190,7 @@
    13.4  #define VMASST_TYPE_4gb_segments         0
    13.5  #define VMASST_TYPE_4gb_segments_notify  1
    13.6  #define VMASST_TYPE_writeable_pagetables 2
    13.7 +#define MAX_VMASST_TYPE 2
    13.8  
    13.9  #ifndef __ASSEMBLY__
   13.10