Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-changelog

[Xen-changelog] Merged.

# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID d3b10a2a82d47bb3e52faf2fa4ba27217f486c54
# Parent  11cd619db03540476cef8ec523d46d9a1d13973c
# Parent  931acb64fbaf762fd47f9035b411ae6f1b5cb50b
Merged.

diff -r 11cd619db035 -r d3b10a2a82d4 Makefile
--- a/Makefile  Tue Dec 20 17:16:15 2005
+++ b/Makefile  Tue Dec 20 17:16:24 2005
@@ -10,7 +10,7 @@
 # Export target architecture overrides to Xen and Linux sub-trees.
 ifneq ($(XEN_TARGET_ARCH),)
 SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH))
-export XEN_TARGET_ARCH SUBARCH
+export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE
 endif
 
 # Default target must appear before any include lines
diff -r 11cd619db035 -r d3b10a2a82d4 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Tue Dec 20 17:16:15 2005
+++ b/buildconfigs/mk.linux-2.6-xen     Tue Dec 20 17:16:24 2005
@@ -30,7 +30,7 @@
        CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' 
$(LINUX_DIR)/Makefile); \
        [ -r 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
          cp 
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) 
$(LINUX_DIR)/.config \
-         || cp 
$(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH) \
+         || cp 
$(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH)$(XEN_SYSTYPE)
 \
                $(LINUX_DIR)/.config
        # See if we need to munge config to enable PAE
        $(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk 
config-update-pae
diff -r 11cd619db035 -r d3b10a2a82d4 
linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c   Tue Dec 20 17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c   Tue Dec 20 17:16:24 2005
@@ -186,8 +186,7 @@
 static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
 {
        struct mm_struct * mm = current->mm;
-       __u32 entry_1, entry_2, *lp;
-       maddr_t mach_lp;
+       __u32 entry_1, entry_2;
        int error;
        struct user_desc ldt_info;
 
@@ -215,9 +214,6 @@
                        goto out_unlock;
        }
 
-       lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) 
mm->context.ldt);
-       mach_lp = arbitrary_virt_to_machine(lp);
-
        /* Allow LDTs to be cleared by the user. */
        if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
                if (oldmode || LDT_empty(&ldt_info)) {
@@ -234,8 +230,8 @@
 
        /* Install the new entry ...  */
 install:
-       error = HYPERVISOR_update_descriptor(
-               mach_lp, (u64)entry_1 | ((u64)entry_2<<32));
+       error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number,
+                               entry_1, entry_2);
 
 out_unlock:
        up(&mm->context.sem);
diff -r 11cd619db035 -r d3b10a2a82d4 
linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c       Tue Dec 20 
17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c       Tue Dec 20 
17:16:24 2005
@@ -24,6 +24,7 @@
 #include <asm/io.h>
 #include <asm/pci.h>
 #include <asm/dma.h>
+#include <asm/uaccess.h>
 #include <asm-xen/xen-public/memory.h>
 
 #define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
@@ -201,6 +202,12 @@
                printk(KERN_INFO "Software IO TLB disabled\n");
 }
 
+/*
+ * We use __copy_to_user to transfer to the host buffer because the buffer
+ * may be mapped read-only (e.g, in blkback driver) but lower-level
+ * drivers map the buffer for DMA_BIDIRECTIONAL access. This causes an
+ * unnecessary copy from the aperture to the host buffer, and a page fault.
+ */
 static void
 __sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir)
 {
@@ -214,9 +221,11 @@
                        kmp  = kmap_atomic(buffer.page, KM_SWIOTLB);
                        dev  = dma_addr + size - len;
                        host = kmp + buffer.offset;
-                       memcpy((dir == DMA_FROM_DEVICE) ? host : dev,
-                              (dir == DMA_FROM_DEVICE) ? dev : host,
-                              bytes);
+                       if (dir == DMA_FROM_DEVICE) {
+                               if (__copy_to_user(host, dev, bytes))
+                                       /* inaccessible */;
+                       } else
+                               memcpy(dev, host, bytes);
                        kunmap_atomic(kmp, KM_SWIOTLB);
                        len -= bytes;
                        buffer.page++;
@@ -225,9 +234,10 @@
        } else {
                char *host = (char *)phys_to_virt(
                        page_to_pseudophys(buffer.page)) + buffer.offset;
-               if (dir == DMA_FROM_DEVICE)
-                       memcpy(host, dma_addr, size);
-               else if (dir == DMA_TO_DEVICE)
+               if (dir == DMA_FROM_DEVICE) {
+                       if (__copy_to_user(host, dma_addr, size))
+                               /* inaccessible */;
+               } else if (dir == DMA_TO_DEVICE)
                        memcpy(dma_addr, host, size);
        }
 }
diff -r 11cd619db035 -r d3b10a2a82d4 
linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c        Tue Dec 20 
17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c        Tue Dec 20 
17:16:24 2005
@@ -438,6 +438,16 @@
        balloon_unlock(flags);
 }
 
+#ifdef __i386__
+int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
+{
+       __u32 *lp = (__u32 *)((char *)ldt + entry * 8);
+       maddr_t mach_lp = arbitrary_virt_to_machine(lp);
+       return HYPERVISOR_update_descriptor(
+               mach_lp, (u64)entry_a | ((u64)entry_b<<32));
+}
+#endif
+
 /*
  * Local variables:
  *  c-file-style: "linux"
diff -r 11cd619db035 -r d3b10a2a82d4 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Dec 20 17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Dec 20 17:16:24 2005
@@ -163,11 +163,10 @@
        while (l1 != 0) {
                l1i = __ffs(l1);
                l1 &= ~(1UL << l1i);
-        
+
                while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
                        l2i = __ffs(l2);
-                       l2 &= ~(1UL << l2i);
-            
+
                        port = (l1i * BITS_PER_LONG) + l2i;
                        if ((irq = evtchn_to_irq[port]) != -1)
                                do_IRQ(irq, regs);
diff -r 11cd619db035 -r d3b10a2a82d4 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h      Tue Dec 20 
17:16:15 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h      Tue Dec 20 
17:16:24 2005
@@ -87,6 +87,8 @@
        (info)->seg_not_present == 1    && \
        (info)->useable         == 0    )
 
+extern int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b);
+
 #if TLS_SIZE != 24
 # error update this code.
 #endif
diff -r 11cd619db035 -r d3b10a2a82d4 
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c     
Tue Dec 20 17:16:15 2005
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c     
Tue Dec 20 17:16:24 2005
@@ -36,11 +36,26 @@
 #include <unistd.h>
 #include <errno.h>
 #include <xenctrl.h>
+#include <thread_db.h>
+#include <xc_ptrace.h>
+
 #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
 
 long (*myptrace)(int xc_handle, enum __ptrace_request, uint32_t, long, long);
 int (*myxcwait)(int xc_handle, int domain, int *status, int options) ;
 static int xc_handle;
+
+static inline int
+curvcpuid()
+{
+  struct process_info *process;
+  if (current_inferior == NULL)
+      return 0;
+  process = get_thread_process(current_inferior);
+  return (process->thread_known ? process->tid : 0);
+
+}
+
 
 #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
 #define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
@@ -48,11 +63,14 @@
 #define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
 #define DOMFLAGS_RUNNING   (1<<5) /* Domain is currently running.            */
 
+
+
 struct inferior_list all_processes;
-static int current_domain;
+static int current_domid;
 static int expect_signal = 0;
 static int signal_to_send = 0; 
 static void linux_resume (struct thread_resume *resume_info);
+static void linux_set_inferior (void);
 
 int debug_threads;
 int using_threads;
@@ -96,7 +114,6 @@
    point at the following instruction.  If we continue and hit a
    breakpoint instruction, our PC will point at the breakpoint
    instruction.  */
-#if 0
 static CORE_ADDR
 get_stop_pc (void)
 {
@@ -107,9 +124,9 @@
   else
     return stop_pc - the_low_target.decr_pc_after_break;
 }
-#endif
+
 static void *
-add_process (int pid)
+add_process (int pid, long tid)
 {
   struct process_info *process;
 
@@ -118,9 +135,8 @@
 
   process->head.id = pid;
 
-  /* Default to tid == lwpid == pid.  */
-  process->tid = pid;
-  process->lwpid = pid;
+  process->tid = tid;
+  process->lwpid = tid;
 
   add_inferior_to_list (&all_processes, &process->head);
 
@@ -143,23 +159,25 @@
 }
 
 int
-linux_attach (int domain)
+linux_attach (int domid)
 {
     struct process_info *new_process;
-    current_domain = domain;
-    if (myptrace (xc_handle, PTRACE_ATTACH, domain, 0, 0) != 0) {
-       fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domain,
+    current_domid = domid;
+    /* this is handled for all active vcpus in PTRACE_ATTACH via the 
thread_create_callback */
+    new_process = (struct process_info *) add_process (domid, curvcpuid());
+    /* Don't ignore the initial SIGSTOP if we just attached to this process.  
*/
+    /* vcpuid == 0 */
+    add_thread (0, new_process);
+    new_process->stop_expected = 0;
+
+    if (myptrace (xc_handle, PTRACE_ATTACH, domid, 0, 0) != 0) {
+       fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
                 strerror (errno), errno);
        fflush (stderr);
-       _exit (0177);
-    }
-    
-    new_process = (struct process_info *) add_process (domain);
-    add_thread (domain, new_process);
-
-    /* Don't ignore the initial SIGSTOP if we just attached to this process.  
*/
-    new_process->stop_expected = 0;
-    
+       if (!using_threads)
+           _exit (0177);
+    }
+
     return 0;
 }
 
@@ -173,20 +191,18 @@
   myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
 }
 
+
 static void
 linux_kill (void)
 {
   for_each_inferior (&all_threads, linux_kill_one_process);
 }
 
-
 static void
 linux_detach_one_process (struct inferior_list_entry *entry)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct process_info *process = get_thread_process (thread);
-
-  myptrace (xc_handle, PTRACE_DETACH, pid_of (process), 0, 0);
+
+  myptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
 }
 
 
@@ -212,14 +228,10 @@
 linux_wait (char *status)
 {
   int w;
-  if (myxcwait(xc_handle, current_domain, &w, 0))
+  if (myxcwait(xc_handle, current_domid, &w, 0))
       return -1;
   
-  if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) {
-      *status = 'W';
-      return 0;
-  }
-
+  linux_set_inferior();
 
   *status = 'T';
   if (expect_signal)
@@ -236,8 +248,10 @@
   TRACE_ENTER;
   expect_signal = resume_info->sig;
   for_each_inferior(&all_threads, regcache_invalidate_one);
-
-  myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 
0, 0);
+  if (debug_threads)
+    fprintf(stderr, "step: %d\n", step);
+  myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, 
+           resume_info->thread, 0, 0);
 
 }
 
@@ -261,7 +275,9 @@
        }
 
       buf = malloc (regset->size);
-      res = myptrace (xc_handle, regset->get_request, inferior_pid, 0, 
(PTRACE_XFER_TYPE)buf);
+      res = myptrace (xc_handle, regset->get_request, 
+                     curvcpuid(),
+                     0, (PTRACE_XFER_TYPE)buf);
       if (res < 0)
        {
          if (errno == EIO)
@@ -313,7 +329,7 @@
 
       buf = malloc (regset->size);
       regset->fill_function (buf);
-      res = myptrace (xc_handle, regset->set_request, inferior_pid, 0, 
(PTRACE_XFER_TYPE)buf);
+      res = myptrace (xc_handle, regset->set_request, curvcpuid(), 0, 
(PTRACE_XFER_TYPE)buf);
       if (res < 0)
        {
          if (errno == EIO)
@@ -391,7 +407,7 @@
   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
     {
       errno = 0;
-      buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid, 
(PTRACE_ARG3_TYPE) addr, 0);
+      buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), 
(PTRACE_ARG3_TYPE) addr, 0);
       if (errno)
        return errno;
     }
@@ -424,13 +440,13 @@
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
 
-  buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
+  buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
                      (PTRACE_ARG3_TYPE) addr, 0);
 
   if (count > 1)
     {
       buffer[count - 1]
-       = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
+       = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
                  (PTRACE_ARG3_TYPE) (addr + (count - 1)
                                      * sizeof (PTRACE_XFER_TYPE)),
                  0);
@@ -444,7 +460,8 @@
   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
     {
       errno = 0;
-      myptrace (xc_handle, PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) 
addr, buffer[i]);
+      myptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(), 
+               (PTRACE_ARG3_TYPE) addr, buffer[i]);
       if (errno)
        return errno;
     }
@@ -455,9 +472,11 @@
 static void
 linux_look_up_symbols (void)
 {
-#if 0
+  if (using_threads) 
+    return;
+
   using_threads = thread_db_init ();
-#endif
+
 }
 
 static void
