WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Merged.

# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID c745e47d8154e2f77ceaa35e099c1163cda47cfc
# Parent  1c4e1d0fd1bbfc30882d40971a9ec83d61dcad24
# Parent  2604abf98edef33f4aa2cab6bc8ac8c5ff81189c
Merged.

diff -r 1c4e1d0fd1bb -r c745e47d8154 .hgtags
--- a/.hgtags   Tue Mar 28 10:51:06 2006
+++ b/.hgtags   Tue Mar 28 10:52:47 2006
@@ -13,3 +13,4 @@
 30c521db4c71960b0cf1d9c9e1b658e77b535a3e split-1.0
 3d330e41f41ce1bc118c02346e18949ad5d67f6b split-1.1
 c8fdb0caa77b429cf47f9707926e83947778cb48 RELEASE-3.0.0
+af0573e9e5258db0a9d28aa954dd302ddd2c2d23 3.0.2-rc
diff -r 1c4e1d0fd1bb -r c745e47d8154 Makefile
--- a/Makefile  Tue Mar 28 10:51:06 2006
+++ b/Makefile  Tue Mar 28 10:52:47 2006
@@ -2,7 +2,7 @@
 # Grand Unified Makefile for Xen.
 #
 
-KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
+KERNELS ?= linux-2.6-xen
 # You may use wildcards in the above e.g. KERNELS=*2.6*
 
 XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst 
buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) )
diff -r 1c4e1d0fd1bb -r c745e47d8154 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Tue Mar 28 10:51:06 2006
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Tue Mar 28 10:52:47 2006
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen0
-# Thu Feb 16 13:20:46 2006
+# Linux kernel version: 2.6.16-xen0
+# Mon Mar 27 14:46:03 2006
 #
 
 #
@@ -95,8 +95,7 @@
 CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_BLKDEV_GRANT=y
 CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_VT=y
-CONFIG_VT=y
+CONFIG_XEN_BLKDEV_BACKEND=y
 CONFIG_XEN_SYSFS=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
@@ -378,7 +377,7 @@
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
@@ -706,6 +705,7 @@
 #
 # Character devices
 #
+CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_NONSTANDARD=y
@@ -1252,11 +1252,7 @@
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
diff -r 1c4e1d0fd1bb -r c745e47d8154 buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64    Tue Mar 28 10:51:06 2006
+++ b/buildconfigs/linux-defconfig_xenU_ia64    Tue Mar 28 10:52:47 2006
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xenU
-# Thu Feb 16 13:47:59 2006
+# Linux kernel version: 2.6.16-xenU
+# Mon Mar 27 14:01:13 2006
 #
 
 #
@@ -92,8 +92,7 @@
 CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_BLKDEV_GRANT=y
 CONFIG_XEN_BLKDEV_FRONTEND=y
-# CONFIG_XEN_VT is not set
-# CONFIG_VT is not set
+CONFIG_XEN_BLKDEV_BACKEND=y
 CONFIG_XEN_SYSFS=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
@@ -607,6 +606,9 @@
 #
 # Character devices
 #
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -863,6 +865,13 @@
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
 
 #
 # Logo configuration
@@ -1122,11 +1131,7 @@
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
diff -r 1c4e1d0fd1bb -r c745e47d8154 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Tue Mar 28 10:51:06 2006
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Tue Mar 28 10:52:47 2006
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen
-# Mon Feb 20 11:37:11 2006
+# Linux kernel version: 2.6.16-xen
+# Mon Mar 27 09:43:44 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -102,6 +102,8 @@
 # CONFIG_MPSC is not set
 CONFIG_GENERIC_CPU=y
 CONFIG_X86_64_XEN=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
 CONFIG_X86_L1_CACHE_BYTES=128
 CONFIG_X86_L1_CACHE_SHIFT=7
 CONFIG_X86_GOOD_APIC=y
@@ -1138,7 +1140,7 @@
 CONFIG_AMD8111E_NAPI=y
 CONFIG_ADAPTEC_STARFIRE=m
 CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_B44=m
+# CONFIG_B44 is not set
 CONFIG_FORCEDETH=m
 CONFIG_DGRS=m
 CONFIG_EEPRO100=m
@@ -1782,8 +1784,8 @@
 CONFIG_VIDEO_HEXIUM_ORION=m
 CONFIG_VIDEO_HEXIUM_GEMINI=m
 CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
 CONFIG_VIDEO_CX88_DVB=m
-CONFIG_VIDEO_CX88_ALSA=m
 CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
 CONFIG_VIDEO_CX88_VP3054=m
 CONFIG_VIDEO_EM28XX=m
@@ -2331,11 +2333,7 @@
 CONFIG_INFINIBAND_SRP=m
 
 #
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 CONFIG_EDAC=m
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Tue Mar 28 10:51:06 2006
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Tue Mar 28 10:52:47 2006
@@ -83,19 +83,6 @@
        depends on XEN
        bool
        default y
-
-config XEN_VT
-       bool "Override for turning on CONFIG_VT for domU"
-       default y
-       help
-         Hack to turn off CONFIG_VT for domU
-
-config VT
-       bool
-       default y if XEN && XEN_VT
-       default n if XEN && !XEN_VT
-       help
-         Hack to turn off CONFIG_VT for domU
 
 config XEN_SYSFS
        bool "Export Xen attributes in sysfs"
diff -r 1c4e1d0fd1bb -r c745e47d8154 
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Tue Mar 28 10:51:06 2006
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Tue Mar 28 10:52:47 2006
@@ -506,6 +506,22 @@
                        conswitchp = &vga_con;
 # endif
        }
+#ifdef CONFIG_XEN
+       if (running_on_xen) {
+               extern shared_info_t *HYPERVISOR_shared_info;
+
+               /* xen_start_info isn't setup yet, get the flags manually */
+               if (HYPERVISOR_shared_info->arch.flags & SIF_INITDOMAIN) {
+                       if (!(HYPERVISOR_shared_info->arch.flags & 
SIF_PRIVILEGED))
+                               panic("Xen granted us console access "
+                                     "but not privileged status");
+               } else {
+                       extern int console_use_vt;
+                       conswitchp = NULL;
+                       console_use_vt = 0;
+               }
+       }
+#endif
 #endif
 
        /* enable IA-64 Machine Check Abort Handling unless disabled */
diff -r 1c4e1d0fd1bb -r c745e47d8154 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Tue Mar 28 
10:51:06 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Tue Mar 28 
10:52:47 2006
@@ -855,32 +855,12 @@
 # i.e. it just resumes from the next instruction interrupted with the same 
context. 
        
 # Hypervisor uses this for application faults while it executes.
+# Unlike i386 there is no need to reload the saved segment selectors:
+# Xen already reloaded all valid ones and zeroed the others.
 ENTRY(failsafe_callback)
-       addq $0x10,%rsp /* skip rcx and r11 */  
-1:     mov  (%rsp),%ds
-2:     mov  8(%rsp),%es
-3:     mov  16(%rsp),%fs
-4:     mov  24(%rsp),%gs
-       addq $0x20,%rsp /* skip the above selectors */          
+       addq $0x30,%rsp /* skip %rcx,%r11,%ds,%es,%fs,%gs */
        SAVE_ALL
        jmp  error_exit
-.section .fixup,"ax";  \
-6:     movq $0,(%rsp); \
-       jmp 1b;         \
-7:     movq $0,8(%rsp);        \
-       jmp 2b;         \
-8:     movq $0,16(%rsp);       \
-       jmp 3b;         \
-9:     movq $0,24(%rsp);       \
-       jmp 4b;         \
-.previous;             \
-.section __ex_table,"a";\
-       .align 16;      \
-       .quad 1b,6b;    \
-       .quad 2b,7b;    \
-       .quad 3b,8b;    \
-       .quad 4b,9b;    \
-.previous
  
 #if 0        
         .section __ex_table,"a"
diff -r 1c4e1d0fd1bb -r c745e47d8154 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Mar 28 
10:51:06 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Mar 28 
10:52:47 2006
@@ -1039,8 +1039,7 @@
                xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
                if (xsd_port_intf)
                        xsd_port_intf->read_proc = xsd_port_read;
-       }
-       else
+       } else
                xenstored_ready = 1;
 
        /* Initialize the interface to xenstore. */
