direct-io.hg

changeset 4369:6244d80c59e5

bitkeeper revision 1.1236.1.151 (424967aaR020l7m4GP2JkhW7oOgK9g)

Remove per-cpu batch queues for mmu updates and multicalls. Instead
batching is done locally within functions that most benefit.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Mar 29 14:35:22 2005 +0000 (2005-03-29)
parents 7d66265be1c5
children 9c722f0a8372
files .rootkeys linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c linux-2.4.29-xen-sparse/arch/xen/kernel/process.c linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c linux-2.4.29-xen-sparse/arch/xen/mm/fault.c linux-2.4.29-xen-sparse/include/asm-xen/desc.h linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h linux-2.4.29-xen-sparse/mkbuildtree linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h linux-2.6.11-xen-sparse/include/asm-xen/multicall.h
line diff
     1.1 --- a/.rootkeys	Tue Mar 29 10:24:22 2005 +0000
     1.2 +++ b/.rootkeys	Tue Mar 29 14:35:22 2005 +0000
     1.3 @@ -337,7 +337,6 @@ 412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6
     1.4  40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h
     1.5  3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.11-xen-sparse/include/asm-xen/linux-public/privcmd.h
     1.6  3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.11-xen-sparse/include/asm-xen/linux-public/suspend.h
     1.7 -40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.11-xen-sparse/include/asm-xen/multicall.h
     1.8  4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.11-xen-sparse/include/asm-xen/queues.h
     1.9  3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.11-xen-sparse/include/asm-xen/xen_proc.h
    1.10  419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.11-xen-sparse/include/linux/gfp.h
     2.1 --- a/linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c	Tue Mar 29 10:24:22 2005 +0000
     2.2 +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c	Tue Mar 29 14:35:22 2005 +0000
     2.3 @@ -14,6 +14,7 @@
     2.4  #include <linux/vmalloc.h>
     2.5  #include <linux/slab.h>
     2.6  
     2.7 +#include <asm/mmu_context.h>
     2.8  #include <asm/uaccess.h>
     2.9  #include <asm/system.h>
    2.10  #include <asm/ldt.h>
    2.11 @@ -58,7 +59,6 @@ static int alloc_ldt(mm_context_t *pc, i
    2.12  			pc->ldt,
    2.13  			(pc->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
    2.14  		load_LDT(pc);
    2.15 -		flush_page_update_queue();
    2.16  #ifdef CONFIG_SMP
    2.17  		if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
    2.18  			smp_call_function(flush_ldt, 0, 1, 1);
    2.19 @@ -66,6 +66,8 @@ static int alloc_ldt(mm_context_t *pc, i
    2.20  	}
    2.21  	wmb();
    2.22  	if (oldsize) {
    2.23 +		make_pages_writable(
    2.24 +			oldldt, (oldsize*LDT_ENTRY_SIZE)/PAGE_SIZE);
    2.25  		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
    2.26  			vfree(oldldt);
    2.27  		else
    2.28 @@ -84,7 +86,6 @@ static inline int copy_ldt(mm_context_t 
    2.29  	}
    2.30  	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
    2.31  	make_pages_readonly(new->ldt, (new->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
    2.32 -	flush_page_update_queue();
    2.33  	return 0;
    2.34  }
    2.35  
    2.36 @@ -116,10 +117,11 @@ int init_new_context(struct task_struct 
    2.37  void destroy_context(struct mm_struct *mm)
    2.38  {
    2.39  	if (mm->context.size) {
    2.40 +		if (mm_state_sync & STATE_SYNC_LDT)
    2.41 +			clear_LDT();
    2.42  		make_pages_writable(
    2.43  			mm->context.ldt, 
    2.44  			(mm->context.size*LDT_ENTRY_SIZE)/PAGE_SIZE);
    2.45 -		flush_page_update_queue();
    2.46  		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
    2.47  			vfree(mm->context.ldt);
    2.48  		else
     3.1 --- a/linux-2.4.29-xen-sparse/arch/xen/kernel/process.c	Tue Mar 29 10:24:22 2005 +0000
     3.2 +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/process.c	Tue Mar 29 14:35:22 2005 +0000
     3.3 @@ -43,7 +43,6 @@
     3.4  #include <asm/i387.h>
     3.5  #include <asm/desc.h>
     3.6  #include <asm/mmu_context.h>
     3.7 -#include <asm/multicall.h>
     3.8  #include <asm-xen/xen-public/physdev.h>
     3.9  
    3.10  #include <linux/irq.h>
    3.11 @@ -305,19 +304,36 @@ void fastcall __switch_to(struct task_st
    3.12  {
    3.13      struct thread_struct *next = &next_p->thread;
    3.14      physdev_op_t op;
    3.15 +    multicall_entry_t _mcl[8], *mcl = _mcl;
    3.16 +    mmu_update_t _mmu[2], *mmu = _mmu;
    3.17  
    3.18 -    __cli();
    3.19 +    if ( mm_state_sync & STATE_SYNC_PT )
    3.20 +    {
    3.21 +        mmu->ptr = virt_to_machine(cur_pgd) | MMU_EXTENDED_COMMAND;
    3.22 +        mmu->val = MMUEXT_NEW_BASEPTR;
    3.23 +        mmu++;
    3.24 +    }
    3.25  
    3.26 -    /*
    3.27 -     * We clobber FS and GS here so that we avoid a GPF when restoring previous
    3.28 -     * task's FS/GS values in Xen when the LDT is switched. If we don't do this
    3.29 -     * then we can end up erroneously re-flushing the page-update queue when
    3.30 -     * we 'execute_multicall_list'.
    3.31 -     */
    3.32 -    __asm__ __volatile__ ( 
    3.33 -        "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs" : : : "eax" );
    3.34 +    if ( mm_state_sync & STATE_SYNC_LDT )
    3.35 +    {
    3.36 +        __asm__ __volatile__ ( 
    3.37 +            "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs" : : : "eax" );
    3.38 +        mmu->ptr = (unsigned long)next_p->mm->context.ldt |
    3.39 +            MMU_EXTENDED_COMMAND;
    3.40 +        mmu->val = (next_p->mm->context.size << MMUEXT_CMD_SHIFT) |
    3.41 +            MMUEXT_SET_LDT;
    3.42 +        mmu++;
    3.43 +    }
    3.44  
    3.45 -    MULTICALL_flush_page_update_queue();
    3.46 +    if ( mm_state_sync != 0 )
    3.47 +    {
    3.48 +        mcl->op      = __HYPERVISOR_mmu_update;
    3.49 +        mcl->args[0] = (unsigned long)_mmu;
    3.50 +        mcl->args[1] = mmu - _mmu;
    3.51 +        mcl->args[2] = 0;
    3.52 +        mcl++;
    3.53 +        mm_state_sync = 0;
    3.54 +    }
    3.55  
    3.56      /*
    3.57       * This is basically 'unlazy_fpu', except that we queue a multicall to 
    3.58 @@ -332,21 +348,26 @@ void fastcall __switch_to(struct task_st
    3.59              asm volatile( "fnsave %0 ; fwait"
    3.60                            : "=m" (prev_p->thread.i387.fsave) );
    3.61  	prev_p->flags &= ~PF_USEDFPU;
    3.62 -        queue_multicall1(__HYPERVISOR_fpu_taskswitch, 1);
    3.63 +        mcl->op      = __HYPERVISOR_fpu_taskswitch;
    3.64 +        mcl->args[0] = 1;
    3.65 +        mcl++;
    3.66      }
    3.67  
    3.68 -    queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0);
    3.69 +    mcl->op      = __HYPERVISOR_stack_switch;
    3.70 +    mcl->args[0] = __KERNEL_DS;
    3.71 +    mcl->args[1] = next->esp0;
    3.72 +    mcl++;
    3.73  
    3.74      if ( prev_p->thread.io_pl != next->io_pl ) 
    3.75      {
    3.76          op.cmd             = PHYSDEVOP_SET_IOPL;
    3.77  	op.u.set_iopl.iopl = next->io_pl;
    3.78 -        queue_multicall1(__HYPERVISOR_physdev_op, (unsigned long)&op);
    3.79 +        mcl->op      = __HYPERVISOR_physdev_op;
    3.80 +        mcl->args[0] = (unsigned long)&op;
    3.81 +        mcl++;
    3.82      }
    3.83  
    3.84 -    /* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */
    3.85 -    execute_multicall_list();
    3.86 -    __sti();
    3.87 +    (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
    3.88  
    3.89      /*
    3.90       * Restore %fs and %gs.
     4.1 --- a/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c	Tue Mar 29 10:24:22 2005 +0000
     4.2 +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c	Tue Mar 29 14:35:22 2005 +0000
     4.3 @@ -62,9 +62,6 @@ shared_info_t *HYPERVISOR_shared_info = 
     4.4  
     4.5  unsigned int *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
     4.6  
     4.7 -DEFINE_PER_CPU(multicall_entry_t, multicall_list[8]);
     4.8 -DEFINE_PER_CPU(int, nr_multicall_ents);
     4.9 -
    4.10  /*
    4.11   * Machine setup..
    4.12   */
    4.13 @@ -1206,7 +1203,6 @@ void __init cpu_init (void)
    4.14      HYPERVISOR_stack_switch(__KERNEL_DS, current->thread.esp0);
    4.15  
    4.16      load_LDT(&init_mm.context);
    4.17 -    flush_page_update_queue();
    4.18  
    4.19      /* Force FPU initialization. */
    4.20      current->flags &= ~PF_USEDFPU;
     5.1 --- a/linux-2.4.29-xen-sparse/arch/xen/mm/fault.c	Tue Mar 29 10:24:22 2005 +0000
     5.2 +++ b/linux-2.4.29-xen-sparse/arch/xen/mm/fault.c	Tue Mar 29 14:35:22 2005 +0000
     5.3 @@ -28,6 +28,7 @@
     5.4  extern void die(const char *,struct pt_regs *,long);
     5.5  
     5.6  pgd_t *cur_pgd;
     5.7 +int mm_state_sync;
     5.8  
     5.9  extern spinlock_t timerlist_lock;
    5.10  
     6.1 --- a/linux-2.4.29-xen-sparse/include/asm-xen/desc.h	Tue Mar 29 10:24:22 2005 +0000
     6.2 +++ b/linux-2.4.29-xen-sparse/include/asm-xen/desc.h	Tue Mar 29 14:35:22 2005 +0000
     6.3 @@ -16,6 +16,11 @@ struct Xgt_desc_struct {
     6.4  
     6.5  extern struct desc_struct default_ldt[];
     6.6  
     6.7 +static inline void clear_LDT(void)
     6.8 +{
     6.9 +    xen_set_ldt(0, 0);
    6.10 +}
    6.11 +
    6.12  static inline void load_LDT(mm_context_t *pc)
    6.13  {
    6.14      void *segments = pc->ldt;
     7.1 --- a/linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h	Tue Mar 29 10:24:22 2005 +0000
     7.2 +++ b/linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h	Tue Mar 29 14:35:22 2005 +0000
     7.3 @@ -28,47 +28,34 @@ static inline void enter_lazy_tlb(struct
     7.4  #endif
     7.5  
     7.6  extern pgd_t *cur_pgd;
     7.7 +extern int mm_state_sync;
     7.8 +#define STATE_SYNC_PT  1
     7.9 +#define STATE_SYNC_LDT 2
    7.10  
    7.11  static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
    7.12  {
    7.13  	if (prev != next) {
    7.14  		/* stop flush ipis for the previous mm */
    7.15  		clear_bit(cpu, &prev->cpu_vm_mask);
    7.16 -#ifdef CONFIG_SMP
    7.17 -		cpu_tlbstate[cpu].state = TLBSTATE_OK;
    7.18 -		cpu_tlbstate[cpu].active_mm = next;
    7.19 -#endif
    7.20 -
    7.21  		/* Re-load page tables */
    7.22  		cur_pgd = next->pgd;
    7.23 -		queue_pt_switch(__pa(cur_pgd));
    7.24 -                /* load_LDT, if either the previous or next thread
    7.25 -                 * has a non-default LDT.
    7.26 -                 */
    7.27 -                if (next->context.size+prev->context.size)
    7.28 -                        load_LDT(&next->context);
    7.29 +		mm_state_sync |= STATE_SYNC_PT;
    7.30 +		/* load_LDT, if either the previous or next thread
    7.31 +		 * has a non-default LDT.
    7.32 +		 */
    7.33 +		if (next->context.size+prev->context.size)
    7.34 +			mm_state_sync |= STATE_SYNC_LDT;
    7.35  	}
    7.36 -#ifdef CONFIG_SMP
    7.37 -	else {
    7.38 -		cpu_tlbstate[cpu].state = TLBSTATE_OK;
    7.39 -		if(cpu_tlbstate[cpu].active_mm != next)
    7.40 -			out_of_line_bug();
    7.41 -		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
    7.42 -			/* We were in lazy tlb mode and leave_mm disabled 
    7.43 -			 * tlb flush IPI delivery. We must reload %cr3.
    7.44 -			 */
    7.45 -		        cur_pgd = next->pgd;
    7.46 -		        queue_pt_switch(__pa(cur_pgd));
    7.47 -			load_LDT(next);
    7.48 -		}
    7.49 -	}
    7.50 -#endif
    7.51  }
    7.52  
    7.53 -#define activate_mm(prev, next) \
    7.54 -do { \
    7.55 -	switch_mm((prev),(next),NULL,smp_processor_id()); \
    7.56 -	flush_page_update_queue(); \
    7.57 +#define activate_mm(prev, next)                                 \
    7.58 +do {                                                            \
    7.59 +	switch_mm((prev),(next),NULL,smp_processor_id());       \
    7.60 +	if (mm_state_sync & STATE_SYNC_PT)                      \
    7.61 +		xen_pt_switch(__pa(cur_pgd));                   \
    7.62 +	if (mm_state_sync & STATE_SYNC_LDT)                     \
    7.63 +		load_LDT(&(next)->context);                     \
    7.64 +	mm_state_sync = 0;                                      \
    7.65  } while ( 0 )
    7.66  
    7.67  #endif
     8.1 --- a/linux-2.4.29-xen-sparse/mkbuildtree	Tue Mar 29 10:24:22 2005 +0000
     8.2 +++ b/linux-2.4.29-xen-sparse/mkbuildtree	Tue Mar 29 14:35:22 2005 +0000
     8.3 @@ -210,7 +210,6 @@ ln -sf ../../${LINUX_26}/include/asm-xen
     8.4  ln -sf ../../${LINUX_26}/include/asm-xen/evtchn.h
     8.5  ln -sf ../../${LINUX_26}/include/asm-xen/gnttab.h
     8.6  ln -sf ../../${LINUX_26}/include/asm-xen/hypervisor.h
     8.7 -ln -sf ../../${LINUX_26}/include/asm-xen/multicall.h
     8.8  ln -sf ../../${LINUX_26}/include/asm-xen/xen_proc.h
     8.9  ln -sf ../../${LINUX_26}/include/asm-xen/asm-i386/synch_bitops.h
    8.10  
     9.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Tue Mar 29 10:24:22 2005 +0000
     9.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Tue Mar 29 14:35:22 2005 +0000
     9.3 @@ -564,7 +564,6 @@ void __init cpu_gdt_init(struct Xgt_desc
     9.4  		frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
     9.5  		make_page_readonly((void *)va);
     9.6  	}
     9.7 -	flush_page_update_queue();
     9.8  	if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
     9.9  		BUG();
    9.10  	lgdt_finish();
    9.11 @@ -622,7 +621,6 @@ void __init cpu_init (void)
    9.12  	load_esp0(t, thread);
    9.13  
    9.14  	load_LDT(&init_mm.context);
    9.15 -	flush_page_update_queue();
    9.16  
    9.17  	/* Clear %fs and %gs. */
    9.18  	asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
    10.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c	Tue Mar 29 10:24:22 2005 +0000
    10.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c	Tue Mar 29 14:35:22 2005 +0000
    10.3 @@ -22,10 +22,8 @@
    10.4  #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
    10.5  static void flush_ldt(void *null)
    10.6  {
    10.7 -	if (current->active_mm) {
    10.8 +	if (current->active_mm)
    10.9  		load_LDT(&current->active_mm->context);
   10.10 -		flush_page_update_queue();
   10.11 -	}
   10.12  }
   10.13  #endif
   10.14  
   10.15 @@ -64,7 +62,6 @@ static int alloc_ldt(mm_context_t *pc, i
   10.16  		make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
   10.17  				    PAGE_SIZE);
   10.18  		load_LDT(pc);
   10.19 -		flush_page_update_queue();
   10.20  #ifdef CONFIG_SMP
   10.21  		mask = cpumask_of_cpu(smp_processor_id());
   10.22  		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
   10.23 @@ -75,7 +72,6 @@ static int alloc_ldt(mm_context_t *pc, i
   10.24  	if (oldsize) {
   10.25  		make_pages_writable(oldldt, (oldsize * LDT_ENTRY_SIZE) /
   10.26  			PAGE_SIZE);
   10.27 -		flush_page_update_queue();
   10.28  		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
   10.29  			vfree(oldldt);
   10.30  		else
   10.31 @@ -92,7 +88,6 @@ static inline int copy_ldt(mm_context_t 
   10.32  	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
   10.33  	make_pages_readonly(new->ldt, (new->size * LDT_ENTRY_SIZE) /
   10.34  			    PAGE_SIZE);
   10.35 -	flush_page_update_queue();
   10.36  	return 0;
   10.37  }
   10.38  
   10.39 @@ -127,7 +122,6 @@ void destroy_context(struct mm_struct *m
   10.40  		make_pages_writable(mm->context.ldt, 
   10.41  				    (mm->context.size * LDT_ENTRY_SIZE) /
   10.42  				    PAGE_SIZE);
   10.43 -		flush_page_update_queue();
   10.44  		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
   10.45  			vfree(mm->context.ldt);
   10.46  		else
    11.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Tue Mar 29 10:24:22 2005 +0000
    11.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Tue Mar 29 14:35:22 2005 +0000
    11.3 @@ -54,10 +54,10 @@ xen_contig_memory(unsigned long vstart, 
    11.4  		pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
    11.5  		pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
    11.6  		pfn = pte->pte_low >> PAGE_SHIFT;
    11.7 -		queue_l1_entry_update(pte, 0);
    11.8 +		HYPERVISOR_update_va_mapping(
    11.9 +			vstart + (i*PAGE_SIZE), __pte_ma(0), 0);
   11.10  		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] =
   11.11  			INVALID_P2M_ENTRY;
   11.12 -		flush_page_update_queue();
   11.13  		if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, 
   11.14  					  &pfn, 1, 0) != 1) BUG();
   11.15  	}
   11.16 @@ -70,14 +70,14 @@ xen_contig_memory(unsigned long vstart, 
   11.17  		pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
   11.18  		pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
   11.19  		pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
   11.20 -		queue_l1_entry_update(
   11.21 -			pte, ((pfn+i)<<PAGE_SHIFT)|__PAGE_KERNEL);
   11.22 -		queue_machphys_update(
   11.23 +		HYPERVISOR_update_va_mapping(
   11.24 +			vstart + (i*PAGE_SIZE),
   11.25 +			__pte_ma(((pfn+i)<<PAGE_SHIFT)|__PAGE_KERNEL), 0);
   11.26 +		xen_machphys_update(
   11.27  			pfn+i, (__pa(vstart)>>PAGE_SHIFT)+i);
   11.28  		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] =
   11.29  			pfn+i;
   11.30  	}
   11.31 -	/* Flush updates through and flush the TLB. */
   11.32  	xen_tlb_flush();
   11.33  
   11.34          balloon_unlock(flags);
    12.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c	Tue Mar 29 10:24:22 2005 +0000
    12.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c	Tue Mar 29 14:35:22 2005 +0000
    12.3 @@ -46,7 +46,6 @@
    12.4  #include <asm/i387.h>
    12.5  #include <asm/irq.h>
    12.6  #include <asm/desc.h>
    12.7 -#include <asm-xen/multicall.h>
    12.8  #include <asm-xen/xen-public/physdev.h>
    12.9  #ifdef CONFIG_MATH_EMULATION
   12.10  #include <asm/math_emu.h>
   12.11 @@ -444,9 +443,7 @@ struct task_struct fastcall * __switch_t
   12.12  	int cpu = smp_processor_id();
   12.13  	struct tss_struct *tss = &per_cpu(init_tss, cpu);
   12.14  	physdev_op_t iopl_op, iobmp_op;
   12.15 -
   12.16 -        /* NB. No need to disable interrupts as already done in sched.c */
   12.17 -        /* __cli(); */
   12.18 +	multicall_entry_t _mcl[8], *mcl = _mcl;
   12.19  
   12.20  	/*
   12.21  	 * Save away %fs and %gs. No need to save %es and %ds, as
   12.22 @@ -463,8 +460,6 @@ struct task_struct fastcall * __switch_t
   12.23  		"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs" : : :
   12.24  		"eax" );
   12.25  
   12.26 -	MULTICALL_flush_page_update_queue();
   12.27 -
   12.28  	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
   12.29  
   12.30  	/*
   12.31 @@ -474,7 +469,9 @@ struct task_struct fastcall * __switch_t
   12.32  	 */
   12.33  	if (prev_p->thread_info->status & TS_USEDFPU) {
   12.34  		__save_init_fpu(prev_p); /* _not_ save_init_fpu() */
   12.35 -		queue_multicall1(__HYPERVISOR_fpu_taskswitch, 1);
   12.36 +		mcl->op      = __HYPERVISOR_fpu_taskswitch;
   12.37 +		mcl->args[0] = 1;
   12.38 +		mcl++;
   12.39  	}
   12.40  
   12.41  	/*
   12.42 @@ -482,20 +479,25 @@ struct task_struct fastcall * __switch_t
   12.43  	 * This is load_esp0(tss, next) with a multicall.
   12.44  	 */
   12.45  	tss->esp0 = next->esp0;
   12.46 -	queue_multicall2(__HYPERVISOR_stack_switch, tss->ss0, tss->esp0);
   12.47 +	mcl->op      = __HYPERVISOR_stack_switch;
   12.48 +	mcl->args[0] = tss->ss0;
   12.49 +	mcl->args[1] = tss->esp0;
   12.50 +	mcl++;
   12.51  
   12.52  	/*
   12.53  	 * Load the per-thread Thread-Local Storage descriptor.
   12.54  	 * This is load_TLS(next, cpu) with multicalls.
   12.55  	 */
   12.56 -#define C(i) do {							    \
   12.57 -	if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||	    \
   12.58 -		     next->tls_array[i].b != prev->tls_array[i].b))	    \
   12.59 -		queue_multicall3(__HYPERVISOR_update_descriptor,	    \
   12.60 -				 virt_to_machine(&get_cpu_gdt_table(cpu)    \
   12.61 -						 [GDT_ENTRY_TLS_MIN + i]),  \
   12.62 -				 ((u32 *)&next->tls_array[i])[0],	    \
   12.63 -				 ((u32 *)&next->tls_array[i])[1]);	    \
   12.64 +#define C(i) do {                                                       \
   12.65 +	if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||    \
   12.66 +		     next->tls_array[i].b != prev->tls_array[i].b)) {   \
   12.67 +		mcl->op      = __HYPERVISOR_update_descriptor;          \
   12.68 +		mcl->args[0] = virt_to_machine(&get_cpu_gdt_table(cpu)  \
   12.69 +					 [GDT_ENTRY_TLS_MIN + i]);      \
   12.70 +		mcl->args[1] = ((u32 *)&next->tls_array[i])[0];         \
   12.71 +		mcl->args[2] = ((u32 *)&next->tls_array[i])[1];         \
   12.72 +		mcl++;                                                  \
   12.73 +	}                                                               \
   12.74  } while (0)
   12.75  	C(0); C(1); C(2);
   12.76  #undef C
   12.77 @@ -503,8 +505,9 @@ struct task_struct fastcall * __switch_t
   12.78  	if (unlikely(prev->io_pl != next->io_pl)) {
   12.79  		iopl_op.cmd             = PHYSDEVOP_SET_IOPL;
   12.80  		iopl_op.u.set_iopl.iopl = next->io_pl;
   12.81 -		queue_multicall1(__HYPERVISOR_physdev_op,
   12.82 -				(unsigned long)&iopl_op);
   12.83 +		mcl->op      = __HYPERVISOR_physdev_op;
   12.84 +		mcl->args[0] = (unsigned long)&iopl_op;
   12.85 +		mcl++;
   12.86  	}
   12.87  
   12.88  	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
   12.89 @@ -514,13 +517,12 @@ struct task_struct fastcall * __switch_t
   12.90  			(unsigned long)next->io_bitmap_ptr;
   12.91  		iobmp_op.u.set_iobitmap.nr_ports =
   12.92  			next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   12.93 -		queue_multicall1(__HYPERVISOR_physdev_op,
   12.94 -				(unsigned long)&iobmp_op);
   12.95 +		mcl->op      = __HYPERVISOR_physdev_op;
   12.96 +		mcl->args[0] = (unsigned long)&iobmp_op;
   12.97 +		mcl++;
   12.98  	}
   12.99  
  12.100 -	/* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */
  12.101 -	execute_multicall_list();
  12.102 -        /* __sti(); */
  12.103 +	(void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
  12.104  
  12.105  	/*
  12.106  	 * Restore %fs and %gs if needed.
    13.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Mar 29 10:24:22 2005 +0000
    13.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Mar 29 14:35:22 2005 +0000
    13.3 @@ -362,9 +362,6 @@ EXPORT_SYMBOL(HYPERVISOR_shared_info);
    13.4  unsigned int *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
    13.5  EXPORT_SYMBOL(phys_to_machine_mapping);
    13.6  
    13.7 -DEFINE_PER_CPU(multicall_entry_t, multicall_list[8]);
    13.8 -DEFINE_PER_CPU(int, nr_multicall_ents);
    13.9 -
   13.10  /* Raw start-of-day parameters from the hypervisor. */
   13.11  union xen_start_info_union xen_start_info_union;
   13.12  
    14.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c	Tue Mar 29 10:24:22 2005 +0000
    14.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c	Tue Mar 29 14:35:22 2005 +0000
    14.3 @@ -898,7 +898,6 @@ static int __init do_boot_cpu(int apicid
    14.4  			make_page_readonly((void *)va);
    14.5  		}
    14.6  		ctxt.gdt_ents = cpu_gdt_descr[cpu].size / 8;
    14.7 -		flush_page_update_queue();
    14.8  	}
    14.9  
   14.10  	/* Ring 1 stack is the initial stack. */
    15.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Mar 29 10:24:22 2005 +0000
    15.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Mar 29 14:35:22 2005 +0000
    15.3 @@ -963,7 +963,6 @@ void __init trap_init(void)
    15.4  	 * and a callgate to lcall27 for Solaris/x86 binaries
    15.5  	 */
    15.6  	make_lowmem_page_readonly(&default_ldt[0]);
    15.7 -	flush_page_update_queue();
    15.8  
    15.9  	/*
   15.10  	 * Should be a barrier for any external CPU state.
    16.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c	Tue Mar 29 10:24:22 2005 +0000
    16.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c	Tue Mar 29 14:35:22 2005 +0000
    16.3 @@ -34,21 +34,11 @@
    16.4  #include <asm/page.h>
    16.5  #include <asm/pgtable.h>
    16.6  #include <asm-xen/hypervisor.h>
    16.7 -#include <asm-xen/multicall.h>
    16.8  #include <asm-xen/balloon.h>
    16.9  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   16.10  #include <linux/percpu.h>
   16.11  #endif
   16.12  
   16.13 -/*
   16.14 - * This suffices to protect us if we ever move to SMP domains.
   16.15 - * Further, it protects us against interrupts. At the very least, this is
   16.16 - * required for the network driver which flushes the update queue before
   16.17 - * pushing new receive buffers.
   16.18 - */
   16.19 -static spinlock_t update_lock = SPIN_LOCK_UNLOCKED;
   16.20 -
   16.21 -#define QUEUE_SIZE 128
   16.22  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   16.23  #define pte_offset_kernel pte_offset
   16.24  #define pud_t pgd_t
   16.25 @@ -57,366 +47,92 @@ static spinlock_t update_lock = SPIN_LOC
   16.26  #define pmd_val_ma(v) (v).pud.pgd.pgd;
   16.27  #endif
   16.28  
   16.29 -DEFINE_PER_CPU(mmu_update_t, update_queue[QUEUE_SIZE]);
   16.30 -DEFINE_PER_CPU(unsigned int, mmu_update_queue_idx);
   16.31 -
   16.32 -/*
   16.33 - * MULTICALL_flush_page_update_queue:
   16.34 - *   This is a version of the flush which queues as part of a multicall.
   16.35 - */
   16.36 -void MULTICALL_flush_page_update_queue(void)
   16.37 -{
   16.38 -    int cpu = smp_processor_id();
   16.39 -    int idx;
   16.40 -    unsigned long flags;
   16.41 -    unsigned int _idx;
   16.42 -    spin_lock_irqsave(&update_lock, flags);
   16.43 -    idx = per_cpu(mmu_update_queue_idx, cpu);
   16.44 -    if ( (_idx = idx) != 0 ) 
   16.45 -    {
   16.46 -        per_cpu(mmu_update_queue_idx, cpu) = 0;
   16.47 -        wmb(); /* Make sure index is cleared first to avoid double updates. */
   16.48 -        queue_multicall3(__HYPERVISOR_mmu_update, 
   16.49 -                         (unsigned long)&per_cpu(update_queue[0], cpu), 
   16.50 -                         (unsigned long)_idx, 
   16.51 -                         (unsigned long)NULL);
   16.52 -    }
   16.53 -    spin_unlock_irqrestore(&update_lock, flags);
   16.54 -}
   16.55 -
   16.56 -static inline void __flush_page_update_queue(void)
   16.57 -{
   16.58 -    int cpu = smp_processor_id();
   16.59 -    unsigned int _idx = per_cpu(mmu_update_queue_idx, cpu);
   16.60 -    per_cpu(mmu_update_queue_idx, cpu) = 0;
   16.61 -    wmb(); /* Make sure index is cleared first to avoid double updates. */
   16.62 -    if ( unlikely(HYPERVISOR_mmu_update(&per_cpu(update_queue[0], cpu), _idx, NULL) < 0) )
   16.63 -    {
   16.64 -        printk(KERN_ALERT "Failed to execute MMU updates.\n");
   16.65 -        BUG();
   16.66 -    }
   16.67 -}
   16.68 -
   16.69 -void _flush_page_update_queue(void)
   16.70 -{
   16.71 -    int cpu = smp_processor_id();
   16.72 -    unsigned long flags;
   16.73 -    spin_lock_irqsave(&update_lock, flags);
   16.74 -    if ( per_cpu(mmu_update_queue_idx, cpu) != 0 ) __flush_page_update_queue();
   16.75 -    spin_unlock_irqrestore(&update_lock, flags);
   16.76 -}
   16.77 -
   16.78 -static inline void increment_index(void)
   16.79 -{
   16.80 -    int cpu = smp_processor_id();
   16.81 -    per_cpu(mmu_update_queue_idx, cpu)++;
   16.82 -    if ( unlikely(per_cpu(mmu_update_queue_idx, cpu) == QUEUE_SIZE) ) __flush_page_update_queue();
   16.83 -}
   16.84 -
   16.85 -static inline void increment_index_and_flush(void)
   16.86 -{
   16.87 -    int cpu = smp_processor_id();
   16.88 -    per_cpu(mmu_update_queue_idx, cpu)++;
   16.89 -    __flush_page_update_queue();
   16.90 -}
   16.91 -
   16.92 -void queue_l1_entry_update(pte_t *ptr, unsigned long val)
   16.93 -{
   16.94 -    int cpu = smp_processor_id();
   16.95 -    int idx;
   16.96 -    unsigned long flags;
   16.97 -    spin_lock_irqsave(&update_lock, flags);
   16.98 -    idx = per_cpu(mmu_update_queue_idx, cpu);
   16.99 -    per_cpu(update_queue[idx], cpu).ptr = virt_to_machine(ptr);
  16.100 -    per_cpu(update_queue[idx], cpu).val = val;
  16.101 -    increment_index();
  16.102 -    spin_unlock_irqrestore(&update_lock, flags);
  16.103 -}
  16.104 -
  16.105 -void queue_l2_entry_update(pmd_t *ptr, pmd_t val)
  16.106 -{
  16.107 -    int cpu = smp_processor_id();
  16.108 -    int idx;
  16.109 -    unsigned long flags;
  16.110 -    spin_lock_irqsave(&update_lock, flags);
  16.111 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.112 -    per_cpu(update_queue[idx], cpu).ptr = virt_to_machine(ptr);
  16.113 -    per_cpu(update_queue[idx], cpu).val = pmd_val_ma(val);
  16.114 -    increment_index();
  16.115 -    spin_unlock_irqrestore(&update_lock, flags);
  16.116 -}
  16.117 -
  16.118 -void queue_pt_switch(unsigned long ptr)
  16.119 -{
  16.120 -    int cpu = smp_processor_id();
  16.121 -    int idx;
  16.122 -    unsigned long flags;
  16.123 -    spin_lock_irqsave(&update_lock, flags);
  16.124 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.125 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.126 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.127 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_NEW_BASEPTR;
  16.128 -    increment_index();
  16.129 -    spin_unlock_irqrestore(&update_lock, flags);
  16.130 -}
  16.131 -
  16.132 -void queue_tlb_flush(void)
  16.133 -{
  16.134 -    int cpu = smp_processor_id();
  16.135 -    int idx;
  16.136 -    unsigned long flags;
  16.137 -    spin_lock_irqsave(&update_lock, flags);
  16.138 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.139 -    per_cpu(update_queue[idx], cpu).ptr  = MMU_EXTENDED_COMMAND;
  16.140 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_TLB_FLUSH;
  16.141 -    increment_index();
  16.142 -    spin_unlock_irqrestore(&update_lock, flags);
  16.143 -}
  16.144 -
  16.145 -void queue_invlpg(unsigned long ptr)
  16.146 -{
  16.147 -    int cpu = smp_processor_id();
  16.148 -    int idx;
  16.149 -    unsigned long flags;
  16.150 -    spin_lock_irqsave(&update_lock, flags);
  16.151 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.152 -    per_cpu(update_queue[idx], cpu).ptr  = MMU_EXTENDED_COMMAND;
  16.153 -    per_cpu(update_queue[idx], cpu).ptr |= ptr & PAGE_MASK;
  16.154 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_INVLPG;
  16.155 -    increment_index();
  16.156 -    spin_unlock_irqrestore(&update_lock, flags);
  16.157 -}
  16.158 -
  16.159 -void queue_pgd_pin(unsigned long ptr)
  16.160 -{
  16.161 -    int cpu = smp_processor_id();
  16.162 -    int idx;
  16.163 -    unsigned long flags;
  16.164 -    spin_lock_irqsave(&update_lock, flags);
  16.165 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.166 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.167 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.168 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L2_TABLE;
  16.169 -    increment_index();
  16.170 -    spin_unlock_irqrestore(&update_lock, flags);
  16.171 -}
  16.172 -
  16.173 -void queue_pgd_unpin(unsigned long ptr)
  16.174 -{
  16.175 -    int cpu = smp_processor_id();
  16.176 -    int idx;
  16.177 -    unsigned long flags;
  16.178 -    spin_lock_irqsave(&update_lock, flags);
  16.179 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.180 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.181 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.182 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
  16.183 -    increment_index();
  16.184 -    spin_unlock_irqrestore(&update_lock, flags);
  16.185 -}
  16.186 -
  16.187 -void queue_pte_pin(unsigned long ptr)
  16.188 -{
  16.189 -    int cpu = smp_processor_id();
  16.190 -    int idx;
  16.191 -    unsigned long flags;
  16.192 -    spin_lock_irqsave(&update_lock, flags);
  16.193 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.194 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.195 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.196 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L1_TABLE;
  16.197 -    increment_index();
  16.198 -    spin_unlock_irqrestore(&update_lock, flags);
  16.199 -}
  16.200 -
  16.201 -void queue_pte_unpin(unsigned long ptr)
  16.202 -{
  16.203 -    int cpu = smp_processor_id();
  16.204 -    int idx;
  16.205 -    unsigned long flags;
  16.206 -    spin_lock_irqsave(&update_lock, flags);
  16.207 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.208 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.209 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.210 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
  16.211 -    increment_index();
  16.212 -    spin_unlock_irqrestore(&update_lock, flags);
  16.213 -}
  16.214 -
  16.215 -void queue_set_ldt(unsigned long ptr, unsigned long len)
  16.216 -{
  16.217 -    int cpu = smp_processor_id();
  16.218 -    int idx;
  16.219 -    unsigned long flags;
  16.220 -    spin_lock_irqsave(&update_lock, flags);
  16.221 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.222 -    per_cpu(update_queue[idx], cpu).ptr  = MMU_EXTENDED_COMMAND | ptr;
  16.223 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_SET_LDT | (len << MMUEXT_CMD_SHIFT);
  16.224 -    increment_index();
  16.225 -    spin_unlock_irqrestore(&update_lock, flags);
  16.226 -}
  16.227 -
  16.228 -void queue_machphys_update(unsigned long mfn, unsigned long pfn)
  16.229 -{
  16.230 -    int cpu = smp_processor_id();
  16.231 -    int idx;
  16.232 -    unsigned long flags;
  16.233 -    spin_lock_irqsave(&update_lock, flags);
  16.234 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.235 -    per_cpu(update_queue[idx], cpu).ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
  16.236 -    per_cpu(update_queue[idx], cpu).val = pfn;
  16.237 -    increment_index();
  16.238 -    spin_unlock_irqrestore(&update_lock, flags);
  16.239 -}
  16.240 -
  16.241 -/* queue and flush versions of the above */
  16.242  void xen_l1_entry_update(pte_t *ptr, unsigned long val)
  16.243  {
  16.244 -    int cpu = smp_processor_id();
  16.245 -    int idx;
  16.246 -    unsigned long flags;
  16.247 -    spin_lock_irqsave(&update_lock, flags);
  16.248 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.249 -    per_cpu(update_queue[idx], cpu).ptr = virt_to_machine(ptr);
  16.250 -    per_cpu(update_queue[idx], cpu).val = val;
  16.251 -    increment_index_and_flush();
  16.252 -    spin_unlock_irqrestore(&update_lock, flags);
  16.253 +    mmu_update_t u;
  16.254 +    u.ptr = virt_to_machine(ptr);
  16.255 +    u.val = val;
  16.256 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.257  }
  16.258  
  16.259  void xen_l2_entry_update(pmd_t *ptr, pmd_t val)
  16.260  {
  16.261 -    int cpu = smp_processor_id();
  16.262 -    int idx;
  16.263 -    unsigned long flags;
  16.264 -    spin_lock_irqsave(&update_lock, flags);
  16.265 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.266 -    per_cpu(update_queue[idx], cpu).ptr = virt_to_machine(ptr);
  16.267 -    per_cpu(update_queue[idx], cpu).val = pmd_val_ma(val);
  16.268 -    increment_index_and_flush();
  16.269 -    spin_unlock_irqrestore(&update_lock, flags);
  16.270 +    mmu_update_t u;
  16.271 +    u.ptr = virt_to_machine(ptr);
  16.272 +    u.val = pmd_val_ma(val);
  16.273 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.274  }
  16.275  
  16.276  void xen_pt_switch(unsigned long ptr)
  16.277  {
  16.278 -    int cpu = smp_processor_id();
  16.279 -    int idx;
  16.280 -    unsigned long flags;
  16.281 -    spin_lock_irqsave(&update_lock, flags);
  16.282 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.283 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.284 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.285 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_NEW_BASEPTR;
  16.286 -    increment_index_and_flush();
  16.287 -    spin_unlock_irqrestore(&update_lock, flags);
  16.288 +    mmu_update_t u;
  16.289 +    u.ptr = phys_to_machine(ptr) | MMU_EXTENDED_COMMAND;
  16.290 +    u.val = MMUEXT_NEW_BASEPTR;
  16.291 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.292  }
  16.293  
  16.294  void xen_tlb_flush(void)
  16.295  {
  16.296 -    int cpu = smp_processor_id();
  16.297 -    int idx;
  16.298 -    unsigned long flags;
  16.299 -    spin_lock_irqsave(&update_lock, flags);
  16.300 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.301 -    per_cpu(update_queue[idx], cpu).ptr  = MMU_EXTENDED_COMMAND;
  16.302 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_TLB_FLUSH;
  16.303 -    increment_index_and_flush();
  16.304 -    spin_unlock_irqrestore(&update_lock, flags);
  16.305 +    mmu_update_t u;
  16.306 +    u.ptr = MMU_EXTENDED_COMMAND;
  16.307 +    u.val = MMUEXT_TLB_FLUSH;
  16.308 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.309  }
  16.310  
  16.311  void xen_invlpg(unsigned long ptr)
  16.312  {
  16.313 -    int cpu = smp_processor_id();
  16.314 -    int idx;
  16.315 -    unsigned long flags;
  16.316 -    spin_lock_irqsave(&update_lock, flags);
  16.317 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.318 -    per_cpu(update_queue[idx], cpu).ptr  = MMU_EXTENDED_COMMAND;
  16.319 -    per_cpu(update_queue[idx], cpu).ptr |= ptr & PAGE_MASK;
  16.320 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_INVLPG;
  16.321 -    increment_index_and_flush();
  16.322 -    spin_unlock_irqrestore(&update_lock, flags);
  16.323 +    mmu_update_t u;
  16.324 +    u.ptr = (ptr & PAGE_MASK) | MMU_EXTENDED_COMMAND;
  16.325 +    u.val = MMUEXT_INVLPG;
  16.326 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.327  }
  16.328  
  16.329  void xen_pgd_pin(unsigned long ptr)
  16.330  {
  16.331 -    int cpu = smp_processor_id();
  16.332 -    int idx;
  16.333 -    unsigned long flags;
  16.334 -    spin_lock_irqsave(&update_lock, flags);
  16.335 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.336 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.337 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.338 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L2_TABLE;
  16.339 -    increment_index_and_flush();
  16.340 -    spin_unlock_irqrestore(&update_lock, flags);
  16.341 +    mmu_update_t u;
  16.342 +    u.ptr = phys_to_machine(ptr) | MMU_EXTENDED_COMMAND;
  16.343 +    u.val = MMUEXT_PIN_L2_TABLE;
  16.344 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.345  }
  16.346  
  16.347  void xen_pgd_unpin(unsigned long ptr)
  16.348  {
  16.349 -    int cpu = smp_processor_id();
  16.350 -    int idx;
  16.351 -    unsigned long flags;
  16.352 -    spin_lock_irqsave(&update_lock, flags);
  16.353 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.354 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.355 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.356 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
  16.357 -    increment_index_and_flush();
  16.358 -    spin_unlock_irqrestore(&update_lock, flags);
  16.359 +    mmu_update_t u;
  16.360 +    u.ptr = phys_to_machine(ptr) | MMU_EXTENDED_COMMAND;
  16.361 +    u.val = MMUEXT_UNPIN_TABLE;
  16.362 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.363  }
  16.364  
  16.365  void xen_pte_pin(unsigned long ptr)
  16.366  {
  16.367 -    int cpu = smp_processor_id();
  16.368 -    int idx;
  16.369 -    unsigned long flags;
  16.370 -    spin_lock_irqsave(&update_lock, flags);
  16.371 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.372 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.373 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.374 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L1_TABLE;
  16.375 -    increment_index_and_flush();
  16.376 -    spin_unlock_irqrestore(&update_lock, flags);
  16.377 +    mmu_update_t u;
  16.378 +    u.ptr = phys_to_machine(ptr) | MMU_EXTENDED_COMMAND;
  16.379 +    u.val = MMUEXT_PIN_L1_TABLE;
  16.380 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.381  }
  16.382  
  16.383  void xen_pte_unpin(unsigned long ptr)
  16.384  {
  16.385 -    int cpu = smp_processor_id();
  16.386 -    int idx;
  16.387 -    unsigned long flags;
  16.388 -    spin_lock_irqsave(&update_lock, flags);
  16.389 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.390 -    per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
  16.391 -    per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
  16.392 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
  16.393 -    increment_index_and_flush();
  16.394 -    spin_unlock_irqrestore(&update_lock, flags);
  16.395 +    mmu_update_t u;
  16.396 +    u.ptr = phys_to_machine(ptr) | MMU_EXTENDED_COMMAND;
  16.397 +    u.val = MMUEXT_UNPIN_TABLE;
  16.398 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.399  }
  16.400  
  16.401  void xen_set_ldt(unsigned long ptr, unsigned long len)
  16.402  {
  16.403 -    int cpu = smp_processor_id();
  16.404 -    int idx;
  16.405 -    unsigned long flags;
  16.406 -    spin_lock_irqsave(&update_lock, flags);
  16.407 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.408 -    per_cpu(update_queue[idx], cpu).ptr  = MMU_EXTENDED_COMMAND | ptr;
  16.409 -    per_cpu(update_queue[idx], cpu).val  = MMUEXT_SET_LDT | (len << MMUEXT_CMD_SHIFT);
  16.410 -    increment_index_and_flush();
  16.411 -    spin_unlock_irqrestore(&update_lock, flags);
  16.412 +    mmu_update_t u;
  16.413 +    u.ptr = ptr | MMU_EXTENDED_COMMAND;
  16.414 +    u.val = (len << MMUEXT_CMD_SHIFT) | MMUEXT_SET_LDT;
  16.415 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.416  }
  16.417  
  16.418  void xen_machphys_update(unsigned long mfn, unsigned long pfn)
  16.419  {
  16.420 -    int cpu = smp_processor_id();
  16.421 -    int idx;
  16.422 -    unsigned long flags;
  16.423 -    spin_lock_irqsave(&update_lock, flags);
  16.424 -    idx = per_cpu(mmu_update_queue_idx, cpu);
  16.425 -    per_cpu(update_queue[idx], cpu).ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
  16.426 -    per_cpu(update_queue[idx], cpu).val = pfn;
  16.427 -    increment_index_and_flush();
  16.428 -    spin_unlock_irqrestore(&update_lock, flags);
  16.429 +    mmu_update_t u;
  16.430 +    u.ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
  16.431 +    u.val = pfn;
  16.432 +    BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL) < 0);
  16.433  }
  16.434  
  16.435  #ifdef CONFIG_XEN_PHYSDEV_ACCESS
  16.436 @@ -449,11 +165,10 @@ unsigned long allocate_empty_lowmem_regi
  16.437          pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
  16.438          pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE))); 
  16.439          pfn_array[i] = pte->pte_low >> PAGE_SHIFT;
  16.440 -        queue_l1_entry_update(pte, 0);
  16.441 +        HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE), __pte_ma(0), 0);
  16.442          phys_to_machine_mapping[__pa(vstart)>>PAGE_SHIFT] = INVALID_P2M_ENTRY;
  16.443      }
  16.444  
  16.445 -    /* Flush updates through and flush the TLB. */
  16.446      xen_tlb_flush();
  16.447  
  16.448      balloon_put_pages(pfn_array, 1 << order);
    17.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c	Tue Mar 29 10:24:22 2005 +0000
    17.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c	Tue Mar 29 14:35:22 2005 +0000
    17.3 @@ -357,7 +357,6 @@ static void __init pagetable_init (void)
    17.4  	make_page_readonly(new_pgd);
    17.5  	xen_pgd_pin(__pa(new_pgd));
    17.6  	load_cr3(new_pgd);
    17.7 -	flush_page_update_queue();
    17.8  	xen_pgd_unpin(__pa(old_pgd));
    17.9  	make_page_writable(old_pgd);
   17.10  	__flush_tlb_all();
    18.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c	Tue Mar 29 10:24:22 2005 +0000
    18.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c	Tue Mar 29 14:35:22 2005 +0000
    18.3 @@ -139,24 +139,6 @@ static struct page *balloon_retrieve(voi
    18.4      return page;
    18.5  }
    18.6  
    18.7 -static inline pte_t *get_ptep(unsigned long addr)
    18.8 -{
    18.9 -    pgd_t *pgd;
   18.10 -    pud_t *pud;
   18.11 -    pmd_t *pmd;
   18.12 -
   18.13 -    pgd = pgd_offset_k(addr);
   18.14 -    if ( pgd_none(*pgd) || pgd_bad(*pgd) ) BUG();
   18.15 -
   18.16 -    pud = pud_offset(pgd, addr);
   18.17 -    if ( pud_none(*pud) || pud_bad(*pud) ) BUG();
   18.18 -
   18.19 -    pmd = pmd_offset(pud, addr);
   18.20 -    if ( pmd_none(*pmd) || pmd_bad(*pmd) ) BUG();
   18.21 -
   18.22 -    return pte_offset_kernel(pmd, addr);
   18.23 -}
   18.24 -
   18.25  static void balloon_alarm(unsigned long unused)
   18.26  {
   18.27      schedule_work(&balloon_worker);
   18.28 @@ -220,14 +202,18 @@ static void balloon_process(void *unused
   18.29  
   18.30              /* Update P->M and M->P tables. */
   18.31              phys_to_machine_mapping[pfn] = mfn_list[i];
   18.32 -            queue_machphys_update(mfn_list[i], pfn);
   18.33 +            xen_machphys_update(mfn_list[i], pfn);
   18.34              
   18.35              /* Link back into the page tables if it's not a highmem page. */
   18.36              if ( pfn < max_low_pfn )
   18.37 -                queue_l1_entry_update(
   18.38 -                    get_ptep((unsigned long)__va(pfn << PAGE_SHIFT)),
   18.39 -                    (mfn_list[i] << PAGE_SHIFT) | pgprot_val(PAGE_KERNEL));
   18.40 -            
   18.41 +            {
   18.42 +                HYPERVISOR_update_va_mapping(
   18.43 +                    (unsigned long)__va(pfn << PAGE_SHIFT),
   18.44 +                    __pte_ma((mfn_list[i] << PAGE_SHIFT) |
   18.45 +                             pgprot_val(PAGE_KERNEL)),
   18.46 +                    0);
   18.47 +            }
   18.48 +
   18.49              /* Finally, relinquish the memory back to the system allocator. */
   18.50              ClearPageReserved(page);
   18.51              set_page_count(page, 1);
   18.52 @@ -259,7 +245,8 @@ static void balloon_process(void *unused
   18.53              {
   18.54                  v = phys_to_virt(pfn << PAGE_SHIFT);
   18.55                  scrub_pages(v, 1);
   18.56 -                queue_l1_entry_update(get_ptep((unsigned long)v), 0);
   18.57 +                HYPERVISOR_update_va_mapping(
   18.58 +                    (unsigned long)v, __pte_ma(0), 0);
   18.59              }
   18.60  #ifdef CONFIG_XEN_SCRUB_PAGES
   18.61              else
   18.62 @@ -274,7 +261,6 @@ static void balloon_process(void *unused
   18.63          /* Ensure that ballooned highmem pages don't have cached mappings. */
   18.64          kmap_flush_unused();
   18.65  
   18.66 -        /* Flush updates through and flush the TLB. */
   18.67          xen_tlb_flush();
   18.68  
   18.69          /* No more mappings: invalidate pages in P2M and add to balloon. */
    19.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h	Tue Mar 29 10:24:22 2005 +0000
    19.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h	Tue Mar 29 14:35:22 2005 +0000
    19.3 @@ -103,7 +103,7 @@ static inline void clear_LDT(void)
    19.4  	 * it slows down context switching. Noone uses it anyway.
    19.5  	 */
    19.6  	cpu = cpu;		/* XXX avoid compiler warning */
    19.7 -	queue_set_ldt(0UL, 0);
    19.8 +	xen_set_ldt(0UL, 0);
    19.9  	put_cpu();
   19.10  }
   19.11  
   19.12 @@ -118,7 +118,7 @@ static inline void load_LDT_nolock(mm_co
   19.13  	if (likely(!count))
   19.14  		segments = NULL;
   19.15  
   19.16 -	queue_set_ldt((unsigned long)segments, count);
   19.17 +	xen_set_ldt((unsigned long)segments, count);
   19.18  }
   19.19  
   19.20  static inline void load_LDT(mm_context_t *pc)
    20.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h	Tue Mar 29 10:24:22 2005 +0000
    20.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h	Tue Mar 29 14:35:22 2005 +0000
    20.3 @@ -68,7 +68,6 @@ static inline void switch_mm(struct mm_s
    20.4  
    20.5  #define activate_mm(prev, next) do {		\
    20.6  	switch_mm((prev),(next),NULL);		\
    20.7 -	flush_page_update_queue();		\
    20.8  } while (0)
    20.9  
   20.10  #endif
    21.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Tue Mar 29 10:24:22 2005 +0000
    21.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Tue Mar 29 14:35:22 2005 +0000
    21.3 @@ -9,13 +9,12 @@
    21.4  #include <asm/io.h>		/* for phys_to_virt and page_to_pseudophys */
    21.5  
    21.6  #define pmd_populate_kernel(mm, pmd, pte) \
    21.7 -		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
    21.8 +	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
    21.9  
   21.10  #define pmd_populate(mm, pmd, pte) do {				\
   21.11  	set_pmd(pmd, __pmd(_PAGE_TABLE +			\
   21.12  		((unsigned long long)page_to_pfn(pte) <<	\
   21.13  			(unsigned long long) PAGE_SHIFT)));	\
   21.14 -	flush_page_update_queue();				\
   21.15  } while (0)
   21.16  /*
   21.17   * Allocate and free page tables.
   21.18 @@ -30,7 +29,6 @@ static inline void pte_free_kernel(pte_t
   21.19  {
   21.20  	free_page((unsigned long)pte);
   21.21  	make_page_writable(pte);
   21.22 -	flush_page_update_queue();
   21.23  }
   21.24  
   21.25  extern void pte_free(struct page *pte);
    22.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Tue Mar 29 10:24:22 2005 +0000
    22.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Tue Mar 29 14:35:22 2005 +0000
    22.3 @@ -432,7 +432,6 @@ do {				  					\
    22.4  	}								\
    22.5  } while (0)
    22.6  
    22.7 -/* NOTE: make_page* callers must call flush_page_update_queue() */
    22.8  void make_lowmem_page_readonly(void *va);
    22.9  void make_lowmem_page_writable(void *va);
   22.10  void make_page_readonly(void *va);
    23.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h	Tue Mar 29 10:24:22 2005 +0000
    23.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h	Tue Mar 29 14:35:22 2005 +0000
    23.3 @@ -193,7 +193,7 @@ static inline unsigned int cpuid_edx(uns
    23.4  }
    23.5  
    23.6  #define load_cr3(pgdir) do {				\
    23.7 -	queue_pt_switch(__pa(pgdir));			\
    23.8 +	xen_pt_switch(__pa(pgdir));			\
    23.9  	per_cpu(cur_pgd, smp_processor_id()) = pgdir;	\
   23.10  } while (/* CONSTCOND */0)
   23.11  
    24.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h	Tue Mar 29 10:24:22 2005 +0000
    24.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h	Tue Mar 29 14:35:22 2005 +0000
    24.3 @@ -71,17 +71,6 @@ void lgdt_finish(void);
    24.4   * be MACHINE addresses.
    24.5   */
    24.6  
    24.7 -void queue_l1_entry_update(pte_t *ptr, unsigned long val);
    24.8 -void queue_l2_entry_update(pmd_t *ptr, pmd_t val);
    24.9 -void queue_pt_switch(unsigned long ptr);
   24.10 -void queue_tlb_flush(void);
   24.11 -void queue_invlpg(unsigned long ptr);
   24.12 -void queue_pgd_pin(unsigned long ptr);
   24.13 -void queue_pgd_unpin(unsigned long ptr);
   24.14 -void queue_pte_pin(unsigned long ptr);
   24.15 -void queue_pte_unpin(unsigned long ptr);
   24.16 -void queue_set_ldt(unsigned long ptr, unsigned long bytes);
   24.17 -void queue_machphys_update(unsigned long mfn, unsigned long pfn);
   24.18  void xen_l1_entry_update(pte_t *ptr, unsigned long val);
   24.19  void xen_l2_entry_update(pmd_t *ptr, pmd_t val);
   24.20  void xen_pt_switch(unsigned long ptr);
   24.21 @@ -94,8 +83,6 @@ void xen_pte_unpin(unsigned long ptr);
   24.22  void xen_set_ldt(unsigned long ptr, unsigned long bytes);
   24.23  void xen_machphys_update(unsigned long mfn, unsigned long pfn);
   24.24  
   24.25 -void _flush_page_update_queue(void);
   24.26 -
   24.27  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   24.28  /* 
   24.29  ** XXX SMH: 2.4 doesn't have percpu.h (or support SMP guests) so just 
   24.30 @@ -112,13 +99,6 @@ void _flush_page_update_queue(void);
   24.31  #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
   24.32  #endif /* linux < 2.6.0 */
   24.33  
   24.34 -#define flush_page_update_queue() do {				\
   24.35 -    DECLARE_PER_CPU(unsigned int, mmu_update_queue_idx);	\
   24.36 -    if (per_cpu(mmu_update_queue_idx, smp_processor_id()))	\
   24.37 -	_flush_page_update_queue();				\
   24.38 -} while (0)
   24.39 -void MULTICALL_flush_page_update_queue(void);
   24.40 -
   24.41  #ifdef CONFIG_XEN_PHYSDEV_ACCESS
   24.42  /* Allocate a contiguous empty region of low memory. Return virtual start. */
   24.43  unsigned long allocate_empty_lowmem_region(unsigned long pages);
    25.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/multicall.h	Tue Mar 29 10:24:22 2005 +0000
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,115 +0,0 @@
    25.4 -/******************************************************************************
    25.5 - * multicall.h
    25.6 - * 
    25.7 - * Copyright (c) 2003-2004, K A Fraser
    25.8 - * 
    25.9 - * This file may be distributed separately from the Linux kernel, or
   25.10 - * incorporated into other software packages, subject to the following license:
   25.11 - * 
   25.12 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   25.13 - * of this source file (the "Software"), to deal in the Software without
   25.14 - * restriction, including without limitation the rights to use, copy, modify,
   25.15 - * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   25.16 - * and to permit persons to whom the Software is furnished to do so, subject to
   25.17 - * the following conditions:
   25.18 - * 
   25.19 - * The above copyright notice and this permission notice shall be included in
   25.20 - * all copies or substantial portions of the Software.
   25.21 - * 
   25.22 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   25.23 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   25.24 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   25.25 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   25.26 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   25.27 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   25.28 - * IN THE SOFTWARE.
   25.29 - */
   25.30 -
   25.31 -#ifndef __MULTICALL_H__
   25.32 -#define __MULTICALL_H__
   25.33 -
   25.34 -#include <asm-xen/hypervisor.h>
   25.35 -
   25.36 -DECLARE_PER_CPU(multicall_entry_t, multicall_list[]);
   25.37 -DECLARE_PER_CPU(int, nr_multicall_ents);
   25.38 -
   25.39 -static inline void queue_multicall0(unsigned long op)
   25.40 -{
   25.41 -    int cpu = smp_processor_id();
   25.42 -    int i = per_cpu(nr_multicall_ents, cpu);
   25.43 -    per_cpu(multicall_list[i], cpu).op      = op;
   25.44 -    per_cpu(nr_multicall_ents, cpu) = i+1;
   25.45 -}
   25.46 -
   25.47 -static inline void queue_multicall1(unsigned long op, unsigned long arg1)
   25.48 -{
   25.49 -    int cpu = smp_processor_id();
   25.50 -    int i = per_cpu(nr_multicall_ents, cpu);
   25.51 -    per_cpu(multicall_list[i], cpu).op      = op;
   25.52 -    per_cpu(multicall_list[i], cpu).args[0] = arg1;
   25.53 -    per_cpu(nr_multicall_ents, cpu) = i+1;
   25.54 -}
   25.55 -
   25.56 -static inline void queue_multicall2(
   25.57 -    unsigned long op, unsigned long arg1, unsigned long arg2)
   25.58 -{
   25.59 -    int cpu = smp_processor_id();
   25.60 -    int i = per_cpu(nr_multicall_ents, cpu);
   25.61 -    per_cpu(multicall_list[i], cpu).op      = op;
   25.62 -    per_cpu(multicall_list[i], cpu).args[0] = arg1;
   25.63 -    per_cpu(multicall_list[i], cpu).args[1] = arg2;
   25.64 -    per_cpu(nr_multicall_ents, cpu) = i+1;
   25.65 -}
   25.66 -
   25.67 -static inline void queue_multicall3(
   25.68 -    unsigned long op, unsigned long arg1, unsigned long arg2,
   25.69 -    unsigned long arg3)
   25.70 -{
   25.71 -    int cpu = smp_processor_id();
   25.72 -    int i = per_cpu(nr_multicall_ents, cpu);
   25.73 -    per_cpu(multicall_list[i], cpu).op      = op;
   25.74 -    per_cpu(multicall_list[i], cpu).args[0] = arg1;
   25.75 -    per_cpu(multicall_list[i], cpu).args[1] = arg2;
   25.76 -    per_cpu(multicall_list[i], cpu).args[2] = arg3;
   25.77 -    per_cpu(nr_multicall_ents, cpu) = i+1;
   25.78 -}
   25.79 -
   25.80 -static inline void queue_multicall4(
   25.81 -    unsigned long op, unsigned long arg1, unsigned long arg2,
   25.82 -    unsigned long arg3, unsigned long arg4)
   25.83 -{
   25.84 -    int cpu = smp_processor_id();
   25.85 -    int i = per_cpu(nr_multicall_ents, cpu);
   25.86 -    per_cpu(multicall_list[i], cpu).op      = op;
   25.87 -    per_cpu(multicall_list[i], cpu).args[0] = arg1;
   25.88 -    per_cpu(multicall_list[i], cpu).args[1] = arg2;
   25.89 -    per_cpu(multicall_list[i], cpu).args[2] = arg3;
   25.90 -    per_cpu(multicall_list[i], cpu).args[3] = arg4;
   25.91 -    per_cpu(nr_multicall_ents, cpu) = i+1;
   25.92 -}
   25.93 -
   25.94 -static inline void queue_multicall5(
   25.95 -    unsigned long op, unsigned long arg1, unsigned long arg2,
   25.96 -    unsigned long arg3, unsigned long arg4, unsigned long arg5)
   25.97 -{
   25.98 -    int cpu = smp_processor_id();
   25.99 -    int i = per_cpu(nr_multicall_ents, cpu);
  25.100 -    per_cpu(multicall_list[i], cpu).op      = op;
  25.101 -    per_cpu(multicall_list[i], cpu).args[0] = arg1;
  25.102 -    per_cpu(multicall_list[i], cpu).args[1] = arg2;
  25.103 -    per_cpu(multicall_list[i], cpu).args[2] = arg3;
  25.104 -    per_cpu(multicall_list[i], cpu).args[3] = arg4;
  25.105 -    per_cpu(multicall_list[i], cpu).args[4] = arg5;
  25.106 -    per_cpu(nr_multicall_ents, cpu) = i+1;
  25.107 -}
  25.108 -
  25.109 -static inline void execute_multicall_list(void)
  25.110 -{
  25.111 -    int cpu = smp_processor_id();
  25.112 -    if ( unlikely(per_cpu(nr_multicall_ents, cpu) == 0) ) return;
  25.113 -    (void)HYPERVISOR_multicall(&per_cpu(multicall_list[0], cpu),
  25.114 -			       per_cpu(nr_multicall_ents, cpu));
  25.115 -    per_cpu(nr_multicall_ents, cpu) = 0;
  25.116 -}
  25.117 -
  25.118 -#endif /* __MULTICALL_H__ */