@@ -535,6 +554,7 @@
 void
 initialize_low (void)
 {
+  using_threads = 0;
   xc_handle = xc_interface_open();
   set_target_ops (&linux_xen_target_ops);
   set_breakpoint_data (the_low_target.breakpoint,
@@ -548,5 +568,122 @@
       myptrace = xc_ptrace;
       myxcwait = xc_waitdomain;
   }
-
-}
+  using_threads = thread_db_init ();
+
+}
+
+
+static void
+thread_create_callback(long vcpuid)
+{
+  struct thread_info *inferior;
+  struct process_info *process;
+
+  /*  If we are attaching to our first thread, things are a little
+   *  different.  
+   */
+  if (all_threads.head == all_threads.tail)
+    {
+      inferior = (struct thread_info *) all_threads.head;
+      process = get_thread_process (inferior);
+      if (process->thread_known == 0)
+       {
+         /* Switch to indexing the threads list by TID.  */
+         change_inferior_id (&all_threads, vcpuid);
+         goto found;
+       }
+    }
+  if (debug_threads)
+    fprintf (stderr, "looking up thread %ld\n",
+            vcpuid);
+  inferior = (struct thread_info *) find_inferior_id (&all_threads,
+                                                     vcpuid);
+  /* if vcpu alread registered - do nothing */
+  if (inferior != NULL) 
+    return;
+
+  if (debug_threads)
+    fprintf (stderr, "Attaching to thread %ld\n",
+            vcpuid);
+
+  process = add_process(current_domid, vcpuid);
+
+  add_thread(vcpuid, process);
+  inferior = (struct thread_info *) find_inferior_id (&all_threads,
+                                                     vcpuid);
+  if (inferior == NULL)
+    {
+      warning ("Could not attach to thread %ld\n",
+              vcpuid);
+      return;
+    }
+
+
+found:
+  if (debug_threads)
+    fprintf (stderr, "notifying of new thread %ld\n",
+            vcpuid);
+  new_thread_notify (vcpuid);
+
+  process->tid = vcpuid;
+  process->lwpid = vcpuid;
+
+  process->thread_known = 1;
+}
+
+static void
+thread_death_callback(long vcpuid)
+{
+    if (debug_threads)
+      fprintf (stderr, "Buuurp...! CPU down event.\n");
+}
+
+int
+thread_db_init(void)
+{
+  debug_threads = 0;
+  xc_register_event_handler(thread_create_callback, TD_CREATE);
+  xc_register_event_handler(thread_death_callback, TD_DEATH);
+  return 1;
+}
+
+/* XXX GAG ME */
+static int breakpoint_found;
+static void
+set_breakpoint_inferior (struct inferior_list_entry *entry)
+{
+  struct thread_info *thread = (struct thread_info *) entry;
+  struct thread_info *saved_inferior = current_inferior;
+  CORE_ADDR eip;
+  unsigned char buf[2] = {0, 0};
+  current_inferior = thread;
+  if (!breakpoint_found) {
+    eip = get_stop_pc();
+    linux_read_memory(eip, buf, 1);
+    if (buf[0] == 0xcc) {
+      breakpoint_found = 1;
+      return;
+    }
+  } else if (breakpoint_found == 2) {
+    if (get_thread_process (current_inferior)->stepping) {
+      printf("stepping\n");
+      breakpoint_found = 1;
+      return;
+    } 
+  }
+  current_inferior = saved_inferior;
+
+
+}
+
+static void
+linux_set_inferior (void)
+{
+  breakpoint_found = 0;
+  for_each_inferior (&all_threads, set_breakpoint_inferior);
+  if (!breakpoint_found) {
+    breakpoint_found = 2;
+    for_each_inferior (&all_threads, set_breakpoint_inferior);
+  }
+}
+
diff -r 11cd619db035 -r d3b10a2a82d4 
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c    Tue Dec 
20 17:16:15 2005
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c    Tue Dec 
20 17:16:24 2005
@@ -20,7 +20,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include "server.h"
-
+#include "linux-low.h"
 #include <unistd.h>
 #include <signal.h>
 #include <sys/wait.h>
@@ -102,7 +102,15 @@
       strcpy (own_buf, "OK");
       return;
     }
-
+  if (strcmp ("qC", own_buf) == 0)
+    {
+      struct process_info *process;
+      if (current_inferior == NULL)
+       return;
+      process = get_thread_process(current_inferior);
+      sprintf(own_buf, "QC%x", process->thread_known ? process->tid : 0);
+
+    }
   if (strcmp ("qfThreadInfo", own_buf) == 0)
     {
       thread_ptr = all_threads.head;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Tue Dec 20 17:16:15 2005
+++ b/tools/examples/xend-config.sxp    Tue Dec 20 17:16:24 2005
@@ -4,9 +4,9 @@
 # Xend configuration file.
 #
 
-# This example configuration is appropriate for an installation that trusts
-# only localhost connections, and is otherwise fully functional, with a
-# bridged network configuration.
+# This example configuration is appropriate for an installation that 
+# utilizes a bridged network configuration. Access to xend via http
+# is disabled.  
 
 # Commented out entries show the default for that entry, unless otherwise
 # specified.
@@ -15,7 +15,6 @@
 #(loglevel DEBUG)
 
 #(xend-http-server no)
-(xend-http-server yes)
 #(xend-unix-server yes)
 #(xend-relocation-server no)
 (xend-relocation-server yes)
@@ -34,7 +33,7 @@
 # Specifying 'localhost' prevents remote connections.
 # Specifying the empty string '' (the default) allows all connections.
 #(xend-address '')
-(xend-address localhost)
+#(xend-address localhost)
 
 # Address xend should listen on for relocation-socket connections, if
 # xend-relocation-server is set.
diff -r 11cd619db035 -r d3b10a2a82d4 tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx      Tue Dec 20 17:16:15 2005
+++ b/tools/examples/xmexample.vmx      Tue Dec 20 17:16:24 2005
@@ -135,7 +135,7 @@
 
 #-----------------------------------------------------------------------------
 #   enable audio support
-#enable-audio=1
+#audio=1
 
 
 #-----------------------------------------------------------------------------
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/cpu-all.h
--- a/tools/ioemu/cpu-all.h     Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/cpu-all.h     Tue Dec 20 17:16:24 2005
@@ -668,7 +668,7 @@
 #endif
 /* memory API */
 
-extern int phys_ram_size;
+extern uint64_t phys_ram_size;
 extern int phys_ram_fd;
 extern uint8_t *phys_ram_base;
 extern uint8_t *phys_ram_dirty;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/exec.c
--- a/tools/ioemu/exec.c        Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/exec.c        Tue Dec 20 17:16:24 2005
@@ -61,7 +61,7 @@
 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
 uint8_t *code_gen_ptr;
 
-int phys_ram_size;
+uint64_t phys_ram_size;
 int phys_ram_fd;
 uint8_t *phys_ram_base;
 uint8_t *phys_ram_dirty;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/hw/pc.c       Tue Dec 20 17:16:24 2005
@@ -119,7 +119,7 @@
 }
 
 /* hd_table must contain 4 block drivers */
-static void cmos_init(int ram_size, int boot_device, BlockDriverState 
**hd_table)
+static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState 
**hd_table)
 {
     RTCState *s = rtc_state;
     int val;
@@ -375,7 +375,7 @@
 #define NOBIOS 1
 
 /* PC hardware initialisation */
-void pc_init(int ram_size, int vga_ram_size, int boot_device,
+void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
              DisplayState *ds, const char **fd_filename, int snapshot,
              const char *kernel_filename, const char *kernel_cmdline,
              const char *initrd_filename)
@@ -563,6 +563,15 @@
 
     kbd_init();
     DMA_init(0);
+   
+    if (audio_enabled) {
+        AUD_init();
+#ifdef USE_SB16
+        if (sb16_enabled)
+            SB16_init();
+#endif
+    }
+    
 
     floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
 
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/hw/pcnet.h
--- a/tools/ioemu/hw/pcnet.h    Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/hw/pcnet.h    Tue Dec 20 17:16:24 2005
@@ -92,7 +92,7 @@
 #define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
 #define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
 #define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
-#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
+#define CSR_CRDA(S)      ((S)->csr[28] | (((uint32_t)((S)->csr[29])) << 16))
 #define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
 #define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
 #define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
@@ -102,7 +102,7 @@
 #define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
 
 #define PHYSADDR(S,A) \
-  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
+  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
 
 struct pcnet_initblk16 {
     uint16_t mode;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/target-i386-dm/Makefile       Tue Dec 20 17:16:24 2005
@@ -272,6 +272,7 @@
 VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o i8254.o pc.o port-e9.o
 VL_OBJS+= cirrus_vga.o pcnet.o
+VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
 
 ifeq ($(TARGET_ARCH), ppc)
 VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/vl.c  Tue Dec 20 17:16:24 2005
@@ -119,7 +119,7 @@
 const char* keyboard_layout = 0;
 int64_t ticks_per_sec;
 int boot_device = 'c';
-int ram_size;
+uint64_t ram_size;
 int domid = -1;
 static char network_script[1024];
 int pit_min_timer_count = 0;
@@ -2906,7 +2906,7 @@
                 help();
                 break;
             case QEMU_OPTION_m:
-                ram_size = atoi(optarg) * 1024 * 1024;
+                ram_size = atol(optarg) * 1024 * 1024;
                 if (ram_size <= 0)
                     help();
                 break;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/vl.h  Tue Dec 20 17:16:24 2005
@@ -37,6 +37,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include "audio/audio.h"
 
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
@@ -116,7 +117,7 @@
 extern int sb16_enabled;
 extern int adlib_enabled;
 extern int gus_enabled;
-extern int ram_size;
+extern uint64_t ram_size;
 extern int bios_size;
 extern int rtc_utc;
 extern int cirrus_vga_enabled;
@@ -649,7 +650,7 @@
 int pit_get_out(PITState *pit, int channel, int64_t current_time);
 
 /* pc.c */
-void pc_init(int ram_size, int vga_ram_size, int boot_device,
+void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
              DisplayState *ds, const char **fd_filename, int snapshot,
              const char *kernel_filename, const char *kernel_cmdline,
              const char *initrd_filename);
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xc_domain.c   Tue Dec 20 17:16:24 2005
@@ -380,6 +380,30 @@
     return do_dom0_op(xc_handle, &op);
 }
 
+int xc_domain_setinfo(int xc_handle,
+                      uint32_t domid,
+                      uint32_t vcpu,
+                      vcpu_guest_context_t *ctxt)
+{
+    dom0_op_t op;
+    int rc;
+
+    op.cmd = DOM0_SETDOMAININFO;
+    op.u.setdomaininfo.domain = domid;
+    op.u.setdomaininfo.vcpu = vcpu;
+    op.u.setdomaininfo.ctxt = ctxt;
+
+    if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
+        return rc;
+
+    rc = do_dom0_op(xc_handle, &op);
+
+    safe_munlock(ctxt, sizeof(*ctxt));
+
+    return rc;
+
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xc_ptrace.c   Tue Dec 20 17:16:24 2005
@@ -1,130 +1,134 @@
+#define XC_PTRACE_PRIVATE
+
+
 #include <sys/ptrace.h>
 #include <sys/wait.h>
+#include <time.h>
+
 #include "xc_private.h"
 #include "xg_private.h"
-#include <time.h>
-
-#define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
-#define X86_CR0_PG              0x80000000 /* Paging                   (RW) */
-#define BSD_PAGE_MASK (PAGE_SIZE-1)
-#define PDRSHIFT        22
-#define PSL_T  0x00000100 /* trace enable bit */
-#define VCPU            0               /* XXX */
-
-char * ptrace_names[] = {
-    "PTRACE_TRACEME",
-    "PTRACE_PEEKTEXT",
-    "PTRACE_PEEKDATA",
-    "PTRACE_PEEKUSER",
-    "PTRACE_POKETEXT",
-    "PTRACE_POKEDATA",
-    "PTRACE_POKEUSER",
-    "PTRACE_CONT",
-    "PTRACE_KILL",
-    "PTRACE_SINGLESTEP",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_GETREGS",
-    "PTRACE_SETREGS",
-    "PTRACE_GETFPREGS",
-    "PTRACE_SETFPREGS",
-    "PTRACE_ATTACH",
-    "PTRACE_DETACH",
-    "PTRACE_GETFPXREGS",
-    "PTRACE_SETFPXREGS",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_INVALID",
-    "PTRACE_SYSCALL",
-};
-
-struct gdb_regs {
-    long ebx; /* 0 */
-    long ecx; /* 4 */
-    long edx; /* 8 */
-    long esi; /* 12 */
-    long edi; /* 16 */
-    long ebp; /* 20 */
-    long eax; /* 24 */ 
-    int  xds; /* 28 */
-    int  xes; /* 32 */
-    int  xfs; /* 36 */
-    int  xgs; /* 40 */
-    long orig_eax; /* 44 */
-    long eip;    /* 48 */
-    int  xcs;    /* 52 */
-    long eflags; /* 56 */
-    long esp;    /* 60 */     
-    int  xss;    /* 64 */
-};
-
-#define FETCH_REGS(cpu)                                         \
-    if (!regs_valid[cpu])                                       \
-    {                                                           \
-        int retval = xc_domain_get_vcpu_context(                \
-            xc_handle, domid, cpu, &ctxt[cpu]);                 \
-        if (retval)                                             \
-            goto error_out;                                     \
-        cr3[cpu] = ctxt[cpu].ctrlreg[3]; /* physical address */ \
-        regs_valid[cpu] = 1;                                    \
-    }
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
-#define SET_PT_REGS(pt, xc)                     \
-{                                               \
-    pt.ebx = xc.ebx;                            \
-    pt.ecx = xc.ecx;                            \
-    pt.edx = xc.edx;                            \
-    pt.esi = xc.esi;                            \
-    pt.edi = xc.edi;                            \
-    pt.ebp = xc.ebp;                            \
-    pt.eax = xc.eax;                            \
-    pt.eip = xc.eip;                            \
-    pt.xcs = xc.cs;                             \
-    pt.eflags = xc.eflags;                      \
-    pt.esp = xc.esp;                            \
-    pt.xss = xc.ss;                             \
-    pt.xes = xc.es;                             \
-    pt.xds = xc.ds;                             \
-    pt.xfs = xc.fs;                             \
-    pt.xgs = xc.gs;                             \
-}
-
-#define SET_XC_REGS(pt, xc)                     \
-{                                               \
-    xc.ebx = pt->ebx;                           \
-    xc.ecx = pt->ecx;                           \
-    xc.edx = pt->edx;                           \
-    xc.esi = pt->esi;                           \
-    xc.edi = pt->edi;                           \
-    xc.ebp = pt->ebp;                           \
-    xc.eax = pt->eax;                           \
-    xc.eip = pt->eip;                           \
-    xc.cs = pt->xcs;                            \
-    xc.eflags = pt->eflags;                     \
-    xc.esp = pt->esp;                           \
-    xc.ss = pt->xss;                            \
-    xc.es = pt->xes;                            \
-    xc.ds = pt->xds;                            \
-    xc.fs = pt->xfs;                            \
-    xc.gs = pt->xgs;                            \
-}
-
-#define vtopdi(va) ((va) >> PDRSHIFT)
-#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
+#include <thread_db.h>
+#include "xc_ptrace.h"
+
 
 /* XXX application state */
-static long   nr_pages = 0;
-unsigned long   *page_array = NULL;
-static int                      regs_valid[MAX_VIRT_CPUS];
-static unsigned long            cr3[MAX_VIRT_CPUS];
-static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
-
-static inline int paging_enabled(vcpu_guest_context_t *v)
+static long                     nr_pages = 0;
+static unsigned long           *page_array = NULL;
+static int                      current_domid = -1;
+
+static cpumap_t                 online_cpumap;
+static cpumap_t                 regs_valid;
+static vcpu_guest_context_t     ctxt[MAX_VIRT_CPUS];
+
+extern int ffsll(long long int);
+#define FOREACH_CPU(cpumap, i)  for ( cpumap = online_cpumap; (i = 
ffsll(cpumap)); cpumap &= ~(1 << (index - 1)) ) 
+
+
+static int
+fetch_regs(int xc_handle, int cpu, int *online)
+{
+    xc_vcpuinfo_t info;
+    int retval = 0;
+
+    if (online)
+        *online = 0;
+    if ( !(regs_valid & (1 << cpu)) ) { 
+        retval = xc_domain_get_vcpu_context(xc_handle, current_domid, 
+                                               cpu, &ctxt[cpu]);
+        if ( retval ) 
+            goto done;
+       regs_valid |= (1 << cpu);
+
+    }
+       if ( online == NULL )
+           goto done;
+
+       retval = xc_domain_get_vcpu_info(xc_handle, current_domid,
+                                        cpu, &info);
+       *online = info.online;
+    
+ done:
+    return retval;    
+}
+
+#define FETCH_REGS(cpu) if (fetch_regs(xc_handle, cpu, NULL)) goto error_out;
+
+
+static struct thr_ev_handlers {
+    thr_ev_handler_t td_create;
+    thr_ev_handler_t td_death;
+} handlers;
+
+void 
+xc_register_event_handler(thr_ev_handler_t h, 
+                          td_event_e e)
+{
+    switch (e) {
+    case TD_CREATE:
+        handlers.td_create = h;
+        break;
+    case TD_DEATH:
+        handlers.td_death = h;
+        break;
+    default:
+        abort(); /* XXX */
+    }
+}
+
+static inline int 
+paging_enabled(vcpu_guest_context_t *v)
 {
     unsigned long cr0 = v->ctrlreg[0];
     return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
+}
+
+/*
+ * Fetch registers for all online cpus and set the cpumap
+ * to indicate which cpus are online
+ *
+ */
+
+static int
+get_online_cpumap(int xc_handle, dom0_getdomaininfo_t *d, cpumap_t *cpumap)
+{
+    int i, online, retval;
+    
+    *cpumap = 0;
+    for (i = 0; i <= d->max_vcpu_id; i++) {
+        if ((retval = fetch_regs(xc_handle, i, &online)))
+            goto error_out;        
+        if (online)
+            *cpumap |= (1 << i);            
+    }
+    
+    return 0;
+ error_out:
+    return retval;
+}
+
+/* 
+ * Notify GDB of any vcpus that have come online or gone offline
+ * update online_cpumap
+ *
+ */
+
+static void
+online_vcpus_changed(cpumap_t cpumap)
+{
+    cpumap_t changed_cpumap = cpumap ^ online_cpumap;
+    int index;
+    
+    while ( (index = ffsll(changed_cpumap)) ) {
+        if ( cpumap & (1 << (index - 1)) ) {
+            if (handlers.td_create) handlers.td_create(index - 1);
+        } else {
+            printf("thread death: %d\n", index - 1);
+            if (handlers.td_death) handlers.td_death(index - 1);
+        }
+        changed_cpumap &= ~(1 << (index - 1));
+    }
+    online_cpumap = cpumap;
+    
 }
 
 /* --------------------- */