diff -r 1c4e1d0fd1bb -r c745e47d8154 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h    Tue Mar 
28 10:51:06 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h    Tue Mar 
28 10:52:47 2006
@@ -237,20 +237,11 @@
 
 static inline void set_in_cr4 (unsigned long mask)
 {
+       unsigned cr4;
        mmu_cr4_features |= mask;
-       switch (mask) {
-       case X86_CR4_OSFXSR:
-       case X86_CR4_OSXMMEXCPT:
-               break;
-       default:
-               do {
-                       const char *msg = "Xen unsupported cr4 update\n";
-                       (void)HYPERVISOR_console_io(
-                               CONSOLEIO_write, __builtin_strlen(msg),
-                               (char *)msg);
-                       BUG();
-               } while (0);
-       }
+       cr4 = read_cr4();
+       cr4 |= mask;
+       write_cr4(cr4);
 }
 
 static inline void clear_in_cr4 (unsigned long mask)
diff -r 1c4e1d0fd1bb -r c745e47d8154 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h  Tue Mar 
28 10:51:06 2006
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h  Tue Mar 
28 10:52:47 2006
@@ -141,31 +141,21 @@
 static inline void set_in_cr4 (unsigned long mask)
 {
        mmu_cr4_features |= mask;
-       switch (mask) {
-       case X86_CR4_OSFXSR:
-       case X86_CR4_OSXMMEXCPT:
-               break;
-       default:
-               do {
-                       const char *msg = "Xen unsupported cr4 update\n";
-                       (void)HYPERVISOR_console_io(
-                               CONSOLEIO_write, __builtin_strlen(msg),
-                               (char *)msg);
-                       BUG();
-               } while (0);
-       }
+       __asm__("movq %%cr4,%%rax\n\t"
+               "orq %0,%%rax\n\t"
+               "movq %%rax,%%cr4\n"
+               : : "irg" (mask)
+               :"ax");
 }
 
 static inline void clear_in_cr4 (unsigned long mask)
 {
-#ifndef CONFIG_XEN
        mmu_cr4_features &= ~mask;
        __asm__("movq %%cr4,%%rax\n\t"
                "andq %0,%%rax\n\t"
                "movq %%rax,%%cr4\n"
                : : "irg" (~mask)
                :"ax");
-#endif
 }
 
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/Makefile
--- a/tools/Makefile    Tue Mar 28 10:51:06 2006
+++ b/tools/Makefile    Tue Mar 28 10:52:47 2006
@@ -37,6 +37,7 @@
                $(MAKE) -C $$subdir $@; \
        done
        $(MAKE) ioemuinstall
+       $(INSTALL_DIR) -p $(DESTDIR)/var/xen/dump
 
 clean: check_clean
        @set -e; for subdir in $(SUBDIRS); do \
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/debugger/gdb/README
--- a/tools/debugger/gdb/README Tue Mar 28 10:51:06 2006
+++ b/tools/debugger/gdb/README Tue Mar 28 10:52:47 2006
@@ -11,8 +11,8 @@
     to your test machine.
 
 To build a debuggable guest kernel image:
- 1. cd linux-2.6.12-xenU
- 2. ARCH=xen make menuconfig
+ 1. cd linux-2.6.xx-xenU
+ 2. make menuconfig
  3. From within the configurator, enable the following options:
     # Kernel hacking -> Compile the kernel with debug info [*]
                      -> Compile the kernel with frame pointers
diff -r 1c4e1d0fd1bb -r c745e47d8154 
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv       
Tue Mar 28 10:51:06 2006
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv       
Tue Mar 28 10:52:47 2006
@@ -61,7 +61,7 @@
                        srv_linux_thread_db=yes
                        ;;
   x86_64-*-linux*)     srv_regobj=reg-x86-64.o
-                       srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o"
+                       srv_tgtobj="linux-xen-low.o linux-x86-64-low.o 
i387-fp.o"
                        srv_linux_regsets=yes
                        ;;
   xscale*-*-linux*)    srv_regobj=reg-arm.o
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent  Tue Mar 28 10:51:06 2006
+++ b/tools/examples/xen-backend.agent  Tue Mar 28 10:52:47 2006
@@ -1,6 +1,10 @@
 #! /bin/sh
 
 PATH=/etc/xen/scripts:$PATH
+
+. /etc/xen/scripts/locking.sh
+
+claim_lock xenbus_hotplug_global
 
 case "$XENBUS_TYPE" in
   vbd)
@@ -25,3 +29,5 @@
   offline)
     ;;
 esac
+
+release_lock xenbus_hotplug_global
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c    Tue Mar 28 10:51:06 2006
+++ b/tools/ioemu/hw/pcnet.c    Tue Mar 28 10:52:47 2006
@@ -45,21 +45,6 @@
 #define PCNET_PNPMMIO_SIZE      0x20
 
 
-typedef struct PCNetState_st PCNetState;
-
-struct PCNetState_st {
-    PCIDevice dev;
-    NetDriverState *nd;
-    int mmio_io_addr, rap, isr, lnkst;
-    target_phys_addr_t rdra, tdra;
-    uint8_t prom[16];
-    uint16_t csr[128];
-    uint16_t bcr[32];
-    uint64_t timer;
-    int xmit_pos, recv_pos;
-    uint8_t buffer[4096];
-};
-
 #include "pcnet.h"
 
 static void pcnet_poll(PCNetState *s);
@@ -217,6 +202,11 @@
     CSR_RCVRC(s) = CSR_RCVRL(s);
     CSR_XMTRC(s) = CSR_XMTRL(s);
 
+    /* flush any cached receive descriptors */
+    s->crmd.rmd1.own = 0;
+    s->nrmd.rmd1.own = 0;
+    s->nnrmd.rmd1.own = 0;
+
 #ifdef PCNET_DEBUG
     printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", 
         BCR_SSIZE32(s),
@@ -239,6 +229,11 @@
     if (!CSR_DRX(s))
         s->csr[0] |= 0x0020;    /* set RXON */
 
+    /* flush any cached receive descriptors */
+    s->crmd.rmd1.own = 0;
+    s->nrmd.rmd1.own = 0;
+    s->nnrmd.rmd1.own = 0;
+
     s->csr[0] &= ~0x0004;       /* clear STOP bit */
     s->csr[0] |= 0x0002;
 }
@@ -260,29 +255,21 @@
     s->csr[28] = s->csr[29] = 0;
     if (s->rdra) {
         int bad = 0;
-#if 1
         target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
         target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
         target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
-#else
-        target_phys_addr_t crda = s->rdra + 
-            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
-            (BCR_SWSTYLE(s) ? 16 : 8 );
-        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
-        target_phys_addr_t nrda = s->rdra + 
-            (CSR_RCVRL(s) - nrdc) *
-            (BCR_SWSTYLE(s) ? 16 : 8 );
-        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
-        target_phys_addr_t nnrd = s->rdra + 
-            (CSR_RCVRL(s) - nnrc) *
-            (BCR_SWSTYLE(s) ? 16 : 8 );
-#endif
-
-        CHECK_RMD(PHYSADDR(s,crda), bad);
+
+       if (!s->crmd.rmd1.own) {
+           CHECK_RMD(&(s->crmd),PHYSADDR(s,crda), bad);
+       }
         if (!bad) {
-            CHECK_RMD(PHYSADDR(s,nrda), bad);
+           if (s->crmd.rmd1.own && !s->nrmd.rmd1.own) {
+               CHECK_RMD(&(s->nrmd),PHYSADDR(s,nrda), bad);
+           }
             if (bad || (nrda == crda)) nrda = 0;
-            CHECK_RMD(PHYSADDR(s,nnrd), bad);
+           if (s->crmd.rmd1.own && s->nrmd.rmd1.own && !s->nnrmd.rmd1.own) {
+               CHECK_RMD(&(s->nnrmd),PHYSADDR(s,nnrd), bad);
+           }
             if (bad || (nnrd == crda)) nnrd = 0;
 
             s->csr[28] = crda & 0xffff;
@@ -303,14 +290,12 @@
     }
     
     if (CSR_CRDA(s)) {
-        struct pcnet_RMD rmd;
-        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
-        CSR_CRBC(s) = rmd.rmd1.bcnt;
-        CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+        CSR_CRBC(s) = s->crmd.rmd1.bcnt;
+        CSR_CRST(s) = ((uint32_t *)&(s->crmd))[1] >> 16;
 #ifdef PCNET_DEBUG_RMD_X
         printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
                 PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
-                ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
+                ((uint32_t *)&(s->crmd))[1], ((uint32_t *)&(s->crmd))[2]);
         PRINT_RMD(&rmd);
 #endif
     } else {
@@ -318,10 +303,8 @@
     }
     
     if (CSR_NRDA(s)) {
-        struct pcnet_RMD rmd;
-        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
-        CSR_NRBC(s) = rmd.rmd1.bcnt;
-        CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+        CSR_NRBC(s) = s->nrmd.rmd1.bcnt;
+        CSR_NRST(s) = ((uint32_t *)&(s->nrmd))[1] >> 16;
     } else {
         CSR_NRBC(s) = CSR_NRST(s) = 0;
     }
