ia64/xen-unstable

changeset 2337:3145fa096b1a

bitkeeper revision 1.1159.45.17 (412b0f07nrZVpzBQ0MnEcFNcQUolbw)

More grant-table code. Various cleanups and speedups.
author kaf24@scramble.cl.cam.ac.uk
date Tue Aug 24 09:48:55 2004 +0000 (2004-08-24)
parents 9cb13e3d3f3a
children c326283ef029
files linux-2.4.26-xen-sparse/arch/xen/kernel/ldt.c linux-2.4.26-xen-sparse/arch/xen/kernel/traps.c linux-2.4.26-xen-sparse/include/asm-xen/pgalloc.h linux-2.4.26-xen-sparse/include/asm-xen/pgtable.h linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h xen/arch/x86/domain.c xen/arch/x86/idle0_task.c xen/arch/x86/memory.c xen/arch/x86/traps.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/usercopy.c xen/common/dom_mem_ops.c xen/common/domain.c xen/common/grant_table.c xen/common/schedule.c xen/include/asm-x86/mm.h xen/include/asm-x86/processor.h xen/include/asm-x86/x86_32/uaccess.h xen/include/asm-x86/x86_64/uaccess.h xen/include/hypervisor-ifs/grant_table.h xen/include/hypervisor-ifs/hypervisor-if.h xen/include/hypervisor-ifs/io/domain_controller.h xen/include/xen/config.h xen/include/xen/grant_table.h xen/include/xen/sched.h
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/ldt.c	Fri Aug 20 18:19:24 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/ldt.c	Tue Aug 24 09:48:55 2004 +0000
     1.3 @@ -115,7 +115,7 @@ int init_new_context(struct task_struct 
     1.4  void destroy_context(struct mm_struct *mm)
     1.5  {
     1.6  	if (mm->context.size) {
     1.7 -		make_pages_writeable(
     1.8 +		make_pages_writable(
     1.9  			mm->context.ldt, 
    1.10  			(mm->context.size*LDT_ENTRY_SIZE)/PAGE_SIZE);
    1.11  		flush_page_update_queue();
     2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/traps.c	Fri Aug 20 18:19:24 2004 +0000
     2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/traps.c	Tue Aug 24 09:48:55 2004 +0000
     2.3 @@ -648,7 +648,7 @@ void __init trap_init(void)
     2.4   * ensures this end result (blow away the selector value) without the dangers
     2.5   * of the normal page-fault handler.
     2.6   * 
     2.7 - * NB. Perhaps this can all go away after we have implemented writeable
     2.8 + * NB. Perhaps this can all go away after we have implemented writable
     2.9   * page tables. :-)
    2.10   */
    2.11  
     3.1 --- a/linux-2.4.26-xen-sparse/include/asm-xen/pgalloc.h	Fri Aug 20 18:19:24 2004 +0000
     3.2 +++ b/linux-2.4.26-xen-sparse/include/asm-xen/pgalloc.h	Tue Aug 24 09:48:55 2004 +0000
     3.3 @@ -111,7 +111,7 @@ static inline void free_pgd_slow(pgd_t *
     3.4  	kmem_cache_free(pae_pgd_cachep, pgd);
     3.5  #else
     3.6  	queue_pgd_unpin(__pa(pgd));
     3.7 -        __make_page_writeable(pgd);
     3.8 +        __make_page_writable(pgd);
     3.9  	free_page((unsigned long)pgd);
    3.10  #endif
    3.11  }
    3.12 @@ -154,7 +154,7 @@ static inline pte_t *pte_alloc_one_fast(
    3.13  static __inline__ void pte_free_slow(pte_t *pte)
    3.14  {
    3.15      queue_pte_unpin(__pa(pte));
    3.16 -    __make_page_writeable(pte);
    3.17 +    __make_page_writable(pte);
    3.18      free_page((unsigned long)pte);
    3.19  }
    3.20  
     4.1 --- a/linux-2.4.26-xen-sparse/include/asm-xen/pgtable.h	Fri Aug 20 18:19:24 2004 +0000
     4.2 +++ b/linux-2.4.26-xen-sparse/include/asm-xen/pgtable.h	Tue Aug 24 09:48:55 2004 +0000
     4.3 @@ -302,7 +302,7 @@ static inline void __make_page_readonly(
     4.4      queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
     4.5  }
     4.6  
     4.7 -static inline void __make_page_writeable(void *va)
     4.8 +static inline void __make_page_writable(void *va)
     4.9  {
    4.10      pgd_t *pgd = pgd_offset_k((unsigned long)va);
    4.11      pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
    4.12 @@ -321,14 +321,14 @@ static inline void make_page_readonly(vo
    4.13              *(unsigned long *)pte&PAGE_MASK));
    4.14  }
    4.15  
    4.16 -static inline void make_page_writeable(void *va)
    4.17 +static inline void make_page_writable(void *va)
    4.18  {
    4.19      pgd_t *pgd = pgd_offset_k((unsigned long)va);
    4.20      pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
    4.21      pte_t *pte = pte_offset(pmd, (unsigned long)va);
    4.22      queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
    4.23      if ( (unsigned long)va >= VMALLOC_START )
    4.24 -        __make_page_writeable(machine_to_virt(
    4.25 +        __make_page_writable(machine_to_virt(
    4.26              *(unsigned long *)pte&PAGE_MASK));
    4.27  }
    4.28  
    4.29 @@ -341,11 +341,11 @@ static inline void make_pages_readonly(v
    4.30      }
    4.31  }
    4.32  
    4.33 -static inline void make_pages_writeable(void *va, unsigned int nr)
    4.34 +static inline void make_pages_writable(void *va, unsigned int nr)
    4.35  {
    4.36      while ( nr-- != 0 )
    4.37      {
    4.38 -        make_page_writeable(va);
    4.39 +        make_page_writable(va);
    4.40          va = (void *)((unsigned long)va + PAGE_SIZE);
    4.41      }
    4.42  }
     5.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c	Fri Aug 20 18:19:24 2004 +0000
     5.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ldt.c	Tue Aug 24 09:48:55 2004 +0000
     5.3 @@ -71,7 +71,7 @@ static int alloc_ldt(mm_context_t *pc, i
     5.4  #endif
     5.5  	}
     5.6  	if (oldsize) {
     5.7 -		make_pages_writeable(oldldt, (oldsize * LDT_ENTRY_SIZE) /
     5.8 +		make_pages_writable(oldldt, (oldsize * LDT_ENTRY_SIZE) /
     5.9  			PAGE_SIZE);
    5.10  		flush_page_update_queue();
    5.11  		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
    5.12 @@ -121,9 +121,9 @@ void destroy_context(struct mm_struct *m
    5.13  	if (mm->context.size) {
    5.14  		if (mm == current->active_mm)
    5.15  			clear_LDT();
    5.16 -		make_pages_writeable(mm->context.ldt, 
    5.17 -				     (mm->context.size * LDT_ENTRY_SIZE) /
    5.18 -				     PAGE_SIZE);
    5.19 +		make_pages_writable(mm->context.ldt, 
    5.20 +                                    (mm->context.size * LDT_ENTRY_SIZE) /
    5.21 +                                    PAGE_SIZE);
    5.22  		flush_page_update_queue();
    5.23  		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
    5.24  			vfree(mm->context.ldt);
     6.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Fri Aug 20 18:19:24 2004 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Aug 24 09:48:55 2004 +0000
     6.3 @@ -1106,7 +1106,7 @@ void __init setup_arch(char **cmdline_p)
     6.4  			     VMASST_TYPE_4gb_segments);
     6.5  #ifdef CONFIG_XEN_WRITABLE_PAGETABLES
     6.6  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
     6.7 -			     VMASST_TYPE_writeable_pagetables);
     6.8 +			     VMASST_TYPE_writable_pagetables);
     6.9  #endif
    6.10  
    6.11  	pm_idle = xen_cpu_idle;
     7.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c	Fri Aug 20 18:19:24 2004 +0000
     7.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Aug 24 09:48:55 2004 +0000
     7.3 @@ -995,7 +995,7 @@ void __init trap_init(void)
     7.4   * ensures this end result (blow away the selector value) without the dangers
     7.5   * of the normal page-fault handler.
     7.6   * 
     7.7 - * NB. Perhaps this can all go away after we have implemented writeable
     7.8 + * NB. Perhaps this can all go away after we have implemented writable
     7.9   * page tables. :-)
    7.10   */
    7.11  
     8.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c	Fri Aug 20 18:19:24 2004 +0000
     8.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/mm/pgtable.c	Tue Aug 24 09:48:55 2004 +0000
     8.3 @@ -280,7 +280,7 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
     8.4  	unsigned long flags; /* can be called from interrupt context */
     8.5  
     8.6  	queue_pgd_unpin(__pa(pgd));
     8.7 -	__make_page_writeable(pgd);
     8.8 +	__make_page_writable(pgd);
     8.9  	flush_page_update_queue();
    8.10  
    8.11  	if (PTRS_PER_PMD > 1)
     9.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 20 18:19:24 2004 +0000
     9.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c	Tue Aug 24 09:48:55 2004 +0000
     9.3 @@ -98,7 +98,7 @@ static void __do_suspend(void)
     9.4  			 VMASST_TYPE_4gb_segments);
     9.5  #ifdef CONFIG_XEN_WRITABLE_PAGETABLES
     9.6      HYPERVISOR_vm_assist(VMASST_CMD_enable,
     9.7 -			 VMASST_TYPE_writeable_pagetables);
     9.8 +			 VMASST_TYPE_writable_pagetables);
     9.9  #endif
    9.10  
    9.11      shutting_down = -1; 
    10.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Fri Aug 20 18:19:24 2004 +0000
    10.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Tue Aug 24 09:48:55 2004 +0000
    10.3 @@ -32,7 +32,7 @@ extern struct page *pte_alloc_one(struct
    10.4  static inline void pte_free_kernel(pte_t *pte)
    10.5  {
    10.6  	free_page((unsigned long)pte);
    10.7 -	__make_page_writeable(pte);
    10.8 +	__make_page_writable(pte);
    10.9  }
   10.10  
   10.11  static inline void pte_free(struct page *pte)
   10.12 @@ -41,7 +41,7 @@ static inline void pte_free(struct page 
   10.13  	if (pte < highmem_start_page)
   10.14  #endif
   10.15  	{
   10.16 -		__make_page_writeable(phys_to_virt(page_to_pseudophys(pte)));
   10.17 +		__make_page_writable(phys_to_virt(page_to_pseudophys(pte)));
   10.18  		__free_page(pte);
   10.19  	}
   10.20  }
    11.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Fri Aug 20 18:19:24 2004 +0000
    11.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Tue Aug 24 09:48:55 2004 +0000
    11.3 @@ -281,7 +281,7 @@ static inline pte_t pte_modify(pte_t pte
    11.4  #define pmd_clear(xp)	do {					\
    11.5  	pmd_t p = *(xp);					\
    11.6  	set_pmd(xp, __pmd(0));					\
    11.7 -	__make_page_writeable((void *)pmd_page_kernel(p));	\
    11.8 +	__make_page_writable((void *)pmd_page_kernel(p));	\
    11.9  	/* XXXcl queue */ \
   11.10  } while (0)
   11.11  
   11.12 @@ -384,7 +384,7 @@ static inline void __make_page_readonly(
   11.13  	queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
   11.14  }
   11.15  
   11.16 -static inline void __make_page_writeable(void *va)
   11.17 +static inline void __make_page_writable(void *va)
   11.18  {
   11.19  	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   11.20  	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   11.21 @@ -404,14 +404,14 @@ static inline void make_page_readonly(vo
   11.22  	/* XXXcl queue */
   11.23  }
   11.24  
   11.25 -static inline void make_page_writeable(void *va)
   11.26 +static inline void make_page_writable(void *va)
   11.27  {
   11.28  	pgd_t *pgd = pgd_offset_k((unsigned long)va);
   11.29  	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
   11.30  	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
   11.31  	queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
   11.32  	if ( (unsigned long)va >= VMALLOC_START )
   11.33 -		__make_page_writeable(machine_to_virt(
   11.34 +		__make_page_writable(machine_to_virt(
   11.35  			*(unsigned long *)pte&PAGE_MASK));
   11.36  	/* XXXcl queue */
   11.37  }
   11.38 @@ -426,11 +426,11 @@ static inline void make_pages_readonly(v
   11.39  	/* XXXcl queue */
   11.40  }
   11.41  
   11.42 -static inline void make_pages_writeable(void *va, unsigned int nr)
   11.43 +static inline void make_pages_writable(void *va, unsigned int nr)
   11.44  {
   11.45  	while ( nr-- != 0 )
   11.46  	{
   11.47 -		make_page_writeable(va);
   11.48 +		make_page_writable(va);
   11.49  		va = (void *)((unsigned long)va + PAGE_SIZE);
   11.50  	}
   11.51  	/* XXXcl queue */
    12.1 --- a/xen/arch/x86/domain.c	Fri Aug 20 18:19:24 2004 +0000
    12.2 +++ b/xen/arch/x86/domain.c	Tue Aug 24 09:48:55 2004 +0000
    12.3 @@ -716,7 +716,7 @@ int construct_dom0(struct domain *p,
    12.4          
    12.5          page = &frame_table[mfn];
    12.6          set_bit(_PGC_tlb_flush_on_type_change, &page->u.inuse.count_info);
    12.7 -        if ( !get_page_and_type(page, p, PGT_writeable_page) )
    12.8 +        if ( !get_page_and_type(page, p, PGT_writable_page) )
    12.9              BUG();
   12.10  
   12.11          mfn++;
    13.1 --- a/xen/arch/x86/idle0_task.c	Fri Aug 20 18:19:24 2004 +0000
    13.2 +++ b/xen/arch/x86/idle0_task.c	Tue Aug 24 09:48:55 2004 +0000
    13.3 @@ -7,7 +7,6 @@
    13.4      processor:   0,              \
    13.5      domain:      IDLE_DOMAIN_ID, \
    13.6      mm:          IDLE0_MM,       \
    13.7 -    addr_limit:  KERNEL_DS,      \
    13.8      thread:      INIT_THREAD,    \
    13.9      flags:       1<<DF_IDLETASK, \
   13.10      refcnt:      ATOMIC_INIT(1)  \
    14.1 --- a/xen/arch/x86/memory.c	Fri Aug 20 18:19:24 2004 +0000
    14.2 +++ b/xen/arch/x86/memory.c	Tue Aug 24 09:48:55 2004 +0000
    14.3 @@ -38,7 +38,7 @@
    14.4   * 
    14.5   * TYPE_COUNT is more subtle. A frame can be put to one of three
    14.6   * mutually-exclusive uses: it might be used as a page directory, or a
    14.7 - * page table, or it may be mapped writeable by the domain [of course, a
    14.8 + * page table, or it may be mapped writable by the domain [of course, a
    14.9   * frame may not be used in any of these three ways!].
   14.10   * So, type_count is a count of the number of times a frame is being 
   14.11   * referred to in its current incarnation. Therefore, a page can only
   14.12 @@ -53,10 +53,10 @@
   14.13   * point safety checks would need to be carried out next time the count
   14.14   * is increased again.
   14.15   * 
   14.16 - * A further note on writeable page mappings:
   14.17 - * ------------------------------------------
   14.18 - * For simplicity, the count of writeable mappings for a page may not
   14.19 - * correspond to reality. The 'writeable count' is incremented for every
   14.20 + * A further note on writable page mappings:
   14.21 + * -----------------------------------------
   14.22 + * For simplicity, the count of writable mappings for a page may not
   14.23 + * correspond to reality. The 'writable count' is incremented for every
   14.24   * PTE which maps the page with the _PAGE_RW flag set. However, for
   14.25   * write access to be possible the page directory entry must also have
   14.26   * its _PAGE_RW bit set. We do not check this as it complicates the 
   14.27 @@ -70,12 +70,12 @@
   14.28   * -----------------------------------------
   14.29   * We want domains to be able to map pages for read-only access. The
   14.30   * main reason is that page tables and directories should be readable
   14.31 - * by a domain, but it would not be safe for them to be writeable.
   14.32 + * by a domain, but it would not be safe for them to be writable.
   14.33   * However, domains have free access to rings 1 & 2 of the Intel
   14.34   * privilege model. In terms of page protection, these are considered
   14.35   * to be part of 'supervisor mode'. The WP bit in CR0 controls whether
   14.36   * read-only restrictions are respected in supervisor mode -- if the 
   14.37 - * bit is clear then any mapped page is writeable.
   14.38 + * bit is clear then any mapped page is writable.
   14.39   * 
   14.40   * We get round this by always setting the WP bit and disallowing 
   14.41   * updates to it. This is very unlikely to cause a problem for guest
   14.42 @@ -143,12 +143,15 @@ static struct domain *dom_xen, *dom_io;
   14.43  void arch_init_memory(void)
   14.44  {
   14.45      static void ptwr_init_backpointers(void);
   14.46 +    static void ptwr_disable(void);
   14.47      unsigned long mfn;
   14.48  
   14.49      memset(percpu_info, 0, sizeof(percpu_info));
   14.50  
   14.51 -    vm_assist_info[VMASST_TYPE_writeable_pagetables].enable =
   14.52 +    vm_assist_info[VMASST_TYPE_writable_pagetables].enable =
   14.53          ptwr_init_backpointers;
   14.54 +    vm_assist_info[VMASST_TYPE_writable_pagetables].disable =
   14.55 +        ptwr_disable;
   14.56  
   14.57      /* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
   14.58      memset(machine_to_phys_mapping, 0x55, 4<<20);
   14.59 @@ -397,7 +400,7 @@ get_page_from_l1e(
   14.60      if ( l1v & _PAGE_RW )
   14.61      {
   14.62          if ( unlikely(!get_page_and_type_from_pagenr(
   14.63 -            pfn, PGT_writeable_page, d)) )
   14.64 +            pfn, PGT_writable_page, d)) )
   14.65              return 0;
   14.66          set_bit(_PGC_tlb_flush_on_type_change, 
   14.67                  &frame_table[pfn].u.inuse.count_info);
   14.68 @@ -1020,17 +1023,21 @@ int do_mmu_update(mmu_update_t *ureqs, i
   14.69      unsigned int cmd;
   14.70      unsigned long prev_spfn = 0;
   14.71      l1_pgentry_t *prev_spl1e = 0;
   14.72 +    struct domain *d = current;
   14.73  
   14.74      perfc_incrc(calls_to_mmu_update); 
   14.75      perfc_addc(num_page_updates, count);
   14.76  
   14.77 -    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
   14.78 +    cleanup_writable_pagetable(d, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
   14.79 +
   14.80 +    if ( unlikely(!access_ok(VERIFY_READ, ureqs, count * sizeof(req))) )
   14.81 +        return -EFAULT;
   14.82  
   14.83      for ( i = 0; i < count; i++ )
   14.84      {
   14.85 -        if ( unlikely(copy_from_user(&req, ureqs, sizeof(req)) != 0) )
   14.86 +        if ( unlikely(__copy_from_user(&req, ureqs, sizeof(req)) != 0) )
   14.87          {
   14.88 -            MEM_LOG("Bad copy_from_user");
   14.89 +            MEM_LOG("Bad __copy_from_user");
   14.90              rc = -EFAULT;
   14.91              break;
   14.92          }
   14.93 @@ -1073,13 +1080,13 @@ int do_mmu_update(mmu_update_t *ureqs, i
   14.94                      okay = mod_l1_entry((l1_pgentry_t *)va, 
   14.95                                          mk_l1_pgentry(req.val)); 
   14.96  
   14.97 -                    if ( okay && unlikely(current->mm.shadow_mode) &&
   14.98 -                         (get_shadow_status(&current->mm, page-frame_table) &
   14.99 +                    if ( unlikely(d->mm.shadow_mode) && okay &&
  14.100 +                         (get_shadow_status(&d->mm, page-frame_table) &
  14.101                            PSH_shadowed) )
  14.102                      {
  14.103 -                        shadow_l1_normal_pt_update( req.ptr, req.val, 
  14.104 -                                                    &prev_spfn, &prev_spl1e );
  14.105 -                        put_shadow_status(&current->mm);
  14.106 +                        shadow_l1_normal_pt_update(
  14.107 +                            req.ptr, req.val, &prev_spfn, &prev_spl1e);
  14.108 +                        put_shadow_status(&d->mm);
  14.109                      }
  14.110  
  14.111                      put_page_type(page);
  14.112 @@ -1092,19 +1099,19 @@ int do_mmu_update(mmu_update_t *ureqs, i
  14.113                                          mk_l2_pgentry(req.val),
  14.114                                          pfn); 
  14.115  
  14.116 -                    if ( okay && unlikely(current->mm.shadow_mode) &&
  14.117 -                         (get_shadow_status(&current->mm, page-frame_table) & 
  14.118 +                    if ( unlikely(d->mm.shadow_mode) && okay &&
  14.119 +                         (get_shadow_status(&d->mm, page-frame_table) & 
  14.120                            PSH_shadowed) )
  14.121                      {
  14.122 -                        shadow_l2_normal_pt_update( req.ptr, req.val );
  14.123 -                        put_shadow_status(&current->mm);
  14.124 +                        shadow_l2_normal_pt_update(req.ptr, req.val);
  14.125 +                        put_shadow_status(&d->mm);
  14.126                      }
  14.127  
  14.128                      put_page_type(page);
  14.129                  }
  14.130                  break;
  14.131              default:
  14.132 -                if ( likely(get_page_type(page, PGT_writeable_page)) )
  14.133 +                if ( likely(get_page_type(page, PGT_writable_page)) )
  14.134                  {
  14.135                      *(unsigned long *)va = req.val;
  14.136                      okay = 1;
  14.137 @@ -1114,7 +1121,6 @@ int do_mmu_update(mmu_update_t *ureqs, i
  14.138              }
  14.139  
  14.140              put_page(page);
  14.141 -
  14.142              break;
  14.143  
  14.144          case MMU_MACHPHYS_UPDATE:
  14.145 @@ -1131,8 +1137,8 @@ int do_mmu_update(mmu_update_t *ureqs, i
  14.146               * If in log-dirty mode, mark the corresponding pseudo-physical
  14.147               * page as dirty.
  14.148               */
  14.149 -            if ( unlikely(current->mm.shadow_mode == SHM_logdirty) )
  14.150 -                mark_dirty(&current->mm, pfn);
  14.151 +            if ( unlikely(d->mm.shadow_mode == SHM_logdirty) )
  14.152 +                mark_dirty(&d->mm, pfn);
  14.153  
  14.154              put_page(&frame_table[pfn]);
  14.155              break;
  14.156 @@ -1163,7 +1169,7 @@ int do_mmu_update(mmu_update_t *ureqs, i
  14.157      if ( prev_pfn != 0 )
  14.158          unmap_domain_mem((void *)va);
  14.159  
  14.160 -    if( prev_spl1e != 0 ) 
  14.161 +    if ( unlikely(prev_spl1e != 0) ) 
  14.162          unmap_domain_mem((void *)prev_spl1e);
  14.163  
  14.164      deferred_ops = percpu_info[cpu].deferred_ops;
  14.165 @@ -1171,7 +1177,7 @@ int do_mmu_update(mmu_update_t *ureqs, i
  14.166  
  14.167      if ( deferred_ops & DOP_FLUSH_TLB )
  14.168          local_flush_tlb();
  14.169 -
  14.170 +        
  14.171      if ( deferred_ops & DOP_RELOAD_LDT )
  14.172          (void)map_ldt_shadow_page(0);
  14.173  
  14.174 @@ -1192,9 +1198,9 @@ int do_update_va_mapping(unsigned long p
  14.175                           unsigned long val, 
  14.176                           unsigned long flags)
  14.177  {
  14.178 -    struct domain *p = current;
  14.179 +    struct domain *d = current;
  14.180      int err = 0;
  14.181 -    unsigned int cpu = p->processor;
  14.182 +    unsigned int cpu = d->processor;
  14.183      unsigned long deferred_ops;
  14.184  
  14.185      perfc_incrc(calls_to_update_va);
  14.186 @@ -1202,7 +1208,7 @@ int do_update_va_mapping(unsigned long p
  14.187      if ( unlikely(page_nr >= (HYPERVISOR_VIRT_START >> PAGE_SHIFT)) )
  14.188          return -EINVAL;
  14.189  
  14.190 -    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
  14.191 +    cleanup_writable_pagetable(d, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
  14.192  
  14.193      /*
  14.194       * XXX When we make this support 4MB superpages we should also deal with 
  14.195 @@ -1213,11 +1219,11 @@ int do_update_va_mapping(unsigned long p
  14.196                                  mk_l1_pgentry(val))) )
  14.197          err = -EINVAL;
  14.198  
  14.199 -    if ( unlikely(p->mm.shadow_mode) )
  14.200 +    if ( unlikely(d->mm.shadow_mode) )
  14.201      {
  14.202          unsigned long sval;
  14.203  
  14.204 -        l1pte_no_fault( &current->mm, &val, &sval );
  14.205 +        l1pte_no_fault(&d->mm, &val, &sval);
  14.206  
  14.207          if ( unlikely(__put_user(sval, ((unsigned long *)(
  14.208              &shadow_linear_pg_table[page_nr])))) )
  14.209 @@ -1234,10 +1240,10 @@ int do_update_va_mapping(unsigned long p
  14.210           * the PTE in the PT-holding page. We need the machine frame number
  14.211           * for this.
  14.212           */
  14.213 -        if ( p->mm.shadow_mode == SHM_logdirty )
  14.214 +        if ( d->mm.shadow_mode == SHM_logdirty )
  14.215              mark_dirty( &current->mm, va_to_l1mfn(page_nr<<PAGE_SHIFT) );  
  14.216    
  14.217 -        check_pagetable( p, p->mm.pagetable, "va" ); /* debug */
  14.218 +        check_pagetable(d, d->mm.pagetable, "va"); /* debug */
  14.219      }
  14.220  
  14.221      deferred_ops = percpu_info[cpu].deferred_ops;
  14.222 @@ -1267,8 +1273,6 @@ int do_update_va_mapping_otherdomain(uns
  14.223      if ( unlikely(!IS_PRIV(current)) )
  14.224          return -EPERM;
  14.225  
  14.226 -    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
  14.227 -
  14.228      percpu_info[cpu].foreign = d = find_domain_by_id(domid);
  14.229      if ( unlikely(d == NULL) )
  14.230      {
  14.231 @@ -1576,6 +1580,11 @@ static void ptwr_init_backpointers(void)
  14.232      }
  14.233  }
  14.234  
  14.235 +static void ptwr_disable(void)
  14.236 +{
  14.237 +    __cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
  14.238 +}
  14.239 +
  14.240  #ifndef NDEBUG
  14.241  void ptwr_status(void)
  14.242  {
    15.1 --- a/xen/arch/x86/traps.c	Fri Aug 20 18:19:24 2004 +0000
    15.2 +++ b/xen/arch/x86/traps.c	Tue Aug 24 09:48:55 2004 +0000
    15.3 @@ -328,17 +328,19 @@ asmlinkage void do_page_fault(struct pt_
    15.4              return; /* successfully copied the mapping */
    15.5      }
    15.6  
    15.7 -    if ( (addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected )
    15.8 +    if ( unlikely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
    15.9      {
   15.10 -        ptwr_reconnect_disconnected(addr);
   15.11 -        return;
   15.12 -    }
   15.13 +        if ( (addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected )
   15.14 +        {
   15.15 +            ptwr_reconnect_disconnected(addr);
   15.16 +            return;
   15.17 +        }
   15.18  
   15.19 -    if ( VM_ASSIST(d, VMASST_TYPE_writeable_pagetables) && 
   15.20 -         (addr < PAGE_OFFSET) &&
   15.21 -         ((error_code & 3) == 3) && /* write-protection fault */
   15.22 -         ptwr_do_page_fault(addr) )
   15.23 -        return;
   15.24 +        if ( (addr < PAGE_OFFSET) &&
   15.25 +             ((error_code & 3) == 3) && /* write-protection fault */
   15.26 +             ptwr_do_page_fault(addr) )
   15.27 +            return;
   15.28 +    }
   15.29  
   15.30      if ( unlikely(d->mm.shadow_mode) && 
   15.31           (addr < PAGE_OFFSET) && shadow_fault(addr, error_code) )
    16.1 --- a/xen/arch/x86/x86_32/entry.S	Fri Aug 20 18:19:24 2004 +0000
    16.2 +++ b/xen/arch/x86/x86_32/entry.S	Tue Aug 24 09:48:55 2004 +0000
    16.3 @@ -718,8 +718,9 @@ ENTRY(hypercall_table)
    16.4          .long SYMBOL_NAME(do_xen_version)
    16.5          .long SYMBOL_NAME(do_console_io)
    16.6          .long SYMBOL_NAME(do_physdev_op)
    16.7 -        .long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 20 */
    16.8 +        .long SYMBOL_NAME(do_grant_table_op)     /* 20 */
    16.9          .long SYMBOL_NAME(do_vm_assist)
   16.10 +        .long SYMBOL_NAME(do_update_va_mapping_otherdomain)
   16.11          .rept NR_hypercalls-((.-hypercall_table)/4)
   16.12          .long SYMBOL_NAME(do_ni_hypercall)
   16.13          .endr
    17.1 --- a/xen/arch/x86/x86_32/mm.c	Fri Aug 20 18:19:24 2004 +0000
    17.2 +++ b/xen/arch/x86/x86_32/mm.c	Tue Aug 24 09:48:55 2004 +0000
    17.3 @@ -357,7 +357,7 @@ long do_update_descriptor(
    17.4              goto out;
    17.5          break;
    17.6      default:
    17.7 -        if ( unlikely(!get_page_type(page, PGT_writeable_page)) )
    17.8 +        if ( unlikely(!get_page_type(page, PGT_writable_page)) )
    17.9              goto out;
   17.10          break;
   17.11      }
    18.1 --- a/xen/arch/x86/x86_32/usercopy.c	Fri Aug 20 18:19:24 2004 +0000
    18.2 +++ b/xen/arch/x86/x86_32/usercopy.c	Tue Aug 24 09:48:55 2004 +0000
    18.3 @@ -6,62 +6,21 @@
    18.4   * Copyright 1997 Linus Torvalds
    18.5   */
    18.6  #include <xen/config.h>
    18.7 +#include <xen/mm.h>
    18.8  #include <asm/uaccess.h>
    18.9 -//#include <asm/mmx.h>
   18.10 -
   18.11 -#ifdef CONFIG_X86_USE_3DNOW_AND_WORKS
   18.12  
   18.13 -unsigned long
   18.14 -__generic_copy_to_user(void *to, const void *from, unsigned long n)
   18.15 -{
   18.16 -	if (access_ok(VERIFY_WRITE, to, n))
   18.17 -	{
   18.18 -		if(n<512)
   18.19 -			__copy_user(to,from,n);
   18.20 -		else
   18.21 -			mmx_copy_user(to,from,n);
   18.22 -	}
   18.23 -	return n;
   18.24 -}
   18.25 +#define might_sleep() ((void)0)
   18.26  
   18.27 -unsigned long
   18.28 -__generic_copy_from_user(void *to, const void *from, unsigned long n)
   18.29 +static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n)
   18.30  {
   18.31 -	if (access_ok(VERIFY_READ, from, n))
   18.32 -	{
   18.33 -		if(n<512)
   18.34 -			__copy_user_zeroing(to,from,n);
   18.35 -		else
   18.36 -			mmx_copy_user_zeroing(to, from, n);
   18.37 -	}
   18.38 -	else
   18.39 -		memset(to, 0, n);
   18.40 -	return n;
   18.41 +#ifdef CONFIG_X86_INTEL_USERCOPY
   18.42 +	if (n >= 64 && ((a1 ^ a2) & movsl_mask.mask))
   18.43 +		return 0;
   18.44 +#endif
   18.45 +	return 1;
   18.46  }
   18.47 -
   18.48 -#else
   18.49 -
   18.50 -unsigned long
   18.51 -__generic_copy_to_user(void *to, const void *from, unsigned long n)
   18.52 -{
   18.53 -	prefetch(from);
   18.54 -	if (access_ok(VERIFY_WRITE, to, n))
   18.55 -		__copy_user(to,from,n);
   18.56 -	return n;
   18.57 -}
   18.58 -
   18.59 -unsigned long
   18.60 -__generic_copy_from_user(void *to, const void *from, unsigned long n)
   18.61 -{
   18.62 -	prefetchw(to);
   18.63 -	if (access_ok(VERIFY_READ, from, n))
   18.64 -		__copy_user_zeroing(to,from,n);
   18.65 -	else
   18.66 -		memset(to, 0, n);
   18.67 -	return n;
   18.68 -}
   18.69 -
   18.70 -#endif
   18.71 +#define movsl_is_ok(a1,a2,n) \
   18.72 +	__movsl_is_ok((unsigned long)(a1),(unsigned long)(a2),(n))
   18.73  
   18.74  /*
   18.75   * Copy a null terminated string from userspace.
   18.76 @@ -95,16 +54,54 @@ do {									   \
   18.77  		: "memory");						   \
   18.78  } while (0)
   18.79  
   18.80 +/**
   18.81 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
   18.82 + * @dst:   Destination address, in kernel space.  This buffer must be at
   18.83 + *         least @count bytes long.
   18.84 + * @src:   Source address, in user space.
   18.85 + * @count: Maximum number of bytes to copy, including the trailing NUL.
   18.86 + * 
   18.87 + * Copies a NUL-terminated string from userspace to kernel space.
   18.88 + * Caller must check the specified block with access_ok() before calling
   18.89 + * this function.
   18.90 + *
   18.91 + * On success, returns the length of the string (not including the trailing
   18.92 + * NUL).
   18.93 + *
   18.94 + * If access to userspace fails, returns -EFAULT (some data may have been
   18.95 + * copied).
   18.96 + *
   18.97 + * If @count is smaller than the length of the string, copies @count bytes
   18.98 + * and returns @count.
   18.99 + */
  18.100  long
  18.101 -__strncpy_from_user(char *dst, const char *src, long count)
  18.102 +__strncpy_from_user(char *dst, const char __user *src, long count)
  18.103  {
  18.104  	long res;
  18.105  	__do_strncpy_from_user(dst, src, count, res);
  18.106  	return res;
  18.107  }
  18.108  
  18.109 +/**
  18.110 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
  18.111 + * @dst:   Destination address, in kernel space.  This buffer must be at
  18.112 + *         least @count bytes long.
  18.113 + * @src:   Source address, in user space.
  18.114 + * @count: Maximum number of bytes to copy, including the trailing NUL.
  18.115 + * 
  18.116 + * Copies a NUL-terminated string from userspace to kernel space.
  18.117 + *
  18.118 + * On success, returns the length of the string (not including the trailing
  18.119 + * NUL).
  18.120 + *
  18.121 + * If access to userspace fails, returns -EFAULT (some data may have been
  18.122 + * copied).
  18.123 + *
  18.124 + * If @count is smaller than the length of the string, copies @count bytes
  18.125 + * and returns @count.
  18.126 + */
  18.127  long
  18.128 -strncpy_from_user(char *dst, const char *src, long count)
  18.129 +strncpy_from_user(char *dst, const char __user *src, long count)
  18.130  {
  18.131  	long res = -EFAULT;
  18.132  	if (access_ok(VERIFY_READ, src, 1))
  18.133 @@ -138,32 +135,61 @@ do {									\
  18.134  		: "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));	\
  18.135  } while (0)
  18.136  
  18.137 +/**
  18.138 + * clear_user: - Zero a block of memory in user space.
  18.139 + * @to:   Destination address, in user space.
  18.140 + * @n:    Number of bytes to zero.
  18.141 + *
  18.142 + * Zero a block of memory in user space.
  18.143 + *
  18.144 + * Returns number of bytes that could not be cleared.
  18.145 + * On success, this will be zero.
  18.146 + */
  18.147  unsigned long
  18.148 -clear_user(void *to, unsigned long n)
  18.149 +clear_user(void __user *to, unsigned long n)
  18.150  {
  18.151 +	might_sleep();
  18.152  	if (access_ok(VERIFY_WRITE, to, n))
  18.153  		__do_clear_user(to, n);
  18.154  	return n;
  18.155  }
  18.156  
  18.157 +/**
  18.158 + * __clear_user: - Zero a block of memory in user space, with less checking.
  18.159 + * @to:   Destination address, in user space.
  18.160 + * @n:    Number of bytes to zero.
  18.161 + *
  18.162 + * Zero a block of memory in user space.  Caller must check
  18.163 + * the specified block with access_ok() before calling this function.
  18.164 + *
  18.165 + * Returns number of bytes that could not be cleared.
  18.166 + * On success, this will be zero.
  18.167 + */
  18.168  unsigned long
  18.169 -__clear_user(void *to, unsigned long n)
  18.170 +__clear_user(void __user *to, unsigned long n)
  18.171  {
  18.172  	__do_clear_user(to, n);
  18.173  	return n;
  18.174  }
  18.175  
  18.176 -/*
  18.177 - * Return the size of a string (including the ending 0)
  18.178 +/**
  18.179 + * strlen_user: - Get the size of a string in user space.
  18.180 + * @s: The string to measure.
  18.181 + * @n: The maximum valid length
  18.182   *
  18.183 - * Return 0 on exception, a value greater than N if too long
  18.184 + * Get the size of a NUL-terminated string in user space.
  18.185 + *
  18.186 + * Returns the size of the string INCLUDING the terminating NUL.
  18.187 + * On exception, returns 0.
  18.188 + * If the string is too long, returns a value greater than @n.
  18.189   */
  18.190 -
  18.191 -long strnlen_user(const char *s, long n)
  18.192 +long strnlen_user(const char __user *s, long n)
  18.193  {
  18.194  	unsigned long mask = -__addr_ok(s);
  18.195  	unsigned long res, tmp;
  18.196  
  18.197 +	might_sleep();
  18.198 +
  18.199  	__asm__ __volatile__(
  18.200  		"	testl %0, %0\n"
  18.201  		"	jz 3f\n"
  18.202 @@ -188,3 +214,366 @@ long strnlen_user(const char *s, long n)
  18.203  		:"cc");
  18.204  	return res & mask;
  18.205  }
  18.206 +
  18.207 +#ifdef CONFIG_X86_INTEL_USERCOPY
  18.208 +static unsigned long
  18.209 +__copy_user_intel(void __user *to, const void *from, unsigned long size)
  18.210 +{
  18.211 +	int d0, d1;
  18.212 +	__asm__ __volatile__(
  18.213 +		       "       .align 2,0x90\n"
  18.214 +		       "1:     movl 32(%4), %%eax\n"
  18.215 +		       "       cmpl $67, %0\n"
  18.216 +		       "       jbe 3f\n"
  18.217 +		       "2:     movl 64(%4), %%eax\n"
  18.218 +		       "       .align 2,0x90\n"
  18.219 +		       "3:     movl 0(%4), %%eax\n"
  18.220 +		       "4:     movl 4(%4), %%edx\n"
  18.221 +		       "5:     movl %%eax, 0(%3)\n"
  18.222 +		       "6:     movl %%edx, 4(%3)\n"
  18.223 +		       "7:     movl 8(%4), %%eax\n"
  18.224 +		       "8:     movl 12(%4),%%edx\n"
  18.225 +		       "9:     movl %%eax, 8(%3)\n"
  18.226 +		       "10:    movl %%edx, 12(%3)\n"
  18.227 +		       "11:    movl 16(%4), %%eax\n"
  18.228 +		       "12:    movl 20(%4), %%edx\n"
  18.229 +		       "13:    movl %%eax, 16(%3)\n"
  18.230 +		       "14:    movl %%edx, 20(%3)\n"
  18.231 +		       "15:    movl 24(%4), %%eax\n"
  18.232 +		       "16:    movl 28(%4), %%edx\n"
  18.233 +		       "17:    movl %%eax, 24(%3)\n"
  18.234 +		       "18:    movl %%edx, 28(%3)\n"
  18.235 +		       "19:    movl 32(%4), %%eax\n"
  18.236 +		       "20:    movl 36(%4), %%edx\n"
  18.237 +		       "21:    movl %%eax, 32(%3)\n"
  18.238 +		       "22:    movl %%edx, 36(%3)\n"
  18.239 +		       "23:    movl 40(%4), %%eax\n"
  18.240 +		       "24:    movl 44(%4), %%edx\n"
  18.241 +		       "25:    movl %%eax, 40(%3)\n"
  18.242 +		       "26:    movl %%edx, 44(%3)\n"
  18.243 +		       "27:    movl 48(%4), %%eax\n"
  18.244 +		       "28:    movl 52(%4), %%edx\n"
  18.245 +		       "29:    movl %%eax, 48(%3)\n"
  18.246 +		       "30:    movl %%edx, 52(%3)\n"
  18.247 +		       "31:    movl 56(%4), %%eax\n"
  18.248 +		       "32:    movl 60(%4), %%edx\n"
  18.249 +		       "33:    movl %%eax, 56(%3)\n"
  18.250 +		       "34:    movl %%edx, 60(%3)\n"
  18.251 +		       "       addl $-64, %0\n"
  18.252 +		       "       addl $64, %4\n"
  18.253 +		       "       addl $64, %3\n"
  18.254 +		       "       cmpl $63, %0\n"
  18.255 +		       "       ja  1b\n"
  18.256 +		       "35:    movl  %0, %%eax\n"
  18.257 +		       "       shrl  $2, %0\n"
  18.258 +		       "       andl  $3, %%eax\n"
  18.259 +		       "       cld\n"
  18.260 +		       "99:    rep; movsl\n"
  18.261 +		       "36:    movl %%eax, %0\n"
  18.262 +		       "37:    rep; movsb\n"
  18.263 +		       "100:\n"
  18.264 +		       ".section .fixup,\"ax\"\n"
  18.265 +		       "101:   lea 0(%%eax,%0,4),%0\n"
  18.266 +		       "       jmp 100b\n"
  18.267 +		       ".previous\n"
  18.268 +		       ".section __ex_table,\"a\"\n"
  18.269 +		       "       .align 4\n"
  18.270 +		       "       .long 1b,100b\n"
  18.271 +		       "       .long 2b,100b\n"
  18.272 +		       "       .long 3b,100b\n"
  18.273 +		       "       .long 4b,100b\n"
  18.274 +		       "       .long 5b,100b\n"
  18.275 +		       "       .long 6b,100b\n"
  18.276 +		       "       .long 7b,100b\n"
  18.277 +		       "       .long 8b,100b\n"
  18.278 +		       "       .long 9b,100b\n"
  18.279 +		       "       .long 10b,100b\n"
  18.280 +		       "       .long 11b,100b\n"
  18.281 +		       "       .long 12b,100b\n"
  18.282 +		       "       .long 13b,100b\n"
  18.283 +		       "       .long 14b,100b\n"
  18.284 +		       "       .long 15b,100b\n"
  18.285 +		       "       .long 16b,100b\n"
  18.286 +		       "       .long 17b,100b\n"
  18.287 +		       "       .long 18b,100b\n"
  18.288 +		       "       .long 19b,100b\n"
  18.289 +		       "       .long 20b,100b\n"
  18.290 +		       "       .long 21b,100b\n"
  18.291 +		       "       .long 22b,100b\n"
  18.292 +		       "       .long 23b,100b\n"
  18.293 +		       "       .long 24b,100b\n"
  18.294 +		       "       .long 25b,100b\n"
  18.295 +		       "       .long 26b,100b\n"
  18.296 +		       "       .long 27b,100b\n"
  18.297 +		       "       .long 28b,100b\n"
  18.298 +		       "       .long 29b,100b\n"
  18.299 +		       "       .long 30b,100b\n"
  18.300 +		       "       .long 31b,100b\n"
  18.301 +		       "       .long 32b,100b\n"
  18.302 +		       "       .long 33b,100b\n"
  18.303 +		       "       .long 34b,100b\n"
  18.304 +		       "       .long 35b,100b\n"
  18.305 +		       "       .long 36b,100b\n"
  18.306 +		       "       .long 37b,100b\n"
  18.307 +		       "       .long 99b,101b\n"
  18.308 +		       ".previous"
  18.309 +		       : "=&c"(size), "=&D" (d0), "=&S" (d1)
  18.310 +		       :  "1"(to), "2"(from), "0"(size)
  18.311 +		       : "eax", "edx", "memory");
  18.312 +	return size;
  18.313 +}
  18.314 +
  18.315 +static unsigned long
  18.316 +__copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size)
  18.317 +{
  18.318 +	int d0, d1;
  18.319 +	__asm__ __volatile__(
  18.320 +		       "        .align 2,0x90\n"
  18.321 +		       "0:      movl 32(%4), %%eax\n"
  18.322 +		       "        cmpl $67, %0\n"      
  18.323 +		       "        jbe 2f\n"            
  18.324 +		       "1:      movl 64(%4), %%eax\n"
  18.325 +		       "        .align 2,0x90\n"     
  18.326 +		       "2:      movl 0(%4), %%eax\n" 
  18.327 +		       "21:     movl 4(%4), %%edx\n" 
  18.328 +		       "        movl %%eax, 0(%3)\n" 
  18.329 +		       "        movl %%edx, 4(%3)\n" 
  18.330 +		       "3:      movl 8(%4), %%eax\n" 
  18.331 +		       "31:     movl 12(%4),%%edx\n" 
  18.332 +		       "        movl %%eax, 8(%3)\n" 
  18.333 +		       "        movl %%edx, 12(%3)\n"
  18.334 +		       "4:      movl 16(%4), %%eax\n"
  18.335 +		       "41:     movl 20(%4), %%edx\n"
  18.336 +		       "        movl %%eax, 16(%3)\n"
  18.337 +		       "        movl %%edx, 20(%3)\n"
  18.338 +		       "10:     movl 24(%4), %%eax\n"
  18.339 +		       "51:     movl 28(%4), %%edx\n"
  18.340 +		       "        movl %%eax, 24(%3)\n"
  18.341 +		       "        movl %%edx, 28(%3)\n"
  18.342 +		       "11:     movl 32(%4), %%eax\n"
  18.343 +		       "61:     movl 36(%4), %%edx\n"
  18.344 +		       "        movl %%eax, 32(%3)\n"
  18.345 +		       "        movl %%edx, 36(%3)\n"
  18.346 +		       "12:     movl 40(%4), %%eax\n"
  18.347 +		       "71:     movl 44(%4), %%edx\n"
  18.348 +		       "        movl %%eax, 40(%3)\n"
  18.349 +		       "        movl %%edx, 44(%3)\n"
  18.350 +		       "13:     movl 48(%4), %%eax\n"
  18.351 +		       "81:     movl 52(%4), %%edx\n"
  18.352 +		       "        movl %%eax, 48(%3)\n"
  18.353 +		       "        movl %%edx, 52(%3)\n"
  18.354 +		       "14:     movl 56(%4), %%eax\n"
  18.355 +		       "91:     movl 60(%4), %%edx\n"
  18.356 +		       "        movl %%eax, 56(%3)\n"
  18.357 +		       "        movl %%edx, 60(%3)\n"
  18.358 +		       "        addl $-64, %0\n"     
  18.359 +		       "        addl $64, %4\n"      
  18.360 +		       "        addl $64, %3\n"      
  18.361 +		       "        cmpl $63, %0\n"      
  18.362 +		       "        ja  0b\n"            
  18.363 +		       "5:      movl  %0, %%eax\n"   
  18.364 +		       "        shrl  $2, %0\n"      
  18.365 +		       "        andl $3, %%eax\n"    
  18.366 +		       "        cld\n"               
  18.367 +		       "6:      rep; movsl\n"   
  18.368 +		       "        movl %%eax,%0\n"
  18.369 +		       "7:      rep; movsb\n"	
  18.370 +		       "8:\n"			
  18.371 +		       ".section .fixup,\"ax\"\n"
  18.372 +		       "9:      lea 0(%%eax,%0,4),%0\n"	
  18.373 +		       "16:     pushl %0\n"	
  18.374 +		       "        pushl %%eax\n"	
  18.375 +		       "        xorl %%eax,%%eax\n"
  18.376 +		       "        rep; stosb\n"	
  18.377 +		       "        popl %%eax\n"	
  18.378 +		       "        popl %0\n"	
  18.379 +		       "        jmp 8b\n"	
  18.380 +		       ".previous\n"		
  18.381 +		       ".section __ex_table,\"a\"\n"
  18.382 +		       "	.align 4\n"	   
  18.383 +		       "	.long 0b,16b\n"	 
  18.384 +		       "	.long 1b,16b\n"
  18.385 +		       "	.long 2b,16b\n"
  18.386 +		       "	.long 21b,16b\n"
  18.387 +		       "	.long 3b,16b\n"	
  18.388 +		       "	.long 31b,16b\n"
  18.389 +		       "	.long 4b,16b\n"	
  18.390 +		       "	.long 41b,16b\n"
  18.391 +		       "	.long 10b,16b\n"
  18.392 +		       "	.long 51b,16b\n"
  18.393 +		       "	.long 11b,16b\n"
  18.394 +		       "	.long 61b,16b\n"
  18.395 +		       "	.long 12b,16b\n"
  18.396 +		       "	.long 71b,16b\n"
  18.397 +		       "	.long 13b,16b\n"
  18.398 +		       "	.long 81b,16b\n"
  18.399 +		       "	.long 14b,16b\n"
  18.400 +		       "	.long 91b,16b\n"
  18.401 +		       "	.long 6b,9b\n"	
  18.402 +		       "        .long 7b,16b\n" 
  18.403 +		       ".previous"		
  18.404 +		       : "=&c"(size), "=&D" (d0), "=&S" (d1)
  18.405 +		       :  "1"(to), "2"(from), "0"(size)
  18.406 +		       : "eax", "edx", "memory");
  18.407 +	return size;
  18.408 +}
  18.409 +#else
  18.410 +/*
  18.411 + * Leave these declared but undefined.  They should not be any references to
  18.412 + * them
  18.413 + */
  18.414 +unsigned long
  18.415 +__copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size);
  18.416 +unsigned long
  18.417 +__copy_user_intel(void __user *to, const void *from, unsigned long size);
  18.418 +#endif /* CONFIG_X86_INTEL_USERCOPY */
  18.419 +
  18.420 +/* Generic arbitrary sized copy.  */
  18.421 +#define __copy_user(to,from,size)					\
  18.422 +do {									\
  18.423 +	int __d0, __d1, __d2;						\
  18.424 +	__asm__ __volatile__(						\
  18.425 +		"	cmp  $7,%0\n"					\
  18.426 +		"	jbe  1f\n"					\
  18.427 +		"	movl %1,%0\n"					\
  18.428 +		"	negl %0\n"					\
  18.429 +		"	andl $7,%0\n"					\
  18.430 +		"	subl %0,%3\n"					\
  18.431 +		"4:	rep; movsb\n"					\
  18.432 +		"	movl %3,%0\n"					\
  18.433 +		"	shrl $2,%0\n"					\
  18.434 +		"	andl $3,%3\n"					\
  18.435 +		"	.align 2,0x90\n"				\
  18.436 +		"0:	rep; movsl\n"					\
  18.437 +		"	movl %3,%0\n"					\
  18.438 +		"1:	rep; movsb\n"					\
  18.439 +		"2:\n"							\
  18.440 +		".section .fixup,\"ax\"\n"				\
  18.441 +		"5:	addl %3,%0\n"					\
  18.442 +		"	jmp 2b\n"					\
  18.443 +		"3:	lea 0(%3,%0,4),%0\n"				\
  18.444 +		"	jmp 2b\n"					\
  18.445 +		".previous\n"						\
  18.446 +		".section __ex_table,\"a\"\n"				\
  18.447 +		"	.align 4\n"					\
  18.448 +		"	.long 4b,5b\n"					\
  18.449 +		"	.long 0b,3b\n"					\
  18.450 +		"	.long 1b,2b\n"					\
  18.451 +		".previous"						\
  18.452 +		: "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)	\
  18.453 +		: "3"(size), "0"(size), "1"(to), "2"(from)		\
  18.454 +		: "memory");						\
  18.455 +} while (0)
  18.456 +
  18.457 +#define __copy_user_zeroing(to,from,size)				\
  18.458 +do {									\
  18.459 +	int __d0, __d1, __d2;						\
  18.460 +	__asm__ __volatile__(						\
  18.461 +		"	cmp  $7,%0\n"					\
  18.462 +		"	jbe  1f\n"					\
  18.463 +		"	movl %1,%0\n"					\
  18.464 +		"	negl %0\n"					\
  18.465 +		"	andl $7,%0\n"					\
  18.466 +		"	subl %0,%3\n"					\
  18.467 +		"4:	rep; movsb\n"					\
  18.468 +		"	movl %3,%0\n"					\
  18.469 +		"	shrl $2,%0\n"					\
  18.470 +		"	andl $3,%3\n"					\
  18.471 +		"	.align 2,0x90\n"				\
  18.472 +		"0:	rep; movsl\n"					\
  18.473 +		"	movl %3,%0\n"					\
  18.474 +		"1:	rep; movsb\n"					\
  18.475 +		"2:\n"							\
  18.476 +		".section .fixup,\"ax\"\n"				\
  18.477 +		"5:	addl %3,%0\n"					\
  18.478 +		"	jmp 6f\n"					\
  18.479 +		"3:	lea 0(%3,%0,4),%0\n"				\
  18.480 +		"6:	pushl %0\n"					\
  18.481 +		"	pushl %%eax\n"					\
  18.482 +		"	xorl %%eax,%%eax\n"				\
  18.483 +		"	rep; stosb\n"					\
  18.484 +		"	popl %%eax\n"					\
  18.485 +		"	popl %0\n"					\
  18.486 +		"	jmp 2b\n"					\
  18.487 +		".previous\n"						\
  18.488 +		".section __ex_table,\"a\"\n"				\
  18.489 +		"	.align 4\n"					\
  18.490 +		"	.long 4b,5b\n"					\
  18.491 +		"	.long 0b,3b\n"					\
  18.492 +		"	.long 1b,6b\n"					\
  18.493 +		".previous"						\
  18.494 +		: "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)	\
  18.495 +		: "3"(size), "0"(size), "1"(to), "2"(from)		\
  18.496 +		: "memory");						\
  18.497 +} while (0)
  18.498 +
  18.499 +
  18.500 +unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n)
  18.501 +{
  18.502 +	if (movsl_is_ok(to, from, n))
  18.503 +		__copy_user(to, from, n);
  18.504 +	else
  18.505 +		n = __copy_user_intel(to, from, n);
  18.506 +	return n;
  18.507 +}
  18.508 +
  18.509 +unsigned long
  18.510 +__copy_from_user_ll(void *to, const void __user *from, unsigned long n)
  18.511 +{
  18.512 +	if (movsl_is_ok(to, from, n))
  18.513 +		__copy_user_zeroing(to, from, n);
  18.514 +	else
  18.515 +		n = __copy_user_zeroing_intel(to, from, n);
  18.516 +	return n;
  18.517 +}
  18.518 +
  18.519 +/**
  18.520 + * copy_to_user: - Copy a block of data into user space.
  18.521 + * @to:   Destination address, in user space.
  18.522 + * @from: Source address, in kernel space.
  18.523 + * @n:    Number of bytes to copy.
  18.524 + *
  18.525 + * Context: User context only.  This function may sleep.
  18.526 + *
  18.527 + * Copy data from kernel space to user space.
  18.528 + *
  18.529 + * Returns number of bytes that could not be copied.
  18.530 + * On success, this will be zero.
  18.531 + */
  18.532 +unsigned long
  18.533 +copy_to_user(void __user *to, const void *from, unsigned long n)
  18.534 +{
  18.535 +	might_sleep();
  18.536 +	if (access_ok(VERIFY_WRITE, to, n))
  18.537 +		n = __copy_to_user(to, from, n);
  18.538 +	return n;
  18.539 +}
  18.540 +EXPORT_SYMBOL(copy_to_user);
  18.541 +
  18.542 +/**
  18.543 + * copy_from_user: - Copy a block of data from user space.
  18.544 + * @to:   Destination address, in kernel space.
  18.545 + * @from: Source address, in user space.
  18.546 + * @n:    Number of bytes to copy.
  18.547 + *
  18.548 + * Context: User context only.  This function may sleep.
  18.549 + *
  18.550 + * Copy data from user space to kernel space.
  18.551 + *
  18.552 + * Returns number of bytes that could not be copied.
  18.553 + * On success, this will be zero.
  18.554 + *
  18.555 + * If some data could not be copied, this function will pad the copied
  18.556 + * data to the requested size using zero bytes.
  18.557 + */
  18.558 +unsigned long
  18.559 +copy_from_user(void *to, const void __user *from, unsigned long n)
  18.560 +{
  18.561 +	might_sleep();
  18.562 +	if (access_ok(VERIFY_READ, from, n))
  18.563 +		n = __copy_from_user(to, from, n);
  18.564 +	else
  18.565 +		memset(to, 0, n);
  18.566 +	return n;
  18.567 +}
  18.568 +EXPORT_SYMBOL(copy_from_user);
    19.1 --- a/xen/common/dom_mem_ops.c	Fri Aug 20 18:19:24 2004 +0000
    19.2 +++ b/xen/common/dom_mem_ops.c	Tue Aug 24 09:48:55 2004 +0000
    19.3 @@ -23,6 +23,10 @@ static long alloc_dom_mem(struct domain 
    19.4      struct pfn_info *page;
    19.5      unsigned long    i;
    19.6  
    19.7 +    if ( unlikely(!access_ok(VERIFY_WRITE, extent_list, 
    19.8 +                             nr_extents*sizeof(*extent_list))) )
    19.9 +        return 0;
   19.10 +
   19.11      if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current) )
   19.12      {
   19.13          DPRINTK("Only I/O-capable domains may allocate > order-0 memory.\n");
   19.14 @@ -38,7 +42,7 @@ static long alloc_dom_mem(struct domain 
   19.15          }
   19.16  
   19.17          /* Inform the domain of the new page's machine address. */ 
   19.18 -        if ( unlikely(put_user(page_to_pfn(page), &extent_list[i]) != 0) )
   19.19 +        if ( unlikely(__put_user(page_to_pfn(page), &extent_list[i]) != 0) )
   19.20              return i;
   19.21      }
   19.22  
   19.23 @@ -53,9 +57,13 @@ static long free_dom_mem(struct domain *
   19.24      struct pfn_info *page;
   19.25      unsigned long    i, j, mpfn;
   19.26  
   19.27 +    if ( unlikely(!access_ok(VERIFY_READ, extent_list, 
   19.28 +                             nr_extents*sizeof(*extent_list))) )
   19.29 +        return 0;
   19.30 +
   19.31      for ( i = 0; i < nr_extents; i++ )
   19.32      {
   19.33 -        if ( unlikely(get_user(mpfn, &extent_list[i]) != 0) )
   19.34 +        if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
   19.35              return i;
   19.36  
   19.37          for ( j = 0; j < (1 << extent_order); j++ )
    20.1 --- a/xen/common/domain.c	Fri Aug 20 18:19:24 2004 +0000
    20.2 +++ b/xen/common/domain.c	Tue Aug 24 09:48:55 2004 +0000
    20.3 @@ -65,8 +65,6 @@ struct domain *do_createdomain(domid_t d
    20.4          strncpy(d->name, buf, MAX_DOMAIN_NAME);
    20.5          d->name[MAX_DOMAIN_NAME-1] = '\0';
    20.6  
    20.7 -        d->addr_limit = USER_DS;
    20.8 -        
    20.9  	arch_do_createdomain(d);
   20.10  
   20.11          sched_add_domain(d);
    21.1 --- a/xen/common/grant_table.c	Fri Aug 20 18:19:24 2004 +0000
    21.2 +++ b/xen/common/grant_table.c	Tue Aug 24 09:48:55 2004 +0000
    21.3 @@ -21,58 +21,141 @@
    21.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    21.5   */
    21.6  
    21.7 -#define __GRANT_TABLE_IMPLEMENTATION__
    21.8 -typedef struct grant_table grant_table_t;
    21.9 -
   21.10  #include <xen/config.h>
   21.11  #include <xen/sched.h>
   21.12 -#include <hypervisor-ifs/grant_table.h>
   21.13 +
   21.14 +#define update_shared_flags(x,y,z) (0)
   21.15 +
   21.16 +static long gnttab_update_pin_status(gnttab_update_pin_status_t *uop)
   21.17 +{
   21.18 +    domid_t        dom, sdom;
   21.19 +    grant_ref_t    ref;
   21.20 +    u16            pin_flags;
   21.21 +    struct domain *ld, *rd;
   21.22 +    u32            sflags;
   21.23 +    active_grant_entry_t *act;
   21.24 +    grant_entry_t *sha;
   21.25 +    long           rc = 0;
   21.26 +
   21.27 +    ld = current;
   21.28 +
   21.29 +    if ( unlikely(__get_user(dom, &uop->dom)) || 
   21.30 +         unlikely(__get_user(ref, &uop->ref)) ||
   21.31 +         unlikely(__get_user(pin_flags, &uop->pin_flags)) )
   21.32 +        return -EFAULT;
   21.33 +
   21.34 +    pin_flags &= (GNTPIN_dev_accessible | 
   21.35 +                  GNTPIN_host_accessible |
   21.36 +                  GNTPIN_readonly);
   21.37 +
   21.38 +    if ( unlikely(ref >= NR_GRANT_ENTRIES) || 
   21.39 +         unlikely(pin_flags == GNTPIN_readonly) )
   21.40 +        return -EINVAL;
   21.41  
   21.42 -/* Active grant entry - used for shadowing GTF_permit_access grants. */
   21.43 -typedef struct {
   21.44 -    u32           counts; /* Reference count information.   */
   21.45 -    u16           next;   /* Mapping hash chain.            */
   21.46 -    domid_t       domid;  /* Domain being granted access.   */
   21.47 -    unsigned long frame;  /* Frame being granted.           */
   21.48 -} active_grant_entry_t;
   21.49 +    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) )
   21.50 +        return -ESRCH;
   21.51 +
   21.52 +    act = &rd->grant_table->active[ref];
   21.53 +    sha = &rd->grant_table->shared[ref];
   21.54 +
   21.55 +    if ( act->status == 0 )
   21.56 +    {
   21.57 +        if ( unlikely(pin_flags == 0) )
   21.58 +            goto out;
   21.59 +
   21.60 +        sflags = sha->flags;
   21.61 +        sdom   = sha->domid;
   21.62 +
   21.63 +        do {
   21.64 +            if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
   21.65 +                 unlikely(sdom != ld->domain) )
   21.66 +            {
   21.67 +            }
   21.68 +        
   21.69 +            sflags |= GTF_reading;
   21.70 +            if ( !(pin_flags & GNTPIN_readonly) )
   21.71 +            {
   21.72 +                sflags |= GTF_writing;
   21.73 +                if ( unlikely(sflags & GTF_readonly) )
   21.74 +                {
   21.75 +                }
   21.76 +            }
   21.77 +        }
   21.78 +        while ( !update_shared_flags(sha, sflags, sdom) );
   21.79 +
   21.80 +        act->status = pin_flags;
   21.81 +        act->domid  = sdom;
   21.82  
   21.83 -/* Bitfields in active_grant_entry_t:counts. */
   21.84 - /* Grant is pinned by 'domid' for read mappings and I/O. */
   21.85 -#define _GNTCNT_read_pinned  (0)
   21.86 -#define GNTCNT_read_pinned   (1<<_GNTCNT_read_pinned)
   21.87 - /* Grant is pinned by 'domid' for write mappings and I/O. */
   21.88 -#define _GNTCNT_write_pinned (1)
   21.89 -#define GNTCNT_write_pinned  (1<<_GNTCNT_write_pinned)
   21.90 - /* Grant is pinned in IOMMU (read-only unless GNTCNT_write_pinned). */
   21.91 -#define _GNTCNT_io_pinned    (2)
   21.92 -#define GNTCNT_io_pinned     (1<<_GNTCNT_io_pinned)
   21.93 - /* Grant is mappable (read-only unless GNTCNT_write_pinned). */
   21.94 -#define _GNTCNT_mappable     (3)
   21.95 -#define GNTCNT_mappable      (1<<_GNTCNT_mappable)
   21.96 - /* Count of writable page mappings. (!GNTCNT_write_pinned => count==0). */
   21.97 -#define GNTCNT_wmap_shift    (4)
   21.98 -#define GNTCNT_wmap_mask     (0x3FFFU << GNTCNT_wmap_shift)
   21.99 - /* Count of read-only page mappings. */
  21.100 -#define GNTCNT_rmap_shift    (18)
  21.101 -#define GNTCNT_rmap_mask     (0x3FFFU << GNTCNT_rmap_shift)
  21.102 +        /* XXX MAP XXX */
  21.103 +    }
  21.104 +    else if ( pin_flags == 0 )
  21.105 +    {
  21.106 +        if ( unlikely((act->status & 
  21.107 +                       (GNTPIN_wmap_mask|GNTPIN_rmap_mask)) != 0) )
  21.108 +        {
  21.109 +        }
  21.110 +
  21.111 +        clear_bit(_GTF_writing, &sha->flags);
  21.112 +        clear_bit(_GTF_reading, &sha->flags);
  21.113 +
  21.114 +        act->status = 0;
  21.115 +
  21.116 +        /* XXX UNMAP XXX */
  21.117 +    }
  21.118 +    else 
  21.119 +    {
  21.120 +        if ( pin_flags & GNTPIN_readonly )
  21.121 +        {
  21.122 +            if ( !(act->status & GNTPIN_readonly) )
  21.123 +            {
  21.124 +            }
  21.125 +        }
  21.126 +        else if ( act->status & GNTPIN_readonly )
  21.127 +        {
  21.128 +        }
  21.129  
  21.130 -#define MAPHASH_SZ       (256)
  21.131 -#define MAPHASH(_k)      ((_k) & (MAPHASH_SZ-1))
  21.132 -#define MAPHASH_INVALID  (0xFFFFU)
  21.133 +        if ( pin_flags & GNTPIN_host_accessible )
  21.134 +        {
  21.135 +            if ( !(act->status & GNTPIN_host_accessible) )
  21.136 +            {
  21.137 +                /* XXX MAP XXX */
  21.138 +            }
  21.139 +        }
  21.140 +        else if ( act->status & GNTPIN_host_accessible )
  21.141 +        {
  21.142 +            /* XXX UNMAP XXX */
  21.143 +        }
  21.144  
  21.145 -#define NR_GRANT_ENTRIES     (PAGE_SIZE / sizeof(grant_entry_t))
  21.146 +        act->status &= ~GNTPIN_dev_accessible;
  21.147 +        act->status |= pin_flags & GNTPIN_dev_accessible; 
  21.148 +    }
  21.149 +
  21.150 + out:
  21.151 +    put_domain(rd);
  21.152 +    return rc;
  21.153 +}
  21.154  
  21.155 -/* Per-domain grant information. */
  21.156 -struct grant_table {
  21.157 -    /* Shared grant table (see include/hypervisor-ifs/grant_table.h). */
  21.158 -    grant_entry_t        *shared;
  21.159 -    /* Active grant table. */
  21.160 -    active_grant_entry_t *active;
  21.161 -    /* Lock protecting updates to maphash and shared grant table. */
  21.162 -    spinlock_t            lock;
  21.163 -    /* Hash table: frame -> active grant entry. */
  21.164 -    u16                   maphash[MAPHASH_SZ];
  21.165 -};
  21.166 +long do_grant_table_op(gnttab_op_t *uop)
  21.167 +{
  21.168 +    long rc;
  21.169 +    u32  cmd;
  21.170 +
  21.171 +    if ( unlikely(!access_ok(VERIFY_WRITE, uop, sizeof(*uop))) ||
  21.172 +         unlikely(__get_user(cmd, &uop->cmd)) )
  21.173 +        return -EFAULT;
  21.174 +
  21.175 +    switch ( cmd )
  21.176 +    {
  21.177 +    case GNTTABOP_update_pin_status:
  21.178 +        rc = gnttab_update_pin_status(&uop->u.update_pin_status);
  21.179 +        break;
  21.180 +    default:
  21.181 +        rc = -ENOSYS;
  21.182 +        break;
  21.183 +    }
  21.184 +
  21.185 +    return rc;
  21.186 +}
  21.187  
  21.188  int grant_table_create(struct domain *d)
  21.189  {
  21.190 @@ -86,8 +169,8 @@ int grant_table_create(struct domain *d)
  21.191      t->shared = NULL;
  21.192      t->active = NULL;
  21.193      spin_lock_init(&t->lock);
  21.194 -    for ( i = 0; i < MAPHASH_SZ; i++ )
  21.195 -        t->maphash[i] = MAPHASH_INVALID;
  21.196 +    for ( i = 0; i < GNT_MAPHASH_SZ; i++ )
  21.197 +        t->maphash[i] = GNT_MAPHASH_INVALID;
  21.198  
  21.199      /* Active grant-table page. */
  21.200      if ( (t->active = xmalloc(sizeof(active_grant_entry_t) * 
    22.1 --- a/xen/common/schedule.c	Fri Aug 20 18:19:24 2004 +0000
    22.2 +++ b/xen/common/schedule.c	Tue Aug 24 09:48:55 2004 +0000
    22.3 @@ -371,7 +371,8 @@ void __enter_scheduler(void)
    22.4      if ( unlikely(prev == next) )
    22.5          return;
    22.6      
    22.7 -    cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
    22.8 +    cleanup_writable_pagetable(
    22.9 +        prev, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
   22.10  
   22.11  #ifdef PTWR_TRACK_DOMAIN
   22.12      {
    23.1 --- a/xen/include/asm-x86/mm.h	Fri Aug 20 18:19:24 2004 +0000
    23.2 +++ b/xen/include/asm-x86/mm.h	Tue Aug 24 09:48:55 2004 +0000
    23.3 @@ -67,7 +67,7 @@ struct pfn_info
    23.4  #define PGT_l4_page_table   (4<<29) /* using this page as an L4 page table? */
    23.5  #define PGT_gdt_page        (5<<29) /* using this page in a GDT? */
    23.6  #define PGT_ldt_page        (6<<29) /* using this page in an LDT? */
    23.7 -#define PGT_writeable_page  (7<<29) /* has writable mappings of this page? */
    23.8 +#define PGT_writable_page   (7<<29) /* has writable mappings of this page? */
    23.9  #define PGT_type_mask       (7<<29) /* Bits 29-31. */
   23.10   /* Has this page been validated for use as its current type? */
   23.11  #define _PGT_validated      28
   23.12 @@ -101,8 +101,8 @@ struct pfn_info
   23.13  #define SHARE_PFN_WITH_DOMAIN(_pfn, _dom)                                   \
   23.14      do {                                                                    \
   23.15          (_pfn)->u.inuse.domain = (_dom);                                    \
   23.16 -        /* The incremented type count is intended to pin to 'writeable'. */ \
   23.17 -        (_pfn)->u.inuse.type_info  = PGT_writeable_page | PGT_validated | 1;\
   23.18 +        /* The incremented type count is intended to pin to 'writable'. */  \
   23.19 +        (_pfn)->u.inuse.type_info  = PGT_writable_page | PGT_validated | 1; \
   23.20          wmb(); /* install valid domain ptr before updating refcnt. */       \
   23.21          spin_lock(&(_dom)->page_alloc_lock);                                \
   23.22          /* _dom holds an allocation reference */                            \
   23.23 @@ -221,8 +221,8 @@ static inline int get_page_type(struct p
   23.24              {
   23.25                  nx &= ~(PGT_type_mask | PGT_validated);
   23.26                  nx |= type;
   23.27 -                /* No extra validation needed for writeable pages. */
   23.28 -                if ( type == PGT_writeable_page )
   23.29 +                /* No extra validation needed for writable pages. */
   23.30 +                if ( type == PGT_writable_page )
   23.31                      nx |= PGT_validated;
   23.32              }
   23.33          }
   23.34 @@ -364,7 +364,7 @@ void ptwr_reconnect_disconnected(unsigne
   23.35  void ptwr_flush_inactive(void);
   23.36  int ptwr_do_page_fault(unsigned long);
   23.37  
   23.38 -static inline void cleanup_writable_pagetable(const int what)
   23.39 +static inline void __cleanup_writable_pagetable(const int what)
   23.40  {
   23.41      int cpu = smp_processor_id();
   23.42  
   23.43 @@ -376,4 +376,10 @@ static inline void cleanup_writable_page
   23.44              ptwr_flush_inactive();
   23.45  }
   23.46  
   23.47 +static inline void cleanup_writable_pagetable(struct domain *d, const int what)
   23.48 +{
   23.49 +    if ( unlikely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
   23.50 +        __cleanup_writable_pagetable(what);
   23.51 +}
   23.52 +
   23.53  #endif /* __ASM_X86_MM_H__ */
    24.1 --- a/xen/include/asm-x86/processor.h	Fri Aug 20 18:19:24 2004 +0000
    24.2 +++ b/xen/include/asm-x86/processor.h	Tue Aug 24 09:48:55 2004 +0000
    24.3 @@ -244,10 +244,6 @@ struct i387_state {
    24.4      u8 state[512]; /* big enough for FXSAVE */
    24.5  } __attribute__ ((aligned (16)));
    24.6  
    24.7 -typedef struct {
    24.8 -    unsigned long seg;
    24.9 -} mm_segment_t;
   24.10 -
   24.11  struct tss_struct {
   24.12      unsigned short	back_link,__blh;
   24.13  #ifdef __x86_64__
    25.1 --- a/xen/include/asm-x86/x86_32/uaccess.h	Fri Aug 20 18:19:24 2004 +0000
    25.2 +++ b/xen/include/asm-x86/x86_32/uaccess.h	Tue Aug 24 09:48:55 2004 +0000
    25.3 @@ -6,54 +6,65 @@
    25.4   */
    25.5  #include <xen/config.h>
    25.6  #include <xen/errno.h>
    25.7 +#include <xen/prefetch.h>
    25.8 +#include <xen/string.h>
    25.9  #include <xen/sched.h>
   25.10 -#include <xen/prefetch.h>
   25.11 -#include <asm/page.h>
   25.12 +
   25.13 +/* No user-pointer checking. */
   25.14 +#define __user
   25.15 +#define __chk_user_ptr(_p) ((void)0)
   25.16  
   25.17  #define VERIFY_READ 0
   25.18  #define VERIFY_WRITE 1
   25.19  
   25.20  /*
   25.21 - * The fs value determines whether argument validity checking should be
   25.22 - * performed or not.  If get_fs() == USER_DS, checking is performed, with
   25.23 - * get_fs() == KERNEL_DS, checking is bypassed.
   25.24 - *
   25.25 - * For historical reasons, these macros are grossly misnamed.
   25.26 + * movsl can be slow when source and dest are not both 8-byte aligned
   25.27   */
   25.28 -
   25.29 -#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
   25.30 -
   25.31 +#ifdef CONFIG_X86_INTEL_USERCOPY
   25.32 +extern struct movsl_mask {
   25.33 +	int mask;
   25.34 +} ____cacheline_aligned_in_smp movsl_mask;
   25.35 +#endif
   25.36  
   25.37 -#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
   25.38 -#define USER_DS		MAKE_MM_SEG(PAGE_OFFSET)
   25.39 -
   25.40 -#define get_ds()	(KERNEL_DS)
   25.41 -#define get_fs()	(current->addr_limit)
   25.42 -#define set_fs(x)	(current->addr_limit = (x))
   25.43 -
   25.44 -#define segment_eq(a,b)	((a).seg == (b).seg)
   25.45 -
   25.46 -extern int __verify_write(const void *, unsigned long);
   25.47 -
   25.48 -#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
   25.49 +#define __addr_ok(addr) ((unsigned long)(addr) < HYPERVISOR_VIRT_START)
   25.50  
   25.51  /*
   25.52 - * Uhhuh, this needs 33-bit arithmetic. We have a carry..
   25.53 + * Test whether a block of memory is a valid user space address.
   25.54 + * Returns 0 if the range is valid, nonzero otherwise.
   25.55 + *
   25.56 + * This is equivalent to the following test:
   25.57 + * (u33)addr + (u33)size >= (u33)HYPERVISOR_VIRT_START
   25.58 + *
   25.59 + * This needs 33-bit arithmetic. We have a carry...
   25.60   */
   25.61  #define __range_ok(addr,size) ({ \
   25.62  	unsigned long flag,sum; \
   25.63 +	__chk_user_ptr(addr); \
   25.64  	asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
   25.65  		:"=&r" (flag), "=r" (sum) \
   25.66 -		:"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \
   25.67 +		:"1" (addr),"g" ((int)(size)),"r" (HYPERVISOR_VIRT_START)); \
   25.68  	flag; })
   25.69  
   25.70 -#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
   25.71 -
   25.72 -static inline int verify_area(int type, const void * addr, unsigned long size)
   25.73 -{
   25.74 -	return access_ok(type,addr,size) ? 0 : -EFAULT;
   25.75 -}
   25.76 -
   25.77 +/**
   25.78 + * access_ok: - Checks if a user space pointer is valid
   25.79 + * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
   25.80 + *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
   25.81 + *        to write to a block, it is always safe to read from it.
   25.82 + * @addr: User space pointer to start of block to check
   25.83 + * @size: Size of block to check
   25.84 + *
   25.85 + * Context: User context only.  This function may sleep.
   25.86 + *
   25.87 + * Checks if a pointer to a block of memory in user space is valid.
   25.88 + *
   25.89 + * Returns true (nonzero) if the memory block may be valid, false (zero)
   25.90 + * if it is definitely invalid.
   25.91 + *
   25.92 + * Note that, depending on architecture, this function probably just
   25.93 + * checks that the pointer is in the user space range - after calling
   25.94 + * this function, memory access functions may still return -EFAULT.
   25.95 + */
   25.96 +#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
   25.97  
   25.98  /*
   25.99   * The exception table consists of pairs of addresses: the first is the
  25.100 @@ -73,81 +84,110 @@ struct exception_table_entry
  25.101  	unsigned long insn, fixup;
  25.102  };
  25.103  
  25.104 -/* Returns 0 if exception not found and fixup otherwise.  */
  25.105  extern unsigned long search_exception_table(unsigned long);
  25.106  
  25.107 -
  25.108 -/*
  25.109 - * These are the main single-value transfer routines.  They automatically
  25.110 - * use the right size if we just have the right pointer type.
  25.111 +/**
  25.112 + * get_user: - Get a simple variable from user space.
  25.113 + * @x:   Variable to store result.
  25.114 + * @ptr: Source address, in user space.
  25.115 + *
  25.116 + * Context: User context only.  This function may sleep.
  25.117   *
  25.118 - * This gets kind of ugly. We want to return _two_ values in "get_user()"
  25.119 - * and yet we don't want to do any pointers, because that is too much
  25.120 - * of a performance impact. Thus we have a few rather ugly macros here,
  25.121 - * and hide all the uglyness from the user.
  25.122 + * This macro copies a single simple variable from user space to kernel
  25.123 + * space.  It supports simple types like char and int, but not larger
  25.124 + * data types like structures or arrays.
  25.125   *
  25.126 - * The "__xxx" versions of the user access functions are versions that
  25.127 - * do not verify the address space, that must have been done previously
  25.128 - * with a separate "access_ok()" call (this is used when we do multiple
  25.129 - * accesses to the same area of user memory).
  25.130 + * @ptr must have pointer-to-simple-variable type, and the result of
  25.131 + * dereferencing @ptr must be assignable to @x without a cast.
  25.132 + *
  25.133 + * Returns zero on success, or -EFAULT on error.
  25.134 + * On error, the variable @x is set to zero.
  25.135   */
  25.136 -
  25.137 -extern void __get_user_1(void);
  25.138 -extern void __get_user_2(void);
  25.139 -extern void __get_user_4(void);
  25.140 -
  25.141 -#define __get_user_x(size,ret,x,ptr) \
  25.142 -	__asm__ __volatile__("call __get_user_" #size \
  25.143 -		:"=a" (ret),"=d" (x) \
  25.144 -		:"0" (ptr))
  25.145 -
  25.146 -/* Careful: we have to cast the result to the type of the pointer for sign reasons */
  25.147 -#define get_user(x,ptr)							\
  25.148 -({	int __ret_gu=1,__val_gu;						\
  25.149 -	switch(sizeof (*(ptr))) {					\
  25.150 -	case 1: __ret_gu=copy_from_user(&__val_gu,ptr,1); break;			\
  25.151 -	case 2: __ret_gu=copy_from_user(&__val_gu,ptr,2); break;                 \
  25.152 -	case 4: __ret_gu=copy_from_user(&__val_gu,ptr,4); break;                 \
  25.153 -	default: __ret_gu=copy_from_user(&__val_gu,ptr,8); break;                 \
  25.154 -	/*case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;*/		\
  25.155 -	/*case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;*/		\
  25.156 -	/*case 4:  __get_user_x(4,__ret_gu,__val_gu,ptr); break;*/		\
  25.157 -	/*default: __get_user_x(X,__ret_gu,__val_gu,ptr); break;*/		\
  25.158 -	}								\
  25.159 -	(x) = (__typeof__(*(ptr)))__val_gu;				\
  25.160 -	__ret_gu;							\
  25.161 -})
  25.162 -
  25.163 -extern void __put_user_1(void);
  25.164 -extern void __put_user_2(void);
  25.165 -extern void __put_user_4(void);
  25.166 -extern void __put_user_8(void);
  25.167 +#define get_user(x,ptr)	\
  25.168 +  __get_user_check((x),(ptr),sizeof(*(ptr)))
  25.169  
  25.170  extern void __put_user_bad(void);
  25.171  
  25.172 +/**
  25.173 + * put_user: - Write a simple value into user space.
  25.174 + * @x:   Value to copy to user space.
  25.175 + * @ptr: Destination address, in user space.
  25.176 + *
  25.177 + * Context: User context only.  This function may sleep.
  25.178 + *
  25.179 + * This macro copies a single simple value from kernel space to user
  25.180 + * space.  It supports simple types like char and int, but not larger
  25.181 + * data types like structures or arrays.
  25.182 + *
  25.183 + * @ptr must have pointer-to-simple-variable type, and @x must be assignable
  25.184 + * to the result of dereferencing @ptr.
  25.185 + *
  25.186 + * Returns zero on success, or -EFAULT on error.
  25.187 + */
  25.188  #define put_user(x,ptr)							\
  25.189    __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  25.190  
  25.191 +
  25.192 +/**
  25.193 + * __get_user: - Get a simple variable from user space, with less checking.
  25.194 + * @x:   Variable to store result.
  25.195 + * @ptr: Source address, in user space.
  25.196 + *
  25.197 + * Context: User context only.  This function may sleep.
  25.198 + *
  25.199 + * This macro copies a single simple variable from user space to kernel
  25.200 + * space.  It supports simple types like char and int, but not larger
  25.201 + * data types like structures or arrays.
  25.202 + *
  25.203 + * @ptr must have pointer-to-simple-variable type, and the result of
  25.204 + * dereferencing @ptr must be assignable to @x without a cast.
  25.205 + *
  25.206 + * Caller must check the pointer with access_ok() before calling this
  25.207 + * function.
  25.208 + *
  25.209 + * Returns zero on success, or -EFAULT on error.
  25.210 + * On error, the variable @x is set to zero.
  25.211 + */
  25.212  #define __get_user(x,ptr) \
  25.213    __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  25.214 +
  25.215 +
  25.216 +/**
  25.217 + * __put_user: - Write a simple value into user space, with less checking.
  25.218 + * @x:   Value to copy to user space.
  25.219 + * @ptr: Destination address, in user space.
  25.220 + *
  25.221 + * Context: User context only.  This function may sleep.
  25.222 + *
  25.223 + * This macro copies a single simple value from kernel space to user
  25.224 + * space.  It supports simple types like char and int, but not larger
  25.225 + * data types like structures or arrays.
  25.226 + *
  25.227 + * @ptr must have pointer-to-simple-variable type, and @x must be assignable
  25.228 + * to the result of dereferencing @ptr.
  25.229 + *
  25.230 + * Caller must check the pointer with access_ok() before calling this
  25.231 + * function.
  25.232 + *
  25.233 + * Returns zero on success, or -EFAULT on error.
  25.234 + */
  25.235  #define __put_user(x,ptr) \
  25.236    __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  25.237  
  25.238 -#define __put_user_nocheck(x,ptr,size)			\
  25.239 -({							\
  25.240 -	long __pu_err;					\
  25.241 -	__put_user_size((x),(ptr),(size),__pu_err);	\
  25.242 -	__pu_err;					\
  25.243 +#define __put_user_nocheck(x,ptr,size)				\
  25.244 +({								\
  25.245 +	long __pu_err;						\
  25.246 +	__put_user_size((x),(ptr),(size),__pu_err,-EFAULT);	\
  25.247 +	__pu_err;						\
  25.248  })
  25.249  
  25.250 -
  25.251 -#define __put_user_check(x,ptr,size)			\
  25.252 -({							\
  25.253 +#define __put_user_check(x,ptr,size)					\
  25.254 +({									\
  25.255  	long __pu_err = -EFAULT;					\
  25.256 -	__typeof__(*(ptr)) *__pu_addr = (ptr);		\
  25.257 -	if (access_ok(VERIFY_WRITE,__pu_addr,size))	\
  25.258 -		__put_user_size((x),__pu_addr,(size),__pu_err);	\
  25.259 -	__pu_err;					\
  25.260 +	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
  25.261 +	if (__addr_ok(__pu_addr))					\
  25.262 +		__put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT);	\
  25.263 +	__pu_err;							\
  25.264  })							
  25.265  
  25.266  #define __put_user_u64(x, addr, err)				\
  25.267 @@ -167,18 +207,33 @@ extern void __put_user_bad(void);
  25.268  		: "=r"(err)					\
  25.269  		: "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
  25.270  
  25.271 -#define __put_user_size(x,ptr,size,retval)				\
  25.272 +#ifdef CONFIG_X86_WP_WORKS_OK
  25.273 +
  25.274 +#define __put_user_size(x,ptr,size,retval,errret)			\
  25.275  do {									\
  25.276  	retval = 0;							\
  25.277 +	__chk_user_ptr(ptr);						\
  25.278  	switch (size) {							\
  25.279 -	  case 1: __put_user_asm(x,ptr,retval,"b","b","iq"); break;	\
  25.280 -	  case 2: __put_user_asm(x,ptr,retval,"w","w","ir"); break;	\
  25.281 -	  case 4: __put_user_asm(x,ptr,retval,"l","","ir"); break;	\
  25.282 -	  case 8: __put_user_u64(x,ptr,retval); break;			\
  25.283 +	case 1: __put_user_asm(x,ptr,retval,"b","b","iq",errret);break;	\
  25.284 +	case 2: __put_user_asm(x,ptr,retval,"w","w","ir",errret);break; \
  25.285 +	case 4: __put_user_asm(x,ptr,retval,"l","","ir",errret); break;	\
  25.286 +	case 8: __put_user_u64((__typeof__(*ptr))(x),ptr,retval); break;\
  25.287  	  default: __put_user_bad();					\
  25.288  	}								\
  25.289  } while (0)
  25.290  
  25.291 +#else
  25.292 +
  25.293 +#define __put_user_size(x,ptr,size,retval,errret)			\
  25.294 +do {									\
  25.295 +	__typeof__(*(ptr)) __pus_tmp = x;				\
  25.296 +	retval = 0;							\
  25.297 +									\
  25.298 +	if(unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0))	\
  25.299 +		retval = errret;					\
  25.300 +} while (0)
  25.301 +
  25.302 +#endif
  25.303  struct __large_struct { unsigned long buf[100]; };
  25.304  #define __m(x) (*(struct __large_struct *)(x))
  25.305  
  25.306 @@ -187,414 +242,178 @@ struct __large_struct { unsigned long bu
  25.307   * we do not write to any memory gcc knows about, so there are no
  25.308   * aliasing issues.
  25.309   */
  25.310 -#define __put_user_asm(x, addr, err, itype, rtype, ltype)	\
  25.311 -	__asm__ __volatile__(					\
  25.312 -		"1:	mov"itype" %"rtype"1,%2\n"		\
  25.313 -		"2:\n"						\
  25.314 -		".section .fixup,\"ax\"\n"			\
  25.315 -		"3:	movl %3,%0\n"				\
  25.316 -		"	jmp 2b\n"				\
  25.317 -		".previous\n"					\
  25.318 -		".section __ex_table,\"a\"\n"			\
  25.319 -		"	.align 4\n"				\
  25.320 -		"	.long 1b,3b\n"				\
  25.321 -		".previous"					\
  25.322 -		: "=r"(err)					\
  25.323 -		: ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err))
  25.324 +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
  25.325 +	__asm__ __volatile__(						\
  25.326 +		"1:	mov"itype" %"rtype"1,%2\n"			\
  25.327 +		"2:\n"							\
  25.328 +		".section .fixup,\"ax\"\n"				\
  25.329 +		"3:	movl %3,%0\n"					\
  25.330 +		"	jmp 2b\n"					\
  25.331 +		".previous\n"						\
  25.332 +		".section __ex_table,\"a\"\n"				\
  25.333 +		"	.align 4\n"					\
  25.334 +		"	.long 1b,3b\n"					\
  25.335 +		".previous"						\
  25.336 +		: "=r"(err)						\
  25.337 +		: ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
  25.338  
  25.339  
  25.340  #define __get_user_nocheck(x,ptr,size)				\
  25.341  ({								\
  25.342  	long __gu_err, __gu_val;				\
  25.343 -	__get_user_size(__gu_val,(ptr),(size),__gu_err);	\
  25.344 +	__get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
  25.345  	(x) = (__typeof__(*(ptr)))__gu_val;			\
  25.346  	__gu_err;						\
  25.347  })
  25.348  
  25.349 +#define __get_user_check(x,ptr,size)					\
  25.350 +({									\
  25.351 +	long __gu_err, __gu_val;					\
  25.352 +	__typeof__(*(ptr)) __user *__gu_addr = (ptr);			\
  25.353 +	__get_user_size(__gu_val,__gu_addr,(size),__gu_err,-EFAULT);	\
  25.354 +	(x) = (__typeof__(*(ptr)))__gu_val;				\
  25.355 +	if (!__addr_ok(__gu_addr)) __gu_err = -EFAULT;			\
  25.356 +	__gu_err;							\
  25.357 +})							
  25.358 +
  25.359  extern long __get_user_bad(void);
  25.360  
  25.361 -#define __get_user_size(x,ptr,size,retval)				\
  25.362 +#define __get_user_size(x,ptr,size,retval,errret)			\
  25.363  do {									\
  25.364  	retval = 0;							\
  25.365 +	__chk_user_ptr(ptr);						\
  25.366  	switch (size) {							\
  25.367 -	  case 1: __get_user_asm(x,ptr,retval,"b","b","=q"); break;	\
  25.368 -	  case 2: __get_user_asm(x,ptr,retval,"w","w","=r"); break;	\
  25.369 -	  case 4: __get_user_asm(x,ptr,retval,"l","","=r"); break;	\
  25.370 -	  default: (x) = __get_user_bad();				\
  25.371 +	case 1: __get_user_asm(x,ptr,retval,"b","b","=q",errret);break;	\
  25.372 +	case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break;	\
  25.373 +	case 4: __get_user_asm(x,ptr,retval,"l","","=r",errret);break;	\
  25.374 +	default: (x) = __get_user_bad();				\
  25.375  	}								\
  25.376  } while (0)
  25.377  
  25.378 -#define __get_user_asm(x, addr, err, itype, rtype, ltype)	\
  25.379 -	__asm__ __volatile__(					\
  25.380 -		"1:	mov"itype" %2,%"rtype"1\n"		\
  25.381 -		"2:\n"						\
  25.382 -		".section .fixup,\"ax\"\n"			\
  25.383 -		"3:	movl %3,%0\n"				\
  25.384 -		"	xor"itype" %"rtype"1,%"rtype"1\n"	\
  25.385 -		"	jmp 2b\n"				\
  25.386 -		".previous\n"					\
  25.387 -		".section __ex_table,\"a\"\n"			\
  25.388 -		"	.align 4\n"				\
  25.389 -		"	.long 1b,3b\n"				\
  25.390 -		".previous"					\
  25.391 -		: "=r"(err), ltype (x)				\
  25.392 -		: "m"(__m(addr)), "i"(-EFAULT), "0"(err))
  25.393 -
  25.394 -
  25.395 -/*
  25.396 - * Copy To/From Userspace
  25.397 - */
  25.398 -
  25.399 -/* Generic arbitrary sized copy.  */
  25.400 -#define __copy_user(to,from,size)					\
  25.401 -do {									\
  25.402 -	int __d0, __d1;							\
  25.403 +#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
  25.404  	__asm__ __volatile__(						\
  25.405 -		"0:	rep; movsl\n"					\
  25.406 -		"	movl %3,%0\n"					\
  25.407 -		"1:	rep; movsb\n"					\
  25.408 +		"1:	mov"itype" %2,%"rtype"1\n"			\
  25.409  		"2:\n"							\
  25.410  		".section .fixup,\"ax\"\n"				\
  25.411 -		"3:	lea 0(%3,%0,4),%0\n"				\
  25.412 -		"	jmp 2b\n"					\
  25.413 -		".previous\n"						\
  25.414 -		".section __ex_table,\"a\"\n"				\
  25.415 -		"	.align 4\n"					\
  25.416 -		"	.long 0b,3b\n"					\
  25.417 -		"	.long 1b,2b\n"					\
  25.418 -		".previous"						\
  25.419 -		: "=&c"(size), "=&D" (__d0), "=&S" (__d1)		\
  25.420 -		: "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)	\
  25.421 -		: "memory");						\
  25.422 -} while (0)
  25.423 -
  25.424 -#define __copy_user_zeroing(to,from,size)				\
  25.425 -do {									\
  25.426 -	int __d0, __d1;							\
  25.427 -	__asm__ __volatile__(						\
  25.428 -		"0:	rep; movsl\n"					\
  25.429 -		"	movl %3,%0\n"					\
  25.430 -		"1:	rep; movsb\n"					\
  25.431 -		"2:\n"							\
  25.432 -		".section .fixup,\"ax\"\n"				\
  25.433 -		"3:	lea 0(%3,%0,4),%0\n"				\
  25.434 -		"4:	pushl %0\n"					\
  25.435 -		"	pushl %%eax\n"					\
  25.436 -		"	xorl %%eax,%%eax\n"				\
  25.437 -		"	rep; stosb\n"					\
  25.438 -		"	popl %%eax\n"					\
  25.439 -		"	popl %0\n"					\
  25.440 +		"3:	movl %3,%0\n"					\
  25.441 +		"	xor"itype" %"rtype"1,%"rtype"1\n"		\
  25.442  		"	jmp 2b\n"					\
  25.443  		".previous\n"						\
  25.444  		".section __ex_table,\"a\"\n"				\
  25.445  		"	.align 4\n"					\
  25.446 -		"	.long 0b,3b\n"					\
  25.447 -		"	.long 1b,4b\n"					\
  25.448 +		"	.long 1b,3b\n"					\
  25.449  		".previous"						\
  25.450 -		: "=&c"(size), "=&D" (__d0), "=&S" (__d1)		\
  25.451 -		: "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)	\
  25.452 -		: "memory");						\
  25.453 -} while (0)
  25.454 -
  25.455 -/* We let the __ versions of copy_from/to_user inline, because they're often
  25.456 - * used in fast paths and have only a small space overhead.
  25.457 - */
  25.458 -static inline unsigned long
  25.459 -__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
  25.460 -{
  25.461 -	__copy_user_zeroing(to,from,n);
  25.462 -	return n;
  25.463 -}
  25.464 -
  25.465 -static inline unsigned long
  25.466 -__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
  25.467 -{
  25.468 -	__copy_user(to,from,n);
  25.469 -	return n;
  25.470 -}
  25.471 +		: "=r"(err), ltype (x)					\
  25.472 +		: "m"(__m(addr)), "i"(errret), "0"(err))
  25.473  
  25.474  
  25.475 -/* Optimize just a little bit when we know the size of the move. */
  25.476 -#define __constant_copy_user(to, from, size)			\
  25.477 -do {								\
  25.478 -	int __d0, __d1;						\
  25.479 -	switch (size & 3) {					\
  25.480 -	default:						\
  25.481 -		__asm__ __volatile__(				\
  25.482 -			"0:	rep; movsl\n"			\
  25.483 -			"1:\n"					\
  25.484 -			".section .fixup,\"ax\"\n"		\
  25.485 -			"2:	shl $2,%0\n"			\
  25.486 -			"	jmp 1b\n"			\
  25.487 -			".previous\n"				\
  25.488 -			".section __ex_table,\"a\"\n"		\
  25.489 -			"	.align 4\n"			\
  25.490 -			"	.long 0b,2b\n"			\
  25.491 -			".previous"				\
  25.492 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.493 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.494 -			: "memory");				\
  25.495 -		break;						\
  25.496 -	case 1:							\
  25.497 -		__asm__ __volatile__(				\
  25.498 -			"0:	rep; movsl\n"			\
  25.499 -			"1:	movsb\n"			\
  25.500 -			"2:\n"					\
  25.501 -			".section .fixup,\"ax\"\n"		\
  25.502 -			"3:	shl $2,%0\n"			\
  25.503 -			"4:	incl %0\n"			\
  25.504 -			"	jmp 2b\n"			\
  25.505 -			".previous\n"				\
  25.506 -			".section __ex_table,\"a\"\n"		\
  25.507 -			"	.align 4\n"			\
  25.508 -			"	.long 0b,3b\n"			\
  25.509 -			"	.long 1b,4b\n"			\
  25.510 -			".previous"				\
  25.511 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.512 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.513 -			: "memory");				\
  25.514 -		break;						\
  25.515 -	case 2:							\
  25.516 -		__asm__ __volatile__(				\
  25.517 -			"0:	rep; movsl\n"			\
  25.518 -			"1:	movsw\n"			\
  25.519 -			"2:\n"					\
  25.520 -			".section .fixup,\"ax\"\n"		\
  25.521 -			"3:	shl $2,%0\n"			\
  25.522 -			"4:	addl $2,%0\n"			\
  25.523 -			"	jmp 2b\n"			\
  25.524 -			".previous\n"				\
  25.525 -			".section __ex_table,\"a\"\n"		\
  25.526 -			"	.align 4\n"			\
  25.527 -			"	.long 0b,3b\n"			\
  25.528 -			"	.long 1b,4b\n"			\
  25.529 -			".previous"				\
  25.530 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.531 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.532 -			: "memory");				\
  25.533 -		break;						\
  25.534 -	case 3:							\
  25.535 -		__asm__ __volatile__(				\
  25.536 -			"0:	rep; movsl\n"			\
  25.537 -			"1:	movsw\n"			\
  25.538 -			"2:	movsb\n"			\
  25.539 -			"3:\n"					\
  25.540 -			".section .fixup,\"ax\"\n"		\
  25.541 -			"4:	shl $2,%0\n"			\
  25.542 -			"5:	addl $2,%0\n"			\
  25.543 -			"6:	incl %0\n"			\
  25.544 -			"	jmp 3b\n"			\
  25.545 -			".previous\n"				\
  25.546 -			".section __ex_table,\"a\"\n"		\
  25.547 -			"	.align 4\n"			\
  25.548 -			"	.long 0b,4b\n"			\
  25.549 -			"	.long 1b,5b\n"			\
  25.550 -			"	.long 2b,6b\n"			\
  25.551 -			".previous"				\
  25.552 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.553 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.554 -			: "memory");				\
  25.555 -		break;						\
  25.556 -	}							\
  25.557 -} while (0)
  25.558 +unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n);
  25.559 +unsigned long __copy_from_user_ll(void *to, const void __user *from, unsigned long n);
  25.560 +
  25.561 +/*
  25.562 + * Here we special-case 1, 2 and 4-byte copy_*_user invocations.  On a fault
  25.563 + * we return the initial request size (1, 2 or 4), as copy_*_user should do.
  25.564 + * If a store crosses a page boundary and gets a fault, the x86 will not write
  25.565 + * anything, so this is accurate.
  25.566 + */
  25.567  
  25.568 -/* Optimize just a little bit when we know the size of the move. */
  25.569 -#define __constant_copy_user_zeroing(to, from, size)		\
  25.570 -do {								\
  25.571 -	int __d0, __d1;						\
  25.572 -	switch (size & 3) {					\
  25.573 -	default:						\
  25.574 -		__asm__ __volatile__(				\
  25.575 -			"0:	rep; movsl\n"			\
  25.576 -			"1:\n"					\
  25.577 -			".section .fixup,\"ax\"\n"		\
  25.578 -			"2:	pushl %0\n"			\
  25.579 -			"	pushl %%eax\n"			\
  25.580 -			"	xorl %%eax,%%eax\n"		\
  25.581 -			"	rep; stosl\n"			\
  25.582 -			"	popl %%eax\n"			\
  25.583 -			"	popl %0\n"			\
  25.584 -			"	shl $2,%0\n"			\
  25.585 -			"	jmp 1b\n"			\
  25.586 -			".previous\n"				\
  25.587 -			".section __ex_table,\"a\"\n"		\
  25.588 -			"	.align 4\n"			\
  25.589 -			"	.long 0b,2b\n"			\
  25.590 -			".previous"				\
  25.591 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.592 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.593 -			: "memory");				\
  25.594 -		break;						\
  25.595 -	case 1:							\
  25.596 -		__asm__ __volatile__(				\
  25.597 -			"0:	rep; movsl\n"			\
  25.598 -			"1:	movsb\n"			\
  25.599 -			"2:\n"					\
  25.600 -			".section .fixup,\"ax\"\n"		\
  25.601 -			"3:	pushl %0\n"			\
  25.602 -			"	pushl %%eax\n"			\
  25.603 -			"	xorl %%eax,%%eax\n"		\
  25.604 -			"	rep; stosl\n"			\
  25.605 -			"	stosb\n"			\
  25.606 -			"	popl %%eax\n"			\
  25.607 -			"	popl %0\n"			\
  25.608 -			"	shl $2,%0\n"			\
  25.609 -			"	incl %0\n"			\
  25.610 -			"	jmp 2b\n"			\
  25.611 -			"4:	pushl %%eax\n"			\
  25.612 -			"	xorl %%eax,%%eax\n"		\
  25.613 -			"	stosb\n"			\
  25.614 -			"	popl %%eax\n"			\
  25.615 -			"	incl %0\n"			\
  25.616 -			"	jmp 2b\n"			\
  25.617 -			".previous\n"				\
  25.618 -			".section __ex_table,\"a\"\n"		\
  25.619 -			"	.align 4\n"			\
  25.620 -			"	.long 0b,3b\n"			\
  25.621 -			"	.long 1b,4b\n"			\
  25.622 -			".previous"				\
  25.623 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.624 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.625 -			: "memory");				\
  25.626 -		break;						\
  25.627 -	case 2:							\
  25.628 -		__asm__ __volatile__(				\
  25.629 -			"0:	rep; movsl\n"			\
  25.630 -			"1:	movsw\n"			\
  25.631 -			"2:\n"					\
  25.632 -			".section .fixup,\"ax\"\n"		\
  25.633 -			"3:	pushl %0\n"			\
  25.634 -			"	pushl %%eax\n"			\
  25.635 -			"	xorl %%eax,%%eax\n"		\
  25.636 -			"	rep; stosl\n"			\
  25.637 -			"	stosw\n"			\
  25.638 -			"	popl %%eax\n"			\
  25.639 -			"	popl %0\n"			\
  25.640 -			"	shl $2,%0\n"			\
  25.641 -			"	addl $2,%0\n"			\
  25.642 -			"	jmp 2b\n"			\
  25.643 -			"4:	pushl %%eax\n"			\
  25.644 -			"	xorl %%eax,%%eax\n"		\
  25.645 -			"	stosw\n"			\
  25.646 -			"	popl %%eax\n"			\
  25.647 -			"	addl $2,%0\n"			\
  25.648 -			"	jmp 2b\n"			\
  25.649 -			".previous\n"				\
  25.650 -			".section __ex_table,\"a\"\n"		\
  25.651 -			"	.align 4\n"			\
  25.652 -			"	.long 0b,3b\n"			\
  25.653 -			"	.long 1b,4b\n"			\
  25.654 -			".previous"				\
  25.655 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.656 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.657 -			: "memory");				\
  25.658 -		break;						\
  25.659 -	case 3:							\
  25.660 -		__asm__ __volatile__(				\
  25.661 -			"0:	rep; movsl\n"			\
  25.662 -			"1:	movsw\n"			\
  25.663 -			"2:	movsb\n"			\
  25.664 -			"3:\n"					\
  25.665 -			".section .fixup,\"ax\"\n"		\
  25.666 -			"4:	pushl %0\n"			\
  25.667 -			"	pushl %%eax\n"			\
  25.668 -			"	xorl %%eax,%%eax\n"		\
  25.669 -			"	rep; stosl\n"			\
  25.670 -			"	stosw\n"			\
  25.671 -			"	stosb\n"			\
  25.672 -			"	popl %%eax\n"			\
  25.673 -			"	popl %0\n"			\
  25.674 -			"	shl $2,%0\n"			\
  25.675 -			"	addl $3,%0\n"			\
  25.676 -			"	jmp 2b\n"			\
  25.677 -			"5:	pushl %%eax\n"			\
  25.678 -			"	xorl %%eax,%%eax\n"		\
  25.679 -			"	stosw\n"			\
  25.680 -			"	stosb\n"			\
  25.681 -			"	popl %%eax\n"			\
  25.682 -			"	addl $3,%0\n"			\
  25.683 -			"	jmp 2b\n"			\
  25.684 -			"6:	pushl %%eax\n"			\
  25.685 -			"	xorl %%eax,%%eax\n"		\
  25.686 -			"	stosb\n"			\
  25.687 -			"	popl %%eax\n"			\
  25.688 -			"	incl %0\n"			\
  25.689 -			"	jmp 3b\n"			\
  25.690 -			".previous\n"				\
  25.691 -			".section __ex_table,\"a\"\n"		\
  25.692 -			"	.align 4\n"			\
  25.693 -			"	.long 0b,4b\n"			\
  25.694 -			"	.long 1b,5b\n"			\
  25.695 -			"	.long 2b,6b\n"			\
  25.696 -			".previous"				\
  25.697 -			: "=c"(size), "=&S" (__d0), "=&D" (__d1)\
  25.698 -			: "1"(from), "2"(to), "0"(size/4)	\
  25.699 -			: "memory");				\
  25.700 -		break;						\
  25.701 -	}							\
  25.702 -} while (0)
  25.703 +/**
  25.704 + * __copy_to_user: - Copy a block of data into user space, with less checking.
  25.705 + * @to:   Destination address, in user space.
  25.706 + * @from: Source address, in kernel space.
  25.707 + * @n:    Number of bytes to copy.
  25.708 + *
  25.709 + * Context: User context only.  This function may sleep.
  25.710 + *
  25.711 + * Copy data from kernel space to user space.  Caller must check
  25.712 + * the specified block with access_ok() before calling this function.
  25.713 + *
  25.714 + * Returns number of bytes that could not be copied.
  25.715 + * On success, this will be zero.
  25.716 + */
  25.717 +static inline unsigned long
  25.718 +__copy_to_user(void __user *to, const void *from, unsigned long n)
  25.719 +{
  25.720 +	if (__builtin_constant_p(n)) {
  25.721 +		unsigned long ret;
  25.722  
  25.723 -unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
  25.724 -unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
  25.725 -
  25.726 -static inline unsigned long
  25.727 -__constant_copy_to_user(void *to, const void *from, unsigned long n)
  25.728 -{
  25.729 -	prefetch(from);
  25.730 -	if (access_ok(VERIFY_WRITE, to, n))
  25.731 -		__constant_copy_user(to,from,n);
  25.732 -	return n;
  25.733 +		switch (n) {
  25.734 +		case 1:
  25.735 +			__put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret, 1);
  25.736 +			return ret;
  25.737 +		case 2:
  25.738 +			__put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret, 2);
  25.739 +			return ret;
  25.740 +		case 4:
  25.741 +			__put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret, 4);
  25.742 +			return ret;
  25.743 +		}
  25.744 +	}
  25.745 +	return __copy_to_user_ll(to, from, n);
  25.746  }
  25.747  
  25.748 -static inline unsigned long
  25.749 -__constant_copy_from_user(void *to, const void *from, unsigned long n)
  25.750 -{
  25.751 -	if (access_ok(VERIFY_READ, from, n))
  25.752 -		__constant_copy_user_zeroing(to,from,n);
  25.753 -	else
  25.754 -		memset(to, 0, n);
  25.755 -	return n;
  25.756 -}
  25.757 -
  25.758 +/**
  25.759 + * __copy_from_user: - Copy a block of data from user space, with less checking.
  25.760 + * @to:   Destination address, in kernel space.
  25.761 + * @from: Source address, in user space.
  25.762 + * @n:    Number of bytes to copy.
  25.763 + *
  25.764 + * Context: User context only.  This function may sleep.
  25.765 + *
  25.766 + * Copy data from user space to kernel space.  Caller must check
  25.767 + * the specified block with access_ok() before calling this function.
  25.768 + *
  25.769 + * Returns number of bytes that could not be copied.
  25.770 + * On success, this will be zero.
  25.771 + *
  25.772 + * If some data could not be copied, this function will pad the copied
  25.773 + * data to the requested size using zero bytes.
  25.774 + */
  25.775  static inline unsigned long
  25.776 -__constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
  25.777 +__copy_from_user(void *to, const void __user *from, unsigned long n)
  25.778  {
  25.779 -	__constant_copy_user(to,from,n);
  25.780 -	return n;
  25.781 -}
  25.782 +	if (__builtin_constant_p(n)) {
  25.783 +		unsigned long ret;
  25.784  
  25.785 -static inline unsigned long
  25.786 -__constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
  25.787 -{
  25.788 -	__constant_copy_user_zeroing(to,from,n);
  25.789 -	return n;
  25.790 +		switch (n) {
  25.791 +		case 1:
  25.792 +			__get_user_size(*(u8 *)to, from, 1, ret, 1);
  25.793 +			return ret;
  25.794 +		case 2:
  25.795 +			__get_user_size(*(u16 *)to, from, 2, ret, 2);
  25.796 +			return ret;
  25.797 +		case 4:
  25.798 +			__get_user_size(*(u32 *)to, from, 4, ret, 4);
  25.799 +			return ret;
  25.800 +		}
  25.801 +	}
  25.802 +	return __copy_from_user_ll(to, from, n);
  25.803  }
  25.804  
  25.805 -#define copy_to_user(to,from,n)				\
  25.806 -	(__builtin_constant_p(n) ?			\
  25.807 -	 __constant_copy_to_user((to),(from),(n)) :	\
  25.808 -	 __generic_copy_to_user((to),(from),(n)))
  25.809 -
  25.810 -#define copy_from_user(to,from,n)			\
  25.811 -	(__builtin_constant_p(n) ?			\
  25.812 -	 __constant_copy_from_user((to),(from),(n)) :	\
  25.813 -	 __generic_copy_from_user((to),(from),(n)))
  25.814 +unsigned long copy_to_user(void __user *to, const void *from, unsigned long n);
  25.815 +unsigned long copy_from_user(void *to,
  25.816 +			const void __user *from, unsigned long n);
  25.817 +long strncpy_from_user(char *dst, const char __user *src, long count);
  25.818 +long __strncpy_from_user(char *dst, const char __user *src, long count);
  25.819  
  25.820 -#define __copy_to_user(to,from,n)			\
  25.821 -	(__builtin_constant_p(n) ?			\
  25.822 -	 __constant_copy_to_user_nocheck((to),(from),(n)) :	\
  25.823 -	 __generic_copy_to_user_nocheck((to),(from),(n)))
  25.824 +/**
  25.825 + * strlen_user: - Get the size of a string in user space.
  25.826 + * @str: The string to measure.
  25.827 + *
  25.828 + * Context: User context only.  This function may sleep.
  25.829 + *
  25.830 + * Get the size of a NUL-terminated string in user space.
  25.831 + *
  25.832 + * Returns the size of the string INCLUDING the terminating NUL.
  25.833 + * On exception, returns 0.
  25.834 + *
  25.835 + * If there is a limit on the length of a valid string, you may wish to
  25.836 + * consider using strnlen_user() instead.
  25.837 + */
  25.838 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
  25.839  
  25.840 -#define __copy_from_user(to,from,n)			\
  25.841 -	(__builtin_constant_p(n) ?			\
  25.842 -	 __constant_copy_from_user_nocheck((to),(from),(n)) :	\
  25.843 -	 __generic_copy_from_user_nocheck((to),(from),(n)))
  25.844 -
  25.845 -long strncpy_from_user(char *dst, const char *src, long count);
  25.846 -long __strncpy_from_user(char *dst, const char *src, long count);
  25.847 -#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
  25.848 -long strnlen_user(const char *str, long n);
  25.849 -unsigned long clear_user(void *mem, unsigned long len);
  25.850 -unsigned long __clear_user(void *mem, unsigned long len);
  25.851 +long strnlen_user(const char __user *str, long n);
  25.852 +unsigned long clear_user(void __user *mem, unsigned long len);
  25.853 +unsigned long __clear_user(void __user *mem, unsigned long len);
  25.854  
  25.855  #endif /* __i386_UACCESS_H */
    26.1 --- a/xen/include/asm-x86/x86_64/uaccess.h	Fri Aug 20 18:19:24 2004 +0000
    26.2 +++ b/xen/include/asm-x86/x86_64/uaccess.h	Tue Aug 24 09:48:55 2004 +0000
    26.3 @@ -4,10 +4,11 @@
    26.4  /*
    26.5   * User space memory access functions
    26.6   */
    26.7 -#include <xen/config.h>
    26.8 -#include <xen/sched.h>
    26.9 -#include <xen/prefetch.h>
   26.10 -#include <xen/errno.h>
   26.11 +#include <linux/config.h>
   26.12 +#include <linux/compiler.h>
   26.13 +#include <linux/errno.h>
   26.14 +#include <linux/sched.h>
   26.15 +#include <linux/prefetch.h>
   26.16  #include <asm/page.h>
   26.17  
   26.18  #define VERIFY_READ 0
   26.19 @@ -23,31 +24,32 @@
   26.20  
   26.21  #define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
   26.22  
   26.23 -#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFFFFFFFFFF)
   26.24 +#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFFFFFFFFFFUL)
   26.25  #define USER_DS		MAKE_MM_SEG(PAGE_OFFSET)
   26.26  
   26.27  #define get_ds()	(KERNEL_DS)
   26.28 -#define get_fs()	(current->addr_limit)
   26.29 -#define set_fs(x)	(current->addr_limit = (x))
   26.30 +#define get_fs()	(current_thread_info()->addr_limit)
   26.31 +#define set_fs(x)	(current_thread_info()->addr_limit = (x))
   26.32  
   26.33  #define segment_eq(a,b)	((a).seg == (b).seg)
   26.34  
   26.35 -#define __addr_ok(addr) (!((unsigned long)(addr) & (current->addr_limit.seg)))
   26.36 +#define __addr_ok(addr) (!((unsigned long)(addr) & (current_thread_info()->addr_limit.seg)))
   26.37  
   26.38  /*
   26.39   * Uhhuh, this needs 65-bit arithmetic. We have a carry..
   26.40   */
   26.41  #define __range_not_ok(addr,size) ({ \
   26.42  	unsigned long flag,sum; \
   26.43 +	__chk_user_ptr(addr); \
   26.44  	asm("# range_ok\n\r" \
   26.45  		"addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0"  \
   26.46  		:"=&r" (flag), "=r" (sum) \
   26.47 -		:"1" (addr),"g" ((long)(size)),"g" (current->addr_limit.seg)); \
   26.48 +		:"1" (addr),"g" ((long)(size)),"g" (current_thread_info()->addr_limit.seg)); \
   26.49  	flag; })
   26.50  
   26.51 -#define access_ok(type,addr,size) (__range_not_ok(addr,size) == 0)
   26.52 +#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
   26.53  
   26.54 -extern inline int verify_area(int type, const void * addr, unsigned long size)
   26.55 +extern inline int verify_area(int type, const void __user * addr, unsigned long size)
   26.56  {
   26.57  	return access_ok(type,addr,size) ? 0 : -EFAULT;
   26.58  }
   26.59 @@ -101,12 +103,13 @@ extern void __get_user_8(void);
   26.60  /* Careful: we have to cast the result to the type of the pointer for sign reasons */
   26.61  #define get_user(x,ptr)							\
   26.62  ({	long __val_gu;							\
   26.63 -	int __ret_gu=1;							\
   26.64 +	int __ret_gu; 							\
   26.65 +	__chk_user_ptr(ptr);						\
   26.66  	switch(sizeof (*(ptr))) {					\
   26.67 -	case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;	\
   26.68 -	case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;	\
   26.69 -	case 4:  __get_user_x(4,__ret_gu,__val_gu,ptr); break;	\
   26.70 -	case 8:  __get_user_x(8,__ret_gu,__val_gu,ptr); break;	\
   26.71 +	case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;		\
   26.72 +	case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;		\
   26.73 +	case 4:  __get_user_x(4,__ret_gu,__val_gu,ptr); break;		\
   26.74 +	case 8:  __get_user_x(8,__ret_gu,__val_gu,ptr); break;		\
   26.75  	default: __get_user_bad(); break;				\
   26.76  	}								\
   26.77  	(x) = (__typeof__(*(ptr)))__val_gu;				\
   26.78 @@ -145,8 +148,8 @@ extern void __put_user_bad(void);
   26.79  #define __put_user_check(x,ptr,size)			\
   26.80  ({							\
   26.81  	int __pu_err = -EFAULT;				\
   26.82 -	__typeof__(*(ptr)) *__pu_addr = (ptr);		\
   26.83 -	if (access_ok(VERIFY_WRITE,__pu_addr,size))	\
   26.84 +	__typeof__(*(ptr)) __user *__pu_addr = (ptr);	\
   26.85 +	if (likely(access_ok(VERIFY_WRITE,__pu_addr,size)))	\
   26.86  		__put_user_size((x),__pu_addr,(size),__pu_err);	\
   26.87  	__pu_err;					\
   26.88  })
   26.89 @@ -154,6 +157,7 @@ extern void __put_user_bad(void);
   26.90  #define __put_user_size(x,ptr,size,retval)				\
   26.91  do {									\
   26.92  	retval = 0;							\
   26.93 +	__chk_user_ptr(ptr);						\
   26.94  	switch (size) {							\
   26.95  	  case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\
   26.96  	  case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\
   26.97 @@ -173,18 +177,18 @@ struct __large_struct { unsigned long bu
   26.98   * aliasing issues.
   26.99   */
  26.100  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errno)	\
  26.101 -	__asm__ __volatile__(				\
  26.102 -		"1:	mov"itype" %"rtype"1,%2\n"	\
  26.103 -		"2:\n"							\
  26.104 -		".section .fixup,\"ax\"\n"		\
  26.105 +	__asm__ __volatile__(					\
  26.106 +		"1:	mov"itype" %"rtype"1,%2\n"		\
  26.107 +		"2:\n"						\
  26.108 +		".section .fixup,\"ax\"\n"			\
  26.109  		"3:	mov %3,%0\n"				\
  26.110 -		"	jmp 2b\n"					\
  26.111 +		"	jmp 2b\n"				\
  26.112  		".previous\n"					\
  26.113 -		".section __ex_table,\"a\"\n"	\
  26.114 -		"	.align 8\n"					\
  26.115 +		".section __ex_table,\"a\"\n"			\
  26.116 +		"	.align 8\n"				\
  26.117  		"	.quad 1b,3b\n"				\
  26.118 -		".previous"						\
  26.119 -		: "=r"(err)						\
  26.120 +		".previous"					\
  26.121 +		: "=r"(err)					\
  26.122  		: ltype (x), "m"(__m(addr)), "i"(errno), "0"(err))
  26.123  
  26.124  
  26.125 @@ -202,6 +206,7 @@ extern int __get_user_bad(void);
  26.126  #define __get_user_size(x,ptr,size,retval)				\
  26.127  do {									\
  26.128  	retval = 0;							\
  26.129 +	__chk_user_ptr(ptr);						\
  26.130  	switch (size) {							\
  26.131  	  case 1: __get_user_asm(x,ptr,retval,"b","b","=q",-EFAULT); break;\
  26.132  	  case 2: __get_user_asm(x,ptr,retval,"w","w","=r",-EFAULT); break;\
  26.133 @@ -234,76 +239,116 @@ do {									\
  26.134  /* Handles exceptions in both to and from, but doesn't do access_ok */
  26.135  extern unsigned long copy_user_generic(void *to, const void *from, unsigned len); 
  26.136  
  26.137 -extern unsigned long copy_to_user(void *to, const void *from, unsigned len); 
  26.138 -extern unsigned long copy_from_user(void *to, const void *from, unsigned len); 
  26.139 +extern unsigned long copy_to_user(void __user *to, const void *from, unsigned len); 
  26.140 +extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len); 
  26.141 +extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len); 
  26.142  
  26.143 -static inline int __copy_from_user(void *dst, const void *src, unsigned size) 
  26.144 +static inline int __copy_from_user(void *dst, const void __user *src, unsigned size) 
  26.145  { 
  26.146 +       int ret = 0;
  26.147  	if (!__builtin_constant_p(size))
  26.148 -		return copy_user_generic(dst,src,size);
  26.149 -	int ret = 0; 
  26.150 +		return copy_user_generic(dst,(__force void *)src,size);
  26.151  	switch (size) { 
  26.152 -	case 1:__get_user_asm(*(u8*)dst,(u8 *)src,ret,"b","b","=q",1); 
  26.153 +	case 1:__get_user_asm(*(u8*)dst,(u8 __user *)src,ret,"b","b","=q",1); 
  26.154  		return ret;
  26.155 -	case 2:__get_user_asm(*(u16*)dst,(u16*)src,ret,"w","w","=r",2);
  26.156 +	case 2:__get_user_asm(*(u16*)dst,(u16 __user *)src,ret,"w","w","=r",2);
  26.157  		return ret;
  26.158 -	case 4:__get_user_asm(*(u32*)dst,(u32*)src,ret,"l","k","=r",4);
  26.159 +	case 4:__get_user_asm(*(u32*)dst,(u32 __user *)src,ret,"l","k","=r",4);
  26.160  		return ret;
  26.161 -	case 8:__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",8);
  26.162 +	case 8:__get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",8);
  26.163  		return ret; 
  26.164  	case 10:
  26.165 -	       	__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
  26.166 -		if (ret) return ret;
  26.167 -		__get_user_asm(*(u16*)(8+dst),(u16*)(8+src),ret,"w","w","=r",2);
  26.168 +	       	__get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
  26.169 +		if (unlikely(ret)) return ret;
  26.170 +		__get_user_asm(*(u16*)(8+(char*)dst),(u16 __user *)(8+(char __user *)src),ret,"w","w","=r",2);
  26.171  		return ret; 
  26.172  	case 16:
  26.173 -		__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
  26.174 -		if (ret) return ret;
  26.175 -		__get_user_asm(*(u64*)(8+dst),(u64*)(8+src),ret,"q","","=r",8);
  26.176 +		__get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
  26.177 +		if (unlikely(ret)) return ret;
  26.178 +		__get_user_asm(*(u64*)(8+(char*)dst),(u64 __user *)(8+(char __user *)src),ret,"q","","=r",8);
  26.179  		return ret; 
  26.180  	default:
  26.181 -		return copy_user_generic(dst,src,size); 
  26.182 +		return copy_user_generic(dst,(__force void *)src,size); 
  26.183  	}
  26.184  }	
  26.185  
  26.186 -static inline int __copy_to_user(void *dst, const void *src, unsigned size) 
  26.187 +static inline int __copy_to_user(void __user *dst, const void *src, unsigned size) 
  26.188  { 
  26.189 +       int ret = 0;
  26.190  	if (!__builtin_constant_p(size))
  26.191 -		return copy_user_generic(dst,src,size);
  26.192 -	int ret = 0; 
  26.193 +		return copy_user_generic((__force void *)dst,src,size);
  26.194  	switch (size) { 
  26.195 -	case 1:__put_user_asm(*(u8*)src,(u8 *)dst,ret,"b","b","iq",1); 
  26.196 +	case 1:__put_user_asm(*(u8*)src,(u8 __user *)dst,ret,"b","b","iq",1); 
  26.197  		return ret;
  26.198 -	case 2:__put_user_asm(*(u16*)src,(u16*)dst,ret,"w","w","ir",2);
  26.199 +	case 2:__put_user_asm(*(u16*)src,(u16 __user *)dst,ret,"w","w","ir",2);
  26.200  		return ret;
  26.201 -	case 4:__put_user_asm(*(u32*)src,(u32*)dst,ret,"l","k","ir",4);
  26.202 +	case 4:__put_user_asm(*(u32*)src,(u32 __user *)dst,ret,"l","k","ir",4);
  26.203  		return ret;
  26.204 -	case 8:__put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",8);
  26.205 +	case 8:__put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",8);
  26.206  		return ret; 
  26.207  	case 10:
  26.208 -		__put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",10);
  26.209 -		if (ret) return ret;
  26.210 +		__put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",10);
  26.211 +		if (unlikely(ret)) return ret;
  26.212  		asm("":::"memory");
  26.213 -		__put_user_asm(4[(u16*)src],4+(u16*)dst,ret,"w","w","ir",2);
  26.214 +		__put_user_asm(4[(u16*)src],4+(u16 __user *)dst,ret,"w","w","ir",2);
  26.215  		return ret; 
  26.216  	case 16:
  26.217 -		__put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",16);
  26.218 -		if (ret) return ret;
  26.219 +		__put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",16);
  26.220 +		if (unlikely(ret)) return ret;
  26.221  		asm("":::"memory");
  26.222 -		__put_user_asm(1[(u64*)src],1+(u64*)dst,ret,"q","","ir",8);
  26.223 +		__put_user_asm(1[(u64*)src],1+(u64 __user *)dst,ret,"q","","ir",8);
  26.224  		return ret; 
  26.225  	default:
  26.226 -		return copy_user_generic(dst,src,size); 
  26.227 +		return copy_user_generic((__force void *)dst,src,size); 
  26.228  	}
  26.229  }	
  26.230  
  26.231 -long strncpy_from_user(char *dst, const char *src, long count);
  26.232 -long __strncpy_from_user(char *dst, const char *src, long count);
  26.233 -long strnlen_user(const char *str, long n);
  26.234 -long strlen_user(const char *str);
  26.235 -unsigned long clear_user(void *mem, unsigned long len);
  26.236 -unsigned long __clear_user(void *mem, unsigned long len);
  26.237 +
  26.238 +static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size) 
  26.239 +{ 
  26.240 +       int ret = 0;
  26.241 +	if (!__builtin_constant_p(size))
  26.242 +		return copy_user_generic((__force void *)dst,(__force void *)src,size);
  26.243 +	switch (size) { 
  26.244 +	case 1: { 
  26.245 +		u8 tmp;
  26.246 +		__get_user_asm(tmp,(u8 __user *)src,ret,"b","b","=q",1); 
  26.247 +		if (likely(!ret))
  26.248 +			__put_user_asm(tmp,(u8 __user *)dst,ret,"b","b","iq",1); 
  26.249 +		return ret;
  26.250 +	}
  26.251 +	case 2: { 
  26.252 +		u16 tmp;
  26.253 +		__get_user_asm(tmp,(u16 __user *)src,ret,"w","w","=r",2); 
  26.254 +		if (likely(!ret))
  26.255 +			__put_user_asm(tmp,(u16 __user *)dst,ret,"w","w","ir",2); 
  26.256 +		return ret;
  26.257 +	}
  26.258  
  26.259 -extern unsigned long search_exception_table(unsigned long);
  26.260 +	case 4: { 
  26.261 +		u32 tmp;
  26.262 +		__get_user_asm(tmp,(u32 __user *)src,ret,"l","k","=r",4); 
  26.263 +		if (likely(!ret))
  26.264 +			__put_user_asm(tmp,(u32 __user *)dst,ret,"l","k","ir",4); 
  26.265 +		return ret;
  26.266 +	}
  26.267 +	case 8: { 
  26.268 +		u64 tmp;
  26.269 +		__get_user_asm(tmp,(u64 __user *)src,ret,"q","","=r",8); 
  26.270 +		if (likely(!ret))
  26.271 +			__put_user_asm(tmp,(u64 __user *)dst,ret,"q","","ir",8); 
  26.272 +		return ret;
  26.273 +	}
  26.274 +	default:
  26.275 +		return copy_user_generic((__force void *)dst,(__force void *)src,size); 
  26.276 +	}
  26.277 +}	
  26.278 +
  26.279 +long strncpy_from_user(char *dst, const char __user *src, long count);
  26.280 +long __strncpy_from_user(char *dst, const char __user *src, long count);
  26.281 +long strnlen_user(const char __user *str, long n);
  26.282 +long strlen_user(const char __user *str);
  26.283 +unsigned long clear_user(void __user *mem, unsigned long len);
  26.284 +unsigned long __clear_user(void __user *mem, unsigned long len);
  26.285  
  26.286  #endif /* __X86_64_UACCESS_H */
    27.1 --- a/xen/include/hypervisor-ifs/grant_table.h	Fri Aug 20 18:19:24 2004 +0000
    27.2 +++ b/xen/include/hypervisor-ifs/grant_table.h	Tue Aug 24 09:48:55 2004 +0000
    27.3 @@ -5,8 +5,17 @@
    27.4   * page-ownership transfers.
    27.5   * 
    27.6   * Copyright (c) 2004, K A Fraser
    27.7 - * 
    27.8 - * Some rough guidelines on accessing and updating grant-table entries
    27.9 + */
   27.10 +
   27.11 +#ifndef __HYPERVISOR_IFS_GRANT_TABLE_H__
   27.12 +#define __HYPERVISOR_IFS_GRANT_TABLE_H__
   27.13 +
   27.14 +
   27.15 +/***********************************
   27.16 + * GRANT TABLE REPRESENTATION
   27.17 + */
   27.18 +
   27.19 +/* Some rough guidelines on accessing and updating grant-table entries
   27.20   * in a concurreny-safe manner. For more information, Linux contains a
   27.21   * reference implementation for guest OSes (arch/xen/kernel/grant_table.c).
   27.22   * 
   27.23 @@ -35,9 +44,6 @@
   27.24   *  Use SMP-safe bit-setting instruction.
   27.25   */
   27.26  
   27.27 -#ifndef __HYPERVISOR_IFS_GRANT_TABLE_H__
   27.28 -#define __HYPERVISOR_IFS_GRANT_TABLE_H__
   27.29 -
   27.30  /*
   27.31   * A grant table comprises a packed array of grant entries in one or more
   27.32   * page frames shared between Xen and a guest.
   27.33 @@ -57,11 +63,6 @@ typedef struct {
   27.34  } PACKED grant_entry_t; /* 8 bytes */
   27.35  
   27.36  /*
   27.37 - * Reference to a grant entry in a specified domain's grant table.
   27.38 - */
   27.39 -typedef u16 grant_ref_t;
   27.40 -
   27.41 -/*
   27.42   * Type of grant entry.
   27.43   *  GTF_invalid: This grant entry grants no privileges.
   27.44   *  GTF_permit_access: Allow @domid to map/access @frame.
   27.45 @@ -82,8 +83,64 @@ typedef u16 grant_ref_t;
   27.46  #define _GTF_readonly       (2)
   27.47  #define GTF_readonly        (1<<_GTF_readonly)
   27.48  #define _GTF_reading        (3)
   27.49 -#define GTF_reading         (1<<_GTF_inuse)
   27.50 +#define GTF_reading         (1<<_GTF_reading)
   27.51  #define _GTF_writing        (4)
   27.52 -#define GTF_writing         (1<<_GTF_inuse)
   27.53 +#define GTF_writing         (1<<_GTF_writing)
   27.54 +
   27.55 +
   27.56 +/***********************************
   27.57 + * GRANT TABLE QUERIES AND USES
   27.58 + */
   27.59 +
   27.60 +/*
   27.61 + * Reference to a grant entry in a specified domain's grant table.
   27.62 + */
   27.63 +typedef u16 grant_ref_t;
   27.64 +
   27.65 +/*
   27.66 + * GNTTABOP_update_pin_status: Change the pin status of of <dom>'s grant entry
   27.67 + * with reference <ref>.
   27.68 + * NOTES:
   27.69 + *  1. If GNTPIN_dev_accessible is specified then <dev_bus_addr> is the address
   27.70 + *     via which I/O devices may access the granted frame.
   27.71 + *  2. If GNTPIN_host_accessible is specified then <host_phys_addr> is the
   27.72 + *     physical address of the frame, which may be mapped into the caller's
   27.73 + *     page tables.
   27.74 + */
   27.75 +#define GNTTABOP_update_pin_status    0
   27.76 +typedef struct {
   27.77 +    /* IN parameters. */
   27.78 +    domid_t     dom;                  /*  0 */
   27.79 +    grant_ref_t ref;                  /*  2 */
   27.80 +    u16         pin_flags;            /*  4 */
   27.81 +    u16         __pad;                /*  6 */
   27.82 +    /* OUT parameters. */
   27.83 +    memory_t    dev_bus_addr;         /*  8 */
   27.84 +    MEMORY_PADDING;
   27.85 +    memory_t    host_phys_addr;       /* 12 */
   27.86 +    MEMORY_PADDING;
   27.87 +} PACKED gnttab_update_pin_status_t; /* 16 bytes */
   27.88 +
   27.89 +typedef struct {
   27.90 +    u32 cmd; /* GNTTABOP_* */         /*  0 */
   27.91 +    u32 __reserved;                   /*  4 */
   27.92 +    union {                           /*  8 */
   27.93 +        gnttab_update_pin_status_t update_pin_status;
   27.94 +        u8                         __dummy[16];
   27.95 +    } PACKED u;
   27.96 +} PACKED gnttab_op_t; /* 24 bytes */
   27.97 +
   27.98 +/*
   27.99 + * Bitfield values for <pin_flags>.
  27.100 + */
  27.101 + /* Pin the grant entry for access by I/O devices. */
  27.102 +#define _GNTPIN_dev_accessible  (0)
  27.103 +#define GNTPIN_dev_accessible   (1<<_GNTPIN_dev_accessible)
  27.104 + /* Pin the grant entry for access by host CPUs. */
  27.105 +#define _GNTPIN_host_accessible (1)
  27.106 +#define GNTPIN_host_accessible  (1<<_GNTPIN_host_accessible)
  27.107 + /* Accesses to the granted frame will be restricted to read-only access. */
  27.108 +#define _GNTPIN_readonly        (2)
  27.109 +#define GNTPIN_readonly         (1<<_GNTPIN_readonly)
  27.110  
  27.111  #endif /* __HYPERVISOR_IFS_GRANT_TABLE_H__ */
    28.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Fri Aug 20 18:19:24 2004 +0000
    28.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Tue Aug 24 09:48:55 2004 +0000
    28.3 @@ -45,8 +45,9 @@
    28.4  #define __HYPERVISOR_xen_version          17
    28.5  #define __HYPERVISOR_console_io           18
    28.6  #define __HYPERVISOR_physdev_op           19
    28.7 -#define __HYPERVISOR_update_va_mapping_otherdomain 20
    28.8 +#define __HYPERVISOR_grant_table_op       20
    28.9  #define __HYPERVISOR_vm_assist            21
   28.10 +#define __HYPERVISOR_update_va_mapping_otherdomain 22
   28.11  
   28.12  /*
   28.13   * MULTICALLS
   28.14 @@ -183,7 +184,7 @@
   28.15  #define VMASST_CMD_disable               1
   28.16  #define VMASST_TYPE_4gb_segments         0
   28.17  #define VMASST_TYPE_4gb_segments_notify  1
   28.18 -#define VMASST_TYPE_writeable_pagetables 2
   28.19 +#define VMASST_TYPE_writable_pagetables  2
   28.20  #define MAX_VMASST_TYPE 2
   28.21  
   28.22  #ifndef __ASSEMBLY__
   28.23 @@ -370,7 +371,7 @@ typedef struct shared_info_st
   28.24   *  7. The list of page frames forms a contiguous 'pseudo-physical' memory
   28.25   *     layout for the domain. In particular, the bootstrap virtual-memory
   28.26   *     region is a 1:1 mapping to the first section of the pseudo-physical map.
   28.27 - *  8. All bootstrap elements are mapped read-writeable for the guest OS. The
   28.28 + *  8. All bootstrap elements are mapped read-writable for the guest OS. The
   28.29   *     only exception is the bootstrap page table, which is mapped read-only.
   28.30   *  9. There is guaranteed to be at least 512kB padding after the final
   28.31   *     bootstrap element. If necessary, the bootstrap virtual region is
    29.1 --- a/xen/include/hypervisor-ifs/io/domain_controller.h	Fri Aug 20 18:19:24 2004 +0000
    29.2 +++ b/xen/include/hypervisor-ifs/io/domain_controller.h	Tue Aug 24 09:48:55 2004 +0000
    29.3 @@ -267,7 +267,7 @@ typedef struct {
    29.4      u16        __pad;
    29.5      u32        blkif_handle;  /*  4: ...ditto...                         */
    29.6      blkif_vdev_t vdevice;     /*  8: Interface-specific id for this VBD. */
    29.7 -    u16        readonly;      /* 10: Non-zero -> VBD isn't writeable.    */
    29.8 +    u16        readonly;      /* 10: Non-zero -> VBD isn't writable.     */
    29.9      /* OUT */
   29.10      u32        status;        /* 12 */
   29.11  } PACKED blkif_be_vbd_create_t; /* 16 bytes */
    30.1 --- a/xen/include/xen/config.h	Fri Aug 20 18:19:24 2004 +0000
    30.2 +++ b/xen/include/xen/config.h	Tue Aug 24 09:48:55 2004 +0000
    30.3 @@ -10,6 +10,8 @@
    30.4  #include <asm/config.h>
    30.5  
    30.6  #define EXPORT_SYMBOL(var)
    30.7 +#define offsetof(_p,_f) ((unsigned long)&(((_p *)0)->_f))
    30.8 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    30.9  
   30.10  /* syslog levels ==> nothing! */
   30.11  #define KERN_NOTICE  ""
   30.12 @@ -21,16 +23,6 @@
   30.13  #define KERN_EMERG   ""
   30.14  #define KERN_ALERT   ""
   30.15  
   30.16 -#define offsetof(_p,_f) ((unsigned long)&(((_p *)0)->_f))
   30.17 -#define struct_cpy(_x,_y) (memcpy((_x),(_y),sizeof(*(_x))))
   30.18 -
   30.19 -#define dev_probe_lock() ((void)0)
   30.20 -#define dev_probe_unlock() ((void)0)
   30.21 -
   30.22 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   30.23 -
   30.24 -#define capable(_c) 0
   30.25 -
   30.26  #ifdef VERBOSE
   30.27  #define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
   30.28                             __FILE__ , __LINE__ , ## _a )
    31.1 --- a/xen/include/xen/grant_table.h	Fri Aug 20 18:19:24 2004 +0000
    31.2 +++ b/xen/include/xen/grant_table.h	Tue Aug 24 09:48:55 2004 +0000
    31.3 @@ -24,9 +24,45 @@
    31.4  #ifndef __XEN_GRANT_H__
    31.5  #define __XEN_GRANT_H__
    31.6  
    31.7 -#ifndef __GRANT_TABLE_IMPLEMENTATION__
    31.8 -typedef void grant_table_t;
    31.9 -#endif
   31.10 +#include <hypervisor-ifs/grant_table.h>
   31.11 +
   31.12 +/* Active grant entry - used for shadowing GTF_permit_access grants. */
   31.13 +typedef struct {
   31.14 +    u32           status; /* Reference count information.  */
   31.15 +    u32           tlbflush_timestamp; /* Flush avoidance.  */
   31.16 +    u16           next;   /* Mapping hash chain.           */
   31.17 +    domid_t       domid;  /* Domain being granted access.  */
   31.18 +    unsigned long frame;  /* Frame being granted.          */
   31.19 +} active_grant_entry_t;
   31.20 +
   31.21 +/*
   31.22 + * Bitfields in active_grant_entry_t:counts.
   31.23 + * NB. Some other GNTPIN_xxx definitions are in hypervisor-ifs/grant_table.h.
   31.24 + */
   31.25 + /* Count of writable host-CPU mappings. */
   31.26 +#define GNTPIN_wmap_shift    (4)
   31.27 +#define GNTPIN_wmap_mask     (0x3FFFU << GNTPIN_wmap_shift)
   31.28 + /* Count of read-only host-CPU mappings. */
   31.29 +#define GNTPIN_rmap_shift    (18)
   31.30 +#define GNTPIN_rmap_mask     (0x3FFFU << GNTPIN_rmap_shift)
   31.31 +
   31.32 +#define GNT_MAPHASH_SZ       (256)
   31.33 +#define GNT_MAPHASH(_k)      ((_k) & (GNT_MAPHASH_SZ-1))
   31.34 +#define GNT_MAPHASH_INVALID  (0xFFFFU)
   31.35 +
   31.36 +#define NR_GRANT_ENTRIES     (PAGE_SIZE / sizeof(grant_entry_t))
   31.37 +
   31.38 +/* Per-domain grant information. */
   31.39 +typedef struct {
   31.40 +    /* Shared grant table (see include/hypervisor-ifs/grant_table.h). */
   31.41 +    grant_entry_t        *shared;
   31.42 +    /* Active grant table. */
   31.43 +    active_grant_entry_t *active;
   31.44 +    /* Lock protecting updates to maphash and shared grant table. */
   31.45 +    spinlock_t            lock;
   31.46 +    /* Hash table: frame -> active grant entry. */
   31.47 +    u16                   maphash[GNT_MAPHASH_SZ];
   31.48 +} grant_table_t;
   31.49  
   31.50  /* Start-of-day system initialisation. */
   31.51  void grant_table_init(void);
    32.1 --- a/xen/include/xen/sched.h	Fri Aug 20 18:19:24 2004 +0000
    32.2 +++ b/xen/include/xen/sched.h	Tue Aug 24 09:48:55 2004 +0000
    32.3 @@ -109,8 +109,6 @@ struct domain
    32.4  
    32.5      struct mm_struct mm;
    32.6  
    32.7 -    mm_segment_t addr_limit;
    32.8 -
    32.9      struct thread_struct thread;
   32.10      struct domain *next_list, *next_hash;
   32.11