ia64/xen-unstable

changeset 902:7bf6fbf9efac

bitkeeper revision 1.570 (3fab8343LyJPc2KVRZYbCwAIS3T15g)

Many files:
Various cleanups and fixes for suspend/resume. Just a couple more bugs to fix.
author kaf24@scramble.cl.cam.ac.uk
date Fri Nov 07 11:34:27 2003 +0000 (2003-11-07)
parents 53a122a3c2b5
children 099ae186d2cd
files tools/internal/xi_build.c tools/internal/xi_restore_linux.c tools/internal/xi_save_linux.c xen/arch/i386/mm.c xen/arch/i386/process.c xen/arch/i386/traps.c xen/common/memory.c xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h
line diff
     1.1 --- a/tools/internal/xi_build.c	Thu Nov 06 20:52:51 2003 +0000
     1.2 +++ b/tools/internal/xi_build.c	Fri Nov 07 11:34:27 2003 +0000
     1.3 @@ -461,7 +461,10 @@ int main(int argc, char **argv)
     1.4                         load_addr, ksize, &launch_op.u.builddomain,
     1.5                         argc, argv, args_start, 
     1.6                         op.u.getdomaininfo.shared_info_frame) < 0 )
     1.7 +    {
     1.8 +        ERROR("Error constructing guest OS");
     1.9          return 1;
    1.10 +    }
    1.11  
    1.12      if ( initrd_fd >= 0 )
    1.13          close(initrd_fd);
     2.1 --- a/tools/internal/xi_restore_linux.c	Thu Nov 06 20:52:51 2003 +0000
     2.2 +++ b/tools/internal/xi_restore_linux.c	Fri Nov 07 11:34:27 2003 +0000
     2.3 @@ -42,12 +42,13 @@ static int get_pfn_list(
     2.4  static mmu_update_t mmu_updates[MAX_MMU_UPDATES];
     2.5  static int mmu_update_idx;
     2.6  
     2.7 -static void flush_mmu_updates(void)
     2.8 +static int flush_mmu_updates(void)
     2.9  {
    2.10 +    int err = 0;
    2.11      privcmd_hypercall_t hypercall;
    2.12  
    2.13      if ( mmu_update_idx == 0 )
    2.14 -        return;
    2.15 +        return 0;
    2.16  
    2.17      hypercall.op     = __HYPERVISOR_mmu_update;
    2.18      hypercall.arg[0] = (unsigned long)mmu_updates;
    2.19 @@ -56,26 +57,31 @@ static void flush_mmu_updates(void)
    2.20      if ( mlock(mmu_updates, sizeof(mmu_updates)) != 0 )
    2.21      {
    2.22          PERROR("Could not lock pagetable update array");
    2.23 -        exit(1);
    2.24 +        err = 1;
    2.25 +        goto out;
    2.26      }
    2.27  
    2.28      if ( do_xen_hypercall(&hypercall) < 0 )
    2.29      {
    2.30          ERROR("Failure when submitting mmu updates");
    2.31 -        exit(1);
    2.32 +        err = 1;
    2.33      }
    2.34  
    2.35      mmu_update_idx = 0;
    2.36      
    2.37      (void)munlock(mmu_updates, sizeof(mmu_updates));
    2.38 +
    2.39 + out:
    2.40 +    return err;
    2.41  }
    2.42  
    2.43 -static void add_mmu_update(unsigned long ptr, unsigned long val)
    2.44 +static int add_mmu_update(unsigned long ptr, unsigned long val)
    2.45  {
    2.46      mmu_updates[mmu_update_idx].ptr = ptr;
    2.47      mmu_updates[mmu_update_idx].val = val;
    2.48      if ( ++mmu_update_idx == MAX_MMU_UPDATES )
    2.49 -        flush_mmu_updates();
    2.50 +        return flush_mmu_updates();
    2.51 +    return 0;
    2.52  }
    2.53  
    2.54  static int devmem_fd;
    2.55 @@ -163,9 +169,9 @@ int main(int argc, char **argv)
    2.56      }
    2.57  
    2.58      filename = argv[1];
    2.59 -    if ( (fd = open(name, O_RDONLY)) == -1 )
    2.60 +    if ( (fd = open(filename, O_RDONLY)) == -1 )
    2.61      {
    2.62 -        PERROR("Could not open file for writing");
    2.63 +        PERROR("Could not open state file for reading");
    2.64          return 1;
    2.65      }
    2.66  
    2.67 @@ -269,8 +275,9 @@ int main(int argc, char **argv)
    2.68          {
    2.69          case L1TAB:
    2.70              memset(ppage, 0, PAGE_SIZE);
    2.71 -            add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
    2.72 -                           MMUEXT_PIN_L1_TABLE);
    2.73 +            if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
    2.74 +                                MMUEXT_PIN_L1_TABLE) )
    2.75 +                goto out;
    2.76              for ( j = 0; j < 1024; j++ )
    2.77              {
    2.78                  if ( page[j] & _PAGE_PRESENT )
    2.79 @@ -285,17 +292,19 @@ int main(int argc, char **argv)
    2.80                          ERROR("Write access requested for a restricted frame");
    2.81                          goto out;
    2.82                      }
    2.83 -                    page[j] &= PAGE_SIZE - 1;
    2.84 +                    page[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PAT);
    2.85                      page[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT;
    2.86                  }
    2.87 -                add_mmu_update((unsigned long)&ppage[j], page[j]);
    2.88 +                if ( add_mmu_update((unsigned long)&ppage[j], page[j]) )
    2.89 +                    goto out;
    2.90              }
    2.91              break;
    2.92          case L2TAB:
    2.93              memset(ppage, 0, PAGE_SIZE);
    2.94 -            add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
    2.95 -                           MMUEXT_PIN_L2_TABLE);
    2.96 -            for ( j = 0; j < 1024; j++ )
    2.97 +            if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_EXTENDED_COMMAND,
    2.98 +                                MMUEXT_PIN_L2_TABLE) )
    2.99 +                goto out;
   2.100 +            for ( j = 0; j < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); j++ )
   2.101              {
   2.102                  if ( page[j] & _PAGE_PRESENT )
   2.103                  {
   2.104 @@ -309,22 +318,35 @@ int main(int argc, char **argv)
   2.105                          ERROR("Page table mistyping");
   2.106                          goto out;
   2.107                      }
   2.108 -                    page[j] &= PAGE_SIZE - 1;
   2.109 +                    /* Haven't reached the L1 table yet. Ensure it is safe! */
   2.110 +                    if ( pfn > i )
   2.111 +                    {
   2.112 +                        unsigned long **l1 = map_pfn(pfn_to_mfn_table[pfn]);
   2.113 +                        memset(l1, 0, PAGE_SIZE);
   2.114 +                        unmap_pfn(l1);
   2.115 +                    }
   2.116 +                    page[j] &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PSE);
   2.117                      page[j] |= pfn_to_mfn_table[pfn] << PAGE_SHIFT;
   2.118                  }
   2.119 -                add_mmu_update((unsigned long)&ppage[j], page[j]);
   2.120 +                if ( add_mmu_update((unsigned long)&ppage[j], page[j]) )
   2.121 +                    goto out;
   2.122              }
   2.123              break;
   2.124          default:
   2.125              memcpy(ppage, page, PAGE_SIZE);
   2.126              break;
   2.127          }
   2.128 +        /* NB. Must flush before unmapping page, as pass VAs to Xen. */
   2.129 +        if ( flush_mmu_updates() )
   2.130 +            goto out;
   2.131          unmap_pfn(ppage);
   2.132  
   2.133 -        add_mmu_update((mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i);
   2.134 +        if ( add_mmu_update((mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i) )
   2.135 +            goto out;
   2.136      }
   2.137  
   2.138 -    flush_mmu_updates();
   2.139 +    if ( flush_mmu_updates() )
   2.140 +        goto out;
   2.141  
   2.142      /* Uncanonicalise the suspend-record frame number and poke resume rec. */
   2.143      pfn = ctxt.i386_ctxt.esi;
   2.144 @@ -391,7 +413,7 @@ int main(int argc, char **argv)
   2.145       *  4. fast_trap_idx is checked by Xen.
   2.146       *  5. ldt base must be page-aligned, no more than 8192 ents, ...
   2.147       *  6. gdt already done, and further checking is done by Xen.
   2.148 -     *  7. check that ring1_ss/esp is safe.
   2.149 +     *  7. check that ring1_ss is safe.
   2.150       *  8. pt_base is already done.
   2.151       *  9. debugregs are checked by Xen.
   2.152       *  10. callback code selectors need checking.
   2.153 @@ -404,8 +426,6 @@ int main(int argc, char **argv)
   2.154      }
   2.155      if ( (ctxt.ring1_ss & 3) == 0 )
   2.156          ctxt.ring1_ss = FLAT_RING1_DS;
   2.157 -    if ( ctxt.ring1_esp > HYPERVISOR_VIRT_START )
   2.158 -        ctxt.ring1_esp = HYPERVISOR_VIRT_START;
   2.159      if ( (ctxt.event_callback_cs & 3) == 0 )
   2.160          ctxt.event_callback_cs = FLAT_RING1_CS;
   2.161      if ( (ctxt.failsafe_callback_cs & 3) == 0 )
   2.162 @@ -419,9 +439,11 @@ int main(int argc, char **argv)
   2.163          goto out;
   2.164      }
   2.165  
   2.166 -
   2.167 -    /* Success! */
   2.168 -    rc = 0;
   2.169 +    op.cmd = DOM0_BUILDDOMAIN;
   2.170 +    op.u.builddomain.domain   = dom;
   2.171 +    op.u.builddomain.num_vifs = 1;
   2.172 +    memcpy(&op.u.builddomain.ctxt, &ctxt, sizeof(ctxt));
   2.173 +    rc = do_dom0_op(&op);
   2.174  
   2.175   out:
   2.176      /* If we experience an error then kill the half-constructed domain. */
     3.1 --- a/tools/internal/xi_save_linux.c	Thu Nov 06 20:52:51 2003 +0000
     3.2 +++ b/tools/internal/xi_save_linux.c	Fri Nov 07 11:34:27 2003 +0000
     3.3 @@ -98,7 +98,7 @@ static int checked_write(int fd, const v
     3.4  int main(int argc, char **argv)
     3.5  {
     3.6      dom0_op_t op;
     3.7 -    int rc = 1, i;
     3.8 +    int rc = 1, i, j;
     3.9      unsigned long mfn, dom;
    3.10  
    3.11      /* Remember if we stopped the guest, so we can restart it on exit. */
    3.12 @@ -148,7 +148,7 @@ int main(int argc, char **argv)
    3.13      }
    3.14  
    3.15      filename = argv[2];
    3.16 -    if ( (fd = open(name, O_CREAT|O_EXCL|O_RDWR)) == -1 )
    3.17 +    if ( (fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
    3.18      {
    3.19          PERROR("Could not open file for writing");
    3.20          return 1;
    3.21 @@ -255,15 +255,14 @@ int main(int argc, char **argv)
    3.22              goto out;
    3.23          }
    3.24  
    3.25 -        pfn_to_mfn_table[i] = mfn;
    3.26 -
    3.27          /* Did we map this MFN already? That would be invalid! */
    3.28          if ( MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
    3.29          {
    3.30              ERROR("A machine frame appears twice in pseudophys space");
    3.31              goto out;
    3.32          }
    3.33 -        
    3.34 +
    3.35 +        pfn_to_mfn_table[i] = mfn;
    3.36          mfn_to_pfn_table[mfn] = i;
    3.37  
    3.38          /* Query page type by MFN, but store it by PFN. */
    3.39 @@ -331,17 +330,20 @@ int main(int argc, char **argv)
    3.40  
    3.41          if ( (pfn_type[i] == L1TAB) || (pfn_type[i] == L2TAB) )
    3.42          {
    3.43 -            for ( i = 0; i < 1024; i++ )
    3.44 +            for ( j = 0; 
    3.45 +                  j < ((pfn_type[i] == L2TAB) ? 
    3.46 +                       (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) : 1024); 
    3.47 +                  j++ )
    3.48              {
    3.49 -                if ( !(page[i] & _PAGE_PRESENT) ) continue;
    3.50 -                mfn = page[i] >> PAGE_SHIFT;
    3.51 +                if ( !(page[j] & _PAGE_PRESENT) ) continue;
    3.52 +                mfn = page[j] >> PAGE_SHIFT;
    3.53                  if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
    3.54                  {
    3.55                      ERROR("Frame number in pagetable page is invalid");
    3.56                      goto out;
    3.57                  }
    3.58 -                page[i] &= PAGE_SIZE - 1;
    3.59 -                page[i] |= mfn_to_pfn_table[mfn] << PAGE_SHIFT;
    3.60 +                page[j] &= PAGE_SIZE - 1;
    3.61 +                page[j] |= mfn_to_pfn_table[mfn] << PAGE_SHIFT;
    3.62              }
    3.63          }
    3.64  
     4.1 --- a/xen/arch/i386/mm.c	Thu Nov 06 20:52:51 2003 +0000
     4.2 +++ b/xen/arch/i386/mm.c	Fri Nov 07 11:34:27 2003 +0000
     4.3 @@ -129,7 +129,8 @@ long do_stack_switch(unsigned long ss, u
     4.4      int nr = smp_processor_id();
     4.5      struct tss_struct *t = &init_tss[nr];
     4.6  
     4.7 -    if ( ((ss & 3) == 0) || (esp > HYPERVISOR_VIRT_START) )
     4.8 +    /* We need to do this check as we load and use SS on guest's behalf. */
     4.9 +    if ( (ss & 3) == 0 )
    4.10          return -EPERM;
    4.11  
    4.12      current->thread.ss1  = ss;
     5.1 --- a/xen/arch/i386/process.c	Thu Nov 06 20:52:51 2003 +0000
     5.2 +++ b/xen/arch/i386/process.c	Fri Nov 07 11:34:27 2003 +0000
     5.3 @@ -248,7 +248,7 @@ void switch_to(struct task_struct *prev_
     5.4       * then we'll #GP.
     5.5       */
     5.6      if ( (stack_ec->cs & 3) == 0 )
     5.7 -        stack_ec->cs = 0;
     5.8 +        stack_ec->cs = FLAT_RING1_CS;
     5.9  
    5.10      unlazy_fpu(prev_p);
    5.11  
     6.1 --- a/xen/arch/i386/traps.c	Thu Nov 06 20:52:51 2003 +0000
     6.2 +++ b/xen/arch/i386/traps.c	Fri Nov 07 11:34:27 2003 +0000
     6.3 @@ -292,14 +292,14 @@ asmlinkage void do_page_fault(struct pt_
     6.4  
     6.5      __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
     6.6  
     6.7 -    if ( unlikely(!(regs->xcs & 3)) )
     6.8 -        goto fault_in_hypervisor;
     6.9 -
    6.10      if ( unlikely(addr > PAGE_OFFSET) )
    6.11          goto fault_in_xen_space;
    6.12  
    6.13   propagate_fault:
    6.14  
    6.15 +    if ( unlikely(!(regs->xcs & 3)) )
    6.16 +        goto fault_in_hypervisor;
    6.17 +
    6.18      ti = p->thread.traps + 14;
    6.19      gtb->flags = GTBF_TRAP_CR2; /* page fault pushes %cr2 */
    6.20      gtb->cr2        = addr;
     7.1 --- a/xen/common/memory.c	Thu Nov 06 20:52:51 2003 +0000
     7.2 +++ b/xen/common/memory.c	Fri Nov 07 11:34:27 2003 +0000
     7.3 @@ -408,17 +408,17 @@ static int get_l2_table(unsigned long pa
     7.4      {
     7.5          l2_entry = *p_l2_entry++;
     7.6          if ( !(l2_pgentry_val(l2_entry) & _PAGE_PRESENT) ) continue;
     7.7 -        if ( (l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE)) )
     7.8 +        if ( unlikely((l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE))) )
     7.9          {
    7.10              MEM_LOG("Bad L2 page type settings %04lx",
    7.11                      l2_pgentry_val(l2_entry) & (_PAGE_GLOBAL|_PAGE_PSE));
    7.12              ret = -1;
    7.13 -            goto out;
    7.14 +            goto fail;
    7.15          }
    7.16          /* Assume we're mapping an L1 table, falling back to twisted L2. */
    7.17          ret = get_l1_table(l2_pgentry_to_pagenr(l2_entry));
    7.18 -        if ( ret ) ret = get_twisted_l2_table(page_nr, l2_entry);
    7.19 -        if ( ret ) goto out;
    7.20 +        if ( unlikely(ret) ) ret = get_twisted_l2_table(page_nr, l2_entry);
    7.21 +        if ( unlikely(ret) ) goto fail;
    7.22      }
    7.23      
    7.24      /* Now we simply slap in our high mapping. */
    7.25 @@ -435,6 +435,18 @@ static int get_l2_table(unsigned long pa
    7.26   out:
    7.27      unmap_domain_mem(p_l2_entry);
    7.28      return ret;
    7.29 +
    7.30 + fail:
    7.31 +    p_l2_entry--;
    7.32 +    while ( i-- > 0 )
    7.33 +    {
    7.34 +        l2_entry = *--p_l2_entry;
    7.35 +        if ( (l2_pgentry_val(l2_entry) & _PAGE_PRESENT) )
    7.36 +            put_l1_table(l2_pgentry_to_pagenr(l2_entry));
    7.37 +    }
    7.38 +    if ( dec_page_refcnt(page_nr, PGT_l2_page_table) != 0 )
    7.39 +        BUG();
    7.40 +    goto out;
    7.41  }
    7.42  
    7.43  
    7.44 @@ -453,24 +465,38 @@ static int get_l1_table(unsigned long pa
    7.45      {
    7.46          l1_entry = *p_l1_entry++;
    7.47          if ( !(l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) continue;
    7.48 -        if ( (l1_pgentry_val(l1_entry) &
    7.49 -              (_PAGE_GLOBAL|_PAGE_PAT)) )
    7.50 +        if ( unlikely((l1_pgentry_val(l1_entry) &
    7.51 +                       (_PAGE_GLOBAL|_PAGE_PAT))) )
    7.52          {
    7.53              MEM_LOG("Bad L1 page type settings %04lx",
    7.54                      l1_pgentry_val(l1_entry) &
    7.55                      (_PAGE_GLOBAL|_PAGE_PAT));
    7.56              ret = -1;
    7.57 -            goto out;
    7.58 +            goto fail;
    7.59          }
    7.60          ret = get_page(l1_pgentry_to_pagenr(l1_entry),
    7.61                         l1_pgentry_val(l1_entry) & _PAGE_RW);
    7.62 -        if ( ret ) goto out;
    7.63 +        if ( unlikely(ret) ) goto fail;
    7.64      }
    7.65  
    7.66   out:
    7.67      /* Make sure we unmap the right page! */
    7.68      unmap_domain_mem(p_l1_entry-1);
    7.69      return ret;
    7.70 +
    7.71 + fail:
    7.72 +    p_l1_entry--;
    7.73 +    while ( i-- > 0 )
    7.74 +    {
    7.75 +        l1_entry = *--p_l1_entry;
    7.76 +        if ( (l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) 
    7.77 +            put_page(l1_pgentry_to_pagenr(l1_entry), 
    7.78 +                     l1_pgentry_val(l1_entry) & _PAGE_RW);
    7.79 +    }
    7.80 +    if ( dec_page_refcnt(page_nr, PGT_l1_page_table) != 0 )
    7.81 +        BUG();
    7.82 +    unmap_domain_mem(p_l1_entry);
    7.83 +    return ret;
    7.84  }
    7.85  
    7.86  
    7.87 @@ -550,10 +576,8 @@ static void put_l1_table(unsigned long p
    7.88      {
    7.89          l1_entry = *p_l1_entry++;
    7.90          if ( (l1_pgentry_val(l1_entry) & _PAGE_PRESENT) ) 
    7.91 -        {
    7.92              put_page(l1_pgentry_to_pagenr(l1_entry), 
    7.93                       l1_pgentry_val(l1_entry) & _PAGE_RW);
    7.94 -        }
    7.95      }
    7.96  
    7.97      /* Make sure we unmap the right page! */
    7.98 @@ -611,9 +635,6 @@ static int mod_l2_entry(l2_pgentry_t *p_
    7.99          if ( ((l2_pgentry_val(old_l2_entry) ^ 
   7.100                 l2_pgentry_val(new_l2_entry)) & 0xfffff001) != 0 )
   7.101          {
   7.102 -            if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) 
   7.103 -                put_l1_table(l2_pgentry_to_pagenr(old_l2_entry));
   7.104 -            
   7.105              /* Assume we're mapping an L1 table, falling back to twisted L2. */
   7.106              if ( unlikely(get_l1_table(l2_pgentry_to_pagenr(new_l2_entry))) )
   7.107              {
   7.108 @@ -623,6 +644,9 @@ static int mod_l2_entry(l2_pgentry_t *p_
   7.109                  if ( get_twisted_l2_table(l1e >> PAGE_SHIFT, new_l2_entry) )
   7.110                      goto fail;
   7.111              }
   7.112 +
   7.113 +            if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) ) 
   7.114 +                put_l1_table(l2_pgentry_to_pagenr(old_l2_entry));            
   7.115          } 
   7.116      }
   7.117      else if ( (l2_pgentry_val(old_l2_entry) & _PAGE_PRESENT) )
   7.118 @@ -659,13 +683,13 @@ static int mod_l1_entry(l1_pgentry_t *p_
   7.119          if ( ((l1_pgentry_val(old_l1_entry) ^
   7.120                 l1_pgentry_val(new_l1_entry)) & 0xfffff003) != 0 )
   7.121          {
   7.122 +            if ( get_page(l1_pgentry_to_pagenr(new_l1_entry),
   7.123 +                          l1_pgentry_val(new_l1_entry) & _PAGE_RW) )
   7.124 +                goto fail;
   7.125 +
   7.126              if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) ) 
   7.127                  put_page(l1_pgentry_to_pagenr(old_l1_entry),
   7.128                           l1_pgentry_val(old_l1_entry) & _PAGE_RW);
   7.129 -
   7.130 -            if ( get_page(l1_pgentry_to_pagenr(new_l1_entry),
   7.131 -                          l1_pgentry_val(new_l1_entry) & _PAGE_RW) )
   7.132 -                goto fail;
   7.133          } 
   7.134      }
   7.135      else if ( (l1_pgentry_val(old_l1_entry) & _PAGE_PRESENT) )
   7.136 @@ -696,10 +720,24 @@ static int do_extended_command(unsigned 
   7.137      switch ( cmd )
   7.138      {
   7.139      case MMUEXT_PIN_L1_TABLE:
   7.140 +        if ( unlikely(page->type_count & REFCNT_PIN_BIT) )
   7.141 +        {
   7.142 +            MEM_LOG("Pfn %08lx already pinned", pfn);
   7.143 +            err = 1;
   7.144 +            break;
   7.145 +        }
   7.146          err = get_l1_table(pfn);
   7.147          goto mark_as_pinned;
   7.148 +
   7.149      case MMUEXT_PIN_L2_TABLE:
   7.150 +        if ( unlikely(page->type_count & REFCNT_PIN_BIT) )
   7.151 +        {
   7.152 +            MEM_LOG("Pfn %08lx already pinned", pfn);
   7.153 +            err = 1;
   7.154 +            break;
   7.155 +        }
   7.156          err = get_l2_table(pfn);
   7.157 +
   7.158      mark_as_pinned:
   7.159          if ( unlikely(err) )
   7.160          {
   7.161 @@ -708,16 +746,8 @@ static int do_extended_command(unsigned 
   7.162          }
   7.163          put_page_type(page);
   7.164          put_page_tot(page);
   7.165 -        if ( likely(!(page->type_count & REFCNT_PIN_BIT)) )
   7.166 -        {
   7.167 -            page->type_count |= REFCNT_PIN_BIT;
   7.168 -            page->tot_count  |= REFCNT_PIN_BIT;
   7.169 -        }
   7.170 -        else
   7.171 -        {
   7.172 -            MEM_LOG("Pfn %08lx already pinned", pfn);
   7.173 -            err = 1;
   7.174 -        }
   7.175 +        page->type_count |= REFCNT_PIN_BIT;
   7.176 +        page->tot_count  |= REFCNT_PIN_BIT;
   7.177          break;
   7.178  
   7.179      case MMUEXT_UNPIN_TABLE:
   7.180 @@ -805,7 +835,7 @@ int do_mmu_update(mmu_update_t *ureqs, i
   7.181      mmu_update_t req;
   7.182      unsigned long flags, pfn, l1e;
   7.183      struct pfn_info *page;
   7.184 -    int err = 0, i, cpu = smp_processor_id();
   7.185 +    int rc = 0, err = 0, i, cpu = smp_processor_id();
   7.186      unsigned int cmd;
   7.187      unsigned long cr0 = 0;
   7.188  
   7.189 @@ -814,11 +844,10 @@ int do_mmu_update(mmu_update_t *ureqs, i
   7.190  
   7.191      for ( i = 0; i < count; i++ )
   7.192      {
   7.193 -
   7.194          if ( unlikely(copy_from_user(&req, ureqs, sizeof(req)) != 0) )
   7.195          {
   7.196 -            if ( cr0 != 0 ) write_cr0(cr0);
   7.197 -            kill_domain_with_errmsg("Cannot read page update request");
   7.198 +            rc = -EFAULT;
   7.199 +            break;
   7.200          }
   7.201  
   7.202          cmd = req.ptr & (sizeof(l1_pgentry_t)-1);
   7.203 @@ -939,8 +968,8 @@ int do_mmu_update(mmu_update_t *ureqs, i
   7.204  
   7.205          if ( unlikely(err) )
   7.206          {
   7.207 -            if ( cr0 != 0 ) write_cr0(cr0);
   7.208 -            kill_domain_with_errmsg("Illegal page update request");
   7.209 +            rc = -EINVAL;
   7.210 +            break;
   7.211          }
   7.212  
   7.213          ureqs++;
   7.214 @@ -961,7 +990,7 @@ int do_mmu_update(mmu_update_t *ureqs, i
   7.215      if ( cr0 != 0 )
   7.216          write_cr0(cr0);
   7.217  
   7.218 -    return 0;
   7.219 +    return rc;
   7.220  }
   7.221  
   7.222  
   7.223 @@ -991,11 +1020,11 @@ int do_update_va_mapping(unsigned long p
   7.224          write_cr0(cr0 & ~X86_CR0_WP);        
   7.225      }
   7.226  
   7.227 -    if ( unlikely((err = mod_l1_entry(&linear_pg_table[page_nr], 
   7.228 -                                      mk_l1_pgentry(val))) != 0) )
   7.229 +    if ( unlikely(mod_l1_entry(&linear_pg_table[page_nr], 
   7.230 +                               mk_l1_pgentry(val)) != 0) )
   7.231      {
   7.232 -        spin_unlock_irq(&p->page_lock);
   7.233 -        kill_domain_with_errmsg("Illegal VA-mapping update request");
   7.234 +        err = -EINVAL;
   7.235 +        goto check_cr0_unlock_and_out;
   7.236      }
   7.237  
   7.238      if ( unlikely(flags & UVMF_INVLPG) )
   7.239 @@ -1004,9 +1033,9 @@ int do_update_va_mapping(unsigned long p
   7.240      if ( unlikely(flags & UVMF_FLUSH_TLB) )
   7.241          __write_cr3_counted(pagetable_val(p->mm.pagetable));
   7.242  
   7.243 + check_cr0_unlock_and_out:
   7.244      if ( unlikely(cr0 != 0) )
   7.245          write_cr0(cr0);
   7.246 -
   7.247   unlock_and_out:
   7.248      spin_unlock_irq(&p->page_lock);
   7.249   out:
     8.1 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c	Thu Nov 06 20:52:51 2003 +0000
     8.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c	Fri Nov 07 11:34:27 2003 +0000
     8.3 @@ -155,8 +155,7 @@ static void __init parse_mem_cmdline (ch
     8.4  
     8.5  void __init setup_arch(char **cmdline_p)
     8.6  {
     8.7 -    unsigned long start_pfn, max_pfn, max_low_pfn;
     8.8 -    unsigned long bootmap_size;
     8.9 +    unsigned long bootmap_size, start_pfn, max_low_pfn;
    8.10      unsigned long i;
    8.11  
    8.12      extern void hypervisor_callback(void);
     9.1 --- a/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h	Thu Nov 06 20:52:51 2003 +0000
     9.2 +++ b/xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h	Fri Nov 07 11:34:27 2003 +0000
     9.3 @@ -10,6 +10,7 @@
     9.4  #define __HYPERVISOR_H__
     9.5  
     9.6  #include <linux/types.h>
     9.7 +#include <linux/kernel.h>
     9.8  #include <asm/hypervisor-ifs/hypervisor-if.h>
     9.9  #include <asm/hypervisor-ifs/dom0_ops.h>
    9.10  #include <asm/ptrace.h>
    9.11 @@ -167,6 +168,9 @@ static inline int HYPERVISOR_mmu_update(
    9.12          : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), 
    9.13          "b" (req), "c" (count) );
    9.14  
    9.15 +    if ( unlikely(ret < 0) )
    9.16 +        panic("Failed mmu update: %p, %d", req, count);
    9.17 +
    9.18      return ret;
    9.19  }
    9.20  
    9.21 @@ -396,6 +400,10 @@ static inline int HYPERVISOR_update_va_m
    9.22          : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), 
    9.23          "b" (page_nr), "c" ((new_val).pte_low), "d" (flags) );
    9.24  
    9.25 +    if ( unlikely(ret < 0) )
    9.26 +        panic("Failed update VA mapping: %08lx, %08lx, %08lx",
    9.27 +              page_nr, (new_val).pte_low, flags);
    9.28 +    
    9.29      return ret;
    9.30  }
    9.31