@@ -336,6 +319,7 @@
             (CSR_XMTRL(s) - CSR_XMTRC(s)) *
             (BCR_SWSTYLE(s) ? 16 : 8 );
         int bad = 0;
+       s->csr[0] &= ~0x0008;   /* clear TDMD */
         CHECK_TMD(PHYSADDR(s, cxda),bad);
         if (!bad) {
             if (CSR_CXDA(s) != cxda) {
@@ -354,12 +338,8 @@
     }
 
     if (CSR_CXDA(s)) {
-        struct pcnet_TMD tmd;
-
-        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
-
-        CSR_CXBC(s) = tmd.tmd1.bcnt;
-        CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
+        CSR_CXBC(s) = s->tmd.tmd1.bcnt;
+        CSR_CXST(s) = ((uint32_t *)&(s->tmd))[1] >> 16;
     } else {
         CSR_CXBC(s) = CSR_CXST(s) = 0;
     }
@@ -373,14 +353,11 @@
     if (CSR_STOP(s) || CSR_SPND(s))
         return 0;
         
-    if (s->recv_pos > 0)
-        return 0;
-
     pcnet_rdte_poll(s);
     if (!(CSR_CRST(s) & 0x8000)) {
         return 0;
     }
-    return sizeof(s->buffer)-16;
+    return sizeof(s->rx_buffer)-16;
 }
 
 #define MIN_BUF_SIZE 60
@@ -389,7 +366,7 @@
 {
     PCNetState *s = opaque;
     int is_padr = 0, is_bcast = 0, is_ladr = 0;
-    uint8_t buf1[60];
+    int pad;
 
     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
         return;
@@ -399,12 +376,10 @@
 #endif
 
     /* if too small buffer, then expand it */
-    if (size < MIN_BUF_SIZE) {
-        memcpy(buf1, buf, size);
-        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
-        buf = buf1;
-        size = MIN_BUF_SIZE;
-    }
+    if (size < MIN_BUF_SIZE)
+        pad = MIN_BUF_SIZE - size + 4;
+    else 
+       pad = 4;
 
     if (CSR_PROM(s) 
         || (is_padr=padr_match(s, buf, size)) 
@@ -413,124 +388,74 @@
 
         pcnet_rdte_poll(s);
 
-        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
-            struct pcnet_RMD rmd;
-            int rcvrc = CSR_RCVRC(s)-1,i;
-            target_phys_addr_t nrda;
-            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
-                if (rcvrc <= 1)
-                    rcvrc = CSR_RCVRL(s);
-                nrda = s->rdra +
-                    (CSR_RCVRL(s) - rcvrc) *
-                    (BCR_SWSTYLE(s) ? 16 : 8 );
-                RMDLOAD(&rmd, PHYSADDR(s,nrda));                  
-                if (rmd.rmd1.own) {                
+       if (size > 2000) {
 #ifdef PCNET_DEBUG_RMD
-                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", 
-                                rcvrc, CSR_RCVRC(s));
-#endif
-                    CSR_RCVRC(s) = rcvrc;
-                    pcnet_rdte_poll(s);
-                    break;
-                }
-            }
-        }
-
-        if (!(CSR_CRST(s) & 0x8000)) {
+           printf("pcnet - oversize packet discarded.\n");
+#endif
+       } else if (!(CSR_CRST(s) & 0x8000)) {
 #ifdef PCNET_DEBUG_RMD
             printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
 #endif
             s->csr[0] |= 0x1000; /* Set MISS flag */
             CSR_MISSC(s)++;
         } else {
-            uint8_t *src = &s->buffer[8];
+            uint8_t *src = &s->rx_buffer[8];
             target_phys_addr_t crda = CSR_CRDA(s);
-            struct pcnet_RMD rmd;
+            target_phys_addr_t nrda = CSR_NRDA(s);
+            target_phys_addr_t nnrda = CSR_NNRD(s);
             int pktcount = 0;
+           int packet_size = size + pad;
 
             memcpy(src, buf, size);
-            
-            if (!CSR_ASTRP_RCV(s)) {
-                uint32_t fcs = ~0;
-#if 0            
-                uint8_t *p = s->buffer;
-                
-                ((uint32_t *)p)[0] = ((uint32_t *)p)[1] = 0xaaaaaaaa;
-                p[7] = 0xab;
-#else
-                uint8_t *p = src;
-#endif
-
-                while (size < 46) {
-                    src[size++] = 0;
-                }
-                
-                while (p != &src[size]) {
-                    CRC(fcs, *p++);
-                }
-                ((uint32_t *)&src[size])[0] = htonl(fcs);
-                size += 4; /* FCS at end of packet */
-            } else size += 4;
+           memset(src + size, 0, pad); 
+            size += pad;
 
 #ifdef PCNET_DEBUG_MATCH
             PRINT_PKTHDR(buf);
 #endif
 
-            RMDLOAD(&rmd, PHYSADDR(s,crda));
-            /*if (!CSR_LAPPEN(s))*/
-                rmd.rmd1.stp = 1;
-
-#define PCNET_RECV_STORE() do {                                 \
-    int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
-    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
-    cpu_physical_memory_write(rbadr, src, count);               \
-    cpu_physical_memory_set_dirty(rbadr);                       \
-    cpu_physical_memory_set_dirty(rbadr+count);                 \
-    src += count; size -= count;                                \
-    rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
-    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
-    pktcount++;                                                 \
-} while (0)
-
-            PCNET_RECV_STORE();
-            if ((size > 0) && CSR_NRDA(s)) {
-                target_phys_addr_t nrda = CSR_NRDA(s);
-                RMDLOAD(&rmd, PHYSADDR(s,nrda));
-                if (rmd.rmd1.own) {
-                    crda = nrda;
-                    PCNET_RECV_STORE();
-                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
-                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
-                        if (rmd.rmd1.own) {
-                            crda = nrda;
-                            PCNET_RECV_STORE();
-                        }
-                    }
-                }                
+           s->crmd.rmd1.stp = 1;
+           do {
+               int count = MIN(4096 - s->crmd.rmd1.bcnt,size);
+               target_phys_addr_t rbadr = PHYSADDR(s, s->crmd.rmd0.rbadr);
+               cpu_physical_memory_write(rbadr, src, count);
+               cpu_physical_memory_set_dirty(rbadr);
+               cpu_physical_memory_set_dirty(rbadr+count);
+               src += count; size -= count;
+               if (size > 0 && s->nrmd.rmd1.own) {
+                   RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
+                   crda = nrda;
+                   nrda = nnrda;
+                   s->crmd = s->nrmd;
+                   s->nrmd = s->nnrmd;
+                   s->nnrmd.rmd1.own = 0;
+               }
+               pktcount++;
+           } while (size > 0 && s->crmd.rmd1.own);
+
+            if (size == 0) {
+                s->crmd.rmd1.enp = 1;
+               s->crmd.rmd2.mcnt = packet_size;
+                s->crmd.rmd1.pam = !CSR_PROM(s) && is_padr;
+                s->crmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
+                s->crmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
+            } else {
+                s->crmd.rmd1.oflo = 1;
+                s->crmd.rmd1.buff = 1;
+                s->crmd.rmd1.err = 1;
             }
-
-#undef PCNET_RECV_STORE
-
-            RMDLOAD(&rmd, PHYSADDR(s,crda));
-            if (size == 0) {
-                rmd.rmd1.enp = 1;
-                rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
-                rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
-                rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
-            } else {
-                rmd.rmd1.oflo = 1;
-                rmd.rmd1.buff = 1;
-                rmd.rmd1.err = 1;
-            }
-            RMDSTORE(&rmd, PHYSADDR(s,crda));
+            RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
             s->csr[0] |= 0x0400;