@@ -132,7 +136,6 @@
 static void *
 map_domain_va_pae(
     int xc_handle,
-    unsigned long domid,
     int cpu,
     void *guest_va,
     int perm)
@@ -144,24 +147,24 @@
     FETCH_REGS(cpu);
 
     l3 = xc_map_foreign_range(
-        xc_handle, domid, PAGE_SIZE, PROT_READ, cr3[cpu] >> PAGE_SHIFT);
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
     if ( l3 == NULL )
         goto error_out;
 
     l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
-    l2 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ, l2p);
+    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
     if ( l2 == NULL )
         goto error_out;
 
     l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
-    l1 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, l1p);
+    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
     if ( l1 == NULL )
         goto error_out;
 
     p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
     if ( v != NULL )
         munmap(v, PAGE_SIZE);
-    v = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, p);
+    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
     if ( v == NULL )
         goto error_out;
 
@@ -174,16 +177,17 @@
 static void *
 map_domain_va(
     int xc_handle,
-    unsigned long domid,
     int cpu,
     void *guest_va,
     int perm)
 {
+
     unsigned long pde, page;
     unsigned long va = (unsigned long)guest_va;
-    long npgs = xc_get_tot_pages(xc_handle, domid);
-
-    static unsigned long  cr3_phys[MAX_VIRT_CPUS];
+    long npgs = xc_get_tot_pages(xc_handle, current_domid);
+
+
+    static uint32_t  cr3_phys[MAX_VIRT_CPUS];
     static unsigned long *cr3_virt[MAX_VIRT_CPUS];
     static unsigned long  pde_phys[MAX_VIRT_CPUS];
     static unsigned long *pde_virt[MAX_VIRT_CPUS];
@@ -202,7 +206,7 @@
     }
 
     if ( mode == MODE_PAE )
-        return map_domain_va_pae(xc_handle, domid, cpu, guest_va, perm);
+        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
 
     if ( nr_pages != npgs )
     {
@@ -214,7 +218,7 @@
             printf("Could not allocate memory\n");
             goto error_out;
         }
