direct-io.hg

changeset 13481:a2b2b2a011f1

merge with xen-unstable.hg
author awilliam@xenbuild2.aw
date Mon Jan 15 15:15:26 2007 -0700 (2007-01-15)
parents c6b683ba68f5 fb46005e0756
children 7d8670a30445
files linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h patches/linux-2.6.16.33/ipv6-no-autoconf.patch tools/xm-test/lib/XmTestLib/XenManagedDomain.py unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
line diff
     1.1 --- a/.hgignore	Sun Jan 14 22:18:38 2007 -0700
     1.2 +++ b/.hgignore	Mon Jan 15 15:15:26 2007 -0700
     1.3 @@ -58,7 +58,7 @@
     1.4  ^docs/xen-api/xenapi-datamodel-graph.eps$
     1.5  ^extras/mini-os/h/hypervisor-ifs$
     1.6  ^extras/mini-os/h/xen-public$
     1.7 -^extras/mini-os/mini-os\..*$
     1.8 +^extras/mini-os/mini-os.*$
     1.9  ^install/.*$
    1.10  ^linux-[^/]*-native/.*$
    1.11  ^linux-[^/]*-xen/.*$
    1.12 @@ -142,6 +142,8 @@
    1.13  ^tools/python/build/.*$
    1.14  ^tools/security/secpol_tool$
    1.15  ^tools/security/xen/.*$
    1.16 +^tools/tests/blowfish\.bin$
    1.17 +^tools/tests/blowfish\.h$
    1.18  ^tools/tests/test_x86_emulator$
    1.19  ^tools/vnet/Make.local$
    1.20  ^tools/vnet/build/.*$
     2.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Sun Jan 14 22:18:38 2007 -0700
     2.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Mon Jan 15 15:15:26 2007 -0700
     2.3 @@ -172,6 +172,7 @@ CONFIG_FLATMEM=y
     2.4  CONFIG_FLAT_NODE_MEM_MAP=y
     2.5  # CONFIG_SPARSEMEM_STATIC is not set
     2.6  CONFIG_SPLIT_PTLOCK_CPUS=4096
     2.7 +# CONFIG_HIGHPTE is not set
     2.8  CONFIG_MTRR=y
     2.9  # CONFIG_REGPARM is not set
    2.10  CONFIG_SECCOMP=y
     3.1 --- a/buildconfigs/linux-defconfig_xenU_x86_32	Sun Jan 14 22:18:38 2007 -0700
     3.2 +++ b/buildconfigs/linux-defconfig_xenU_x86_32	Mon Jan 15 15:15:26 2007 -0700
     3.3 @@ -172,6 +172,7 @@ CONFIG_FLATMEM=y
     3.4  CONFIG_FLAT_NODE_MEM_MAP=y
     3.5  # CONFIG_SPARSEMEM_STATIC is not set
     3.6  CONFIG_SPLIT_PTLOCK_CPUS=4096
     3.7 +# CONFIG_HIGHPTE is not set
     3.8  # CONFIG_REGPARM is not set
     3.9  CONFIG_SECCOMP=y
    3.10  CONFIG_HZ_100=y
     4.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Sun Jan 14 22:18:38 2007 -0700
     4.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Mon Jan 15 15:15:26 2007 -0700
     4.3 @@ -180,6 +180,7 @@ CONFIG_FLATMEM=y
     4.4  CONFIG_FLAT_NODE_MEM_MAP=y
     4.5  # CONFIG_SPARSEMEM_STATIC is not set
     4.6  CONFIG_SPLIT_PTLOCK_CPUS=4096
     4.7 +# CONFIG_HIGHPTE is not set
     4.8  CONFIG_MTRR=y
     4.9  CONFIG_REGPARM=y
    4.10  CONFIG_SECCOMP=y
     5.1 --- a/docs/xen-api/wire-protocol.tex	Sun Jan 14 22:18:38 2007 -0700
     5.2 +++ b/docs/xen-api/wire-protocol.tex	Mon Jan 15 15:15:26 2007 -0700
     5.3 @@ -153,7 +153,7 @@ you must login and initiate a session. F
     5.4  \end{verbatim}
     5.5  Where {\tt uname} and {\tt password} refer to your username and password
     5.6  respectively, as defined by the Xen administrator.
     5.7 -The {\tt session\_id} returned by {\tt session.login_with_password} is passed
     5.8 +The {\tt session\_id} returned by {\tt session.login\_with\_password} is passed
     5.9  to subequent RPC calls as an authentication token.
    5.10  
    5.11  A session can be terminated with the {\tt session.logout} function:
     6.1 --- a/extras/mini-os/Makefile	Sun Jan 14 22:18:38 2007 -0700
     6.2 +++ b/extras/mini-os/Makefile	Mon Jan 15 15:15:26 2007 -0700
     6.3 @@ -7,7 +7,7 @@ include $(XEN_ROOT)/Config.mk
     6.4  # Set TARGET_ARCH
     6.5  override TARGET_ARCH     := $(XEN_TARGET_ARCH)
     6.6  
     6.7 -XEN_INTERFACE_VERSION := 0x00030203
     6.8 +XEN_INTERFACE_VERSION := 0x00030204
     6.9  
    6.10  # NB. '-Wcast-qual' is nasty, so I omitted it.
    6.11  CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
    6.12 @@ -17,7 +17,13 @@ CFLAGS += -D__XEN_INTERFACE_VERSION__=$(
    6.13  ASFLAGS = -D__ASSEMBLY__
    6.14  
    6.15  LDLIBS =  -L. -lminios
    6.16 -LDFLAGS := -N -T minios-$(TARGET_ARCH).lds
    6.17 +LDFLAGS_FINAL := -N -T minios-$(TARGET_ARCH).lds
    6.18 +LDFLAGS :=
    6.19 +
    6.20 +# Prefix for global API names. All other symbols are localised before
    6.21 +# linking with EXTRA_OBJS.
    6.22 +GLOBAL_PREFIX := xenos_
    6.23 +EXTRA_OBJS =
    6.24  
    6.25  # For possible special source directories.
    6.26  EXTRA_SRC =
    6.27 @@ -110,18 +116,16 @@ endif
    6.28  links:	$(ARCH_LINKS)
    6.29  	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
    6.30  
    6.31 -libminios.a: links $(OBJS) $(HEAD)
    6.32 -	$(AR) r libminios.a $(HEAD) $(OBJS)
    6.33 -
    6.34 -$(TARGET): libminios.a $(HEAD)
    6.35 -	$(LD) $(LDFLAGS) $(HEAD) $(LDLIBS) -o $@.elf
    6.36 -	gzip -f -9 -c $@.elf >$@.gz
    6.37 +$(TARGET): links $(OBJS) $(HEAD)
    6.38 +	$(LD) -r $(LDFLAGS) $(HEAD) $(OBJS) -o $@.o
    6.39 +	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
    6.40 +	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
    6.41 +	gzip -f -9 -c $@ >$@.gz
    6.42  
    6.43  .PHONY: clean
    6.44  clean:
    6.45  	find . -type f -name '*.o' | xargs rm -f
    6.46 -	rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
    6.47 -	rm -f libminios.a
    6.48 +	rm -f *.o *~ core $(TARGET) $(TARGET).gz
    6.49  	find . -type l | xargs rm -f
    6.50  	rm -f tags TAGS
    6.51  
     7.1 --- a/extras/mini-os/gnttab.c	Sun Jan 14 22:18:38 2007 -0700
     7.2 +++ b/extras/mini-os/gnttab.c	Mon Jan 15 15:15:26 2007 -0700
     7.3 @@ -23,39 +23,32 @@
     7.4  
     7.5  #define NR_GRANT_FRAMES 4
     7.6  #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
     7.7 -#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
     7.8  
     7.9  static grant_entry_t *gnttab_table;
    7.10  static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
    7.11 -static grant_ref_t gnttab_free_head;
    7.12 +
    7.13 +static void
    7.14 +put_free_entry(grant_ref_t ref)
    7.15 +{
    7.16 +    gnttab_list[ref] = gnttab_list[0];
    7.17 +    gnttab_list[0]  = ref;
    7.18 +
    7.19 +}
    7.20  
    7.21  static grant_ref_t
    7.22 -get_free_entries(int count)
    7.23 +get_free_entry(void)
    7.24  {
    7.25 -    grant_ref_t ref;
    7.26 -    grant_ref_t head;
    7.27 -
    7.28 -    ref = head = gnttab_free_head;
    7.29 -    while (count-- > 1)
    7.30 -	head = gnttab_list[head];
    7.31 -    gnttab_free_head = gnttab_list[head];
    7.32 -    gnttab_list[head] = GNTTAB_LIST_END;
    7.33 +    unsigned int ref = gnttab_list[0];
    7.34 +    gnttab_list[0] = gnttab_list[ref];
    7.35      return ref;
    7.36  }
    7.37  
    7.38 -static void
    7.39 -put_free_entry(grant_ref_t gref)
    7.40 -{
    7.41 -    gnttab_list[gref] = gnttab_free_head;
    7.42 -    gnttab_free_head = gref;
    7.43 -}
    7.44 -
    7.45  grant_ref_t
    7.46  gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
    7.47  {
    7.48      grant_ref_t ref;
    7.49  
    7.50 -    ref = get_free_entries(1);
    7.51 +    ref = get_free_entry();
    7.52      gnttab_table[ref].frame = frame;
    7.53      gnttab_table[ref].domid = domid;
    7.54      wmb();
    7.55 @@ -70,7 +63,7 @@ gnttab_grant_transfer(domid_t domid, uns
    7.56  {
    7.57      grant_ref_t ref;
    7.58  
    7.59 -    ref = get_free_entries(1);
    7.60 +    ref = get_free_entry();
    7.61      gnttab_table[ref].frame = pfn;
    7.62      gnttab_table[ref].domid = domid;
    7.63      wmb();
    7.64 @@ -157,8 +150,7 @@ init_gnttab(void)
    7.65      int i;
    7.66  
    7.67      for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
    7.68 -	gnttab_list[i] = i + 1;
    7.69 -    gnttab_free_head = NR_RESERVED_ENTRIES;
    7.70 +        put_free_entry(i);
    7.71  
    7.72      setup.dom = DOMID_SELF;
    7.73      setup.nr_frames = NR_GRANT_FRAMES;
     8.1 --- a/extras/mini-os/include/hypervisor.h	Sun Jan 14 22:18:38 2007 -0700
     8.2 +++ b/extras/mini-os/include/hypervisor.h	Mon Jan 15 15:15:26 2007 -0700
     8.3 @@ -15,7 +15,6 @@
     8.4  
     8.5  #include <types.h>
     8.6  #include <xen/xen.h>
     8.7 -#include <xen/dom0_ops.h>
     8.8  #if defined(__i386__)
     8.9  #include <hypercall-x86_32.h>
    8.10  #elif defined(__x86_64__)
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/extras/mini-os/include/netfront.h	Mon Jan 15 15:15:26 2007 -0700
     9.3 @@ -0,0 +1,2 @@
     9.4 +void init_netfront(void*);
     9.5 +void netfront_xmit(unsigned char* data,int len);
    10.1 --- a/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h	Sun Jan 14 22:18:38 2007 -0700
    10.2 +++ b/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h	Mon Jan 15 15:15:26 2007 -0700
    10.3 @@ -182,14 +182,6 @@ HYPERVISOR_set_timer_op(
    10.4  }
    10.5  
    10.6  static inline int
    10.7 -HYPERVISOR_dom0_op(
    10.8 -	dom0_op_t *dom0_op)
    10.9 -{
   10.10 -	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   10.11 -	return _hypercall1(int, dom0_op, dom0_op);
   10.12 -}
   10.13 -
   10.14 -static inline int
   10.15  HYPERVISOR_set_debugreg(
   10.16  	int reg, unsigned long value)
   10.17  {
    11.1 --- a/extras/mini-os/include/x86/x86_64/hypercall-x86_64.h	Sun Jan 14 22:18:38 2007 -0700
    11.2 +++ b/extras/mini-os/include/x86/x86_64/hypercall-x86_64.h	Mon Jan 15 15:15:26 2007 -0700
    11.3 @@ -184,14 +184,6 @@ HYPERVISOR_set_timer_op(
    11.4  }
    11.5  
    11.6  static inline int
    11.7 -HYPERVISOR_dom0_op(
    11.8 -	dom0_op_t *dom0_op)
    11.9 -{
   11.10 -	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   11.11 -	return _hypercall1(int, dom0_op, dom0_op);
   11.12 -}
   11.13 -
   11.14 -static inline int
   11.15  HYPERVISOR_set_debugreg(
   11.16  	int reg, unsigned long value)
   11.17  {
    12.1 --- a/extras/mini-os/include/xenbus.h	Sun Jan 14 22:18:38 2007 -0700
    12.2 +++ b/extras/mini-os/include/xenbus.h	Mon Jan 15 15:15:26 2007 -0700
    12.3 @@ -12,6 +12,9 @@ void init_xenbus(void);
    12.4     set to a malloc'd copy of the value. */
    12.5  char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
    12.6  
    12.7 +char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path);
    12.8 +char* xenbus_wait_for_value(const char*,const char*);
    12.9 +
   12.10  /* Associates a value with a path.  Returns a malloc'd error string on
   12.11     failure. */
   12.12  char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
    13.1 --- a/extras/mini-os/kernel.c	Sun Jan 14 22:18:38 2007 -0700
    13.2 +++ b/extras/mini-os/kernel.c	Mon Jan 15 15:15:26 2007 -0700
    13.3 @@ -37,6 +37,7 @@
    13.4  #include <sched.h>
    13.5  #include <xenbus.h>
    13.6  #include <gnttab.h>
    13.7 +#include <netfront.h>
    13.8  #include <xen/features.h>
    13.9  #include <xen/version.h>
   13.10  
   13.11 @@ -61,13 +62,13 @@ void setup_xen_features(void)
   13.12  
   13.13  void test_xenbus(void);
   13.14  
   13.15 -void xenbus_tester(void *p)
   13.16 +static void xenbus_tester(void *p)
   13.17  {
   13.18      printk("Xenbus tests disabled, because of a Xend bug.\n");
   13.19      /* test_xenbus(); */
   13.20  }
   13.21  
   13.22 -void periodic_thread(void *p)
   13.23 +static void periodic_thread(void *p)
   13.24  {
   13.25      struct timeval tv;
   13.26      printk("Periodic thread started.\n");
   13.27 @@ -79,12 +80,18 @@ void periodic_thread(void *p)
   13.28      }
   13.29  }
   13.30  
   13.31 +static void netfront_thread(void *p)
   13.32 +{
   13.33 +    init_netfront(&start_info);
   13.34 +}
   13.35 +
   13.36  /* This should be overridden by the application we are linked against. */
   13.37  __attribute__((weak)) int app_main(start_info_t *si)
   13.38  {
   13.39      printk("Dummy main: start_info=%p\n", si);
   13.40      create_thread("xenbus_tester", xenbus_tester, si);
   13.41      create_thread("periodic_thread", periodic_thread, si);
   13.42 +    create_thread("netfront", netfront_thread, si);
   13.43      return 0;
   13.44  }
   13.45  
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/extras/mini-os/netfront.c	Mon Jan 15 15:15:26 2007 -0700
    14.3 @@ -0,0 +1,455 @@
    14.4 +/* Minimal network driver for Mini-OS. 
    14.5 + * Copyright (c) 2006-2007 Jacob Gorm Hansen, University of Copenhagen.
    14.6 + * Based on netfront.c from Xen Linux.
    14.7 + *
    14.8 + * Does not handle fragments or extras.
    14.9 + */
   14.10 +
   14.11 +#include <os.h>
   14.12 +#include <xenbus.h>
   14.13 +#include <events.h>
   14.14 +#include <errno.h>
   14.15 +#include <xen/io/netif.h>
   14.16 +#include <gnttab.h>
   14.17 +#include <xmalloc.h>
   14.18 +#include <time.h>
   14.19 +
   14.20 +void init_rx_buffers(void);
   14.21 +
   14.22 +struct net_info {
   14.23 +    struct netif_tx_front_ring tx;
   14.24 +    struct netif_rx_front_ring rx;
   14.25 +    int tx_ring_ref;
   14.26 +    int rx_ring_ref;
   14.27 +    unsigned int evtchn, local_port;
   14.28 +
   14.29 +} net_info;
   14.30 +
   14.31 +
   14.32 +char* xenbus_printf(xenbus_transaction_t xbt,
   14.33 +        char* node,char* path,
   14.34 +        char* fmt,unsigned int arg)
   14.35 +{
   14.36 +    char fullpath[256];
   14.37 +    char val[256];
   14.38 +
   14.39 +    sprintf(fullpath,"%s/%s",node,path);
   14.40 +    sprintf(val,fmt,arg);
   14.41 +    xenbus_write(xbt,fullpath,val);
   14.42 +
   14.43 +    return NULL;
   14.44 +}
   14.45 +
   14.46 +
   14.47 +#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
   14.48 +#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
   14.49 +#define GRANT_INVALID_REF 0
   14.50 +
   14.51 +
   14.52 +unsigned short rx_freelist[NET_RX_RING_SIZE];
   14.53 +unsigned short tx_freelist[NET_TX_RING_SIZE];
   14.54 +
   14.55 +struct net_buffer {
   14.56 +    void* page;
   14.57 +    int gref;
   14.58 +};
   14.59 +struct net_buffer rx_buffers[NET_RX_RING_SIZE];
   14.60 +struct net_buffer tx_buffers[NET_TX_RING_SIZE];
   14.61 +
   14.62 +static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
   14.63 +{
   14.64 +    freelist[id] = freelist[0];
   14.65 +    freelist[0]  = id;
   14.66 +}
   14.67 +
   14.68 +static inline unsigned short get_id_from_freelist(unsigned short* freelist)
   14.69 +{
   14.70 +    unsigned int id = freelist[0];
   14.71 +    freelist[0] = freelist[id];
   14.72 +    return id;
   14.73 +}
   14.74 +
   14.75 +__attribute__((weak)) void netif_rx(unsigned char* data,int len)
   14.76 +{
   14.77 +    printk("%d bytes incoming at %p\n",len,data);
   14.78 +}
   14.79 +
   14.80 +__attribute__((weak)) void net_app_main(void*si,unsigned char*mac) {}
   14.81 +
   14.82 +static inline int xennet_rxidx(RING_IDX idx)
   14.83 +{
   14.84 +    return idx & (NET_RX_RING_SIZE - 1);
   14.85 +}
   14.86 +
   14.87 +void network_rx(void)
   14.88 +{
   14.89 +    struct net_info *np = &net_info;
   14.90 +    RING_IDX rp,cons;
   14.91 +    struct netif_rx_response *rx;
   14.92 +
   14.93 +
   14.94 +moretodo:
   14.95 +    rp = np->rx.sring->rsp_prod;
   14.96 +    rmb(); /* Ensure we see queued responses up to 'rp'. */
   14.97 +    cons = np->rx.rsp_cons;
   14.98 +
   14.99 +    int nr_consumed=0;
  14.100 +    while ((cons != rp))
  14.101 +    {
  14.102 +        struct net_buffer* buf;
  14.103 +        unsigned char* page;
  14.104 +
  14.105 +        rx = RING_GET_RESPONSE(&np->rx, cons);
  14.106 +
  14.107 +        if (rx->flags & NETRXF_extra_info)
  14.108 +        {
  14.109 +            printk("+++++++++++++++++++++ we have extras!\n");
  14.110 +            continue;
  14.111 +        }
  14.112 +
  14.113 +
  14.114 +        if (rx->status == NETIF_RSP_NULL) continue;
  14.115 +
  14.116 +        int id = rx->id;
  14.117 +
  14.118 +        buf = &rx_buffers[id];
  14.119 +        page = (unsigned char*)buf->page;
  14.120 +        gnttab_end_access(buf->gref);
  14.121 +
  14.122 +        if(rx->status>0)
  14.123 +        {
  14.124 +            netif_rx(page+rx->offset,rx->status);
  14.125 +        }
  14.126 +
  14.127 +        add_id_to_freelist(id,rx_freelist);
  14.128 +
  14.129 +        nr_consumed++;
  14.130 +
  14.131 +        ++cons;
  14.132 +    }
  14.133 +    np->rx.rsp_cons=rp;
  14.134 +
  14.135 +    int more;
  14.136 +    RING_FINAL_CHECK_FOR_RESPONSES(&np->rx,more);
  14.137 +    if(more) goto moretodo;
  14.138 +
  14.139 +    RING_IDX req_prod = np->rx.req_prod_pvt;
  14.140 +
  14.141 +    int i;
  14.142 +    netif_rx_request_t *req;
  14.143 +
  14.144 +    for(i=0; i<nr_consumed; i++)
  14.145 +    {
  14.146 +        int id = xennet_rxidx(req_prod + i);
  14.147 +        req = RING_GET_REQUEST(&np->rx, req_prod + i);
  14.148 +        struct net_buffer* buf = &rx_buffers[id];
  14.149 +        void* page = buf->page;
  14.150 +
  14.151 +        buf->gref = req->gref = 
  14.152 +            gnttab_grant_access(0,virt_to_mfn(page),0);
  14.153 +
  14.154 +        req->id = id;
  14.155 +    }
  14.156 +
  14.157 +    wmb();
  14.158 +
  14.159 +    np->rx.req_prod_pvt = req_prod + i;
  14.160 +    
  14.161 +    int notify;
  14.162 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
  14.163 +    if (notify)
  14.164 +        notify_remote_via_evtchn(np->evtchn);
  14.165 +
  14.166 +}
  14.167 +
  14.168 +void network_tx_buf_gc(void)
  14.169 +{
  14.170 +
  14.171 +
  14.172 +    RING_IDX cons, prod;
  14.173 +    unsigned short id;
  14.174 +    struct net_info *np = &net_info;
  14.175 +
  14.176 +    do {
  14.177 +        prod = np->tx.sring->rsp_prod;
  14.178 +        rmb(); /* Ensure we see responses up to 'rp'. */
  14.179 +
  14.180 +        for (cons = np->tx.rsp_cons; cons != prod; cons++) 
  14.181 +        {
  14.182 +            struct netif_tx_response *txrsp;
  14.183 +
  14.184 +            txrsp = RING_GET_RESPONSE(&np->tx, cons);
  14.185 +            if (txrsp->status == NETIF_RSP_NULL)
  14.186 +                continue;
  14.187 +
  14.188 +            id  = txrsp->id;
  14.189 +            struct net_buffer* buf = &tx_buffers[id];
  14.190 +            gnttab_end_access(buf->gref);
  14.191 +            buf->gref=GRANT_INVALID_REF;
  14.192 +
  14.193 +            add_id_to_freelist(id,tx_freelist);
  14.194 +        }
  14.195 +
  14.196 +        np->tx.rsp_cons = prod;
  14.197 +
  14.198 +        /*
  14.199 +         * Set a new event, then check for race with update of tx_cons.
  14.200 +         * Note that it is essential to schedule a callback, no matter
  14.201 +         * how few tx_buffers are pending. Even if there is space in the
  14.202 +         * transmit ring, higher layers may be blocked because too much
  14.203 +         * data is outstanding: in such cases notification from Xen is
  14.204 +         * likely to be the only kick that we'll get.
  14.205 +         */
  14.206 +        np->tx.sring->rsp_event =
  14.207 +            prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
  14.208 +        mb();
  14.209 +    } while ((cons == prod) && (prod != np->tx.sring->rsp_prod));
  14.210 +
  14.211 +
  14.212 +}
  14.213 +
  14.214 +void netfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
  14.215 +{
  14.216 +    int flags;
  14.217 +
  14.218 +    local_irq_save(flags);
  14.219 +
  14.220 +    network_tx_buf_gc();
  14.221 +    network_rx();
  14.222 +
  14.223 +    local_irq_restore(flags);
  14.224 +}
  14.225 +
  14.226 +char* backend;
  14.227 +
  14.228 +void init_netfront(void* si)
  14.229 +{
  14.230 +    xenbus_transaction_t xbt;
  14.231 +    struct net_info* info = &net_info;
  14.232 +    char* err;
  14.233 +    char* message=NULL;
  14.234 +    char nodename[] = "device/vif/0";
  14.235 +    struct netif_tx_sring *txs;
  14.236 +    struct netif_rx_sring *rxs;
  14.237 +    int retry=0;
  14.238 +    int i;
  14.239 +    char* mac;
  14.240 +    char* msg;
  14.241 +
  14.242 +    printk("************************ NETFRONT **********\n\n\n");
  14.243 +
  14.244 +    for(i=0;i<NET_TX_RING_SIZE;i++)
  14.245 +    {
  14.246 +        add_id_to_freelist(i,tx_freelist);
  14.247 +        tx_buffers[i].page = (char*)alloc_page();
  14.248 +    }
  14.249 +
  14.250 +    for(i=0;i<NET_RX_RING_SIZE;i++)
  14.251 +    {
  14.252 +        add_id_to_freelist(i,rx_freelist);
  14.253 +        rx_buffers[i].page = (char*)alloc_page();
  14.254 +    }
  14.255 +
  14.256 +    txs = (struct netif_tx_sring*) alloc_page();
  14.257 +    rxs = (struct netif_rx_sring *) alloc_page();
  14.258 +    memset(txs,0,PAGE_SIZE);
  14.259 +    memset(rxs,0,PAGE_SIZE);
  14.260 +
  14.261 +
  14.262 +    SHARED_RING_INIT(txs);
  14.263 +    SHARED_RING_INIT(rxs);
  14.264 +    FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
  14.265 +    FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
  14.266 +
  14.267 +    info->tx_ring_ref = gnttab_grant_access(0,virt_to_mfn(txs),0);
  14.268 +    info->rx_ring_ref = gnttab_grant_access(0,virt_to_mfn(rxs),0);
  14.269 +
  14.270 +    evtchn_alloc_unbound_t op;
  14.271 +    op.dom = DOMID_SELF;
  14.272 +    op.remote_dom = 0;
  14.273 +    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
  14.274 +    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
  14.275 +    info->local_port = bind_evtchn(op.port, netfront_handler, NULL);
  14.276 +    info->evtchn=op.port;
  14.277 +
  14.278 +again:
  14.279 +    err = xenbus_transaction_start(&xbt);
  14.280 +    if (err) {
  14.281 +        printk("starting transaction\n");
  14.282 +    }
  14.283 +
  14.284 +    err = xenbus_printf(xbt, nodename, "tx-ring-ref","%u",
  14.285 +                info->tx_ring_ref);
  14.286 +    if (err) {
  14.287 +        message = "writing tx ring-ref";
  14.288 +        goto abort_transaction;
  14.289 +    }
  14.290 +    err = xenbus_printf(xbt, nodename, "rx-ring-ref","%u",
  14.291 +                info->rx_ring_ref);
  14.292 +    if (err) {
  14.293 +        message = "writing rx ring-ref";
  14.294 +        goto abort_transaction;
  14.295 +    }
  14.296 +    err = xenbus_printf(xbt, nodename,
  14.297 +                "event-channel", "%u", info->evtchn);
  14.298 +    if (err) {
  14.299 +        message = "writing event-channel";
  14.300 +        goto abort_transaction;
  14.301 +    }
  14.302 +
  14.303 +    err = xenbus_printf(xbt, nodename, "request-rx-copy", "%u", 1);
  14.304 +
  14.305 +    if (err) {
  14.306 +        message = "writing request-rx-copy";
  14.307 +        goto abort_transaction;
  14.308 +    }
  14.309 +
  14.310 +    err = xenbus_printf(xbt, nodename, "state", "%u",
  14.311 +            4); /* connected */
  14.312 +
  14.313 +
  14.314 +    err = xenbus_transaction_end(xbt, 0, &retry);
  14.315 +    if (retry) {
  14.316 +            goto again;
  14.317 +        printk("completing transaction\n");
  14.318 +    }
  14.319 +
  14.320 +    goto done;
  14.321 +
  14.322 +abort_transaction:
  14.323 +    xenbus_transaction_end(xbt, 1, &retry);
  14.324 +
  14.325 +done:
  14.326 +
  14.327 +    msg = xenbus_read(XBT_NIL, "device/vif/0/backend", &backend);
  14.328 +    msg = xenbus_read(XBT_NIL, "device/vif/0/mac", &mac);
  14.329 +
  14.330 +    printk("backend at %s\n",backend);
  14.331 +    printk("mac is %s\n",mac);
  14.332 +
  14.333 +    char *res;
  14.334 +    char path[256];
  14.335 +    sprintf(path,"%s/state",backend);
  14.336 +
  14.337 +    xenbus_watch_path(XBT_NIL, path);
  14.338 +
  14.339 +    xenbus_wait_for_value(path,"4");
  14.340 +
  14.341 +    //free(backend);
  14.342 +    free(res);
  14.343 +
  14.344 +    printk("**************************\n");
  14.345 +
  14.346 +    init_rx_buffers();
  14.347 +
  14.348 +    unsigned char rawmac[6];
  14.349 +    sscanf(mac,"%x:%x:%x:%x:%x:%x",
  14.350 +            &rawmac[0],
  14.351 +            &rawmac[1],
  14.352 +            &rawmac[2],
  14.353 +            &rawmac[3],
  14.354 +            &rawmac[4],
  14.355 +            &rawmac[5]);
  14.356 +
  14.357 +    net_app_main(si,rawmac);
  14.358 +}
  14.359 +
  14.360 +void shutdown_netfront(void)
  14.361 +{
  14.362 +    //xenbus_transaction_t xbt;
  14.363 +    char* err;
  14.364 +    char nodename[] = "device/vif/0";
  14.365 +
  14.366 +    char path[256];
  14.367 +
  14.368 +    printk("close network: backend at %s\n",backend);
  14.369 +
  14.370 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); /* closing */
  14.371 +    sprintf(path,"%s/state",backend);
  14.372 +
  14.373 +    xenbus_wait_for_value(path,"6");
  14.374 +
  14.375 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
  14.376 +
  14.377 +    xenbus_wait_for_value(path,"2");
  14.378 +
  14.379 +    unbind_all_ports();
  14.380 +
  14.381 +}
  14.382 +
  14.383 +
  14.384 +void init_rx_buffers(void)
  14.385 +{
  14.386 +    struct net_info* np = &net_info;
  14.387 +    int i, requeue_idx;
  14.388 +    netif_rx_request_t *req;
  14.389 +    int notify;
  14.390 +
  14.391 +    np->rx.req_prod_pvt = requeue_idx;
  14.392 +
  14.393 +
  14.394 +    /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
  14.395 +    for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) 
  14.396 +    {
  14.397 +        struct net_buffer* buf = &rx_buffers[requeue_idx];
  14.398 +        req = RING_GET_REQUEST(&np->rx, requeue_idx);
  14.399 +
  14.400 +        buf->gref = req->gref = 
  14.401 +            gnttab_grant_access(0,virt_to_mfn(buf->page),0);
  14.402 +
  14.403 +        req->id = requeue_idx;
  14.404 +
  14.405 +        requeue_idx++;
  14.406 +    }
  14.407 +
  14.408 +    np->rx.req_prod_pvt = requeue_idx;
  14.409 +
  14.410 +
  14.411 +
  14.412 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
  14.413 +
  14.414 +    if(notify) 
  14.415 +        notify_remote_via_evtchn(np->evtchn);
  14.416 +
  14.417 +    np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
  14.418 +
  14.419 +
  14.420 +}
  14.421 +
  14.422 +
  14.423 +void netfront_xmit(unsigned char* data,int len)
  14.424 +{
  14.425 +    int flags;
  14.426 +    local_irq_save(flags);
  14.427 +
  14.428 +    struct net_info* info = &net_info;
  14.429 +    struct netif_tx_request *tx;
  14.430 +    RING_IDX i = info->tx.req_prod_pvt;
  14.431 +    int notify;
  14.432 +    int id = get_id_from_freelist(tx_freelist);
  14.433 +    struct net_buffer* buf = &tx_buffers[id];
  14.434 +    void* page = buf->page;
  14.435 +
  14.436 +    tx = RING_GET_REQUEST(&info->tx, i);
  14.437 +
  14.438 +    memcpy(page,data,len);
  14.439 +
  14.440 +    buf->gref = 
  14.441 +        tx->gref = gnttab_grant_access(0,virt_to_mfn(page),0);
  14.442 +
  14.443 +    tx->offset=0;
  14.444 +    tx->size = len;
  14.445 +    tx->flags=0;
  14.446 +    tx->id = id;
  14.447 +    info->tx.req_prod_pvt = i + 1;
  14.448 +
  14.449 +    wmb();
  14.450 +
  14.451 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->tx, notify);
  14.452 +
  14.453 +    if(notify) notify_remote_via_evtchn(info->evtchn);
  14.454 +
  14.455 +    network_tx_buf_gc();
  14.456 +
  14.457 +    local_irq_restore(flags);
  14.458 +}
    15.1 --- a/extras/mini-os/xenbus/xenbus.c	Sun Jan 14 22:18:38 2007 -0700
    15.2 +++ b/extras/mini-os/xenbus/xenbus.c	Mon Jan 15 15:15:26 2007 -0700
    15.3 @@ -45,9 +45,9 @@
    15.4  #define DEBUG(_f, _a...)    ((void)0)
    15.5  #endif
    15.6  
    15.7 -
    15.8  static struct xenstore_domain_interface *xenstore_buf;
    15.9  static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
   15.10 +static DECLARE_WAIT_QUEUE_HEAD(watch_queue);
   15.11  struct xenbus_req_info 
   15.12  {
   15.13      int in_use:1;
   15.14 @@ -72,6 +72,34 @@ static void memcpy_from_ring(const void 
   15.15      memcpy(dest + c1, ring, c2);
   15.16  }
   15.17  
   15.18 +static inline void wait_for_watch(void)
   15.19 +{
   15.20 +    DEFINE_WAIT(w);
   15.21 +    add_waiter(w,watch_queue);
   15.22 +    schedule();
   15.23 +    wake(current);
   15.24 +}
   15.25 +
   15.26 +char* xenbus_wait_for_value(const char* path,const char* value)
   15.27 +{
   15.28 +    for(;;)
   15.29 +    {
   15.30 +        char *res, *msg;
   15.31 +        int r;
   15.32 +
   15.33 +        msg = xenbus_read(XBT_NIL, path, &res);
   15.34 +        if(msg) return msg;
   15.35 +
   15.36 +        r = strcmp(value,res);
   15.37 +        free(res);
   15.38 +
   15.39 +        if(r==0) break;
   15.40 +        else wait_for_watch();
   15.41 +    }
   15.42 +    return NULL;
   15.43 +}
   15.44 +
   15.45 +
   15.46  static void xenbus_thread_func(void *ign)
   15.47  {
   15.48      struct xsd_sockmsg msg;
   15.49 @@ -101,13 +129,35 @@ static void xenbus_thread_func(void *ign
   15.50                  break;
   15.51  
   15.52              DEBUG("Message is good.\n");
   15.53 -            req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
   15.54 -            memcpy_from_ring(xenstore_buf->rsp,
   15.55 +
   15.56 +            if(msg.type == XS_WATCH_EVENT)
   15.57 +            {
   15.58 +                char* payload = (char*)malloc(sizeof(msg) + msg.len);
   15.59 +                char *path,*token;
   15.60 +
   15.61 +                memcpy_from_ring(xenstore_buf->rsp,
   15.62 +                    payload,
   15.63 +                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
   15.64 +                    msg.len + sizeof(msg));
   15.65 +
   15.66 +                path = payload + sizeof(msg);
   15.67 +                token = path + strlen(path) + 1;
   15.68 +
   15.69 +                xenstore_buf->rsp_cons += msg.len + sizeof(msg);
   15.70 +                free(payload);
   15.71 +                wake_up(&watch_queue);
   15.72 +            }
   15.73 +
   15.74 +            else
   15.75 +            {
   15.76 +                req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
   15.77 +                memcpy_from_ring(xenstore_buf->rsp,
   15.78                      req_info[msg.req_id].reply,
   15.79                      MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
   15.80                      msg.len + sizeof(msg));
   15.81 -            wake_up(&req_info[msg.req_id].waitq);
   15.82 -            xenstore_buf->rsp_cons += msg.len + sizeof(msg);
   15.83 +                xenstore_buf->rsp_cons += msg.len + sizeof(msg);
   15.84 +                wake_up(&req_info[msg.req_id].waitq);
   15.85 +            }
   15.86          }
   15.87      }
   15.88  }
   15.89 @@ -381,12 +431,32 @@ char *xenbus_write(xenbus_transaction_t 
   15.90      struct xsd_sockmsg *rep;
   15.91      rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
   15.92      char *msg = errmsg(rep);
   15.93 -    if (msg)
   15.94 -	return msg;
   15.95 +    if (msg) return msg;
   15.96      free(rep);
   15.97      return NULL;
   15.98  }
   15.99  
  15.100 +char* xenbus_watch_path( xenbus_transaction_t xbt, const char *path)
  15.101 +{
  15.102 +	/* in the future one could have multiple watch queues, and use
  15.103 +	 * the token for demuxing. For now the token is 0. */
  15.104 +
  15.105 +    struct xsd_sockmsg *rep;
  15.106 +
  15.107 +    struct write_req req[] = { 
  15.108 +        {path, strlen(path) + 1},
  15.109 +        {"0",2 },
  15.110 +    };
  15.111 +
  15.112 +    rep = xenbus_msg_reply(XS_WATCH, xbt, req, ARRAY_SIZE(req));
  15.113 +
  15.114 +    char *msg = errmsg(rep);
  15.115 +    if (msg) return msg;
  15.116 +    free(rep);
  15.117 +
  15.118 +    return NULL;
  15.119 +}
  15.120 +
  15.121  char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
  15.122  {
  15.123      struct write_req req[] = { {path, strlen(path) + 1} };
    16.1 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig	Sun Jan 14 22:18:38 2007 -0700
    16.2 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig	Mon Jan 15 15:15:26 2007 -0700
    16.3 @@ -594,7 +594,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
    16.4  
    16.5  config HIGHPTE
    16.6  	bool "Allocate 3rd-level pagetables from highmem"
    16.7 -	depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN
    16.8 +	depends on HIGHMEM4G || HIGHMEM64G
    16.9  	help
   16.10  	  The VM uses one page table entry for each page of physical memory.
   16.11  	  For systems with a lot of RAM, this can be wasteful of precious
    17.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c	Sun Jan 14 22:18:38 2007 -0700
    17.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c	Mon Jan 15 15:15:26 2007 -0700
    17.3 @@ -94,13 +94,7 @@ dma_unmap_sg(struct device *hwdev, struc
    17.4  }
    17.5  EXPORT_SYMBOL(dma_unmap_sg);
    17.6  
    17.7 -/*
    17.8 - * XXX This file is also used by xenLinux/ia64. 
    17.9 - * "defined(__i386__) || defined (__x86_64__)" means "!defined(__ia64__)".
   17.10 - * This #if work around should be removed once this file is merbed back into
   17.11 - * i386' pci-dma or is moved to drivers/xen/core.
   17.12 - */
   17.13 -#if defined(__i386__) || defined(__x86_64__)
   17.14 +#ifdef CONFIG_HIGHMEM
   17.15  dma_addr_t
   17.16  dma_map_page(struct device *dev, struct page *page, unsigned long offset,
   17.17  	     size_t size, enum dma_data_direction direction)
   17.18 @@ -130,7 +124,7 @@ dma_unmap_page(struct device *dev, dma_a
   17.19  		swiotlb_unmap_page(dev, dma_address, size, direction);
   17.20  }
   17.21  EXPORT_SYMBOL(dma_unmap_page);
   17.22 -#endif /* defined(__i386__) || defined(__x86_64__) */
   17.23 +#endif /* CONFIG_HIGHMEM */
   17.24  
   17.25  int
   17.26  dma_mapping_error(dma_addr_t dma_addr)
   17.27 @@ -161,6 +155,8 @@ void *dma_alloc_coherent(struct device *
   17.28  	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
   17.29  	unsigned int order = get_order(size);
   17.30  	unsigned long vstart;
   17.31 +	u64 mask;
   17.32 +
   17.33  	/* ignore region specifiers */
   17.34  	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
   17.35  
   17.36 @@ -183,9 +179,14 @@ void *dma_alloc_coherent(struct device *
   17.37  	vstart = __get_free_pages(gfp, order);
   17.38  	ret = (void *)vstart;
   17.39  
   17.40 +	if (dev != NULL && dev->coherent_dma_mask)
   17.41 +		mask = dev->coherent_dma_mask;
   17.42 +	else
   17.43 +		mask = 0xffffffff;
   17.44 +
   17.45  	if (ret != NULL) {
   17.46  		if (xen_create_contiguous_region(vstart, order,
   17.47 -						 dma_bits) != 0) {
   17.48 +						 fls64(mask)) != 0) {
   17.49  			free_pages(vstart, order);
   17.50  			return NULL;
   17.51  		}
    18.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Sun Jan 14 22:18:38 2007 -0700
    18.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Mon Jan 15 15:15:26 2007 -0700
    18.3 @@ -47,9 +47,6 @@ EXPORT_SYMBOL(swiotlb);
    18.4   */
    18.5  #define IO_TLB_SHIFT 11
    18.6  
    18.7 -/* Width of DMA addresses. 30 bits is a b44 limitation. */
    18.8 -#define DEFAULT_DMA_BITS 30
    18.9 -
   18.10  static int swiotlb_force;
   18.11  static char *iotlb_virt_start;
   18.12  static unsigned long iotlb_nslabs;
   18.13 @@ -98,11 +95,12 @@ static struct phys_addr {
   18.14   */
   18.15  static DEFINE_SPINLOCK(io_tlb_lock);
   18.16  
   18.17 -unsigned int dma_bits = DEFAULT_DMA_BITS;
   18.18 +static unsigned int dma_bits;
   18.19 +static unsigned int __initdata max_dma_bits = 32;
   18.20  static int __init
   18.21  setup_dma_bits(char *str)
   18.22  {
   18.23 -	dma_bits = simple_strtoul(str, NULL, 0);
   18.24 +	max_dma_bits = simple_strtoul(str, NULL, 0);
   18.25  	return 0;
   18.26  }
   18.27  __setup("dma_bits=", setup_dma_bits);
   18.28 @@ -143,6 +141,7 @@ void
   18.29  swiotlb_init_with_default_size (size_t default_size)
   18.30  {
   18.31  	unsigned long i, bytes;
   18.32 +	int rc;
   18.33  
   18.34  	if (!iotlb_nslabs) {
   18.35  		iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
   18.36 @@ -159,16 +158,33 @@ swiotlb_init_with_default_size (size_t d
   18.37  	 */
   18.38  	iotlb_virt_start = alloc_bootmem_low_pages(bytes);
   18.39  	if (!iotlb_virt_start)
   18.40 -		panic("Cannot allocate SWIOTLB buffer!\n"
   18.41 -		      "Use dom0_mem Xen boot parameter to reserve\n"
   18.42 -		      "some DMA memory (e.g., dom0_mem=-128M).\n");
   18.43 +		panic("Cannot allocate SWIOTLB buffer!\n");
   18.44  
   18.45 +	dma_bits = get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT) + PAGE_SHIFT;
   18.46  	for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
   18.47 -		int rc = xen_create_contiguous_region(
   18.48 -			(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
   18.49 -			get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
   18.50 -			dma_bits);
   18.51 -		BUG_ON(rc);
   18.52 +		do {
   18.53 +			rc = xen_create_contiguous_region(
   18.54 +				(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
   18.55 +				get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
   18.56 +				dma_bits);
   18.57 +		} while (rc && dma_bits++ < max_dma_bits);
   18.58 +		if (rc) {
   18.59 +			if (i == 0)
   18.60 +				panic("No suitable physical memory available for SWIOTLB buffer!\n"
   18.61 +				      "Use dom0_mem Xen boot parameter to reserve\n"
   18.62 +				      "some DMA memory (e.g., dom0_mem=-128M).\n");
   18.63 +			iotlb_nslabs = i;
   18.64 +			i <<= IO_TLB_SHIFT;
   18.65 +			free_bootmem(__pa(iotlb_virt_start + i), bytes - i);
   18.66 +			bytes = i;
   18.67 +			for (dma_bits = 0; i > 0; i -= IO_TLB_SEGSIZE << IO_TLB_SHIFT) {
   18.68 +				unsigned int bits = fls64(virt_to_bus(iotlb_virt_start + i - 1));
   18.69 +
   18.70 +				if (bits > dma_bits)
   18.71 +					dma_bits = bits;
   18.72 +			}
   18.73 +			break;
   18.74 +		}
   18.75  	}
   18.76  
   18.77  	/*
   18.78 @@ -186,17 +202,27 @@ swiotlb_init_with_default_size (size_t d
   18.79  	 * Get the overflow emergency buffer
   18.80  	 */
   18.81  	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
   18.82 +	if (!io_tlb_overflow_buffer)
   18.83 +		panic("Cannot allocate SWIOTLB overflow buffer!\n");
   18.84 +
   18.85 +	do {
   18.86 +		rc = xen_create_contiguous_region(
   18.87 +			(unsigned long)io_tlb_overflow_buffer,
   18.88 +			get_order(io_tlb_overflow),
   18.89 +			dma_bits);
   18.90 +	} while (rc && dma_bits++ < max_dma_bits);
   18.91 +	if (rc)
   18.92 +		panic("No suitable physical memory available for SWIOTLB overflow buffer!\n");
   18.93  
   18.94  	iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
   18.95  	iotlb_pfn_end   = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
   18.96  
   18.97  	printk(KERN_INFO "Software IO TLB enabled: \n"
   18.98  	       " Aperture:     %lu megabytes\n"
   18.99 -	       " Kernel range: 0x%016lx - 0x%016lx\n"
  18.100 +	       " Kernel range: %p - %p\n"
  18.101  	       " Address size: %u bits\n",
  18.102  	       bytes >> 20,
  18.103 -	       (unsigned long)iotlb_virt_start,
  18.104 -	       (unsigned long)iotlb_virt_start + bytes,
  18.105 +	       iotlb_virt_start, iotlb_virt_start + bytes,
  18.106  	       dma_bits);
  18.107  }
  18.108  
  18.109 @@ -238,9 +264,12 @@ static void
  18.110  		char *dev, *host, *kmp;
  18.111  		len = size;
  18.112  		while (len != 0) {
  18.113 +			unsigned long flags;
  18.114 +
  18.115  			if (((bytes = len) + buffer.offset) > PAGE_SIZE)
  18.116  				bytes = PAGE_SIZE - buffer.offset;
  18.117 -			kmp  = kmap_atomic(buffer.page, KM_SWIOTLB);
  18.118 +			local_irq_save(flags); /* protects KM_BOUNCE_READ */
  18.119 +			kmp  = kmap_atomic(buffer.page, KM_BOUNCE_READ);
  18.120  			dev  = dma_addr + size - len;
  18.121  			host = kmp + buffer.offset;
  18.122  			if (dir == DMA_FROM_DEVICE) {
  18.123 @@ -248,7 +277,8 @@ static void
  18.124  					/* inaccessible */;
  18.125  			} else
  18.126  				memcpy(dev, host, bytes);
  18.127 -			kunmap_atomic(kmp, KM_SWIOTLB);
  18.128 +			kunmap_atomic(kmp, KM_BOUNCE_READ);
  18.129 +			local_irq_restore(flags);
  18.130  			len -= bytes;
  18.131  			buffer.page++;
  18.132  			buffer.offset = 0;
  18.133 @@ -617,6 +647,8 @@ swiotlb_sync_sg_for_device(struct device
  18.134  				    sg->dma_length, dir);
  18.135  }
  18.136  
  18.137 +#ifdef CONFIG_HIGHMEM
  18.138 +
  18.139  dma_addr_t
  18.140  swiotlb_map_page(struct device *hwdev, struct page *page,
  18.141  		 unsigned long offset, size_t size,
  18.142 @@ -650,6 +682,8 @@ swiotlb_unmap_page(struct device *hwdev,
  18.143  		unmap_single(hwdev, bus_to_virt(dma_address), size, direction);
  18.144  }
  18.145  
  18.146 +#endif
  18.147 +
  18.148  int
  18.149  swiotlb_dma_mapping_error(dma_addr_t dma_addr)
  18.150  {
  18.151 @@ -677,7 +711,5 @@ EXPORT_SYMBOL(swiotlb_sync_single_for_cp
  18.152  EXPORT_SYMBOL(swiotlb_sync_single_for_device);
  18.153  EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
  18.154  EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
  18.155 -EXPORT_SYMBOL(swiotlb_map_page);
  18.156 -EXPORT_SYMBOL(swiotlb_unmap_page);
  18.157  EXPORT_SYMBOL(swiotlb_dma_mapping_error);
  18.158  EXPORT_SYMBOL(swiotlb_dma_supported);
    19.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c	Sun Jan 14 22:18:38 2007 -0700
    19.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c	Mon Jan 15 15:15:26 2007 -0700
    19.3 @@ -225,7 +225,7 @@ static void dump_fault_path(unsigned lon
    19.4  	p += (address >> 30) * 2;
    19.5  	printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
    19.6  	if (p[0] & 1) {
    19.7 -		mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
    19.8 +		mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
    19.9  		page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
   19.10  		p  = (unsigned long *)__va(page);
   19.11  		address &= 0x3fffffff;
   19.12 @@ -234,7 +234,7 @@ static void dump_fault_path(unsigned lon
   19.13  		       page, p[1], p[0]);
   19.14  #ifndef CONFIG_HIGHPTE
   19.15  		if (p[0] & 1) {
   19.16 -			mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
   19.17 +			mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
   19.18  			page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
   19.19  			p  = (unsigned long *) __va(page);
   19.20  			address &= 0x001fffff;
    20.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Sun Jan 14 22:18:38 2007 -0700
    20.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Mon Jan 15 15:15:26 2007 -0700
    20.3 @@ -129,5 +129,6 @@ struct page *kmap_atomic_to_page(void *p
    20.4  EXPORT_SYMBOL(kmap);
    20.5  EXPORT_SYMBOL(kunmap);
    20.6  EXPORT_SYMBOL(kmap_atomic);
    20.7 +EXPORT_SYMBOL(kmap_atomic_pte);
    20.8  EXPORT_SYMBOL(kunmap_atomic);
    20.9  EXPORT_SYMBOL(kmap_atomic_to_page);
    21.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Sun Jan 14 22:18:38 2007 -0700
    21.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Mon Jan 15 15:15:26 2007 -0700
    21.3 @@ -238,23 +238,41 @@ struct page *pte_alloc_one(struct mm_str
    21.4  
    21.5  #ifdef CONFIG_HIGHPTE
    21.6  	pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
    21.7 +	if (pte && PageHighMem(pte)) {
    21.8 +		struct mmuext_op op;
    21.9 +
   21.10 +		kmap_flush_unused();
   21.11 +		op.cmd = MMUEXT_PIN_L1_TABLE;
   21.12 +		op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte));
   21.13 +		BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
   21.14 +	}
   21.15  #else
   21.16  	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
   21.17 +#endif
   21.18  	if (pte) {
   21.19  		SetPageForeign(pte, pte_free);
   21.20  		set_page_count(pte, 1);
   21.21  	}
   21.22 -#endif
   21.23  	return pte;
   21.24  }
   21.25  
   21.26  void pte_free(struct page *pte)
   21.27  {
   21.28 -	unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
   21.29 +	unsigned long pfn = page_to_pfn(pte);
   21.30 +
   21.31 +	if (!PageHighMem(pte)) {
   21.32 +		unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
   21.33  
   21.34 -	if (!pte_write(*virt_to_ptep(va)))
   21.35 -		BUG_ON(HYPERVISOR_update_va_mapping(
   21.36 -			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
   21.37 +		if (!pte_write(*virt_to_ptep(va)))
   21.38 +			BUG_ON(HYPERVISOR_update_va_mapping(
   21.39 +			       va, pfn_pte(pfn, PAGE_KERNEL), 0));
   21.40 +	} else {
   21.41 +		struct mmuext_op op;
   21.42 +
   21.43 +		op.cmd = MMUEXT_UNPIN_TABLE;
   21.44 +		op.arg1.mfn = pfn_to_mfn(pfn);
   21.45 +		BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
   21.46 +	}
   21.47  
   21.48  	ClearPageForeign(pte);
   21.49  	set_page_count(pte, 1);
    22.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Sun Jan 14 22:18:38 2007 -0700
    22.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Mon Jan 15 15:15:26 2007 -0700
    22.3 @@ -164,6 +164,18 @@ void _arch_exit_mmap(struct mm_struct *m
    22.4          mm_unpin(mm);
    22.5  }
    22.6  
    22.7 +struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
    22.8 +{
    22.9 +	struct page *pte;
   22.10 +
   22.11 +	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
   22.12 +	if (pte) {
   22.13 +		SetPageForeign(pte, pte_free);
   22.14 +		set_page_count(pte, 1);
   22.15 +	}
   22.16 +	return pte;
   22.17 +}
   22.18 +
   22.19  void pte_free(struct page *pte)
   22.20  {
   22.21  	unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
   22.22 @@ -171,6 +183,10 @@ void pte_free(struct page *pte)
   22.23  	if (!pte_write(*virt_to_ptep(va)))
   22.24  		BUG_ON(HYPERVISOR_update_va_mapping(
   22.25  			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
   22.26 +
   22.27 +	ClearPageForeign(pte);
   22.28 +	set_page_count(pte, 1);
   22.29 +
   22.30  	__free_page(pte);
   22.31  }
   22.32  #endif	/* CONFIG_XEN */
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Sun Jan 14 22:18:38 2007 -0700
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Mon Jan 15 15:15:26 2007 -0700
    23.3 @@ -42,9 +42,30 @@ static int connect_ring(struct backend_i
    23.4  static void backend_changed(struct xenbus_watch *, const char **,
    23.5  			    unsigned int);
    23.6  
    23.7 +static int blkback_name(blkif_t *blkif, char *buf)
    23.8 +{
    23.9 +	char *devpath, *devname;
   23.10 +	struct xenbus_device *dev = blkif->be->dev;
   23.11 +
   23.12 +	devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
   23.13 +	if (IS_ERR(devpath)) 
   23.14 +		return PTR_ERR(devpath);
   23.15 +	
   23.16 +	if ((devname = strstr(devpath, "/dev/")) != NULL)
   23.17 +		devname += strlen("/dev/");
   23.18 +	else
   23.19 +		devname  = devpath;
   23.20 +
   23.21 +	snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname);
   23.22 +	kfree(devpath);
   23.23 +	
   23.24 +	return 0;
   23.25 +}
   23.26 +
   23.27  static void update_blkif_status(blkif_t *blkif)
   23.28  { 
   23.29  	int err;
   23.30 +	char name[TASK_COMM_LEN];
   23.31  
   23.32  	/* Not ready to connect? */
   23.33  	if (!blkif->irq || !blkif->vbd.bdev)
   23.34 @@ -59,10 +80,13 @@ static void update_blkif_status(blkif_t 
   23.35  	if (blkif->be->dev->state != XenbusStateConnected)
   23.36  		return;
   23.37  
   23.38 -	blkif->xenblkd = kthread_run(blkif_schedule, blkif,
   23.39 -				     "xvd %d %02x:%02x",
   23.40 -				     blkif->domid,
   23.41 -				     blkif->be->major, blkif->be->minor);
   23.42 +	err = blkback_name(blkif, name);
   23.43 +	if (err) {
   23.44 +		xenbus_dev_error(blkif->be->dev, err, "get blkback dev name");
   23.45 +		return;
   23.46 +	}
   23.47 +
   23.48 +	blkif->xenblkd = kthread_run(blkif_schedule, blkif, name);
   23.49  	if (IS_ERR(blkif->xenblkd)) {
   23.50  		err = PTR_ERR(blkif->xenblkd);
   23.51  		blkif->xenblkd = NULL;
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Sun Jan 14 22:18:38 2007 -0700
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Mon Jan 15 15:15:26 2007 -0700
    24.3 @@ -92,9 +92,30 @@ static long get_id(const char *str)
    24.4          return simple_strtol(num, NULL, 10);
    24.5  }				
    24.6  
    24.7 +static int blktap_name(blkif_t *blkif, char *buf)
    24.8 +{
    24.9 +	char *devpath, *devname;
   24.10 +	struct xenbus_device *dev = blkif->be->dev;
   24.11 +
   24.12 +	devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
   24.13 +	if (IS_ERR(devpath)) 
   24.14 +		return PTR_ERR(devpath);
   24.15 +	
   24.16 +	if ((devname = strstr(devpath, "/dev/")) != NULL)
   24.17 +		devname += strlen("/dev/");
   24.18 +	else
   24.19 +		devname  = devpath;
   24.20 +
   24.21 +	snprintf(buf, TASK_COMM_LEN, "blktap.%d.%s", blkif->domid, devname);
   24.22 +	kfree(devpath);
   24.23 +	
   24.24 +	return 0;
   24.25 +}
   24.26 +
   24.27  static void tap_update_blkif_status(blkif_t *blkif)
   24.28  { 
   24.29  	int err;
   24.30 +	char name[TASK_COMM_LEN];
   24.31  
   24.32  	/* Not ready to connect? */
   24.33  	if(!blkif->irq || !blkif->sectors) {
   24.34 @@ -110,10 +131,13 @@ static void tap_update_blkif_status(blki
   24.35  	if (blkif->be->dev->state != XenbusStateConnected)
   24.36  		return;
   24.37  
   24.38 -	blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif,
   24.39 -				     "xvd %d",
   24.40 -				     blkif->domid);
   24.41 +	err = blktap_name(blkif, name);
   24.42 +	if (err) {
   24.43 +		xenbus_dev_error(blkif->be->dev, err, "get blktap dev name");
   24.44 +		return;
   24.45 +	}
   24.46  
   24.47 +	blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name);
   24.48  	if (IS_ERR(blkif->xenblkd)) {
   24.49  		err = PTR_ERR(blkif->xenblkd);
   24.50  		blkif->xenblkd = NULL;
    25.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h	Sun Jan 14 22:18:38 2007 -0700
    25.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h	Mon Jan 15 15:15:26 2007 -0700
    25.3 @@ -53,6 +53,7 @@ extern int dma_map_sg(struct device *hwd
    25.4  extern void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg,
    25.5  			 int nents, enum dma_data_direction direction);
    25.6  
    25.7 +#ifdef CONFIG_HIGHMEM
    25.8  extern dma_addr_t
    25.9  dma_map_page(struct device *dev, struct page *page, unsigned long offset,
   25.10  	     size_t size, enum dma_data_direction direction);
   25.11 @@ -60,6 +61,11 @@ dma_map_page(struct device *dev, struct 
   25.12  extern void
   25.13  dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
   25.14  	       enum dma_data_direction direction);
   25.15 +#else
   25.16 +#define dma_map_page(dev, page, offset, size, dir) \
   25.17 +	dma_map_single(dev, page_address(page) + (offset), (size), (dir))
   25.18 +#define dma_unmap_page dma_unmap_single
   25.19 +#endif
   25.20  
   25.21  extern void
   25.22  dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
    26.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h	Sun Jan 14 22:18:38 2007 -0700
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,32 +0,0 @@
    26.4 -#ifndef _ASM_KMAP_TYPES_H
    26.5 -#define _ASM_KMAP_TYPES_H
    26.6 -
    26.7 -#include <linux/config.h>
    26.8 -
    26.9 -#ifdef CONFIG_DEBUG_HIGHMEM
   26.10 -# define D(n) __KM_FENCE_##n ,
   26.11 -#else
   26.12 -# define D(n)
   26.13 -#endif
   26.14 -
   26.15 -enum km_type {
   26.16 -D(0)	KM_BOUNCE_READ,
   26.17 -D(1)	KM_SKB_SUNRPC_DATA,
   26.18 -D(2)	KM_SKB_DATA_SOFTIRQ,
   26.19 -D(3)	KM_USER0,
   26.20 -D(4)	KM_USER1,
   26.21 -D(5)	KM_BIO_SRC_IRQ,
   26.22 -D(6)	KM_BIO_DST_IRQ,
   26.23 -D(7)	KM_PTE0,
   26.24 -D(8)	KM_PTE1,
   26.25 -D(9)	KM_IRQ0,
   26.26 -D(10)	KM_IRQ1,
   26.27 -D(11)	KM_SOFTIRQ0,
   26.28 -D(12)	KM_SOFTIRQ1,
   26.29 -D(13)	KM_SWIOTLB,
   26.30 -D(14)	KM_TYPE_NR
   26.31 -};
   26.32 -
   26.33 -#undef D
   26.34 -
   26.35 -#endif
    27.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h	Sun Jan 14 22:18:38 2007 -0700
    27.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgalloc.h	Mon Jan 15 15:15:26 2007 -0700
    27.3 @@ -42,7 +42,7 @@ extern struct page *pte_alloc_one(struct
    27.4  static inline void pte_free_kernel(pte_t *pte)
    27.5  {
    27.6  	free_page((unsigned long)pte);
    27.7 -	make_page_writable(pte, XENFEAT_writable_page_tables);
    27.8 +	make_lowmem_page_writable(pte, XENFEAT_writable_page_tables);
    27.9  }
   27.10  
   27.11  extern void pte_free(struct page *pte);
    28.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h	Sun Jan 14 22:18:38 2007 -0700
    28.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/swiotlb.h	Mon Jan 15 15:15:26 2007 -0700
    28.3 @@ -26,16 +26,16 @@ extern int swiotlb_map_sg(struct device 
    28.4  extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
    28.5  			 int nents, int direction);
    28.6  extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
    28.7 +#ifdef CONFIG_HIGHMEM
    28.8  extern dma_addr_t swiotlb_map_page(struct device *hwdev, struct page *page,
    28.9                                     unsigned long offset, size_t size,
   28.10                                     enum dma_data_direction direction);
   28.11  extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
   28.12                                 size_t size, enum dma_data_direction direction);
   28.13 +#endif
   28.14  extern int swiotlb_dma_supported(struct device *hwdev, u64 mask);
   28.15  extern void swiotlb_init(void);
   28.16  
   28.17 -extern unsigned int dma_bits;
   28.18 -
   28.19  #ifdef CONFIG_SWIOTLB
   28.20  extern int swiotlb;
   28.21  #else
    29.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h	Sun Jan 14 22:18:38 2007 -0700
    29.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgalloc.h	Mon Jan 15 15:15:26 2007 -0700
    29.3 @@ -64,50 +64,43 @@ static inline void pgd_populate(struct m
    29.4  	}
    29.5  }
    29.6  
    29.7 -static inline void pmd_free(pmd_t *pmd)
    29.8 -{
    29.9 -	pte_t *ptep = virt_to_ptep(pmd);
   29.10 -
   29.11 -	if (!pte_write(*ptep)) {
   29.12 -		BUG_ON(HYPERVISOR_update_va_mapping(
   29.13 -			(unsigned long)pmd,
   29.14 -			pfn_pte(virt_to_phys(pmd)>>PAGE_SHIFT, PAGE_KERNEL),
   29.15 -			0));
   29.16 -	}
   29.17 -	free_page((unsigned long)pmd);
   29.18 -}
   29.19 +extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
   29.20 +extern void pte_free(struct page *pte);
   29.21  
   29.22  static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
   29.23  {
   29.24 -        pmd_t *pmd = (pmd_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   29.25 -        return pmd;
   29.26 +	struct page *pg;
   29.27 +
   29.28 +	pg = pte_alloc_one(mm, addr);
   29.29 +	return pg ? page_address(pg) : NULL;
   29.30 +}
   29.31 +
   29.32 +static inline void pmd_free(pmd_t *pmd)
   29.33 +{
   29.34 +	BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
   29.35 +	pte_free(virt_to_page(pmd));
   29.36  }
   29.37  
   29.38  static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
   29.39  {
   29.40 -        pud_t *pud = (pud_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   29.41 -        return pud;
   29.42 +	struct page *pg;
   29.43 +
   29.44 +	pg = pte_alloc_one(mm, addr);
   29.45 +	return pg ? page_address(pg) : NULL;
   29.46  }
   29.47  
   29.48  static inline void pud_free(pud_t *pud)
   29.49  {
   29.50 -	pte_t *ptep = virt_to_ptep(pud);
   29.51 -
   29.52 -	if (!pte_write(*ptep)) {
   29.53 -		BUG_ON(HYPERVISOR_update_va_mapping(
   29.54 -			(unsigned long)pud,
   29.55 -			pfn_pte(virt_to_phys(pud)>>PAGE_SHIFT, PAGE_KERNEL),
   29.56 -			0));
   29.57 -	}
   29.58 -	free_page((unsigned long)pud);
   29.59 +	BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
   29.60 +	pte_free(virt_to_page(pud));
   29.61  }
   29.62  
   29.63  static inline pgd_t *pgd_alloc(struct mm_struct *mm)
   29.64  {
   29.65 -        /*
   29.66 -         * We allocate two contiguous pages for kernel and user.
   29.67 -         */
   29.68 -        unsigned boundary;
   29.69 +	/*
   29.70 +	 * We allocate two contiguous pages for kernel and user.
   29.71 +	 */
   29.72 +	unsigned boundary;
   29.73  	pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1);
   29.74  
   29.75  	if (!pgd)
   29.76 @@ -124,11 +117,11 @@ static inline pgd_t *pgd_alloc(struct mm
   29.77  	       (PTRS_PER_PGD - boundary) * sizeof(pgd_t));
   29.78  
   29.79  	memset(__user_pgd(pgd), 0, PAGE_SIZE); /* clean up user pgd */
   29.80 -        /*
   29.81 -         * Set level3_user_pgt for vsyscall area
   29.82 -         */
   29.83 +	/*
   29.84 +	 * Set level3_user_pgt for vsyscall area
   29.85 +	 */
   29.86  	set_pgd(__user_pgd(pgd) + pgd_index(VSYSCALL_START), 
   29.87 -                mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
   29.88 +		mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
   29.89  	return pgd;
   29.90  }
   29.91  
   29.92 @@ -160,39 +153,25 @@ static inline void pgd_free(pgd_t *pgd)
   29.93  
   29.94  static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
   29.95  {
   29.96 -        pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   29.97 -        if (pte)
   29.98 +	pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
   29.99 +	if (pte)
  29.100  		make_page_readonly(pte, XENFEAT_writable_page_tables);
  29.101  
  29.102  	return pte;
  29.103  }
  29.104  
  29.105 -static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  29.106 -{
  29.107 -	struct page *pte;
  29.108 -
  29.109 -	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
  29.110 -	return pte;
  29.111 -}
  29.112 -
  29.113  /* Should really implement gc for free page table pages. This could be
  29.114     done with a reference count in struct page. */
  29.115  
  29.116  static inline void pte_free_kernel(pte_t *pte)
  29.117  {
  29.118  	BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
  29.119 -        make_page_writable(pte, XENFEAT_writable_page_tables);
  29.120 +	make_page_writable(pte, XENFEAT_writable_page_tables);
  29.121  	free_page((unsigned long)pte); 
  29.122  }
  29.123  
  29.124 -extern void pte_free(struct page *pte);
  29.125 -
  29.126 -//#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) 
  29.127 -//#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  29.128 -//#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  29.129 -
  29.130 -#define __pte_free_tlb(tlb,x)   pte_free((x))
  29.131 -#define __pmd_free_tlb(tlb,x)   pmd_free((x))
  29.132 -#define __pud_free_tlb(tlb,x)   pud_free((x))
  29.133 +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
  29.134 +#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  29.135 +#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
  29.136  
  29.137  #endif /* _X86_64_PGALLOC_H */
    30.1 --- a/patches/linux-2.6.16.33/ipv6-no-autoconf.patch	Sun Jan 14 22:18:38 2007 -0700
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,19 +0,0 @@
    30.4 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/addrconf.c ./net/ipv6/addrconf.c
    30.5 ---- ../orig-linux-2.6.16.29/net/ipv6/addrconf.c	2006-09-12 19:02:10.000000000 +0100
    30.6 -+++ ./net/ipv6/addrconf.c	2006-09-19 13:59:11.000000000 +0100
    30.7 -@@ -2471,6 +2471,7 @@ static void addrconf_dad_start(struct in
    30.8 - 	spin_lock_bh(&ifp->lock);
    30.9 - 
   30.10 - 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
   30.11 -+	    !(dev->flags&IFF_MULTICAST) ||
   30.12 - 	    !(ifp->flags&IFA_F_TENTATIVE)) {
   30.13 - 		ifp->flags &= ~IFA_F_TENTATIVE;
   30.14 - 		spin_unlock_bh(&ifp->lock);
   30.15 -@@ -2555,6 +2556,7 @@ static void addrconf_dad_completed(struc
   30.16 - 	if (ifp->idev->cnf.forwarding == 0 &&
   30.17 - 	    ifp->idev->cnf.rtr_solicits > 0 &&
   30.18 - 	    (dev->flags&IFF_LOOPBACK) == 0 &&
   30.19 -+	    (dev->flags & IFF_MULTICAST) &&
   30.20 - 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
   30.21 - 		struct in6_addr all_routers;
   30.22 - 
    31.1 --- a/patches/linux-2.6.16.33/series	Sun Jan 14 22:18:38 2007 -0700
    31.2 +++ b/patches/linux-2.6.16.33/series	Mon Jan 15 15:15:26 2007 -0700
    31.3 @@ -9,7 +9,6 @@ device_bind.patch
    31.4  fix-hz-suspend.patch
    31.5  fix-ide-cd-pio-mode.patch
    31.6  i386-mach-io-check-nmi.patch
    31.7 -ipv6-no-autoconf.patch
    31.8  net-csum.patch
    31.9  net-gso-0-base.patch
   31.10  net-gso-1-check-dodgy.patch
    32.1 --- a/tools/check/check_udev	Sun Jan 14 22:18:38 2007 -0700
    32.2 +++ b/tools/check/check_udev	Mon Jan 15 15:15:26 2007 -0700
    32.3 @@ -11,7 +11,7 @@ OpenBSD|NetBSD|FreeBSD)
    32.4  Linux)
    32.5  	TOOL="udevinfo"
    32.6  	UDEV_VERSION="0"
    32.7 -	test -x "$(which ${TOOL})" && \
    32.8 +	test -x "$(which ${TOOL} 2>/dev/null)" && \
    32.9  		UDEV_VERSION=$(${TOOL} -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
   32.10  	if test "${UDEV_VERSION}" -ge 059; then
   32.11  		RC=0
   32.12 @@ -28,7 +28,7 @@ esac
   32.13  
   32.14  if test ${RC} -ne 0; then
   32.15  	echo
   32.16 -	echo ' *** Check for ${TOOL} FAILED'
   32.17 +	echo " *** Check for ${TOOL} FAILED"
   32.18  fi
   32.19  
   32.20  exit ${RC}
    33.1 --- a/tools/examples/vtpm-common.sh	Sun Jan 14 22:18:38 2007 -0700
    33.2 +++ b/tools/examples/vtpm-common.sh	Mon Jan 15 15:15:26 2007 -0700
    33.3 @@ -24,7 +24,9 @@ VTPMDB="/etc/xen/vtpm.db"
    33.4  
    33.5  #In the vtpm-impl file some commands should be defined:
    33.6  #      vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
    33.7 -if [ -r "$dir/vtpm-impl" ]; then
    33.8 +if [ -r "$dir/vtpm-impl.alt" ]; then
    33.9 +	. "$dir/vtpm-impl.alt"
   33.10 +elif [ -r "$dir/vtpm-impl" ]; then
   33.11  	. "$dir/vtpm-impl"
   33.12  else
   33.13  	function vtpm_create () {
    34.1 --- a/tools/examples/xen-network-common.sh	Sun Jan 14 22:18:38 2007 -0700
    34.2 +++ b/tools/examples/xen-network-common.sh	Mon Jan 15 15:15:26 2007 -0700
    34.3 @@ -117,7 +117,12 @@ create_bridge () {
    34.4          ip link set ${bridge} arp off
    34.5          ip link set ${bridge} multicast off
    34.6      fi
    34.7 +
    34.8 +    # A small MTU disables IPv6 (and therefore IPv6 addrconf).
    34.9 +    mtu=$(ip link show ${bridge} | sed -n 's/.* mtu \([0-9]\+\).*/\1/p')
   34.10 +    ip link set ${bridge} mtu 68
   34.11      ip link set ${bridge} up
   34.12 +    ip link set ${bridge} mtu ${mtu:-1500}
   34.13  }
   34.14  
   34.15  # Usage: add_to_bridge bridge dev
    35.1 --- a/tools/examples/xmexample1	Sun Jan 14 22:18:38 2007 -0700
    35.2 +++ b/tools/examples/xmexample1	Mon Jan 15 15:15:26 2007 -0700
    35.3 @@ -66,6 +66,40 @@ vif = [ '' ]
    35.4  disk = [ 'phy:hda1,hda1,w' ]
    35.5  
    35.6  #----------------------------------------------------------------------------
    35.7 +# Define frame buffer device.
    35.8 +#
    35.9 +# By default, no frame buffer device is configured.
   35.10 +#
   35.11 +# To create one using the SDL backend and sensible defaults:
   35.12 +#
   35.13 +# vfb = [ 'type=sdl' ]
   35.14 +#
   35.15 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   35.16 +# can override that:
   35.17 +#
   35.18 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   35.19 +#
   35.20 +# To create one using the VNC backend and sensible defaults:
   35.21 +#
   35.22 +# vfb = [ 'type=vnc' ]
   35.23 +#
   35.24 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   35.25 +# the domain ID.  You can override both address and N:
   35.26 +#
   35.27 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=1' ]
   35.28 +#
   35.29 +# Or you can bind the first unused port above 5900:
   35.30 +#
   35.31 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ]
   35.32 +#
   35.33 +# You can override the password:
   35.34 +#
   35.35 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
   35.36 +#
   35.37 +# Empty password disables authentication.  Defaults to the vncpasswd
   35.38 +# configured in xend-config.sxp.
   35.39 +
   35.40 +#----------------------------------------------------------------------------
   35.41  # Define to which TPM instance the user domain should communicate.
   35.42  # The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   35.43  # where INSTANCE indicates the instance number of the TPM the VM
    36.1 --- a/tools/examples/xmexample2	Sun Jan 14 22:18:38 2007 -0700
    36.2 +++ b/tools/examples/xmexample2	Mon Jan 15 15:15:26 2007 -0700
    36.3 @@ -102,6 +102,40 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
    36.4           'phy:sda6,sda6,r' ]
    36.5  
    36.6  #----------------------------------------------------------------------------
    36.7 +# Define frame buffer device.
    36.8 +#
    36.9 +# By default, no frame buffer device is configured.
   36.10 +#
   36.11 +# To create one using the SDL backend and sensible defaults:
   36.12 +#
   36.13 +# vfb = [ 'type=sdl' ]
   36.14 +#
   36.15 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   36.16 +# can override that:
   36.17 +#
   36.18 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   36.19 +#
   36.20 +# To create one using the VNC backend and sensible defaults:
   36.21 +#
   36.22 +# vfb = [ 'type=vnc' ]
   36.23 +#
   36.24 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   36.25 +# the domain ID.  You can override both address and N:
   36.26 +#
   36.27 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=%d' % vmid ]
   36.28 +#
   36.29 +# Or you can bind the first unused port above 5900:
   36.30 +#
   36.31 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ]
   36.32 +#
   36.33 +# You can override the password:
   36.34 +#
   36.35 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
   36.36 +#
   36.37 +# Empty password disables authentication.  Defaults to the vncpasswd
   36.38 +# configured in xend-config.sxp.
   36.39 +
   36.40 +#----------------------------------------------------------------------------
   36.41  # Define to which TPM instance the user domain should communicate.
   36.42  # The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   36.43  # where INSTANCE indicates the instance number of the TPM the VM
    37.1 --- a/tools/examples/xmexample3	Sun Jan 14 22:18:38 2007 -0700
    37.2 +++ b/tools/examples/xmexample3	Mon Jan 15 15:15:26 2007 -0700
    37.3 @@ -87,6 +87,40 @@ vif = [ 'ip=192.168.%d.1/24' % (vmid)]
    37.4  disk = [ 'phy:hda%d,hda1,w' % (vmid)]
    37.5  
    37.6  #----------------------------------------------------------------------------
    37.7 +# Define frame buffer device.
    37.8 +#
    37.9 +# By default, no frame buffer device is configured.
   37.10 +#
   37.11 +# To create one using the SDL backend and sensible defaults:
   37.12 +#
   37.13 +# vfb = [ 'type=sdl' ]
   37.14 +#
   37.15 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   37.16 +# can override that:
   37.17 +#
   37.18 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   37.19 +#
   37.20 +# To create one using the VNC backend and sensible defaults:
   37.21 +#
   37.22 +# vfb = [ 'type=vnc' ]
   37.23 +#
   37.24 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   37.25 +# the domain ID.  You can override both address and N:
   37.26 +#
   37.27 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=%d' % vmid ]
   37.28 +#
   37.29 +# Or you can bind the first unused port above 5900:
   37.30 +#
   37.31 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ]
   37.32 +#
   37.33 +# You can override the password:
   37.34 +#
   37.35 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
   37.36 +#
   37.37 +# Empty password disables authentication.  Defaults to the vncpasswd
   37.38 +# configured in xend-config.sxp.
   37.39 +
   37.40 +#----------------------------------------------------------------------------
   37.41  # Define to which TPM instance the user domain should communicate.
   37.42  # The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   37.43  # where INSTANCE indicates the instance number of the TPM the VM
    38.1 --- a/tools/libxc/xc_load_elf.c	Sun Jan 14 22:18:38 2007 -0700
    38.2 +++ b/tools/libxc/xc_load_elf.c	Mon Jan 15 15:15:26 2007 -0700
    38.3 @@ -406,17 +406,19 @@ static int parseelfimage(const char *ima
    38.4      }
    38.5  
    38.6      /*
    38.7 -     * A "bimodal" ELF note indicates the kernel will adjust to the
    38.8 -     * current paging mode, including handling extended cr3 syntax.
    38.9 -     * If we have ELF notes then PAE=yes implies that we must support
   38.10 -     * the extended cr3 syntax. Otherwise we need to find the
   38.11 -     * [extended-cr3] syntax in the __xen_guest string.
   38.12 +     * A "bimodal" ELF note indicates the kernel will adjust to the current
   38.13 +     * paging mode, including handling extended cr3 syntax.  If we have ELF
   38.14 +     * notes then PAE=yes implies that we must support the extended cr3 syntax.
   38.15 +     * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest
   38.16 +     * string. We use strstr() to look for "bimodal" to allow guests to use
   38.17 +     * "yes,bimodal" or "no,bimodal" for compatibility reasons.
   38.18       */
   38.19 +
   38.20      dsi->pae_kernel = PAEKERN_no;
   38.21      if ( dsi->__elfnote_section )
   38.22      {
   38.23          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   38.24 -        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
   38.25 +        if ( p != NULL && strstr(p, "bimodal") != NULL )
   38.26              dsi->pae_kernel = PAEKERN_bimodal;
   38.27          else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   38.28              dsi->pae_kernel = PAEKERN_extended_cr3;
    39.1 --- a/tools/libxc/xc_ptrace.c	Sun Jan 14 22:18:38 2007 -0700
    39.2 +++ b/tools/libxc/xc_ptrace.c	Mon Jan 15 15:15:26 2007 -0700
    39.3 @@ -166,14 +166,11 @@ static unsigned long           *page_arr
    39.4   * tables.
    39.5   *
    39.6   */
    39.7 -static unsigned long
    39.8 -to_ma(int cpu,
    39.9 -      unsigned long in_addr)
   39.10 +static uint64_t
   39.11 +to_ma(int cpu, uint64_t maddr)
   39.12  {
   39.13 -    unsigned long maddr = in_addr;
   39.14 -
   39.15      if ( current_is_hvm && paging_enabled(&ctxt[cpu]) )
   39.16 -        maddr = page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
   39.17 +        maddr = (uint64_t)page_array[maddr >> PAGE_SHIFT] << PAGE_SHIFT;
   39.18      return maddr;
   39.19  }
   39.20  
   39.21 @@ -225,7 +222,8 @@ map_domain_va_pae(
   39.22      void *guest_va,
   39.23      int perm)
   39.24  {
   39.25 -    unsigned long l3e, l2e, l1e, l2p, l1p, p, va = (unsigned long)guest_va;
   39.26 +    uint64_t l3e, l2e, l1e, l2p, l1p, p;
   39.27 +    unsigned long va = (unsigned long)guest_va;
   39.28      uint64_t *l3, *l2, *l1;
   39.29      static void *v[MAX_VIRT_CPUS];
   39.30  
   39.31 @@ -380,12 +378,12 @@ map_domain_va(
   39.32  
   39.33      if (!paging_enabled(&ctxt[cpu])) {
   39.34          static void * v;
   39.35 -        unsigned long page;
   39.36 +        uint64_t page;
   39.37  
   39.38          if ( v != NULL )
   39.39              munmap(v, PAGE_SIZE);
   39.40  
   39.41 -        page = to_ma(cpu, page_array[va >> PAGE_SHIFT]);
   39.42 +        page = to_ma(cpu, va);
   39.43  
   39.44          v = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE,
   39.45                  perm, page >> PAGE_SHIFT);
    40.1 --- a/tools/pygrub/src/pygrub	Sun Jan 14 22:18:38 2007 -0700
    40.2 +++ b/tools/pygrub/src/pygrub	Mon Jan 15 15:15:26 2007 -0700
    40.3 @@ -48,8 +48,7 @@ def is_disk_image(file):
    40.4          return True
    40.5      return False
    40.6  
    40.7 -SECTOR_SIZE=512
    40.8 -def get_active_offset(file):
    40.9 +def get_active_partition(file):
   40.10      """Find the offset for the start of the first active partition "
   40.11      "in the disk image file."""
   40.12  
   40.13 @@ -58,22 +57,56 @@ def get_active_offset(file):
   40.14      for poff in (446, 462, 478, 494): # partition offsets
   40.15          # active partition has 0x80 as the first byte
   40.16          if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
   40.17 -            return struct.unpack("<L",
   40.18 -                                 buf[poff+8:poff+12])[0] * SECTOR_SIZE
   40.19 +            return buf[poff:poff+16]
   40.20  
   40.21      # if there's not a partition marked as active, fall back to
   40.22      # the first partition
   40.23 -    P1 = 446
   40.24 -    return struct.unpack("<L", buf[P1+8:P1+12])[0] * SECTOR_SIZE
   40.25 +    return buf[446:446+16]
   40.26 +
   40.27 +SECTOR_SIZE=512
   40.28 +DK_LABEL_LOC=1
   40.29 +DKL_MAGIC=0xdabe
   40.30 +V_ROOT=0x2
   40.31 +
   40.32 +def get_solaris_slice(file, offset):
   40.33 +    """Find the root slice in a Solaris VTOC."""
   40.34 +
   40.35 +    fd = os.open(file, os.O_RDONLY)
   40.36 +    os.lseek(fd, offset + (DK_LABEL_LOC * SECTOR_SIZE), 0)
   40.37 +    buf = os.read(fd, 512)
   40.38 +    if struct.unpack("<H", buf[508:510])[0] != DKL_MAGIC:
   40.39 +        raise RuntimeError, "Invalid disklabel magic"
   40.40 +
   40.41 +    nslices = struct.unpack("<H", buf[30:32])[0]
   40.42  
   40.43 -def open_fs(file):
   40.44 -    offset = 0
   40.45 -    if is_disk_image(file):
   40.46 -        offset = get_active_offset(file)
   40.47 -        if offset == -1:
   40.48 -            raise RuntimeError, "Unable to find active partition on disk"
   40.49 +    for i in range(nslices):
   40.50 +        sliceoff = 72 + 12 * i
   40.51 +        slicetag = struct.unpack("<H", buf[sliceoff:sliceoff+2])[0]
   40.52 +        slicesect = struct.unpack("<L", buf[sliceoff+4:sliceoff+8])[0]
   40.53 +        if slicetag == V_ROOT:
   40.54 +            return slicesect * SECTOR_SIZE
   40.55 +
   40.56 +    raise RuntimeError, "No root slice found"      
   40.57 +
   40.58 +FDISK_PART_SOLARIS=0xbf
   40.59 +FDISK_PART_SOLARIS_OLD=0x82
   40.60  
   40.61 -    return fsimage.open(file, offset)
   40.62 +def get_fs_offset(file):
   40.63 +    if not is_disk_image(file):
   40.64 +        return 0
   40.65 +
   40.66 +    partbuf = get_active_partition(file)
   40.67 +    if len(partbuf) == 0:
   40.68 +        raise RuntimeError, "Unable to find active partition on disk"
   40.69 +
   40.70 +    offset = struct.unpack("<L", partbuf[8:12])[0] * SECTOR_SIZE
   40.71 +
   40.72 +    type = struct.unpack("<B", partbuf[4:5])[0]
   40.73 +
   40.74 +    if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
   40.75 +        offset += get_solaris_slice(file, offset)
   40.76 +
   40.77 +    return offset
   40.78  
   40.79  class GrubLineEditor(curses.textpad.Textbox):
   40.80      def __init__(self, screen, startx, starty, line = ""):
   40.81 @@ -571,7 +604,7 @@ if __name__ == "__main__":
   40.82          print "  args: %s" % chosencfg["args"]
   40.83          sys.exit(0)
   40.84  
   40.85 -    fs = open_fs(file)
   40.86 +    fs = fsimage.open(file, get_fs_offset(file))
   40.87  
   40.88      chosencfg = sniff_solaris(fs, incfg)
   40.89  
    41.1 --- a/tools/python/xen/xend/XendConfig.py	Sun Jan 14 22:18:38 2007 -0700
    41.2 +++ b/tools/python/xen/xend/XendConfig.py	Mon Jan 15 15:15:26 2007 -0700
    41.3 @@ -1020,10 +1020,11 @@ class XendConfig(dict):
    41.4          @return: Returns True if succesfully found and updated a device conf
    41.5          """
    41.6          if dev_uuid in self['devices']:
    41.7 -            config = sxp.child0(cfg_sxp)
    41.8 -            dev_type = sxp.name(config)
    41.9 -            dev_info = {}
   41.10 -
   41.11 +            if sxp.child0(cfg_sxp) == 'device':            
   41.12 +                config = sxp.child0(cfg_sxp)
   41.13 +            else:
   41.14 +                config = cfg_sxp
   41.15 +                
   41.16              for opt_val in config[1:]:
   41.17                  try:
   41.18                      opt, val = opt_val
    42.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sun Jan 14 22:18:38 2007 -0700
    42.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Jan 15 15:15:26 2007 -0700
    42.3 @@ -496,7 +496,7 @@ class XendDomainInfo:
    42.4          self._waitForDevice(dev_type, devid)
    42.5          return self.getDeviceController(dev_type).sxpr(devid)
    42.6  
    42.7 -    def device_configure(self, dev_config, devid = None):
    42.8 +    def device_configure(self, dev_sxp, devid = None):
    42.9          """Configure an existing device.
   42.10          
   42.11          @param dev_config: device configuration
   42.12 @@ -506,19 +506,24 @@ class XendDomainInfo:
   42.13          @return: Returns True if successfully updated device
   42.14          @rtype: boolean
   42.15          """
   42.16 -        deviceClass = sxp.name(dev_config)
   42.17 -        
   42.18 -        # look up uuid of the device
   42.19 -        dev_control =  self.getDeviceController(deviceClass)
   42.20 -        dev_sxpr = dev_control.sxpr(devid)
   42.21 -        dev_uuid = sxp.child_value(dev_sxpr, 'uuid')
   42.22 -        if not dev_uuid:
   42.23 -            return False
   42.24  
   42.25 -        self.info.device_update(dev_uuid, dev_config)
   42.26 -        dev_config_dict = self.info['devices'].get(dev_uuid)
   42.27 -        if dev_config_dict:
   42.28 -            dev_control.reconfigureDevice(devid, dev_config_dict[1])
   42.29 +        # convert device sxp to a dict
   42.30 +        dev_class = sxp.name(dev_sxp)
   42.31 +        dev_config = {}
   42.32 +        for opt_val in dev_sxp[1:]:
   42.33 +            try:
   42.34 +                dev_config[opt_val[0]] = opt_val[1]
   42.35 +            except IndexError:
   42.36 +                pass
   42.37 +
   42.38 +        # use DevController.reconfigureDevice to change device config
   42.39 +        dev_control = self.getDeviceController(dev_class)
   42.40 +        dev_uuid = dev_control.reconfigureDevice(devid, dev_config)
   42.41 +
   42.42 +        # update XendConfig with new device info
   42.43 +        if dev_uuid:
   42.44 +            self.info.device_update(dev_uuid, dev_sxp)
   42.45 +            
   42.46          return True
   42.47  
   42.48      def waitForDevices(self):
    43.1 --- a/tools/python/xen/xend/server/blkif.py	Sun Jan 14 22:18:38 2007 -0700
    43.2 +++ b/tools/python/xen/xend/server/blkif.py	Mon Jan 15 15:15:26 2007 -0700
    43.3 @@ -101,6 +101,7 @@ class BlkifController(DevController):
    43.4              self.writeBackend(devid,
    43.5                                'type', new_back['type'],
    43.6                                'params', new_back['params'])
    43.7 +            return new_back.get('uuid')
    43.8          else:
    43.9              raise VmError('Refusing to reconfigure device %s:%d to %s' %
   43.10                            (self.deviceClass, devid, config))
    44.1 --- a/tools/python/xen/xm/create.py	Sun Jan 14 22:18:38 2007 -0700
    44.2 +++ b/tools/python/xen/xm/create.py	Mon Jan 15 15:15:26 2007 -0700
    44.3 @@ -292,7 +292,8 @@ gopts.var('vfb', val="type={vnc,sdl},vnc
    44.4            For type=vnc, connect an external vncviewer.  The server will listen
    44.5            on ADDR (default 127.0.0.1) on port N+5900.  N defaults to the
    44.6            domain id.  If vncunused=1, the server will try to find an arbitrary
    44.7 -          unused port above 5900.
    44.8 +          unused port above 5900.  vncpasswd overrides the XenD configured
    44.9 +          default password.
   44.10            For type=sdl, a viewer will be started automatically using the
   44.11            given DISPLAY and XAUTHORITY, which default to the current user's
   44.12            ones.""")
    45.1 --- a/tools/tests/Makefile	Sun Jan 14 22:18:38 2007 -0700
    45.2 +++ b/tools/tests/Makefile	Mon Jan 15 15:15:26 2007 -0700
    45.3 @@ -7,12 +7,21 @@ TARGET := test_x86_emulator
    45.4  .PHONY: all
    45.5  all: $(TARGET)
    45.6  
    45.7 +.PHONY: blowfish.bin
    45.8 +blowfish.bin:
    45.9 +	make -f blowfish.mk all
   45.10 +
   45.11 +blowfish.h: blowfish.bin
   45.12 +	(echo "static unsigned int blowfish_code[] = {"; \
   45.13 +	od -v -t x $< | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$$/,/';\
   45.14 +	echo "};") >$@
   45.15 +
   45.16  $(TARGET): x86_emulate.o test_x86_emulator.o
   45.17  	$(HOSTCC) -o $@ $^
   45.18  
   45.19  .PHONY: clean
   45.20  clean:
   45.21 -	rm -rf $(TARGET) *.o *~ core
   45.22 +	rm -rf $(TARGET) *.o *~ core blowfish.h blowfish.bin
   45.23  
   45.24  .PHONY: install
   45.25  install:
   45.26 @@ -20,5 +29,5 @@ install:
   45.27  x86_emulate.o: $(XEN_ROOT)/xen/arch/x86/x86_emulate.c
   45.28  	$(HOSTCC) $(HOSTCFLAGS) -I$(XEN_ROOT)/xen/include -c -o $@ $<
   45.29  
   45.30 -%.o: %.c
   45.31 +test_x86_emulator.o: test_x86_emulator.c blowfish.h
   45.32  	$(HOSTCC) $(HOSTCFLAGS) -I$(XEN_ROOT)/xen/include -c -o $@ $<
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tools/tests/blowfish.c	Mon Jan 15 15:15:26 2007 -0700
    46.3 @@ -0,0 +1,439 @@
    46.4 +/*
    46.5 +blowfish.c:  C implementation of the Blowfish algorithm.
    46.6 +
    46.7 +Copyright (C) 1997 by Paul Kocher
    46.8 +
    46.9 +This library is free software; you can redistribute it and/or
   46.10 +modify it under the terms of the GNU Lesser General Public
   46.11 +License as published by the Free Software Foundation; either
   46.12 +version 2.1 of the License, or (at your option) any later version.
   46.13 +This library is distributed in the hope that it will be useful,
   46.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   46.16 +Lesser General Public License for more details.
   46.17 +You should have received a copy of the GNU Lesser General Public
   46.18 +License along with this library; if not, write to the Free Software
   46.19 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   46.20 +*/
   46.21 +
   46.22 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
   46.23 +#define __attribute_used__ __attribute__((__used__))
   46.24 +#else
   46.25 +#define __attribute_used__ __attribute__((__unused__))
   46.26 +#endif
   46.27 +
   46.28 +static unsigned long long blowfish_test(unsigned long long input)
   46.29 +    __attribute_used__;
   46.30 +
   46.31 +asm (
   46.32 +    ".globl _start\n"
   46.33 +    "_start:\n"
   46.34 +    "push %edx; push %eax; "
   46.35 +    "call blowfish_test; "
   46.36 +    "addl $8,%esp; "
   46.37 +    "ret"
   46.38 +    );
   46.39 +
   46.40 +typedef struct {
   46.41 +  unsigned long P[16 + 2];
   46.42 +  unsigned long S[4][256];
   46.43 +} BLOWFISH_CTX;
   46.44 +
   46.45 +#define N               16
   46.46 +
   46.47 +static const unsigned long ORIG_P[16 + 2] = {
   46.48 +        0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
   46.49 +        0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
   46.50 +        0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
   46.51 +        0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
   46.52 +        0x9216D5D9L, 0x8979FB1BL
   46.53 +};
   46.54 +
   46.55 +static const unsigned long ORIG_S[4][256] = {
   46.56 +    {   0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
   46.57 +        0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
   46.58 +        0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
   46.59 +        0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
   46.60 +        0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
   46.61 +        0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
   46.62 +        0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
   46.63 +        0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
   46.64 +        0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
   46.65 +        0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
   46.66 +        0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
   46.67 +        0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
   46.68 +        0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
   46.69 +        0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
   46.70 +        0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
   46.71 +        0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
   46.72 +        0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
   46.73 +        0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
   46.74 +        0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
   46.75 +        0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
   46.76 +        0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
   46.77 +        0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
   46.78 +        0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
   46.79 +        0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
   46.80 +        0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
   46.81 +        0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
   46.82 +        0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
   46.83 +        0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
   46.84 +        0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
   46.85 +        0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
   46.86 +        0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
   46.87 +        0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
   46.88 +        0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
   46.89 +        0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
   46.90 +        0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
   46.91 +        0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
   46.92 +        0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
   46.93 +        0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
   46.94 +        0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
   46.95 +        0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
   46.96 +        0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
   46.97 +        0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
   46.98 +        0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
   46.99 +        0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
  46.100 +        0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
  46.101 +        0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
  46.102 +        0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
  46.103 +        0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
  46.104 +        0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
  46.105 +        0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
  46.106 +        0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
  46.107 +        0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
  46.108 +        0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
  46.109 +        0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
  46.110 +        0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
  46.111 +        0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
  46.112 +        0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
  46.113 +        0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
  46.114 +        0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
  46.115 +        0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
  46.116 +        0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
  46.117 +        0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
  46.118 +        0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
  46.119 +        0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL   },
  46.120 +    {   0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
  46.121 +        0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
  46.122 +        0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
  46.123 +        0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
  46.124 +        0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
  46.125 +        0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
  46.126 +        0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
  46.127 +        0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
  46.128 +        0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
  46.129 +        0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
  46.130 +        0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
  46.131 +        0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
  46.132 +        0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
  46.133 +        0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
  46.134 +        0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
  46.135 +        0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
  46.136 +        0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
  46.137 +        0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
  46.138 +        0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
  46.139 +        0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
  46.140 +        0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
  46.141 +        0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
  46.142 +        0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
  46.143 +        0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
  46.144 +        0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
  46.145 +        0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
  46.146 +        0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
  46.147 +        0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
  46.148 +        0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
  46.149 +        0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
  46.150 +        0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
  46.151 +        0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
  46.152 +        0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
  46.153 +        0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
  46.154 +        0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
  46.155 +        0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
  46.156 +        0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
  46.157 +        0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
  46.158 +        0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
  46.159 +        0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
  46.160 +        0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
  46.161 +        0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
  46.162 +        0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
  46.163 +        0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
  46.164 +        0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
  46.165 +        0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
  46.166 +        0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
  46.167 +        0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
  46.168 +        0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
  46.169 +        0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
  46.170 +        0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
  46.171 +        0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
  46.172 +        0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
  46.173 +        0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
  46.174 +        0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
  46.175 +        0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
  46.176 +        0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
  46.177 +        0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
  46.178 +        0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
  46.179 +        0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
  46.180 +        0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
  46.181 +        0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
  46.182 +        0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
  46.183 +        0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L   },
  46.184 +    {   0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
  46.185 +        0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
  46.186 +        0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
  46.187 +        0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
  46.188 +        0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
  46.189 +        0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
  46.190 +        0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
  46.191 +        0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
  46.192 +        0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
  46.193 +        0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
  46.194 +        0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
  46.195 +        0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
  46.196 +        0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
  46.197 +        0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
  46.198 +        0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
  46.199 +        0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
  46.200 +        0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
  46.201 +        0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
  46.202 +        0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
  46.203 +        0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
  46.204 +        0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
  46.205 +        0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
  46.206 +        0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
  46.207 +        0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
  46.208 +        0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
  46.209 +        0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
  46.210 +        0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
  46.211 +        0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
  46.212 +        0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
  46.213 +        0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
  46.214 +        0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
  46.215 +        0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
  46.216 +        0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
  46.217 +        0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
  46.218 +        0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
  46.219 +        0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
  46.220 +        0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
  46.221 +        0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
  46.222 +        0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
  46.223 +        0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
  46.224 +        0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
  46.225 +        0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
  46.226 +        0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
  46.227 +        0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
  46.228 +        0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
  46.229 +        0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
  46.230 +        0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
  46.231 +        0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
  46.232 +        0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
  46.233 +        0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
  46.234 +        0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
  46.235 +        0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
  46.236 +        0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
  46.237 +        0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
  46.238 +        0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
  46.239 +        0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
  46.240 +        0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
  46.241 +        0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
  46.242 +        0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
  46.243 +        0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
  46.244 +        0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
  46.245 +        0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
  46.246 +        0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
  46.247 +        0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L  },
  46.248 +    {   0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
  46.249 +        0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
  46.250 +        0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
  46.251 +        0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
  46.252 +        0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
  46.253 +        0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
  46.254 +        0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
  46.255 +        0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
  46.256 +        0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
  46.257 +        0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
  46.258 +        0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
  46.259 +        0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
  46.260 +        0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
  46.261 +        0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
  46.262 +        0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
  46.263 +        0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
  46.264 +        0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
  46.265 +        0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
  46.266 +        0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
  46.267 +        0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
  46.268 +        0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
  46.269 +        0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
  46.270 +        0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
  46.271 +        0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
  46.272 +        0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
  46.273 +        0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
  46.274 +        0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
  46.275 +        0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
  46.276 +        0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
  46.277 +        0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
  46.278 +        0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
  46.279 +        0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
  46.280 +        0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
  46.281 +        0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
  46.282 +        0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
  46.283 +        0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
  46.284 +        0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
  46.285 +        0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
  46.286 +        0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
  46.287 +        0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
  46.288 +        0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
  46.289 +        0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
  46.290 +        0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
  46.291 +        0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
  46.292 +        0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
  46.293 +        0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
  46.294 +        0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
  46.295 +        0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
  46.296 +        0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
  46.297 +        0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
  46.298 +        0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
  46.299 +        0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
  46.300 +        0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
  46.301 +        0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
  46.302 +        0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
  46.303 +        0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
  46.304 +        0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
  46.305 +        0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
  46.306 +        0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
  46.307 +        0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
  46.308 +        0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
  46.309 +        0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
  46.310 +        0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
  46.311 +        0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L  }
  46.312 +};
  46.313 +
  46.314 +
  46.315 +static unsigned long F(BLOWFISH_CTX *ctx, unsigned long x) {
  46.316 +   unsigned short a, b, c, d;
  46.317 +   unsigned long  y;
  46.318 +
  46.319 +   d = (unsigned short)(x & 0xFF);
  46.320 +   x >>= 8;
  46.321 +   c = (unsigned short)(x & 0xFF);
  46.322 +   x >>= 8;
  46.323 +   b = (unsigned short)(x & 0xFF);
  46.324 +   x >>= 8;
  46.325 +   a = (unsigned short)(x & 0xFF);
  46.326 +   y = ctx->S[0][a] + ctx->S[1][b];
  46.327 +   y = y ^ ctx->S[2][c];
  46.328 +   y = y + ctx->S[3][d];
  46.329 +
  46.330 +   return y;
  46.331 +}
  46.332 +
  46.333 +
  46.334 +static void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr){
  46.335 +  unsigned long  Xl;
  46.336 +  unsigned long  Xr;
  46.337 +  unsigned long  temp;
  46.338 +  short       i;
  46.339 +
  46.340 +  Xl = *xl;
  46.341 +  Xr = *xr;
  46.342 +
  46.343 +  for (i = 0; i < N; ++i) {
  46.344 +    Xl = Xl ^ ctx->P[i];
  46.345 +    Xr = F(ctx, Xl) ^ Xr;
  46.346 +
  46.347 +    temp = Xl;
  46.348 +    Xl = Xr;
  46.349 +    Xr = temp;
  46.350 +  }
  46.351 +
  46.352 +  temp = Xl;
  46.353 +  Xl = Xr;
  46.354 +  Xr = temp;
  46.355 +
  46.356 +  Xr = Xr ^ ctx->P[N];
  46.357 +  Xl = Xl ^ ctx->P[N + 1];
  46.358 +
  46.359 +  *xl = Xl;
  46.360 +  *xr = Xr;
  46.361 +}
  46.362 +
  46.363 +
  46.364 +static void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr){
  46.365 +  unsigned long  Xl;
  46.366 +  unsigned long  Xr;
  46.367 +  unsigned long  temp;
  46.368 +  short       i;
  46.369 +
  46.370 +  Xl = *xl;
  46.371 +  Xr = *xr;
  46.372 +
  46.373 +  for (i = N + 1; i > 1; --i) {
  46.374 +    Xl = Xl ^ ctx->P[i];
  46.375 +    Xr = F(ctx, Xl) ^ Xr;
  46.376 +
  46.377 +    /* Exchange Xl and Xr */
  46.378 +    temp = Xl;
  46.379 +    Xl = Xr;
  46.380 +    Xr = temp;
  46.381 +  }
  46.382 +
  46.383 +  /* Exchange Xl and Xr */
  46.384 +  temp = Xl;
  46.385 +  Xl = Xr;
  46.386 +  Xr = temp;
  46.387 +
  46.388 +  Xr = Xr ^ ctx->P[1];
  46.389 +  Xl = Xl ^ ctx->P[0];
  46.390 +
  46.391 +  *xl = Xl;
  46.392 +  *xr = Xr;
  46.393 +}
  46.394 +
  46.395 +static void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen) {
  46.396 +  int i, j, k;
  46.397 +  unsigned long data, datal, datar;
  46.398 +
  46.399 +  for (i = 0; i < 4; i++) {
  46.400 +    for (j = 0; j < 256; j++)
  46.401 +      ctx->S[i][j] = ORIG_S[i][j];
  46.402 +  }
  46.403 +
  46.404 +  j = 0;
  46.405 +  for (i = 0; i < N + 2; ++i) {
  46.406 +    data = 0x00000000;
  46.407 +    for (k = 0; k < 4; ++k) {
  46.408 +      data = (data << 8) | key[j];
  46.409 +      j = j + 1;
  46.410 +      if (j >= keyLen)
  46.411 +        j = 0;
  46.412 +    }
  46.413 +    ctx->P[i] = ORIG_P[i] ^ data;
  46.414 +  }
  46.415 +
  46.416 +  datal = 0x00000000;
  46.417 +  datar = 0x00000000;
  46.418 +
  46.419 +  for (i = 0; i < N + 2; i += 2) {
  46.420 +    Blowfish_Encrypt(ctx, &datal, &datar);
  46.421 +    ctx->P[i] = datal;
  46.422 +    ctx->P[i + 1] = datar;
  46.423 +  }
  46.424 +
  46.425 +  for (i = 0; i < 4; ++i) {
  46.426 +    for (j = 0; j < 256; j += 2) {
  46.427 +      Blowfish_Encrypt(ctx, &datal, &datar);
  46.428 +      ctx->S[i][j] = datal;
  46.429 +      ctx->S[i][j + 1] = datar;
  46.430 +    }
  46.431 +  }
  46.432 +}
  46.433 +
  46.434 +static unsigned long long blowfish_test(unsigned long long input)
  46.435 +{
  46.436 +    unsigned long L = input >> 32, R = input;
  46.437 +    BLOWFISH_CTX ctx;
  46.438 +    Blowfish_Init(&ctx, (unsigned char*)"TESTKEY", 7);
  46.439 +    Blowfish_Encrypt(&ctx, &L, &R);
  46.440 +    Blowfish_Decrypt(&ctx, &L, &R);
  46.441 +    return ((unsigned long long)L << 32) | R;
  46.442 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tools/tests/blowfish.mk	Mon Jan 15 15:15:26 2007 -0700
    47.3 @@ -0,0 +1,23 @@
    47.4 +
    47.5 +override XEN_TARGET_ARCH = x86_32
    47.6 +XEN_ROOT = ../..
    47.7 +CFLAGS :=
    47.8 +include $(XEN_ROOT)/tools/Rules.mk
    47.9 +
   47.10 +# Disable PIE/SSP if GCC supports them. They can break us.
   47.11 +CFLAGS  += $(call cc-option,$(CC),-nopie,)
   47.12 +CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector,)
   47.13 +CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector-all,)
   47.14 +
   47.15 +OBJCOPY  = objcopy
   47.16 +CFLAGS  += -fno-builtin -O2 -msoft-float
   47.17 +LDFLAGS  = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0x100000
   47.18 +
   47.19 +.PHONY: all
   47.20 +all: blowfish.bin
   47.21 +
   47.22 +blowfish.bin: blowfish.c
   47.23 +	$(CC) $(CFLAGS) -c blowfish.c
   47.24 +	$(CC) $(CFLAGS) $(LDFLAGS) -o blowfish.tmp blowfish.o
   47.25 +	$(OBJCOPY) -O binary blowfish.tmp blowfish.bin
   47.26 +	rm -f blowfish.tmp
    48.1 --- a/tools/tests/test_x86_emulator.c	Sun Jan 14 22:18:38 2007 -0700
    48.2 +++ b/tools/tests/test_x86_emulator.c	Mon Jan 15 15:15:26 2007 -0700
    48.3 @@ -15,6 +15,10 @@ typedef int64_t            s64;
    48.4  #include <asm-x86/x86_emulate.h>
    48.5  #include <sys/mman.h>
    48.6  
    48.7 +#include "blowfish.h"
    48.8 +
    48.9 +#define MMAP_SZ 16384
   48.10 +
   48.11  /* EFLAGS bit definitions. */
   48.12  #define EFLG_OF (1<<11)
   48.13  #define EFLG_DF (1<<10)
   48.14 @@ -107,16 +111,16 @@ int main(int argc, char **argv)
   48.15      struct x86_emulate_ctxt ctxt;
   48.16      struct cpu_user_regs regs;
   48.17      char *instr;
   48.18 -    unsigned int *res;
   48.19 +    unsigned int *res, i;
   48.20      int rc;
   48.21  #ifndef __x86_64__
   48.22 -    unsigned int i, bcdres_native, bcdres_emul;
   48.23 +    unsigned int bcdres_native, bcdres_emul;
   48.24  #endif
   48.25  
   48.26      ctxt.regs = &regs;
   48.27      ctxt.address_bytes = 4;
   48.28  
   48.29 -    res = mmap((void *)0x100000, 0x1000, PROT_READ|PROT_WRITE,
   48.30 +    res = mmap((void *)0x100000, MMAP_SZ, PROT_READ|PROT_WRITE,
   48.31                 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
   48.32      if ( res == MAP_FAILED )
   48.33      {
   48.34 @@ -482,6 +486,42 @@ int main(int argc, char **argv)
   48.35      printf("skipped\n");
   48.36  #endif
   48.37  
   48.38 +    printf("Testing blowfish code sequence");
   48.39 +    memcpy(res, blowfish_code, sizeof(blowfish_code));
   48.40 +    regs.eax = 2;
   48.41 +    regs.edx = 1;
   48.42 +    regs.eip = (unsigned long)res;
   48.43 +    regs.esp = (unsigned long)res + MMAP_SZ - 4;
   48.44 +    *(uint32_t *)(unsigned long)regs.esp = 0x12345678;
   48.45 +    regs.eflags = 2;
   48.46 +    i = 0;
   48.47 +    while ( (uint32_t)regs.eip != 0x12345678 )
   48.48 +    {
   48.49 +        if ( (i++ & 8191) == 0 )
   48.50 +            printf(".");
   48.51 +        rc = x86_emulate(&ctxt, &emulops);
   48.52 +        if ( rc != 0 )
   48.53 +        {
   48.54 +            printf("failed at %%eip == %08x\n", (unsigned int)regs.eip);
   48.55 +            return 1;
   48.56 +        }
   48.57 +    }
   48.58 +    if ( (regs.esp != ((unsigned long)res + MMAP_SZ)) ||
   48.59 +         (regs.eax != 2) || (regs.edx != 1) )
   48.60 +        goto fail;
   48.61 +    printf("okay\n");
   48.62 +
   48.63 +#ifndef __x86_64__
   48.64 +    printf("%-40s", "Testing blowfish native execution...");    
   48.65 +    asm volatile (
   48.66 +        "movl $0x100000,%%ecx; call *%%ecx"
   48.67 +        : "=a" (regs.eax), "=d" (regs.edx)
   48.68 +        : "0" (2), "1" (1) : "ecx" );
   48.69 +    if ( (regs.eax != 2) || (regs.edx != 1) )
   48.70 +        goto fail;
   48.71 +    printf("okay\n");
   48.72 +#endif    
   48.73 +
   48.74      return 0;
   48.75  
   48.76   fail:
    49.1 --- a/tools/xenstat/xentop/xentop.c	Sun Jan 14 22:18:38 2007 -0700
    49.2 +++ b/tools/xenstat/xentop/xentop.c	Mon Jan 15 15:15:26 2007 -0700
    49.3 @@ -1067,9 +1067,9 @@ int main(int argc, char **argv)
    49.4  				gettimeofday(&curtime, NULL);
    49.5  				top();
    49.6  				oldtime = curtime;
    49.7 -				sleep(delay);
    49.8  				if ((!loop) && !(--iterations))
    49.9  					break;
   49.10 +				sleep(delay);
   49.11  			} while (1);
   49.12  	}
   49.13  
    50.1 --- a/tools/xm-test/README	Sun Jan 14 22:18:38 2007 -0700
    50.2 +++ b/tools/xm-test/README	Mon Jan 15 15:15:26 2007 -0700
    50.3 @@ -207,6 +207,49 @@ dedicated machine.  As such, the library
    50.4  running DomUs on the system to provide each test with a "clean slate".
    50.5  
    50.6  
    50.7 +Testing the XML-RPC and Xen-API interfaces of xend
    50.8 +==================================================
    50.9 +
   50.10 +The xm-test suite can be used to test xm's interface with xend using
   50.11 +either XML-RPC or the Xen-API. In order to use either one of these modes,
   50.12 +xm needs to be configured using its configuration file
   50.13 +'/etc/xen/xm-config.xml'.
   50.14 +Note: The current default configuration after a fresh install of the xen
   50.15 +sources currently is to use the XML-RPC interface for communication with xend.
   50.16 +
   50.17 +Example content for the xm-config.xml for using the Xen-API looks as
   50.18 +follows:
   50.19 +
   50.20 +<xm>
   50.21 +  <server type='Xen-API'
   50.22 +          uri='http://localhost:9363/'
   50.23 +          username='me'
   50.24 +          password='mypassword' />
   50.25 +</xm>
   50.26 +
   50.27 +This configuration makes xm talk to xend using port 9363. For this to
   50.28 +work, also xend needs to be configured to listen to port 9363. Therefore
   50.29 +The following line must be in /etc/xen/xend-config.sxp.
   50.30 +
   50.31 +(xen-api-server (( 127.0.0.1:9363 none )))
   50.32 +
   50.33 +To communicate via the legacy XML-RPC interface, the file
   50.34 +'/etc/xen/xm-config.xml' may simply have the following content or
   50.35 +may be complete remove from the /etc/xen directory.
   50.36 +
   50.37 +<xm>
   50.38 +</xm>
   50.39 +
   50.40 +A few tests have been written for the xm-test suite that test the
   50.41 +Xen-API interface directly without relying on 'xm'. These tests can be
   50.42 +found in the grouptest 'xapi' and for them to work properly, xm must have
   50.43 +been configured to use the Xen-API following the instructions above. To
   50.44 +run these test, the following command line can be invoked:
   50.45 +
   50.46 +   # ./runtest.sh -g xapi <logfile>
   50.47 +
   50.48 +
   50.49 +
   50.50  Extending
   50.51  =========
   50.52  
    51.1 --- a/tools/xm-test/configure.ac	Sun Jan 14 22:18:38 2007 -0700
    51.2 +++ b/tools/xm-test/configure.ac	Mon Jan 15 15:15:26 2007 -0700
    51.3 @@ -150,6 +150,7 @@ AC_CONFIG_FILES([
    51.4      tests/vcpu-pin/Makefile
    51.5      tests/vcpu-disable/Makefile
    51.6      tests/vtpm/Makefile
    51.7 +    tests/xapi/Makefile
    51.8      tests/enforce_dom0_cpus/Makefile
    51.9      lib/XmTestReport/xmtest.py
   51.10      lib/XmTestLib/config.py
    52.1 --- a/tools/xm-test/grouptest/xapi	Sun Jan 14 22:18:38 2007 -0700
    52.2 +++ b/tools/xm-test/grouptest/xapi	Mon Jan 15 15:15:26 2007 -0700
    52.3 @@ -1,1 +1,2 @@
    52.4 +xapi
    52.5  vtpm 09_vtpm-xapi.test
    53.1 --- a/tools/xm-test/lib/XmTestLib/DomainTracking.py	Sun Jan 14 22:18:38 2007 -0700
    53.2 +++ b/tools/xm-test/lib/XmTestLib/DomainTracking.py	Mon Jan 15 15:15:26 2007 -0700
    53.3 @@ -20,9 +20,11 @@
    53.4  
    53.5  import atexit
    53.6  import Test
    53.7 +import xapi
    53.8  
    53.9  # Tracking of managed domains
   53.10  _managedDomains = []
   53.11 +_VMuuids = []
   53.12  registered = 0
   53.13  
   53.14  def addManagedDomain(name):
   53.15 @@ -36,8 +38,24 @@ def delManagedDomain(name):
   53.16      if name in _managedDomains:
   53.17          del _managedDomains[_managedDomains.index(name)]
   53.18  
   53.19 +def addXAPIDomain(uuid):
   53.20 +    global registered
   53.21 +    _VMuuids.append(uuid)
   53.22 +    if not registered:
   53.23 +        atexit.register(destroyManagedDomains)
   53.24 +        registered = 1
   53.25 +
   53.26 +def delXAPIDomain(uuid):
   53.27 +    _VMuuids.remove(uuid)
   53.28 +
   53.29  def destroyManagedDomains():
   53.30      if len(_managedDomains) > 0:
   53.31          for m in _managedDomains:
   53.32              Test.traceCommand("xm destroy %s" % m)
   53.33              Test.traceCommand("xm delete %s" % m)
   53.34 +    if len(_VMuuids) > 0:
   53.35 +        for uuid in _VMuuids:
   53.36 +            Test.traceCommand("xm destroy %s" % uuid)
   53.37 +            Test.traceCommand("xm delete %s" % uuid)
   53.38 +
   53.39 +
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py	Mon Jan 15 15:15:26 2007 -0700
    54.3 @@ -0,0 +1,176 @@
    54.4 +#!/usr/bin/python
    54.5 +"""
    54.6 + Copyright (C) International Business Machines Corp., 2005
    54.7 + Author: Stefan Berger <stefanb@us.ibm.com>
    54.8 +
    54.9 + Based on XenDomain.py by Dan Smith <danms@us.ibm.com>
   54.10 +
   54.11 + This program is free software; you can redistribute it and/or modify
   54.12 + it under the terms of the GNU General Public License as published by
   54.13 + the Free Software Foundation; under version 2 of the License.
   54.14 +
   54.15 + This program is distributed in the hope that it will be useful,
   54.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   54.18 + GNU General Public License for more details.
   54.19 +
   54.20 + You should have received a copy of the GNU General Public License
   54.21 + along with this program; if not, write to the Free Software
   54.22 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   54.23 +
   54.24 +"""
   54.25 +import os
   54.26 +import sys
   54.27 +from XmTestLib import *
   54.28 +from xen.util.xmlrpclib2 import ServerProxy
   54.29 +from types import DictType
   54.30 +
   54.31 +
   54.32 +class XenAPIConfig:
   54.33 +    """An object to help create a VM configuration usable via Xen-API"""
   54.34 +    def __init__(self):
   54.35 +        self.opts = {}
   54.36 +        #Array to translate old option to new ones
   54.37 +        self.opttrlate = { 'name' : 'name_label' ,
   54.38 +                           'memory' : [ 'memory_static_max' ,
   54.39 +                                        'memory_static_min' ,
   54.40 +                                        'memory_dynamic_min',
   54.41 +                                        'memory_dynamic_max' ],
   54.42 +                           'kernel' : 'PV_kernel',
   54.43 +                           'ramdisk': 'PV_ramdisk',
   54.44 +                           'root'   : 'PV_args'}
   54.45 +
   54.46 +    def setOpt(self, name, value):
   54.47 +        """Set an option in the config"""
   54.48 +        if name in self.opttrlate.keys():
   54.49 +            _name = self.opttrlate[name]
   54.50 +        else:
   54.51 +            _name = name
   54.52 +
   54.53 +        if isinstance(_name, list):
   54.54 +            for _n in _name:
   54.55 +                self.opts[_n] = value
   54.56 +        else:
   54.57 +            self.opts[_name] = value
   54.58 +
   54.59 +    def getOpt(self, name):
   54.60 +        """Return the value of a config option"""
   54.61 +        if name in self.opts.keys():
   54.62 +            return self.opts[name]
   54.63 +        else:
   54.64 +            return None
   54.65 +
   54.66 +    def setOpts(self, opts):
   54.67 +        """Batch-set options from a dictionary"""
   54.68 +        for k, v in opts.items():
   54.69 +            self.setOpt(k, v)
   54.70 +
   54.71 +    def getOpts(self):
   54.72 +        return self.opts
   54.73 +
   54.74 +
   54.75 +class XenAPIDomain(XenDomain):
   54.76 +
   54.77 +    def __init__(self, name=None, config=None):
   54.78 +        if name:
   54.79 +            self.name = name
   54.80 +        else:
   54.81 +            self.name = getUniqueName()
   54.82 +
   54.83 +        self.config = config
   54.84 +        self.console = None
   54.85 +        self.netEnv = "bridge"
   54.86 +
   54.87 +        self.session = xapi.connect()
   54.88 +        session = self.session
   54.89 +        try:
   54.90 +            self.vm_uuid = session.xenapi.VM.create(self.config.getOpts())
   54.91 +            addXAPIDomain(self.vm_uuid)
   54.92 +        except:
   54.93 +            raise DomainError("Could not create VM config file for "
   54.94 +                              "managed domain.")
   54.95 +
   54.96 +        #Only support PV for now.
   54.97 +        self.type = "PV"
   54.98 +
   54.99 +    def start(self, noConsole=False, startpaused=False):
  54.100 +        #start the VM
  54.101 +        session = self.session
  54.102 +        if self.vm_uuid:
  54.103 +            try:
  54.104 +                session.xenapi.VM.start(self.vm_uuid, startpaused)
  54.105 +            except:
  54.106 +                raise DomainError("Could not start domain")
  54.107 +        else:
  54.108 +            raise DomainError("VM has no UUID - does VM config exist?")
  54.109 +
  54.110 +        if startpaused:
  54.111 +           return
  54.112 +
  54.113 +        if self.getDomainType() == "HVM":
  54.114 +           waitForBoot()
  54.115 +
  54.116 +        if self.console and noConsole == True:
  54.117 +            self.closeConsole()
  54.118 +
  54.119 +        elif self.console and noConsole == False:
  54.120 +            return self.console
  54.121 +
  54.122 +        elif not self.console and noConsole == False:
  54.123 +            return self.getConsole()
  54.124 +
  54.125 +    def stop(self):
  54.126 +        if self.vm_uuid:
  54.127 +            self.session.xenapi.VM.hard_shutdown(self.vm_uuid)
  54.128 +        else:
  54.129 +            raise DomainError("VM has no UUID - does VM config exist?")
  54.130 +
  54.131 +    def destroy(self):
  54.132 +        #Stop VM first.
  54.133 +        self.stop()
  54.134 +        if self.vm_uuid:
  54.135 +            self.session.xenapi.VM.destroy(self.vm_uuid)
  54.136 +            delXAPIDomain(self.vm_uuid)
  54.137 +        else:
  54.138 +            raise DomainError("VM has no UUID - does VM config exist?")
  54.139 +
  54.140 +    def get_uuid(self):
  54.141 +        return self.vm_uuid
  54.142 +
  54.143 +    def newDevice(self, Device, *args):
  54.144 +        raise DomainError("No support for newDevice().")
  54.145 +
  54.146 +    def removeDevice(self, id):
  54.147 +        raise DomainError("No support for removeDevice().")
  54.148 +
  54.149 +    def removeAllDevices(self, id):
  54.150 +        raise DomainError("No support for removeAllDevices().")
  54.151 +
  54.152 +    def isRunning(self):
  54.153 +        return isDomainRunning(self.name)
  54.154 +
  54.155 +    def getDevice(self, id):
  54.156 +        raise DomainError("No support for getDevice().")
  54.157 +
  54.158 +
  54.159 +class XmTestAPIDomain(XenAPIDomain):
  54.160 +
  54.161 +    """Create a new managed xm-test domain
  54.162 +    @param name: The requested domain name
  54.163 +    @param extraConfig: Additional configuration options
  54.164 +    @param baseConfig: The initial configuration defaults to use
  54.165 +    """
  54.166 +    def __init__(self, name=None, extraConfig=None,
  54.167 +                 baseConfig=arch.configDefaults):
  54.168 +        config = XenAPIConfig()
  54.169 +        config.setOpts(baseConfig)
  54.170 +        if extraConfig:
  54.171 +            config.setOpts(extraConfig)
  54.172 +
  54.173 +        if name:
  54.174 +            config.setOpt("name_label", name)
  54.175 +        elif not config.getOpt("name_label"):
  54.176 +            config.setOpt("name_label", getUniqueName())
  54.177 +
  54.178 +        XenAPIDomain.__init__(self, config.getOpt("name_label"),
  54.179 +                              config=config)
    55.1 --- a/tools/xm-test/lib/XmTestLib/XenManagedDomain.py	Sun Jan 14 22:18:38 2007 -0700
    55.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.3 @@ -1,177 +0,0 @@
    55.4 -#!/usr/bin/python
    55.5 -"""
    55.6 - Copyright (C) International Business Machines Corp., 2005
    55.7 - Author: Stefan Berger <stefanb@us.ibm.com>
    55.8 -
    55.9 - Based on XenDomain.py by Dan Smith <danms@us.ibm.com>
   55.10 -
   55.11 - This program is free software; you can redistribute it and/or modify
   55.12 - it under the terms of the GNU General Public License as published by
   55.13 - the Free Software Foundation; under version 2 of the License.
   55.14 -
   55.15 - This program is distributed in the hope that it will be useful,
   55.16 - but WITHOUT ANY WARRANTY; without even the implied warranty of
   55.17 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   55.18 - GNU General Public License for more details.
   55.19 -
   55.20 - You should have received a copy of the GNU General Public License
   55.21 - along with this program; if not, write to the Free Software
   55.22 - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   55.23 -
   55.24 -"""
   55.25 -import os
   55.26 -import sys
   55.27 -from XmTestLib import *
   55.28 -from xen.util.xmlrpclib2 import ServerProxy
   55.29 -from types import DictType
   55.30 -
   55.31 -
   55.32 -class XenManagedConfig:
   55.33 -    """An object to help create a VM configuration usable via Xen-API"""
   55.34 -    def __init__(self):
   55.35 -        self.opts = {}
   55.36 -        #Array to translate old option to new ones
   55.37 -        self.opttrlate = { 'name' : 'name_label' ,
   55.38 -                           'memory' : [ 'memory_static_max' ,
   55.39 -                                        'memory_static_min' ,
   55.40 -                                        'memory_dynamic_min',
   55.41 -                                        'memory_dynamic_max' ],
   55.42 -                           'kernel' : 'kernel_kernel',
   55.43 -                           'ramdisk': 'kernel_initrd',
   55.44 -                           'root'   : 'kernel_args'}
   55.45 -
   55.46 -    def setOpt(self, name, value):
   55.47 -        """Set an option in the config"""
   55.48 -        if name in self.opttrlate.keys():
   55.49 -            _name = self.opttrlate[name]
   55.50 -        else:
   55.51 -            _name = name
   55.52 -
   55.53 -        if isinstance(_name, list):
   55.54 -            for _n in _name:
   55.55 -                self.opts[_n] = value
   55.56 -        else:
   55.57 -            self.opts[_name] = value
   55.58 -
   55.59 -    def getOpt(self, name):
   55.60 -        """Return the value of a config option"""
   55.61 -        if name in self.opts.keys():
   55.62 -            return self.opts[name]
   55.63 -        else:
   55.64 -            return None
   55.65 -
   55.66 -    def setOpts(self, opts):
   55.67 -        """Batch-set options from a dictionary"""
   55.68 -        for k, v in opts.items():
   55.69 -            self.setOpt(k, v)
   55.70 -
   55.71 -    def getOpts(self):
   55.72 -        return self.opts
   55.73 -
   55.74 -
   55.75 -class XenManagedDomain(XenDomain):
   55.76 -
   55.77 -    def __init__(self, name=None, config=None):
   55.78 -        if name:
   55.79 -            self.name = name
   55.80 -        else:
   55.81 -            self.name = getUniqueName()
   55.82 -
   55.83 -        self.config = config
   55.84 -        self.console = None
   55.85 -        self.netEnv = "bridge"
   55.86 -
   55.87 -        self.server, self.session = xapi._connect()
   55.88 -        server = self.server
   55.89 -        try:
   55.90 -            self.vm_uuid = xapi.execute(server.VM.create, self.session,
   55.91 -                                        self.config.getOpts())
   55.92 -            xapi._VMuuids.append(self.vm_uuid)
   55.93 -        except:
   55.94 -            raise DomainError("Could not create VM config file for "
   55.95 -                              "managed domain.")
   55.96 -
   55.97 -        #Only support PV for now.
   55.98 -        self.type = "PV"
   55.99 -
  55.100 -    def start(self, noConsole=False, startpaused=False):
  55.101 -        #start the VM
  55.102 -        server = self.server
  55.103 -        if self.vm_uuid:
  55.104 -            try:
  55.105 -                xapi.execute(server.VM.start, self.session, self.vm_uuid,
  55.106 -                             startpaused)
  55.107 -            except:
  55.108 -                raise DomainError("Could not start domain")
  55.109 -        else:
  55.110 -            raise DomainError("VM has not UUID - VM config does not exist?")
  55.111 -
  55.112 -        if self.getDomainType() == "HVM":
  55.113 -           waitForBoot()
  55.114 -
  55.115 -        if self.console and noConsole == True:
  55.116 -            self.closeConsole()
  55.117 -
  55.118 -        elif self.console and noConsole == False:
  55.119 -            return self.console
  55.120 -
  55.121 -        elif not self.console and noConsole == False:
  55.122 -            return self.getConsole()
  55.123 -
  55.124 -    def stop(self):
  55.125 -        if self.vm_uuid:
  55.126 -            server = self.server
  55.127 -            xapi.execute(server.VM.hard_shutdown, self.session, self.vm_uuid)
  55.128 -        else:
  55.129 -            raise DomainError("VM has not UUID - VM config does not exist?")
  55.130 -
  55.131 -    def destroy(self):
  55.132 -        #Stop VM first.
  55.133 -        self.stop()
  55.134 -        if self.vm_uuid:
  55.135 -            server = self.server
  55.136 -            xapi.execute(server.VM.destroy, self.session, self.vm_uuid)
  55.137 -            xapi._VMuuids.remove(self.vm_uuid)
  55.138 -        else:
  55.139 -            raise DomainError("VM has not UUID - VM config does not exist?")
  55.140 -
  55.141 -    def get_uuid(self):
  55.142 -        return self.vm_uuid
  55.143 -
  55.144 -    def newDevice(self, Device, *args):
  55.145 -        raise DomainError("No support for newDevice().")
  55.146 -
  55.147 -    def removeDevice(self, id):
  55.148 -        raise DomainError("No support for removeDevice().")
  55.149 -
  55.150 -    def removeAllDevices(self, id):
  55.151 -        raise DomainError("No support for removeAllDevices().")
  55.152 -
  55.153 -    def isRunning(self):
  55.154 -        return isDomainRunning(self.name)
  55.155 -
  55.156 -    def getDevice(self, id):
  55.157 -        raise DomainError("No support for getDevice().")
  55.158 -
  55.159 -
  55.160 -class XmTestManagedDomain(XenManagedDomain):
  55.161 -
  55.162 -    """Create a new managed xm-test domain
  55.163 -    @param name: The requested domain name
  55.164 -    @param extraConfig: Additional configuration options
  55.165 -    @param baseConfig: The initial configuration defaults to use
  55.166 -    """
  55.167 -    def __init__(self, name=None, extraConfig=None,
  55.168 -                 baseConfig=arch.configDefaults):
  55.169 -        config = XenManagedConfig()
  55.170 -        config.setOpts(baseConfig)
  55.171 -        if extraConfig:
  55.172 -            config.setOpts(extraConfig)
  55.173 -
  55.174 -        if name:
  55.175 -            config.setOpt("name_label", name)
  55.176 -        elif not config.getOpt("name_label"):
  55.177 -            config.setOpt("name_label", getUniqueName())
  55.178 -
  55.179 -        XenManagedDomain.__init__(self, config.getOpt("name_label"),
  55.180 -                                  config=config)
    56.1 --- a/tools/xm-test/lib/XmTestLib/Xm.py	Sun Jan 14 22:18:38 2007 -0700
    56.2 +++ b/tools/xm-test/lib/XmTestLib/Xm.py	Mon Jan 15 15:15:26 2007 -0700
    56.3 @@ -49,6 +49,8 @@ def domid(name):
    56.4  
    56.5      if status != 0 or "Traceback" in output:
    56.6          return -1
    56.7 +    if output == "None":
    56.8 +        return -1
    56.9      try:
   56.10          return int(output)
   56.11      except:
    57.1 --- a/tools/xm-test/lib/XmTestLib/xapi.py	Sun Jan 14 22:18:38 2007 -0700
    57.2 +++ b/tools/xm-test/lib/XmTestLib/xapi.py	Mon Jan 15 15:15:26 2007 -0700
    57.3 @@ -17,50 +17,49 @@
    57.4  # Copyright (C) 2006 IBM Corporation
    57.5  #============================================================================
    57.6  
    57.7 +import atexit
    57.8  import os
    57.9  import sys
   57.10  from XmTestLib import *
   57.11 -from xen.util.xmlrpclib2 import ServerProxy
   57.12 +from xen.xm import main as xmmain
   57.13 +from xen.xm import XenAPI
   57.14 +from xen.xm.opts import OptionError
   57.15  from types import DictType
   57.16 -
   57.17 -
   57.18 -XAPI_DEFAULT_LOGIN = " "
   57.19 -XAPI_DEFAULT_PASSWORD = " "
   57.20 -
   57.21 -class XenAPIError(Exception):
   57.22 -    pass
   57.23 -
   57.24 +import xml.dom.minidom
   57.25  
   57.26 -#A list of VMs' UUIDs that were created using vm_create
   57.27 -_VMuuids = []
   57.28 +def get_login_pwd():
   57.29 +    if xmmain.serverType == xmmain.SERVER_XEN_API:
   57.30 +        try:
   57.31 +            login, password = xmmain.parseAuthentication()
   57.32 +            return (login, password)
   57.33 +        except:
   57.34 +            raise OptionError("Configuration for login/pwd not found. "
   57.35 +                              "Need to run xapi-setup.py?")
   57.36 +    raise OptionError("Xm configuration file not using Xen-API for "
   57.37 +                      "communication with xend.")
   57.38  
   57.39 -#Terminate previously created managed(!) VMs and destroy their configs
   57.40 -def vm_destroy_all():
   57.41 -    server, session = _connect()
   57.42 -    for uuid in _VMuuids:
   57.43 -        execute(server.VM.hard_shutdown, session, uuid)
   57.44 -        execute(server.VM.destroy      , session, uuid)
   57.45 -
   57.46 +sessions=[]
   57.47  
   57.48 -def execute(fn, *args):
   57.49 -    result = fn(*args)
   57.50 -    if type(result) != DictType:
   57.51 -        raise TypeError("Function returned object of type: %s" %
   57.52 -                        str(type(result)))
   57.53 -    if 'Value' not in result:
   57.54 -        raise XenAPIError(*result['ErrorDescription'])
   57.55 -    return result['Value']
   57.56 -
   57.57 -_initialised = False
   57.58 -_server = None
   57.59 -_session = None
   57.60 -def _connect(*args):
   57.61 -    global _server, _session, _initialised
   57.62 -    if not _initialised:
   57.63 -        _server = ServerProxy('httpu:///var/run/xend/xen-api.sock')
   57.64 -        login = XAPI_DEFAULT_LOGIN
   57.65 -        password = XAPI_DEFAULT_PASSWORD
   57.66 -        creds = (login, password)
   57.67 -        _session = execute(_server.session.login_with_password, *creds)
   57.68 -        _initialised = True
   57.69 -    return (_server, _session)
   57.70 +def connect(*args):
   57.71 +    try:
   57.72 +        creds = get_login_pwd()
   57.73 +    except Exception, e:
   57.74 +        FAIL("%s" % str(e))
   57.75 +    try:
   57.76 +        session = XenAPI.Session(xmmain.serverURI)
   57.77 +    except:
   57.78 +        raise OptionError("Could not create XenAPI session with Xend." \
   57.79 +                          "URI=%s" % xmmain.serverURI)
   57.80 +    try:
   57.81 +        session.login_with_password(*creds)
   57.82 +    except:
   57.83 +        raise OptionError("Could not login to Xend. URI=%s" % xmmain.serverURI)
   57.84 +    def logout():
   57.85 +        try:
   57.86 +            for s in sessions:
   57.87 +                s.xenapi.session.logout()
   57.88 +        except:
   57.89 +            pass
   57.90 +    sessions.append(session)
   57.91 +    atexit.register(logout)
   57.92 +    return session
    58.1 --- a/tools/xm-test/runtest.sh	Sun Jan 14 22:18:38 2007 -0700
    58.2 +++ b/tools/xm-test/runtest.sh	Mon Jan 15 15:15:26 2007 -0700
    58.3 @@ -16,6 +16,7 @@ usage() {
    58.4      echo "  -r <url>    : url of test results repository to use"
    58.5      echo "  -s <report> : just submit report <report>"
    58.6      echo "  -u          : unsafe -- do not run the sanity checks before starting"
    58.7 +    echo "  -md         : all created domains are xend-'managed' domains"
    58.8      echo "  -h | --help : show this help"
    58.9  }
   58.10  
   58.11 @@ -218,11 +219,14 @@ run=yes
   58.12  unsafe=no
   58.13  GROUPENTERED=default
   58.14  
   58.15 +#Prepare for usage with ACM
   58.16  if [ -d /etc/xen/acm-security/policies ]; then
   58.17  	cp -f tests/security-acm/xm-test-security_policy.xml \
   58.18  	      /etc/xen/acm-security/policies
   58.19  fi
   58.20  
   58.21 +unset XM_MANAGED_DOMAINS
   58.22 +
   58.23  # Resolve options
   58.24  while [ $# -gt 0 ]
   58.25    do
   58.26 @@ -260,6 +264,10 @@ while [ $# -gt 0 ]
   58.27  	  unsafe=yes
   58.28  	  report=no
   58.29  	  ;;
   58.30 +      -md)
   58.31 +          echo "(use managed domains)"
   58.32 +          export XM_MANAGED_DOMAINS=1
   58.33 +          ;;
   58.34        -h|--help)
   58.35            usage
   58.36            exit 0
    59.1 --- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py	Sun Jan 14 22:18:38 2007 -0700
    59.2 +++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py	Mon Jan 15 15:15:26 2007 -0700
    59.3 @@ -6,71 +6,66 @@
    59.4  # Test to test the vtpm class through the Xen-API
    59.5  
    59.6  from XmTestLib import xapi
    59.7 -from XmTestLib.XenManagedDomain import XmTestManagedDomain
    59.8 +from XmTestLib.XenAPIDomain import XmTestAPIDomain
    59.9  from XmTestLib import *
   59.10  from vtpm_utils import *
   59.11  import commands
   59.12  import os
   59.13  
   59.14 -def do_test():
   59.15 -    domain = XmTestManagedDomain()
   59.16 -    vm_uuid = domain.get_uuid()
   59.17 -
   59.18 -    vtpmcfg = {}
   59.19 -    vtpmcfg['type'] = "paravirtualised"
   59.20 -    vtpmcfg['backend'] = "Domain-0"
   59.21 -    vtpmcfg['instance'] = 1
   59.22 -    vtpmcfg['VM'] = vm_uuid
   59.23 -
   59.24 -    server, session = xapi._connect()
   59.25 +try:
   59.26 +    # XmTestAPIDomain tries to establish a connection to XenD
   59.27 +    domain = XmTestAPIDomain()
   59.28 +except Exception, e:
   59.29 +    SKIP("Skipping test. Error: %s" % str(e))
   59.30 +vm_uuid = domain.get_uuid()
   59.31  
   59.32 -    vtpm_uuid = xapi.execute(server.VTPM.create, session, vtpmcfg)
   59.33 +vtpmcfg = {}
   59.34 +vtpmcfg['type'] = "paravirtualised"
   59.35 +vtpmcfg['backend'] = "Domain-0"
   59.36 +vtpmcfg['instance'] = 1
   59.37 +vtpmcfg['VM'] = vm_uuid
   59.38  
   59.39 -    vtpm_id = xapi.execute(server.VTPM.get_instance, session, vtpm_uuid)
   59.40 -    vtpm_be = xapi.execute(server.VTPM.get_backend , session, vtpm_uuid)
   59.41 -    if vtpm_be != vtpmcfg['backend']:
   59.42 -        FAIL("vTPM's backend is in '%s', expected: '%s'" %
   59.43 -             (vtpm_be, vtpmcfg['backend']))
   59.44 +session = xapi.connect()
   59.45  
   59.46 -    driver = xapi.execute(server.VTPM.get_driver, session, vtpm_uuid)
   59.47 -    if driver != vtpmcfg['type']:
   59.48 -        FAIL("vTPM has driver type '%s', expected: '%s'" %
   59.49 -             (driver, vtpmcfg['type']))
   59.50 -
   59.51 -    vtpm_rec = xapi.execute(server.VTPM.get_record, session, vtpm_uuid)
   59.52 +vtpm_uuid = session.xenapi.VTPM.create(vtpmcfg)
   59.53  
   59.54 -    if vtpm_rec['driver']  != vtpmcfg['type']:
   59.55 -        FAIL("vTPM record shows driver type '%s', expected: '%s'" %
   59.56 -             (vtpm_rec['driver'], vtpmcfg['type']))
   59.57 -    if vtpm_rec['uuid']  != vtpm_uuid:
   59.58 -        FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
   59.59 -             (vtpm_rec['uuid'], vtpm_uuid))
   59.60 -    if vtpm_rec['VM']  != vm_uuid:
   59.61 -        FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
   59.62 -             (vtpm_rec['VM'], vm_uuid))
   59.63 +vtpm_id = session.xenapi.VTPM.get_instance(vtpm_uuid)
   59.64 +vtpm_be = session.xenapi.VTPM.get_backend(vtpm_uuid)
   59.65 +if vtpm_be != vtpmcfg['backend']:
   59.66 +    FAIL("vTPM's backend is in '%s', expected: '%s'" %
   59.67 +         (vtpm_be, vtpmcfg['backend']))
   59.68  
   59.69 -    success = domain.start()
   59.70 +driver = session.xenapi.VTPM.get_driver(vtpm_uuid)
   59.71 +if driver != vtpmcfg['type']:
   59.72 +    FAIL("vTPM has driver type '%s', expected: '%s'" %
   59.73 +         (driver, vtpmcfg['type']))
   59.74  
   59.75 -    console = domain.getConsole()
   59.76 +vtpm_rec = session.xenapi.VTPM.get_record(vtpm_uuid)
   59.77  
   59.78 -    try:
   59.79 -        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   59.80 -    except ConsoleError, e:
   59.81 -        saveLog(console.getHistory())
   59.82 -        vtpm_cleanup(domName)
   59.83 -        FAIL("No result from dumping the PCRs")
   59.84 +if vtpm_rec['driver']  != vtpmcfg['type']:
   59.85 +    FAIL("vTPM record shows driver type '%s', expected: '%s'" %
   59.86 +         (vtpm_rec['driver'], vtpmcfg['type']))
   59.87 +if vtpm_rec['uuid']  != vtpm_uuid:
   59.88 +    FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
   59.89 +         (vtpm_rec['uuid'], vtpm_uuid))
   59.90 +if vtpm_rec['VM']  != vm_uuid:
   59.91 +    FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
   59.92 +         (vtpm_rec['VM'], vm_uuid))
   59.93  
   59.94 -    if re.search("No such file",run["output"]):
   59.95 -        vtpm_cleanup(domName)
   59.96 -        FAIL("TPM frontend support not compiled into (domU?) kernel")
   59.97 +success = domain.start()
   59.98  
   59.99 -    domain.stop()
  59.100 -    domain.destroy()
  59.101 -
  59.102 -
  59.103 +console = domain.getConsole()
  59.104  
  59.105  try:
  59.106 -    do_test()
  59.107 -finally:
  59.108 -    #Make sure all domains are gone that were created in this test case
  59.109 -    xapi.vm_destroy_all()
  59.110 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  59.111 +except ConsoleError, e:
  59.112 +    saveLog(console.getHistory())
  59.113 +    vtpm_cleanup(domName)
  59.114 +    FAIL("No result from dumping the PCRs")
  59.115 +
  59.116 +if re.search("No such file",run["output"]):
  59.117 +    vtpm_cleanup(domName)
  59.118 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
  59.119 +
  59.120 +domain.stop()
  59.121 +domain.destroy()
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/tools/xm-test/tests/xapi/01_xapi-vm_basic.py	Mon Jan 15 15:15:26 2007 -0700
    60.3 @@ -0,0 +1,61 @@
    60.4 +#!/usr/bin/python
    60.5 +
    60.6 +# Copyright (C) International Business Machines Corp., 2006
    60.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    60.8 +
    60.9 +# Basic VM creation test
   60.10 +
   60.11 +from XmTestLib import xapi
   60.12 +from XmTestLib.XenAPIDomain import XmTestAPIDomain
   60.13 +from XmTestLib import *
   60.14 +from xen.xend import XendAPIConstants
   60.15 +import commands
   60.16 +import os
   60.17 +
   60.18 +try:
   60.19 +    # XmTestAPIDomain tries to establish a connection to XenD
   60.20 +    domain = XmTestAPIDomain()
   60.21 +except Exception, e:
   60.22 +    SKIP("Skipping test. Error: %s" % str(e))
   60.23 +vm_uuid = domain.get_uuid()
   60.24 +
   60.25 +session = xapi.connect()
   60.26 +
   60.27 +domain.start(startpaused=True)
   60.28 +
   60.29 +res = session.xenapi.VM.get_power_state(vm_uuid)
   60.30 +
   60.31 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_PAUSED]:
   60.32 +    FAIL("VM was not started in 'paused' state")
   60.33 +
   60.34 +res = session.xenapi.VM.unpause(vm_uuid)
   60.35 +
   60.36 +res = session.xenapi.VM.get_power_state(vm_uuid)
   60.37 +
   60.38 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_RUNNING]:
   60.39 +    FAIL("VM could not be put into 'running' state")
   60.40 +
   60.41 +console = domain.getConsole()
   60.42 +
   60.43 +try:
   60.44 +    run = console.runCmd("cat /proc/interrupts")
   60.45 +except ConsoleError, e:
   60.46 +    saveLog(console.getHistory())
   60.47 +    FAIL("Could not access proc-filesystem")
   60.48 +
   60.49 +res = session.xenapi.VM.pause(vm_uuid)
   60.50 +
   60.51 +res = session.xenapi.VM.get_power_state(vm_uuid)
   60.52 +
   60.53 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_PAUSED]:
   60.54 +    FAIL("VM could not be put into 'paused' state")
   60.55 +
   60.56 +res = session.xenapi.VM.unpause(vm_uuid)
   60.57 +
   60.58 +res = session.xenapi.VM.get_power_state(vm_uuid)
   60.59 +
   60.60 +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_RUNNING]:
   60.61 +    FAIL("VM could not be 'unpaused'")
   60.62 +
   60.63 +domain.stop()
   60.64 +domain.destroy()
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/tools/xm-test/tests/xapi/Makefile.am	Mon Jan 15 15:15:26 2007 -0700
    61.3 @@ -0,0 +1,19 @@
    61.4 +SUBDIRS =
    61.5 +
    61.6 +TESTS = 01_xapi-vm_basic.test
    61.7 +
    61.8 +XFAIL_TESTS =
    61.9 +
   61.10 +EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) xapi_utils.py
   61.11 +TESTS_ENVIRONMENT=@TENV@
   61.12 +
   61.13 +%.test: %.py
   61.14 +	cp $< $@
   61.15 +	chmod +x $@
   61.16 +
   61.17 +clean-local: am_config_clean-local
   61.18 +
   61.19 +am_config_clean-local:
   61.20 +	rm -f *test
   61.21 +	rm -f *log
   61.22 +	rm -f *~
    62.1 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Sun Jan 14 22:18:38 2007 -0700
    62.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Mon Jan 15 15:15:26 2007 -0700
    62.3 @@ -179,7 +179,7 @@ static int get_hypercall_stubs(void)
    62.4  #define get_hypercall_stubs()	(0)
    62.5  #endif
    62.6  
    62.7 -static int get_callback_irq(struct pci_dev *pdev)
    62.8 +static uint64_t get_callback_via(struct pci_dev *pdev)
    62.9  {
   62.10  #ifdef __ia64__
   62.11  	int irq, rid;
   62.12 @@ -194,16 +194,24 @@ static int get_callback_irq(struct pci_d
   62.13  	       rid);
   62.14  	return rid | IA64_CALLBACK_IRQ_RID;
   62.15  #else /* !__ia64__ */
   62.16 -	return pdev->irq;
   62.17 +	if (pdev->irq < 16)
   62.18 +		return pdev->irq; /* ISA IRQ */
   62.19 +	/* We don't know the GSI. Specify the PCI INTx line instead. */
   62.20 +	return (((uint64_t)0x01 << 56) | /* PCI INTx identifier */
   62.21 +		((uint64_t)pci_domain_nr(pdev->bus) << 32) |
   62.22 +		((uint64_t)pdev->bus->number << 16) |
   62.23 +		((uint64_t)(pdev->devfn & 0xff) << 8) |
   62.24 +		((uint64_t)(pdev->pin - 1) & 3));
   62.25  #endif
   62.26  }
   62.27  
   62.28  static int __devinit platform_pci_init(struct pci_dev *pdev,
   62.29  				       const struct pci_device_id *ent)
   62.30  {
   62.31 -	int i, ret, callback_irq;
   62.32 +	int i, ret;
   62.33  	long ioaddr, iolen;
   62.34  	long mmio_addr, mmio_len;
   62.35 +	uint64_t callback_via;
   62.36  
   62.37  	i = pci_enable_device(pdev);
   62.38  	if (i)
   62.39 @@ -215,9 +223,9 @@ static int __devinit platform_pci_init(s
   62.40  	mmio_addr = pci_resource_start(pdev, 1);
   62.41  	mmio_len = pci_resource_len(pdev, 1);
   62.42  
   62.43 -	callback_irq = get_callback_irq(pdev);
   62.44 +	callback_via = get_callback_via(pdev);
   62.45  
   62.46 -	if (mmio_addr == 0 || ioaddr == 0 || callback_irq == 0) {
   62.47 +	if (mmio_addr == 0 || ioaddr == 0 || callback_via == 0) {
   62.48  		printk(KERN_WARNING DRV_NAME ":no resources found\n");
   62.49  		return -ENOENT;
   62.50  	}
   62.51 @@ -247,12 +255,12 @@ static int __devinit platform_pci_init(s
   62.52  	if ((ret = init_xen_info()))
   62.53  		goto out;
   62.54  
   62.55 -	if ((ret = request_irq(pdev->irq, evtchn_interrupt, SA_SHIRQ,
   62.56 -			       "xen-platform-pci", pdev))) {
   62.57 +	if ((ret = request_irq(pdev->irq, evtchn_interrupt,
   62.58 +			       SA_SHIRQ | SA_SAMPLE_RANDOM,
   62.59 +			       "xen-platform-pci", pdev)))
   62.60  		goto out;
   62.61 -	}
   62.62  
   62.63 -	if ((ret = set_callback_irq(callback_irq)))
   62.64 +	if ((ret = set_callback_via(callback_via)))
   62.65  		goto out;
   62.66  
   62.67   out:
   62.68 @@ -302,7 +310,7 @@ static void __exit platform_pci_module_c
   62.69  {
   62.70  	printk(KERN_INFO DRV_NAME ":Do platform module cleanup\n");
   62.71  	/* disable hypervisor for callback irq */
   62.72 -	set_callback_irq(0);
   62.73 +	set_callback_via(0);
   62.74  	if (pci_device_registered)
   62.75  		pci_unregister_driver(&platform_driver);
   62.76  }
    63.1 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h	Sun Jan 14 22:18:38 2007 -0700
    63.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h	Mon Jan 15 15:15:26 2007 -0700
    63.3 @@ -24,13 +24,13 @@
    63.4  #include <linux/interrupt.h>
    63.5  #include <xen/interface/hvm/params.h>
    63.6  
    63.7 -static inline int set_callback_irq(int irq)
    63.8 +static inline int set_callback_via(uint64_t via)
    63.9  {
   63.10  	struct xen_hvm_param a;
   63.11  
   63.12  	a.domid = DOMID_SELF;
   63.13  	a.index = HVM_PARAM_CALLBACK_IRQ;
   63.14 -	a.value = irq;
   63.15 +	a.value = via;
   63.16  	return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
   63.17  }
   63.18  
    64.1 --- a/xen/arch/ia64/linux-xen/unaligned.c	Sun Jan 14 22:18:38 2007 -0700
    64.2 +++ b/xen/arch/ia64/linux-xen/unaligned.c	Mon Jan 15 15:15:26 2007 -0700
    64.3 @@ -24,7 +24,7 @@
    64.4  #include <asm/uaccess.h>
    64.5  #include <asm/unaligned.h>
    64.6  
    64.7 -extern void die_if_kernel(char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
    64.8 +extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
    64.9  
   64.10  #undef DEBUG_UNALIGNED_TRAP
   64.11  
    65.1 --- a/xen/arch/ia64/xen/xenmisc.c	Sun Jan 14 22:18:38 2007 -0700
    65.2 +++ b/xen/arch/ia64/xen/xenmisc.c	Mon Jan 15 15:15:26 2007 -0700
    65.3 @@ -77,7 +77,7 @@ void console_print(char *msg)
    65.4  // called from unaligned.c
    65.5  ////////////////////////////////////
    65.6  
    65.7 -void die_if_kernel(char *str, struct pt_regs *regs, long err) /* __attribute__ ((noreturn)) */
    65.8 +void die_if_kernel(char *str, struct pt_regs *regs, long err)
    65.9  {
   65.10  	if (user_mode(regs))
   65.11  		return;
   65.12 @@ -88,7 +88,7 @@ void die_if_kernel(char *str, struct pt_
   65.13  	domain_crash_synchronous();
   65.14  }
   65.15  
   65.16 -void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err) /* __attribute__ ((noreturn)) */
   65.17 +void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err)
   65.18  {
   65.19  	if (vmx_user_mode(regs))
   65.20  		return;
    66.1 --- a/xen/arch/x86/domain.c	Sun Jan 14 22:18:38 2007 -0700
    66.2 +++ b/xen/arch/x86/domain.c	Mon Jan 15 15:15:26 2007 -0700
    66.3 @@ -1047,7 +1047,7 @@ void context_switch(struct vcpu *prev, s
    66.4  
    66.5      local_irq_disable();
    66.6  
    66.7 -    if ( is_hvm_vcpu(prev) )
    66.8 +    if ( is_hvm_vcpu(prev) && !list_empty(&prev->arch.hvm_vcpu.tm_list) )
    66.9          pt_freeze_time(prev);
   66.10  
   66.11      set_current(next);
    67.1 --- a/xen/arch/x86/hvm/hpet.c	Sun Jan 14 22:18:38 2007 -0700
    67.2 +++ b/xen/arch/x86/hvm/hpet.c	Mon Jan 15 15:15:26 2007 -0700
    67.3 @@ -356,8 +356,6 @@ static void hpet_timer_fn(void *opaque)
    67.4          }
    67.5          set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn]));
    67.6      }
    67.7 -
    67.8 -    vcpu_kick(h->vcpu);    
    67.9  }
   67.10  
   67.11  void hpet_migrate_timers(struct vcpu *v)
    68.1 --- a/xen/arch/x86/hvm/hvm.c	Sun Jan 14 22:18:38 2007 -0700
    68.2 +++ b/xen/arch/x86/hvm/hvm.c	Mon Jan 15 15:15:26 2007 -0700
    68.3 @@ -800,7 +800,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
    68.4                  d->arch.hvm_domain.buffered_io_va = (unsigned long)p;
    68.5                  break;
    68.6              case HVM_PARAM_CALLBACK_IRQ:
    68.7 -                hvm_set_callback_gsi(d, a.value);
    68.8 +                hvm_set_callback_via(d, a.value);
    68.9                  break;
   68.10              }
   68.11              d->arch.hvm_domain.params[a.index] = a.value;
    69.1 --- a/xen/arch/x86/hvm/irq.c	Sun Jan 14 22:18:38 2007 -0700
    69.2 +++ b/xen/arch/x86/hvm/irq.c	Mon Jan 15 15:15:26 2007 -0700
    69.3 @@ -25,7 +25,7 @@
    69.4  #include <xen/sched.h>
    69.5  #include <asm/hvm/domain.h>
    69.6  
    69.7 -void hvm_pci_intx_assert(
    69.8 +static void __hvm_pci_intx_assert(
    69.9      struct domain *d, unsigned int device, unsigned int intx)
   69.10  {
   69.11      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
   69.12 @@ -33,10 +33,8 @@ void hvm_pci_intx_assert(
   69.13  
   69.14      ASSERT((device <= 31) && (intx <= 3));
   69.15  
   69.16 -    spin_lock(&hvm_irq->lock);
   69.17 -
   69.18      if ( __test_and_set_bit(device*4 + intx, &hvm_irq->pci_intx) )
   69.19 -        goto out;
   69.20 +        return;
   69.21  
   69.22      gsi = hvm_pci_intx_gsi(device, intx);
   69.23      if ( hvm_irq->gsi_assert_count[gsi]++ == 0 )
   69.24 @@ -50,12 +48,19 @@ void hvm_pci_intx_assert(
   69.25          vioapic_irq_positive_edge(d, isa_irq);
   69.26          vpic_irq_positive_edge(d, isa_irq);
   69.27      }
   69.28 +}
   69.29  
   69.30 - out:
   69.31 +void hvm_pci_intx_assert(
   69.32 +    struct domain *d, unsigned int device, unsigned int intx)
   69.33 +{
   69.34 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
   69.35 +
   69.36 +    spin_lock(&hvm_irq->lock);
   69.37 +    __hvm_pci_intx_assert(d, device, intx);
   69.38      spin_unlock(&hvm_irq->lock);
   69.39  }
   69.40  
   69.41 -void hvm_pci_intx_deassert(
   69.42 +static void __hvm_pci_intx_deassert(
   69.43      struct domain *d, unsigned int device, unsigned int intx)
   69.44  {
   69.45      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
   69.46 @@ -63,10 +68,8 @@ void hvm_pci_intx_deassert(
   69.47  
   69.48      ASSERT((device <= 31) && (intx <= 3));
   69.49  
   69.50 -    spin_lock(&hvm_irq->lock);
   69.51 -
   69.52      if ( !__test_and_clear_bit(device*4 + intx, &hvm_irq->pci_intx) )
   69.53 -        goto out;
   69.54 +        return;
   69.55  
   69.56      gsi = hvm_pci_intx_gsi(device, intx);
   69.57      --hvm_irq->gsi_assert_count[gsi];
   69.58 @@ -76,8 +79,15 @@ void hvm_pci_intx_deassert(
   69.59      if ( (--hvm_irq->pci_link_assert_count[link] == 0) && isa_irq &&
   69.60           (--hvm_irq->gsi_assert_count[isa_irq] == 0) )
   69.61          vpic_irq_negative_edge(d, isa_irq);
   69.62 +}
   69.63  
   69.64 - out:
   69.65 +void hvm_pci_intx_deassert(
   69.66 +    struct domain *d, unsigned int device, unsigned int intx)
   69.67 +{
   69.68 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
   69.69 +
   69.70 +    spin_lock(&hvm_irq->lock);
   69.71 +    __hvm_pci_intx_deassert(d, device, intx);
   69.72      spin_unlock(&hvm_irq->lock);
   69.73  }
   69.74  
   69.75 @@ -123,37 +133,47 @@ void hvm_set_callback_irq_level(void)
   69.76      struct vcpu *v = current;
   69.77      struct domain *d = v->domain;
   69.78      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
   69.79 -    unsigned int gsi = hvm_irq->callback_gsi;
   69.80 +    unsigned int gsi, pdev, pintx, asserted;
   69.81  
   69.82      /* Fast lock-free tests. */
   69.83 -    if ( (v->vcpu_id != 0) || (gsi == 0) )
   69.84 +    if ( (v->vcpu_id != 0) ||
   69.85 +         (hvm_irq->callback_via_type == HVMIRQ_callback_none) )
   69.86          return;
   69.87  
   69.88      spin_lock(&hvm_irq->lock);
   69.89  
   69.90 -    gsi = hvm_irq->callback_gsi;
   69.91 -    if ( gsi == 0 )
   69.92 +    /* NB. Do not check the evtchn_upcall_mask. It is not used in HVM mode. */
   69.93 +    asserted = !!vcpu_info(v, evtchn_upcall_pending);
   69.94 +    if ( hvm_irq->callback_via_asserted == asserted )
   69.95          goto out;
   69.96 +    hvm_irq->callback_via_asserted = asserted;
   69.97  
   69.98 -    /* NB. Do not check the evtchn_upcall_mask. It is not used in HVM mode. */
   69.99 -    if ( vcpu_info(v, evtchn_upcall_pending) )
  69.100 +    /* Callback status has changed. Update the callback via. */
  69.101 +    switch ( hvm_irq->callback_via_type )
  69.102      {
  69.103 -        if ( !__test_and_set_bit(0, &hvm_irq->callback_irq_wire) &&
  69.104 -             (hvm_irq->gsi_assert_count[gsi]++ == 0) )
  69.105 +    case HVMIRQ_callback_gsi:
  69.106 +        gsi = hvm_irq->callback_via.gsi;
  69.107 +        if ( asserted && (hvm_irq->gsi_assert_count[gsi]++ == 0) )
  69.108          {
  69.109              vioapic_irq_positive_edge(d, gsi);
  69.110              if ( gsi <= 15 )
  69.111                  vpic_irq_positive_edge(d, gsi);
  69.112          }
  69.113 -    }
  69.114 -    else
  69.115 -    {
  69.116 -        if ( __test_and_clear_bit(0, &hvm_irq->callback_irq_wire) &&
  69.117 -             (--hvm_irq->gsi_assert_count[gsi] == 0) )
  69.118 +        else if ( !asserted && (--hvm_irq->gsi_assert_count[gsi] == 0) )
  69.119          {
  69.120              if ( gsi <= 15 )
  69.121                  vpic_irq_negative_edge(d, gsi);
  69.122          }
  69.123 +        break;
  69.124 +    case HVMIRQ_callback_pci_intx:
  69.125 +        pdev  = hvm_irq->callback_via.pci.dev;
  69.126 +        pintx = hvm_irq->callback_via.pci.intx;
  69.127 +        if ( asserted )
  69.128 +            __hvm_pci_intx_assert(d, pdev, pintx);
  69.129 +        else
  69.130 +            __hvm_pci_intx_deassert(d, pdev, pintx);
  69.131 +    default:
  69.132 +        break;
  69.133      }
  69.134  
  69.135   out:
  69.136 @@ -193,40 +213,79 @@ void hvm_set_pci_link_route(struct domai
  69.137              d->domain_id, link, old_isa_irq, isa_irq);
  69.138  }
  69.139  
  69.140 -void hvm_set_callback_gsi(struct domain *d, unsigned int gsi)
  69.141 +void hvm_set_callback_via(struct domain *d, uint64_t via)
  69.142  {
  69.143      struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
  69.144 -    unsigned int old_gsi;
  69.145 +    unsigned int gsi=0, pdev=0, pintx=0;
  69.146 +    uint8_t via_type;
  69.147  
  69.148 -    if ( gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count) )
  69.149 -        gsi = 0;
  69.150 +    via_type = (uint8_t)(via >> 56) + 1;
  69.151 +    if ( ((via_type == HVMIRQ_callback_gsi) && (via == 0)) ||
  69.152 +         (via_type > HVMIRQ_callback_pci_intx) )
  69.153 +        via_type = HVMIRQ_callback_none;
  69.154  
  69.155      spin_lock(&hvm_irq->lock);
  69.156  
  69.157 -    old_gsi = hvm_irq->callback_gsi;
  69.158 -    if ( old_gsi == gsi )
  69.159 -        goto out;
  69.160 -    hvm_irq->callback_gsi = gsi;
  69.161 -
  69.162 -    if ( !test_bit(0, &hvm_irq->callback_irq_wire) )
  69.163 -        goto out;
  69.164 -
  69.165 -    if ( old_gsi && (--hvm_irq->gsi_assert_count[old_gsi] == 0) )
  69.166 -        if ( old_gsi <= 15 )
  69.167 -            vpic_irq_negative_edge(d, old_gsi);
  69.168 -
  69.169 -    if ( gsi && (hvm_irq->gsi_assert_count[gsi]++ == 0) )
  69.170 +    /* Tear down old callback via. */
  69.171 +    if ( hvm_irq->callback_via_asserted )
  69.172      {
  69.173 -        vioapic_irq_positive_edge(d, gsi);
  69.174 -        if ( gsi <= 15 )
  69.175 -            vpic_irq_positive_edge(d, gsi);
  69.176 +        switch ( hvm_irq->callback_via_type )
  69.177 +        {
  69.178 +        case HVMIRQ_callback_gsi:
  69.179 +            gsi = hvm_irq->callback_via.gsi;
  69.180 +            if ( (--hvm_irq->gsi_assert_count[gsi] == 0) && (gsi <= 15) )
  69.181 +                vpic_irq_negative_edge(d, gsi);
  69.182 +            break;
  69.183 +        case HVMIRQ_callback_pci_intx:
  69.184 +            pdev  = hvm_irq->callback_via.pci.dev;
  69.185 +            pintx = hvm_irq->callback_via.pci.intx;
  69.186 +            __hvm_pci_intx_deassert(d, pdev, pintx);
  69.187 +            break;
  69.188 +        default:
  69.189 +            break;
  69.190 +        }
  69.191      }
  69.192  
  69.193 - out:
  69.194 +    /* Set up new callback via. */
  69.195 +    switch ( hvm_irq->callback_via_type = via_type )
  69.196 +    {
  69.197 +    case HVMIRQ_callback_gsi:
  69.198 +        gsi = hvm_irq->callback_via.gsi = (uint8_t)via;
  69.199 +        if ( (gsi == 0) || (gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count)) )
  69.200 +            hvm_irq->callback_via_type = HVMIRQ_callback_none;
  69.201 +        else if ( hvm_irq->callback_via_asserted &&
  69.202 +                  (hvm_irq->gsi_assert_count[gsi]++ == 0) )
  69.203 +        {
  69.204 +            vioapic_irq_positive_edge(d, gsi);
  69.205 +            if ( gsi <= 15 )
  69.206 +                vpic_irq_positive_edge(d, gsi);
  69.207 +        }
  69.208 +        break;
  69.209 +    case HVMIRQ_callback_pci_intx:
  69.210 +        pdev  = hvm_irq->callback_via.pci.dev  = (uint8_t)(via >> 11) & 31;
  69.211 +        pintx = hvm_irq->callback_via.pci.intx = (uint8_t)via & 3;
  69.212 +        if ( hvm_irq->callback_via_asserted )
  69.213 +             __hvm_pci_intx_assert(d, pdev, pintx);
  69.214 +        break;
  69.215 +    default:
  69.216 +        break;
  69.217 +    }
  69.218 +
  69.219      spin_unlock(&hvm_irq->lock);
  69.220  
  69.221 -    dprintk(XENLOG_G_INFO, "Dom%u callback GSI changed %u -> %u\n",
  69.222 -            d->domain_id, old_gsi, gsi);
  69.223 +    dprintk(XENLOG_G_INFO, "Dom%u callback via changed to ", d->domain_id);
  69.224 +    switch ( via_type )
  69.225 +    {
  69.226 +    case HVMIRQ_callback_gsi:
  69.227 +        printk("GSI %u\n", gsi);
  69.228 +        break;
  69.229 +    case HVMIRQ_callback_pci_intx:
  69.230 +        printk("PCI INTx Dev 0x%02x Int%c\n", pdev, 'A' + pintx);
  69.231 +        break;
  69.232 +    default:
  69.233 +        printk("None\n");
  69.234 +        break;
  69.235 +    }
  69.236  }
  69.237  
  69.238  int cpu_has_pending_irq(struct vcpu *v)
    70.1 --- a/xen/arch/x86/hvm/vioapic.c	Sun Jan 14 22:18:38 2007 -0700
    70.2 +++ b/xen/arch/x86/hvm/vioapic.c	Mon Jan 15 15:15:26 2007 -0700
    70.3 @@ -309,6 +309,13 @@ static uint32_t ioapic_get_delivery_bitm
    70.4      return mask;
    70.5  }
    70.6  
    70.7 +static inline int pit_channel0_enabled(void)
    70.8 +{
    70.9 +    PITState *pit = &current->domain->arch.hvm_domain.pl_time.vpit;
   70.10 +    struct periodic_time *pt = &pit->channels[0].pt;
   70.11 +    return pt->enabled;
   70.12 +}
   70.13 +
   70.14  static void vioapic_deliver(struct vioapic *vioapic, int irq)
   70.15  {
   70.16      uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
   70.17 @@ -341,7 +348,7 @@ static void vioapic_deliver(struct vioap
   70.18      {
   70.19  #ifdef IRQ0_SPECIAL_ROUTING
   70.20          /* Force round-robin to pick VCPU 0 */
   70.21 -        if ( irq == hvm_isa_irq_to_gsi(0) )
   70.22 +        if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
   70.23          {
   70.24              v = vioapic_domain(vioapic)->vcpu[0];
   70.25              target = v ? vcpu_vlapic(v) : NULL;
   70.26 @@ -374,7 +381,7 @@ static void vioapic_deliver(struct vioap
   70.27              deliver_bitmask &= ~(1 << bit);
   70.28  #ifdef IRQ0_SPECIAL_ROUTING
   70.29              /* Do not deliver timer interrupts to VCPU != 0 */
   70.30 -            if ( irq == hvm_isa_irq_to_gsi(0) )
   70.31 +            if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
   70.32                  v = vioapic_domain(vioapic)->vcpu[0];
   70.33              else
   70.34  #endif
    71.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Sun Jan 14 22:18:38 2007 -0700
    71.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Mon Jan 15 15:15:26 2007 -0700
    71.3 @@ -278,7 +278,14 @@ static void vmx_set_host_env(struct vcpu
    71.4      host_env.tr_base = (unsigned long) &init_tss[cpu];
    71.5      __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
    71.6      __vmwrite(HOST_TR_BASE, host_env.tr_base);
    71.7 -    __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
    71.8 +
    71.9 +    /*
   71.10 +     * Skip end of cpu_user_regs when entering the hypervisor because the
   71.11 +     * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc
   71.12 +     * all get saved into the VMCS instead.
   71.13 +     */
   71.14 +    __vmwrite(HOST_RSP,
   71.15 +              (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code);
   71.16  }
   71.17  
   71.18  static void construct_vmcs(struct vcpu *v)
    72.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Sun Jan 14 22:18:38 2007 -0700
    72.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Jan 15 15:15:26 2007 -0700
    72.3 @@ -410,10 +410,6 @@ static void vmx_store_cpu_guest_regs(
    72.4          regs->eflags = __vmread(GUEST_RFLAGS);
    72.5          regs->ss = __vmread(GUEST_SS_SELECTOR);
    72.6          regs->cs = __vmread(GUEST_CS_SELECTOR);
    72.7 -        regs->ds = __vmread(GUEST_DS_SELECTOR);
    72.8 -        regs->es = __vmread(GUEST_ES_SELECTOR);
    72.9 -        regs->gs = __vmread(GUEST_GS_SELECTOR);
   72.10 -        regs->fs = __vmread(GUEST_FS_SELECTOR);
   72.11          regs->eip = __vmread(GUEST_RIP);
   72.12          regs->esp = __vmread(GUEST_RSP);
   72.13      }
   72.14 @@ -429,62 +425,39 @@ static void vmx_store_cpu_guest_regs(
   72.15      vmx_vmcs_exit(v);
   72.16  }
   72.17  
   72.18 -/*
   72.19 - * The VMX spec (section 4.3.1.2, Checks on Guest Segment
   72.20 - * Registers) says that virtual-8086 mode guests' segment
   72.21 - * base-address fields in the VMCS must be equal to their
   72.22 - * corresponding segment selector field shifted right by
   72.23 - * four bits upon vmentry.
   72.24 - *
   72.25 - * This function (called only for VM86-mode guests) fixes
   72.26 - * the bases to be consistent with the selectors in regs
   72.27 - * if they're not already.  Without this, we can fail the
   72.28 - * vmentry check mentioned above.
   72.29 - */
   72.30 -static void fixup_vm86_seg_bases(struct cpu_user_regs *regs)
   72.31 +static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
   72.32  {
   72.33      unsigned long base;
   72.34  
   72.35 -    base = __vmread(GUEST_ES_BASE);
   72.36 -    if (regs->es << 4 != base)
   72.37 -        __vmwrite(GUEST_ES_BASE, regs->es << 4);
   72.38 -    base = __vmread(GUEST_CS_BASE);
   72.39 -    if (regs->cs << 4 != base)
   72.40 -        __vmwrite(GUEST_CS_BASE, regs->cs << 4);
   72.41 -    base = __vmread(GUEST_SS_BASE);
   72.42 -    if (regs->ss << 4 != base)
   72.43 -        __vmwrite(GUEST_SS_BASE, regs->ss << 4);
   72.44 -    base = __vmread(GUEST_DS_BASE);
   72.45 -    if (regs->ds << 4 != base)
   72.46 -        __vmwrite(GUEST_DS_BASE, regs->ds << 4);
   72.47 -    base = __vmread(GUEST_FS_BASE);
   72.48 -    if (regs->fs << 4 != base)
   72.49 -        __vmwrite(GUEST_FS_BASE, regs->fs << 4);
   72.50 -    base = __vmread(GUEST_GS_BASE);
   72.51 -    if (regs->gs << 4 != base)
   72.52 -        __vmwrite(GUEST_GS_BASE, regs->gs << 4);
   72.53 -}
   72.54 -
   72.55 -static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
   72.56 -{
   72.57      vmx_vmcs_enter(v);
   72.58  
   72.59      __vmwrite(GUEST_SS_SELECTOR, regs->ss);
   72.60 -    __vmwrite(GUEST_DS_SELECTOR, regs->ds);
   72.61 -    __vmwrite(GUEST_ES_SELECTOR, regs->es);
   72.62 -    __vmwrite(GUEST_GS_SELECTOR, regs->gs);
   72.63 -    __vmwrite(GUEST_FS_SELECTOR, regs->fs);
   72.64 -
   72.65      __vmwrite(GUEST_RSP, regs->esp);
   72.66  
   72.67      /* NB. Bit 1 of RFLAGS must be set for VMENTRY to succeed. */
   72.68      __vmwrite(GUEST_RFLAGS, regs->eflags | 2UL);
   72.69 -    if (regs->eflags & EF_TF)
   72.70 +
   72.71 +    if ( regs->eflags & EF_TF )
   72.72          __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
   72.73      else
   72.74          __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
   72.75 -    if (regs->eflags & EF_VM)
   72.76 -        fixup_vm86_seg_bases(regs);
   72.77 +
   72.78 +    if ( regs->eflags & EF_VM )
   72.79 +    {
   72.80 +        /*
   72.81 +         * The VMX spec (section 4.3.1.2, Checks on Guest Segment
   72.82 +         * Registers) says that virtual-8086 mode guests' segment
   72.83 +         * base-address fields in the VMCS must be equal to their
   72.84 +         * corresponding segment selector field shifted right by
   72.85 +         * four bits upon vmentry.
   72.86 +         */
   72.87 +        base = __vmread(GUEST_CS_BASE);
   72.88 +        if ( (regs->cs << 4) != base )
   72.89 +            __vmwrite(GUEST_CS_BASE, regs->cs << 4);
   72.90 +        base = __vmread(GUEST_SS_BASE);
   72.91 +        if ( (regs->ss << 4) != base )
   72.92 +            __vmwrite(GUEST_SS_BASE, regs->ss << 4);
   72.93 +    }
   72.94  
   72.95      __vmwrite(GUEST_CS_SELECTOR, regs->cs);
   72.96      __vmwrite(GUEST_RIP, regs->eip);
   72.97 @@ -2251,47 +2224,54 @@ static void vmx_reflect_exception(struct
   72.98      }
   72.99  }
  72.100  
  72.101 +static void vmx_failed_vmentry(unsigned int exit_reason)
  72.102 +{
  72.103 +    unsigned int failed_vmentry_reason = (uint16_t)exit_reason;
  72.104 +    unsigned long exit_qualification;
  72.105 +
  72.106 +    exit_qualification = __vmread(EXIT_QUALIFICATION);
  72.107 +    printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
  72.108 +    switch ( failed_vmentry_reason )
  72.109 +    {
  72.110 +    case EXIT_REASON_INVALID_GUEST_STATE:
  72.111 +        printk("caused by invalid guest state (%ld).\n", exit_qualification);
  72.112 +        break;
  72.113 +    case EXIT_REASON_MSR_LOADING:
  72.114 +        printk("caused by MSR entry %ld loading.\n", exit_qualification);
  72.115 +        break;
  72.116 +    case EXIT_REASON_MACHINE_CHECK:
  72.117 +        printk("caused by machine check.\n");
  72.118 +        break;
  72.119 +    default:
  72.120 +        printk("reason not known yet!");
  72.121 +        break;
  72.122 +    }
  72.123 +
  72.124 +    printk("************* VMCS Area **************\n");
  72.125 +    vmcs_dump_vcpu();
  72.126 +    printk("**************************************\n");
  72.127 +
  72.128 +    domain_crash(current->domain);
  72.129 +}
  72.130 +
  72.131  asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
  72.132  {
  72.133      unsigned int exit_reason;
  72.134      unsigned long exit_qualification, inst_len = 0;
  72.135      struct vcpu *v = current;
  72.136  
  72.137 +    TRACE_3D(TRC_VMX_VMEXIT + v->vcpu_id, 0, 0, 0);
  72.138 +
  72.139      exit_reason = __vmread(VM_EXIT_REASON);
  72.140  
  72.141      perfc_incra(vmexits, exit_reason);
  72.142 +    TRACE_VMEXIT(0, exit_reason);
  72.143  
  72.144      if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT )
  72.145          local_irq_enable();
  72.146  
  72.147      if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
  72.148 -    {
  72.149 -        unsigned int failed_vmentry_reason = exit_reason & 0xFFFF;
  72.150 -
  72.151 -        exit_qualification = __vmread(EXIT_QUALIFICATION);
  72.152 -        printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
  72.153 -        switch ( failed_vmentry_reason ) {
  72.154 -        case EXIT_REASON_INVALID_GUEST_STATE:
  72.155 -            printk("caused by invalid guest state (%ld).\n", exit_qualification);
  72.156 -            break;
  72.157 -        case EXIT_REASON_MSR_LOADING:
  72.158 -            printk("caused by MSR entry %ld loading.\n", exit_qualification);
  72.159 -            break;
  72.160 -        case EXIT_REASON_MACHINE_CHECK:
  72.161 -            printk("caused by machine check.\n");
  72.162 -            break;
  72.163 -        default:
  72.164 -            printk("reason not known yet!");
  72.165 -            break;
  72.166 -        }
  72.167 -
  72.168 -        printk("************* VMCS Area **************\n");
  72.169 -        vmcs_dump_vcpu();
  72.170 -        printk("**************************************\n");
  72.171 -        goto exit_and_crash;
  72.172 -    }
  72.173 -
  72.174 -    TRACE_VMEXIT(0, exit_reason);
  72.175 +        return vmx_failed_vmentry(exit_reason);
  72.176  
  72.177      switch ( exit_reason )
  72.178      {
  72.179 @@ -2519,11 +2499,6 @@ asmlinkage void vmx_trace_vmentry(void)
  72.180      TRACE_VMEXIT(4, 0);
  72.181  }
  72.182  
  72.183 -asmlinkage void vmx_trace_vmexit (void)
  72.184 -{
  72.185 -    TRACE_3D(TRC_VMX_VMEXIT + current->vcpu_id, 0, 0, 0);
  72.186 -}
  72.187 -
  72.188  /*
  72.189   * Local variables:
  72.190   * mode: C
    73.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S	Sun Jan 14 22:18:38 2007 -0700
    73.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S	Mon Jan 15 15:15:26 2007 -0700
    73.3 @@ -29,35 +29,7 @@
    73.4          andl $~3,reg;            \
    73.5          movl (reg),reg;
    73.6  
    73.7 -/*
    73.8 - * At VMExit time the processor saves the guest selectors, esp, eip, 
    73.9 - * and eflags. Therefore we don't save them, but simply decrement 
   73.10 - * the kernel stack pointer to make it consistent with the stack frame 
   73.11 - * at usual interruption time. The eflags of the host is not saved by VMX, 
   73.12 - * and we set it to the fixed value.
   73.13 - *
   73.14 - * We also need the room, especially because orig_eax field is used 
   73.15 - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
   73.16 - *   (10) u32 gs;                 
   73.17 - *   (9)  u32 fs;
   73.18 - *   (8)  u32 ds;
   73.19 - *   (7)  u32 es;
   73.20 - *               <- get_stack_bottom() (= HOST_ESP)
   73.21 - *   (6)  u32 ss;
   73.22 - *   (5)  u32 esp;
   73.23 - *   (4)  u32 eflags;
   73.24 - *   (3)  u32 cs;
   73.25 - *   (2)  u32 eip;
   73.26 - * (2/1)  u16 entry_vector;
   73.27 - * (1/1)  u16 error_code;
   73.28 - * However, get_stack_bottom() actually returns 20 bytes before the real
   73.29 - * bottom of the stack to allow space for:
   73.30 - * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers.
   73.31 - */
   73.32 -
   73.33 -#define NR_SKIPPED_REGS 6 /* See the above explanation */
   73.34  #define HVM_SAVE_ALL_NOSEGREGS                                              \
   73.35 -        subl $(NR_SKIPPED_REGS*4), %esp;                                    \
   73.36          movl $0, 0xc(%esp);  /* XXX why do we need to force eflags==0 ?? */ \
   73.37          pushl %eax;                                                         \
   73.38          pushl %ebp;                                                         \
   73.39 @@ -74,14 +46,11 @@
   73.40          popl %esi;                              \
   73.41          popl %edi;                              \
   73.42          popl %ebp;                              \
   73.43 -        popl %eax;                              \
   73.44 -        addl $(NR_SKIPPED_REGS*4), %esp
   73.45 +        popl %eax
   73.46  
   73.47          ALIGN
   73.48  ENTRY(vmx_asm_vmexit_handler)
   73.49 -        /* selectors are restored/saved by VMX */
   73.50          HVM_SAVE_ALL_NOSEGREGS
   73.51 -        call vmx_trace_vmexit
   73.52          movl %esp,%eax
   73.53          push %eax
   73.54          call vmx_vmexit_handler
    74.1 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S	Sun Jan 14 22:18:38 2007 -0700
    74.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S	Mon Jan 15 15:15:26 2007 -0700
    74.3 @@ -29,31 +29,7 @@
    74.4          andq $~7,reg;            \
    74.5          movq (reg),reg;
    74.6  
    74.7 -/*
    74.8 - * At VMExit time the processor saves the guest selectors, rsp, rip, 
    74.9 - * and rflags. Therefore we don't save them, but simply decrement 
   74.10 - * the kernel stack pointer to make it consistent with the stack frame 
   74.11 - * at usual interruption time. The rflags of the host is not saved by VMX, 
   74.12 - * and we set it to the fixed value.
   74.13 - *
   74.14 - * We also need the room, especially because orig_eax field is used 
   74.15 - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
   74.16 - *   (10) u64 gs;                 
   74.17 - *   (9)  u64 fs;
   74.18 - *   (8)  u64 ds;
   74.19 - *   (7)  u64 es;
   74.20 - *               <- get_stack_bottom() (= HOST_ESP)
   74.21 - *   (6)  u64 ss;
   74.22 - *   (5)  u64 rsp;
   74.23 - *   (4)  u64 rflags;
   74.24 - *   (3)  u64 cs;
   74.25 - *   (2)  u64 rip;
   74.26 - * (2/1)  u32 entry_vector;
   74.27 - * (1/1)  u32 error_code;
   74.28 - */
   74.29 -#define NR_SKIPPED_REGS 6 /* See the above explanation */
   74.30  #define HVM_SAVE_ALL_NOSEGREGS                  \
   74.31 -        subq $(NR_SKIPPED_REGS*8), %rsp;        \
   74.32          pushq %rdi;                             \
   74.33          pushq %rsi;                             \
   74.34          pushq %rdx;                             \
   74.35 @@ -85,14 +61,11 @@
   74.36          popq %rcx;                              \
   74.37          popq %rdx;                              \
   74.38          popq %rsi;                              \
   74.39 -        popq %rdi;                              \
   74.40 -        addq $(NR_SKIPPED_REGS*8), %rsp;
   74.41 +        popq %rdi
   74.42  
   74.43          ALIGN
   74.44  ENTRY(vmx_asm_vmexit_handler)
   74.45 -        /* selectors are restored/saved by VMX */
   74.46          HVM_SAVE_ALL_NOSEGREGS
   74.47 -        call vmx_trace_vmexit
   74.48          movq %rsp,%rdi
   74.49          call vmx_vmexit_handler
   74.50          jmp vmx_asm_do_vmentry
    75.1 --- a/xen/arch/x86/mm.c	Sun Jan 14 22:18:38 2007 -0700
    75.2 +++ b/xen/arch/x86/mm.c	Mon Jan 15 15:15:26 2007 -0700
    75.3 @@ -826,7 +826,7 @@ static void put_page_from_l2e(l2_pgentry
    75.4  {
    75.5      if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && 
    75.6           (l2e_get_pfn(l2e) != pfn) )
    75.7 -        put_page_and_type(mfn_to_page(l2e_get_pfn(l2e)));
    75.8 +        put_page_and_type(l2e_get_page(l2e));
    75.9  }
   75.10  
   75.11  
   75.12 @@ -835,7 +835,7 @@ static void put_page_from_l3e(l3_pgentry
   75.13  {
   75.14      if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && 
   75.15           (l3e_get_pfn(l3e) != pfn) )
   75.16 -        put_page_and_type(mfn_to_page(l3e_get_pfn(l3e)));
   75.17 +        put_page_and_type(l3e_get_page(l3e));
   75.18  }
   75.19  #endif
   75.20  
   75.21 @@ -844,7 +844,7 @@ static void put_page_from_l4e(l4_pgentry
   75.22  {
   75.23      if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && 
   75.24           (l4e_get_pfn(l4e) != pfn) )
   75.25 -        put_page_and_type(mfn_to_page(l4e_get_pfn(l4e)));
   75.26 +        put_page_and_type(l4e_get_page(l4e));
   75.27  }
   75.28  #endif
   75.29  
   75.30 @@ -1376,7 +1376,7 @@ static int mod_l2_entry(l2_pgentry_t *pl
   75.31          if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT))
   75.32              return UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, current);
   75.33  
   75.34 -        if ( unlikely(!get_page_from_l2e(nl2e, pfn, current->domain)) )
   75.35 +        if ( unlikely(!get_page_from_l2e(nl2e, pfn, d)) )
   75.36              return 0;
   75.37  
   75.38          if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, current)) )
   75.39 @@ -1439,7 +1439,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
   75.40          if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT))
   75.41              return UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, current);
   75.42  
   75.43 -        if ( unlikely(!get_page_from_l3e(nl3e, pfn, current->domain)) )
   75.44 +        if ( unlikely(!get_page_from_l3e(nl3e, pfn, d)) )
   75.45              return 0;
   75.46  
   75.47          if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, current)) )
   75.48 @@ -3182,7 +3182,7 @@ static int ptwr_emulated_update(
   75.49      unsigned int do_cmpxchg,
   75.50      struct ptwr_emulate_ctxt *ptwr_ctxt)
   75.51  {
   75.52 -    unsigned long gmfn, mfn;
   75.53 +    unsigned long mfn;
   75.54      struct page_info *page;
   75.55      l1_pgentry_t pte, ol1e, nl1e, *pl1e;
   75.56      struct vcpu *v = current;
   75.57 @@ -3222,8 +3222,7 @@ static int ptwr_emulated_update(
   75.58      }
   75.59  
   75.60      pte  = ptwr_ctxt->pte;
   75.61 -    gmfn = l1e_get_pfn(pte);
   75.62 -    mfn  = gmfn_to_mfn(d, gmfn);
   75.63 +    mfn  = l1e_get_pfn(pte);
   75.64      page = mfn_to_page(mfn);
   75.65  
   75.66      /* We are looking only for read-only mappings of p.t. pages. */
   75.67 @@ -3354,7 +3353,6 @@ int ptwr_do_page_fault(struct vcpu *v, u
   75.68                         struct cpu_user_regs *regs)
   75.69  {
   75.70      struct domain *d = v->domain;
   75.71 -    unsigned long     pfn;
   75.72      struct page_info *page;
   75.73      l1_pgentry_t      pte;
   75.74      struct ptwr_emulate_ctxt ptwr_ctxt;
   75.75 @@ -3368,8 +3366,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
   75.76      guest_get_eff_l1e(v, addr, &pte);
   75.77      if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
   75.78          goto bail;
   75.79 -    pfn  = l1e_get_pfn(pte);
   75.80 -    page = mfn_to_page(pfn);
   75.81 +    page = l1e_get_page(pte);
   75.82  
   75.83      /* We are looking only for read-only mappings of p.t. pages. */
   75.84      if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) ||
    76.1 --- a/xen/arch/x86/mm/shadow/common.c	Sun Jan 14 22:18:38 2007 -0700
    76.2 +++ b/xen/arch/x86/mm/shadow/common.c	Mon Jan 15 15:15:26 2007 -0700
    76.3 @@ -1303,6 +1303,9 @@ shadow_alloc_p2m_table(struct domain *d)
    76.4      if ( !shadow_set_p2m_entry(d, gfn, mfn) )
    76.5          goto error;
    76.6  
    76.7 +    /* Build a p2m map that matches the m2p entries for this domain's
    76.8 +     * allocated pages.  Skip any pages that have an explicitly invalid
    76.9 +     * or obviously bogus m2p entry. */
   76.10      for ( entry = d->page_list.next;
   76.11            entry != &d->page_list;
   76.12            entry = entry->next )
   76.13 @@ -1318,6 +1321,8 @@ shadow_alloc_p2m_table(struct domain *d)
   76.14              (gfn != 0x55555555L)
   76.15  #endif
   76.16               && gfn != INVALID_M2P_ENTRY
   76.17 +             && (gfn < 
   76.18 +                 (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof (l1_pgentry_t))
   76.19               && !shadow_set_p2m_entry(d, gfn, mfn) )
   76.20              goto error;
   76.21      }
    77.1 --- a/xen/arch/x86/oprofile/nmi_int.c	Sun Jan 14 22:18:38 2007 -0700
    77.2 +++ b/xen/arch/x86/oprofile/nmi_int.c	Mon Jan 15 15:15:26 2007 -0700
    77.3 @@ -42,7 +42,7 @@ extern int is_profiled(struct domain *d)
    77.4  extern size_t strlcpy(char *dest, const char *src, size_t size);
    77.5  
    77.6  
    77.7 -int nmi_callback(struct cpu_user_regs *regs, int cpu)
    77.8 +static int nmi_callback(struct cpu_user_regs *regs, int cpu)
    77.9  {
   77.10  	int xen_mode, ovf;
   77.11  
    78.1 --- a/xen/arch/x86/setup.c	Sun Jan 14 22:18:38 2007 -0700
    78.2 +++ b/xen/arch/x86/setup.c	Mon Jan 15 15:15:26 2007 -0700
    78.3 @@ -411,6 +411,23 @@ void __init __start_xen(multiboot_info_t
    78.4          printk("WARNING: Buggy e820 map detected and fixed "
    78.5                 "(truncated length fields).\n");
    78.6  
    78.7 +    /* Ensure that all E820 RAM regions are page-aligned and -sized. */
    78.8 +    for ( i = 0; i < e820_raw_nr; i++ )
    78.9 +    {
   78.10 +        uint64_t s, e;
   78.11 +        if ( e820_raw[i].type != E820_RAM )
   78.12 +            continue;
   78.13 +        s = PFN_UP(e820_raw[i].addr);
   78.14 +        e = PFN_DOWN(e820_raw[i].addr + e820_raw[i].size);
   78.15 +        e820_raw[i].size = 0; /* discarded later */
   78.16 +        if ( s < e )
   78.17 +        {
   78.18 +            e820_raw[i].addr = s << PAGE_SHIFT;
   78.19 +            e820_raw[i].size = (e - s) << PAGE_SHIFT;
   78.20 +        }
   78.21 +    }
   78.22 +
   78.23 +    /* Sanitise the raw E820 map to produce a final clean version. */
   78.24      max_page = init_e820(e820_raw, &e820_raw_nr);
   78.25  
   78.26      modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
   78.27 @@ -423,7 +440,7 @@ void __init __start_xen(multiboot_info_t
   78.28              printk("Not enough memory to stash the DOM0 kernel image.\n");
   78.29              for ( ; ; ) ;
   78.30          }
   78.31 -        
   78.32 +
   78.33          if ( (e820.map[i].type == E820_RAM) &&
   78.34               (e820.map[i].size >= modules_length) &&
   78.35               ((e820.map[i].addr + e820.map[i].size) >=
   78.36 @@ -474,10 +491,10 @@ void __init __start_xen(multiboot_info_t
   78.37              start = PFN_UP(e820.map[i].addr);
   78.38              end   = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
   78.39              /* Clip the range to exclude what the bootstrapper initialised. */
   78.40 -            if ( end < init_mapped )
   78.41 -                continue;
   78.42              if ( start < init_mapped )
   78.43                  start = init_mapped;
   78.44 +            if ( end <= start )
   78.45 +                continue;
   78.46              /* Request the mapping. */
   78.47              map_pages_to_xen(
   78.48                  PAGE_OFFSET + (start << PAGE_SHIFT),
   78.49 @@ -486,7 +503,7 @@ void __init __start_xen(multiboot_info_t
   78.50  #endif
   78.51      }
   78.52  
   78.53 -    if ( kexec_crash_area.size > 0 )
   78.54 +    if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0)
   78.55      {
   78.56          unsigned long kdump_start, kdump_size, k;
   78.57  
    79.1 --- a/xen/arch/x86/traps.c	Sun Jan 14 22:18:38 2007 -0700
    79.2 +++ b/xen/arch/x86/traps.c	Mon Jan 15 15:15:26 2007 -0700
    79.3 @@ -1121,7 +1121,7 @@ static int emulate_privileged_op(struct 
    79.4  {
    79.5      struct vcpu *v = current;
    79.6      unsigned long *reg, eip = regs->eip, res;
    79.7 -    u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0;
    79.8 +    u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0;
    79.9      enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none;
   79.10      unsigned int port, i, data_sel, ar, data, rc;
   79.11      unsigned int op_bytes, op_default, ad_bytes, ad_default;
   79.12 @@ -1184,6 +1184,7 @@ static int emulate_privileged_op(struct 
   79.13              data_sel = regs->ss;
   79.14              continue;
   79.15          case 0xf0: /* LOCK */
   79.16 +            lock = 1;
   79.17              continue;
   79.18          case 0xf2: /* REPNE/REPNZ */
   79.19          case 0xf3: /* REP/REPE/REPZ */
   79.20 @@ -1210,6 +1211,9 @@ static int emulate_privileged_op(struct 
   79.21      if ( opcode == 0x0f )
   79.22          goto twobyte_opcode;
   79.23      
   79.24 +    if ( lock )
   79.25 +        goto fail;
   79.26 +
   79.27      /* Input/Output String instructions. */
   79.28      if ( (opcode >= 0x6c) && (opcode <= 0x6f) )
   79.29      {
   79.30 @@ -1472,6 +1476,8 @@ static int emulate_privileged_op(struct 
   79.31  
   79.32      /* Privileged (ring 0) instructions. */
   79.33      opcode = insn_fetch(u8, code_base, eip, code_limit);
   79.34 +    if ( lock && (opcode & ~3) != 0x20 )
   79.35 +        goto fail;
   79.36      switch ( opcode )
   79.37      {
   79.38      case 0x06: /* CLTS */
   79.39 @@ -1490,7 +1496,7 @@ static int emulate_privileged_op(struct 
   79.40  
   79.41      case 0x20: /* MOV CR?,<reg> */
   79.42          opcode = insn_fetch(u8, code_base, eip, code_limit);
   79.43 -        modrm_reg |= (opcode >> 3) & 7;
   79.44 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
   79.45          modrm_rm  |= (opcode >> 0) & 7;
   79.46          reg = decode_register(modrm_rm, regs, 0);
   79.47          switch ( modrm_reg )
   79.48 @@ -1530,7 +1536,7 @@ static int emulate_privileged_op(struct 
   79.49  
   79.50      case 0x21: /* MOV DR?,<reg> */
   79.51          opcode = insn_fetch(u8, code_base, eip, code_limit);
   79.52 -        modrm_reg |= (opcode >> 3) & 7;
   79.53 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
   79.54          modrm_rm  |= (opcode >> 0) & 7;
   79.55          reg = decode_register(modrm_rm, regs, 0);
   79.56          if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 )
   79.57 @@ -1540,7 +1546,7 @@ static int emulate_privileged_op(struct 
   79.58  
   79.59      case 0x22: /* MOV <reg>,CR? */
   79.60          opcode = insn_fetch(u8, code_base, eip, code_limit);
   79.61 -        modrm_reg |= (opcode >> 3) & 7;
   79.62 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
   79.63          modrm_rm  |= (opcode >> 0) & 7;
   79.64          reg = decode_register(modrm_rm, regs, 0);
   79.65          switch ( modrm_reg )
   79.66 @@ -1588,7 +1594,7 @@ static int emulate_privileged_op(struct 
   79.67  
   79.68      case 0x23: /* MOV <reg>,DR? */
   79.69          opcode = insn_fetch(u8, code_base, eip, code_limit);
   79.70 -        modrm_reg |= (opcode >> 3) & 7;
   79.71 +        modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
   79.72          modrm_rm  |= (opcode >> 0) & 7;
   79.73          reg = decode_register(modrm_rm, regs, 0);
   79.74          if ( do_set_debugreg(modrm_reg, *reg) != 0 )
   79.75 @@ -1854,7 +1860,7 @@ static int dummy_nmi_callback(struct cpu
   79.76  }
   79.77   
   79.78  static nmi_callback_t nmi_callback = dummy_nmi_callback;
   79.79 - 
   79.80 +
   79.81  asmlinkage void do_nmi(struct cpu_user_regs *regs)
   79.82  {
   79.83      unsigned int cpu = smp_processor_id();
    80.1 --- a/xen/arch/x86/x86_64/compat/mm.c	Sun Jan 14 22:18:38 2007 -0700
    80.2 +++ b/xen/arch/x86/x86_64/compat/mm.c	Mon Jan 15 15:15:26 2007 -0700
    80.3 @@ -1,6 +1,7 @@
    80.4  #ifdef CONFIG_COMPAT
    80.5  
    80.6  #include <xen/event.h>
    80.7 +#include <xen/multicall.h>
    80.8  #include <compat/memory.h>
    80.9  #include <compat/xen.h>
   80.10  
   80.11 @@ -289,20 +290,27 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
   80.12              if ( err == __HYPERVISOR_mmuext_op )
   80.13              {
   80.14                  struct cpu_user_regs *regs = guest_cpu_user_regs();
   80.15 -                unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED;
   80.16 +                struct mc_state *mcs = &this_cpu(mc_state);
   80.17 +                unsigned int arg1 = !test_bit(_MCSF_in_multicall, &mcs->flags)
   80.18 +                                    ? regs->ecx
   80.19 +                                    : mcs->call.args[1];
   80.20 +                unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED;
   80.21  
   80.22 -                BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED));
   80.23 +                BUG_ON(left == arg1);
   80.24                  BUG_ON(left > count);
   80.25                  guest_handle_add_offset(nat_ops, count - left);
   80.26                  BUG_ON(left + i < count);
   80.27                  guest_handle_add_offset(cmp_uops, (signed int)(count - left - i));
   80.28                  left = 1;
   80.29                  BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
   80.30 -                BUG_ON(left != regs->ecx);
   80.31 -                regs->ecx += count - i;
   80.32 +                BUG_ON(left != arg1);
   80.33 +                if (!test_bit(_MCSF_in_multicall, &mcs->flags))
   80.34 +                    regs->_ecx += count - i;
   80.35 +                else
   80.36 +                    mcs->compat_call.args[1] += count - i;
   80.37              }
   80.38              else
   80.39 -                BUG_ON(rc > 0);
   80.40 +                BUG_ON(err > 0);
   80.41              rc = err;
   80.42          }
   80.43  
    81.1 --- a/xen/arch/x86/x86_emulate.c	Sun Jan 14 22:18:38 2007 -0700
    81.2 +++ b/xen/arch/x86/x86_emulate.c	Mon Jan 15 15:15:26 2007 -0700
    81.3 @@ -3,7 +3,21 @@
    81.4   * 
    81.5   * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
    81.6   * 
    81.7 - * Copyright (c) 2005 Keir Fraser
    81.8 + * Copyright (c) 2005-2007 Keir Fraser
    81.9 + * 
   81.10 + * This program is free software; you can redistribute it and/or modify
   81.11 + * it under the terms of the GNU General Public License as published by
   81.12 + * the Free Software Foundation; either version 2 of the License, or
   81.13 + * (at your option) any later version.
   81.14 + * 
   81.15 + * This program is distributed in the hope that it will be useful,
   81.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   81.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   81.18 + * GNU General Public License for more details.
   81.19 + * 
   81.20 + * You should have received a copy of the GNU General Public License
   81.21 + * along with this program; if not, write to the Free Software
   81.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   81.23   */
   81.24  
   81.25  #ifndef __XEN__
   81.26 @@ -33,9 +47,8 @@
   81.27  #define SrcReg      (1<<3) /* Register operand. */
   81.28  #define SrcMem      (2<<3) /* Memory operand. */
   81.29  #define SrcMem16    (3<<3) /* Memory operand (16-bit). */
   81.30 -#define SrcMem32    (4<<3) /* Memory operand (32-bit). */
   81.31 -#define SrcImm      (5<<3) /* Immediate operand. */
   81.32 -#define SrcImmByte  (6<<3) /* 8-bit sign-extended immediate operand. */
   81.33 +#define SrcImm      (4<<3) /* Immediate operand. */
   81.34 +#define SrcImmByte  (5<<3) /* 8-bit sign-extended immediate operand. */
   81.35  #define SrcMask     (7<<3)
   81.36  /* Generic ModRM decode. */
   81.37  #define ModRM       (1<<6)
   81.38 @@ -85,9 +98,13 @@ static uint8_t opcode_table[256] = {
   81.39      ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
   81.40      ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
   81.41      ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
   81.42 -    /* 0x60 - 0x6F */
   81.43 -    0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */,
   81.44 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   81.45 +    /* 0x60 - 0x67 */
   81.46 +    ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcMem16|ModRM|Mov,
   81.47 +    0, 0, 0, 0,
   81.48 +    /* 0x68 - 0x6F */
   81.49 +    ImplicitOps|Mov, DstMem|SrcImm|ModRM|Mov,
   81.50 +    ImplicitOps|Mov, DstMem|SrcImmByte|ModRM|Mov,
   81.51 +    0, 0, 0, 0,
   81.52      /* 0x70 - 0x77 */
   81.53      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
   81.54      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
   81.55 @@ -107,7 +124,7 @@ static uint8_t opcode_table[256] = {
   81.56      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
   81.57      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
   81.58      /* 0x98 - 0x9F */
   81.59 -    0, 0, 0, 0, 0, 0, 0, 0,
   81.60 +    ImplicitOps, ImplicitOps, 0, 0, 0, 0, ImplicitOps, ImplicitOps,
   81.61      /* 0xA0 - 0xA7 */
   81.62      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   81.63      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   81.64 @@ -125,7 +142,8 @@ static uint8_t opcode_table[256] = {
   81.65      DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
   81.66      DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
   81.67      /* 0xC0 - 0xC7 */
   81.68 -    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
   81.69 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
   81.70 +    ImplicitOps, ImplicitOps,
   81.71      0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
   81.72      /* 0xC8 - 0xCF */
   81.73      0, 0, 0, 0, 0, 0, 0, 0,
   81.74 @@ -136,9 +154,9 @@ static uint8_t opcode_table[256] = {
   81.75      /* 0xD8 - 0xDF */
   81.76      0, 0, 0, 0, 0, 0, 0, 0,
   81.77      /* 0xE0 - 0xE7 */
   81.78 -    0, 0, 0, ImplicitOps, 0, 0, 0, 0,
   81.79 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0,
   81.80      /* 0xE8 - 0xEF */
   81.81 -    0, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
   81.82 +    ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
   81.83      /* 0xF0 - 0xF7 */
   81.84      0, 0, 0, 0,
   81.85      0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
   81.86 @@ -150,8 +168,11 @@ static uint8_t opcode_table[256] = {
   81.87  static uint8_t twobyte_table[256] = {
   81.88      /* 0x00 - 0x0F */
   81.89      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
   81.90 -    /* 0x10 - 0x1F */
   81.91 -    0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0,
   81.92 +    /* 0x10 - 0x17 */
   81.93 +    0, 0, 0, 0, 0, 0, 0, 0,
   81.94 +    /* 0x18 - 0x1F */
   81.95 +    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
   81.96 +    ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
   81.97      /* 0x20 - 0x2F */
   81.98      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   81.99      /* 0x30 - 0x3F */
  81.100 @@ -178,24 +199,34 @@ static uint8_t twobyte_table[256] = {
  81.101      /* 0x88 - 0x8F */
  81.102      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  81.103      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  81.104 -    /* 0x90 - 0x9F */
  81.105 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  81.106 +    /* 0x90 - 0x97 */
  81.107 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.108 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.109 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.110 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.111 +    /* 0x98 - 0x9F */
  81.112 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.113 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.114 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.115 +    ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
  81.116      /* 0xA0 - 0xA7 */
  81.117      0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0, 
  81.118      /* 0xA8 - 0xAF */
  81.119 -    0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0,
  81.120 +    0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, DstReg|SrcMem|ModRM,
  81.121      /* 0xB0 - 0xB7 */
  81.122      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
  81.123      0, DstBitBase|SrcReg|ModRM,
  81.124      0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
  81.125      /* 0xB8 - 0xBF */
  81.126      0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,
  81.127 -    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
  81.128 +    DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
  81.129 +    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
  81.130      /* 0xC0 - 0xC7 */
  81.131      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
  81.132      0, 0, 0, ImplicitOps|ModRM,
  81.133      /* 0xC8 - 0xCF */
  81.134 -    0, 0, 0, 0, 0, 0, 0, 0,
  81.135 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  81.136 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
  81.137      /* 0xD0 - 0xDF */
  81.138      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  81.139      /* 0xE0 - 0xEF */
  81.140 @@ -206,7 +237,7 @@ static uint8_t twobyte_table[256] = {
  81.141  
  81.142  /* Type, address-of, and value of an instruction's operand. */
  81.143  struct operand {
  81.144 -    enum { OP_REG, OP_MEM, OP_IMM } type;
  81.145 +    enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
  81.146      unsigned int  bytes;
  81.147      unsigned long val, orig_val;
  81.148      union {
  81.149 @@ -230,7 +261,10 @@ struct operand {
  81.150  #define EFLG_CF (1<<0)
  81.151  
  81.152  /* Exception definitions. */
  81.153 -#define EXC_DE 0
  81.154 +#define EXC_DE  0
  81.155 +#define EXC_BR  5
  81.156 +#define EXC_UD  6
  81.157 +#define EXC_GP 13
  81.158  
  81.159  /*
  81.160   * Instruction emulation:
  81.161 @@ -289,7 +323,8 @@ do{ unsigned long _tmp;                 
  81.162              _op"w %"_wx"3,%1; "                                            \
  81.163              _POST_EFLAGS("0","4","2")                                      \
  81.164              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
  81.165 -            : _wy ((_src).val), "i" (EFLAGS_MASK) );                       \
  81.166 +            : _wy ((_src).val), "i" (EFLAGS_MASK),                         \
  81.167 +              "m" (_eflags), "m" ((_dst).val) );                           \
  81.168          break;                                                             \
  81.169      case 4:                                                                \
  81.170          __asm__ __volatile__ (                                             \
  81.171 @@ -297,7 +332,8 @@ do{ unsigned long _tmp;                 
  81.172              _op"l %"_lx"3,%1; "                                            \
  81.173              _POST_EFLAGS("0","4","2")                                      \
  81.174              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
  81.175 -            : _ly ((_src).val), "i" (EFLAGS_MASK) );                       \
  81.176 +            : _ly ((_src).val), "i" (EFLAGS_MASK),                         \
  81.177 +              "m" (_eflags), "m" ((_dst).val) );                           \
  81.178          break;                                                             \
  81.179      case 8:                                                                \
  81.180          __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy);           \
  81.181 @@ -314,7 +350,8 @@ do{ unsigned long _tmp;                 
  81.182              _op"b %"_bx"3,%1; "                                            \
  81.183              _POST_EFLAGS("0","4","2")                                      \
  81.184              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
  81.185 -            : _by ((_src).val), "i" (EFLAGS_MASK) );                       \
  81.186 +            : _by ((_src).val), "i" (EFLAGS_MASK),                         \
  81.187 +              "m" (_eflags), "m" ((_dst).val) );                           \
  81.188          break;                                                             \
  81.189      default:                                                               \
  81.190          __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy);\
  81.191 @@ -345,7 +382,7 @@ do{ unsigned long _tmp;                 
  81.192              _op"b %1; "                                                    \
  81.193              _POST_EFLAGS("0","3","2")                                      \
  81.194              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
  81.195 -            : "i" (EFLAGS_MASK) );                                         \
  81.196 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
  81.197          break;                                                             \
  81.198      case 2:                                                                \
  81.199          __asm__ __volatile__ (                                             \
  81.200 @@ -353,7 +390,7 @@ do{ unsigned long _tmp;                 
  81.201              _op"w %1; "                                                    \
  81.202              _POST_EFLAGS("0","3","2")                                      \
  81.203              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
  81.204 -            : "i" (EFLAGS_MASK) );                                         \
  81.205 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
  81.206          break;                                                             \
  81.207      case 4:                                                                \
  81.208          __asm__ __volatile__ (                                             \
  81.209 @@ -361,7 +398,7 @@ do{ unsigned long _tmp;                 
  81.210              _op"l %1; "                                                    \
  81.211              _POST_EFLAGS("0","3","2")                                      \
  81.212              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
  81.213 -            : "i" (EFLAGS_MASK) );                                         \
  81.214 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
  81.215          break;                                                             \
  81.216      case 8:                                                                \
  81.217          __emulate_1op_8byte(_op, _dst, _eflags);                           \
  81.218 @@ -377,7 +414,8 @@ do{ __asm__ __volatile__ (              
  81.219          _op"q %"_qx"3,%1; "                                             \
  81.220          _POST_EFLAGS("0","4","2")                                       \
  81.221          : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
  81.222 -        : _qy ((_src).val), "i" (EFLAGS_MASK) );                        \
  81.223 +        : _qy ((_src).val), "i" (EFLAGS_MASK),                          \
  81.224 +          "m" (_eflags), "m" ((_dst).val) );                            \
  81.225  } while (0)
  81.226  #define __emulate_1op_8byte(_op, _dst, _eflags)                         \
  81.227  do{ __asm__ __volatile__ (                                              \
  81.228 @@ -385,7 +423,7 @@ do{ __asm__ __volatile__ (              
  81.229          _op"q %1; "                                                     \
  81.230          _POST_EFLAGS("0","3","2")                                       \
  81.231          : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
  81.232 -        : "i" (EFLAGS_MASK) );                                          \
  81.233 +        : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );         \
  81.234  } while (0)
  81.235  #elif defined(__i386__)
  81.236  #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
  81.237 @@ -394,11 +432,13 @@ do{ __asm__ __volatile__ (              
  81.238  
  81.239  /* Fetch next part of the instruction being emulated. */
  81.240  #define insn_fetch_bytes(_size)                                         \
  81.241 -({ unsigned long _x, _eip = _truncate_ea(_regs.eip, def_ad_bytes);      \
  81.242 +({ unsigned long _x, _eip = _regs.eip;                                  \
  81.243     if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
  81.244 +   _regs.eip += (_size); /* real hardware doesn't truncate */           \
  81.245 +   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
  81.246 +                         EXC_GP);                                       \
  81.247     rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
  81.248     if ( rc ) goto done;                                                 \
  81.249 -   _regs.eip += (_size); /* real hardware doesn't truncate */           \
  81.250     _x;                                                                  \
  81.251  })
  81.252  #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
  81.253 @@ -452,6 +492,92 @@ do {                                    
  81.254                       ? (uint16_t)_regs.eip : (uint32_t)_regs.eip);      \
  81.255  } while (0)
  81.256  
  81.257 +/*
  81.258 + * Unsigned multiplication with double-word result.
  81.259 + * IN:  Multiplicand=m[0], Multiplier=m[1]
  81.260 + * OUT: Return CF/OF (overflow status); Result=m[1]:m[0]
  81.261 + */
  81.262 +static int mul_dbl(unsigned long m[2])
  81.263 +{
  81.264 +    int rc;
  81.265 +    asm ( "mul %4; seto %b2"
  81.266 +          : "=a" (m[0]), "=d" (m[1]), "=q" (rc)
  81.267 +          : "0" (m[0]), "1" (m[1]), "2" (0) );
  81.268 +    return rc;
  81.269 +}
  81.270 +
  81.271 +/*
  81.272 + * Signed multiplication with double-word result.
  81.273 + * IN:  Multiplicand=m[0], Multiplier=m[1]
  81.274 + * OUT: Return CF/OF (overflow status); Result=m[1]:m[0]
  81.275 + */
  81.276 +static int imul_dbl(unsigned long m[2])
  81.277 +{
  81.278 +    int rc;
  81.279 +    asm ( "imul %4; seto %b2"
  81.280 +          : "=a" (m[0]), "=d" (m[1]), "=q" (rc)
  81.281 +          : "0" (m[0]), "1" (m[1]), "2" (0) );
  81.282 +    return rc;
  81.283 +}
  81.284 +
  81.285 +/*
  81.286 + * Unsigned division of double-word dividend.
  81.287 + * IN:  Dividend=u[1]:u[0], Divisor=v
  81.288 + * OUT: Return 1: #DE
  81.289 + *      Return 0: Quotient=u[0], Remainder=u[1]
  81.290 + */
  81.291 +static int div_dbl(unsigned long u[2], unsigned long v)
  81.292 +{
  81.293 +    if ( (v == 0) || (u[1] > v) || ((u[1] == v) && (u[0] != 0)) )
  81.294 +        return 1;
  81.295 +    asm ( "div %4"
  81.296 +          : "=a" (u[0]), "=d" (u[1])
  81.297 +          : "0" (u[0]), "1" (u[1]), "r" (v) );
  81.298 +    return 0;
  81.299 +}
  81.300 +
  81.301 +/*
  81.302 + * Signed division of double-word dividend.
  81.303 + * IN:  Dividend=u[1]:u[0], Divisor=v
  81.304 + * OUT: Return 1: #DE
  81.305 + *      Return 0: Quotient=u[0], Remainder=u[1]
  81.306 + * NB. We don't use idiv directly as it's moderately hard to work out
  81.307 + *     ahead of time whether it will #DE, which we cannot allow to happen.
  81.308 + */
  81.309 +static int idiv_dbl(unsigned long u[2], unsigned long v)
  81.310 +{
  81.311 +    int negu = (long)u[1] < 0, negv = (long)v < 0;
  81.312 +
  81.313 +    /* u = abs(u) */
  81.314 +    if ( negu )
  81.315 +    {
  81.316 +        u[1] = ~u[1];
  81.317 +        if ( (u[0] = -u[0]) == 0 )
  81.318 +            u[1]++;
  81.319 +    }
  81.320 +
  81.321 +    /* abs(u) / abs(v) */
  81.322 +    if ( div_dbl(u, negv ? -v : v) )
  81.323 +        return 1;
  81.324 +
  81.325 +    /* Remainder has same sign as dividend. It cannot overflow. */
  81.326 +    if ( negu )
  81.327 +        u[1] = -u[1];
  81.328 +
  81.329 +    /* Quotient is overflowed if sign bit is set. */
  81.330 +    if ( negu ^ negv )
  81.331 +    {
  81.332 +        if ( (long)u[0] >= 0 )
  81.333 +            u[0] = -u[0];
  81.334 +        else if ( (u[0] << 1) != 0 ) /* == 0x80...0 is okay */
  81.335 +            return 1;
  81.336 +    }
  81.337 +    else if ( (long)u[0] < 0 )
  81.338 +        return 1;
  81.339 +
  81.340 +    return 0;
  81.341 +}
  81.342 +
  81.343  static int
  81.344  test_cc(
  81.345      unsigned int condition, unsigned int flags)
  81.346 @@ -540,8 +666,8 @@ x86_emulate(
  81.347  
  81.348      uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0;
  81.349      uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
  81.350 -    unsigned int op_bytes, ad_bytes, def_ad_bytes;
  81.351 -    unsigned int lock_prefix = 0, rep_prefix = 0, i;
  81.352 +    unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes;
  81.353 +    unsigned int lock_prefix = 0, rep_prefix = 0;
  81.354      int rc = 0;
  81.355      struct operand src, dst;
  81.356  
  81.357 @@ -553,28 +679,25 @@ x86_emulate(
  81.358      ea.mem.seg = x86_seg_ds;
  81.359      ea.mem.off = 0;
  81.360  
  81.361 -    op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes;
  81.362 +    op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes;
  81.363      if ( op_bytes == 8 )
  81.364      {
  81.365 -        op_bytes = 4;
  81.366 +        op_bytes = def_op_bytes = 4;
  81.367  #ifndef __x86_64__
  81.368          return -1;
  81.369  #endif
  81.370      }
  81.371  
  81.372      /* Prefix bytes. */
  81.373 -    for ( i = 0; i < 8; i++ )
  81.374 +    for ( ; ; )
  81.375      {
  81.376          switch ( b = insn_fetch_type(uint8_t) )
  81.377          {
  81.378          case 0x66: /* operand-size override */
  81.379 -            op_bytes ^= 6;      /* switch between 2/4 bytes */
  81.380 +            op_bytes = def_op_bytes ^ 6;
  81.381              break;
  81.382          case 0x67: /* address-size override */
  81.383 -            if ( mode_64bit() )
  81.384 -                ad_bytes ^= 12; /* switch between 4/8 bytes */
  81.385 -            else
  81.386 -                ad_bytes ^= 6;  /* switch between 2/4 bytes */
  81.387 +            ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6);
  81.388              break;
  81.389          case 0x2e: /* CS override */
  81.390              ea.mem.seg = x86_seg_cs;
  81.391 @@ -635,6 +758,9 @@ x86_emulate(
  81.392              goto cannot_emulate;
  81.393      }
  81.394  
  81.395 +    /* Lock prefix is allowed only on RMW instructions. */
  81.396 +    generate_exception_if((d & Mov) && lock_prefix, EXC_GP);
  81.397 +
  81.398      /* ModRM and SIB bytes. */
  81.399      if ( d & ModRM )
  81.400      {
  81.401 @@ -767,9 +893,6 @@ x86_emulate(
  81.402      case SrcMem16:
  81.403          ea.bytes = 2;
  81.404          goto srcmem_common;
  81.405 -    case SrcMem32:
  81.406 -        ea.bytes = 4;
  81.407 -        goto srcmem_common;
  81.408      case SrcMem:
  81.409          ea.bytes = (d & ByteOp) ? 1 : op_bytes;
  81.410      srcmem_common:
  81.411 @@ -838,7 +961,7 @@ x86_emulate(
  81.412          {
  81.413              /*
  81.414               * EA       += BitOffset DIV op_bytes*8
  81.415 -             * BitOffset = BitOffset MOD op_byte*8
  81.416 +             * BitOffset = BitOffset MOD op_bytes*8
  81.417               * DIV truncates towards negative infinity.
  81.418               * MOD always produces a positive result.
  81.419               */
  81.420 @@ -874,13 +997,18 @@ x86_emulate(
  81.421              case 8: dst.val = *(uint64_t *)dst.reg; break;
  81.422              }
  81.423          }
  81.424 -        else if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
  81.425 -                  (rc = ops->read(dst.mem.seg, dst.mem.off,
  81.426 -                                  &dst.val, dst.bytes, ctxt)) )
  81.427 -            goto done;
  81.428 +        else if ( !(d & Mov) ) /* optimisation - avoid slow emulated read */
  81.429 +        {
  81.430 +            if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
  81.431 +                                 &dst.val, dst.bytes, ctxt)) )
  81.432 +                goto done;
  81.433 +            dst.orig_val = dst.val;
  81.434 +        }
  81.435          break;
  81.436      }
  81.437 -    dst.orig_val = dst.val;
  81.438 +
  81.439 +    /* LOCK prefix allowed only on instructions with memory destination. */
  81.440 +    generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP);
  81.441  
  81.442      if ( twobyte )
  81.443          goto twobyte_insn;
  81.444 @@ -889,65 +1017,132 @@ x86_emulate(
  81.445      {
  81.446      case 0x04 ... 0x05: /* add imm,%%eax */
  81.447          dst.reg = (unsigned long *)&_regs.eax;
  81.448 -        dst.val = dst.orig_val = _regs.eax;
  81.449 +        dst.val = _regs.eax;
  81.450      case 0x00 ... 0x03: add: /* add */
  81.451          emulate_2op_SrcV("add", src, dst, _regs.eflags);
  81.452          break;
  81.453  
  81.454      case 0x0c ... 0x0d: /* or imm,%%eax */
  81.455          dst.reg = (unsigned long *)&_regs.eax;
  81.456 -        dst.val = dst.orig_val = _regs.eax;
  81.457 +        dst.val = _regs.eax;
  81.458      case 0x08 ... 0x0b: or:  /* or */
  81.459          emulate_2op_SrcV("or", src, dst, _regs.eflags);
  81.460          break;
  81.461  
  81.462      case 0x14 ... 0x15: /* adc imm,%%eax */
  81.463          dst.reg = (unsigned long *)&_regs.eax;
  81.464 -        dst.val = dst.orig_val = _regs.eax;
  81.465 +        dst.val = _regs.eax;
  81.466      case 0x10 ... 0x13: adc: /* adc */
  81.467          emulate_2op_SrcV("adc", src, dst, _regs.eflags);
  81.468          break;
  81.469  
  81.470      case 0x1c ... 0x1d: /* sbb imm,%%eax */
  81.471          dst.reg = (unsigned long *)&_regs.eax;
  81.472 -        dst.val = dst.orig_val = _regs.eax;
  81.473 +        dst.val = _regs.eax;
  81.474      case 0x18 ... 0x1b: sbb: /* sbb */
  81.475          emulate_2op_SrcV("sbb", src, dst, _regs.eflags);
  81.476          break;
  81.477  
  81.478      case 0x24 ... 0x25: /* and imm,%%eax */
  81.479          dst.reg = (unsigned long *)&_regs.eax;
  81.480 -        dst.val = dst.orig_val = _regs.eax;
  81.481 +        dst.val = _regs.eax;
  81.482      case 0x20 ... 0x23: and: /* and */
  81.483          emulate_2op_SrcV("and", src, dst, _regs.eflags);
  81.484          break;
  81.485  
  81.486      case 0x2c ... 0x2d: /* sub imm,%%eax */
  81.487          dst.reg = (unsigned long *)&_regs.eax;
  81.488 -        dst.val = dst.orig_val = _regs.eax;
  81.489 +        dst.val = _regs.eax;
  81.490      case 0x28 ... 0x2b: sub: /* sub */
  81.491          emulate_2op_SrcV("sub", src, dst, _regs.eflags);
  81.492          break;
  81.493  
  81.494      case 0x34 ... 0x35: /* xor imm,%%eax */
  81.495          dst.reg = (unsigned long *)&_regs.eax;
  81.496 -        dst.val = dst.orig_val = _regs.eax;
  81.497 +        dst.val = _regs.eax;
  81.498      case 0x30 ... 0x33: xor: /* xor */
  81.499          emulate_2op_SrcV("xor", src, dst, _regs.eflags);
  81.500          break;
  81.501  
  81.502      case 0x3c ... 0x3d: /* cmp imm,%%eax */
  81.503          dst.reg = (unsigned long *)&_regs.eax;
  81.504 -        dst.val = dst.orig_val = _regs.eax;
  81.505 +        dst.val = _regs.eax;
  81.506      case 0x38 ... 0x3b: cmp: /* cmp */
  81.507          emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
  81.508          break;
  81.509  
  81.510 -    case 0x63: /* movsxd */
  81.511 -        if ( !mode_64bit() )
  81.512 -            goto cannot_emulate;
  81.513 -        dst.val = (int32_t)src.val;
  81.514 +    case 0x62: /* bound */ {
  81.515 +        unsigned long src_val2;
  81.516 +        int lb, ub, idx;
  81.517 +        generate_exception_if(mode_64bit() || (src.type != OP_MEM), EXC_UD);
  81.518 +        if ( (rc = ops->read(src.mem.seg, src.mem.off + op_bytes,
  81.519 +                             &src_val2, op_bytes, ctxt)) )
  81.520 +            goto done;
  81.521 +        ub  = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2;
  81.522 +        lb  = (op_bytes == 2) ? (int16_t)src.val  : (int32_t)src.val;
  81.523 +        idx = (op_bytes == 2) ? (int16_t)dst.val  : (int32_t)dst.val;
  81.524 +        generate_exception_if((idx < lb) || (idx > ub), EXC_BR);
  81.525 +        dst.type = OP_NONE;
  81.526          break;
  81.527 +    }
  81.528 +
  81.529 +    case 0x63: /* movsxd (x86/64) / arpl (x86/32) */
  81.530 +        if ( mode_64bit() )
  81.531 +        {
  81.532 +            /* movsxd */
  81.533 +            if ( src.type == OP_REG )
  81.534 +                src.val = *(int32_t *)src.reg;
  81.535 +            else if ( (rc = ops->read(src.mem.seg, src.mem.off,
  81.536 +                                      &src.val, 4, ctxt)) )
  81.537 +                goto done;
  81.538 +            dst.val = (int32_t)src.val;
  81.539 +        }
  81.540 +        else
  81.541 +        {
  81.542 +            /* arpl */
  81.543 +            uint16_t src_val = dst.val;
  81.544 +            dst = src;
  81.545 +            _regs.eflags &= ~EFLG_ZF;
  81.546 +            _regs.eflags |= ((src_val & 3) > (dst.val & 3)) ? EFLG_ZF : 0;
  81.547 +            if ( _regs.eflags & EFLG_ZF )
  81.548 +                dst.val  = (dst.val & ~3) | (src_val & 3);
  81.549 +            else
  81.550 +                dst.type = OP_NONE;
  81.551 +        }
  81.552 +        break;
  81.553 +
  81.554 +    case 0x69: /* imul imm16/32 */
  81.555 +    case 0x6b: /* imul imm8 */ {
  81.556 +        unsigned long reg = *(long *)decode_register(modrm_reg, &_regs, 0);
  81.557 +        _regs.eflags &= ~(EFLG_OF|EFLG_CF);
  81.558 +        switch ( dst.bytes )
  81.559 +        {
  81.560 +        case 2:
  81.561 +            dst.val = ((uint32_t)(int16_t)src.val *
  81.562 +                       (uint32_t)(int16_t)reg);
  81.563 +            if ( (int16_t)dst.val != (uint32_t)dst.val )
  81.564 +                _regs.eflags |= EFLG_OF|EFLG_CF;
  81.565 +            break;
  81.566 +#ifdef __x86_64__
  81.567 +        case 4:
  81.568 +            dst.val = ((uint64_t)(int32_t)src.val *
  81.569 +                       (uint64_t)(int32_t)reg);
  81.570 +            if ( (int32_t)dst.val != dst.val )
  81.571 +                _regs.eflags |= EFLG_OF|EFLG_CF;
  81.572 +            break;
  81.573 +#endif
  81.574 +        default: {
  81.575 +            unsigned long m[2] = { src.val, reg };
  81.576 +            if ( imul_dbl(m) )
  81.577 +                _regs.eflags |= EFLG_OF|EFLG_CF;
  81.578 +            dst.val = m[0];
  81.579 +            break;
  81.580 +        }
  81.581 +        }
  81.582 +        dst.type = OP_REG;
  81.583 +        dst.reg  = decode_register(modrm_reg, &_regs, 0);
  81.584 +        break;
  81.585 +    }
  81.586  
  81.587      case 0x80 ... 0x83: /* Grp1 */
  81.588          switch ( modrm_reg & 7 )
  81.589 @@ -965,7 +1160,7 @@ x86_emulate(
  81.590  
  81.591      case 0xa8 ... 0xa9: /* test imm,%%eax */
  81.592          dst.reg = (unsigned long *)&_regs.eax;
  81.593 -        dst.val = dst.orig_val = _regs.eax;
  81.594 +        dst.val = _regs.eax;
  81.595      case 0x84 ... 0x85: test: /* test */
  81.596          emulate_2op_SrcV("test", src, dst, _regs.eflags);
  81.597          break;
  81.598 @@ -985,7 +1180,7 @@ x86_emulate(
  81.599          break;
  81.600  
  81.601      case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
  81.602 -        fail_if((modrm_reg & 7) != 0);
  81.603 +        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
  81.604      case 0x88 ... 0x8b: /* mov */
  81.605          dst.val = src.val;
  81.606          break;
  81.607 @@ -995,7 +1190,7 @@ x86_emulate(
  81.608          break;
  81.609  
  81.610      case 0x8f: /* pop (sole member of Grp1a) */
  81.611 -        fail_if((modrm_reg & 7) != 0);
  81.612 +        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
  81.613          /* 64-bit mode: POP defaults to a 64-bit operand. */
  81.614          if ( mode_64bit() && (dst.bytes == 4) )
  81.615              dst.bytes = 8;
  81.616 @@ -1077,13 +1272,190 @@ x86_emulate(
  81.617          case 3: /* neg */
  81.618              emulate_1op("neg", dst, _regs.eflags);
  81.619              break;
  81.620 +        case 4: /* mul */
  81.621 +            src = dst;
  81.622 +            dst.type = OP_REG;
  81.623 +            dst.reg  = (unsigned long *)&_regs.eax;
  81.624 +            dst.val  = *dst.reg;
  81.625 +            _regs.eflags &= ~(EFLG_OF|EFLG_CF);
  81.626 +            switch ( src.bytes )
  81.627 +            {
  81.628 +            case 1:
  81.629 +                dst.val *= src.val;
  81.630 +                if ( (uint8_t)dst.val != (uint16_t)dst.val )
  81.631 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.632 +                break;
  81.633 +            case 2:
  81.634 +                dst.val *= src.val;
  81.635 +                if ( (uint16_t)dst.val != (uint32_t)dst.val )
  81.636 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.637 +                *(uint16_t *)&_regs.edx = dst.val >> 16;
  81.638 +                break;
  81.639 +#ifdef __x86_64__
  81.640 +            case 4:
  81.641 +                dst.val *= src.val;
  81.642 +                if ( (uint32_t)dst.val != dst.val )
  81.643 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.644 +                _regs.edx = (uint32_t)(dst.val >> 32);
  81.645 +                break;
  81.646 +#endif
  81.647 +            default: {
  81.648 +                unsigned long m[2] = { src.val, dst.val };
  81.649 +                if ( mul_dbl(m) )
  81.650 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.651 +                _regs.edx = m[1];
  81.652 +                dst.val  = m[0];
  81.653 +                break;
  81.654 +            }
  81.655 +            }
  81.656 +            break;
  81.657 +        case 5: /* imul */
  81.658 +            src = dst;
  81.659 +            dst.type = OP_REG;
  81.660 +            dst.reg  = (unsigned long *)&_regs.eax;
  81.661 +            dst.val  = *dst.reg;
  81.662 +            _regs.eflags &= ~(EFLG_OF|EFLG_CF);
  81.663 +            switch ( src.bytes )
  81.664 +            {
  81.665 +            case 1:
  81.666 +                dst.val = ((uint16_t)(int8_t)src.val *
  81.667 +                           (uint16_t)(int8_t)dst.val);
  81.668 +                if ( (int8_t)dst.val != (uint16_t)dst.val )
  81.669 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.670 +                break;
  81.671 +            case 2:
  81.672 +                dst.val = ((uint32_t)(int16_t)src.val *
  81.673 +                           (uint32_t)(int16_t)dst.val);
  81.674 +                if ( (int16_t)dst.val != (uint32_t)dst.val )
  81.675 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.676 +                *(uint16_t *)&_regs.edx = dst.val >> 16;
  81.677 +                break;
  81.678 +#ifdef __x86_64__
  81.679 +            case 4:
  81.680 +                dst.val = ((uint64_t)(int32_t)src.val *
  81.681 +                           (uint64_t)(int32_t)dst.val);
  81.682 +                if ( (int32_t)dst.val != dst.val )
  81.683 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.684 +                _regs.edx = (uint32_t)(dst.val >> 32);
  81.685 +                break;
  81.686 +#endif
  81.687 +            default: {
  81.688 +                unsigned long m[2] = { src.val, dst.val };
  81.689 +                if ( imul_dbl(m) )
  81.690 +                    _regs.eflags |= EFLG_OF|EFLG_CF;
  81.691 +                _regs.edx = m[1];
  81.692 +                dst.val  = m[0];
  81.693 +                break;
  81.694 +            }
  81.695 +            }
  81.696 +            break;
  81.697 +        case 6: /* div */ {
  81.698 +            unsigned long u[2], v;
  81.699 +            src = dst;
  81.700 +            dst.type = OP_REG;
  81.701 +            dst.reg  = (unsigned long *)&_regs.eax;
  81.702 +            switch ( src.bytes )
  81.703 +            {
  81.704 +            case 1:
  81.705 +                u[0] = (uint16_t)_regs.eax;
  81.706 +                u[1] = 0;
  81.707 +                v    = (uint8_t)src.val;
  81.708 +                generate_exception_if(
  81.709 +                    div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]),
  81.710 +                    EXC_DE);
  81.711 +                dst.val = (uint8_t)u[0];
  81.712 +                ((uint8_t *)&_regs.eax)[1] = u[1];
  81.713 +                break;
  81.714 +            case 2:
  81.715 +                u[0] = ((uint32_t)_regs.edx << 16) | (uint16_t)_regs.eax;
  81.716 +                u[1] = 0;
  81.717 +                v    = (uint16_t)src.val;
  81.718 +                generate_exception_if(
  81.719 +                    div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]),
  81.720 +                    EXC_DE);
  81.721 +                dst.val = (uint16_t)u[0];
  81.722 +                *(uint16_t *)&_regs.edx = u[1];
  81.723 +                break;
  81.724 +#ifdef __x86_64__
  81.725 +            case 4:
  81.726 +                u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax;
  81.727 +                u[1] = 0;
  81.728 +                v    = (uint32_t)src.val;
  81.729 +                generate_exception_if(
  81.730 +                    div_dbl(u, v) || ((uint32_t)u[0] != u[0]),
  81.731 +                    EXC_DE);
  81.732 +                dst.val   = (uint32_t)u[0];
  81.733 +                _regs.edx = (uint32_t)u[1];
  81.734 +                break;
  81.735 +#endif
  81.736 +            default:
  81.737 +                u[0] = _regs.eax;
  81.738 +                u[1] = _regs.edx;
  81.739 +                v    = src.val;
  81.740 +                generate_exception_if(div_dbl(u, v), EXC_DE);
  81.741 +                dst.val   = u[0];
  81.742 +                _regs.edx = u[1];
  81.743 +                break;
  81.744 +            }
  81.745 +            break;
  81.746 +        }
  81.747 +        case 7: /* idiv */ {
  81.748 +            unsigned long u[2], v;
  81.749 +            src = dst;
  81.750 +            dst.type = OP_REG;
  81.751 +            dst.reg  = (unsigned long *)&_regs.eax;
  81.752 +            switch ( src.bytes )
  81.753 +            {
  81.754 +            case 1:
  81.755 +                u[0] = (int16_t)_regs.eax;
  81.756 +                u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
  81.757 +                v    = (int8_t)src.val;
  81.758 +                generate_exception_if(
  81.759 +                    idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]),
  81.760 +                    EXC_DE);
  81.761 +                dst.val = (int8_t)u[0];
  81.762 +                ((int8_t *)&_regs.eax)[1] = u[1];
  81.763 +                break;
  81.764 +            case 2:
  81.765 +                u[0] = (int32_t)((_regs.edx << 16) | (uint16_t)_regs.eax);
  81.766 +                u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
  81.767 +                v    = (int16_t)src.val;
  81.768 +                generate_exception_if(
  81.769 +                    idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]),
  81.770 +                    EXC_DE);
  81.771 +                dst.val = (int16_t)u[0];
  81.772 +                *(int16_t *)&_regs.edx = u[1];
  81.773 +                break;
  81.774 +#ifdef __x86_64__
  81.775 +            case 4:
  81.776 +                u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax;
  81.777 +                u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
  81.778 +                v    = (int32_t)src.val;
  81.779 +                generate_exception_if(
  81.780 +                    idiv_dbl(u, v) || ((int32_t)u[0] != u[0]),
  81.781 +                    EXC_DE);
  81.782 +                dst.val   = (int32_t)u[0];
  81.783 +                _regs.edx = (uint32_t)u[1];
  81.784 +                break;
  81.785 +#endif
  81.786 +            default:
  81.787 +                u[0] = _regs.eax;
  81.788 +                u[1] = _regs.edx;
  81.789 +                v    = src.val;
  81.790 +                generate_exception_if(idiv_dbl(u, v), EXC_DE);
  81.791 +                dst.val   = u[0];
  81.792 +                _regs.edx = u[1];
  81.793 +                break;
  81.794 +            }
  81.795 +            break;
  81.796 +        }
  81.797          default:
  81.798              goto cannot_emulate;
  81.799          }
  81.800          break;
  81.801  
  81.802      case 0xfe: /* Grp4 */
  81.803 -        fail_if((modrm_reg & 7) >= 2);
  81.804 +        generate_exception_if((modrm_reg & 7) >= 2, EXC_UD);
  81.805      case 0xff: /* Grp5 */
  81.806          switch ( modrm_reg & 7 )
  81.807          {
  81.808 @@ -1093,6 +1465,20 @@ x86_emulate(
  81.809          case 1: /* dec */
  81.810              emulate_1op("dec", dst, _regs.eflags);
  81.811              break;
  81.812 +        case 2: /* call (near) */
  81.813 +        case 3: /* jmp (near) */
  81.814 +            if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() )
  81.815 +            {
  81.816 +                dst.bytes = op_bytes = 8;
  81.817 +                if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
  81.818 +                                     &dst.val, 8, ctxt)) != 0 )
  81.819 +                    goto done;
  81.820 +            }
  81.821 +            src.val = _regs.eip;
  81.822 +            _regs.eip = dst.val;
  81.823 +            if ( (modrm_reg & 7) == 2 )
  81.824 +                goto push; /* call */
  81.825 +            break;
  81.826          case 6: /* push */
  81.827              /* 64-bit mode: PUSH defaults to a 64-bit operand. */
  81.828              if ( mode_64bit() && (dst.bytes == 4) )
  81.829 @@ -1106,10 +1492,10 @@ x86_emulate(
  81.830              if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp),
  81.831                                    dst.val, dst.bytes, ctxt)) != 0 )
  81.832                  goto done;
  81.833 -            dst.val = dst.orig_val; /* skanky: disable writeback */
  81.834 +            dst.type = OP_NONE;
  81.835              break;
  81.836          case 7:
  81.837 -            fail_if(1);
  81.838 +            generate_exception_if(1, EXC_UD);
  81.839          default:
  81.840              goto cannot_emulate;
  81.841          }
  81.842 @@ -1117,33 +1503,32 @@ x86_emulate(
  81.843      }
  81.844  
  81.845   writeback:
  81.846 -    if ( (d & Mov) || (dst.orig_val != dst.val) )
  81.847 +    switch ( dst.type )
  81.848      {
  81.849 -        switch ( dst.type )
  81.850 +    case OP_REG:
  81.851 +        /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
  81.852 +        switch ( dst.bytes )
  81.853          {
  81.854 -        case OP_REG:
  81.855 -            /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
  81.856 -            switch ( dst.bytes )
  81.857 -            {
  81.858 -            case 1: *(uint8_t  *)dst.reg = (uint8_t)dst.val; break;
  81.859 -            case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break;
  81.860 -            case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */
  81.861 -            case 8: *dst.reg = dst.val; break;
  81.862 -            }
  81.863 -            break;
  81.864 -        case OP_MEM:
  81.865 -            if ( lock_prefix )
  81.866 -                rc = ops->cmpxchg(
  81.867 -                    dst.mem.seg, dst.mem.off, dst.orig_val,
  81.868 -                    dst.val, dst.bytes, ctxt);
  81.869 -            else
  81.870 -                rc = ops->write(
  81.871 -                    dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt);
  81.872 -            if ( rc != 0 )
  81.873 -                goto done;
  81.874 -        default:
  81.875 -            break;
  81.876 +        case 1: *(uint8_t  *)dst.reg = (uint8_t)dst.val; break;
  81.877 +        case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break;
  81.878 +        case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */
  81.879 +        case 8: *dst.reg = dst.val; break;
  81.880          }
  81.881 +        break;
  81.882 +    case OP_MEM:
  81.883 +        if ( !(d & Mov) && (dst.orig_val == dst.val) )
  81.884 +            /* nothing to do */;
  81.885 +        else if ( lock_prefix )
  81.886 +            rc = ops->cmpxchg(
  81.887 +                dst.mem.seg, dst.mem.off, dst.orig_val,
  81.888 +                dst.val, dst.bytes, ctxt);
  81.889 +        else
  81.890 +            rc = ops->write(
  81.891 +                dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt);
  81.892 +        if ( rc != 0 )
  81.893 +            goto done;
  81.894 +    default:
  81.895 +        break;
  81.896      }
  81.897  
  81.898      /* Commit shadow register state. */
  81.899 @@ -1153,8 +1538,13 @@ x86_emulate(
  81.900      return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
  81.901  
  81.902   special_insn:
  81.903 -    /* Default action: disable writeback. There may be no dest operand. */
  81.904 -    dst.orig_val = dst.val;
  81.905 +    dst.type = OP_NONE;
  81.906 +
  81.907 +    /*
  81.908 +     * The only implicit-operands instruction allowed a LOCK prefix is
  81.909 +     * CMPXCHG{8,16}B.
  81.910 +     */
  81.911 +    generate_exception_if(lock_prefix && (b != 0xc7), EXC_GP);
  81.912  
  81.913      if ( twobyte )
  81.914          goto twobyte_special_insn;
  81.915 @@ -1175,7 +1565,7 @@ x86_emulate(
  81.916      case 0x27: /* daa */ {
  81.917          uint8_t al = _regs.eax;
  81.918          unsigned long eflags = _regs.eflags;
  81.919 -        fail_if(mode_64bit());
  81.920 +        generate_exception_if(mode_64bit(), EXC_UD);
  81.921          _regs.eflags &= ~(EFLG_CF|EFLG_AF);
  81.922          if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
  81.923          {
  81.924 @@ -1197,7 +1587,7 @@ x86_emulate(
  81.925      case 0x2f: /* das */ {
  81.926          uint8_t al = _regs.eax;
  81.927          unsigned long eflags = _regs.eflags;
  81.928 -        fail_if(mode_64bit());
  81.929 +        generate_exception_if(mode_64bit(), EXC_UD);
  81.930          _regs.eflags &= ~(EFLG_CF|EFLG_AF);
  81.931          if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
  81.932          {
  81.933 @@ -1220,7 +1610,7 @@ x86_emulate(
  81.934  
  81.935      case 0x37: /* aaa */
  81.936      case 0x3f: /* aas */
  81.937 -        fail_if(mode_64bit());
  81.938 +        generate_exception_if(mode_64bit(), EXC_UD);
  81.939          _regs.eflags &= ~EFLG_CF;
  81.940          if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) )
  81.941          {
  81.942 @@ -1235,7 +1625,7 @@ x86_emulate(
  81.943          dst.type  = OP_REG;
  81.944          dst.reg   = decode_register(b & 7, &_regs, 0);
  81.945          dst.bytes = op_bytes;
  81.946 -        dst.orig_val = dst.val = *dst.reg;
  81.947 +        dst.val   = *dst.reg;
  81.948          if ( b & 8 )
  81.949              emulate_1op("dec", dst, _regs.eflags);
  81.950          else
  81.951 @@ -1243,16 +1633,9 @@ x86_emulate(
  81.952          break;
  81.953  
  81.954      case 0x50 ... 0x57: /* push reg */
  81.955 -        dst.type  = OP_MEM;
  81.956 -        dst.bytes = op_bytes;
  81.957 -        if ( mode_64bit() && (dst.bytes == 4) )
  81.958 -            dst.bytes = 8;
  81.959 -        dst.val = *(unsigned long *)decode_register(
  81.960 +        src.val = *(unsigned long *)decode_register(
  81.961              (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
  81.962 -        register_address_increment(_regs.esp, -dst.bytes);
  81.963 -        dst.mem.seg = x86_seg_ss;
  81.964 -        dst.mem.off = truncate_ea(_regs.esp);
  81.965 -        break;
  81.966 +        goto push;
  81.967  
  81.968      case 0x58 ... 0x5f: /* pop reg */
  81.969          dst.type  = OP_REG;
  81.970 @@ -1267,6 +1650,58 @@ x86_emulate(
  81.971          register_address_increment(_regs.esp, dst.bytes);
  81.972          break;
  81.973  
  81.974 +    case 0x60: /* pusha */ {
  81.975 +        int i;
  81.976 +        unsigned long regs[] = {
  81.977 +            _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
  81.978 +            _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
  81.979 +        generate_exception_if(mode_64bit(), EXC_UD);
  81.980 +        for ( i = 0; i < 8; i++ )
  81.981 +            if ( (rc = ops->write(x86_seg_ss,
  81.982 +                                  truncate_ea(_regs.esp-(i+1)*op_bytes),
  81.983 +                                  regs[i], op_bytes, ctxt)) != 0 )
  81.984 +            goto done;
  81.985 +        register_address_increment(_regs.esp, -8*op_bytes);
  81.986 +        break;
  81.987 +    }
  81.988 +
  81.989 +    case 0x61: /* popa */ {
  81.990 +        int i;
  81.991 +        unsigned long dummy_esp, *regs[] = {
  81.992 +            (unsigned long *)&_regs.edi, (unsigned long *)&_regs.esi,
  81.993 +            (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp,
  81.994 +            (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx,
  81.995 +            (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
  81.996 +        generate_exception_if(mode_64bit(), EXC_UD);
  81.997 +        for ( i = 0; i < 8; i++ )
  81.998 +            if ( (rc = ops->read(x86_seg_ss,
  81.999 +                                 truncate_ea(_regs.esp+i*op_bytes),
 81.1000 +                                 regs[i], op_bytes, ctxt)) != 0 )
 81.1001 +            goto done;
 81.1002 +        register_address_increment(_regs.esp, 8*op_bytes);
 81.1003 +        break;
 81.1004 +    }
 81.1005 +
 81.1006 +    case 0x68: /* push imm{16,32,64} */
 81.1007 +        src.val = ((op_bytes == 2)
 81.1008 +                   ? (int32_t)insn_fetch_type(int16_t)
 81.1009 +                   : insn_fetch_type(int32_t));
 81.1010 +        goto push;
 81.1011 +
 81.1012 +    case 0x6a: /* push imm8 */
 81.1013 +        src.val = insn_fetch_type(int8_t);
 81.1014 +    push:
 81.1015 +        d |= Mov; /* force writeback */
 81.1016 +        dst.type  = OP_MEM;
 81.1017 +        dst.bytes = op_bytes;
 81.1018 +        if ( mode_64bit() && (dst.bytes == 4) )
 81.1019 +            dst.bytes = 8;
 81.1020 +        dst.val = src.val;
 81.1021 +        register_address_increment(_regs.esp, -dst.bytes);
 81.1022 +        dst.mem.seg = x86_seg_ss;
 81.1023 +        dst.mem.off = truncate_ea(_regs.esp);
 81.1024 +        break;
 81.1025 +
 81.1026      case 0x70 ... 0x7f: /* jcc (short) */ {
 81.1027          int rel = insn_fetch_type(int8_t);
 81.1028          if ( test_cc(b, _regs.eflags) )
 81.1029 @@ -1285,9 +1720,41 @@ x86_emulate(
 81.1030          src.val  = *src.reg;
 81.1031          dst.reg  = decode_register(
 81.1032              (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
 81.1033 -        dst.val  = dst.orig_val = *dst.reg;
 81.1034 +        dst.val  = *dst.reg;
 81.1035          goto xchg;
 81.1036  
 81.1037 +    case 0x98: /* cbw/cwde/cdqe */
 81.1038 +        switch ( op_bytes )
 81.1039 +        {
 81.1040 +        case 2: *(int16_t *)&_regs.eax = (int8_t)_regs.eax; break; /* cbw */
 81.1041 +        case 4: _regs.eax = (uint32_t)(int16_t)_regs.eax; break; /* cwde */
 81.1042 +        case 8: _regs.eax = (int32_t)_regs.eax; break; /* cdqe */
 81.1043 +        }
 81.1044 +        break;
 81.1045 +
 81.1046 +    case 0x99: /* cwd/cdq/cqo */
 81.1047 +        switch ( op_bytes )
 81.1048 +        {
 81.1049 +        case 2:
 81.1050 +            *(int16_t *)&_regs.edx = ((int16_t)_regs.eax < 0) ? -1 : 0;
 81.1051 +            break;
 81.1052 +        case 4:
 81.1053 +            _regs.edx = (uint32_t)(((int32_t)_regs.eax < 0) ? -1 : 0);
 81.1054 +            break;
 81.1055 +        case 8:
 81.1056 +            _regs.edx = (_regs.eax < 0) ? -1 : 0;
 81.1057 +            break;
 81.1058 +        }
 81.1059 +        break;
 81.1060 +
 81.1061 +    case 0x9e: /* sahf */
 81.1062 +        *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02;
 81.1063 +        break;
 81.1064 +
 81.1065 +    case 0x9f: /* lahf */
 81.1066 +        ((uint8_t *)&_regs.eax)[1] = (_regs.eflags & 0xd7) | 0x02;
 81.1067 +        break;
 81.1068 +
 81.1069      case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */
 81.1070          /* Source EA is not encoded via ModRM. */
 81.1071          dst.type  = OP_REG;
 81.1072 @@ -1342,10 +1809,22 @@ x86_emulate(
 81.1073              _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
 81.1074          break;
 81.1075  
 81.1076 +    case 0xc2: /* ret imm16 (near) */
 81.1077 +    case 0xc3: /* ret (near) */ {
 81.1078 +        int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0;
 81.1079 +        op_bytes = mode_64bit() ? 8 : op_bytes;
 81.1080 +        if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
 81.1081 +                             &dst.val, op_bytes, ctxt)) != 0 )
 81.1082 +            goto done;
 81.1083 +        _regs.eip = dst.val;
 81.1084 +        register_address_increment(_regs.esp, op_bytes + offset);
 81.1085 +        break;
 81.1086 +    }
 81.1087 +
 81.1088      case 0xd4: /* aam */ {
 81.1089          unsigned int base = insn_fetch_type(uint8_t);
 81.1090          uint8_t al = _regs.eax;
 81.1091 -        fail_if(mode_64bit());
 81.1092 +        generate_exception_if(mode_64bit(), EXC_UD);
 81.1093          generate_exception_if(base == 0, EXC_DE);
 81.1094          *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
 81.1095          _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
 81.1096 @@ -1358,7 +1837,7 @@ x86_emulate(
 81.1097      case 0xd5: /* aad */ {
 81.1098          unsigned int base = insn_fetch_type(uint8_t);
 81.1099          uint16_t ax = _regs.eax;
 81.1100 -        fail_if(mode_64bit());
 81.1101 +        generate_exception_if(mode_64bit(), EXC_UD);
 81.1102          *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
 81.1103          _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
 81.1104          _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
 81.1105 @@ -1368,7 +1847,7 @@ x86_emulate(
 81.1106      }
 81.1107  
 81.1108      case 0xd6: /* salc */
 81.1109 -        fail_if(mode_64bit());
 81.1110 +        generate_exception_if(mode_64bit(), EXC_UD);
 81.1111          *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00;
 81.1112          break;
 81.1113  
 81.1114 @@ -1381,6 +1860,31 @@ x86_emulate(
 81.1115          break;
 81.1116      }
 81.1117  
 81.1118 +    case 0xe0 ... 0xe2: /* loop{,z,nz} */ {
 81.1119 +        int rel = insn_fetch_type(int8_t);
 81.1120 +        int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */
 81.1121 +        if ( b == 0xe1 )
 81.1122 +            do_jmp = !do_jmp; /* loopz */
 81.1123 +        else if ( b == 0xe2 )
 81.1124 +            do_jmp = 1; /* loop */
 81.1125 +        switch ( ad_bytes )
 81.1126 +        {
 81.1127 +        case 2:
 81.1128 +            do_jmp &= --(*(uint16_t *)&_regs.ecx) != 0;
 81.1129 +            break;
 81.1130 +        case 4:
 81.1131 +            do_jmp &= --(*(uint32_t *)&_regs.ecx) != 0;
 81.1132 +            _regs.ecx = (uint32_t)_regs.ecx; /* zero extend in x86/64 mode */
 81.1133 +            break;
 81.1134 +        default: /* case 8: */
 81.1135 +            do_jmp &= --_regs.ecx != 0;
 81.1136 +            break;
 81.1137 +        }
 81.1138 +        if ( do_jmp )
 81.1139 +            jmp_rel(rel);
 81.1140 +        break;
 81.1141 +    }
 81.1142 +
 81.1143      case 0xe3: /* jcxz/jecxz (short) */ {
 81.1144          int rel = insn_fetch_type(int8_t);
 81.1145          if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx :
 81.1146 @@ -1389,12 +1893,26 @@ x86_emulate(
 81.1147          break;
 81.1148      }
 81.1149  
 81.1150 -    case 0xe9: /* jmp (short) */
 81.1151 -        jmp_rel(insn_fetch_type(int8_t));
 81.1152 +    case 0xe8: /* call (near) */ {
 81.1153 +        int rel = (((op_bytes == 2) && !mode_64bit())
 81.1154 +                   ? (int32_t)insn_fetch_type(int16_t)
 81.1155 +                   : insn_fetch_type(int32_t));
 81.1156 +        op_bytes = mode_64bit() ? 8 : op_bytes;
 81.1157 +        src.val = _regs.eip;
 81.1158 +        jmp_rel(rel);
 81.1159 +        goto push;
 81.1160 +    }
 81.1161 +
 81.1162 +    case 0xe9: /* jmp (near) */ {
 81.1163 +        int rel = (((op_bytes == 2) && !mode_64bit())
 81.1164 +                   ? (int32_t)insn_fetch_type(int16_t)
 81.1165 +                   : insn_fetch_type(int32_t));
 81.1166 +        jmp_rel(rel);
 81.1167          break;
 81.1168 +    }
 81.1169  
 81.1170 -    case 0xeb: /* jmp (near) */
 81.1171 -        jmp_rel(insn_fetch_bytes(mode_64bit() ? 4 : op_bytes));
 81.1172 +    case 0xeb: /* jmp (short) */
 81.1173 +        jmp_rel(insn_fetch_type(int8_t));
 81.1174          break;
 81.1175  
 81.1176      case 0xf5: /* cmc */
 81.1177 @@ -1422,9 +1940,14 @@ x86_emulate(
 81.1178   twobyte_insn:
 81.1179      switch ( b )
 81.1180      {
 81.1181 -    case 0x40 ... 0x4f: /* cmov */
 81.1182 -        dst.val = dst.orig_val = src.val;
 81.1183 -        d = (d & ~Mov) | (test_cc(b, _regs.eflags) ? Mov : 0);
 81.1184 +    case 0x40 ... 0x4f: /* cmovcc */
 81.1185 +        dst.val = src.val;
 81.1186 +        if ( !test_cc(b, _regs.eflags) )
 81.1187 +            dst.type = OP_NONE;
 81.1188 +        break;
 81.1189 +
 81.1190 +    case 0x90 ... 0x9f: /* setcc */
 81.1191 +        dst.val = test_cc(b, _regs.eflags);
 81.1192          break;
 81.1193  
 81.1194      case 0xb0 ... 0xb1: /* cmpxchg */
 81.1195 @@ -1459,6 +1982,34 @@ x86_emulate(
 81.1196          emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
 81.1197          break;
 81.1198  
 81.1199 +    case 0xaf: /* imul */
 81.1200 +        _regs.eflags &= ~(EFLG_OF|EFLG_CF);
 81.1201 +        switch ( dst.bytes )
 81.1202 +        {
 81.1203 +        case 2:
 81.1204 +            dst.val = ((uint32_t)(int16_t)src.val *
 81.1205 +                       (uint32_t)(int16_t)dst.val);
 81.1206 +            if ( (int16_t)dst.val != (uint32_t)dst.val )
 81.1207 +                _regs.eflags |= EFLG_OF|EFLG_CF;
 81.1208 +            break;
 81.1209 +#ifdef __x86_64__
 81.1210 +        case 4:
 81.1211 +            dst.val = ((uint64_t)(int32_t)src.val *
 81.1212 +                       (uint64_t)(int32_t)dst.val);
 81.1213 +            if ( (int32_t)dst.val != dst.val )
 81.1214 +                _regs.eflags |= EFLG_OF|EFLG_CF;
 81.1215 +            break;
 81.1216 +#endif
 81.1217 +        default: {
 81.1218 +            unsigned long m[2] = { src.val, dst.val };
 81.1219 +            if ( imul_dbl(m) )
 81.1220 +                _regs.eflags |= EFLG_OF|EFLG_CF;
 81.1221 +            dst.val = m[0];
 81.1222 +            break;
 81.1223 +        }
 81.1224 +        }
 81.1225 +        break;
 81.1226 +
 81.1227      case 0xb6: /* movzx rm8,r{16,32,64} */
 81.1228          /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */
 81.1229          dst.reg   = decode_register(modrm_reg, &_regs, 0);
 81.1230 @@ -1466,6 +2017,26 @@ x86_emulate(
 81.1231          dst.val   = (uint8_t)src.val;
 81.1232          break;
 81.1233  
 81.1234 +    case 0xbc: /* bsf */ {
 81.1235 +        int zf;
 81.1236 +        asm ( "bsf %2,%0; setc %b1"
 81.1237 +              : "=r" (dst.val), "=q" (zf)
 81.1238 +              : "r" (src.val), "1" (0) );
 81.1239 +        _regs.eflags &= ~EFLG_ZF;
 81.1240 +        _regs.eflags |= zf ? EFLG_ZF : 0;
 81.1241 +        break;
 81.1242 +    }
 81.1243 +
 81.1244 +    case 0xbd: /* bsr */ {
 81.1245 +        int zf;
 81.1246 +        asm ( "bsr %2,%0; setc %b1"
 81.1247 +              : "=r" (dst.val), "=q" (zf)
 81.1248 +              : "r" (src.val), "1" (0) );
 81.1249 +        _regs.eflags &= ~EFLG_ZF;
 81.1250 +        _regs.eflags |= zf ? EFLG_ZF : 0;
 81.1251 +        break;
 81.1252 +    }
 81.1253 +
 81.1254      case 0xb7: /* movzx rm16,r{16,32,64} */
 81.1255          dst.val = (uint16_t)src.val;
 81.1256          break;
 81.1257 @@ -1513,10 +2084,13 @@ x86_emulate(
 81.1258      {
 81.1259      case 0x0d: /* GrpP (prefetch) */
 81.1260      case 0x18: /* Grp16 (prefetch/nop) */
 81.1261 +    case 0x19 ... 0x1f: /* nop (amd-defined) */
 81.1262          break;
 81.1263  
 81.1264      case 0x80 ... 0x8f: /* jcc (near) */ {
 81.1265 -        int rel = insn_fetch_bytes(mode_64bit() ? 4 : op_bytes);
 81.1266 +        int rel = (((op_bytes == 2) && !mode_64bit())
 81.1267 +                   ? (int32_t)insn_fetch_type(int16_t)
 81.1268 +                   : insn_fetch_type(int32_t));
 81.1269          if ( test_cc(b, _regs.eflags) )
 81.1270              jmp_rel(rel);
 81.1271          break;
 81.1272 @@ -1572,6 +2146,37 @@ x86_emulate(
 81.1273          break;
 81.1274      }
 81.1275  #endif
 81.1276 +
 81.1277 +    case 0xc8 ... 0xcf: /* bswap */
 81.1278 +        dst.type  = OP_REG;
 81.1279 +        dst.reg   = decode_register(b & 7, &_regs, 0);
 81.1280 +        dst.val = *dst.reg;
 81.1281 +        switch ( dst.bytes = op_bytes )
 81.1282 +        {
 81.1283 +        case 2:
 81.1284 +            dst.val = (((dst.val & 0x00FFUL) << 8) |
 81.1285 +                       ((dst.val & 0xFF00UL) >> 8));
 81.1286 +            break;
 81.1287 +        case 4:
 81.1288 +            dst.val = (((dst.val & 0x000000FFUL) << 24) |
 81.1289 +                       ((dst.val & 0x0000FF00UL) <<  8) |
 81.1290 +                       ((dst.val & 0x00FF0000UL) >>  8) |
 81.1291 +                       ((dst.val & 0xFF000000UL) >> 24));
 81.1292 +            break;
 81.1293 +#ifdef __x86_64__
 81.1294 +        case 8:
 81.1295 +            dst.val = (((dst.val & 0x00000000000000FFUL) << 56) |
 81.1296 +                       ((dst.val & 0x000000000000FF00UL) << 40) |
 81.1297 +                       ((dst.val & 0x0000000000FF0000UL) << 24) |
 81.1298 +                       ((dst.val & 0x00000000FF000000UL) <<  8) |
 81.1299 +                       ((dst.val & 0x000000FF00000000UL) >>  8) |
 81.1300 +                       ((dst.val & 0x0000FF0000000000UL) >> 24) |
 81.1301 +                       ((dst.val & 0x00FF000000000000UL) >> 40) |
 81.1302 +                       ((dst.val & 0xFF00000000000000UL) >> 56));
 81.1303 +            break;
 81.1304 +#endif
 81.1305 +        }
 81.1306 +        break;
 81.1307      }
 81.1308      goto writeback;
 81.1309  
    82.1 --- a/xen/common/elf.c	Sun Jan 14 22:18:38 2007 -0700
    82.2 +++ b/xen/common/elf.c	Mon Jan 15 15:15:26 2007 -0700
    82.3 @@ -300,7 +300,7 @@ int parseelfimage(struct domain_setup_in
    82.4      if ( dsi->__elfnote_section )
    82.5      {
    82.6          p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
    82.7 -        if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
    82.8 +        if ( p != NULL && strstr(p, "bimodal") != NULL )
    82.9              dsi->pae_kernel = PAEKERN_bimodal;
   82.10          else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   82.11              dsi->pae_kernel = PAEKERN_extended_cr3;
    83.1 --- a/xen/common/kexec.c	Sun Jan 14 22:18:38 2007 -0700
    83.2 +++ b/xen/common/kexec.c	Mon Jan 15 15:15:26 2007 -0700
    83.3 @@ -51,19 +51,9 @@ xen_kexec_reserve_t kexec_crash_area;
    83.4  
    83.5  static void __init parse_crashkernel(const char *str)
    83.6  {
    83.7 -    unsigned long start, size;
    83.8 -
    83.9 -    size = parse_size_and_unit(str, &str);
   83.10 +    kexec_crash_area.size = parse_size_and_unit(str, &str);
   83.11      if ( *str == '@' )
   83.12 -        start = parse_size_and_unit(str+1, NULL);
   83.13 -    else
   83.14 -        start = 0;
   83.15 -
   83.16 -    if ( start && size )
   83.17 -    {
   83.18 -        kexec_crash_area.start = start;
   83.19 -        kexec_crash_area.size = size;
   83.20 -    }
   83.21 +        kexec_crash_area.start = parse_size_and_unit(str+1, NULL);
   83.22  }
   83.23  custom_param("crashkernel", parse_crashkernel);
   83.24  
   83.25 @@ -158,8 +148,12 @@ static void setup_note(Elf_Note *n, cons
   83.26  
   83.27  static int kexec_get(reserve)(xen_kexec_range_t *range)
   83.28  {
   83.29 -    range->start = kexec_crash_area.start;
   83.30 -    range->size = kexec_crash_area.size;
   83.31 +    if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0) {
   83.32 +        range->start = kexec_crash_area.start;
   83.33 +        range->size = kexec_crash_area.size;
   83.34 +    }
   83.35 +    else
   83.36 +        range->start = range->size = 0;
   83.37      return 0;
   83.38  }
   83.39  
    84.1 --- a/xen/common/keyhandler.c	Sun Jan 14 22:18:38 2007 -0700
    84.2 +++ b/xen/common/keyhandler.c	Mon Jan 15 15:15:26 2007 -0700
    84.3 @@ -95,6 +95,11 @@ static void show_handlers(unsigned char 
    84.4  static void __dump_execstate(void *unused)
    84.5  {
    84.6      dump_execution_state();
    84.7 +    printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
    84.8 +    if ( is_idle_vcpu(current) )
    84.9 +        printk("No guest context (CPU is idle).\n");
   84.10 +    else
   84.11 +        show_execution_state(guest_cpu_user_regs());
   84.12  }
   84.13  
   84.14  static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
   84.15 @@ -104,16 +109,18 @@ static void dump_registers(unsigned char
   84.16      printk("'%c' pressed -> dumping registers\n", key);
   84.17  
   84.18      /* Get local execution state out immediately, in case we get stuck. */
   84.19 -    printk("\n*** Dumping CPU%d state: ***\n", smp_processor_id());
   84.20 -    show_execution_state(regs);
   84.21 +    printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
   84.22 +    __dump_execstate(NULL);
   84.23  
   84.24      for_each_online_cpu ( cpu )
   84.25      {
   84.26          if ( cpu == smp_processor_id() )
   84.27              continue;
   84.28 -        printk("\n*** Dumping CPU%d state: ***\n", cpu);
   84.29 +        printk("\n*** Dumping CPU%d host state: ***\n", cpu);
   84.30          on_selected_cpus(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
   84.31      }
   84.32 +
   84.33 +    printk("\n");
   84.34  }
   84.35  
   84.36  static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
    85.1 --- a/xen/common/lib.c	Sun Jan 14 22:18:38 2007 -0700
    85.2 +++ b/xen/common/lib.c	Mon Jan 15 15:15:26 2007 -0700
    85.3 @@ -1,41 +1,44 @@
    85.4  
    85.5  #include <xen/ctype.h>
    85.6  #include <xen/lib.h>
    85.7 -
    85.8 +#include <xen/types.h>
    85.9  
   85.10 -/* for inc/ctype.h */
   85.11 +/* for ctype.h */
   85.12  unsigned char _ctype[] = {
   85.13 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
   85.14 -_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
   85.15 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
   85.16 -_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
   85.17 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
   85.18 -_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
   85.19 -_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
   85.20 -_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
   85.21 -_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
   85.22 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
   85.23 -_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
   85.24 -_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
   85.25 -_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
   85.26 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
   85.27 -_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
   85.28 -_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
   85.29 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
   85.30 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
   85.31 -_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
   85.32 -_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
   85.33 -_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
   85.34 -_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
   85.35 -_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
   85.36 -_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
   85.37 +    _C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
   85.38 +    _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
   85.39 +    _C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
   85.40 +    _C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
   85.41 +    _S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
   85.42 +    _P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
   85.43 +    _D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
   85.44 +    _D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
   85.45 +    _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
   85.46 +    _U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
   85.47 +    _U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
   85.48 +    _U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
   85.49 +    _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
   85.50 +    _L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
   85.51 +    _L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
   85.52 +    _L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
   85.53 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
   85.54 +    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
   85.55 +    _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
   85.56 +    _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
   85.57 +    _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
   85.58 +    _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
   85.59 +    _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
   85.60 +    _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
   85.61  
   85.62 -
   85.63 -/* a couple of 64 bit operations ported from freebsd */
   85.64 -
   85.65 -/*-
   85.66 +/*
   85.67 + * A couple of 64 bit operations ported from FreeBSD.
   85.68 + * The code within the '#if BITS_PER_LONG == 32' block below, and no other
   85.69 + * code in this file, is distributed under the following licensing terms
   85.70 + * This is the modified '3-clause' BSD license with the obnoxious
   85.71 + * advertising clause removed, as permitted by University of California.
   85.72 + *
   85.73   * Copyright (c) 1992, 1993
   85.74 - *	The Regents of the University of California.  All rights reserved.
   85.75 + * The Regents of the University of California.  All rights reserved.
   85.76   *
   85.77   * This software was developed by the Computer Systems Engineering group
   85.78   * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
   85.79 @@ -49,11 +52,7 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        
   85.80   * 2. Redistributions in binary form must reproduce the above copyright
   85.81   *    notice, this list of conditions and the following disclaimer in the
   85.82   *    documentation and/or other materials provided with the distribution.
   85.83 - * 3. All advertising materials mentioning features or use of this software
   85.84 - *    must display the following acknowledgement:
   85.85 - *	This product includes software developed by the University of
   85.86 - *	California, Berkeley and its contributors.
   85.87 - * 4. Neither the name of the University nor the names of its contributors
   85.88 + * 3. Neither the name of the University nor the names of its contributors
   85.89   *    may be used to endorse or promote products derived from this software
   85.90   *    without specific prior written permission.
   85.91   *
   85.92 @@ -68,12 +67,7 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        
   85.93   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   85.94   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   85.95   * SUCH DAMAGE.
   85.96 - *
   85.97 - * $FreeBSD: src/sys/libkern/divdi3.c,v 1.6 1999/08/28 00:46:31 peter Exp $
   85.98   */
   85.99 -
  85.100 -#include <asm/types.h>
  85.101 -
  85.102  #if BITS_PER_LONG == 32
  85.103  
  85.104  /*
  85.105 @@ -81,10 +75,10 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        
  85.106   * one or more of the following formats.
  85.107   */
  85.108  union uu {
  85.109 -        s64            q;              /* as a (signed) quad */
  85.110 -        s64            uq;             /* as an unsigned quad */
  85.111 -        long           sl[2];          /* as two signed longs */
  85.112 -        unsigned long  ul[2];          /* as two unsigned longs */
  85.113 +    s64            q;              /* as a (signed) quad */
  85.114 +    s64            uq;             /* as an unsigned quad */
  85.115 +    long           sl[2];          /* as two signed longs */
  85.116 +    unsigned long  ul[2];          /* as two unsigned longs */
  85.117  };
  85.118  /* XXX RN: Yuck hardcoded endianess :) */
  85.119  #define _QUAD_HIGHWORD 1
  85.120 @@ -122,31 +116,26 @@ union uu {
  85.121   * Multiprecision divide.  This algorithm is from Knuth vol. 2 (2nd ed),
  85.122   * section 4.3.1, pp. 257--259.
  85.123   */
  85.124 -#define	B	(1 << HALF_BITS)	/* digit base */
  85.125 +#define B (1 << HALF_BITS) /* digit base */
  85.126  
  85.127  /* Combine two `digits' to make a single two-digit number. */
  85.128 -#define	COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
  85.129 +#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
  85.130  
  85.131 -/* select a type for digits in base B: use unsigned short if they fit */
  85.132 -#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
  85.133 -typedef unsigned short digit;
  85.134 -#else
  85.135 +/* select a type for digits in base B */
  85.136  typedef u_long digit;
  85.137 -#endif
  85.138  
  85.139  /*
  85.140   * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
  85.141   * `fall out' the left (there never will be any such anyway).
  85.142   * We may assume len >= 0.  NOTE THAT THIS WRITES len+1 DIGITS.
  85.143   */
  85.144 -static void
  85.145 -shl(register digit *p, register int len, register int sh)
  85.146 +static void shl(register digit *p, register int len, register int sh)
  85.147  {
  85.148 -	register int i;
  85.149 +    register int i;
  85.150  
  85.151 -	for (i = 0; i < len; i++)
  85.152 -		p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
  85.153 -	p[i] = LHALF(p[i] << sh);
  85.154 +    for (i = 0; i < len; i++)
  85.155 +        p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
  85.156 +    p[i] = LHALF(p[i] << sh);
  85.157  }
  85.158  
  85.159  /*
  85.160 @@ -157,234 +146,222 @@ shl(register digit *p, register int len,
  85.161   * divisor are 4 `digits' in this base (they are shorter if they have
  85.162   * leading zeros).
  85.163   */
  85.164 -u64
  85.165 -__qdivrem(u64 uq, u64 vq, u64 *arq)
  85.166 +u64 __qdivrem(u64 uq, u64 vq, u64 *arq)
  85.167  {
  85.168 -	union uu tmp;
  85.169 -	digit *u, *v, *q;
  85.170 -	register digit v1, v2;
  85.171 -	u_long qhat, rhat, t;
  85.172 -	int m, n, d, j, i;
  85.173 -	digit uspace[5], vspace[5], qspace[5];
  85.174 +    union uu tmp;
  85.175 +    digit *u, *v, *q;
  85.176 +    register digit v1, v2;
  85.177 +    u_long qhat, rhat, t;
  85.178 +    int m, n, d, j, i;
  85.179 +    digit uspace[5], vspace[5], qspace[5];
  85.180  
  85.181 -	/*
  85.182 -	 * Take care of special cases: divide by zero, and u < v.
  85.183 -	 */
  85.184 -	if (vq == 0) {
  85.185 -		/* divide by zero. */
  85.186 -		static volatile const unsigned int zero = 0;
  85.187 +    /*
  85.188 +     * Take care of special cases: divide by zero, and u < v.
  85.189 +     */
  85.190 +    if (vq == 0) {
  85.191 +        /* divide by zero. */
  85.192 +        static volatile const unsigned int zero = 0;
  85.193  
  85.194 -		tmp.ul[H] = tmp.ul[L] = 1 / zero;
  85.195 -		if (arq)
  85.196 -			*arq = uq;
  85.197 -		return (tmp.q);
  85.198 -	}
  85.199 -	if (uq < vq) {
  85.200 -		if (arq)
  85.201 -			*arq = uq;
  85.202 -		return (0);
  85.203 -	}
  85.204 -	u = &uspace[0];
  85.205 -	v = &vspace[0];
  85.206 -	q = &qspace[0];
  85.207 +        tmp.ul[H] = tmp.ul[L] = 1 / zero;
  85.208 +        if (arq)
  85.209 +            *arq = uq;
  85.210 +        return (tmp.q);
  85.211 +    }
  85.212 +    if (uq < vq) {
  85.213 +        if (arq)
  85.214 +            *arq = uq;
  85.215 +        return (0);
  85.216 +    }
  85.217 +    u = &uspace[0];
  85.218 +    v = &vspace[0];
  85.219 +    q = &qspace[0];
  85.220  
  85.221 -	/*
  85.222 -	 * Break dividend and divisor into digits in base B, then
  85.223 -	 * count leading zeros to determine m and n.  When done, we
  85.224 -	 * will have:
  85.225 -	 *	u = (u[1]u[2]...u[m+n]) sub B
  85.226 -	 *	v = (v[1]v[2]...v[n]) sub B
  85.227 -	 *	v[1] != 0
  85.228 -	 *	1 < n <= 4 (if n = 1, we use a different division algorithm)
  85.229 -	 *	m >= 0 (otherwise u < v, which we already checked)
  85.230 -	 *	m + n = 4
  85.231 -	 * and thus
  85.232 -	 *	m = 4 - n <= 2
  85.233 -	 */
  85.234 -	tmp.uq = uq;
  85.235 -	u[0] = 0;
  85.236 -	u[1] = HHALF(tmp.ul[H]);
  85.237 -	u[2] = LHALF(tmp.ul[H]);
  85.238 -	u[3] = HHALF(tmp.ul[L]);
  85.239 -	u[4] = LHALF(tmp.ul[L]);
  85.240 -	tmp.uq = vq;
  85.241 -	v[1] = HHALF(tmp.ul[H]);
  85.242 -	v[2] = LHALF(tmp.ul[H]);
  85.243 -	v[3] = HHALF(tmp.ul[L]);
  85.244 -	v[4] = LHALF(tmp.ul[L]);
  85.245 -	for (n = 4; v[1] == 0; v++) {
  85.246 -		if (--n == 1) {
  85.247 -			u_long rbj;	/* r*B+u[j] (not root boy jim) */
  85.248 -			digit q1, q2, q3, q4;
  85.249 +    /*
  85.250 +     * Break dividend and divisor into digits in base B, then
  85.251 +     * count leading zeros to determine m and n.  When done, we
  85.252 +     * will have:
  85.253 +     * u = (u[1]u[2]...u[m+n]) sub B
  85.254 +     * v = (v[1]v[2]...v[n]) sub B
  85.255 +     * v[1] != 0
  85.256 +     * 1 < n <= 4 (if n = 1, we use a different division algorithm)
  85.257 +     * m >= 0 (otherwise u < v, which we already checked)
  85.258 +     * m + n = 4
  85.259 +     * and thus
  85.260 +     * m = 4 - n <= 2
  85.261 +     */
  85.262 +    tmp.uq = uq;
  85.263 +    u[0] = 0;
  85.264 +    u[1] = HHALF(tmp.ul[H]);
  85.265 +    u[2] = LHALF(tmp.ul[H]);
  85.266 +    u[3] = HHALF(tmp.ul[L]);
  85.267 +    u[4] = LHALF(tmp.ul[L]);
  85.268 +    tmp.uq = vq;
  85.269 +    v[1] = HHALF(tmp.ul[H]);
  85.270 +    v[2] = LHALF(tmp.ul[H]);
  85.271 +    v[3] = HHALF(tmp.ul[L]);
  85.272 +    v[4] = LHALF(tmp.ul[L]);
  85.273 +    for (n = 4; v[1] == 0; v++) {
  85.274 +        if (--n == 1) {
  85.275 +            u_long rbj; /* r*B+u[j] (not root boy jim) */
  85.276 +            digit q1, q2, q3, q4;
  85.277  
  85.278 -			/*
  85.279 -			 * Change of plan, per exercise 16.
  85.280 -			 *	r = 0;
  85.281 -			 *	for j = 1..4:
  85.282 -			 *		q[j] = floor((r*B + u[j]) / v),
  85.283 -			 *		r = (r*B + u[j]) % v;
  85.284 -			 * We unroll this completely here.
  85.285 -			 */
  85.286 -			t = v[2];	/* nonzero, by definition */
  85.287 -			q1 = u[1] / t;
  85.288 -			rbj = COMBINE(u[1] % t, u[2]);
  85.289 -			q2 = rbj / t;
  85.290 -			rbj = COMBINE(rbj % t, u[3]);
  85.291 -			q3 = rbj / t;
  85.292 -			rbj = COMBINE(rbj % t, u[4]);
  85.293 -			q4 = rbj / t;
  85.294 -			if (arq)
  85.295 -				*arq = rbj % t;
  85.296 -			tmp.ul[H] = COMBINE(q1, q2);
  85.297 -			tmp.ul[L] = COMBINE(q3, q4);
  85.298 -			return (tmp.q);
  85.299 -		}
  85.300 -	}
  85.301 +            /*
  85.302 +             * Change of plan, per exercise 16.
  85.303 +             * r = 0;
  85.304 +             * for j = 1..4:
  85.305 +             *  q[j] = floor((r*B + u[j]) / v),
  85.306 +             *  r = (r*B + u[j]) % v;
  85.307 +             * We unroll this completely here.
  85.308 +             */
  85.309 +            t = v[2]; /* nonzero, by definition */
  85.310 +            q1 = u[1] / t;
  85.311 +            rbj = COMBINE(u[1] % t, u[2]);
  85.312 +            q2 = rbj / t;
  85.313 +            rbj = COMBINE(rbj % t, u[3]);
  85.314 +            q3 = rbj / t;
  85.315 +            rbj = COMBINE(rbj % t, u[4]);
  85.316 +            q4 = rbj / t;
  85.317 +            if (arq)
  85.318 +                *arq = rbj % t;
  85.319 +            tmp.ul[H] = COMBINE(q1, q2);
  85.320 +            tmp.ul[L] = COMBINE(q3, q4);
  85.321 +            return (tmp.q);
  85.322 +        }
  85.323 +    }
  85.324  
  85.325 -	/*
  85.326 -	 * By adjusting q once we determine m, we can guarantee that
  85.327 -	 * there is a complete four-digit quotient at &qspace[1] when
  85.328 -	 * we finally stop.
  85.329 -	 */
  85.330 -	for (m = 4 - n; u[1] == 0; u++)
  85.331 -		m--;
  85.332 -	for (i = 4 - m; --i >= 0;)
  85.333 -		q[i] = 0;
  85.334 -	q += 4 - m;
  85.335 +    /*
  85.336 +     * By adjusting q once we determine m, we can guarantee that
  85.337 +     * there is a complete four-digit quotient at &qspace[1] when
  85.338 +     * we finally stop.
  85.339 +     */
  85.340 +    for (m = 4 - n; u[1] == 0; u++)
  85.341 +        m--;
  85.342 +    for (i = 4 - m; --i >= 0;)
  85.343 +        q[i] = 0;
  85.344 +    q += 4 - m;
  85.345  
  85.346 -	/*
  85.347 -	 * Here we run Program D, translated from MIX to C and acquiring
  85.348 -	 * a few minor changes.
  85.349 -	 *
  85.350 -	 * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
  85.351 -	 */
  85.352 -	d = 0;
  85.353 -	for (t = v[1]; t < B / 2; t <<= 1)
  85.354 -		d++;
  85.355 -	if (d > 0) {
  85.356 -		shl(&u[0], m + n, d);		/* u <<= d */
  85.357 -		shl(&v[1], n - 1, d);		/* v <<= d */
  85.358 -	}
  85.359 -	/*
  85.360 -	 * D2: j = 0.
  85.361 -	 */
  85.362 -	j = 0;
  85.363 -	v1 = v[1];	/* for D3 -- note that v[1..n] are constant */
  85.364 -	v2 = v[2];	/* for D3 */
  85.365 -	do {
  85.366 -		register digit uj0, uj1, uj2;
  85.367 +    /*
  85.368 +     * Here we run Program D, translated from MIX to C and acquiring
  85.369 +     * a few minor changes.
  85.370 +     *
  85.371 +     * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
  85.372 +     */
  85.373 +    d = 0;
  85.374 +    for (t = v[1]; t < B / 2; t <<= 1)
  85.375 +        d++;
  85.376 +    if (d > 0) {
  85.377 +        shl(&u[0], m + n, d);  /* u <<= d */
  85.378 +        shl(&v[1], n - 1, d);  /* v <<= d */
  85.379 +    }
  85.380 +    /*
  85.381 +     * D2: j = 0.
  85.382 +     */
  85.383 +    j = 0;
  85.384 +    v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
  85.385 +    v2 = v[2]; /* for D3 */
  85.386 +    do {
  85.387 +        register digit uj0, uj1, uj2;
  85.388  
  85.389 -		/*
  85.390 -		 * D3: Calculate qhat (\^q, in TeX notation).
  85.391 -		 * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
  85.392 -		 * let rhat = (u[j]*B + u[j+1]) mod v[1].
  85.393 -		 * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
  85.394 -		 * decrement qhat and increase rhat correspondingly.
  85.395 -		 * Note that if rhat >= B, v[2]*qhat < rhat*B.
  85.396 -		 */
  85.397 -		uj0 = u[j + 0];	/* for D3 only -- note that u[j+...] change */
  85.398 -		uj1 = u[j + 1];	/* for D3 only */
  85.399 -		uj2 = u[j + 2];	/* for D3 only */
  85.400 -		if (uj0 == v1) {
  85.401 -			qhat = B;
  85.402 -			rhat = uj1;
  85.403 -			goto qhat_too_big;
  85.404 -		} else {
  85.405 -			u_long nn = COMBINE(uj0, uj1);
  85.406 -			qhat = nn / v1;
  85.407 -			rhat = nn % v1;
  85.408 -		}
  85.409 -		while (v2 * qhat > COMBINE(rhat, uj2)) {
  85.410 -	qhat_too_big:
  85.411 -			qhat--;
  85.412 -			if ((rhat += v1) >= B)
  85.413 -				break;
  85.414 -		}
  85.415 -		/*
  85.416 -		 * D4: Multiply and subtract.
  85.417 -		 * The variable `t' holds any borrows across the loop.
  85.418 -		 * We split this up so that we do not require v[0] = 0,
  85.419 -		 * and to eliminate a final special case.
  85.420 -		 */
  85.421 -		for (t = 0, i = n; i > 0; i--) {
  85.422 -			t = u[i + j] - v[i] * qhat - t;
  85.423 -			u[i + j] = LHALF(t);
  85.424 -			t = (B - HHALF(t)) & (B - 1);
  85.425 -		}
  85.426 -		t = u[j] - t;
  85.427 -		u[j] = LHALF(t);
  85.428 -		/*
  85.429 -		 * D5: test remainder.
  85.430 -		 * There is a borrow if and only if HHALF(t) is nonzero;
  85.431 -		 * in that (rare) case, qhat was too large (by exactly 1).
  85.432 -		 * Fix it by adding v[1..n] to u[j..j+n].
  85.433 -		 */
  85.434 -		if (HHALF(t)) {
  85.435 -			qhat--;
  85.436 -			for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
  85.437 -				t += u[i + j] + v[i];
  85.438 -				u[i + j] = LHALF(t);
  85.439 -				t = HHALF(t);
  85.440 -			}
  85.441 -			u[j] = LHALF(u[j] + t);
  85.442 -		}
  85.443 -		q[j] = qhat;
  85.444 -	} while (++j <= m);		/* D7: loop on j. */
  85.445 +        /*
  85.446 +         * D3: Calculate qhat (\^q, in TeX notation).
  85.447 +         * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
  85.448 +         * let rhat = (u[j]*B + u[j+1]) mod v[1].
  85.449 +         * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
  85.450 +         * decrement qhat and increase rhat correspondingly.
  85.451 +         * Note that if rhat >= B, v[2]*qhat < rhat*B.
  85.452 +         */
  85.453 +        uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
  85.454 +        uj1 = u[j + 1]; /* for D3 only */
  85.455 +        uj2 = u[j + 2]; /* for D3 only */
  85.456 +        if (uj0 == v1) {
  85.457 +            qhat = B;
  85.458 +            rhat = uj1;
  85.459 +            goto qhat_too_big;
  85.460 +        } else {
  85.461 +            u_long nn = COMBINE(uj0, uj1);
  85.462 +            qhat = nn / v1;
  85.463 +            rhat = nn % v1;
  85.464 +        }
  85.465 +        while (v2 * qhat > COMBINE(rhat, uj2)) {
  85.466 +        qhat_too_big:
  85.467 +            qhat--;
  85.468 +            if ((rhat += v1) >= B)
  85.469 +                break;
  85.470 +        }
  85.471 +        /*
  85.472 +         * D4: Multiply and subtract.
  85.473 +         * The variable `t' holds any borrows across the loop.
  85.474 +         * We split this up so that we do not require v[0] = 0,
  85.475 +         * and to eliminate a final special case.
  85.476 +         */
  85.477 +        for (t = 0, i = n; i > 0; i--) {
  85.478 +            t = u[i + j] - v[i] * qhat - t;
  85.479 +            u[i + j] = LHALF(t);
  85.480 +            t = (B - HHALF(t)) & (B - 1);
  85.481 +        }
  85.482 +        t = u[j] - t;
  85.483 +        u[j] = LHALF(t);
  85.484 +        /*
  85.485 +         * D5: test remainder.
  85.486 +         * There is a borrow if and only if HHALF(t) is nonzero;
  85.487 +         * in that (rare) case, qhat was too large (by exactly 1).
  85.488 +         * Fix it by adding v[1..n] to u[j..j+n].
  85.489 +         */
  85.490 +        if (HHALF(t)) {
  85.491 +            qhat--;
  85.492 +            for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
  85.493 +                t += u[i + j] + v[i];
  85.494 +                u[i + j] = LHALF(t);
  85.495 +                t = HHALF(t);
  85.496 +            }
  85.497 +            u[j] = LHALF(u[j] + t);
  85.498 +        }
  85.499 +        q[j] = qhat;
  85.500 +    } while (++j <= m);  /* D7: loop on j. */
  85.501  
  85.502 -	/*
  85.503 -	 * If caller wants the remainder, we have to calculate it as
  85.504 -	 * u[m..m+n] >> d (this is at most n digits and thus fits in
  85.505 -	 * u[m+1..m+n], but we may need more source digits).
  85.506 -	 */
  85.507 -	if (arq) {
  85.508 -		if (d) {
  85.509 -			for (i = m + n; i > m; --i)
  85.510 -				u[i] = (u[i] >> d) |
  85.511 -				    LHALF(u[i - 1] << (HALF_BITS - d));
  85.512 -			u[i] = 0;
  85.513 -		}
  85.514 -		tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
  85.515 -		tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
  85.516 -		*arq = tmp.q;
  85.517 -	}
  85.518 +    /*
  85.519 +     * If caller wants the remainder, we have to calculate it as
  85.520 +     * u[m..m+n] >> d (this is at most n digits and thus fits in
  85.521 +     * u[m+1..m+n], but we may need more source digits).
  85.522 +     */
  85.523 +    if (arq) {
  85.524 +        if (d) {
  85.525 +            for (i = m + n; i > m; --i)
  85.526 +                u[i] = (u[i] >> d) |
  85.527 +                    LHALF(u[i - 1] << (HALF_BITS - d));
  85.528 +            u[i] = 0;
  85.529 +        }
  85.530 +        tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
  85.531 +        tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
  85.532 +        *arq = tmp.q;
  85.533 +    }
  85.534  
  85.535 -	tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
  85.536 -	tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
  85.537 -	return (tmp.q);
  85.538 +    tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
  85.539 +    tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
  85.540 +    return (tmp.q);
  85.541  }
  85.542  
  85.543  /*
  85.544   * Divide two signed quads.
  85.545 - * ??? if -1/2 should produce -1 on this machine, this code is wrong
  85.546 - * (Grzegorz Milos) Note for the above: -1/2 is 0. And so it should.
  85.547 + * Truncates towards zero, as required by C99.
  85.548   */
  85.549 -s64
  85.550 -__divdi3(s64 a, s64 b)
  85.551 +s64 __divdi3(s64 a, s64 b)
  85.552  {
  85.553 -	u64 ua, ub, uq;
  85.554 -	int neg;
  85.555 -
  85.556 -	if (a < 0)
  85.557 -		ua = -(u64)a, neg = 1;
  85.558 -	else
  85.559 -		ua = a, neg = 0;
  85.560 -	if (b < 0)
  85.561 -		ub = -(u64)b, neg ^= 1;
  85.562 -	else
  85.563 -		ub = b;
  85.564 -	uq = __qdivrem(ua, ub, (u64 *)0);
  85.565 -	return (neg ? -uq : uq);
  85.566 +    u64 ua, ub, uq;
  85.567 +    int neg = (a < 0) ^ (b < 0);
  85.568 +    ua = (a < 0) ? -(u64)a : a;
  85.569 +    ub = (b < 0) ? -(u64)b : b;
  85.570 +    uq = __qdivrem(ua, ub, (u64 *)0);
  85.571 +    return (neg ? -uq : uq);
  85.572  }
  85.573  
  85.574  
  85.575  /*
  85.576   * Divide two unsigned quads.
  85.577   */
  85.578 -u64
  85.579 -__udivdi3(u64 a, u64 b)
  85.580 +u64 __udivdi3(u64 a, u64 b)
  85.581  {
  85.582 -
  85.583 -        return (__qdivrem(a, b, (u64 *)0));
  85.584 +    return __qdivrem(a, b, (u64 *)0);
  85.585  }
  85.586  
  85.587  /*
  85.588 @@ -392,87 +369,66 @@ u64
  85.589   */
  85.590  u64 __umoddi3(u64 a, u64 b)
  85.591  {
  85.592 -	u64 rem;
  85.593 -	__qdivrem(a, b, &rem);
  85.594 -	return rem;
  85.595 +    u64 rem;
  85.596 +    __qdivrem(a, b, &rem);
  85.597 +    return rem;
  85.598  }
  85.599  
  85.600  /*
  85.601   * Remainder of signed quad division.
  85.602 - * The result of mod is not always equal to division
  85.603 - * remainder. The following example shows the result for all
  85.604 - * four possible cases:
  85.605 + * Truncates towards zero, as required by C99:
  85.606   *  11 %  5 =  1
  85.607 - * -11 %  5 =  4
  85.608 - *  11 % -5 = -4
  85.609 - * -11 % -5 = -1
  85.610 + * -11 %  5 = -1
  85.611 + *  11 % -5 =  1
  85.612 + * -11 % -5 =  1
  85.613   */
  85.614  s64 __moddi3(s64 a, s64 b)
  85.615  {
  85.616 -	u64 ua, ub, urem;
  85.617 -	int neg1, neg2;
  85.618 -
  85.619 -	if (a < 0)
  85.620 -		ua = -(u64)a, neg1 = 1;
  85.621 -	else
  85.622 -		ua = a, neg1 = 0;
  85.623 -        
  85.624 -	if (b < 0)
  85.625 -		ub = -(u64)b, neg2 = 1;
  85.626 -	else
  85.627 -		ub = b, neg2 = 0;
  85.628 -	__qdivrem(ua, ub, &urem);
  85.629 -    
  85.630 -	/* There 4 different cases: */
  85.631 -	if (neg1) {
  85.632 -		if (neg2)
  85.633 -			return -urem;
  85.634 -		else
  85.635 -			return ub - urem;
  85.636 -	} else {
  85.637 -		if (neg2)
  85.638 -			return -ub + urem;
  85.639 -		else
  85.640 -			return urem;
  85.641 -	}
  85.642 +    u64 ua, ub, urem;
  85.643 +    int neg = (a < 0);
  85.644 +    ua = neg ? -(u64)a : a;
  85.645 +    ub = (b < 0) ? -(u64)b : b;
  85.646 +    __qdivrem(ua, ub, &urem);
  85.647 +    return (neg ? -urem : urem);
  85.648  }
  85.649  
  85.650  #endif /* BITS_PER_LONG == 32 */
  85.651  
  85.652  unsigned long long parse_size_and_unit(const char *s, const char **ps)
  85.653  {
  85.654 -	unsigned long long ret;
  85.655 -	const char *s1;
  85.656 +    unsigned long long ret;
  85.657 +    const char *s1;
  85.658  
  85.659 -	ret = simple_strtoull(s, &s1, 0);
  85.660 +    ret = simple_strtoull(s, &s1, 0);
  85.661  
  85.662 -	switch (*s1) {
  85.663 -	case 'G': case 'g':
  85.664 -		ret <<= 10;
  85.665 -	case 'M': case 'm':
  85.666 -		ret <<= 10;
  85.667 -	case 'K': case 'k':
  85.668 -		ret <<= 10;
  85.669 -	case 'B': case 'b':
  85.670 -		s1++;
  85.671 -		break;
  85.672 -	default:
  85.673 -		ret <<= 10; /* default to kB */
  85.674 -		break;
  85.675 -	}
  85.676 +    switch ( *s1 )
  85.677 +    {
  85.678 +    case 'G': case 'g':
  85.679 +        ret <<= 10;
  85.680 +    case 'M': case 'm':
  85.681 +        ret <<= 10;
  85.682 +    case 'K': case 'k':
  85.683 +        ret <<= 10;
  85.684 +    case 'B': case 'b':
  85.685 +        s1++;
  85.686 +        break;
  85.687 +    default:
  85.688 +        ret <<= 10; /* default to kB */
  85.689 +        break;
  85.690 +    }
  85.691  
  85.692 -	if (ps != NULL)
  85.693 -		*ps = s1;
  85.694 +    if ( ps != NULL )
  85.695 +        *ps = s1;
  85.696  
  85.697 -	return ret;
  85.698 +    return ret;
  85.699  }
  85.700  
  85.701  /*
  85.702   * Local variables:
  85.703   * mode: C
  85.704   * c-set-style: "BSD"
  85.705 - * c-basic-offset: 8
  85.706 - * tab-width: 8
  85.707 - * indent-tabs-mode: t
  85.708 + * c-basic-offset: 4
  85.709 + * tab-width: 4
  85.710 + * indent-tabs-mode: nil
  85.711   * End:
  85.712   */
    86.1 --- a/xen/common/xencomm.c	Sun Jan 14 22:18:38 2007 -0700
    86.2 +++ b/xen/common/xencomm.c	Mon Jan 15 15:15:26 2007 -0700
    86.3 @@ -119,7 +119,7 @@ xencomm_copy_from_guest(void *to, const 
    86.4          chunksz -= chunk_skip;
    86.5          skip -= chunk_skip;
    86.6  
    86.7 -        if (skip == 0) {
    86.8 +        if (skip == 0 && chunksz > 0) {
    86.9              unsigned long src_maddr;
   86.10              unsigned long dest = (unsigned long)to + to_pos;
   86.11              unsigned int bytes = min(chunksz, n - to_pos);
   86.12 @@ -225,7 +225,7 @@ xencomm_copy_to_guest(void *to, const vo
   86.13          chunksz -= chunk_skip;
   86.14          skip -= chunk_skip;
   86.15  
   86.16 -        if (skip == 0) {
   86.17 +        if (skip == 0 && chunksz > 0) {
   86.18              unsigned long dest_maddr;
   86.19              unsigned long source = (unsigned long)from + from_pos;
   86.20              unsigned int bytes = min(chunksz, n - from_pos);
    87.1 --- a/xen/drivers/video/vga.c	Sun Jan 14 22:18:38 2007 -0700
    87.2 +++ b/xen/drivers/video/vga.c	Mon Jan 15 15:15:26 2007 -0700
    87.3 @@ -557,7 +557,7 @@ static int vga_load_font(const struct fo
    87.4  
    87.5  static int vgacon_enabled = 0;
    87.6  static int vgacon_keep    = 0;
    87.7 -static int vgacon_lines   = 25;
    87.8 +static int vgacon_lines   = 50;
    87.9  static const struct font_desc *font;
   87.10  
   87.11  static int xpos, ypos;
   87.12 @@ -606,12 +606,9 @@ void vga_init(void)
   87.13      case 60:
   87.14          font = &font_vga_8x8;
   87.15          break;
   87.16 -    default:
   87.17 -        vgacon_lines = 25;
   87.18 -        break;
   87.19      }
   87.20  
   87.21 -    if ( (font != NULL) && (vga_load_font(font, vgacon_lines) < 0) )
   87.22 +    if ( (font == NULL) || (vga_load_font(font, vgacon_lines) < 0) )
   87.23      {
   87.24          vgacon_lines = 25;
   87.25          font = NULL;
    88.1 --- a/xen/include/Makefile	Sun Jan 14 22:18:38 2007 -0700
    88.2 +++ b/xen/include/Makefile	Mon Jan 15 15:15:26 2007 -0700
    88.3 @@ -2,8 +2,28 @@ ifneq ($(CONFIG_COMPAT),)
    88.4  
    88.5  compat-arch-$(CONFIG_X86) := x86_32
    88.6  
    88.7 -headers-y                 := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g')
    88.8 -headers-y                 := $(filter-out %/dom0_ops.h,$(headers-y))
    88.9 +headers-y := \
   88.10 +    compat/acm.h \
   88.11 +    compat/acm_ops.h \
   88.12 +    compat/callback.h \
   88.13 +    compat/domctl.h \
   88.14 +    compat/elfnote.h \
   88.15 +    compat/event_channel.h \
   88.16 +    compat/features.h \
   88.17 +    compat/grant_table.h \
   88.18 +    compat/kexec.h \
   88.19 +    compat/memory.h \
   88.20 +    compat/nmi.h \
   88.21 +    compat/physdev.h \
   88.22 +    compat/platform.h \
   88.23 +    compat/sched.h \
   88.24 +    compat/sysctl.h \
   88.25 +    compat/trace.h \
   88.26 +    compat/vcpu.h \
   88.27 +    compat/version.h \
   88.28 +    compat/xen.h \
   88.29 +    compat/xencomm.h \
   88.30 +    compat/xenoprof.h
   88.31  headers-$(CONFIG_X86)     += compat/arch-x86/xen.h
   88.32  headers-$(CONFIG_X86)     += compat/arch-x86/xen-$(compat-arch-y).h
   88.33  headers-y                 += compat/arch-$(compat-arch-y).h compat/xlat.h
   88.34 @@ -21,24 +41,14 @@ endif
   88.35  all: $(headers-y)
   88.36  
   88.37  compat/%.h: compat/%.i Makefile
   88.38 -	id=_$$(echo $@ | sed 'y,abcdefghijklmnopqrstuvwxyz-/.,ABCDEFGHIJKLMNOPQRSTUVWXYZ___,'); \
   88.39 +	id=_$$(echo $@ | tr '[:lower:]-/.' '[:upper:]___'); \
   88.40  	echo "#ifndef $$id" >$@.new; \
   88.41  	echo "#define $$id" >>$@.new; \
   88.42  	echo "#include <xen/compat.h>" >>$@.new; \
   88.43  	$(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \
   88.44  	$(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \
   88.45 -	grep -v '^# [[:digit:]]' $< | \
   88.46 -	sed -e 's,__InClUdE__,#include,' \
   88.47 -	    -e 's,"xen-compat.h",<public/xen-compat.h>,' \
   88.48 -	    -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \
   88.49 -	    -e 's,@KeeP@,,g' \
   88.50 -	    -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \
   88.51 -	    -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \
   88.52 -	    -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \
   88.53 -	    -e 's,\(^\|[^[:alnum:]_]\)XEN_\?,\1COMPAT_,' \
   88.54 -	    -e 's,\(^\|[^[:alnum:]_]\)Xen_\?,\1Compat_,' \
   88.55 -	    -e 's,\(^\|[^[:alnum:]]\)long\([^[:alnum:]]\|$$\),\1int\2,g' | \
   88.56 -	uniq >>$@.new; \
   88.57 +	grep -v '^# [0-9]' $< | \
   88.58 +	$(BASEDIR)/tools/compat-build-header.py | uniq >>$@.new; \
   88.59  	$(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \
   88.60  	echo "#endif /* $$id */" >>$@.new
   88.61  	mv -f $@.new $@
   88.62 @@ -49,19 +59,13 @@ compat/%.i: compat/%.c Makefile
   88.63  compat/%.c: public/%.h xlat.lst Makefile
   88.64  	mkdir -p $(@D)
   88.65  	grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \
   88.66 -	sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \
   88.67 -	    -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \
   88.68 -	    -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \
   88.69 -	    -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \
   88.70 -	    $(foreach n,$(shell sed -n 's,^[[:space:]]*?[[:space:]]\+\([[:alnum:]_]*\)[[:space:]].*,\1,p' xlat.lst), \
   88.71 -	                -e 's,\(struct\|union\)[[:space:]]\+\(xen_\?\)\?$n[[:space:]]\+\([[:alpha:]_]\),\1 @KeeP@\2$n \3,g') \
   88.72 -	    >$@.new
   88.73 +        $(BASEDIR)/tools/compat-build-source.py >$@.new
   88.74  	mv -f $@.new $@
   88.75  
   88.76  compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) $(BASEDIR)/tools/get-fields.sh Makefile
   88.77 -	grep -v '^[[:space:]]*#' xlat.lst | \
   88.78 +	grep -v '^[	 ]*#' xlat.lst | \
   88.79  	while read what name hdr; do \
   88.80 -		$(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed 's,@arch@,$(compat-arch-y),g') || exit $$?; \
   88.81 +		/bin/bash $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed 's,@arch@,$(compat-arch-y),g') || exit $$?; \
   88.82  	done >$@.new
   88.83  	mv -f $@.new $@
   88.84  
    89.1 --- a/xen/include/asm-x86/guest_access.h	Sun Jan 14 22:18:38 2007 -0700
    89.2 +++ b/xen/include/asm-x86/guest_access.h	Mon Jan 15 15:15:26 2007 -0700
    89.3 @@ -32,7 +32,7 @@
    89.4   * specifying an offset into the guest array.
    89.5   */
    89.6  #define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
    89.7 -    const typeof(ptr) _x = (hnd).p;                     \
    89.8 +    typeof(ptr) _x = (hnd).p;                           \
    89.9      const typeof(ptr) _y = (ptr);                       \
   89.10      is_hvm_vcpu(current) ?                              \
   89.11      copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) :  \
   89.12 @@ -45,7 +45,7 @@
   89.13   */
   89.14  #define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
   89.15      const typeof(ptr) _x = (hnd).p;                     \
   89.16 -    const typeof(ptr) _y = (ptr);                       \
   89.17 +    typeof(ptr) _y = (ptr);                             \
   89.18      is_hvm_vcpu(current) ?                              \
   89.19      copy_from_user_hvm(_y, _x+(off), sizeof(*_x)*(nr)) :\
   89.20      copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
   89.21 @@ -53,7 +53,7 @@
   89.22  
   89.23  /* Copy sub-field of a structure to guest context via a guest handle. */
   89.24  #define copy_field_to_guest(hnd, ptr, field) ({         \
   89.25 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
   89.26 +    typeof(&(ptr)->field) _x = &(hnd).p->field;         \
   89.27      const typeof(&(ptr)->field) _y = &(ptr)->field;     \
   89.28      is_hvm_vcpu(current) ?                              \
   89.29      copy_to_user_hvm(_x, _y, sizeof(*_x)) :             \
   89.30 @@ -63,7 +63,7 @@
   89.31  /* Copy sub-field of a structure from guest context via a guest handle. */
   89.32  #define copy_field_from_guest(ptr, hnd, field) ({       \
   89.33      const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
   89.34 -    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
   89.35 +    typeof(&(ptr)->field) _y = &(ptr)->field;           \
   89.36      is_hvm_vcpu(current) ?                              \
   89.37      copy_from_user_hvm(_y, _x, sizeof(*_x)) :           \
   89.38      copy_from_user(_y, _x, sizeof(*_x));                \
   89.39 @@ -78,7 +78,7 @@
   89.40       array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
   89.41  
   89.42  #define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
   89.43 -    const typeof(ptr) _x = (hnd).p;                     \
   89.44 +    typeof(ptr) _x = (hnd).p;                           \
   89.45      const typeof(ptr) _y = (ptr);                       \
   89.46      is_hvm_vcpu(current) ?                              \
   89.47      copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) :  \
   89.48 @@ -87,14 +87,14 @@
   89.49  
   89.50  #define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
   89.51      const typeof(ptr) _x = (hnd).p;                     \
   89.52 -    const typeof(ptr) _y = (ptr);                       \
   89.53 +    typeof(ptr) _y = (ptr);                             \
   89.54      is_hvm_vcpu(current) ?                              \
   89.55      copy_from_user_hvm(_y, _x+(off),sizeof(*_x)*(nr)) : \
   89.56      __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
   89.57  })
   89.58  
   89.59  #define __copy_field_to_guest(hnd, ptr, field) ({       \
   89.60 -    const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
   89.61 +    typeof(&(ptr)->field) _x = &(hnd).p->field;         \
   89.62      const typeof(&(ptr)->field) _y = &(ptr)->field;     \
   89.63      is_hvm_vcpu(current) ?                              \
   89.64      copy_to_user_hvm(_x, _y, sizeof(*_x)) :             \
   89.65 @@ -103,9 +103,9 @@
   89.66  
   89.67  #define __copy_field_from_guest(ptr, hnd, field) ({     \
   89.68      const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
   89.69 -    const typeof(&(ptr)->field) _y = &(ptr)->field;     \
   89.70 +    typeof(&(ptr)->field) _y = &(ptr)->field;           \
   89.71      is_hvm_vcpu(current) ?                              \
   89.72 -    copy_from_user_hvm(_x, _y, sizeof(*_x)) :           \
   89.73 +    copy_from_user_hvm(_y, _x, sizeof(*_x)) :           \
   89.74      __copy_from_user(_y, _x, sizeof(*_x));              \
   89.75  })
   89.76  
    90.1 --- a/xen/include/asm-x86/hvm/irq.h	Sun Jan 14 22:18:38 2007 -0700
    90.2 +++ b/xen/include/asm-x86/hvm/irq.h	Mon Jan 15 15:15:26 2007 -0700
    90.3 @@ -43,9 +43,17 @@ struct hvm_irq {
    90.4       */
    90.5      DECLARE_BITMAP(isa_irq, 16);
    90.6  
    90.7 -    /* Virtual interrupt wire and GSI link for paravirtual platform driver. */
    90.8 -    DECLARE_BITMAP(callback_irq_wire, 1);
    90.9 -    unsigned int callback_gsi;
   90.10 +    /* Virtual interrupt and via-link for paravirtual platform driver. */
   90.11 +    unsigned int callback_via_asserted;
   90.12 +    enum {
   90.13 +        HVMIRQ_callback_none,
   90.14 +        HVMIRQ_callback_gsi,
   90.15 +        HVMIRQ_callback_pci_intx
   90.16 +    } callback_via_type;
   90.17 +    union {
   90.18 +        unsigned int gsi;
   90.19 +        struct { uint8_t dev, intx; } pci;
   90.20 +    } callback_via;
   90.21  
   90.22      /*
   90.23       * PCI-ISA interrupt router.
   90.24 @@ -105,7 +113,7 @@ void hvm_isa_irq_deassert(
   90.25  void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq);
   90.26  
   90.27  void hvm_set_callback_irq_level(void);
   90.28 -void hvm_set_callback_gsi(struct domain *d, unsigned int gsi);
   90.29 +void hvm_set_callback_via(struct domain *d, uint64_t via);
   90.30  
   90.31  int cpu_get_interrupt(struct vcpu *v, int *type);
   90.32  int cpu_has_pending_irq(struct vcpu *v);
    91.1 --- a/xen/include/asm-x86/x86_emulate.h	Sun Jan 14 22:18:38 2007 -0700
    91.2 +++ b/xen/include/asm-x86/x86_emulate.h	Mon Jan 15 15:15:26 2007 -0700
    91.3 @@ -3,7 +3,21 @@
    91.4   * 
    91.5   * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
    91.6   * 
    91.7 - * Copyright (c) 2005 Keir Fraser
    91.8 + * Copyright (c) 2005-2007 Keir Fraser
    91.9 + * 
   91.10 + * This program is free software; you can redistribute it and/or modify
   91.11 + * it under the terms of the GNU General Public License as published by
   91.12 + * the Free Software Foundation; either version 2 of the License, or
   91.13 + * (at your option) any later version.
   91.14 + * 
   91.15 + * This program is distributed in the hope that it will be useful,
   91.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   91.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   91.18 + * GNU General Public License for more details.
   91.19 + * 
   91.20 + * You should have received a copy of the GNU General Public License
   91.21 + * along with this program; if not, write to the Free Software
   91.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   91.23   */
   91.24  
   91.25  #ifndef __X86_EMULATE_H__
    92.1 --- a/xen/include/public/elfnote.h	Sun Jan 14 22:18:38 2007 -0700
    92.2 +++ b/xen/include/public/elfnote.h	Mon Jan 15 15:15:26 2007 -0700
    92.3 @@ -40,8 +40,6 @@
    92.4  
    92.5  /*
    92.6   * NAME=VALUE pair (string).
    92.7 - *
    92.8 - * LEGACY: FEATURES and PAE
    92.9   */
   92.10  #define XEN_ELFNOTE_INFO           0
   92.11  
   92.12 @@ -108,7 +106,12 @@
   92.13  #define XEN_ELFNOTE_LOADER         8
   92.14  
   92.15  /*
   92.16 - * The kernel supports PAE (x86/32 only, string = "yes" or "no").
   92.17 + * The kernel supports PAE (x86/32 only, string = "yes", "no" or
   92.18 + * "bimodal").
   92.19 + *
   92.20 + * For compatibility with Xen 3.0.3 and earlier the "bimodal" setting
   92.21 + * may be given as "yes,bimodal" which will cause older Xen to treat
   92.22 + * this kernel as PAE.
   92.23   *
   92.24   * LEGACY: PAE (n.b. The legacy interface included a provision to
   92.25   * indicate 'extended-cr3' support allowing L3 page tables to be
    93.1 --- a/xen/include/public/hvm/params.h	Sun Jan 14 22:18:38 2007 -0700
    93.2 +++ b/xen/include/public/hvm/params.h	Mon Jan 15 15:15:26 2007 -0700
    93.3 @@ -24,13 +24,33 @@
    93.4  
    93.5  #include "hvm_op.h"
    93.6  
    93.7 -/* Parameter space for HVMOP_{set,get}_param. */
    93.8 +/*
    93.9 + * Parameter space for HVMOP_{set,get}_param.
   93.10 + */
   93.11 +
   93.12 +/*
   93.13 + * How should CPU0 event-channel notifications be delivered?
   93.14 + * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
   93.15 + * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
   93.16 + *                  Domain = val[47:32], Bus  = val[31:16],
   93.17 + *                  DevFn  = val[15: 8], IntX = val[ 1: 0]
   93.18 + * If val == 0 then CPU0 event-channel notifications are not delivered.
   93.19 + */
   93.20  #define HVM_PARAM_CALLBACK_IRQ 0
   93.21 +
   93.22 +/*
   93.23 + * These are not used by Xen. They are here for convenience of HVM-guest
   93.24 + * xenbus implementations.
   93.25 + */
   93.26  #define HVM_PARAM_STORE_PFN    1
   93.27  #define HVM_PARAM_STORE_EVTCHN 2
   93.28 +
   93.29  #define HVM_PARAM_PAE_ENABLED  4
   93.30 +
   93.31  #define HVM_PARAM_IOREQ_PFN    5
   93.32 +
   93.33  #define HVM_PARAM_BUFIOREQ_PFN 6
   93.34 +
   93.35  #define HVM_NR_PARAMS          7
   93.36  
   93.37  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/xen/tools/compat-build-header.py	Mon Jan 15 15:15:26 2007 -0700
    94.3 @@ -0,0 +1,21 @@
    94.4 +#!/usr/bin/python
    94.5 +
    94.6 +import re,sys
    94.7 +
    94.8 +pats = [
    94.9 + [ r"__InClUdE__", r"#include" ],
   94.10 + [ r"\"xen-compat.h\"", r"<public/xen-compat.h>" ],
   94.11 + [ r"(struct|union|enum)\s+(xen_?)?(\w)", r"\1 compat_\3" ],
   94.12 + [ r"@KeeP@", r"" ],
   94.13 + [ r"_t([^\w]|$)", r"_compat_t\1" ],
   94.14 + [ r"(8|16|32|64)_compat_t([^\w]|$)", r"\1_t\2" ],
   94.15 + [ r"(^|[^\w])xen_?(\w*)_compat_t([^\w]|$$)", r"\1compat_\2_t\3" ],
   94.16 + [ r"(^|[^\w])XEN_?", r"\1COMPAT_" ],
   94.17 + [ r"(^|[^\w])Xen_?", r"\1Compat_" ],
   94.18 + [ r"(^|[^\w])long([^\w]|$$)", r"\1int\2" ]
   94.19 +];
   94.20 +
   94.21 +for line in sys.stdin.readlines():
   94.22 +    for pat in pats:
   94.23 +        line = re.subn(pat[0], pat[1], line)[0]
   94.24 +    print line.rstrip()
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/xen/tools/compat-build-source.py	Mon Jan 15 15:15:26 2007 -0700
    95.3 @@ -0,0 +1,27 @@
    95.4 +#!/usr/bin/python
    95.5 +
    95.6 +import re,sys
    95.7 +
    95.8 +pats = [
    95.9 + [ r"^\s*#\s*include\s+", r"__InClUdE__ " ],
   95.10 + [ r"^\s*#\s*define\s+([A-Z_]*_GUEST_HANDLE)", r"#define HIDE_\1" ],
   95.11 + [ r"^\s*#\s*define\s+([a-z_]*_guest_handle)", r"#define hide_\1" ],
   95.12 + [ r"XEN_GUEST_HANDLE(_[0-9A-Fa-f]+)?", r"COMPAT_HANDLE" ],
   95.13 +];
   95.14 +
   95.15 +xlats = []
   95.16 +
   95.17 +xlatf = open('xlat.lst', 'r')
   95.18 +for line in xlatf.readlines():
   95.19 +    match = re.subn(r"^\s*\?\s+(\w*)\s.*", r"\1", line.rstrip())
   95.20 +    if match[1]:
   95.21 +        xlats.append(match[0])
   95.22 +xlatf.close()
   95.23 +
   95.24 +for line in sys.stdin.readlines():
   95.25 +    for pat in pats:
   95.26 +        line = re.subn(pat[0], pat[1], line)[0]
   95.27 +    for xlat in xlats:
   95.28 +        line = re.subn(r"(struct|union)\s+(%s|xen_%s)\s+(\w)" % (xlat, xlat),
   95.29 +            r"\1 @KeeP@\2 \3", line.rstrip())[0]
   95.30 +    print line.rstrip()
    96.1 --- a/xen/tools/get-fields.sh	Sun Jan 14 22:18:38 2007 -0700
    96.2 +++ b/xen/tools/get-fields.sh	Mon Jan 15 15:15:26 2007 -0700
    96.3 @@ -1,7 +1,10 @@
    96.4 -#!/bin/sh
    96.5 +#!/bin/bash
    96.6  test -n "$1" -a -n "$2" -a -n "$3"
    96.7  set -ef
    96.8  
    96.9 +SED=sed
   96.10 +[ -x /usr/xpg4/bin/sed ] && SED=/usr/xpg4/bin/sed
   96.11 +
   96.12  get_fields() {
   96.13  	local level=1 aggr=0 name= fields=
   96.14  	for token in $2
   96.15 @@ -90,11 +93,15 @@ handle_field() {
   96.16  		then
   96.17  			echo -n "$1(_d_)->$3 = (_s_)->$3;"
   96.18  		else
   96.19 -			echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 's,\.,_,g')(_d_, _s_);"
   96.20 +			echo -n "$1XLAT_${2}_HNDL_$(echo $3 | $SED 's,\.,_,g')(_d_, _s_);"
   96.21  		fi
   96.22 -	elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ]
   96.23 +	elif [ -z "$(echo "$5" | $SED 's,[^{}],,g')" ]
   96.24  	then
   96.25 -		local tag=$(echo "$5" | sed 's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,')
   96.26 +		local tag=$(echo "$5" | python -c '
   96.27 +import re,sys
   96.28 +for line in sys.stdin.readlines():
   96.29 +    print re.subn(r"\s*(struct|union)\s+(compat_)?(\w+)\s.*", r"\3", line)[0].rstrip()
   96.30 +')
   96.31  		echo " \\"
   96.32  		echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);"
   96.33  	else
   96.34 @@ -104,13 +111,13 @@ handle_field() {
   96.35  			case "$token" in
   96.36  			struct|union)
   96.37  				test $level != 2 || fields=" "
   96.38 -				if [ $level == 1 ]
   96.39 +				if [ $level = 1 ]
   96.40  				then
   96.41  					kind=$token
   96.42  					if [ $kind = union ]
   96.43  					then
   96.44  						echo " \\"
   96.45 -						echo -n "${1}switch ($(echo $3 | sed 's,\.,_,g')) {"
   96.46 +						echo -n "${1}switch ($(echo $3 | $SED 's,\.,_,g')) {"
   96.47  					fi
   96.48  				fi
   96.49  				;;
   96.50 @@ -119,7 +126,7 @@ handle_field() {
   96.51  				;;
   96.52  			"}")
   96.53  				level=$(expr $level - 1) id=
   96.54 -				if [ $level == 1 -a $kind = union ]
   96.55 +				if [ $level = 1 -a $kind = union ]
   96.56  				then
   96.57  					echo " \\"
   96.58  					echo -n "$1}"
   96.59 @@ -141,7 +148,7 @@ handle_field() {
   96.60  				arrlvl=$(expr $arrlvl - 1)
   96.61  				;;
   96.62  			COMPAT_HANDLE\(*\))
   96.63 -				if [ $level == 2 -a -z "$id" ]
   96.64 +				if [ $level = 2 -a -z "$id" ]
   96.65  				then
   96.66  					type=${token#COMPAT_HANDLE?}
   96.67  					type=${type%?}
   96.68 @@ -149,7 +156,7 @@ handle_field() {
   96.69  				fi
   96.70  				;;
   96.71  			compat_domain_handle_t)
   96.72 -				if [ $level == 2 -a -z "$id" ]
   96.73 +				if [ $level = 2 -a -z "$id" ]
   96.74  				then
   96.75  					array_type=$token
   96.76  				fi
   96.77 @@ -158,12 +165,12 @@ handle_field() {
   96.78  				id=$token
   96.79  				;;
   96.80  			[\,\;])
   96.81 -				if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
   96.82 +				if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
   96.83  				then
   96.84  					if [ $kind = union ]
   96.85  					then
   96.86  						echo " \\"
   96.87 -						echo -n "${1}case XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):"
   96.88 +						echo -n "${1}case XLAT_${2}_$(echo $3.$id | $SED 's,\.,_,g'):"
   96.89  						handle_field "$1    " $2 $3.$id "$type" "$fields"
   96.90  					elif [ -z "$array" -a -z "$array_type" ]
   96.91  					then
   96.92 @@ -202,7 +209,7 @@ copy_array() {
   96.93  }
   96.94  
   96.95  handle_array() {
   96.96 -	local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)"
   96.97 +	local i="i$(echo $4 | $SED 's,[^;], ,g' | wc -w | $SED 's,[[:space:]]*,,g')"
   96.98  	echo " \\"
   96.99  	echo "$1{ \\"
  96.100  	echo "$1    unsigned int $i; \\"
  96.101 @@ -250,7 +257,7 @@ build_body() {
  96.102  			arrlvl=$(expr $arrlvl - 1)
  96.103  			;;
  96.104  		COMPAT_HANDLE\(*\))
  96.105 -			if [ $level == 2 -a -z "$id" ]
  96.106 +			if [ $level = 2 -a -z "$id" ]
  96.107  			then
  96.108  				type=${token#COMPAT_HANDLE?}
  96.109  				type=${type%?}
  96.110 @@ -258,7 +265,7 @@ build_body() {
  96.111  			fi
  96.112  			;;
  96.113  		compat_domain_handle_t)
  96.114 -			if [ $level == 2 -a -z "$id" ]
  96.115 +			if [ $level = 2 -a -z "$id" ]
  96.116  			then
  96.117  				array_type=$token
  96.118  			fi
  96.119 @@ -272,7 +279,7 @@ build_body() {
  96.120  			fi
  96.121  			;;
  96.122  		[\,\;])
  96.123 -			if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
  96.124 +			if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
  96.125  			then
  96.126  				if [ -z "$array" -a -z "$array_type" ]
  96.127  				then
  96.128 @@ -300,10 +307,10 @@ build_body() {
  96.129  }
  96.130  
  96.131  check_field() {
  96.132 -	if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ]
  96.133 +	if [ -z "$(echo "$4" | $SED 's,[^{}],,g')" ]
  96.134  	then
  96.135  		echo "; \\"
  96.136 -		local n=$(echo $3 | sed 's,[^.], ,g' | wc -w)
  96.137 +		local n=$(echo $3 | $SED 's,[^.], ,g' | wc -w | $SED 's,[[:space:]]*,,g')
  96.138  		if [ -n "$4" ]
  96.139  		then
  96.140  			for n in $4
  96.141 @@ -325,7 +332,7 @@ check_field() {
  96.142  		then
  96.143  			echo -n "    CHECK_FIELD_($1, $2, $3)"
  96.144  		else
  96.145 -			echo -n "    CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | sed 's!\.!, !g'))"
  96.146 +			echo -n "    CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | $SED 's!\.!, !g'))"
  96.147  		fi
  96.148  	else
  96.149  		local level=1 fields= id= token
  96.150 @@ -345,7 +352,7 @@ check_field() {
  96.151  				id=$token
  96.152  				;;
  96.153  			[\,\;])
  96.154 -				if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
  96.155 +				if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
  96.156  				then
  96.157  					check_field $1 $2 $3.$id "$fields"
  96.158  					test "$token" != ";" || fields= id=
  96.159 @@ -365,11 +372,11 @@ build_check() {
  96.160  	do
  96.161  		case "$token" in
  96.162  		struct|union)
  96.163 -			if [ $level == 1 ]
  96.164 +			if [ $level = 1 ]
  96.165  			then
  96.166  				kind=$token
  96.167  				echo -n "    CHECK_SIZE_($kind, $1)"
  96.168 -			elif [ $level == 2 ]
  96.169 +			elif [ $level = 2 ]
  96.170  			then
  96.171  				fields=" "
  96.172  			fi
  96.173 @@ -390,7 +397,7 @@ build_check() {
  96.174  			test $level != 2 -o $arrlvl != 1 || id=$token
  96.175  			;;
  96.176  		[\,\;])
  96.177 -			if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
  96.178 +			if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ]
  96.179  			then
  96.180  				check_field $kind $1 $id "$fields"
  96.181  				test "$token" != ";" || fields= id=
  96.182 @@ -402,7 +409,7 @@ build_check() {
  96.183  	echo ""
  96.184  }
  96.185  
  96.186 -fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")"
  96.187 +fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$($SED -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")"
  96.188  if [ -z "$fields" ]
  96.189  then
  96.190  	echo "Fields of '$2' not found in '$3'" >&2