+           s->crmd = s->nrmd;
+           s->nrmd = s->nnrmd;
+           s->nnrmd.rmd1.own = 0;
 
 #ifdef PCNET_DEBUG
             printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
                 CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
 #endif
 #ifdef PCNET_DEBUG_RMD
-            PRINT_RMD(&rmd);
+            PRINT_RMD(&s->crmd);
 #endif        
 
             while (pktcount--) {
@@ -551,80 +476,88 @@
 
 static void pcnet_transmit(PCNetState *s)
 {
-    target_phys_addr_t xmit_cxda = 0;
+    target_phys_addr_t start_addr = 0;
+    struct pcnet_TMD start_tmd;
     int count = CSR_XMTRL(s)-1;
-    s->xmit_pos = -1;
+    int xmit_pos = 0;
+    int len;
+
     
     if (!CSR_TXON(s)) {
         s->csr[0] &= ~0x0008;
         return;
     }
     
-    txagain:
-    if (pcnet_tdte_poll(s)) {
-        struct pcnet_TMD tmd;
-
-        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
+    while (pcnet_tdte_poll(s)) {
 
 #ifdef PCNET_DEBUG_TMD
         printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
-        PRINT_TMD(&tmd);
-#endif
-        if (tmd.tmd1.stp) {
-            s->xmit_pos = 0;                
-            if (!tmd.tmd1.enp) {
-                cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
-                        s->buffer, 4096 - tmd.tmd1.bcnt);
-                s->xmit_pos += 4096 - tmd.tmd1.bcnt;
-            } 
-            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
-        }
-        if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
-            cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
-                    s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
-            s->xmit_pos += 4096 - tmd.tmd1.bcnt;
-
-           tmd.tmd1.own = 0;
-           TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-
-#ifdef PCNET_DEBUG
-            printf("pcnet_transmit size=%d\n", s->xmit_pos);
-#endif            
-            if (CSR_LOOP(s))
-                pcnet_receive(s, s->buffer, s->xmit_pos);
-            else
-                qemu_send_packet(s->nd, s->buffer, s->xmit_pos);
-
-            s->csr[0] &= ~0x0008;   /* clear TDMD */
-            s->csr[4] |= 0x0004;    /* set TXSTRT */
-            s->xmit_pos = -1;
-        } else {
-           tmd.tmd1.own = 0;
-           TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-       }
-        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
-            s->csr[0] |= 0x0200;    /* set TINT */
-
-        if (CSR_XMTRC(s)<=1)
+        PRINT_TMD(&(s->tmd));
+#endif
+       len = 4096 - s->tmd.tmd1.bcnt;
+        if (CSR_XMTRC(s) <= 1)
             CSR_XMTRC(s) = CSR_XMTRL(s);
         else
             CSR_XMTRC(s)--;
-        if (count--)
-            goto txagain;
-
-    } else 
-    if (s->xmit_pos >= 0) {
-        struct pcnet_TMD tmd;
-        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
-        tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
-        tmd.tmd1.own = 0;
-        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
+
+       /* handle start followed by start */
+        if (s->tmd.tmd1.stp && start_addr) {
+           TMDSTORE(&start_tmd, start_addr);
+           start_addr = 0;
+           xmit_pos = 0;
+       }
+       if ((xmit_pos + len) < sizeof(s->tx_buffer)) {
+           cpu_physical_memory_read(PHYSADDR(s, s->tmd.tmd0.tbadr),
+                       s->tx_buffer + xmit_pos, len);
+           xmit_pos += len;
+       } else {
+           s->tmd.tmd2.buff = s->tmd.tmd2.uflo = s->tmd.tmd1.err = 1;
+           TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+           if (start_addr == PHYSADDR(s,CSR_CXDA(s)))
+               start_addr = 0;         /* don't clear own bit twice */
+           continue;
+       }
+        if (s->tmd.tmd1.stp) {
+           if (s->tmd.tmd1.enp) {
+               if (CSR_LOOP(s))
+                   pcnet_receive(s, s->tx_buffer, xmit_pos);
+               else
+                   qemu_send_packet(s->nd, s->tx_buffer, xmit_pos);
+
+               s->csr[4] |= 0x0008;    /* set TXSTRT */
+               TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+               xmit_pos = 0;
+               count--;
+           } else {
+               start_tmd = s->tmd;
+               start_addr = PHYSADDR(s,CSR_CXDA(s));
+           }
+        } else if (s->tmd.tmd1.enp) {
+           TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+           if (start_addr) {
+               TMDSTORE(&start_tmd, start_addr);
+           }
+           start_addr = 0;
+           xmit_pos = 0;
+           count--;
+
+        } else {
+           TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+       }
+        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && s->tmd.tmd1.ltint))
+            s->csr[0] |= 0x0200;    /* set TINT */
+
+        if (count <= 0)
+            break;
+
+    }
+    if (start_addr) {
+        start_tmd.tmd2.buff = start_tmd.tmd2.uflo = start_tmd.tmd1.err = 1;
+        TMDSTORE(&start_tmd, PHYSADDR(s,start_addr));
         s->csr[0] |= 0x0200;    /* set TINT */
         if (!CSR_DXSUFLO(s)) {
             s->csr[0] &= ~0x0010;
-        } else
-        if (count--)
-          goto txagain;
+        }
     }
 }
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/ioemu/hw/pcnet.h
--- a/tools/ioemu/hw/pcnet.h    Tue Mar 28 10:51:06 2006
+++ b/tools/ioemu/hw/pcnet.h    Tue Mar 28 10:52:47 2006
@@ -177,6 +177,26 @@
     } rmd3;    
 };
 
+typedef struct PCNetState_st PCNetState;
+
+struct PCNetState_st {
+    PCIDevice dev;
+    NetDriverState *nd;
+    int mmio_io_addr, rap, isr, lnkst;
+    target_phys_addr_t rdra, tdra;
+    uint8_t prom[16];
+    uint16_t csr[128];
+    uint16_t bcr[32];
+    uint64_t timer;
+    int recv_pos;
+    uint8_t tx_buffer[2048];
+    uint8_t rx_buffer[2048];
+    struct pcnet_TMD tmd;
+    struct pcnet_RMD crmd;
+    struct pcnet_RMD nrmd;
+    struct pcnet_RMD nnrmd;
+};
+
 
 #define PRINT_TMD(T) printf(    \
         "TMD0 : TBADR=0x%08x\n" \
@@ -230,18 +250,17 @@
         cpu_physical_memory_read(addr+4, (void *)&tmd->tmd1, 4);
         cpu_physical_memory_read(addr, (void *)&tmd->tmd0, 4);
     } else {
-        uint32_t xda[4];
-        cpu_physical_memory_read(addr,
-                (void *)&xda[0], sizeof(xda));
-        ((uint32_t *)tmd)[0] = xda[2];
-        ((uint32_t *)tmd)[1] = xda[1];
-        ((uint32_t *)tmd)[2] = xda[0];
-        ((uint32_t *)tmd)[3] = xda[3];
+        uint32_t xda[2];
+        cpu_physical_memory_read(addr+4, (void *)&xda[0], sizeof(xda));
+        ((uint32_t *)tmd)[0] = xda[1];
+        ((uint32_t *)tmd)[1] = xda[0];
+        ((uint32_t *)tmd)[2] = 0;
     }
 }
 
 static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, 
target_phys_addr_t addr)
 {
+    tmd->tmd1.own = 0;
     cpu_physical_memory_set_dirty(addr);
     if (!BCR_SWSTYLE(s)) {
         uint16_t xda[4];
@@ -259,13 +278,10 @@
             cpu_physical_memory_write(addr+8, (void *)&tmd->tmd2, 4);
             cpu_physical_memory_write(addr+4, (void *)&tmd->tmd1, 4);
         } else {
-            uint32_t xda[4];
+            uint32_t xda[2];
             xda[0] = ((uint32_t *)tmd)[2];
             xda[1] = ((uint32_t *)tmd)[1];
-            xda[2] = ((uint32_t *)tmd)[0];
-            xda[3] = ((uint32_t *)tmd)[3];
-            cpu_physical_memory_write(addr,
-                    (void *)&xda[0], sizeof(xda));
+            cpu_physical_memory_write(addr, (void *)&xda[0], sizeof(xda));
         }
         cpu_physical_memory_set_dirty(addr+15);
     }