-        if ( xc_get_pfn_list(xc_handle, domid,
+        if ( xc_get_pfn_list(xc_handle, current_domid,
                              page_array, nr_pages) != nr_pages )
         {
             printf("Could not get the page frame list\n");
@@ -224,13 +228,13 @@
 
     FETCH_REGS(cpu);
 
-    if ( cr3[cpu] != cr3_phys[cpu] )
-    {
-        cr3_phys[cpu] = cr3[cpu];
+    if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
+    {
+        cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
         if ( cr3_virt[cpu] )
             munmap(cr3_virt[cpu], PAGE_SIZE);
         cr3_virt[cpu] = xc_map_foreign_range(
-            xc_handle, domid, PAGE_SIZE, PROT_READ,
+            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
             cr3_phys[cpu] >> PAGE_SHIFT);
         if ( cr3_virt[cpu] == NULL )
             goto error_out;
@@ -245,7 +249,7 @@
         if ( pde_virt[cpu] )
             munmap(pde_virt[cpu], PAGE_SIZE);
         pde_virt[cpu] = xc_map_foreign_range(
-            xc_handle, domid, PAGE_SIZE, PROT_READ,
+            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
             pde_phys[cpu] >> PAGE_SHIFT);
         if ( pde_virt[cpu] == NULL )
             goto error_out;
@@ -260,7 +264,7 @@
         if ( page_virt[cpu] )
             munmap(page_virt[cpu], PAGE_SIZE);
         page_virt[cpu] = xc_map_foreign_range(
-            xc_handle, domid, PAGE_SIZE, perm,
+            xc_handle, current_domid, PAGE_SIZE, perm,
             page_phys[cpu] >> PAGE_SHIFT);
         if ( page_virt[cpu] == NULL )
         {
@@ -286,12 +290,15 @@
     DECLARE_DOM0_OP;
     int retval;
     struct timespec ts;
+    cpumap_t cpumap;
+
     ts.tv_sec = 0;
     ts.tv_nsec = 10*1000*1000;
 
     op.cmd = DOM0_GETDOMAININFO;
     op.u.getdomaininfo.domain = domain;
-
+    
+    
  retry:
     retval = do_dom0_op(xc_handle, &op);
     if ( retval || (op.u.getdomaininfo.domain != domain) )
@@ -309,17 +316,22 @@
         nanosleep(&ts,NULL);
         goto retry;
     }
-
+    /* XXX check for ^C here */
  done:
+    if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
+        printf("get_online_cpumap failed\n");
+    if (online_cpumap != cpumap)
+        online_vcpus_changed(cpumap);
     return retval;
 
 }
+
 
 long
 xc_ptrace(
     int xc_handle,
     enum __ptrace_request request,
-    uint32_t domid,
+    uint32_t domid_tid,
     long eaddr,
     long edata)
 {
@@ -328,18 +340,19 @@
     struct gdb_regs pt;
     long            retval = 0;
     unsigned long  *guest_va;
-    int             cpu = VCPU;
+    cpumap_t        cpumap;
+    int             cpu, index;
     void           *addr = (char *)eaddr;
     void           *data = (char *)edata;
 
-    op.interface_version = DOM0_INTERFACE_VERSION;
+    cpu = (request != PTRACE_ATTACH) ? domid_tid : 0;
     
     switch ( request )
     { 
     case PTRACE_PEEKTEXT:
     case PTRACE_PEEKDATA:
         guest_va = (unsigned long *)map_domain_va(
-            xc_handle, domid, cpu, addr, PROT_READ);
+            xc_handle, cpu, addr, PROT_READ);
         if ( guest_va == NULL )
         {
             status = EFAULT;
@@ -350,10 +363,10 @@
 
     case PTRACE_POKETEXT:
     case PTRACE_POKEDATA:
+        /* XXX assume that all CPUs have the same address space */
         guest_va = (unsigned long *)map_domain_va(
-            xc_handle, domid, cpu, addr, PROT_READ|PROT_WRITE);
-        if ( guest_va == NULL )
-        {
+                            xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
+        if ( guest_va == NULL ) {
             status = EFAULT;
             goto error_out;
         }
@@ -363,6 +376,7 @@
     case PTRACE_GETREGS:
     case PTRACE_GETFPREGS:
     case PTRACE_GETFPXREGS:
+        
         FETCH_REGS(cpu);
         if ( request == PTRACE_GETREGS )
         {
@@ -380,44 +394,18 @@
         break;
 
     case PTRACE_SETREGS:
-        op.cmd = DOM0_SETDOMAININFO;
-        SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs);
-        op.u.setdomaininfo.domain = domid;
-        /* XXX need to understand multiple vcpus */
-        op.u.setdomaininfo.vcpu = cpu;
-        op.u.setdomaininfo.ctxt = &ctxt[cpu];
-        retval = do_dom0_op(xc_handle, &op);
+        SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
+        retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
         if (retval)
             goto error_out;
         break;
 
-    case PTRACE_ATTACH:
-        op.cmd = DOM0_GETDOMAININFO;
-        op.u.getdomaininfo.domain = domid;
-        retval = do_dom0_op(xc_handle, &op);
-        if ( retval || (op.u.getdomaininfo.domain != domid) )
-        {
-            perror("dom0 op failed");
-            goto error_out;
-        }
-        if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
-        {
-            printf("domain currently paused\n");
-            goto error_out;
-        }
-        printf("domain not currently paused\n");
-        op.cmd = DOM0_PAUSEDOMAIN;
-        op.u.pausedomain.domain = domid;
-        retval = do_dom0_op(xc_handle, &op);
-        break;
-
     case PTRACE_SINGLESTEP:
-        ctxt[VCPU].user_regs.eflags |= PSL_T;
-        op.cmd = DOM0_SETDOMAININFO;
-        op.u.setdomaininfo.domain = domid;
-        op.u.setdomaininfo.vcpu = 0;
-        op.u.setdomaininfo.ctxt = &ctxt[cpu];
-        retval = do_dom0_op(xc_handle, &op); 
+        /*  XXX we can still have problems if the user switches threads
+         *  during single-stepping - but that just seems retarded
+         */
+        ctxt[cpu].user_regs.eflags |= PSL_T; 
+        retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
         if ( retval )
         {
             perror("dom0 op failed");
@@ -429,27 +417,56 @@
     case PTRACE_DETACH:
         if ( request != PTRACE_SINGLESTEP )
         {
-            FETCH_REGS(cpu);
-            /* Clear trace flag */
-            if ( ctxt[cpu].user_regs.eflags & PSL_T )
-            {
-                ctxt[cpu].user_regs.eflags &= ~PSL_T;
-                op.cmd = DOM0_SETDOMAININFO;
-                op.u.setdomaininfo.domain = domid;
-                op.u.setdomaininfo.vcpu = cpu;
-                op.u.setdomaininfo.ctxt = &ctxt[cpu];
-                retval = do_dom0_op(xc_handle, &op); 
-                if ( retval )
-                {
-                    perror("dom0 op failed");
-                    goto error_out;
+            FOREACH_CPU(cpumap, index) {
+                cpu = index - 1;
+                FETCH_REGS(cpu);
+                /* Clear trace flag */
+                if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
+                    ctxt[cpu].user_regs.eflags &= ~PSL_T;
+                    retval = xc_domain_setinfo(xc_handle, current_domid, 
+                                               cpu, &ctxt[cpu]);
+                    if ( retval ) {
+                        perror("dom0 op failed");
+                        goto error_out;
+                    }
                 }
             }
         }
-        regs_valid[cpu] = 0;
-        op.cmd = DOM0_UNPAUSEDOMAIN;
-        op.u.unpausedomain.domain = domid > 0 ? domid : -domid;
+        if ( request == PTRACE_DETACH )
+        {
+            op.cmd = DOM0_SETDEBUGGING;
+            op.u.setdebugging.domain = current_domid;
+            op.u.setdebugging.enable = 0;
+            retval = do_dom0_op(xc_handle, &op);
+        }
+        regs_valid = 0;
+        xc_domain_unpause(xc_handle, current_domid > 0 ? current_domid : 
-current_domid);
+        break;
+
+    case PTRACE_ATTACH:
+        current_domid = domid_tid;
+        op.cmd = DOM0_GETDOMAININFO;
+        op.u.getdomaininfo.domain = current_domid;
         retval = do_dom0_op(xc_handle, &op);
+        if ( retval || (op.u.getdomaininfo.domain != current_domid) )
+        {
+            perror("dom0 op failed");
+            goto error_out;
+        }
+        if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
+        {
+            printf("domain currently paused\n");
+        } else
+            retval = xc_domain_pause(xc_handle, current_domid);
+        op.cmd = DOM0_SETDEBUGGING;
+        op.u.setdebugging.domain = current_domid;
+        op.u.setdebugging.enable = 1;
+        retval = do_dom0_op(xc_handle, &op);
+
+        if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
+            printf("get_online_cpumap failed\n");
+        if (online_cpumap != cpumap)
+            online_vcpus_changed(cpumap);
         break;
 
     case PTRACE_SETFPREGS:
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xc_vmx_build.c        Tue Dec 20 17:16:24 2005
@@ -288,11 +288,11 @@
     l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
     unsigned long *page_array = NULL;
 #ifdef __x86_64__
-    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
+    l3_pgentry_t *vl3tab=NULL;
     unsigned long l3tab;
 #endif
-    unsigned long l2tab;
-    unsigned long l1tab;
+    unsigned long l2tab = 0;
+    unsigned long l1tab = 0;
     unsigned long count, i;
     shared_info_t *shared_info;
     void *e820_page;
@@ -323,7 +323,7 @@
     }
 
     /* memsize is in megabytes */
-    v_end              = memsize << 20;
+    v_end              = (unsigned long)memsize << 20;
 
 #ifdef __i386__
     nr_pt_pages = 1 + ((memsize + 3) >> 2);
@@ -435,15 +435,16 @@
             goto error_out;
         memset(vl2tab, 0, PAGE_SIZE);
         munmap(vl2tab, PAGE_SIZE);
+        vl2tab = NULL;
         vl3tab[i] = l2tab | L3_PROT;
     }
 
-    vl3e = &vl3tab[l3_table_offset(0)];
     for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
     {
-        if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
+        if ( !(count & ((1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)) - 1)) 
)
+        {
             l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
-                & PAGE_MASK;
+                    & PAGE_MASK;
 
             if (vl2tab != NULL)
                 munmap(vl2tab, PAGE_SIZE);
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xenctrl.h     Tue Dec 20 17:16:24 2005
@@ -94,25 +94,12 @@
 } xc_core_header_t;
 
 
-long xc_ptrace(
-    int xc_handle,
-    enum __ptrace_request request, 
-    uint32_t  domid,
-    long addr, 
-    long data);
-
 long xc_ptrace_core(
     int xc_handle,
     enum __ptrace_request request, 
     uint32_t domid, 
     long addr, 
     long data);
-
-int xc_waitdomain(
-    int xc_handle,
-    int domain, 
-    int *status, 
-    int options);
 
 int xc_waitdomain_core(
     int xc_handle,
@@ -219,6 +206,20 @@
                       unsigned int max_doms,
                       xc_dominfo_t *info);
 
+
+/**
+ * This function will set the vcpu context for the specified domain.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain to set the vcpu context for
+ * @parm vcpu the vcpu number for the context
+ * @parm ctxt pointer to the the cpu context with the values to set
+ * @return the number of domains enumerated or -1 on error
+ */
+int xc_domain_setinfo(int xc_handle,
+                      uint32_t domid,
+                      uint32_t vcpu,
+                      vcpu_guest_context_t *ctxt);
 /**
  * This function will return information about one or more domains, using a
  * single hypercall.  The domain information will be stored into the supplied
diff -r 11cd619db035 -r d3b10a2a82d4 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Dec 20 17:16:15 2005
+++ b/tools/python/xen/xend/image.py    Tue Dec 20 17:16:24 2005
@@ -237,7 +237,7 @@
     # Return a list of cmd line args to the device models based on the
     # xm config file
     def parseDeviceModelArgs(self, imageConfig, deviceConfig):
-        dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 
+        dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 'audio',
                    'localtime', 'serial', 'stdvga', 'isa', 'vcpus']
         ret = []
         for a in dmargs:
@@ -246,9 +246,10 @@
             # python doesn't allow '-' in variable names
             if a == 'stdvga': a = 'std-vga'
             if a == 'ne2000': a = 'nic-ne2000'
+            if a == 'audio': a = 'enable-audio'
 
             # Handle booleans gracefully
-            if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000']:
+            if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000', 
'enable-audio']:
                 if v != None: v = int(v)
                 if v: ret.append("-%s" % a)
             else:
diff -r 11cd619db035 -r d3b10a2a82d4 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Dec 20 17:16:15 2005
+++ b/tools/python/xen/xm/create.py     Tue Dec 20 17:16:24 2005
@@ -371,6 +371,10 @@
 gopts.var('ne2000', val='no|yes',
           fn=set_bool, default=0,
           use="Should device models use ne2000?")
+
+gopts.var('audio', val='no|yes',
+          fn=set_bool, default=0,
+          use="Should device models enable audio?")
 
 gopts.var('vnc', val='',
           fn=set_value, default=None,
@@ -521,7 +525,7 @@
     """Create the config for VMX devices.
     """
     args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
-             'localtime', 'serial', 'stdvga', 'isa', 'nographic',
+             'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
              'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
     for a in args:
         if (vals.__dict__[a]):
diff -r 11cd619db035 -r d3b10a2a82d4 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c        Tue Dec 20 17:16:15 2005
+++ b/tools/vtpm_manager/manager/securestorage.c        Tue Dec 20 17:16:24 2005
@@ -54,48 +54,138 @@
 #include "buffer.h"
 #include "log.h"
 
+TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
+                            CRYPTO_INFO  *asymkey,
+                            buffer_t           *sealed_data) {
+  TPM_RESULT status = TPM_SUCCESS;
+  symkey_t    symkey;
+  buffer_t    data_cipher = NULL_BUF,
+              symkey_cipher = NULL_BUF;
+  
+  UINT32 i;
+  struct pack_constbuf_t symkey_cipher32, data_cipher32;
+  
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
+  for (i=0; i< buffer_len(inbuf); i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+  
+  // Generate a sym key and encrypt state with it
+  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
+  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, 
&data_cipher) );
+  
+  // Encrypt symmetric key
+  TPMTRYRETURN( VTSP_Bind(    asymkey, 
+                             &symkey.key, 
+                             &symkey_cipher) );
+  
+  // Create output blob: symkey_size + symkey_cipher + state_cipher_size + 
state_cipher
+  
+  symkey_cipher32.size = buffer_len(&symkey_cipher);
+  symkey_cipher32.data = symkey_cipher.bytes;
+  
+  data_cipher32.size = buffer_len(&data_cipher);
+  data_cipher32.data = data_cipher.bytes;
+  
+  TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + 
symkey_cipher32.size + data_cipher32.size, NULL));
+  
+  BSG_PackList(sealed_data->bytes, 2,
+              BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+              BSG_TPM_SIZE32_DATA, &data_cipher32);
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of 
E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
+  goto egress;
+
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope encrypt\n.");
+  
+ egress:
+  
+  buffer_free ( &data_cipher);
+  buffer_free ( &symkey_cipher);
+  Crypto_symcrypto_freekey (&symkey);
+  
+  return status;
+}
+
+TPM_RESULT envelope_decrypt(const long         cipher_size,
+                            const BYTE         *cipher,
+                            TCS_CONTEXT_HANDLE TCSContext,
+                           TPM_HANDLE         keyHandle,
+                           const TPM_AUTHDATA *key_usage_auth,
+                            buffer_t           *unsealed_data) {
+
+  TPM_RESULT status = TPM_SUCCESS;
+  symkey_t    symkey;
+  buffer_t    data_cipher = NULL_BUF, 
+              symkey_clear = NULL_BUF, 
+              symkey_cipher = NULL_BUF;
+  struct pack_buf_t symkey_cipher32, data_cipher32;
+  int i;
+
+  memset(&symkey, 0, sizeof(symkey_t));
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
+  for (i=0; i< cipher_size; i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+  
+  BSG_UnpackList(cipher, 2,
+                BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+                BSG_TPM_SIZE32_DATA, &data_cipher32);
+  
+  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
+                                    symkey_cipher32.size, 
+                                    symkey_cipher32.data) );
+  
+  TPMTRYRETURN( buffer_init_convert (&data_cipher, 
+                                    data_cipher32.size, 
+                                    data_cipher32.data) );
+
+  // Decrypt Symmetric Key
+  TPMTRYRETURN( VTSP_Unbind(  TCSContext,
+                             keyHandle,
+                             &symkey_cipher,
+                             key_usage_auth,
+                             &symkey_clear,
+                             &(vtpm_globals->keyAuth) ) );
+  
+  // create symmetric key using saved bits
+  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
+  
+  // Decrypt State
+  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, 
unsealed_data) );
+  
+  goto egress;
+  
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope decrypt data\n.");
+  
+ egress:
+  buffer_free ( &data_cipher);
+  buffer_free ( &symkey_clear);
+  buffer_free ( &symkey_cipher);
+  Crypto_symcrypto_freekey (&symkey);
+  
+  return status;
+}
+
 TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
                                const buffer_t *inbuf, 
                                buffer_t *outbuf) {
   
   TPM_RESULT status = TPM_SUCCESS;
-  symkey_t    symkey;
-  buffer_t    state_cipher = NULL_BUF,
-              symkey_cipher = NULL_BUF;
   int fh;
   long bytes_written;
-  BYTE *sealed_NVM=NULL;
-  UINT32 sealed_NVM_size, i;
-  struct pack_constbuf_t symkey_cipher32, state_cipher32;
-  
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
-  for (i=0; i< buffer_len(inbuf); i++)
-    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
-  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-  
-  // Generate a sym key and encrypt state with it
-  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
-  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, 
&state_cipher) );
-  
-  // Encrypt symmetric key
-  TPMTRYRETURN( VTSP_Bind(    &vtpm_globals->storageKey, 
-                             &symkey.key, 
-                             &symkey_cipher) );
-  
-  // Create output blob: symkey_size + symkey_cipher + state_cipher_size + 
state_cipher
-  
-  symkey_cipher32.size = buffer_len(&symkey_cipher);
-  symkey_cipher32.data = symkey_cipher.bytes;
-  
-  state_cipher32.size = buffer_len(&state_cipher);
-  state_cipher32.data = state_cipher.bytes;
-  
-  sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size + 
state_cipher32.size);
-  
-  sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
-                                BSG_TPM_SIZE32_DATA, &symkey_cipher32,
-                                BSG_TPM_SIZE32_DATA, &state_cipher32);
-  
+  buffer_t sealed_NVM;
+  
+  
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
+
+  TPMTRYRETURN( envelope_encrypt(inbuf,
+                                 &vtpm_globals->storageKey,
+                                 &sealed_NVM) );
+                                 
   // Mark DMI Table so new save state info will get pushed to disk on return.
   vtpm_globals->DMI_table_dirty = TRUE;
   
@@ -104,28 +194,22 @@
   //       after writing the file? We can't get the old one back.
   // TODO: Backup old file and try and recover that way.
   fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
-  if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long) 
sealed_NVM_size) {
-    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to 
finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
+  if ( (bytes_written = write(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM) ) 
!= (long) buffer_len(&sealed_NVM))) {
+    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to 
finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_NVM));
     status = TPM_IOERROR;
     goto abort_egress;
   }
   close(fh);
   
-  Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *) 
&myDMI->NVM_measurement);   
-  
-  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of 
E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
-  goto egress;
-  
- abort_egress:
-  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
-  
- egress:
-  
-  buffer_free ( &state_cipher);
-  buffer_free ( &symkey_cipher);
-  free(sealed_NVM);
-  Crypto_symcrypto_freekey (&symkey);
-  
+  Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) 
&myDMI->NVM_measurement);   
+  
+  goto egress;
+  
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
+  
+ egress:
+  buffer_free(&sealed_NVM);
   return status;
 }
 
@@ -136,11 +220,7 @@
                                buffer_t *outbuf) {
   
   TPM_RESULT status = TPM_SUCCESS;
-  symkey_t    symkey;
-  buffer_t    state_cipher = NULL_BUF, 
-              symkey_clear = NULL_BUF, 
-              symkey_cipher = NULL_BUF;
-  struct pack_buf_t symkey_cipher32, state_cipher32;
+
   
   UINT32 sealed_NVM_size;
   BYTE *sealed_NVM = NULL;
@@ -148,9 +228,7 @@
   int fh, stat_ret, i;
   struct stat file_stat;
   TPM_DIGEST sealedNVMHash;
-  
-  memset(&symkey, 0, sizeof(symkey_t));
-  
+   
   if (myDMI->NVMLocation == NULL) {
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name 
NULL.\n");
     status = TPM_AUTHFAIL;
@@ -168,28 +246,14 @@
   }
   
   sealed_NVM = (BYTE *) malloc(fh_size);
+  sealed_NVM_size = (UINT32) fh_size;
   if (read(fh, sealed_NVM, fh_size) != fh_size) {
     status = TPM_IOERROR;
     goto abort_egress;
   }
   close(fh);
   
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
-  for (i=0; i< fh_size; i++)
-    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
-  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-  
-  sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
-                                  BSG_TPM_SIZE32_DATA, &symkey_cipher32,
-                                  BSG_TPM_SIZE32_DATA, &state_cipher32);
-  
-  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
-                                    symkey_cipher32.size, 
-                                    symkey_cipher32.data) );
-  
-  TPMTRYRETURN( buffer_init_convert (&state_cipher, 
-                                    state_cipher32.size, 
-                                    state_cipher32.data) );
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld],\n", fh_size);
   
   Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
   
@@ -210,32 +274,19 @@
     goto abort_egress;
   }
   
-  // Decrypt Symmetric Key
-  TPMTRYRETURN( VTSP_Unbind(  myDMI->TCSContext,
-                             vtpm_globals->storageKeyHandle,
-                             &symkey_cipher,
-                             (const 
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
-                             &symkey_clear,
-                             &(vtpm_globals->keyAuth) ) );
-  
-  // create symmetric key using saved bits
-  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
-  
-  // Decrypt State
-  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher, 
outbuf) );
-  
+    TPMTRYRETURN( envelope_decrypt(fh_size,
+                                 sealed_NVM,
+                                 myDMI->TCSContext,
+                                vtpm_globals->storageKeyHandle,
+                                (const 
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+                                 outbuf) );  
   goto egress;
   
  abort_egress:
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
   
  egress:
-  
-  buffer_free ( &state_cipher);
-  buffer_free ( &symkey_clear);
-  buffer_free ( &symkey_cipher);
   free( sealed_NVM );
-  Crypto_symcrypto_freekey (&symkey);
   
   return status;
 }
diff -r 11cd619db035 -r d3b10a2a82d4 tools/xm-test/README
--- a/tools/xm-test/README      Tue Dec 20 17:16:15 2005
+++ b/tools/xm-test/README      Tue Dec 20 17:16:24 2005
@@ -54,6 +54,26 @@
 you should not attempt to use a ramdisk from a previous minor version
 of xm-test (i.e., don't use a ramdisk from 0.4.0 with 0.5.0.  0.5.0
 should work for 0.5.3 though)
+
+If you'd like to build and run this with hardware virtual machine assist
+(HVM) support to test fully virtualized disk images on VMX hardware, 
+please add the --enable-vmx-support option to configure:
+
+  # ./autogen
+  # ./configure --enable-vmx-support
+  # make
+
+The ramdisk/bin/create_disk_image script, which builds the full virt
+disk.img, requires Lilo 22.7+ to be installed on the system. Lilo is 
+used to install the bootloader on the disk.img.
+
+If HVM / VMX support is enabled, the ramdisk/bin/create_disk_image script
+will be run to create a full virt disk.img in the ramdisk directory. The
+script, by default, will look in /boot for the first non-Xen kernel it
+runs across. If you wish to use a different kernel or the script fails
+to find a kernel, please run the script manually to make a disk.img 
+using the -k option. Xm-test will look for disk.img in the ramdisk
+directory when run by default.
 
 
 Running
diff -r 11cd619db035 -r d3b10a2a82d4 tools/xm-test/ramdisk/Makefile.am
--- a/tools/xm-test/ramdisk/Makefile.am Tue Dec 20 17:16:15 2005
+++ b/tools/xm-test/ramdisk/Makefile.am Tue Dec 20 17:16:24 2005
@@ -45,7 +45,7 @@
 
 disk.img: $(XMTEST_VER_IMG)
        chmod a+x $(VMX_SCRIPT)
-       $(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -i disk.img
+       $(VMX_SCRIPT) -r $(XMTEST_VER_IMG)
 
 existing:
        @[ -f $(XMTEST_VER_IMG) ] && ln -sf $(XMTEST_VER_IMG) initrd.img || \
diff -r 11cd619db035 -r d3b10a2a82d4 tools/xm-test/ramdisk/bin/create_disk_image
--- a/tools/xm-test/ramdisk/bin/create_disk_image       Tue Dec 20 17:16:15 2005
+++ b/tools/xm-test/ramdisk/bin/create_disk_image       Tue Dec 20 17:16:24 2005
@@ -77,7 +77,7 @@
 function initialize_globals()
 {
        PROGNAME="create_disk_image"
-       IMAGE="hvm.img"
+       IMAGE="disk.img"
        KERNEL=""
        LCONF="lilo.conf"
        LOOPD=""    # Loop device for entire disk image
diff -r 11cd619db035 -r d3b10a2a82d4 xen/Rules.mk
--- a/xen/Rules.mk      Tue Dec 20 17:16:15 2005
+++ b/xen/Rules.mk      Tue Dec 20 17:16:24 2005
@@ -6,7 +6,6 @@
 debug       ?= n
 perfc       ?= n
 perfc_arrays?= n
-domu_debug  ?= n
 crash_debug ?= n
 
 XEN_ROOT=$(BASEDIR)/..
@@ -54,10 +53,6 @@
 CFLAGS += -g -DVERBOSE
 endif
 
-ifeq ($(domu_debug),y)
-CFLAGS += -DDOMU_DEBUG
-endif
-
 ifeq ($(crash_debug),y)
 CFLAGS += -g -DCRASH_DEBUG
 endif
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c      Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/audit.c      Tue Dec 20 17:16:24 2005
@@ -61,7 +61,7 @@
 #ifdef __i386__
 #ifdef CONFIG_X86_PAE
         /* 32b PAE */
-        if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask ) 
+        if ( (( pfn_to_page(mfn)->u.inuse.type_info & PGT_va_mask ) 
            >> PGT_va_shift) == 3 )
             return l2_table_offset(HYPERVISOR_VIRT_START); 
         else
@@ -364,7 +364,7 @@
             {
                 gmfn = __gpfn_to_mfn(d, a->gpfn_and_flags & PGT_mfn_mask);
                 smfn = a->smfn;
-                page = &frame_table[smfn];
+                page = pfn_to_page(smfn);
 
                 switch ( a->gpfn_and_flags & PGT_type_mask ) {
                 case PGT_writable_pred:
@@ -433,11 +433,13 @@
         for_each_vcpu(d, v)
         {
             if ( pagetable_get_paddr(v->arch.guest_table) )
-                adjust(&frame_table[pagetable_get_pfn(v->arch.guest_table)], 
!shadow_mode_refcounts(d));
+                adjust(pfn_to_page(pagetable_get_pfn(v->arch.guest_table)),
+                       !shadow_mode_refcounts(d));
             if ( pagetable_get_paddr(v->arch.shadow_table) )
-                adjust(&frame_table[pagetable_get_pfn(v->arch.shadow_table)], 
0);
+                adjust(pfn_to_page(pagetable_get_pfn(v->arch.shadow_table)),
+                       0);
             if ( v->arch.monitor_shadow_ref )
-                adjust(&frame_table[v->arch.monitor_shadow_ref], 0);
+                adjust(pfn_to_page(v->arch.monitor_shadow_ref), 0);
         }
     }
 
@@ -617,7 +619,7 @@
     void scan_for_pfn_in_mfn(struct domain *d, unsigned long xmfn,
                              unsigned long mfn)
     {
-        struct pfn_info *page = &frame_table[mfn];
+        struct pfn_info *page = pfn_to_page(mfn);
         l1_pgentry_t *pt = map_domain_page(mfn);
         int i;
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/dom0_ops.c   Tue Dec 20 17:16:24 2005
@@ -210,7 +210,7 @@
              unlikely((d = find_domain_by_id(dom)) == NULL) )
             break;
 
-        page = &frame_table[pfn];
+        page = pfn_to_page(pfn);
 
         if ( likely(get_page(page, d)) )
         {
@@ -285,7 +285,7 @@
                 struct pfn_info *page;
                 unsigned long mfn = l_arr[j];
 
-                page = &frame_table[mfn];
+                page = pfn_to_page(mfn);
 
                 if ( likely(pfn_valid(mfn) && get_page(page, d)) ) 
                 {
@@ -350,15 +350,14 @@
             list_ent = d->page_list.next;
             for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
             {
-                pfn = list_entry(list_ent, struct pfn_info, list) - 
-                    frame_table;
+                pfn = page_to_pfn(list_entry(list_ent, struct pfn_info, list));
                 if ( put_user(pfn, buffer) )
                 {
                     ret = -EFAULT;
                     break;
                 }
                 buffer++;
-                list_ent = frame_table[pfn].list.next;
+                list_ent = pfn_to_page(pfn)->list.next;
             }
             spin_unlock(&d->page_alloc_lock);
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/domain.c     Tue Dec 20 17:16:24 2005
@@ -190,7 +190,7 @@
         list_for_each_entry ( page, &d->page_list, list )
         {
             printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
-                   _p(page_to_phys(page)), _p(page - frame_table),
+                   _p(page_to_phys(page)), _p(page_to_pfn(page)),
                    page->count_info, page->u.inuse.type_info);
         }
     }
@@ -198,13 +198,13 @@
     list_for_each_entry ( page, &d->xenpage_list, list )
     {
         printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
-               _p(page_to_phys(page)), _p(page - frame_table),
+               _p(page_to_phys(page)), _p(page_to_pfn(page)),
                page->count_info, page->u.inuse.type_info);
     }
 
     page = virt_to_page(d->shared_info);
     printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
-           _p(page_to_phys(page)), _p(page - frame_table), page->count_info,
+           _p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info,
            page->u.inuse.type_info);
 }
 
@@ -391,19 +391,19 @@
 
     if ( shadow_mode_refcounts(d) )
     {
-        if ( !get_page(&frame_table[phys_basetab>>PAGE_SHIFT], d) )
+        if ( !get_page(pfn_to_page(phys_basetab>>PAGE_SHIFT), d) )
             return -EINVAL;
     }
     else if ( !(c->flags & VGCF_VMX_GUEST) )
     {
-        if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
+        if ( !get_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT), d,
                                 PGT_base_page_table) )
             return -EINVAL;
     }
 
     if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
     {
-        put_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT]);
+        put_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT));
         return rc;
     }
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/domain_build.c       Tue Dec 20 17:16:24 2005
@@ -405,7 +405,7 @@
         *l1tab = l1e_from_pfn(mfn, L1_PROT);
         l1tab++;
         
