[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.