@@ -286,22 +302,21 @@
     }
     else
     if (BCR_SWSTYLE(s) != 3) {
-        rmd->rmd2.zeros = 0;
+        ((uint32_t *)rmd)[2] = 0;
         cpu_physical_memory_read(addr+4, (void *)&rmd->rmd1, 4);
         cpu_physical_memory_read(addr, (void *)&rmd->rmd0, 4);
     } else {
-        uint32_t rda[4];
-        cpu_physical_memory_read(addr,
-                (void *)&rda[0], sizeof(rda));
-        ((uint32_t *)rmd)[0] = rda[2];
-        ((uint32_t *)rmd)[1] = rda[1];
-        ((uint32_t *)rmd)[2] = rda[0];
-        ((uint32_t *)rmd)[3] = rda[3];
+        uint32_t rda[2];
+        cpu_physical_memory_read(addr+4, (void *)&rda[0], sizeof(rda));
+        ((uint32_t *)rmd)[0] = rda[1];
+        ((uint32_t *)rmd)[1] = rda[0];
+        ((uint32_t *)rmd)[2] = 0;
     }
 }
 
 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, 
target_phys_addr_t addr)
 {
+    rmd->rmd1.own = 0;
     cpu_physical_memory_set_dirty(addr);
     if (!BCR_SWSTYLE(s)) {
         uint16_t rda[4];                        \
@@ -319,13 +334,10 @@
             cpu_physical_memory_write(addr+8, (void *)&rmd->rmd2, 4);
             cpu_physical_memory_write(addr+4, (void *)&rmd->rmd1, 4);
         } else {
-            uint32_t rda[4];
+            uint32_t rda[2];
             rda[0] = ((uint32_t *)rmd)[2];
             rda[1] = ((uint32_t *)rmd)[1];
-            rda[2] = ((uint32_t *)rmd)[0];
-            rda[3] = ((uint32_t *)rmd)[3];
-            cpu_physical_memory_write(addr,
-                    (void *)&rda[0], sizeof(rda));
+            cpu_physical_memory_write(addr, (void *)&rda[0], sizeof(rda));
         }
         cpu_physical_memory_set_dirty(addr+15);
     }
@@ -340,79 +352,16 @@
 
 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
 
-#if 1
-
-#define CHECK_RMD(ADDR,RES) do {                \
-    struct pcnet_RMD rmd;                       \
-    RMDLOAD(&rmd,(ADDR));                       \
-    (RES) |= (rmd.rmd1.ones != 15);             \
+#define CHECK_RMD(RMD,ADDR,RES) do {            \
+    RMDLOAD((RMD),(ADDR));                      \
+    (RES) |= ((RMD)->rmd1.ones != 15);          \
 } while (0)
 
-#define CHECK_TMD(ADDR,RES) do {                \
-    struct pcnet_TMD tmd;                       \
-    TMDLOAD(&tmd,(ADDR));                       \
-    (RES) |= (tmd.tmd1.ones != 15);             \
+#define CHECK_TMD(ADDR,RES) do {            \
+    TMDLOAD(&(s->tmd),(ADDR));                       \
+    (RES) |= (s->tmd.tmd1.ones != 15);             \
 } while (0)
 
-#else
-
-#define CHECK_RMD(ADDR,RES) do {                \
-    switch (BCR_SWSTYLE(s)) {                   \
-    case 0x00:                                  \
-        do {                                    \
-            uint16_t rda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&rda[0], sizeof(rda));  \
-            (RES) |= (rda[2] & 0xf000)!=0xf000; \
-            (RES) |= (rda[3] & 0xf000)!=0x0000; \
-        } while (0);                            \
-        break;                                  \
-    case 0x01:                                  \
-    case 0x02:                                  \
-        do {                                    \
-            uint32_t rda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&rda[0], sizeof(rda)); \
-            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
-            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
-        } while (0);                            \
-        break;                                  \
-    case 0x03:                                  \
-        do {                                    \
-            uint32_t rda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&rda[0], sizeof(rda)); \
-            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
-            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
-        } while (0);                            \
-        break;                                  \
-    }                                           \
-} while (0)
-
-#define CHECK_TMD(ADDR,RES) do {                \
-    switch (BCR_SWSTYLE(s)) {                   \
-    case 0x00:                                  \
-        do {                                    \
-            uint16_t xda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&xda[0], sizeof(xda));  \
-            (RES) |= (xda[2] & 0xf000)!=0xf000;\
-        } while (0);                            \
-        break;                                  \
-    case 0x01:                                  \
-    case 0x02:                                  \
-    case 0x03:                                  \
-        do {                                    \
-            uint32_t xda[4];                    \
-            cpu_physical_memory_read((ADDR),    \
-                (void *)&xda[0], sizeof(xda));  \
-            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
-        } while (0);                            \
-        break;                                  \
-    }                                           \
-} while (0)
-
-#endif
 
 #define PRINT_PKTHDR(BUF) do {                  \
     struct ether_header *hdr = (void *)(BUF);   \
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue Mar 28 10:51:06 2006
+++ b/tools/libxc/Makefile      Tue Mar 28 10:52:47 2006
@@ -21,13 +21,9 @@
 SRCS       += xc_sedf.c
 SRCS       += xc_tbuf.c
 
-ifeq ($(XEN_TARGET_ARCH),x86_32)
+ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86)
 SRCS       += xc_ptrace.c
 SRCS       += xc_ptrace_core.c
-SRCS       += xc_pagetab.c
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
 SRCS       += xc_pagetab.c
 endif
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Tue Mar 28 10:51:06 2006
+++ b/tools/libxc/xc_ptrace.c   Tue Mar 28 10:52:47 2006
@@ -38,9 +38,6 @@
 };
 #endif
 
-/* XXX application state */
-static long                     nr_pages = 0;
-static unsigned long           *page_array = NULL;
 static int                      current_domid = -1;
 static int                      current_isfile;
 
@@ -196,6 +193,60 @@
     return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
 }
 
+#ifdef __x86_64__
+static void *
+map_domain_va(
+    int xc_handle,
+    int cpu,
+    void *guest_va,
+    int perm)
+{
+    unsigned long l3p, l2p, l1p, p, va = (unsigned long)guest_va;
+    uint64_t *l4, *l3, *l2, *l1;
+    static void *v;
+
+    if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
+        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
+
+    if (fetch_regs(xc_handle, cpu, NULL))
+        return NULL;
+
+    l4 = xc_map_foreign_range(
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+    if ( l4 == NULL )
+        return NULL;
+
+    l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
+    l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l3p);
+    if ( l3 == NULL )
+        return NULL;
+
+    l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
+    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
+    if ( l2 == NULL )
+        return NULL;
+
+    l1p = l2[l2_table_offset(va)] >> PAGE_SHIFT;
+    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+    if ( l1 == NULL )
+        return NULL;
+
+    p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
+    if ( v != NULL )
+        munmap(v, PAGE_SIZE);
+    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+    if ( v == NULL )
+        return NULL;
+
+    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+}
+#endif
+
+#ifdef __i386__
+/* XXX application state */
+static long                     nr_pages = 0;
+static unsigned long           *page_array = NULL;
+
 static void *
 map_domain_va(
     int xc_handle,
@@ -216,15 +267,18 @@
     static unsigned long  page_phys[MAX_VIRT_CPUS];
     static unsigned long *page_virt[MAX_VIRT_CPUS];    
     static int            prev_perm[MAX_VIRT_CPUS];
-    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE } mode;
+    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE, MODE_64 } mode;
 
     if ( mode == MODE_UNKNOWN )
     {
         xen_capabilities_info_t caps;
         (void)xc_version(xc_handle, XENVER_capabilities, caps);
-        mode = MODE_32;
-        if ( strstr(caps, "_x86_32p") )
+        if ( strstr(caps, "-x86_64") )
+            mode = MODE_64;
+        else if ( strstr(caps, "-x86_32p") )
             mode = MODE_PAE;
+        else if ( strstr(caps, "-x86_32") ) 
+            mode = MODE_32;
     }
 
     if ( mode == MODE_PAE )
@@ -303,6 +357,8 @@
 
     return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
 }