-        page = &frame_table[mfn];
+        page = pfn_to_page(mfn);
         if ( !get_page_and_type(page, d, PGT_writable_page) )
             BUG();
 
@@ -418,7 +418,7 @@
     l1tab += l1_table_offset(vpt_start);
     for ( count = 0; count < nr_pt_pages; count++ ) 
     {
-        page = &frame_table[l1e_get_pfn(*l1tab)];
+        page = pfn_to_page(l1e_get_pfn(*l1tab));
         if ( !opt_dom0_shadow )
             l1e_remove_flags(*l1tab, _PAGE_RW);
         else
@@ -548,7 +548,7 @@
         *l1tab = l1e_from_pfn(mfn, L1_PROT);
         l1tab++;
 
-        page = &frame_table[mfn];
+        page = pfn_to_page(mfn);
         if ( (page->u.inuse.type_info == 0) &&
              !get_page_and_type(page, d, PGT_writable_page) )
             BUG();
@@ -567,7 +567,7 @@
     for ( count = 0; count < nr_pt_pages; count++ ) 
     {
         l1e_remove_flags(*l1tab, _PAGE_RW);
-        page = &frame_table[l1e_get_pfn(*l1tab)];
+        page = pfn_to_page(l1e_get_pfn(*l1tab));
 
         /* Read-only mapping + PGC_allocated + page-table page. */
         page->count_info         = PGC_allocated | 3;
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/mm.c Tue Dec 20 17:16:24 2005
@@ -202,7 +202,7 @@
     /* First 1MB of RAM is historically marked as I/O. */
     for ( i = 0; i < 0x100; i++ )
     {
-        page = &frame_table[i];
+        page = pfn_to_page(i);
         page->count_info        = PGC_allocated | 1;
         page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
         page_set_owner(page, dom_io);
@@ -216,10 +216,10 @@
         /* Every page from cursor to start of next RAM region is I/O. */
         rstart_pfn = PFN_UP(e820.map[i].addr);
         rend_pfn   = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
-        while ( pfn < rstart_pfn )
+        for ( ; pfn < rstart_pfn; pfn++ )
         {
             BUG_ON(!pfn_valid(pfn));
-            page = &frame_table[pfn++];
+            page = pfn_to_page(pfn);
             page->count_info        = PGC_allocated | 1;
             page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
             page_set_owner(page, dom_io);
@@ -253,7 +253,7 @@
         pfn = l1e_get_pfn(v->arch.perdomain_ptes[i]);
         if ( pfn == 0 ) continue;
         v->arch.perdomain_ptes[i] = l1e_empty();
-        page = &frame_table[pfn];
+        page = pfn_to_page(pfn);
         ASSERT_PAGE_IS_TYPE(page, PGT_ldt_page);
         ASSERT_PAGE_IS_DOMAIN(page, v->domain);
         put_page_and_type(page);
@@ -320,13 +320,13 @@
     if ( unlikely(!VALID_MFN(gmfn)) )
         return 0;
 
-    res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
+    res = get_page_and_type(pfn_to_page(gmfn), d, PGT_ldt_page);
 
     if ( !res && unlikely(shadow_mode_refcounts(d)) )
     {
         shadow_lock(d);
         shadow_remove_all_write_access(d, gpfn, gmfn);
-        res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
+        res = get_page_and_type(pfn_to_page(gmfn), d, PGT_ldt_page);
         shadow_unlock(d);
     }
 
@@ -344,7 +344,7 @@
 
 static int get_page_from_pagenr(unsigned long page_nr, struct domain *d)
 {
-    struct pfn_info *page = &frame_table[page_nr];
+    struct pfn_info *page = pfn_to_page(page_nr);
 
     if ( unlikely(!pfn_valid(page_nr)) || unlikely(!get_page(page, d)) )
     {
@@ -360,7 +360,7 @@
                                          unsigned long type,
                                          struct domain *d)
 {
-    struct pfn_info *page = &frame_table[page_nr];
+    struct pfn_info *page = pfn_to_page(page_nr);
 
     if ( unlikely(!get_page_from_pagenr(page_nr, d)) )
         return 0;
@@ -412,7 +412,7 @@
          * Make sure that the mapped frame is an already-validated L2 table. 
          * If so, atomically increment the count (checking for overflow).
          */
-        page = &frame_table[pfn];
+        page = pfn_to_page(pfn);
         y = page->u.inuse.type_info;
         do {
             x = y;
@@ -435,7 +435,7 @@
     l1_pgentry_t l1e, struct domain *d)
 {
     unsigned long mfn = l1e_get_pfn(l1e);
-    struct pfn_info *page = &frame_table[mfn];
+    struct pfn_info *page = pfn_to_page(mfn);
     int okay;
     extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn);
 
@@ -587,7 +587,7 @@
 void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
 {
     unsigned long    pfn  = l1e_get_pfn(l1e);
-    struct pfn_info *page = &frame_table[pfn];
+    struct pfn_info *page = pfn_to_page(pfn);
     struct domain   *e;
     struct vcpu     *v;
 
@@ -645,7 +645,7 @@
 {
     if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && 
          (l2e_get_pfn(l2e) != pfn) )
-        put_page_and_type(&frame_table[l2e_get_pfn(l2e)]);
+        put_page_and_type(pfn_to_page(l2e_get_pfn(l2e)));
 }
 
 
@@ -655,7 +655,7 @@
 {
     if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && 
          (l3e_get_pfn(l3e) != pfn) )
-        put_page_and_type(&frame_table[l3e_get_pfn(l3e)]);
+        put_page_and_type(pfn_to_page(l3e_get_pfn(l3e)));
 }
 
 #endif
@@ -666,7 +666,7 @@
 {
     if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && 
          (l4e_get_pfn(l4e) != pfn) )
-        put_page_and_type(&frame_table[l4e_get_pfn(l4e)]);
+        put_page_and_type(pfn_to_page(l4e_get_pfn(l4e)));
 }
 
 #endif
@@ -1584,9 +1584,9 @@
         write_ptbase(v);
 
         if ( shadow_mode_refcounts(d) )
-            put_page(&frame_table[old_base_mfn]);
+            put_page(pfn_to_page(old_base_mfn));
         else
-            put_page_and_type(&frame_table[old_base_mfn]);
+            put_page_and_type(pfn_to_page(old_base_mfn));
 
         /* CR3 also holds a ref to its shadow... */
         if ( shadow_mode_enabled(d) )
@@ -1595,7 +1595,7 @@
                 put_shadow_ref(v->arch.monitor_shadow_ref);
             v->arch.monitor_shadow_ref =
                 pagetable_get_pfn(v->arch.monitor_table);
-            ASSERT(!page_get_owner(&frame_table[v->arch.monitor_shadow_ref]));
+            ASSERT(!page_get_owner(pfn_to_page(v->arch.monitor_shadow_ref)));
             get_shadow_ref(v->arch.monitor_shadow_ref);
         }
     }
@@ -1763,7 +1763,7 @@
 
         okay = 1;
         mfn  = op.arg1.mfn;
-        page = &frame_table[mfn];
+        page = pfn_to_page(mfn);
 
         switch ( op.cmd )
         {
@@ -1845,7 +1845,7 @@
                     pagetable_get_pfn(v->arch.guest_table_user);
                 v->arch.guest_table_user = mk_pagetable(mfn << PAGE_SHIFT);
                 if ( old_mfn != 0 )
-                    put_page_and_type(&frame_table[old_mfn]);
+                    put_page_and_type(pfn_to_page(old_mfn));
             }
             break;
 #endif
@@ -2145,7 +2145,7 @@
             va = map_domain_page_with_cache(mfn, &mapcache);
             va = (void *)((unsigned long)va +
                           (unsigned long)(req.ptr & ~PAGE_MASK));
-            page = &frame_table[mfn];
+            page = pfn_to_page(mfn);
 
             switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
             {
@@ -2285,7 +2285,7 @@
 
             mark_dirty(FOREIGNDOM, mfn);
 
-            put_page(&frame_table[mfn]);
+            put_page(pfn_to_page(mfn));
             break;
 
         default:
@@ -2728,7 +2728,7 @@
     for ( i = 0; i < FIRST_RESERVED_GDT_PAGE; i++ )
     {
         if ( (pfn = l1e_get_pfn(v->arch.perdomain_ptes[i])) != 0 )
-            put_page_and_type(&frame_table[pfn]);
+            put_page_and_type(pfn_to_page(pfn));
         v->arch.perdomain_ptes[i] = l1e_empty();
         v->arch.guest_context.gdt_frames[i] = 0;
     }
@@ -2753,7 +2753,7 @@
     for ( i = 0; i < nr_pages; i++ ) {
         pfn = frames[i];
         if ((pfn >= max_page) ||
-            !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
+            !get_page_and_type(pfn_to_page(pfn), d, PGT_gdt_page) )
             goto fail;
     }
 
@@ -2773,7 +2773,7 @@
 
  fail:
     while ( i-- > 0 )
-        put_page_and_type(&frame_table[frames[i]]);
+        put_page_and_type(pfn_to_page(frames[i]));
     return -EINVAL;
 }
 
@@ -2827,7 +2827,7 @@
         return -EINVAL;
     }
 
-    page = &frame_table[mfn];
+    page = pfn_to_page(mfn);
     if ( unlikely(!get_page(page, dom)) )
     {
         UNLOCK_BIGLOCK(dom);
@@ -3037,7 +3037,7 @@
         if ( likely(l1e_get_intpte(ol1e) == (l1e_get_intpte(nl1e)|_PAGE_RW)) )
         {
             if ( likely(l1e_get_flags(nl1e) & _PAGE_PRESENT) )
-                put_page_type(&frame_table[l1e_get_pfn(nl1e)]);
+                put_page_type(pfn_to_page(l1e_get_pfn(nl1e)));
             continue;
         }
 
@@ -3220,7 +3220,7 @@
     }
 
     pfn  = l1e_get_pfn(pte);
-    page = &frame_table[pfn];
+    page = pfn_to_page(pfn);
 
     /* We are looking only for read-only mappings of p.t. pages. */
     if ( ((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) != _PAGE_PRESENT) ||
@@ -3331,7 +3331,7 @@
     }
 
     pfn  = l1e_get_pfn(pte);
-    page = &frame_table[pfn];
+    page = pfn_to_page(pfn);
 
 #ifdef CONFIG_X86_64
 #define WRPT_PTE_FLAGS (_PAGE_RW | _PAGE_PRESENT | _PAGE_USER)
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/setup.c      Tue Dec 20 17:16:24 2005
@@ -264,7 +264,7 @@
     unsigned long _initrd_start = 0, _initrd_len = 0;
     unsigned int initrdidx = 1;
     physaddr_t s, e;
-    int i, e820_raw_nr = 0, bytes = 0;
+    int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
     struct ns16550_defaults ns16550 = {
         .data_bits = 8,
         .parity    = 'n',
@@ -313,6 +313,22 @@
         while ( bytes < mbi->mmap_length )
         {
             memory_map_t *map = __va(mbi->mmap_addr + bytes);
+
+            /*
+             * This is a gross workaround for a BIOS bug. Some bootloaders do
+             * not write e820 map entries into pre-zeroed memory. This is
+             * okay if the BIOS fills in all fields of the map entry, but
+             * some broken BIOSes do not bother to write the high word of
+             * the length field if the length is smaller than 4GB. We
+             * detect and fix this by flagging sections below 4GB that
+             * appear to be larger than 4GB in size.
+             */
+            if ( (map->base_addr_high == 0) && (map->length_high != 0) )
+            {
+                e820_warn = 1;
+                map->length_high = 0;
+            }
+
             e820_raw[e820_raw_nr].addr = 
                 ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
             e820_raw[e820_raw_nr].size = 
@@ -320,6 +336,7 @@
             e820_raw[e820_raw_nr].type = 
                 (map->type > E820_SHARED_PAGE) ? E820_RESERVED : map->type;
             e820_raw_nr++;
+
             bytes += map->size + 4;
         }
     }
@@ -338,6 +355,10 @@
         printk("FATAL ERROR: Bootloader provided no memory information.\n");
         for ( ; ; ) ;
     }
