ia64/xen-unstable

changeset 9968:5d9eb92e63e2

merge with xen-unstable.hg
author awilliam@xenbuild.aw
date Mon May 08 14:46:11 2006 -0600 (2006-05-08)
parents 707737b66f58 1e3977e029fd
children f090ab3f06e7
files linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h linux-2.6-xen-sparse/include/xen/tpmfe.h patches/linux-2.6.16/device_bind.patch patches/linux-2.6.16/i386-mach-io-check-nmi.patch patches/linux-2.6.16/net-csum.patch patches/linux-2.6.16/pmd-shared.patch patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch patches/linux-2.6.16/smp-alts.patch patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch patches/linux-2.6.16/xenoprof-generic.patch tools/xenstat/libxenstat/src/xen-interface.c tools/xenstat/libxenstat/src/xen-interface.h tools/xm-test/lib/XmTestLib/Network.py xen/arch/ia64/vmx/vmx_ivt.S xen/include/public/arch-ia64.h
line diff
     1.1 --- a/.hgignore	Mon May 08 13:41:18 2006 -0600
     1.2 +++ b/.hgignore	Mon May 08 14:46:11 2006 -0600
     1.3 @@ -14,6 +14,7 @@
     1.4  .*\.orig$
     1.5  .*\.rej$
     1.6  .*/a\.out$
     1.7 +.*/cscope\.*$
     1.8  ^[^/]*\.bz2$
     1.9  ^TAGS$
    1.10  ^dist/.*$
    1.11 @@ -184,7 +185,6 @@
    1.12  ^tools/xm-test/ramdisk/buildroot
    1.13  ^xen/BLOG$
    1.14  ^xen/TAGS$
    1.15 -^xen/cscope\.*$
    1.16  ^xen/arch/x86/asm-offsets\.s$
    1.17  ^xen/arch/x86/boot/mkelf32$
    1.18  ^xen/arch/x86/xen\.lds$
     2.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Mon May 08 13:41:18 2006 -0600
     2.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Mon May 08 14:46:11 2006 -0600
     2.3 @@ -1235,6 +1235,7 @@ CONFIG_IEEE1394_RAWIO=m
     2.4  CONFIG_I2O=m
     2.5  CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
     2.6  CONFIG_I2O_EXT_ADAPTEC=y
     2.7 +CONFIG_I2O_EXT_ADAPTEC_DMA64=y
     2.8  CONFIG_I2O_CONFIG=m
     2.9  CONFIG_I2O_CONFIG_OLD_IOCTL=y
    2.10  CONFIG_I2O_BUS=m
     3.1 --- a/buildconfigs/mk.linux-2.6-xen	Mon May 08 13:41:18 2006 -0600
     3.2 +++ b/buildconfigs/mk.linux-2.6-xen	Mon May 08 14:46:11 2006 -0600
     3.3 @@ -1,6 +1,5 @@
     3.4  LINUX_SERIES = 2.6
     3.5 -LINUX_VER    = 2.6.16
     3.6 -LINUX_SRCS = linux-2.6.16.tar.bz2
     3.7 +LINUX_VER    = 2.6.16.13
     3.8  
     3.9  EXTRAVERSION ?= xen
    3.10  
     4.1 --- a/docs/misc/vtpm.txt	Mon May 08 13:41:18 2006 -0600
     4.2 +++ b/docs/misc/vtpm.txt	Mon May 08 14:46:11 2006 -0600
     4.3 @@ -21,11 +21,11 @@ Compile the XEN tree as usual after the 
     4.4  linux-2.6.??-xen/.config file:
     4.5  
     4.6  CONFIG_XEN_TPMDEV_BACKEND=y
     4.7 -CONFIG_XEN_TPMDEV_GRANT=y
     4.8  
     4.9 -CONFIG_TCG_TPM=m
    4.10 +CONFIG_TCG_TPM=y
    4.11  CONFIG_TCG_NSC=m
    4.12  CONFIG_TCG_ATMEL=m
    4.13 +CONFIG_TCG_XEN=y
    4.14  
    4.15  You must also enable the virtual TPM to be built:
    4.16  
    4.17 @@ -33,6 +33,12 @@ In Config.mk in the Xen root directory s
    4.18  
    4.19  VTPM_TOOLS ?= y
    4.20  
    4.21 +and in
    4.22 +
    4.23 +tools/vtpm/Rules.mk set the line
    4.24 +
    4.25 +BUILD_EMULATOR = y
    4.26 +
    4.27  Now build the Xen sources from Xen's root directory:
    4.28  
    4.29  make install
     5.1 --- a/extras/mini-os/Makefile	Mon May 08 13:41:18 2006 -0600
     5.2 +++ b/extras/mini-os/Makefile	Mon May 08 14:46:11 2006 -0600
     5.3 @@ -60,4 +60,12 @@ clean:
     5.4  %.o: %.S $(HDRS) Makefile
     5.5  	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
     5.6  
     5.7 +define all_sources
     5.8 +     ( find . -follow -name SCCS -prune -o -name '*.[chS]' -print )
     5.9 +endef
    5.10  
    5.11 +.PHONY: cscope
    5.12 +cscope:
    5.13 +	$(all_sources) > cscope.files
    5.14 +	cscope -k -b -q
    5.15 +
     6.1 --- a/extras/mini-os/console/console.c	Mon May 08 13:41:18 2006 -0600
     6.2 +++ b/extras/mini-os/console/console.c	Mon May 08 14:46:11 2006 -0600
     6.3 @@ -128,7 +128,7 @@ void printk(const char *fmt, ...)
     6.4  {
     6.5      va_list       args;
     6.6      va_start(args, fmt);
     6.7 -    print(0, fmt, args);
     6.8 +    print(1, fmt, args);
     6.9      va_end(args);        
    6.10  }
    6.11  
     7.1 --- a/extras/mini-os/events.c	Mon May 08 13:41:18 2006 -0600
     7.2 +++ b/extras/mini-os/events.c	Mon May 08 14:46:11 2006 -0600
     7.3 @@ -106,6 +106,17 @@ void unbind_virq( u32 port )
     7.4  	unbind_evtchn(port);
     7.5  }
     7.6  
     7.7 +#if defined(__x86_64__)
     7.8 +/* Allocate 4 pages for the irqstack */
     7.9 +#define STACK_PAGES 4
    7.10 +char irqstack[1024 * 4 * STACK_PAGES];
    7.11 +
    7.12 +static struct pda
    7.13 +{
    7.14 +    int irqcount;       /* offset 0 (used in x86_64.S) */
    7.15 +    char *irqstackptr;  /*        8 */
    7.16 +} cpu0_pda;
    7.17 +#endif
    7.18  
    7.19  /*
    7.20   * Initially all events are without a handler and disabled
    7.21 @@ -113,7 +124,12 @@ void unbind_virq( u32 port )
    7.22  void init_events(void)
    7.23  {
    7.24      int i;
    7.25 -
    7.26 +#if defined(__x86_64__)
    7.27 +    asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
    7.28 +    wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
    7.29 +    cpu0_pda.irqcount = -1;
    7.30 +    cpu0_pda.irqstackptr = irqstack + 1024 * 4 * STACK_PAGES;
    7.31 +#endif
    7.32      /* inintialise event handler */
    7.33      for ( i = 0; i < NR_EVS; i++ )
    7.34      {
     8.1 --- a/extras/mini-os/hypervisor.c	Mon May 08 13:41:18 2006 -0600
     8.2 +++ b/extras/mini-os/hypervisor.c	Mon May 08 14:46:11 2006 -0600
     8.3 @@ -41,8 +41,8 @@ void do_hypervisor_callback(struct pt_re
     8.4      shared_info_t *s = HYPERVISOR_shared_info;
     8.5      vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
     8.6  
     8.7 +   
     8.8      vcpu_info->evtchn_upcall_pending = 0;
     8.9 -    
    8.10      /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
    8.11      l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
    8.12      while ( l1 != 0 )
     9.1 --- a/extras/mini-os/include/lib.h	Mon May 08 13:41:18 2006 -0600
     9.2 +++ b/extras/mini-os/include/lib.h	Mon May 08 14:46:11 2006 -0600
     9.3 @@ -56,6 +56,7 @@
     9.4  #define _LIB_H_
     9.5  
     9.6  #include <stdarg.h>
     9.7 +#include <stddef.h>
     9.8  #include <console.h>
     9.9  
    9.10  /* printing */
    10.1 --- a/extras/mini-os/include/mm.h	Mon May 08 13:41:18 2006 -0600
    10.2 +++ b/extras/mini-os/include/mm.h	Mon May 08 14:46:11 2006 -0600
    10.3 @@ -148,7 +148,7 @@ static __inline__ unsigned long machine_
    10.4  }
    10.5  
    10.6  #if defined(__x86_64__)
    10.7 -#define VIRT_START              0xFFFFFFFF00000000UL
    10.8 +#define VIRT_START              0xFFFFFFFF80000000UL
    10.9  #elif defined(__i386__)
   10.10  #define VIRT_START              0xC0000000UL
   10.11  #endif
    11.1 --- a/extras/mini-os/include/os.h	Mon May 08 13:41:18 2006 -0600
    11.2 +++ b/extras/mini-os/include/os.h	Mon May 08 14:46:11 2006 -0600
    11.3 @@ -7,9 +7,6 @@
    11.4  #ifndef _OS_H_
    11.5  #define _OS_H_
    11.6  
    11.7 -#define NULL 0
    11.8 -
    11.9 -
   11.10  #if __GNUC__ == 2 && __GNUC_MINOR__ < 96
   11.11  #define __builtin_expect(x, expected_value) (x)
   11.12  #endif
   11.13 @@ -434,6 +431,13 @@ static __inline__ unsigned long __ffs(un
   11.14       (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
   11.15  } while(0)
   11.16  
   11.17 +#define wrmsr(msr,val1,val2) \
   11.18 +      __asm__ __volatile__("wrmsr" \
   11.19 +                           : /* no outputs */ \
   11.20 +                           : "c" (msr), "a" (val1), "d" (val2))
   11.21 +
   11.22 +#define wrmsrl(msr,val) wrmsr(msr,(u32)((u64)(val)),((u64)(val))>>32)
   11.23 +
   11.24  
   11.25  #else /* ifdef __x86_64__ */
   11.26  #error "Unsupported architecture"
    12.1 --- a/extras/mini-os/include/sched.h	Mon May 08 13:41:18 2006 -0600
    12.2 +++ b/extras/mini-os/include/sched.h	Mon May 08 14:46:11 2006 -0600
    12.3 @@ -7,8 +7,8 @@ struct thread
    12.4  {
    12.5      char *name;
    12.6      char *stack;
    12.7 -    unsigned long eps;
    12.8 -    unsigned long eip;
    12.9 +    unsigned long sp;  /* Stack pointer */
   12.10 +    unsigned long ip;  /* Instruction pointer */
   12.11      struct list_head thread_list;
   12.12      u32 flags;
   12.13  };
   12.14 @@ -25,7 +25,9 @@ static inline struct thread* get_current
   12.15      struct thread **current;
   12.16  #ifdef __i386__    
   12.17      __asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
   12.18 -#endif    
   12.19 +#else
   12.20 +    __asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
   12.21 +#endif 
   12.22      return *current;
   12.23  }
   12.24            
    13.1 --- a/extras/mini-os/include/types.h	Mon May 08 13:41:18 2006 -0600
    13.2 +++ b/extras/mini-os/include/types.h	Mon May 08 14:46:11 2006 -0600
    13.3 @@ -34,8 +34,6 @@ typedef signed long         s64;
    13.4  typedef unsigned long       u64;
    13.5  #endif
    13.6  
    13.7 -typedef unsigned int        size_t;
    13.8 -
    13.9  /* FreeBSD compat types */
   13.10  typedef unsigned char       u_char;
   13.11  typedef unsigned int        u_int;
    14.1 --- a/extras/mini-os/kernel.c	Mon May 08 13:41:18 2006 -0600
    14.2 +++ b/extras/mini-os/kernel.c	Mon May 08 14:46:11 2006 -0600
    14.3 @@ -35,6 +35,8 @@
    14.4  #include <lib.h>
    14.5  #include <sched.h>
    14.6  #include <xenbus.h>
    14.7 +#include <xen/features.h>
    14.8 +#include <xen/version.h>
    14.9  
   14.10  /*
   14.11   * Shared page for communicating with the hypervisor.
   14.12 @@ -85,6 +87,26 @@ static void init_xs(void *ign)
   14.13      test_xenbus();
   14.14  }
   14.15  
   14.16 +
   14.17 +u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
   14.18 +
   14.19 +void setup_xen_features(void)
   14.20 +{
   14.21 +    xen_feature_info_t fi;
   14.22 +    int i, j;
   14.23 +
   14.24 +    for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) 
   14.25 +    {
   14.26 +        fi.submap_idx = i;
   14.27 +        if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
   14.28 +            break;
   14.29 +        
   14.30 +        for (j=0; j<32; j++)
   14.31 +            xen_features[i*32+j] = !!(fi.submap & 1<<j);
   14.32 +    }
   14.33 +}
   14.34 +
   14.35 +
   14.36  /*
   14.37   * INITIAL C ENTRY POINT.
   14.38   */
   14.39 @@ -127,7 +149,9 @@ void start_kernel(start_info_t *si)
   14.40      printk("  flags:      0x%x\n",  (unsigned int)si->flags);
   14.41      printk("  cmd_line:   %s\n",  
   14.42             si->cmd_line ? (const char *)si->cmd_line : "NULL");
   14.43 +    printk("  stack:      %p-%p\n", stack, stack + 8192);
   14.44  
   14.45 +    setup_xen_features();
   14.46  
   14.47      /* Init memory management. */
   14.48      init_mm();
   14.49 @@ -146,7 +170,7 @@ void start_kernel(start_info_t *si)
   14.50   
   14.51      /* Init XenBus from a separate thread */
   14.52      create_thread("init_xs", init_xs, NULL);
   14.53 -    
   14.54 +
   14.55      /* Everything initialised, start idle thread */
   14.56      run_idle_thread();
   14.57  }
    15.1 --- a/extras/mini-os/minios-x86_64.lds	Mon May 08 13:41:18 2006 -0600
    15.2 +++ b/extras/mini-os/minios-x86_64.lds	Mon May 08 14:46:11 2006 -0600
    15.3 @@ -3,7 +3,7 @@ OUTPUT_ARCH(i386:x86-64)
    15.4  ENTRY(_start)
    15.5  SECTIONS
    15.6  {
    15.7 -  . = 0xFFFFFFFF00000000;
    15.8 +  . = 0xFFFFFFFF80000000;
    15.9    _text = .;			/* Text and read-only data */
   15.10    .text : {
   15.11  	*(.text)
    16.1 --- a/extras/mini-os/sched.c	Mon May 08 13:41:18 2006 -0600
    16.2 +++ b/extras/mini-os/sched.c	Mon May 08 14:46:11 2006 -0600
    16.3 @@ -69,17 +69,27 @@ void idle_thread_fn(void *unused);
    16.4  
    16.5  void dump_stack(struct thread *thread)
    16.6  {
    16.7 -    unsigned long *bottom = (unsigned long *)thread->stack + 2048; 
    16.8 -    unsigned long *pointer = (unsigned long *)thread->eps;
    16.9 +    unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024); 
   16.10 +    unsigned long *pointer = (unsigned long *)thread->sp;
   16.11      int count;
   16.12 +    if(thread == current)
   16.13 +    {
   16.14 +#ifdef __i386__    
   16.15 +        asm("movl %%esp,%0"
   16.16 +            : "=r"(pointer));
   16.17 +#else
   16.18 +        asm("movq %%rsp,%0"
   16.19 +            : "=r"(pointer));
   16.20 +#endif
   16.21 +    }
   16.22      printk("The stack for \"%s\"\n", thread->name);
   16.23 -    for(count = 0; count < 15 && pointer < bottom; count ++)
   16.24 +    for(count = 0; count < 25 && pointer < bottom; count ++)
   16.25      {
   16.26          printk("[0x%lx] 0x%lx\n", pointer, *pointer);
   16.27          pointer++;
   16.28      }
   16.29      
   16.30 -    if(pointer < bottom) printk("Not the whole stack printed\n");
   16.31 +    if(pointer < bottom) printk(" ... continues.\n");
   16.32  }
   16.33  
   16.34  #ifdef __i386__
   16.35 @@ -95,13 +105,29 @@ void dump_stack(struct thread *thread)
   16.36                           "1:\t"                                         \
   16.37                           "popl %%ebp\n\t"                               \
   16.38                           "popfl"                                        \
   16.39 -                         :"=m" (prev->eps),"=m" (prev->eip),            \
   16.40 +                         :"=m" (prev->sp),"=m" (prev->ip),            \
   16.41                            "=S" (esi),"=D" (edi)             \
   16.42 -                         :"m" (next->eps),"m" (next->eip),              \
   16.43 +                         :"m" (next->sp),"m" (next->ip),              \
   16.44                            "2" (prev), "d" (next));                      \
   16.45  } while (0)
   16.46  #elif __x86_64__
   16.47 -/* FIXME */
   16.48 +#define switch_threads(prev, next) do {                                 \
   16.49 +    unsigned long rsi,rdi;                                              \
   16.50 +    __asm__ __volatile__("pushfq\n\t"                                   \
   16.51 +                         "pushq %%rbp\n\t"                              \
   16.52 +                         "movq %%rsp,%0\n\t"         /* save RSP */     \
   16.53 +                         "movq %4,%%rsp\n\t"        /* restore RSP */   \
   16.54 +                         "movq $1f,%1\n\t"          /* save RIP */      \
   16.55 +                         "pushq %5\n\t"             /* restore RIP */   \
   16.56 +                         "ret\n\t"                                      \
   16.57 +                         "1:\t"                                         \
   16.58 +                         "popq %%rbp\n\t"                               \
   16.59 +                         "popfq"                                        \
   16.60 +                         :"=m" (prev->sp),"=m" (prev->ip),            \
   16.61 +                          "=S" (rsi),"=D" (rdi)             \
   16.62 +                         :"m" (next->sp),"m" (next->ip),              \
   16.63 +                          "2" (prev), "d" (next));                      \
   16.64 +} while (0)
   16.65  #endif
   16.66  
   16.67  void inline print_runqueue(void)
   16.68 @@ -151,17 +177,19 @@ void schedule(void)
   16.69      local_irq_restore(flags);
   16.70      /* Interrupting the switch is equivalent to having the next thread
   16.71         inturrupted at the return instruction. And therefore at safe point. */
   16.72 -/* The thread switching only works for i386 at the moment */    
   16.73 -#ifdef __i386__    
   16.74      if(prev != next) switch_threads(prev, next);
   16.75 -#endif    
   16.76  }
   16.77  
   16.78  
   16.79 +/* Gets run when a new thread is scheduled the first time ever, 
   16.80 +   defined in x86_[32/64].S */
   16.81 +extern void thread_starter(void);
   16.82  
   16.83 -void exit_thread(struct thread *thread)
   16.84 +
   16.85 +void exit_thread(void)
   16.86  {
   16.87      unsigned long flags;
   16.88 +    struct thread *thread = current;
   16.89      printk("Thread \"%s\" exited.\n", thread->name);
   16.90      local_irq_save(flags);
   16.91      /* Remove from the thread list */
   16.92 @@ -174,6 +202,12 @@ void exit_thread(struct thread *thread)
   16.93      schedule();
   16.94  }
   16.95  
   16.96 +/* Pushes the specified value onto the stack of the specified thread */
   16.97 +static void stack_push(struct thread *thread, unsigned long value)
   16.98 +{
   16.99 +    thread->sp -= sizeof(unsigned long);
  16.100 +    *((unsigned long *)thread->sp) = value;
  16.101 +}
  16.102  
  16.103  struct thread* create_thread(char *name, void (*function)(void *), void *data)
  16.104  {
  16.105 @@ -187,23 +221,17 @@ struct thread* create_thread(char *name,
  16.106      printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread, 
  16.107              thread->stack);
  16.108      
  16.109 -    thread->eps = (unsigned long)thread->stack + 4096 * 2 - 4;
  16.110 +    thread->sp = (unsigned long)thread->stack + 4096 * 2;
  16.111      /* Save pointer to the thread on the stack, used by current macro */
  16.112      *((unsigned long *)thread->stack) = (unsigned long)thread;
  16.113 -    *((unsigned long *)thread->eps) = (unsigned long)thread;
  16.114 -    thread->eps -= 4; 
  16.115 -    *((unsigned long *)thread->eps) = (unsigned long)data;
  16.116      
  16.117 -    /* No return address */
  16.118 -    thread->eps -= 4;
  16.119 -    *((unsigned long *)thread->eps) = (unsigned long)exit_thread;
  16.120 -    
  16.121 -    thread->eip = (unsigned long)function;
  16.122 +    stack_push(thread, (unsigned long) function);
  16.123 +    stack_push(thread, (unsigned long) data);
  16.124 +    thread->ip = (unsigned long) thread_starter;
  16.125       
  16.126      /* Not runable, not exited */ 
  16.127      thread->flags = 0;
  16.128      set_runnable(thread);
  16.129 -    
  16.130      local_irq_save(flags);
  16.131      if(idle_thread != NULL) {
  16.132          list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
  16.133 @@ -213,7 +241,6 @@ struct thread* create_thread(char *name,
  16.134          BUG();
  16.135      }
  16.136      local_irq_restore(flags);
  16.137 -
  16.138      return thread;
  16.139  }
  16.140  
  16.141 @@ -240,11 +267,19 @@ void idle_thread_fn(void *unused)
  16.142  void run_idle_thread(void)
  16.143  {
  16.144      /* Switch stacks and run the thread */ 
  16.145 +#if defined(__i386__)
  16.146      __asm__ __volatile__("mov %0,%%esp\n\t"
  16.147                           "push %1\n\t" 
  16.148                           "ret"                                            
  16.149 -                         :"=m" (idle_thread->eps)
  16.150 -                         :"m" (idle_thread->eip));                          
  16.151 +                         :"=m" (idle_thread->sp)
  16.152 +                         :"m" (idle_thread->ip));                          
  16.153 +#elif defined(__x86_64__)
  16.154 +    __asm__ __volatile__("mov %0,%%rsp\n\t"
  16.155 +                         "push %1\n\t" 
  16.156 +                         "ret"                                            
  16.157 +                         :"=m" (idle_thread->sp)
  16.158 +                         :"m" (idle_thread->ip));                          
  16.159 +#endif
  16.160  }
  16.161  
  16.162  
  16.163 @@ -289,7 +324,7 @@ void th_f2(void *data)
  16.164  
  16.165  void init_sched(void)
  16.166  {
  16.167 -    printk("Initialising scheduler, idle_thread %p\n", idle_thread);
  16.168 +    printk("Initialising scheduler\n");
  16.169  
  16.170      idle_thread = create_thread("Idle", idle_thread_fn, NULL);
  16.171      INIT_LIST_HEAD(&idle_thread->thread_list);
    17.1 --- a/extras/mini-os/traps.c	Mon May 08 13:41:18 2006 -0600
    17.2 +++ b/extras/mini-os/traps.c	Mon May 08 14:46:11 2006 -0600
    17.3 @@ -123,8 +123,13 @@ void page_walk(unsigned long virt_addres
    17.4  void do_page_fault(struct pt_regs *regs, unsigned long error_code)
    17.5  {
    17.6      unsigned long addr = read_cr2();
    17.7 -    printk("Page fault at linear address %p, regs %p, code %lx\n", addr, regs,
    17.8 -	   error_code);
    17.9 +#if defined(__x86_64__)
   17.10 +    printk("Page fault at linear address %p, rip %p, code %lx\n",
   17.11 +           addr, regs->rip, error_code);
   17.12 +#else
   17.13 +    printk("Page fault at linear address %p, eip %p, code %lx\n",
   17.14 +           addr, regs->eip, error_code);
   17.15 +#endif
   17.16      dump_regs(regs);
   17.17      page_walk(addr);
   17.18      do_exit();
   17.19 @@ -195,7 +200,6 @@ static trap_info_t trap_table[] = {
   17.20      { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug      },
   17.21      { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error           },
   17.22      { 17, 0, __KERNEL_CS, (unsigned long)alignment_check             },
   17.23 -    { 18, 0, __KERNEL_CS, (unsigned long)machine_check               },
   17.24      { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error      },
   17.25      {  0, 0,           0, 0                           }
   17.26  };
    18.1 --- a/extras/mini-os/x86_32.S	Mon May 08 13:41:18 2006 -0600
    18.2 +++ b/extras/mini-os/x86_32.S	Mon May 08 14:46:11 2006 -0600
    18.3 @@ -30,10 +30,10 @@ shared_info:
    18.4  hypercall_page:
    18.5          .org 0x3000
    18.6  
    18.7 -ES		= 0x1c
    18.8 -ORIG_EAX	= 0x20
    18.9 -EIP		= 0x24
   18.10 -CS		= 0x28
   18.11 +ES		= 0x20
   18.12 +ORIG_EAX	= 0x24
   18.13 +EIP		= 0x28
   18.14 +CS		= 0x2C
   18.15  
   18.16  #define ENTRY(X) .globl X ; X :
   18.17  
   18.18 @@ -69,7 +69,7 @@ ENTRY(divide_error)
   18.19  	pushl $0		# no error code
   18.20  	pushl $do_divide_error
   18.21  do_exception:
   18.22 -	pushl %ds
   18.23 +    pushl %ds
   18.24  	pushl %eax
   18.25  	xorl %eax, %eax
   18.26  	pushl %ebp
   18.27 @@ -92,7 +92,7 @@ do_exception:
   18.28      pushl %edx
   18.29      pushl %eax
   18.30  	call *%edi
   18.31 -    addl $8,%esp
   18.32 +    jmp ret_from_exception
   18.33      
   18.34  ret_from_exception:
   18.35          movb CS(%esp),%cl
   18.36 @@ -223,66 +223,59 @@ ENTRY(invalid_op)
   18.37  	pushl $do_invalid_op
   18.38  	jmp do_exception
   18.39  
   18.40 +
   18.41  ENTRY(coprocessor_segment_overrun)
   18.42  	pushl $0
   18.43  	pushl $do_coprocessor_segment_overrun
   18.44  	jmp do_exception
   18.45  
   18.46 +
   18.47  ENTRY(invalid_TSS)
   18.48  	pushl $do_invalid_TSS
   18.49  	jmp do_exception
   18.50  
   18.51 +
   18.52  ENTRY(segment_not_present)
   18.53  	pushl $do_segment_not_present
   18.54  	jmp do_exception
   18.55  
   18.56 +
   18.57  ENTRY(stack_segment)
   18.58  	pushl $do_stack_segment
   18.59  	jmp do_exception
   18.60  
   18.61 +
   18.62  ENTRY(general_protection)
   18.63  	pushl $do_general_protection
   18.64  	jmp do_exception
   18.65  
   18.66 +
   18.67  ENTRY(alignment_check)
   18.68  	pushl $do_alignment_check
   18.69  	jmp do_exception
   18.70  
   18.71 -# This handler is special, because it gets an extra value on its stack,
   18.72 -# which is the linear faulting address.
   18.73 -# fastcall register usage:  %eax = pt_regs, %edx = error code,
   18.74 -#			    %ecx = fault address
   18.75 +
   18.76  ENTRY(page_fault)
   18.77 -	pushl %ds
   18.78 -	pushl %eax
   18.79 -	xorl %eax, %eax
   18.80 -	pushl %ebp
   18.81 -	pushl %edi
   18.82 -	pushl %esi
   18.83 -	pushl %edx
   18.84 -	decl %eax			/* eax = -1 */
   18.85 -	pushl %ecx
   18.86 -	pushl %ebx
   18.87 -	cld
   18.88 -	movl ORIG_EAX(%esp), %edi
   18.89 -	movl %eax, ORIG_EAX(%esp)
   18.90 -	movl %es, %ecx
   18.91 -	movl %ecx, ES(%esp)
   18.92 -	movl $(__KERNEL_DS),%eax
   18.93 -	movl %eax, %ds
   18.94 -	movl %eax, %es
   18.95 -	pushl %edi
   18.96 -	movl %esp, %eax
   18.97 -	pushl %eax
   18.98 -	call do_page_fault
   18.99 -	jmp ret_from_exception
  18.100 -
  18.101 +    pushl $do_page_fault
  18.102 +    jmp do_exception
  18.103 +    
  18.104  ENTRY(machine_check)
  18.105  	pushl $0
  18.106  	pushl $do_machine_check
  18.107  	jmp do_exception
  18.108  
  18.109 +
  18.110  ENTRY(spurious_interrupt_bug)
  18.111  	pushl $0
  18.112  	pushl $do_spurious_interrupt_bug
  18.113  	jmp do_exception
  18.114 +
  18.115 +
  18.116 +
  18.117 +ENTRY(thread_starter)
  18.118 +    popl %eax
  18.119 +    popl %ebx
  18.120 +    pushl %eax
  18.121 +    call *%ebx
  18.122 +    call exit_thread 
  18.123 +    
    19.1 --- a/extras/mini-os/x86_64.S	Mon May 08 13:41:18 2006 -0600
    19.2 +++ b/extras/mini-os/x86_64.S	Mon May 08 14:46:11 2006 -0600
    19.3 @@ -1,4 +1,5 @@
    19.4  #include <os.h>
    19.5 +#include <xen/features.h>
    19.6  
    19.7  .section __xen_guest
    19.8  	.ascii	"GUEST_OS=Mini-OS"
    19.9 @@ -12,40 +13,6 @@
   19.10  #define ENTRY(X) .globl X ; X :
   19.11  .globl _start, shared_info, hypercall_page
   19.12  
   19.13 -#define SAVE_ALL \
   19.14 -        cld; \
   19.15 -        pushq %rdi; \
   19.16 -        pushq %rsi; \
   19.17 -        pushq %rdx; \
   19.18 -        pushq %rcx; \
   19.19 -        pushq %rax; \
   19.20 -        pushq %r8; \
   19.21 -        pushq %r9; \
   19.22 -        pushq %r10; \
   19.23 -        pushq %r11; \
   19.24 -        pushq %rbx; \
   19.25 -        pushq %rbp; \
   19.26 -        pushq %r12; \
   19.27 -        pushq %r13; \
   19.28 -        pushq %r14; \
   19.29 -        pushq %r15;
   19.30 -
   19.31 -#define RESTORE_ALL \
   19.32 -        popq  %r15; \
   19.33 -        popq  %r14; \
   19.34 -        popq  %r13; \
   19.35 -        popq  %r12; \
   19.36 -        popq  %rbp; \
   19.37 -        popq  %rbx; \
   19.38 -        popq  %r11; \
   19.39 -        popq  %r10; \
   19.40 -        popq  %r9; \
   19.41 -        popq  %r8; \
   19.42 -        popq  %rax; \
   19.43 -        popq  %rcx; \
   19.44 -        popq  %rdx; \
   19.45 -        popq  %rsi; \
   19.46 -        popq  %rdi
   19.47  
   19.48  _start:
   19.49          cld
   19.50 @@ -65,166 +32,353 @@ shared_info:
   19.51  hypercall_page:
   19.52          .org 0x3000
   19.53  
   19.54 +
   19.55 +/* Offsets into shared_info_t. */                
   19.56 +#define evtchn_upcall_pending		/* 0 */
   19.57 +#define evtchn_upcall_mask		1
   19.58 +
   19.59 +NMI_MASK = 0x80000000
   19.60 +
   19.61 +#define RDI 112
   19.62 +#define ORIG_RAX 120       /* + error_code */ 
   19.63 +#define EFLAGS 144
   19.64 +
   19.65 +#define REST_SKIP 6*8			
   19.66 +.macro SAVE_REST
   19.67 +	subq $REST_SKIP,%rsp
   19.68 +#	CFI_ADJUST_CFA_OFFSET	REST_SKIP
   19.69 +	movq %rbx,5*8(%rsp) 
   19.70 +#	CFI_REL_OFFSET	rbx,5*8
   19.71 +	movq %rbp,4*8(%rsp) 
   19.72 +#	CFI_REL_OFFSET	rbp,4*8
   19.73 +	movq %r12,3*8(%rsp) 
   19.74 +#	CFI_REL_OFFSET	r12,3*8
   19.75 +	movq %r13,2*8(%rsp) 
   19.76 +#	CFI_REL_OFFSET	r13,2*8
   19.77 +	movq %r14,1*8(%rsp) 
   19.78 +#	CFI_REL_OFFSET	r14,1*8
   19.79 +	movq %r15,(%rsp) 
   19.80 +#	CFI_REL_OFFSET	r15,0*8
   19.81 +.endm		
   19.82 +
   19.83 +
   19.84 +.macro RESTORE_REST
   19.85 +	movq (%rsp),%r15
   19.86 +#	CFI_RESTORE r15
   19.87 +	movq 1*8(%rsp),%r14
   19.88 +#	CFI_RESTORE r14
   19.89 +	movq 2*8(%rsp),%r13
   19.90 +#	CFI_RESTORE r13
   19.91 +	movq 3*8(%rsp),%r12
   19.92 +#	CFI_RESTORE r12
   19.93 +	movq 4*8(%rsp),%rbp
   19.94 +#	CFI_RESTORE rbp
   19.95 +	movq 5*8(%rsp),%rbx
   19.96 +#	CFI_RESTORE rbx
   19.97 +	addq $REST_SKIP,%rsp
   19.98 +#	CFI_ADJUST_CFA_OFFSET	-(REST_SKIP)
   19.99 +.endm
  19.100 +
  19.101 +
  19.102 +#define ARG_SKIP 9*8
  19.103 +.macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0
  19.104 +	.if \skipr11
  19.105 +	.else
  19.106 +	movq (%rsp),%r11
  19.107 +#	CFI_RESTORE r11
  19.108 +	.endif
  19.109 +	.if \skipr8910
  19.110 +	.else
  19.111 +	movq 1*8(%rsp),%r10
  19.112 +#	CFI_RESTORE r10
  19.113 +	movq 2*8(%rsp),%r9
  19.114 +#	CFI_RESTORE r9
  19.115 +	movq 3*8(%rsp),%r8
  19.116 +#	CFI_RESTORE r8
  19.117 +	.endif
  19.118 +	.if \skiprax
  19.119 +	.else
  19.120 +	movq 4*8(%rsp),%rax
  19.121 +#	CFI_RESTORE rax
  19.122 +	.endif
  19.123 +	.if \skiprcx
  19.124 +	.else
  19.125 +	movq 5*8(%rsp),%rcx
  19.126 +#	CFI_RESTORE rcx
  19.127 +	.endif
  19.128 +	.if \skiprdx
  19.129 +	.else
  19.130 +	movq 6*8(%rsp),%rdx
  19.131 +#	CFI_RESTORE rdx
  19.132 +	.endif
  19.133 +	movq 7*8(%rsp),%rsi
  19.134 +#	CFI_RESTORE rsi
  19.135 +	movq 8*8(%rsp),%rdi
  19.136 +#	CFI_RESTORE rdi
  19.137 +	.if ARG_SKIP+\addskip > 0
  19.138 +	addq $ARG_SKIP+\addskip,%rsp
  19.139 +#	CFI_ADJUST_CFA_OFFSET	-(ARG_SKIP+\addskip)
  19.140 +	.endif
  19.141 +.endm	
  19.142 +
  19.143 +
  19.144 +.macro HYPERVISOR_IRET flag
  19.145 +#    testb $3,1*8(%rsp)    /* Don't need to do that in Mini-os, as */
  19.146 +#	jnz   2f               /* there is no userspace? */
  19.147 +	testl $NMI_MASK,2*8(%rsp)
  19.148 +	jnz   2f
  19.149 +
  19.150 +	testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
  19.151 +	jnz   1f
  19.152 +
  19.153 +	/* Direct iret to kernel space. Correct CS and SS. */
  19.154 +	orb   $3,1*8(%rsp)
  19.155 +	orb   $3,4*8(%rsp)
  19.156 +1:	iretq
  19.157 +
  19.158 +2:	/* Slow iret via hypervisor. */
  19.159 +	andl  $~NMI_MASK, 16(%rsp)
  19.160 +	pushq $\flag
  19.161 +	jmp  hypercall_page + (__HYPERVISOR_iret * 32)
  19.162 +.endm
  19.163 +
  19.164 +/*
  19.165 + * Exception entry point. This expects an error code/orig_rax on the stack
  19.166 + * and the exception handler in %rax.	
  19.167 + */ 		  				
  19.168 +ENTRY(error_entry)
  19.169 +#	_frame RDI
  19.170 +	/* rdi slot contains rax, oldrax contains error code */
  19.171 +	cld	
  19.172 +	subq  $14*8,%rsp
  19.173 +#	CFI_ADJUST_CFA_OFFSET	(14*8)
  19.174 +	movq %rsi,13*8(%rsp)
  19.175 +#	CFI_REL_OFFSET	rsi,RSI
  19.176 +	movq 14*8(%rsp),%rsi	/* load rax from rdi slot */
  19.177 +	movq %rdx,12*8(%rsp)
  19.178 +#	CFI_REL_OFFSET	rdx,RDX
  19.179 +	movq %rcx,11*8(%rsp)
  19.180 +#	CFI_REL_OFFSET	rcx,RCX
  19.181 +	movq %rsi,10*8(%rsp)	/* store rax */ 
  19.182 +#	CFI_REL_OFFSET	rax,RAX
  19.183 +	movq %r8, 9*8(%rsp)
  19.184 +#	CFI_REL_OFFSET	r8,R8
  19.185 +	movq %r9, 8*8(%rsp)
  19.186 +#	CFI_REL_OFFSET	r9,R9
  19.187 +	movq %r10,7*8(%rsp)
  19.188 +#	CFI_REL_OFFSET	r10,R10
  19.189 +	movq %r11,6*8(%rsp)
  19.190 +#	CFI_REL_OFFSET	r11,R11
  19.191 +	movq %rbx,5*8(%rsp) 
  19.192 +#	CFI_REL_OFFSET	rbx,RBX
  19.193 +	movq %rbp,4*8(%rsp) 
  19.194 +#	CFI_REL_OFFSET	rbp,RBP
  19.195 +	movq %r12,3*8(%rsp) 
  19.196 +#	CFI_REL_OFFSET	r12,R12
  19.197 +	movq %r13,2*8(%rsp) 
  19.198 +#	CFI_REL_OFFSET	r13,R13
  19.199 +	movq %r14,1*8(%rsp) 
  19.200 +#	CFI_REL_OFFSET	r14,R14
  19.201 +	movq %r15,(%rsp) 
  19.202 +#	CFI_REL_OFFSET	r15,R15
  19.203 +#if 0        
  19.204 +	cmpl $__KERNEL_CS,CS(%rsp)
  19.205 +	je  error_kernelspace
  19.206 +#endif        
  19.207 +error_call_handler:
  19.208 +	movq %rdi, RDI(%rsp)            
  19.209 +	movq %rsp,%rdi
  19.210 +	movq ORIG_RAX(%rsp),%rsi	# get error code 
  19.211 +	movq $-1,ORIG_RAX(%rsp)
  19.212 +	call *%rax
  19.213 +
  19.214 +.macro zeroentry sym
  19.215 +#	INTR_FRAME
  19.216 +    movq (%rsp),%rcx
  19.217 +    movq 8(%rsp),%r11
  19.218 +    addq $0x10,%rsp /* skip rcx and r11 */
  19.219 +	pushq $0	/* push error code/oldrax */ 
  19.220 +#	CFI_ADJUST_CFA_OFFSET 8
  19.221 +	pushq %rax	/* push real oldrax to the rdi slot */ 
  19.222 +#	CFI_ADJUST_CFA_OFFSET 8
  19.223 +	leaq  \sym(%rip),%rax
  19.224 +	jmp error_entry
  19.225 +#	CFI_ENDPROC
  19.226 +.endm	
  19.227 +
  19.228 +.macro errorentry sym
  19.229 +#	XCPT_FRAME
  19.230 +        movq (%rsp),%rcx
  19.231 +        movq 8(%rsp),%r11
  19.232 +        addq $0x10,%rsp /* rsp points to the error code */
  19.233 +	pushq %rax
  19.234 +#	CFI_ADJUST_CFA_OFFSET 8
  19.235 +	leaq  \sym(%rip),%rax
  19.236 +	jmp error_entry
  19.237 +#	CFI_ENDPROC
  19.238 +.endm
  19.239 +
  19.240 +#define XEN_GET_VCPU_INFO(reg)	movq HYPERVISOR_shared_info,reg
  19.241 +#define XEN_PUT_VCPU_INFO(reg)
  19.242 +#define XEN_PUT_VCPU_INFO_fixup
  19.243 +#define XEN_LOCKED_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
  19.244 +#define XEN_LOCKED_UNBLOCK_EVENTS(reg)	movb $0,evtchn_upcall_mask(reg)
  19.245 +#define XEN_TEST_PENDING(reg)	testb $0xFF,evtchn_upcall_pending(reg)
  19.246 +
  19.247 +#define XEN_BLOCK_EVENTS(reg)	XEN_GET_VCPU_INFO(reg)			; \
  19.248 +                    			XEN_LOCKED_BLOCK_EVENTS(reg)	; \
  19.249 +    				            XEN_PUT_VCPU_INFO(reg)
  19.250 +
  19.251 +#define XEN_UNBLOCK_EVENTS(reg)	XEN_GET_VCPU_INFO(reg)			; \
  19.252 +                				XEN_LOCKED_UNBLOCK_EVENTS(reg)	; \
  19.253 +    			            	XEN_PUT_VCPU_INFO(reg)
  19.254 +
  19.255 +
  19.256 +
  19.257  ENTRY(hypervisor_callback)
  19.258 -        popq  %rcx
  19.259 -        popq  %r11
  19.260 -        iretq
  19.261 +    zeroentry hypervisor_callback2
  19.262 +
  19.263 +ENTRY(hypervisor_callback2)
  19.264 +        movq %rdi, %rsp 
  19.265 +11:     movq %gs:8,%rax
  19.266 +        incl %gs:0
  19.267 +        cmovzq %rax,%rsp
  19.268 +        pushq %rdi
  19.269 +        call do_hypervisor_callback 
  19.270 +        popq %rsp
  19.271 +        decl %gs:0
  19.272 +        jmp error_exit
  19.273 +
  19.274 +#        ALIGN
  19.275 +restore_all_enable_events:  
  19.276 +	XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
  19.277 +
  19.278 +scrit:	/**** START OF CRITICAL REGION ****/
  19.279 +	XEN_TEST_PENDING(%rsi)
  19.280 +	jnz  14f			# process more events if necessary...
  19.281 +	XEN_PUT_VCPU_INFO(%rsi)
  19.282 +        RESTORE_ARGS 0,8,0
  19.283 +        HYPERVISOR_IRET 0
  19.284 +        
  19.285 +14:	XEN_LOCKED_BLOCK_EVENTS(%rsi)
  19.286 +	XEN_PUT_VCPU_INFO(%rsi)
  19.287 +	SAVE_REST
  19.288 +        movq %rsp,%rdi                  # set the argument again
  19.289 +	jmp  11b
  19.290 +ecrit:  /**** END OF CRITICAL REGION ****/
  19.291 +
  19.292 +
  19.293 +retint_kernel:
  19.294 +retint_restore_args:
  19.295 +	movl EFLAGS-REST_SKIP(%rsp), %eax
  19.296 +	shr $9, %eax			# EAX[0] == IRET_EFLAGS.IF
  19.297 +	XEN_GET_VCPU_INFO(%rsi)
  19.298 +	andb evtchn_upcall_mask(%rsi),%al
  19.299 +	andb $1,%al			# EAX[0] == IRET_EFLAGS.IF & event_mask
  19.300 +	jnz restore_all_enable_events	#        != 0 => enable event delivery
  19.301 +	XEN_PUT_VCPU_INFO(%rsi)
  19.302 +		
  19.303 +	RESTORE_ARGS 0,8,0
  19.304 +	HYPERVISOR_IRET 0
  19.305 +
  19.306 +
  19.307 +error_exit:		
  19.308 +	RESTORE_REST
  19.309 +/*	cli */
  19.310 +	XEN_BLOCK_EVENTS(%rsi)		
  19.311 +	jmp retint_kernel
  19.312 +
  19.313 +
  19.314  
  19.315  ENTRY(failsafe_callback)
  19.316          popq  %rcx
  19.317          popq  %r11
  19.318          iretq
  19.319  
  19.320 -error_code:
  19.321 -        SAVE_ALL
  19.322 -        movq  %rsp,%rdi
  19.323 -        movl  15*8+4(%rsp),%eax
  19.324 -        leaq  exception_table(%rip),%rdx
  19.325 -        callq *(%rdx,%rax,8)
  19.326 -        RESTORE_ALL
  19.327 -        addq  $8,%rsp
  19.328 -        iretq
  19.329 -                        
  19.330 -ENTRY(divide_error)
  19.331 -        popq  %rcx
  19.332 -        popq  %r11
  19.333 -	pushq $0
  19.334 -        movl  $TRAP_divide_error,4(%rsp)
  19.335 -        jmp   error_code
  19.336 -        
  19.337 +
  19.338  ENTRY(coprocessor_error)
  19.339 -        popq  %rcx
  19.340 -        popq  %r11
  19.341 -	pushq $0
  19.342 -        movl  $TRAP_copro_error,4(%rsp)
  19.343 -        jmp   error_code
  19.344 +        zeroentry do_coprocessor_error
  19.345 +
  19.346  
  19.347  ENTRY(simd_coprocessor_error)
  19.348 -        popq  %rcx
  19.349 -        popq  %r11
  19.350 -	pushq $0
  19.351 -        movl  $TRAP_simd_error,4(%rsp)
  19.352 -        jmp   error_code
  19.353 +        zeroentry do_simd_coprocessor_error
  19.354 +
  19.355  
  19.356  ENTRY(device_not_available)
  19.357 -        popq  %rcx
  19.358 -        popq  %r11
  19.359 -        movl  $TRAP_no_device,4(%rsp)
  19.360 -        jmp   error_code
  19.361 +        zeroentry do_device_not_available
  19.362 +
  19.363  
  19.364  ENTRY(debug)
  19.365 -        popq  %rcx
  19.366 -        popq  %r11
  19.367 -	pushq $0
  19.368 -        movl  $TRAP_debug,4(%rsp)
  19.369 -        jmp   error_code
  19.370 +#       INTR_FRAME
  19.371 +#       CFI_ADJUST_CFA_OFFSET 8 */
  19.372 +        zeroentry do_debug
  19.373 +#       CFI_ENDPROC
  19.374 +
  19.375  
  19.376  ENTRY(int3)
  19.377 -        popq  %rcx
  19.378 -        popq  %r11
  19.379 -	pushq $0
  19.380 -        movl  $TRAP_int3,4(%rsp)
  19.381 -        jmp   error_code
  19.382 +#       INTR_FRAME
  19.383 +#       CFI_ADJUST_CFA_OFFSET 8 */
  19.384 +        zeroentry do_int3
  19.385 +#       CFI_ENDPROC
  19.386  
  19.387  ENTRY(overflow)
  19.388 -        popq  %rcx
  19.389 -        popq  %r11
  19.390 -	pushq $0
  19.391 -        movl  $TRAP_overflow,4(%rsp)
  19.392 -        jmp   error_code
  19.393 +        zeroentry do_overflow
  19.394 +
  19.395  
  19.396  ENTRY(bounds)
  19.397 -        popq  %rcx
  19.398 -        popq  %r11
  19.399 -	pushq $0
  19.400 -        movl  $TRAP_bounds,4(%rsp)
  19.401 -        jmp   error_code
  19.402 +        zeroentry do_bounds
  19.403 +    
  19.404 +    
  19.405 +ENTRY(invalid_op)
  19.406 +        zeroentry do_invalid_op
  19.407  
  19.408 -ENTRY(invalid_op)
  19.409 -        popq  %rcx
  19.410 -        popq  %r11
  19.411 -	pushq $0
  19.412 -        movl  $TRAP_invalid_op,4(%rsp)
  19.413 -        jmp   error_code
  19.414  
  19.415  ENTRY(coprocessor_segment_overrun)
  19.416 -        popq  %rcx
  19.417 -        popq  %r11
  19.418 -	pushq $0
  19.419 -        movl  $TRAP_copro_seg,4(%rsp)
  19.420 -        jmp   error_code
  19.421 +        zeroentry do_coprocessor_segment_overrun
  19.422 +
  19.423  
  19.424  ENTRY(invalid_TSS)
  19.425 -        popq  %rcx
  19.426 -        popq  %r11
  19.427 -        movl  $TRAP_invalid_tss,4(%rsp)
  19.428 -        jmp   error_code
  19.429 +        errorentry do_invalid_TSS
  19.430 +
  19.431  
  19.432  ENTRY(segment_not_present)
  19.433 -        popq  %rcx
  19.434 -        popq  %r11
  19.435 -        movl  $TRAP_no_segment,4(%rsp)
  19.436 -        jmp   error_code
  19.437 +        errorentry do_segment_not_present
  19.438  
  19.439 +
  19.440 +/* runs on exception stack */
  19.441  ENTRY(stack_segment)
  19.442 -        popq  %rcx
  19.443 -        popq  %r11
  19.444 -        movl  $TRAP_stack_error,4(%rsp)
  19.445 -        jmp   error_code
  19.446 +#       XCPT_FRAME
  19.447 +        errorentry do_stack_segment
  19.448 +#       CFI_ENDPROC
  19.449 +                    
  19.450  
  19.451  ENTRY(general_protection)
  19.452 -        popq  %rcx
  19.453 -        popq  %r11
  19.454 -        movl  $TRAP_gp_fault,4(%rsp)
  19.455 -        jmp   error_code
  19.456 +        errorentry do_general_protection
  19.457 +
  19.458  
  19.459  ENTRY(alignment_check)
  19.460 -        popq  %rcx
  19.461 -        popq  %r11
  19.462 -        movl  $TRAP_alignment_check,4(%rsp)
  19.463 -        jmp   error_code
  19.464 +        errorentry do_alignment_check
  19.465  
  19.466 -ENTRY(virt_cr2)
  19.467 -        .quad 0
  19.468 -ENTRY(page_fault)
  19.469 -        popq  %rcx
  19.470 -        popq  %r11
  19.471 -        popq  virt_cr2(%rip)
  19.472 -        movl  $TRAP_page_fault,4(%rsp)
  19.473 -        jmp   error_code
  19.474 -        
  19.475 -ENTRY(machine_check)
  19.476 -        popq  %rcx
  19.477 -        popq  %r11
  19.478 -	pushq $0
  19.479 -        movl  $TRAP_machine_check,4(%rsp)
  19.480 -        jmp   error_code
  19.481 +
  19.482 +ENTRY(divide_error)
  19.483 +        zeroentry do_divide_error
  19.484 +
  19.485  
  19.486  ENTRY(spurious_interrupt_bug)
  19.487 -        popq  %rcx
  19.488 -        popq  %r11
  19.489 -	pushq $0
  19.490 -        movl  $TRAP_spurious_int,4(%rsp)
  19.491 -        jmp   error_code
  19.492 +        zeroentry do_spurious_interrupt_bug
  19.493 +            
  19.494  
  19.495 -ENTRY(exception_table)
  19.496 -        .quad do_divide_error
  19.497 -        .quad do_debug
  19.498 -        .quad 0 # nmi
  19.499 -        .quad do_int3
  19.500 -        .quad do_overflow
  19.501 -        .quad do_bounds
  19.502 -        .quad do_invalid_op
  19.503 -        .quad 0
  19.504 -        .quad 0
  19.505 -        .quad do_coprocessor_segment_overrun
  19.506 -        .quad do_invalid_TSS
  19.507 -        .quad do_segment_not_present
  19.508 -        .quad do_stack_segment
  19.509 -        .quad do_general_protection
  19.510 -        .quad do_page_fault
  19.511 -        .quad do_spurious_interrupt_bug
  19.512 -        .quad do_coprocessor_error
  19.513 -        .quad do_alignment_check
  19.514 -        .quad do_machine_check
  19.515 -        .quad do_simd_coprocessor_error
  19.516 +ENTRY(page_fault)
  19.517 +        errorentry do_page_fault
  19.518 +
  19.519 +
  19.520 +
  19.521 +
  19.522 +
  19.523 +ENTRY(thread_starter)
  19.524 +        popq %rdi
  19.525 +        popq %rbx
  19.526 +        call *%rbx
  19.527 +        call exit_thread 
  19.528 +        
  19.529 +
    20.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c	Mon May 08 13:41:18 2006 -0600
    20.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c	Mon May 08 14:46:11 2006 -0600
    20.3 @@ -57,27 +57,25 @@ unsigned long io_apic_irqs;
    20.4  
    20.5  static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
    20.6  {
    20.7 -	physdev_op_t op;
    20.8 +	struct physdev_apic apic_op;
    20.9  	int ret;
   20.10  
   20.11 -	op.cmd = PHYSDEVOP_APIC_READ;
   20.12 -	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   20.13 -	op.u.apic_op.reg = reg;
   20.14 -	ret = HYPERVISOR_physdev_op(&op);
   20.15 +	apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   20.16 +	apic_op.reg = reg;
   20.17 +	ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
   20.18  	if (ret)
   20.19  		return ret;
   20.20 -	return op.u.apic_op.value;
   20.21 +	return apic_op.value;
   20.22  }
   20.23  
   20.24  static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
   20.25  {
   20.26 -	physdev_op_t op;
   20.27 -
   20.28 -	op.cmd = PHYSDEVOP_APIC_WRITE;
   20.29 -	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   20.30 -	op.u.apic_op.reg = reg;
   20.31 -	op.u.apic_op.value = value;
   20.32 -	HYPERVISOR_physdev_op(&op);
   20.33 +	struct physdev_apic apic_op;
   20.34 +
   20.35 +	apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   20.36 +	apic_op.reg = reg;
   20.37 +	apic_op.value = value;
   20.38 +	HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
   20.39  }
   20.40  
   20.41  #define io_apic_read(a,r)    xen_io_apic_read(a,r)
   20.42 @@ -1205,22 +1203,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos
   20.43  
   20.44  int assign_irq_vector(int irq)
   20.45  {
   20.46 -	physdev_op_t op;
   20.47 +	struct physdev_irq irq_op;
   20.48  
   20.49  	BUG_ON(irq >= NR_IRQ_VECTORS);
   20.50  	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
   20.51  		return IO_APIC_VECTOR(irq);
   20.52  
   20.53 -	op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
   20.54 -	op.u.irq_op.irq = irq;
   20.55 -	if (HYPERVISOR_physdev_op(&op))
   20.56 +	irq_op.irq = irq;
   20.57 +	if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
   20.58  		return -ENOSPC;
   20.59  
   20.60 -	vector_irq[op.u.irq_op.vector] = irq;
   20.61 +	vector_irq[irq_op.vector] = irq;
   20.62  	if (irq != AUTO_ASSIGN)
   20.63 -		IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
   20.64 -
   20.65 -	return op.u.irq_op.vector;
   20.66 +		IO_APIC_VECTOR(irq) = irq_op.vector;
   20.67 +
   20.68 +	return irq_op.vector;
   20.69  }
   20.70  
   20.71  #ifndef CONFIG_XEN
    21.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c	Mon May 08 13:41:18 2006 -0600
    21.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c	Mon May 08 14:46:11 2006 -0600
    21.3 @@ -60,7 +60,7 @@ asmlinkage long sys_ioperm(unsigned long
    21.4  {
    21.5  	struct thread_struct * t = &current->thread;
    21.6  	unsigned long *bitmap;
    21.7 -	physdev_op_t op;
    21.8 +	struct physdev_set_iobitmap set_iobitmap;
    21.9  
   21.10  	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
   21.11  		return -EINVAL;
   21.12 @@ -80,10 +80,9 @@ asmlinkage long sys_ioperm(unsigned long
   21.13  		memset(bitmap, 0xff, IO_BITMAP_BYTES);
   21.14  		t->io_bitmap_ptr = bitmap;
   21.15  
   21.16 -		op.cmd = PHYSDEVOP_SET_IOBITMAP;
   21.17 -		op.u.set_iobitmap.bitmap   = (char *)bitmap;
   21.18 -		op.u.set_iobitmap.nr_ports = IO_BITMAP_BITS;
   21.19 -		HYPERVISOR_physdev_op(&op);
   21.20 +		set_iobitmap.bitmap   = (char *)bitmap;
   21.21 +		set_iobitmap.nr_ports = IO_BITMAP_BITS;
   21.22 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
   21.23  	}
   21.24  
   21.25  	set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
    22.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Mon May 08 13:41:18 2006 -0600
    22.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Mon May 08 14:46:11 2006 -0600
    22.3 @@ -70,7 +70,7 @@ static int do_microcode_update (void)
    22.4  		return err;
    22.5  
    22.6  	op.cmd = DOM0_MICROCODE;
    22.7 -	op.u.microcode.data = user_buffer;
    22.8 +	set_xen_guest_handle(op.u.microcode.data, user_buffer);
    22.9  	op.u.microcode.length = user_buffer_size;
   22.10  	err = HYPERVISOR_dom0_op(&op);
   22.11  
    23.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c	Mon May 08 13:41:18 2006 -0600
    23.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c	Mon May 08 14:46:11 2006 -0600
    23.3 @@ -297,9 +297,8 @@ void exit_thread(void)
    23.4  
    23.5  	/* The process may have allocated an io port bitmap... nuke it. */
    23.6  	if (unlikely(NULL != t->io_bitmap_ptr)) {
    23.7 -		physdev_op_t op = { 0 };
    23.8 -		op.cmd = PHYSDEVOP_SET_IOBITMAP;
    23.9 -		HYPERVISOR_physdev_op(&op);
   23.10 +		struct physdev_set_iobitmap set_iobitmap = { 0 };
   23.11 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
   23.12  		kfree(t->io_bitmap_ptr);
   23.13  		t->io_bitmap_ptr = NULL;
   23.14  	}
   23.15 @@ -521,7 +520,8 @@ struct task_struct fastcall * __switch_t
   23.16  #ifndef CONFIG_X86_NO_TSS
   23.17  	struct tss_struct *tss = &per_cpu(init_tss, cpu);
   23.18  #endif
   23.19 -	physdev_op_t iopl_op, iobmp_op;
   23.20 +	struct physdev_set_iopl iopl_op;
   23.21 +	struct physdev_set_iobitmap iobmp_op;
   23.22  	multicall_entry_t _mcl[8], *mcl = _mcl;
   23.23  
   23.24  	/* XEN NOTE: FS/GS saved in switch_mm(), not here. */
   23.25 @@ -568,23 +568,19 @@ struct task_struct fastcall * __switch_t
   23.26  #undef C
   23.27  
   23.28  	if (unlikely(prev->iopl != next->iopl)) {
   23.29 -		iopl_op.cmd             = PHYSDEVOP_SET_IOPL;
   23.30 -		iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 :
   23.31 -			(next->iopl >> 12) & 3;
   23.32 +		iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
   23.33  		mcl->op      = __HYPERVISOR_physdev_op;
   23.34 -		mcl->args[0] = (unsigned long)&iopl_op;
   23.35 +		mcl->args[0] = PHYSDEVOP_set_iopl;
   23.36 +		mcl->args[1] = (unsigned long)&iopl_op;
   23.37  		mcl++;
   23.38  	}
   23.39  
   23.40  	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
   23.41 -		iobmp_op.cmd                     =
   23.42 -			PHYSDEVOP_SET_IOBITMAP;
   23.43 -		iobmp_op.u.set_iobitmap.bitmap   =
   23.44 -			(char *)next->io_bitmap_ptr;
   23.45 -		iobmp_op.u.set_iobitmap.nr_ports =
   23.46 -			next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   23.47 +		iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
   23.48 +		iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   23.49  		mcl->op      = __HYPERVISOR_physdev_op;
   23.50 -		mcl->args[0] = (unsigned long)&iobmp_op;
   23.51 +		mcl->args[0] = PHYSDEVOP_set_iobitmap;
   23.52 +		mcl->args[1] = (unsigned long)&iobmp_op;
   23.53  		mcl++;
   23.54  	}
   23.55  
    24.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon May 08 13:41:18 2006 -0600
    24.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon May 08 14:46:11 2006 -0600
    24.3 @@ -1368,7 +1368,7 @@ legacy_init_iomem_resources(struct resou
    24.4  #ifdef CONFIG_XEN
    24.5  	map = alloc_bootmem_low_pages(PAGE_SIZE);
    24.6  	op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
    24.7 -	op.u.physical_memory_map.memory_map = map;
    24.8 +	set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
    24.9  	op.u.physical_memory_map.max_map_entries =
   24.10  		PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
   24.11  	BUG_ON(HYPERVISOR_dom0_op(&op));
   24.12 @@ -1630,7 +1630,7 @@ static void set_mca_bus(int x) { }
   24.13  void __init setup_arch(char **cmdline_p)
   24.14  {
   24.15  	int i, j, k, fpp;
   24.16 -	physdev_op_t op;
   24.17 +	struct physdev_set_iopl set_iopl;
   24.18  	unsigned long max_low_pfn;
   24.19  
   24.20  	/* Force a quick death if the kernel panics (not domain 0). */
   24.21 @@ -1815,9 +1815,8 @@ void __init setup_arch(char **cmdline_p)
   24.22  	if (efi_enabled)
   24.23  		efi_map_memmap();
   24.24  
   24.25 -	op.cmd             = PHYSDEVOP_SET_IOPL;
   24.26 -	op.u.set_iopl.iopl = 1;
   24.27 -	HYPERVISOR_physdev_op(&op);
   24.28 +	set_iopl.iopl = 1;
   24.29 +	HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
   24.30  
   24.31  #ifdef CONFIG_X86_IO_APIC
   24.32  	check_acpi_pci();	/* Checks more than just ACPI actually */
    25.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c	Mon May 08 13:41:18 2006 -0600
    25.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c	Mon May 08 14:46:11 2006 -0600
    25.3 @@ -43,6 +43,7 @@
    25.4  #include <linux/smp_lock.h>
    25.5  #include <linux/highmem.h>
    25.6  #include <linux/ptrace.h>
    25.7 +#include <linux/audit.h>
    25.8  
    25.9  #include <asm/uaccess.h>
   25.10  #include <asm/io.h>
   25.11 @@ -258,6 +259,7 @@ static void do_sys_vm86(struct kernel_vm
   25.12  #ifndef CONFIG_X86_NO_TSS
   25.13  	struct tss_struct *tss;
   25.14  #endif
   25.15 +	long eax;
   25.16  /*
   25.17   * make sure the vm86() system call doesn't try to do anything silly
   25.18   */
   25.19 @@ -313,13 +315,19 @@ static void do_sys_vm86(struct kernel_vm
   25.20  	tsk->thread.screen_bitmap = info->screen_bitmap;
   25.21  	if (info->flags & VM86_SCREEN_BITMAP)
   25.22  		mark_screen_rdonly(tsk->mm);
   25.23 +	__asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t");
   25.24 +	__asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax));
   25.25 +
   25.26 +	/*call audit_syscall_exit since we do not exit via the normal paths */
   25.27 +	if (unlikely(current->audit_context))
   25.28 +		audit_syscall_exit(current, AUDITSC_RESULT(eax), eax);
   25.29 +
   25.30  	__asm__ __volatile__(
   25.31 -		"xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
   25.32  		"movl %0,%%esp\n\t"
   25.33  		"movl %1,%%ebp\n\t"
   25.34  		"jmp resume_userspace"
   25.35  		: /* no outputs */
   25.36 -		:"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax");
   25.37 +		:"r" (&info->regs), "r" (task_thread_info(tsk)));
   25.38  	/* we never return here */
   25.39  }
   25.40  
    26.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Mon May 08 13:41:18 2006 -0600
    26.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Mon May 08 14:46:11 2006 -0600
    26.3 @@ -271,11 +271,11 @@ int xen_create_contiguous_region(
    26.4  	pte_t         *pte;
    26.5  	unsigned long  frame, i, flags;
    26.6  	struct xen_memory_reservation reservation = {
    26.7 -		.extent_start = &frame,
    26.8  		.nr_extents   = 1,
    26.9  		.extent_order = 0,
   26.10  		.domid        = DOMID_SELF
   26.11  	};
   26.12 +	set_xen_guest_handle(reservation.extent_start, &frame);
   26.13  
   26.14  	/*
   26.15  	 * Currently an auto-translated guest will not perform I/O, nor will
   26.16 @@ -357,11 +357,11 @@ void xen_destroy_contiguous_region(unsig
   26.17  	pte_t         *pte;
   26.18  	unsigned long  frame, i, flags;
   26.19  	struct xen_memory_reservation reservation = {
   26.20 -		.extent_start = &frame,
   26.21  		.nr_extents   = 1,
   26.22  		.extent_order = 0,
   26.23  		.domid        = DOMID_SELF
   26.24  	};
   26.25 +	set_xen_guest_handle(reservation.extent_start, &frame);
   26.26  
   26.27  	if (xen_feature(XENFEAT_auto_translated_physmap))
   26.28  		return;
    27.1 --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig	Mon May 08 13:41:18 2006 -0600
    27.2 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig	Mon May 08 14:46:11 2006 -0600
    27.3 @@ -90,12 +90,19 @@ config XEN_BLKDEV_BACKEND
    27.4  	default y
    27.5  
    27.6  config XEN_IA64_DOM0_VP
    27.7 +	bool "dom0 vp model"
    27.8  	depends on XEN
    27.9 -	bool
   27.10  	default n
   27.11  	help
   27.12  	  dom0 vp model
   27.13  
   27.14 +config XEN_IA64_DOM0_NON_VP
   27.15 +	bool
   27.16 +	depends on !(XEN && XEN_IA64_DOM0_VP)
   27.17 +	default y
   27.18 +	help
   27.19 +	  dom0 P=M model
   27.20 +
   27.21  config XEN_SYSFS
   27.22  	bool "Export Xen attributes in sysfs"
   27.23  	depends on XEN && SYSFS
   27.24 @@ -106,7 +113,7 @@ config XEN_SYSFS
   27.25  config XEN_INTERFACE_VERSION
   27.26  	hex
   27.27  	depends on XEN
   27.28 -	default 0x00030101
   27.29 +	default 0x00030202
   27.30  
   27.31  config SCHED_NO_NO_OMIT_FRAME_POINTER
   27.32  	bool
    28.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c	Mon May 08 13:41:18 2006 -0600
    28.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c	Mon May 08 14:46:11 2006 -0600
    28.3 @@ -146,29 +146,27 @@ static LIST_HEAD(free_rte_list);
    28.4  #include <asm/hypervisor.h>
    28.5  static inline unsigned int xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
    28.6  {
    28.7 -	physdev_op_t op;
    28.8 +	struct physdev_apic apic_op;
    28.9  	int ret;
   28.10  
   28.11 -	op.cmd = PHYSDEVOP_APIC_READ;
   28.12 -	op.u.apic_op.apic_physbase = (unsigned long)iosapic -
   28.13 +	apic_op.apic_physbase = (unsigned long)iosapic -
   28.14  					__IA64_UNCACHED_OFFSET;
   28.15 -	op.u.apic_op.reg = reg;
   28.16 -	ret = HYPERVISOR_physdev_op(&op);
   28.17 +	apic_op.reg = reg;
   28.18 +	ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
   28.19  	if (ret)
   28.20  		return ret;
   28.21 -	return op.u.apic_op.value;
   28.22 +	return apic_op.value;
   28.23  }
   28.24  
   28.25  static inline void xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
   28.26  {
   28.27 -	physdev_op_t op;
   28.28 +	struct physdev_apic apic_op;
   28.29  
   28.30 -	op.cmd = PHYSDEVOP_APIC_WRITE;
   28.31 -	op.u.apic_op.apic_physbase = (unsigned long)iosapic - 
   28.32 +	apic_op.apic_physbase = (unsigned long)iosapic - 
   28.33  					__IA64_UNCACHED_OFFSET;
   28.34 -	op.u.apic_op.reg = reg;
   28.35 -	op.u.apic_op.value = val;
   28.36 -	HYPERVISOR_physdev_op(&op);
   28.37 +	apic_op.reg = reg;
   28.38 +	apic_op.value = val;
   28.39 +	HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
   28.40  }
   28.41  
   28.42  static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
   28.43 @@ -191,14 +189,13 @@ static inline void iosapic_write(char __
   28.44  
   28.45  int xen_assign_irq_vector(int irq)
   28.46  {
   28.47 -	physdev_op_t op;
   28.48 +	struct physdev_irq irq_op;
   28.49  
   28.50 -	op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
   28.51 -	op.u.irq_op.irq = irq;
   28.52 -	if (HYPERVISOR_physdev_op(&op))
   28.53 +	irq_op.irq = irq;
   28.54 +	if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
   28.55  		return -ENOSPC;
   28.56  
   28.57 -	return op.u.irq_op.vector;
   28.58 +	return irq_op.vector;
   28.59  }
   28.60  #endif /* XEN */
   28.61  
    29.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre	Mon May 08 13:41:18 2006 -0600
    29.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre	Mon May 08 14:46:11 2006 -0600
    29.3 @@ -14,28 +14,12 @@ function try_to_mv() {
    29.4  	fi
    29.5  }
    29.6  
    29.7 -function try_to_mkdir() {
    29.8 -	if [ ! -e $2 ]
    29.9 -	then
   29.10 -		mv $1 $2
   29.11 -		mkdir $1
   29.12 -	fi
   29.13 -}
   29.14 -
   29.15 -try_to_mkdir mm mm.xen-x86
   29.16 -try_to_mv net net.xen-x86
   29.17 -try_to_mv kernel kernel.xen-x86
   29.18 -try_to_mv drivers/acpi/tables.c drivers/acpi/tables.c.xen-x86
   29.19 -#try_to_mv arch/xen/kernel drivers/xen/core
   29.20 -#try_to_mkdir arch/xen arch/xen.xen-x86
   29.21 -#try_to_mv arch/xen.xen-x86/configs arch/xen
   29.22 -#try_to_mv include/asm-generic include/asm-generic.xen-x86
   29.23 -try_to_mkdir include/linux include/linux.xen-x86
   29.24 +try_to_mv mm/Kconfig mm/Kconfig.xen-x86
   29.25  
   29.26  # need to grab a couple of xen-modified files for generic_page_range and
   29.27  # typedef pte_fn_t which are used by driver/xen blkif
   29.28 -ln -sf ../mm.xen-x86/memory.c mm/
   29.29 -ln -sf ../linux.xen-x86/mm.h include/linux/
   29.30 +#ln -sf ../mm.xen-x86/memory.c mm/
   29.31 +#ln -sf ../linux.xen-x86/mm.h include/linux/
   29.32  
   29.33  #eventually asm-xsi-offsets needs to be part of hypervisor.h/hypercall.h
   29.34  ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/asm-ia64/xen/
    30.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c	Mon May 08 13:41:18 2006 -0600
    30.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c	Mon May 08 14:46:11 2006 -0600
    30.3 @@ -61,9 +61,8 @@ void unmask_evtchn(int port)
    30.4  #if 0	// FIXME: diverged from x86 evtchn.c
    30.5  	/* Slow path (hypercall) if this is a non-local port. */
    30.6  	if (unlikely(cpu != cpu_from_evtchn(port))) {
    30.7 -		evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
    30.8 -				   .u.unmask.port = port };
    30.9 -		(void)HYPERVISOR_event_channel_op(&op);
   30.10 +		struct evtchn_unmask op = { .port = port };
   30.11 +		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &op);
   30.12  		return;
   30.13  	}
   30.14  #endif
   30.15 @@ -95,16 +94,16 @@ int bind_virq_to_irqhandler(
   30.16  	const char *devname,
   30.17  	void *dev_id)
   30.18  {
   30.19 -    evtchn_op_t op;
   30.20 +    struct evtchn_bind_virq bind_virq;
   30.21      int evtchn;
   30.22  
   30.23      spin_lock(&irq_mapping_update_lock);
   30.24  
   30.25 -    op.cmd = EVTCHNOP_bind_virq;
   30.26 -    op.u.bind_virq.virq = virq;
   30.27 -    op.u.bind_virq.vcpu = cpu;
   30.28 -    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0 );
   30.29 -    evtchn = op.u.bind_virq.port;
   30.30 +    bind_virq.virq = virq;
   30.31 +    bind_virq.vcpu = cpu;
   30.32 +    if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq) != 0)
   30.33 +        BUG();
   30.34 +    evtchn = bind_virq.port;
   30.35  
   30.36      if (!unbound_irq(evtchn)) {
   30.37          evtchn = -EINVAL;
   30.38 @@ -158,7 +157,7 @@ int bind_ipi_to_irqhandler(
   30.39  
   30.40  void unbind_from_irqhandler(unsigned int irq, void *dev_id)
   30.41  {
   30.42 -    evtchn_op_t op;
   30.43 +    struct evtchn_close close;
   30.44      int evtchn = evtchn_from_irq(irq);
   30.45  
   30.46      spin_lock(&irq_mapping_update_lock);
   30.47 @@ -166,9 +165,9 @@ void unbind_from_irqhandler(unsigned int
   30.48      if (unbound_irq(irq))
   30.49          goto out;
   30.50  
   30.51 -    op.cmd = EVTCHNOP_close;
   30.52 -    op.u.close.port = evtchn;
   30.53 -    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
   30.54 +    close.port = evtchn;
   30.55 +    if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
   30.56 +        BUG();
   30.57  
   30.58      switch (type_from_irq(irq)) {
   30.59  	case IRQT_VIRQ:
    31.1 --- a/linux-2.6-xen-sparse/arch/x86_64/ia32/Makefile	Mon May 08 13:41:18 2006 -0600
    31.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/ia32/Makefile	Mon May 08 14:46:11 2006 -0600
    31.3 @@ -28,11 +28,11 @@ quiet_cmd_syscall = SYSCALL $@
    31.4  $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
    31.5  	$(call if_changed,syscall)
    31.6  
    31.7 -AFLAGS_vsyscall-sysenter.o = -m32 -Iarch/i386/kernel
    31.8 -AFLAGS_vsyscall-syscall.o = -m32 -Iarch/i386/kernel
    31.9 +AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel
   31.10 +AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel
   31.11  
   31.12  ifdef CONFIG_XEN
   31.13 -AFLAGS_vsyscall-int80.o = -m32 -Iarch/i386/kernel
   31.14 +AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel
   31.15  CFLAGS_syscall32-xen.o += -DUSE_INT80
   31.16  AFLAGS_syscall32_syscall-xen.o += -DUSE_INT80
   31.17  
    32.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Mon May 08 13:41:18 2006 -0600
    32.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Mon May 08 14:46:11 2006 -0600
    32.3 @@ -600,7 +600,7 @@ void __init e820_reserve_resources(void)
    32.4  
    32.5  	map = alloc_bootmem_low_pages(PAGE_SIZE);
    32.6  	op.cmd = DOM0_PHYSICAL_MEMORY_MAP;
    32.7 -	op.u.physical_memory_map.memory_map = map;
    32.8 +	set_xen_guest_handle(op.u.physical_memory_map.memory_map, map);
    32.9  	op.u.physical_memory_map.max_map_entries =
   32.10  		PAGE_SIZE / sizeof(struct dom0_memory_map_entry);
   32.11  	BUG_ON(HYPERVISOR_dom0_op(&op));
    33.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Mon May 08 13:41:18 2006 -0600
    33.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Mon May 08 14:46:11 2006 -0600
    33.3 @@ -221,6 +221,10 @@ rff_trace:
    33.4   *
    33.5   * XXX	if we had a free scratch register we could save the RSP into the stack frame
    33.6   *      and report it properly in ps. Unfortunately we haven't.
    33.7 + *
    33.8 + * When user can change the frames always force IRET. That is because
    33.9 + * it deals with uncanonical addresses better. SYSRET has trouble
   33.10 + * with them due to bugs in both AMD and Intel CPUs.
   33.11   */ 			 		
   33.12  
   33.13  ENTRY(system_call)
   33.14 @@ -289,7 +293,10 @@ sysret_signal:
   33.15  	xorl %esi,%esi # oldset -> arg2
   33.16  	call ptregscall_common
   33.17  1:	movl $_TIF_NEED_RESCHED,%edi
   33.18 -	jmp sysret_check
   33.19 +	/* Use IRET because user could have changed frame. This
   33.20 +	   works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
   33.21 +	cli
   33.22 +	jmp int_with_check
   33.23  	
   33.24  badsys:
   33.25  	movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
   33.26 @@ -315,7 +322,8 @@ 1:	SAVE_REST
   33.27  	call syscall_trace_leave
   33.28  	RESTORE_TOP_OF_STACK %rbx
   33.29  	RESTORE_REST
   33.30 -	jmp ret_from_sys_call
   33.31 +	/* Use IRET because user could have changed frame */
   33.32 +	jmp int_ret_from_sys_call
   33.33  	CFI_ENDPROC
   33.34  		
   33.35  /* 
   33.36 @@ -449,25 +457,9 @@ ENTRY(stub_execve)
   33.37  	CFI_ADJUST_CFA_OFFSET -8
   33.38  	CFI_REGISTER rip, r11
   33.39  	SAVE_REST
   33.40 -	movq %r11, %r15
   33.41 -	CFI_REGISTER rip, r15
   33.42  	FIXUP_TOP_OF_STACK %r11
   33.43  	call sys_execve
   33.44 -	GET_THREAD_INFO(%rcx)
   33.45 -	bt $TIF_IA32,threadinfo_flags(%rcx)
   33.46 -	CFI_REMEMBER_STATE
   33.47 -	jc exec_32bit
   33.48  	RESTORE_TOP_OF_STACK %r11
   33.49 -	movq %r15, %r11
   33.50 -	CFI_REGISTER rip, r11
   33.51 -	RESTORE_REST
   33.52 -	pushq %r11
   33.53 -	CFI_ADJUST_CFA_OFFSET 8
   33.54 -	CFI_REL_OFFSET rip, 0
   33.55 -	ret
   33.56 -
   33.57 -exec_32bit:
   33.58 -	CFI_RESTORE_STATE
   33.59  	movq %rax,RAX(%rsp)
   33.60  	RESTORE_REST
   33.61  	jmp int_ret_from_sys_call
    34.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c	Mon May 08 13:41:18 2006 -0600
    34.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c	Mon May 08 14:46:11 2006 -0600
    34.3 @@ -104,27 +104,25 @@ unsigned long io_apic_irqs;
    34.4  
    34.5  static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
    34.6  {
    34.7 -	physdev_op_t op;
    34.8 +	struct physdev_apic apic_op;
    34.9  	int ret;
   34.10  
   34.11 -	op.cmd = PHYSDEVOP_APIC_READ;
   34.12 -	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   34.13 -	op.u.apic_op.reg = reg;
   34.14 -	ret = HYPERVISOR_physdev_op(&op);
   34.15 +	apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   34.16 +	apic_op.reg = reg;
   34.17 +	ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
   34.18  	if (ret)
   34.19  		return ret;
   34.20 -	return op.u.apic_op.value;
   34.21 +	return apic_op.value;
   34.22  }
   34.23  
   34.24  static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
   34.25  {
   34.26 -	physdev_op_t op;
   34.27 +	struct physdev_apic apic_op;
   34.28  
   34.29 -	op.cmd = PHYSDEVOP_APIC_WRITE;
   34.30 -	op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   34.31 -	op.u.apic_op.reg = reg;
   34.32 -	op.u.apic_op.value = value;
   34.33 -	HYPERVISOR_physdev_op(&op);
   34.34 +	apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
   34.35 +	apic_op.reg = reg;
   34.36 +	apic_op.value = value;
   34.37 +	HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
   34.38  }
   34.39  
   34.40  #define io_apic_read(a,r)    xen_io_apic_read(a,r)
   34.41 @@ -869,22 +867,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos
   34.42  
   34.43  int assign_irq_vector(int irq)
   34.44  {
   34.45 -	physdev_op_t op;
   34.46 +	struct physdev_irq irq_op;
   34.47    
   34.48    	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
   34.49    	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
   34.50    		return IO_APIC_VECTOR(irq);
   34.51  
   34.52 -	op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
   34.53 -	op.u.irq_op.irq = irq;
   34.54 -	if (HYPERVISOR_physdev_op(&op))
   34.55 +	irq_op.irq = irq;
   34.56 +	if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
   34.57  		return -ENOSPC;
   34.58  
   34.59 -	vector_irq[op.u.irq_op.vector] = irq;
   34.60 +	vector_irq[irq_op.vector] = irq;
   34.61  	if (irq != AUTO_ASSIGN)
   34.62 -		IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
   34.63 +		IO_APIC_VECTOR(irq) = irq_op.vector;
   34.64  
   34.65 -	return op.u.irq_op.vector;
   34.66 +	return irq_op.vector;
   34.67  }
   34.68  
   34.69  extern void (*interrupt[NR_IRQS])(void);
    35.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Mon May 08 13:41:18 2006 -0600
    35.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Mon May 08 14:46:11 2006 -0600
    35.3 @@ -28,8 +28,8 @@
    35.4  
    35.5  asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
    35.6  {
    35.7 -        unsigned int old_iopl = current->thread.iopl;
    35.8 -        physdev_op_t op;
    35.9 +	unsigned int old_iopl = current->thread.iopl;
   35.10 +	struct physdev_set_iopl set_iopl;
   35.11  
   35.12  	if (new_iopl > 3)
   35.13  		return -EINVAL;
   35.14 @@ -42,9 +42,8 @@ asmlinkage long sys_iopl(unsigned int ne
   35.15  	current->thread.iopl = new_iopl;
   35.16  
   35.17  	/* Force the change at ring 0. */
   35.18 -	op.cmd             = PHYSDEVOP_SET_IOPL;
   35.19 -	op.u.set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
   35.20 -	HYPERVISOR_physdev_op(&op);
   35.21 +	set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
   35.22 +	HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
   35.23  
   35.24  	return 0;
   35.25  }
    36.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c	Mon May 08 13:41:18 2006 -0600
    36.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c	Mon May 08 14:46:11 2006 -0600
    36.3 @@ -293,9 +293,7 @@ void exit_thread(void)
    36.4  		struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
    36.5  #endif
    36.6  #ifdef CONFIG_XEN
    36.7 -		static physdev_op_t iobmp_op = {
    36.8 -			.cmd = PHYSDEVOP_SET_IOBITMAP
    36.9 -		};
   36.10 +		struct physdev_set_iobitmap iobmp_op = { 0 };
   36.11  #endif
   36.12  
   36.13  		kfree(t->io_bitmap_ptr);
   36.14 @@ -308,7 +306,7 @@ void exit_thread(void)
   36.15  		put_cpu();
   36.16  #endif
   36.17  #ifdef CONFIG_XEN
   36.18 -		HYPERVISOR_physdev_op(&iobmp_op);
   36.19 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobmp_op);
   36.20  #endif
   36.21  		t->io_bitmap_max = 0;
   36.22  	}
   36.23 @@ -478,13 +476,18 @@ static inline void __save_init_fpu( stru
   36.24  #ifndef CONFIG_X86_NO_TSS
   36.25  	struct tss_struct *tss = &per_cpu(init_tss, cpu);
   36.26  #endif
   36.27 -	physdev_op_t iopl_op, iobmp_op;
   36.28 +	struct physdev_set_iopl iopl_op;
   36.29 +	struct physdev_set_iobitmap iobmp_op;
   36.30  	multicall_entry_t _mcl[8], *mcl = _mcl;
   36.31  
   36.32  	/*
   36.33  	 * This is basically '__unlazy_fpu', except that we queue a
   36.34  	 * multicall to indicate FPU task switch, rather than
   36.35  	 * synchronously trapping to Xen.
   36.36 +	 * This must be here to ensure both math_state_restore() and
   36.37 +	 * kernel_fpu_begin() work consistently.
   36.38 +	 * The AMD workaround requires it to be after DS reload, or
   36.39 +	 * after DS has been cleared, which we do in __prepare_arch_switch.
   36.40  	 */
   36.41  	if (prev_p->thread_info->status & TS_USEDFPU) {
   36.42  		__save_init_fpu(prev_p); /* _not_ save_init_fpu() */
   36.43 @@ -518,22 +521,19 @@ static inline void __save_init_fpu( stru
   36.44  #undef C
   36.45  
   36.46  	if (unlikely(prev->iopl != next->iopl)) {
   36.47 -		iopl_op.cmd             = PHYSDEVOP_SET_IOPL;
   36.48 -		iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 : next->iopl;
   36.49 +		iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
   36.50  		mcl->op      = __HYPERVISOR_physdev_op;
   36.51 -		mcl->args[0] = (unsigned long)&iopl_op;
   36.52 +		mcl->args[0] = PHYSDEVOP_set_iopl;
   36.53 +		mcl->args[1] = (unsigned long)&iopl_op;
   36.54  		mcl++;
   36.55  	}
   36.56  
   36.57  	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
   36.58 -		iobmp_op.cmd                     =
   36.59 -			PHYSDEVOP_SET_IOBITMAP;
   36.60 -		iobmp_op.u.set_iobitmap.bitmap   =
   36.61 -			(char *)next->io_bitmap_ptr;
   36.62 -		iobmp_op.u.set_iobitmap.nr_ports =
   36.63 -			next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   36.64 +		iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
   36.65 +		iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   36.66  		mcl->op      = __HYPERVISOR_physdev_op;
   36.67 -		mcl->args[0] = (unsigned long)&iobmp_op;
   36.68 +		mcl->args[0] = PHYSDEVOP_set_iobitmap;
   36.69 +		mcl->args[1] = (unsigned long)&iobmp_op;
   36.70  		mcl++;
   36.71  	}
   36.72  
    37.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Mon May 08 13:41:18 2006 -0600
    37.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Mon May 08 14:46:11 2006 -0600
    37.3 @@ -959,11 +959,10 @@ void __init setup_arch(char **cmdline_p)
    37.4  
    37.5  #ifdef CONFIG_XEN
    37.6  	{
    37.7 -		physdev_op_t op;
    37.8 +		struct physdev_set_iopl set_iopl;
    37.9  
   37.10 -		op.cmd             = PHYSDEVOP_SET_IOPL;
   37.11 -		op.u.set_iopl.iopl = 1;
   37.12 -		HYPERVISOR_physdev_op(&op);
   37.13 +		set_iopl.iopl = 1;
   37.14 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
   37.15  
   37.16  		if (xen_start_info->flags & SIF_INITDOMAIN) {
   37.17  			if (!(xen_start_info->flags & SIF_PRIVILEGED))
   37.18 @@ -1158,6 +1157,10 @@ static int __init init_amd(struct cpuinf
   37.19  	if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
   37.20  		set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
   37.21  
   37.22 +	/* Enable workaround for FXSAVE leak */
   37.23 +	if (c->x86 >= 6)
   37.24 +		set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
   37.25 +
   37.26  	r = get_model_name(c);
   37.27  	if (!r) { 
   37.28  		switch (c->x86) { 
    38.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Mon May 08 13:41:18 2006 -0600
    38.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Mon May 08 14:46:11 2006 -0600
    38.3 @@ -51,7 +51,7 @@ config TCG_INFINEON
    38.4  
    38.5  config TCG_XEN
    38.6  	tristate "XEN TPM Interface"
    38.7 -	depends on TCG_TPM && XEN && XEN_TPMDEV_FRONTEND
    38.8 +	depends on TCG_TPM && XEN
    38.9  	---help---
   38.10  	  If you want to make TPM support available to a Xen
   38.11  	  user domain, say Yes and it will
   38.12 @@ -60,4 +60,3 @@ config TCG_XEN
   38.13            tpm_xen.
   38.14  
   38.15  endmenu
   38.16 -
    39.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Mon May 08 13:41:18 2006 -0600
    39.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Mon May 08 14:46:11 2006 -0600
    39.3 @@ -8,4 +8,4 @@ endif
    39.4  obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
    39.5  obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
    39.6  obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
    39.7 -obj-$(CONFIG_TCG_XEN) += tpm_xen.o
    39.8 +obj-$(CONFIG_TCG_XEN) += tpm_xen.o tpm_vtpm.o
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Mon May 08 14:46:11 2006 -0600
    40.3 @@ -0,0 +1,546 @@
    40.4 +/*
    40.5 + * Copyright (C) 2006 IBM Corporation
    40.6 + *
    40.7 + * Authors:
    40.8 + * Stefan Berger <stefanb@us.ibm.com>
    40.9 + *
   40.10 + * Generic device driver part for device drivers in a virtualized
   40.11 + * environment.
   40.12 + *
   40.13 + * This program is free software; you can redistribute it and/or
   40.14 + * modify it under the terms of the GNU General Public License as
   40.15 + * published by the Free Software Foundation, version 2 of the
   40.16 + * License.
   40.17 + *
   40.18 + */
   40.19 +
   40.20 +#include <asm/uaccess.h>
   40.21 +#include <linux/list.h>
   40.22 +#include <linux/device.h>
   40.23 +#include <linux/interrupt.h>
   40.24 +#include <linux/platform_device.h>
   40.25 +#include "tpm.h"
   40.26 +#include "tpm_vtpm.h"
   40.27 +
   40.28 +/* read status bits */
   40.29 +enum {
   40.30 +	STATUS_BUSY = 0x01,
   40.31 +	STATUS_DATA_AVAIL = 0x02,
   40.32 +	STATUS_READY = 0x04
   40.33 +};
   40.34 +
   40.35 +#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
   40.36 +
   40.37 +struct transmission {
   40.38 +	struct list_head next;
   40.39 +
   40.40 +	unsigned char *request;
   40.41 +	size_t  request_len;
   40.42 +	size_t  request_buflen;
   40.43 +
   40.44 +	unsigned char *response;
   40.45 +	size_t  response_len;
   40.46 +	size_t  response_buflen;
   40.47 +
   40.48 +	unsigned int flags;
   40.49 +};
   40.50 +
   40.51 +enum {
   40.52 +	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
   40.53 +};
   40.54 +
   40.55 +struct vtpm_state {
   40.56 +	struct transmission *current_request;
   40.57 +	spinlock_t           req_list_lock;
   40.58 +	wait_queue_head_t    req_wait_queue;
   40.59 +
   40.60 +	struct list_head     queued_requests;
   40.61 +
   40.62 +	struct transmission *current_response;
   40.63 +	spinlock_t           resp_list_lock;
   40.64 +	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
   40.65 +
   40.66 +	struct transmission *req_cancelled;       // if a cancellation was encounterd
   40.67 +
   40.68 +	u8                   vd_status;
   40.69 +	u8                   flags;
   40.70 +
   40.71 +	unsigned long        disconnect_time;
   40.72 +
   40.73 +	struct tpm_virtual_device *tpmvd;
   40.74 +};
   40.75 +
   40.76 +enum {
   40.77 +	DATAEX_FLAG_QUEUED_ONLY = 0x1
   40.78 +};
   40.79 +
   40.80 +
   40.81 +/* local variables */
   40.82 +static struct vtpm_state *vtpms;
   40.83 +
   40.84 +/* local function prototypes */
   40.85 +static int _vtpm_send_queued(struct tpm_chip *chip);
   40.86 +
   40.87 +
   40.88 +/* =============================================================
   40.89 + * Some utility functions
   40.90 + * =============================================================
   40.91 + */
   40.92 +static void vtpm_state_init(struct vtpm_state *vtpms)
   40.93 +{
   40.94 +	vtpms->current_request = NULL;
   40.95 +	spin_lock_init(&vtpms->req_list_lock);
   40.96 +	init_waitqueue_head(&vtpms->req_wait_queue);
   40.97 +	INIT_LIST_HEAD(&vtpms->queued_requests);
   40.98 +
   40.99 +	vtpms->current_response = NULL;
  40.100 +	spin_lock_init(&vtpms->resp_list_lock);
  40.101 +	init_waitqueue_head(&vtpms->resp_wait_queue);
  40.102 +
  40.103 +	vtpms->disconnect_time = jiffies;
  40.104 +}
  40.105 +
  40.106 +
  40.107 +static inline struct transmission *transmission_alloc(void)
  40.108 +{
  40.109 +	return kzalloc(sizeof(struct transmission), GFP_ATOMIC);
  40.110 +}
  40.111 +
  40.112 +static unsigned char *
  40.113 +transmission_set_req_buffer(struct transmission *t,
  40.114 +                            unsigned char *buffer, size_t len)
  40.115 +{
  40.116 +	if (t->request_buflen < len) {
  40.117 +		kfree(t->request);
  40.118 +		t->request = kmalloc(len, GFP_KERNEL);
  40.119 +		if (!t->request) {
  40.120 +			t->request_buflen = 0;
  40.121 +			return NULL;
  40.122 +		}
  40.123 +		t->request_buflen = len;
  40.124 +	}
  40.125 +
  40.126 +	memcpy(t->request, buffer, len);
  40.127 +	t->request_len = len;
  40.128 +
  40.129 +	return t->request;
  40.130 +}
  40.131 +
  40.132 +static unsigned char *
  40.133 +transmission_set_res_buffer(struct transmission *t,
  40.134 +                            const unsigned char *buffer, size_t len)
  40.135 +{
  40.136 +	if (t->response_buflen < len) {
  40.137 +		kfree(t->response);
  40.138 +		t->response = kmalloc(len, GFP_ATOMIC);
  40.139 +		if (!t->response) {
  40.140 +			t->response_buflen = 0;
  40.141 +			return NULL;
  40.142 +		}
  40.143 +		t->response_buflen = len;
  40.144 +	}
  40.145 +
  40.146 +	memcpy(t->response, buffer, len);
  40.147 +	t->response_len = len;
  40.148 +
  40.149 +	return t->response;
  40.150 +}
  40.151 +
  40.152 +static inline void transmission_free(struct transmission *t)
  40.153 +{
  40.154 +	kfree(t->request);
  40.155 +	kfree(t->response);
  40.156 +	kfree(t);
  40.157 +}
  40.158 +
  40.159 +/* =============================================================
  40.160 + * Interface with the lower layer driver
  40.161 + * =============================================================
  40.162 + */
  40.163 +/*
  40.164 + * Lower layer uses this function to make a response available.
  40.165 + */
  40.166 +int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
  40.167 +{
  40.168 +	unsigned long flags;
  40.169 +	int ret_size = 0;
  40.170 +	struct transmission *t;
  40.171 +
  40.172 +	/*
  40.173 +	 * The list with requests must contain one request
  40.174 +	 * only and the element there must be the one that
  40.175 +	 * was passed to me from the front-end.
  40.176 +	 */
  40.177 +	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
  40.178 +	if (vtpms->current_request != ptr) {
  40.179 +		printk("WARNING: The request pointer is different than the "
  40.180 +		       "pointer the shared memory driver returned to me. "
  40.181 +		       "%p != %p\n",
  40.182 +		       vtpms->current_request, ptr);
  40.183 +	}
  40.184 +
  40.185 +	/*
  40.186 +	 * If the request has been cancelled, just quit here
  40.187 +	 */
  40.188 +	if (vtpms->req_cancelled == (struct transmission *)ptr) {
  40.189 +		if (vtpms->current_request == vtpms->req_cancelled) {
  40.190 +			vtpms->current_request = NULL;
  40.191 +		}
  40.192 +		transmission_free(vtpms->req_cancelled);
  40.193 +		vtpms->req_cancelled = NULL;
  40.194 +		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.195 +		return 0;
  40.196 +	}
  40.197 +
  40.198 +	if (NULL != (t = vtpms->current_request)) {
  40.199 +		transmission_free(t);
  40.200 +		vtpms->current_request = NULL;
  40.201 +	}
  40.202 +
  40.203 +	t = transmission_alloc();
  40.204 +	if (t) {
  40.205 +		if (!transmission_set_res_buffer(t, buffer, count)) {
  40.206 +			transmission_free(t);
  40.207 +			spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.208 +			return -ENOMEM;
  40.209 +		}
  40.210 +		ret_size = count;
  40.211 +		vtpms->current_response = t;
  40.212 +		wake_up_interruptible(&vtpms->resp_wait_queue);
  40.213 +	}
  40.214 +	spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.215 +
  40.216 +	return ret_size;
  40.217 +}
  40.218 +
  40.219 +
  40.220 +/*
  40.221 + * Lower layer indicates its status (connected/disconnected)
  40.222 + */
  40.223 +void vtpm_vd_status(u8 vd_status)
  40.224 +{
  40.225 +	vtpms->vd_status = vd_status;
  40.226 +	if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
  40.227 +		vtpms->disconnect_time = jiffies;
  40.228 +	}
  40.229 +}
  40.230 +
  40.231 +/* =============================================================
  40.232 + * Interface with the generic TPM driver
  40.233 + * =============================================================
  40.234 + */
  40.235 +static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  40.236 +{
  40.237 +	int rc = 0;
  40.238 +	unsigned long flags;
  40.239 +
  40.240 +	/*
  40.241 +	 * Check if the previous operation only queued the command
  40.242 +	 * In this case there won't be a response, so I just
  40.243 +	 * return from here and reset that flag. In any other
  40.244 +	 * case I should receive a response from the back-end.
  40.245 +	 */
  40.246 +	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
  40.247 +	if ((vtpms->flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
  40.248 +		vtpms->flags &= ~DATAEX_FLAG_QUEUED_ONLY;
  40.249 +		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.250 +		/*
  40.251 +		 * The first few commands (measurements) must be
  40.252 +		 * queued since it might not be possible to talk to the
  40.253 +		 * TPM, yet.
  40.254 +		 * Return a response of up to 30 '0's.
  40.255 +		 */
  40.256 +
  40.257 +		count = MIN(count, 30);
  40.258 +		memset(buf, 0x0, count);
  40.259 +		return count;
  40.260 +	}
  40.261 +	/*
  40.262 +	 * Check whether something is in the responselist and if
  40.263 +	 * there's nothing in the list wait for something to appear.
  40.264 +	 */
  40.265 +
  40.266 +	if (!vtpms->current_response) {
  40.267 +		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.268 +		interruptible_sleep_on_timeout(&vtpms->resp_wait_queue,
  40.269 +		                               1000);
  40.270 +		spin_lock_irqsave(&vtpms->resp_list_lock ,flags);
  40.271 +	}
  40.272 +
  40.273 +	if (vtpms->current_response) {
  40.274 +		struct transmission *t = vtpms->current_response;
  40.275 +		vtpms->current_response = NULL;
  40.276 +		rc = MIN(count, t->response_len);
  40.277 +		memcpy(buf, t->response, rc);
  40.278 +		transmission_free(t);
  40.279 +	}
  40.280 +
  40.281 +	spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.282 +	return rc;
  40.283 +}
  40.284 +
  40.285 +static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
  40.286 +{
  40.287 +	int rc = 0;
  40.288 +	unsigned long flags;
  40.289 +	struct transmission *t = transmission_alloc();
  40.290 +
  40.291 +	if (!t)
  40.292 +		return -ENOMEM;
  40.293 +	/*
  40.294 +	 * If there's a current request, it must be the
  40.295 +	 * previous request that has timed out.
  40.296 +	 */
  40.297 +	spin_lock_irqsave(&vtpms->req_list_lock, flags);
  40.298 +	if (vtpms->current_request != NULL) {
  40.299 +		printk("WARNING: Sending although there is a request outstanding.\n"
  40.300 +		       "         Previous request must have timed out.\n");
  40.301 +		transmission_free(vtpms->current_request);
  40.302 +		vtpms->current_request = NULL;
  40.303 +	}
  40.304 +	spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
  40.305 +
  40.306 +	/*
  40.307 +	 * Queue the packet if the driver below is not
  40.308 +	 * ready, yet, or there is any packet already
  40.309 +	 * in the queue.
  40.310 +	 * If the driver below is ready, unqueue all
  40.311 +	 * packets first before sending our current
  40.312 +	 * packet.
  40.313 +	 * For each unqueued packet, except for the
  40.314 +	 * last (=current) packet, call the function
  40.315 +	 * tpm_xen_recv to wait for the response to come
  40.316 +	 * back.
  40.317 +	 */
  40.318 +	if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
  40.319 +		if (time_after(jiffies,
  40.320 +		               vtpms->disconnect_time + HZ * 10)) {
  40.321 +			rc = -ENOENT;
  40.322 +		} else {
  40.323 +			goto queue_it;
  40.324 +		}
  40.325 +	} else {
  40.326 +		/*
  40.327 +		 * Send all queued packets.
  40.328 +		 */
  40.329 +		if (_vtpm_send_queued(chip) == 0) {
  40.330 +
  40.331 +			vtpms->current_request = t;
  40.332 +
  40.333 +			rc = vtpm_vd_send(chip,
  40.334 +			                  vtpms->tpmvd->tpm_private,
  40.335 +			                  buf,
  40.336 +			                  count,
  40.337 +			                  t);
  40.338 +			/*
  40.339 +			 * The generic TPM driver will call
  40.340 +			 * the function to receive the response.
  40.341 +			 */
  40.342 +			if (rc < 0) {
  40.343 +				vtpms->current_request = NULL;
  40.344 +				goto queue_it;
  40.345 +			}
  40.346 +		} else {
  40.347 +queue_it:
  40.348 +			if (!transmission_set_req_buffer(t, buf, count)) {
  40.349 +				transmission_free(t);
  40.350 +				rc = -ENOMEM;
  40.351 +				goto exit;
  40.352 +			}
  40.353 +			/*
  40.354 +			 * An error occurred. Don't event try
  40.355 +			 * to send the current request. Just
  40.356 +			 * queue it.
  40.357 +			 */
  40.358 +			spin_lock_irqsave(&vtpms->req_list_lock, flags);
  40.359 +			vtpms->flags |= DATAEX_FLAG_QUEUED_ONLY;
  40.360 +			list_add_tail(&t->next, &vtpms->queued_requests);
  40.361 +			spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
  40.362 +		}
  40.363 +	}
  40.364 +
  40.365 +exit:
  40.366 +	return rc;
  40.367 +}
  40.368 +
  40.369 +
  40.370 +/*
  40.371 + * Send all queued requests.
  40.372 + */
  40.373 +static int _vtpm_send_queued(struct tpm_chip *chip)
  40.374 +{
  40.375 +	int rc;
  40.376 +	int error = 0;
  40.377 +	long flags;
  40.378 +	unsigned char buffer[1];
  40.379 +
  40.380 +	spin_lock_irqsave(&vtpms->req_list_lock, flags);
  40.381 +
  40.382 +	while (!list_empty(&vtpms->queued_requests)) {
  40.383 +		/*
  40.384 +		 * Need to dequeue them.
  40.385 +		 * Read the result into a dummy buffer.
  40.386 +		 */
  40.387 +		struct transmission *qt = (struct transmission *)
  40.388 +		                          vtpms->queued_requests.next;
  40.389 +		list_del(&qt->next);
  40.390 +		vtpms->current_request = qt;
  40.391 +		spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
  40.392 +
  40.393 +		rc = vtpm_vd_send(chip,
  40.394 +		                  vtpms->tpmvd->tpm_private,
  40.395 +		                  qt->request,
  40.396 +		                  qt->request_len,
  40.397 +		                  qt);
  40.398 +
  40.399 +		if (rc < 0) {
  40.400 +			spin_lock_irqsave(&vtpms->req_list_lock, flags);
  40.401 +			if ((qt = vtpms->current_request) != NULL) {
  40.402 +				/*
  40.403 +				 * requeue it at the beginning
  40.404 +				 * of the list
  40.405 +				 */
  40.406 +				list_add(&qt->next,
  40.407 +				         &vtpms->queued_requests);
  40.408 +			}
  40.409 +			vtpms->current_request = NULL;
  40.410 +			error = 1;
  40.411 +			break;
  40.412 +		}
  40.413 +		/*
  40.414 +		 * After this point qt is not valid anymore!
  40.415 +		 * It is freed when the front-end is delivering
  40.416 +		 * the data by calling tpm_recv
  40.417 +		 */
  40.418 +		/*
  40.419 +		 * Receive response into provided dummy buffer
  40.420 +		 */
  40.421 +		rc = vtpm_recv(chip, buffer, sizeof(buffer));
  40.422 +		spin_lock_irqsave(&vtpms->req_list_lock, flags);
  40.423 +	}
  40.424 +
  40.425 +	spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
  40.426 +
  40.427 +	return error;
  40.428 +}
  40.429 +
  40.430 +static void vtpm_cancel(struct tpm_chip *chip)
  40.431 +{
  40.432 +	unsigned long flags;
  40.433 +	spin_lock_irqsave(&vtpms->resp_list_lock,flags);
  40.434 +
  40.435 +	vtpms->req_cancelled = vtpms->current_request;
  40.436 +
  40.437 +	spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
  40.438 +}
  40.439 +
  40.440 +static u8 vtpm_status(struct tpm_chip *chip)
  40.441 +{
  40.442 +	u8 rc = 0;
  40.443 +	unsigned long flags;
  40.444 +
  40.445 +	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
  40.446 +	/*
  40.447 +	 * Data are available if:
  40.448 +	 *  - there's a current response
  40.449 +	 *  - the last packet was queued only (this is fake, but necessary to
  40.450 +	 *      get the generic TPM layer to call the receive function.)
  40.451 +	 */
  40.452 +	if (vtpms->current_response ||
  40.453 +	    0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
  40.454 +		rc = STATUS_DATA_AVAIL;
  40.455 +	}
  40.456 +	spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  40.457 +	return rc;
  40.458 +}
  40.459 +
  40.460 +static struct file_operations vtpm_ops = {
  40.461 +	.owner = THIS_MODULE,
  40.462 +	.llseek = no_llseek,
  40.463 +	.open = tpm_open,
  40.464 +	.read = tpm_read,
  40.465 +	.write = tpm_write,
  40.466 +	.release = tpm_release,
  40.467 +};
  40.468 +
  40.469 +static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  40.470 +static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
  40.471 +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
  40.472 +static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
  40.473 +
  40.474 +static struct attribute *vtpm_attrs[] = {
  40.475 +	&dev_attr_pubek.attr,
  40.476 +	&dev_attr_pcrs.attr,
  40.477 +	&dev_attr_caps.attr,
  40.478 +	&dev_attr_cancel.attr,
  40.479 +	NULL,
  40.480 +};
  40.481 +
  40.482 +static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
  40.483 +
  40.484 +static struct tpm_vendor_specific tpm_vtpm = {
  40.485 +	.recv = vtpm_recv,
  40.486 +	.send = vtpm_send,
  40.487 +	.cancel = vtpm_cancel,
  40.488 +	.status = vtpm_status,
  40.489 +	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
  40.490 +	.req_complete_val  = STATUS_DATA_AVAIL,
  40.491 +	.req_canceled = STATUS_READY,
  40.492 +	.base = 0,
  40.493 +	.attr_group = &vtpm_attr_grp,
  40.494 +	.miscdev = {
  40.495 +		.fops = &vtpm_ops,
  40.496 +	},
  40.497 +};
  40.498 +
  40.499 +static struct platform_device *pdev;
  40.500 +
  40.501 +int __init init_vtpm(struct tpm_virtual_device *tvd)
  40.502 +{
  40.503 +	int rc;
  40.504 +
  40.505 +	/* vtpms is global - only allow one user */
  40.506 +	if (vtpms)
  40.507 +		return -EBUSY;
  40.508 +
  40.509 +	vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
  40.510 +	if (!vtpms)
  40.511 +		return -ENOMEM;
  40.512 +
  40.513 +	vtpm_state_init(vtpms);
  40.514 +	vtpms->tpmvd = tvd;
  40.515 +
  40.516 +	pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
  40.517 +	if (IS_ERR(pdev)) {
  40.518 +		rc = PTR_ERR(pdev);
  40.519 +		goto err_free_mem;
  40.520 +	}
  40.521 +
  40.522 +	if (tvd)
  40.523 +		tpm_vtpm.buffersize = tvd->max_tx_size;
  40.524 +
  40.525 +	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
  40.526 +		goto err_unreg_pdev;
  40.527 +	}
  40.528 +
  40.529 +	return 0;
  40.530 +
  40.531 +err_unreg_pdev:
  40.532 +	platform_device_unregister(pdev);
  40.533 +err_free_mem:
  40.534 +	kfree(vtpms);
  40.535 +	vtpms = NULL;
  40.536 +
  40.537 +	return rc;
  40.538 +}
  40.539 +
  40.540 +void __exit cleanup_vtpm(void)
  40.541 +{
  40.542 +	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
  40.543 +	if (chip) {
  40.544 +		tpm_remove_hardware(chip->dev);
  40.545 +		platform_device_unregister(pdev);
  40.546 +	}
  40.547 +	kfree(vtpms);
  40.548 +	vtpms = NULL;
  40.549 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Mon May 08 14:46:11 2006 -0600
    41.3 @@ -0,0 +1,38 @@
    41.4 +#ifndef TPM_VTPM_H
    41.5 +#define TPM_VTPM_H
    41.6 +
    41.7 +struct tpm_chip;
    41.8 +struct tpm_private;
    41.9 +
   41.10 +struct tpm_virtual_device {
   41.11 +	/*
   41.12 +	 * This field indicates the maximum size the driver can
   41.13 +	 * transfer in one chunk. It is filled in by the front-end
   41.14 +	 * driver and should be propagated to the generic tpm driver
   41.15 +	 * for allocation of buffers.
   41.16 +	 */
   41.17 +	unsigned int max_tx_size;
   41.18 +	/*
   41.19 +	 * The following is a private structure of the underlying
   41.20 +	 * driver. It is passed as parameter in the send function.
   41.21 +	 */
   41.22 +	struct tpm_private *tpm_private;
   41.23 +};
   41.24 +
   41.25 +enum vdev_status {
   41.26 +	TPM_VD_STATUS_DISCONNECTED = 0x0,
   41.27 +	TPM_VD_STATUS_CONNECTED = 0x1
   41.28 +};
   41.29 +
   41.30 +/* this function is called from tpm_vtpm.c */
   41.31 +int vtpm_vd_send(struct tpm_chip *tc,
   41.32 +                 struct tpm_private * tp,
   41.33 +                 const u8 * buf, size_t count, void *ptr);
   41.34 +
   41.35 +/* these functions are offered by tpm_vtpm.c */
   41.36 +int __init init_vtpm(struct tpm_virtual_device *);
   41.37 +void __exit cleanup_vtpm(void);
   41.38 +int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
   41.39 +void vtpm_vd_status(u8 status);
   41.40 +
   41.41 +#endif
    42.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Mon May 08 13:41:18 2006 -0600
    42.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Mon May 08 14:46:11 2006 -0600
    42.3 @@ -1,536 +1,767 @@
    42.4  /*
    42.5 - * Copyright (C) 2004 IBM Corporation
    42.6 + * Copyright (c) 2005, IBM Corporation
    42.7   *
    42.8 - * Authors:
    42.9 - * Leendert van Doorn <leendert@watson.ibm.com>
   42.10 - * Dave Safford <safford@watson.ibm.com>
   42.11 - * Reiner Sailer <sailer@watson.ibm.com>
   42.12 - * Kylene Hall <kjhall@us.ibm.com>
   42.13 - * Stefan Berger <stefanb@us.ibm.com>
   42.14 + * Author: Stefan Berger, stefanb@us.ibm.com
   42.15 + * Grant table support: Mahadevan Gomathisankaran
   42.16   *
   42.17 - * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   42.18 + * This code has been derived from drivers/xen/netfront/netfront.c
   42.19   *
   42.20 - * Device driver for TCG/TCPA TPM (trusted platform module) for XEN.
   42.21 - * Specifications at www.trustedcomputinggroup.org
   42.22 + * Copyright (c) 2002-2004, K A Fraser
   42.23   *
   42.24   * This program is free software; you can redistribute it and/or
   42.25 - * modify it under the terms of the GNU General Public License as
   42.26 - * published by the Free Software Foundation, version 2 of the
   42.27 - * License.
   42.28 + * modify it under the terms of the GNU General Public License version 2
   42.29 + * as published by the Free Software Foundation; or, when distributed
   42.30 + * separately from the Linux kernel or incorporated into other
   42.31 + * software packages, subject to the following license:
   42.32   *
   42.33 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   42.34 + * of this source file (the "Software"), to deal in the Software without
   42.35 + * restriction, including without limitation the rights to use, copy, modify,
   42.36 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   42.37 + * and to permit persons to whom the Software is furnished to do so, subject to
   42.38 + * the following conditions:
   42.39 + *
   42.40 + * The above copyright notice and this permission notice shall be included in
   42.41 + * all copies or substantial portions of the Software.
   42.42 + *
   42.43 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   42.44 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   42.45 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   42.46 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   42.47 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   42.48 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   42.49 + * IN THE SOFTWARE.
   42.50   */
   42.51  
   42.52 -#include <asm/uaccess.h>
   42.53 -#include <linux/list.h>
   42.54 -#include <xen/tpmfe.h>
   42.55 -#include <linux/device.h>
   42.56 +#include <linux/errno.h>
   42.57  #include <linux/interrupt.h>
   42.58 -#include <linux/platform_device.h>
   42.59 -#include "tpm.h"
   42.60 +#include <linux/mutex.h>
   42.61 +#include <asm/uaccess.h>
   42.62 +#include <xen/evtchn.h>
   42.63 +#include <xen/interface/grant_table.h>
   42.64 +#include <xen/interface/io/tpmif.h>
   42.65 +#include <xen/xenbus.h>
   42.66 +#include "tpm_vtpm.h"
   42.67  
   42.68 -/* read status bits */
   42.69 -enum {
   42.70 -	STATUS_BUSY = 0x01,
   42.71 -	STATUS_DATA_AVAIL = 0x02,
   42.72 -	STATUS_READY = 0x04
   42.73 +#undef DEBUG
   42.74 +
   42.75 +/* local structures */
   42.76 +struct tpm_private {
   42.77 +	tpmif_tx_interface_t *tx;
   42.78 +	atomic_t refcnt;
   42.79 +	unsigned int evtchn;
   42.80 +	unsigned int irq;
   42.81 +	u8 is_connected;
   42.82 +	u8 is_suspended;
   42.83 +
   42.84 +	spinlock_t tx_lock;
   42.85 +
   42.86 +	struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
   42.87 +
   42.88 +	atomic_t tx_busy;
   42.89 +	void *tx_remember;
   42.90 +	domid_t backend_id;
   42.91 +	wait_queue_head_t wait_q;
   42.92 +
   42.93 +	struct xenbus_device *dev;
   42.94 +	int ring_ref;
   42.95  };
   42.96  
   42.97 -#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
   42.98 -
   42.99 -struct transmission {
  42.100 -	struct list_head next;
  42.101 -	unsigned char *request;
  42.102 -	unsigned int request_len;
  42.103 -	unsigned char *rcv_buffer;
  42.104 -	unsigned int  buffersize;
  42.105 -	unsigned int flags;
  42.106 -};
  42.107 -
  42.108 -enum {
  42.109 -	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
  42.110 +struct tx_buffer {
  42.111 +	unsigned int size;	// available space in data
  42.112 +	unsigned int len;	// used space in data
  42.113 +	unsigned char *data;	// pointer to a page
  42.114  };
  42.115  
  42.116 -struct data_exchange {
  42.117 -	struct transmission *current_request;
  42.118 -	spinlock_t           req_list_lock;
  42.119 -	wait_queue_head_t    req_wait_queue;
  42.120 -
  42.121 -	struct list_head     queued_requests;
  42.122 -
  42.123 -	struct transmission *current_response;
  42.124 -	spinlock_t           resp_list_lock;
  42.125 -	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
  42.126 -
  42.127 -	struct transmission *req_cancelled;       // if a cancellation was encounterd
  42.128 -
  42.129 -	unsigned int         fe_status;
  42.130 -	unsigned int         flags;
  42.131 -};
  42.132 -
  42.133 -enum {
  42.134 -	DATAEX_FLAG_QUEUED_ONLY = 0x1
  42.135 -};
  42.136 -
  42.137 -static struct data_exchange dataex;
  42.138 -
  42.139 -static unsigned long disconnect_time;
  42.140 -
  42.141 -static struct tpmfe_device tpmfe;
  42.142 -
  42.143 -/* local function prototypes */
  42.144 -static void __exit cleanup_xen(void);
  42.145 -
  42.146  
  42.147 -/* =============================================================
  42.148 - * Some utility functions
  42.149 - * =============================================================
  42.150 - */
  42.151 -static inline struct transmission *
  42.152 -transmission_alloc(void)
  42.153 -{
  42.154 -	return kzalloc(sizeof(struct transmission), GFP_KERNEL);
  42.155 -}
  42.156 +/* locally visible variables */
  42.157 +static grant_ref_t gref_head;
  42.158 +static struct tpm_private *my_priv;
  42.159  
  42.160 -static inline unsigned char *
  42.161 -transmission_set_buffer(struct transmission *t,
  42.162 -                        unsigned char *buffer, unsigned int len)
  42.163 +/* local function prototypes */
  42.164 +static irqreturn_t tpmif_int(int irq,
  42.165 +                             void *tpm_priv,
  42.166 +                             struct pt_regs *ptregs);
  42.167 +static void tpmif_rx_action(unsigned long unused);
  42.168 +static int tpmif_connect(struct xenbus_device *dev,
  42.169 +                         struct tpm_private *tp,
  42.170 +                         domid_t domid);
  42.171 +static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
  42.172 +static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
  42.173 +static void tpmif_free_tx_buffers(struct tpm_private *tp);
  42.174 +static void tpmif_set_connected_state(struct tpm_private *tp,
  42.175 +                                      u8 newstate);
  42.176 +static int tpm_xmit(struct tpm_private *tp,
  42.177 +                    const u8 * buf, size_t count, int userbuffer,
  42.178 +                    void *remember);
  42.179 +static void destroy_tpmring(struct tpm_private *tp);
  42.180 +
  42.181 +#define DPRINTK(fmt, args...) \
  42.182 +    pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
  42.183 +#define IPRINTK(fmt, args...) \
  42.184 +    printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
  42.185 +#define WPRINTK(fmt, args...) \
  42.186 +    printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
  42.187 +
  42.188 +#define GRANT_INVALID_REF	0
  42.189 +
  42.190 +
  42.191 +static inline int
  42.192 +tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
  42.193 +               int isuserbuffer)
  42.194  {
  42.195 -	kfree(t->request);
  42.196 -	t->request = kmalloc(len, GFP_KERNEL);
  42.197 -	if (t->request) {
  42.198 -		memcpy(t->request,
  42.199 -		       buffer,
  42.200 -		       len);
  42.201 -		t->request_len = len;
  42.202 +	int copied = len;
  42.203 +
  42.204 +	if (len > txb->size) {
  42.205 +		copied = txb->size;
  42.206  	}
  42.207 -	return t->request;
  42.208 -}
  42.209 -
  42.210 -static inline void
  42.211 -transmission_free(struct transmission *t)
  42.212 -{
  42.213 -	kfree(t->request);
  42.214 -	kfree(t->rcv_buffer);
  42.215 -	kfree(t);
  42.216 +	if (isuserbuffer) {
  42.217 +		if (copy_from_user(txb->data, src, copied))
  42.218 +			return -EFAULT;
  42.219 +	} else {
  42.220 +		memcpy(txb->data, src, copied);
  42.221 +	}
  42.222 +	txb->len = len;
  42.223 +	return copied;
  42.224  }
  42.225  
  42.226 -/* =============================================================
  42.227 - * Interface with the TPM shared memory driver for XEN
  42.228 - * =============================================================
  42.229 - */
  42.230 -static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
  42.231 +static inline struct tx_buffer *tx_buffer_alloc(void)
  42.232  {
  42.233 -	int ret_size = 0;
  42.234 -	struct transmission *t;
  42.235 +	struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
  42.236 +					GFP_KERNEL);
  42.237  
  42.238 -	/*
  42.239 -	 * The list with requests must contain one request
  42.240 -	 * only and the element there must be the one that
  42.241 -	 * was passed to me from the front-end.
  42.242 -	 */
  42.243 -	if (dataex.current_request != ptr) {
  42.244 -		printk("WARNING: The request pointer is different than the "
  42.245 -		       "pointer the shared memory driver returned to me. "
  42.246 -		       "%p != %p\n",
  42.247 -		       dataex.current_request, ptr);
  42.248 -	}
  42.249 -
  42.250 -	/*
  42.251 -	 * If the request has been cancelled, just quit here
  42.252 -	 */
  42.253 -	if (dataex.req_cancelled == (struct transmission *)ptr) {
  42.254 -		if (dataex.current_request == dataex.req_cancelled) {
  42.255 -			dataex.current_request = NULL;
  42.256 +	if (txb) {
  42.257 +		txb->len = 0;
  42.258 +		txb->size = PAGE_SIZE;
  42.259 +		txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
  42.260 +		if (txb->data == NULL) {
  42.261 +			kfree(txb);
  42.262 +			txb = NULL;
  42.263  		}
  42.264 -		transmission_free(dataex.req_cancelled);
  42.265 -		dataex.req_cancelled = NULL;
  42.266 -		return 0;
  42.267 -	}
  42.268 -
  42.269 -	if (NULL != (t = dataex.current_request)) {
  42.270 -		transmission_free(t);
  42.271 -		dataex.current_request = NULL;
  42.272  	}
  42.273 -
  42.274 -	t = transmission_alloc();
  42.275 -	if (t) {
  42.276 -		unsigned long flags;
  42.277 -		t->rcv_buffer = kmalloc(count, GFP_KERNEL);
  42.278 -		if (! t->rcv_buffer) {
  42.279 -			transmission_free(t);
  42.280 -			return -ENOMEM;
  42.281 -		}
  42.282 -		t->buffersize = count;
  42.283 -		memcpy(t->rcv_buffer, buffer, count);
  42.284 -		ret_size = count;
  42.285 -
  42.286 -		spin_lock_irqsave(&dataex.resp_list_lock ,flags);
  42.287 -		dataex.current_response = t;
  42.288 -		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  42.289 -		wake_up_interruptible(&dataex.resp_wait_queue);
  42.290 -	}
  42.291 -	return ret_size;
  42.292 +	return txb;
  42.293  }
  42.294  
  42.295  
  42.296 -static void tpm_fe_status(unsigned int flags)
  42.297 +static inline void tx_buffer_free(struct tx_buffer *txb)
  42.298  {
  42.299 -	dataex.fe_status = flags;
  42.300 -	if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
  42.301 -		disconnect_time = jiffies;
  42.302 +	if (txb) {
  42.303 +		free_page((long)txb->data);
  42.304 +		kfree(txb);
  42.305  	}
  42.306  }
  42.307  
  42.308 -/* =============================================================
  42.309 - * Interface with the generic TPM driver
  42.310 - * =============================================================
  42.311 - */
  42.312 -static int tpm_xen_recv(struct tpm_chip *chip, u8 * buf, size_t count)
  42.313 +/**************************************************************
  42.314 + Utility function for the tpm_private structure
  42.315 +**************************************************************/
  42.316 +static inline void tpm_private_init(struct tpm_private *tp)
  42.317  {
  42.318 -	unsigned long flags;
  42.319 -	int rc = 0;
  42.320 -
  42.321 -	spin_lock_irqsave(&dataex.resp_list_lock, flags);
  42.322 -	/*
  42.323 -	 * Check if the previous operation only queued the command
  42.324 -	 * In this case there won't be a response, so I just
  42.325 -	 * return from here and reset that flag. In any other
  42.326 -	 * case I should receive a response from the back-end.
  42.327 -	 */
  42.328 -	if ((dataex.flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
  42.329 -		dataex.flags &= ~DATAEX_FLAG_QUEUED_ONLY;
  42.330 -		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  42.331 -		/*
  42.332 -		 * a little hack here. The first few measurements
  42.333 -		 * are queued since there's no way to talk to the
  42.334 -		 * TPM yet (due to slowness of the control channel)
  42.335 -		 * So we just make IMA happy by giving it 30 NULL
  42.336 -		 * bytes back where the most important part is
  42.337 -		 * that the result code is '0'.
  42.338 -		 */
  42.339 -
  42.340 -		count = MIN(count, 30);
  42.341 -		memset(buf, 0x0, count);
  42.342 -		return count;
  42.343 -	}
  42.344 -	/*
  42.345 -	 * Check whether something is in the responselist and if
  42.346 -	 * there's nothing in the list wait for something to appear.
  42.347 -	 */
  42.348 -
  42.349 -	if (NULL == dataex.current_response) {
  42.350 -		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  42.351 -		interruptible_sleep_on_timeout(&dataex.resp_wait_queue,
  42.352 -		                               1000);
  42.353 -		spin_lock_irqsave(&dataex.resp_list_lock ,flags);
  42.354 -	}
  42.355 -
  42.356 -	if (NULL != dataex.current_response) {
  42.357 -		struct transmission *t = dataex.current_response;
  42.358 -		dataex.current_response = NULL;
  42.359 -		rc = MIN(count, t->buffersize);
  42.360 -		memcpy(buf, t->rcv_buffer, rc);
  42.361 -		transmission_free(t);
  42.362 -	}
  42.363 -
  42.364 -	spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  42.365 -	return rc;
  42.366 +	spin_lock_init(&tp->tx_lock);
  42.367 +	init_waitqueue_head(&tp->wait_q);
  42.368 +	atomic_set(&tp->refcnt, 1);
  42.369  }
  42.370  
  42.371 -static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
  42.372 +static inline void tpm_private_put(void)
  42.373  {
  42.374 -	/*
  42.375 -	 * We simply pass the packet onto the XEN shared
  42.376 -	 * memory driver.
  42.377 -	 */
  42.378 -	unsigned long flags;
  42.379 -	int rc;
  42.380 -	struct transmission *t = transmission_alloc();
  42.381 -
  42.382 -	spin_lock_irqsave(&dataex.req_list_lock, flags);
  42.383 -	/*
  42.384 -	 * If there's a current request, it must be the
  42.385 -	 * previous request that has timed out.
  42.386 -	 */
  42.387 -	if (dataex.current_request != NULL) {
  42.388 -		printk("WARNING: Sending although there is a request outstanding.\n"
  42.389 -		       "         Previous request must have timed out.\n");
  42.390 -		transmission_free(dataex.current_request);
  42.391 -		dataex.current_request = NULL;
  42.392 +	if ( atomic_dec_and_test(&my_priv->refcnt)) {
  42.393 +		tpmif_free_tx_buffers(my_priv);
  42.394 +		kfree(my_priv);
  42.395 +		my_priv = NULL;
  42.396  	}
  42.397 -
  42.398 -	if (t != NULL) {
  42.399 -		unsigned int error = 0;
  42.400 -		/*
  42.401 -		 * Queue the packet if the driver below is not
  42.402 -		 * ready, yet, or there is any packet already
  42.403 -		 * in the queue.
  42.404 -		 * If the driver below is ready, unqueue all
  42.405 -		 * packets first before sending our current
  42.406 -		 * packet.
  42.407 -		 * For each unqueued packet, except for the
  42.408 -		 * last (=current) packet, call the function
  42.409 -		 * tpm_xen_recv to wait for the response to come
  42.410 -		 * back.
  42.411 -		 */
  42.412 -		if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
  42.413 -			if (time_after(jiffies, disconnect_time + HZ * 10)) {
  42.414 -				rc = -ENOENT;
  42.415 -			} else {
  42.416 -				/*
  42.417 -				 * copy the request into the buffer
  42.418 -				 */
  42.419 -				if (transmission_set_buffer(t, buf, count)
  42.420 -				    == NULL) {
  42.421 -					transmission_free(t);
  42.422 -					rc = -ENOMEM;
  42.423 -					goto exit;
  42.424 -				}
  42.425 -				dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
  42.426 -				list_add_tail(&t->next, &dataex.queued_requests);
  42.427 -				rc = 0;
  42.428 -			}
  42.429 -		} else {
  42.430 -			/*
  42.431 -			 * Check whether there are any packets in the queue
  42.432 -			 */
  42.433 -			while (!list_empty(&dataex.queued_requests)) {
  42.434 -				/*
  42.435 -				 * Need to dequeue them.
  42.436 -				 * Read the result into a dummy buffer.
  42.437 -				 */
  42.438 -				unsigned char buffer[1];
  42.439 -				struct transmission *qt = (struct transmission *) dataex.queued_requests.next;
  42.440 -				list_del(&qt->next);
  42.441 -				dataex.current_request = qt;
  42.442 -				spin_unlock_irqrestore(&dataex.req_list_lock,
  42.443 -				                       flags);
  42.444 +}
  42.445  
  42.446 -				rc = tpm_fe_send(tpmfe.tpm_private,
  42.447 -				                 qt->request,
  42.448 -				                 qt->request_len,
  42.449 -				                 qt);
  42.450 -
  42.451 -				if (rc < 0) {
  42.452 -					spin_lock_irqsave(&dataex.req_list_lock, flags);
  42.453 -					if ((qt = dataex.current_request) != NULL) {
  42.454 -						/*
  42.455 -						 * requeue it at the beginning
  42.456 -						 * of the list
  42.457 -						 */
  42.458 -						list_add(&qt->next,
  42.459 -						         &dataex.queued_requests);
  42.460 -					}
  42.461 -					dataex.current_request = NULL;
  42.462 -					error = 1;
  42.463 -					break;
  42.464 -				}
  42.465 -				/*
  42.466 -				 * After this point qt is not valid anymore!
  42.467 -				 * It is freed when the front-end is delivering the data
  42.468 -				 * by calling tpm_recv
  42.469 -				 */
  42.470 -
  42.471 -				/*
  42.472 -				 * Try to receive the response now into the provided dummy
  42.473 -				 * buffer (I don't really care about this response since
  42.474 -				 * there is no receiver anymore for this response)
  42.475 -				 */
  42.476 -				rc = tpm_xen_recv(chip, buffer, sizeof(buffer));
  42.477 -
  42.478 -				spin_lock_irqsave(&dataex.req_list_lock, flags);
  42.479 -			}
  42.480 -
  42.481 -			if (error == 0) {
  42.482 -				/*
  42.483 -				 * Finally, send the current request.
  42.484 -				 */
  42.485 -				dataex.current_request = t;
  42.486 -				/*
  42.487 -				 * Call the shared memory driver
  42.488 -				 * Pass to it the buffer with the request, the
  42.489 -				 * amount of bytes in the request and
  42.490 -				 * a void * pointer (here: transmission structure)
  42.491 -				 */
  42.492 -				rc = tpm_fe_send(tpmfe.tpm_private,
  42.493 -				                 buf, count, t);
  42.494 -				/*
  42.495 -				 * The generic TPM driver will call
  42.496 -				 * the function to receive the response.
  42.497 -				 */
  42.498 -				if (rc < 0) {
  42.499 -					dataex.current_request = NULL;
  42.500 -					goto queue_it;
  42.501 -				}
  42.502 -			} else {
  42.503 -queue_it:
  42.504 -				if (transmission_set_buffer(t, buf, count) == NULL) {
  42.505 -					transmission_free(t);
  42.506 -					rc = -ENOMEM;
  42.507 -					goto exit;
  42.508 -				}
  42.509 -				/*
  42.510 -				 * An error occurred. Don't event try
  42.511 -				 * to send the current request. Just
  42.512 -				 * queue it.
  42.513 -				 */
  42.514 -				dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
  42.515 -				list_add_tail(&t->next,
  42.516 -				              &dataex.queued_requests);
  42.517 -				rc = 0;
  42.518 +static struct tpm_private *tpm_private_get(void)
  42.519 +{
  42.520 +	int err;
  42.521 +	if (!my_priv) {
  42.522 +		my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
  42.523 +		if (my_priv) {
  42.524 +			tpm_private_init(my_priv);
  42.525 +			err = tpmif_allocate_tx_buffers(my_priv);
  42.526 +			if (err < 0) {
  42.527 +				tpm_private_put();
  42.528  			}
  42.529  		}
  42.530  	} else {
  42.531 -		rc = -ENOMEM;
  42.532 +		atomic_inc(&my_priv->refcnt);
  42.533  	}
  42.534 -
  42.535 -exit:
  42.536 -	spin_unlock_irqrestore(&dataex.req_list_lock, flags);
  42.537 -	return rc;
  42.538 -}
  42.539 -
  42.540 -static void tpm_xen_cancel(struct tpm_chip *chip)
  42.541 -{
  42.542 -	unsigned long flags;
  42.543 -	spin_lock_irqsave(&dataex.resp_list_lock,flags);
  42.544 -
  42.545 -	dataex.req_cancelled = dataex.current_request;
  42.546 -
  42.547 -	spin_unlock_irqrestore(&dataex.resp_list_lock,flags);
  42.548 -}
  42.549 -
  42.550 -static u8 tpm_xen_status(struct tpm_chip *chip)
  42.551 -{
  42.552 -	unsigned long flags;
  42.553 -	u8 rc = 0;
  42.554 -	spin_lock_irqsave(&dataex.resp_list_lock, flags);
  42.555 -	/*
  42.556 -	 * Data are available if:
  42.557 -	 *  - there's a current response
  42.558 -	 *  - the last packet was queued only (this is fake, but necessary to
  42.559 -	 *      get the generic TPM layer to call the receive function.)
  42.560 -	 */
  42.561 -	if (NULL != dataex.current_response ||
  42.562 -	    0 != (dataex.flags & DATAEX_FLAG_QUEUED_ONLY)) {
  42.563 -		rc = STATUS_DATA_AVAIL;
  42.564 -	}
  42.565 -	spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  42.566 -	return rc;
  42.567 +	return my_priv;
  42.568  }
  42.569  
  42.570 -static struct file_operations tpm_xen_ops = {
  42.571 -	.owner = THIS_MODULE,
  42.572 -	.llseek = no_llseek,
  42.573 -	.open = tpm_open,
  42.574 -	.read = tpm_read,
  42.575 -	.write = tpm_write,
  42.576 -	.release = tpm_release,
  42.577 -};
  42.578 +/**************************************************************
  42.579  
  42.580 -static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  42.581 -static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
  42.582 -static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
  42.583 -static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
  42.584 + The interface to let the tpm plugin register its callback
  42.585 + function and send data to another partition using this module
  42.586  
  42.587 -static struct attribute* xen_attrs[] = {
  42.588 -	&dev_attr_pubek.attr,
  42.589 -	&dev_attr_pcrs.attr,
  42.590 -	&dev_attr_caps.attr,
  42.591 -	&dev_attr_cancel.attr,
  42.592 -	NULL,
  42.593 +**************************************************************/
  42.594 +
  42.595 +static DEFINE_MUTEX(suspend_lock);
  42.596 +/*
  42.597 + * Send data via this module by calling this function
  42.598 + */
  42.599 +int vtpm_vd_send(struct tpm_chip *chip,
  42.600 +                 struct tpm_private *tp,
  42.601 +                 const u8 * buf, size_t count, void *ptr)
  42.602 +{
  42.603 +	int sent;
  42.604 +
  42.605 +	mutex_lock(&suspend_lock);
  42.606 +	sent = tpm_xmit(tp, buf, count, 0, ptr);
  42.607 +	mutex_unlock(&suspend_lock);
  42.608 +
  42.609 +	return sent;
  42.610 +}
  42.611 +
  42.612 +/**************************************************************
  42.613 + XENBUS support code
  42.614 +**************************************************************/
  42.615 +
  42.616 +static int setup_tpmring(struct xenbus_device *dev,
  42.617 +                         struct tpm_private *tp)
  42.618 +{
  42.619 +	tpmif_tx_interface_t *sring;
  42.620 +	int err;
  42.621 +
  42.622 +	tp->ring_ref = GRANT_INVALID_REF;
  42.623 +
  42.624 +	sring = (void *)__get_free_page(GFP_KERNEL);
  42.625 +	if (!sring) {
  42.626 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
  42.627 +		return -ENOMEM;
  42.628 +	}
  42.629 +	tp->tx = sring;
  42.630 +
  42.631 +	err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
  42.632 +	if (err < 0) {
  42.633 +		free_page((unsigned long)sring);
  42.634 +		tp->tx = NULL;
  42.635 +		xenbus_dev_fatal(dev, err, "allocating grant reference");
  42.636 +		goto fail;
  42.637 +	}
  42.638 +	tp->ring_ref = err;
  42.639 +
  42.640 +	err = tpmif_connect(dev, tp, dev->otherend_id);
  42.641 +	if (err)
  42.642 +		goto fail;
  42.643 +
  42.644 +	return 0;
  42.645 +fail:
  42.646 +	destroy_tpmring(tp);
  42.647 +	return err;
  42.648 +}
  42.649 +
  42.650 +
  42.651 +static void destroy_tpmring(struct tpm_private *tp)
  42.652 +{
  42.653 +	tpmif_set_connected_state(tp, 0);
  42.654 +
  42.655 +	if (tp->ring_ref != GRANT_INVALID_REF) {
  42.656 +		gnttab_end_foreign_access(tp->ring_ref, 0,
  42.657 +					  (unsigned long)tp->tx);
  42.658 +		tp->ring_ref = GRANT_INVALID_REF;
  42.659 +		tp->tx = NULL;
  42.660 +	}
  42.661 +
  42.662 +	if (tp->irq)
  42.663 +		unbind_from_irqhandler(tp->irq, tp);
  42.664 +
  42.665 +	tp->evtchn = tp->irq = 0;
  42.666 +}
  42.667 +
  42.668 +
  42.669 +static int talk_to_backend(struct xenbus_device *dev,
  42.670 +                           struct tpm_private *tp)
  42.671 +{
  42.672 +	const char *message = NULL;
  42.673 +	int err;
  42.674 +	xenbus_transaction_t xbt;
  42.675 +
  42.676 +	err = setup_tpmring(dev, tp);
  42.677 +	if (err) {
  42.678 +		xenbus_dev_fatal(dev, err, "setting up ring");
  42.679 +		goto out;
  42.680 +	}
  42.681 +
  42.682 +again:
  42.683 +	err = xenbus_transaction_start(&xbt);
  42.684 +	if (err) {
  42.685 +		xenbus_dev_fatal(dev, err, "starting transaction");
  42.686 +		goto destroy_tpmring;
  42.687 +	}
  42.688 +
  42.689 +	err = xenbus_printf(xbt, dev->nodename,
  42.690 +	                    "ring-ref","%u", tp->ring_ref);
  42.691 +	if (err) {
  42.692 +		message = "writing ring-ref";
  42.693 +		goto abort_transaction;
  42.694 +	}
  42.695 +
  42.696 +	err = xenbus_printf(xbt, dev->nodename,
  42.697 +			    "event-channel", "%u", tp->evtchn);
  42.698 +	if (err) {
  42.699 +		message = "writing event-channel";
  42.700 +		goto abort_transaction;
  42.701 +	}
  42.702 +
  42.703 +	err = xenbus_transaction_end(xbt, 0);
  42.704 +	if (err == -EAGAIN)
  42.705 +		goto again;
  42.706 +	if (err) {
  42.707 +		xenbus_dev_fatal(dev, err, "completing transaction");
  42.708 +		goto destroy_tpmring;
  42.709 +	}
  42.710 +
  42.711 +	xenbus_switch_state(dev, XenbusStateConnected);
  42.712 +
  42.713 +	return 0;
  42.714 +
  42.715 +abort_transaction:
  42.716 +	xenbus_transaction_end(xbt, 1);
  42.717 +	if (message)
  42.718 +		xenbus_dev_error(dev, err, "%s", message);
  42.719 +destroy_tpmring:
  42.720 +	destroy_tpmring(tp);
  42.721 +out:
  42.722 +	return err;
  42.723 +}
  42.724 +
  42.725 +/**
  42.726 + * Callback received when the backend's state changes.
  42.727 + */
  42.728 +static void backend_changed(struct xenbus_device *dev,
  42.729 +			    XenbusState backend_state)
  42.730 +{
  42.731 +	struct tpm_private *tp = dev->data;
  42.732 +	DPRINTK("\n");
  42.733 +
  42.734 +	switch (backend_state) {
  42.735 +	case XenbusStateInitialising:
  42.736 +	case XenbusStateInitWait:
  42.737 +	case XenbusStateInitialised:
  42.738 +	case XenbusStateUnknown:
  42.739 +		break;
  42.740 +
  42.741 +	case XenbusStateConnected:
  42.742 +		tpmif_set_connected_state(tp, 1);
  42.743 +		break;
  42.744 +
  42.745 +	case XenbusStateClosing:
  42.746 +		tpmif_set_connected_state(tp, 0);
  42.747 +		break;
  42.748 +
  42.749 +	case XenbusStateClosed:
  42.750 +		if (tp->is_suspended == 0) {
  42.751 +			device_unregister(&dev->dev);
  42.752 +		}
  42.753 +		xenbus_switch_state(dev, XenbusStateClosed);
  42.754 +		break;
  42.755 +	}
  42.756 +}
  42.757 +
  42.758 +
  42.759 +static int tpmfront_probe(struct xenbus_device *dev,
  42.760 +                          const struct xenbus_device_id *id)
  42.761 +{
  42.762 +	int err;
  42.763 +	int handle;
  42.764 +	struct tpm_private *tp = tpm_private_get();
  42.765 +
  42.766 +	if (!tp)
  42.767 +		return -ENOMEM;
  42.768 +
  42.769 +	err = xenbus_scanf(XBT_NULL, dev->nodename,
  42.770 +	                   "handle", "%i", &handle);
  42.771 +	if (XENBUS_EXIST_ERR(err))
  42.772 +		return err;
  42.773 +
  42.774 +	if (err < 0) {
  42.775 +		xenbus_dev_fatal(dev,err,"reading virtual-device");
  42.776 +		return err;
  42.777 +	}
  42.778 +
  42.779 +	tp->dev = dev;
  42.780 +	dev->data = tp;
  42.781 +
  42.782 +	err = talk_to_backend(dev, tp);
  42.783 +	if (err) {
  42.784 +		tpm_private_put();
  42.785 +		dev->data = NULL;
  42.786 +		return err;
  42.787 +	}
  42.788 +	return 0;
  42.789 +}
  42.790 +
  42.791 +
  42.792 +static int tpmfront_remove(struct xenbus_device *dev)
  42.793 +{
  42.794 +	struct tpm_private *tp = (struct tpm_private *)dev->data;
  42.795 +	destroy_tpmring(tp);
  42.796 +	return 0;
  42.797 +}
  42.798 +
  42.799 +static int tpmfront_suspend(struct xenbus_device *dev)
  42.800 +{
  42.801 +	struct tpm_private *tp = (struct tpm_private *)dev->data;
  42.802 +	u32 ctr;
  42.803 +
  42.804 +	/* lock, so no app can send */
  42.805 +	mutex_lock(&suspend_lock);
  42.806 +	tp->is_suspended = 1;
  42.807 +
  42.808 +	for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
  42.809 +		if ((ctr % 10) == 0)
  42.810 +			printk("TPM-FE [INFO]: Waiting for outstanding request.\n");
  42.811 +		/*
  42.812 +		 * Wait for a request to be responded to.
  42.813 +		 */
  42.814 +		interruptible_sleep_on_timeout(&tp->wait_q, 100);
  42.815 +	}
  42.816 +	xenbus_switch_state(dev, XenbusStateClosed);
  42.817 +
  42.818 +	if (atomic_read(&tp->tx_busy)) {
  42.819 +		/*
  42.820 +		 * A temporary work-around.
  42.821 +		 */
  42.822 +		printk("TPM-FE [WARNING]: Resetting busy flag.");
  42.823 +		atomic_set(&tp->tx_busy, 0);
  42.824 +	}
  42.825 +
  42.826 +	return 0;
  42.827 +}
  42.828 +
  42.829 +static int tpmfront_resume(struct xenbus_device *dev)
  42.830 +{
  42.831 +	struct tpm_private *tp = (struct tpm_private *)dev->data;
  42.832 +	destroy_tpmring(tp);
  42.833 +	return talk_to_backend(dev, tp);
  42.834 +}
  42.835 +
  42.836 +static int tpmif_connect(struct xenbus_device *dev,
  42.837 +                         struct tpm_private *tp,
  42.838 +                         domid_t domid)
  42.839 +{
  42.840 +	int err;
  42.841 +
  42.842 +	tp->backend_id = domid;
  42.843 +
  42.844 +	err = xenbus_alloc_evtchn(dev, &tp->evtchn);
  42.845 +	if (err)
  42.846 +		return err;
  42.847 +
  42.848 +	err = bind_evtchn_to_irqhandler(tp->evtchn,
  42.849 +					tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
  42.850 +					tp);
  42.851 +	if (err <= 0) {
  42.852 +		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  42.853 +		return err;
  42.854 +	}
  42.855 +
  42.856 +	tp->irq = err;
  42.857 +	return 0;
  42.858 +}
  42.859 +
  42.860 +static struct xenbus_device_id tpmfront_ids[] = {
  42.861 +	{ "vtpm" },
  42.862 +	{ "" }
  42.863  };
  42.864  
  42.865 -static struct attribute_group xen_attr_grp = { .attrs = xen_attrs };
  42.866 -
  42.867 -static struct tpm_vendor_specific tpm_xen = {
  42.868 -	.recv = tpm_xen_recv,
  42.869 -	.send = tpm_xen_send,
  42.870 -	.cancel = tpm_xen_cancel,
  42.871 -	.status = tpm_xen_status,
  42.872 -	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
  42.873 -	.req_complete_val  = STATUS_DATA_AVAIL,
  42.874 -	.req_canceled = STATUS_READY,
  42.875 -	.base = 0,
  42.876 -	.attr_group = &xen_attr_grp,
  42.877 -	.miscdev.fops = &tpm_xen_ops,
  42.878 -	.buffersize = 64 * 1024,
  42.879 +static struct xenbus_driver tpmfront = {
  42.880 +	.name = "vtpm",
  42.881 +	.owner = THIS_MODULE,
  42.882 +	.ids = tpmfront_ids,
  42.883 +	.probe = tpmfront_probe,
  42.884 +	.remove =  tpmfront_remove,
  42.885 +	.resume = tpmfront_resume,
  42.886 +	.otherend_changed = backend_changed,
  42.887 +	.suspend = tpmfront_suspend,
  42.888  };
  42.889  
  42.890 -static struct platform_device *pdev;
  42.891 +static void __init init_tpm_xenbus(void)
  42.892 +{
  42.893 +	xenbus_register_frontend(&tpmfront);
  42.894 +}
  42.895  
  42.896 -static struct tpmfe_device tpmfe = {
  42.897 -	.receive = tpm_recv,
  42.898 -	.status  = tpm_fe_status,
  42.899 +static void __exit exit_tpm_xenbus(void)
  42.900 +{
  42.901 +	xenbus_unregister_driver(&tpmfront);
  42.902 +}
  42.903 +
  42.904 +static int tpmif_allocate_tx_buffers(struct tpm_private *tp)
  42.905 +{
  42.906 +	unsigned int i;
  42.907 +
  42.908 +	for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
  42.909 +		tp->tx_buffers[i] = tx_buffer_alloc();
  42.910 +		if (!tp->tx_buffers[i]) {
  42.911 +			tpmif_free_tx_buffers(tp);
  42.912 +			return -ENOMEM;
  42.913 +		}
  42.914 +	}
  42.915 +	return 0;
  42.916 +}
  42.917 +
  42.918 +static void tpmif_free_tx_buffers(struct tpm_private *tp)
  42.919 +{
  42.920 +	unsigned int i;
  42.921 +
  42.922 +	for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
  42.923 +		tx_buffer_free(tp->tx_buffers[i]);
  42.924 +	}
  42.925 +}
  42.926 +
  42.927 +static void tpmif_rx_action(unsigned long priv)
  42.928 +{
  42.929 +	struct tpm_private *tp = (struct tpm_private *)priv;
  42.930 +
  42.931 +	int i = 0;
  42.932 +	unsigned int received;
  42.933 +	unsigned int offset = 0;
  42.934 +	u8 *buffer;
  42.935 +	tpmif_tx_request_t *tx;
  42.936 +	tx = &tp->tx->ring[i].req;
  42.937 +
  42.938 +	atomic_set(&tp->tx_busy, 0);
  42.939 +	wake_up_interruptible(&tp->wait_q);
  42.940 +
  42.941 +	received = tx->size;
  42.942 +
  42.943 +	buffer = kmalloc(received, GFP_ATOMIC);
  42.944 +	if (NULL == buffer) {
  42.945 +		goto exit;
  42.946 +	}
  42.947 +
  42.948 +	for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
  42.949 +		struct tx_buffer *txb = tp->tx_buffers[i];
  42.950 +		tpmif_tx_request_t *tx;
  42.951 +		unsigned int tocopy;
  42.952 +
  42.953 +		tx = &tp->tx->ring[i].req;
  42.954 +		tocopy = tx->size;
  42.955 +		if (tocopy > PAGE_SIZE) {
  42.956 +			tocopy = PAGE_SIZE;
  42.957 +		}
  42.958 +
  42.959 +		memcpy(&buffer[offset], txb->data, tocopy);
  42.960 +
  42.961 +		gnttab_release_grant_reference(&gref_head, tx->ref);
  42.962 +
  42.963 +		offset += tocopy;
  42.964 +	}
  42.965 +
  42.966 +	vtpm_vd_recv(buffer, received, tp->tx_remember);
  42.967 +	kfree(buffer);
  42.968 +
  42.969 +exit:
  42.970 +
  42.971 +	return;
  42.972 +}
  42.973 +
  42.974 +
  42.975 +static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
  42.976 +{
  42.977 +	struct tpm_private *tp = tpm_priv;
  42.978 +	unsigned long flags;
  42.979 +
  42.980 +	spin_lock_irqsave(&tp->tx_lock, flags);
  42.981 +	tpmif_rx_tasklet.data = (unsigned long)tp;
  42.982 +	tasklet_schedule(&tpmif_rx_tasklet);
  42.983 +	spin_unlock_irqrestore(&tp->tx_lock, flags);
  42.984 +
  42.985 +	return IRQ_HANDLED;
  42.986 +}
  42.987 +
  42.988 +
  42.989 +static int tpm_xmit(struct tpm_private *tp,
  42.990 +                    const u8 * buf, size_t count, int isuserbuffer,
  42.991 +                    void *remember)
  42.992 +{
  42.993 +	tpmif_tx_request_t *tx;
  42.994 +	TPMIF_RING_IDX i;
  42.995 +	unsigned int offset = 0;
  42.996 +
  42.997 +	spin_lock_irq(&tp->tx_lock);
  42.998 +
  42.999 +	if (unlikely(atomic_read(&tp->tx_busy))) {
 42.1000 +		printk("tpm_xmit: There's an outstanding request/response "
 42.1001 +		       "on the way!\n");
 42.1002 +		spin_unlock_irq(&tp->tx_lock);
 42.1003 +		return -EBUSY;
 42.1004 +	}
 42.1005 +
 42.1006 +	if (tp->is_connected != 1) {
 42.1007 +		spin_unlock_irq(&tp->tx_lock);
 42.1008 +		return -EIO;
 42.1009 +	}
 42.1010 +
 42.1011 +	for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
 42.1012 +		struct tx_buffer *txb = tp->tx_buffers[i];
 42.1013 +		int copied;
 42.1014 +
 42.1015 +		if (NULL == txb) {
 42.1016 +			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
 42.1017 +				"Not transmitting anything!\n", i);
 42.1018 +			spin_unlock_irq(&tp->tx_lock);
 42.1019 +			return -EFAULT;
 42.1020 +		}
 42.1021 +		copied = tx_buffer_copy(txb, &buf[offset], count,
 42.1022 +		                        isuserbuffer);
 42.1023 +		if (copied < 0) {
 42.1024 +			/* An error occurred */
 42.1025 +			spin_unlock_irq(&tp->tx_lock);
 42.1026 +			return copied;
 42.1027 +		}
 42.1028 +		count -= copied;
 42.1029 +		offset += copied;
 42.1030 +
 42.1031 +		tx = &tp->tx->ring[i].req;
 42.1032 +
 42.1033 +		tx->addr = virt_to_machine(txb->data);
 42.1034 +		tx->size = txb->len;
 42.1035 +
 42.1036 +		DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
 42.1037 +		        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
 42.1038 +
 42.1039 +		/* get the granttable reference for this page */
 42.1040 +		tx->ref = gnttab_claim_grant_reference(&gref_head);
 42.1041 +
 42.1042 +		if (-ENOSPC == tx->ref) {
 42.1043 +			spin_unlock_irq(&tp->tx_lock);
 42.1044 +			DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
 42.1045 +			return -ENOSPC;
 42.1046 +		}
 42.1047 +		gnttab_grant_foreign_access_ref( tx->ref,
 42.1048 +		                                 tp->backend_id,
 42.1049 +		                                 (tx->addr >> PAGE_SHIFT),
 42.1050 +		                                 0 /*RW*/);
 42.1051 +		wmb();
 42.1052 +	}
 42.1053 +
 42.1054 +	atomic_set(&tp->tx_busy, 1);
 42.1055 +	tp->tx_remember = remember;
 42.1056 +	mb();
 42.1057 +
 42.1058 +	DPRINTK("Notifying backend via event channel %d\n",
 42.1059 +	        tp->evtchn);
 42.1060 +
 42.1061 +	notify_remote_via_irq(tp->irq);
 42.1062 +
 42.1063 +	spin_unlock_irq(&tp->tx_lock);
 42.1064 +	return offset;
 42.1065 +}
 42.1066 +
 42.1067 +
 42.1068 +static void tpmif_notify_upperlayer(struct tpm_private *tp)
 42.1069 +{
 42.1070 +	/*
 42.1071 +	 * Notify upper layer about the state of the connection
 42.1072 +	 * to the BE.
 42.1073 +	 */
 42.1074 +	if (tp->is_connected) {
 42.1075 +		vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
 42.1076 +	} else {
 42.1077 +		vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
 42.1078 +	}
 42.1079 +}
 42.1080 +
 42.1081 +
 42.1082 +static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
 42.1083 +{
 42.1084 +	/*
 42.1085 +	 * Don't notify upper layer if we are in suspend mode and
 42.1086 +	 * should disconnect - assumption is that we will resume
 42.1087 +	 * The mutex keeps apps from sending.
 42.1088 +	 */
 42.1089 +	if (is_connected == 0 && tp->is_suspended == 1) {
 42.1090 +		return;
 42.1091 +	}
 42.1092 +
 42.1093 +	/*
 42.1094 +	 * Unlock the mutex if we are connected again
 42.1095 +	 * after being suspended - now resuming.
 42.1096 +	 * This also removes the suspend state.
 42.1097 +	 */
 42.1098 +	if (is_connected == 1 && tp->is_suspended == 1) {
 42.1099 +		tp->is_suspended = 0;
 42.1100 +		/* unlock, so apps can resume sending */
 42.1101 +		mutex_unlock(&suspend_lock);
 42.1102 +	}
 42.1103 +
 42.1104 +	if (is_connected != tp->is_connected) {
 42.1105 +		tp->is_connected = is_connected;
 42.1106 +		tpmif_notify_upperlayer(tp);
 42.1107 +	}
 42.1108 +}
 42.1109 +
 42.1110 +
 42.1111 +
 42.1112 +/* =================================================================
 42.1113 + * Initialization function.
 42.1114 + * =================================================================
 42.1115 + */
 42.1116 +
 42.1117 +struct tpm_virtual_device tvd = {
 42.1118 +	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
 42.1119  };
 42.1120  
 42.1121 -
 42.1122 -static int __init init_xen(void)
 42.1123 +static int __init tpmif_init(void)
 42.1124  {
 42.1125  	int rc;
 42.1126 +	struct tpm_private *tp;
 42.1127  
 42.1128  	if ((xen_start_info->flags & SIF_INITDOMAIN)) {
 42.1129  		return -EPERM;
 42.1130  	}
 42.1131 -	/*
 42.1132 -	 * Register device with the low lever front-end
 42.1133 -	 * driver
 42.1134 -	 */
 42.1135 -	if ((rc = tpm_fe_register_receiver(&tpmfe)) < 0) {
 42.1136 -		goto err_exit;
 42.1137 -	}
 42.1138  
 42.1139 -	/*
 42.1140 -	 * Register our device with the system.
 42.1141 -	 */
 42.1142 -	pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
 42.1143 -	if (IS_ERR(pdev)) {
 42.1144 -		rc = PTR_ERR(pdev);
 42.1145 -		goto err_unreg_fe;
 42.1146 +	tp = tpm_private_get();
 42.1147 +	if (!tp) {
 42.1148 +		rc = -ENOMEM;
 42.1149 +		goto failexit;
 42.1150  	}
 42.1151  
 42.1152 -	tpm_xen.buffersize = tpmfe.max_tx_size;
 42.1153 +	tvd.tpm_private = tp;
 42.1154 +	rc = init_vtpm(&tvd);
 42.1155 +	if (rc)
 42.1156 +		goto init_vtpm_failed;
 42.1157  
 42.1158 -	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_xen)) < 0) {
 42.1159 -		goto err_unreg_pdev;
 42.1160 +	IPRINTK("Initialising the vTPM driver.\n");
 42.1161 +	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
 42.1162 +	                                     &gref_head ) < 0) {
 42.1163 +		rc = -EFAULT;
 42.1164 +		goto gnttab_alloc_failed;
 42.1165  	}
 42.1166  
 42.1167 -	dataex.current_request = NULL;
 42.1168 -	spin_lock_init(&dataex.req_list_lock);
 42.1169 -	init_waitqueue_head(&dataex.req_wait_queue);
 42.1170 -	INIT_LIST_HEAD(&dataex.queued_requests);
 42.1171 -
 42.1172 -	dataex.current_response = NULL;
 42.1173 -	spin_lock_init(&dataex.resp_list_lock);
 42.1174 -	init_waitqueue_head(&dataex.resp_wait_queue);
 42.1175 -
 42.1176 -	disconnect_time = jiffies;
 42.1177 -
 42.1178 +	init_tpm_xenbus();
 42.1179  	return 0;
 42.1180  
 42.1181 +gnttab_alloc_failed:
 42.1182 +	cleanup_vtpm();
 42.1183 +init_vtpm_failed:
 42.1184 +	tpm_private_put();
 42.1185 +failexit:
 42.1186  
 42.1187 -err_unreg_pdev:
 42.1188 -	platform_device_unregister(pdev);
 42.1189 -err_unreg_fe:
 42.1190 -	tpm_fe_unregister_receiver();
 42.1191 -
 42.1192 -err_exit:
 42.1193  	return rc;
 42.1194  }
 42.1195  
 42.1196 -static void __exit cleanup_xen(void)
 42.1197 +
 42.1198 +static void __exit tpmif_exit(void)
 42.1199  {
 42.1200 -	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
 42.1201 -	if (chip) {
 42.1202 -		tpm_remove_hardware(chip->dev);
 42.1203 -		platform_device_unregister(pdev);
 42.1204 -		tpm_fe_unregister_receiver();
 42.1205 -	}
 42.1206 +	cleanup_vtpm();
 42.1207 +	tpm_private_put();
 42.1208 +	exit_tpm_xenbus();
 42.1209 +	gnttab_free_grant_references(gref_head);
 42.1210  }
 42.1211  
 42.1212 -module_init(init_xen);
 42.1213 -module_exit(cleanup_xen);
 42.1214 +module_init(tpmif_init);
 42.1215 +module_exit(tpmif_exit);
 42.1216  
 42.1217 -MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
 42.1218 -MODULE_DESCRIPTION("TPM Driver for XEN (shared memory)");
 42.1219 -MODULE_VERSION("1.0");
 42.1220 -MODULE_LICENSE("GPL");
 42.1221 +MODULE_LICENSE("Dual BSD/GPL");
 42.1222 +
 42.1223 +/*
 42.1224 + * Local variables:
 42.1225 + *  c-file-style: "linux"
 42.1226 + *  indent-tabs-mode: t
 42.1227 + *  c-indent-level: 8
 42.1228 + *  c-basic-offset: 8
 42.1229 + *  tab-width: 8
 42.1230 + * End:
 42.1231 + */
    43.1 --- a/linux-2.6-xen-sparse/drivers/char/tty_io.c	Mon May 08 13:41:18 2006 -0600
    43.2 +++ b/linux-2.6-xen-sparse/drivers/char/tty_io.c	Mon May 08 14:46:11 2006 -0600
    43.3 @@ -2708,7 +2708,11 @@ static void __do_SAK(void *arg)
    43.4  		}
    43.5  		task_lock(p);
    43.6  		if (p->files) {
    43.7 -			rcu_read_lock();
    43.8 +			/*
    43.9 +			 * We don't take a ref to the file, so we must
   43.10 +			 * hold ->file_lock instead.
   43.11 +			 */
   43.12 +			spin_lock(&p->files->file_lock);
   43.13  			fdt = files_fdtable(p->files);
   43.14  			for (i=0; i < fdt->max_fds; i++) {
   43.15  				filp = fcheck_files(p->files, i);
   43.16 @@ -2723,7 +2727,7 @@ static void __do_SAK(void *arg)
   43.17  					break;
   43.18  				}
   43.19  			}
   43.20 -			rcu_read_unlock();
   43.21 +			spin_unlock(&p->files->file_lock);
   43.22  		}
   43.23  		task_unlock(p);
   43.24  	} while_each_task_pid(session, PIDTYPE_SID, p);
    44.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig	Mon May 08 13:41:18 2006 -0600
    44.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig	Mon May 08 14:46:11 2006 -0600
    44.3 @@ -13,7 +13,7 @@ config XEN
    44.4  if XEN
    44.5  config XEN_INTERFACE_VERSION
    44.6  	hex
    44.7 -	default 0x00030101
    44.8 +	default 0x00030202
    44.9  
   44.10  menu "XEN"
   44.11  
   44.12 @@ -99,7 +99,7 @@ config XEN_BLKDEV_TAP_BE
   44.13  
   44.14  config XEN_NETDEV_BACKEND
   44.15  	tristate "Network-device backend driver"
   44.16 -        depends on XEN_BACKEND
   44.17 +        depends on XEN_BACKEND && NET
   44.18  	default y
   44.19  	help
   44.20  	  The network-device backend driver allows the kernel to export its
   44.21 @@ -155,7 +155,7 @@ config XEN_BLKDEV_FRONTEND
   44.22  
   44.23  config XEN_NETDEV_FRONTEND
   44.24  	tristate "Network-device frontend driver"
   44.25 -	depends on XEN
   44.26 +	depends on XEN && NET
   44.27  	default y
   44.28  	help
   44.29  	  The network-device frontend driver allows the kernel to access
   44.30 @@ -173,14 +173,6 @@ config XEN_BLKDEV_TAP
   44.31  	  to a character device, allowing device prototyping in application
   44.32  	  space.  Odds are that you want to say N here.
   44.33  
   44.34 -config XEN_TPMDEV_FRONTEND
   44.35 -	tristate "TPM-device frontend driver"
   44.36 -	default n
   44.37 -	select TCG_TPM
   44.38 -	select TCG_XEN
   44.39 -	help
   44.40 -	  The TPM-device frontend driver.
   44.41 -
   44.42  config XEN_SCRUB_PAGES
   44.43  	bool "Scrub memory before freeing it to Xen"
   44.44  	default y
    45.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Mon May 08 13:41:18 2006 -0600
    45.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Mon May 08 14:46:11 2006 -0600
    45.3 @@ -16,7 +16,6 @@ obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmb
    45.4  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
    45.5  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
    45.6  obj-$(CONFIG_XEN_BLKDEV_TAP)    	+= blktap/
    45.7 -obj-$(CONFIG_XEN_TPMDEV_FRONTEND)	+= tpmfront/
    45.8  obj-$(CONFIG_XEN_PCIDEV_BACKEND)	+= pciback/
    45.9  obj-$(CONFIG_XEN_PCIDEV_FRONTEND)	+= pcifront/
   45.10  
    46.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Mon May 08 13:41:18 2006 -0600
    46.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Mon May 08 14:46:11 2006 -0600
    46.3 @@ -94,8 +94,8 @@ static void balloon_process(void *unused
    46.4  static DECLARE_WORK(balloon_worker, balloon_process, NULL);
    46.5  static struct timer_list balloon_timer;
    46.6  
    46.7 -#define PAGE_TO_LIST(p) (&(p)->ballooned)
    46.8 -#define LIST_TO_PAGE(l) list_entry((l), struct page, ballooned)
    46.9 +#define PAGE_TO_LIST(p) (&(p)->lru)
   46.10 +#define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
   46.11  #define UNLIST_PAGE(p)				\
   46.12  	do {					\
   46.13  		list_del(PAGE_TO_LIST(p));	\
   46.14 @@ -195,14 +195,14 @@ static int increase_reservation(unsigned
   46.15  		page = balloon_next_page(page);
   46.16  	}
   46.17  
   46.18 -	reservation.extent_start = frame_list;
   46.19 +	set_xen_guest_handle(reservation.extent_start, frame_list);
   46.20  	reservation.nr_extents   = nr_pages;
   46.21  	rc = HYPERVISOR_memory_op(
   46.22  		XENMEM_populate_physmap, &reservation);
   46.23  	if (rc < nr_pages) {
   46.24  		int ret;
   46.25  		/* We hit the Xen hard limit: reprobe. */
   46.26 -		reservation.extent_start = frame_list;
   46.27 +		set_xen_guest_handle(reservation.extent_start, frame_list);
   46.28  		reservation.nr_extents   = rc;
   46.29  		ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
   46.30  				&reservation);
   46.31 @@ -216,7 +216,8 @@ static int increase_reservation(unsigned
   46.32  		BUG_ON(page == NULL);
   46.33  
   46.34  		pfn = page_to_pfn(page);
   46.35 -		BUG_ON(phys_to_machine_mapping_valid(pfn));
   46.36 +		BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
   46.37 +		       phys_to_machine_mapping_valid(pfn));
   46.38  
   46.39  		/* Update P->M and M->P tables. */
   46.40  		set_phys_to_machine(pfn, frame_list[i]);
   46.41 @@ -308,7 +309,7 @@ static int decrease_reservation(unsigned
   46.42  		balloon_append(pfn_to_page(pfn));
   46.43  	}
   46.44  
   46.45 -	reservation.extent_start = frame_list;
   46.46 +	set_xen_guest_handle(reservation.extent_start, frame_list);
   46.47  	reservation.nr_extents   = nr_pages;
   46.48  	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
   46.49  	BUG_ON(ret != nr_pages);
   46.50 @@ -522,11 +523,11 @@ static int dealloc_pte_fn(
   46.51  	unsigned long mfn = pte_mfn(*pte);
   46.52  	int ret;
   46.53  	struct xen_memory_reservation reservation = {
   46.54 -		.extent_start = &mfn,
   46.55  		.nr_extents   = 1,
   46.56  		.extent_order = 0,
   46.57  		.domid        = DOMID_SELF
   46.58  	};
   46.59 +	set_xen_guest_handle(reservation.extent_start, &mfn);
   46.60  	set_pte_at(&init_mm, addr, pte, __pte_ma(0));
   46.61  	set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
   46.62  	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
   46.63 @@ -539,6 +540,8 @@ struct page *balloon_alloc_empty_page_ra
   46.64  	unsigned long vstart, flags;
   46.65  	unsigned int  order = get_order(nr_pages * PAGE_SIZE);
   46.66  	int ret;
   46.67 +	unsigned long i;
   46.68 +	struct page *page;
   46.69  
   46.70  	vstart = __get_free_pages(GFP_KERNEL, order);
   46.71  	if (vstart == 0)
   46.72 @@ -547,9 +550,22 @@ struct page *balloon_alloc_empty_page_ra
   46.73  	scrub_pages(vstart, 1 << order);
   46.74  
   46.75  	balloon_lock(flags);
   46.76 -	ret = apply_to_page_range(&init_mm, vstart,
   46.77 -				  PAGE_SIZE << order, dealloc_pte_fn, NULL);
   46.78 -	BUG_ON(ret);
   46.79 +	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   46.80 +		unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT;
   46.81 +		struct xen_memory_reservation reservation = {
   46.82 +			.nr_extents   = 1,
   46.83 +			.extent_order = order,
   46.84 +			.domid        = DOMID_SELF
   46.85 +		};
   46.86 +		set_xen_guest_handle(reservation.extent_start, &gmfn);
   46.87 +		ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
   46.88 +					   &reservation);
   46.89 +		BUG_ON(ret != 1);
   46.90 +	} else {
   46.91 +		ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
   46.92 +					  dealloc_pte_fn, NULL);
   46.93 +		BUG_ON(ret);
   46.94 +	}
   46.95  	current_pages -= 1UL << order;
   46.96  	totalram_pages = current_pages;
   46.97  	balloon_unlock(flags);
   46.98 @@ -558,7 +574,12 @@ struct page *balloon_alloc_empty_page_ra
   46.99  
  46.100  	flush_tlb_all();
  46.101  
  46.102 -	return virt_to_page(vstart);
  46.103 +	page = virt_to_page(vstart);
  46.104 +
  46.105 +	for (i = 0; i < (1UL << order); i++)
  46.106 +		set_page_count(page + i, 1);
  46.107 +
  46.108 +	return page;
  46.109  }
  46.110  
  46.111  void balloon_dealloc_empty_page_range(
  46.112 @@ -568,8 +589,10 @@ void balloon_dealloc_empty_page_range(
  46.113  	unsigned int  order = get_order(nr_pages * PAGE_SIZE);
  46.114  
  46.115  	balloon_lock(flags);
  46.116 -	for (i = 0; i < (1UL << order); i++)
  46.117 +	for (i = 0; i < (1UL << order); i++) {
  46.118 +		BUG_ON(page_count(page + i) != 1);
  46.119  		balloon_append(page + i);
  46.120 +	}
  46.121  	balloon_unlock(flags);
  46.122  
  46.123  	schedule_work(&balloon_worker);
    47.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Mon May 08 13:41:18 2006 -0600
    47.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Mon May 08 14:46:11 2006 -0600
    47.3 @@ -410,7 +410,7 @@ static void dispatch_rw_block_io(blkif_t
    47.4  		}
    47.5  
    47.6  		pending_handle(pending_req, i) = map[i].handle;
    47.7 -#ifdef __ia64__
    47.8 +#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
    47.9  		pending_vaddrs[vaddr_pagenr(pending_req, i)] =
   47.10  			(unsigned long)gnttab_map_vaddr(map[i]);
   47.11  #else
   47.12 @@ -546,7 +546,7 @@ static int __init blkif_init(void)
   47.13  
   47.14  	blkif_interface_init();
   47.15  	
   47.16 -#ifdef __ia64__
   47.17 +#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
   47.18  	extern unsigned long alloc_empty_foreign_map_page_range(
   47.19  		unsigned long pages);
   47.20  	mmap_vstart = (unsigned long)
    48.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Mon May 08 13:41:18 2006 -0600
    48.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Mon May 08 14:46:11 2006 -0600
    48.3 @@ -74,7 +74,7 @@ static int map_frontend_page(blkif_t *bl
    48.4  	blkif->shmem_ref = shared_page;
    48.5  	blkif->shmem_handle = op.handle;
    48.6  
    48.7 -#ifdef __ia64__
    48.8 +#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
    48.9  	/* on some arch's, map_grant_ref behaves like mmap, in that the
   48.10  	 * passed address is a hint and a different address may be returned */
   48.11  	blkif->blk_ring_area->addr = gnttab_map_vaddr(op);
   48.12 @@ -101,10 +101,7 @@ int blkif_map(blkif_t *blkif, unsigned l
   48.13  {
   48.14  	blkif_sring_t *sring;
   48.15  	int err;
   48.16 -	evtchn_op_t op = {
   48.17 -		.cmd = EVTCHNOP_bind_interdomain,
   48.18 -		.u.bind_interdomain.remote_dom = blkif->domid,
   48.19 -		.u.bind_interdomain.remote_port = evtchn };
   48.20 +	struct evtchn_bind_interdomain bind_interdomain;
   48.21  
   48.22  	/* Already connected through? */
   48.23  	if (blkif->irq)
   48.24 @@ -119,14 +116,18 @@ int blkif_map(blkif_t *blkif, unsigned l
   48.25  		return err;
   48.26  	}
   48.27  
   48.28 -	err = HYPERVISOR_event_channel_op(&op);
   48.29 +	bind_interdomain.remote_dom  = blkif->domid;
   48.30 +	bind_interdomain.remote_port = evtchn;
   48.31 +
   48.32 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   48.33 +					  &bind_interdomain);
   48.34  	if (err) {
   48.35  		unmap_frontend_page(blkif);
   48.36  		free_vm_area(blkif->blk_ring_area);
   48.37  		return err;
   48.38  	}
   48.39  
   48.40 -	blkif->evtchn = op.u.bind_interdomain.local_port;
   48.41 +	blkif->evtchn = bind_interdomain.local_port;
   48.42  
   48.43  	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
   48.44  	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    49.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Mon May 08 13:41:18 2006 -0600
    49.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Mon May 08 14:46:11 2006 -0600
    49.3 @@ -70,10 +70,7 @@ int blkif_map(blkif_t *blkif, unsigned l
    49.4  {
    49.5  	blkif_sring_t *sring;
    49.6  	int err;
    49.7 -	evtchn_op_t op = {
    49.8 -		.cmd = EVTCHNOP_bind_interdomain,
    49.9 -		.u.bind_interdomain.remote_dom  = blkif->domid,
   49.10 -		.u.bind_interdomain.remote_port = evtchn };
   49.11 +	struct evtchn_bind_interdomain bind_interdomain;
   49.12  
   49.13  	if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
   49.14  		return -ENOMEM;
   49.15 @@ -84,14 +81,18 @@ int blkif_map(blkif_t *blkif, unsigned l
   49.16  		return err;
   49.17  	}
   49.18  
   49.19 -	err = HYPERVISOR_event_channel_op(&op);
   49.20 +	bind_interdomain.remote_dom  = blkif->domid;
   49.21 +	bind_interdomain.remote_port = evtchn;
   49.22 +
   49.23 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   49.24 +					  &bind_interdomain);
   49.25  	if (err) {
   49.26  		unmap_frontend_page(blkif);
   49.27  		free_vm_area(blkif->blk_ring_area);
   49.28  		return err;
   49.29  	}
   49.30  
   49.31 -	blkif->evtchn = op.u.bind_interdomain.local_port;
   49.32 +	blkif->evtchn = bind_interdomain.local_port;
   49.33  
   49.34  	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
   49.35  	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    50.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Mon May 08 13:41:18 2006 -0600
    50.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Mon May 08 14:46:11 2006 -0600
    50.3 @@ -103,7 +103,7 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS])
    50.4  static int irq_bindcount[NR_IRQS];
    50.5  
    50.6  /* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
    50.7 -static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
    50.8 +static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)];
    50.9  
   50.10  #ifdef CONFIG_SMP
   50.11  
   50.12 @@ -226,7 +226,8 @@ static int find_unbound_irq(void)
   50.13  {
   50.14  	int irq;
   50.15  
   50.16 -	for (irq = 0; irq < NR_IRQS; irq++)
   50.17 +	/* Only allocate from dynirq range */
   50.18 +	for (irq = DYNIRQ_BASE; irq < NR_IRQS; irq++)
   50.19  		if (irq_bindcount[irq] == 0)
   50.20  			break;
   50.21  
   50.22 @@ -257,16 +258,18 @@ static int bind_evtchn_to_irq(unsigned i
   50.23  
   50.24  static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
   50.25  {
   50.26 -	evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
   50.27 +	struct evtchn_bind_virq bind_virq;
   50.28  	int evtchn, irq;
   50.29  
   50.30  	spin_lock(&irq_mapping_update_lock);
   50.31  
   50.32  	if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
   50.33 -		op.u.bind_virq.virq = virq;
   50.34 -		op.u.bind_virq.vcpu = cpu;
   50.35 -		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
   50.36 -		evtchn = op.u.bind_virq.port;
   50.37 +		bind_virq.virq = virq;
   50.38 +		bind_virq.vcpu = cpu;
   50.39 +		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
   50.40 +						&bind_virq) != 0)
   50.41 +			BUG();
   50.42 +		evtchn = bind_virq.port;
   50.43  
   50.44  		irq = find_unbound_irq();
   50.45  		evtchn_to_irq[evtchn] = irq;
   50.46 @@ -286,15 +289,17 @@ static int bind_virq_to_irq(unsigned int
   50.47  
   50.48  static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
   50.49  {
   50.50 -	evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
   50.51 +	struct evtchn_bind_ipi bind_ipi;
   50.52  	int evtchn, irq;
   50.53  
   50.54  	spin_lock(&irq_mapping_update_lock);
   50.55  
   50.56  	if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
   50.57 -		op.u.bind_ipi.vcpu = cpu;
   50.58 -		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
   50.59 -		evtchn = op.u.bind_ipi.port;
   50.60 +		bind_ipi.vcpu = cpu;
   50.61 +		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
   50.62 +						&bind_ipi) != 0)
   50.63 +			BUG();
   50.64 +		evtchn = bind_ipi.port;
   50.65  
   50.66  		irq = find_unbound_irq();
   50.67  		evtchn_to_irq[evtchn] = irq;
   50.68 @@ -314,14 +319,15 @@ static int bind_ipi_to_irq(unsigned int 
   50.69  
   50.70  static void unbind_from_irq(unsigned int irq)
   50.71  {
   50.72 -	evtchn_op_t op = { .cmd = EVTCHNOP_close };
   50.73 +	struct evtchn_close close;
   50.74  	int evtchn = evtchn_from_irq(irq);
   50.75  
   50.76  	spin_lock(&irq_mapping_update_lock);
   50.77  
   50.78  	if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
   50.79 -		op.u.close.port = evtchn;
   50.80 -		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
   50.81 +		close.port = evtchn;
   50.82 +		if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
   50.83 +			BUG();
   50.84  
   50.85  		switch (type_from_irq(irq)) {
   50.86  		case IRQT_VIRQ:
   50.87 @@ -427,7 +433,7 @@ static void do_nothing_function(void *ig
   50.88  /* Rebind an evtchn so that it gets delivered to a specific cpu */
   50.89  static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
   50.90  {
   50.91 -	evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu };
   50.92 +	struct evtchn_bind_vcpu bind_vcpu;
   50.93  	int evtchn;
   50.94  
   50.95  	spin_lock(&irq_mapping_update_lock);
   50.96 @@ -439,15 +445,15 @@ static void rebind_irq_to_cpu(unsigned i
   50.97  	}
   50.98  
   50.99  	/* Send future instances of this interrupt to other vcpu. */
  50.100 -	op.u.bind_vcpu.port = evtchn;
  50.101 -	op.u.bind_vcpu.vcpu = tcpu;
  50.102 +	bind_vcpu.port = evtchn;
  50.103 +	bind_vcpu.vcpu = tcpu;
  50.104  
  50.105  	/*
  50.106  	 * If this fails, it usually just indicates that we're dealing with a 
  50.107  	 * virq or IPI channel, which don't actually need to be rebound. Ignore
  50.108  	 * it, but don't do the xenlinux-level rebind in that case.
  50.109  	 */
  50.110 -	if (HYPERVISOR_event_channel_op(&op) >= 0)
  50.111 +	if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
  50.112  		bind_evtchn_to_cpu(evtchn, tcpu);
  50.113  
  50.114  	spin_unlock(&irq_mapping_update_lock);
  50.115 @@ -543,22 +549,19 @@ static struct hw_interrupt_type dynirq_t
  50.116  
  50.117  static inline void pirq_unmask_notify(int pirq)
  50.118  {
  50.119 -	physdev_op_t op;
  50.120 -	if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
  50.121 -		op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
  50.122 -		(void)HYPERVISOR_physdev_op(&op);
  50.123 -	}
  50.124 +	struct physdev_eoi eoi = { .irq = pirq };
  50.125 +	if (unlikely(test_bit(pirq, &pirq_needs_eoi[0])))
  50.126 +		(void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
  50.127  }
  50.128  
  50.129  static inline void pirq_query_unmask(int pirq)
  50.130  {
  50.131 -	physdev_op_t op;
  50.132 -	op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
  50.133 -	op.u.irq_status_query.irq = pirq;
  50.134 -	(void)HYPERVISOR_physdev_op(&op);
  50.135 -	clear_bit(pirq, &pirq_needs_unmask_notify[0]);
  50.136 -	if (op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
  50.137 -		set_bit(pirq, &pirq_needs_unmask_notify[0]);
  50.138 +	struct physdev_irq_status_query irq_status;
  50.139 +	irq_status.irq = pirq;
  50.140 +	(void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
  50.141 +	clear_bit(pirq, &pirq_needs_eoi[0]);
  50.142 +	if (irq_status.flags & XENIRQSTAT_needs_eoi)
  50.143 +		set_bit(pirq, &pirq_needs_eoi[0]);
  50.144  }
  50.145  
  50.146  /*
  50.147 @@ -569,22 +572,22 @@ static inline void pirq_query_unmask(int
  50.148  
  50.149  static unsigned int startup_pirq(unsigned int irq)
  50.150  {
  50.151 -	evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
  50.152 +	struct evtchn_bind_pirq bind_pirq;
  50.153  	int evtchn = evtchn_from_irq(irq);
  50.154  
  50.155  	if (VALID_EVTCHN(evtchn))
  50.156  		goto out;
  50.157  
  50.158 -	op.u.bind_pirq.pirq  = irq;
  50.159 +	bind_pirq.pirq  = irq;
  50.160  	/* NB. We are happy to share unless we are probing. */
  50.161 -	op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
  50.162 -	if (HYPERVISOR_event_channel_op(&op) != 0) {
  50.163 +	bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
  50.164 +	if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
  50.165  		if (!probing_irq(irq))
  50.166  			printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
  50.167  			       irq);
  50.168  		return 0;
  50.169  	}
  50.170 -	evtchn = op.u.bind_pirq.port;
  50.171 +	evtchn = bind_pirq.port;
  50.172  
  50.173  	pirq_query_unmask(irq_to_pirq(irq));
  50.174  
  50.175 @@ -601,7 +604,7 @@ static unsigned int startup_pirq(unsigne
  50.176  
  50.177  static void shutdown_pirq(unsigned int irq)
  50.178  {
  50.179 -	evtchn_op_t op = { .cmd = EVTCHNOP_close };
  50.180 +	struct evtchn_close close;
  50.181  	int evtchn = evtchn_from_irq(irq);
  50.182  
  50.183  	if (!VALID_EVTCHN(evtchn))
  50.184 @@ -609,8 +612,9 @@ static void shutdown_pirq(unsigned int i
  50.185  
  50.186  	mask_evtchn(evtchn);
  50.187  
  50.188 -	op.u.close.port = evtchn;
  50.189 -	BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
  50.190 +	close.port = evtchn;
  50.191 +	if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
  50.192 +		BUG();
  50.193  
  50.194  	bind_evtchn_to_cpu(evtchn, 0);
  50.195  	evtchn_to_irq[evtchn] = -1;
  50.196 @@ -702,9 +706,8 @@ void unmask_evtchn(int port)
  50.197  
  50.198  	/* Slow path (hypercall) if this is a non-local port. */
  50.199  	if (unlikely(cpu != cpu_from_evtchn(port))) {
  50.200 -		evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
  50.201 -				   .u.unmask.port = port };
  50.202 -		(void)HYPERVISOR_event_channel_op(&op);
  50.203 +		struct evtchn_unmask unmask = { .port = port };
  50.204 +		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
  50.205  		return;
  50.206  	}
  50.207  
  50.208 @@ -727,8 +730,9 @@ EXPORT_SYMBOL_GPL(unmask_evtchn);
  50.209  
  50.210  void irq_resume(void)
  50.211  {
  50.212 -	evtchn_op_t op;
  50.213 -	int         cpu, pirq, virq, ipi, irq, evtchn;
  50.214 +	struct evtchn_bind_virq bind_virq;
  50.215 +	struct evtchn_bind_ipi  bind_ipi;
  50.216 +	int cpu, pirq, virq, ipi, irq, evtchn;
  50.217  
  50.218  	init_evtchn_cpu_bindings();
  50.219  
  50.220 @@ -762,12 +766,12 @@ void irq_resume(void)
  50.221  		BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
  50.222  
  50.223  		/* Get a new binding from Xen. */
  50.224 -		memset(&op, 0, sizeof(op));
  50.225 -		op.cmd              = EVTCHNOP_bind_virq;
  50.226 -		op.u.bind_virq.virq = virq;
  50.227 -		op.u.bind_virq.vcpu = 0;
  50.228 -		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
  50.229 -		evtchn = op.u.bind_virq.port;
  50.230 +		bind_virq.virq = virq;
  50.231 +		bind_virq.vcpu = 0;
  50.232 +		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
  50.233 +						&bind_virq) != 0)
  50.234 +			BUG();
  50.235 +		evtchn = bind_virq.port;
  50.236  
  50.237  		/* Record the new mapping. */
  50.238  		evtchn_to_irq[evtchn] = irq;
  50.239 @@ -785,11 +789,11 @@ void irq_resume(void)
  50.240  		BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
  50.241  
  50.242  		/* Get a new binding from Xen. */
  50.243 -		memset(&op, 0, sizeof(op));
  50.244 -		op.cmd = EVTCHNOP_bind_ipi;
  50.245 -		op.u.bind_ipi.vcpu = 0;
  50.246 -		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
  50.247 -		evtchn = op.u.bind_ipi.port;
  50.248 +		bind_ipi.vcpu = 0;
  50.249 +		if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
  50.250 +						&bind_ipi) != 0)
  50.251 +			BUG();
  50.252 +		evtchn = bind_ipi.port;
  50.253  
  50.254  		/* Record the new mapping. */
  50.255  		evtchn_to_irq[evtchn] = irq;
    51.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Mon May 08 13:41:18 2006 -0600
    51.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Mon May 08 14:46:11 2006 -0600
    51.3 @@ -399,7 +399,7 @@ gnttab_resume(void)
    51.4  
    51.5  	setup.dom        = DOMID_SELF;
    51.6  	setup.nr_frames  = NR_GRANT_FRAMES;
    51.7 -	setup.frame_list = frames;
    51.8 +	set_xen_guest_handle(setup.frame_list, frames);
    51.9  
   51.10  	rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
   51.11  	if (rc == -ENOSYS)
    52.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Mon May 08 13:41:18 2006 -0600
    52.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Mon May 08 14:46:11 2006 -0600
    52.3 @@ -206,68 +206,71 @@ static int evtchn_ioctl(struct inode *in
    52.4  	int rc;
    52.5  	struct per_user_data *u = file->private_data;
    52.6  	void __user *uarg = (void __user *) arg;
    52.7 -	evtchn_op_t op = { 0 };
    52.8  
    52.9  	switch (cmd) {
   52.10  	case IOCTL_EVTCHN_BIND_VIRQ: {
   52.11  		struct ioctl_evtchn_bind_virq bind;
   52.12 +		struct evtchn_bind_virq bind_virq;
   52.13  
   52.14  		rc = -EFAULT;
   52.15  		if (copy_from_user(&bind, uarg, sizeof(bind)))
   52.16  			break;
   52.17  
   52.18 -		op.cmd = EVTCHNOP_bind_virq;
   52.19 -		op.u.bind_virq.virq = bind.virq;
   52.20 -		op.u.bind_virq.vcpu = 0;
   52.21 -		rc = HYPERVISOR_event_channel_op(&op);
   52.22 +		bind_virq.virq = bind.virq;
   52.23 +		bind_virq.vcpu = 0;
   52.24 +		rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
   52.25 +						 &bind_virq);
   52.26  		if (rc != 0)
   52.27  			break;
   52.28  
   52.29 -		rc = op.u.bind_virq.port;
   52.30 +		rc = bind_virq.port;
   52.31  		evtchn_bind_to_user(u, rc);
   52.32  		break;
   52.33  	}
   52.34  
   52.35  	case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
   52.36  		struct ioctl_evtchn_bind_interdomain bind;
   52.37 +		struct evtchn_bind_interdomain bind_interdomain;
   52.38  
   52.39  		rc = -EFAULT;
   52.40  		if (copy_from_user(&bind, uarg, sizeof(bind)))
   52.41  			break;
   52.42  
   52.43 -		op.cmd = EVTCHNOP_bind_interdomain;
   52.44 -		op.u.bind_interdomain.remote_dom  = bind.remote_domain;
   52.45 -		op.u.bind_interdomain.remote_port = bind.remote_port;
   52.46 -		rc = HYPERVISOR_event_channel_op(&op);
   52.47 +		bind_interdomain.remote_dom  = bind.remote_domain;
   52.48 +		bind_interdomain.remote_port = bind.remote_port;
   52.49 +		rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   52.50 +						 &bind_interdomain);
   52.51  		if (rc != 0)
   52.52  			break;
   52.53  
   52.54 -		rc = op.u.bind_interdomain.local_port;
   52.55 +		rc = bind_interdomain.local_port;
   52.56  		evtchn_bind_to_user(u, rc);
   52.57  		break;
   52.58  	}
   52.59  
   52.60  	case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
   52.61  		struct ioctl_evtchn_bind_unbound_port bind;
   52.62 +		struct evtchn_alloc_unbound alloc_unbound;
   52.63  
   52.64  		rc = -EFAULT;
   52.65  		if (copy_from_user(&bind, uarg, sizeof(bind)))
   52.66  			break;
   52.67  
   52.68 -		op.cmd = EVTCHNOP_alloc_unbound;
   52.69 -		op.u.alloc_unbound.dom        = DOMID_SELF;
   52.70 -		op.u.alloc_unbound.remote_dom = bind.remote_domain;
   52.71 -		rc = HYPERVISOR_event_channel_op(&op);
   52.72 +		alloc_unbound.dom        = DOMID_SELF;
   52.73 +		alloc_unbound.remote_dom = bind.remote_domain;
   52.74 +		rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
   52.75 +						 &alloc_unbound);
   52.76  		if (rc != 0)
   52.77  			break;
   52.78  
   52.79 -		rc = op.u.alloc_unbound.port;
   52.80 +		rc = alloc_unbound.port;
   52.81  		evtchn_bind_to_user(u, rc);
   52.82  		break;
   52.83  	}
   52.84  
   52.85  	case IOCTL_EVTCHN_UNBIND: {
   52.86  		struct ioctl_evtchn_unbind unbind;
   52.87 +		struct evtchn_close close;
   52.88  		int ret;
   52.89  
   52.90  		rc = -EFAULT;
   52.91 @@ -291,9 +294,8 @@ static int evtchn_ioctl(struct inode *in
   52.92  
   52.93  		spin_unlock_irq(&port_user_lock);
   52.94  
   52.95 -		op.cmd = EVTCHNOP_close;
   52.96 -		op.u.close.port = unbind.port;
   52.97 -		ret = HYPERVISOR_event_channel_op(&op);
   52.98 +		close.port = unbind.port;
   52.99 +		ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
  52.100  		BUG_ON(ret);
  52.101  
  52.102  		rc = 0;
  52.103 @@ -379,7 +381,7 @@ static int evtchn_release(struct inode *
  52.104  {
  52.105  	int i;
  52.106  	struct per_user_data *u = filp->private_data;
  52.107 -	evtchn_op_t op = { 0 };
  52.108 +	struct evtchn_close close;
  52.109  
  52.110  	spin_lock_irq(&port_user_lock);
  52.111  
  52.112 @@ -393,9 +395,8 @@ static int evtchn_release(struct inode *
  52.113  		port_user[i] = NULL;
  52.114  		mask_evtchn(i);
  52.115  
  52.116 -		op.cmd = EVTCHNOP_close;
  52.117 -		op.u.close.port = i;
  52.118 -		ret = HYPERVISOR_event_channel_op(&op);
  52.119 +		close.port = i;
  52.120 +		ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
  52.121  		BUG_ON(ret);
  52.122  	}
  52.123  
    53.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Mon May 08 13:41:18 2006 -0600
    53.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Mon May 08 14:46:11 2006 -0600
    53.3 @@ -213,10 +213,7 @@ int netif_map(netif_t *netif, unsigned l
    53.4  	int err = -ENOMEM;
    53.5  	netif_tx_sring_t *txs;
    53.6  	netif_rx_sring_t *rxs;
    53.7 -	evtchn_op_t op = {
    53.8 -		.cmd = EVTCHNOP_bind_interdomain,
    53.9 -		.u.bind_interdomain.remote_dom = netif->domid,
   53.10 -		.u.bind_interdomain.remote_port = evtchn };
   53.11 +	struct evtchn_bind_interdomain bind_interdomain;
   53.12  
   53.13  	/* Already connected through? */
   53.14  	if (netif->irq)
   53.15 @@ -233,11 +230,15 @@ int netif_map(netif_t *netif, unsigned l
   53.16  	if (err)
   53.17  		goto err_map;
   53.18  
   53.19 -	err = HYPERVISOR_event_channel_op(&op);
   53.20 +	bind_interdomain.remote_dom = netif->domid;
   53.21 +	bind_interdomain.remote_port = evtchn;
   53.22 +
   53.23 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   53.24 +					  &bind_interdomain);
   53.25  	if (err)
   53.26  		goto err_hypervisor;
   53.27  
   53.28 -	netif->evtchn = op.u.bind_interdomain.local_port;
   53.29 +	netif->evtchn = bind_interdomain.local_port;
   53.30  
   53.31  	netif->irq = bind_evtchn_to_irqhandler(
   53.32  		netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
    54.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Mon May 08 13:41:18 2006 -0600
    54.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Mon May 08 14:46:11 2006 -0600
    54.3 @@ -127,6 +127,14 @@ static struct ethtool_ops network_ethtoo
    54.4  	.set_tx_csum = ethtool_op_set_tx_csum,
    54.5  };
    54.6  
    54.7 +/*
    54.8 + * Nothing to do here. Virtual interface is point-to-point and the
    54.9 + * physical interface is probably promiscuous anyway.
   54.10 + */
   54.11 +static void loopback_set_multicast_list(struct net_device *dev)
   54.12 +{
   54.13 +}
   54.14 +
   54.15  static void loopback_construct(struct net_device *dev, struct net_device *lo)
   54.16  {
   54.17  	struct net_private *np = netdev_priv(dev);
   54.18 @@ -137,6 +145,7 @@ static void loopback_construct(struct ne
   54.19  	dev->stop            = loopback_close;
   54.20  	dev->hard_start_xmit = loopback_start_xmit;
   54.21  	dev->get_stats       = loopback_get_stats;
   54.22 +	dev->set_multicast_list = loopback_set_multicast_list;
   54.23  
   54.24  	dev->tx_queue_len    = 0;
   54.25  
    55.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Mon May 08 13:41:18 2006 -0600
    55.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Mon May 08 14:46:11 2006 -0600
    55.3 @@ -105,11 +105,11 @@ static unsigned long alloc_mfn(void)
    55.4  {
    55.5  	unsigned long mfn = 0, flags;
    55.6  	struct xen_memory_reservation reservation = {
    55.7 -		.extent_start = mfn_list,
    55.8  		.nr_extents   = MAX_MFN_ALLOC,
    55.9  		.extent_order = 0,
   55.10  		.domid        = DOMID_SELF
   55.11  	};
   55.12 +	set_xen_guest_handle(reservation.extent_start, mfn_list);
   55.13  	spin_lock_irqsave(&mfn_lock, flags);
   55.14  	if ( unlikely(alloc_index == 0) )
   55.15  		alloc_index = HYPERVISOR_memory_op(
   55.16 @@ -235,23 +235,35 @@ static void net_rx_action(unsigned long 
   55.17  		vdata   = (unsigned long)skb->data;
   55.18  		old_mfn = virt_to_mfn(vdata);
   55.19  
   55.20 -		/* Memory squeeze? Back off for an arbitrary while. */
   55.21 -		if ((new_mfn = alloc_mfn()) == 0) {
   55.22 -			if ( net_ratelimit() )
   55.23 -				WPRINTK("Memory squeeze in netback driver.\n");
   55.24 -			mod_timer(&net_timer, jiffies + HZ);
   55.25 -			skb_queue_head(&rx_queue, skb);
   55.26 -			break;
   55.27 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
   55.28 +			/* Memory squeeze? Back off for an arbitrary while. */
   55.29 +			if ((new_mfn = alloc_mfn()) == 0) {
   55.30 +				if ( net_ratelimit() )
   55.31 +					WPRINTK("Memory squeeze in netback "
   55.32 +						"driver.\n");
   55.33 +				mod_timer(&net_timer, jiffies + HZ);
   55.34 +				skb_queue_head(&rx_queue, skb);
   55.35 +				break;
   55.36 +			}
   55.37 +			/*
   55.38 +			 * Set the new P2M table entry before reassigning
   55.39 +			 * the old data page. Heed the comment in
   55.40 +			 * pgtable-2level.h:pte_page(). :-)
   55.41 +			 */
   55.42 +			set_phys_to_machine(
   55.43 +				__pa(skb->data) >> PAGE_SHIFT,
   55.44 +				new_mfn);
   55.45 +
   55.46 +			MULTI_update_va_mapping(mcl, vdata,
   55.47 +						pfn_pte_ma(new_mfn,
   55.48 +							   PAGE_KERNEL), 0);
   55.49 +			mcl++;
   55.50 +
   55.51 +			mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
   55.52 +				MMU_MACHPHYS_UPDATE;
   55.53 +			mmu->val = __pa(vdata) >> PAGE_SHIFT;
   55.54 +			mmu++;
   55.55  		}
   55.56 -		/*
   55.57 -		 * Set the new P2M table entry before reassigning the old data
   55.58 -		 * page. Heed the comment in pgtable-2level.h:pte_page(). :-)
   55.59 -		 */
   55.60 -		set_phys_to_machine(__pa(skb->data) >> PAGE_SHIFT, new_mfn);
   55.61 -
   55.62 -		MULTI_update_va_mapping(mcl, vdata,
   55.63 -					pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
   55.64 -		mcl++;
   55.65  
   55.66  		gop->mfn = old_mfn;
   55.67  		gop->domid = netif->domid;
   55.68 @@ -260,13 +272,6 @@ static void net_rx_action(unsigned long 
   55.69  		netif->rx.req_cons++;
   55.70  		gop++;
   55.71  
   55.72 -		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
   55.73 -			mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
   55.74 -				MMU_MACHPHYS_UPDATE;
   55.75 -			mmu->val = __pa(vdata) >> PAGE_SHIFT;
   55.76 -			mmu++;
   55.77 -		}
   55.78 -
   55.79  		__skb_queue_tail(&rxq, skb);
   55.80  
   55.81  		/* Filled the batch queue? */
   55.82 @@ -274,23 +279,25 @@ static void net_rx_action(unsigned long 
   55.83  			break;
   55.84  	}
   55.85  
   55.86 -	if (mcl == rx_mcl)
   55.87 -		return;
   55.88 -
   55.89 -	mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
   55.90 +	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
   55.91 +		if (mcl == rx_mcl)
   55.92 +			return;
   55.93  
   55.94 -	if (mmu - rx_mmu) {
   55.95 -		mcl->op = __HYPERVISOR_mmu_update;
   55.96 -		mcl->args[0] = (unsigned long)rx_mmu;
   55.97 -		mcl->args[1] = mmu - rx_mmu;
   55.98 -		mcl->args[2] = 0;
   55.99 -		mcl->args[3] = DOMID_SELF;
  55.100 -		mcl++;
  55.101 +		mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
  55.102 +
  55.103 +		if (mmu - rx_mmu) {
  55.104 +			mcl->op = __HYPERVISOR_mmu_update;
  55.105 +			mcl->args[0] = (unsigned long)rx_mmu;
  55.106 +			mcl->args[1] = mmu - rx_mmu;
  55.107 +			mcl->args[2] = 0;
  55.108 +			mcl->args[3] = DOMID_SELF;
  55.109 +			mcl++;
  55.110 +		}
  55.111 +
  55.112 +		ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
  55.113 +		BUG_ON(ret != 0);
  55.114  	}
  55.115  
  55.116 -	ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
  55.117 -	BUG_ON(ret != 0);
  55.118 -
  55.119  	ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
  55.120  					gop - grant_rx_op);
  55.121  	BUG_ON(ret != 0);
  55.122 @@ -308,8 +315,11 @@ static void net_rx_action(unsigned long 
  55.123  		netif->stats.tx_bytes += size;
  55.124  		netif->stats.tx_packets++;
  55.125  
  55.126 -		/* The update_va_mapping() must not fail. */
  55.127 -		BUG_ON(mcl->result != 0);
  55.128 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
  55.129 +			/* The update_va_mapping() must not fail. */
  55.130 +			BUG_ON(mcl->result != 0);
  55.131 +			mcl++;
  55.132 +		}
  55.133  
  55.134  		/* Check the reassignment error code. */
  55.135  		status = NETIF_RSP_OKAY;
  55.136 @@ -340,7 +350,6 @@ static void net_rx_action(unsigned long 
  55.137  
  55.138  		netif_put(netif);
  55.139  		dev_kfree_skb(skb);
  55.140 -		mcl++;
  55.141  		gop++;
  55.142  	}
  55.143  
  55.144 @@ -650,6 +659,7 @@ static void net_tx_action(unsigned long 
  55.145  
  55.146  		skb->data_len  = txreq.size - data_len;
  55.147  		skb->len      += skb->data_len;
  55.148 +		skb->truesize += skb->data_len;
  55.149  
  55.150  		skb->dev      = netif->dev;
  55.151  		skb->protocol = eth_type_trans(skb, skb->dev);
    56.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Mon May 08 13:41:18 2006 -0600
    56.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Mon May 08 14:46:11 2006 -0600
    56.3 @@ -607,7 +607,7 @@ static void network_alloc_rx_buffers(str
    56.4  	/* Tell the ballon driver what is going on. */
    56.5  	balloon_update_driver_allowance(i);
    56.6  
    56.7 -	reservation.extent_start = np->rx_pfn_array;
    56.8 +	set_xen_guest_handle(reservation.extent_start, np->rx_pfn_array);
    56.9  	reservation.nr_extents   = i;
   56.10  	reservation.extent_order = 0;
   56.11  	reservation.address_bits = 0;
   56.12 @@ -1094,6 +1094,14 @@ static struct ethtool_ops network_ethtoo
   56.13  	.set_tx_csum = ethtool_op_set_tx_csum,
   56.14  };
   56.15  
   56.16 +/*
   56.17 + * Nothing to do here. Virtual interface is point-to-point and the
   56.18 + * physical interface is probably promiscuous anyway.
   56.19 + */
   56.20 +static void network_set_multicast_list(struct net_device *dev)
   56.21 +{
   56.22 +}
   56.23 +
   56.24  /** Create a network device.
   56.25   * @param handle device handle
   56.26   * @param val return parameter for created device
   56.27 @@ -1163,6 +1171,7 @@ static int create_netdev(int handle, str
   56.28  	netdev->stop            = network_close;
   56.29  	netdev->get_stats       = network_get_stats;
   56.30  	netdev->poll            = netif_poll;
   56.31 +	netdev->set_multicast_list = network_set_multicast_list;
   56.32  	netdev->uninit          = netif_uninit;
   56.33  	netdev->weight          = 64;
   56.34  	netdev->features        = NETIF_F_IP_CSUM;
    57.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile	Mon May 08 13:41:18 2006 -0600
    57.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/Makefile	Mon May 08 14:46:11 2006 -0600
    57.3 @@ -1,7 +1,10 @@
    57.4  obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback.o
    57.5  
    57.6  pciback-y := pci_stub.o pciback_ops.o xenbus.o
    57.7 -pciback-y += conf_space.o conf_space_header.o
    57.8 +pciback-y += conf_space.o conf_space_header.o \
    57.9 +	     conf_space_capability.o \
   57.10 +	     conf_space_capability_vpd.o \
   57.11 +	     conf_space_capability_pm.o
   57.12  pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
   57.13  pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
   57.14  
    58.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c	Mon May 08 13:41:18 2006 -0600
    58.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c	Mon May 08 14:46:11 2006 -0600
    58.3 @@ -17,10 +17,10 @@
    58.4  static int permissive = 0;
    58.5  module_param(permissive, bool, 0644);
    58.6  
    58.7 -#define DEFINE_PCI_CONFIG(op,size,type) 					\
    58.8 -int pciback_##op##_config_##size 							\
    58.9 +#define DEFINE_PCI_CONFIG(op,size,type) 			\
   58.10 +int pciback_##op##_config_##size 				\
   58.11  (struct pci_dev *dev, int offset, type value, void *data)	\
   58.12 -{															\
   58.13 +{								\
   58.14  	return pci_##op##_config_##size (dev, offset, value);	\
   58.15  }
   58.16  
   58.17 @@ -175,8 +175,8 @@ int pciback_config_read(struct pci_dev *
   58.18  
   58.19  		req_start = offset;
   58.20  		req_end = offset + size;
   58.21 -		field_start = field->offset;
   58.22 -		field_end = field->offset + field->size;
   58.23 +		field_start = OFFSET(cfg_entry);
   58.24 +		field_end = OFFSET(cfg_entry) + field->size;
   58.25  
   58.26  		if ((req_start >= field_start && req_start < field_end)
   58.27  		    || (req_end > field_start && req_end <= field_end)) {
   58.28 @@ -222,8 +222,8 @@ int pciback_config_write(struct pci_dev 
   58.29  
   58.30  		req_start = offset;
   58.31  		req_end = offset + size;
   58.32 -		field_start = field->offset;
   58.33 -		field_end = field->offset + field->size;
   58.34 +		field_start = OFFSET(cfg_entry);
   58.35 +		field_end = OFFSET(cfg_entry) + field->size;
   58.36  
   58.37  		if ((req_start >= field_start && req_start < field_end)
   58.38  		    || (req_end > field_start && req_end <= field_end)) {
   58.39 @@ -239,60 +239,99 @@ int pciback_config_write(struct pci_dev 
   58.40  
   58.41  			err = conf_space_write(dev, cfg_entry, field_start,
   58.42  					       tmp_val);
   58.43 +
   58.44 +			/* handled is set true here, but not every byte
   58.45 +			 * may have been written! Properly detecting if
   58.46 +			 * every byte is handled is unnecessary as the
   58.47 +			 * flag is used to detect devices that need
   58.48 +			 * special helpers to work correctly.
   58.49 +			 */
   58.50  			handled = 1;
   58.51  		}
   58.52  	}
   58.53  
   58.54 -	if (!handled && !err && permissive) {
   58.55 -		switch (size) {
   58.56 -		case 1:
   58.57 -			err = pci_write_config_byte(dev, offset, (u8)value);
   58.58 -			break;
   58.59 -		case 2:
   58.60 -			err = pci_write_config_word(dev, offset, (u16)value);
   58.61 -			break;
   58.62 -		case 4:
   58.63 -			err = pci_write_config_dword(dev, offset, (u32)value);
   58.64 -			break;
   58.65 +	if (!handled && !err) {
   58.66 +		/* By default, anything not specificially handled above is
   58.67 +		 * read-only. The permissive flag changes this behavior so
   58.68 +		 * that anything not specifically handled above is writable.
   58.69 +		 * This means that some fields may still be read-only because
   58.70 +		 * they have entries in the config_field list that intercept
   58.71 +		 * the write and do nothing. */
   58.72 +		if (permissive) {
   58.73 +			switch (size) {
   58.74 +			case 1:
   58.75 +				err = pci_write_config_byte(dev, offset,
   58.76 +							    (u8)value);
   58.77 +				break;
   58.78 +			case 2:
   58.79 +				err = pci_write_config_word(dev, offset,
   58.80 +							    (u16)value);
   58.81 +				break;
   58.82 +			case 4:
   58.83 +				err = pci_write_config_dword(dev, offset,
   58.84 +							     (u32)value);
   58.85 +				break;
   58.86 +			}
   58.87 +		} else if (!dev_data->warned_on_write) {
   58.88 +			dev_data->warned_on_write = 1;
   58.89 +			dev_warn(&dev->dev, "Driver wrote to a read-only "
   58.90 +				 "configuration space field!\n");
   58.91 +			dev_warn(&dev->dev, "Write at offset 0x%x size %d\n",
   58.92 +				offset, size);
   58.93 +			dev_warn(&dev->dev, "This may be harmless, but if\n");
   58.94 +			dev_warn(&dev->dev, "you have problems with your "
   58.95 +				 "device:\n");
   58.96 +			dev_warn(&dev->dev, "1) see the permissive "
   58.97 +				 "attribute in sysfs.\n");
   58.98 +			dev_warn(&dev->dev, "2) report problems to the "
   58.99 +				 "xen-devel mailing list along\n");
  58.100 +			dev_warn(&dev->dev, "   with details of your device "
  58.101 +				 "obtained from lspci.\n");
  58.102  		}
  58.103  	}
  58.104  
  58.105  	return pcibios_err_to_errno(err);
  58.106  }
  58.107  
  58.108 -void pciback_config_reset(struct pci_dev *dev)
  58.109 +void pciback_config_reset_dev(struct pci_dev *dev)
  58.110  {
  58.111  	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
  58.112  	struct config_field_entry *cfg_entry;
  58.113  	struct config_field *field;
  58.114  
  58.115 +	dev_dbg(&dev->dev, "resetting virtual configuration space\n");
  58.116 +
  58.117  	list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
  58.118  		field = cfg_entry->field;
  58.119  
  58.120  		if (field->reset)
  58.121 -			field->reset(dev, field->offset, cfg_entry->data);
  58.122 +			field->reset(dev, OFFSET(cfg_entry), cfg_entry->data);
  58.123  	}
  58.124  }
  58.125  
  58.126 -void pciback_config_free(struct pci_dev *dev)
  58.127 +void pciback_config_free_dev(struct pci_dev *dev)
  58.128  {
  58.129  	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
  58.130  	struct config_field_entry *cfg_entry, *t;
  58.131  	struct config_field *field;
  58.132  
  58.133 +	dev_dbg(&dev->dev, "free-ing virtual configuration space fields\n");
  58.134 +
  58.135  	list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) {
  58.136  		list_del(&cfg_entry->list);
  58.137  
  58.138  		field = cfg_entry->field;
  58.139  
  58.140  		if (field->release)
  58.141 -			field->release(dev, field->offset, cfg_entry->data);
  58.142 +			field->release(dev, OFFSET(cfg_entry), cfg_entry->data);
  58.143  
  58.144  		kfree(cfg_entry);
  58.145  	}
  58.146  }
  58.147  
  58.148 -int pciback_config_add_field(struct pci_dev *dev, struct config_field *field)
  58.149 +int pciback_config_add_field_offset(struct pci_dev *dev,
  58.150 +				    struct config_field *field,
  58.151 +				    unsigned int offset)
  58.152  {
  58.153  	int err = 0;
  58.154  	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
  58.155 @@ -307,9 +346,10 @@ int pciback_config_add_field(struct pci_
  58.156  
  58.157  	cfg_entry->data = NULL;
  58.158  	cfg_entry->field = field;
  58.159 +	cfg_entry->base_offset = offset;
  58.160  
  58.161  	if (field->init) {
  58.162 -		tmp = field->init(dev, field->offset);
  58.163 +		tmp = field->init(dev, OFFSET(cfg_entry));
  58.164  
  58.165  		if (IS_ERR(tmp)) {
  58.166  			err = PTR_ERR(tmp);
  58.167 @@ -319,6 +359,8 @@ int pciback_config_add_field(struct pci_
  58.168  		cfg_entry->data = tmp;
  58.169  	}
  58.170  
  58.171 +	dev_dbg(&dev->dev, "added config field at offset 0x%02x\n",
  58.172 +		OFFSET(cfg_entry));
  58.173  	list_add_tail(&cfg_entry->list, &dev_data->config_fields);
  58.174  
  58.175        out:
  58.176 @@ -332,14 +374,30 @@ int pciback_config_add_field(struct pci_
  58.177   * certain registers (like the base address registers (BARs) so that we can
  58.178   * keep the client from manipulating them directly.
  58.179   */
  58.180 -int pciback_config_init(struct pci_dev *dev)
  58.181 +int pciback_config_init_dev(struct pci_dev *dev)
  58.182  {
  58.183  	int err = 0;
  58.184  	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
  58.185  
  58.186 +	dev_dbg(&dev->dev, "initializing virtual configuration space\n");
  58.187 +
  58.188  	INIT_LIST_HEAD(&dev_data->config_fields);
  58.189  
  58.190  	err = pciback_config_header_add_fields(dev);
  58.191 +	if (err)
  58.192 +		goto out;
  58.193 +
  58.194 +	err = pciback_config_capability_add_fields(dev);
  58.195 +
  58.196 +      out:
  58.197 +	return err;
  58.198 +}
  58.199 +
  58.200 +int pciback_config_init(void)
  58.201 +{
  58.202 +	int err;
  58.203 +
  58.204 +	err = pciback_config_capability_init();
  58.205  
  58.206  	return err;
  58.207  }
    59.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.h	Mon May 08 13:41:18 2006 -0600
    59.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.h	Mon May 08 14:46:11 2006 -0600
    59.3 @@ -8,7 +8,9 @@
    59.4  #define __XEN_PCIBACK_CONF_SPACE_H__
    59.5  
    59.6  #include <linux/list.h>
    59.7 +#include <linux/err.h>
    59.8  
    59.9 +/* conf_field_init can return an errno in a ptr with ERR_PTR() */
   59.10  typedef void *(*conf_field_init) (struct pci_dev * dev, int offset);
   59.11  typedef void (*conf_field_reset) (struct pci_dev * dev, int offset, void *data);
   59.12  typedef void (*conf_field_free) (struct pci_dev * dev, int offset, void *data);
   59.13 @@ -55,13 +57,25 @@ struct config_field {
   59.14  struct config_field_entry {
   59.15  	struct list_head list;
   59.16  	struct config_field *field;
   59.17 +	unsigned int base_offset;
   59.18  	void *data;
   59.19  };
   59.20  
   59.21 +#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
   59.22 +
   59.23  /* Add fields to a device - the add_fields macro expects to get a pointer to
   59.24   * the first entry in an array (of which the ending is marked by size==0)
   59.25   */
   59.26 -int pciback_config_add_field(struct pci_dev *dev, struct config_field *field);
   59.27 +int pciback_config_add_field_offset(struct pci_dev *dev,
   59.28 +				    struct config_field *field,
   59.29 +				    unsigned int offset);
   59.30 +
   59.31 +static inline int pciback_config_add_field(struct pci_dev *dev,
   59.32 +					   struct config_field *field)
   59.33 +{
   59.34 +	return pciback_config_add_field_offset(dev, field, 0);
   59.35 +}
   59.36 +
   59.37  static inline int pciback_config_add_fields(struct pci_dev *dev,
   59.38  					    struct config_field *field)
   59.39  {
   59.40 @@ -74,11 +88,18 @@ static inline int pciback_config_add_fie
   59.41  	return err;
   59.42  }
   59.43  
   59.44 -/* Initializers which add fields to the virtual configuration space
   59.45 - * ** We could add initializers to allow a guest domain to touch
   59.46 - * the capability lists (for power management, the AGP bridge, etc.)
   59.47 - */
   59.48 -int pciback_config_header_add_fields(struct pci_dev *dev);
   59.49 +static inline int pciback_config_add_fields_offset(struct pci_dev *dev,
   59.50 +						   struct config_field *field,
   59.51 +						   unsigned int offset)
   59.52 +{
   59.53 +	int i, err = 0;
   59.54 +	for (i = 0; field[i].size != 0; i++) {
   59.55 +		err = pciback_config_add_field_offset(dev, &field[i], offset);
   59.56 +		if (err)
   59.57 +			break;
   59.58 +	}
   59.59 +	return err;
   59.60 +}
   59.61  
   59.62  /* Read/Write the real configuration space */
   59.63  int pciback_read_config_byte(struct pci_dev *dev, int offset, u8 * value,
   59.64 @@ -94,4 +115,9 @@ int pciback_write_config_word(struct pci
   59.65  int pciback_write_config_dword(struct pci_dev *dev, int offset, u32 value,
   59.66  			       void *data);
   59.67  
   59.68 +int pciback_config_capability_init(void);
   59.69 +
   59.70 +int pciback_config_header_add_fields(struct pci_dev *dev);
   59.71 +int pciback_config_capability_add_fields(struct pci_dev *dev);
   59.72 +
   59.73  #endif				/* __XEN_PCIBACK_CONF_SPACE_H__ */
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.c	Mon May 08 14:46:11 2006 -0600
    60.3 @@ -0,0 +1,71 @@
    60.4 +/*
    60.5 + * PCI Backend - Handles the virtual fields found on the capability lists
    60.6 + *               in the configuration space.
    60.7 + *
    60.8 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
    60.9 + */
   60.10 +
   60.11 +#include <linux/kernel.h>
   60.12 +#include <linux/pci.h>
   60.13 +#include "pciback.h"
   60.14 +#include "conf_space.h"
   60.15 +#include "conf_space_capability.h"
   60.16 +
   60.17 +static LIST_HEAD(capabilities);
   60.18 +
   60.19 +static struct config_field caplist_header[] = {
   60.20 +	{
   60.21 +	 .offset    = PCI_CAP_LIST_ID,
   60.22 +	 .size      = 2, /* encompass PCI_CAP_LIST_ID & PCI_CAP_LIST_NEXT */
   60.23 +	 .u.w.read  = pciback_read_config_word,
   60.24 +	 .u.w.write = NULL,
   60.25 +	},
   60.26 +	{
   60.27 +	 .size = 0,
   60.28 +	},
   60.29 +};
   60.30 +
   60.31 +static inline void register_capability(struct pciback_config_capability *cap)
   60.32 +{
   60.33 +	list_add_tail(&cap->cap_list, &capabilities);
   60.34 +}
   60.35 +
   60.36 +int pciback_config_capability_add_fields(struct pci_dev *dev)
   60.37 +{
   60.38 +	int err = 0;
   60.39 +	struct pciback_config_capability *cap;
   60.40 +	int cap_offset;
   60.41 +
   60.42 +	list_for_each_entry(cap, &capabilities, cap_list) {
   60.43 +		cap_offset = pci_find_capability(dev, cap->capability);
   60.44 +		if (cap_offset) {
   60.45 +			dev_dbg(&dev->dev, "Found capability 0x%x at 0x%x\n",
   60.46 +				cap->capability, cap_offset);
   60.47 +
   60.48 +			err = pciback_config_add_fields_offset(dev,
   60.49 +							       caplist_header,
   60.50 +							       cap_offset);
   60.51 +			if (err)
   60.52 +				goto out;
   60.53 +			err = pciback_config_add_fields_offset(dev,
   60.54 +							       cap->fields,
   60.55 +							       cap_offset);
   60.56 +			if (err)
   60.57 +				goto out;
   60.58 +		}
   60.59 +	}
   60.60 +
   60.61 +      out:
   60.62 +	return err;
   60.63 +}
   60.64 +
   60.65 +extern struct pciback_config_capability pciback_config_capability_vpd;
   60.66 +extern struct pciback_config_capability pciback_config_capability_pm;
   60.67 +
   60.68 +int pciback_config_capability_init(void)
   60.69 +{
   60.70 +	register_capability(&pciback_config_capability_vpd);
   60.71 +	register_capability(&pciback_config_capability_pm);
   60.72 +
   60.73 +	return 0;
   60.74 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability.h	Mon May 08 14:46:11 2006 -0600
    61.3 @@ -0,0 +1,23 @@
    61.4 +/*
    61.5 + * PCI Backend - Data structures for special overlays for structures on
    61.6 + *               the capability list.
    61.7 + *
    61.8 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
    61.9 + */
   61.10 +
   61.11 +#ifndef __PCIBACK_CONFIG_CAPABILITY_H__
   61.12 +#define __PCIBACK_CONFIG_CAPABILITY_H__
   61.13 +
   61.14 +#include <linux/pci.h>
   61.15 +#include <linux/list.h>
   61.16 +
   61.17 +struct pciback_config_capability {
   61.18 +	struct list_head cap_list;
   61.19 +
   61.20 +	int capability;
   61.21 +
   61.22 +	/* If the device has the capability found above, add these fields */
   61.23 +	struct config_field *fields;
   61.24 +};
   61.25 +
   61.26 +#endif
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c	Mon May 08 14:46:11 2006 -0600
    62.3 @@ -0,0 +1,113 @@
    62.4 +/*
    62.5 + * PCI Backend - Configuration space overlay for power management
    62.6 + *
    62.7 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
    62.8 + */
    62.9 +
   62.10 +#include <linux/pci.h>
   62.11 +#include "conf_space.h"
   62.12 +#include "conf_space_capability.h"
   62.13 +
   62.14 +static int pm_caps_read(struct pci_dev *dev, int offset, u16 *value,
   62.15 +			void *data)
   62.16 +{
   62.17 +	int err;
   62.18 +	u16 real_value;
   62.19 +
   62.20 +	err = pci_read_config_word(dev, offset, &real_value);
   62.21 +	if (err)
   62.22 +		goto out;
   62.23 +
   62.24 +	*value = real_value & ~PCI_PM_CAP_PME_MASK;
   62.25 +
   62.26 +      out:
   62.27 +	return err;
   62.28 +}
   62.29 +
   62.30 +/* PM_OK_BITS specifies the bits that the driver domain is allowed to change.
   62.31 + * Can't allow driver domain to enable PMEs - they're shared */
   62.32 +#define PM_OK_BITS (PCI_PM_CTRL_PME_STATUS|PCI_PM_CTRL_DATA_SEL_MASK)
   62.33 +
   62.34 +static int pm_ctrl_write(struct pci_dev *dev, int offset, u16 new_value,
   62.35 +			 void *data)
   62.36 +{
   62.37 +	int err;
   62.38 +	u16 cur_value;
   62.39 +	pci_power_t new_state;
   62.40 +
   62.41 +	/* Handle setting power state separately */
   62.42 +	new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
   62.43 +
   62.44 +	err = pci_read_config_word(dev, offset, &cur_value);
   62.45 +	if (err)
   62.46 +		goto out;
   62.47 +
   62.48 +	new_value &= PM_OK_BITS;
   62.49 +	if ((cur_value & PM_OK_BITS) != new_value) {
   62.50 +		new_value = (cur_value & ~PM_OK_BITS) | new_value;
   62.51 +		err = pci_write_config_word(dev, offset, new_value);
   62.52 +		if (err)
   62.53 +			goto out;
   62.54 +	}
   62.55 +
   62.56 +	/* Let pci core handle the power management change */
   62.57 +	dev_dbg(&dev->dev, "set power state to %x\n", new_state);
   62.58 +	err = pci_set_power_state(dev, new_state);
   62.59 +	if (err)
   62.60 +		err = PCIBIOS_SET_FAILED;
   62.61 +
   62.62 +      out:
   62.63 +	return err;
   62.64 +}
   62.65 +
   62.66 +/* Ensure PMEs are disabled */
   62.67 +static void *pm_ctrl_init(struct pci_dev *dev, int offset)
   62.68 +{
   62.69 +	int err;
   62.70 +	u16 value;
   62.71 +
   62.72 +	err = pci_read_config_word(dev, offset, &value);
   62.73 +	if (err)
   62.74 +		goto out;
   62.75 +
   62.76 +	if (value & PCI_PM_CTRL_PME_ENABLE) {
   62.77 +		value &= ~PCI_PM_CTRL_PME_ENABLE;
   62.78 +		err = pci_write_config_word(dev, offset, value);
   62.79 +	}
   62.80 +
   62.81 +      out:
   62.82 +	return ERR_PTR(err);
   62.83 +}
   62.84 +
   62.85 +static struct config_field caplist_pm[] = {
   62.86 +	{
   62.87 +		.offset     = PCI_PM_PMC,
   62.88 +		.size       = 2,
   62.89 +		.u.w.read   = pm_caps_read,
   62.90 +	},
   62.91 +	{
   62.92 +		.offset     = PCI_PM_CTRL,
   62.93 +		.size       = 2,
   62.94 +		.init       = pm_ctrl_init,
   62.95 +		.u.w.read   = pciback_read_config_word,
   62.96 +		.u.w.write  = pm_ctrl_write,
   62.97 +	},
   62.98 +	{
   62.99 +		.offset     = PCI_PM_PPB_EXTENSIONS,
  62.100 +		.size       = 1,
  62.101 +		.u.b.read   = pciback_read_config_byte,
  62.102 +	},
  62.103 +	{
  62.104 +		.offset     = PCI_PM_DATA_REGISTER,
  62.105 +		.size       = 1,
  62.106 +		.u.b.read   = pciback_read_config_byte,
  62.107 +	},
  62.108 +	{
  62.109 +		.size = 0,
  62.110 +	},
  62.111 +};
  62.112 +
  62.113 +struct pciback_config_capability pciback_config_capability_pm = {
  62.114 +	.capability = PCI_CAP_ID_PM,
  62.115 +	.fields = caplist_pm,
  62.116 +};
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_vpd.c	Mon May 08 14:46:11 2006 -0600
    63.3 @@ -0,0 +1,42 @@
    63.4 +/*
    63.5 + * PCI Backend - Configuration space overlay for Vital Product Data
    63.6 + *
    63.7 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
    63.8 + */
    63.9 +
   63.10 +#include <linux/pci.h>
   63.11 +#include "conf_space.h"
   63.12 +#include "conf_space_capability.h"
   63.13 +
   63.14 +static int vpd_address_write(struct pci_dev *dev, int offset, u16 value,
   63.15 +			     void *data)
   63.16 +{
   63.17 +	/* Disallow writes to the vital product data */
   63.18 +	if (value & PCI_VPD_ADDR_F)
   63.19 +		return PCIBIOS_SET_FAILED;
   63.20 +	else
   63.21 +		return pci_write_config_word(dev, offset, value);
   63.22 +}
   63.23 +
   63.24 +static struct config_field caplist_vpd[] = {
   63.25 +	{
   63.26 +	 .offset    = PCI_VPD_ADDR,
   63.27 +	 .size      = 2,
   63.28 +	 .u.w.read  = pciback_read_config_word,
   63.29 +	 .u.w.write = vpd_address_write,
   63.30 +	 },
   63.31 +	{
   63.32 +	 .offset     = PCI_VPD_DATA,
   63.33 +	 .size       = 4,
   63.34 +	 .u.dw.read  = pciback_read_config_dword,
   63.35 +	 .u.dw.write = NULL,
   63.36 +	 },
   63.37 +	{
   63.38 +	 .size = 0,
   63.39 +	 },
   63.40 +};
   63.41 + 
   63.42 +struct pciback_config_capability pciback_config_capability_vpd = {
   63.43 +	.capability = PCI_CAP_ID_VPD,
   63.44 +	.fields = caplist_vpd,
   63.45 +};
    64.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c	Mon May 08 13:41:18 2006 -0600
    64.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c	Mon May 08 14:46:11 2006 -0600
    64.3 @@ -169,29 +169,61 @@ static int interrupt_read(struct pci_dev
    64.4  	return 0;
    64.5  }
    64.6  
    64.7 -struct config_field header_common[] = {
    64.8 +static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)
    64.9 +{
   64.10 +	u8 cur_value;
   64.11 +	int err;
   64.12 +
   64.13 +	err = pci_read_config_byte(dev, offset, &cur_value);
   64.14 +	if (err)
   64.15 +		goto out;
   64.16 +
   64.17 +	if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)
   64.18 +	    || value == PCI_BIST_START)
   64.19 +		err = pci_write_config_byte(dev, offset, value);
   64.20 +
   64.21 +      out:
   64.22 +	return err;
   64.23 +}
   64.24 +
   64.25 +static struct config_field header_common[] = {
   64.26  	{
   64.27  	 .offset    = PCI_COMMAND,
   64.28  	 .size      = 2,
   64.29  	 .u.w.read  = pciback_read_config_word,
   64.30  	 .u.w.write = command_write,
   64.31 -	 },
   64.32 +	},
   64.33  	{
   64.34  	 .offset    = PCI_INTERRUPT_LINE,
   64.35  	 .size      = 1,
   64.36  	 .u.b.read  = interrupt_read,
   64.37 -	 .u.b.write = NULL,
   64.38 -	 },
   64.39 +	},
   64.40 +	{
   64.41 +	 .offset    = PCI_INTERRUPT_PIN,
   64.42 +	 .size      = 1,
   64.43 +	 .u.b.read  = pciback_read_config_byte,
   64.44 +	},
   64.45  	{
   64.46  	 /* Any side effects of letting driver domain control cache line? */
   64.47  	 .offset    = PCI_CACHE_LINE_SIZE,
   64.48  	 .size      = 1,
   64.49  	 .u.b.read  = pciback_read_config_byte,
   64.50  	 .u.b.write = pciback_write_config_byte,
   64.51 -	 },
   64.52 +	},
   64.53 +	{
   64.54 +	 .offset    = PCI_LATENCY_TIMER,
   64.55 +	 .size      = 1,
   64.56 +	 .u.b.read  = pciback_read_config_byte,
   64.57 +	},
   64.58 +	{
   64.59 +	 .offset    = PCI_BIST,
   64.60 +	 .size      = 1,
   64.61 +	 .u.b.read  = pciback_read_config_byte,
   64.62 +	 .u.b.write = bist_write,
   64.63 +	},
   64.64  	{
   64.65  	 .size = 0,
   64.66 -	 },
   64.67 +	},
   64.68  };
   64.69  
   64.70  #define CFG_FIELD_BAR(reg_offset) 			\
   64.71 @@ -216,7 +248,7 @@ struct config_field header_common[] = {
   64.72  	 .u.dw.write = rom_write, 			\
   64.73  	 }
   64.74  
   64.75 -struct config_field header_0[] = {
   64.76 +static struct config_field header_0[] = {
   64.77  	CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
   64.78  	CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
   64.79  	CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),
   64.80 @@ -226,16 +258,16 @@ struct config_field header_0[] = {
   64.81  	CFG_FIELD_ROM(PCI_ROM_ADDRESS),
   64.82  	{
   64.83  	 .size = 0,
   64.84 -	 },
   64.85 +	},
   64.86  };
   64.87  
   64.88 -struct config_field header_1[] = {
   64.89 +static struct config_field header_1[] = {
   64.90  	CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
   64.91  	CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
   64.92  	CFG_FIELD_ROM(PCI_ROM_ADDRESS1),
   64.93  	{
   64.94  	 .size = 0,
   64.95 -	 },
   64.96 +	},
   64.97  };
   64.98  
   64.99  int pciback_config_header_add_fields(struct pci_dev *dev)
    65.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c	Mon May 08 13:41:18 2006 -0600
    65.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c	Mon May 08 14:46:11 2006 -0600
    65.3 @@ -76,7 +76,7 @@ static void pcistub_device_release(struc
    65.4  
    65.5  	/* Clean-up the device */
    65.6  	pciback_reset_device(psdev->dev);
    65.7 -	pciback_config_free(psdev->dev);
    65.8 +	pciback_config_free_dev(psdev->dev);
    65.9  	kfree(pci_get_drvdata(psdev->dev));
   65.10  	pci_set_drvdata(psdev->dev, NULL);
   65.11  
   65.12 @@ -180,7 +180,7 @@ void pcistub_put_pci_dev(struct pci_dev 
   65.13  	 * (so it's ready for the next domain)
   65.14  	 */
   65.15  	pciback_reset_device(found_psdev->dev);
   65.16 -	pciback_config_reset(found_psdev->dev);
   65.17 +	pciback_config_reset_dev(found_psdev->dev);
   65.18  
   65.19  	spin_lock_irqsave(&found_psdev->lock, flags);
   65.20  	found_psdev->pdev = NULL;
   65.21 @@ -235,7 +235,7 @@ static int __devinit pcistub_init_device
   65.22  	 * would need to be called somewhere to free the memory allocated
   65.23  	 * here and then to call kfree(pci_get_drvdata(psdev->dev)).
   65.24  	 */
   65.25 -	dev_data = kmalloc(sizeof(*dev_data), GFP_ATOMIC);
   65.26 +	dev_data = kzalloc(sizeof(*dev_data), GFP_ATOMIC);
   65.27  	if (!dev_data) {
   65.28  		err = -ENOMEM;
   65.29  		goto out;
   65.30 @@ -243,7 +243,7 @@ static int __devinit pcistub_init_device
   65.31  	pci_set_drvdata(dev, dev_data);
   65.32  
   65.33  	dev_dbg(&dev->dev, "initializing config\n");
   65.34 -	err = pciback_config_init(dev);
   65.35 +	err = pciback_config_init_dev(dev);
   65.36  	if (err)
   65.37  		goto out;
   65.38  
   65.39 @@ -268,7 +268,7 @@ static int __devinit pcistub_init_device
   65.40  	return 0;
   65.41  
   65.42        config_release:
   65.43 -	pciback_config_free(dev);
   65.44 +	pciback_config_free_dev(dev);
   65.45  
   65.46        out:
   65.47  	pci_set_drvdata(dev, NULL);
   65.48 @@ -324,40 +324,31 @@ static int __devinit pcistub_seize(struc
   65.49  {
   65.50  	struct pcistub_device *psdev;
   65.51  	unsigned long flags;
   65.52 -	int initialize_devices_copy;
   65.53  	int err = 0;
   65.54  
   65.55  	psdev = pcistub_device_alloc(dev);
   65.56  	if (!psdev)
   65.57  		return -ENOMEM;
   65.58  
   65.59 -	/* initialize_devices has to be accessed under a spin lock. But since
   65.60 -	 * it can only change from 0 -> 1, if it's already 1, we don't have to
   65.61 -	 * worry about it changing. That's why we can take a *copy* of
   65.62 -	 * initialize_devices and wait till we're outside of the lock to
   65.63 -	 * check if it's 1 (don't ever check if it's 0 outside of the lock)
   65.64 -	 */
   65.65  	spin_lock_irqsave(&pcistub_devices_lock, flags);
   65.66  
   65.67 -	initialize_devices_copy = initialize_devices;
   65.68 +	if (initialize_devices) {
   65.69 +		spin_unlock_irqrestore(&pcistub_devices_lock, flags);
   65.70  
   65.71 -	if (!initialize_devices_copy) {
   65.72 +		/* don't want irqs disabled when calling pcistub_init_device */
   65.73 +		err = pcistub_init_device(psdev->dev);
   65.74 +
   65.75 +		spin_lock_irqsave(&pcistub_devices_lock, flags);
   65.76 +
   65.77 +		if (!err)
   65.78 +			list_add(&psdev->dev_list, &pcistub_devices);
   65.79 +	} else {
   65.80  		dev_dbg(&dev->dev, "deferring initialization\n");
   65.81  		list_add(&psdev->dev_list, &seized_devices);
   65.82  	}
   65.83  
   65.84  	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
   65.85  
   65.86 -	if (initialize_devices_copy) {
   65.87 -		/* don't want irqs disabled when calling pcistub_init_device */
   65.88 -		err = pcistub_init_device(psdev->dev);
   65.89 -		if (err)
   65.90 -			goto out;
   65.91 -
   65.92 -		list_add(&psdev->dev_list, &pcistub_devices);
   65.93 -	}
   65.94 -
   65.95 -      out:
   65.96  	if (err)
   65.97  		pcistub_device_put(psdev);
   65.98  
   65.99 @@ -663,9 +654,13 @@ fs_initcall(pcistub_init);
  65.100  
  65.101  static int __init pciback_init(void)
  65.102  {
  65.103 -#ifdef MODULE
  65.104  	int err;
  65.105  
  65.106 +	err = pciback_config_init();
  65.107 +	if (err)
  65.108 +		return err;
  65.109 +
  65.110 +#ifdef MODULE
  65.111  	err = pcistub_init();
  65.112  	if (err < 0)
  65.113  		return err;
    66.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h	Mon May 08 13:41:18 2006 -0600
    66.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h	Mon May 08 14:46:11 2006 -0600
    66.3 @@ -44,6 +44,7 @@ struct pciback_device {
    66.4  
    66.5  struct pciback_dev_data {
    66.6  	struct list_head config_fields;
    66.7 +	int warned_on_write;
    66.8  };
    66.9  
   66.10  /* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
   66.11 @@ -58,9 +59,10 @@ void pcistub_put_pci_dev(struct pci_dev 
   66.12  void pciback_reset_device(struct pci_dev *pdev);
   66.13  
   66.14  /* Access a virtual configuration space for a PCI device */
   66.15 -int pciback_config_init(struct pci_dev *dev);
   66.16 -void pciback_config_reset(struct pci_dev *dev);
   66.17 -void pciback_config_free(struct pci_dev *dev);
   66.18 +int pciback_config_init(void);
   66.19 +int pciback_config_init_dev(struct pci_dev *dev);
   66.20 +void pciback_config_reset_dev(struct pci_dev *dev);
   66.21 +void pciback_config_free_dev(struct pci_dev *dev);
   66.22  int pciback_config_read(struct pci_dev *dev, int offset, int size,
   66.23  			u32 * ret_val);
   66.24  int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value);
    67.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c	Mon May 08 13:41:18 2006 -0600
    67.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c	Mon May 08 14:46:11 2006 -0600
    67.3 @@ -36,8 +36,6 @@ void pciback_reset_device(struct pci_dev
    67.4  			dev->is_busmaster = 0;
    67.5  		}
    67.6  	}
    67.7 -
    67.8 -	pciback_config_reset(dev);
    67.9  }
   67.10  
   67.11  static inline void test_and_schedule_op(struct pciback_device *pdev)
    68.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c	Mon May 08 13:41:18 2006 -0600
    68.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c	Mon May 08 14:46:11 2006 -0600
    68.3 @@ -6,6 +6,7 @@
    68.4  #include <linux/module.h>
    68.5  #include <linux/init.h>
    68.6  #include <linux/list.h>
    68.7 +#include <linux/vmalloc.h>
    68.8  #include <xen/xenbus.h>
    68.9  #include <xen/evtchn.h>
   68.10  #include "pciback.h"
    69.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon May 08 13:41:18 2006 -0600
    69.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon May 08 14:46:11 2006 -0600
    69.3 @@ -35,7 +35,7 @@
    69.4  static struct proc_dir_entry *privcmd_intf;
    69.5  static struct proc_dir_entry *capabilities_intf;
    69.6  
    69.7 -#define NR_HYPERCALLS 32
    69.8 +#define NR_HYPERCALLS 64
    69.9  static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
   69.10  
   69.11  static int privcmd_ioctl(struct inode *inode, struct file *file,
   69.12 @@ -159,12 +159,14 @@ static int privcmd_ioctl(struct inode *i
   69.13  	break;
   69.14  
   69.15  	case IOCTL_PRIVCMD_MMAPBATCH: {
   69.16 +#ifndef __ia64__
   69.17  		mmu_update_t u;
   69.18 +		uint64_t ptep;
   69.19 +#endif
   69.20  		privcmd_mmapbatch_t m;
   69.21  		struct vm_area_struct *vma = NULL;
   69.22  		unsigned long __user *p;
   69.23  		unsigned long addr, mfn; 
   69.24 -		uint64_t ptep;
   69.25  		int i;
   69.26  
   69.27  		if (copy_from_user(&m, udata, sizeof(m))) {
   69.28 @@ -199,11 +201,9 @@ static int privcmd_ioctl(struct inode *i
   69.29  			if (get_user(mfn, p))
   69.30  				return -EFAULT;
   69.31  #ifdef __ia64__
   69.32 -			ret = remap_pfn_range(vma,
   69.33 -					      addr&PAGE_MASK,
   69.34 -					      mfn,
   69.35 -					      1<<PAGE_SHIFT,
   69.36 -					      vma->vm_page_prot);
   69.37 +			ret = direct_remap_pfn_range(vma, addr & PAGE_MASK,
   69.38 +						     mfn, 1 << PAGE_SHIFT,
   69.39 +						     vma->vm_page_prot, m.dom);
   69.40  			if (ret < 0)
   69.41  			    goto batch_err;
   69.42  #else
   69.43 @@ -241,6 +241,7 @@ static int privcmd_ioctl(struct inode *i
   69.44  	return ret;
   69.45  }
   69.46  
   69.47 +#ifndef HAVE_ARCH_PRIVCMD_MMAP
   69.48  static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
   69.49  {
   69.50  	/* DONTCOPY is essential for Xen as copy_page_range is broken. */
   69.51 @@ -248,6 +249,7 @@ static int privcmd_mmap(struct file * fi
   69.52  
   69.53  	return 0;
   69.54  }
   69.55 +#endif
   69.56  
   69.57  static struct file_operations privcmd_file_ops = {
   69.58  	.ioctl = privcmd_ioctl,
    70.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Mon May 08 13:41:18 2006 -0600
    70.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Mon May 08 14:46:11 2006 -0600
    70.3 @@ -50,6 +50,8 @@ typedef struct tpmif_st {
    70.4  	grant_handle_t shmem_handle;
    70.5  	grant_ref_t shmem_ref;
    70.6  	struct page *pagerange;
    70.7 +
    70.8 +	char devname[20];
    70.9  } tpmif_t;
   70.10  
   70.11  void tpmif_disconnect_complete(tpmif_t * tpmif);
    71.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Mon May 08 13:41:18 2006 -0600
    71.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Mon May 08 14:46:11 2006 -0600
    71.3 @@ -32,6 +32,7 @@ static tpmif_t *alloc_tpmif(domid_t domi
    71.4  	tpmif->domid = domid;
    71.5  	tpmif->status = DISCONNECTED;
    71.6  	tpmif->tpm_instance = instance;
    71.7 +	snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
    71.8  	atomic_set(&tpmif->refcnt, 1);
    71.9  
   71.10  	tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
   71.11 @@ -112,11 +113,7 @@ static void unmap_frontend_page(tpmif_t 
   71.12  int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
   71.13  {
   71.14  	int err;
   71.15 -	evtchn_op_t op = {
   71.16 -		.cmd = EVTCHNOP_bind_interdomain,
   71.17 -		.u.bind_interdomain.remote_dom = tpmif->domid,
   71.18 -		.u.bind_interdomain.remote_port = evtchn,
   71.19 -	};
   71.20 +	struct evtchn_bind_interdomain bind_interdomain;
   71.21  
   71.22  	if (tpmif->irq) {
   71.23  		return 0;
   71.24 @@ -131,19 +128,24 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
   71.25  		return err;
   71.26  	}
   71.27  
   71.28 -	err = HYPERVISOR_event_channel_op(&op);
   71.29 +
   71.30 +	bind_interdomain.remote_dom  = tpmif->domid;
   71.31 +	bind_interdomain.remote_port = evtchn;
   71.32 +
   71.33 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   71.34 +					  &bind_interdomain);
   71.35  	if (err) {
   71.36  		unmap_frontend_page(tpmif);
   71.37  		free_vm_area(tpmif->tx_area);
   71.38  		return err;
   71.39  	}
   71.40  
   71.41 -	tpmif->evtchn = op.u.bind_interdomain.local_port;
   71.42 +	tpmif->evtchn = bind_interdomain.local_port;
   71.43  
   71.44  	tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
   71.45  
   71.46  	tpmif->irq = bind_evtchn_to_irqhandler(
   71.47 -		tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
   71.48 +		tpmif->evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
   71.49  	tpmif->shmem_ref = shared_page;
   71.50  	tpmif->active = 1;
   71.51  
    72.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Mon May 08 13:41:18 2006 -0600
    72.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Mon May 08 14:46:11 2006 -0600
    72.3 @@ -28,7 +28,8 @@ struct data_exchange {
    72.4  	struct list_head pending_pak;
    72.5  	struct list_head current_pak;
    72.6  	unsigned int copied_so_far;
    72.7 -	u8 has_opener;
    72.8 +	u8 has_opener:1;
    72.9 +	u8 aborted:1;
   72.10  	rwlock_t pak_lock;	// protects all of the previous fields
   72.11  	wait_queue_head_t wait_queue;
   72.12  };
   72.13 @@ -101,6 +102,16 @@ static inline int copy_to_buffer(void *t
   72.14  	return 0;
   72.15  }
   72.16  
   72.17 +
   72.18 +static void dataex_init(struct data_exchange *dataex)
   72.19 +{
   72.20 +	INIT_LIST_HEAD(&dataex->pending_pak);
   72.21 +	INIT_LIST_HEAD(&dataex->current_pak);
   72.22 +	dataex->has_opener = 0;
   72.23 +	rwlock_init(&dataex->pak_lock);
   72.24 +	init_waitqueue_head(&dataex->wait_queue);
   72.25 +}
   72.26 +
   72.27  /***************************************************************
   72.28   Packet-related functions
   72.29  ***************************************************************/
   72.30 @@ -148,11 +159,12 @@ static struct packet *packet_alloc(tpmif
   72.31  				   u32 size, u8 req_tag, u8 flags)
   72.32  {
   72.33  	struct packet *pak = NULL;
   72.34 -	pak = kzalloc(sizeof (struct packet), GFP_KERNEL);
   72.35 +	pak = kzalloc(sizeof (struct packet), GFP_ATOMIC);
   72.36  	if (NULL != pak) {
   72.37  		if (tpmif) {
   72.38  			pak->tpmif = tpmif;
   72.39  			pak->tpm_instance = tpmif->tpm_instance;
   72.40 +			tpmif_get(tpmif);
   72.41  		}
   72.42  		pak->data_len = size;
   72.43  		pak->req_tag = req_tag;
   72.44 @@ -180,6 +192,9 @@ static void packet_free(struct packet *p
   72.45  	if (timer_pending(&pak->processing_timer)) {
   72.46  		BUG();
   72.47  	}
   72.48 +
   72.49 +	if (pak->tpmif)
   72.50 +		tpmif_put(pak->tpmif);
   72.51  	kfree(pak->data_buffer);
   72.52  	/*
   72.53  	 * cannot do tpmif_put(pak->tpmif); bad things happen
   72.54 @@ -271,7 +286,6 @@ int _packet_write(struct packet *pak,
   72.55  		struct gnttab_map_grant_ref map_op;
   72.56  		struct gnttab_unmap_grant_ref unmap_op;
   72.57  		tpmif_tx_request_t *tx;
   72.58 -		unsigned long pfn, mfn, mfn_orig;
   72.59  
   72.60  		tx = &tpmif->tx->ring[i].req;
   72.61  
   72.62 @@ -295,12 +309,6 @@ int _packet_write(struct packet *pak,
   72.63  			return 0;
   72.64  		}
   72.65  
   72.66 -		pfn = __pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT;
   72.67 -		mfn = FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
   72.68 -		mfn_orig = phys_to_machine_mapping[pfn];
   72.69 -
   72.70 -		set_phys_to_machine(pfn, mfn);
   72.71 -
   72.72  		tocopy = MIN(size - offset, PAGE_SIZE);
   72.73  
   72.74  		if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) |
   72.75 @@ -311,8 +319,6 @@ int _packet_write(struct packet *pak,
   72.76  		}
   72.77  		tx->size = tocopy;
   72.78  
   72.79 -		set_phys_to_machine(pfn, mfn_orig);
   72.80 -
   72.81  		gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
   72.82  				    GNTMAP_host_map, handle);
   72.83  
   72.84 @@ -514,27 +520,41 @@ static ssize_t vtpm_op_read(struct file 
   72.85  	unsigned long flags;
   72.86  
   72.87  	write_lock_irqsave(&dataex.pak_lock, flags);
   72.88 +	if (dataex.aborted) {
   72.89 +		dataex.aborted = 0;
   72.90 +		dataex.copied_so_far = 0;
   72.91 +		write_unlock_irqrestore(&dataex.pak_lock, flags);
   72.92 +		return -EIO;
   72.93 +	}
   72.94  
   72.95  	if (list_empty(&dataex.pending_pak)) {
   72.96  		write_unlock_irqrestore(&dataex.pak_lock, flags);
   72.97  		wait_event_interruptible(dataex.wait_queue,
   72.98  					 !list_empty(&dataex.pending_pak));
   72.99  		write_lock_irqsave(&dataex.pak_lock, flags);
  72.100 +		dataex.copied_so_far = 0;
  72.101  	}
  72.102  
  72.103  	if (!list_empty(&dataex.pending_pak)) {
  72.104  		unsigned int left;
  72.105 +
  72.106  		pak = list_entry(dataex.pending_pak.next, struct packet, next);
  72.107 -
  72.108  		left = pak->data_len - dataex.copied_so_far;
  72.109 +		list_del(&pak->next);
  72.110 +		write_unlock_irqrestore(&dataex.pak_lock, flags);
  72.111  
  72.112  		DPRINTK("size given by app: %d, available: %d\n", size, left);
  72.113  
  72.114  		ret_size = MIN(size, left);
  72.115  
  72.116  		ret_size = packet_read(pak, ret_size, data, size, 1);
  72.117 +
  72.118 +		write_lock_irqsave(&dataex.pak_lock, flags);
  72.119 +
  72.120  		if (ret_size < 0) {
  72.121 -			ret_size = -EFAULT;
  72.122 +			del_singleshot_timer_sync(&pak->processing_timer);
  72.123 +			packet_free(pak);
  72.124 +			dataex.copied_so_far = 0;
  72.125  		} else {
  72.126  			DPRINTK("Copied %d bytes to user buffer\n", ret_size);
  72.127  
  72.128 @@ -545,7 +565,6 @@ static ssize_t vtpm_op_read(struct file 
  72.129  
  72.130  				del_singleshot_timer_sync(&pak->
  72.131  							  processing_timer);
  72.132 -				list_del(&pak->next);
  72.133  				list_add_tail(&pak->next, &dataex.current_pak);
  72.134  				/*
  72.135  				 * The more fontends that are handled at the same time,
  72.136 @@ -554,6 +573,8 @@ static ssize_t vtpm_op_read(struct file 
  72.137  				mod_timer(&pak->processing_timer,
  72.138  					  jiffies + (num_frontends * 60 * HZ));
  72.139  				dataex.copied_so_far = 0;
  72.140 +			} else {
  72.141 +				list_add(&pak->next, &dataex.pending_pak);
  72.142  			}
  72.143  		}
  72.144  	}
  72.145 @@ -601,8 +622,8 @@ static ssize_t vtpm_op_write(struct file
  72.146  
  72.147  	if (pak == NULL) {
  72.148  		write_unlock_irqrestore(&dataex.pak_lock, flags);
  72.149 -		printk(KERN_ALERT "No associated packet! (inst=%d)\n",
  72.150 -		       ntohl(vrh.instance_no));
  72.151 +		DPRINTK(KERN_ALERT "No associated packet! (inst=%d)\n",
  72.152 +		        ntohl(vrh.instance_no));
  72.153  		return -EFAULT;
  72.154  	}
  72.155  
  72.156 @@ -784,15 +805,17 @@ static int tpm_send_fail_message(struct 
  72.157  	return rc;
  72.158  }
  72.159  
  72.160 -static void _vtpm_release_packets(struct list_head *head,
  72.161 -				  tpmif_t * tpmif, int send_msgs)
  72.162 +static int _vtpm_release_packets(struct list_head *head,
  72.163 +				 tpmif_t * tpmif, int send_msgs)
  72.164  {
  72.165 +	int aborted = 0;
  72.166 +	int c = 0;
  72.167  	struct packet *pak;
  72.168 -	struct list_head *pos,
  72.169 -	         *tmp;
  72.170 +	struct list_head *pos, *tmp;
  72.171  
  72.172  	list_for_each_safe(pos, tmp, head) {
  72.173  		pak = list_entry(pos, struct packet, next);
  72.174 +		c += 1;
  72.175  
  72.176  		if (tpmif == NULL || pak->tpmif == tpmif) {
  72.177  			int can_send = 0;
  72.178 @@ -808,8 +831,11 @@ static void _vtpm_release_packets(struct
  72.179  				tpm_send_fail_message(pak, pak->req_tag);
  72.180  			}
  72.181  			packet_free(pak);
  72.182 +			if (c == 1)
  72.183 +				aborted = 1;
  72.184  		}
  72.185  	}
  72.186 +	return aborted;
  72.187  }
  72.188  
  72.189  int vtpm_release_packets(tpmif_t * tpmif, int send_msgs)
  72.190 @@ -818,7 +844,9 @@ int vtpm_release_packets(tpmif_t * tpmif
  72.191  
  72.192  	write_lock_irqsave(&dataex.pak_lock, flags);
  72.193  
  72.194 -	_vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
  72.195 +	dataex.aborted = _vtpm_release_packets(&dataex.pending_pak,
  72.196 +					       tpmif,
  72.197 +					       send_msgs);
  72.198  	_vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
  72.199  
  72.200  	write_unlock_irqrestore(&dataex.pak_lock, flags);
  72.201 @@ -1020,11 +1048,7 @@ static int __init tpmback_init(void)
  72.202  		return rc;
  72.203  	}
  72.204  
  72.205 -	INIT_LIST_HEAD(&dataex.pending_pak);
  72.206 -	INIT_LIST_HEAD(&dataex.current_pak);
  72.207 -	dataex.has_opener = 0;
  72.208 -	rwlock_init(&dataex.pak_lock);
  72.209 -	init_waitqueue_head(&dataex.wait_queue);
  72.210 +	dataex_init(&dataex);
  72.211  
  72.212  	spin_lock_init(&tpm_schedule_list_lock);
  72.213  	INIT_LIST_HEAD(&tpm_schedule_list);
  72.214 @@ -1041,6 +1065,7 @@ module_init(tpmback_init);
  72.215  
  72.216  static void __exit tpmback_exit(void)
  72.217  {
  72.218 +	vtpm_release_packets(NULL, 0);
  72.219  	tpmif_xenbus_exit();
  72.220  	tpmif_interface_exit();
  72.221  	misc_deregister(&vtpms_miscdevice);
    73.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile	Mon May 08 13:41:18 2006 -0600
    73.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.3 @@ -1,2 +0,0 @@
    73.4 -
    73.5 -obj-$(CONFIG_XEN_TPMDEV_FRONTEND)	+= tpmfront.o
    74.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Mon May 08 13:41:18 2006 -0600
    74.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.3 @@ -1,767 +0,0 @@
    74.4 -/*
    74.5 - * Copyright (c) 2005, IBM Corporation
    74.6 - *
    74.7 - * Author: Stefan Berger, stefanb@us.ibm.com
    74.8 - * Grant table support: Mahadevan Gomathisankaran
    74.9 - *
   74.10 - * This code has been derived from drivers/xen/netfront/netfront.c
   74.11 - *
   74.12 - * Copyright (c) 2002-2004, K A Fraser
   74.13 - *
   74.14 - * This program is free software; you can redistribute it and/or
   74.15 - * modify it under the terms of the GNU General Public License version 2
   74.16 - * as published by the Free Software Foundation; or, when distributed
   74.17 - * separately from the Linux kernel or incorporated into other
   74.18 - * software packages, subject to the following license:
   74.19 - * 
   74.20 - * Permission is hereby granted, free of charge, to any person obtaining a copy
   74.21 - * of this source file (the "Software"), to deal in the Software without
   74.22 - * restriction, including without limitation the rights to use, copy, modify,
   74.23 - * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   74.24 - * and to permit persons to whom the Software is furnished to do so, subject to
   74.25 - * the following conditions:
   74.26 - *
   74.27 - * The above copyright notice and this permission notice shall be included in
   74.28 - * all copies or substantial portions of the Software.
   74.29 - *
   74.30 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   74.31 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   74.32 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   74.33 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   74.34 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   74.35 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   74.36 - * IN THE SOFTWARE.
   74.37 - */
   74.38 -
   74.39 -#include <linux/config.h>
   74.40 -#include <linux/module.h>
   74.41 -#include <linux/version.h>
   74.42 -#include <linux/kernel.h>
   74.43 -#include <linux/slab.h>
   74.44 -#include <linux/errno.h>
   74.45 -#include <linux/interrupt.h>
   74.46 -#include <linux/init.h>
   74.47 -#include <xen/tpmfe.h>
   74.48 -#include <linux/err.h>
   74.49 -#include <linux/mutex.h>
   74.50 -#include <asm/io.h>
   74.51 -#include <xen/evtchn.h>
   74.52 -#include <xen/interface/grant_table.h>
   74.53 -#include <xen/interface/io/tpmif.h>
   74.54 -#include <asm/uaccess.h>
   74.55 -#include <xen/xenbus.h>
   74.56 -#include <xen/interface/grant_table.h>
   74.57 -
   74.58 -#include "tpmfront.h"
   74.59 -
   74.60 -#undef DEBUG
   74.61 -
   74.62 -/* locally visible variables */
   74.63 -static grant_ref_t gref_head;
   74.64 -static struct tpm_private *my_priv;
   74.65 -
   74.66 -/* local function prototypes */
   74.67 -static irqreturn_t tpmif_int(int irq,
   74.68 -                             void *tpm_priv,
   74.69 -                             struct pt_regs *ptregs);
   74.70 -static void tpmif_rx_action(unsigned long unused);
   74.71 -static int tpmif_connect(struct xenbus_device *dev,
   74.72 -                         struct tpm_private *tp,
   74.73 -                         domid_t domid);
   74.74 -static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
   74.75 -static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
   74.76 -static void tpmif_free_tx_buffers(struct tpm_private *tp);
   74.77 -static void tpmif_set_connected_state(struct tpm_private *tp,
   74.78 -                                      u8 newstate);
   74.79 -static int tpm_xmit(struct tpm_private *tp,
   74.80 -                    const u8 * buf, size_t count, int userbuffer,
   74.81 -                    void *remember);
   74.82 -static void destroy_tpmring(struct tpm_private *tp);
   74.83 -
   74.84 -#define DPRINTK(fmt, args...) \
   74.85 -    pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   74.86 -#define IPRINTK(fmt, args...) \
   74.87 -    printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
   74.88 -#define WPRINTK(fmt, args...) \
   74.89 -    printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
   74.90 -
   74.91 -#define GRANT_INVALID_REF	0
   74.92 -
   74.93 -
   74.94 -static inline int
   74.95 -tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
   74.96 -               int isuserbuffer)
   74.97 -{
   74.98 -	int copied = len;
   74.99 -
  74.100 -	if (len > txb->size) {
  74.101 -		copied = txb->size;
  74.102 -	}
  74.103 -	if (isuserbuffer) {
  74.104 -		if (copy_from_user(txb->data, src, copied))
  74.105 -			return -EFAULT;
  74.106 -	} else {
  74.107 -		memcpy(txb->data, src, copied);
  74.108 -	}
  74.109 -	txb->len = len;
  74.110 -	return copied;
  74.111 -}
  74.112 -
  74.113 -static inline struct tx_buffer *tx_buffer_alloc(void)
  74.114 -{
  74.115 -	struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
  74.116 -					GFP_KERNEL);
  74.117 -
  74.118 -	if (txb) {
  74.119 -		txb->len = 0;
  74.120 -		txb->size = PAGE_SIZE;
  74.121 -		txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
  74.122 -		if (txb->data == NULL) {
  74.123 -			kfree(txb);
  74.124 -			txb = NULL;
  74.125 -		}
  74.126 -	}
  74.127 -	return txb;
  74.128 -}
  74.129 -
  74.130 -
  74.131 -static inline void tx_buffer_free(struct tx_buffer *txb)
  74.132 -{
  74.133 -	if (txb) {
  74.134 -		free_page((long)txb->data);
  74.135 -		kfree(txb);
  74.136 -	}
  74.137 -}
  74.138 -
  74.139 -/**************************************************************
  74.140 - Utility function for the tpm_private structure
  74.141 -**************************************************************/
  74.142 -static inline void tpm_private_init(struct tpm_private *tp)
  74.143 -{
  74.144 -	spin_lock_init(&tp->tx_lock);
  74.145 -	init_waitqueue_head(&tp->wait_q);
  74.146 -}
  74.147 -
  74.148 -static inline void tpm_private_free(void)
  74.149 -{
  74.150 -	tpmif_free_tx_buffers(my_priv);
  74.151 -	kfree(my_priv);
  74.152 -	my_priv = NULL;
  74.153 -}
  74.154 -
  74.155 -static struct tpm_private *tpm_private_get(void)
  74.156 -{
  74.157 -	int err;
  74.158 -	if (!my_priv) {
  74.159 -		my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
  74.160 -		if (my_priv) {
  74.161 -			tpm_private_init(my_priv);
  74.162 -			err = tpmif_allocate_tx_buffers(my_priv);
  74.163 -			if (err < 0) {
  74.164 -				tpm_private_free();
  74.165 -			}
  74.166 -		}
  74.167 -	}
  74.168 -	return my_priv;
  74.169 -}
  74.170 -
  74.171 -/**************************************************************
  74.172 -
  74.173 - The interface to let the tpm plugin register its callback
  74.174 - function and send data to another partition using this module
  74.175 -
  74.176 -**************************************************************/
  74.177 -
  74.178 -static DEFINE_MUTEX(upperlayer_lock);
  74.179 -static DEFINE_MUTEX(suspend_lock);
  74.180 -static struct tpmfe_device *upperlayer_tpmfe;
  74.181 -
  74.182 -/*
  74.183 - * Send data via this module by calling this function
  74.184 - */
  74.185 -int tpm_fe_send(struct tpm_private *tp, const u8 * buf, size_t count, void *ptr)
  74.186 -{
  74.187 -	int sent;
  74.188 -
  74.189 -	mutex_lock(&suspend_lock);
  74.190 -	sent = tpm_xmit(tp, buf, count, 0, ptr);
  74.191 -	mutex_unlock(&suspend_lock);
  74.192 -
  74.193 -	return sent;
  74.194 -}
  74.195 -EXPORT_SYMBOL(tpm_fe_send);
  74.196 -
  74.197 -/*
  74.198 - * Register a callback for receiving data from this module
  74.199 - */
  74.200 -int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
  74.201 -{
  74.202 -	int rc = 0;
  74.203 -
  74.204 -	mutex_lock(&upperlayer_lock);
  74.205 -	if (NULL == upperlayer_tpmfe) {
  74.206 -		upperlayer_tpmfe = tpmfe_dev;
  74.207 -		tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
  74.208 -		tpmfe_dev->tpm_private = tpm_private_get();
  74.209 -		if (!tpmfe_dev->tpm_private) {
  74.210 -			rc = -ENOMEM;
  74.211 -		}
  74.212 -	} else {
  74.213 -		rc = -EBUSY;
  74.214 -	}
  74.215 -	mutex_unlock(&upperlayer_lock);
  74.216 -	return rc;
  74.217 -}
  74.218 -EXPORT_SYMBOL(tpm_fe_register_receiver);
  74.219 -
  74.220 -/*
  74.221 - * Unregister the callback for receiving data from this module
  74.222 - */
  74.223 -void tpm_fe_unregister_receiver(void)
  74.224 -{
  74.225 -	mutex_lock(&upperlayer_lock);
  74.226 -	upperlayer_tpmfe = NULL;
  74.227 -	mutex_unlock(&upperlayer_lock);
  74.228 -}
  74.229 -EXPORT_SYMBOL(tpm_fe_unregister_receiver);
  74.230 -
  74.231 -/*
  74.232 - * Call this function to send data to the upper layer's
  74.233 - * registered receiver function.
  74.234 - */
  74.235 -static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
  74.236 -                                  const void *ptr)
  74.237 -{
  74.238 -	int rc = 0;
  74.239 -
  74.240 -	mutex_lock(&upperlayer_lock);
  74.241 -
  74.242 -	if (upperlayer_tpmfe && upperlayer_tpmfe->receive)
  74.243 -		rc = upperlayer_tpmfe->receive(buf, count, ptr);
  74.244 -
  74.245 -	mutex_unlock(&upperlayer_lock);
  74.246 -	return rc;
  74.247 -}
  74.248 -
  74.249 -/**************************************************************
  74.250 - XENBUS support code
  74.251 -**************************************************************/
  74.252 -
  74.253 -static int setup_tpmring(struct xenbus_device *dev,
  74.254 -                         struct tpm_private *tp)
  74.255 -{
  74.256 -	tpmif_tx_interface_t *sring;
  74.257 -	int err;
  74.258 -
  74.259 -	tp->ring_ref = GRANT_INVALID_REF;
  74.260 -
  74.261 -	sring = (void *)__get_free_page(GFP_KERNEL);
  74.262 -	if (!sring) {
  74.263 -		xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
  74.264 -		return -ENOMEM;
  74.265 -	}
  74.266 -	tp->tx = sring;
  74.267 -
  74.268 -	err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
  74.269 -	if (err < 0) {
  74.270 -		free_page((unsigned long)sring);
  74.271 -		tp->tx = NULL;
  74.272 -		xenbus_dev_fatal(dev, err, "allocating grant reference");
  74.273 -		goto fail;
  74.274 -	}
  74.275 -	tp->ring_ref = err;
  74.276 -
  74.277 -	err = tpmif_connect(dev, tp, dev->otherend_id);
  74.278 -	if (err)
  74.279 -		goto fail;
  74.280 -
  74.281 -	return 0;
  74.282 -fail:
  74.283 -	destroy_tpmring(tp);
  74.284 -	return err;
  74.285 -}
  74.286 -
  74.287 -
  74.288 -static void destroy_tpmring(struct tpm_private *tp)
  74.289 -{
  74.290 -	tpmif_set_connected_state(tp, 0);
  74.291 -
  74.292 -	if (tp->ring_ref != GRANT_INVALID_REF) {
  74.293 -		gnttab_end_foreign_access(tp->ring_ref, 0,
  74.294 -					  (unsigned long)tp->tx);
  74.295 -		tp->ring_ref = GRANT_INVALID_REF;
  74.296 -		tp->tx = NULL;
  74.297 -	}
  74.298 -
  74.299 -	if (tp->irq)
  74.300 -		unbind_from_irqhandler(tp->irq, tp);
  74.301 -
  74.302 -	tp->evtchn = tp->irq = 0;
  74.303 -}
  74.304 -
  74.305 -
  74.306 -static int talk_to_backend(struct xenbus_device *dev,
  74.307 -                           struct tpm_private *tp)
  74.308 -{
  74.309 -	const char *message = NULL;
  74.310 -	int err;
  74.311 -	xenbus_transaction_t xbt;
  74.312 -
  74.313 -	err = setup_tpmring(dev, tp);
  74.314 -	if (err) {
  74.315 -		xenbus_dev_fatal(dev, err, "setting up ring");
  74.316 -		goto out;
  74.317 -	}
  74.318 -
  74.319 -again:
  74.320 -	err = xenbus_transaction_start(&xbt);
  74.321 -	if (err) {
  74.322 -		xenbus_dev_fatal(dev, err, "starting transaction");
  74.323 -		goto destroy_tpmring;
  74.324 -	}
  74.325 -
  74.326 -	err = xenbus_printf(xbt, dev->nodename,
  74.327 -	                    "ring-ref","%u", tp->ring_ref);
  74.328 -	if (err) {
  74.329 -		message = "writing ring-ref";
  74.330 -		goto abort_transaction;
  74.331 -	}
  74.332 -
  74.333 -	err = xenbus_printf(xbt, dev->nodename,
  74.334 -			    "event-channel", "%u", tp->evtchn);
  74.335 -	if (err) {
  74.336 -		message = "writing event-channel";
  74.337 -		goto abort_transaction;
  74.338 -	}
  74.339 -
  74.340 -	err = xenbus_transaction_end(xbt, 0);
  74.341 -	if (err == -EAGAIN)
  74.342 -		goto again;
  74.343 -	if (err) {
  74.344 -		xenbus_dev_fatal(dev, err, "completing transaction");
  74.345 -		goto destroy_tpmring;
  74.346 -	}
  74.347 -
  74.348 -	xenbus_switch_state(dev, XenbusStateConnected);
  74.349 -
  74.350 -	return 0;
  74.351 -
  74.352 -abort_transaction:
  74.353 -	xenbus_transaction_end(xbt, 1);
  74.354 -	if (message)
  74.355 -		xenbus_dev_error(dev, err, "%s", message);
  74.356 -destroy_tpmring:
  74.357 -	destroy_tpmring(tp);
  74.358 -out:
  74.359 -	return err;
  74.360 -}
  74.361 -
  74.362 -/**
  74.363 - * Callback received when the backend's state changes.
  74.364 - */
  74.365 -static void backend_changed(struct xenbus_device *dev,
  74.366 -			    XenbusState backend_state)
  74.367 -{
  74.368 -	struct tpm_private *tp = dev->data;
  74.369 -	DPRINTK("\n");
  74.370 -
  74.371 -	switch (backend_state) {
  74.372 -	case XenbusStateInitialising:
  74.373 -	case XenbusStateInitWait:
  74.374 -	case XenbusStateInitialised:
  74.375 -	case XenbusStateUnknown:
  74.376 -		break;
  74.377 -
  74.378 -	case XenbusStateConnected:
  74.379 -		tpmif_set_connected_state(tp, 1);
  74.380 -		break;
  74.381 -
  74.382 -	case XenbusStateClosing:
  74.383 -		tpmif_set_connected_state(tp, 0);
  74.384 -		break;
  74.385 -
  74.386 -	case XenbusStateClosed:
  74.387 -		if (tp->is_suspended == 0) {
  74.388 -			device_unregister(&dev->dev);
  74.389 -		}
  74.390 -		xenbus_switch_state(dev, XenbusStateClosed);
  74.391 -		break;
  74.392 -	}
  74.393 -}
  74.394 -
  74.395 -
  74.396 -static int tpmfront_probe(struct xenbus_device *dev,
  74.397 -                          const struct xenbus_device_id *id)
  74.398 -{
  74.399 -	int err;
  74.400 -	int handle;
  74.401 -	struct tpm_private *tp = tpm_private_get();
  74.402 -
  74.403 -	if (!tp)
  74.404 -		return -ENOMEM;
  74.405 -
  74.406 -	err = xenbus_scanf(XBT_NULL, dev->nodename,
  74.407 -	                   "handle", "%i", &handle);
  74.408 -	if (XENBUS_EXIST_ERR(err))
  74.409 -		return err;
  74.410 -
  74.411 -	if (err < 0) {
  74.412 -		xenbus_dev_fatal(dev,err,"reading virtual-device");
  74.413 -		return err;
  74.414 -	}
  74.415 -
  74.416 -	tp->dev = dev;
  74.417 -	dev->data = tp;
  74.418 -
  74.419 -	err = talk_to_backend(dev, tp);
  74.420 -	if (err) {
  74.421 -		tpm_private_free();
  74.422 -		dev->data = NULL;
  74.423 -		return err;
  74.424 -	}
  74.425 -	return 0;
  74.426 -}
  74.427 -
  74.428 -
  74.429 -static int tpmfront_remove(struct xenbus_device *dev)
  74.430 -{
  74.431 -	struct tpm_private *tp = (struct tpm_private *)dev->data;
  74.432 -	destroy_tpmring(tp);
  74.433 -	return 0;
  74.434 -}
  74.435 -
  74.436 -static int tpmfront_suspend(struct xenbus_device *dev)
  74.437 -{
  74.438 -	struct tpm_private *tp = (struct tpm_private *)dev->data;
  74.439 -	u32 ctr;
  74.440 -
  74.441 -	/* lock, so no app can send */
  74.442 -	mutex_lock(&suspend_lock);
  74.443 -	xenbus_switch_state(dev, XenbusStateClosed);
  74.444 -	tp->is_suspended = 1;
  74.445 -
  74.446 -	for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
  74.447 -		if ((ctr % 10) == 0)
  74.448 -			printk("TPM-FE [INFO]: Waiting for outstanding request.\n");
  74.449 -		/*
  74.450 -		 * Wait for a request to be responded to.
  74.451 -		 */
  74.452 -		interruptible_sleep_on_timeout(&tp->wait_q, 100);
  74.453 -	}
  74.454 -
  74.455 -	if (atomic_read(&tp->tx_busy)) {
  74.456 -		/*
  74.457 -		 * A temporary work-around.
  74.458 -		 */
  74.459 -		printk("TPM-FE [WARNING]: Resetting busy flag.");
  74.460 -		atomic_set(&tp->tx_busy, 0);
  74.461 -	}
  74.462 -
  74.463 -	return 0;
  74.464 -}
  74.465 -
  74.466 -static int tpmfront_resume(struct xenbus_device *dev)
  74.467 -{
  74.468 -	struct tpm_private *tp = (struct tpm_private *)dev->data;
  74.469 -	destroy_tpmring(tp);
  74.470 -	return talk_to_backend(dev, tp);
  74.471 -}
  74.472 -
  74.473 -static int tpmif_connect(struct xenbus_device *dev,
  74.474 -                         struct tpm_private *tp,
  74.475 -                         domid_t domid)
  74.476 -{
  74.477 -	int err;
  74.478 -
  74.479 -	tp->backend_id = domid;
  74.480 -
  74.481 -	err = xenbus_alloc_evtchn(dev, &tp->evtchn);
  74.482 -	if (err)
  74.483 -		return err;
  74.484 -
  74.485 -	err = bind_evtchn_to_irqhandler(tp->evtchn,
  74.486 -					tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
  74.487 -					tp);
  74.488 -	if (err <= 0) {
  74.489 -		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  74.490 -		return err;
  74.491 -	}
  74.492 -
  74.493 -	tp->irq = err;
  74.494 -	return 0;
  74.495 -}
  74.496 -
  74.497 -static struct xenbus_device_id tpmfront_ids[] = {
  74.498 -	{ "vtpm" },
  74.499 -	{ "" }
  74.500 -};
  74.501 -
  74.502 -static struct xenbus_driver tpmfront = {
  74.503 -	.name = "vtpm",
  74.504 -	.owner = THIS_MODULE,
  74.505 -	.ids = tpmfront_ids,
  74.506 -	.probe = tpmfront_probe,
  74.507 -	.remove =  tpmfront_remove,
  74.508 -	.resume = tpmfront_resume,
  74.509 -	.otherend_changed = backend_changed,
  74.510 -	.suspend = tpmfront_suspend,
  74.511 -};
  74.512 -
  74.513 -static void __init init_tpm_xenbus(void)
  74.514 -{
  74.515 -	xenbus_register_frontend(&tpmfront);
  74.516 -}
  74.517 -
  74.518 -static void __exit exit_tpm_xenbus(void)
  74.519 -{
  74.520 -	xenbus_unregister_driver(&tpmfront);
  74.521 -}
  74.522 -
  74.523 -static int tpmif_allocate_tx_buffers(struct tpm_private *tp)
  74.524 -{
  74.525 -	unsigned int i;
  74.526 -
  74.527 -	for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
  74.528 -		tp->tx_buffers[i] = tx_buffer_alloc();
  74.529 -		if (!tp->tx_buffers[i]) {
  74.530 -			tpmif_free_tx_buffers(tp);
  74.531 -			return -ENOMEM;
  74.532 -		}
  74.533 -	}
  74.534 -	return 0;
  74.535 -}
  74.536 -
  74.537 -static void tpmif_free_tx_buffers(struct tpm_private *tp)
  74.538 -{
  74.539 -	unsigned int i;
  74.540 -
  74.541 -	for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
  74.542 -		tx_buffer_free(tp->tx_buffers[i]);
  74.543 -	}
  74.544 -}
  74.545 -
  74.546 -static void tpmif_rx_action(unsigned long priv)
  74.547 -{
  74.548 -	struct tpm_private *tp = (struct tpm_private *)priv;
  74.549 -
  74.550 -	int i = 0;
  74.551 -	unsigned int received;
  74.552 -	unsigned int offset = 0;
  74.553 -	u8 *buffer;
  74.554 -	tpmif_tx_request_t *tx;
  74.555 -	tx = &tp->tx->ring[i].req;
  74.556 -
  74.557 -	received = tx->size;
  74.558 -
  74.559 -	buffer = kmalloc(received, GFP_KERNEL);
  74.560 -	if (NULL == buffer) {
  74.561 -		goto exit;
  74.562 -	}
  74.563 -
  74.564 -	for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
  74.565 -		struct tx_buffer *txb = tp->tx_buffers[i];
  74.566 -		tpmif_tx_request_t *tx;
  74.567 -		unsigned int tocopy;
  74.568 -
  74.569 -		tx = &tp->tx->ring[i].req;
  74.570 -		tocopy = tx->size;
  74.571 -		if (tocopy > PAGE_SIZE) {
  74.572 -			tocopy = PAGE_SIZE;
  74.573 -		}
  74.574 -
  74.575 -		memcpy(&buffer[offset], txb->data, tocopy);
  74.576 -
  74.577 -		gnttab_release_grant_reference(&gref_head, tx->ref);
  74.578 -
  74.579 -		offset += tocopy;
  74.580 -	}
  74.581 -
  74.582 -	tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
  74.583 -	kfree(buffer);
  74.584 -
  74.585 -exit:
  74.586 -	atomic_set(&tp->tx_busy, 0);
  74.587 -	wake_up_interruptible(&tp->wait_q);
  74.588 -}
  74.589 -
  74.590 -
  74.591 -static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
  74.592 -{
  74.593 -	struct tpm_private *tp = tpm_priv;
  74.594 -	unsigned long flags;
  74.595 -
  74.596 -	spin_lock_irqsave(&tp->tx_lock, flags);
  74.597 -	tpmif_rx_tasklet.data = (unsigned long)tp;
  74.598 -	tasklet_schedule(&tpmif_rx_tasklet);
  74.599 -	spin_unlock_irqrestore(&tp->tx_lock, flags);
  74.600 -
  74.601 -	return IRQ_HANDLED;
  74.602 -}
  74.603 -
  74.604 -
  74.605 -static int tpm_xmit(struct tpm_private *tp,
  74.606 -                    const u8 * buf, size_t count, int isuserbuffer,
  74.607 -                    void *remember)
  74.608 -{
  74.609 -	tpmif_tx_request_t *tx;
  74.610 -	TPMIF_RING_IDX i;
  74.611 -	unsigned int offset = 0;
  74.612 -
  74.613 -	spin_lock_irq(&tp->tx_lock);
  74.614 -
  74.615 -	if (unlikely(atomic_read(&tp->tx_busy))) {
  74.616 -		printk("tpm_xmit: There's an outstanding request/response "
  74.617 -		       "on the way!\n");
  74.618 -		spin_unlock_irq(&tp->tx_lock);
  74.619 -		return -EBUSY;
  74.620 -	}
  74.621 -
  74.622 -	if (tp->is_connected != 1) {
  74.623 -		spin_unlock_irq(&tp->tx_lock);
  74.624 -		return -EIO;
  74.625 -	}
  74.626 -
  74.627 -	for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
  74.628 -		struct tx_buffer *txb = tp->tx_buffers[i];
  74.629 -		int copied;
  74.630 -
  74.631 -		if (NULL == txb) {
  74.632 -			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
  74.633 -				"Not transmitting anything!\n", i);
  74.634 -			spin_unlock_irq(&tp->tx_lock);
  74.635 -			return -EFAULT;
  74.636 -		}
  74.637 -		copied = tx_buffer_copy(txb, &buf[offset], count,
  74.638 -		                        isuserbuffer);
  74.639 -		if (copied < 0) {
  74.640 -			/* An error occurred */
  74.641 -			spin_unlock_irq(&tp->tx_lock);
  74.642 -			return copied;
  74.643 -		}
  74.644 -		count -= copied;
  74.645 -		offset += copied;
  74.646 -
  74.647 -		tx = &tp->tx->ring[i].req;
  74.648 -
  74.649 -		tx->addr = virt_to_machine(txb->data);
  74.650 -		tx->size = txb->len;
  74.651 -
  74.652 -		DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
  74.653 -		        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
  74.654 -
  74.655 -		/* get the granttable reference for this page */
  74.656 -		tx->ref = gnttab_claim_grant_reference(&gref_head);
  74.657 -
  74.658 -		if (-ENOSPC == tx->ref) {
  74.659 -			spin_unlock_irq(&tp->tx_lock);
  74.660 -			DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
  74.661 -			return -ENOSPC;
  74.662 -		}
  74.663 -		gnttab_grant_foreign_access_ref( tx->ref,
  74.664 -		                                 tp->backend_id,
  74.665 -		                                 (tx->addr >> PAGE_SHIFT),
  74.666 -		                                 0 /*RW*/);
  74.667 -		wmb();
  74.668 -	}
  74.669 -
  74.670 -	atomic_set(&tp->tx_busy, 1);
  74.671 -	tp->tx_remember = remember;
  74.672 -	mb();
  74.673 -
  74.674 -	DPRINTK("Notifying backend via event channel %d\n",
  74.675 -	        tp->evtchn);
  74.676 -
  74.677 -	notify_remote_via_irq(tp->irq);
  74.678 -
  74.679 -	spin_unlock_irq(&tp->tx_lock);
  74.680 -	return offset;
  74.681 -}
  74.682 -
  74.683 -
  74.684 -static void tpmif_notify_upperlayer(struct tpm_private *tp)
  74.685 -{
  74.686 -	/*
  74.687 -	 * Notify upper layer about the state of the connection
  74.688 -	 * to the BE.
  74.689 -	 */
  74.690 -	mutex_lock(&upperlayer_lock);
  74.691 -
  74.692 -	if (upperlayer_tpmfe != NULL) {
  74.693 -		if (tp->is_connected) {
  74.694 -			upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
  74.695 -		} else {
  74.696 -			upperlayer_tpmfe->status(0);
  74.697 -		}
  74.698 -	}
  74.699 -	mutex_unlock(&upperlayer_lock);
  74.700 -}
  74.701 -
  74.702 -
  74.703 -static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
  74.704 -{
  74.705 -	/*
  74.706 -	 * Don't notify upper layer if we are in suspend mode and
  74.707 -	 * should disconnect - assumption is that we will resume
  74.708 -	 * The mutex keeps apps from sending.
  74.709 -	 */
  74.710 -	if (is_connected == 0 && tp->is_suspended == 1) {
  74.711 -		return;
  74.712 -	}
  74.713 -
  74.714 -	/*
  74.715 -	 * Unlock the mutex if we are connected again
  74.716 -	 * after being suspended - now resuming.
  74.717 -	 * This also removes the suspend state.
  74.718 -	 */
  74.719 -	if (is_connected == 1 && tp->is_suspended == 1) {
  74.720 -		tp->is_suspended = 0;
  74.721 -		/* unlock, so apps can resume sending */
  74.722 -		mutex_unlock(&suspend_lock);
  74.723 -	}
  74.724 -
  74.725 -	if (is_connected != tp->is_connected) {
  74.726 -		tp->is_connected = is_connected;
  74.727 -		tpmif_notify_upperlayer(tp);
  74.728 -	}
  74.729 -}
  74.730 -
  74.731 -
  74.732 -/* =================================================================
  74.733 - * Initialization function.
  74.734 - * =================================================================
  74.735 - */
  74.736 -
  74.737 -static int __init tpmif_init(void)
  74.738 -{
  74.739 -	IPRINTK("Initialising the vTPM driver.\n");
  74.740 -	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
  74.741 -	                                     &gref_head ) < 0) {
  74.742 -		return -EFAULT;
  74.743 -	}
  74.744 -
  74.745 -	init_tpm_xenbus();
  74.746 -
  74.747 -	return 0;
  74.748 -}
  74.749 -
  74.750 -module_init(tpmif_init);
  74.751 -
  74.752 -static void __exit tpmif_exit(void)
  74.753 -{
  74.754 -	exit_tpm_xenbus();
  74.755 -	gnttab_free_grant_references(gref_head);
  74.756 -}
  74.757 -
  74.758 -module_exit(tpmif_exit);
  74.759 -
  74.760 -MODULE_LICENSE("Dual BSD/GPL");
  74.761 -
  74.762 -/*
  74.763 - * Local variables:
  74.764 - *  c-file-style: "linux"
  74.765 - *  indent-tabs-mode: t
  74.766 - *  c-indent-level: 8
  74.767 - *  c-basic-offset: 8
  74.768 - *  tab-width: 8
  74.769 - * End:
  74.770 - */
    75.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Mon May 08 13:41:18 2006 -0600
    75.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.3 @@ -1,40 +0,0 @@
    75.4 -#ifndef TPM_FRONT_H
    75.5 -#define TPM_FRONT_H
    75.6 -
    75.7 -struct tpm_private {
    75.8 -	tpmif_tx_interface_t *tx;
    75.9 -	unsigned int evtchn;
   75.10 -	unsigned int irq;
   75.11 -	u8 is_connected;
   75.12 -	u8 is_suspended;
   75.13 -
   75.14 -	spinlock_t tx_lock;
   75.15 -
   75.16 -	struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
   75.17 -
   75.18 -	atomic_t tx_busy;
   75.19 -	void *tx_remember;
   75.20 -	domid_t backend_id;
   75.21 -	wait_queue_head_t wait_q;
   75.22 -
   75.23 -	struct xenbus_device *dev;
   75.24 -	int ring_ref;
   75.25 -};
   75.26 -
   75.27 -struct tx_buffer {
   75.28 -	unsigned int size;	// available space in data
   75.29 -	unsigned int len;	// used space in data
   75.30 -	unsigned char *data;	// pointer to a page
   75.31 -};
   75.32 -
   75.33 -#endif
   75.34 -
   75.35 -/*
   75.36 - * Local variables:
   75.37 - *  c-file-style: "linux"
   75.38 - *  indent-tabs-mode: t
   75.39 - *  c-indent-level: 8
   75.40 - *  c-basic-offset: 8
   75.41 - *  tab-width: 8
   75.42 - * End:
   75.43 - */
    76.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c	Mon May 08 13:41:18 2006 -0600
    76.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c	Mon May 08 14:46:11 2006 -0600
    76.3 @@ -132,6 +132,7 @@ int xenbus_unmap_ring(struct xenbus_devi
    76.4  }
    76.5  EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
    76.6  
    76.7 +MODULE_LICENSE("Dual BSD/GPL");
    76.8  
    76.9  /*
   76.10   * Local variables:
    77.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Mon May 08 13:41:18 2006 -0600
    77.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Mon May 08 14:46:11 2006 -0600
    77.3 @@ -214,16 +214,19 @@ EXPORT_SYMBOL_GPL(xenbus_grant_ring);
    77.4  
    77.5  int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
    77.6  {
    77.7 -	evtchn_op_t op = {
    77.8 -		.cmd = EVTCHNOP_alloc_unbound,
    77.9 -		.u.alloc_unbound.dom = DOMID_SELF,
   77.10 -		.u.alloc_unbound.remote_dom = dev->otherend_id
   77.11 -	};
   77.12 -	int err = HYPERVISOR_event_channel_op(&op);
   77.13 +	struct evtchn_alloc_unbound alloc_unbound;
   77.14 +	int err;
   77.15 +
   77.16 +	alloc_unbound.dom        = DOMID_SELF;
   77.17 +	alloc_unbound.remote_dom = dev->otherend_id;
   77.18 +
   77.19 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
   77.20 +					  &alloc_unbound);
   77.21  	if (err)
   77.22  		xenbus_dev_fatal(dev, err, "allocating event channel");
   77.23  	else
   77.24 -		*port = op.u.alloc_unbound.port;
   77.25 +		*port = alloc_unbound.port;
   77.26 +
   77.27  	return err;
   77.28  }
   77.29  EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
   77.30 @@ -231,18 +234,21 @@ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
   77.31  
   77.32  int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
   77.33  {
   77.34 -	evtchn_op_t op = {
   77.35 -		.cmd = EVTCHNOP_bind_interdomain,
   77.36 -		.u.bind_interdomain.remote_dom = dev->otherend_id,
   77.37 -		.u.bind_interdomain.remote_port = remote_port,
   77.38 -	};
   77.39 -	int err = HYPERVISOR_event_channel_op(&op);
   77.40 +	struct evtchn_bind_interdomain bind_interdomain;
   77.41 +	int err;
   77.42 +
   77.43 +	bind_interdomain.remote_dom  = dev->otherend_id;
   77.44 +	bind_interdomain.remote_port = remote_port,
   77.45 +
   77.46 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   77.47 +					  &bind_interdomain);
   77.48  	if (err)
   77.49  		xenbus_dev_fatal(dev, err,
   77.50  				 "binding to event channel %d from domain %d",
   77.51  				 remote_port, dev->otherend_id);
   77.52  	else
   77.53 -		*port = op.u.bind_interdomain.local_port;
   77.54 +		*port = bind_interdomain.local_port;
   77.55 +
   77.56  	return err;
   77.57  }
   77.58  EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
   77.59 @@ -250,13 +256,15 @@ EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
   77.60  
   77.61  int xenbus_free_evtchn(struct xenbus_device *dev, int port)
   77.62  {
   77.63 -	evtchn_op_t op = {
   77.64 -		.cmd = EVTCHNOP_close,
   77.65 -		.u.close.port = port,
   77.66 -	};
   77.67 -	int err = HYPERVISOR_event_channel_op(&op);
   77.68 +	struct evtchn_close close;
   77.69 +	int err;
   77.70 +
   77.71 +	close.port = port;
   77.72 +
   77.73 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
   77.74  	if (err)
   77.75  		xenbus_dev_error(dev, err, "freeing event channel %d", port);
   77.76 +
   77.77  	return err;
   77.78  }
   77.79  
    78.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon May 08 13:41:18 2006 -0600
    78.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon May 08 14:46:11 2006 -0600
    78.3 @@ -981,7 +981,7 @@ static int __init xenbus_probe_init(void
    78.4  	dom0 = (xen_start_info->store_evtchn == 0);
    78.5  
    78.6  	if (dom0) {
    78.7 -		evtchn_op_t op = { 0 };
    78.8 +		struct evtchn_alloc_unbound alloc_unbound;
    78.9  
   78.10  		/* Allocate page. */
   78.11  		page = get_zeroed_page(GFP_KERNEL);
   78.12 @@ -993,15 +993,15 @@ static int __init xenbus_probe_init(void
   78.13  				   PAGE_SHIFT);
   78.14  
   78.15  		/* Next allocate a local port which xenstored can bind to */
   78.16 -		op.cmd = EVTCHNOP_alloc_unbound;
   78.17 -		op.u.alloc_unbound.dom        = DOMID_SELF;
   78.18 -		op.u.alloc_unbound.remote_dom = 0;
   78.19 +		alloc_unbound.dom        = DOMID_SELF;
   78.20 +		alloc_unbound.remote_dom = 0;
   78.21  
   78.22 -		err = HYPERVISOR_event_channel_op(&op);
   78.23 +		err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
   78.24 +						  &alloc_unbound);
   78.25  		if (err == -ENOSYS)
   78.26  			goto err;
   78.27  		BUG_ON(err);
   78.28 -		xen_start_info->store_evtchn = op.u.alloc_unbound.port;
   78.29 +		xen_start_info->store_evtchn = alloc_unbound.port;
   78.30  
   78.31  		/* And finally publish the above info in /proc/xen */
   78.32  		xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
   78.33 @@ -1069,6 +1069,11 @@ static int __init wait_for_devices(void)
   78.34  {
   78.35  	unsigned long timeout = jiffies + 10*HZ;
   78.36  
   78.37 +	if (xen_init() < 0) {
   78.38 +		DPRINTK("failed");
   78.39 +		return -ENODEV;
   78.40 +	}
   78.41 +
   78.42  	while (time_before(jiffies, timeout)) {
   78.43  		if (all_devices_ready())
   78.44  			return 0;
    79.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Mon May 08 13:41:18 2006 -0600
    79.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Mon May 08 14:46:11 2006 -0600
    79.3 @@ -183,7 +183,7 @@ void *xenbus_dev_request_and_reply(struc
    79.4  
    79.5  	mutex_unlock(&xs_state.request_mutex);
    79.6  
    79.7 -	if ((msg->type == XS_TRANSACTION_END) ||
    79.8 +	if ((req_msg.type == XS_TRANSACTION_END) ||
    79.9  	    ((req_msg.type == XS_TRANSACTION_START) &&
   79.10  	     (msg->type == XS_ERROR)))
   79.11  		up_read(&xs_state.suspend_mutex);
    80.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Mon May 08 13:41:18 2006 -0600
    80.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Mon May 08 14:46:11 2006 -0600
    80.3 @@ -33,6 +33,8 @@
    80.4  #ifndef __HYPERCALL_H__
    80.5  #define __HYPERCALL_H__
    80.6  
    80.7 +#include <linux/string.h> /* memcpy() */
    80.8 +
    80.9  #ifndef __HYPERVISOR_H__
   80.10  # error "please don't include this file directly"
   80.11  #endif
   80.12 @@ -245,9 +247,16 @@ HYPERVISOR_update_va_mapping(
   80.13  
   80.14  static inline int
   80.15  HYPERVISOR_event_channel_op(
   80.16 -	void *op)
   80.17 +	int cmd, void *arg)
   80.18  {
   80.19 -	return _hypercall1(int, event_channel_op, op);
   80.20 +	int rc = _hypercall2(int, event_channel_op, cmd, arg);
   80.21 +	if (unlikely(rc == -ENOSYS)) {
   80.22 +		struct evtchn_op op;
   80.23 +		op.cmd = cmd;
   80.24 +		memcpy(&op.u, arg, sizeof(op.u));
   80.25 +		rc = _hypercall1(int, event_channel_op_compat, &op);
   80.26 +	}
   80.27 +	return rc;
   80.28  }
   80.29  
   80.30  static inline int
   80.31 @@ -266,9 +275,16 @@ HYPERVISOR_console_io(
   80.32  
   80.33  static inline int
   80.34  HYPERVISOR_physdev_op(
   80.35 -	void *physdev_op)
   80.36 +	int cmd, void *arg)
   80.37  {
   80.38 -	return _hypercall1(int, physdev_op, physdev_op);
   80.39 +	int rc = _hypercall2(int, physdev_op, cmd, arg);
   80.40 +	if (unlikely(rc == -ENOSYS)) {
   80.41 +		struct physdev_op op;
   80.42 +		op.cmd = cmd;
   80.43 +		memcpy(&op.u, arg, sizeof(op.u));
   80.44 +		rc = _hypercall1(int, physdev_op_compat, &op);
   80.45 +	}
   80.46 +	return rc;
   80.47  }
   80.48  
   80.49  static inline int
    81.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h	Mon May 08 13:41:18 2006 -0600
    81.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h	Mon May 08 14:46:11 2006 -0600
    81.3 @@ -40,6 +40,8 @@
    81.4  #include <linux/errno.h>
    81.5  #include <xen/interface/xen.h>
    81.6  #include <xen/interface/dom0_ops.h>
    81.7 +#include <xen/interface/event_channel.h>
    81.8 +#include <xen/interface/physdev.h>
    81.9  #include <xen/interface/sched.h>
   81.10  #include <xen/interface/nmi.h>
   81.11  #include <asm/ptrace.h>
   81.12 @@ -162,14 +164,14 @@ static inline int
   81.13  HYPERVISOR_poll(
   81.14  	evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
   81.15  {
   81.16 +	int rc;
   81.17  	struct sched_poll sched_poll = {
   81.18 -		.ports = ports,
   81.19  		.nr_ports = nr_ports,
   81.20  		.timeout = jiffies_to_st(timeout)
   81.21  	};
   81.22 +	set_xen_guest_handle(sched_poll.ports, ports);
   81.23  
   81.24 -	int rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
   81.25 -
   81.26 +	rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
   81.27  	if (rc == -ENOSYS)
   81.28  		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
   81.29  
    82.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h	Mon May 08 13:41:18 2006 -0600
    82.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h	Mon May 08 14:46:11 2006 -0600
    82.3 @@ -33,6 +33,9 @@
    82.4  
    82.5  #define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
    82.6  
    82.7 +#define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
    82.8 +#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
    82.9 +
   82.10  #define ptep_get_and_clear(mm,addr,xp)	__pte_ma(xchg(&(xp)->pte_low, 0))
   82.11  #define pte_same(a, b)		((a).pte_low == (b).pte_low)
   82.12  #define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
    83.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h	Mon May 08 13:41:18 2006 -0600
    83.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h	Mon May 08 14:46:11 2006 -0600
    83.3 @@ -107,6 +107,20 @@ static inline void pud_clear (pud_t * pu
    83.4  #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \
    83.5  			pmd_index(address))
    83.6  
    83.7 +/*
    83.8 + * For PTEs and PDEs, we must clear the P-bit first when clearing a page table
    83.9 + * entry, so clear the bottom half first and enforce ordering with a compiler
   83.10 + * barrier.
   83.11 + */
   83.12 +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
   83.13 +{
   83.14 +	ptep->pte_low = 0;
   83.15 +	smp_wmb();
   83.16 +	ptep->pte_high = 0;
   83.17 +}
   83.18 +
   83.19 +#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
   83.20 +
   83.21  static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
   83.22  {
   83.23  	pte_t res;
    84.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h	Mon May 08 13:41:18 2006 -0600
    84.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h	Mon May 08 14:46:11 2006 -0600
    84.3 @@ -205,14 +205,12 @@ extern unsigned long long __PAGE_KERNEL,
    84.4  extern unsigned long pg0[];
    84.5  
    84.6  #define pte_present(x)	((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
    84.7 -#define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
    84.8  
    84.9  /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
   84.10  #define pmd_none(x)	(!(unsigned long)pmd_val(x))
   84.11  /* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
   84.12     can temporarily clear it. */
   84.13  #define pmd_present(x)	(pmd_val(x))
   84.14 -#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
   84.15  #define pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
   84.16  
   84.17  
   84.18 @@ -272,16 +270,7 @@ static inline pte_t ptep_get_and_clear_f
   84.19  	pte_t pte;
   84.20  	if (full) {
   84.21  		pte = *ptep;
   84.22 -#ifdef CONFIG_X86_PAE
   84.23 -		/* Cannot do this in a single step, as the compiler may
   84.24 -		   issue the two stores in either order, but the hypervisor
   84.25 -		   must not see the high part before the low one. */
   84.26 -		ptep->pte_low = 0;
   84.27 -		barrier();
   84.28 -		ptep->pte_high = 0;
   84.29 -#else
   84.30 -		*ptep = __pte(0);
   84.31 -#endif
   84.32 +		pte_clear(mm, addr, ptep);
   84.33  	} else {
   84.34  		pte = ptep_get_and_clear(mm, addr, ptep);
   84.35  	}
    85.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h	Mon May 08 13:41:18 2006 -0600
    85.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h	Mon May 08 14:46:11 2006 -0600
    85.3 @@ -534,12 +534,11 @@ static inline void __load_esp0(struct ts
    85.4   */
    85.5  static inline void set_iopl_mask(unsigned mask)
    85.6  {
    85.7 -	physdev_op_t op;
    85.8 +	struct physdev_set_iopl set_iopl;
    85.9  
   85.10  	/* Force the change at ring 0. */
   85.11 -	op.cmd = PHYSDEVOP_SET_IOPL;
   85.12 -	op.u.set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
   85.13 -	HYPERVISOR_physdev_op(&op);
   85.14 +	set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
   85.15 +	HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
   85.16  }
   85.17  
   85.18  /* Forward declaration, a strange C thing */
    86.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon May 08 13:41:18 2006 -0600
    86.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon May 08 14:46:11 2006 -0600
    86.3 @@ -33,6 +33,8 @@
    86.4  #ifndef __HYPERCALL_H__
    86.5  #define __HYPERCALL_H__
    86.6  
    86.7 +#include <linux/string.h> /* memcpy() */
    86.8 +
    86.9  #ifndef __HYPERVISOR_H__
   86.10  # error "please don't include this file directly"
   86.11  #endif
   86.12 @@ -202,9 +204,16 @@ HYPERVISOR_memory_op(
   86.13  
   86.14  static inline int
   86.15  HYPERVISOR_event_channel_op(
   86.16 -    void *op)
   86.17 +    int cmd, void *arg)
   86.18  {
   86.19 -    return _hypercall1(int, event_channel_op, op);
   86.20 +    int rc = _hypercall2(int, event_channel_op, cmd, arg);
   86.21 +    if (unlikely(rc == -ENOSYS)) {
   86.22 +        struct evtchn_op op;
   86.23 +        op.cmd = cmd;
   86.24 +        memcpy(&op.u, arg, sizeof(op.u));
   86.25 +        rc = _hypercall1(int, event_channel_op_compat, &op);
   86.26 +    }
   86.27 +    return rc;
   86.28  }
   86.29  
   86.30  static inline int
   86.31 @@ -223,9 +232,16 @@ HYPERVISOR_console_io(
   86.32  
   86.33  static inline int
   86.34  HYPERVISOR_physdev_op(
   86.35 -    void *physdev_op)
   86.36 +    int cmd, void *arg)
   86.37  {
   86.38 -    return _hypercall1(int, physdev_op, physdev_op);
   86.39 +    int rc = _hypercall2(int, physdev_op, cmd, arg);
   86.40 +    if (unlikely(rc == -ENOSYS)) {
   86.41 +        struct physdev_op op;
   86.42 +        op.cmd = cmd;
   86.43 +        memcpy(&op.u, arg, sizeof(op.u));
   86.44 +        rc = _hypercall1(int, physdev_op_compat, &op);
   86.45 +    }
   86.46 +    return rc;
   86.47  }
   86.48  
   86.49  static inline int
    87.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Mon May 08 13:41:18 2006 -0600
    87.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Mon May 08 14:46:11 2006 -0600
    87.3 @@ -40,6 +40,8 @@
    87.4  #include <linux/errno.h>
    87.5  #include <xen/interface/xen.h>
    87.6  #include <xen/interface/dom0_ops.h>
    87.7 +#include <xen/interface/event_channel.h>
    87.8 +#include <xen/interface/physdev.h>
    87.9  #include <xen/interface/sched.h>
   87.10  #include <asm/hypercall.h>
   87.11  #include <asm/ptrace.h>
   87.12 @@ -101,13 +103,14 @@ HYPERVISOR_poll(
   87.13  	evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
   87.14  {
   87.15  	struct sched_poll sched_poll = {
   87.16 -		.ports = ports,
   87.17  		.nr_ports = nr_ports,
   87.18  		.timeout = jiffies_to_st(timeout)
   87.19  	};
   87.20  
   87.21 -	int rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
   87.22 +	int rc;
   87.23  
   87.24 +	set_xen_guest_handle(sched_poll.ports, ports);
   87.25 +	rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
   87.26  	if (rc == -ENOSYS)
   87.27  		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
   87.28  
   87.29 @@ -131,7 +134,6 @@ HYPERVISOR_poll(
   87.30  #define	pte_mfn(_x)	pte_pfn(_x)
   87.31  #define __pte_ma(_x)	((pte_t) {(_x)})
   87.32  #define phys_to_machine_mapping_valid(_x)	(1)
   87.33 -#define	kmap_flush_unused()	do {} while (0)
   87.34  #define pfn_pte_ma(_x,_y)	__pte_ma(0)
   87.35  #ifndef CONFIG_XEN_IA64_DOM0_VP //XXX
   87.36  #define set_phys_to_machine(_x,_y)	do {} while (0)
    88.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Mon May 08 13:41:18 2006 -0600
    88.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Mon May 08 14:46:11 2006 -0600
    88.3 @@ -37,6 +37,8 @@
    88.4  #ifndef __HYPERCALL_H__
    88.5  #define __HYPERCALL_H__
    88.6  
    88.7 +#include <linux/string.h> /* memcpy() */
    88.8 +
    88.9  #ifndef __HYPERVISOR_H__
   88.10  # error "please don't include this file directly"
   88.11  #endif
   88.12 @@ -243,9 +245,16 @@ HYPERVISOR_update_va_mapping(
   88.13  
   88.14  static inline int
   88.15  HYPERVISOR_event_channel_op(
   88.16 -	void *op)
   88.17 +	int cmd, void *arg)
   88.18  {
   88.19 -	return _hypercall1(int, event_channel_op, op);
   88.20 +	int rc = _hypercall2(int, event_channel_op, cmd, arg);
   88.21 +	if (unlikely(rc == -ENOSYS)) {
   88.22 +		struct evtchn_op op;
   88.23 +		op.cmd = cmd;
   88.24 +		memcpy(&op.u, arg, sizeof(op.u));
   88.25 +		rc = _hypercall1(int, event_channel_op_compat, &op);
   88.26 +	}
   88.27 +	return rc;
   88.28  }
   88.29  
   88.30  static inline int
   88.31 @@ -264,9 +273,16 @@ HYPERVISOR_console_io(
   88.32  
   88.33  static inline int
   88.34  HYPERVISOR_physdev_op(
   88.35 -	void *physdev_op)
   88.36 +	int cmd, void *arg)
   88.37  {
   88.38 -	return _hypercall1(int, physdev_op, physdev_op);
   88.39 +	int rc = _hypercall2(int, physdev_op, cmd, arg);
   88.40 +	if (unlikely(rc == -ENOSYS)) {
   88.41 +		struct physdev_op op;
   88.42 +		op.cmd = cmd;
   88.43 +		memcpy(&op.u, arg, sizeof(op.u));
   88.44 +		rc = _hypercall1(int, physdev_op_compat, &op);
   88.45 +	}
   88.46 +	return rc;
   88.47  }
   88.48  
   88.49  static inline int
    89.1 --- a/linux-2.6-xen-sparse/include/linux/mm.h	Mon May 08 13:41:18 2006 -0600
    89.2 +++ b/linux-2.6-xen-sparse/include/linux/mm.h	Mon May 08 14:46:11 2006 -0600
    89.3 @@ -232,10 +232,9 @@ struct page {
    89.4  		unsigned long private;		/* Mapping-private opaque data:
    89.5  					 	 * usually used for buffer_heads
    89.6  						 * if PagePrivate set; used for
    89.7 -						 * swp_entry_t if PageSwapCache.
    89.8 -						 * When page is free, this
    89.9 +						 * swp_entry_t if PageSwapCache;
   89.10  						 * indicates order in the buddy
   89.11 -						 * system.
   89.12 +						 * system if PG_buddy is set.
   89.13  						 */
   89.14  		struct address_space *mapping;	/* If low bit clear, points to
   89.15  						 * inode address_space, or NULL.
   89.16 @@ -248,9 +247,6 @@ struct page {
   89.17  #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
   89.18  	    spinlock_t ptl;
   89.19  #endif
   89.20 -#ifdef CONFIG_XEN
   89.21 -	    struct list_head ballooned;
   89.22 -#endif
   89.23  	};
   89.24  	pgoff_t index;			/* Our offset within mapping. */
   89.25  	struct list_head lru;		/* Pageout list, eg. active_list
    90.1 --- a/linux-2.6-xen-sparse/include/xen/evtchn.h	Mon May 08 13:41:18 2006 -0600
    90.2 +++ b/linux-2.6-xen-sparse/include/xen/evtchn.h	Mon May 08 14:46:11 2006 -0600
    90.3 @@ -101,10 +101,8 @@ static inline void clear_evtchn(int port
    90.4  
    90.5  static inline void notify_remote_via_evtchn(int port)
    90.6  {
    90.7 -	evtchn_op_t op;
    90.8 -	op.cmd         = EVTCHNOP_send,
    90.9 -	op.u.send.port = port;
   90.10 -	(void)HYPERVISOR_event_channel_op(&op);
   90.11 +	struct evtchn_send send = { .port = port };
   90.12 +	(void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
   90.13  }
   90.14  
   90.15  /*
    91.1 --- a/linux-2.6-xen-sparse/include/xen/public/privcmd.h	Mon May 08 13:41:18 2006 -0600
    91.2 +++ b/linux-2.6-xen-sparse/include/xen/public/privcmd.h	Mon May 08 14:46:11 2006 -0600
    91.3 @@ -62,13 +62,6 @@ typedef struct privcmd_mmapbatch {
    91.4  	unsigned long __user *arr; /* array of mfns - top nibble set on err */
    91.5  } privcmd_mmapbatch_t; 
    91.6  
    91.7 -typedef struct privcmd_blkmsg
    91.8 -{
    91.9 -	unsigned long op;
   91.10 -	void         *buf;
   91.11 -	int           buf_size;
   91.12 -} privcmd_blkmsg_t;
   91.13 -
   91.14  /*
   91.15   * @cmd: IOCTL_PRIVCMD_HYPERCALL
   91.16   * @arg: &privcmd_hypercall_t
    92.1 --- a/linux-2.6-xen-sparse/include/xen/tpmfe.h	Mon May 08 13:41:18 2006 -0600
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,40 +0,0 @@
    92.4 -#ifndef TPM_FE_H
    92.5 -#define TPM_FE_H
    92.6 -
    92.7 -struct tpm_private;
    92.8 -
    92.9 -struct tpmfe_device {
   92.10 -	/*
   92.11 -	 * Let upper layer receive data from front-end
   92.12 -	 */
   92.13 -	int (*receive)(const u8 *buffer, size_t count, const void *ptr);
   92.14 -	/*
   92.15 -	 * Indicate the status of the front-end to the upper
   92.16 -	 * layer.
   92.17 -	 */
   92.18 -	void (*status)(unsigned int flags);
   92.19 -
   92.20 -	/*
   92.21 -	 * This field indicates the maximum size the driver can
   92.22 -	 * transfer in one chunk. It is filled out by the front-end
   92.23 -	 * driver and should be propagated to the generic tpm driver
   92.24 -	 * for allocation of buffers.
   92.25 -	 */
   92.26 -	unsigned int max_tx_size;
   92.27 -	/*
   92.28 -	 * The following is a private structure of the underlying
   92.29 -	 * driver. It's expected as first parameter in the send function.
   92.30 -	 */
   92.31 -	struct tpm_private *tpm_private;
   92.32 -};
   92.33 -
   92.34 -enum {
   92.35 -	TPMFE_STATUS_DISCONNECTED = 0x0,
   92.36 -	TPMFE_STATUS_CONNECTED = 0x1
   92.37 -};
   92.38 -
   92.39 -int tpm_fe_send(struct tpm_private * tp, const u8 * buf, size_t count, void *ptr);
   92.40 -int tpm_fe_register_receiver(struct tpmfe_device *);
   92.41 -void tpm_fe_unregister_receiver(void);
   92.42 -
   92.43 -#endif
    93.1 --- a/linux-2.6-xen-sparse/lib/Makefile	Mon May 08 13:41:18 2006 -0600
    93.2 +++ b/linux-2.6-xen-sparse/lib/Makefile	Mon May 08 14:46:11 2006 -0600
    93.3 @@ -45,7 +45,7 @@ obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
    93.4  obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
    93.5  
    93.6  obj-$(CONFIG_SWIOTLB) += swiotlb.o
    93.7 -ifneq ($(CONFIG_IA64),y)
    93.8 +ifneq ($(CONFIG_XEN_IA64_DOM0_NON_VP),y)
    93.9  swiotlb-$(CONFIG_XEN) := ../arch/i386/kernel/swiotlb.o
   93.10  endif
   93.11  
    94.1 --- a/linux-2.6-xen-sparse/mm/Kconfig	Mon May 08 13:41:18 2006 -0600
    94.2 +++ b/linux-2.6-xen-sparse/mm/Kconfig	Mon May 08 14:46:11 2006 -0600
    94.3 @@ -126,14 +126,14 @@ comment "Memory hotplug is currently inc
    94.4  # Default to 4 for wider testing, though 8 might be more appropriate.
    94.5  # ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
    94.6  # PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
    94.7 -# XEN uses the mapping field on pagetable pages to store a pointer to
    94.8 -# the destructor.
    94.9 +# XEN on x86 architecture uses the mapping field on pagetable pages to store a
   94.10 +# pointer to the destructor. This conflicts with pte_lock_deinit().
   94.11  #
   94.12  config SPLIT_PTLOCK_CPUS
   94.13  	int
   94.14  	default "4096" if ARM && !CPU_CACHE_VIPT
   94.15  	default "4096" if PARISC && !PA20
   94.16 -	default "4096" if XEN
   94.17 +	default "4096" if X86_XEN || X86_64_XEN
   94.18  	default "4"
   94.19  
   94.20  #
    95.1 --- a/linux-2.6-xen-sparse/mm/memory.c	Mon May 08 13:41:18 2006 -0600
    95.2 +++ b/linux-2.6-xen-sparse/mm/memory.c	Mon May 08 14:46:11 2006 -0600
    95.3 @@ -968,6 +968,7 @@ int get_user_pages(struct task_struct *t
    95.4  {
    95.5  	int i;
    95.6  	unsigned int vm_flags;
    95.7 +	int xenpage = 0;
    95.8  
    95.9  	/* 
   95.10  	 * Require read or write permissions.
   95.11 @@ -1025,10 +1026,14 @@ int get_user_pages(struct task_struct *t
   95.12  		if (vma && (vma->vm_flags & VM_FOREIGN)) {
   95.13  			struct page **map = vma->vm_private_data;
   95.14  			int offset = (start - vma->vm_start) >> PAGE_SHIFT;
   95.15 -
   95.16 +			xenpage =1;
   95.17  			if (map[offset] != NULL) {
   95.18 -				if (pages)
   95.19 -					pages[i] = map[offset];
   95.20 +			        if (pages) {
   95.21 +			                struct page *page = map[offset];
   95.22 +					
   95.23 +					pages[i] = page;
   95.24 +					get_page(page);
   95.25 +				}
   95.26  				if (vmas)
   95.27  					vmas[i] = vma;
   95.28  				i++;
    96.1 --- a/linux-2.6-xen-sparse/mm/page_alloc.c	Mon May 08 13:41:18 2006 -0600
    96.2 +++ b/linux-2.6-xen-sparse/mm/page_alloc.c	Mon May 08 14:46:11 2006 -0600
    96.3 @@ -153,7 +153,8 @@ static void bad_page(struct page *page)
    96.4  			1 << PG_reclaim |
    96.5  			1 << PG_slab    |
    96.6  			1 << PG_swapcache |
    96.7 -			1 << PG_writeback );
    96.8 +			1 << PG_writeback |
    96.9 +			1 << PG_buddy );
   96.10  	set_page_count(page, 0);
   96.11  	reset_page_mapcount(page);
   96.12  	page->mapping = NULL;
   96.13 @@ -224,12 +225,12 @@ static inline unsigned long page_order(s
   96.14  
   96.15  static inline void set_page_order(struct page *page, int order) {
   96.16  	set_page_private(page, order);
   96.17 -	__SetPagePrivate(page);
   96.18 +	__SetPageBuddy(page);
   96.19  }
   96.20  
   96.21  static inline void rmv_page_order(struct page *page)
   96.22  {
   96.23 -	__ClearPagePrivate(page);
   96.24 +	__ClearPageBuddy(page);
   96.25  	set_page_private(page, 0);
   96.26  }
   96.27  
   96.28 @@ -268,11 +269,13 @@ static inline unsigned long
   96.29   * This function checks whether a page is free && is the buddy
   96.30   * we can do coalesce a page and its buddy if
   96.31   * (a) the buddy is not in a hole &&
   96.32 - * (b) the buddy is free &&
   96.33 - * (c) the buddy is on the buddy system &&
   96.34 - * (d) a page and its buddy have the same order.
   96.35 - * for recording page's order, we use page_private(page) and PG_private.
   96.36 + * (b) the buddy is in the buddy system &&
   96.37 + * (c) a page and its buddy have the same order.
   96.38   *
   96.39 + * For recording whether a page is in the buddy system, we use PG_buddy.
   96.40 + * Setting, clearing, and testing PG_buddy is serialized by zone->lock.
   96.41 + *
   96.42 + * For recording page's order, we use page_private(page).
   96.43   */
   96.44  static inline int page_is_buddy(struct page *page, int order)
   96.45  {
   96.46 @@ -281,10 +284,10 @@ static inline int page_is_buddy(struct p
   96.47  		return 0;
   96.48  #endif
   96.49  
   96.50 -       if (PagePrivate(page)           &&
   96.51 -           (page_order(page) == order) &&
   96.52 -            page_count(page) == 0)
   96.53 +	if (PageBuddy(page) && page_order(page) == order) {
   96.54 +		BUG_ON(page_count(page) != 0);
   96.55                 return 1;
   96.56 +	}
   96.57         return 0;
   96.58  }
   96.59  
   96.60 @@ -301,7 +304,7 @@ static inline int page_is_buddy(struct p
   96.61   * as necessary, plus some accounting needed to play nicely with other
   96.62   * parts of the VM system.
   96.63   * At each level, we keep a list of pages, which are heads of continuous
   96.64 - * free pages of length of (1 << order) and marked with PG_Private.Page's
   96.65 + * free pages of length of (1 << order) and marked with PG_buddy. Page's
   96.66   * order is recorded in page_private(page) field.
   96.67   * So when we are allocating or freeing one, we can derive the state of the
   96.68   * other.  That is, if we allocate a small block, and both were   
   96.69 @@ -364,7 +367,8 @@ static inline int free_pages_check(struc
   96.70  			1 << PG_slab	|
   96.71  			1 << PG_swapcache |
   96.72  			1 << PG_writeback |
   96.73 -			1 << PG_reserved ))))
   96.74 +			1 << PG_reserved |
   96.75 +			1 << PG_buddy ))))
   96.76  		bad_page(page);
   96.77  	if (PageDirty(page))
   96.78  		__ClearPageDirty(page);
   96.79 @@ -523,7 +527,8 @@ static int prep_new_page(struct page *pa
   96.80  			1 << PG_slab    |
   96.81  			1 << PG_swapcache |
   96.82  			1 << PG_writeback |
   96.83 -			1 << PG_reserved ))))
   96.84 +			1 << PG_reserved |
   96.85 +			1 << PG_buddy ))))
   96.86  		bad_page(page);
   96.87  
   96.88  	/*
    97.1 --- a/linux-2.6-xen-sparse/net/core/dev.c	Mon May 08 13:41:18 2006 -0600
    97.2 +++ b/linux-2.6-xen-sparse/net/core/dev.c	Mon May 08 14:46:11 2006 -0600
    97.3 @@ -2994,11 +2994,11 @@ void netdev_run_todo(void)
    97.4  
    97.5  		switch(dev->reg_state) {
    97.6  		case NETREG_REGISTERING:
    97.7 +			dev->reg_state = NETREG_REGISTERED;
    97.8  			err = netdev_register_sysfs(dev);
    97.9  			if (err)
   97.10  				printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
   97.11  				       dev->name, err);
   97.12 -			dev->reg_state = NETREG_REGISTERED;
   97.13  			break;
   97.14  
   97.15  		case NETREG_UNREGISTERING:
    98.1 --- a/linux-2.6-xen-sparse/scripts/Makefile.xen	Mon May 08 13:41:18 2006 -0600
    98.2 +++ b/linux-2.6-xen-sparse/scripts/Makefile.xen	Mon May 08 14:46:11 2006 -0600
    98.3 @@ -2,9 +2,9 @@
    98.4  # cherrypickxen($1 = allobj)
    98.5  cherrypickxen = $(foreach var, $(1), \
    98.6  		$(shell o=$(var); \
    98.7 -			c=$${o/%.o/-xen.c}; \
    98.8 -			s=$${o/%.o/-xen.S}; \
    98.9 -			oxen=$${o/%.o/-xen.o}; \
   98.10 +			c=$${o%.o}-xen.c; \
   98.11 +			s=$${o%.o}-xen.S; \
   98.12 +			oxen=$${o%.o}-xen.o; \
   98.13  			[ -f $(srctree)/$(src)/$${c} ] || \
   98.14  			   [ -f $(srctree)/$(src)/$${s} ] \
   98.15  				&& echo $$oxen \
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/patches/linux-2.6.16.13/device_bind.patch	Mon May 08 14:46:11 2006 -0600
    99.3 @@ -0,0 +1,15 @@
    99.4 +diff -pruN ../pristine-linux-2.6.16.13/drivers/base/bus.c ./drivers/base/bus.c
    99.5 +--- ../pristine-linux-2.6.16.13/drivers/base/bus.c	2006-05-02 22:38:44.000000000 +0100
    99.6 ++++ ./drivers/base/bus.c	2006-05-04 17:41:30.000000000 +0100
    99.7 +@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
    99.8 + 		up(&dev->sem);
    99.9 + 		if (dev->parent)
   99.10 + 			up(&dev->parent->sem);
   99.11 ++
   99.12 ++		if (err > 0) 		/* success */
   99.13 ++			err = count;
   99.14 ++		else if (err == 0)	/* driver didn't accept device */
   99.15 ++			err = -ENODEV;
   99.16 + 	}
   99.17 + 	put_device(dev);
   99.18 + 	put_bus(bus);
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/patches/linux-2.6.16.13/i386-mach-io-check-nmi.patch	Mon May 08 14:46:11 2006 -0600
   100.3 @@ -0,0 +1,45 @@
   100.4 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
   100.5 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/traps.c	2006-05-02 22:38:44.000000000 +0100
   100.6 ++++ ./arch/i386/kernel/traps.c	2006-05-04 17:41:34.000000000 +0100
   100.7 +@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
   100.8 + 
   100.9 + static void io_check_error(unsigned char reason, struct pt_regs * regs)
  100.10 + {
  100.11 +-	unsigned long i;
  100.12 +-
  100.13 + 	printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
  100.14 + 	show_registers(regs);
  100.15 + 
  100.16 + 	/* Re-enable the IOCK line, wait for a few seconds */
  100.17 +-	reason = (reason & 0xf) | 8;
  100.18 +-	outb(reason, 0x61);
  100.19 +-	i = 2000;
  100.20 +-	while (--i) udelay(1000);
  100.21 +-	reason &= ~8;
  100.22 +-	outb(reason, 0x61);
  100.23 ++	clear_io_check_error(reason);
  100.24 + }
  100.25 + 
  100.26 + static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
  100.27 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
  100.28 +--- ../pristine-linux-2.6.16.13/include/asm-i386/mach-default/mach_traps.h	2006-05-02 22:38:44.000000000 +0100
  100.29 ++++ ./include/asm-i386/mach-default/mach_traps.h	2006-05-04 17:41:34.000000000 +0100
  100.30 +@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
  100.31 + 	outb(reason, 0x61);
  100.32 + }
  100.33 + 
  100.34 ++static inline void clear_io_check_error(unsigned char reason)
  100.35 ++{
  100.36 ++	unsigned long i;
  100.37 ++
  100.38 ++	reason = (reason & 0xf) | 8;
  100.39 ++	outb(reason, 0x61);
  100.40 ++	i = 2000;
  100.41 ++	while (--i) udelay(1000);
  100.42 ++	reason &= ~8;
  100.43 ++	outb(reason, 0x61);
  100.44 ++}
  100.45 ++
  100.46 + static inline unsigned char get_nmi_reason(void)
  100.47 + {
  100.48 + 	return inb(0x61);
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/patches/linux-2.6.16.13/net-csum.patch	Mon May 08 14:46:11 2006 -0600
   101.3 @@ -0,0 +1,64 @@
   101.4 +diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
   101.5 +--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-05-02 22:38:44.000000000 +0100
   101.6 ++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-05-04 17:41:37.000000000 +0100
   101.7 +@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
   101.8 + 	if (hdrsize < sizeof(*hdr))
   101.9 + 		return 1;
  101.10 + 
  101.11 +-	hdr->check = ip_nat_cheat_check(~oldip, newip,
  101.12 ++	if ((*pskb)->proto_csum_blank) {
  101.13 ++		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
  101.14 ++	} else {
  101.15 ++		hdr->check = ip_nat_cheat_check(~oldip, newip,
  101.16 + 					ip_nat_cheat_check(oldport ^ 0xFFFF,
  101.17 + 							   newport,
  101.18 + 							   hdr->check));
  101.19 ++	}
  101.20 + 	return 1;
  101.21 + }
  101.22 + 
  101.23 +diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
  101.24 +--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-05-02 22:38:44.000000000 +0100
  101.25 ++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c	2006-05-04 17:41:37.000000000 +0100
  101.26 +@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
  101.27 + 		newport = tuple->dst.u.udp.port;
  101.28 + 		portptr = &hdr->dest;
  101.29 + 	}
  101.30 +-	if (hdr->check) /* 0 is a special case meaning no checksum */
  101.31 +-		hdr->check = ip_nat_cheat_check(~oldip, newip,
  101.32 ++	if (hdr->check) { /* 0 is a special case meaning no checksum */
  101.33 ++		if ((*pskb)->proto_csum_blank) {
  101.34 ++			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
  101.35 ++		} else {
  101.36 ++			hdr->check = ip_nat_cheat_check(~oldip, newip,
  101.37 + 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
  101.38 + 							   newport,
  101.39 + 							   hdr->check));
  101.40 ++		}
  101.41 ++	}
  101.42 + 	*portptr = newport;
  101.43 + 	return 1;
  101.44 + }
  101.45 +diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c
  101.46 +--- ../pristine-linux-2.6.16.13/net/ipv4/xfrm4_output.c	2006-05-02 22:38:44.000000000 +0100
  101.47 ++++ ./net/ipv4/xfrm4_output.c	2006-05-04 17:41:37.000000000 +0100
  101.48 +@@ -17,6 +17,8 @@
  101.49 + #include <net/xfrm.h>
  101.50 + #include <net/icmp.h>
  101.51 + 
  101.52 ++extern int skb_checksum_setup(struct sk_buff *skb);
  101.53 ++
  101.54 + /* Add encapsulation header.
  101.55 +  *
  101.56 +  * In transport mode, the IP header will be moved forward to make space
  101.57 +@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu
  101.58 + 	struct xfrm_state *x = dst->xfrm;
  101.59 + 	int err;
  101.60 + 	
  101.61 ++	err = skb_checksum_setup(skb);
  101.62 ++	if (err)
  101.63 ++		goto error_nolock;
  101.64 ++
  101.65 + 	if (skb->ip_summed == CHECKSUM_HW) {
  101.66 + 		err = skb_checksum_help(skb, 0);
  101.67 + 		if (err)
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/patches/linux-2.6.16.13/pmd-shared.patch	Mon May 08 14:46:11 2006 -0600
   102.3 @@ -0,0 +1,111 @@
   102.4 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
   102.5 +--- ../pristine-linux-2.6.16.13/arch/i386/mm/pageattr.c	2006-05-02 22:38:44.000000000 +0100
   102.6 ++++ ./arch/i386/mm/pageattr.c	2006-05-04 17:41:40.000000000 +0100
   102.7 +@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
   102.8 + 	unsigned long flags;
   102.9 + 
  102.10 + 	set_pte_atomic(kpte, pte); 	/* change init_mm */
  102.11 +-	if (PTRS_PER_PMD > 1)
  102.12 ++	if (HAVE_SHARED_KERNEL_PMD)
  102.13 + 		return;
  102.14 + 
  102.15 + 	spin_lock_irqsave(&pgd_lock, flags);
  102.16 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
  102.17 +--- ../pristine-linux-2.6.16.13/arch/i386/mm/pgtable.c	2006-05-02 22:38:44.000000000 +0100
  102.18 ++++ ./arch/i386/mm/pgtable.c	2006-05-04 17:41:40.000000000 +0100
  102.19 +@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
  102.20 + 		spin_lock_irqsave(&pgd_lock, flags);
  102.21 + 	}
  102.22 + 
  102.23 +-	clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
  102.24 +-			swapper_pg_dir + USER_PTRS_PER_PGD,
  102.25 +-			KERNEL_PGD_PTRS);
  102.26 ++	if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
  102.27 ++		clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
  102.28 ++				swapper_pg_dir + USER_PTRS_PER_PGD,
  102.29 ++				KERNEL_PGD_PTRS);
  102.30 + 	if (PTRS_PER_PMD > 1)
  102.31 + 		return;
  102.32 + 
  102.33 +@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
  102.34 + 			goto out_oom;
  102.35 + 		set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
  102.36 + 	}
  102.37 ++
  102.38 ++	if (!HAVE_SHARED_KERNEL_PMD) {
  102.39 ++		unsigned long flags;
  102.40 ++
  102.41 ++		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
  102.42 ++			pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
  102.43 ++			if (!pmd)
  102.44 ++				goto out_oom;
  102.45 ++			set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
  102.46 ++		}
  102.47 ++
  102.48 ++		spin_lock_irqsave(&pgd_lock, flags);
  102.49 ++		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
  102.50 ++			unsigned long v = (unsigned long)i << PGDIR_SHIFT;
  102.51 ++			pgd_t *kpgd = pgd_offset_k(v);
  102.52 ++			pud_t *kpud = pud_offset(kpgd, v);
  102.53 ++			pmd_t *kpmd = pmd_offset(kpud, v);
  102.54 ++			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
  102.55 ++			memcpy(pmd, kpmd, PAGE_SIZE);
  102.56 ++		}
  102.57 ++		pgd_list_add(pgd);
  102.58 ++		spin_unlock_irqrestore(&pgd_lock, flags);
  102.59 ++	}
  102.60 ++
  102.61 + 	return pgd;
  102.62 + 
  102.63 + out_oom:
  102.64 +@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
  102.65 + 	int i;
  102.66 + 
  102.67 + 	/* in the PAE case user pgd entries are overwritten before usage */
  102.68 +-	if (PTRS_PER_PMD > 1)
  102.69 +-		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
  102.70 +-			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
  102.71 ++	if (PTRS_PER_PMD > 1) {
  102.72 ++		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
  102.73 ++			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
  102.74 ++			kmem_cache_free(pmd_cache, pmd);
  102.75 ++		}
  102.76 ++		if (!HAVE_SHARED_KERNEL_PMD) {
  102.77 ++			unsigned long flags;
  102.78 ++			spin_lock_irqsave(&pgd_lock, flags);
  102.79 ++			pgd_list_del(pgd);
  102.80 ++			spin_unlock_irqrestore(&pgd_lock, flags);
  102.81 ++			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
  102.82 ++				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
  102.83 ++				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
  102.84 ++				kmem_cache_free(pmd_cache, pmd);
  102.85 ++			}
  102.86 ++		}
  102.87 ++	}
  102.88 + 	/* in the non-PAE case, free_pgtables() clears user pgd entries */
  102.89 + 	kmem_cache_free(pgd_cache, pgd);
  102.90 + }
  102.91 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
  102.92 +--- ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-2level-defs.h	2006-05-02 22:38:44.000000000 +0100
  102.93 ++++ ./include/asm-i386/pgtable-2level-defs.h	2006-05-04 17:41:40.000000000 +0100
  102.94 +@@ -1,6 +1,8 @@
  102.95 + #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
  102.96 + #define _I386_PGTABLE_2LEVEL_DEFS_H
  102.97 + 
  102.98 ++#define HAVE_SHARED_KERNEL_PMD 0
  102.99 ++
 102.100 + /*
 102.101 +  * traditional i386 two-level paging structure:
 102.102 +  */
 102.103 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
 102.104 +--- ../pristine-linux-2.6.16.13/include/asm-i386/pgtable-3level-defs.h	2006-05-02 22:38:44.000000000 +0100
 102.105 ++++ ./include/asm-i386/pgtable-3level-defs.h	2006-05-04 17:41:40.000000000 +0100
 102.106 +@@ -1,6 +1,8 @@
 102.107 + #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
 102.108 + #define _I386_PGTABLE_3LEVEL_DEFS_H
 102.109 + 
 102.110 ++#define HAVE_SHARED_KERNEL_PMD 1
 102.111 ++
 102.112 + /*
 102.113 +  * PGDIR_SHIFT determines what a top-level page table entry can map
 102.114 +  */
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/patches/linux-2.6.16.13/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch	Mon May 08 14:46:11 2006 -0600
   103.3 @@ -0,0 +1,30 @@
   103.4 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
   103.5 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S	2006-05-02 22:38:44.000000000 +0100
   103.6 ++++ ./arch/i386/kernel/entry.S	2006-05-04 17:41:44.000000000 +0100
   103.7 +@@ -177,7 +177,7 @@ need_resched:
   103.8 + 
   103.9 + 	# sysenter call handler stub
  103.10 + ENTRY(sysenter_entry)
  103.11 +-	movl TSS_sysenter_esp0(%esp),%esp
  103.12 ++	movl SYSENTER_stack_esp0(%esp),%esp
  103.13 + sysenter_past_esp:
  103.14 + 	sti
  103.15 + 	pushl $(__USER_DS)
  103.16 +@@ -492,7 +492,7 @@ device_not_available_emulate:
  103.17 +  * that sets up the real kernel stack. Check here, since we can't
  103.18 +  * allow the wrong stack to be used.
  103.19 +  *
  103.20 +- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
  103.21 ++ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
  103.22 +  * already pushed 3 words if it hits on the sysenter instruction:
  103.23 +  * eflags, cs and eip.
  103.24 +  *
  103.25 +@@ -504,7 +504,7 @@ device_not_available_emulate:
  103.26 + 	cmpw $__KERNEL_CS,4(%esp);		\
  103.27 + 	jne ok;					\
  103.28 + label:						\
  103.29 +-	movl TSS_sysenter_esp0+offset(%esp),%esp;	\
  103.30 ++	movl SYSENTER_stack_esp0+offset(%esp),%esp;	\
  103.31 + 	pushfl;					\
  103.32 + 	pushl $__KERNEL_CS;			\
  103.33 + 	pushl $sysenter_past_esp
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/patches/linux-2.6.16.13/smp-alts.patch	Mon May 08 14:46:11 2006 -0600
   104.3 @@ -0,0 +1,591 @@
   104.4 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/Kconfig ./arch/i386/Kconfig
   104.5 +--- ../pristine-linux-2.6.16.13/arch/i386/Kconfig	2006-05-02 22:38:44.000000000 +0100
   104.6 ++++ ./arch/i386/Kconfig	2006-05-04 17:41:45.000000000 +0100
   104.7 +@@ -202,6 +202,19 @@ config SMP
   104.8 + 
   104.9 + 	  If you don't know what to do here, say N.
  104.10 + 
  104.11 ++config SMP_ALTERNATIVES
  104.12 ++	bool "SMP alternatives support (EXPERIMENTAL)"
  104.13 ++	depends on SMP && EXPERIMENTAL
  104.14 ++	help
  104.15 ++	  Try to reduce the overhead of running an SMP kernel on a uniprocessor
  104.16 ++	  host slightly by replacing certain key instruction sequences
  104.17 ++	  according to whether we currently have more than one CPU available.
  104.18 ++	  This should provide a noticeable boost to performance when
  104.19 ++	  running SMP kernels on UP machines, and have negligible impact
  104.20 ++	  when running on an true SMP host.
  104.21 ++
  104.22 ++          If unsure, say N.
  104.23 ++	  
  104.24 + config NR_CPUS
  104.25 + 	int "Maximum number of CPUs (2-255)"
  104.26 + 	range 2 255
  104.27 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
  104.28 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/Makefile	2006-05-02 22:38:44.000000000 +0100
  104.29 ++++ ./arch/i386/kernel/Makefile	2006-05-04 17:41:45.000000000 +0100
  104.30 +@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
  104.31 + obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
  104.32 + obj-$(CONFIG_VM86)		+= vm86.o
  104.33 + obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
  104.34 ++obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
  104.35 + 
  104.36 + EXTRA_AFLAGS   := -traditional
  104.37 + 
  104.38 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
  104.39 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/smpalts.c	1970-01-01 01:00:00.000000000 +0100
  104.40 ++++ ./arch/i386/kernel/smpalts.c	2006-05-04 17:41:45.000000000 +0100
  104.41 +@@ -0,0 +1,85 @@
  104.42 ++#include <linux/kernel.h>
  104.43 ++#include <asm/system.h>
  104.44 ++#include <asm/smp_alt.h>
  104.45 ++#include <asm/processor.h>
  104.46 ++#include <asm/string.h>
  104.47 ++
  104.48 ++struct smp_replacement_record {
  104.49 ++	unsigned char targ_size;
  104.50 ++	unsigned char smp1_size;
  104.51 ++	unsigned char smp2_size;
  104.52 ++	unsigned char up_size;
  104.53 ++	unsigned char feature;
  104.54 ++	unsigned char data[0];
  104.55 ++};
  104.56 ++
  104.57 ++struct smp_alternative_record {
  104.58 ++	void *targ_start;
  104.59 ++	struct smp_replacement_record *repl;
  104.60 ++};
  104.61 ++
  104.62 ++extern struct smp_alternative_record __start_smp_alternatives_table,
  104.63 ++  __stop_smp_alternatives_table;
  104.64 ++extern unsigned long __init_begin, __init_end;
  104.65 ++
  104.66 ++void prepare_for_smp(void)
  104.67 ++{
  104.68 ++	struct smp_alternative_record *r;
  104.69 ++	printk(KERN_INFO "Enabling SMP...\n");
  104.70 ++	for (r = &__start_smp_alternatives_table;
  104.71 ++	     r != &__stop_smp_alternatives_table;
  104.72 ++	     r++) {
  104.73 ++		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
  104.74 ++		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
  104.75 ++		BUG_ON(r->repl->targ_size < r->repl->up_size);
  104.76 ++               if (system_state == SYSTEM_RUNNING &&
  104.77 ++                   r->targ_start >= (void *)&__init_begin &&
  104.78 ++                   r->targ_start < (void *)&__init_end)
  104.79 ++                       continue;
  104.80 ++		if (r->repl->feature != (unsigned char)-1 &&
  104.81 ++		    boot_cpu_has(r->repl->feature)) {
  104.82 ++			memcpy(r->targ_start,
  104.83 ++			       r->repl->data + r->repl->smp1_size,
  104.84 ++			       r->repl->smp2_size);
  104.85 ++			memset(r->targ_start + r->repl->smp2_size,
  104.86 ++			       0x90,
  104.87 ++			       r->repl->targ_size - r->repl->smp2_size);
  104.88 ++		} else {
  104.89 ++			memcpy(r->targ_start,
  104.90 ++			       r->repl->data,
  104.91 ++			       r->repl->smp1_size);
  104.92 ++			memset(r->targ_start + r->repl->smp1_size,
  104.93 ++			       0x90,
  104.94 ++			       r->repl->targ_size - r->repl->smp1_size);
  104.95 ++		}
  104.96 ++	}
  104.97 ++	/* Paranoia */
  104.98 ++	asm volatile ("jmp 1f\n1:");
  104.99 ++	mb();
 104.100 ++}
 104.101 ++
 104.102 ++void unprepare_for_smp(void)
 104.103 ++{
 104.104 ++	struct smp_alternative_record *r;
 104.105 ++	printk(KERN_INFO "Disabling SMP...\n");
 104.106 ++	for (r = &__start_smp_alternatives_table;
 104.107 ++	     r != &__stop_smp_alternatives_table;
 104.108 ++	     r++) {
 104.109 ++		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
 104.110 ++		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
 104.111 ++		BUG_ON(r->repl->targ_size < r->repl->up_size);
 104.112 ++               if (system_state == SYSTEM_RUNNING &&
 104.113 ++                   r->targ_start >= (void *)&__init_begin &&
 104.114 ++                   r->targ_start < (void *)&__init_end)
 104.115 ++                       continue;
 104.116 ++		memcpy(r->targ_start,
 104.117 ++		       r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
 104.118 ++		       r->repl->up_size);
 104.119 ++		memset(r->targ_start + r->repl->up_size,
 104.120 ++		       0x90,
 104.121 ++		       r->repl->targ_size - r->repl->up_size);
 104.122 ++	}
 104.123 ++	/* Paranoia */
 104.124 ++	asm volatile ("jmp 1f\n1:");
 104.125 ++	mb();
 104.126 ++}
 104.127 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
 104.128 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/smpboot.c	2006-05-02 22:38:44.000000000 +0100
 104.129 ++++ ./arch/i386/kernel/smpboot.c	2006-05-04 17:41:45.000000000 +0100
 104.130 +@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne
 104.131 + 		if (max_cpus <= cpucount+1)
 104.132 + 			continue;
 104.133 + 
 104.134 ++#ifdef CONFIG_SMP_ALTERNATIVES
 104.135 ++		if (kicked == 1)
 104.136 ++			prepare_for_smp();
 104.137 ++#endif
 104.138 ++
 104.139 + 		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
 104.140 + 			printk("CPU #%d not responding - cannot use it.\n",
 104.141 + 								apicid);
 104.142 +@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu)
 104.143 + 		return -EIO;
 104.144 + 	}
 104.145 + 
 104.146 ++#ifdef CONFIG_SMP_ALTERNATIVES
 104.147 ++	if (num_online_cpus() == 1)
 104.148 ++		prepare_for_smp();
 104.149 ++#endif
 104.150 ++
 104.151 + 	local_irq_enable();
 104.152 + 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 104.153 + 	/* Unleash the CPU! */
 104.154 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
 104.155 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/vmlinux.lds.S	2006-05-02 22:38:44.000000000 +0100
 104.156 ++++ ./arch/i386/kernel/vmlinux.lds.S	2006-05-04 17:41:45.000000000 +0100
 104.157 +@@ -34,6 +34,13 @@ SECTIONS
 104.158 +   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
 104.159 +   __stop___ex_table = .;
 104.160 + 
 104.161 ++  . = ALIGN(16);
 104.162 ++  __start_smp_alternatives_table = .;
 104.163 ++  __smp_alternatives : { *(__smp_alternatives) }
 104.164 ++  __stop_smp_alternatives_table = .;
 104.165 ++
 104.166 ++  __smp_replacements : { *(__smp_replacements) }
 104.167 ++
 104.168 +   RODATA
 104.169 + 
 104.170 +   /* writeable */
 104.171 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
 104.172 +--- ../pristine-linux-2.6.16.13/include/asm-i386/atomic.h	2006-05-02 22:38:44.000000000 +0100
 104.173 ++++ ./include/asm-i386/atomic.h	2006-05-04 17:41:45.000000000 +0100
 104.174 +@@ -4,18 +4,13 @@
 104.175 + #include <linux/config.h>
 104.176 + #include <linux/compiler.h>
 104.177 + #include <asm/processor.h>
 104.178 ++#include <asm/smp_alt.h>
 104.179 + 
 104.180 + /*
 104.181 +  * Atomic operations that C can't guarantee us.  Useful for
 104.182 +  * resource counting etc..
 104.183 +  */
 104.184 + 
 104.185 +-#ifdef CONFIG_SMP
 104.186 +-#define LOCK "lock ; "
 104.187 +-#else
 104.188 +-#define LOCK ""
 104.189 +-#endif
 104.190 +-
 104.191 + /*
 104.192 +  * Make sure gcc doesn't try to be clever and move things around
 104.193 +  * on us. We need to use _exactly_ the address the user gave us,
 104.194 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
 104.195 +--- ../pristine-linux-2.6.16.13/include/asm-i386/bitops.h	2006-05-02 22:38:44.000000000 +0100
 104.196 ++++ ./include/asm-i386/bitops.h	2006-05-04 17:41:45.000000000 +0100
 104.197 +@@ -7,6 +7,7 @@
 104.198 + 
 104.199 + #include <linux/config.h>
 104.200 + #include <linux/compiler.h>
 104.201 ++#include <asm/smp_alt.h>
 104.202 + 
 104.203 + /*
 104.204 +  * These have to be done with inline assembly: that way the bit-setting
 104.205 +@@ -16,12 +17,6 @@
 104.206 +  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
 104.207 +  */
 104.208 + 
 104.209 +-#ifdef CONFIG_SMP
 104.210 +-#define LOCK_PREFIX "lock ; "
 104.211 +-#else
 104.212 +-#define LOCK_PREFIX ""
 104.213 +-#endif
 104.214 +-
 104.215 + #define ADDR (*(volatile long *) addr)
 104.216 + 
 104.217 + /**
 104.218 +@@ -41,7 +36,7 @@
 104.219 +  */
 104.220 + static inline void set_bit(int nr, volatile unsigned long * addr)
 104.221 + {
 104.222 +-	__asm__ __volatile__( LOCK_PREFIX
 104.223 ++	__asm__ __volatile__( LOCK
 104.224 + 		"btsl %1,%0"
 104.225 + 		:"+m" (ADDR)
 104.226 + 		:"Ir" (nr));
 104.227 +@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
 104.228 +  */
 104.229 + static inline void clear_bit(int nr, volatile unsigned long * addr)
 104.230 + {
 104.231 +-	__asm__ __volatile__( LOCK_PREFIX
 104.232 ++	__asm__ __volatile__( LOCK
 104.233 + 		"btrl %1,%0"
 104.234 + 		:"+m" (ADDR)
 104.235 + 		:"Ir" (nr));
 104.236 +@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 
 104.237 +  */
 104.238 + static inline void change_bit(int nr, volatile unsigned long * addr)
 104.239 + {
 104.240 +-	__asm__ __volatile__( LOCK_PREFIX
 104.241 ++	__asm__ __volatile__( LOCK
 104.242 + 		"btcl %1,%0"
 104.243 + 		:"+m" (ADDR)
 104.244 + 		:"Ir" (nr));
 104.245 +@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
 104.246 + {
 104.247 + 	int oldbit;
 104.248 + 
 104.249 +-	__asm__ __volatile__( LOCK_PREFIX
 104.250 ++	__asm__ __volatile__( LOCK
 104.251 + 		"btsl %2,%1\n\tsbbl %0,%0"
 104.252 + 		:"=r" (oldbit),"+m" (ADDR)
 104.253 + 		:"Ir" (nr) : "memory");
 104.254 +@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
 104.255 + {
 104.256 + 	int oldbit;
 104.257 + 
 104.258 +-	__asm__ __volatile__( LOCK_PREFIX
 104.259 ++	__asm__ __volatile__( LOCK
 104.260 + 		"btrl %2,%1\n\tsbbl %0,%0"
 104.261 + 		:"=r" (oldbit),"+m" (ADDR)
 104.262 + 		:"Ir" (nr) : "memory");
 104.263 +@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
 104.264 + {
 104.265 + 	int oldbit;
 104.266 + 
 104.267 +-	__asm__ __volatile__( LOCK_PREFIX
 104.268 ++	__asm__ __volatile__( LOCK
 104.269 + 		"btcl %2,%1\n\tsbbl %0,%0"
 104.270 + 		:"=r" (oldbit),"+m" (ADDR)
 104.271 + 		:"Ir" (nr) : "memory");
 104.272 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/futex.h ./include/asm-i386/futex.h
 104.273 +--- ../pristine-linux-2.6.16.13/include/asm-i386/futex.h	2006-05-02 22:38:44.000000000 +0100
 104.274 ++++ ./include/asm-i386/futex.h	2006-05-04 17:41:45.000000000 +0100
 104.275 +@@ -28,7 +28,7 @@
 104.276 + "1:	movl	%2, %0\n\
 104.277 + 	movl	%0, %3\n"					\
 104.278 + 	insn "\n"						\
 104.279 +-"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
 104.280 ++"2:	" LOCK "cmpxchgl %3, %2\n\
 104.281 + 	jnz	1b\n\
 104.282 + 3:	.section .fixup,\"ax\"\n\
 104.283 + 4:	mov	%5, %1\n\
 104.284 +@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 
 104.285 + #endif
 104.286 + 		switch (op) {
 104.287 + 		case FUTEX_OP_ADD:
 104.288 +-			__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
 104.289 ++			__futex_atomic_op1(LOCK "xaddl %0, %2", ret,
 104.290 + 					   oldval, uaddr, oparg);
 104.291 + 			break;
 104.292 + 		case FUTEX_OP_OR:
 104.293 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
 104.294 +--- ../pristine-linux-2.6.16.13/include/asm-i386/rwsem.h	2006-05-02 22:38:44.000000000 +0100
 104.295 ++++ ./include/asm-i386/rwsem.h	2006-05-04 17:41:45.000000000 +0100
 104.296 +@@ -40,6 +40,7 @@
 104.297 + 
 104.298 + #include <linux/list.h>
 104.299 + #include <linux/spinlock.h>
 104.300 ++#include <asm/smp_alt.h>
 104.301 + 
 104.302 + struct rwsem_waiter;
 104.303 + 
 104.304 +@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
 104.305 + {
 104.306 + 	__asm__ __volatile__(
 104.307 + 		"# beginning down_read\n\t"
 104.308 +-LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 104.309 ++LOCK	        "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 104.310 + 		"  js        2f\n\t" /* jump if we weren't granted the lock */
 104.311 + 		"1:\n\t"
 104.312 + 		LOCK_SECTION_START("")
 104.313 +@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
 104.314 + 		"  movl	     %1,%2\n\t"
 104.315 + 		"  addl      %3,%2\n\t"
 104.316 + 		"  jle	     2f\n\t"
 104.317 +-LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
 104.318 ++LOCK	        "  cmpxchgl  %2,%0\n\t"
 104.319 + 		"  jnz	     1b\n\t"
 104.320 + 		"2:\n\t"
 104.321 + 		"# ending __down_read_trylock\n\t"
 104.322 +@@ -150,7 +151,7 @@ static inline void __down_write(struct r
 104.323 + 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
 104.324 + 	__asm__ __volatile__(
 104.325 + 		"# beginning down_write\n\t"
 104.326 +-LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
 104.327 ++LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
 104.328 + 		"  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
 104.329 + 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
 104.330 + 		"1:\n\t"
 104.331 +@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
 104.332 + 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
 104.333 + 	__asm__ __volatile__(
 104.334 + 		"# beginning __up_read\n\t"
 104.335 +-LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 104.336 ++LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 104.337 + 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 104.338 + 		"1:\n\t"
 104.339 + 		LOCK_SECTION_START("")
 104.340 +@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
 104.341 + 	__asm__ __volatile__(
 104.342 + 		"# beginning __up_write\n\t"
 104.343 + 		"  movl      %2,%%edx\n\t"
 104.344 +-LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 104.345 ++LOCK	        "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 104.346 + 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
 104.347 + 		"1:\n\t"
 104.348 + 		LOCK_SECTION_START("")
 104.349 +@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
 104.350 + {
 104.351 + 	__asm__ __volatile__(
 104.352 + 		"# beginning __downgrade_write\n\t"
 104.353 +-LOCK_PREFIX	"  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
 104.354 ++LOCK	        "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
 104.355 + 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 104.356 + 		"1:\n\t"
 104.357 + 		LOCK_SECTION_START("")
 104.358 +@@ -263,7 +264,7 @@ LOCK_PREFIX	"  addl      %2,(%%eax)\n\t"
 104.359 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
 104.360 + {
 104.361 + 	__asm__ __volatile__(
 104.362 +-LOCK_PREFIX	"addl %1,%0"
 104.363 ++LOCK	          "addl %1,%0"
 104.364 + 		: "=m"(sem->count)
 104.365 + 		: "ir"(delta), "m"(sem->count));
 104.366 + }
 104.367 +@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
 104.368 + 	int tmp = delta;
 104.369 + 
 104.370 + 	__asm__ __volatile__(
 104.371 +-LOCK_PREFIX	"xadd %0,(%2)"
 104.372 ++LOCK  	          "xadd %0,(%2)"
 104.373 + 		: "+r"(tmp), "=m"(sem->count)
 104.374 + 		: "r"(sem), "m"(sem->count)
 104.375 + 		: "memory");
 104.376 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
 104.377 +--- ../pristine-linux-2.6.16.13/include/asm-i386/smp_alt.h	1970-01-01 01:00:00.000000000 +0100
 104.378 ++++ ./include/asm-i386/smp_alt.h	2006-05-04 17:41:45.000000000 +0100
 104.379 +@@ -0,0 +1,32 @@
 104.380 ++#ifndef __ASM_SMP_ALT_H__
 104.381 ++#define __ASM_SMP_ALT_H__
 104.382 ++
 104.383 ++#include <linux/config.h>
 104.384 ++
 104.385 ++#ifdef CONFIG_SMP
 104.386 ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
 104.387 ++#define LOCK \
 104.388 ++        "6677: nop\n" \
 104.389 ++	".section __smp_alternatives,\"a\"\n" \
 104.390 ++	".long 6677b\n" \
 104.391 ++	".long 6678f\n" \
 104.392 ++	".previous\n" \
 104.393 ++	".section __smp_replacements,\"a\"\n" \
 104.394 ++	"6678: .byte 1\n" \
 104.395 ++	".byte 1\n" \
 104.396 ++	".byte 0\n" \
 104.397 ++        ".byte 1\n" \
 104.398 ++	".byte -1\n" \
 104.399 ++	"lock\n" \
 104.400 ++	"nop\n" \
 104.401 ++	".previous\n"
 104.402 ++void prepare_for_smp(void);
 104.403 ++void unprepare_for_smp(void);
 104.404 ++#else
 104.405 ++#define LOCK "lock ; "
 104.406 ++#endif
 104.407 ++#else
 104.408 ++#define LOCK ""
 104.409 ++#endif
 104.410 ++
 104.411 ++#endif /* __ASM_SMP_ALT_H__ */
 104.412 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
 104.413 +--- ../pristine-linux-2.6.16.13/include/asm-i386/spinlock.h	2006-05-02 22:38:44.000000000 +0100
 104.414 ++++ ./include/asm-i386/spinlock.h	2006-05-04 17:41:45.000000000 +0100
 104.415 +@@ -6,6 +6,7 @@
 104.416 + #include <asm/page.h>
 104.417 + #include <linux/config.h>
 104.418 + #include <linux/compiler.h>
 104.419 ++#include <asm/smp_alt.h>
 104.420 + 
 104.421 + /*
 104.422 +  * Your basic SMP spinlocks, allowing only a single CPU anywhere
 104.423 +@@ -23,7 +24,8 @@
 104.424 + 
 104.425 + #define __raw_spin_lock_string \
 104.426 + 	"\n1:\t" \
 104.427 +-	"lock ; decb %0\n\t" \
 104.428 ++	LOCK \
 104.429 ++	"decb %0\n\t" \
 104.430 + 	"jns 3f\n" \
 104.431 + 	"2:\t" \
 104.432 + 	"rep;nop\n\t" \
 104.433 +@@ -34,7 +36,8 @@
 104.434 + 
 104.435 + #define __raw_spin_lock_string_flags \
 104.436 + 	"\n1:\t" \
 104.437 +-	"lock ; decb %0\n\t" \
 104.438 ++	LOCK \
 104.439 ++	"decb %0\n\t" \
 104.440 + 	"jns 4f\n\t" \
 104.441 + 	"2:\t" \
 104.442 + 	"testl $0x200, %1\n\t" \
 104.443 +@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
 104.444 + static inline int __raw_spin_trylock(raw_spinlock_t *lock)
 104.445 + {
 104.446 + 	char oldval;
 104.447 ++#ifdef CONFIG_SMP_ALTERNATIVES
 104.448 + 	__asm__ __volatile__(
 104.449 +-		"xchgb %b0,%1"
 104.450 ++		"1:movb %1,%b0\n"
 104.451 ++		"movb $0,%1\n"
 104.452 ++		"2:"
 104.453 ++		".section __smp_alternatives,\"a\"\n"
 104.454 ++		".long 1b\n"
 104.455 ++		".long 3f\n"
 104.456 ++		".previous\n"
 104.457 ++		".section __smp_replacements,\"a\"\n"
 104.458 ++		"3: .byte 2b - 1b\n"
 104.459 ++		".byte 5f-4f\n"
 104.460 ++		".byte 0\n"
 104.461 ++		".byte 6f-5f\n"
 104.462 ++		".byte -1\n"
 104.463 ++		"4: xchgb %b0,%1\n"
 104.464 ++		"5: movb %1,%b0\n"
 104.465 ++		"movb $0,%1\n"
 104.466 ++		"6:\n"
 104.467 ++		".previous\n"
 104.468 + 		:"=q" (oldval), "=m" (lock->slock)
 104.469 + 		:"0" (0) : "memory");
 104.470 ++#else
 104.471 ++	__asm__ __volatile__(
 104.472 ++		"xchgb %b0,%1\n"
 104.473 ++		:"=q" (oldval), "=m" (lock->slock)
 104.474 ++		:"0" (0) : "memory");
 104.475 ++#endif
 104.476 + 	return oldval > 0;
 104.477 + }
 104.478 + 
 104.479 +@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
 104.480 + 
 104.481 + static inline void __raw_read_unlock(raw_rwlock_t *rw)
 104.482 + {
 104.483 +-	asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
 104.484 ++	asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
 104.485 + }
 104.486 + 
 104.487 + static inline void __raw_write_unlock(raw_rwlock_t *rw)
 104.488 + {
 104.489 +-	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
 104.490 ++	asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
 104.491 + 				 : "=m" (rw->lock) : : "memory");
 104.492 + }
 104.493 + 
 104.494 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-i386/system.h ./include/asm-i386/system.h
 104.495 +--- ../pristine-linux-2.6.16.13/include/asm-i386/system.h	2006-05-02 22:38:44.000000000 +0100
 104.496 ++++ ./include/asm-i386/system.h	2006-05-04 17:41:45.000000000 +0100
 104.497 +@@ -5,7 +5,7 @@
 104.498 + #include <linux/kernel.h>
 104.499 + #include <asm/segment.h>
 104.500 + #include <asm/cpufeature.h>
 104.501 +-#include <linux/bitops.h> /* for LOCK_PREFIX */
 104.502 ++#include <asm/smp_alt.h>
 104.503 + 
 104.504 + #ifdef __KERNEL__
 104.505 + 
 104.506 +@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
 104.507 + 	unsigned long prev;
 104.508 + 	switch (size) {
 104.509 + 	case 1:
 104.510 +-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
 104.511 ++		__asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
 104.512 + 				     : "=a"(prev)
 104.513 + 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
 104.514 + 				     : "memory");
 104.515 + 		return prev;
 104.516 + 	case 2:
 104.517 +-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
 104.518 ++		__asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
 104.519 + 				     : "=a"(prev)
 104.520 + 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
 104.521 + 				     : "memory");
 104.522 + 		return prev;
 104.523 + 	case 4:
 104.524 +-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
 104.525 ++		__asm__ __volatile__(LOCK "cmpxchgl %1,%2"
 104.526 + 				     : "=a"(prev)
 104.527 + 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
 104.528 + 				     : "memory");
 104.529 +@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
 104.530 + 				      unsigned long long new)
 104.531 + {
 104.532 + 	unsigned long long prev;
 104.533 +-	__asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
 104.534 ++	__asm__ __volatile__(LOCK "cmpxchg8b %3"
 104.535 + 			     : "=A"(prev)
 104.536 + 			     : "b"((unsigned long)new),
 104.537 + 			       "c"((unsigned long)(new >> 32)),
 104.538 +@@ -503,11 +503,55 @@ struct alt_instr { 
 104.539 + #endif
 104.540 + 
 104.541 + #ifdef CONFIG_SMP
 104.542 ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
 104.543 ++#define smp_alt_mb(instr)                                           \
 104.544 ++__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
 104.545 ++		     ".section __smp_alternatives,\"a\"\n"          \
 104.546 ++		     ".long 6667b\n"                                \
 104.547 ++                     ".long 6673f\n"                                \
 104.548 ++		     ".previous\n"                                  \
 104.549 ++		     ".section __smp_replacements,\"a\"\n"          \
 104.550 ++		     "6673:.byte 6668b-6667b\n"                     \
 104.551 ++		     ".byte 6670f-6669f\n"                          \
 104.552 ++		     ".byte 6671f-6670f\n"                          \
 104.553 ++                     ".byte 0\n"                                    \
 104.554 ++		     ".byte %c0\n"                                  \
 104.555 ++		     "6669:lock;addl $0,0(%%esp)\n"                 \
 104.556 ++		     "6670:" instr "\n"                             \
 104.557 ++		     "6671:\n"                                      \
 104.558 ++		     ".previous\n"                                  \
 104.559 ++		     :                                              \
 104.560 ++		     : "i" (X86_FEATURE_XMM2)                       \
 104.561 ++		     : "memory")
 104.562 ++#define smp_rmb() smp_alt_mb("lfence")
 104.563 ++#define smp_mb()  smp_alt_mb("mfence")
 104.564 ++#define set_mb(var, value) do {                                     \
 104.565 ++unsigned long __set_mb_temp;                                        \
 104.566 ++__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
 104.567 ++		     ".section __smp_alternatives,\"a\"\n"          \
 104.568 ++		     ".long 6667b\n"                                \
 104.569 ++		     ".long 6673f\n"                                \
 104.570 ++		     ".previous\n"                                  \
 104.571 ++		     ".section __smp_replacements,\"a\"\n"          \
 104.572 ++		     "6673: .byte 6668b-6667b\n"                    \
 104.573 ++		     ".byte 6670f-6669f\n"                          \
 104.574 ++		     ".byte 0\n"                                    \
 104.575 ++		     ".byte 6671f-6670f\n"                          \
 104.576 ++		     ".byte -1\n"                                   \
 104.577 ++		     "6669: xchg %1, %0\n"                          \
 104.578 ++		     "6670:movl %1, %0\n"                           \
 104.579 ++		     "6671:\n"                                      \
 104.580 ++		     ".previous\n"                                  \
 104.581 ++		     : "=m" (var), "=r" (__set_mb_temp)             \
 104.582 ++		     : "1" (value)                                  \
 104.583 ++		     : "memory"); } while (0)
 104.584 ++#else
 104.585 + #define smp_mb()	mb()
 104.586 + #define smp_rmb()	rmb()
 104.587 ++#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 104.588 ++#endif
 104.589 + #define smp_wmb()	wmb()
 104.590 + #define smp_read_barrier_depends()	read_barrier_depends()
 104.591 +-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 104.592 + #else
 104.593 + #define smp_mb()	barrier()
 104.594 + #define smp_rmb()	barrier()
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/patches/linux-2.6.16.13/x86-increase-interrupt-vector-range.patch	Mon May 08 14:46:11 2006 -0600
   105.3 @@ -0,0 +1,89 @@
   105.4 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
   105.5 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/entry.S	2006-05-02 22:38:44.000000000 +0100
   105.6 ++++ ./arch/i386/kernel/entry.S	2006-05-04 17:41:49.000000000 +0100
   105.7 +@@ -406,7 +406,7 @@ vector=0
   105.8 + ENTRY(irq_entries_start)
   105.9 + .rept NR_IRQS
  105.10 + 	ALIGN
  105.11 +-1:	pushl $vector-256
  105.12 ++1:	pushl $~(vector)
  105.13 + 	jmp common_interrupt
  105.14 + .data
  105.15 + 	.long 1b
  105.16 +@@ -423,7 +423,7 @@ common_interrupt:
  105.17 + 
  105.18 + #define BUILD_INTERRUPT(name, nr)	\
  105.19 + ENTRY(name)				\
  105.20 +-	pushl $nr-256;			\
  105.21 ++	pushl $~(nr);			\
  105.22 + 	SAVE_ALL			\
  105.23 + 	movl %esp,%eax;			\
  105.24 + 	call smp_/**/name;		\
  105.25 +diff -pruN ../pristine-linux-2.6.16.13/arch/i386/kernel/irq.c ./arch/i386/kernel/irq.c
  105.26 +--- ../pristine-linux-2.6.16.13/arch/i386/kernel/irq.c	2006-05-02 22:38:44.000000000 +0100
  105.27 ++++ ./arch/i386/kernel/irq.c	2006-05-04 17:41:49.000000000 +0100
  105.28 +@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
  105.29 +  */
  105.30 + fastcall unsigned int do_IRQ(struct pt_regs *regs)
  105.31 + {	
  105.32 +-	/* high bits used in ret_from_ code */
  105.33 +-	int irq = regs->orig_eax & 0xff;
  105.34 ++	/* high bit used in ret_from_ code */
  105.35 ++	int irq = ~regs->orig_eax;
  105.36 + #ifdef CONFIG_4KSTACKS
  105.37 + 	union irq_ctx *curctx, *irqctx;
  105.38 + 	u32 *isp;
  105.39 +diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/entry.S ./arch/x86_64/kernel/entry.S
  105.40 +--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/entry.S	2006-05-02 22:38:44.000000000 +0100
  105.41 ++++ ./arch/x86_64/kernel/entry.S	2006-05-04 17:41:49.000000000 +0100
  105.42 +@@ -601,7 +601,7 @@ retint_kernel:	
  105.43 +  */		
  105.44 + 	.macro apicinterrupt num,func
  105.45 + 	INTR_FRAME
  105.46 +-	pushq $\num-256
  105.47 ++	pushq $~(\num)
  105.48 + 	CFI_ADJUST_CFA_OFFSET 8
  105.49 + 	interrupt \func
  105.50 + 	jmp ret_from_intr
  105.51 +diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/irq.c ./arch/x86_64/kernel/irq.c
  105.52 +--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/irq.c	2006-05-02 22:38:44.000000000 +0100
  105.53 ++++ ./arch/x86_64/kernel/irq.c	2006-05-04 17:41:49.000000000 +0100
  105.54 +@@ -96,8 +96,8 @@ skip:
  105.55 +  */
  105.56 + asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
  105.57 + {	
  105.58 +-	/* high bits used in ret_from_ code  */
  105.59 +-	unsigned irq = regs->orig_rax & 0xff;
  105.60 ++	/* high bit used in ret_from_ code  */
  105.61 ++	unsigned irq = ~regs->orig_rax;
  105.62 + 
  105.63 + 	exit_idle();
  105.64 + 	irq_enter();
  105.65 +diff -pruN ../pristine-linux-2.6.16.13/arch/x86_64/kernel/smp.c ./arch/x86_64/kernel/smp.c
  105.66 +--- ../pristine-linux-2.6.16.13/arch/x86_64/kernel/smp.c	2006-05-02 22:38:44.000000000 +0100
  105.67 ++++ ./arch/x86_64/kernel/smp.c	2006-05-04 17:41:49.000000000 +0100
  105.68 +@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
  105.69 + 
  105.70 + 	cpu = smp_processor_id();
  105.71 + 	/*
  105.72 +-	 * orig_rax contains the interrupt vector - 256.
  105.73 ++	 * orig_rax contains the negated interrupt vector.
  105.74 + 	 * Use that to determine where the sender put the data.
  105.75 + 	 */
  105.76 +-	sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
  105.77 ++	sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
  105.78 + 	f = &per_cpu(flush_state, sender);
  105.79 + 
  105.80 + 	if (!cpu_isset(cpu, f->flush_cpumask))
  105.81 +diff -pruN ../pristine-linux-2.6.16.13/include/asm-x86_64/hw_irq.h ./include/asm-x86_64/hw_irq.h
  105.82 +--- ../pristine-linux-2.6.16.13/include/asm-x86_64/hw_irq.h	2006-05-02 22:38:44.000000000 +0100
  105.83 ++++ ./include/asm-x86_64/hw_irq.h	2006-05-04 17:41:49.000000000 +0100
  105.84 +@@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \
  105.85 + __asm__( \
  105.86 + "\n.p2align\n" \
  105.87 + "IRQ" #nr "_interrupt:\n\t" \
  105.88 +-	"push $" #nr "-256 ; " \
  105.89 ++	"push $~(" #nr ") ; " \
  105.90 + 	"jmp common_interrupt");
  105.91 + 
  105.92 + #if defined(CONFIG_X86_IO_APIC)
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/patches/linux-2.6.16.13/xenoprof-generic.patch	Mon May 08 14:46:11 2006 -0600
   106.3 @@ -0,0 +1,384 @@
   106.4 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
   106.5 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c	2006-05-02 22:38:44.000000000 +0100
   106.6 ++++ ./drivers/oprofile/buffer_sync.c	2006-05-04 17:41:51.000000000 +0100
   106.7 +@@ -6,6 +6,10 @@
   106.8 +  *
   106.9 +  * @author John Levon <levon@movementarian.org>
  106.10 +  *
  106.11 ++ * Modified by Aravind Menon for Xen
  106.12 ++ * These modifications are:
  106.13 ++ * Copyright (C) 2005 Hewlett-Packard Co.
  106.14 ++ *
  106.15 +  * This is the core of the buffer management. Each
  106.16 +  * CPU buffer is processed and entered into the
  106.17 +  * global event buffer. Such processing is necessary
  106.18 +@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
  106.19 + 	last_cookie = INVALID_COOKIE;
  106.20 + }
  106.21 + 
  106.22 +-static void add_kernel_ctx_switch(unsigned int in_kernel)
  106.23 ++static void add_cpu_mode_switch(unsigned int cpu_mode)
  106.24 + {
  106.25 + 	add_event_entry(ESCAPE_CODE);
  106.26 +-	if (in_kernel)
  106.27 +-		add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
  106.28 +-	else
  106.29 +-		add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
  106.30 ++	switch (cpu_mode) {
  106.31 ++	case CPU_MODE_USER:
  106.32 ++		add_event_entry(USER_ENTER_SWITCH_CODE);
  106.33 ++		break;
  106.34 ++	case CPU_MODE_KERNEL:
  106.35 ++		add_event_entry(KERNEL_ENTER_SWITCH_CODE);
  106.36 ++		break;
  106.37 ++	case CPU_MODE_XEN:
  106.38 ++		add_event_entry(XEN_ENTER_SWITCH_CODE);
  106.39 ++		break;
  106.40 ++	default:
  106.41 ++		break;
  106.42 ++	}
  106.43 + }
  106.44 +- 
  106.45 ++
  106.46 + static void
  106.47 + add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
  106.48 + {
  106.49 +@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
  106.50 +  * for later lookup from userspace.
  106.51 +  */
  106.52 + static int
  106.53 +-add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
  106.54 ++add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
  106.55 + {
  106.56 +-	if (in_kernel) {
  106.57 ++	if (cpu_mode >= CPU_MODE_KERNEL) {
  106.58 + 		add_sample_entry(s->eip, s->event);
  106.59 + 		return 1;
  106.60 + 	} else if (mm) {
  106.61 +@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
  106.62 + 	struct mm_struct *mm = NULL;
  106.63 + 	struct task_struct * new;
  106.64 + 	unsigned long cookie = 0;
  106.65 +-	int in_kernel = 1;
  106.66 ++	int cpu_mode = 1;
  106.67 + 	unsigned int i;
  106.68 + 	sync_buffer_state state = sb_buffer_start;
  106.69 + 	unsigned long available;
  106.70 +@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
  106.71 + 		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
  106.72 +  
  106.73 + 		if (is_code(s->eip)) {
  106.74 +-			if (s->event <= CPU_IS_KERNEL) {
  106.75 ++			if (s->event <= CPU_MODE_XEN) {
  106.76 + 				/* kernel/userspace switch */
  106.77 +-				in_kernel = s->event;
  106.78 ++				cpu_mode = s->event;
  106.79 + 				if (state == sb_buffer_start)
  106.80 + 					state = sb_sample_start;
  106.81 +-				add_kernel_ctx_switch(s->event);
  106.82 ++				add_cpu_mode_switch(s->event);
  106.83 + 			} else if (s->event == CPU_TRACE_BEGIN) {
  106.84 + 				state = sb_bt_start;
  106.85 + 				add_trace_begin();
  106.86 +@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
  106.87 + 			}
  106.88 + 		} else {
  106.89 + 			if (state >= sb_bt_start &&
  106.90 +-			    !add_sample(mm, s, in_kernel)) {
  106.91 ++			    !add_sample(mm, s, cpu_mode)) {
  106.92 + 				if (state == sb_bt_start) {
  106.93 + 					state = sb_bt_ignore;
  106.94 + 					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  106.95 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
  106.96 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c	2006-05-02 22:38:44.000000000 +0100
  106.97 ++++ ./drivers/oprofile/cpu_buffer.c	2006-05-04 17:41:51.000000000 +0100
  106.98 +@@ -6,6 +6,10 @@
  106.99 +  *
 106.100 +  * @author John Levon <levon@movementarian.org>
 106.101 +  *
 106.102 ++ * Modified by Aravind Menon for Xen
 106.103 ++ * These modifications are:
 106.104 ++ * Copyright (C) 2005 Hewlett-Packard Co.
 106.105 ++ *
 106.106 +  * Each CPU has a local buffer that stores PC value/event
 106.107 +  * pairs. We also log context switches when we notice them.
 106.108 +  * Eventually each CPU's buffer is processed into the global
 106.109 +@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
 106.110 + 			goto fail;
 106.111 +  
 106.112 + 		b->last_task = NULL;
 106.113 +-		b->last_is_kernel = -1;
 106.114 ++		b->last_cpu_mode = -1;
 106.115 + 		b->tracing = 0;
 106.116 + 		b->buffer_size = buffer_size;
 106.117 + 		b->tail_pos = 0;
 106.118 +@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
 106.119 + 	 * collected will populate the buffer with proper
 106.120 + 	 * values to initialize the buffer
 106.121 + 	 */
 106.122 +-	cpu_buf->last_is_kernel = -1;
 106.123 ++	cpu_buf->last_cpu_mode = -1;
 106.124 + 	cpu_buf->last_task = NULL;
 106.125 + }
 106.126 + 
 106.127 +@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
 106.128 +  * because of the head/tail separation of the writer and reader
 106.129 +  * of the CPU buffer.
 106.130 +  *
 106.131 +- * is_kernel is needed because on some architectures you cannot
 106.132 ++ * cpu_mode is needed because on some architectures you cannot
 106.133 +  * tell if you are in kernel or user space simply by looking at
 106.134 +- * pc. We tag this in the buffer by generating kernel enter/exit
 106.135 +- * events whenever is_kernel changes
 106.136 ++ * pc. We tag this in the buffer by generating kernel/user (and xen)
 106.137 ++ *  enter events whenever cpu_mode changes
 106.138 +  */
 106.139 + static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
 106.140 +-		      int is_kernel, unsigned long event)
 106.141 ++		      int cpu_mode, unsigned long event)
 106.142 + {
 106.143 + 	struct task_struct * task;
 106.144 + 
 106.145 +@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
 106.146 + 		return 0;
 106.147 + 	}
 106.148 + 
 106.149 +-	is_kernel = !!is_kernel;
 106.150 ++	WARN_ON(cpu_mode > CPU_MODE_XEN);
 106.151 + 
 106.152 + 	task = current;
 106.153 + 
 106.154 + 	/* notice a switch from user->kernel or vice versa */
 106.155 +-	if (cpu_buf->last_is_kernel != is_kernel) {
 106.156 +-		cpu_buf->last_is_kernel = is_kernel;
 106.157 +-		add_code(cpu_buf, is_kernel);
 106.158 ++	if (cpu_buf->last_cpu_mode != cpu_mode) {
 106.159 ++		cpu_buf->last_cpu_mode = cpu_mode;
 106.160 ++		add_code(cpu_buf, cpu_mode);
 106.161 + 	}
 106.162 +-
 106.163 ++	
 106.164 + 	/* notice a task switch */
 106.165 + 	if (cpu_buf->last_task != task) {
 106.166 + 		cpu_buf->last_task = task;
 106.167 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
 106.168 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h	2006-05-02 22:38:44.000000000 +0100
 106.169 ++++ ./drivers/oprofile/cpu_buffer.h	2006-05-04 17:41:51.000000000 +0100
 106.170 +@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
 106.171 + 	volatile unsigned long tail_pos;
 106.172 + 	unsigned long buffer_size;
 106.173 + 	struct task_struct * last_task;
 106.174 +-	int last_is_kernel;
 106.175 ++	int last_cpu_mode;
 106.176 + 	int tracing;
 106.177 + 	struct op_sample * buffer;
 106.178 + 	unsigned long sample_received;
 106.179 +@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
 106.180 + void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
 106.181 + 
 106.182 + /* transient events for the CPU buffer -> event buffer */
 106.183 +-#define CPU_IS_KERNEL 1
 106.184 +-#define CPU_TRACE_BEGIN 2
 106.185 ++#define CPU_MODE_USER    0
 106.186 ++#define CPU_MODE_KERNEL  1
 106.187 ++#define CPU_MODE_XEN     2
 106.188 ++#define CPU_TRACE_BEGIN  3
 106.189 + 
 106.190 + #endif /* OPROFILE_CPU_BUFFER_H */
 106.191 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
 106.192 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h	2006-05-02 22:38:44.000000000 +0100
 106.193 ++++ ./drivers/oprofile/event_buffer.h	2006-05-04 17:41:51.000000000 +0100
 106.194 +@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
 106.195 + #define CPU_SWITCH_CODE 		2
 106.196 + #define COOKIE_SWITCH_CODE 		3
 106.197 + #define KERNEL_ENTER_SWITCH_CODE	4
 106.198 +-#define KERNEL_EXIT_SWITCH_CODE		5
 106.199 ++#define USER_ENTER_SWITCH_CODE		5
 106.200 + #define MODULE_LOADED_CODE		6
 106.201 + #define CTX_TGID_CODE			7
 106.202 + #define TRACE_BEGIN_CODE		8
 106.203 + #define TRACE_END_CODE			9
 106.204 ++#define XEN_ENTER_SWITCH_CODE		10
 106.205 +  
 106.206 + #define INVALID_COOKIE ~0UL
 106.207 + #define NO_COOKIE 0UL
 106.208 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
 106.209 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c	2006-05-02 22:38:44.000000000 +0100
 106.210 ++++ ./drivers/oprofile/oprof.c	2006-05-04 17:41:51.000000000 +0100
 106.211 +@@ -5,6 +5,10 @@
 106.212 +  * @remark Read the file COPYING
 106.213 +  *
 106.214 +  * @author John Levon <levon@movementarian.org>
 106.215 ++ *
 106.216 ++ * Modified by Aravind Menon for Xen
 106.217 ++ * These modifications are:
 106.218 ++ * Copyright (C) 2005 Hewlett-Packard Co.
 106.219 +  */
 106.220 + 
 106.221 + #include <linux/kernel.h>
 106.222 +@@ -19,7 +23,7 @@
 106.223 + #include "cpu_buffer.h"
 106.224 + #include "buffer_sync.h"
 106.225 + #include "oprofile_stats.h"
 106.226 +- 
 106.227 ++
 106.228 + struct oprofile_operations oprofile_ops;
 106.229 + 
 106.230 + unsigned long oprofile_started;
 106.231 +@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem);
 106.232 +  */
 106.233 + static int timer = 0;
 106.234 + 
 106.235 ++extern unsigned int adomains;
 106.236 ++extern int active_domains[MAX_OPROF_DOMAINS];
 106.237 ++
 106.238 ++int oprofile_set_active(void)
 106.239 ++{
 106.240 ++	if (oprofile_ops.set_active)
 106.241 ++		return oprofile_ops.set_active(active_domains, adomains);
 106.242 ++
 106.243 ++	return -EINVAL;
 106.244 ++}
 106.245 ++
 106.246 + int oprofile_setup(void)
 106.247 + {
 106.248 + 	int err;
 106.249 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
 106.250 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h	2006-05-02 22:38:44.000000000 +0100
 106.251 ++++ ./drivers/oprofile/oprof.h	2006-05-04 17:41:51.000000000 +0100
 106.252 +@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
 106.253 + void oprofile_timer_init(struct oprofile_operations * ops);
 106.254 + 
 106.255 + int oprofile_set_backtrace(unsigned long depth);
 106.256 ++
 106.257 ++int oprofile_set_active(void);
 106.258 +  
 106.259 + #endif /* OPROF_H */
 106.260 +diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
 106.261 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c	2006-05-02 22:38:44.000000000 +0100
 106.262 ++++ ./drivers/oprofile/oprofile_files.c	2006-05-04 17:41:51.000000000 +0100
 106.263 +@@ -5,15 +5,21 @@
 106.264 +  * @remark Read the file COPYING
 106.265 +  *
 106.266 +  * @author John Levon <levon@movementarian.org>
 106.267 ++ *
 106.268 ++ * Modified by Aravind Menon for Xen
 106.269 ++ * These modifications are:
 106.270 ++ * Copyright (C) 2005 Hewlett-Packard Co.	
 106.271 +  */
 106.272 + 
 106.273 + #include <linux/fs.h>
 106.274 + #include <linux/oprofile.h>
 106.275 ++#include <asm/uaccess.h>
 106.276 ++#include <linux/ctype.h>
 106.277 + 
 106.278 + #include "event_buffer.h"
 106.279 + #include "oprofile_stats.h"
 106.280 + #include "oprof.h"
 106.281 +- 
 106.282 ++
 106.283 + unsigned long fs_buffer_size = 131072;
 106.284 + unsigned long fs_cpu_buffer_size = 8192;
 106.285 + unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
 106.286 +@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file * 
 106.287 + static struct file_operations dump_fops = {
 106.288 + 	.write		= dump_write,
 106.289 + };
 106.290 +- 
 106.291 ++
 106.292 ++#define TMPBUFSIZE 512
 106.293 ++
 106.294 ++unsigned int adomains = 0;
 106.295 ++long active_domains[MAX_OPROF_DOMAINS];
 106.296 ++
 106.297 ++static ssize_t adomain_write(struct file * file, char const __user * buf, 
 106.298 ++			     size_t count, loff_t * offset)
 106.299 ++{
 106.300 ++	char tmpbuf[TMPBUFSIZE];
 106.301 ++	char * startp = tmpbuf;
 106.302 ++	char * endp = tmpbuf;
 106.303 ++	int i;
 106.304 ++	unsigned long val;
 106.305 ++	
 106.306 ++	if (*offset)
 106.307 ++		return -EINVAL;	
 106.308 ++	if (!count)
 106.309 ++		return 0;
 106.310 ++	if (count > TMPBUFSIZE - 1)
 106.311 ++		return -EINVAL;
 106.312 ++
 106.313 ++	memset(tmpbuf, 0x0, TMPBUFSIZE);
 106.314 ++
 106.315 ++	if (copy_from_user(tmpbuf, buf, count))
 106.316 ++		return -EFAULT;
 106.317 ++	
 106.318 ++	for (i = 0; i < MAX_OPROF_DOMAINS; i++)
 106.319 ++		active_domains[i] = -1;
 106.320 ++	adomains = 0;
 106.321 ++
 106.322 ++	while (1) {
 106.323 ++		val = simple_strtol(startp, &endp, 0);
 106.324 ++		if (endp == startp)
 106.325 ++			break;
 106.326 ++		while (ispunct(*endp))
 106.327 ++			endp++;
 106.328 ++		active_domains[adomains++] = val;
 106.329 ++		if (adomains >= MAX_OPROF_DOMAINS)
 106.330 ++			break;
 106.331 ++		startp = endp;
 106.332 ++	}
 106.333 ++	if (oprofile_set_active())
 106.334 ++		return -EINVAL; 
 106.335 ++	return count;
 106.336 ++}
 106.337 ++
 106.338 ++static ssize_t adomain_read(struct file * file, char __user * buf, 
 106.339 ++			    size_t count, loff_t * offset)
 106.340 ++{
 106.341 ++	char tmpbuf[TMPBUFSIZE];
 106.342 ++	size_t len = 0;
 106.343 ++	int i;
 106.344 ++	/* This is all screwed up if we run out of space */
 106.345 ++	for (i = 0; i < adomains; i++) 
 106.346 ++		len += snprintf(tmpbuf + len, TMPBUFSIZE - len, 
 106.347 ++				"%u ", (unsigned int)active_domains[i]);
 106.348 ++	len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
 106.349 ++	return simple_read_from_buffer((void __user *)buf, count, 
 106.350 ++				       offset, tmpbuf, len);
 106.351 ++}
 106.352 ++
 106.353 ++
 106.354 ++static struct file_operations active_domain_ops = {
 106.355 ++	.read		= adomain_read,
 106.356 ++	.write		= adomain_write,
 106.357 ++};
 106.358 ++
 106.359 + void oprofile_create_files(struct super_block * sb, struct dentry * root)
 106.360 + {
 106.361 + 	oprofilefs_create_file(sb, root, "enable", &enable_fops);
 106.362 + 	oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
 106.363 ++	oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
 106.364 + 	oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
 106.365 + 	oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
 106.366 + 	oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
 106.367 +diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h ./include/linux/oprofile.h
 106.368 +--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h	2006-05-02 22:38:44.000000000 +0100
 106.369 ++++ ./include/linux/oprofile.h	2006-05-04 17:41:51.000000000 +0100
 106.370 +@@ -16,6 +16,8 @@
 106.371 + #include <linux/types.h>
 106.372 + #include <linux/spinlock.h>
 106.373 + #include <asm/atomic.h>
 106.374 ++
 106.375 ++#include <xen/interface/xenoprof.h>
 106.376 +  
 106.377 + struct super_block;
 106.378 + struct dentry;
 106.379 +@@ -27,6 +29,8 @@ struct oprofile_operations {
 106.380 + 	/* create any necessary configuration files in the oprofile fs.
 106.381 + 	 * Optional. */
 106.382 + 	int (*create_files)(struct super_block * sb, struct dentry * root);
 106.383 ++	/* setup active domains with Xen */
 106.384 ++	int (*set_active)(int *active_domains, unsigned int adomains);
 106.385 + 	/* Do any necessary interrupt setup. Optional. */
 106.386 + 	int (*setup)(void);
 106.387 + 	/* Do any necessary interrupt shutdown. Optional. */
   107.1 --- a/patches/linux-2.6.16/device_bind.patch	Mon May 08 13:41:18 2006 -0600
   107.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.3 @@ -1,14 +0,0 @@
   107.4 ---- linux-2.6.16/drivers/base/bus.c	2006-03-16 10:50:20.000000000 -0500
   107.5 -+++ linux-2.6.16/drivers/base/bus.c	2006-03-16 11:02:08.000000000 -0500
   107.6 -@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
   107.7 - 		up(&dev->sem);
   107.8 - 		if (dev->parent)
   107.9 - 			up(&dev->parent->sem);
  107.10 -+
  107.11 -+		if (err > 0) 		/* success */
  107.12 -+			err = count;
  107.13 -+		else if (err == 0)	/* driver didn't accept device */
  107.14 -+			err = -ENODEV;
  107.15 - 	}
  107.16 - 	put_device(dev);
  107.17 - 	put_bus(bus);
   108.1 --- a/patches/linux-2.6.16/i386-mach-io-check-nmi.patch	Mon May 08 13:41:18 2006 -0600
   108.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.3 @@ -1,45 +0,0 @@
   108.4 -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
   108.5 ---- ../pristine-linux-2.6.16/arch/i386/kernel/traps.c	2006-03-20 05:53:29.000000000 +0000
   108.6 -+++ ./arch/i386/kernel/traps.c	2006-03-20 19:38:17.000000000 +0000
   108.7 -@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
   108.8 - 
   108.9 - static void io_check_error(unsigned char reason, struct pt_regs * regs)
  108.10 - {
  108.11 --	unsigned long i;
  108.12 --
  108.13 - 	printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
  108.14 - 	show_registers(regs);
  108.15 - 
  108.16 - 	/* Re-enable the IOCK line, wait for a few seconds */
  108.17 --	reason = (reason & 0xf) | 8;
  108.18 --	outb(reason, 0x61);
  108.19 --	i = 2000;
  108.20 --	while (--i) udelay(1000);
  108.21 --	reason &= ~8;
  108.22 --	outb(reason, 0x61);
  108.23 -+	clear_io_check_error(reason);
  108.24 - }
  108.25 - 
  108.26 - static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
  108.27 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
  108.28 ---- ../pristine-linux-2.6.16/include/asm-i386/mach-default/mach_traps.h	2006-03-20 05:53:29.000000000 +0000
  108.29 -+++ ./include/asm-i386/mach-default/mach_traps.h	2006-03-20 19:38:17.000000000 +0000
  108.30 -@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
  108.31 - 	outb(reason, 0x61);
  108.32 - }
  108.33 - 
  108.34 -+static inline void clear_io_check_error(unsigned char reason)
  108.35 -+{
  108.36 -+	unsigned long i;
  108.37 -+
  108.38 -+	reason = (reason & 0xf) | 8;
  108.39 -+	outb(reason, 0x61);
  108.40 -+	i = 2000;
  108.41 -+	while (--i) udelay(1000);
  108.42 -+	reason &= ~8;
  108.43 -+	outb(reason, 0x61);
  108.44 -+}
  108.45 -+
  108.46 - static inline unsigned char get_nmi_reason(void)
  108.47 - {
  108.48 - 	return inb(0x61);
   109.1 --- a/patches/linux-2.6.16/net-csum.patch	Mon May 08 13:41:18 2006 -0600
   109.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.3 @@ -1,64 +0,0 @@
   109.4 -diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
   109.5 ---- ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-03-20 05:53:29.000000000 +0000
   109.6 -+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-03-20 19:38:19.000000000 +0000
   109.7 -@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
   109.8 - 	if (hdrsize < sizeof(*hdr))
   109.9 - 		return 1;
  109.10 - 
  109.11 --	hdr->check = ip_nat_cheat_check(~oldip, newip,
  109.12 -+	if ((*pskb)->proto_csum_blank) {
  109.13 -+		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
  109.14 -+	} else {
  109.15 -+		hdr->check = ip_nat_cheat_check(~oldip, newip,
  109.16 - 					ip_nat_cheat_check(oldport ^ 0xFFFF,
  109.17 - 							   newport,
  109.18 - 							   hdr->check));
  109.19 -+	}
  109.20 - 	return 1;
  109.21 - }
  109.22 - 
  109.23 -diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
  109.24 ---- ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-03-20 05:53:29.000000000 +0000
  109.25 -+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c	2006-03-20 19:38:19.000000000 +0000
  109.26 -@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
  109.27 - 		newport = tuple->dst.u.udp.port;
  109.28 - 		portptr = &hdr->dest;
  109.29 - 	}
  109.30 --	if (hdr->check) /* 0 is a special case meaning no checksum */
  109.31 --		hdr->check = ip_nat_cheat_check(~oldip, newip,
  109.32 -+	if (hdr->check) { /* 0 is a special case meaning no checksum */
  109.33 -+		if ((*pskb)->proto_csum_blank) {
  109.34 -+			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
  109.35 -+		} else {
  109.36 -+			hdr->check = ip_nat_cheat_check(~oldip, newip,
  109.37 - 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
  109.38 - 							   newport,
  109.39 - 							   hdr->check));
  109.40 -+		}
  109.41 -+	}
  109.42 - 	*portptr = newport;
  109.43 - 	return 1;
  109.44 - }
  109.45 -diff -r 601fa226a761 net/ipv4/xfrm4_output.c
  109.46 ---- a/net/ipv4/xfrm4_output.c	Wed Apr 19 18:52:30 2006
  109.47 -+++ b/net/ipv4/xfrm4_output.c	Thu Apr 20 15:49:40 2006
  109.48 -@@ -16,6 +16,8 @@
  109.49 - #include <net/ip.h>
  109.50 - #include <net/xfrm.h>
  109.51 - #include <net/icmp.h>
  109.52 -+
  109.53 -+extern int skb_checksum_setup(struct sk_buff *skb);
  109.54 - 
  109.55 - /* Add encapsulation header.
  109.56 -  *
  109.57 -@@ -103,6 +105,10 @@
  109.58 - 	struct xfrm_state *x = dst->xfrm;
  109.59 - 	int err;
  109.60 - 	
  109.61 -+	err = skb_checksum_setup(skb);
  109.62 -+	if (err)
  109.63 -+		goto error_nolock;
  109.64 -+
  109.65 - 	if (skb->ip_summed == CHECKSUM_HW) {
  109.66 - 		err = skb_checksum_help(skb, 0);
  109.67 - 		if (err)
   110.1 --- a/patches/linux-2.6.16/pmd-shared.patch	Mon May 08 13:41:18 2006 -0600
   110.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.3 @@ -1,111 +0,0 @@
   110.4 -diff -pruN ../pristine-linux-2.6.16/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
   110.5 ---- ../pristine-linux-2.6.16/arch/i386/mm/pageattr.c	2006-03-20 05:53:29.000000000 +0000
   110.6 -+++ ./arch/i386/mm/pageattr.c	2006-03-20 19:38:23.000000000 +0000
   110.7 -@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
   110.8 - 	unsigned long flags;
   110.9 - 
  110.10 - 	set_pte_atomic(kpte, pte); 	/* change init_mm */
  110.11 --	if (PTRS_PER_PMD > 1)
  110.12 -+	if (HAVE_SHARED_KERNEL_PMD)
  110.13 - 		return;
  110.14 - 
  110.15 - 	spin_lock_irqsave(&pgd_lock, flags);
  110.16 -diff -pruN ../pristine-linux-2.6.16/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
  110.17 ---- ../pristine-linux-2.6.16/arch/i386/mm/pgtable.c	2006-03-20 05:53:29.000000000 +0000
  110.18 -+++ ./arch/i386/mm/pgtable.c	2006-03-20 19:38:23.000000000 +0000
  110.19 -@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
  110.20 - 		spin_lock_irqsave(&pgd_lock, flags);
  110.21 - 	}
  110.22 - 
  110.23 --	clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
  110.24 --			swapper_pg_dir + USER_PTRS_PER_PGD,
  110.25 --			KERNEL_PGD_PTRS);
  110.26 -+	if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
  110.27 -+		clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
  110.28 -+				swapper_pg_dir + USER_PTRS_PER_PGD,
  110.29 -+				KERNEL_PGD_PTRS);
  110.30 - 	if (PTRS_PER_PMD > 1)
  110.31 - 		return;
  110.32 - 
  110.33 -@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
  110.34 - 			goto out_oom;
  110.35 - 		set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
  110.36 - 	}
  110.37 -+
  110.38 -+	if (!HAVE_SHARED_KERNEL_PMD) {
  110.39 -+		unsigned long flags;
  110.40 -+
  110.41 -+		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
  110.42 -+			pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
  110.43 -+			if (!pmd)
  110.44 -+				goto out_oom;
  110.45 -+			set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
  110.46 -+		}
  110.47 -+
  110.48 -+		spin_lock_irqsave(&pgd_lock, flags);
  110.49 -+		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
  110.50 -+			unsigned long v = (unsigned long)i << PGDIR_SHIFT;
  110.51 -+			pgd_t *kpgd = pgd_offset_k(v);
  110.52 -+			pud_t *kpud = pud_offset(kpgd, v);
  110.53 -+			pmd_t *kpmd = pmd_offset(kpud, v);
  110.54 -+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
  110.55 -+			memcpy(pmd, kpmd, PAGE_SIZE);
  110.56 -+		}
  110.57 -+		pgd_list_add(pgd);
  110.58 -+		spin_unlock_irqrestore(&pgd_lock, flags);
  110.59 -+	}
  110.60 -+
  110.61 - 	return pgd;
  110.62 - 
  110.63 - out_oom:
  110.64 -@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
  110.65 - 	int i;
  110.66 - 
  110.67 - 	/* in the PAE case user pgd entries are overwritten before usage */
  110.68 --	if (PTRS_PER_PMD > 1)
  110.69 --		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
  110.70 --			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
  110.71 -+	if (PTRS_PER_PMD > 1) {
  110.72 -+		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
  110.73 -+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
  110.74 -+			kmem_cache_free(pmd_cache, pmd);
  110.75 -+		}
  110.76 -+		if (!HAVE_SHARED_KERNEL_PMD) {
  110.77 -+			unsigned long flags;
  110.78 -+			spin_lock_irqsave(&pgd_lock, flags);
  110.79 -+			pgd_list_del(pgd);
  110.80 -+			spin_unlock_irqrestore(&pgd_lock, flags);
  110.81 -+			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
  110.82 -+				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
  110.83 -+				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
  110.84 -+				kmem_cache_free(pmd_cache, pmd);
  110.85 -+			}
  110.86 -+		}
  110.87 -+	}
  110.88 - 	/* in the non-PAE case, free_pgtables() clears user pgd entries */
  110.89 - 	kmem_cache_free(pgd_cache, pgd);
  110.90 - }
  110.91 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
  110.92 ---- ../pristine-linux-2.6.16/include/asm-i386/pgtable-2level-defs.h	2006-03-20 05:53:29.000000000 +0000
  110.93 -+++ ./include/asm-i386/pgtable-2level-defs.h	2006-03-20 19:38:23.000000000 +0000
  110.94 -@@ -1,6 +1,8 @@
  110.95 - #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
  110.96 - #define _I386_PGTABLE_2LEVEL_DEFS_H
  110.97 - 
  110.98 -+#define HAVE_SHARED_KERNEL_PMD 0
  110.99 -+
 110.100 - /*
 110.101 -  * traditional i386 two-level paging structure:
 110.102 -  */
 110.103 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
 110.104 ---- ../pristine-linux-2.6.16/include/asm-i386/pgtable-3level-defs.h	2006-03-20 05:53:29.000000000 +0000
 110.105 -+++ ./include/asm-i386/pgtable-3level-defs.h	2006-03-20 19:38:23.000000000 +0000
 110.106 -@@ -1,6 +1,8 @@
 110.107 - #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
 110.108 - #define _I386_PGTABLE_3LEVEL_DEFS_H
 110.109 - 
 110.110 -+#define HAVE_SHARED_KERNEL_PMD 1
 110.111 -+
 110.112 - /*
 110.113 -  * PGDIR_SHIFT determines what a top-level page table entry can map
 110.114 -  */
   111.1 --- a/patches/linux-2.6.16/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch	Mon May 08 13:41:18 2006 -0600
   111.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.3 @@ -1,31 +0,0 @@
   111.4 -Index: sysenter/linux-2.6-xen-sparse/arch/i386/kernel/entry.S
   111.5 -===================================================================
   111.6 ---- linux-2.6.16.orig/arch/i386/kernel/entry.S	2006-04-05 11:12:51.000000000 +0100
   111.7 -+++ linux-2.6.16/arch/i386/kernel/entry.S	2006-04-05 11:12:52.000000000 +0100
   111.8 -@@ -177,7 +177,7 @@
   111.9 - 
  111.10 - 	# sysenter call handler stub
  111.11 - ENTRY(sysenter_entry)
  111.12 --	movl TSS_sysenter_esp0(%esp),%esp
  111.13 -+	movl SYSENTER_stack_esp0(%esp),%esp
  111.14 - sysenter_past_esp:
  111.15 - 	sti
  111.16 - 	pushl $(__USER_DS)
  111.17 -@@ -492,7 +492,7 @@
  111.18 -  * that sets up the real kernel stack. Check here, since we can't
  111.19 -  * allow the wrong stack to be used.
  111.20 -  *
  111.21 -- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
  111.22 -+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
  111.23 -  * already pushed 3 words if it hits on the sysenter instruction:
  111.24 -  * eflags, cs and eip.
  111.25 -  *
  111.26 -@@ -504,7 +504,7 @@
  111.27 - 	cmpw $__KERNEL_CS,4(%esp);		\
  111.28 - 	jne ok;					\
  111.29 - label:						\
  111.30 --	movl TSS_sysenter_esp0+offset(%esp),%esp;	\
  111.31 -+	movl SYSENTER_stack_esp0+offset(%esp),%esp;	\
  111.32 - 	pushfl;					\
  111.33 - 	pushl $__KERNEL_CS;			\
  111.34 - 	pushl $sysenter_past_esp
   112.1 --- a/patches/linux-2.6.16/smp-alts.patch	Mon May 08 13:41:18 2006 -0600
   112.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.3 @@ -1,591 +0,0 @@
   112.4 -diff -pruN ../pristine-linux-2.6.16/arch/i386/Kconfig ./arch/i386/Kconfig
   112.5 ---- ../pristine-linux-2.6.16/arch/i386/Kconfig	2006-03-20 05:53:29.000000000 +0000
   112.6 -+++ ./arch/i386/Kconfig	2006-03-20 19:38:27.000000000 +0000
   112.7 -@@ -202,6 +202,19 @@ config SMP
   112.8 - 
   112.9 - 	  If you don't know what to do here, say N.
  112.10 - 
  112.11 -+config SMP_ALTERNATIVES
  112.12 -+	bool "SMP alternatives support (EXPERIMENTAL)"
  112.13 -+	depends on SMP && EXPERIMENTAL
  112.14 -+	help
  112.15 -+	  Try to reduce the overhead of running an SMP kernel on a uniprocessor
  112.16 -+	  host slightly by replacing certain key instruction sequences
  112.17 -+	  according to whether we currently have more than one CPU available.
  112.18 -+	  This should provide a noticeable boost to performance when
  112.19 -+	  running SMP kernels on UP machines, and have negligible impact
  112.20 -+	  when running on an true SMP host.
  112.21 -+
  112.22 -+          If unsure, say N.
  112.23 -+	  
  112.24 - config NR_CPUS
  112.25 - 	int "Maximum number of CPUs (2-255)"
  112.26 - 	range 2 255
  112.27 -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
  112.28 ---- ../pristine-linux-2.6.16/arch/i386/kernel/Makefile	2006-03-20 05:53:29.000000000 +0000
  112.29 -+++ ./arch/i386/kernel/Makefile	2006-03-20 19:38:27.000000000 +0000
  112.30 -@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
  112.31 - obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
  112.32 - obj-$(CONFIG_VM86)		+= vm86.o
  112.33 - obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
  112.34 -+obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
  112.35 - 
  112.36 - EXTRA_AFLAGS   := -traditional
  112.37 - 
  112.38 -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
  112.39 ---- ../pristine-linux-2.6.16/arch/i386/kernel/smpalts.c	1970-01-01 01:00:00.000000000 +0100
  112.40 -+++ ./arch/i386/kernel/smpalts.c	2006-03-20 19:38:27.000000000 +0000
  112.41 -@@ -0,0 +1,85 @@
  112.42 -+#include <linux/kernel.h>
  112.43 -+#include <asm/system.h>
  112.44 -+#include <asm/smp_alt.h>
  112.45 -+#include <asm/processor.h>
  112.46 -+#include <asm/string.h>
  112.47 -+
  112.48 -+struct smp_replacement_record {
  112.49 -+	unsigned char targ_size;
  112.50 -+	unsigned char smp1_size;
  112.51 -+	unsigned char smp2_size;
  112.52 -+	unsigned char up_size;
  112.53 -+	unsigned char feature;
  112.54 -+	unsigned char data[0];
  112.55 -+};
  112.56 -+
  112.57 -+struct smp_alternative_record {
  112.58 -+	void *targ_start;
  112.59 -+	struct smp_replacement_record *repl;
  112.60 -+};
  112.61 -+
  112.62 -+extern struct smp_alternative_record __start_smp_alternatives_table,
  112.63 -+  __stop_smp_alternatives_table;
  112.64 -+extern unsigned long __init_begin, __init_end;
  112.65 -+
  112.66 -+void prepare_for_smp(void)
  112.67 -+{
  112.68 -+	struct smp_alternative_record *r;
  112.69 -+	printk(KERN_INFO "Enabling SMP...\n");
  112.70 -+	for (r = &__start_smp_alternatives_table;
  112.71 -+	     r != &__stop_smp_alternatives_table;
  112.72 -+	     r++) {
  112.73 -+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
  112.74 -+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
  112.75 -+		BUG_ON(r->repl->targ_size < r->repl->up_size);
  112.76 -+               if (system_state == SYSTEM_RUNNING &&
  112.77 -+                   r->targ_start >= (void *)&__init_begin &&
  112.78 -+                   r->targ_start < (void *)&__init_end)
  112.79 -+                       continue;
  112.80 -+		if (r->repl->feature != (unsigned char)-1 &&
  112.81 -+		    boot_cpu_has(r->repl->feature)) {
  112.82 -+			memcpy(r->targ_start,
  112.83 -+			       r->repl->data + r->repl->smp1_size,
  112.84 -+			       r->repl->smp2_size);
  112.85 -+			memset(r->targ_start + r->repl->smp2_size,
  112.86 -+			       0x90,
  112.87 -+			       r->repl->targ_size - r->repl->smp2_size);
  112.88 -+		} else {
  112.89 -+			memcpy(r->targ_start,
  112.90 -+			       r->repl->data,
  112.91 -+			       r->repl->smp1_size);
  112.92 -+			memset(r->targ_start + r->repl->smp1_size,
  112.93 -+			       0x90,
  112.94 -+			       r->repl->targ_size - r->repl->smp1_size);
  112.95 -+		}
  112.96 -+	}
  112.97 -+	/* Paranoia */
  112.98 -+	asm volatile ("jmp 1f\n1:");
  112.99 -+	mb();
 112.100 -+}
 112.101 -+
 112.102 -+void unprepare_for_smp(void)
 112.103 -+{
 112.104 -+	struct smp_alternative_record *r;
 112.105 -+	printk(KERN_INFO "Disabling SMP...\n");
 112.106 -+	for (r = &__start_smp_alternatives_table;
 112.107 -+	     r != &__stop_smp_alternatives_table;
 112.108 -+	     r++) {
 112.109 -+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
 112.110 -+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
 112.111 -+		BUG_ON(r->repl->targ_size < r->repl->up_size);
 112.112 -+               if (system_state == SYSTEM_RUNNING &&
 112.113 -+                   r->targ_start >= (void *)&__init_begin &&
 112.114 -+                   r->targ_start < (void *)&__init_end)
 112.115 -+                       continue;
 112.116 -+		memcpy(r->targ_start,
 112.117 -+		       r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
 112.118 -+		       r->repl->up_size);
 112.119 -+		memset(r->targ_start + r->repl->up_size,
 112.120 -+		       0x90,
 112.121 -+		       r->repl->targ_size - r->repl->up_size);
 112.122 -+	}
 112.123 -+	/* Paranoia */
 112.124 -+	asm volatile ("jmp 1f\n1:");
 112.125 -+	mb();
 112.126 -+}
 112.127 -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
 112.128 ---- ../pristine-linux-2.6.16/arch/i386/kernel/smpboot.c	2006-03-20 05:53:29.000000000 +0000
 112.129 -+++ ./arch/i386/kernel/smpboot.c	2006-03-20 19:38:27.000000000 +0000
 112.130 -@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne
 112.131 - 		if (max_cpus <= cpucount+1)
 112.132 - 			continue;
 112.133 - 
 112.134 -+#ifdef CONFIG_SMP_ALTERNATIVES
 112.135 -+		if (kicked == 1)
 112.136 -+			prepare_for_smp();
 112.137 -+#endif
 112.138 -+
 112.139 - 		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
 112.140 - 			printk("CPU #%d not responding - cannot use it.\n",
 112.141 - 								apicid);
 112.142 -@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu)
 112.143 - 		return -EIO;
 112.144 - 	}
 112.145 - 
 112.146 -+#ifdef CONFIG_SMP_ALTERNATIVES
 112.147 -+	if (num_online_cpus() == 1)
 112.148 -+		prepare_for_smp();
 112.149 -+#endif
 112.150 -+
 112.151 - 	local_irq_enable();
 112.152 - 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 112.153 - 	/* Unleash the CPU! */
 112.154 -diff -pruN ../pristine-linux-2.6.16/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
 112.155 ---- ../pristine-linux-2.6.16/arch/i386/kernel/vmlinux.lds.S	2006-03-20 05:53:29.000000000 +0000
 112.156 -+++ ./arch/i386/kernel/vmlinux.lds.S	2006-03-20 19:38:27.000000000 +0000
 112.157 -@@ -34,6 +34,13 @@ SECTIONS
 112.158 -   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
 112.159 -   __stop___ex_table = .;
 112.160 - 
 112.161 -+  . = ALIGN(16);
 112.162 -+  __start_smp_alternatives_table = .;
 112.163 -+  __smp_alternatives : { *(__smp_alternatives) }
 112.164 -+  __stop_smp_alternatives_table = .;
 112.165 -+
 112.166 -+  __smp_replacements : { *(__smp_replacements) }
 112.167 -+
 112.168 -   RODATA
 112.169 - 
 112.170 -   /* writeable */
 112.171 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
 112.172 ---- ../pristine-linux-2.6.16/include/asm-i386/atomic.h	2006-03-20 05:53:29.000000000 +0000
 112.173 -+++ ./include/asm-i386/atomic.h	2006-03-20 19:38:27.000000000 +0000
 112.174 -@@ -4,18 +4,13 @@
 112.175 - #include <linux/config.h>
 112.176 - #include <linux/compiler.h>
 112.177 - #include <asm/processor.h>
 112.178 -+#include <asm/smp_alt.h>
 112.179 - 
 112.180 - /*
 112.181 -  * Atomic operations that C can't guarantee us.  Useful for
 112.182 -  * resource counting etc..
 112.183 -  */
 112.184 - 
 112.185 --#ifdef CONFIG_SMP
 112.186 --#define LOCK "lock ; "
 112.187 --#else
 112.188 --#define LOCK ""
 112.189 --#endif
 112.190 --
 112.191 - /*
 112.192 -  * Make sure gcc doesn't try to be clever and move things around
 112.193 -  * on us. We need to use _exactly_ the address the user gave us,
 112.194 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
 112.195 ---- ../pristine-linux-2.6.16/include/asm-i386/bitops.h	2006-03-20 05:53:29.000000000 +0000
 112.196 -+++ ./include/asm-i386/bitops.h	2006-03-20 19:38:27.000000000 +0000
 112.197 -@@ -7,6 +7,7 @@
 112.198 - 
 112.199 - #include <linux/config.h>
 112.200 - #include <linux/compiler.h>
 112.201 -+#include <asm/smp_alt.h>
 112.202 - 
 112.203 - /*
 112.204 -  * These have to be done with inline assembly: that way the bit-setting
 112.205 -@@ -16,12 +17,6 @@
 112.206 -  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
 112.207 -  */
 112.208 - 
 112.209 --#ifdef CONFIG_SMP
 112.210 --#define LOCK_PREFIX "lock ; "
 112.211 --#else
 112.212 --#define LOCK_PREFIX ""
 112.213 --#endif
 112.214 --
 112.215 - #define ADDR (*(volatile long *) addr)
 112.216 - 
 112.217 - /**
 112.218 -@@ -41,7 +36,7 @@
 112.219 -  */
 112.220 - static inline void set_bit(int nr, volatile unsigned long * addr)
 112.221 - {
 112.222 --	__asm__ __volatile__( LOCK_PREFIX
 112.223 -+	__asm__ __volatile__( LOCK
 112.224 - 		"btsl %1,%0"
 112.225 - 		:"+m" (ADDR)
 112.226 - 		:"Ir" (nr));
 112.227 -@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
 112.228 -  */
 112.229 - static inline void clear_bit(int nr, volatile unsigned long * addr)
 112.230 - {
 112.231 --	__asm__ __volatile__( LOCK_PREFIX
 112.232 -+	__asm__ __volatile__( LOCK
 112.233 - 		"btrl %1,%0"
 112.234 - 		:"+m" (ADDR)
 112.235 - 		:"Ir" (nr));
 112.236 -@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 
 112.237 -  */
 112.238 - static inline void change_bit(int nr, volatile unsigned long * addr)
 112.239 - {
 112.240 --	__asm__ __volatile__( LOCK_PREFIX
 112.241 -+	__asm__ __volatile__( LOCK
 112.242 - 		"btcl %1,%0"
 112.243 - 		:"+m" (ADDR)
 112.244 - 		:"Ir" (nr));
 112.245 -@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
 112.246 - {
 112.247 - 	int oldbit;
 112.248 - 
 112.249 --	__asm__ __volatile__( LOCK_PREFIX
 112.250 -+	__asm__ __volatile__( LOCK
 112.251 - 		"btsl %2,%1\n\tsbbl %0,%0"
 112.252 - 		:"=r" (oldbit),"+m" (ADDR)
 112.253 - 		:"Ir" (nr) : "memory");
 112.254 -@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
 112.255 - {
 112.256 - 	int oldbit;
 112.257 - 
 112.258 --	__asm__ __volatile__( LOCK_PREFIX
 112.259 -+	__asm__ __volatile__( LOCK
 112.260 - 		"btrl %2,%1\n\tsbbl %0,%0"
 112.261 - 		:"=r" (oldbit),"+m" (ADDR)
 112.262 - 		:"Ir" (nr) : "memory");
 112.263 -@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
 112.264 - {
 112.265 - 	int oldbit;
 112.266 - 
 112.267 --	__asm__ __volatile__( LOCK_PREFIX
 112.268 -+	__asm__ __volatile__( LOCK
 112.269 - 		"btcl %2,%1\n\tsbbl %0,%0"
 112.270 - 		:"=r" (oldbit),"+m" (ADDR)
 112.271 - 		:"Ir" (nr) : "memory");
 112.272 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/futex.h ./include/asm-i386/futex.h
 112.273 ---- ../pristine-linux-2.6.16/include/asm-i386/futex.h	2006-03-20 05:53:29.000000000 +0000
 112.274 -+++ ./include/asm-i386/futex.h	2006-03-20 19:38:27.000000000 +0000
 112.275 -@@ -28,7 +28,7 @@
 112.276 - "1:	movl	%2, %0\n\
 112.277 - 	movl	%0, %3\n"					\
 112.278 - 	insn "\n"						\
 112.279 --"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
 112.280 -+"2:	" LOCK "cmpxchgl %3, %2\n\
 112.281 - 	jnz	1b\n\
 112.282 - 3:	.section .fixup,\"ax\"\n\
 112.283 - 4:	mov	%5, %1\n\
 112.284 -@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 
 112.285 - #endif
 112.286 - 		switch (op) {
 112.287 - 		case FUTEX_OP_ADD:
 112.288 --			__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
 112.289 -+			__futex_atomic_op1(LOCK "xaddl %0, %2", ret,
 112.290 - 					   oldval, uaddr, oparg);
 112.291 - 			break;
 112.292 - 		case FUTEX_OP_OR:
 112.293 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
 112.294 ---- ../pristine-linux-2.6.16/include/asm-i386/rwsem.h	2006-03-20 05:53:29.000000000 +0000
 112.295 -+++ ./include/asm-i386/rwsem.h	2006-03-20 19:38:27.000000000 +0000
 112.296 -@@ -40,6 +40,7 @@
 112.297 - 
 112.298 - #include <linux/list.h>
 112.299 - #include <linux/spinlock.h>
 112.300 -+#include <asm/smp_alt.h>
 112.301 - 
 112.302 - struct rwsem_waiter;
 112.303 - 
 112.304 -@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
 112.305 - {
 112.306 - 	__asm__ __volatile__(
 112.307 - 		"# beginning down_read\n\t"
 112.308 --LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 112.309 -+LOCK	        "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 112.310 - 		"  js        2f\n\t" /* jump if we weren't granted the lock */
 112.311 - 		"1:\n\t"
 112.312 - 		LOCK_SECTION_START("")
 112.313 -@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
 112.314 - 		"  movl	     %1,%2\n\t"
 112.315 - 		"  addl      %3,%2\n\t"
 112.316 - 		"  jle	     2f\n\t"
 112.317 --LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
 112.318 -+LOCK	        "  cmpxchgl  %2,%0\n\t"
 112.319 - 		"  jnz	     1b\n\t"
 112.320 - 		"2:\n\t"
 112.321 - 		"# ending __down_read_trylock\n\t"
 112.322 -@@ -150,7 +151,7 @@ static inline void __down_write(struct r
 112.323 - 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
 112.324 - 	__asm__ __volatile__(
 112.325 - 		"# beginning down_write\n\t"
 112.326 --LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
 112.327 -+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
 112.328 - 		"  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
 112.329 - 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
 112.330 - 		"1:\n\t"
 112.331 -@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
 112.332 - 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
 112.333 - 	__asm__ __volatile__(
 112.334 - 		"# beginning __up_read\n\t"
 112.335 --LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 112.336 -+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 112.337 - 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 112.338 - 		"1:\n\t"
 112.339 - 		LOCK_SECTION_START("")
 112.340 -@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
 112.341 - 	__asm__ __volatile__(
 112.342 - 		"# beginning __up_write\n\t"
 112.343 - 		"  movl      %2,%%edx\n\t"
 112.344 --LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 112.345 -+LOCK	        "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 112.346 - 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
 112.347 - 		"1:\n\t"
 112.348 - 		LOCK_SECTION_START("")
 112.349 -@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
 112.350 - {
 112.351 - 	__asm__ __volatile__(
 112.352 - 		"# beginning __downgrade_write\n\t"
 112.353 --LOCK_PREFIX	"  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
 112.354 -+LOCK	        "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
 112.355 - 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 112.356 - 		"1:\n\t"
 112.357 - 		LOCK_SECTION_START("")
 112.358 -@@ -263,7 +264,7 @@ LOCK_PREFIX	"  addl      %2,(%%eax)\n\t"
 112.359 - static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
 112.360 - {
 112.361 - 	__asm__ __volatile__(
 112.362 --LOCK_PREFIX	"addl %1,%0"
 112.363 -+LOCK	          "addl %1,%0"
 112.364 - 		: "=m"(sem->count)
 112.365 - 		: "ir"(delta), "m"(sem->count));
 112.366 - }
 112.367 -@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
 112.368 - 	int tmp = delta;
 112.369 - 
 112.370 - 	__asm__ __volatile__(
 112.371 --LOCK_PREFIX	"xadd %0,(%2)"
 112.372 -+LOCK  	          "xadd %0,(%2)"
 112.373 - 		: "+r"(tmp), "=m"(sem->count)
 112.374 - 		: "r"(sem), "m"(sem->count)
 112.375 - 		: "memory");
 112.376 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
 112.377 ---- ../pristine-linux-2.6.16/include/asm-i386/smp_alt.h	1970-01-01 01:00:00.000000000 +0100
 112.378 -+++ ./include/asm-i386/smp_alt.h	2006-03-20 19:38:27.000000000 +0000
 112.379 -@@ -0,0 +1,32 @@
 112.380 -+#ifndef __ASM_SMP_ALT_H__
 112.381 -+#define __ASM_SMP_ALT_H__
 112.382 -+
 112.383 -+#include <linux/config.h>
 112.384 -+
 112.385 -+#ifdef CONFIG_SMP
 112.386 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
 112.387 -+#define LOCK \
 112.388 -+        "6677: nop\n" \
 112.389 -+	".section __smp_alternatives,\"a\"\n" \
 112.390 -+	".long 6677b\n" \
 112.391 -+	".long 6678f\n" \
 112.392 -+	".previous\n" \
 112.393 -+	".section __smp_replacements,\"a\"\n" \
 112.394 -+	"6678: .byte 1\n" \
 112.395 -+	".byte 1\n" \
 112.396 -+	".byte 0\n" \
 112.397 -+        ".byte 1\n" \
 112.398 -+	".byte -1\n" \
 112.399 -+	"lock\n" \
 112.400 -+	"nop\n" \
 112.401 -+	".previous\n"
 112.402 -+void prepare_for_smp(void);
 112.403 -+void unprepare_for_smp(void);
 112.404 -+#else
 112.405 -+#define LOCK "lock ; "
 112.406 -+#endif
 112.407 -+#else
 112.408 -+#define LOCK ""
 112.409 -+#endif
 112.410 -+
 112.411 -+#endif /* __ASM_SMP_ALT_H__ */
 112.412 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
 112.413 ---- ../pristine-linux-2.6.16/include/asm-i386/spinlock.h	2006-03-20 05:53:29.000000000 +0000
 112.414 -+++ ./include/asm-i386/spinlock.h	2006-03-20 19:38:27.000000000 +0000
 112.415 -@@ -6,6 +6,7 @@
 112.416 - #include <asm/page.h>
 112.417 - #include <linux/config.h>
 112.418 - #include <linux/compiler.h>
 112.419 -+#include <asm/smp_alt.h>
 112.420 - 
 112.421 - /*
 112.422 -  * Your basic SMP spinlocks, allowing only a single CPU anywhere
 112.423 -@@ -23,7 +24,8 @@
 112.424 - 
 112.425 - #define __raw_spin_lock_string \
 112.426 - 	"\n1:\t" \
 112.427 --	"lock ; decb %0\n\t" \
 112.428 -+	LOCK \
 112.429 -+	"decb %0\n\t" \
 112.430 - 	"jns 3f\n" \
 112.431 - 	"2:\t" \
 112.432 - 	"rep;nop\n\t" \
 112.433 -@@ -34,7 +36,8 @@
 112.434 - 
 112.435 - #define __raw_spin_lock_string_flags \
 112.436 - 	"\n1:\t" \
 112.437 --	"lock ; decb %0\n\t" \
 112.438 -+	LOCK \
 112.439 -+	"decb %0\n\t" \
 112.440 - 	"jns 4f\n\t" \
 112.441 - 	"2:\t" \
 112.442 - 	"testl $0x200, %1\n\t" \
 112.443 -@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
 112.444 - static inline int __raw_spin_trylock(raw_spinlock_t *lock)
 112.445 - {
 112.446 - 	char oldval;
 112.447 -+#ifdef CONFIG_SMP_ALTERNATIVES
 112.448 - 	__asm__ __volatile__(
 112.449 --		"xchgb %b0,%1"
 112.450 -+		"1:movb %1,%b0\n"
 112.451 -+		"movb $0,%1\n"
 112.452 -+		"2:"
 112.453 -+		".section __smp_alternatives,\"a\"\n"
 112.454 -+		".long 1b\n"
 112.455 -+		".long 3f\n"
 112.456 -+		".previous\n"
 112.457 -+		".section __smp_replacements,\"a\"\n"
 112.458 -+		"3: .byte 2b - 1b\n"
 112.459 -+		".byte 5f-4f\n"
 112.460 -+		".byte 0\n"
 112.461 -+		".byte 6f-5f\n"
 112.462 -+		".byte -1\n"
 112.463 -+		"4: xchgb %b0,%1\n"
 112.464 -+		"5: movb %1,%b0\n"
 112.465 -+		"movb $0,%1\n"
 112.466 -+		"6:\n"
 112.467 -+		".previous\n"
 112.468 - 		:"=q" (oldval), "=m" (lock->slock)
 112.469 - 		:"0" (0) : "memory");
 112.470 -+#else
 112.471 -+	__asm__ __volatile__(
 112.472 -+		"xchgb %b0,%1\n"
 112.473 -+		:"=q" (oldval), "=m" (lock->slock)
 112.474 -+		:"0" (0) : "memory");
 112.475 -+#endif
 112.476 - 	return oldval > 0;
 112.477 - }
 112.478 - 
 112.479 -@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
 112.480 - 
 112.481 - static inline void __raw_read_unlock(raw_rwlock_t *rw)
 112.482 - {
 112.483 --	asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
 112.484 -+	asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
 112.485 - }
 112.486 - 
 112.487 - static inline void __raw_write_unlock(raw_rwlock_t *rw)
 112.488 - {
 112.489 --	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
 112.490 -+	asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
 112.491 - 				 : "=m" (rw->lock) : : "memory");
 112.492 - }
 112.493 - 
 112.494 -diff -pruN ../pristine-linux-2.6.16/include/asm-i386/system.h ./include/asm-i386/system.h
 112.495 ---- ../pristine-linux-2.6.16/include/asm-i386/system.h	2006-03-20 05:53:29.000000000 +0000
 112.496 -+++ ./include/asm-i386/system.h	2006-03-20 19:38:27.000000000 +0000
 112.497 -@@ -5,7 +5,7 @@
 112.498 - #include <linux/kernel.h>
 112.499 - #include <asm/segment.h>
 112.500 - #include <asm/cpufeature.h>
 112.501 --#include <linux/bitops.h> /* for LOCK_PREFIX */
 112.502 -+#include <asm/smp_alt.h>
 112.503 - 
 112.504 - #ifdef __KERNEL__
 112.505 - 
 112.506 -@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
 112.507 - 	unsigned long prev;
 112.508 - 	switch (size) {
 112.509 - 	case 1:
 112.510 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
 112.511 -+		__asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
 112.512 - 				     : "=a"(prev)
 112.513 - 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
 112.514 - 				     : "memory");
 112.515 - 		return prev;
 112.516 - 	case 2:
 112.517 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
 112.518 -+		__asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
 112.519 - 				     : "=a"(prev)
 112.520 - 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
 112.521 - 				     : "memory");
 112.522 - 		return prev;
 112.523 - 	case 4:
 112.524 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
 112.525 -+		__asm__ __volatile__(LOCK "cmpxchgl %1,%2"
 112.526 - 				     : "=a"(prev)
 112.527 - 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
 112.528 - 				     : "memory");
 112.529 -@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
 112.530 - 				      unsigned long long new)
 112.531 - {
 112.532 - 	unsigned long long prev;
 112.533 --	__asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
 112.534 -+	__asm__ __volatile__(LOCK "cmpxchg8b %3"
 112.535 - 			     : "=A"(prev)
 112.536 - 			     : "b"((unsigned long)new),
 112.537 - 			       "c"((unsigned long)(new >> 32)),
 112.538 -@@ -503,11 +503,55 @@ struct alt_instr { 
 112.539 - #endif
 112.540 - 
 112.541 - #ifdef CONFIG_SMP
 112.542 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
 112.543 -+#define smp_alt_mb(instr)                                           \
 112.544 -+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
 112.545 -+		     ".section __smp_alternatives,\"a\"\n"          \
 112.546 -+		     ".long 6667b\n"                                \
 112.547 -+                     ".long 6673f\n"                                \
 112.548 -+		     ".previous\n"                                  \
 112.549 -+		     ".section __smp_replacements,\"a\"\n"          \
 112.550 -+		     "6673:.byte 6668b-6667b\n"                     \
 112.551 -+		     ".byte 6670f-6669f\n"                          \
 112.552 -+		     ".byte 6671f-6670f\n"                          \
 112.553 -+                     ".byte 0\n"                                    \
 112.554 -+		     ".byte %c0\n"                                  \
 112.555 -+		     "6669:lock;addl $0,0(%%esp)\n"                 \
 112.556 -+		     "6670:" instr "\n"                             \
 112.557 -+		     "6671:\n"                                      \
 112.558 -+		     ".previous\n"                                  \
 112.559 -+		     :                                              \
 112.560 -+		     : "i" (X86_FEATURE_XMM2)                       \
 112.561 -+		     : "memory")
 112.562 -+#define smp_rmb() smp_alt_mb("lfence")
 112.563 -+#define smp_mb()  smp_alt_mb("mfence")
 112.564 -+#define set_mb(var, value) do {                                     \
 112.565 -+unsigned long __set_mb_temp;                                        \
 112.566 -+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
 112.567 -+		     ".section __smp_alternatives,\"a\"\n"          \
 112.568 -+		     ".long 6667b\n"                                \
 112.569 -+		     ".long 6673f\n"                                \
 112.570 -+		     ".previous\n"                                  \
 112.571 -+		     ".section __smp_replacements,\"a\"\n"          \
 112.572 -+		     "6673: .byte 6668b-6667b\n"                    \
 112.573 -+		     ".byte 6670f-6669f\n"                          \
 112.574 -+		     ".byte 0\n"                                    \
 112.575 -+		     ".byte 6671f-6670f\n"                          \
 112.576 -+		     ".byte -1\n"                                   \
 112.577 -+		     "6669: xchg %1, %0\n"                          \
 112.578 -+		     "6670:movl %1, %0\n"                           \
 112.579 -+		     "6671:\n"                                      \
 112.580 -+		     ".previous\n"                                  \
 112.581 -+		     : "=m" (var), "=r" (__set_mb_temp)             \
 112.582 -+		     : "1" (value)                                  \
 112.583 -+		     : "memory"); } while (0)
 112.584 -+#else
 112.585 - #define smp_mb()	mb()
 112.586 - #define smp_rmb()	rmb()
 112.587 -+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 112.588 -+#endif
 112.589 - #define smp_wmb()	wmb()
 112.590 - #define smp_read_barrier_depends()	read_barrier_depends()
 112.591 --#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 112.592 - #else
 112.593 - #define smp_mb()	barrier()
 112.594 - #define smp_rmb()	barrier()
   113.1 --- a/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch	Mon May 08 13:41:18 2006 -0600
   113.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.3 @@ -1,107 +0,0 @@
   113.4 -Subject: Increase x86 interrupt vector range
   113.5 -
   113.6 -Remove the limit of 256 interrupt vectors by changing the value
   113.7 -stored in orig_{e,r}ax to be the negated interrupt vector.
   113.8 -The orig_{e,r}ax needs to be < 0 to allow the signal code to
   113.9 -distinguish between return from interrupt and return from syscall.
  113.10 -With this change applied, NR_IRQS can be > 256.
  113.11 -
  113.12 -Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
  113.13 ----
  113.14 - arch/i386/kernel/entry.S    |    4 ++--
  113.15 - arch/i386/kernel/irq.c      |    4 ++--
  113.16 - arch/x86_64/kernel/entry.S  |    2 +-
  113.17 - arch/x86_64/kernel/irq.c    |    4 ++--
  113.18 - arch/x86_64/kernel/smp.c    |    4 ++--
  113.19 - include/asm-x86_64/hw_irq.h |    2 +-
  113.20 - 6 files changed, 10 insertions(+), 10 deletions(-)
  113.21 -
  113.22 -diff -r 7d239c83edea arch/i386/kernel/entry.S
  113.23 ---- a/arch/i386/kernel/entry.S	Mon Mar 20 06:00:20 2006 +0000
  113.24 -+++ b/arch/i386/kernel/entry.S	Fri Mar 31 17:01:35 2006 +0100
  113.25 -@@ -406,7 +406,7 @@ ENTRY(irq_entries_start)
  113.26 - ENTRY(irq_entries_start)
  113.27 - .rept NR_IRQS
  113.28 - 	ALIGN
  113.29 --1:	pushl $vector-256
  113.30 -+1:	pushl $~(vector)
  113.31 - 	jmp common_interrupt
  113.32 - .data
  113.33 - 	.long 1b
  113.34 -@@ -423,7 +423,7 @@ common_interrupt:
  113.35 - 
  113.36 - #define BUILD_INTERRUPT(name, nr)	\
  113.37 - ENTRY(name)				\
  113.38 --	pushl $nr-256;			\
  113.39 -+	pushl $~(nr);			\
  113.40 - 	SAVE_ALL			\
  113.41 - 	movl %esp,%eax;			\
  113.42 - 	call smp_/**/name;		\
  113.43 -diff -r 7d239c83edea arch/i386/kernel/irq.c
  113.44 ---- a/arch/i386/kernel/irq.c	Mon Mar 20 06:00:20 2006 +0000
  113.45 -+++ b/arch/i386/kernel/irq.c	Fri Mar 31 17:01:35 2006 +0100
  113.46 -@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
  113.47 -  */
  113.48 - fastcall unsigned int do_IRQ(struct pt_regs *regs)
  113.49 - {	
  113.50 --	/* high bits used in ret_from_ code */
  113.51 --	int irq = regs->orig_eax & 0xff;
  113.52 -+	/* high bit used in ret_from_ code */
  113.53 -+	int irq = ~regs->orig_eax;
  113.54 - #ifdef CONFIG_4KSTACKS
  113.55 - 	union irq_ctx *curctx, *irqctx;
  113.56 - 	u32 *isp;
  113.57 -diff -r 7d239c83edea arch/x86_64/kernel/entry.S
  113.58 ---- a/arch/x86_64/kernel/entry.S	Mon Mar 20 06:00:20 2006 +0000
  113.59 -+++ b/arch/x86_64/kernel/entry.S	Fri Mar 31 17:01:35 2006 +0100
  113.60 -@@ -609,7 +609,7 @@ retint_kernel:
  113.61 -  */		
  113.62 - 	.macro apicinterrupt num,func
  113.63 - 	INTR_FRAME
  113.64 --	pushq $\num-256
  113.65 -+	pushq $~(\num)
  113.66 - 	CFI_ADJUST_CFA_OFFSET 8
  113.67 - 	interrupt \func
  113.68 - 	jmp ret_from_intr
  113.69 -diff -r 7d239c83edea arch/x86_64/kernel/irq.c
  113.70 ---- a/arch/x86_64/kernel/irq.c	Mon Mar 20 06:00:20 2006 +0000
  113.71 -+++ b/arch/x86_64/kernel/irq.c	Fri Mar 31 17:01:35 2006 +0100
  113.72 -@@ -96,8 +96,8 @@ skip:
  113.73 -  */
  113.74 - asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
  113.75 - {	
  113.76 --	/* high bits used in ret_from_ code  */
  113.77 --	unsigned irq = regs->orig_rax & 0xff;
  113.78 -+	/* high bit used in ret_from_ code  */
  113.79 -+	unsigned irq = ~regs->orig_rax;
  113.80 - 
  113.81 - 	exit_idle();
  113.82 - 	irq_enter();
  113.83 -diff -r 7d239c83edea arch/x86_64/kernel/smp.c
  113.84 ---- a/arch/x86_64/kernel/smp.c	Mon Mar 20 06:00:20 2006 +0000
  113.85 -+++ b/arch/x86_64/kernel/smp.c	Fri Mar 31 17:01:35 2006 +0100
  113.86 -@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
  113.87 - 
  113.88 - 	cpu = smp_processor_id();
  113.89 - 	/*
  113.90 --	 * orig_rax contains the interrupt vector - 256.
  113.91 -+	 * orig_rax contains the negated interrupt vector.
  113.92 - 	 * Use that to determine where the sender put the data.
  113.93 - 	 */
  113.94 --	sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
  113.95 -+	sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
  113.96 - 	f = &per_cpu(flush_state, sender);
  113.97 - 
  113.98 - 	if (!cpu_isset(cpu, f->flush_cpumask))
  113.99 -diff -r 7d239c83edea include/asm-x86_64/hw_irq.h
 113.100 ---- a/include/asm-x86_64/hw_irq.h	Mon Mar 20 06:00:20 2006 +0000
 113.101 -+++ b/include/asm-x86_64/hw_irq.h	Fri Mar 31 17:01:35 2006 +0100
 113.102 -@@ -127,7 +127,7 @@ __asm__( \
 113.103 - __asm__( \
 113.104 - "\n.p2align\n" \
 113.105 - "IRQ" #nr "_interrupt:\n\t" \
 113.106 --	"push $" #nr "-256 ; " \
 113.107 -+	"push $~(" #nr ") ; " \
 113.108 - 	"jmp common_interrupt");
 113.109 - 
 113.110 - #if defined(CONFIG_X86_IO_APIC)
   114.1 --- a/patches/linux-2.6.16/xenoprof-generic.patch	Mon May 08 13:41:18 2006 -0600
   114.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.3 @@ -1,384 +0,0 @@
   114.4 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
   114.5 ---- ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c	2006-03-20 05:53:29.000000000 +0000
   114.6 -+++ ./drivers/oprofile/buffer_sync.c	2006-04-03 15:53:05.000000000 +0100
   114.7 -@@ -6,6 +6,10 @@
   114.8 -  *
   114.9 -  * @author John Levon <levon@movementarian.org>
  114.10 -  *
  114.11 -+ * Modified by Aravind Menon for Xen
  114.12 -+ * These modifications are:
  114.13 -+ * Copyright (C) 2005 Hewlett-Packard Co.
  114.14 -+ *
  114.15 -  * This is the core of the buffer management. Each
  114.16 -  * CPU buffer is processed and entered into the
  114.17 -  * global event buffer. Such processing is necessary
  114.18 -@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
  114.19 - 	last_cookie = INVALID_COOKIE;
  114.20 - }
  114.21 - 
  114.22 --static void add_kernel_ctx_switch(unsigned int in_kernel)
  114.23 -+static void add_cpu_mode_switch(unsigned int cpu_mode)
  114.24 - {
  114.25 - 	add_event_entry(ESCAPE_CODE);
  114.26 --	if (in_kernel)
  114.27 --		add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
  114.28 --	else
  114.29 --		add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
  114.30 -+	switch (cpu_mode) {
  114.31 -+	case CPU_MODE_USER:
  114.32 -+		add_event_entry(USER_ENTER_SWITCH_CODE);
  114.33 -+		break;
  114.34 -+	case CPU_MODE_KERNEL:
  114.35 -+		add_event_entry(KERNEL_ENTER_SWITCH_CODE);
  114.36 -+		break;
  114.37 -+	case CPU_MODE_XEN:
  114.38 -+		add_event_entry(XEN_ENTER_SWITCH_CODE);
  114.39 -+		break;
  114.40 -+	default:
  114.41 -+		break;
  114.42 -+	}
  114.43 - }
  114.44 -- 
  114.45 -+
  114.46 - static void
  114.47 - add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
  114.48 - {
  114.49 -@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
  114.50 -  * for later lookup from userspace.
  114.51 -  */
  114.52 - static int
  114.53 --add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
  114.54 -+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
  114.55 - {
  114.56 --	if (in_kernel) {
  114.57 -+	if (cpu_mode >= CPU_MODE_KERNEL) {
  114.58 - 		add_sample_entry(s->eip, s->event);
  114.59 - 		return 1;
  114.60 - 	} else if (mm) {
  114.61 -@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
  114.62 - 	struct mm_struct *mm = NULL;
  114.63 - 	struct task_struct * new;
  114.64 - 	unsigned long cookie = 0;
  114.65 --	int in_kernel = 1;
  114.66 -+	int cpu_mode = 1;
  114.67 - 	unsigned int i;
  114.68 - 	sync_buffer_state state = sb_buffer_start;
  114.69 - 	unsigned long available;
  114.70 -@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
  114.71 - 		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
  114.72 -  
  114.73 - 		if (is_code(s->eip)) {
  114.74 --			if (s->event <= CPU_IS_KERNEL) {
  114.75 -+			if (s->event <= CPU_MODE_XEN) {
  114.76 - 				/* kernel/userspace switch */
  114.77 --				in_kernel = s->event;
  114.78 -+				cpu_mode = s->event;
  114.79 - 				if (state == sb_buffer_start)
  114.80 - 					state = sb_sample_start;
  114.81 --				add_kernel_ctx_switch(s->event);
  114.82 -+				add_cpu_mode_switch(s->event);
  114.83 - 			} else if (s->event == CPU_TRACE_BEGIN) {
  114.84 - 				state = sb_bt_start;
  114.85 - 				add_trace_begin();
  114.86 -@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
  114.87 - 			}
  114.88 - 		} else {
  114.89 - 			if (state >= sb_bt_start &&
  114.90 --			    !add_sample(mm, s, in_kernel)) {
  114.91 -+			    !add_sample(mm, s, cpu_mode)) {
  114.92 - 				if (state == sb_bt_start) {
  114.93 - 					state = sb_bt_ignore;
  114.94 - 					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  114.95 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
  114.96 ---- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c	2006-03-20 05:53:29.000000000 +0000
  114.97 -+++ ./drivers/oprofile/cpu_buffer.c	2006-04-03 15:53:05.000000000 +0100
  114.98 -@@ -6,6 +6,10 @@
  114.99 -  *
 114.100 -  * @author John Levon <levon@movementarian.org>
 114.101 -  *
 114.102 -+ * Modified by Aravind Menon for Xen
 114.103 -+ * These modifications are:
 114.104 -+ * Copyright (C) 2005 Hewlett-Packard Co.
 114.105 -+ *
 114.106 -  * Each CPU has a local buffer that stores PC value/event
 114.107 -  * pairs. We also log context switches when we notice them.
 114.108 -  * Eventually each CPU's buffer is processed into the global
 114.109 -@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
 114.110 - 			goto fail;
 114.111 -  
 114.112 - 		b->last_task = NULL;
 114.113 --		b->last_is_kernel = -1;
 114.114 -+		b->last_cpu_mode = -1;
 114.115 - 		b->tracing = 0;
 114.116 - 		b->buffer_size = buffer_size;
 114.117 - 		b->tail_pos = 0;
 114.118 -@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
 114.119 - 	 * collected will populate the buffer with proper
 114.120 - 	 * values to initialize the buffer
 114.121 - 	 */
 114.122 --	cpu_buf->last_is_kernel = -1;
 114.123 -+	cpu_buf->last_cpu_mode = -1;
 114.124 - 	cpu_buf->last_task = NULL;
 114.125 - }
 114.126 - 
 114.127 -@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
 114.128 -  * because of the head/tail separation of the writer and reader
 114.129 -  * of the CPU buffer.
 114.130 -  *
 114.131 -- * is_kernel is needed because on some architectures you cannot
 114.132 -+ * cpu_mode is needed because on some architectures you cannot
 114.133 -  * tell if you are in kernel or user space simply by looking at
 114.134 -- * pc. We tag this in the buffer by generating kernel enter/exit
 114.135 -- * events whenever is_kernel changes
 114.136 -+ * pc. We tag this in the buffer by generating kernel/user (and xen)
 114.137 -+ *  enter events whenever cpu_mode changes
 114.138 -  */
 114.139 - static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
 114.140 --		      int is_kernel, unsigned long event)
 114.141 -+		      int cpu_mode, unsigned long event)
 114.142 - {
 114.143 - 	struct task_struct * task;
 114.144 - 
 114.145 -@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
 114.146 - 		return 0;
 114.147 - 	}
 114.148 - 
 114.149 --	is_kernel = !!is_kernel;
 114.150 -+	WARN_ON(cpu_mode > CPU_MODE_XEN);
 114.151 - 
 114.152 - 	task = current;
 114.153 - 
 114.154 - 	/* notice a switch from user->kernel or vice versa */
 114.155 --	if (cpu_buf->last_is_kernel != is_kernel) {
 114.156 --		cpu_buf->last_is_kernel = is_kernel;
 114.157 --		add_code(cpu_buf, is_kernel);
 114.158 -+	if (cpu_buf->last_cpu_mode != cpu_mode) {
 114.159 -+		cpu_buf->last_cpu_mode = cpu_mode;
 114.160 -+		add_code(cpu_buf, cpu_mode);
 114.161 - 	}
 114.162 --
 114.163 -+	
 114.164 - 	/* notice a task switch */
 114.165 - 	if (cpu_buf->last_task != task) {
 114.166 - 		cpu_buf->last_task = task;
 114.167 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
 114.168 ---- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h	2006-03-20 05:53:29.000000000 +0000
 114.169 -+++ ./drivers/oprofile/cpu_buffer.h	2006-04-03 15:53:05.000000000 +0100
 114.170 -@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
 114.171 - 	volatile unsigned long tail_pos;
 114.172 - 	unsigned long buffer_size;
 114.173 - 	struct task_struct * last_task;
 114.174 --	int last_is_kernel;
 114.175 -+	int last_cpu_mode;
 114.176 - 	int tracing;
 114.177 - 	struct op_sample * buffer;
 114.178 - 	unsigned long sample_received;
 114.179 -@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
 114.180 - void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
 114.181 - 
 114.182 - /* transient events for the CPU buffer -> event buffer */
 114.183 --#define CPU_IS_KERNEL 1
 114.184 --#define CPU_TRACE_BEGIN 2
 114.185 -+#define CPU_MODE_USER    0
 114.186 -+#define CPU_MODE_KERNEL  1
 114.187 -+#define CPU_MODE_XEN     2
 114.188 -+#define CPU_TRACE_BEGIN  3
 114.189 - 
 114.190 - #endif /* OPROFILE_CPU_BUFFER_H */
 114.191 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
 114.192 ---- ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h	2006-03-20 05:53:29.000000000 +0000
 114.193 -+++ ./drivers/oprofile/event_buffer.h	2006-04-03 15:53:05.000000000 +0100
 114.194 -@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
 114.195 - #define CPU_SWITCH_CODE 		2
 114.196 - #define COOKIE_SWITCH_CODE 		3
 114.197 - #define KERNEL_ENTER_SWITCH_CODE	4
 114.198 --#define KERNEL_EXIT_SWITCH_CODE		5
 114.199 -+#define USER_ENTER_SWITCH_CODE		5
 114.200 - #define MODULE_LOADED_CODE		6
 114.201 - #define CTX_TGID_CODE			7
 114.202 - #define TRACE_BEGIN_CODE		8
 114.203 - #define TRACE_END_CODE			9
 114.204 -+#define XEN_ENTER_SWITCH_CODE		10
 114.205 -  
 114.206 - #define INVALID_COOKIE ~0UL
 114.207 - #define NO_COOKIE 0UL
 114.208 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
 114.209 ---- ../pristine-linux-2.6.16/drivers/oprofile/oprof.c	2006-03-20 05:53:29.000000000 +0000
 114.210 -+++ ./drivers/oprofile/oprof.c	2006-04-03 15:53:05.000000000 +0100
 114.211 -@@ -5,6 +5,10 @@
 114.212 -  * @remark Read the file COPYING
 114.213 -  *
 114.214 -  * @author John Levon <levon@movementarian.org>
 114.215 -+ *
 114.216 -+ * Modified by Aravind Menon for Xen
 114.217 -+ * These modifications are:
 114.218 -+ * Copyright (C) 2005 Hewlett-Packard Co.
 114.219 -  */
 114.220 - 
 114.221 - #include <linux/kernel.h>
 114.222 -@@ -19,7 +23,7 @@
 114.223 - #include "cpu_buffer.h"
 114.224 - #include "buffer_sync.h"
 114.225 - #include "oprofile_stats.h"
 114.226 -- 
 114.227 -+
 114.228 - struct oprofile_operations oprofile_ops;
 114.229 - 
 114.230 - unsigned long oprofile_started;
 114.231 -@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem);
 114.232 -  */
 114.233 - static int timer = 0;
 114.234 - 
 114.235 -+extern unsigned int adomains;
 114.236 -+extern int active_domains[MAX_OPROF_DOMAINS];
 114.237 -+
 114.238 -+int oprofile_set_active(void)
 114.239 -+{
 114.240 -+	if (oprofile_ops.set_active)
 114.241 -+		return oprofile_ops.set_active(active_domains, adomains);
 114.242 -+
 114.243 -+	return -EINVAL;
 114.244 -+}
 114.245 -+
 114.246 - int oprofile_setup(void)
 114.247 - {
 114.248 - 	int err;
 114.249 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
 114.250 ---- ../pristine-linux-2.6.16/drivers/oprofile/oprof.h	2006-03-20 05:53:29.000000000 +0000
 114.251 -+++ ./drivers/oprofile/oprof.h	2006-04-03 15:53:05.000000000 +0100
 114.252 -@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
 114.253 - void oprofile_timer_init(struct oprofile_operations * ops);
 114.254 - 
 114.255 - int oprofile_set_backtrace(unsigned long depth);
 114.256 -+
 114.257 -+int oprofile_set_active(void);
 114.258 -  
 114.259 - #endif /* OPROF_H */
 114.260 -diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
 114.261 ---- ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c	2006-03-20 05:53:29.000000000 +0000
 114.262 -+++ ./drivers/oprofile/oprofile_files.c	2006-04-03 15:53:05.000000000 +0100
 114.263 -@@ -5,15 +5,21 @@
 114.264 -  * @remark Read the file COPYING
 114.265 -  *
 114.266 -  * @author John Levon <levon@movementarian.org>
 114.267 -+ *
 114.268 -+ * Modified by Aravind Menon for Xen
 114.269 -+ * These modifications are:
 114.270 -+ * Copyright (C) 2005 Hewlett-Packard Co.	
 114.271 -  */
 114.272 - 
 114.273 - #include <linux/fs.h>
 114.274 - #include <linux/oprofile.h>
 114.275 -+#include <asm/uaccess.h>
 114.276 -+#include <linux/ctype.h>
 114.277 - 
 114.278 - #include "event_buffer.h"
 114.279 - #include "oprofile_stats.h"
 114.280 - #include "oprof.h"
 114.281 -- 
 114.282 -+
 114.283 - unsigned long fs_buffer_size = 131072;
 114.284 - unsigned long fs_cpu_buffer_size = 8192;
 114.285 - unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
 114.286 -@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file * 
 114.287 - static struct file_operations dump_fops = {
 114.288 - 	.write		= dump_write,
 114.289 - };
 114.290 -- 
 114.291 -+
 114.292 -+#define TMPBUFSIZE 512
 114.293 -+
 114.294 -+unsigned int adomains = 0;
 114.295 -+long active_domains[MAX_OPROF_DOMAINS];
 114.296 -+
 114.297 -+static ssize_t adomain_write(struct file * file, char const __user * buf, 
 114.298 -+			     size_t count, loff_t * offset)
 114.299 -+{
 114.300 -+	char tmpbuf[TMPBUFSIZE];
 114.301 -+	char * startp = tmpbuf;
 114.302 -+	char * endp = tmpbuf;
 114.303 -+	int i;
 114.304 -+	unsigned long val;
 114.305 -+	
 114.306 -+	if (*offset)
 114.307 -+		return -EINVAL;	
 114.308 -+	if (!count)
 114.309 -+		return 0;
 114.310 -+	if (count > TMPBUFSIZE - 1)
 114.311 -+		return -EINVAL;
 114.312 -+
 114.313 -+	memset(tmpbuf, 0x0, TMPBUFSIZE);
 114.314 -+
 114.315 -+	if (copy_from_user(tmpbuf, buf, count))
 114.316 -+		return -EFAULT;
 114.317 -+	
 114.318 -+	for (i = 0; i < MAX_OPROF_DOMAINS; i++)
 114.319 -+		active_domains[i] = -1;
 114.320 -+	adomains = 0;
 114.321 -+
 114.322 -+	while (1) {
 114.323 -+		val = simple_strtol(startp, &endp, 0);
 114.324 -+		if (endp == startp)
 114.325 -+			break;
 114.326 -+		while (ispunct(*endp))
 114.327 -+			endp++;
 114.328 -+		active_domains[adomains++] = val;
 114.329 -+		if (adomains >= MAX_OPROF_DOMAINS)
 114.330 -+			break;
 114.331 -+		startp = endp;
 114.332 -+	}
 114.333 -+	if (oprofile_set_active())
 114.334 -+		return -EINVAL; 
 114.335 -+	return count;
 114.336 -+}
 114.337 -+
 114.338 -+static ssize_t adomain_read(struct file * file, char __user * buf, 
 114.339 -+			    size_t count, loff_t * offset)
 114.340 -+{
 114.341 -+	char tmpbuf[TMPBUFSIZE];
 114.342 -+	size_t len = 0;
 114.343 -+	int i;
 114.344 -+	/* This is all screwed up if we run out of space */
 114.345 -+	for (i = 0; i < adomains; i++) 
 114.346 -+		len += snprintf(tmpbuf + len, TMPBUFSIZE - len, 
 114.347 -+				"%u ", (unsigned int)active_domains[i]);
 114.348 -+	len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
 114.349 -+	return simple_read_from_buffer((void __user *)buf, count, 
 114.350 -+				       offset, tmpbuf, len);
 114.351 -+}
 114.352 -+
 114.353 -+
 114.354 -+static struct file_operations active_domain_ops = {
 114.355 -+	.read		= adomain_read,
 114.356 -+	.write		= adomain_write,
 114.357 -+};
 114.358 -+
 114.359 - void oprofile_create_files(struct super_block * sb, struct dentry * root)
 114.360 - {
 114.361 - 	oprofilefs_create_file(sb, root, "enable", &enable_fops);
 114.362 - 	oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
 114.363 -+	oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
 114.364 - 	oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
 114.365 - 	oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
 114.366 - 	oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
 114.367 -diff -pruN ../pristine-linux-2.6.16/include/linux/oprofile.h ./include/linux/oprofile.h
 114.368 ---- ../pristine-linux-2.6.16/include/linux/oprofile.h	2006-03-20 05:53:29.000000000 +0000
 114.369 -+++ ./include/linux/oprofile.h	2006-04-03 15:53:05.000000000 +0100
 114.370 -@@ -16,6 +16,8 @@
 114.371 - #include <linux/types.h>
 114.372 - #include <linux/spinlock.h>
 114.373 - #include <asm/atomic.h>
 114.374 -+
 114.375 -+#include <xen/interface/xenoprof.h>
 114.376 -  
 114.377 - struct super_block;
 114.378 - struct dentry;
 114.379 -@@ -27,6 +29,8 @@ struct oprofile_operations {
 114.380 - 	/* create any necessary configuration files in the oprofile fs.
 114.381 - 	 * Optional. */
 114.382 - 	int (*create_files)(struct super_block * sb, struct dentry * root);
 114.383 -+	/* setup active domains with Xen */
 114.384 -+	int (*set_active)(int *active_domains, unsigned int adomains);
 114.385 - 	/* Do any necessary interrupt setup. Optional. */
 114.386 - 	int (*setup)(void);
 114.387 - 	/* Do any necessary interrupt shutdown. Optional. */
   115.1 --- a/tools/Rules.mk	Mon May 08 13:41:18 2006 -0600
   115.2 +++ b/tools/Rules.mk	Mon May 08 14:46:11 2006 -0600
   115.3 @@ -12,7 +12,7 @@ XEN_LIBXENSTAT     = $(XEN_ROOT)/tools/x
   115.4  
   115.5  X11_LDPATH = -L/usr/X11R6/$(LIBDIR)
   115.6  
   115.7 -CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030101
   115.8 +CFLAGS += -D__XEN_TOOLS__
   115.9  
  115.10  %.opic: %.c
  115.11  	$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
  115.12 @@ -23,15 +23,23 @@ CFLAGS += -D__XEN_INTERFACE_VERSION__=0x
  115.13  %.o: %.cc
  115.14  	$(CC) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
  115.15  
  115.16 -.PHONY: mk-symlinks
  115.17 -mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
  115.18 -mk-symlinks:
  115.19 +OS = $(shell uname -s)
  115.20 +
  115.21 +.PHONY: mk-symlinks mk-symlinks-xen mk-symlinks-$(OS)
  115.22 +
  115.23 +mk-symlinks-Linux: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
  115.24 +mk-symlinks-Linux:
  115.25 +	mkdir -p xen/linux
  115.26 +	( cd xen/linux && \
  115.27 +	  ln -sf ../../$(LINUX_ROOT)/include/xen/public/*.h . )
  115.28 +	( cd xen && rm -f sys && ln -sf linux sys )
  115.29 +
  115.30 +mk-symlinks-xen:
  115.31  	mkdir -p xen
  115.32  	( cd xen && ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
  115.33  	mkdir -p xen/hvm
  115.34  	( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . )
  115.35  	mkdir -p xen/io
  115.36  	( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
  115.37 -	mkdir -p xen/linux
  115.38 -	( cd xen/linux && \
  115.39 -	  ln -sf ../../$(LINUX_ROOT)/include/xen/public/*.h . )
  115.40 +
  115.41 +mk-symlinks: mk-symlinks-xen mk-symlinks-$(OS)
   116.1 --- a/tools/debugger/pdb/pdb_caml_process.c	Mon May 08 13:41:18 2006 -0600
   116.2 +++ b/tools/debugger/pdb/pdb_caml_process.c	Mon May 08 14:46:11 2006 -0600
   116.3 @@ -18,7 +18,6 @@
   116.4  #include <xenctrl.h>
   116.5  #include <xen/xen.h>
   116.6  #include <xen/io/domain_controller.h>
   116.7 -#include <xen/linux/privcmd.h>
   116.8  #include "pdb_module.h"
   116.9  #include "pdb_caml_xen.h"
  116.10  
   117.1 --- a/tools/debugger/pdb/pdb_caml_xcs.c	Mon May 08 13:41:18 2006 -0600
   117.2 +++ b/tools/debugger/pdb/pdb_caml_xcs.c	Mon May 08 14:46:11 2006 -0600
   117.3 @@ -21,7 +21,6 @@
   117.4  
   117.5  #include <xen/xen.h>
   117.6  #include <xen/io/domain_controller.h>
   117.7 -#include <xen/linux/privcmd.h>
   117.8  
   117.9  #include <arpa/inet.h>
  117.10  #include <xcs_proto.h>
   118.1 --- a/tools/examples/network-bridge	Mon May 08 13:41:18 2006 -0600
   118.2 +++ b/tools/examples/network-bridge	Mon May 08 14:46:11 2006 -0600
   118.3 @@ -59,9 +59,8 @@ dir=$(dirname "$0")
   118.4  findCommand "$@"
   118.5  evalVariables "$@"
   118.6  
   118.7 -vifnum=${vifnum:-0}
   118.8 +vifnum=${vifnum:-$(ip route list | awk '/^default / { sub(/eth/,"",$NF); print $NF }')}
   118.9  bridge=${bridge:-xenbr${vifnum}}
  118.10 -netdev=${netdev:-$(ip route list default scope global| awk '{ print $NF }')}
  118.11  netdev=${netdev:-eth${vifnum}}
  118.12  antispoof=${antispoof:-no}
  118.13  
   119.1 --- a/tools/ioemu/configure	Mon May 08 13:41:18 2006 -0600
   119.2 +++ b/tools/ioemu/configure	Mon May 08 14:46:11 2006 -0600
   119.3 @@ -230,7 +230,7 @@ fi
   119.4  
   119.5  if test -z "$vnc"; then
   119.6  
   119.7 -if libvncserver-config --version >& /dev/null; then
   119.8 +if libvncserver-config --version > /dev/null 2>&1; then
   119.9      vnc=yes
  119.10  else
  119.11      vnc=no
   120.1 --- a/tools/ioemu/hw/pc.c	Mon May 08 13:41:18 2006 -0600
   120.2 +++ b/tools/ioemu/hw/pc.c	Mon May 08 14:46:11 2006 -0600
   120.3 @@ -166,14 +166,20 @@ static void cmos_init(uint64_t ram_size,
   120.4      switch(boot_device) {
   120.5      case 'a':
   120.6      case 'b':
   120.7 -        rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
   120.8 +        //rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
   120.9 +        rtc_set_memory(s, 0x3d, 0x21);   /* a->c->d */
  120.10 +        rtc_set_memory(s, 0x38, 0x30);
  120.11          break;
  120.12      default:
  120.13      case 'c':
  120.14 -        rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
  120.15 +        //rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
  120.16 +        rtc_set_memory(s, 0x3d, 0x32);   /* c->d->a */
  120.17 +        rtc_set_memory(s, 0x38, 0x10);
  120.18          break;
  120.19      case 'd':
  120.20 -        rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
  120.21 +        //rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
  120.22 +        rtc_set_memory(s, 0x3d, 0x23);   /* d->c->a */
  120.23 +        rtc_set_memory(s, 0x38, 0x10);
  120.24          break;
  120.25      }
  120.26  
   121.1 --- a/tools/libxc/Makefile	Mon May 08 13:41:18 2006 -0600
   121.2 +++ b/tools/libxc/Makefile	Mon May 08 14:46:11 2006 -0600
   121.3 @@ -16,6 +16,7 @@ SRCS       += xc_core.c
   121.4  SRCS       += xc_domain.c
   121.5  SRCS       += xc_evtchn.c
   121.6  SRCS       += xc_misc.c
   121.7 +SRCS       += xc_acm.c   
   121.8  SRCS       += xc_physdev.c
   121.9  SRCS       += xc_private.c
  121.10  SRCS       += xc_sedf.c
  121.11 @@ -27,6 +28,10 @@ SRCS       += xc_ptrace_core.c
  121.12  SRCS       += xc_pagetab.c
  121.13  endif
  121.14  
  121.15 +SRCS_Linux += xc_linux.c
  121.16 +
  121.17 +SRCS       += $(SRCS_Linux)
  121.18 +
  121.19  BUILD_SRCS :=
  121.20  BUILD_SRCS += xc_linux_build.c
  121.21  BUILD_SRCS += xc_load_bin.c
   122.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.2 +++ b/tools/libxc/xc_acm.c	Mon May 08 14:46:11 2006 -0600
   122.3 @@ -0,0 +1,54 @@
   122.4 +/******************************************************************************
   122.5 + *
   122.6 + * Copyright (C) 2005 IBM Corporation
   122.7 + *
   122.8 + * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
   122.9 + * Use is subject to license terms.
  122.10 + *
  122.11 + * Authors:
  122.12 + * Reiner Sailer <sailer@watson.ibm.com>
  122.13 + * Stefan Berger <stefanb@watson.ibm.com>
  122.14 + *
  122.15 + * This program is free software; you can redistribute it and/or
  122.16 + * modify it under the terms of the GNU General Public License as
  122.17 + * published by the Free Software Foundation, version 2 of the
  122.18 + * License.
  122.19 + */
  122.20 +
  122.21 +#include "xc_private.h"
  122.22 +
  122.23 +int xc_acm_op(int xc_handle, struct acm_op *op)
  122.24 +{
  122.25 +    int ret = -1;
  122.26 +    DECLARE_HYPERCALL;
  122.27 +
  122.28 +    op->interface_version = ACM_INTERFACE_VERSION;
  122.29 +
  122.30 +    hypercall.op = __HYPERVISOR_acm_op;
  122.31 +    hypercall.arg[0] = (unsigned long) op;
  122.32 +
  122.33 +    if (mlock(op, sizeof(*op)) != 0) {
  122.34 +        PERROR("Could not lock memory for Xen policy hypercall");
  122.35 +        goto out1;
  122.36 +    }
  122.37 +
  122.38 +    ret = do_xen_hypercall(xc_handle, &hypercall);
  122.39 +    ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
  122.40 +    if (ret < 0) {
  122.41 +        goto out2;
  122.42 +    }
  122.43 + out2:
  122.44 +    safe_munlock(op, sizeof(*op));
  122.45 + out1:
  122.46 +    return ret;
  122.47 +}
  122.48 +
  122.49 +/*
  122.50 + * Local variables:
  122.51 + * mode: C
  122.52 + * c-set-style: "BSD"
  122.53 + * c-basic-offset: 4
  122.54 + * tab-width: 4
  122.55 + * indent-tabs-mode: nil
  122.56 + * End:
  122.57 + */
   123.1 --- a/tools/libxc/xc_domain.c	Mon May 08 13:41:18 2006 -0600
   123.2 +++ b/tools/libxc/xc_domain.c	Mon May 08 14:46:11 2006 -0600
   123.3 @@ -171,7 +171,7 @@ int xc_domain_getinfolist(int xc_handle,
   123.4      op.cmd = DOM0_GETDOMAININFOLIST;
   123.5      op.u.getdomaininfolist.first_domain = first_domain;
   123.6      op.u.getdomaininfolist.max_domains  = max_domains;
   123.7 -    op.u.getdomaininfolist.buffer       = info;
   123.8 +    set_xen_guest_handle(op.u.getdomaininfolist.buffer, info);
   123.9  
  123.10      if ( xc_dom0_op(xc_handle, &op) < 0 )
  123.11          ret = -1;
  123.12 @@ -195,7 +195,7 @@ int xc_vcpu_getcontext(int xc_handle,
  123.13      op.cmd = DOM0_GETVCPUCONTEXT;
  123.14      op.u.getvcpucontext.domain = (domid_t)domid;
  123.15      op.u.getvcpucontext.vcpu   = (uint16_t)vcpu;
  123.16 -    op.u.getvcpucontext.ctxt   = ctxt;
  123.17 +    set_xen_guest_handle(op.u.getvcpucontext.ctxt, ctxt);
  123.18  
  123.19      if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
  123.20          return rc;
  123.21 @@ -220,7 +220,7 @@ int xc_shadow_control(int xc_handle,
  123.22      op.cmd = DOM0_SHADOW_CONTROL;
  123.23      op.u.shadow_control.domain = (domid_t)domid;
  123.24      op.u.shadow_control.op     = sop;
  123.25 -    op.u.shadow_control.dirty_bitmap = dirty_bitmap;
  123.26 +    set_xen_guest_handle(op.u.shadow_control.dirty_bitmap, dirty_bitmap);
  123.27      op.u.shadow_control.pages  = pages;
  123.28  
  123.29      rc = do_dom0_op(xc_handle, &op);
  123.30 @@ -295,13 +295,15 @@ int xc_domain_memory_increase_reservatio
  123.31  {
  123.32      int err;
  123.33      struct xen_memory_reservation reservation = {
  123.34 -        .extent_start = extent_start, /* may be NULL */
  123.35          .nr_extents   = nr_extents,
  123.36          .extent_order = extent_order,
  123.37          .address_bits = address_bits,
  123.38          .domid        = domid
  123.39      };
  123.40  
  123.41 +    /* may be NULL */
  123.42 +    set_xen_guest_handle(reservation.extent_start, extent_start);
  123.43 +
  123.44      err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
  123.45      if ( err == nr_extents )
  123.46          return 0;
  123.47 @@ -326,13 +328,14 @@ int xc_domain_memory_decrease_reservatio
  123.48  {
  123.49      int err;
  123.50      struct xen_memory_reservation reservation = {
  123.51 -        .extent_start = extent_start,
  123.52          .nr_extents   = nr_extents,
  123.53          .extent_order = extent_order,
  123.54          .address_bits = 0,
  123.55          .domid        = domid
  123.56      };
  123.57  
  123.58 +    set_xen_guest_handle(reservation.extent_start, extent_start);
  123.59 +
  123.60      if ( extent_start == NULL )
  123.61      {
  123.62          fprintf(stderr,"decrease_reservation extent_start is NULL!\n");
  123.63 @@ -364,12 +367,12 @@ int xc_domain_memory_populate_physmap(in
  123.64  {
  123.65      int err;
  123.66      struct xen_memory_reservation reservation = {
  123.67 -        .extent_start = extent_start,
  123.68          .nr_extents   = nr_extents,
  123.69          .extent_order = extent_order,
  123.70          .address_bits = address_bits,
  123.71          .domid        = domid
  123.72      };
  123.73 +    set_xen_guest_handle(reservation.extent_start, extent_start);
  123.74  
  123.75      err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
  123.76      if ( err == nr_extents )
  123.77 @@ -395,9 +398,9 @@ int xc_domain_translate_gpfn_list(int xc
  123.78      struct xen_translate_gpfn_list op = {
  123.79          .domid        = domid,
  123.80          .nr_gpfns     = nr_gpfns,
  123.81 -        .gpfn_list    = gpfn_list,
  123.82 -        .mfn_list     = mfn_list
  123.83      };
  123.84 +    set_xen_guest_handle(op.gpfn_list, gpfn_list);
  123.85 +    set_xen_guest_handle(op.mfn_list, mfn_list);
  123.86  
  123.87      return xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &op);
  123.88  }
  123.89 @@ -467,7 +470,7 @@ int xc_vcpu_setcontext(int xc_handle,
  123.90      op.cmd = DOM0_SETVCPUCONTEXT;
  123.91      op.u.setvcpucontext.domain = domid;
  123.92      op.u.setvcpucontext.vcpu = vcpu;
  123.93 -    op.u.setvcpucontext.ctxt = ctxt;
  123.94 +    set_xen_guest_handle(op.u.setvcpucontext.ctxt, ctxt);
  123.95  
  123.96      if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
  123.97          return rc;
   124.1 --- a/tools/libxc/xc_evtchn.c	Mon May 08 13:41:18 2006 -0600
   124.2 +++ b/tools/libxc/x