+
+#endif
 
 static int 
 __xc_waitdomain(
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h   Tue Mar 28 10:51:06 2006
+++ b/tools/libxc/xc_ptrace.h   Tue Mar 28 10:52:47 2006
@@ -9,6 +9,96 @@
 #define BSD_PAGE_MASK (PAGE_SIZE-1)
 #define PDRSHIFT        22
 #define PSL_T  0x00000100 /* trace enable bit */
+
+#ifdef __x86_64__
+struct gdb_regs
+{
+  unsigned long r15;
+  unsigned long r14;
+  unsigned long r13;
+  unsigned long r12;
+  unsigned long rbp;
+  unsigned long rbx;
+  unsigned long r11;
+  unsigned long r10;
+  unsigned long r9;
+  unsigned long r8;
+  unsigned long rax;
+  unsigned long rcx;
+  unsigned long rdx;
+  unsigned long rsi;
+  unsigned long rdi;
+  unsigned long orig_rax;
+  unsigned long rip;
+  unsigned long xcs;
+  unsigned long eflags;
+  unsigned long rsp;
+  unsigned long xss;
+  unsigned long fs_base;
+  unsigned long gs_base;
+  unsigned long xds;
+  unsigned long xes;
+  unsigned long xfs;
+  unsigned long xgs;
+};
+
+#define SET_PT_REGS(pt, xc)                     \
+{                                               \
+    pt.r8 = xc.r8;                              \
+    pt.r9 = xc.r9;                              \
+    pt.r10 = xc.r10;                            \
+    pt.r11 = xc.r11;                            \
+    pt.r12 = xc.r12;                            \
+    pt.r13 = xc.r13;                            \
+    pt.r14 = xc.r14;                            \
+    pt.r15 = xc.r15;                            \
+    pt.rbx = xc.rbx;                            \
+    pt.rcx = xc.rcx;                            \
+    pt.rdx = xc.rdx;                            \
+    pt.rsi = xc.rsi;                            \
+    pt.rdi = xc.rdi;                            \
+    pt.rbp = xc.rbp;                            \
+    pt.rax = xc.rax;                            \
+    pt.rip = xc.rip;                            \
+    pt.xcs = xc.cs;                             \
+    pt.eflags = xc.eflags;                      \
+    pt.rsp = xc.rsp;                            \
+    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.r8 = pt->r8;                             \
+    xc.r9 = pt->r9;                             \
+    xc.r10 = pt->r10;                           \
+    xc.r11 = pt->r11;                           \
+    xc.r12 = pt->r12;                           \
+    xc.r13 = pt->r13;                           \
+    xc.r14 = pt->r14;                           \
+    xc.r15 = pt->r15;                           \
+    xc.rbx = pt->rbx;                           \
+    xc.rcx = pt->rcx;                           \
+    xc.rdx = pt->rdx;                           \
+    xc.rsi = pt->rsi;                           \
+    xc.rdi = pt->rdi;                           \
+    xc.rbp = pt->rbp;                           \
+    xc.rax = pt->rax;                           \
+    xc.rip = pt->rip;                           \
+    xc.cs = pt->xcs;                            \
+    xc.eflags = pt->eflags;                     \
+    xc.rsp = pt->rsp;                           \
+    xc.ss = pt->xss;                            \
+    xc.es = pt->xes;                            \
+    xc.ds = pt->xds;                            \
+    xc.fs = pt->xfs;                            \
+    xc.gs = pt->xgs;                            \
+}
+
+#elif __i386__
 
 struct gdb_regs {
     long ebx; /* 0 */
@@ -30,8 +120,6 @@
     int  xss;    /* 64 */
 };
 
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
 #define SET_PT_REGS(pt, xc)                     \
 {                                               \
     pt.ebx = xc.ebx;                            \
@@ -71,7 +159,9 @@
     xc.fs = pt->xfs;                            \
     xc.gs = pt->xgs;                            \
 }
+#endif
 
+#define printval(x) printf("%s = %lx\n", #x, (long)x);
 #define vtopdi(va) ((va) >> PDRSHIFT)
 #define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
 #endif
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py        Tue Mar 28 10:51:06 2006
+++ b/tools/python/xen/xend/XendError.py        Tue Mar 28 10:52:47 2006
@@ -19,6 +19,10 @@
 
 import XendClient
 
+class XendInvalidDomain(Fault):
+    def __init__(self, value):
+        Fault.__init__(self, XendClient.ERROR_INVALID_DOMAIN, value)
+
 class XendError(Fault):
     
     def __init__(self, value):
diff -r 1c4e1d0fd1bb -r c745e47d8154 
tools/python/xen/xend/server/XMLRPCServer.py
--- a/tools/python/xen/xend/server/XMLRPCServer.py      Tue Mar 28 10:51:06 2006
+++ b/tools/python/xen/xend/server/XMLRPCServer.py      Tue Mar 28 10:52:47 2006
@@ -23,35 +23,21 @@
 from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
 
 from xen.xend.XendClient import XML_RPC_SOCKET, ERROR_INVALID_DOMAIN
+from xen.xend.XendError import *
 
 def lookup(domid):
-    try:
-        return XendDomain.instance().domain_lookup_by_name_or_id(domid)
-    except exn:
-        log.exception(exn)
-        raise exn
+    info = XendDomain.instance().domain_lookup_by_name_or_id(domid)
+    if not info:
+        raise XendInvalidDomain(str(domid))
+    return info
 
 def dispatch(domid, fn, args):
     info = lookup(domid)
-    if info:
-        try:
-            return getattr(info, fn)(*args)
-        except exn:
-            log.exception(exn)
-            raise exn
-    else:
-        raise xmlrpclib.Fault(ERROR_INVALID_DOMAIN, domid)
+    return getattr(info, fn)(*args)
 
 def domain(domid):
     info = lookup(domid)
-    if info:
-        try:
-            return info.sxpr()
-        except exn:
-            log.exception(exn)
-            raise exn
-    else:
-        raise xmlrpclib.Fault(ERROR_INVALID_DOMAIN, domid)
+    return info.sxpr()
 
 def domains(detail=1):
     if detail < 1:
@@ -90,7 +76,7 @@
         if self.use_tcp:
             # bind to something fixed for now as we may eliminate
             # tcp support completely.
-            self.server = TCPXMLRPCServer(("localhost", 8005, False))
+            self.server = TCPXMLRPCServer(("localhost", 8005), 
logRequests=False)
         else:
             self.server = UnixXMLRPCServer(XML_RPC_SOCKET, False)
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Tue Mar 28 10:51:06 2006
+++ b/tools/python/xen/xm/main.py       Tue Mar 28 10:52:47 2006
@@ -1102,12 +1102,6 @@
             else:
                 err("Error connecting to xend: %s." % ex[1])
             sys.exit(1)
-        except xmlrpclib.ProtocolError, ex:
-            if os.geteuid() != 0:
-                err("Most commands need root access.  Please try again as 
root.")
-            else:
-                err("Error connecting to xend: %s." % ex.errmsg)
-            sys.exit(1)
         except SystemExit:
             sys.exit(1)
         except xmlrpclib.Fault, ex:
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/xentrace/Makefile
--- a/tools/xentrace/Makefile   Tue Mar 28 10:51:06 2006
+++ b/tools/xentrace/Makefile   Tue Mar 28 10:52:47 2006
@@ -6,7 +6,7 @@
 XEN_ROOT=../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-CFLAGS  += -Werror
+CFLAGS  += -Werror -D_LARGEFILE64_SOURCE
 
 CFLAGS  += -I $(XEN_XC)
 CFLAGS  += -I $(XEN_LIBXC)
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/xentrace/formats
--- a/tools/xentrace/formats    Tue Mar 28 10:51:06 2006
+++ b/tools/xentrace/formats    Tue Mar 28 10:52:47 2006
@@ -16,6 +16,6 @@
 0x00080002     CPU%(cpu)d      %(tsc)d         VMX_VECTOR              [ domid 
= 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ]
 0x00080003     CPU%(cpu)d      %(tsc)d         VMX_INT                 [ domid 
= 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
 
-0x00090001      CPU%(cpu)d      %(tsc)d         VMENTRY                 
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
-0x00090002      CPU%(cpu)d      %(tsc)d         VMEXIT                  
0x%(1)08x 0x%(2)08x 0x%(3)08x 
+0x00081001      CPU%(cpu)d      %(tsc)d         VMEXIT                  
0x%(1)08x 0x%(2)08x 0x%(3)08x 
+0x00081002      CPU%(cpu)d      %(tsc)d         VMENTRY                 
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Tue Mar 28 10:51:06 2006
+++ b/tools/xentrace/xentrace.c Tue Mar 28 10:52:47 2006
@@ -498,7 +498,7 @@
     }
 
     if ( opts.outfile )
-        outfd = open(opts.outfile, O_WRONLY | O_CREAT);
+        outfd = open(opts.outfile, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
 
     if(outfd < 0)
     {
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Mar 28 10:52:47 2006
@@ -728,6 +728,8 @@
 
     for_each_vcpu ( d, v )
     {
+        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+            continue;
 #if 0
         /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */
         free_host_save_area(v->arch.hvm_svm.host_save_area);
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Mar 28 10:52:47 2006
@@ -89,6 +89,8 @@
 
     for_each_vcpu ( d, v )
     {
+        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+            continue;
         vmx_request_clear_vmcs(v);
         destroy_vmcs(&v->arch.hvm_vmx);
         free_monitor_pagetable(v);
@@ -988,7 +990,7 @@
         port = (exit_qualification >> 16) & 0xFFFF;
     else
         port = regs->edx & 0xffff;
-    TRACE_VMEXIT(2, port);
+    TRACE_VMEXIT(1, port);
     size = (exit_qualification & 7) + 1;
     dir = test_bit(3, &exit_qualification); /* direction */
 
@@ -1913,6 +1915,7 @@
 
     vector &= 0xff;
     local_irq_disable();
+    TRACE_VMEXIT(1,vector);
 
     switch(vector) {
     case LOCAL_TIMER_VECTOR:
@@ -2042,7 +2045,6 @@
 
     {
         __vmread(GUEST_RIP, &eip);
-        TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
         TRACE_VMEXIT(0,exit_reason);
     }
 
@@ -2066,7 +2068,6 @@
         TRACE_VMEXIT(1,vector);
         perfc_incra(cause_vector, vector);
 
-        TRACE_3D(TRC_VMX_VECTOR, v->domain->domain_id, eip, vector);
         switch (vector) {
 #ifdef XEN_DEBUGGER
         case TRAP_debug:
@@ -2250,7 +2251,7 @@
 
 asmlinkage void vmx_trace_vmentry (void)
 {
-    TRACE_5D(TRC_VMENTRY,
+    TRACE_5D(TRC_VMX_VMENTRY,
              trace_values[smp_processor_id()][0],
              trace_values[smp_processor_id()][1],
              trace_values[smp_processor_id()][2],
@@ -2266,7 +2267,7 @@
 
 asmlinkage void vmx_trace_vmexit (void)
 {
-    TRACE_3D(TRC_VMEXIT,0,0,0);
+    TRACE_3D(TRC_VMX_VMEXIT,0,0,0);
     return;
 }
 
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/mm.c Tue Mar 28 10:52:47 2006
@@ -3351,8 +3351,9 @@
      * permissions in page directories by writing back to the linear mapping.
      */
     if ( (flags = l1e_get_flags(pte) & WRPT_PTE_FLAGS) == WRPT_PTE_FLAGS )
-        return !__put_user(
-            pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1);
+        return __put_user(
+            pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1) ?
+            0 : EXCRET_not_a_fault;
 
     /* We are looking only for read-only mappings of p.t. pages. */
     if ( ((flags | _PAGE_RW) != WRPT_PTE_FLAGS) ||
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/shadow.c     Tue Mar 28 10:52:47 2006
@@ -1807,6 +1807,16 @@
                   entry_has_changed(
                       guest_pt[i], snapshot_pt[i], PAGE_FLAG_MASK) )
                 {
+
+                    unsigned long gpfn;
+
+                    gpfn = entry_get_pfn(guest_pt[i]);
+                    /*
+                     * Looks like it's longer a page table.
+                     */
+                    if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) )
+                        continue;
+
                     need_flush |= validate_entry_change(
                         d, &guest_pt[i], &shadow_pt[i],
                         shadow_type_to_level(stype));
@@ -1851,6 +1861,14 @@
                 {
 #ifndef GUEST_PGENTRY_32
                     l4_pgentry_t *shadow4 = shadow;
+                    unsigned long gpfn;
+
+                    gpfn = l4e_get_pfn(new_root_e);
+                    /*
+                     * Looks like it's longer a page table.
+                     */
+                    if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) )
+                        continue;
 
                     if ( d->arch.ops->guest_paging_levels == PAGING_L4 ) 
                     {
@@ -1894,7 +1912,7 @@
         unmap_domain_page(snapshot);
         unmap_domain_page(guest);
 
-        if ( unlikely(unshadow) )
+        if ( unlikely(unshadow && stype == PGT_root_page_table) )
         {
             for_each_vcpu(d, v)
                 if(smfn == pagetable_get_pfn(v->arch.shadow_table))
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/traps.c      Tue Mar 28 10:52:47 2006
@@ -620,6 +620,46 @@
     return 0;
 }
 
+static int spurious_page_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+    struct vcpu   *v = current;
+    struct domain *d = v->domain;
+    int            rc;
+
+    /*
+     * The only possible reason for a spurious page fault not to be picked
+     * up already is that a page directory was unhooked by writable page table
+     * logic and then reattached before the faulting VCPU could detect it.
+     */
+    if ( is_idle_domain(d) ||               /* no ptwr in idle domain       */
+         IN_HYPERVISOR_RANGE(addr) ||       /* no ptwr on hypervisor addrs  */
+         shadow_mode_enabled(d) ||          /* no ptwr logic in shadow mode */
+         ((regs->error_code & 0x1d) != 0) ) /* simple not-present fault?    */
+        return 0;
+
+    LOCK_BIGLOCK(d);
+
+    /*
+     * The page directory could have been detached again while we weren't
+     * holding the per-domain lock. Detect that and fix up if it's the case.
+     */
+    if ( unlikely(d->arch.ptwr[PTWR_PT_ACTIVE].l1va) &&
+         unlikely(l2_linear_offset(addr) ==
+                  d->arch.ptwr[PTWR_PT_ACTIVE].l2_idx) )
+    {
+        ptwr_flush(d, PTWR_PT_ACTIVE);
+        rc = 1;
+    }
+    else
+    {
+        /* Okay, walk the page tables. Only check for not-present faults.*/
+        rc = __spurious_page_fault(addr);
+    }
+
+    UNLOCK_BIGLOCK(d);
+    return rc;
+}
+
 /*
  * #PF error code:
  *  Bit 0: Protection violation (=1) ; Page not present (=0)
@@ -644,6 +684,13 @@
 
     if ( unlikely(!guest_mode(regs)) )
     {
+        if ( spurious_page_fault(addr, regs) )
+        {
+            DPRINTK("Spurious fault in domain %u:%u at addr %lx\n",
+                    current->domain->domain_id, current->vcpu_id, addr);
+            return EXCRET_not_a_fault;
+        }
+
         if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
         {
             perfc_incrc(copy_user_faults);
@@ -658,7 +705,7 @@
         panic("CPU%d FATAL PAGE FAULT\n"
               "[error_code=%04x]\n"
               "Faulting linear address: %p\n",
-              smp_processor_id(), regs->error_code, addr);
+              smp_processor_id(), regs->error_code, _p(addr));
     }
 
     propagate_page_fault(addr, regs->error_code);
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/x86_32/traps.c       Tue Mar 28 10:52:47 2006
@@ -70,38 +70,77 @@
 
 void show_page_walk(unsigned long addr)
 {
+    unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
+#ifdef CONFIG_X86_PAE
+    l3_pgentry_t l3e, *l3t;
+#endif
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
+    printk("Pagetable walk from %08lx:\n", addr);
+
+#ifdef CONFIG_X86_PAE
+    l3t = map_domain_page(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk(" L3 = %"PRIpte" %08lx\n", l3e_get_intpte(l3e), pfn);
+    unmap_domain_page(l3t);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return;
+#endif
+
+    l2t = map_domain_page(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("  L2 = %"PRIpte" %08lx %s\n", l2e_get_intpte(l2e), pfn, 
+           (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
+    unmap_domain_page(l2t);
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+         (l2e_get_flags(l2e) & _PAGE_PSE) )
+        return;
+
+    l1t = map_domain_page(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("   L1 = %"PRIpte" %08lx\n", l1e_get_intpte(l1e), pfn);
+    unmap_domain_page(l1t);
+}
+
+int __spurious_page_fault(unsigned long addr)
+{
     unsigned long mfn = read_cr3() >> PAGE_SHIFT;
-    intpte_t *ptab, ent;
-    unsigned long pfn; 
-
-    printk("Pagetable walk from %08lx:\n", addr);
-
 #ifdef CONFIG_X86_PAE
-    ptab = map_domain_page(mfn);
-    ent  = ptab[l3_table_offset(addr)];
-    pfn  = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT)); 
-    printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
-    unmap_domain_page(ptab);
-    if ( !(ent & _PAGE_PRESENT) )
-        return;
-    mfn = ent >> PAGE_SHIFT;
+    l3_pgentry_t l3e, *l3t;
 #endif
-
-    ptab = map_domain_page(mfn);
-    ent  = ptab[l2_table_offset(addr)];
-    pfn  = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
-    printk("  L2 = %"PRIpte" %08lx %s\n", ent, pfn, 
-           (ent & _PAGE_PSE) ? "(PSE)" : "");
-    unmap_domain_page(ptab);
-    if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
-        return;
-    mfn = ent >> PAGE_SHIFT;
-
-    ptab = map_domain_page(ent >> PAGE_SHIFT);
-    ent  = ptab[l1_table_offset(addr)];
-    pfn  = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
-    printk("   L1 = %"PRIpte" %08lx\n", ent, pfn);
-    unmap_domain_page(ptab);
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
+#ifdef CONFIG_X86_PAE
+    l3t = map_domain_page(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    unmap_domain_page(l3t);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return 0;
+#endif
+
+    l2t = map_domain_page(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    unmap_domain_page(l2t);
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+        return 0;
+    if ( l2e_get_flags(l2e) & _PAGE_PSE )
+        return 1;
+
+    l1t = map_domain_page(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    unmap_domain_page(l1t);
+    return !!(l1e_get_flags(l1e) & _PAGE_PRESENT);
 }
 
 #define DOUBLEFAULT_STACK_SIZE 1024
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Tue Mar 28 10:51:06 2006
+++ b/xen/arch/x86/x86_64/traps.c       Tue Mar 28 10:52:47 2006
@@ -70,31 +70,79 @@
 
 void show_page_walk(unsigned long addr)
 {
-    unsigned long page = read_cr3();
-    
+    unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
+    l4_pgentry_t l4e, *l4t;
+    l3_pgentry_t l3e, *l3t;
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
     printk("Pagetable walk from %016lx:\n", addr);
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
-    printk(" L4 = %016lx\n", page);
-    if ( !(page & _PAGE_PRESENT) )
+    l4t = mfn_to_virt(mfn);
+    l4e = l4t[l4_table_offset(addr)];
+    mfn = l4e_get_pfn(l4e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk(" L4 = %"PRIpte" %016lx\n", l4e_get_intpte(l4e), pfn);
+    if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
         return;
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
-    printk("  L3 = %016lx\n", page);
-    if ( !(page & _PAGE_PRESENT) )
+    l3t = mfn_to_virt(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("  L3 = %"PRIpte" %016lx\n", l3e_get_intpte(l3e), pfn);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
         return;
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
-    printk("   L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
-    if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
+    l2t = mfn_to_virt(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("   L2 = %"PRIpte" %016lx %s\n", l2e_get_intpte(l2e), pfn,
+           (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+         (l2e_get_flags(l2e) & _PAGE_PSE) )
         return;
 
-    page &= PAGE_MASK;
-    page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
-    printk("    L1 = %016lx\n", page);
+    l1t = mfn_to_virt(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    pfn = get_gpfn_from_mfn(mfn);
+    printk("    L1 = %"PRIpte" %016lx\n", l1e_get_intpte(l1e), pfn);
+}
+
+int __spurious_page_fault(unsigned long addr)
+{
+    unsigned long mfn = read_cr3() >> PAGE_SHIFT;
+    l4_pgentry_t l4e, *l4t;
+    l3_pgentry_t l3e, *l3t;
+    l2_pgentry_t l2e, *l2t;
+    l1_pgentry_t l1e, *l1t;
+
+    l4t = mfn_to_virt(mfn);
+    l4e = l4t[l4_table_offset(addr)];
+    mfn = l4e_get_pfn(l4e);
+    if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
+        return 0;
+
+    l3t = mfn_to_virt(mfn);
+    l3e = l3t[l3_table_offset(addr)];
+    mfn = l3e_get_pfn(l3e);
+    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+        return 0;
+
+    l2t = mfn_to_virt(mfn);
+    l2e = l2t[l2_table_offset(addr)];
+    mfn = l2e_get_pfn(l2e);
+    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+        return 0;
+    if ( l2e_get_flags(l2e) & _PAGE_PSE )
+        return 1;
+
+    l1t = mfn_to_virt(mfn);
+    l1e = l1t[l1_table_offset(addr)];
+    mfn = l1e_get_pfn(l1e);
+    return !!(l1e_get_flags(l1e) & _PAGE_PRESENT);
 }
 
 asmlinkage void double_fault(void);
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Tue Mar 28 10:51:06 2006
+++ b/xen/common/page_alloc.c   Tue Mar 28 10:52:47 2006
@@ -219,8 +219,6 @@
 #define pfn_dom_zone_type(_pfn)                                 \
     (((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM)
 
-/* Up to 2^20 pages can be allocated at once. */
-#define MAX_ORDER 20
 static struct list_head heap[NR_ZONES][MAX_ORDER+1];
 
 static unsigned long avail[NR_ZONES];
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Tue Mar 28 10:51:06 2006
+++ b/xen/include/asm-x86/processor.h   Tue Mar 28 10:52:47 2006
@@ -524,6 +524,7 @@
 void show_stack(struct cpu_user_regs *regs);
 void show_registers(struct cpu_user_regs *regs);
 void show_page_walk(unsigned long addr);
+int __spurious_page_fault(unsigned long addr);
 asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
 
 extern void mtrr_ap_init(void);
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/include/public/trace.h
--- a/xen/include/public/trace.h        Tue Mar 28 10:51:06 2006
+++ b/xen/include/public/trace.h        Tue Mar 28 10:52:47 2006
@@ -24,7 +24,6 @@
 #define TRC_VMXTIMER 0x00082000   /* VMX timer trace           */
 #define TRC_VMXINT   0x00084000   /* VMX interrupt trace       */
 #define TRC_VMXIO    0x00088000   /* VMX io emulation trace  */
-#define TRC_VMEXIT_HANDLER    0x00090000   /* VMX handler trace  */
 
 /* Trace events per class */
 
@@ -50,14 +49,11 @@
 
 /* trace events per subclass */
 #define TRC_VMX_VMEXIT          (TRC_VMXEXIT + 1)
-#define TRC_VMX_VECTOR          (TRC_VMXEXIT + 2)
+#define TRC_VMX_VMENTRY         (TRC_VMXEXIT + 2)
 
 #define TRC_VMX_TIMER_INTR      (TRC_VMXTIMER + 1)
 
 #define TRC_VMX_INT             (TRC_VMXINT + 1)
-
-#define TRC_VMEXIT              (TRC_VMEXIT_HANDLER + 1)
-#define TRC_VMENTRY             (TRC_VMEXIT_HANDLER + 2)
 
 
 /* This structure represents a single trace buffer record. */
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Tue Mar 28 10:51:06 2006
+++ b/xen/include/xen/lib.h     Tue Mar 28 10:52:47 2006
@@ -47,7 +47,8 @@
 #define printk(_f , _a...) printf( _f , ## _a )
 extern void printf(const char *format, ...)
     __attribute__ ((format (printf, 1, 2)));
-extern void panic(const char *format, ...);
+extern void panic(const char *format, ...)
+    __attribute__ ((format (printf, 1, 2)));
 extern long vm_assist(struct domain *, unsigned int, unsigned int);
 
 /* vsprintf.c */
diff -r 1c4e1d0fd1bb -r c745e47d8154 xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Tue Mar 28 10:51:06 2006
+++ b/xen/include/xen/mm.h      Tue Mar 28 10:52:47 2006
@@ -68,6 +68,9 @@
 
 #define ALLOC_DOM_DMA 1
 
+/* Up to 2^20 pages can be allocated at once. */
+#define MAX_ORDER 20
+
 /* Automatic page scrubbing for dead domains. */
 extern struct list_head page_scrub_list;
 #define page_scrub_schedule_work()              \

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>