+
+    if ( e820_warn )
+        printk("WARNING: Buggy e820 map detected and fixed "
+               "(truncated length fields).\n");
 
     max_page = init_e820(e820_raw, &e820_raw_nr);
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/shadow.c     Tue Dec 20 17:16:24 2005
@@ -504,7 +504,7 @@
             l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
 
         spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-            
l2e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt),
+            
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
                             __PAGE_HYPERVISOR);
 
         if ( shadow_mode_translate(d) ) // NB: not external
@@ -670,7 +670,7 @@
             set_guest_back_ptr(d, sl1e, sl1mfn, i);
         }
 
-        frame_table[sl1mfn].tlbflush_timestamp =
+        pfn_to_page(sl1mfn)->tlbflush_timestamp =
             SHADOW_ENCODE_MIN_MAX(min, max);
 
         unmap_domain_page(gpl1e);
@@ -907,7 +907,7 @@
     u32 min_max = 0;
     int min, max, length;
 
-    if ( test_and_set_bit(_PGC_out_of_sync, &frame_table[gmfn].count_info) )
+    if ( test_and_set_bit(_PGC_out_of_sync, &pfn_to_page(gmfn)->count_info) )
     {
         ASSERT(__shadow_status(d, gpfn, PGT_snapshot));
         return SHADOW_SNAPSHOT_ELSEWHERE;
@@ -953,7 +953,7 @@
                              unsigned long mfn)
 {
     struct domain *d = v->domain;
-    struct pfn_info *page = &frame_table[mfn];
+    struct pfn_info *page = pfn_to_page(mfn);
     struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d);
 
     ASSERT(shadow_lock_is_acquired(d));
@@ -1174,7 +1174,7 @@
                 && i == PAGING_L4)
                 continue;       /* skip the top-level for 3-level */
 
-            if ( page_out_of_sync(&frame_table[gmfn]) &&
+            if ( page_out_of_sync(pfn_to_page(gmfn)) &&
                  !snapshot_entry_matches(
                      d, guest_pt, gpfn, table_offset_64(va, i)) )
             {
@@ -1200,7 +1200,7 @@
         }
 
         /* L2 */
-        if ( page_out_of_sync(&frame_table[gmfn]) &&
+        if ( page_out_of_sync(pfn_to_page(gmfn)) &&
              !snapshot_entry_matches(d, guest_pt, gpfn, l2_table_offset(va)) )
         {
             unmap_and_return (1);
@@ -1214,7 +1214,7 @@
 #undef unmap_and_return
 #endif /* CONFIG_PAGING_LEVELS >= 3 */
     {
-        if ( page_out_of_sync(&frame_table[l2mfn]) &&
+        if ( page_out_of_sync(pfn_to_page(l2mfn)) &&
              !snapshot_entry_matches(d, (guest_l1_pgentry_t 
*)v->arch.guest_vtable,
                                      l2pfn, guest_l2_table_offset(va)) )
             return 1;
@@ -1234,7 +1234,7 @@
 
     guest_pt = (guest_l1_pgentry_t *) map_domain_page(l1mfn);
 
-    if ( page_out_of_sync(&frame_table[l1mfn]) &&
+    if ( page_out_of_sync(pfn_to_page(l1mfn)) &&
          !snapshot_entry_matches(
              d, guest_pt, l1pfn, guest_l1_table_offset(va)) ) 
     {
@@ -1324,18 +1324,18 @@
     int i;
     u32 found = 0;
     int is_l1_shadow =
-        ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
+        ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
          PGT_l1_shadow);
 #if CONFIG_PAGING_LEVELS == 4
     is_l1_shadow |=
-      ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
+      ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
                 PGT_fl1_shadow);
 #endif
 
     match = l1e_from_pfn(readonly_gmfn, flags);
 
     if ( shadow_mode_external(d) ) {
-        i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask)
+        i = (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_va_mask)
             >> PGT_va_shift;
 
         if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
@@ -1373,7 +1373,7 @@
 
     // If it's not a writable page, then no writable refs can be outstanding.
     //
-    if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
+    if ( (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_type_mask) !=
          PGT_writable_page )
     {
         perfc_incrc(remove_write_not_writable);
@@ -1383,7 +1383,7 @@
     // How many outstanding writable PTEs for this page are there?
     //
     write_refs =
-        (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
+        (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_count_mask);
     if ( write_refs && MFN_PINNED(readonly_gmfn) )
     {
         write_refs--;
@@ -1401,7 +1401,7 @@
 
          // Use the back pointer to locate the shadow page that can contain
          // the PTE of interest
-         if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp) 
) {
+         if ( (predicted_smfn = 
pfn_to_page(readonly_gmfn)->tlbflush_timestamp) ) {
              found += remove_all_write_access_in_ptpage(
                  d, predicted_smfn, predicted_smfn, readonly_gpfn, 
readonly_gmfn, write_refs, 0);
              if ( found == write_refs )
@@ -1670,7 +1670,7 @@
                     if ( !(entry_get_flags(guest_pt[i]) & _PAGE_PRESENT) &&
                          unlikely(entry_get_value(guest_pt[i]) != 0) &&
                          !unshadow &&
-                         (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
+                         (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) )
                         unshadow = 1;
                 }
 #endif
@@ -1718,7 +1718,7 @@
                 if ( !(guest_root_get_flags(new_root_e) & _PAGE_PRESENT) &&
                      unlikely(guest_root_get_intpte(new_root_e) != 0) &&
                      !unshadow &&
-                     (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
+                     (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) )
                     unshadow = 1;
             }
             if ( max == -1 )
@@ -2401,7 +2401,7 @@
     {
         printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08lx 
page_table_page=%d\n",
                eff_guest_pfn, eff_guest_mfn, shadow_mfn,
-               frame_table[eff_guest_mfn].u.inuse.type_info,
+               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
                page_table_page);
         FAIL("RW coherence");
     }
@@ -2412,7 +2412,7 @@
     {
         printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08lx 
page_table_page=%d\n",
                eff_guest_pfn, eff_guest_mfn, shadow_mfn,
-               frame_table[eff_guest_mfn].u.inuse.type_info,
+               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
                page_table_page);
         FAIL("RW2 coherence");
     }
@@ -2781,7 +2781,7 @@
          * When we free L2 pages, we need to tell if the page contains
          * Xen private mappings. Use the va_mask part.
          */
-        frame_table[s2mfn].u.inuse.type_info |= 
+        pfn_to_page(s2mfn)->u.inuse.type_info |= 
             (unsigned long) 3 << PGT_score_shift; 
 
         memset(spl2e, 0, 
@@ -2794,7 +2794,7 @@
         for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
             spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
                 l2e_from_page(
-                    
virt_to_page(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt) + i, 
+                    
virt_to_page(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt) + i, 
                     __PAGE_HYPERVISOR);
         for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
             spl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
@@ -2896,7 +2896,7 @@
            ROOT_PAGETABLE_XEN_SLOTS * sizeof(l4_pgentry_t));
 
         spl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
-            
l4e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_l3),
+            
l4e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_l3),
                             __PAGE_HYPERVISOR);
 
         if ( shadow_mode_translate(d) ) // NB: not external
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/shadow32.c   Tue Dec 20 17:16:24 2005
@@ -30,7 +30,7 @@
 #include <xen/sched.h>
 #include <xen/trace.h>
 
-#define MFN_PINNED(_x) (frame_table[_x].u.inuse.type_info & PGT_pinned)
+#define MFN_PINNED(_x) (pfn_to_page(_x)->u.inuse.type_info & PGT_pinned)
 #define va_to_l1mfn(_ed, _va) \
     (l2e_get_pfn(linear_l2_table(_ed)[_va>>L2_PAGETABLE_SHIFT]))
 
@@ -144,11 +144,11 @@
     if ( !shadow_mode_refcounts(d) )
         return;
 
-    ASSERT(frame_table[gmfn].count_info & PGC_page_table);
+    ASSERT(pfn_to_page(gmfn)->count_info & PGC_page_table);
 
     if ( shadow_max_pgtable_type(d, gpfn, NULL) == PGT_none )
     {
-        clear_bit(_PGC_page_table, &frame_table[gmfn].count_info);
+        clear_bit(_PGC_page_table, &pfn_to_page(gmfn)->count_info);
 
         if ( page_out_of_sync(pfn_to_page(gmfn)) )
         {
@@ -380,7 +380,7 @@
 
 void free_shadow_page(unsigned long smfn)
 {
-    struct pfn_info *page = &frame_table[smfn];
+    struct pfn_info *page = pfn_to_page(smfn);
     unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
     struct domain *d = page_get_owner(pfn_to_page(gmfn));
     unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
@@ -465,8 +465,8 @@
 {
     struct pfn_info *page;
 
-    page = &frame_table[entry->gmfn];
-        
+    page = pfn_to_page(entry->gmfn);
+
     // Decrement ref count of guest & shadow pages
     //
     put_page(page);
@@ -795,7 +795,7 @@
      */
     mfn = pagetable_get_pfn(v->arch.monitor_table);
     unmap_domain_page(v->arch.monitor_vtable);
-    free_domheap_page(&frame_table[mfn]);
+    free_domheap_page(pfn_to_page(mfn));
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
@@ -1018,8 +1018,8 @@
         {
             // external guests provide their own memory for their P2M maps.
             //
-            ASSERT( d == page_get_owner(
-                        &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
+            ASSERT(d == page_get_owner(pfn_to_page(pagetable_get_pfn(
+                d->arch.phys_table))));
         }
     }
 
@@ -1543,7 +1543,7 @@
             l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
 
         spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-            
l2e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt),
+            
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
                             __PAGE_HYPERVISOR);
 
         if ( shadow_mode_translate(d) ) // NB: not external
@@ -1675,7 +1675,7 @@
             set_guest_back_ptr(d, sl1e, sl1mfn, i);
         }
 
-        frame_table[sl1mfn].tlbflush_timestamp =
+        pfn_to_page(sl1mfn)->tlbflush_timestamp =
             SHADOW_ENCODE_MIN_MAX(min, max);
     }
 }
@@ -1758,7 +1758,7 @@
     u32 min_max = 0;
     int min, max, length;
 
-    if ( test_and_set_bit(_PGC_out_of_sync, &frame_table[gmfn].count_info) )
+    if ( test_and_set_bit(_PGC_out_of_sync, &pfn_to_page(gmfn)->count_info) )
     {
         ASSERT(__shadow_status(d, gpfn, PGT_snapshot));
         return SHADOW_SNAPSHOT_ELSEWHERE;
@@ -1809,7 +1809,7 @@
 
     // Clear the out_of_sync bit.
     //
-    clear_bit(_PGC_out_of_sync, &frame_table[entry->gmfn].count_info);
+    clear_bit(_PGC_out_of_sync, &pfn_to_page(entry->gmfn)->count_info);
 
     // XXX Need to think about how to protect the domain's
     // information less expensively.
@@ -1826,7 +1826,7 @@
                              unsigned long mfn)
 {
     struct domain *d = v->domain;
-    struct pfn_info *page = &frame_table[mfn];
+    struct pfn_info *page = pfn_to_page(mfn);
     struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d);
 
     ASSERT(shadow_lock_is_acquired(d));
@@ -1992,7 +1992,7 @@
 
     perfc_incrc(shadow_out_of_sync_calls);
 
-    if ( page_out_of_sync(&frame_table[l2mfn]) &&
+    if ( page_out_of_sync(pfn_to_page(l2mfn)) &&
          !snapshot_entry_matches(d, (l1_pgentry_t *)v->arch.guest_vtable,
                                  l2pfn, l2_table_offset(va)) )
         return 1;
@@ -2008,7 +2008,7 @@
     if ( !VALID_MFN(l1mfn) )
         return 0;
 
-    if ( page_out_of_sync(&frame_table[l1mfn]) &&
+    if ( page_out_of_sync(pfn_to_page(l1mfn)) &&
          !snapshot_entry_matches(
              d, &linear_pg_table[l1_linear_offset(va) & 
~(L1_PAGETABLE_ENTRIES-1)],
              l1pfn, l1_table_offset(va)) )
@@ -2136,13 +2136,13 @@
     int i;
     u32 found = 0;
     int is_l1_shadow =
-        ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
+        ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
          PGT_l1_shadow);
 
     match = l1e_from_pfn(readonly_gmfn, flags);
 
     if ( shadow_mode_external(d) ) {
-        i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) 
+        i = (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_va_mask) 
             >> PGT_va_shift;
 
         if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
@@ -2180,7 +2180,7 @@
 
     // If it's not a writable page, then no writable refs can be outstanding.
     //
-    if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
+    if ( (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_type_mask) !=
          PGT_writable_page )
     {
         perfc_incrc(remove_write_not_writable);
@@ -2190,7 +2190,7 @@
     // How many outstanding writable PTEs for this page are there?
     //
     write_refs =
-        (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
+        (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_count_mask);
     if ( write_refs && MFN_PINNED(readonly_gmfn) )
     {
         write_refs--;
@@ -2208,7 +2208,7 @@
 
          // Use the back pointer to locate the shadow page that can contain
          // the PTE of interest
-         if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp) 
) {
+         if ( (predicted_smfn = 
pfn_to_page(readonly_gmfn)->tlbflush_timestamp) ) {
              found += remove_all_write_access_in_ptpage(
                  d, predicted_smfn, predicted_smfn, readonly_gpfn, 
readonly_gmfn, write_refs, 0);
              if ( found == write_refs )
@@ -2249,7 +2249,7 @@
     int i;
     u32 count = 0;
     int is_l1_shadow =
-        ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
+        ((pfn_to_page(l1mfn)->u.inuse.type_info & PGT_type_mask) ==
          PGT_l1_shadow);
 
     match = l1e_from_pfn(forbidden_gmfn, flags);
@@ -2266,7 +2266,7 @@
         if ( is_l1_shadow )
             shadow_put_page_from_l1e(ol2e, d);
         else /* must be an hl2 page */
-            put_page(&frame_table[forbidden_gmfn]);
+            put_page(pfn_to_page(forbidden_gmfn));
     }
 
     unmap_domain_page(pl1e);
@@ -2982,6 +2982,23 @@
     }
 }
 
+void clear_all_shadow_status(struct domain *d)
+{
+    shadow_lock(d);
+    free_shadow_pages(d);
+    free_shadow_ht_entries(d);
+    d->arch.shadow_ht = 
+        xmalloc_array(struct shadow_status, shadow_ht_buckets);
+    if ( d->arch.shadow_ht == NULL ) {
+        printk("clear all shadow status:xmalloc fail\n");
+        domain_crash_synchronous();
+    }
+    memset(d->arch.shadow_ht, 0,
+           shadow_ht_buckets * sizeof(struct shadow_status));
+
+    free_out_of_sync_entries(d);
+    shadow_unlock(d);
+}
 
 /************************************************************************/
 /************************************************************************/
@@ -3139,7 +3156,7 @@
     {
         printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx 
page_table_page=%d\n",
                eff_guest_pfn, eff_guest_mfn, shadow_mfn,
-               frame_table[eff_guest_mfn].u.inuse.type_info,
+               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
                page_table_page);
         FAIL("RW coherence");
     }
@@ -3150,7 +3167,7 @@
     {
         printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx 
page_table_page=%d\n",
                eff_guest_pfn, eff_guest_mfn, shadow_mfn,
-               frame_table[eff_guest_mfn].u.inuse.type_info,
+               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
                page_table_page);
         FAIL("RW2 coherence");
     }
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/shadow_public.c      Tue Dec 20 17:16:24 2005
@@ -168,14 +168,14 @@
 #if CONFIG_PAGING_LEVELS >=3
     if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
     {
-        struct pfn_info *page = &frame_table[smfn];
+        struct pfn_info *page = pfn_to_page(smfn);
         for ( i = 0; i < PDP_ENTRIES; i++ )
         {
             if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
                 free_fake_shadow_l2(d,entry_get_pfn(ple[i]));
         }
 
-        page = &frame_table[entry_get_pfn(ple[0])];
+        page = pfn_to_page(entry_get_pfn(ple[0]));
         free_domheap_pages(page, SL2_ORDER);
         unmap_domain_page(ple);
     }
@@ -208,7 +208,7 @@
                     break;
                 if ( level == PAGING_L2 )
                 {
-                    struct pfn_info *page = &frame_table[smfn]; 
+                    struct pfn_info *page = pfn_to_page(smfn);
                     if ( is_xen_l2_slot(page->u.inuse.type_info, i) )
                         continue;
                 }
@@ -299,7 +299,7 @@
      */
     mfn = pagetable_get_pfn(v->arch.monitor_table);
     unmap_domain_page(v->arch.monitor_vtable);
-    free_domheap_page(&frame_table[mfn]);
+    free_domheap_page(pfn_to_page(mfn));
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
@@ -394,7 +394,7 @@
      */
     mfn = pagetable_get_pfn(v->arch.monitor_table);
     unmap_domain_page(v->arch.monitor_vtable);
-    free_domheap_page(&frame_table[mfn]);
+    free_domheap_page(pfn_to_page(mfn));
 
     v->arch.monitor_table = mk_pagetable(0);
     v->arch.monitor_vtable = 0;
@@ -411,7 +411,7 @@
 
     // Clear the out_of_sync bit.
     //
-    clear_bit(_PGC_out_of_sync, &frame_table[entry->gmfn].count_info);
+    clear_bit(_PGC_out_of_sync, &pfn_to_page(entry->gmfn)->count_info);
 
     // XXX Need to think about how to protect the domain's
     // information less expensively.
@@ -428,7 +428,7 @@
 {
     struct pfn_info *page;
 
-    page = &frame_table[entry->gmfn];
+    page = pfn_to_page(entry->gmfn);
         
     // Decrement ref count of guest & shadow pages
     //
@@ -501,11 +501,11 @@
     if ( !shadow_mode_refcounts(d) )
         return;
 
-    ASSERT(frame_table[gmfn].count_info & PGC_page_table);
+    ASSERT(pfn_to_page(gmfn)->count_info & PGC_page_table);
 
     if ( shadow_max_pgtable_type(d, gpfn, NULL) == PGT_none )
     {
-        clear_bit(_PGC_page_table, &frame_table[gmfn].count_info);
+        clear_bit(_PGC_page_table, &pfn_to_page(gmfn)->count_info);
 
         if ( page_out_of_sync(pfn_to_page(gmfn)) )
         {
@@ -600,7 +600,7 @@
 
 void free_shadow_page(unsigned long smfn)
 {
-    struct pfn_info *page = &frame_table[smfn];
+    struct pfn_info *page = pfn_to_page(smfn);
 
     unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
     struct domain *d = page_get_owner(pfn_to_page(gmfn));
@@ -1067,8 +1067,8 @@
         {
             // external guests provide their own memory for their P2M maps.
             //
-            ASSERT( d == page_get_owner(
-                &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
+            ASSERT(d == page_get_owner(pfn_to_page(pagetable_get_pfn(
+                d->arch.phys_table))));
         }
     }
 
@@ -1643,7 +1643,7 @@
     int i;
     u32 count = 0;
     int is_l1_shadow =
-        ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
+        ((pfn_to_page(l1mfn)->u.inuse.type_info & PGT_type_mask) ==
          PGT_l1_shadow);
 
     match = l1e_from_pfn(forbidden_gmfn, flags);
@@ -1660,7 +1660,7 @@
         if ( is_l1_shadow )
             shadow_put_page_from_l1e(ol2e, d);
         else /* must be an hl2 page */
-            put_page(&frame_table[forbidden_gmfn]);
+            put_page(pfn_to_page(forbidden_gmfn));
     }
 
     unmap_domain_page(pl1e);
@@ -1747,6 +1747,24 @@
     shadow_unlock(d);
 }
 
+void clear_all_shadow_status(struct domain *d)
+{
+    shadow_lock(d);
+    free_shadow_pages(d);
+    free_shadow_ht_entries(d);
+    d->arch.shadow_ht = 
+        xmalloc_array(struct shadow_status, shadow_ht_buckets);
+    if ( d->arch.shadow_ht == NULL ) {
+        printk("clear all shadow status:xmalloc fail\n");
+        domain_crash_synchronous();
+    }
+    memset(d->arch.shadow_ht, 0,
+           shadow_ht_buckets * sizeof(struct shadow_status));
+
+    free_out_of_sync_entries(d);
+    shadow_unlock(d);
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/traps.c      Tue Dec 20 17:16:24 2005
@@ -1074,29 +1074,35 @@
     return 0;
 }
 
-unsigned long nmi_softirq_reason;
-static void nmi_softirq(void)
+
+/* Defer dom0 notification to softirq context (unsafe in NMI context). */
+static unsigned long nmi_dom0_softirq_reason;
+#define NMI_DOM0_PARITY_ERR 0
+#define NMI_DOM0_IO_ERR     1
+#define NMI_DOM0_UNKNOWN    2
+
+static void nmi_dom0_softirq(void)
 {
     if ( dom0 == NULL )
         return;
 
-    if ( test_and_clear_bit(0, &nmi_softirq_reason) )
+    if ( test_and_clear_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason) )
         send_guest_virq(dom0->vcpu[0], VIRQ_PARITY_ERR);
 
-    if ( test_and_clear_bit(1, &nmi_softirq_reason) )
+    if ( test_and_clear_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason) )
         send_guest_virq(dom0->vcpu[0], VIRQ_IO_ERR);
+
+    if ( test_and_clear_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason) )
+        send_guest_virq(dom0->vcpu[0], VIRQ_NMI);
 }
 
 asmlinkage void mem_parity_error(struct cpu_user_regs *regs)
 {
-    /* Clear and disable the parity-error line. */
-    outb((inb(0x61)&15)|4,0x61);
-
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        set_bit(0, &nmi_softirq_reason);
-        raise_softirq(NMI_SOFTIRQ);
+        set_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason);
+        raise_softirq(NMI_DOM0_SOFTIRQ);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
@@ -1104,18 +1110,19 @@
         printk("\n\nNMI - MEMORY ERROR\n");
         fatal_trap(TRAP_nmi, regs);
     }
+
+    outb((inb(0x61) & 0x0f) | 0x04, 0x61); /* clear-and-disable parity check */
+    mdelay(1);
+    outb((inb(0x61) & 0x0b) | 0x00, 0x61); /* enable parity check */
 }
 
 asmlinkage void io_check_error(struct cpu_user_regs *regs)
 {
-    /* Clear and disable the I/O-error line. */
-    outb((inb(0x61)&15)|8,0x61);
-
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        set_bit(0, &nmi_softirq_reason);
-        raise_softirq(NMI_SOFTIRQ);
+        set_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason);
+        raise_softirq(NMI_DOM0_SOFTIRQ);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
@@ -1123,43 +1130,59 @@
         printk("\n\nNMI - I/O ERROR\n");
         fatal_trap(TRAP_nmi, regs);
     }
+
+    outb((inb(0x61) & 0x0f) | 0x08, 0x61); /* clear-and-disable IOCK */
+    mdelay(1);
+    outb((inb(0x61) & 0x07) | 0x00, 0x61); /* enable IOCK */
 }
 
 static void unknown_nmi_error(unsigned char reason)
 {
-    printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
-    printk("Dazed and confused, but trying to continue\n");
-    printk("Do you have a strange power saving mode enabled?\n");
-}
-
-static void default_do_nmi(struct cpu_user_regs *regs, unsigned long reason)
-{
-    if ( nmi_watchdog )
-        nmi_watchdog_tick(regs);
-
-    if ( reason & 0x80 )
-        mem_parity_error(regs);
-    else if ( reason & 0x40 )
-        io_check_error(regs);
-    else if ( !nmi_watchdog )
-        unknown_nmi_error((unsigned char)(reason&0xff));
+    switch ( opt_nmi[0] )
+    {
+    case 'd': /* 'dom0' */
+        set_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason);
+        raise_softirq(NMI_DOM0_SOFTIRQ);
+    case 'i': /* 'ignore' */
+        break;
+    default:  /* 'fatal' */
+        printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
+        printk("Dazed and confused, but trying to continue\n");
+        printk("Do you have a strange power saving mode enabled?\n");
+    }
 }
 
 static int dummy_nmi_callback(struct cpu_user_regs *regs, int cpu)
 {
-       return 0;
+    return 0;
 }
  
 static nmi_callback_t nmi_callback = dummy_nmi_callback;
  
-asmlinkage void do_nmi(struct cpu_user_regs *regs, unsigned long reason)
+asmlinkage void do_nmi(struct cpu_user_regs *regs)
 {
     unsigned int cpu = smp_processor_id();
+    unsigned char reason;
 
     ++nmi_count(cpu);
 
-       if ( !nmi_callback(regs, cpu) )
-               default_do_nmi(regs, reason);
+    if ( nmi_callback(regs, cpu) )
+        return;
+
+    if ( nmi_watchdog )
+        nmi_watchdog_tick(regs);
+
+    /* Only the BSP gets external NMIs from the system. */
+    if ( cpu == 0 )
+    {
+        reason = inb(0x61);
+        if ( reason & 0x80 )
+            mem_parity_error(regs);
+        else if ( reason & 0x40 )
+            io_check_error(regs);
+        else if ( !nmi_watchdog )
+            unknown_nmi_error((unsigned char)(reason&0xff));
+    }
 }
 
 void set_nmi_callback(nmi_callback_t callback)
@@ -1169,7 +1192,7 @@
 
 void unset_nmi_callback(void)
 {
-       nmi_callback = dummy_nmi_callback;
+    nmi_callback = dummy_nmi_callback;
 }
 
 asmlinkage int math_state_restore(struct cpu_user_regs *regs)
@@ -1318,7 +1341,7 @@
 
     cpu_init();
 
-    open_softirq(NMI_SOFTIRQ, nmi_softirq);
+    open_softirq(NMI_DOM0_SOFTIRQ, nmi_dom0_softirq);
 }
 
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/vmx.c        Tue Dec 20 17:16:24 2005
@@ -102,7 +102,8 @@
     if (v->vcpu_id == 0) {
         /* unmap IO shared page */
         struct domain *d = v->domain;
-        unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
+        if ( d->arch.vmx_platform.shared_page_va )
+            unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
     }
 
     destroy_vmcs(&v->arch.arch_vmx);
@@ -110,12 +111,12 @@
     vpit = &v->domain->arch.vmx_platform.vmx_pit;
     if ( active_ac_timer(&(vpit->pit_timer)) )
         rem_ac_timer(&vpit->pit_timer);
-    if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) {
+    if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) )
         rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
-    }
-    if ( vmx_apic_support(v->domain) ) {
-        rem_ac_timer( &(VLAPIC(v)->vlapic_timer) );
-        xfree( VLAPIC(v) );
+    if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
+    {
+        rem_ac_timer(&VLAPIC(v)->vlapic_timer);
+        xfree(VLAPIC(v));
     }
 }
 
@@ -334,7 +335,7 @@
 
 extern long evtchn_send(int lport);
 extern long do_block(void);
-void do_nmi(struct cpu_user_regs *, unsigned long);
+void do_nmi(struct cpu_user_regs *);
 
 static int check_vmx_controls(ctrls, msr)
 {
@@ -543,6 +544,13 @@
         clear_bit(X86_FEATURE_VMXE & 31, &ecx);
         clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
     }
+#ifdef __i386__
+    else if ( input == 0x80000001 )
+    {
+        /* Mask feature for Intel ia32e or AMD long mode. */
+        clear_bit(X86_FEATURE_LM & 31, &edx);
+    }
+#endif
 
     regs->eax = (unsigned long) eax;
     regs->ebx = (unsigned long) ebx;
@@ -1223,6 +1231,7 @@
             }
         }
 
+        clear_all_shadow_status(v->domain);
         if (vmx_assist(v, VMX_ASSIST_INVOKE)) {
             set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &v->arch.arch_vmx.cpu_state);
             __vmread(GUEST_RIP, &eip);
@@ -1841,7 +1850,7 @@
             break;
         }
         case TRAP_nmi:
-            do_nmi(&regs, 0);
+            do_nmi(&regs);
             break;
         default:
             vmx_reflect_exception(v);
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c      Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/vmx_intercept.c      Tue Dec 20 17:16:24 2005
@@ -203,6 +203,12 @@
     u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point));
     if (nsec_delta > vpit->period)
         VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT:long time has passed from last 
injection!");
+    if(vpit->init_val == 0)
+    {
+        printk("PIT init value == 0!\n");
+        domain_crash_synchronous();
+    }
+
     vpit->count = vpit->init_val - ((nsec_delta * PIT_FREQ / 1000000000ULL) % 
vpit->init_val );
 }
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_32/entry.S       Tue Dec 20 17:16:24 2005
@@ -601,15 +601,7 @@
        pushl %eax
        SAVE_ALL_NOSEGREGS(a)
 
-        # Check for hardware problems.
-        inb   $0x61,%al
-        testb $0x80,%al
-        jne   nmi_parity_err
-        testb $0x40,%al
-        jne   nmi_io_err
-        movl  %eax,%ebx
-        
-        # Okay, its almost a normal NMI tick. We can only process it if:
+        # We can only process the NMI if:
         #  A. We are the outermost Xen activation (in which case we have
         #     the selectors safely saved on our stack)
         #  B. DS and ES contain sane Xen values.
@@ -619,7 +611,7 @@
         movl  UREGS_eflags(%esp),%eax
         movb  UREGS_cs(%esp),%al
         testl $(3|X86_EFLAGS_VM),%eax
-        jnz   do_watchdog_tick
+        jnz   continue_nmi
         movl  %ds,%eax
         cmpw  $(__HYPERVISOR_DS),%ax
         jne   defer_nmi
@@ -627,15 +619,14 @@
         cmpw  $(__HYPERVISOR_DS),%ax
         jne   defer_nmi
 
-do_watchdog_tick:
+continue_nmi:
         movl  $(__HYPERVISOR_DS),%edx
         movl  %edx,%ds
         movl  %edx,%es
         movl  %esp,%edx
-        pushl %ebx   # reason
-        pushl %edx   # regs
+        pushl %edx
         call  do_nmi
-        addl  $8,%esp
+        addl  $4,%esp
         jmp   ret_from_intr
 
 defer_nmi:
@@ -648,55 +639,6 @@
         movl  $(APIC_DM_FIXED | APIC_DEST_SELF | APIC_DEST_LOGICAL | \
                 TRAP_deferred_nmi),%ss:APIC_ICR(%eax)
         jmp   restore_all_xen
-
-nmi_parity_err:
-        # Clear and disable the parity-error line
-        andb $0xf,%al
-        orb  $0x4,%al
-        outb %al,$0x61
-        cmpb $'i',%ss:opt_nmi # nmi=ignore
-        je   nmi_out
-        bts  $0,%ss:nmi_softirq_reason
-        bts  $NMI_SOFTIRQ,%ss:irq_stat
-        cmpb $'d',%ss:opt_nmi # nmi=dom0
-        je   nmi_out
-        movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
-        movl %edx,%ds
-        movl %edx,%es
-        movl %esp,%edx
-        push %edx
-        call mem_parity_error
-        addl $4,%esp
-nmi_out:movl  %ss:UREGS_eflags(%esp),%eax
-        movb  %ss:UREGS_cs(%esp),%al
-        testl $(3|X86_EFLAGS_VM),%eax
-        jz    restore_all_xen
-        movl  $(__HYPERVISOR_DS),%edx
-        movl  %edx,%ds
-        movl  %edx,%es
-        GET_CURRENT(%ebx)
-        jmp   test_all_events
-                
-nmi_io_err: 
-        # Clear and disable the I/O-error line
-        andb $0xf,%al
-        orb  $0x8,%al
-        outb %al,$0x61
-        cmpb $'i',%ss:opt_nmi # nmi=ignore
-        je   nmi_out
-        bts  $1,%ss:nmi_softirq_reason
-        bts  $NMI_SOFTIRQ,%ss:irq_stat
-        cmpb $'d',%ss:opt_nmi # nmi=dom0
-        je   nmi_out
-        movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
-        movl %edx,%ds
-        movl %edx,%es
-        movl %esp,%edx
-        push %edx
-        call io_check_error                        
-        addl $4,%esp
-        jmp  nmi_out
-
 
 ENTRY(setup_vm86_frame)
         # Copies the entire stack frame forwards by 16 bytes.
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_32/mm.c  Tue Dec 20 17:16:24 2005
@@ -177,10 +177,11 @@
             idle_pg_table_l2[l2_linear_offset(RDWR_MPT_VIRT_START) + i]);
         for ( j = 0; j < L2_PAGETABLE_ENTRIES; j++ )
         {
-            frame_table[m2p_start_mfn+j].count_info = PGC_allocated | 1;
+            struct pfn_info *page = pfn_to_page(m2p_start_mfn + j);
+            page->count_info = PGC_allocated | 1;
             /* Ensure it's only mapped read-only by domains. */
-            frame_table[m2p_start_mfn+j].u.inuse.type_info = PGT_gdt_page | 1;
-            page_set_owner(&frame_table[m2p_start_mfn+j], dom_xen);
+            page->u.inuse.type_info = PGT_gdt_page | 1;
+            page_set_owner(page, dom_xen);
         }
     }
 }
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_32/traps.c       Tue Dec 20 17:16:24 2005
@@ -160,9 +160,9 @@
 BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
 asmlinkage void smp_deferred_nmi(struct cpu_user_regs regs)
 {
-    asmlinkage void do_nmi(struct cpu_user_regs *, unsigned long);
+    asmlinkage void do_nmi(struct cpu_user_regs *);
     ack_APIC_irq();
-    do_nmi(&regs, 0);
+    do_nmi(&regs);
 }
 
 void __init percpu_traps_init(void)
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_64/entry.S       Tue Dec 20 17:16:24 2005
@@ -567,9 +567,7 @@
 ENTRY(nmi)
         pushq $0
         SAVE_ALL
-        inb   $0x61,%al
-        movl  %eax,%esi # reason
-        movq  %rsp,%rdi # regs
+        movq  %rsp,%rdi
         call  do_nmi
        jmp   restore_all_xen
 
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_64/mm.c  Tue Dec 20 17:16:24 2005
@@ -166,11 +166,12 @@
 
         for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
         {
-            frame_table[m2p_start_mfn+i].count_info = PGC_allocated | 1;
+            struct pfn_info *page = pfn_to_page(m2p_start_mfn + i);
+            page->count_info = PGC_allocated | 1;
             /* gdt to make sure it's only mapped read-only by non-privileged
                domains. */
-            frame_table[m2p_start_mfn+i].u.inuse.type_info = PGT_gdt_page | 1;
-            page_set_owner(&frame_table[m2p_start_mfn+i], dom_xen);
+            page->u.inuse.type_info = PGT_gdt_page | 1;
+            page_set_owner(page, dom_xen);
         }
     }
 }
diff -r 11cd619db035 -r d3b10a2a82d4 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Tue Dec 20 17:16:15 2005
+++ b/xen/common/dom0_ops.c     Tue Dec 20 17:16:24 2005
@@ -358,12 +358,17 @@
     case DOM0_GETDOMAININFO:
     { 
         struct domain *d;
+        domid_t dom;
+
+        dom = op->u.getdomaininfo.domain;
+        if ( dom == DOMID_SELF )
+            dom = current->domain->domain_id;
 
         read_lock(&domlist_lock);
 
         for_each_domain ( d )
         {
-            if ( d->domain_id >= op->u.getdomaininfo.domain )
+            if ( d->domain_id >= dom )
                 break;
         }
 
@@ -577,6 +582,22 @@
         }
     }
     break;
+    case DOM0_SETDEBUGGING:
+    {
+        struct domain *d; 
+        ret = -ESRCH;
+        d = find_domain_by_id(op->u.setdebugging.domain);
+        if ( d != NULL )
+        {
+            if ( op->u.setdebugging.enable )
+                set_bit(_DOMF_debugging, &d->domain_flags);
+            else
+                clear_bit(_DOMF_debugging, &d->domain_flags);
+            put_domain(d);
+            ret = 0;
+        }
+    }
+    break;
 
 #ifdef PERF_COUNTERS
     case DOM0_PERFCCONTROL:
diff -r 11cd619db035 -r d3b10a2a82d4 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Tue Dec 20 17:16:15 2005
+++ b/xen/common/grant_table.c  Tue Dec 20 17:16:24 2005
@@ -238,8 +238,8 @@
 
         if ( unlikely(!pfn_valid(frame)) ||
              unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
-                        get_page(&frame_table[frame], rd) :
-                        get_page_and_type(&frame_table[frame], rd,
+                        get_page(pfn_to_page(frame), rd) :
+                        get_page_and_type(pfn_to_page(frame), rd,
                                           PGT_writable_page))) )
         {
             clear_bit(_GTF_writing, &sha->flags);
@@ -301,7 +301,7 @@
                 sflags = prev_sflags;
             }
 
-            if ( unlikely(!get_page_type(&frame_table[frame],
+            if ( unlikely(!get_page_type(pfn_to_page(frame),
                                          PGT_writable_page)) )
             {
                 clear_bit(_GTF_writing, &sha->flags);
@@ -347,14 +347,14 @@
                 if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
                 {
                     clear_bit(_GTF_writing, &sha->flags);
-                    put_pag