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] [xen-3.0.4-testing] [LINUX] Update to 2.6.16.38 point re

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.0.4-testing] [LINUX] Update to 2.6.16.38 point release.
From: "Xen patchbot-3.0.4-testing" <patchbot-3.0.4-testing@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 29 Jan 2007 05:55:14 -0800
Delivery-date: Mon, 29 Jan 2007 05:55:26 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1170064833 0
# Node ID 4be85bb2f54d62338ddd7b793299ef5381850333
# Parent  18f30d7ef2b87b67e8cd1fd36acaabea39b1bfc3
[LINUX] Update to 2.6.16.38 point release.

Only required update was to net-gso-0-base.patch to fixup a call to
skb_linearize with the old prototype in net/sctp.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 patches/linux-2.6.16.33/blktap-aio-16_03_06.patch                              
          |  271 -
 patches/linux-2.6.16.33/device_bind.patch                                      
          |   14 
 patches/linux-2.6.16.33/fix-hz-suspend.patch                                   
          |   25 
 patches/linux-2.6.16.33/fix-ide-cd-pio-mode.patch                              
          |   13 
 patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch     
          |   43 
 patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch     
          |   74 
 patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch     
          |  292 -
 patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch     
          |  320 -
 patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch     
          |   45 
 patches/linux-2.6.16.33/i386-mach-io-check-nmi.patch                           
          |   35 
 patches/linux-2.6.16.33/ipv6-no-autoconf.patch                                 
          |   18 
 patches/linux-2.6.16.33/kasprintf.patch                                        
          |   57 
 patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch    
          |  102 
 patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch  
          |   95 
 patches/linux-2.6.16.33/net-csum.patch                                         
          |   57 
 patches/linux-2.6.16.33/net-gso-0-base.patch                                   
          | 2501 ----------
 patches/linux-2.6.16.33/net-gso-1-check-dodgy.patch                            
          |   22 
 patches/linux-2.6.16.33/net-gso-2-checksum-fix.patch                           
          |  400 -
 patches/linux-2.6.16.33/net-gso-3-fix-errorcheck.patch                         
          |   13 
 patches/linux-2.6.16.33/net-gso-4-kill-warnon.patch                            
          |   16 
 patches/linux-2.6.16.33/net-gso-5-rcv-mss.patch                                
          |   11 
 patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch                    
          |   20 
 patches/linux-2.6.16.33/pci-mmconfig-fix-from-2.6.17.patch                     
          |  252 -
 patches/linux-2.6.16.33/pmd-shared.patch                                       
          |  100 
 patches/linux-2.6.16.33/rcu_needs_cpu.patch                                    
          |   33 
 patches/linux-2.6.16.33/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch     
          |   26 
 patches/linux-2.6.16.33/series                                                 
          |   35 
 patches/linux-2.6.16.33/smp-alts.patch                                         
          |  540 --
 patches/linux-2.6.16.33/tpm_plugin_2.6.17.patch                                
          | 1380 -----
 patches/linux-2.6.16.33/vsnprintf.patch                                        
          |  178 
 patches/linux-2.6.16.33/x86-elfnote-as-preprocessor-macro.patch                
          |   27 
 patches/linux-2.6.16.33/x86-increase-interrupt-vector-range.patch              
          |   73 
 
patches/linux-2.6.16.33/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
    |  138 
 
patches/linux-2.6.16.33/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
 |   72 
 patches/linux-2.6.16.33/xen-hotplug.patch                                      
          |   10 
 patches/linux-2.6.16.33/xenoprof-generic.patch                                 
          |  615 --
 buildconfigs/linux-defconfig_xen0_x86_32                                       
          |   27 
 buildconfigs/linux-defconfig_xen0_x86_64                                       
          |   27 
 buildconfigs/linux-defconfig_xen_x86_32                                        
          |   44 
 buildconfigs/linux-defconfig_xen_x86_64                                        
          |   44 
 buildconfigs/mk.linux-2.6-xen                                                  
          |    2 
 linux-2.6-xen-sparse/arch/i386/Kconfig.cpu                                     
          |    3 
 linux-2.6-xen-sparse/include/asm-i386/system.h                                 
          |    8 
 linux-2.6-xen-sparse/net/core/dev.c                                            
          |   16 
 patches/linux-2.6.16.38/blktap-aio-16_03_06.patch                              
          |  161 
 patches/linux-2.6.16.38/device_bind.patch                                      
          |    9 
 patches/linux-2.6.16.38/fix-hz-suspend.patch                                   
          |    9 
 patches/linux-2.6.16.38/fix-ide-cd-pio-mode.patch                              
          |   13 
 patches/linux-2.6.16.38/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch     
          |   50 
 patches/linux-2.6.16.38/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch     
          |   75 
 patches/linux-2.6.16.38/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch     
          |  197 
 patches/linux-2.6.16.38/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch     
          |  156 
 patches/linux-2.6.16.38/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch     
          |   44 
 patches/linux-2.6.16.38/i386-mach-io-check-nmi.patch                           
          |   30 
 patches/linux-2.6.16.38/ipv6-no-autoconf.patch                                 
          |   16 
 patches/linux-2.6.16.38/kasprintf.patch                                        
          |   32 
 patches/linux-2.6.16.38/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch    
          |  114 
 patches/linux-2.6.16.38/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch  
          |  114 
 patches/linux-2.6.16.38/net-csum.patch                                         
          |   40 
 patches/linux-2.6.16.38/net-gso-0-base.patch                                   
          | 1970 +++++++
 patches/linux-2.6.16.38/net-gso-1-check-dodgy.patch                            
          |   16 
 patches/linux-2.6.16.38/net-gso-2-checksum-fix.patch                           
          |  311 +
 patches/linux-2.6.16.38/net-gso-3-fix-errorcheck.patch                         
          |   13 
 patches/linux-2.6.16.38/net-gso-4-kill-warnon.patch                            
          |   26 
 patches/linux-2.6.16.38/net-gso-5-rcv-mss.patch                                
          |   11 
 patches/linux-2.6.16.38/net-gso-6-linear-segmentation.patch                    
          |   21 
 patches/linux-2.6.16.38/pci-mmconfig-fix-from-2.6.17.patch                     
          |  143 
 patches/linux-2.6.16.38/pmd-shared.patch                                       
          |   57 
 patches/linux-2.6.16.38/rcu_needs_cpu.patch                                    
          |   18 
 patches/linux-2.6.16.38/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch     
          |   26 
 patches/linux-2.6.16.38/series                                                 
          |   35 
 patches/linux-2.6.16.38/smp-alts.patch                                         
          |  330 +
 patches/linux-2.6.16.38/tpm_plugin_2.6.17.patch                                
          |  703 ++
 patches/linux-2.6.16.38/vsnprintf.patch                                        
          |  177 
 patches/linux-2.6.16.38/x86-elfnote-as-preprocessor-macro.patch                
          |   25 
 patches/linux-2.6.16.38/x86-increase-interrupt-vector-range.patch              
          |   73 
 
patches/linux-2.6.16.38/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
    |   39 
 
patches/linux-2.6.16.38/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
 |   63 
 patches/linux-2.6.16.38/xen-hotplug.patch                                      
          |   10 
 patches/linux-2.6.16.38/xenoprof-generic.patch                                 
          |  294 +
 80 files changed, 5542 insertions(+), 7973 deletions(-)

diff -r 18f30d7ef2b8 -r 4be85bb2f54d buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32  Tue Jan 23 19:06:31 2007 -0800
+++ b/buildconfigs/linux-defconfig_xen0_x86_32  Mon Jan 29 10:00:33 2007 +0000
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.13-xen0
-# Thu May 11 17:06:31 2006
+# Linux kernel version: 2.6.16.38
+# Fri Jan 26 15:57:32 2007
 #
 CONFIG_X86_32=y
 CONFIG_SEMAPHORE_SLEEPERS=y
@@ -182,6 +182,7 @@ CONFIG_KEXEC=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x100000
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 
 #
 # Power management options (ACPI, APM)
@@ -542,6 +543,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 CONFIG_AIC79XX_DEBUG_MASK=0
 CONFIG_AIC79XX_REG_PRETTY_PRINT=y
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
 CONFIG_MEGARAID_NEWGEN=y
 # CONFIG_MEGARAID_MM is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -553,6 +555,7 @@ CONFIG_SCSI_ATA_PIIX=y
 # CONFIG_SCSI_SATA_MV is not set
 # CONFIG_SCSI_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_SATA_QSTOR is not set
 CONFIG_SCSI_SATA_PROMISE=y
 CONFIG_SCSI_SATA_SX4=y
@@ -1310,24 +1313,26 @@ CONFIG_CRYPTO_CRC32C=m
 #
 # CONFIG_CRYPTO_DEV_PADLOCK is not set
 CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030202
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
 
 #
 # XEN
 #
 CONFIG_XEN_PRIVILEGED_GUEST=y
 # CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
+CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=y
 CONFIG_XEN_PCIDEV_BACKEND=y
 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
 CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 # CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
-CONFIG_XEN_BLKDEV_BACKEND=y
-CONFIG_XEN_BLKDEV_TAP=y
-CONFIG_XEN_NETDEV_BACKEND=y
-# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
-CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
@@ -1339,7 +1344,13 @@ CONFIG_XEN_COMPAT_030002=y
 CONFIG_XEN_COMPAT_030002=y
 CONFIG_HAVE_ARCH_ALLOC_SKB=y
 CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
 CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
 
 #
 # Library routines
diff -r 18f30d7ef2b8 -r 4be85bb2f54d buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64  Tue Jan 23 19:06:31 2007 -0800
+++ b/buildconfigs/linux-defconfig_xen0_x86_64  Mon Jan 29 10:00:33 2007 +0000
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.13-xen0
-# Thu May 11 17:17:19 2006
+# Linux kernel version: 2.6.16.38
+# Fri Jan 26 15:57:41 2007
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -115,7 +115,6 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -125,6 +124,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_SWIOTLB=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
@@ -504,6 +504,7 @@ CONFIG_SCSI_ATA_PIIX=y
 # CONFIG_SCSI_SATA_MV is not set
 # CONFIG_SCSI_SATA_NV is not set
 # CONFIG_SCSI_PDC_ADMA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_SATA_QSTOR is not set
 CONFIG_SCSI_SATA_PROMISE=y
 CONFIG_SCSI_SATA_SX4=y
@@ -1251,24 +1252,26 @@ CONFIG_CRYPTO_CRC32C=m
 # Hardware crypto devices
 #
 CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030202
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
 
 #
 # XEN
 #
 CONFIG_XEN_PRIVILEGED_GUEST=y
 # CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
+CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=y
 CONFIG_XEN_PCIDEV_BACKEND=y
 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
 CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 # CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
-CONFIG_XEN_BLKDEV_BACKEND=y
-CONFIG_XEN_BLKDEV_TAP=y
-CONFIG_XEN_NETDEV_BACKEND=y
-# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
-CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
@@ -1280,7 +1283,13 @@ CONFIG_XEN_COMPAT_030002=y
 CONFIG_XEN_COMPAT_030002=y
 CONFIG_HAVE_ARCH_ALLOC_SKB=y
 CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
 CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
 
 #
 # Library routines
diff -r 18f30d7ef2b8 -r 4be85bb2f54d buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Tue Jan 23 19:06:31 2007 -0800
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Mon Jan 29 10:00:33 2007 +0000
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.13-xen
-# Thu May 11 17:11:00 2006
+# Linux kernel version: 2.6.16.38
+# Fri Jan 26 15:58:01 2007
 #
 CONFIG_X86_32=y
 CONFIG_SEMAPHORE_SLEEPERS=y
@@ -184,13 +184,14 @@ CONFIG_REGPARM=y
 CONFIG_REGPARM=y
 CONFIG_SECCOMP=y
 CONFIG_HZ_100=y
-CONFIG_KEXEC=y
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
+CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x100000
 CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 
 #
 # Power management options (ACPI, APM)
@@ -1102,6 +1103,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 CONFIG_AIC79XX_DEBUG_MASK=0
 CONFIG_AIC79XX_REG_PRETTY_PRINT=y
 CONFIG_SCSI_DPT_I2O=m
+CONFIG_SCSI_ADVANSYS=m
 CONFIG_MEGARAID_NEWGEN=y
 CONFIG_MEGARAID_MM=m
 CONFIG_MEGARAID_MAILBOX=m
@@ -1114,6 +1116,7 @@ CONFIG_SCSI_SATA_MV=m
 CONFIG_SCSI_SATA_MV=m
 CONFIG_SCSI_SATA_NV=m
 CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
 CONFIG_SCSI_SATA_QSTOR=m
 CONFIG_SCSI_SATA_PROMISE=m
 CONFIG_SCSI_SATA_SX4=m
@@ -2371,6 +2374,18 @@ CONFIG_SND_CS46XX=m
 CONFIG_SND_CS46XX=m
 CONFIG_SND_CS46XX_NEW_DSP=y
 CONFIG_SND_CS5535AUDIO=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
 CONFIG_SND_EMU10K1=m
 CONFIG_SND_EMU10K1X=m
 CONFIG_SND_ENS1370=m
@@ -2379,7 +2394,6 @@ CONFIG_SND_ES1968=m
 CONFIG_SND_ES1968=m
 CONFIG_SND_FM801=m
 # CONFIG_SND_FM801_TEA575X_BOOL is not set
-CONFIG_SND_FM801_TEA575X=m
 CONFIG_SND_HDA_INTEL=m
 CONFIG_SND_HDSP=m
 CONFIG_SND_HDSPM=m
@@ -2777,7 +2791,6 @@ CONFIG_NTFS_FS=m
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
-# CONFIG_PROC_VMCORE is not set
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
@@ -3013,24 +3026,26 @@ CONFIG_CRYPTO_TEST=m
 #
 # CONFIG_CRYPTO_DEV_PADLOCK is not set
 CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030202
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
 
 #
 # XEN
 #
 CONFIG_XEN_PRIVILEGED_GUEST=y
 # CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
+CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=y
 CONFIG_XEN_PCIDEV_BACKEND=m
 CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
 # CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
-CONFIG_XEN_BLKDEV_BACKEND=y
-CONFIG_XEN_BLKDEV_TAP=y
-CONFIG_XEN_NETDEV_BACKEND=y
-# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
-CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
@@ -3044,7 +3059,14 @@ CONFIG_XEN_COMPAT_030002=y
 CONFIG_XEN_COMPAT_030002=y
 CONFIG_HAVE_ARCH_ALLOC_SKB=y
 CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
 CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
 
 #
 # Library routines
diff -r 18f30d7ef2b8 -r 4be85bb2f54d buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Tue Jan 23 19:06:31 2007 -0800
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Mon Jan 29 10:00:33 2007 +0000
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.13-xen
-# Thu May 11 17:18:58 2006
+# Linux kernel version: 2.6.16.38
+# Fri Jan 26 15:58:21 2007
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -122,7 +122,6 @@ CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -134,12 +133,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_SWIOTLB=y
+CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x100000
 CONFIG_SECCOMP=y
 CONFIG_HZ_100=y
-CONFIG_KEXEC=y
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
@@ -1062,6 +1062,7 @@ CONFIG_SCSI_SATA_MV=m
 CONFIG_SCSI_SATA_MV=m
 CONFIG_SCSI_SATA_NV=m
 CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_HPTIOP=m
 CONFIG_SCSI_SATA_QSTOR=m
 CONFIG_SCSI_SATA_PROMISE=m
 CONFIG_SCSI_SATA_SX4=m
@@ -2231,6 +2232,18 @@ CONFIG_SND_CS4281=m
 CONFIG_SND_CS4281=m
 CONFIG_SND_CS46XX=m
 CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
 CONFIG_SND_EMU10K1=m
 CONFIG_SND_EMU10K1X=m
 CONFIG_SND_ENS1370=m
@@ -2239,7 +2252,6 @@ CONFIG_SND_ES1968=m
 CONFIG_SND_ES1968=m
 CONFIG_SND_FM801=m
 # CONFIG_SND_FM801_TEA575X_BOOL is not set
-CONFIG_SND_FM801_TEA575X=m
 CONFIG_SND_HDA_INTEL=m
 CONFIG_SND_HDSP=m
 CONFIG_SND_HDSPM=m
@@ -2844,26 +2856,27 @@ CONFIG_CRYPTO_TEST=m
 # Hardware crypto devices
 #
 CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030202
+CONFIG_XEN_INTERFACE_VERSION=0x00030203
 
 #
 # XEN
 #
 CONFIG_XEN_PRIVILEGED_GUEST=y
 # CONFIG_XEN_UNPRIVILEGED_GUEST is not set
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
+CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
+CONFIG_XEN_NETDEV_LOOPBACK=y
 CONFIG_XEN_PCIDEV_BACKEND=m
 # CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
 CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 # CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
-CONFIG_XEN_BLKDEV_BACKEND=y
-CONFIG_XEN_BLKDEV_TAP=y
-CONFIG_XEN_NETDEV_BACKEND=y
-# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
-CONFIG_XEN_NETDEV_LOOPBACK=y
 CONFIG_XEN_TPMDEV_BACKEND=m
-# CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_FRAMEBUFFER=y
@@ -2876,7 +2889,14 @@ CONFIG_XEN_COMPAT_030002=y
 CONFIG_XEN_COMPAT_030002=y
 CONFIG_HAVE_ARCH_ALLOC_SKB=y
 CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
 CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_UTIL=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_DEVMEM=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_REBOOT=y
+CONFIG_XEN_SMPBOOT=y
 
 #
 # Library routines
diff -r 18f30d7ef2b8 -r 4be85bb2f54d buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Tue Jan 23 19:06:31 2007 -0800
+++ b/buildconfigs/mk.linux-2.6-xen     Mon Jan 29 10:00:33 2007 +0000
@@ -1,5 +1,5 @@ LINUX_SERIES = 2.6
 LINUX_SERIES = 2.6
-LINUX_VER    = 2.6.16.33
+LINUX_VER    = 2.6.16.38
 
 EXTRAVERSION ?= xen
 
diff -r 18f30d7ef2b8 -r 4be85bb2f54d linux-2.6-xen-sparse/arch/i386/Kconfig.cpu
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu        Tue Jan 23 19:06:31 
2007 -0800
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu        Mon Jan 29 10:00:33 
2007 +0000
@@ -7,6 +7,7 @@ choice
 
 config M386
        bool "386"
+       depends on !UML
        ---help---
          This is the processor type of your CPU. This information is used for
          optimizing purposes. In order to compile a kernel that can run on
@@ -301,7 +302,7 @@ config X86_USE_PPRO_CHECKSUM
 
 config X86_USE_3DNOW
        bool
-       depends on MCYRIXIII || MK7 || MGEODE_LX
+       depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
        default y
 
 config X86_OOSTORE
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
linux-2.6-xen-sparse/include/asm-i386/system.h
--- a/linux-2.6-xen-sparse/include/asm-i386/system.h    Tue Jan 23 19:06:31 
2007 -0800
+++ b/linux-2.6-xen-sparse/include/asm-i386/system.h    Mon Jan 29 10:00:33 
2007 +0000
@@ -12,9 +12,14 @@ struct task_struct;  /* one of the strang
 struct task_struct;    /* one of the stranger aspects of C forward 
declarations.. */
 extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, 
struct task_struct *next));
 
+/*
+ * Saving eflags is important. It switches not only IOPL between tasks,
+ * it also protects other tasks from NT leaking through sysenter etc.
+ */
 #define switch_to(prev,next,last) do {                                 \
        unsigned long esi,edi;                                          \
-       asm volatile("pushl %%ebp\n\t"                                  \
+       asm volatile("pushfl\n\t"               /* Save flags */        \
+                    "pushl %%ebp\n\t"                                  \
                     "movl %%esp,%0\n\t"        /* save ESP */          \
                     "movl %5,%%esp\n\t"        /* restore ESP */       \
                     "movl $1f,%1\n\t"          /* save EIP */          \
@@ -22,6 +27,7 @@ extern struct task_struct * FASTCALL(__s
                     "jmp __switch_to\n"                                \
                     "1:\t"                                             \
                     "popl %%ebp\n\t"                                   \
+                    "popfl"                                            \
                     :"=m" (prev->thread.esp),"=m" (prev->thread.eip),  \
                      "=a" (last),"=S" (esi),"=D" (edi)                 \
                     :"m" (next->thread.esp),"m" (next->thread.eip),    \
diff -r 18f30d7ef2b8 -r 4be85bb2f54d linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c       Tue Jan 23 19:06:31 2007 -0800
+++ b/linux-2.6-xen-sparse/net/core/dev.c       Mon Jan 29 10:00:33 2007 +0000
@@ -1441,14 +1441,16 @@ gso:
        if (q->enqueue) {
                /* Grab device queue */
                spin_lock(&dev->queue_lock);
-
-               rc = q->enqueue(skb, q);
-
-               qdisc_run(dev);
-
+               q = dev->qdisc;
+               if (q->enqueue) {
+                       rc = q->enqueue(skb, q);
+                       qdisc_run(dev);
+                       spin_unlock(&dev->queue_lock);
+
+                       rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
+                       goto out;
+               }
                spin_unlock(&dev->queue_lock);
-               rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
-               goto out;
        }
 
        /* The device has no queue. Common case for software devices:
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/blktap-aio-16_03_06.patch
--- a/patches/linux-2.6.16.33/blktap-aio-16_03_06.patch Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,294 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/fs/aio.c ./fs/aio.c
---- ../orig-linux-2.6.16.29/fs/aio.c   2006-09-12 19:02:10.000000000 +0100
-+++ ./fs/aio.c 2006-09-19 13:58:49.000000000 +0100
-@@ -34,6 +34,11 @@
- #include <asm/uaccess.h>
- #include <asm/mmu_context.h>
- 
-+#ifdef CONFIG_EPOLL
-+#include <linux/poll.h>
-+#include <linux/eventpoll.h>
-+#endif
-+
- #if DEBUG > 1
- #define dprintk               printk
- #else
-@@ -1016,6 +1021,10 @@ put_rq:
-       if (waitqueue_active(&ctx->wait))
-               wake_up(&ctx->wait);
- 
-+#ifdef CONFIG_EPOLL
-+      if (ctx->file && waitqueue_active(&ctx->poll_wait))
-+              wake_up(&ctx->poll_wait);
-+#endif
-       if (ret)
-               put_ioctx(ctx);
- 
-@@ -1025,6 +1034,8 @@ put_rq:
- /* aio_read_evt
-  *    Pull an event off of the ioctx's event ring.  Returns the number of 
-  *    events fetched (0 or 1 ;-)
-+ *    If ent parameter is 0, just returns the number of events that would
-+ *    be fetched.
-  *    FIXME: make this use cmpxchg.
-  *    TODO: make the ringbuffer user mmap()able (requires FIXME).
-  */
-@@ -1047,13 +1058,18 @@ static int aio_read_evt(struct kioctx *i
- 
-       head = ring->head % info->nr;
-       if (head != ring->tail) {
--              struct io_event *evp = aio_ring_event(info, head, KM_USER1);
--              *ent = *evp;
--              head = (head + 1) % info->nr;
--              smp_mb(); /* finish reading the event before updatng the head */
--              ring->head = head;
--              ret = 1;
--              put_aio_ring_event(evp, KM_USER1);
-+              if (ent) { /* event requested */
-+                      struct io_event *evp =
-+                              aio_ring_event(info, head, KM_USER1);
-+                      *ent = *evp;
-+                      head = (head + 1) % info->nr;
-+                      /* finish reading the event before updatng the head */
-+                      smp_mb();
-+                      ring->head = head;
-+                      ret = 1;
-+                      put_aio_ring_event(evp, KM_USER1);
-+              } else /* only need to know availability */
-+                      ret = 1;
-       }
-       spin_unlock(&info->ring_lock);
- 
-@@ -1236,9 +1252,78 @@ static void io_destroy(struct kioctx *io
- 
-       aio_cancel_all(ioctx);
-       wait_for_all_aios(ioctx);
-+#ifdef CONFIG_EPOLL
-+      /* forget the poll file, but it's up to the user to close it */
-+      if (ioctx->file) {
-+              ioctx->file->private_data = 0;
-+              ioctx->file = 0;
-+      }
-+#endif
-       put_ioctx(ioctx);       /* once for the lookup */
- }
- 
-+#ifdef CONFIG_EPOLL
-+
-+static int aio_queue_fd_close(struct inode *inode, struct file *file)
-+{
-+      struct kioctx *ioctx = file->private_data;
-+      if (ioctx) {
-+              file->private_data = 0;
-+              spin_lock_irq(&ioctx->ctx_lock);
-+              ioctx->file = 0;
-+              spin_unlock_irq(&ioctx->ctx_lock);
-+      }
-+      return 0;
-+}
-+
-+static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
-+{     unsigned int pollflags = 0;
-+      struct kioctx *ioctx = file->private_data;
-+
-+      if (ioctx) {
-+
-+              spin_lock_irq(&ioctx->ctx_lock);
-+              /* Insert inside our poll wait queue */
-+              poll_wait(file, &ioctx->poll_wait, wait);
-+
-+              /* Check our condition */
-+              if (aio_read_evt(ioctx, 0))
-+                      pollflags = POLLIN | POLLRDNORM;
-+              spin_unlock_irq(&ioctx->ctx_lock);
-+      }
-+
-+      return pollflags;
-+}
-+
-+static struct file_operations aioq_fops = {
-+      .release        = aio_queue_fd_close,
-+      .poll           = aio_queue_fd_poll
-+};
-+
-+/* make_aio_fd:
-+ *  Create a file descriptor that can be used to poll the event queue.
-+ *  Based and piggybacked on the excellent epoll code.
-+ */
-+
-+static int make_aio_fd(struct kioctx *ioctx)
-+{
-+      int error, fd;
-+      struct inode *inode;
-+      struct file *file;
-+
-+      error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
-+      if (error)
-+              return error;
-+
-+      /* associate the file with the IO context */
-+      file->private_data = ioctx;
-+      ioctx->file = file;
-+      init_waitqueue_head(&ioctx->poll_wait);
-+      return fd;
-+}
-+#endif
-+
-+
- /* sys_io_setup:
-  *    Create an aio_context capable of receiving at least nr_events.
-  *    ctxp must not point to an aio_context that already exists, and
-@@ -1251,18 +1336,30 @@ static void io_destroy(struct kioctx *io
-  *    resources are available.  May fail with -EFAULT if an invalid
-  *    pointer is passed for ctxp.  Will fail with -ENOSYS if not
-  *    implemented.
-+ *
-+ *    To request a selectable fd, the user context has to be initialized
-+ *    to 1, instead of 0, and the return value is the fd.
-+ *    This keeps the system call compatible, since a non-zero value
-+ *    was not allowed so far.
-  */
- asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
- {
-       struct kioctx *ioctx = NULL;
-       unsigned long ctx;
-       long ret;
-+      int make_fd = 0;
- 
-       ret = get_user(ctx, ctxp);
-       if (unlikely(ret))
-               goto out;
- 
-       ret = -EINVAL;
-+#ifdef CONFIG_EPOLL
-+      if (ctx == 1) {
-+              make_fd = 1;
-+              ctx = 0;
-+      }
-+#endif
-       if (unlikely(ctx || nr_events == 0)) {
-               pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
-                        ctx, nr_events);
-@@ -1273,8 +1370,12 @@ asmlinkage long sys_io_setup(unsigned nr
-       ret = PTR_ERR(ioctx);
-       if (!IS_ERR(ioctx)) {
-               ret = put_user(ioctx->user_id, ctxp);
--              if (!ret)
--                      return 0;
-+#ifdef CONFIG_EPOLL
-+              if (make_fd && ret >= 0)
-+                      ret = make_aio_fd(ioctx);
-+#endif
-+              if (ret >= 0)
-+                      return ret;
- 
-               get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
-               io_destroy(ioctx);
-diff -pruN ../orig-linux-2.6.16.29/fs/eventpoll.c ./fs/eventpoll.c
---- ../orig-linux-2.6.16.29/fs/eventpoll.c     2006-09-12 19:02:10.000000000 
+0100
-+++ ./fs/eventpoll.c   2006-09-19 13:58:49.000000000 +0100
-@@ -235,8 +235,6 @@ struct ep_pqueue {
- 
- static void ep_poll_safewake_init(struct poll_safewake *psw);
- static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t 
*wq);
--static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
--                  struct eventpoll *ep);
- static int ep_alloc(struct eventpoll **pep);
- static void ep_free(struct eventpoll *ep);
- static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int 
fd);
-@@ -266,7 +264,7 @@ static int ep_events_transfer(struct eve
- static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
-                  int maxevents, long timeout);
- static int eventpollfs_delete_dentry(struct dentry *dentry);
--static struct inode *ep_eventpoll_inode(void);
-+static struct inode *ep_eventpoll_inode(struct file_operations *fops);
- static struct super_block *eventpollfs_get_sb(struct file_system_type 
*fs_type,
-                                             int flags, const char *dev_name,
-                                             void *data);
-@@ -525,7 +523,7 @@ asmlinkage long sys_epoll_create(int siz
-        * Creates all the items needed to setup an eventpoll file. That is,
-        * a file structure, and inode and a free file descriptor.
-        */
--      error = ep_getfd(&fd, &inode, &file, ep);
-+      error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
-       if (error)
-               goto eexit_2;
- 
-@@ -710,8 +708,8 @@ eexit_1:
- /*
-  * Creates the file descriptor to be used by the epoll interface.
-  */
--static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
--                  struct eventpoll *ep)
-+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
-+                  struct eventpoll *ep, struct file_operations *fops)
- {
-       struct qstr this;
-       char name[32];
-@@ -727,7 +725,7 @@ static int ep_getfd(int *efd, struct ino
-               goto eexit_1;
- 
-       /* Allocates an inode from the eventpoll file system */
--      inode = ep_eventpoll_inode();
-+      inode = ep_eventpoll_inode(fops);
-       error = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto eexit_2;
-@@ -758,7 +756,7 @@ static int ep_getfd(int *efd, struct ino
- 
-       file->f_pos = 0;
-       file->f_flags = O_RDONLY;
--      file->f_op = &eventpoll_fops;
-+      file->f_op = fops;
-       file->f_mode = FMODE_READ;
-       file->f_version = 0;
-       file->private_data = ep;
-@@ -1574,7 +1572,7 @@ static int eventpollfs_delete_dentry(str
- }
- 
- 
--static struct inode *ep_eventpoll_inode(void)
-+static struct inode *ep_eventpoll_inode(struct file_operations *fops)
- {
-       int error = -ENOMEM;
-       struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
-@@ -1582,7 +1580,7 @@ static struct inode *ep_eventpoll_inode(
-       if (!inode)
-               goto eexit_1;
- 
--      inode->i_fop = &eventpoll_fops;
-+      inode->i_fop = fops;
- 
-       /*
-        * Mark the inode dirty from the very beginning,
-diff -pruN ../orig-linux-2.6.16.29/include/linux/aio.h ./include/linux/aio.h
---- ../orig-linux-2.6.16.29/include/linux/aio.h        2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/linux/aio.h      2006-09-19 13:58:49.000000000 +0100
-@@ -191,6 +191,11 @@ struct kioctx {
-       struct aio_ring_info    ring_info;
- 
-       struct work_struct      wq;
-+#ifdef CONFIG_EPOLL
-+      // poll integration
-+      wait_queue_head_t       poll_wait;
-+      struct file             *file;
-+#endif
- };
- 
- /* prototypes */
-diff -pruN ../orig-linux-2.6.16.29/include/linux/eventpoll.h 
./include/linux/eventpoll.h
---- ../orig-linux-2.6.16.29/include/linux/eventpoll.h  2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/linux/eventpoll.h        2006-09-19 13:58:49.000000000 +0100
-@@ -86,6 +86,12 @@ static inline void eventpoll_release(str
- }
- 
- 
-+/*
-+ * called by aio code to create fd that can poll the  aio event queueQ
-+ */
-+struct eventpoll;
-+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
-+             struct eventpoll *ep, struct file_operations *fops);
- #else
- 
- static inline void eventpoll_init_file(struct file *file) {}
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/device_bind.patch
--- a/patches/linux-2.6.16.33/device_bind.patch Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/drivers/base/bus.c ./drivers/base/bus.c
---- ../orig-linux-2.6.16.29/drivers/base/bus.c 2006-09-12 19:02:10.000000000 
+0100
-+++ ./drivers/base/bus.c       2006-09-19 13:58:54.000000000 +0100
-@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
-               up(&dev->sem);
-               if (dev->parent)
-                       up(&dev->parent->sem);
-+
-+              if (err > 0)            /* success */
-+                      err = count;
-+              else if (err == 0)      /* driver didn't accept device */
-+                      err = -ENODEV;
-       }
-       put_device(dev);
-       put_bus(bus);
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/fix-hz-suspend.patch
--- a/patches/linux-2.6.16.33/fix-hz-suspend.patch      Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/kernel/timer.c ./kernel/timer.c
---- ../orig-linux-2.6.16.29/kernel/timer.c     2006-09-12 19:02:10.000000000 
+0100
-+++ ./kernel/timer.c   2006-09-19 13:58:58.000000000 +0100
-@@ -555,6 +555,22 @@ found:
-       }
-       spin_unlock(&base->t_base.lock);
- 
-+      /*
-+       * It can happen that other CPUs service timer IRQs and increment
-+       * jiffies, but we have not yet got a local timer tick to process
-+       * the timer wheels.  In that case, the expiry time can be before
-+       * jiffies, but since the high-resolution timer here is relative to
-+       * jiffies, the default expression when high-resolution timers are
-+       * not active,
-+       *
-+       *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
-+       *
-+       * would falsely evaluate to true.  If that is the case, just
-+       * return jiffies so that we can immediately fire the local timer
-+       */
-+      if (time_before(expires, jiffies))
-+              return jiffies;
-+
-       if (time_before(hr_expires, expires))
-               return hr_expires;
- 
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/fix-ide-cd-pio-mode.patch
--- a/patches/linux-2.6.16.33/fix-ide-cd-pio-mode.patch Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/drivers/ide/ide-lib.c 
./drivers/ide/ide-lib.c
---- ../orig-linux-2.6.16.29/drivers/ide/ide-lib.c      2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/ide/ide-lib.c    2006-09-19 13:59:03.000000000 +0100
-@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *driv
- {
-       u64 addr = BLK_BOUNCE_HIGH;     /* dma64_addr_t */
- 
--      if (!PCI_DMA_BUS_IS_PHYS) {
--              addr = BLK_BOUNCE_ANY;
--      } else if (on && drive->media == ide_disk) {
--              if (HWIF(drive)->pci_dev)
-+      if (on && drive->media == ide_disk) {
-+              if (!PCI_DMA_BUS_IS_PHYS)
-+                      addr = BLK_BOUNCE_ANY;
-+              else if (HWIF(drive)->pci_dev)
-                       addr = HWIF(drive)->pci_dev->dma_mask;
-       }
- 
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
--- 
a/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch    
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-From: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
-Date: Sun, 30 Jul 2006 10:03:20 +0000 (-0700)
-Subject: [PATCH] machine_kexec.c: Fix the description of segment handling
-X-Git-Tag: v2.6.18-rc4
-X-Git-Url: 
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2a8a3d5b65e86ec1dfef7d268c64a909eab94af7
-
-[PATCH] machine_kexec.c: Fix the description of segment handling
-
-One of my original comments in machine_kexec was unclear
-and this should fix it.
-
-Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx>
-Cc: Andi Kleen <ak@xxxxxx>
-Acked-by: Horms <horms@xxxxxxxxxxxx>
-Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
-Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx>
----
-
---- a/arch/i386/kernel/machine_kexec.c
-+++ b/arch/i386/kernel/machine_kexec.c
-@@ -189,14 +189,11 @@ NORET_TYPE void machine_kexec(struct kim
-       memcpy((void *)reboot_code_buffer, relocate_new_kernel,
-                                               relocate_new_kernel_size);
- 
--      /* The segment registers are funny things, they are
--       * automatically loaded from a table, in memory wherever you
--       * set them to a specific selector, but this table is never
--       * accessed again you set the segment to a different selector.
--       *
--       * The more common model is are caches where the behide
--       * the scenes work is done, but is also dropped at arbitrary
--       * times.
-+      /* The segment registers are funny things, they have both a
-+       * visible and an invisible part.  Whenever the visible part is
-+       * set to a specific selector, the invisible part is loaded
-+       * with from a table in memory.  At no other time is the
-+       * descriptor table in memory accessed.
-        *
-        * I take advantage of this here by force loading the
-        * segments, before I zap the gdt with an invalid value.
---- a/arch/x86_64/kernel/machine_kexec.c
-+++ b/arch/x86_64/kernel/machine_kexec.c
-@@ -207,14 +207,11 @@ NORET_TYPE void machine_kexec(struct kim
-       __flush_tlb();
- 
- 
--      /* The segment registers are funny things, they are
--       * automatically loaded from a table, in memory wherever you
--       * set them to a specific selector, but this table is never
--       * accessed again unless you set the segment to a different selector.
--       *
--       * The more common model are caches where the behide
--       * the scenes work is done, but is also dropped at arbitrary
--       * times.
-+      /* The segment registers are funny things, they have both a
-+       * visible and an invisible part.  Whenever the visible part is
-+       * set to a specific selector, the invisible part is loaded
-+       * with from a table in memory.  At no other time is the
-+       * descriptor table in memory accessed.
-        *
-        * I take advantage of this here by force loading the
-        * segments, before I zap the gdt with an invalid value.
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
--- 
a/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch    
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-From: Tobias Klauser <tklauser@xxxxxxxxxxx>
-Date: Mon, 26 Jun 2006 16:57:34 +0000 (+0200)
-Subject: Storage class should be first
-X-Git-Tag: v2.6.18-rc1
-X-Git-Url: 
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2efe55a9cec8418f0e0cde3dc3787a42fddc4411
-
-Storage class should be first
-
-Storage class should be before const
-
-Signed-off-by: Tobias Klauser <tklauser@xxxxxxxxxxx>
-Signed-off-by: Adrian Bunk <bunk@xxxxxxxxx>
----
-
---- a/arch/i386/kernel/machine_kexec.c
-+++ b/arch/i386/kernel/machine_kexec.c
-@@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*rel
-                                       unsigned long start_address,
-                                       unsigned int has_pae) ATTRIB_NORET;
- 
--const extern unsigned char relocate_new_kernel[];
-+extern const unsigned char relocate_new_kernel[];
- extern void relocate_new_kernel_end(void);
--const extern unsigned int relocate_new_kernel_size;
-+extern const unsigned int relocate_new_kernel_size;
- 
- /*
-  * A architecture hook called to validate the
---- a/arch/powerpc/kernel/machine_kexec_32.c
-+++ b/arch/powerpc/kernel/machine_kexec_32.c
-@@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_k
-  */
- void default_machine_kexec(struct kimage *image)
- {
--      const extern unsigned char relocate_new_kernel[];
--      const extern unsigned int relocate_new_kernel_size;
-+      extern const unsigned char relocate_new_kernel[];
-+      extern const unsigned int relocate_new_kernel_size;
-       unsigned long page_list;
-       unsigned long reboot_code_buffer, reboot_code_buffer_phys;
-       relocate_new_kernel_t rnk;
---- a/arch/ppc/kernel/machine_kexec.c
-+++ b/arch/ppc/kernel/machine_kexec.c
-@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
-                               unsigned long reboot_code_buffer,
-                               unsigned long start_address) ATTRIB_NORET;
- 
--const extern unsigned char relocate_new_kernel[];
--const extern unsigned int relocate_new_kernel_size;
-+extern const unsigned char relocate_new_kernel[];
-+extern const unsigned int relocate_new_kernel_size;
- 
- void machine_shutdown(void)
- {
---- a/arch/s390/kernel/machine_kexec.c
-+++ b/arch/s390/kernel/machine_kexec.c
-@@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *);
- 
- typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
- 
--const extern unsigned char relocate_kernel[];
--const extern unsigned long long relocate_kernel_len;
-+extern const unsigned char relocate_kernel[];
-+extern const unsigned long long relocate_kernel_len;
- 
- int
- machine_kexec_prepare(struct kimage *image)
---- a/arch/sh/kernel/machine_kexec.c
-+++ b/arch/sh/kernel/machine_kexec.c
-@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k
-                               unsigned long start_address,
-                               unsigned long vbr_reg) ATTRIB_NORET;
- 
--const extern unsigned char relocate_new_kernel[];
--const extern unsigned int relocate_new_kernel_size;
-+extern const unsigned char relocate_new_kernel[];
-+extern const unsigned int relocate_new_kernel_size;
- extern void *gdb_vbr_vector;
- 
- /*
---- a/arch/x86_64/kernel/machine_kexec.c
-+++ b/arch/x86_64/kernel/machine_kexec.c
-@@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_k
-                                       unsigned long start_address,
-                                       unsigned long pgtable) ATTRIB_NORET;
- 
--const extern unsigned char relocate_new_kernel[];
--const extern unsigned long relocate_new_kernel_size;
-+extern const unsigned char relocate_new_kernel[];
-+extern const unsigned long relocate_new_kernel_size;
- 
- int machine_kexec_prepare(struct kimage *image)
- {
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch
--- 
a/patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch    
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,401 +0,0 @@
-From: Magnus Damm <magnus@xxxxxxxxxxxxx>
-Date: Tue, 26 Sep 2006 08:52:38 +0000 (+0200)
-Subject: [PATCH] i386: Avoid overwriting the current pgd (V4, i386)
-X-Git-Url: 
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3566561bfadffcb5dbc85d576be80c0dbf2cccc9
-
-[PATCH] i386: Avoid overwriting the current pgd (V4, i386)
-
-kexec: Avoid overwriting the current pgd (V4, i386)
-
-This patch upgrades the i386-specific kexec code to avoid overwriting the
-current pgd. Overwriting the current pgd is bad when CONFIG_CRASH_DUMP is used
-to start a secondary kernel that dumps the memory of the previous kernel.
-
-The code introduces a new set of page tables. These tables are used to provide
-an executable identity mapping without overwriting the current pgd.
-
-Signed-off-by: Magnus Damm <magnus@xxxxxxxxxxxxx>
-Signed-off-by: Andi Kleen <ak@xxxxxxx>
----
-
---- a/arch/i386/kernel/machine_kexec.c
-+++ b/arch/i386/kernel/machine_kexec.c
-@@ -21,70 +21,13 @@
- #include <asm/system.h>
- 
- #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
--
--#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define L2_ATTR (_PAGE_PRESENT)
--
--#define LEVEL0_SIZE (1UL << 12UL)
--
--#ifndef CONFIG_X86_PAE
--#define LEVEL1_SIZE (1UL << 22UL)
--static u32 pgtable_level1[1024] PAGE_ALIGNED;
--
--static void identity_map_page(unsigned long address)
--{
--      unsigned long level1_index, level2_index;
--      u32 *pgtable_level2;
--
--      /* Find the current page table */
--      pgtable_level2 = __va(read_cr3());
--
--      /* Find the indexes of the physical address to identity map */
--      level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
--      level2_index = address / LEVEL1_SIZE;
--
--      /* Identity map the page table entry */
--      pgtable_level1[level1_index] = address | L0_ATTR;
--      pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
--
--      /* Flush the tlb so the new mapping takes effect.
--       * Global tlb entries are not flushed but that is not an issue.
--       */
--      load_cr3(pgtable_level2);
--}
--
--#else
--#define LEVEL1_SIZE (1UL << 21UL)
--#define LEVEL2_SIZE (1UL << 30UL)
--static u64 pgtable_level1[512] PAGE_ALIGNED;
--static u64 pgtable_level2[512] PAGE_ALIGNED;
--
--static void identity_map_page(unsigned long address)
--{
--      unsigned long level1_index, level2_index, level3_index;
--      u64 *pgtable_level3;
--
--      /* Find the current page table */
--      pgtable_level3 = __va(read_cr3());
--
--      /* Find the indexes of the physical address to identity map */
--      level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
--      level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
--      level3_index = address / LEVEL2_SIZE;
--
--      /* Identity map the page table entry */
--      pgtable_level1[level1_index] = address | L0_ATTR;
--      pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
--      set_64bit(&pgtable_level3[level3_index],
--                                             __pa(pgtable_level2) | L2_ATTR);
--
--      /* Flush the tlb so the new mapping takes effect.
--       * Global tlb entries are not flushed but that is not an issue.
--       */
--      load_cr3(pgtable_level3);
--}
-+static u32 kexec_pgd[1024] PAGE_ALIGNED;
-+#ifdef CONFIG_X86_PAE
-+static u32 kexec_pmd0[1024] PAGE_ALIGNED;
-+static u32 kexec_pmd1[1024] PAGE_ALIGNED;
- #endif
-+static u32 kexec_pte0[1024] PAGE_ALIGNED;
-+static u32 kexec_pte1[1024] PAGE_ALIGNED;
- 
- static void set_idt(void *newidt, __u16 limit)
- {
-@@ -128,16 +71,6 @@ static void load_segments(void)
- #undef __STR
- }
- 
--typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
--                                      unsigned long indirection_page,
--                                      unsigned long reboot_code_buffer,
--                                      unsigned long start_address,
--                                      unsigned int has_pae) ATTRIB_NORET;
--
--extern const unsigned char relocate_new_kernel[];
--extern void relocate_new_kernel_end(void);
--extern const unsigned int relocate_new_kernel_size;
--
- /*
-  * A architecture hook called to validate the
-  * proposed image and prepare the control pages
-@@ -170,25 +103,29 @@ void machine_kexec_cleanup(struct kimage
-  */
- NORET_TYPE void machine_kexec(struct kimage *image)
- {
--      unsigned long page_list;
--      unsigned long reboot_code_buffer;
--
--      relocate_new_kernel_t rnk;
-+      unsigned long page_list[PAGES_NR];
-+      void *control_page;
- 
-       /* Interrupts aren't acceptable while we reboot */
-       local_irq_disable();
- 
--      /* Compute some offsets */
--      reboot_code_buffer = page_to_pfn(image->control_code_page)
--                                                              << PAGE_SHIFT;
--      page_list = image->head;
--
--      /* Set up an identity mapping for the reboot_code_buffer */
--      identity_map_page(reboot_code_buffer);
--
--      /* copy it out */
--      memcpy((void *)reboot_code_buffer, relocate_new_kernel,
--                                              relocate_new_kernel_size);
-+      control_page = page_address(image->control_code_page);
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
-+
-+      page_list[PA_CONTROL_PAGE] = __pa(control_page);
-+      page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
-+      page_list[PA_PGD] = __pa(kexec_pgd);
-+      page_list[VA_PGD] = (unsigned long)kexec_pgd;
-+#ifdef CONFIG_X86_PAE
-+      page_list[PA_PMD_0] = __pa(kexec_pmd0);
-+      page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
-+      page_list[PA_PMD_1] = __pa(kexec_pmd1);
-+      page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
-+#endif
-+      page_list[PA_PTE_0] = __pa(kexec_pte0);
-+      page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
-+      page_list[PA_PTE_1] = __pa(kexec_pte1);
-+      page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
- 
-       /* The segment registers are funny things, they have both a
-        * visible and an invisible part.  Whenever the visible part is
-@@ -207,8 +144,8 @@ NORET_TYPE void machine_kexec(struct kim
-       set_idt(phys_to_virt(0),0);
- 
-       /* now call it */
--      rnk = (relocate_new_kernel_t) reboot_code_buffer;
--      (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
-+      relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-+                      image->start, cpu_has_pae);
- }
- 
- /* crashkernel=size@addr specifies the location to reserve for
---- a/arch/i386/kernel/relocate_kernel.S
-+++ b/arch/i386/kernel/relocate_kernel.S
-@@ -7,16 +7,138 @@
-  */
- 
- #include <linux/linkage.h>
-+#include <asm/page.h>
-+#include <asm/kexec.h>
-+
-+/*
-+ * Must be relocatable PIC code callable as a C function
-+ */
-+
-+#define PTR(x) (x << 2)
-+#define PAGE_ALIGNED (1 << PAGE_SHIFT)
-+#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
-+#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
-+
-+      .text
-+      .align PAGE_ALIGNED
-+      .globl relocate_kernel
-+relocate_kernel:
-+      movl    8(%esp), %ebp /* list of pages */
-+
-+#ifdef CONFIG_X86_PAE
-+      /* map the control page at its virtual address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xc0000000, %eax
-+      shrl    $27, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PMD_0)(%ebp), %edx
-+      orl     $PAE_PGD_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PMD_0)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x3fe00000, %eax
-+      shrl    $18, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_0)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_0)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x001ff000, %eax
-+      shrl    $9, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      /* identity map the control page at its physical address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xc0000000, %eax
-+      shrl    $27, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PMD_1)(%ebp), %edx
-+      orl     $PAE_PGD_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PMD_1)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x3fe00000, %eax
-+      shrl    $18, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_1)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_1)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x001ff000, %eax
-+      shrl    $9, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+#else
-+      /* map the control page at its virtual address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xffc00000, %eax
-+      shrl    $20, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_0)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_0)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x003ff000, %eax
-+      shrl    $10, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      /* identity map the control page at its physical address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xffc00000, %eax
-+      shrl    $20, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_1)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_1)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x003ff000, %eax
-+      shrl    $10, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+#endif
- 
--      /*
--       * Must be relocatable PIC code callable as a C function, that once
--       * it starts can not use the previous processes stack.
--       */
--      .globl relocate_new_kernel
- relocate_new_kernel:
-       /* read the arguments and say goodbye to the stack */
-       movl  4(%esp), %ebx /* page_list */
--      movl  8(%esp), %ebp /* reboot_code_buffer */
-+      movl  8(%esp), %ebp /* list of pages */
-       movl  12(%esp), %edx /* start address */
-       movl  16(%esp), %ecx /* cpu_has_pae */
- 
-@@ -24,11 +146,26 @@ relocate_new_kernel:
-       pushl $0
-       popfl
- 
--      /* set a new stack at the bottom of our page... */
--      lea   4096(%ebp), %esp
-+      /* get physical address of control page now */
-+      /* this is impossible after page table switch */
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edi
-+
-+      /* switch to new set of page tables */
-+      movl    PTR(PA_PGD)(%ebp), %eax
-+      movl    %eax, %cr3
-+
-+      /* setup a new stack at the end of the physical control page */
-+      lea     4096(%edi), %esp
- 
--      /* store the parameters back on the stack */
--      pushl   %edx /* store the start address */
-+      /* jump to identity mapped page */
-+      movl    %edi, %eax
-+      addl    $(identity_mapped - relocate_kernel), %eax
-+      pushl   %eax
-+      ret
-+
-+identity_mapped:
-+      /* store the start address on the stack */
-+      pushl   %edx
- 
-       /* Set cr0 to a known state:
-        * 31 0 == Paging disabled
-@@ -113,8 +250,3 @@ relocate_new_kernel:
-       xorl    %edi, %edi
-       xorl    %ebp, %ebp
-       ret
--relocate_new_kernel_end:
--
--      .globl relocate_new_kernel_size
--relocate_new_kernel_size:
--      .long relocate_new_kernel_end - relocate_new_kernel
---- a/include/asm-i386/kexec.h
-+++ b/include/asm-i386/kexec.h
-@@ -1,6 +1,26 @@
- #ifndef _I386_KEXEC_H
- #define _I386_KEXEC_H
- 
-+#define PA_CONTROL_PAGE  0
-+#define VA_CONTROL_PAGE  1
-+#define PA_PGD           2
-+#define VA_PGD           3
-+#define PA_PTE_0         4
-+#define VA_PTE_0         5
-+#define PA_PTE_1         6
-+#define VA_PTE_1         7
-+#ifdef CONFIG_X86_PAE
-+#define PA_PMD_0         8
-+#define VA_PMD_0         9
-+#define PA_PMD_1         10
-+#define VA_PMD_1         11
-+#define PAGES_NR         12
-+#else
-+#define PAGES_NR         8
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+
- #include <asm/fixmap.h>
- #include <asm/ptrace.h>
- #include <asm/string.h>
-@@ -72,5 +92,12 @@ static inline void crash_setup_regs(stru
-                newregs->eip = (unsigned long)current_text_addr();
-        }
- }
-+asmlinkage NORET_TYPE void
-+relocate_kernel(unsigned long indirection_page,
-+              unsigned long control_page,
-+              unsigned long start_address,
-+              unsigned int has_pae) ATTRIB_NORET;
-+
-+#endif /* __ASSEMBLY__ */
- 
- #endif /* _I386_KEXEC_H */
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch
--- 
a/patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch    
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,375 +0,0 @@
-From: Magnus Damm <magnus@xxxxxxxxxxxxx>
-Date: Tue, 26 Sep 2006 08:52:38 +0000 (+0200)
-Subject: [PATCH] Avoid overwriting the current pgd (V4, x86_64)
-X-Git-Tag: v2.6.19-rc1
-X-Git-Url: 
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f
-
-[PATCH] Avoid overwriting the current pgd (V4, x86_64)
-
-kexec: Avoid overwriting the current pgd (V4, x86_64)
-
-This patch upgrades the x86_64-specific kexec code to avoid overwriting the
-current pgd. Overwriting the current pgd is bad when CONFIG_CRASH_DUMP is used
-to start a secondary kernel that dumps the memory of the previous kernel.
-
-The code introduces a new set of page tables. These tables are used to provide
-an executable identity mapping without overwriting the current pgd.
-
-Signed-off-by: Magnus Damm <magnus@xxxxxxxxxxxxx>
-Signed-off-by: Andi Kleen <ak@xxxxxxx>
----
-
---- a/arch/x86_64/kernel/machine_kexec.c
-+++ b/arch/x86_64/kernel/machine_kexec.c
-@@ -15,6 +15,15 @@
- #include <asm/mmu_context.h>
- #include <asm/io.h>
- 
-+#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
-+static u64 kexec_pgd[512] PAGE_ALIGNED;
-+static u64 kexec_pud0[512] PAGE_ALIGNED;
-+static u64 kexec_pmd0[512] PAGE_ALIGNED;
-+static u64 kexec_pte0[512] PAGE_ALIGNED;
-+static u64 kexec_pud1[512] PAGE_ALIGNED;
-+static u64 kexec_pmd1[512] PAGE_ALIGNED;
-+static u64 kexec_pte1[512] PAGE_ALIGNED;
-+
- static void init_level2_page(pmd_t *level2p, unsigned long addr)
- {
-       unsigned long end_addr;
-@@ -144,32 +153,19 @@ static void load_segments(void)
-               );
- }
- 
--typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long 
indirection_page,
--                                      unsigned long control_code_buffer,
--                                      unsigned long start_address,
--                                      unsigned long pgtable) ATTRIB_NORET;
--
--extern const unsigned char relocate_new_kernel[];
--extern const unsigned long relocate_new_kernel_size;
--
- int machine_kexec_prepare(struct kimage *image)
- {
--      unsigned long start_pgtable, control_code_buffer;
-+      unsigned long start_pgtable;
-       int result;
- 
-       /* Calculate the offsets */
-       start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
--      control_code_buffer = start_pgtable + PAGE_SIZE;
- 
-       /* Setup the identity mapped 64bit page table */
-       result = init_pgtable(image, start_pgtable);
-       if (result)
-               return result;
- 
--      /* Place the code in the reboot code buffer */
--      memcpy(__va(control_code_buffer), relocate_new_kernel,
--                                              relocate_new_kernel_size);
--
-       return 0;
- }
- 
-@@ -184,28 +180,34 @@ void machine_kexec_cleanup(struct kimage
-  */
- NORET_TYPE void machine_kexec(struct kimage *image)
- {
--      unsigned long page_list;
--      unsigned long control_code_buffer;
--      unsigned long start_pgtable;
--      relocate_new_kernel_t rnk;
-+      unsigned long page_list[PAGES_NR];
-+      void *control_page;
- 
-       /* Interrupts aren't acceptable while we reboot */
-       local_irq_disable();
- 
--      /* Calculate the offsets */
--      page_list = image->head;
--      start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
--      control_code_buffer = start_pgtable + PAGE_SIZE;
-+      control_page = page_address(image->control_code_page) + PAGE_SIZE;
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
- 
--      /* Set the low half of the page table to my identity mapped
--       * page table for kexec.  Leave the high half pointing at the
--       * kernel pages.   Don't bother to flush the global pages
--       * as that will happen when I fully switch to my identity mapped
--       * page table anyway.
--       */
--      memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
--      __flush_tlb();
-+      page_list[PA_CONTROL_PAGE] = __pa(control_page);
-+      page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
-+      page_list[PA_PGD] = __pa(kexec_pgd);
-+      page_list[VA_PGD] = (unsigned long)kexec_pgd;
-+      page_list[PA_PUD_0] = __pa(kexec_pud0);
-+      page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
-+      page_list[PA_PMD_0] = __pa(kexec_pmd0);
-+      page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
-+      page_list[PA_PTE_0] = __pa(kexec_pte0);
-+      page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
-+      page_list[PA_PUD_1] = __pa(kexec_pud1);
-+      page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
-+      page_list[PA_PMD_1] = __pa(kexec_pmd1);
-+      page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
-+      page_list[PA_PTE_1] = __pa(kexec_pte1);
-+      page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
- 
-+      page_list[PA_TABLE_PAGE] =
-+        (unsigned long)__pa(page_address(image->control_code_page));
- 
-       /* The segment registers are funny things, they have both a
-        * visible and an invisible part.  Whenever the visible part is
-@@ -222,9 +224,10 @@ NORET_TYPE void machine_kexec(struct kim
-        */
-       set_gdt(phys_to_virt(0),0);
-       set_idt(phys_to_virt(0),0);
-+
-       /* now call it */
--      rnk = (relocate_new_kernel_t) control_code_buffer;
--      (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
-+      relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-+                      image->start);
- }
- 
- /* crashkernel=size@addr specifies the location to reserve for
---- a/arch/x86_64/kernel/relocate_kernel.S
-+++ b/arch/x86_64/kernel/relocate_kernel.S
-@@ -7,31 +7,169 @@
-  */
- 
- #include <linux/linkage.h>
-+#include <asm/page.h>
-+#include <asm/kexec.h>
- 
--      /*
--       * Must be relocatable PIC code callable as a C function, that once
--       * it starts can not use the previous processes stack.
--       */
--      .globl relocate_new_kernel
-+/*
-+ * Must be relocatable PIC code callable as a C function
-+ */
-+
-+#define PTR(x) (x << 3)
-+#define PAGE_ALIGNED (1 << PAGE_SHIFT)
-+#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
-+
-+      .text
-+      .align PAGE_ALIGNED
-       .code64
-+      .globl relocate_kernel
-+relocate_kernel:
-+      /* %rdi indirection_page
-+       * %rsi page_list
-+       * %rdx start address
-+       */
-+
-+      /* map the control page at its virtual address */
-+
-+      movq    $0x0000ff8000000000, %r10        /* mask */
-+      mov     $(39 - 3), %cl                   /* bits to shift */
-+      movq    PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PGD)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PUD_0)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PUD_0)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PMD_0)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PMD_0)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PTE_0)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PTE_0)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      /* identity map the control page at its physical address */
-+
-+      movq    $0x0000ff8000000000, %r10        /* mask */
-+      mov     $(39 - 3), %cl                   /* bits to shift */
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PGD)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PUD_1)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PUD_1)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PMD_1)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PMD_1)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PTE_1)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PTE_1)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
- relocate_new_kernel:
--      /* %rdi page_list
--       * %rsi reboot_code_buffer
-+      /* %rdi indirection_page
-+       * %rsi page_list
-        * %rdx start address
--       * %rcx page_table
--       * %r8  arg5
--       * %r9  arg6
-        */
- 
-       /* zero out flags, and disable interrupts */
-       pushq $0
-       popfq
- 
--      /* set a new stack at the bottom of our page... */
--      lea   4096(%rsi), %rsp
-+      /* get physical address of control page now */
-+      /* this is impossible after page table switch */
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
-+
-+      /* get physical address of page table now too */
-+      movq    PTR(PA_TABLE_PAGE)(%rsi), %rcx
-+
-+      /* switch to new set of page tables */
-+      movq    PTR(PA_PGD)(%rsi), %r9
-+      movq    %r9, %cr3
-+
-+      /* setup a new stack at the end of the physical control page */
-+      lea     4096(%r8), %rsp
-+
-+      /* jump to identity mapped page */
-+      addq    $(identity_mapped - relocate_kernel), %r8
-+      pushq   %r8
-+      ret
- 
--      /* store the parameters back on the stack */
--      pushq   %rdx /* store the start address */
-+identity_mapped:
-+      /* store the start address on the stack */
-+      pushq   %rdx
- 
-       /* Set cr0 to a known state:
-        * 31 1 == Paging enabled
-@@ -136,8 +274,3 @@ relocate_new_kernel:
-       xorq    %r15, %r15
- 
-       ret
--relocate_new_kernel_end:
--
--      .globl relocate_new_kernel_size
--relocate_new_kernel_size:
--      .quad relocate_new_kernel_end - relocate_new_kernel
---- a/include/asm-x86_64/kexec.h
-+++ b/include/asm-x86_64/kexec.h
-@@ -1,6 +1,27 @@
- #ifndef _X86_64_KEXEC_H
- #define _X86_64_KEXEC_H
- 
-+#define PA_CONTROL_PAGE  0
-+#define VA_CONTROL_PAGE  1
-+#define PA_PGD           2
-+#define VA_PGD           3
-+#define PA_PUD_0         4
-+#define VA_PUD_0         5
-+#define PA_PMD_0         6
-+#define VA_PMD_0         7
-+#define PA_PTE_0         8
-+#define VA_PTE_0         9
-+#define PA_PUD_1         10
-+#define VA_PUD_1         11
-+#define PA_PMD_1         12
-+#define VA_PMD_1         13
-+#define PA_PTE_1         14
-+#define VA_PTE_1         15
-+#define PA_TABLE_PAGE    16
-+#define PAGES_NR         17
-+
-+#ifndef __ASSEMBLY__
-+
- #include <linux/string.h>
- 
- #include <asm/page.h>
-@@ -64,4 +85,12 @@ static inline void crash_setup_regs(stru
-               newregs->rip = (unsigned long)current_text_addr();
-       }
- }
-+
-+NORET_TYPE void
-+relocate_kernel(unsigned long indirection_page,
-+              unsigned long page_list,
-+              unsigned long start_address) ATTRIB_NORET;
-+
-+#endif /* __ASSEMBLY__ */
-+
- #endif /* _X86_64_KEXEC_H */
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
--- 
a/patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch    
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-commit dbaab49f92ff6ae6255762a948375e4036cbdbd2
-Author: Vivek Goyal <vgoyal@xxxxxxxxxx>
-Date:   Sat Oct 21 18:37:03 2006 +0200
-
-    [PATCH] x86-64: Overlapping program headers in physical addr space fix
-    
-    o A recent change to vmlinux.ld.S file broke kexec as now resulting vmlinux
-      program headers are overlapping in physical address space.
-    
-    o Now all the vsyscall related sections are placed after data and after
-      that mostly init data sections are placed. To avoid physical overlap
-      among phdrs, there are three possible solutions.
-       - Place vsyscall sections also in data phdrs instead of user
-       - move vsyscal sections after init data in bss.
-       - create another phdrs say data.init and move all the sections
-         after vsyscall into this new phdr.
-    
-    o This patch implements the third solution.
-    
-    Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx>
-    Signed-off-by: Andi Kleen <ak@xxxxxxx>
-    Cc: Magnus Damm <magnus@xxxxxxxxxxxxx>
-    Cc: Andi Kleen <ak@xxxxxxx>
-    Cc: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx>
-    Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
-
-diff --git a/arch/x86_64/kernel/vmlinux.lds.S 
b/arch/x86_64/kernel/vmlinux.lds.S
-index b9df2ab..1283614 100644
---- a/arch/x86_64/kernel/vmlinux.lds.S
-+++ b/arch/x86_64/kernel/vmlinux.lds.S
-@@ -17,6 +17,7 @@ PHDRS {
-       text PT_LOAD FLAGS(5);  /* R_E */
-       data PT_LOAD FLAGS(7);  /* RWE */
-       user PT_LOAD FLAGS(7);  /* RWE */
-+      data.init PT_LOAD FLAGS(7);     /* RWE */
-       note PT_NOTE FLAGS(4);  /* R__ */
- }
- SECTIONS
-@@ -131,7 +132,7 @@ SECTIONS
-   . = ALIGN(8192);            /* init_task */
-   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-       *(.data.init_task)
--  } :data
-+  }:data.init
- 
-   . = ALIGN(4096);
-   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/i386-mach-io-check-nmi.patch
--- a/patches/linux-2.6.16.33/i386-mach-io-check-nmi.patch      Tue Jan 23 
19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/traps.c 
./arch/i386/kernel/traps.c
---- ../orig-linux-2.6.16.29/arch/i386/kernel/traps.c   2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/kernel/traps.c 2006-09-19 13:59:06.000000000 +0100
-@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
- 
- static void io_check_error(unsigned char reason, struct pt_regs * regs)
- {
--      unsigned long i;
--
-       printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
-       show_registers(regs);
- 
-       /* Re-enable the IOCK line, wait for a few seconds */
--      reason = (reason & 0xf) | 8;
--      outb(reason, 0x61);
--      i = 2000;
--      while (--i) udelay(1000);
--      reason &= ~8;
--      outb(reason, 0x61);
-+      clear_io_check_error(reason);
- }
- 
- static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/mach-default/mach_traps.h 
./include/asm-i386/mach-default/mach_traps.h
---- ../orig-linux-2.6.16.29/include/asm-i386/mach-default/mach_traps.h 
2006-09-12 19:02:10.000000000 +0100
-+++ ./include/asm-i386/mach-default/mach_traps.h       2006-09-19 
13:59:06.000000000 +0100
-@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
-       outb(reason, 0x61);
- }
- 
-+static inline void clear_io_check_error(unsigned char reason)
-+{
-+      unsigned long i;
-+
-+      reason = (reason & 0xf) | 8;
-+      outb(reason, 0x61);
-+      i = 2000;
-+      while (--i) udelay(1000);
-+      reason &= ~8;
-+      outb(reason, 0x61);
-+}
-+
- static inline unsigned char get_nmi_reason(void)
- {
-       return inb(0x61);
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/ipv6-no-autoconf.patch
--- a/patches/linux-2.6.16.33/ipv6-no-autoconf.patch    Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/net/ipv6/addrconf.c ./net/ipv6/addrconf.c
---- ../orig-linux-2.6.16.29/net/ipv6/addrconf.c        2006-09-12 
19:02:10.000000000 +0100
-+++ ./net/ipv6/addrconf.c      2006-09-19 13:59:11.000000000 +0100
-@@ -2471,6 +2471,7 @@ static void addrconf_dad_start(struct in
-       spin_lock_bh(&ifp->lock);
- 
-       if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
-+          !(dev->flags&IFF_MULTICAST) ||
-           !(ifp->flags&IFA_F_TENTATIVE)) {
-               ifp->flags &= ~IFA_F_TENTATIVE;
-               spin_unlock_bh(&ifp->lock);
-@@ -2555,6 +2556,7 @@ static void addrconf_dad_completed(struc
-       if (ifp->idev->cnf.forwarding == 0 &&
-           ifp->idev->cnf.rtr_solicits > 0 &&
-           (dev->flags&IFF_LOOPBACK) == 0 &&
-+          (dev->flags & IFF_MULTICAST) &&
-           (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
-               struct in6_addr all_routers;
- 
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/kasprintf.patch
--- a/patches/linux-2.6.16.33/kasprintf.patch   Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-commit e905914f96e11862b130dd229f73045dad9a34e8
-Author: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx>
-Date:   Sun Jun 25 05:49:17 2006 -0700
-
-    [PATCH] Implement kasprintf
-    
-    Implement kasprintf, a kernel version of asprintf.  This allocates the
-    memory required for the formatted string, including the trailing '\0'.
-    Returns NULL on allocation failure.
-    
-    Signed-off-by: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx>
-    Signed-off-by: Chris Wright <chrisw@xxxxxxxxxxxx>
-    Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
-    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx>
-
-diff --git a/include/linux/kernel.h b/include/linux/kernel.h
-index 8c21aaa..3c5e4c2 100644
---- a/include/linux/kernel.h
-+++ b/include/linux/kernel.h
-@@ -117,6 +117,8 @@ extern int scnprintf(char * buf, size_t
-       __attribute__ ((format (printf, 3, 4)));
- extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-       __attribute__ ((format (printf, 3, 0)));
-+extern char *kasprintf(gfp_t gfp, const char *fmt, ...)
-+      __attribute__ ((format (printf, 2, 3)));
- 
- extern int sscanf(const char *, const char *, ...)
-       __attribute__ ((format (scanf, 2, 3)));
-diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index f595947..797428a 100644
---- a/lib/vsprintf.c
-+++ b/lib/vsprintf.c
-@@ -849,3 +849,26 @@ int sscanf(const char * buf, const char
- }
- 
- EXPORT_SYMBOL(sscanf);
-+
-+
-+/* Simplified asprintf. */
-+char *kasprintf(gfp_t gfp, const char *fmt, ...)
-+{
-+      va_list ap;
-+      unsigned int len;
-+      char *p;
-+
-+      va_start(ap, fmt);
-+      len = vsnprintf(NULL, 0, fmt, ap);
-+      va_end(ap);
-+
-+      p = kmalloc(len+1, gfp);
-+      if (!p)
-+              return NULL;
-+      va_start(ap, fmt);
-+      vsnprintf(p, len+1, fmt, ap);
-+      va_end(ap);
-+      return p;
-+}
-+
-+EXPORT_SYMBOL(kasprintf);
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
--- 
a/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch   
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-kexec: Move asm segment handling code to the assembly file (i386)
-
-This patch moves the idt, gdt, and segment handling code from machine_kexec.c
-to relocate_kernel.S. The main reason behind this move is to avoid code 
-duplication in the Xen hypervisor. With this patch all code required to kexec
-is put on the control page.
-
-On top of that this patch also counts as a cleanup - I think it is much
-nicer to write assembly directly in assembly files than wrap inline assembly
-in C functions for no apparent reason.
-
-Signed-off-by: Magnus Damm <magnus@xxxxxxxxxxxxx>
----
-
- Applies to 2.6.19-rc1.
-
- machine_kexec.c   |   59 -----------------------------------------------------
- relocate_kernel.S |   58 +++++++++++++++++++++++++++++++++++++++++++++++-----
- 2 files changed, 53 insertions(+), 64 deletions(-)
-
---- 0002/arch/i386/kernel/machine_kexec.c
-+++ work/arch/i386/kernel/machine_kexec.c      2006-10-05 15:49:08.000000000 
+0900
-@@ -29,48 +29,6 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
- static u32 kexec_pte0[1024] PAGE_ALIGNED;
- static u32 kexec_pte1[1024] PAGE_ALIGNED;
- 
--static void set_idt(void *newidt, __u16 limit)
--{
--      struct Xgt_desc_struct curidt;
--
--      /* ia32 supports unaliged loads & stores */
--      curidt.size    = limit;
--      curidt.address = (unsigned long)newidt;
--
--      load_idt(&curidt);
--};
--
--
--static void set_gdt(void *newgdt, __u16 limit)
--{
--      struct Xgt_desc_struct curgdt;
--
--      /* ia32 supports unaligned loads & stores */
--      curgdt.size    = limit;
--      curgdt.address = (unsigned long)newgdt;
--
--      load_gdt(&curgdt);
--};
--
--static void load_segments(void)
--{
--#define __STR(X) #X
--#define STR(X) __STR(X)
--
--      __asm__ __volatile__ (
--              "\tljmp $"STR(__KERNEL_CS)",$1f\n"
--              "\t1:\n"
--              "\tmovl $"STR(__KERNEL_DS)",%%eax\n"
--              "\tmovl %%eax,%%ds\n"
--              "\tmovl %%eax,%%es\n"
--              "\tmovl %%eax,%%fs\n"
--              "\tmovl %%eax,%%gs\n"
--              "\tmovl %%eax,%%ss\n"
--              ::: "eax", "memory");
--#undef STR
--#undef __STR
--}
--
- /*
-  * A architecture hook called to validate the
-  * proposed image and prepare the control pages
-@@ -127,23 +85,6 @@ NORET_TYPE void machine_kexec(struct kim
-       page_list[PA_PTE_1] = __pa(kexec_pte1);
-       page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
- 
--      /* The segment registers are funny things, they have both a
--       * visible and an invisible part.  Whenever the visible part is
--       * set to a specific selector, the invisible part is loaded
--       * with from a table in memory.  At no other time is the
--       * descriptor table in memory accessed.
--       *
--       * I take advantage of this here by force loading the
--       * segments, before I zap the gdt with an invalid value.
--       */
--      load_segments();
--      /* The gdt & idt are now invalid.
--       * If you want to load them you must set up your own idt & gdt.
--       */
--      set_gdt(phys_to_virt(0),0);
--      set_idt(phys_to_virt(0),0);
--
--      /* now call it */
-       relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-                       image->start, cpu_has_pae);
- }
---- 0002/arch/i386/kernel/relocate_kernel.S
-+++ work/arch/i386/kernel/relocate_kernel.S    2006-10-05 16:03:21.000000000 
+0900
-@@ -154,14 +154,45 @@ relocate_new_kernel:
-       movl    PTR(PA_PGD)(%ebp), %eax
-       movl    %eax, %cr3
- 
-+      /* setup idt */
-+      movl    %edi, %eax
-+      addl    $(idt_48 - relocate_kernel), %eax
-+      lidtl   (%eax)
-+
-+      /* setup gdt */
-+      movl    %edi, %eax
-+      addl    $(gdt - relocate_kernel), %eax
-+      movl    %edi, %esi
-+      addl    $((gdt_48 - relocate_kernel) + 2), %esi
-+      movl    %eax, (%esi)
-+      
-+      movl    %edi, %eax
-+      addl    $(gdt_48 - relocate_kernel), %eax
-+      lgdtl   (%eax)
-+
-+      /* setup data segment registers */
-+      mov     $(gdt_ds - gdt), %eax
-+      mov     %eax, %ds
-+      mov     %eax, %es
-+      mov     %eax, %fs
-+      mov     %eax, %gs
-+      mov     %eax, %ss
-+      
-       /* setup a new stack at the end of the physical control page */
-       lea     4096(%edi), %esp
- 
--      /* jump to identity mapped page */
--      movl    %edi, %eax
--      addl    $(identity_mapped - relocate_kernel), %eax
--      pushl   %eax
--      ret
-+      /* load new code segment and jump to identity mapped page */
-+      movl    %edi, %esi
-+      xorl    %eax, %eax
-+      pushl   %eax
-+      pushl   %esi
-+      pushl   %eax
-+      movl    $(gdt_cs - gdt), %eax
-+      pushl   %eax    
-+      movl    %edi, %eax
-+      addl    $(identity_mapped - relocate_kernel),%eax
-+      pushl   %eax
-+      iretl
- 
- identity_mapped:
-       /* store the start address on the stack */
-@@ -250,3 +281,20 @@ identity_mapped:
-       xorl    %edi, %edi
-       xorl    %ebp, %ebp
-       ret
-+
-+      .align  16
-+gdt:
-+      .quad   0x0000000000000000      /* NULL descriptor */
-+gdt_cs:       
-+      .quad   0x00cf9a000000ffff      /* kernel 4GB code at 0x00000000 */
-+gdt_ds:
-+      .quad   0x00cf92000000ffff      /* kernel 4GB data at 0x00000000 */
-+gdt_end:
-+      
-+gdt_48:
-+      .word   gdt_end - gdt - 1       /* limit */
-+      .long   0                       /* base - filled in by code above */
-+
-+idt_48:
-+      .word   0                       /* limit */
-+      .long   0                       /* base */
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch
--- 
a/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch 
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-kexec: Move asm segment handling code to the assembly file (x86_64)
-
-This patch moves the idt, gdt, and segment handling code from machine_kexec.c
-to relocate_kernel.S.  The main reason behind this move is to avoid code 
-duplication in the Xen hypervisor. With this patch all code required to kexec
-is put on the control page.
-
-On top of that this patch also counts as a cleanup - I think it is much
-nicer to write assembly directly in assembly files than wrap inline assembly
-in C functions for no apparent reason.
-
-Signed-off-by: Magnus Damm <magnus@xxxxxxxxxxxxx>
----
-
- Applies to 2.6.19-rc1.
-
- machine_kexec.c   |   58 -----------------------------------------------------
- relocate_kernel.S |   50 +++++++++++++++++++++++++++++++++++++++++----
- 2 files changed, 45 insertions(+), 63 deletions(-)
-
---- 0002/arch/x86_64/kernel/machine_kexec.c
-+++ work/arch/x86_64/kernel/machine_kexec.c    2006-10-05 16:15:49.000000000 
+0900
-@@ -112,47 +112,6 @@ static int init_pgtable(struct kimage *i
-       return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
- }
- 
--static void set_idt(void *newidt, u16 limit)
--{
--      struct desc_ptr curidt;
--
--      /* x86-64 supports unaliged loads & stores */
--      curidt.size    = limit;
--      curidt.address = (unsigned long)newidt;
--
--      __asm__ __volatile__ (
--              "lidtq %0\n"
--              : : "m" (curidt)
--              );
--};
--
--
--static void set_gdt(void *newgdt, u16 limit)
--{
--      struct desc_ptr curgdt;
--
--      /* x86-64 supports unaligned loads & stores */
--      curgdt.size    = limit;
--      curgdt.address = (unsigned long)newgdt;
--
--      __asm__ __volatile__ (
--              "lgdtq %0\n"
--              : : "m" (curgdt)
--              );
--};
--
--static void load_segments(void)
--{
--      __asm__ __volatile__ (
--              "\tmovl %0,%%ds\n"
--              "\tmovl %0,%%es\n"
--              "\tmovl %0,%%ss\n"
--              "\tmovl %0,%%fs\n"
--              "\tmovl %0,%%gs\n"
--              : : "a" (__KERNEL_DS) : "memory"
--              );
--}
--
- int machine_kexec_prepare(struct kimage *image)
- {
-       unsigned long start_pgtable;
-@@ -209,23 +168,6 @@ NORET_TYPE void machine_kexec(struct kim
-       page_list[PA_TABLE_PAGE] =
-         (unsigned long)__pa(page_address(image->control_code_page));
- 
--      /* The segment registers are funny things, they have both a
--       * visible and an invisible part.  Whenever the visible part is
--       * set to a specific selector, the invisible part is loaded
--       * with from a table in memory.  At no other time is the
--       * descriptor table in memory accessed.
--       *
--       * I take advantage of this here by force loading the
--       * segments, before I zap the gdt with an invalid value.
--       */
--      load_segments();
--      /* The gdt & idt are now invalid.
--       * If you want to load them you must set up your own idt & gdt.
--       */
--      set_gdt(phys_to_virt(0),0);
--      set_idt(phys_to_virt(0),0);
--
--      /* now call it */
-       relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-                       image->start);
- }
---- 0002/arch/x86_64/kernel/relocate_kernel.S
-+++ work/arch/x86_64/kernel/relocate_kernel.S  2006-10-05 16:18:07.000000000 
+0900
-@@ -159,13 +159,39 @@ relocate_new_kernel:
-       movq    PTR(PA_PGD)(%rsi), %r9
-       movq    %r9, %cr3
- 
-+      /* setup idt */
-+      movq    %r8, %rax
-+      addq    $(idt_80 - relocate_kernel), %rax
-+      lidtq   (%rax)
-+
-+      /* setup gdt */
-+      movq    %r8, %rax
-+      addq    $(gdt - relocate_kernel), %rax
-+      movq    %r8, %r9
-+      addq    $((gdt_80 - relocate_kernel) + 2), %r9
-+      movq    %rax, (%r9)
-+
-+      movq    %r8, %rax
-+      addq    $(gdt_80 - relocate_kernel), %rax
-+      lgdtq   (%rax)
-+
-+      /* setup data segment registers */
-+      xorl    %eax, %eax
-+      movl    %eax, %ds
-+      movl    %eax, %es
-+      movl    %eax, %fs
-+      movl    %eax, %gs
-+      movl    %eax, %ss
-+      
-       /* setup a new stack at the end of the physical control page */
-       lea     4096(%r8), %rsp
- 
--      /* jump to identity mapped page */
--      addq    $(identity_mapped - relocate_kernel), %r8
--      pushq   %r8
--      ret
-+      /* load new code segment and jump to identity mapped page */
-+      movq    %r8, %rax
-+      addq    $(identity_mapped - relocate_kernel), %rax
-+      pushq   $(gdt_cs - gdt)
-+      pushq   %rax
-+      lretq
- 
- identity_mapped:
-       /* store the start address on the stack */
-@@ -272,5 +298,19 @@ identity_mapped:
-       xorq    %r13, %r13
-       xorq    %r14, %r14
-       xorq    %r15, %r15
--
-       ret
-+
-+      .align  16
-+gdt:
-+      .quad   0x0000000000000000      /* NULL descriptor */
-+gdt_cs:
-+      .quad   0x00af9a000000ffff
-+gdt_end:
-+
-+gdt_80:
-+      .word   gdt_end - gdt - 1       /* limit */
-+      .quad   0                       /* base - filled in by code above */
-+
-+idt_80:
-+      .word   0                       /* limit */
-+      .quad   0                       /* base */
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/net-csum.patch
--- a/patches/linux-2.6.16.33/net-csum.patch    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_tcp.c 
./net/ipv4/netfilter/ip_nat_proto_tcp.c
---- ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_tcp.c      
2006-09-12 19:02:10.000000000 +0100
-+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c    2006-09-19 13:59:15.000000000 
+0100
-@@ -129,7 +129,12 @@ tcp_manip_pkt(struct sk_buff **pskb,
-       if (hdrsize < sizeof(*hdr))
-               return 1;
- 
--      hdr->check = ip_nat_cheat_check(~oldip, newip,
-+#ifdef CONFIG_XEN
-+      if ((*pskb)->proto_csum_blank)
-+              hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+      else
-+#endif
-+              hdr->check = ip_nat_cheat_check(~oldip, newip,
-                                       ip_nat_cheat_check(oldport ^ 0xFFFF,
-                                                          newport,
-                                                          hdr->check));
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_udp.c 
./net/ipv4/netfilter/ip_nat_proto_udp.c
---- ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_udp.c      
2006-09-12 19:02:10.000000000 +0100
-+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c    2006-09-19 13:59:15.000000000 
+0100
-@@ -113,11 +113,17 @@ udp_manip_pkt(struct sk_buff **pskb,
-               newport = tuple->dst.u.udp.port;
-               portptr = &hdr->dest;
-       }
--      if (hdr->check) /* 0 is a special case meaning no checksum */
--              hdr->check = ip_nat_cheat_check(~oldip, newip,
-+      if (hdr->check) { /* 0 is a special case meaning no checksum */
-+#ifdef CONFIG_XEN
-+              if ((*pskb)->proto_csum_blank)
-+                      hdr->check = ip_nat_cheat_check(oldip, ~newip, 
hdr->check);
-+              else
-+#endif
-+                      hdr->check = ip_nat_cheat_check(~oldip, newip,
-                                       ip_nat_cheat_check(*portptr ^ 0xFFFF,
-                                                          newport,
-                                                          hdr->check));
-+      }
-       *portptr = newport;
-       return 1;
- }
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c 
./net/ipv4/xfrm4_output.c
---- ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c    2006-09-12 
19:02:10.000000000 +0100
-+++ ./net/ipv4/xfrm4_output.c  2006-09-19 13:59:15.000000000 +0100
-@@ -17,6 +17,8 @@
- #include <net/xfrm.h>
- #include <net/icmp.h>
- 
-+extern int skb_checksum_setup(struct sk_buff *skb);
-+
- /* Add encapsulation header.
-  *
-  * In transport mode, the IP header will be moved forward to make space
-@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu
-       struct xfrm_state *x = dst->xfrm;
-       int err;
-       
-+      err = skb_checksum_setup(skb);
-+      if (err)
-+              goto error_nolock;
-+
-       if (skb->ip_summed == CHECKSUM_HW) {
-               err = skb_checksum_help(skb, 0);
-               if (err)
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-0-base.patch
--- a/patches/linux-2.6.16.33/net-gso-0-base.patch      Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,2898 +0,0 @@
-Index: tmp-xxx/Documentation/networking/netdevices.txt
-===================================================================
---- tmp-xxx.orig/Documentation/networking/netdevices.txt       2006-11-15 
10:38:39.000000000 +0000
-+++ tmp-xxx/Documentation/networking/netdevices.txt    2006-11-27 
10:52:42.000000000 +0000
-@@ -42,9 +42,9 @@
-       Context: nominally process, but don't sleep inside an rwlock
- 
- dev->hard_start_xmit:
--      Synchronization: dev->xmit_lock spinlock.
-+      Synchronization: netif_tx_lock spinlock.
-       When the driver sets NETIF_F_LLTX in dev->features this will be
--      called without holding xmit_lock. In this case the driver 
-+      called without holding netif_tx_lock. In this case the driver
-       has to lock by itself when needed. It is recommended to use a try lock
-       for this and return -1 when the spin lock fails. 
-       The locking there should also properly protect against 
-@@ -62,12 +62,12 @@
-         Only valid when NETIF_F_LLTX is set.
- 
- dev->tx_timeout:
--      Synchronization: dev->xmit_lock spinlock.
-+      Synchronization: netif_tx_lock spinlock.
-       Context: BHs disabled
-       Notes: netif_queue_stopped() is guaranteed true
- 
- dev->set_multicast_list:
--      Synchronization: dev->xmit_lock spinlock.
-+      Synchronization: netif_tx_lock spinlock.
-       Context: BHs disabled
- 
- dev->poll:
-Index: tmp-xxx/drivers/block/aoe/aoenet.c
-===================================================================
---- tmp-xxx.orig/drivers/block/aoe/aoenet.c    2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/block/aoe/aoenet.c 2006-11-27 10:52:42.000000000 +0000
-@@ -95,9 +95,8 @@
- static struct sk_buff *
- skb_check(struct sk_buff *skb)
- {
--      if (skb_is_nonlinear(skb))
-       if ((skb = skb_share_check(skb, GFP_ATOMIC)))
--      if (skb_linearize(skb, GFP_ATOMIC) < 0) {
-+      if (skb_linearize(skb)) {
-               dev_kfree_skb(skb);
-               return NULL;
-       }
-Index: tmp-xxx/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-===================================================================
---- tmp-xxx.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c        
2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/infiniband/ulp/ipoib/ipoib_multicast.c     2006-11-27 
10:52:42.000000000 +0000
-@@ -821,7 +821,8 @@
- 
-       ipoib_mcast_stop_thread(dev, 0);
- 
--      spin_lock_irqsave(&dev->xmit_lock, flags);
-+      local_irq_save(flags);
-+      netif_tx_lock(dev);
-       spin_lock(&priv->lock);
- 
-       /*
-@@ -896,7 +897,8 @@
-       }
- 
-       spin_unlock(&priv->lock);
--      spin_unlock_irqrestore(&dev->xmit_lock, flags);
-+      netif_tx_unlock(dev);
-+      local_irq_restore(flags);
- 
-       /* We have to cancel outside of the spinlock */
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
-Index: tmp-xxx/drivers/media/dvb/dvb-core/dvb_net.c
-===================================================================
---- tmp-xxx.orig/drivers/media/dvb/dvb-core/dvb_net.c  2006-11-15 
10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/media/dvb/dvb-core/dvb_net.c       2006-11-27 
10:52:42.000000000 +0000
-@@ -1053,7 +1053,7 @@
- 
-       dvb_net_feed_stop(dev);
-       priv->rx_mode = RX_MODE_UNI;
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
- 
-       if (dev->flags & IFF_PROMISC) {
-               dprintk("%s: promiscuous mode\n", dev->name);
-@@ -1078,7 +1078,7 @@
-               }
-       }
- 
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       dvb_net_feed_start(dev);
- }
- 
-Index: tmp-xxx/drivers/net/8139cp.c
-===================================================================
---- tmp-xxx.orig/drivers/net/8139cp.c  2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/8139cp.c       2006-11-27 10:52:42.000000000 +0000
-@@ -794,7 +794,7 @@
-       entry = cp->tx_head;
-       eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-       if (dev->features & NETIF_F_TSO)
--              mss = skb_shinfo(skb)->tso_size;
-+              mss = skb_shinfo(skb)->gso_size;
- 
-       if (skb_shinfo(skb)->nr_frags == 0) {
-               struct cp_desc *txd = &cp->tx_ring[entry];
-Index: tmp-xxx/drivers/net/bnx2.c
-===================================================================
---- tmp-xxx.orig/drivers/net/bnx2.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/bnx2.c 2006-11-27 10:52:42.000000000 +0000
-@@ -1593,7 +1593,7 @@
-               skb = tx_buf->skb;
- #ifdef BCM_TSO 
-               /* partial BD completions possible with TSO packets */
--              if (skb_shinfo(skb)->tso_size) {
-+              if (skb_shinfo(skb)->gso_size) {
-                       u16 last_idx, last_ring_idx;
- 
-                       last_idx = sw_cons +
-@@ -1948,7 +1948,7 @@
-       return 1;
- }
- 
--/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
-+/* Called with rtnl_lock from vlan functions and also netif_tx_lock
-  * from set_multicast.
-  */
- static void
-@@ -4403,7 +4403,7 @@
- }
- #endif
- 
--/* Called with dev->xmit_lock.
-+/* Called with netif_tx_lock.
-  * hard_start_xmit is pseudo-lockless - a lock is only required when
-  * the tx queue is full. This way, we get the benefit of lockless
-  * operations most of the time without the complexities to handle
-@@ -4441,7 +4441,7 @@
-                       (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
-       }
- #ifdef BCM_TSO 
--      if ((mss = skb_shinfo(skb)->tso_size) &&
-+      if ((mss = skb_shinfo(skb)->gso_size) &&
-               (skb->len > (bp->dev->mtu + ETH_HLEN))) {
-               u32 tcp_opt_len, ip_tcp_len;
- 
-Index: tmp-xxx/drivers/net/bonding/bond_main.c
-===================================================================
---- tmp-xxx.orig/drivers/net/bonding/bond_main.c       2006-11-15 
10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/bonding/bond_main.c    2006-11-27 10:52:42.000000000 
+0000
-@@ -1145,8 +1145,7 @@
- }
- 
- #define BOND_INTERSECT_FEATURES \
--      (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
--      NETIF_F_TSO|NETIF_F_UFO)
-+      (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
- 
- /* 
-  * Compute the common dev->feature set available to all slaves.  Some
-@@ -1164,9 +1163,7 @@
-               features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
- 
-       if ((features & NETIF_F_SG) && 
--          !(features & (NETIF_F_IP_CSUM |
--                        NETIF_F_NO_CSUM |
--                        NETIF_F_HW_CSUM)))
-+          !(features & NETIF_F_ALL_CSUM))
-               features &= ~NETIF_F_SG;
- 
-       /* 
-@@ -4147,7 +4144,7 @@
-        */
-       bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
- 
--      /* don't acquire bond device's xmit_lock when 
-+      /* don't acquire bond device's netif_tx_lock when
-        * transmitting */
-       bond_dev->features |= NETIF_F_LLTX;
- 
-Index: tmp-xxx/drivers/net/chelsio/sge.c
-===================================================================
---- tmp-xxx.orig/drivers/net/chelsio/sge.c     2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/chelsio/sge.c  2006-11-27 10:52:42.000000000 +0000
-@@ -1419,7 +1419,7 @@
-       struct cpl_tx_pkt *cpl;
- 
- #ifdef NETIF_F_TSO
--      if (skb_shinfo(skb)->tso_size) {
-+      if (skb_shinfo(skb)->gso_size) {
-               int eth_type;
-               struct cpl_tx_pkt_lso *hdr;
- 
-@@ -1434,7 +1434,7 @@
-               hdr->ip_hdr_words = skb->nh.iph->ihl;
-               hdr->tcp_hdr_words = skb->h.th->doff;
-               hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
--                                              skb_shinfo(skb)->tso_size));
-+                                              skb_shinfo(skb)->gso_size));
-               hdr->len = htonl(skb->len - sizeof(*hdr));
-               cpl = (struct cpl_tx_pkt *)hdr;
-               sge->stats.tx_lso_pkts++;
-Index: tmp-xxx/drivers/net/e1000/e1000_main.c
-===================================================================
---- tmp-xxx.orig/drivers/net/e1000/e1000_main.c        2006-11-15 
10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/e1000/e1000_main.c     2006-11-27 10:52:42.000000000 
+0000
-@@ -2526,7 +2526,7 @@
-       uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
-       int err;
- 
--      if (skb_shinfo(skb)->tso_size) {
-+      if (skb_shinfo(skb)->gso_size) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (err)
-@@ -2534,7 +2534,7 @@
-               }
- 
-               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
--              mss = skb_shinfo(skb)->tso_size;
-+              mss = skb_shinfo(skb)->gso_size;
-               if (skb->protocol == ntohs(ETH_P_IP)) {
-                       skb->nh.iph->tot_len = 0;
-                       skb->nh.iph->check = 0;
-@@ -2651,7 +2651,7 @@
-                * tso gets written back prematurely before the data is fully
-                * DMAd to the controller */
-               if (!skb->data_len && tx_ring->last_tx_tso &&
--                              !skb_shinfo(skb)->tso_size) {
-+                              !skb_shinfo(skb)->gso_size) {
-                       tx_ring->last_tx_tso = 0;
-                       size -= 4;
-               }
-@@ -2893,7 +2893,7 @@
-       }
- 
- #ifdef NETIF_F_TSO
--      mss = skb_shinfo(skb)->tso_size;
-+      mss = skb_shinfo(skb)->gso_size;
-       /* The controller does a simple calculation to 
-        * make sure there is enough room in the FIFO before
-        * initiating the DMA for each buffer.  The calc is:
-@@ -2935,7 +2935,7 @@
- #ifdef NETIF_F_TSO
-       /* Controller Erratum workaround */
-       if (!skb->data_len && tx_ring->last_tx_tso &&
--              !skb_shinfo(skb)->tso_size)
-+              !skb_shinfo(skb)->gso_size)
-               count++;
- #endif
- 
-Index: tmp-xxx/drivers/net/forcedeth.c
-===================================================================
---- tmp-xxx.orig/drivers/net/forcedeth.c       2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/forcedeth.c    2006-11-27 10:52:42.000000000 +0000
-@@ -482,9 +482,9 @@
-  * critical parts:
-  * - rx is (pseudo-) lockless: it relies on the single-threading provided
-  *    by the arch code for interrupts.
-- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
-+ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
-  *    needs dev->priv->lock :-(
-- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
-+ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
-  */
- 
- /* in dev: base, irq */
-@@ -1016,7 +1016,7 @@
- 
- /*
-  * nv_start_xmit: dev->hard_start_xmit function
-- * Called with dev->xmit_lock held.
-+ * Called with netif_tx_lock held.
-  */
- static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
-@@ -1105,8 +1105,8 @@
-       np->tx_skbuff[nr] = skb;
- 
- #ifdef NETIF_F_TSO
--      if (skb_shinfo(skb)->tso_size)
--              tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << 
NV_TX2_TSO_SHIFT);
-+      if (skb_shinfo(skb)->gso_size)
-+              tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << 
NV_TX2_TSO_SHIFT);
-       else
- #endif
-       tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? 
(NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
-@@ -1203,7 +1203,7 @@
- 
- /*
-  * nv_tx_timeout: dev->tx_timeout function
-- * Called with dev->xmit_lock held.
-+ * Called with netif_tx_lock held.
-  */
- static void nv_tx_timeout(struct net_device *dev)
- {
-@@ -1524,7 +1524,7 @@
-                * Changing the MTU is a rare event, it shouldn't matter.
-                */
-               disable_irq(dev->irq);
--              spin_lock_bh(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               spin_lock(&np->lock);
-               /* stop engines */
-               nv_stop_rx(dev);
-@@ -1559,7 +1559,7 @@
-               nv_start_rx(dev);
-               nv_start_tx(dev);
-               spin_unlock(&np->lock);
--              spin_unlock_bh(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-               enable_irq(dev->irq);
-       }
-       return 0;
-@@ -1594,7 +1594,7 @@
-       memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
- 
-       if (netif_running(dev)) {
--              spin_lock_bh(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               spin_lock_irq(&np->lock);
- 
-               /* stop rx engine */
-@@ -1606,7 +1606,7 @@
-               /* restart rx engine */
-               nv_start_rx(dev);
-               spin_unlock_irq(&np->lock);
--              spin_unlock_bh(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-       } else {
-               nv_copy_mac_to_hw(dev);
-       }
-@@ -1615,7 +1615,7 @@
- 
- /*
-  * nv_set_multicast: dev->set_multicast function
-- * Called with dev->xmit_lock held.
-+ * Called with netif_tx_lock held.
-  */
- static void nv_set_multicast(struct net_device *dev)
- {
-Index: tmp-xxx/drivers/net/hamradio/6pack.c
-===================================================================
---- tmp-xxx.orig/drivers/net/hamradio/6pack.c  2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/hamradio/6pack.c       2006-11-27 10:52:42.000000000 
+0000
-@@ -308,9 +308,9 @@
- {
-       struct sockaddr_ax25 *sa = addr;
- 
--      spin_lock_irq(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
--      spin_unlock_irq(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- 
-       return 0;
- }
-@@ -767,9 +767,9 @@
-                       break;
-               }
- 
--              spin_lock_irq(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
--              spin_unlock_irq(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
- 
-               err = 0;
-               break;
-Index: tmp-xxx/drivers/net/hamradio/mkiss.c
-===================================================================
---- tmp-xxx.orig/drivers/net/hamradio/mkiss.c  2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/hamradio/mkiss.c       2006-11-27 10:52:42.000000000 
+0000
-@@ -357,9 +357,9 @@
- {
-       struct sockaddr_ax25 *sa = addr;
- 
--      spin_lock_irq(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
--      spin_unlock_irq(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- 
-       return 0;
- }
-@@ -886,9 +886,9 @@
-                       break;
-               }
- 
--              spin_lock_irq(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
--              spin_unlock_irq(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
- 
-               err = 0;
-               break;
-Index: tmp-xxx/drivers/net/ifb.c
-===================================================================
---- tmp-xxx.orig/drivers/net/ifb.c     2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/ifb.c  2006-11-27 10:52:42.000000000 +0000
-@@ -76,13 +76,13 @@
-       dp->st_task_enter++;
-       if ((skb = skb_peek(&dp->tq)) == NULL) {
-               dp->st_txq_refl_try++;
--              if (spin_trylock(&_dev->xmit_lock)) {
-+              if (netif_tx_trylock(_dev)) {
-                       dp->st_rxq_enter++;
-                       while ((skb = skb_dequeue(&dp->rq)) != NULL) {
-                               skb_queue_tail(&dp->tq, skb);
-                               dp->st_rx2tx_tran++;
-                       }
--                      spin_unlock(&_dev->xmit_lock);
-+                      netif_tx_unlock(_dev);
-               } else {
-                       /* reschedule */
-                       dp->st_rxq_notenter++;
-@@ -110,7 +110,7 @@
-               }
-       }
- 
--      if (spin_trylock(&_dev->xmit_lock)) {
-+      if (netif_tx_trylock(_dev)) {
-               dp->st_rxq_check++;
-               if ((skb = skb_peek(&dp->rq)) == NULL) {
-                       dp->tasklet_pending = 0;
-@@ -118,10 +118,10 @@
-                               netif_wake_queue(_dev);
-               } else {
-                       dp->st_rxq_rsch++;
--                      spin_unlock(&_dev->xmit_lock);
-+                      netif_tx_unlock(_dev);
-                       goto resched;
-               }
--              spin_unlock(&_dev->xmit_lock);
-+              netif_tx_unlock(_dev);
-       } else {
- resched:
-               dp->tasklet_pending = 1;
-Index: tmp-xxx/drivers/net/irda/vlsi_ir.c
-===================================================================
---- tmp-xxx.orig/drivers/net/irda/vlsi_ir.c    2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/irda/vlsi_ir.c 2006-11-27 10:52:42.000000000 +0000
-@@ -959,7 +959,7 @@
-                           ||  (now.tv_sec==ready.tv_sec && 
now.tv_usec>=ready.tv_usec))
-                               break;
-                       udelay(100);
--                      /* must not sleep here - we are called under xmit_lock! 
*/
-+                      /* must not sleep here - called under netif_tx_lock! */
-               }
-       }
- 
-Index: tmp-xxx/drivers/net/ixgb/ixgb_main.c
-===================================================================
---- tmp-xxx.orig/drivers/net/ixgb/ixgb_main.c  2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/ixgb/ixgb_main.c       2006-11-27 10:52:42.000000000 
+0000
-@@ -1163,7 +1163,7 @@
-       uint16_t ipcse, tucse, mss;
-       int err;
- 
--      if(likely(skb_shinfo(skb)->tso_size)) {
-+      if(likely(skb_shinfo(skb)->gso_size)) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (err)
-@@ -1171,7 +1171,7 @@
-               }
- 
-               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
--              mss = skb_shinfo(skb)->tso_size;
-+              mss = skb_shinfo(skb)->gso_size;
-               skb->nh.iph->tot_len = 0;
-               skb->nh.iph->check = 0;
-               skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-Index: tmp-xxx/drivers/net/loopback.c
-===================================================================
---- tmp-xxx.orig/drivers/net/loopback.c        2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/loopback.c     2006-11-27 10:52:42.000000000 +0000
-@@ -74,7 +74,7 @@
-       struct iphdr *iph = skb->nh.iph;
-       struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
-       unsigned int doffset = (iph->ihl + th->doff) * 4;
--      unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
-+      unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
-       unsigned int offset = 0;
-       u32 seq = ntohl(th->seq);
-       u16 id  = ntohs(iph->id);
-@@ -139,7 +139,7 @@
- #endif
- 
- #ifdef LOOPBACK_TSO
--      if (skb_shinfo(skb)->tso_size) {
-+      if (skb_shinfo(skb)->gso_size) {
-               BUG_ON(skb->protocol != htons(ETH_P_IP));
-               BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
- 
-Index: tmp-xxx/drivers/net/mv643xx_eth.c
-===================================================================
---- tmp-xxx.orig/drivers/net/mv643xx_eth.c     2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/mv643xx_eth.c  2006-11-27 10:52:42.000000000 +0000
-@@ -1107,7 +1107,7 @@
- 
- #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
-       if (has_tiny_unaligned_frags(skb)) {
--              if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
-+              if (__skb_linearize(skb)) {
-                       stats->tx_dropped++;
-                       printk(KERN_DEBUG "%s: failed to linearize tiny "
-                                       "unaligned fragment\n", dev->name);
-Index: tmp-xxx/drivers/net/natsemi.c
-===================================================================
---- tmp-xxx.orig/drivers/net/natsemi.c 2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/natsemi.c      2006-11-27 10:52:42.000000000 +0000
-@@ -323,12 +323,12 @@
- The rx process only runs in the interrupt handler. Access from outside
- the interrupt handler is only permitted after disable_irq().
- 
--The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
-+The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
- is set, then access is permitted under spin_lock_irq(&np->lock).
- 
- Thus configuration functions that want to access everything must call
-       disable_irq(dev->irq);
--      spin_lock_bh(dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       spin_lock_irq(&np->lock);
- 
- IV. Notes
-Index: tmp-xxx/drivers/net/r8169.c
-===================================================================
---- tmp-xxx.orig/drivers/net/r8169.c   2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/r8169.c        2006-11-27 10:52:42.000000000 +0000
-@@ -2171,7 +2171,7 @@
- static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device 
*dev)
- {
-       if (dev->features & NETIF_F_TSO) {
--              u32 mss = skb_shinfo(skb)->tso_size;
-+              u32 mss = skb_shinfo(skb)->gso_size;
- 
-               if (mss)
-                       return LargeSend | ((mss & MSSMask) << MSSShift);
-Index: tmp-xxx/drivers/net/s2io.c
-===================================================================
---- tmp-xxx.orig/drivers/net/s2io.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/s2io.c 2006-11-27 10:52:42.000000000 +0000
-@@ -3522,8 +3522,8 @@
-       txdp->Control_1 = 0;
-       txdp->Control_2 = 0;
- #ifdef NETIF_F_TSO
--      mss = skb_shinfo(skb)->tso_size;
--      if (mss) {
-+      mss = skb_shinfo(skb)->gso_size;
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
-               txdp->Control_1 |= TXD_TCP_LSO_EN;
-               txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
-       }
-@@ -3543,10 +3543,10 @@
-       }
- 
-       frg_len = skb->len - skb->data_len;
--      if (skb_shinfo(skb)->ufo_size) {
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
-               int ufo_size;
- 
--              ufo_size = skb_shinfo(skb)->ufo_size;
-+              ufo_size = skb_shinfo(skb)->gso_size;
-               ufo_size &= ~7;
-               txdp->Control_1 |= TXD_UFO_EN;
-               txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
-@@ -3572,7 +3572,7 @@
-       txdp->Host_Control = (unsigned long) skb;
-       txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
- 
--      if (skb_shinfo(skb)->ufo_size)
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-               txdp->Control_1 |= TXD_UFO_EN;
- 
-       frg_cnt = skb_shinfo(skb)->nr_frags;
-@@ -3587,12 +3587,12 @@
-                   (sp->pdev, frag->page, frag->page_offset,
-                    frag->size, PCI_DMA_TODEVICE);
-               txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
--              if (skb_shinfo(skb)->ufo_size)
-+              if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-                       txdp->Control_1 |= TXD_UFO_EN;
-       }
-       txdp->Control_1 |= TXD_GATHER_CODE_LAST;
- 
--      if (skb_shinfo(skb)->ufo_size)
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-               frg_cnt++; /* as Txd0 was used for inband header */
- 
-       tx_fifo = mac_control->tx_FIFO_start[queue];
-@@ -3606,7 +3606,7 @@
-       if (mss)
-               val64 |= TX_FIFO_SPECIAL_FUNC;
- #endif
--      if (skb_shinfo(skb)->ufo_size)
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-               val64 |= TX_FIFO_SPECIAL_FUNC;
-       writeq(val64, &tx_fifo->List_Control);
- 
-Index: tmp-xxx/drivers/net/sky2.c
-===================================================================
---- tmp-xxx.orig/drivers/net/sky2.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/sky2.c 2006-11-27 10:52:42.000000000 +0000
-@@ -1141,7 +1141,7 @@
-       count = sizeof(dma_addr_t) / sizeof(u32);
-       count += skb_shinfo(skb)->nr_frags * count;
- 
--      if (skb_shinfo(skb)->tso_size)
-+      if (skb_shinfo(skb)->gso_size)
-               ++count;
- 
-       if (skb->ip_summed == CHECKSUM_HW)
-@@ -1213,7 +1213,7 @@
-       }
- 
-       /* Check for TCP Segmentation Offload */
--      mss = skb_shinfo(skb)->tso_size;
-+      mss = skb_shinfo(skb)->gso_size;
-       if (mss != 0) {
-               /* just drop the packet if non-linear expansion fails */
-               if (skb_header_cloned(skb) &&
-Index: tmp-xxx/drivers/net/tg3.c
-===================================================================
---- tmp-xxx.orig/drivers/net/tg3.c     2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/tg3.c  2006-11-27 10:52:42.000000000 +0000
-@@ -3664,7 +3664,7 @@
- #if TG3_TSO_SUPPORT != 0
-       mss = 0;
-       if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
--          (mss = skb_shinfo(skb)->tso_size) != 0) {
-+          (mss = skb_shinfo(skb)->gso_size) != 0) {
-               int tcp_opt_len, ip_tcp_len;
- 
-               if (skb_header_cloned(skb) &&
-Index: tmp-xxx/drivers/net/tulip/winbond-840.c
-===================================================================
---- tmp-xxx.orig/drivers/net/tulip/winbond-840.c       2006-11-15 
10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/tulip/winbond-840.c    2006-11-27 10:52:42.000000000 
+0000
-@@ -1605,11 +1605,11 @@
-  * - get_stats:
-  *    spin_lock_irq(np->lock), doesn't touch hw if not present
-  * - hard_start_xmit:
-- *    netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
-+ *    synchronize_irq + netif_tx_disable;
-  * - tx_timeout:
-- *    netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
-+ *    netif_device_detach + netif_tx_disable;
-  * - set_multicast_list
-- *    netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
-+ *    netif_device_detach + netif_tx_disable;
-  * - interrupt handler
-  *    doesn't touch hw if not present, synchronize_irq waits for
-  *    running instances of the interrupt handler.
-@@ -1635,11 +1635,10 @@
-               netif_device_detach(dev);
-               update_csr6(dev, 0);
-               iowrite32(0, ioaddr + IntrEnable);
--              netif_stop_queue(dev);
-               spin_unlock_irq(&np->lock);
- 
--              spin_unlock_wait(&dev->xmit_lock);
-               synchronize_irq(dev->irq);
-+              netif_tx_disable(dev);
-       
-               np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 
0xffff;
- 
-Index: tmp-xxx/drivers/net/typhoon.c
-===================================================================
---- tmp-xxx.orig/drivers/net/typhoon.c 2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/typhoon.c      2006-11-27 10:52:42.000000000 +0000
-@@ -340,7 +340,7 @@
- #endif
- 
- #if defined(NETIF_F_TSO)
--#define skb_tso_size(x)               (skb_shinfo(x)->tso_size)
-+#define skb_tso_size(x)               (skb_shinfo(x)->gso_size)
- #define TSO_NUM_DESCRIPTORS   2
- #define TSO_OFFLOAD_ON                TYPHOON_OFFLOAD_TCP_SEGMENT
- #else
-Index: tmp-xxx/drivers/net/via-velocity.c
-===================================================================
---- tmp-xxx.orig/drivers/net/via-velocity.c    2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/net/via-velocity.c 2006-11-27 10:52:42.000000000 +0000
-@@ -1905,6 +1905,13 @@
- 
-       int pktlen = skb->len;
- 
-+#ifdef VELOCITY_ZERO_COPY_SUPPORT
-+      if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
-+              kfree_skb(skb);
-+              return 0;
-+      }
-+#endif
-+
-       spin_lock_irqsave(&vptr->lock, flags);
- 
-       index = vptr->td_curr[qnum];
-@@ -1920,8 +1927,6 @@
-        */
-       if (pktlen < ETH_ZLEN) {
-               /* Cannot occur until ZC support */
--              if(skb_linearize(skb, GFP_ATOMIC))
--                      return 0; 
-               pktlen = ETH_ZLEN;
-               memcpy(tdinfo->buf, skb->data, skb->len);
-               memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
-@@ -1939,7 +1944,6 @@
-               int nfrags = skb_shinfo(skb)->nr_frags;
-               tdinfo->skb = skb;
-               if (nfrags > 6) {
--                      skb_linearize(skb, GFP_ATOMIC);
-                       memcpy(tdinfo->buf, skb->data, skb->len);
-                       tdinfo->skb_dma[0] = tdinfo->buf_dma;
-                       td_ptr->tdesc0.pktsize = 
-Index: tmp-xxx/drivers/net/wireless/orinoco.c
-===================================================================
---- tmp-xxx.orig/drivers/net/wireless/orinoco.c        2006-11-15 
10:38:39.000000000 +0000
-+++ tmp-xxx/drivers/net/wireless/orinoco.c     2006-11-27 10:52:42.000000000 
+0000
-@@ -1835,7 +1835,9 @@
-       /* Set promiscuity / multicast*/
-       priv->promiscuous = 0;
-       priv->mc_count = 0;
--      __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
-+
-+      /* FIXME: what about netif_tx_lock */
-+      __orinoco_set_multicast_list(dev);
- 
-       return 0;
- }
-Index: tmp-xxx/drivers/s390/net/qeth_eddp.c
-===================================================================
---- tmp-xxx.orig/drivers/s390/net/qeth_eddp.c  2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/s390/net/qeth_eddp.c       2006-11-27 10:52:42.000000000 
+0000
-@@ -421,7 +421,7 @@
-        }
-       tcph = eddp->skb->h.th;
-       while (eddp->skb_offset < eddp->skb->len) {
--              data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
-+              data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
-                              (int)(eddp->skb->len - eddp->skb_offset));
-               /* prepare qdio hdr */
-               if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
-@@ -516,20 +516,20 @@
-       
-       QETH_DBF_TEXT(trace, 5, "eddpcanp");
-       /* can we put multiple skbs in one page? */
--      skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
-+      skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
-       if (skbs_per_page > 1){
--              ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
-+              ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
-                                skbs_per_page + 1;
-               ctx->elements_per_skb = 1;
-       } else {
-               /* no -> how many elements per skb? */
--              ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
-+              ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
-                                    PAGE_SIZE) >> PAGE_SHIFT;
-               ctx->num_pages = ctx->elements_per_skb *
--                               (skb_shinfo(skb)->tso_segs + 1);
-+                               (skb_shinfo(skb)->gso_segs + 1);
-       }
-       ctx->num_elements = ctx->elements_per_skb *
--                          (skb_shinfo(skb)->tso_segs + 1);
-+                          (skb_shinfo(skb)->gso_segs + 1);
- }
- 
- static inline struct qeth_eddp_context *
-Index: tmp-xxx/drivers/s390/net/qeth_main.c
-===================================================================
---- tmp-xxx.orig/drivers/s390/net/qeth_main.c  2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/s390/net/qeth_main.c       2006-11-27 10:52:42.000000000 
+0000
-@@ -4454,7 +4454,7 @@
-       queue = card->qdio.out_qs
-               [qeth_get_priority_queue(card, skb, ipv, cast_type)];
- 
--      if (skb_shinfo(skb)->tso_size)
-+      if (skb_shinfo(skb)->gso_size)
-               large_send = card->options.large_send;
- 
-       /*are we able to do TSO ? If so ,prepare and send it from here */
-@@ -4501,7 +4501,7 @@
-               card->stats.tx_packets++;
-               card->stats.tx_bytes += skb->len;
- #ifdef CONFIG_QETH_PERF_STATS
--              if (skb_shinfo(skb)->tso_size &&
-+              if (skb_shinfo(skb)->gso_size &&
-                  !(large_send == QETH_LARGE_SEND_NO)) {
-                       card->perf_stats.large_send_bytes += skb->len;
-                       card->perf_stats.large_send_cnt++;
-Index: tmp-xxx/drivers/s390/net/qeth_tso.h
-===================================================================
---- tmp-xxx.orig/drivers/s390/net/qeth_tso.h   2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/drivers/s390/net/qeth_tso.h        2006-11-27 10:52:42.000000000 
+0000
-@@ -51,7 +51,7 @@
-       hdr->ext.hdr_version = 1;
-       hdr->ext.hdr_len     = 28;
-       /*insert non-fix values */
--      hdr->ext.mss = skb_shinfo(skb)->tso_size;
-+      hdr->ext.mss = skb_shinfo(skb)->gso_size;
-       hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
-       hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
-                                      sizeof(struct qeth_hdr_tso));
-Index: tmp-xxx/include/linux/ethtool.h
-===================================================================
---- tmp-xxx.orig/include/linux/ethtool.h       2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/include/linux/ethtool.h    2006-11-27 10:52:42.000000000 +0000
-@@ -408,6 +408,8 @@
- #define ETHTOOL_GPERMADDR     0x00000020 /* Get permanent hardware address */
- #define ETHTOOL_GUFO          0x00000021 /* Get UFO enable (ethtool_value) */
- #define ETHTOOL_SUFO          0x00000022 /* Set UFO enable (ethtool_value) */
-+#define ETHTOOL_GGSO          0x00000023 /* Get GSO enable (ethtool_value) */
-+#define ETHTOOL_SGSO          0x00000024 /* Set GSO enable (ethtool_value) */
- 
- /* compatibility with older code */
- #define SPARC_ETH_GSET                ETHTOOL_GSET
-Index: tmp-xxx/include/linux/netdevice.h
-===================================================================
---- tmp-xxx.orig/include/linux/netdevice.h     2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/include/linux/netdevice.h  2006-11-27 10:52:42.000000000 +0000
-@@ -230,7 +230,8 @@
-       __LINK_STATE_SCHED,
-       __LINK_STATE_NOCARRIER,
-       __LINK_STATE_RX_SCHED,
--      __LINK_STATE_LINKWATCH_PENDING
-+      __LINK_STATE_LINKWATCH_PENDING,
-+      __LINK_STATE_QDISC_RUNNING,
- };
- 
- 
-@@ -306,9 +307,17 @@
- #define NETIF_F_HW_VLAN_RX    256     /* Receive VLAN hw acceleration */
- #define NETIF_F_HW_VLAN_FILTER        512     /* Receive filtering on VLAN */
- #define NETIF_F_VLAN_CHALLENGED       1024    /* Device cannot handle VLAN 
packets */
--#define NETIF_F_TSO           2048    /* Can offload TCP/IP segmentation */
-+#define NETIF_F_GSO           2048    /* Enable software GSO. */
- #define NETIF_F_LLTX          4096    /* LockLess TX */
--#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
-+
-+      /* Segmentation offload features */
-+#define NETIF_F_GSO_SHIFT     16
-+#define NETIF_F_TSO           (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
-+#define NETIF_F_UFO           (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
-+#define NETIF_F_GSO_ROBUST    (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
-+
-+#define NETIF_F_GEN_CSUM      (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-+#define NETIF_F_ALL_CSUM      (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
- 
-       struct net_device       *next_sched;
- 
-@@ -394,6 +403,9 @@
-       struct list_head        qdisc_list;
-       unsigned long           tx_queue_len;   /* Max frames per queue allowed 
*/
- 
-+      /* Partially transmitted GSO packet. */
-+      struct sk_buff          *gso_skb;
-+
-       /* ingress path synchronizer */
-       spinlock_t              ingress_lock;
-       struct Qdisc            *qdisc_ingress;
-@@ -402,7 +414,7 @@
-  * One part is mostly used on xmit path (device)
-  */
-       /* hard_start_xmit synchronizer */
--      spinlock_t              xmit_lock ____cacheline_aligned_in_smp;
-+      spinlock_t              _xmit_lock ____cacheline_aligned_in_smp;
-       /* cpu id of processor entered to hard_start_xmit or -1,
-          if nobody entered there.
-        */
-@@ -527,6 +539,8 @@
-                                        struct net_device *,
-                                        struct packet_type *,
-                                        struct net_device *);
-+      struct sk_buff          *(*gso_segment)(struct sk_buff *skb,
-+                                              int features);
-       void                    *af_packet_priv;
-       struct list_head        list;
- };
-@@ -693,7 +707,8 @@
- extern int            dev_set_mtu(struct net_device *, int);
- extern int            dev_set_mac_address(struct net_device *,
-                                           struct sockaddr *);
--extern void           dev_queue_xmit_nit(struct sk_buff *skb, struct 
net_device *dev);
-+extern int            dev_hard_start_xmit(struct sk_buff *skb,
-+                                          struct net_device *dev);
- 
- extern void           dev_init(void);
- 
-@@ -900,11 +915,43 @@
-       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
- }
- 
-+static inline void netif_tx_lock(struct net_device *dev)
-+{
-+      spin_lock(&dev->_xmit_lock);
-+      dev->xmit_lock_owner = smp_processor_id();
-+}
-+
-+static inline void netif_tx_lock_bh(struct net_device *dev)
-+{
-+      spin_lock_bh(&dev->_xmit_lock);
-+      dev->xmit_lock_owner = smp_processor_id();
-+}
-+
-+static inline int netif_tx_trylock(struct net_device *dev)
-+{
-+      int err = spin_trylock(&dev->_xmit_lock);
-+      if (!err)
-+              dev->xmit_lock_owner = smp_processor_id();
-+      return err;
-+}
-+
-+static inline void netif_tx_unlock(struct net_device *dev)
-+{
-+      dev->xmit_lock_owner = -1;
-+      spin_unlock(&dev->_xmit_lock);
-+}
-+
-+static inline void netif_tx_unlock_bh(struct net_device *dev)
-+{
-+      dev->xmit_lock_owner = -1;
-+      spin_unlock_bh(&dev->_xmit_lock);
-+}
-+
- static inline void netif_tx_disable(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       netif_stop_queue(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- 
- /* These functions live elsewhere (drivers/net/net_init.c, but related) */
-@@ -932,6 +979,7 @@
- extern int            weight_p;
- extern int            netdev_set_master(struct net_device *dev, struct 
net_device *master);
- extern int skb_checksum_help(struct sk_buff *skb, int inward);
-+extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
- #ifdef CONFIG_BUG
- extern void netdev_rx_csum_fault(struct net_device *dev);
- #else
-@@ -951,6 +999,18 @@
- 
- extern void linkwatch_run_queue(void);
- 
-+static inline int skb_gso_ok(struct sk_buff *skb, int features)
-+{
-+      int feature = skb_shinfo(skb)->gso_size ?
-+                    skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
-+      return (features & feature) == feature;
-+}
-+
-+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
-+{
-+      return !skb_gso_ok(skb, dev->features);
-+}
-+
- #endif /* __KERNEL__ */
- 
- #endif        /* _LINUX_DEV_H */
-Index: tmp-xxx/include/linux/skbuff.h
-===================================================================
---- tmp-xxx.orig/include/linux/skbuff.h        2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/include/linux/skbuff.h     2006-11-27 10:52:42.000000000 +0000
-@@ -134,9 +134,10 @@
- struct skb_shared_info {
-       atomic_t        dataref;
-       unsigned short  nr_frags;
--      unsigned short  tso_size;
--      unsigned short  tso_segs;
--      unsigned short  ufo_size;
-+      unsigned short  gso_size;
-+      /* Warning: this field is not always filled in (UFO)! */
-+      unsigned short  gso_segs;
-+      unsigned short  gso_type;
-       unsigned int    ip6_frag_id;
-       struct sk_buff  *frag_list;
-       skb_frag_t      frags[MAX_SKB_FRAGS];
-@@ -168,6 +169,14 @@
-       SKB_FCLONE_CLONE,
- };
- 
-+enum {
-+      SKB_GSO_TCPV4 = 1 << 0,
-+      SKB_GSO_UDPV4 = 1 << 1,
-+
-+      /* This indicates the skb is from an untrusted source. */
-+      SKB_GSO_DODGY = 1 << 2,
-+};
-+
- /** 
-  *    struct sk_buff - socket buffer
-  *    @next: Next buffer in list
-@@ -1148,18 +1157,34 @@
-       return 0;
- }
- 
-+static inline int __skb_linearize(struct sk_buff *skb)
-+{
-+      return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
-+}
-+
- /**
-  *    skb_linearize - convert paged skb to linear one
-  *    @skb: buffer to linarize
-- *    @gfp: allocation mode
-  *
-  *    If there is no free memory -ENOMEM is returned, otherwise zero
-  *    is returned and the old skb data released.
-  */
--extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
--static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
-+static inline int skb_linearize(struct sk_buff *skb)
-+{
-+      return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
-+}
-+
-+/**
-+ *    skb_linearize_cow - make sure skb is linear and writable
-+ *    @skb: buffer to process
-+ *
-+ *    If there is no free memory -ENOMEM is returned, otherwise zero
-+ *    is returned and the old skb data released.
-+ */
-+static inline int skb_linearize_cow(struct sk_buff *skb)
- {
--      return __skb_linearize(skb, gfp);
-+      return skb_is_nonlinear(skb) || skb_cloned(skb) ?
-+             __skb_linearize(skb) : 0;
- }
- 
- /**
-@@ -1254,6 +1279,7 @@
-                                struct sk_buff *skb1, const u32 len);
- 
- extern void          skb_release_data(struct sk_buff *skb);
-+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
- 
- static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
-                                      int len, void *buffer)
-Index: tmp-xxx/include/net/pkt_sched.h
-===================================================================
---- tmp-xxx.orig/include/net/pkt_sched.h       2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/include/net/pkt_sched.h    2006-11-27 10:52:42.000000000 +0000
-@@ -218,12 +218,13 @@
-               struct rtattr *tab);
- extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
- 
--extern int qdisc_restart(struct net_device *dev);
-+extern void __qdisc_run(struct net_device *dev);
- 
- static inline void qdisc_run(struct net_device *dev)
- {
--      while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
--              /* NOTHING */;
-+      if (!netif_queue_stopped(dev) &&
-+          !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
-+              __qdisc_run(dev);
- }
- 
- extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
-Index: tmp-xxx/include/net/protocol.h
-===================================================================
---- tmp-xxx.orig/include/net/protocol.h        2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/include/net/protocol.h     2006-11-27 10:52:42.000000000 +0000
-@@ -37,6 +37,8 @@
- struct net_protocol {
-       int                     (*handler)(struct sk_buff *skb);
-       void                    (*err_handler)(struct sk_buff *skb, u32 info);
-+      struct sk_buff         *(*gso_segment)(struct sk_buff *skb,
-+                                             int features);
-       int                     no_policy;
- };
- 
-Index: tmp-xxx/include/net/sock.h
-===================================================================
---- tmp-xxx.orig/include/net/sock.h    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/include/net/sock.h 2006-11-27 10:52:42.000000000 +0000
-@@ -1064,9 +1064,13 @@
- {
-       __sk_dst_set(sk, dst);
-       sk->sk_route_caps = dst->dev->features;
-+      if (sk->sk_route_caps & NETIF_F_GSO)
-+              sk->sk_route_caps |= NETIF_F_TSO;
-       if (sk->sk_route_caps & NETIF_F_TSO) {
-               if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
-                       sk->sk_route_caps &= ~NETIF_F_TSO;
-+              else 
-+                      sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
-       }
- }
- 
-Index: tmp-xxx/include/net/tcp.h
-===================================================================
---- tmp-xxx.orig/include/net/tcp.h     2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/include/net/tcp.h  2006-11-27 10:52:42.000000000 +0000
-@@ -552,13 +552,13 @@
-  */
- static inline int tcp_skb_pcount(const struct sk_buff *skb)
- {
--      return skb_shinfo(skb)->tso_segs;
-+      return skb_shinfo(skb)->gso_segs;
- }
- 
- /* This is valid iff tcp_skb_pcount() > 1. */
- static inline int tcp_skb_mss(const struct sk_buff *skb)
- {
--      return skb_shinfo(skb)->tso_size;
-+      return skb_shinfo(skb)->gso_size;
- }
- 
- static inline void tcp_dec_pcount_approx(__u32 *count,
-@@ -1063,6 +1063,8 @@
- 
- extern int tcp_v4_destroy_sock(struct sock *sk);
- 
-+extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
-+
- #ifdef CONFIG_PROC_FS
- extern int  tcp4_proc_init(void);
- extern void tcp4_proc_exit(void);
-Index: tmp-xxx/net/atm/clip.c
-===================================================================
---- tmp-xxx.orig/net/atm/clip.c        2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/atm/clip.c     2006-11-27 10:52:42.000000000 +0000
-@@ -101,7 +101,7 @@
-               printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
-               return;
-       }
--      spin_lock_bh(&entry->neigh->dev->xmit_lock);    /* block 
clip_start_xmit() */
-+      netif_tx_lock_bh(entry->neigh->dev);    /* block clip_start_xmit() */
-       entry->neigh->used = jiffies;
-       for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
-               if (*walk == clip_vcc) {
-@@ -125,7 +125,7 @@
-       printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
-         "0x%p)\n",entry,clip_vcc);
- out:
--      spin_unlock_bh(&entry->neigh->dev->xmit_lock);
-+      netif_tx_unlock_bh(entry->neigh->dev);
- }
- 
- /* The neighbour entry n->lock is held. */
-Index: tmp-xxx/net/bridge/br_device.c
-===================================================================
---- tmp-xxx.orig/net/bridge/br_device.c        2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/net/bridge/br_device.c     2006-11-27 10:52:42.000000000 +0000
-@@ -146,9 +146,9 @@
-       struct net_bridge *br = netdev_priv(dev);
- 
-       if (data)
--              br->feature_mask |= NETIF_F_IP_CSUM;
-+              br->feature_mask |= NETIF_F_NO_CSUM;
-       else
--              br->feature_mask &= ~NETIF_F_IP_CSUM;
-+              br->feature_mask &= ~NETIF_F_ALL_CSUM;
- 
-       br_features_recompute(br);
-       return 0;
-@@ -185,6 +185,6 @@
-       dev->set_mac_address = br_set_mac_address;
-       dev->priv_flags = IFF_EBRIDGE;
- 
--      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
--              | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
-+      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
-+                      NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
- }
-Index: tmp-xxx/net/bridge/br_forward.c
-===================================================================
---- tmp-xxx.orig/net/bridge/br_forward.c       2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/net/bridge/br_forward.c    2006-11-27 10:52:42.000000000 +0000
-@@ -32,7 +32,7 @@
- int br_dev_queue_push_xmit(struct sk_buff *skb)
- {
-       /* drop mtu oversized packets except tso */
--      if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
-+      if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
-               kfree_skb(skb);
-       else {
- #ifdef CONFIG_BRIDGE_NETFILTER
-Index: tmp-xxx/net/bridge/br_if.c
-===================================================================
---- tmp-xxx.orig/net/bridge/br_if.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/bridge/br_if.c 2006-11-27 10:52:42.000000000 +0000
-@@ -385,17 +385,28 @@
-       struct net_bridge_port *p;
-       unsigned long features, checksum;
- 
--      features = br->feature_mask &~ NETIF_F_IP_CSUM;
--      checksum = br->feature_mask & NETIF_F_IP_CSUM;
-+      checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
-+      features = br->feature_mask & ~NETIF_F_ALL_CSUM;
- 
-       list_for_each_entry(p, &br->port_list, list) {
--              if (!(p->dev->features 
--                    & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
-+              unsigned long feature = p->dev->features;
-+
-+              if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
-+                      checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
-+              if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
-+                      checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
-+              if (!(feature & NETIF_F_IP_CSUM))
-                       checksum = 0;
--              features &= p->dev->features;
-+
-+              if (feature & NETIF_F_GSO)
-+                      feature |= NETIF_F_TSO;
-+              feature |= NETIF_F_GSO;
-+
-+              features &= feature;
-       }
- 
--      br->dev->features = features | checksum | NETIF_F_LLTX;
-+      br->dev->features = features | checksum | NETIF_F_LLTX |
-+                          NETIF_F_GSO_ROBUST;
- }
- 
- /* called with RTNL */
-Index: tmp-xxx/net/bridge/br_netfilter.c
-===================================================================
---- tmp-xxx.orig/net/bridge/br_netfilter.c     2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/net/bridge/br_netfilter.c  2006-11-27 10:52:42.000000000 +0000
-@@ -743,7 +743,7 @@
- {
-       if (skb->protocol == htons(ETH_P_IP) &&
-           skb->len > skb->dev->mtu &&
--          !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-+          !skb_shinfo(skb)->gso_size)
-               return ip_fragment(skb, br_dev_queue_push_xmit);
-       else
-               return br_dev_queue_push_xmit(skb);
-Index: tmp-xxx/net/core/dev.c
-===================================================================
---- tmp-xxx.orig/net/core/dev.c        2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/core/dev.c     2006-11-27 10:57:31.000000000 +0000
-@@ -115,6 +115,7 @@
- #include <net/iw_handler.h>
- #endif        /* CONFIG_NET_RADIO */
- #include <asm/current.h>
-+#include <linux/err.h>
- 
- /*
-  *    The list of packet types we will receive (as opposed to discard)
-@@ -1032,7 +1033,7 @@
-  *    taps currently in use.
-  */
- 
--void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
-+static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
- {
-       struct packet_type *ptype;
- 
-@@ -1106,6 +1107,45 @@
-       return ret;
- }
- 
-+/**
-+ *    skb_gso_segment - Perform segmentation on skb.
-+ *    @skb: buffer to segment
-+ *    @features: features for the output path (see dev->features)
-+ *
-+ *    This function segments the given skb and returns a list of segments.
-+ *
-+ *    It may return NULL if the skb requires no segmentation.  This is
-+ *    only possible when GSO is used for verifying header integrity.
-+ */
-+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
-+      struct packet_type *ptype;
-+      int type = skb->protocol;
-+
-+      BUG_ON(skb_shinfo(skb)->frag_list);
-+      BUG_ON(skb->ip_summed != CHECKSUM_HW);
-+
-+      skb->mac.raw = skb->data;
-+      skb->mac_len = skb->nh.raw - skb->data;
-+      __skb_pull(skb, skb->mac_len);
-+
-+      rcu_read_lock();
-+      list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
-+              if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
-+                      segs = ptype->gso_segment(skb, features);
-+                      break;
-+              }
-+      }
-+      rcu_read_unlock();
-+
-+      __skb_push(skb, skb->data - skb->mac.raw);
-+
-+      return segs;
-+}
-+
-+EXPORT_SYMBOL(skb_gso_segment);
-+
- /* Take action when hardware reception checksum errors are detected. */
- #ifdef CONFIG_BUG
- void netdev_rx_csum_fault(struct net_device *dev)
-@@ -1142,76 +1182,107 @@
- #define illegal_highdma(dev, skb)     (0)
- #endif
- 
--/* Keep head the same: replace data */
--int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
-+struct dev_gso_cb {
-+      void (*destructor)(struct sk_buff *skb);
-+};
-+
-+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
-+
-+static void dev_gso_skb_destructor(struct sk_buff *skb)
- {
--      unsigned int size;
--      u8 *data;
--      long offset;
--      struct skb_shared_info *ninfo;
--      int headerlen = skb->data - skb->head;
--      int expand = (skb->tail + skb->data_len) - skb->end;
--
--      if (skb_shared(skb))
--              BUG();
--
--      if (expand <= 0)
--              expand = 0;
--
--      size = skb->end - skb->head + expand;
--      size = SKB_DATA_ALIGN(size);
--      data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
--      if (!data)
--              return -ENOMEM;
--
--      /* Copy entire thing */
--      if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
--              BUG();
--
--      /* Set up shinfo */
--      ninfo = (struct skb_shared_info*)(data + size);
--      atomic_set(&ninfo->dataref, 1);
--      ninfo->tso_size = skb_shinfo(skb)->tso_size;
--      ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
--      ninfo->ufo_size = skb_shinfo(skb)->ufo_size;
--      ninfo->nr_frags = 0;
--      ninfo->frag_list = NULL;
--
--      /* Offset between the two in bytes */
--      offset = data - skb->head;
--
--      /* Free old data. */
--      skb_release_data(skb);
--
--      skb->head = data;
--      skb->end  = data + size;
--
--      /* Set up new pointers */
--      skb->h.raw   += offset;
--      skb->nh.raw  += offset;
--      skb->mac.raw += offset;
--      skb->tail    += offset;
--      skb->data    += offset;
-+      struct dev_gso_cb *cb;
- 
--      /* We are no longer a clone, even if we were. */
--      skb->cloned    = 0;
-+      do {
-+              struct sk_buff *nskb = skb->next;
- 
--      skb->tail     += skb->data_len;
--      skb->data_len  = 0;
-+              skb->next = nskb->next;
-+              nskb->next = NULL;
-+              kfree_skb(nskb);
-+      } while (skb->next);
-+
-+      cb = DEV_GSO_CB(skb);
-+      if (cb->destructor)
-+              cb->destructor(skb);
-+}
-+
-+/**
-+ *    dev_gso_segment - Perform emulated hardware segmentation on skb.
-+ *    @skb: buffer to segment
-+ *
-+ *    This function segments the given skb and stores the list of segments
-+ *    in skb->next.
-+ */
-+static int dev_gso_segment(struct sk_buff *skb)
-+{
-+      struct net_device *dev = skb->dev;
-+      struct sk_buff *segs;
-+      int features = dev->features & ~(illegal_highdma(dev, skb) ?
-+                                       NETIF_F_SG : 0);
-+
-+      segs = skb_gso_segment(skb, features);
-+
-+      /* Verifying header integrity only. */
-+      if (!segs)
-+              return 0;
-+  
-+      if (unlikely(IS_ERR(segs)))
-+              return PTR_ERR(segs);
-+
-+      skb->next = segs;
-+      DEV_GSO_CB(skb)->destructor = skb->destructor;
-+      skb->destructor = dev_gso_skb_destructor;
-+      return 0;
-+}
-+
-+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      if (likely(!skb->next)) {
-+              if (netdev_nit)
-+                      dev_queue_xmit_nit(skb, dev);
-+
-+              if (netif_needs_gso(dev, skb)) {
-+                      if (unlikely(dev_gso_segment(skb)))
-+                              goto out_kfree_skb;
-+                      if (skb->next)
-+                              goto gso;
-+              }
-+
-+              return dev->hard_start_xmit(skb, dev);
-+      }
-+
-+gso:
-+      do {
-+              struct sk_buff *nskb = skb->next;
-+              int rc;
-+
-+              skb->next = nskb->next;
-+              nskb->next = NULL;
-+              rc = dev->hard_start_xmit(nskb, dev);
-+              if (unlikely(rc)) {
-+                      nskb->next = skb->next;
-+                      skb->next = nskb;
-+                      return rc;
-+              }
-+              if (unlikely(netif_queue_stopped(dev) && skb->next))
-+                      return NETDEV_TX_BUSY;
-+      } while (skb->next);
-+      
-+      skb->destructor = DEV_GSO_CB(skb)->destructor;
-+
-+out_kfree_skb:
-+      kfree_skb(skb);
-       return 0;
- }
- 
- #define HARD_TX_LOCK(dev, cpu) {                      \
-       if ((dev->features & NETIF_F_LLTX) == 0) {      \
--              spin_lock(&dev->xmit_lock);             \
--              dev->xmit_lock_owner = cpu;             \
-+              netif_tx_lock(dev);                     \
-       }                                               \
- }
- 
- #define HARD_TX_UNLOCK(dev) {                         \
-       if ((dev->features & NETIF_F_LLTX) == 0) {      \
--              dev->xmit_lock_owner = -1;              \
--              spin_unlock(&dev->xmit_lock);           \
-+              netif_tx_unlock(dev);                   \
-       }                                               \
- }
- 
-@@ -1247,9 +1318,13 @@
-       struct Qdisc *q;
-       int rc = -ENOMEM;
- 
-+      /* GSO will handle the following emulations directly. */
-+      if (netif_needs_gso(dev, skb))
-+              goto gso;
-+
-       if (skb_shinfo(skb)->frag_list &&
-           !(dev->features & NETIF_F_FRAGLIST) &&
--          __skb_linearize(skb, GFP_ATOMIC))
-+          __skb_linearize(skb))
-               goto out_kfree_skb;
- 
-       /* Fragmented skb is linearized if device does not support SG,
-@@ -1258,25 +1333,26 @@
-        */
-       if (skb_shinfo(skb)->nr_frags &&
-           (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
--          __skb_linearize(skb, GFP_ATOMIC))
-+          __skb_linearize(skb))
-               goto out_kfree_skb;
- 
-       /* If packet is not checksummed and device does not support
-        * checksumming for this protocol, complete checksumming here.
-        */
-       if (skb->ip_summed == CHECKSUM_HW &&
--          (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
-+          (!(dev->features & NETIF_F_GEN_CSUM) &&
-            (!(dev->features & NETIF_F_IP_CSUM) ||
-             skb->protocol != htons(ETH_P_IP))))
-               if (skb_checksum_help(skb, 0))
-                       goto out_kfree_skb;
- 
-+gso:
-       spin_lock_prefetch(&dev->queue_lock);
- 
-       /* Disable soft irqs for various locks below. Also 
-        * stops preemption for RCU. 
-        */
--      local_bh_disable(); 
-+      rcu_read_lock_bh(); 
- 
-       /* Updates of qdisc are serialized by queue_lock. 
-        * The struct Qdisc which is pointed to by qdisc is now a 
-@@ -1310,8 +1386,8 @@
-       /* The device has no queue. Common case for software devices:
-          loopback, all the sorts of tunnels...
- 
--         Really, it is unlikely that xmit_lock protection is necessary here.
--         (f.e. loopback and IP tunnels are clean ignoring statistics
-+         Really, it is unlikely that netif_tx_lock protection is necessary
-+         here.  (f.e. loopback and IP tunnels are clean ignoring statistics
-          counters.)
-          However, it is possible, that they rely on protection
-          made by us here.
-@@ -1327,11 +1403,8 @@
-                       HARD_TX_LOCK(dev, cpu);
- 
-                       if (!netif_queue_stopped(dev)) {
--                              if (netdev_nit)
--                                      dev_queue_xmit_nit(skb, dev);
--
-                               rc = 0;
--                              if (!dev->hard_start_xmit(skb, dev)) {
-+                              if (!dev_hard_start_xmit(skb, dev)) {
-                                       HARD_TX_UNLOCK(dev);
-                                       goto out;
-                               }
-@@ -1350,13 +1423,13 @@
-       }
- 
-       rc = -ENETDOWN;
--      local_bh_enable();
-+      rcu_read_unlock_bh();
- 
- out_kfree_skb:
-       kfree_skb(skb);
-       return rc;
- out:
--      local_bh_enable();
-+      rcu_read_unlock_bh();
-       return rc;
- }
- 
-@@ -2671,7 +2744,7 @@
-       BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
- 
-       spin_lock_init(&dev->queue_lock);
--      spin_lock_init(&dev->xmit_lock);
-+      spin_lock_init(&dev->_xmit_lock);
-       dev->xmit_lock_owner = -1;
- #ifdef CONFIG_NET_CLS_ACT
-       spin_lock_init(&dev->ingress_lock);
-@@ -2715,9 +2788,7 @@
- 
-       /* Fix illegal SG+CSUM combinations. */
-       if ((dev->features & NETIF_F_SG) &&
--          !(dev->features & (NETIF_F_IP_CSUM |
--                             NETIF_F_NO_CSUM |
--                             NETIF_F_HW_CSUM))) {
-+          !(dev->features & NETIF_F_ALL_CSUM)) {
-               printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
-                      dev->name);
-               dev->features &= ~NETIF_F_SG;
-@@ -3269,7 +3340,6 @@
- EXPORT_SYMBOL(__dev_get_by_index);
- EXPORT_SYMBOL(__dev_get_by_name);
- EXPORT_SYMBOL(__dev_remove_pack);
--EXPORT_SYMBOL(__skb_linearize);
- EXPORT_SYMBOL(dev_valid_name);
- EXPORT_SYMBOL(dev_add_pack);
- EXPORT_SYMBOL(dev_alloc_name);
-Index: tmp-xxx/net/core/dev_mcast.c
-===================================================================
---- tmp-xxx.orig/net/core/dev_mcast.c  2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/core/dev_mcast.c       2006-11-27 10:52:42.000000000 +0000
-@@ -62,7 +62,7 @@
-  *    Device mc lists are changed by bh at least if IPv6 is enabled,
-  *    so that it must be bh protected.
-  *
-- *    We block accesses to device mc filters with dev->xmit_lock.
-+ *    We block accesses to device mc filters with netif_tx_lock.
-  */
- 
- /*
-@@ -93,9 +93,9 @@
- 
- void dev_mc_upload(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       __dev_mc_upload(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- 
- /*
-@@ -107,7 +107,7 @@
-       int err = 0;
-       struct dev_mc_list *dmi, **dmip;
- 
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
- 
-       for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
-               /*
-@@ -139,13 +139,13 @@
-                        */
-                       __dev_mc_upload(dev);
-                       
--                      spin_unlock_bh(&dev->xmit_lock);
-+                      netif_tx_unlock_bh(dev);
-                       return 0;
-               }
-       }
-       err = -ENOENT;
- done:
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return err;
- }
- 
-@@ -160,7 +160,7 @@
- 
-       dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
- 
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
-               if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-                   dmi->dmi_addrlen == alen) {
-@@ -176,7 +176,7 @@
-       }
- 
-       if ((dmi = dmi1) == NULL) {
--              spin_unlock_bh(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-               return -ENOMEM;
-       }
-       memcpy(dmi->dmi_addr, addr, alen);
-@@ -189,11 +189,11 @@
- 
-       __dev_mc_upload(dev);
-       
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return 0;
- 
- done:
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       kfree(dmi1);
-       return err;
- }
-@@ -204,7 +204,7 @@
- 
- void dev_mc_discard(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       
-       while (dev->mc_list != NULL) {
-               struct dev_mc_list *tmp = dev->mc_list;
-@@ -215,7 +215,7 @@
-       }
-       dev->mc_count = 0;
- 
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- 
- #ifdef CONFIG_PROC_FS
-@@ -250,7 +250,7 @@
-       struct dev_mc_list *m;
-       struct net_device *dev = v;
- 
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       for (m = dev->mc_list; m; m = m->next) {
-               int i;
- 
-@@ -262,7 +262,7 @@
- 
-               seq_putc(seq, '\n');
-       }
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return 0;
- }
- 
-Index: tmp-xxx/net/core/ethtool.c
-===================================================================
---- tmp-xxx.orig/net/core/ethtool.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/core/ethtool.c 2006-11-27 10:52:42.000000000 +0000
-@@ -30,7 +30,7 @@
- 
- u32 ethtool_op_get_tx_csum(struct net_device *dev)
- {
--      return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0;
-+      return (dev->features & NETIF_F_ALL_CSUM) != 0;
- }
- 
- int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-@@ -551,9 +551,7 @@
-               return -EFAULT;
- 
-       if (edata.data && 
--          !(dev->features & (NETIF_F_IP_CSUM |
--                             NETIF_F_NO_CSUM |
--                             NETIF_F_HW_CSUM)))
-+          !(dev->features & NETIF_F_ALL_CSUM))
-               return -EINVAL;
- 
-       return __ethtool_set_sg(dev, edata.data);
-@@ -561,7 +559,7 @@
- 
- static int ethtool_get_tso(struct net_device *dev, char __user *useraddr)
- {
--      struct ethtool_value edata = { ETHTOOL_GTSO };
-+      struct ethtool_value edata = { ETHTOOL_GUFO };
- 
-       if (!dev->ethtool_ops->get_tso)
-               return -EOPNOTSUPP;
-@@ -616,6 +614,29 @@
-       return dev->ethtool_ops->set_ufo(dev, edata.data);
- }
- 
-+static int ethtool_get_gso(struct net_device *dev, char __user *useraddr)
-+{
-+      struct ethtool_value edata = { ETHTOOL_GGSO };
-+
-+      edata.data = dev->features & NETIF_F_GSO;
-+      if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+               return -EFAULT;
-+      return 0;
-+}
-+
-+static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
-+{
-+      struct ethtool_value edata;
-+
-+      if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+              return -EFAULT;
-+      if (edata.data)
-+              dev->features |= NETIF_F_GSO;
-+      else
-+              dev->features &= ~NETIF_F_GSO;
-+      return 0;
-+}
-+
- static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
- {
-       struct ethtool_test test;
-@@ -907,6 +928,12 @@
-       case ETHTOOL_SUFO:
-               rc = ethtool_set_ufo(dev, useraddr);
-               break;
-+      case ETHTOOL_GGSO:
-+              rc = ethtool_get_gso(dev, useraddr);
-+              break;
-+      case ETHTOOL_SGSO:
-+              rc = ethtool_set_gso(dev, useraddr);
-+              break;
-       default:
-               rc =  -EOPNOTSUPP;
-       }
-Index: tmp-xxx/net/core/netpoll.c
-===================================================================
---- tmp-xxx.orig/net/core/netpoll.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/core/netpoll.c 2006-11-27 10:52:42.000000000 +0000
-@@ -273,24 +273,21 @@
- 
-       do {
-               npinfo->tries--;
--              spin_lock(&np->dev->xmit_lock);
--              np->dev->xmit_lock_owner = smp_processor_id();
-+              netif_tx_lock(np->dev);
- 
-               /*
-                * network drivers do not expect to be called if the queue is
-                * stopped.
-                */
-               if (netif_queue_stopped(np->dev)) {
--                      np->dev->xmit_lock_owner = -1;
--                      spin_unlock(&np->dev->xmit_lock);
-+                      netif_tx_unlock(np->dev);
-                       netpoll_poll(np);
-                       udelay(50);
-                       continue;
-               }
- 
-               status = np->dev->hard_start_xmit(skb, np->dev);
--              np->dev->xmit_lock_owner = -1;
--              spin_unlock(&np->dev->xmit_lock);
-+              netif_tx_unlock(np->dev);
- 
-               /* success */
-               if(!status) {
-Index: tmp-xxx/net/core/pktgen.c
-===================================================================
---- tmp-xxx.orig/net/core/pktgen.c     2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/core/pktgen.c  2006-11-27 10:52:42.000000000 +0000
-@@ -2586,7 +2586,7 @@
-               }
-       }
-       
--      spin_lock_bh(&odev->xmit_lock);
-+      netif_tx_lock_bh(odev);
-       if (!netif_queue_stopped(odev)) {
- 
-               atomic_inc(&(pkt_dev->skb->users));
-@@ -2631,7 +2631,7 @@
-               pkt_dev->next_tx_ns = 0;
-         }
- 
--      spin_unlock_bh(&odev->xmit_lock);
-+      netif_tx_unlock_bh(odev);
-       
-       /* If pkt_dev->count is zero, then run forever */
-       if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
-Index: tmp-xxx/net/core/skbuff.c
-===================================================================
---- tmp-xxx.orig/net/core/skbuff.c     2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/core/skbuff.c  2006-11-27 10:58:31.000000000 +0000
-@@ -164,9 +164,9 @@
-       shinfo = skb_shinfo(skb);
-       atomic_set(&shinfo->dataref, 1);
-       shinfo->nr_frags  = 0;
--      shinfo->tso_size = 0;
--      shinfo->tso_segs = 0;
--      shinfo->ufo_size = 0;
-+      shinfo->gso_size = 0;
-+      shinfo->gso_segs = 0;
-+      shinfo->gso_type = 0;
-       shinfo->ip6_frag_id = 0;
-       shinfo->frag_list = NULL;
- 
-@@ -230,9 +230,9 @@
- 
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags  = 0;
--      skb_shinfo(skb)->tso_size = 0;
--      skb_shinfo(skb)->tso_segs = 0;
--      skb_shinfo(skb)->ufo_size = 0;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 0;
-+      skb_shinfo(skb)->gso_type = 0;
-       skb_shinfo(skb)->frag_list = NULL;
- out:
-       return skb;
-@@ -507,9 +507,9 @@
-       new->tc_index   = old->tc_index;
- #endif
-       atomic_set(&new->users, 1);
--      skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
--      skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
--      skb_shinfo(new)->ufo_size = skb_shinfo(old)->ufo_size;
-+      skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
-+      skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
-+      skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
- }
- 
- /**
-@@ -1822,6 +1822,133 @@
-       return 0;
- }
- 
-+/**
-+ *    skb_segment - Perform protocol segmentation on skb.
-+ *    @skb: buffer to segment
-+ *    @features: features for the output path (see dev->features)
-+ *
-+ *    This function performs segmentation on the given skb.  It returns
-+ *    the segment at the given position.  It returns NULL if there are
-+ *    no more segments to generate, or when an error is encountered.
-+ */
-+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = NULL;
-+      struct sk_buff *tail = NULL;
-+      unsigned int mss = skb_shinfo(skb)->gso_size;
-+      unsigned int doffset = skb->data - skb->mac.raw;
-+      unsigned int offset = doffset;
-+      unsigned int headroom;
-+      unsigned int len;
-+      int sg = features & NETIF_F_SG;
-+      int nfrags = skb_shinfo(skb)->nr_frags;
-+      int err = -ENOMEM;
-+      int i = 0;
-+      int pos;
-+
-+      __skb_push(skb, doffset);
-+      headroom = skb_headroom(skb);
-+      pos = skb_headlen(skb);
-+
-+      do {
-+              struct sk_buff *nskb;
-+              skb_frag_t *frag;
-+              int hsize, nsize;
-+              int k;
-+              int size;
-+
-+              len = skb->len - offset;
-+              if (len > mss)
-+                      len = mss;
-+
-+              hsize = skb_headlen(skb) - offset;
-+              if (hsize < 0)
-+                      hsize = 0;
-+              nsize = hsize + doffset;
-+              if (nsize > len + doffset || !sg)
-+                      nsize = len + doffset;
-+
-+              nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
-+              if (unlikely(!nskb))
-+                      goto err;
-+
-+              if (segs)
-+                      tail->next = nskb;
-+              else
-+                      segs = nskb;
-+              tail = nskb;
-+
-+              nskb->dev = skb->dev;
-+              nskb->priority = skb->priority;
-+              nskb->protocol = skb->protocol;
-+              nskb->dst = dst_clone(skb->dst);
-+              memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-+              nskb->pkt_type = skb->pkt_type;
-+              nskb->mac_len = skb->mac_len;
-+
-+              skb_reserve(nskb, headroom);
-+              nskb->mac.raw = nskb->data;
-+              nskb->nh.raw = nskb->data + skb->mac_len;
-+              nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
-+              memcpy(skb_put(nskb, doffset), skb->data, doffset);
-+
-+              if (!sg) {
-+                      nskb->csum = skb_copy_and_csum_bits(skb, offset,
-+                                                          skb_put(nskb, len),
-+                                                          len, 0);
-+                      continue;
-+              }
-+
-+              frag = skb_shinfo(nskb)->frags;
-+              k = 0;
-+
-+              nskb->ip_summed = CHECKSUM_HW;
-+              nskb->csum = skb->csum;
-+              memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
-+
-+              while (pos < offset + len) {
-+                      BUG_ON(i >= nfrags);
-+
-+                      *frag = skb_shinfo(skb)->frags[i];
-+                      get_page(frag->page);
-+                      size = frag->size;
-+
-+                      if (pos < offset) {
-+                              frag->page_offset += offset - pos;
-+                              frag->size -= offset - pos;
-+                      }
-+
-+                      k++;
-+
-+                      if (pos + size <= offset + len) {
-+                              i++;
-+                              pos += size;
-+                      } else {
-+                              frag->size -= pos + size - (offset + len);
-+                              break;
-+                      }
-+
-+                      frag++;
-+              }
-+
-+              skb_shinfo(nskb)->nr_frags = k;
-+              nskb->data_len = len - hsize;
-+              nskb->len += nskb->data_len;
-+              nskb->truesize += nskb->data_len;
-+      } while ((offset += len) < skb->len);
-+
-+      return segs;
-+
-+err:
-+      while ((skb = segs)) {
-+              segs = skb->next;
-+              kfree(skb);
-+      }
-+      return ERR_PTR(err);
-+}
-+
-+EXPORT_SYMBOL_GPL(skb_segment);
-+
- void __init skb_init(void)
- {
-       skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
-Index: tmp-xxx/net/decnet/dn_nsp_in.c
-===================================================================
---- tmp-xxx.orig/net/decnet/dn_nsp_in.c        2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/net/decnet/dn_nsp_in.c     2006-11-27 10:52:42.000000000 +0000
-@@ -801,8 +801,7 @@
-                * We linearize everything except data segments here.
-                */
-               if (cb->nsp_flags & ~0x60) {
--                      if (unlikely(skb_is_nonlinear(skb)) &&
--                          skb_linearize(skb, GFP_ATOMIC) != 0)
-+                      if (unlikely(skb_linearize(skb)))
-                               goto free_out;
-               }
- 
-Index: tmp-xxx/net/decnet/dn_route.c
-===================================================================
---- tmp-xxx.orig/net/decnet/dn_route.c 2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/decnet/dn_route.c      2006-11-27 10:52:42.000000000 +0000
-@@ -629,8 +629,7 @@
-                       padlen);
- 
-         if (flags & DN_RT_PKT_CNTL) {
--              if (unlikely(skb_is_nonlinear(skb)) &&
--                  skb_linearize(skb, GFP_ATOMIC) != 0)
-+              if (unlikely(skb_linearize(skb)))
-                       goto dump_it;
- 
-                 switch(flags & DN_RT_CNTL_MSK) {
-Index: tmp-xxx/net/ipv4/af_inet.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/af_inet.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv4/af_inet.c 2006-11-27 10:52:42.000000000 +0000
-@@ -68,6 +68,7 @@
-  */
- 
- #include <linux/config.h>
-+#include <linux/err.h>
- #include <linux/errno.h>
- #include <linux/types.h>
- #include <linux/socket.h>
-@@ -1084,6 +1085,54 @@
- 
- EXPORT_SYMBOL(inet_sk_rebuild_header);
- 
-+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = ERR_PTR(-EINVAL);
-+      struct iphdr *iph;
-+      struct net_protocol *ops;
-+      int proto;
-+      int ihl;
-+      int id;
-+
-+      if (!pskb_may_pull(skb, sizeof(*iph)))
-+              goto out;
-+
-+      iph = skb->nh.iph;
-+      ihl = iph->ihl * 4;
-+      if (ihl < sizeof(*iph))
-+              goto out;
-+
-+      if (!pskb_may_pull(skb, ihl))
-+              goto out;
-+
-+      skb->h.raw = __skb_pull(skb, ihl);
-+      iph = skb->nh.iph;
-+      id = ntohs(iph->id);
-+      proto = iph->protocol & (MAX_INET_PROTOS - 1);
-+      segs = ERR_PTR(-EPROTONOSUPPORT);
-+
-+      rcu_read_lock();
-+      ops = rcu_dereference(inet_protos[proto]);
-+      if (ops && ops->gso_segment)
-+              segs = ops->gso_segment(skb, features);
-+      rcu_read_unlock();
-+
-+      if (!segs || unlikely(IS_ERR(segs)))
-+              goto out;
-+
-+      skb = segs;
-+      do {
-+              iph = skb->nh.iph;
-+              iph->id = htons(id++);
-+              iph->tot_len = htons(skb->len - skb->mac_len);
-+              iph->check = 0;
-+              iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
-+      } while ((skb = skb->next));
-+
-+out:
-+      return segs;
-+}
-+
- #ifdef CONFIG_IP_MULTICAST
- static struct net_protocol igmp_protocol = {
-       .handler =      igmp_rcv,
-@@ -1093,6 +1142,7 @@
- static struct net_protocol tcp_protocol = {
-       .handler =      tcp_v4_rcv,
-       .err_handler =  tcp_v4_err,
-+      .gso_segment =  tcp_tso_segment,
-       .no_policy =    1,
- };
- 
-@@ -1138,6 +1188,7 @@
- static struct packet_type ip_packet_type = {
-       .type = __constant_htons(ETH_P_IP),
-       .func = ip_rcv,
-+      .gso_segment = inet_gso_segment,
- };
- 
- static int __init inet_init(void)
-Index: tmp-xxx/net/ipv4/ip_output.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/ip_output.c  2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv4/ip_output.c       2006-11-27 10:52:42.000000000 +0000
-@@ -210,8 +210,7 @@
-               return dst_output(skb);
-       }
- #endif
--      if (skb->len > dst_mtu(skb->dst) &&
--          !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-+      if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size)
-               return ip_fragment(skb, ip_finish_output2);
-       else
-               return ip_finish_output2(skb);
-@@ -362,7 +361,7 @@
-       }
- 
-       ip_select_ident_more(iph, &rt->u.dst, sk,
--                           (skb_shinfo(skb)->tso_segs ?: 1) - 1);
-+                           (skb_shinfo(skb)->gso_segs ?: 1) - 1);
- 
-       /* Add an IP checksum. */
-       ip_send_check(iph);
-@@ -743,7 +742,8 @@
-                              (length - transhdrlen));
-       if (!err) {
-               /* specify the length of each IP datagram fragment*/
--              skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
-+              skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
-+              skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
-               __skb_queue_tail(&sk->sk_write_queue, skb);
- 
-               return 0;
-@@ -839,7 +839,7 @@
-        */
-       if (transhdrlen &&
-           length + fragheaderlen <= mtu &&
--          
rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) &&
-+          rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
-           !exthdrlen)
-               csummode = CHECKSUM_HW;
- 
-@@ -1086,14 +1086,16 @@
- 
-       inet->cork.length += size;
-       if ((sk->sk_protocol == IPPROTO_UDP) &&
--          (rt->u.dst.dev->features & NETIF_F_UFO))
--              skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
-+          (rt->u.dst.dev->features & NETIF_F_UFO)) {
-+              skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
-+              skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
-+      }
- 
- 
-       while (size > 0) {
-               int i;
- 
--              if (skb_shinfo(skb)->ufo_size)
-+              if (skb_shinfo(skb)->gso_size)
-                       len = size;
-               else {
- 
-Index: tmp-xxx/net/ipv4/ipcomp.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/ipcomp.c     2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv4/ipcomp.c  2006-11-27 10:52:42.000000000 +0000
-@@ -84,7 +84,7 @@
-                         struct xfrm_decap_state *decap, struct sk_buff *skb)
- {
-       u8 nexthdr;
--      int err = 0;
-+      int err = -ENOMEM;
-       struct iphdr *iph;
-       union {
-               struct iphdr    iph;
-@@ -92,11 +92,8 @@
-       } tmp_iph;
- 
- 
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--          skb_linearize(skb, GFP_ATOMIC) != 0) {
--              err = -ENOMEM;
-+      if (skb_linearize_cow(skb))
-               goto out;
--      }
- 
-       skb->ip_summed = CHECKSUM_NONE;
- 
-@@ -171,10 +168,8 @@
-               goto out_ok;
-       }
- 
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--          skb_linearize(skb, GFP_ATOMIC) != 0) {
-+      if (skb_linearize_cow(skb))
-               goto out_ok;
--      }
-       
-       err = ipcomp_compress(x, skb);
-       iph = skb->nh.iph;
-Index: tmp-xxx/net/ipv4/tcp.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/tcp.c        2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv4/tcp.c     2006-11-27 10:52:42.000000000 +0000
-@@ -257,6 +257,7 @@
- #include <linux/fs.h>
- #include <linux/random.h>
- #include <linux/bootmem.h>
-+#include <linux/err.h>
- 
- #include <net/icmp.h>
- #include <net/tcp.h>
-@@ -570,7 +571,7 @@
-               skb->ip_summed = CHECKSUM_HW;
-               tp->write_seq += copy;
-               TCP_SKB_CB(skb)->end_seq += copy;
--              skb_shinfo(skb)->tso_segs = 0;
-+              skb_shinfo(skb)->gso_segs = 0;
- 
-               if (!copied)
-                       TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
-@@ -621,14 +622,10 @@
-       ssize_t res;
-       struct sock *sk = sock->sk;
- 
--#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | 
NETIF_F_HW_CSUM)
--
-       if (!(sk->sk_route_caps & NETIF_F_SG) ||
--          !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS))
-+          !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
-               return sock_no_sendpage(sock, page, offset, size, flags);
- 
--#undef TCP_ZC_CSUM_FLAGS
--
-       lock_sock(sk);
-       TCP_CHECK_TIMER(sk);
-       res = do_tcp_sendpages(sk, &page, offset, size, flags);
-@@ -725,9 +722,7 @@
-                               /*
-                                * Check whether we can use HW checksum.
-                                */
--                              if (sk->sk_route_caps &
--                                  (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM |
--                                   NETIF_F_HW_CSUM))
-+                              if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
-                                       skb->ip_summed = CHECKSUM_HW;
- 
-                               skb_entail(sk, tp, skb);
-@@ -823,7 +818,7 @@
- 
-                       tp->write_seq += copy;
-                       TCP_SKB_CB(skb)->end_seq += copy;
--                      skb_shinfo(skb)->tso_segs = 0;
-+                      skb_shinfo(skb)->gso_segs = 0;
- 
-                       from += copy;
-                       copied += copy;
-@@ -2026,6 +2021,71 @@
- }
- 
- 
-+struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = ERR_PTR(-EINVAL);
-+      struct tcphdr *th;
-+      unsigned thlen;
-+      unsigned int seq;
-+      unsigned int delta;
-+      unsigned int oldlen;
-+      unsigned int len;
-+
-+      if (!pskb_may_pull(skb, sizeof(*th)))
-+              goto out;
-+
-+      th = skb->h.th;
-+      thlen = th->doff * 4;
-+      if (thlen < sizeof(*th))
-+              goto out;
-+
-+      if (!pskb_may_pull(skb, thlen))
-+              goto out;
-+
-+      segs = NULL;
-+      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
-+              goto out;
-+
-+      oldlen = (u16)~skb->len;
-+      __skb_pull(skb, thlen);
-+
-+      segs = skb_segment(skb, features);
-+      if (IS_ERR(segs))
-+              goto out;
-+
-+      len = skb_shinfo(skb)->gso_size;
-+      delta = htonl(oldlen + (thlen + len));
-+
-+      skb = segs;
-+      th = skb->h.th;
-+      seq = ntohl(th->seq);
-+
-+      do {
-+              th->fin = th->psh = 0;
-+
-+              th->check = ~csum_fold(th->check + delta);
-+              if (skb->ip_summed != CHECKSUM_HW)
-+                      th->check = csum_fold(csum_partial(skb->h.raw, thlen,
-+                                                         skb->csum));
-+
-+              seq += len;
-+              skb = skb->next;
-+              th = skb->h.th;
-+
-+              th->seq = htonl(seq);
-+              th->cwr = 0;
-+      } while (skb->next);
-+
-+      delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
-+      th->check = ~csum_fold(th->check + delta);
-+      if (skb->ip_summed != CHECKSUM_HW)
-+              th->check = csum_fold(csum_partial(skb->h.raw, thlen,
-+                                                 skb->csum));
-+
-+out:
-+      return segs;
-+}
-+
- extern void __skb_cb_too_small_for_tcp(int, int);
- extern struct tcp_congestion_ops tcp_reno;
- 
-Index: tmp-xxx/net/ipv4/tcp_input.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/tcp_input.c  2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv4/tcp_input.c       2006-11-27 10:52:42.000000000 +0000
-@@ -1072,7 +1072,7 @@
-                               else
-                                       pkt_len = (end_seq -
-                                                  TCP_SKB_CB(skb)->seq);
--                              if (tcp_fragment(sk, skb, pkt_len, 
skb_shinfo(skb)->tso_size))
-+                              if (tcp_fragment(sk, skb, pkt_len, 
skb_shinfo(skb)->gso_size))
-                                       break;
-                               pcount = tcp_skb_pcount(skb);
-                       }
-Index: tmp-xxx/net/ipv4/tcp_output.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/tcp_output.c 2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv4/tcp_output.c      2006-11-27 10:52:42.000000000 +0000
-@@ -497,15 +497,17 @@
-               /* Avoid the costly divide in the normal
-                * non-TSO case.
-                */
--              skb_shinfo(skb)->tso_segs = 1;
--              skb_shinfo(skb)->tso_size = 0;
-+              skb_shinfo(skb)->gso_segs = 1;
-+              skb_shinfo(skb)->gso_size = 0;
-+              skb_shinfo(skb)->gso_type = 0;
-       } else {
-               unsigned int factor;
- 
-               factor = skb->len + (mss_now - 1);
-               factor /= mss_now;
--              skb_shinfo(skb)->tso_segs = factor;
--              skb_shinfo(skb)->tso_size = mss_now;
-+              skb_shinfo(skb)->gso_segs = factor;
-+              skb_shinfo(skb)->gso_size = mss_now;
-+              skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
-       }
- }
- 
-@@ -850,7 +852,7 @@
- 
-       if (!tso_segs ||
-           (tso_segs > 1 &&
--           skb_shinfo(skb)->tso_size != mss_now)) {
-+           tcp_skb_mss(skb) != mss_now)) {
-               tcp_set_skb_tso_segs(sk, skb, mss_now);
-               tso_segs = tcp_skb_pcount(skb);
-       }
-@@ -1510,8 +1512,9 @@
-          tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
-               if (!pskb_trim(skb, 0)) {
-                       TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
--                      skb_shinfo(skb)->tso_segs = 1;
--                      skb_shinfo(skb)->tso_size = 0;
-+                      skb_shinfo(skb)->gso_segs = 1;
-+                      skb_shinfo(skb)->gso_size = 0;
-+                      skb_shinfo(skb)->gso_type = 0;
-                       skb->ip_summed = CHECKSUM_NONE;
-                       skb->csum = 0;
-               }
-@@ -1716,8 +1719,9 @@
-               skb->csum = 0;
-               TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
-               TCP_SKB_CB(skb)->sacked = 0;
--              skb_shinfo(skb)->tso_segs = 1;
--              skb_shinfo(skb)->tso_size = 0;
-+              skb_shinfo(skb)->gso_segs = 1;
-+              skb_shinfo(skb)->gso_size = 0;
-+              skb_shinfo(skb)->gso_type = 0;
- 
-               /* FIN eats a sequence byte, write_seq advanced by 
tcp_queue_skb(). */
-               TCP_SKB_CB(skb)->seq = tp->write_seq;
-@@ -1749,8 +1753,9 @@
-       skb->csum = 0;
-       TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
-       TCP_SKB_CB(skb)->sacked = 0;
--      skb_shinfo(skb)->tso_segs = 1;
--      skb_shinfo(skb)->tso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 1;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_type = 0;
- 
-       /* Send it off. */
-       TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp);
-@@ -1833,8 +1838,9 @@
-       TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
-       TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
-       TCP_SKB_CB(skb)->sacked = 0;
--      skb_shinfo(skb)->tso_segs = 1;
--      skb_shinfo(skb)->tso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 1;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_type = 0;
-       th->seq = htonl(TCP_SKB_CB(skb)->seq);
-       th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
-       if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
-@@ -1937,8 +1943,9 @@
-       TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
-       TCP_ECN_send_syn(sk, tp, buff);
-       TCP_SKB_CB(buff)->sacked = 0;
--      skb_shinfo(buff)->tso_segs = 1;
--      skb_shinfo(buff)->tso_size = 0;
-+      skb_shinfo(buff)->gso_segs = 1;
-+      skb_shinfo(buff)->gso_size = 0;
-+      skb_shinfo(buff)->gso_type = 0;
-       buff->csum = 0;
-       TCP_SKB_CB(buff)->seq = tp->write_seq++;
-       TCP_SKB_CB(buff)->end_seq = tp->write_seq;
-@@ -2042,8 +2049,9 @@
-               buff->csum = 0;
-               TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
-               TCP_SKB_CB(buff)->sacked = 0;
--              skb_shinfo(buff)->tso_segs = 1;
--              skb_shinfo(buff)->tso_size = 0;
-+              skb_shinfo(buff)->gso_segs = 1;
-+              skb_shinfo(buff)->gso_size = 0;
-+              skb_shinfo(buff)->gso_type = 0;
- 
-               /* Send it off, this clears delayed acks for us. */
-               TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = 
tcp_acceptable_seq(sk, tp);
-@@ -2078,8 +2086,9 @@
-       skb->csum = 0;
-       TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
-       TCP_SKB_CB(skb)->sacked = urgent;
--      skb_shinfo(skb)->tso_segs = 1;
--      skb_shinfo(skb)->tso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 1;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_type = 0;
- 
-       /* Use a previous sequence.  This should cause the other
-        * end to send an ack.  Don't queue or clone SKB, just
-Index: tmp-xxx/net/ipv4/xfrm4_output.c
-===================================================================
---- tmp-xxx.orig/net/ipv4/xfrm4_output.c       2006-11-27 10:52:32.000000000 
+0000
-+++ tmp-xxx/net/ipv4/xfrm4_output.c    2006-11-27 10:52:42.000000000 +0000
-@@ -9,6 +9,8 @@
-  */
- 
- #include <linux/compiler.h>
-+#include <linux/if_ether.h>
-+#include <linux/kernel.h>
- #include <linux/skbuff.h>
- #include <linux/spinlock.h>
- #include <linux/netfilter_ipv4.h>
-@@ -158,16 +160,10 @@
-       goto out_exit;
- }
- 
--static int xfrm4_output_finish(struct sk_buff *skb)
-+static int xfrm4_output_finish2(struct sk_buff *skb)
- {
-       int err;
- 
--#ifdef CONFIG_NETFILTER
--      if (!skb->dst->xfrm) {
--              IPCB(skb)->flags |= IPSKB_REROUTED;
--              return dst_output(skb);
--      }
--#endif
-       while (likely((err = xfrm4_output_one(skb)) == 0)) {
-               nf_reset(skb);
- 
-@@ -180,7 +176,7 @@
-                       return dst_output(skb);
- 
-               err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
--                            skb->dst->dev, xfrm4_output_finish);
-+                            skb->dst->dev, xfrm4_output_finish2);
-               if (unlikely(err != 1))
-                       break;
-       }
-@@ -188,6 +184,48 @@
-       return err;
- }
- 
-+static int xfrm4_output_finish(struct sk_buff *skb)
-+{
-+      struct sk_buff *segs;
-+
-+#ifdef CONFIG_NETFILTER
-+      if (!skb->dst->xfrm) {
-+              IPCB(skb)->flags |= IPSKB_REROUTED;
-+              return dst_output(skb);
-+      }
-+#endif
-+
-+      if (!skb_shinfo(skb)->gso_size)
-+              return xfrm4_output_finish2(skb);
-+
-+      skb->protocol = htons(ETH_P_IP);
-+      segs = skb_gso_segment(skb, 0);
-+      kfree_skb(skb);
-+      if (unlikely(IS_ERR(segs)))
-+              return PTR_ERR(segs);
-+
-+      do {
-+              struct sk_buff *nskb = segs->next;
-+              int err;
-+
-+              segs->next = NULL;
-+              err = xfrm4_output_finish2(segs);
-+
-+              if (unlikely(err)) {
-+                      while ((segs = nskb)) {
-+                              nskb = segs->next;
-+                              segs->next = NULL;
-+                              kfree_skb(segs);
-+                      }
-+                      return err;
-+              }
-+
-+              segs = nskb;
-+      } while (segs);
-+
-+      return 0;
-+}
-+
- int xfrm4_output(struct sk_buff *skb)
- {
-       return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, 
skb->dst->dev,
-Index: tmp-xxx/net/ipv6/ip6_output.c
-===================================================================
---- tmp-xxx.orig/net/ipv6/ip6_output.c 2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv6/ip6_output.c      2006-11-27 10:52:42.000000000 +0000
-@@ -147,7 +147,7 @@
- 
- int ip6_output(struct sk_buff *skb)
- {
--      if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
-+      if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) ||
-                               dst_allfrag(skb->dst))
-               return ip6_fragment(skb, ip6_output2);
-       else
-@@ -829,8 +829,9 @@
-               struct frag_hdr fhdr;
- 
-               /* specify the length of each IP datagram fragment*/
--              skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - 
--                                              sizeof(struct frag_hdr);
-+              skb_shinfo(skb)->gso_size = mtu - fragheaderlen - 
-+                                          sizeof(struct frag_hdr);
-+              skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
-               ipv6_select_ident(skb, &fhdr);
-               skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
-               __skb_queue_tail(&sk->sk_write_queue, skb);
-Index: tmp-xxx/net/ipv6/ipcomp6.c
-===================================================================
---- tmp-xxx.orig/net/ipv6/ipcomp6.c    2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/ipv6/ipcomp6.c 2006-11-27 10:52:42.000000000 +0000
-@@ -64,7 +64,7 @@
- 
- static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state 
*decap, struct sk_buff *skb)
- {
--      int err = 0;
-+      int err = -ENOMEM;
-       u8 nexthdr = 0;
-       int hdr_len = skb->h.raw - skb->nh.raw;
-       unsigned char *tmp_hdr = NULL;
-@@ -75,11 +75,8 @@
-       struct crypto_tfm *tfm;
-       int cpu;
- 
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--              skb_linearize(skb, GFP_ATOMIC) != 0) {
--              err = -ENOMEM;
-+      if (skb_linearize_cow(skb))
-               goto out;
--      }
- 
-       skb->ip_summed = CHECKSUM_NONE;
- 
-@@ -158,10 +155,8 @@
-               goto out_ok;
-       }
- 
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--              skb_linearize(skb, GFP_ATOMIC) != 0) {
-+      if (skb_linearize_cow(skb))
-               goto out_ok;
--      }
- 
-       /* compression */
-       plen = skb->len - hdr_len;
-Index: tmp-xxx/net/ipv6/xfrm6_output.c
-===================================================================
---- tmp-xxx.orig/net/ipv6/xfrm6_output.c       2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/net/ipv6/xfrm6_output.c    2006-11-27 10:52:42.000000000 +0000
-@@ -151,7 +151,7 @@
-       goto out_exit;
- }
- 
--static int xfrm6_output_finish(struct sk_buff *skb)
-+static int xfrm6_output_finish2(struct sk_buff *skb)
- {
-       int err;
- 
-@@ -167,7 +167,7 @@
-                       return dst_output(skb);
- 
-               err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
--                            skb->dst->dev, xfrm6_output_finish);
-+                            skb->dst->dev, xfrm6_output_finish2);
-               if (unlikely(err != 1))
-                       break;
-       }
-@@ -175,6 +175,41 @@
-       return err;
- }
- 
-+static int xfrm6_output_finish(struct sk_buff *skb)
-+{
-+      struct sk_buff *segs;
-+
-+      if (!skb_shinfo(skb)->gso_size)
-+              return xfrm6_output_finish2(skb);
-+
-+      skb->protocol = htons(ETH_P_IP);
-+      segs = skb_gso_segment(skb, 0);
-+      kfree_skb(skb);
-+      if (unlikely(IS_ERR(segs)))
-+              return PTR_ERR(segs);
-+
-+      do {
-+              struct sk_buff *nskb = segs->next;
-+              int err;
-+
-+              segs->next = NULL;
-+              err = xfrm6_output_finish2(segs);
-+
-+              if (unlikely(err)) {
-+                      while ((segs = nskb)) {
-+                              nskb = segs->next;
-+                              segs->next = NULL;
-+                              kfree_skb(segs);
-+                      }
-+                      return err;
-+              }
-+
-+              segs = nskb;
-+      } while (segs);
-+
-+      return 0;
-+}
-+
- int xfrm6_output(struct sk_buff *skb)
- {
-       return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
-Index: tmp-xxx/net/sched/sch_generic.c
-===================================================================
---- tmp-xxx.orig/net/sched/sch_generic.c       2006-11-15 10:38:39.000000000 
+0000
-+++ tmp-xxx/net/sched/sch_generic.c    2006-11-27 10:52:42.000000000 +0000
-@@ -72,9 +72,9 @@
-    dev->queue_lock serializes queue accesses for this device
-    AND dev->qdisc pointer itself.
- 
--   dev->xmit_lock serializes accesses to device driver.
-+   netif_tx_lock serializes accesses to device driver.
- 
--   dev->queue_lock and dev->xmit_lock are mutually exclusive,
-+   dev->queue_lock and netif_tx_lock are mutually exclusive,
-    if one is grabbed, another must be free.
-  */
- 
-@@ -90,14 +90,17 @@
-    NOTE: Called under dev->queue_lock with locally disabled BH.
- */
- 
--int qdisc_restart(struct net_device *dev)
-+static inline int qdisc_restart(struct net_device *dev)
- {
-       struct Qdisc *q = dev->qdisc;
-       struct sk_buff *skb;
- 
-       /* Dequeue packet */
--      if ((skb = q->dequeue(q)) != NULL) {
-+      if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
-               unsigned nolock = (dev->features & NETIF_F_LLTX);
-+
-+              dev->gso_skb = NULL;
-+
-               /*
-                * When the driver has LLTX set it does its own locking
-                * in start_xmit. No need to add additional overhead by
-@@ -108,7 +111,7 @@
-                * will be requeued.
-                */
-               if (!nolock) {
--                      if (!spin_trylock(&dev->xmit_lock)) {
-+                      if (!netif_tx_trylock(dev)) {
-                       collision:
-                               /* So, someone grabbed the driver. */
-                               
-@@ -126,8 +129,6 @@
-                               __get_cpu_var(netdev_rx_stat).cpu_collision++;
-                               goto requeue;
-                       }
--                      /* Remember that the driver is grabbed by us. */
--                      dev->xmit_lock_owner = smp_processor_id();
-               }
-               
-               {
-@@ -136,14 +137,11 @@
- 
-                       if (!netif_queue_stopped(dev)) {
-                               int ret;
--                              if (netdev_nit)
--                                      dev_queue_xmit_nit(skb, dev);
- 
--                              ret = dev->hard_start_xmit(skb, dev);
-+                              ret = dev_hard_start_xmit(skb, dev);
-                               if (ret == NETDEV_TX_OK) { 
-                                       if (!nolock) {
--                                              dev->xmit_lock_owner = -1;
--                                              spin_unlock(&dev->xmit_lock);
-+                                              netif_tx_unlock(dev);
-                                       }
-                                       spin_lock(&dev->queue_lock);
-                                       return -1;
-@@ -157,8 +155,7 @@
-                       /* NETDEV_TX_BUSY - we need to requeue */
-                       /* Release the driver */
-                       if (!nolock) { 
--                              dev->xmit_lock_owner = -1;
--                              spin_unlock(&dev->xmit_lock);
-+                              netif_tx_unlock(dev);
-                       } 
-                       spin_lock(&dev->queue_lock);
-                       q = dev->qdisc;
-@@ -175,7 +172,10 @@
-                */
- 
- requeue:
--              q->ops->requeue(skb, q);
-+              if (skb->next)
-+                      dev->gso_skb = skb;
-+              else
-+                      q->ops->requeue(skb, q);
-               netif_schedule(dev);
-               return 1;
-       }
-@@ -183,11 +183,23 @@
-       return q->q.qlen;
- }
- 
-+void __qdisc_run(struct net_device *dev)
-+{
-+      if (unlikely(dev->qdisc == &noop_qdisc))
-+              goto out;
-+
-+      while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
-+              /* NOTHING */;
-+
-+out:
-+      clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
-+}
-+
- static void dev_watchdog(unsigned long arg)
- {
-       struct net_device *dev = (struct net_device *)arg;
- 
--      spin_lock(&dev->xmit_lock);
-+      netif_tx_lock(dev);
-       if (dev->qdisc != &noop_qdisc) {
-               if (netif_device_present(dev) &&
-                   netif_running(dev) &&
-@@ -201,7 +213,7 @@
-                               dev_hold(dev);
-               }
-       }
--      spin_unlock(&dev->xmit_lock);
-+      netif_tx_unlock(dev);
- 
-       dev_put(dev);
- }
-@@ -225,17 +237,17 @@
- 
- static void dev_watchdog_up(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       __netdev_watchdog_up(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- 
- static void dev_watchdog_down(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       if (del_timer(&dev->watchdog_timer))
-               __dev_put(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- 
- void netif_carrier_on(struct net_device *dev)
-@@ -577,10 +589,17 @@
- 
-       dev_watchdog_down(dev);
- 
--      while (test_bit(__LINK_STATE_SCHED, &dev->state))
-+      /* Wait for outstanding dev_queue_xmit calls. */
-+      synchronize_rcu();
-+
-+      /* Wait for outstanding qdisc_run calls. */
-+      while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
-               yield();
- 
--      spin_unlock_wait(&dev->xmit_lock);
-+      if (dev->gso_skb) {
-+              kfree_skb(dev->gso_skb);
-+              dev->gso_skb = NULL;
-+      }
- }
- 
- void dev_init_scheduler(struct net_device *dev)
-@@ -622,6 +641,5 @@
- EXPORT_SYMBOL(qdisc_alloc);
- EXPORT_SYMBOL(qdisc_destroy);
- EXPORT_SYMBOL(qdisc_reset);
--EXPORT_SYMBOL(qdisc_restart);
- EXPORT_SYMBOL(qdisc_lock_tree);
- EXPORT_SYMBOL(qdisc_unlock_tree);
-Index: tmp-xxx/net/sched/sch_teql.c
-===================================================================
---- tmp-xxx.orig/net/sched/sch_teql.c  2006-11-15 10:38:39.000000000 +0000
-+++ tmp-xxx/net/sched/sch_teql.c       2006-11-27 10:52:42.000000000 +0000
-@@ -302,20 +302,17 @@
- 
-               switch (teql_resolve(skb, skb_res, slave)) {
-               case 0:
--                      if (spin_trylock(&slave->xmit_lock)) {
--                              slave->xmit_lock_owner = smp_processor_id();
-+                      if (netif_tx_trylock(slave)) {
-                               if (!netif_queue_stopped(slave) &&
-                                   slave->hard_start_xmit(skb, slave) == 0) {
--                                      slave->xmit_lock_owner = -1;
--                                      spin_unlock(&slave->xmit_lock);
-+                                      netif_tx_unlock(slave);
-                                       master->slaves = NEXT_SLAVE(q);
-                                       netif_wake_queue(dev);
-                                       master->stats.tx_packets++;
-                                       master->stats.tx_bytes += len;
-                                       return 0;
-                               }
--                              slave->xmit_lock_owner = -1;
--                              spin_unlock(&slave->xmit_lock);
-+                              netif_tx_unlock(slave);
-                       }
-                       if (netif_queue_stopped(dev))
-                               busy = 1;
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-1-check-dodgy.patch
--- a/patches/linux-2.6.16.33/net-gso-1-check-dodgy.patch       Tue Jan 23 
19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp.c ./net/ipv4/tcp.c
---- ../orig-linux-2.6.16.29/net/ipv4/tcp.c     2006-09-19 13:59:20.000000000 
+0100
-+++ ./net/ipv4/tcp.c   2006-09-19 13:59:42.000000000 +0100
-@@ -2042,13 +2042,19 @@ struct sk_buff *tcp_tso_segment(struct s
-       if (!pskb_may_pull(skb, thlen))
-               goto out;
- 
--      segs = NULL;
--      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
--              goto out;
--
-       oldlen = (u16)~skb->len;
-       __skb_pull(skb, thlen);
- 
-+      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
-+              /* Packet is from an untrusted source, reset gso_segs. */
-+              int mss = skb_shinfo(skb)->gso_size;
-+
-+              skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
-+
-+              segs = NULL;
-+              goto out;
-+      }
-+
-       segs = skb_segment(skb, features);
-       if (IS_ERR(segs))
-               goto out;
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-2-checksum-fix.patch
--- a/patches/linux-2.6.16.33/net-gso-2-checksum-fix.patch      Tue Jan 23 
19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/bnx2.c ./drivers/net/bnx2.c
---- ../orig-linux-2.6.16.29/drivers/net/bnx2.c 2006-09-19 13:59:20.000000000 
+0100
-+++ ./drivers/net/bnx2.c       2006-09-19 13:59:46.000000000 +0100
-@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp)
-               skb = tx_buf->skb;
- #ifdef BCM_TSO 
-               /* partial BD completions possible with TSO packets */
--              if (skb_shinfo(skb)->gso_size) {
-+              if (skb_is_gso(skb)) {
-                       u16 last_idx, last_ring_idx;
- 
-                       last_idx = sw_cons +
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/chelsio/sge.c 
./drivers/net/chelsio/sge.c
---- ../orig-linux-2.6.16.29/drivers/net/chelsio/sge.c  2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/net/chelsio/sge.c        2006-09-19 13:59:46.000000000 +0100
-@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s
-       struct cpl_tx_pkt *cpl;
- 
- #ifdef NETIF_F_TSO
--      if (skb_shinfo(skb)->gso_size) {
-+      if (skb_is_gso(skb)) {
-               int eth_type;
-               struct cpl_tx_pkt_lso *hdr;
- 
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/e1000/e1000_main.c 
./drivers/net/e1000/e1000_main.c
---- ../orig-linux-2.6.16.29/drivers/net/e1000/e1000_main.c     2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/net/e1000/e1000_main.c   2006-09-19 13:59:46.000000000 +0100
-@@ -2526,7 +2526,7 @@ e1000_tso(struct e1000_adapter *adapter,
-       uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
-       int err;
- 
--      if (skb_shinfo(skb)->gso_size) {
-+      if (skb_is_gso(skb)) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (err)
-@@ -2651,7 +2651,7 @@ e1000_tx_map(struct e1000_adapter *adapt
-                * tso gets written back prematurely before the data is fully
-                * DMAd to the controller */
-               if (!skb->data_len && tx_ring->last_tx_tso &&
--                              !skb_shinfo(skb)->gso_size) {
-+                  !skb_is_gso(skb)) {
-                       tx_ring->last_tx_tso = 0;
-                       size -= 4;
-               }
-@@ -2934,8 +2934,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
- 
- #ifdef NETIF_F_TSO
-       /* Controller Erratum workaround */
--      if (!skb->data_len && tx_ring->last_tx_tso &&
--              !skb_shinfo(skb)->gso_size)
-+      if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
-               count++;
- #endif
- 
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/forcedeth.c 
./drivers/net/forcedeth.c
---- ../orig-linux-2.6.16.29/drivers/net/forcedeth.c    2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/net/forcedeth.c  2006-09-19 13:59:46.000000000 +0100
-@@ -1105,7 +1105,7 @@ static int nv_start_xmit(struct sk_buff 
-       np->tx_skbuff[nr] = skb;
- 
- #ifdef NETIF_F_TSO
--      if (skb_shinfo(skb)->gso_size)
-+      if (skb_is_gso(skb))
-               tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << 
NV_TX2_TSO_SHIFT);
-       else
- #endif
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/ixgb/ixgb_main.c 
./drivers/net/ixgb/ixgb_main.c
---- ../orig-linux-2.6.16.29/drivers/net/ixgb/ixgb_main.c       2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/net/ixgb/ixgb_main.c     2006-09-19 13:59:46.000000000 +0100
-@@ -1163,7 +1163,7 @@ ixgb_tso(struct ixgb_adapter *adapter, s
-       uint16_t ipcse, tucse, mss;
-       int err;
- 
--      if(likely(skb_shinfo(skb)->gso_size)) {
-+      if (likely(skb_is_gso(skb))) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (err)
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/loopback.c 
./drivers/net/loopback.c
---- ../orig-linux-2.6.16.29/drivers/net/loopback.c     2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/net/loopback.c   2006-09-19 13:59:46.000000000 +0100
-@@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff 
- #endif
- 
- #ifdef LOOPBACK_TSO
--      if (skb_shinfo(skb)->gso_size) {
-+      if (skb_is_gso(skb)) {
-               BUG_ON(skb->protocol != htons(ETH_P_IP));
-               BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
- 
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/sky2.c ./drivers/net/sky2.c
---- ../orig-linux-2.6.16.29/drivers/net/sky2.c 2006-09-19 13:59:20.000000000 
+0100
-+++ ./drivers/net/sky2.c       2006-09-19 13:59:46.000000000 +0100
-@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s
-       count = sizeof(dma_addr_t) / sizeof(u32);
-       count += skb_shinfo(skb)->nr_frags * count;
- 
--      if (skb_shinfo(skb)->gso_size)
-+      if (skb_is_gso(skb))
-               ++count;
- 
-       if (skb->ip_summed == CHECKSUM_HW)
-diff -pruN ../orig-linux-2.6.16.29/drivers/net/typhoon.c 
./drivers/net/typhoon.c
---- ../orig-linux-2.6.16.29/drivers/net/typhoon.c      2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/net/typhoon.c    2006-09-19 13:59:46.000000000 +0100
-@@ -805,7 +805,7 @@ typhoon_start_tx(struct sk_buff *skb, st
-        * If problems develop with TSO, check this first.
-        */
-       numDesc = skb_shinfo(skb)->nr_frags + 1;
--      if(skb_tso_size(skb))
-+      if (skb_is_gso(skb))
-               numDesc++;
- 
-       /* When checking for free space in the ring, we need to also
-@@ -845,7 +845,7 @@ typhoon_start_tx(struct sk_buff *skb, st
-                               TYPHOON_TX_PF_VLAN_TAG_SHIFT);
-       }
- 
--      if(skb_tso_size(skb)) {
-+      if (skb_is_gso(skb)) {
-               first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT;
-               first_txd->numDesc++;
- 
-diff -pruN ../orig-linux-2.6.16.29/drivers/s390/net/qeth_main.c 
./drivers/s390/net/qeth_main.c
---- ../orig-linux-2.6.16.29/drivers/s390/net/qeth_main.c       2006-09-19 
13:59:20.000000000 +0100
-+++ ./drivers/s390/net/qeth_main.c     2006-09-19 13:59:46.000000000 +0100
-@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card,
-       queue = card->qdio.out_qs
-               [qeth_get_priority_queue(card, skb, ipv, cast_type)];
- 
--      if (skb_shinfo(skb)->gso_size)
-+      if (skb_is_gso(skb))
-               large_send = card->options.large_send;
- 
-       /*are we able to do TSO ? If so ,prepare and send it from here */
-@@ -4501,8 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
-               card->stats.tx_packets++;
-               card->stats.tx_bytes += skb->len;
- #ifdef CONFIG_QETH_PERF_STATS
--              if (skb_shinfo(skb)->gso_size &&
--                 !(large_send == QETH_LARGE_SEND_NO)) {
-+              if (skb_is_gso(skb) && !(large_send == QETH_LARGE_SEND_NO)) {
-                       card->perf_stats.large_send_bytes += skb->len;
-                       card->perf_stats.large_send_cnt++;
-               }
-diff -pruN ../orig-linux-2.6.16.29/include/linux/netdevice.h 
./include/linux/netdevice.h
---- ../orig-linux-2.6.16.29/include/linux/netdevice.h  2006-09-19 
13:59:20.000000000 +0100
-+++ ./include/linux/netdevice.h        2006-09-19 13:59:46.000000000 +0100
-@@ -541,6 +541,7 @@ struct packet_type {
-                                        struct net_device *);
-       struct sk_buff          *(*gso_segment)(struct sk_buff *skb,
-                                               int features);
-+      int                     (*gso_send_check)(struct sk_buff *skb);
-       void                    *af_packet_priv;
-       struct list_head        list;
- };
-@@ -1001,14 +1002,15 @@ extern void linkwatch_run_queue(void);
- 
- static inline int skb_gso_ok(struct sk_buff *skb, int features)
- {
--      int feature = skb_shinfo(skb)->gso_size ?
--                    skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
-+      int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT;
-       return (features & feature) == feature;
- }
- 
- static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
- {
--      return !skb_gso_ok(skb, dev->features);
-+      return skb_is_gso(skb) &&
-+             (!skb_gso_ok(skb, dev->features) ||
-+              unlikely(skb->ip_summed != CHECKSUM_HW));
- }
- 
- #endif /* __KERNEL__ */
-diff -pruN ../orig-linux-2.6.16.29/include/linux/skbuff.h 
./include/linux/skbuff.h
---- ../orig-linux-2.6.16.29/include/linux/skbuff.h     2006-09-19 
13:59:20.000000000 +0100
-+++ ./include/linux/skbuff.h   2006-09-19 13:59:46.000000000 +0100
-@@ -1403,5 +1403,10 @@ static inline void nf_bridge_get(struct 
- static inline void nf_reset(struct sk_buff *skb) {}
- #endif /* CONFIG_NETFILTER */
- 
-+static inline int skb_is_gso(const struct sk_buff *skb)
-+{
-+      return skb_shinfo(skb)->gso_size;
-+}
-+
- #endif        /* __KERNEL__ */
- #endif        /* _LINUX_SKBUFF_H */
-diff -pruN ../orig-linux-2.6.16.29/include/net/protocol.h 
./include/net/protocol.h
---- ../orig-linux-2.6.16.29/include/net/protocol.h     2006-09-19 
13:59:20.000000000 +0100
-+++ ./include/net/protocol.h   2006-09-19 13:59:46.000000000 +0100
-@@ -37,6 +37,7 @@
- struct net_protocol {
-       int                     (*handler)(struct sk_buff *skb);
-       void                    (*err_handler)(struct sk_buff *skb, u32 info);
-+      int                     (*gso_send_check)(struct sk_buff *skb);
-       struct sk_buff         *(*gso_segment)(struct sk_buff *skb,
-                                              int features);
-       int                     no_policy;
-diff -pruN ../orig-linux-2.6.16.29/include/net/tcp.h ./include/net/tcp.h
---- ../orig-linux-2.6.16.29/include/net/tcp.h  2006-09-19 13:59:20.000000000 
+0100
-+++ ./include/net/tcp.h        2006-09-19 13:59:46.000000000 +0100
-@@ -1063,6 +1063,7 @@ extern struct request_sock_ops tcp_reque
- 
- extern int tcp_v4_destroy_sock(struct sock *sk);
- 
-+extern int tcp_v4_gso_send_check(struct sk_buff *skb);
- extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
- 
- #ifdef CONFIG_PROC_FS
-diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_forward.c 
./net/bridge/br_forward.c
---- ../orig-linux-2.6.16.29/net/bridge/br_forward.c    2006-09-19 
13:59:20.000000000 +0100
-+++ ./net/bridge/br_forward.c  2006-09-19 13:59:46.000000000 +0100
-@@ -32,7 +32,7 @@ static inline int should_deliver(const s
- int br_dev_queue_push_xmit(struct sk_buff *skb)
- {
-       /* drop mtu oversized packets except tso */
--      if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
-+      if (skb->len > skb->dev->mtu && !skb_is_gso(skb))
-               kfree_skb(skb);
-       else {
- #ifdef CONFIG_BRIDGE_NETFILTER
-diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_netfilter.c 
./net/bridge/br_netfilter.c
---- ../orig-linux-2.6.16.29/net/bridge/br_netfilter.c  2006-09-19 
13:59:20.000000000 +0100
-+++ ./net/bridge/br_netfilter.c        2006-09-19 13:59:46.000000000 +0100
-@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s
- {
-       if (skb->protocol == htons(ETH_P_IP) &&
-           skb->len > skb->dev->mtu &&
--          !skb_shinfo(skb)->gso_size)
-+          !skb_is_gso(skb))
-               return ip_fragment(skb, br_dev_queue_push_xmit);
-       else
-               return br_dev_queue_push_xmit(skb);
-diff -pruN ../orig-linux-2.6.16.29/net/core/dev.c ./net/core/dev.c
---- ../orig-linux-2.6.16.29/net/core/dev.c     2006-09-19 13:59:20.000000000 
+0100
-+++ ./net/core/dev.c   2006-09-19 13:59:46.000000000 +0100
-@@ -1083,9 +1083,17 @@ int skb_checksum_help(struct sk_buff *sk
-       unsigned int csum;
-       int ret = 0, offset = skb->h.raw - skb->data;
- 
--      if (inward) {
--              skb->ip_summed = CHECKSUM_NONE;
--              goto out;
-+      if (inward)
-+              goto out_set_summed;
-+
-+      if (unlikely(skb_shinfo(skb)->gso_size)) {
-+              static int warned;
-+
-+              WARN_ON(!warned);
-+              warned = 1;
-+
-+              /* Let GSO fix up the checksum. */
-+              goto out_set_summed;
-       }
- 
-       if (skb_cloned(skb)) {
-@@ -1102,6 +1110,8 @@ int skb_checksum_help(struct sk_buff *sk
-       BUG_ON(skb->csum + 2 > offset);
- 
-       *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
-+
-+out_set_summed:
-       skb->ip_summed = CHECKSUM_NONE;
- out:  
-       return ret;
-@@ -1122,17 +1132,35 @@ struct sk_buff *skb_gso_segment(struct s
-       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
-       struct packet_type *ptype;
-       int type = skb->protocol;
-+      int err;
- 
-       BUG_ON(skb_shinfo(skb)->frag_list);
--      BUG_ON(skb->ip_summed != CHECKSUM_HW);
- 
-       skb->mac.raw = skb->data;
-       skb->mac_len = skb->nh.raw - skb->data;
-       __skb_pull(skb, skb->mac_len);
- 
-+      if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
-+              static int warned;
-+
-+              WARN_ON(!warned);
-+              warned = 1;
-+
-+              if (skb_header_cloned(skb) &&
-+                  (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
-+                      return ERR_PTR(err);
-+      }
-+
-       rcu_read_lock();
-       list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
-               if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
-+                      if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
-+                              err = ptype->gso_send_check(skb);
-+                              segs = ERR_PTR(err);
-+                              if (err || skb_gso_ok(skb, features))
-+                                      break;
-+                              __skb_push(skb, skb->data - skb->nh.raw);
-+                      }
-                       segs = ptype->gso_segment(skb, features);
-                       break;
-               }
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/af_inet.c ./net/ipv4/af_inet.c
---- ../orig-linux-2.6.16.29/net/ipv4/af_inet.c 2006-09-19 13:59:20.000000000 
+0100
-+++ ./net/ipv4/af_inet.c       2006-09-19 13:59:46.000000000 +0100
-@@ -1085,6 +1085,40 @@ int inet_sk_rebuild_header(struct sock *
- 
- EXPORT_SYMBOL(inet_sk_rebuild_header);
- 
-+static int inet_gso_send_check(struct sk_buff *skb)
-+{
-+      struct iphdr *iph;
-+      struct net_protocol *ops;
-+      int proto;
-+      int ihl;
-+      int err = -EINVAL;
-+
-+      if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
-+              goto out;
-+
-+      iph = skb->nh.iph;
-+      ihl = iph->ihl * 4;
-+      if (ihl < sizeof(*iph))
-+              goto out;
-+
-+      if (unlikely(!pskb_may_pull(skb, ihl)))
-+              goto out;
-+
-+      skb->h.raw = __skb_pull(skb, ihl);
-+      iph = skb->nh.iph;
-+      proto = iph->protocol & (MAX_INET_PROTOS - 1);
-+      err = -EPROTONOSUPPORT;
-+
-+      rcu_read_lock();
-+      ops = rcu_dereference(inet_protos[proto]);
-+      if (likely(ops && ops->gso_send_check))
-+              err = ops->gso_send_check(skb);
-+      rcu_read_unlock();
-+
-+out:
-+      return err;
-+}
-+
- static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
- {
-       struct sk_buff *segs = ERR_PTR(-EINVAL);
-@@ -1142,6 +1176,7 @@ static struct net_protocol igmp_protocol
- static struct net_protocol tcp_protocol = {
-       .handler =      tcp_v4_rcv,
-       .err_handler =  tcp_v4_err,
-+      .gso_send_check = tcp_v4_gso_send_check,
-       .gso_segment =  tcp_tso_segment,
-       .no_policy =    1,
- };
-@@ -1188,6 +1223,7 @@ static int ipv4_proc_init(void);
- static struct packet_type ip_packet_type = {
-       .type = __constant_htons(ETH_P_IP),
-       .func = ip_rcv,
-+      .gso_send_check = inet_gso_send_check,
-       .gso_segment = inet_gso_segment,
- };
- 
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/ip_output.c ./net/ipv4/ip_output.c
---- ../orig-linux-2.6.16.29/net/ipv4/ip_output.c       2006-09-19 
13:59:20.000000000 +0100
-+++ ./net/ipv4/ip_output.c     2006-09-19 13:59:46.000000000 +0100
-@@ -210,7 +210,7 @@ static inline int ip_finish_output(struc
-               return dst_output(skb);
-       }
- #endif
--      if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size)
-+      if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb))
-               return ip_fragment(skb, ip_finish_output2);
-       else
-               return ip_finish_output2(skb);
-@@ -1095,7 +1095,7 @@ ssize_t  ip_append_page(struct sock *sk, 
-       while (size > 0) {
-               int i;
- 
--              if (skb_shinfo(skb)->gso_size)
-+              if (skb_is_gso(skb))
-                       len = size;
-               else {
- 
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp_ipv4.c ./net/ipv4/tcp_ipv4.c
---- ../orig-linux-2.6.16.29/net/ipv4/tcp_ipv4.c        2006-09-12 
19:02:10.000000000 +0100
-+++ ./net/ipv4/tcp_ipv4.c      2006-09-19 13:59:46.000000000 +0100
-@@ -495,6 +495,24 @@ void tcp_v4_send_check(struct sock *sk, 
-       }
- }
- 
-+int tcp_v4_gso_send_check(struct sk_buff *skb)
-+{
-+      struct iphdr *iph;
-+      struct tcphdr *th;
-+
-+      if (!pskb_may_pull(skb, sizeof(*th)))
-+              return -EINVAL;
-+
-+      iph = skb->nh.iph;
-+      th = skb->h.th;
-+
-+      th->check = 0;
-+      th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
-+      skb->csum = offsetof(struct tcphdr, check);
-+      skb->ip_summed = CHECKSUM_HW;
-+      return 0;
-+}
-+
- /*
-  *    This routine will send an RST to the other tcp.
-  *
-diff -pruN ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c 
./net/ipv4/xfrm4_output.c
---- ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c    2006-09-19 
13:59:20.000000000 +0100
-+++ ./net/ipv4/xfrm4_output.c  2006-09-19 13:59:46.000000000 +0100
-@@ -195,7 +195,7 @@ static int xfrm4_output_finish(struct sk
-       }
- #endif
- 
--      if (!skb_shinfo(skb)->gso_size)
-+      if (!skb_is_gso(skb))
-               return xfrm4_output_finish2(skb);
- 
-       skb->protocol = htons(ETH_P_IP);
-diff -pruN ../orig-linux-2.6.16.29/net/ipv6/ip6_output.c 
./net/ipv6/ip6_output.c
---- ../orig-linux-2.6.16.29/net/ipv6/ip6_output.c      2006-09-19 
13:59:20.000000000 +0100
-+++ ./net/ipv6/ip6_output.c    2006-09-19 13:59:46.000000000 +0100
-@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *s
- 
- int ip6_output(struct sk_buff *skb)
- {
--      if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) ||
-+      if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) ||
-                               dst_allfrag(skb->dst))
-               return ip6_fragment(skb, ip6_output2);
-       else
-diff -pruN ../orig-linux-2.6.16.29/net/ipv6/xfrm6_output.c 
./net/ipv6/xfrm6_output.c
---- ../orig-linux-2.6.16.29/net/ipv6/xfrm6_output.c    2006-09-19 
13:59:20.000000000 +0100
-+++ ./net/ipv6/xfrm6_output.c  2006-09-19 13:59:46.000000000 +0100
-@@ -179,7 +179,7 @@ static int xfrm6_output_finish(struct sk
- {
-       struct sk_buff *segs;
- 
--      if (!skb_shinfo(skb)->gso_size)
-+      if (!skb_is_gso(skb))
-               return xfrm6_output_finish2(skb);
- 
-       skb->protocol = htons(ETH_P_IP);
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-3-fix-errorcheck.patch
--- a/patches/linux-2.6.16.33/net-gso-3-fix-errorcheck.patch    Tue Jan 23 
19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/include/linux/netdevice.h 
./include/linux/netdevice.h
---- ../orig-linux-2.6.16.29/include/linux/netdevice.h  2006-09-19 
13:59:46.000000000 +0100
-+++ ./include/linux/netdevice.h        2006-09-19 14:05:28.000000000 +0100
-@@ -930,10 +930,10 @@ static inline void netif_tx_lock_bh(stru
- 
- static inline int netif_tx_trylock(struct net_device *dev)
- {
--      int err = spin_trylock(&dev->_xmit_lock);
--      if (!err)
-+      int ok = spin_trylock(&dev->_xmit_lock);
-+      if (likely(ok))
-               dev->xmit_lock_owner = smp_processor_id();
--      return err;
-+      return ok;
- }
- 
- static inline void netif_tx_unlock(struct net_device *dev)
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-4-kill-warnon.patch
--- a/patches/linux-2.6.16.33/net-gso-4-kill-warnon.patch       Tue Jan 23 
19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/net/core/dev.c ./net/core/dev.c
---- ../orig-linux-2.6.16.29/net/core/dev.c     2006-09-19 13:59:46.000000000 
+0100
-+++ ./net/core/dev.c   2006-09-19 14:05:32.000000000 +0100
-@@ -1087,11 +1087,6 @@ int skb_checksum_help(struct sk_buff *sk
-               goto out_set_summed;
- 
-       if (unlikely(skb_shinfo(skb)->gso_size)) {
--              static int warned;
--
--              WARN_ON(!warned);
--              warned = 1;
--
-               /* Let GSO fix up the checksum. */
-               goto out_set_summed;
-       }
-@@ -1141,11 +1136,6 @@ struct sk_buff *skb_gso_segment(struct s
-       __skb_pull(skb, skb->mac_len);
- 
-       if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
--              static int warned;
--
--              WARN_ON(!warned);
--              warned = 1;
--
-               if (skb_header_cloned(skb) &&
-                   (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
-                       return ERR_PTR(err);
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-5-rcv-mss.patch
--- a/patches/linux-2.6.16.33/net-gso-5-rcv-mss.patch   Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index 104af5d..1fa1536 100644
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -127,7 +127,7 @@ static void tcp_measure_rcv_mss(struct s
-       /* skb->len may jitter because of SACKs, even if peer
-        * sends good full-sized frames.
-        */
--      len = skb->len;
-+      len = skb_shinfo(skb)->gso_size ?: skb->len;
-       if (len >= icsk->icsk_ack.rcv_mss) {
-               icsk->icsk_ack.rcv_mss = len;
-       } else {
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch
--- a/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch       Tue Jan 
23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-diff -Naru a/net/core/skbuff.c b/net/core/skbuff.c
---- a/net/core/skbuff.c        2006-12-14 09:32:04 -08:00
-+++ b/net/core/skbuff.c        2006-12-14 09:32:04 -08:00
-@@ -1946,7 +1946,7 @@
-       do {
-               struct sk_buff *nskb;
-               skb_frag_t *frag;
--              int hsize, nsize;
-+              int hsize;
-               int k;
-               int size;
- 
-@@ -1957,11 +1957,10 @@
-               hsize = skb_headlen(skb) - offset;
-               if (hsize < 0)
-                       hsize = 0;
--              nsize = hsize + doffset;
--              if (nsize > len + doffset || !sg)
--                      nsize = len + doffset;
-+              if (hsize > len || !sg)
-+                      hsize = len;
- 
--              nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
-+              nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
-               if (unlikely(!nskb))
-                       goto err;
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/pci-mmconfig-fix-from-2.6.17.patch
--- a/patches/linux-2.6.16.33/pci-mmconfig-fix-from-2.6.17.patch        Tue Jan 
23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/pci/mmconfig.c 
./arch/i386/pci/mmconfig.c
---- ../orig-linux-2.6.16.29/arch/i386/pci/mmconfig.c   2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/pci/mmconfig.c 2006-09-21 09:35:27.000000000 +0100
-@@ -12,14 +12,22 @@
- #include <linux/pci.h>
- #include <linux/init.h>
- #include <linux/acpi.h>
-+#include <asm/e820.h>
- #include "pci.h"
- 
-+/* aperture is up to 256MB but BIOS may reserve less */
-+#define MMCONFIG_APER_MIN     (2 * 1024*1024)
-+#define MMCONFIG_APER_MAX     (256 * 1024*1024)
-+
-+/* Assume systems with more busses have correct MCFG */
-+#define MAX_CHECK_BUS 16
-+
- #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
- 
- /* The base address of the last MMCONFIG device accessed */
- static u32 mmcfg_last_accessed_device;
- 
--static DECLARE_BITMAP(fallback_slots, 32);
-+static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
- 
- /*
-  * Functions for accessing PCI configuration space with MMCONFIG accesses
-@@ -29,8 +37,8 @@ static u32 get_base_addr(unsigned int se
-       int cfg_num = -1;
-       struct acpi_table_mcfg_config *cfg;
- 
--      if (seg == 0 && bus == 0 &&
--          test_bit(PCI_SLOT(devfn), fallback_slots))
-+      if (seg == 0 && bus < MAX_CHECK_BUS &&
-+          test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots))
-               return 0;
- 
-       while (1) {
-@@ -74,8 +82,10 @@ static int pci_mmcfg_read(unsigned int s
-       unsigned long flags;
-       u32 base;
- 
--      if (!value || (bus > 255) || (devfn > 255) || (reg > 4095))
-+      if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
-+              *value = -1;
-               return -EINVAL;
-+      }
- 
-       base = get_base_addr(seg, bus, devfn);
-       if (!base)
-@@ -146,30 +156,66 @@ static struct pci_raw_ops pci_mmcfg = {
-    Normally this can be expressed in the MCFG by not listing them
-    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
-    Instead try to discover all devices on bus 0 that are unreachable using MM
--   and fallback for them.
--   We only do this for bus 0/seg 0 */
-+   and fallback for them. */
- static __init void unreachable_devices(void)
- {
--      int i;
-+      int i, k;
-       unsigned long flags;
- 
--      for (i = 0; i < 32; i++) {
--              u32 val1;
--              u32 addr;
-+      for (k = 0; k < MAX_CHECK_BUS; k++) {
-+              for (i = 0; i < 32; i++) {
-+                      u32 val1;
-+                      u32 addr;
-+
-+                      pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1);
-+                      if (val1 == 0xffffffff)
-+                              continue;
-+
-+                      /* Locking probably not needed, but safer */
-+                      spin_lock_irqsave(&pci_config_lock, flags);
-+                      addr = get_base_addr(0, k, PCI_DEVFN(i, 0));
-+                      if (addr != 0)
-+                              pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0));
-+                      if (addr == 0 ||
-+                          readl((u32 __iomem *)mmcfg_virt_addr) != val1) {
-+                              set_bit(i, fallback_slots);
-+                              printk(KERN_NOTICE
-+                      "PCI: No mmconfig possible on %x:%x\n", k, i);
-+                      }
-+                      spin_unlock_irqrestore(&pci_config_lock, flags);
-+              }
-+      }
-+}
- 
--              pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1);
--              if (val1 == 0xffffffff)
-+/* NB. Ripped from arch/i386/kernel/setup.c for this Xen bugfix patch. */
-+#ifdef CONFIG_XEN
-+extern struct e820map machine_e820;
-+#define e820 machine_e820
-+#endif
-+static int __init
-+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
-+{
-+      u64 start = s;
-+      u64 end = e;
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i];
-+              if (type && ei->type != type)
-                       continue;
--
--              /* Locking probably not needed, but safer */
--              spin_lock_irqsave(&pci_config_lock, flags);
--              addr = get_base_addr(0, 0, PCI_DEVFN(i, 0));
--              if (addr != 0)
--                      pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0));
--              if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1)
--                      set_bit(i, fallback_slots);
--              spin_unlock_irqrestore(&pci_config_lock, flags);
-+              /* is the region (part) in overlap with the current region ?*/
-+              if (ei->addr >= end || ei->addr + ei->size <= start)
-+                      continue;
-+              /* if the region is at the beginning of <start,end> we move
-+               * start to the end of the region since it's ok until there
-+               */
-+              if (ei->addr <= start)
-+                      start = ei->addr + ei->size;
-+              /* if start is now at or beyond end, we're done, full
-+               * coverage */
-+              if (start >= end)
-+                      return 1; /* we're done */
-       }
-+      return 0;
- }
- 
- static int __init pci_mmcfg_init(void)
-@@ -183,6 +229,15 @@ static int __init pci_mmcfg_init(void)
-           (pci_mmcfg_config[0].base_address == 0))
-               goto out;
- 
-+      if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
-+                      pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
-+                      E820_RESERVED)) {
-+              printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not 
E820-reserved\n",
-+                              pci_mmcfg_config[0].base_address);
-+              printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
-+              goto out;
-+      }
-+
-       printk(KERN_INFO "PCI: Using MMCONFIG\n");
-       raw_pci_ops = &pci_mmcfg;
-       pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
-diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/pci/mmconfig.c 
./arch/x86_64/pci/mmconfig.c
---- ../orig-linux-2.6.16.29/arch/x86_64/pci/mmconfig.c 2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/x86_64/pci/mmconfig.c       2006-09-21 09:35:40.000000000 +0100
-@@ -9,11 +9,19 @@
- #include <linux/init.h>
- #include <linux/acpi.h>
- #include <linux/bitmap.h>
-+#include <asm/e820.h>
-+
- #include "pci.h"
- 
--#define MMCONFIG_APER_SIZE (256*1024*1024)
-+/* aperture is up to 256MB but BIOS may reserve less */
-+#define MMCONFIG_APER_MIN     (2 * 1024*1024)
-+#define MMCONFIG_APER_MAX     (256 * 1024*1024)
-+
-+/* Verify the first 16 busses. We assume that systems with more busses
-+   get MCFG right. */
-+#define MAX_CHECK_BUS 16
- 
--static DECLARE_BITMAP(fallback_slots, 32);
-+static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS);
- 
- /* Static virtual mapping of the MMCONFIG aperture */
- struct mmcfg_virt {
-@@ -55,7 +63,8 @@ static char __iomem *get_virt(unsigned i
- static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, 
unsigned int devfn)
- {
-       char __iomem *addr;
--      if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots))
-+      if (seg == 0 && bus < MAX_CHECK_BUS &&
-+              test_bit(32*bus + PCI_SLOT(devfn), fallback_slots))
-               return NULL;
-       addr = get_virt(seg, bus);
-       if (!addr)
-@@ -69,8 +78,10 @@ static int pci_mmcfg_read(unsigned int s
-       char __iomem *addr;
- 
-       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
--      if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
-+      if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
-+              *value = -1;
-               return -EINVAL;
-+      }
- 
-       addr = pci_dev_base(seg, bus, devfn);
-       if (!addr)
-@@ -129,23 +140,56 @@ static struct pci_raw_ops pci_mmcfg = {
-    Normally this can be expressed in the MCFG by not listing them
-    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
-    Instead try to discover all devices on bus 0 that are unreachable using MM
--   and fallback for them.
--   We only do this for bus 0/seg 0 */
-+   and fallback for them. */
- static __init void unreachable_devices(void)
- {
--      int i;
--      for (i = 0; i < 32; i++) {
--              u32 val1;
--              char __iomem *addr;
-+      int i, k;
-+      /* Use the max bus number from ACPI here? */
-+      for (k = 0; k < MAX_CHECK_BUS; k++) {
-+              for (i = 0; i < 32; i++) {
-+                      u32 val1;
-+                      char __iomem *addr;
-+
-+                      pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
-+                      if (val1 == 0xffffffff)
-+                              continue;
-+                      addr = pci_dev_base(0, k, PCI_DEVFN(i, 0));
-+                      if (addr == NULL|| readl(addr) != val1) {
-+                              set_bit(i + 32*k, fallback_slots);
-+                              printk(KERN_NOTICE
-+                              "PCI: No mmconfig possible on device %x:%x\n",
-+                                      k, i);
-+                      }
-+              }
-+      }
-+}
- 
--              pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
--              if (val1 == 0xffffffff)
-+/* NB. Ripped from arch/x86_64/kernel/e820.c for this Xen bugfix patch. */
-+#ifdef CONFIG_XEN
-+extern struct e820map machine_e820;
-+#define e820 machine_e820
-+#endif
-+static int __init e820_all_mapped(unsigned long start, unsigned long end, 
unsigned type)
-+{
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i];
-+              if (type && ei->type != type)
-                       continue;
--              addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0));
--              if (addr == NULL|| readl(addr) != val1) {
--                      set_bit(i, &fallback_slots);
--              }
-+              /* is the region (part) in overlap with the current region ?*/
-+              if (ei->addr >= end || ei->addr + ei->size <= start)
-+                      continue;
-+
-+              /* if the region is at the beginning of <start,end> we move
-+               * start to the end of the region since it's ok until there
-+               */
-+              if (ei->addr <= start)
-+                      start = ei->addr + ei->size;
-+              /* if start is now at or beyond end, we're done, full coverage 
*/
-+              if (start >= end)
-+                      return 1; /* we're done */
-       }
-+      return 0;
- }
- 
- static int __init pci_mmcfg_init(void)
-@@ -161,6 +205,15 @@ static int __init pci_mmcfg_init(void)
-           (pci_mmcfg_config[0].base_address == 0))
-               return 0;
- 
-+      if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
-+                      pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
-+                      E820_RESERVED)) {
-+              printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not 
E820-reserved\n",
-+                              pci_mmcfg_config[0].base_address);
-+              printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
-+              return 0;
-+      }
-+
-       /* RED-PEN i386 doesn't do _nocache right now */
-       pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * 
pci_mmcfg_config_num, GFP_KERNEL);
-       if (pci_mmcfg_virt == NULL) {
-@@ -169,7 +222,8 @@ static int __init pci_mmcfg_init(void)
-       }
-       for (i = 0; i < pci_mmcfg_config_num; ++i) {
-               pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
--              pci_mmcfg_virt[i].virt = 
ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
-+              pci_mmcfg_virt[i].virt = 
ioremap_nocache(pci_mmcfg_config[i].base_address,
-+                                                       MMCONFIG_APER_MAX);
-               if (!pci_mmcfg_virt[i].virt) {
-                       printk("PCI: Cannot map mmconfig aperture for segment 
%d\n",
-                              pci_mmcfg_config[i].pci_segment_group_number);
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/pmd-shared.patch
--- a/patches/linux-2.6.16.33/pmd-shared.patch  Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/mm/pageattr.c 
./arch/i386/mm/pageattr.c
---- ../orig-linux-2.6.16.29/arch/i386/mm/pageattr.c    2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/mm/pageattr.c  2006-09-19 14:05:35.000000000 +0100
-@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
-       unsigned long flags;
- 
-       set_pte_atomic(kpte, pte);      /* change init_mm */
--      if (PTRS_PER_PMD > 1)
-+      if (HAVE_SHARED_KERNEL_PMD)
-               return;
- 
-       spin_lock_irqsave(&pgd_lock, flags);
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/mm/pgtable.c 
./arch/i386/mm/pgtable.c
---- ../orig-linux-2.6.16.29/arch/i386/mm/pgtable.c     2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/mm/pgtable.c   2006-09-19 14:05:35.000000000 +0100
-@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
-               spin_lock_irqsave(&pgd_lock, flags);
-       }
- 
--      clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
--                      swapper_pg_dir + USER_PTRS_PER_PGD,
--                      KERNEL_PGD_PTRS);
-+      if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
-+              clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-+                              swapper_pg_dir + USER_PTRS_PER_PGD,
-+                              KERNEL_PGD_PTRS);
-       if (PTRS_PER_PMD > 1)
-               return;
- 
-@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
-                       goto out_oom;
-               set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
-       }
-+
-+      if (!HAVE_SHARED_KERNEL_PMD) {
-+              unsigned long flags;
-+
-+              for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+                      pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-+                      if (!pmd)
-+                              goto out_oom;
-+                      set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
-+              }
-+
-+              spin_lock_irqsave(&pgd_lock, flags);
-+              for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+                      unsigned long v = (unsigned long)i << PGDIR_SHIFT;
-+                      pgd_t *kpgd = pgd_offset_k(v);
-+                      pud_t *kpud = pud_offset(kpgd, v);
-+                      pmd_t *kpmd = pmd_offset(kpud, v);
-+                      pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+                      memcpy(pmd, kpmd, PAGE_SIZE);
-+              }
-+              pgd_list_add(pgd);
-+              spin_unlock_irqrestore(&pgd_lock, flags);
-+      }
-+
-       return pgd;
- 
- out_oom:
-@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
-       int i;
- 
-       /* in the PAE case user pgd entries are overwritten before usage */
--      if (PTRS_PER_PMD > 1)
--              for (i = 0; i < USER_PTRS_PER_PGD; ++i)
--                      kmem_cache_free(pmd_cache, (void 
*)__va(pgd_val(pgd[i])-1));
-+      if (PTRS_PER_PMD > 1) {
-+              for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
-+                      pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+                      kmem_cache_free(pmd_cache, pmd);
-+              }
-+              if (!HAVE_SHARED_KERNEL_PMD) {
-+                      unsigned long flags;
-+                      spin_lock_irqsave(&pgd_lock, flags);
-+                      pgd_list_del(pgd);
-+                      spin_unlock_irqrestore(&pgd_lock, flags);
-+                      for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+                              pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+                              memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
-+                              kmem_cache_free(pmd_cache, pmd);
-+                      }
-+              }
-+      }
-       /* in the non-PAE case, free_pgtables() clears user pgd entries */
-       kmem_cache_free(pgd_cache, pgd);
- }
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/pgtable-2level-defs.h 
./include/asm-i386/pgtable-2level-defs.h
---- ../orig-linux-2.6.16.29/include/asm-i386/pgtable-2level-defs.h     
2006-09-12 19:02:10.000000000 +0100
-+++ ./include/asm-i386/pgtable-2level-defs.h   2006-09-19 14:05:35.000000000 
+0100
-@@ -1,6 +1,8 @@
- #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
- #define _I386_PGTABLE_2LEVEL_DEFS_H
- 
-+#define HAVE_SHARED_KERNEL_PMD 0
-+
- /*
-  * traditional i386 two-level paging structure:
-  */
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/pgtable-3level-defs.h 
./include/asm-i386/pgtable-3level-defs.h
---- ../orig-linux-2.6.16.29/include/asm-i386/pgtable-3level-defs.h     
2006-09-12 19:02:10.000000000 +0100
-+++ ./include/asm-i386/pgtable-3level-defs.h   2006-09-19 14:05:35.000000000 
+0100
-@@ -1,6 +1,8 @@
- #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
- #define _I386_PGTABLE_3LEVEL_DEFS_H
- 
-+#define HAVE_SHARED_KERNEL_PMD 1
-+
- /*
-  * PGDIR_SHIFT determines what a top-level page table entry can map
-  */
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/rcu_needs_cpu.patch
--- a/patches/linux-2.6.16.33/rcu_needs_cpu.patch       Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/include/linux/rcupdate.h 
./include/linux/rcupdate.h
---- ../orig-linux-2.6.16.29/include/linux/rcupdate.h   2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/linux/rcupdate.h 2006-09-19 14:05:39.000000000 +0100
-@@ -134,6 +134,7 @@ static inline void rcu_bh_qsctr_inc(int 
- }
- 
- extern int rcu_pending(int cpu);
-+extern int rcu_needs_cpu(int cpu);
- 
- /**
-  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
-diff -pruN ../orig-linux-2.6.16.29/kernel/rcupdate.c ./kernel/rcupdate.c
---- ../orig-linux-2.6.16.29/kernel/rcupdate.c  2006-09-12 19:02:10.000000000 
+0100
-+++ ./kernel/rcupdate.c        2006-09-19 14:05:39.000000000 +0100
-@@ -485,6 +485,20 @@ int rcu_pending(int cpu)
-               __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
- }
- 
-+/*
-+ * Check to see if any future RCU-related work will need to be done
-+ * by the current CPU, even if none need be done immediately, returning
-+ * 1 if so.  This function is part of the RCU implementation; it is -not-
-+ * an exported member of the RCU API.
-+ */
-+int rcu_needs_cpu(int cpu)
-+{
-+      struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
-+      struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu);
-+
-+      return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu));
-+}
-+
- void rcu_check_callbacks(int cpu, int user)
- {
-       if (user || 
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch
--- 
a/patches/linux-2.6.16.33/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch    
    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S 
./arch/i386/kernel/entry.S
---- ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S   2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/kernel/entry.S 2006-09-19 14:05:44.000000000 +0100
-@@ -177,7 +177,7 @@ need_resched:
- 
-       # sysenter call handler stub
- ENTRY(sysenter_entry)
--      movl TSS_sysenter_esp0(%esp),%esp
-+      movl SYSENTER_stack_esp0(%esp),%esp
- sysenter_past_esp:
-       sti
-       pushl $(__USER_DS)
-@@ -492,7 +492,7 @@ device_not_available_emulate:
-  * that sets up the real kernel stack. Check here, since we can't
-  * allow the wrong stack to be used.
-  *
-- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
-+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
-  * already pushed 3 words if it hits on the sysenter instruction:
-  * eflags, cs and eip.
-  *
-@@ -504,7 +504,7 @@ device_not_available_emulate:
-       cmpw $__KERNEL_CS,4(%esp);              \
-       jne ok;                                 \
- label:                                                \
--      movl TSS_sysenter_esp0+offset(%esp),%esp;       \
-+      movl SYSENTER_stack_esp0+offset(%esp),%esp;     \
-       pushfl;                                 \
-       pushl $__KERNEL_CS;                     \
-       pushl $sysenter_past_esp
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/series
--- a/patches/linux-2.6.16.33/series    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
-git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
-git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch
-linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
-git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch
-linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch
-blktap-aio-16_03_06.patch
-device_bind.patch
-fix-hz-suspend.patch
-fix-ide-cd-pio-mode.patch
-i386-mach-io-check-nmi.patch
-ipv6-no-autoconf.patch
-net-csum.patch
-net-gso-0-base.patch
-net-gso-1-check-dodgy.patch
-net-gso-2-checksum-fix.patch
-net-gso-3-fix-errorcheck.patch
-net-gso-4-kill-warnon.patch
-net-gso-5-rcv-mss.patch
-net-gso-6-linear-segmentation.patch
-pci-mmconfig-fix-from-2.6.17.patch
-pmd-shared.patch
-rcu_needs_cpu.patch
-rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch
-smp-alts.patch
-tpm_plugin_2.6.17.patch
-x86-increase-interrupt-vector-range.patch
-xen-hotplug.patch
-xenoprof-generic.patch
-x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
-x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
-git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
-x86-elfnote-as-preprocessor-macro.patch
-vsnprintf.patch
-kasprintf.patch
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/smp-alts.patch
--- a/patches/linux-2.6.16.33/smp-alts.patch    Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,591 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/Kconfig ./arch/i386/Kconfig
---- ../orig-linux-2.6.16.29/arch/i386/Kconfig  2006-09-12 19:02:10.000000000 
+0100
-+++ ./arch/i386/Kconfig        2006-09-19 14:05:48.000000000 +0100
-@@ -202,6 +202,19 @@ config SMP
- 
-         If you don't know what to do here, say N.
- 
-+config SMP_ALTERNATIVES
-+      bool "SMP alternatives support (EXPERIMENTAL)"
-+      depends on SMP && EXPERIMENTAL
-+      help
-+        Try to reduce the overhead of running an SMP kernel on a uniprocessor
-+        host slightly by replacing certain key instruction sequences
-+        according to whether we currently have more than one CPU available.
-+        This should provide a noticeable boost to performance when
-+        running SMP kernels on UP machines, and have negligible impact
-+        when running on an true SMP host.
-+
-+          If unsure, say N.
-+        
- config NR_CPUS
-       int "Maximum number of CPUs (2-255)"
-       range 2 255
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/Makefile 
./arch/i386/kernel/Makefile
---- ../orig-linux-2.6.16.29/arch/i386/kernel/Makefile  2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/kernel/Makefile        2006-09-19 14:05:48.000000000 +0100
-@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI)            += efi.o efi_stub.o
- obj-$(CONFIG_DOUBLEFAULT)     += doublefault.o
- obj-$(CONFIG_VM86)            += vm86.o
- obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
-+obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
- 
- EXTRA_AFLAGS   := -traditional
- 
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/smpalts.c 
./arch/i386/kernel/smpalts.c
---- ../orig-linux-2.6.16.29/arch/i386/kernel/smpalts.c 1970-01-01 
01:00:00.000000000 +0100
-+++ ./arch/i386/kernel/smpalts.c       2006-09-19 14:05:48.000000000 +0100
-@@ -0,0 +1,85 @@
-+#include <linux/kernel.h>
-+#include <asm/system.h>
-+#include <asm/smp_alt.h>
-+#include <asm/processor.h>
-+#include <asm/string.h>
-+
-+struct smp_replacement_record {
-+      unsigned char targ_size;
-+      unsigned char smp1_size;
-+      unsigned char smp2_size;
-+      unsigned char up_size;
-+      unsigned char feature;
-+      unsigned char data[0];
-+};
-+
-+struct smp_alternative_record {
-+      void *targ_start;
-+      struct smp_replacement_record *repl;
-+};
-+
-+extern struct smp_alternative_record __start_smp_alternatives_table,
-+  __stop_smp_alternatives_table;
-+extern unsigned long __init_begin, __init_end;
-+
-+void prepare_for_smp(void)
-+{
-+      struct smp_alternative_record *r;
-+      printk(KERN_INFO "Enabling SMP...\n");
-+      for (r = &__start_smp_alternatives_table;
-+           r != &__stop_smp_alternatives_table;
-+           r++) {
-+              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
-+              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
-+              BUG_ON(r->repl->targ_size < r->repl->up_size);
-+               if (system_state == SYSTEM_RUNNING &&
-+                   r->targ_start >= (void *)&__init_begin &&
-+                   r->targ_start < (void *)&__init_end)
-+                       continue;
-+              if (r->repl->feature != (unsigned char)-1 &&
-+                  boot_cpu_has(r->repl->feature)) {
-+                      memcpy(r->targ_start,
-+                             r->repl->data + r->repl->smp1_size,
-+                             r->repl->smp2_size);
-+                      memset(r->targ_start + r->repl->smp2_size,
-+                             0x90,
-+                             r->repl->targ_size - r->repl->smp2_size);
-+              } else {
-+                      memcpy(r->targ_start,
-+                             r->repl->data,
-+                             r->repl->smp1_size);
-+                      memset(r->targ_start + r->repl->smp1_size,
-+                             0x90,
-+                             r->repl->targ_size - r->repl->smp1_size);
-+              }
-+      }
-+      /* Paranoia */
-+      asm volatile ("jmp 1f\n1:");
-+      mb();
-+}
-+
-+void unprepare_for_smp(void)
-+{
-+      struct smp_alternative_record *r;
-+      printk(KERN_INFO "Disabling SMP...\n");
-+      for (r = &__start_smp_alternatives_table;
-+           r != &__stop_smp_alternatives_table;
-+           r++) {
-+              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
-+              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
-+              BUG_ON(r->repl->targ_size < r->repl->up_size);
-+               if (system_state == SYSTEM_RUNNING &&
-+                   r->targ_start >= (void *)&__init_begin &&
-+                   r->targ_start < (void *)&__init_end)
-+                       continue;
-+              memcpy(r->targ_start,
-+                     r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
-+                     r->repl->up_size);
-+              memset(r->targ_start + r->repl->up_size,
-+                     0x90,
-+                     r->repl->targ_size - r->repl->up_size);
-+      }
-+      /* Paranoia */
-+      asm volatile ("jmp 1f\n1:");
-+      mb();
-+}
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/smpboot.c 
./arch/i386/kernel/smpboot.c
---- ../orig-linux-2.6.16.29/arch/i386/kernel/smpboot.c 2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/kernel/smpboot.c       2006-09-19 14:05:48.000000000 +0100
-@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne
-               if (max_cpus <= cpucount+1)
-                       continue;
- 
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+              if (kicked == 1)
-+                      prepare_for_smp();
-+#endif
-+
-               if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
-                       printk("CPU #%d not responding - cannot use it.\n",
-                                                               apicid);
-@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu)
-               return -EIO;
-       }
- 
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+      if (num_online_cpus() == 1)
-+              prepare_for_smp();
-+#endif
-+
-       local_irq_enable();
-       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
-       /* Unleash the CPU! */
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S 
./arch/i386/kernel/vmlinux.lds.S
---- ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S     2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/kernel/vmlinux.lds.S   2006-09-19 14:05:48.000000000 +0100
-@@ -34,6 +34,13 @@ SECTIONS
-   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
-   __stop___ex_table = .;
- 
-+  . = ALIGN(16);
-+  __start_smp_alternatives_table = .;
-+  __smp_alternatives : { *(__smp_alternatives) }
-+  __stop_smp_alternatives_table = .;
-+
-+  __smp_replacements : { *(__smp_replacements) }
-+
-   RODATA
- 
-   /* writeable */
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/atomic.h 
./include/asm-i386/atomic.h
---- ../orig-linux-2.6.16.29/include/asm-i386/atomic.h  2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-i386/atomic.h        2006-09-19 14:05:48.000000000 +0100
-@@ -4,18 +4,13 @@
- #include <linux/config.h>
- #include <linux/compiler.h>
- #include <asm/processor.h>
-+#include <asm/smp_alt.h>
- 
- /*
-  * Atomic operations that C can't guarantee us.  Useful for
-  * resource counting etc..
-  */
- 
--#ifdef CONFIG_SMP
--#define LOCK "lock ; "
--#else
--#define LOCK ""
--#endif
--
- /*
-  * Make sure gcc doesn't try to be clever and move things around
-  * on us. We need to use _exactly_ the address the user gave us,
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/bitops.h 
./include/asm-i386/bitops.h
---- ../orig-linux-2.6.16.29/include/asm-i386/bitops.h  2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-i386/bitops.h        2006-09-19 14:05:48.000000000 +0100
-@@ -7,6 +7,7 @@
- 
- #include <linux/config.h>
- #include <linux/compiler.h>
-+#include <asm/smp_alt.h>
- 
- /*
-  * These have to be done with inline assembly: that way the bit-setting
-@@ -16,12 +17,6 @@
-  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
-  */
- 
--#ifdef CONFIG_SMP
--#define LOCK_PREFIX "lock ; "
--#else
--#define LOCK_PREFIX ""
--#endif
--
- #define ADDR (*(volatile long *) addr)
- 
- /**
-@@ -41,7 +36,7 @@
-  */
- static inline void set_bit(int nr, volatile unsigned long * addr)
- {
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btsl %1,%0"
-               :"+m" (ADDR)
-               :"Ir" (nr));
-@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
-  */
- static inline void clear_bit(int nr, volatile unsigned long * addr)
- {
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btrl %1,%0"
-               :"+m" (ADDR)
-               :"Ir" (nr));
-@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 
-  */
- static inline void change_bit(int nr, volatile unsigned long * addr)
- {
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btcl %1,%0"
-               :"+m" (ADDR)
-               :"Ir" (nr));
-@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
- {
-       int oldbit;
- 
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btsl %2,%1\n\tsbbl %0,%0"
-               :"=r" (oldbit),"+m" (ADDR)
-               :"Ir" (nr) : "memory");
-@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
- {
-       int oldbit;
- 
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btrl %2,%1\n\tsbbl %0,%0"
-               :"=r" (oldbit),"+m" (ADDR)
-               :"Ir" (nr) : "memory");
-@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
- {
-       int oldbit;
- 
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btcl %2,%1\n\tsbbl %0,%0"
-               :"=r" (oldbit),"+m" (ADDR)
-               :"Ir" (nr) : "memory");
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/futex.h 
./include/asm-i386/futex.h
---- ../orig-linux-2.6.16.29/include/asm-i386/futex.h   2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-i386/futex.h 2006-09-19 14:05:48.000000000 +0100
-@@ -28,7 +28,7 @@
- "1:   movl    %2, %0\n\
-       movl    %0, %3\n"                                       \
-       insn "\n"                                               \
--"2:   " LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2:   " LOCK "cmpxchgl %3, %2\n\
-       jnz     1b\n\
- 3:    .section .fixup,\"ax\"\n\
- 4:    mov     %5, %1\n\
-@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 
- #endif
-               switch (op) {
-               case FUTEX_OP_ADD:
--                      __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
-+                      __futex_atomic_op1(LOCK "xaddl %0, %2", ret,
-                                          oldval, uaddr, oparg);
-                       break;
-               case FUTEX_OP_OR:
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/rwsem.h 
./include/asm-i386/rwsem.h
---- ../orig-linux-2.6.16.29/include/asm-i386/rwsem.h   2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-i386/rwsem.h 2006-09-19 14:05:48.000000000 +0100
-@@ -40,6 +40,7 @@
- 
- #include <linux/list.h>
- #include <linux/spinlock.h>
-+#include <asm/smp_alt.h>
- 
- struct rwsem_waiter;
- 
-@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
- {
-       __asm__ __volatile__(
-               "# beginning down_read\n\t"
--LOCK_PREFIX   "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old 
value */
-+LOCK          "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old 
value */
-               "  js        2f\n\t" /* jump if we weren't granted the lock */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
-               "  movl      %1,%2\n\t"
-               "  addl      %3,%2\n\t"
-               "  jle       2f\n\t"
--LOCK_PREFIX   "  cmpxchgl  %2,%0\n\t"
-+LOCK          "  cmpxchgl  %2,%0\n\t"
-               "  jnz       1b\n\t"
-               "2:\n\t"
-               "# ending __down_read_trylock\n\t"
-@@ -150,7 +151,7 @@ static inline void __down_write(struct r
-       tmp = RWSEM_ACTIVE_WRITE_BIAS;
-       __asm__ __volatile__(
-               "# beginning down_write\n\t"
--LOCK_PREFIX   "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns 
the old value */
-+LOCK          "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns 
the old value */
-               "  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
-               "  jnz       2f\n\t" /* jump if we weren't granted the lock */
-               "1:\n\t"
-@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
-       __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
-       __asm__ __volatile__(
-               "# beginning __up_read\n\t"
--LOCK_PREFIX   "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old 
value */
-+LOCK          "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old 
value */
-               "  js        2f\n\t" /* jump if the lock is being waited upon */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
-       __asm__ __volatile__(
-               "# beginning __up_write\n\t"
-               "  movl      %2,%%edx\n\t"
--LOCK_PREFIX   "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 
0xffff0001 -> 0x00000000 */
-+LOCK          "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 
0xffff0001 -> 0x00000000 */
-               "  jnz       2f\n\t" /* jump if the lock is being waited upon */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
- {
-       __asm__ __volatile__(
-               "# beginning __downgrade_write\n\t"
--LOCK_PREFIX   "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 
0xYYYY0001 */
-+LOCK          "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 
0xYYYY0001 */
-               "  js        2f\n\t" /* jump if the lock is being waited upon */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -263,7 +264,7 @@ LOCK_PREFIX        "  addl      %2,(%%eax)\n\t"
- static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
- {
-       __asm__ __volatile__(
--LOCK_PREFIX   "addl %1,%0"
-+LOCK            "addl %1,%0"
-               : "=m"(sem->count)
-               : "ir"(delta), "m"(sem->count));
- }
-@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
-       int tmp = delta;
- 
-       __asm__ __volatile__(
--LOCK_PREFIX   "xadd %0,(%2)"
-+LOCK                    "xadd %0,(%2)"
-               : "+r"(tmp), "=m"(sem->count)
-               : "r"(sem), "m"(sem->count)
-               : "memory");
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/smp_alt.h 
./include/asm-i386/smp_alt.h
---- ../orig-linux-2.6.16.29/include/asm-i386/smp_alt.h 1970-01-01 
01:00:00.000000000 +0100
-+++ ./include/asm-i386/smp_alt.h       2006-09-19 14:05:48.000000000 +0100
-@@ -0,0 +1,32 @@
-+#ifndef __ASM_SMP_ALT_H__
-+#define __ASM_SMP_ALT_H__
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define LOCK \
-+        "6677: nop\n" \
-+      ".section __smp_alternatives,\"a\"\n" \
-+      ".long 6677b\n" \
-+      ".long 6678f\n" \
-+      ".previous\n" \
-+      ".section __smp_replacements,\"a\"\n" \
-+      "6678: .byte 1\n" \
-+      ".byte 1\n" \
-+      ".byte 0\n" \
-+        ".byte 1\n" \
-+      ".byte -1\n" \
-+      "lock\n" \
-+      "nop\n" \
-+      ".previous\n"
-+void prepare_for_smp(void);
-+void unprepare_for_smp(void);
-+#else
-+#define LOCK "lock ; "
-+#endif
-+#else
-+#define LOCK ""
-+#endif
-+
-+#endif /* __ASM_SMP_ALT_H__ */
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/spinlock.h 
./include/asm-i386/spinlock.h
---- ../orig-linux-2.6.16.29/include/asm-i386/spinlock.h        2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-i386/spinlock.h      2006-09-19 14:05:48.000000000 +0100
-@@ -6,6 +6,7 @@
- #include <asm/page.h>
- #include <linux/config.h>
- #include <linux/compiler.h>
-+#include <asm/smp_alt.h>
- 
- /*
-  * Your basic SMP spinlocks, allowing only a single CPU anywhere
-@@ -23,7 +24,8 @@
- 
- #define __raw_spin_lock_string \
-       "\n1:\t" \
--      "lock ; decb %0\n\t" \
-+      LOCK \
-+      "decb %0\n\t" \
-       "jns 3f\n" \
-       "2:\t" \
-       "rep;nop\n\t" \
-@@ -34,7 +36,8 @@
- 
- #define __raw_spin_lock_string_flags \
-       "\n1:\t" \
--      "lock ; decb %0\n\t" \
-+      LOCK \
-+      "decb %0\n\t" \
-       "jns 4f\n\t" \
-       "2:\t" \
-       "testl $0x200, %1\n\t" \
-@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
- static inline int __raw_spin_trylock(raw_spinlock_t *lock)
- {
-       char oldval;
-+#ifdef CONFIG_SMP_ALTERNATIVES
-       __asm__ __volatile__(
--              "xchgb %b0,%1"
-+              "1:movb %1,%b0\n"
-+              "movb $0,%1\n"
-+              "2:"
-+              ".section __smp_alternatives,\"a\"\n"
-+              ".long 1b\n"
-+              ".long 3f\n"
-+              ".previous\n"
-+              ".section __smp_replacements,\"a\"\n"
-+              "3: .byte 2b - 1b\n"
-+              ".byte 5f-4f\n"
-+              ".byte 0\n"
-+              ".byte 6f-5f\n"
-+              ".byte -1\n"
-+              "4: xchgb %b0,%1\n"
-+              "5: movb %1,%b0\n"
-+              "movb $0,%1\n"
-+              "6:\n"
-+              ".previous\n"
-               :"=q" (oldval), "=m" (lock->slock)
-               :"0" (0) : "memory");
-+#else
-+      __asm__ __volatile__(
-+              "xchgb %b0,%1\n"
-+              :"=q" (oldval), "=m" (lock->slock)
-+              :"0" (0) : "memory");
-+#endif
-       return oldval > 0;
- }
- 
-@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
- 
- static inline void __raw_read_unlock(raw_rwlock_t *rw)
- {
--      asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
-+      asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
- }
- 
- static inline void __raw_write_unlock(raw_rwlock_t *rw)
- {
--      asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
-+      asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
-                                : "=m" (rw->lock) : : "memory");
- }
- 
-diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/system.h 
./include/asm-i386/system.h
---- ../orig-linux-2.6.16.29/include/asm-i386/system.h  2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-i386/system.h        2006-09-19 14:05:48.000000000 +0100
-@@ -5,7 +5,7 @@
- #include <linux/kernel.h>
- #include <asm/segment.h>
- #include <asm/cpufeature.h>
--#include <linux/bitops.h> /* for LOCK_PREFIX */
-+#include <asm/smp_alt.h>
- 
- #ifdef __KERNEL__
- 
-@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
-       unsigned long prev;
-       switch (size) {
-       case 1:
--              __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
-+              __asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
-                                    : "=a"(prev)
-                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
-                                    : "memory");
-               return prev;
-       case 2:
--              __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
-+              __asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
-                                    : "=a"(prev)
-                                    : "r"(new), "m"(*__xg(ptr)), "0"(old)
-                                    : "memory");
-               return prev;
-       case 4:
--              __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
-+              __asm__ __volatile__(LOCK "cmpxchgl %1,%2"
-                                    : "=a"(prev)
-                                    : "r"(new), "m"(*__xg(ptr)), "0"(old)
-                                    : "memory");
-@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
-                                     unsigned long long new)
- {
-       unsigned long long prev;
--      __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
-+      __asm__ __volatile__(LOCK "cmpxchg8b %3"
-                            : "=A"(prev)
-                            : "b"((unsigned long)new),
-                              "c"((unsigned long)(new >> 32)),
-@@ -503,11 +503,55 @@ struct alt_instr { 
- #endif
- 
- #ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define smp_alt_mb(instr)                                           \
-+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
-+                   ".section __smp_alternatives,\"a\"\n"          \
-+                   ".long 6667b\n"                                \
-+                     ".long 6673f\n"                                \
-+                   ".previous\n"                                  \
-+                   ".section __smp_replacements,\"a\"\n"          \
-+                   "6673:.byte 6668b-6667b\n"                     \
-+                   ".byte 6670f-6669f\n"                          \
-+                   ".byte 6671f-6670f\n"                          \
-+                     ".byte 0\n"                                    \
-+                   ".byte %c0\n"                                  \
-+                   "6669:lock;addl $0,0(%%esp)\n"                 \
-+                   "6670:" instr "\n"                             \
-+                   "6671:\n"                                      \
-+                   ".previous\n"                                  \
-+                   :                                              \
-+                   : "i" (X86_FEATURE_XMM2)                       \
-+                   : "memory")
-+#define smp_rmb() smp_alt_mb("lfence")
-+#define smp_mb()  smp_alt_mb("mfence")
-+#define set_mb(var, value) do {                                     \
-+unsigned long __set_mb_temp;                                        \
-+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
-+                   ".section __smp_alternatives,\"a\"\n"          \
-+                   ".long 6667b\n"                                \
-+                   ".long 6673f\n"                                \
-+                   ".previous\n"                                  \
-+                   ".section __smp_replacements,\"a\"\n"          \
-+                   "6673: .byte 6668b-6667b\n"                    \
-+                   ".byte 6670f-6669f\n"                          \
-+                   ".byte 0\n"                                    \
-+                   ".byte 6671f-6670f\n"                          \
-+                   ".byte -1\n"                                   \
-+                   "6669: xchg %1, %0\n"                          \
-+                   "6670:movl %1, %0\n"                           \
-+                   "6671:\n"                                      \
-+                   ".previous\n"                                  \
-+                   : "=m" (var), "=r" (__set_mb_temp)             \
-+                   : "1" (value)                                  \
-+                   : "memory"); } while (0)
-+#else
- #define smp_mb()      mb()
- #define smp_rmb()     rmb()
-+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-+#endif
- #define smp_wmb()     wmb()
- #define smp_read_barrier_depends()    read_barrier_depends()
--#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
- #else
- #define smp_mb()      barrier()
- #define smp_rmb()     barrier()
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/tpm_plugin_2.6.17.patch
--- a/patches/linux-2.6.16.33/tpm_plugin_2.6.17.patch   Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1545 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.c 
./drivers/char/tpm/tpm_atmel.c
---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.c       2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/char/tpm/tpm_atmel.c     2006-09-19 14:05:52.000000000 +0100
-@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
-               return -EIO;
- 
-       for (i = 0; i < 6; i++) {
--              status = ioread8(chip->vendor->iobase + 1);
-+              status = ioread8(chip->vendor.iobase + 1);
-               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                       dev_err(chip->dev, "error reading header\n");
-                       return -EIO;
-               }
--              *buf++ = ioread8(chip->vendor->iobase);
-+              *buf++ = ioread8(chip->vendor.iobase);
-       }
- 
-       /* size of the data received */
-@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
-               dev_err(chip->dev,
-                       "Recv size(%d) less than available space\n", size);
-               for (; i < size; i++) { /* clear the waiting data anyway */
--                      status = ioread8(chip->vendor->iobase + 1);
-+                      status = ioread8(chip->vendor.iobase + 1);
-                       if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                               dev_err(chip->dev, "error reading data\n");
-                               return -EIO;
-@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
- 
-       /* read all the data available */
-       for (; i < size; i++) {
--              status = ioread8(chip->vendor->iobase + 1);
-+              status = ioread8(chip->vendor.iobase + 1);
-               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                       dev_err(chip->dev, "error reading data\n");
-                       return -EIO;
-               }
--              *buf++ = ioread8(chip->vendor->iobase);
-+              *buf++ = ioread8(chip->vendor.iobase);
-       }
- 
-       /* make sure data available is gone */
--      status = ioread8(chip->vendor->iobase + 1);
-+      status = ioread8(chip->vendor.iobase + 1);
- 
-       if (status & ATML_STATUS_DATA_AVAIL) {
-               dev_err(chip->dev, "data available is stuck\n");
-@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
-       dev_dbg(chip->dev, "tpm_atml_send:\n");
-       for (i = 0; i < count; i++) {
-               dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
--              iowrite8(buf[i], chip->vendor->iobase);
-+              iowrite8(buf[i], chip->vendor.iobase);
-       }
- 
-       return count;
-@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
- 
- static void tpm_atml_cancel(struct tpm_chip *chip)
- {
--      iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
-+      iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
- }
- 
- static u8 tpm_atml_status(struct tpm_chip *chip)
- {
--      return ioread8(chip->vendor->iobase + 1);
-+      return ioread8(chip->vendor.iobase + 1);
- }
- 
- static struct file_operations atmel_ops = {
-@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
- 
- static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
- 
--static struct tpm_vendor_specific tpm_atmel = {
-+static const struct tpm_vendor_specific tpm_atmel = {
-       .recv = tpm_atml_recv,
-       .send = tpm_atml_send,
-       .cancel = tpm_atml_cancel,
-@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
-       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
- 
-       if (chip) {
--              if (chip->vendor->have_region)
--                      atmel_release_region(chip->vendor->base,
--                                           chip->vendor->region_size);
--              atmel_put_base_addr(chip->vendor);
-+              if (chip->vendor.have_region)
-+                      atmel_release_region(chip->vendor.base,
-+                                           chip->vendor.region_size);
-+              atmel_put_base_addr(chip->vendor.iobase);
-               tpm_remove_hardware(chip->dev);
-               platform_device_unregister(pdev);
-       }
-@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
- static int __init init_atmel(void)
- {
-       int rc = 0;
-+      void __iomem *iobase = NULL;
-+      int have_region, region_size;
-+      unsigned long base;
-+      struct  tpm_chip *chip;
- 
-       driver_register(&atml_drv);
- 
--      if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
-+      if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
-               rc = -ENODEV;
-               goto err_unreg_drv;
-       }
- 
--      tpm_atmel.have_region =
-+      have_region =
-           (atmel_request_region
--           (tpm_atmel.base, tpm_atmel.region_size,
--            "tpm_atmel0") == NULL) ? 0 : 1;
-+           (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
-+
- 
-       if (IS_ERR
-           (pdev =
-@@ -199,17 +203,25 @@ static int __init init_atmel(void)
-               goto err_rel_reg;
-       }
- 
--      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
-+      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
-+              rc = -ENODEV;
-               goto err_unreg_dev;
-+      }
-+
-+      chip->vendor.iobase = iobase;
-+      chip->vendor.base = base;
-+      chip->vendor.have_region = have_region;
-+      chip->vendor.region_size = region_size;
-+
-       return 0;
- 
- err_unreg_dev:
-       platform_device_unregister(pdev);
- err_rel_reg:
--      atmel_put_base_addr(&tpm_atmel);
--      if (tpm_atmel.have_region)
--              atmel_release_region(tpm_atmel.base,
--                                   tpm_atmel.region_size);
-+      atmel_put_base_addr(iobase);
-+      if (have_region)
-+              atmel_release_region(base,
-+                                   region_size);
- err_unreg_drv:
-       driver_unregister(&atml_drv);
-       return rc;
-diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.h 
./drivers/char/tpm/tpm_atmel.h
---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.h       2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/char/tpm/tpm_atmel.h     2006-09-19 14:05:52.000000000 +0100
-@@ -28,13 +28,12 @@
- #define atmel_request_region request_mem_region
- #define atmel_release_region release_mem_region
- 
--static inline void atmel_put_base_addr(struct tpm_vendor_specific
--                                       *vendor)
-+static inline void atmel_put_base_addr(void __iomem *iobase)
- {
--      iounmap(vendor->iobase);
-+      iounmap(iobase);
- }
- 
--static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
-+static void __iomem * atmel_get_base_addr(unsigned long *base, int 
*region_size)
- {
-       struct device_node *dn;
-       unsigned long address, size;
-@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
-       else
-               size = reg[naddrc];
- 
--      vendor->base = address;
--      vendor->region_size = size;
--      return ioremap(vendor->base, vendor->region_size);
-+      *base = address;
-+      *region_size = size;
-+      return ioremap(*base, *region_size);
- }
- #else
- #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
-@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
-       return 0;
- }
- 
--static inline void atmel_put_base_addr(struct tpm_vendor_specific
--                                       *vendor)
-+static inline void atmel_put_base_addr(void __iomem *iobase)
- {
- }
- 
- /* Determine where to talk to device */
--static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
--                                       *vendor)
-+static void __iomem * atmel_get_base_addr(unsigned long *base, int 
*region_size)
- {
-       int lo, hi;
- 
-@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
-       lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
-       hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
- 
--      vendor->base = (hi << 8) | lo;
--      vendor->region_size = 2;
-+      *base = (hi << 8) | lo;
-+      *region_size = 2;
- 
--      return ioport_map(vendor->base, vendor->region_size);
-+      return ioport_map(*base, *region_size);
- }
- #endif
-diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_bios.c 
./drivers/char/tpm/tpm_bios.c
---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_bios.c        2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/char/tpm/tpm_bios.c      2006-09-19 14:05:52.000000000 +0100
-@@ -29,6 +29,11 @@
- #define MAX_TEXT_EVENT                1000    /* Max event string length */
- #define ACPI_TCPA_SIG         "TCPA"  /* 0x41504354 /'TCPA' */
- 
-+enum bios_platform_class {
-+      BIOS_CLIENT = 0x00,
-+      BIOS_SERVER = 0x01,
-+};
-+
- struct tpm_bios_log {
-       void *bios_event_log;
-       void *bios_event_log_end;
-@@ -36,9 +41,18 @@ struct tpm_bios_log {
- 
- struct acpi_tcpa {
-       struct acpi_table_header hdr;
--      u16 reserved;
--      u32 log_max_len __attribute__ ((packed));
--      u32 log_start_addr __attribute__ ((packed));
-+      u16 platform_class;
-+      union {
-+              struct client_hdr {
-+                      u32 log_max_len __attribute__ ((packed));
-+                      u64 log_start_addr __attribute__ ((packed));
-+              } client;
-+              struct server_hdr {
-+                      u16 reserved;
-+                      u64 log_max_len __attribute__ ((packed));
-+                      u64 log_start_addr __attribute__ ((packed));
-+              } server;
-+      };
- };
- 
- struct tcpa_event {
-@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
-       "Non-Host Info"
- };
- 
-+struct tcpa_pc_event {
-+      u32 event_id;
-+      u32 event_size;
-+      u8 event_data[0];
-+};
-+
- enum tcpa_pc_event_ids {
-       SMBIOS = 1,
-       BIS_CERT,
-@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
-       NVRAM,
-       OPTION_ROM_EXEC,
-       OPTION_ROM_CONFIG,
--      OPTION_ROM_MICROCODE,
-+      OPTION_ROM_MICROCODE = 10,
-       S_CRTM_VERSION,
-       S_CRTM_CONTENTS,
-       POST_CONTENTS,
-+      HOST_TABLE_OF_DEVICES,
- };
- 
- static const char* tcpa_pc_event_id_strings[] = {
--      ""
-+      "",
-       "SMBIOS",
-       "BIS Certificate",
-       "POST BIOS ",
-@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
-       "NVRAM",
-       "Option ROM",
-       "Option ROM config",
--      "Option ROM microcode",
-+      "",
-+      "Option ROM microcode ",
-       "S-CRTM Version",
--      "S-CRTM Contents",
--      "S-CRTM POST Contents",
-+      "S-CRTM Contents ",
-+      "POST Contents ",
-+      "Table of Devices",
- };
- 
- /* returns pointer to start of pos. entry of tcg log */
-@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
-       const char *name = "";
-       char data[40] = "";
-       int i, n_len = 0, d_len = 0;
--      u32 event_id;
-+      struct tcpa_pc_event *pc_event;
- 
-       switch(event->event_type) {
-       case PREBOOT:
-@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
-               }
-               break;
-       case EVENT_TAG:
--              event_id = be32_to_cpu(*((u32 *)event_entry));
-+              pc_event = (struct tcpa_pc_event *)event_entry;
- 
-               /* ToDo Row data -> Base64 */
- 
--              switch (event_id) {
-+              switch (pc_event->event_id) {
-               case SMBIOS:
-               case BIS_CERT:
-               case CMOS:
-               case NVRAM:
-               case OPTION_ROM_EXEC:
-               case OPTION_ROM_CONFIG:
--              case OPTION_ROM_MICROCODE:
-               case S_CRTM_VERSION:
--              case S_CRTM_CONTENTS:
--              case POST_CONTENTS:
--                      name = tcpa_pc_event_id_strings[event_id];
-+                      name = tcpa_pc_event_id_strings[pc_event->event_id];
-                       n_len = strlen(name);
-                       break;
-+              /* hash data */
-               case POST_BIOS_ROM:
-               case ESCD:
--                      name = tcpa_pc_event_id_strings[event_id];
-+              case OPTION_ROM_MICROCODE:
-+              case S_CRTM_CONTENTS:
-+              case POST_CONTENTS:
-+                      name = tcpa_pc_event_id_strings[pc_event->event_id];
-                       n_len = strlen(name);
-                       for (i = 0; i < 20; i++)
--                              d_len += sprintf(data, "%02x",
--                                              event_entry[8 + i]);
-+                              d_len += sprintf(&data[2*i], "%02x",
-+                                              pc_event->event_data[i]);
-                       break;
-               default:
-                       break;
-@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
- 
- static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
- {
-+      struct tcpa_event *event = v;
-+      char *data = v;
-+      int i;
- 
--      char *eventname;
--      char data[4];
--      u32 help;
--      int i, len;
--      struct tcpa_event *event = (struct tcpa_event *) v;
--      unsigned char *event_entry =
--          (unsigned char *) (v + sizeof(struct tcpa_event));
--
--      eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
--      if (!eventname) {
--              printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
--                     __func__);
--              return -ENOMEM;
--      }
--
--      /* 1st: PCR used is in little-endian format (4 bytes) */
--      help = le32_to_cpu(event->pcr_index);
--      memcpy(data, &help, 4);
--      for (i = 0; i < 4; i++)
--              seq_putc(m, data[i]);
--
--      /* 2nd: SHA1 (20 bytes) */
--      for (i = 0; i < 20; i++)
--              seq_putc(m, event->pcr_value[i]);
--
--      /* 3rd: event type identifier (4 bytes) */
--      help = le32_to_cpu(event->event_type);
--      memcpy(data, &help, 4);
--      for (i = 0; i < 4; i++)
-+      for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
-               seq_putc(m, data[i]);
- 
--      len = 0;
--
--      len += get_event_name(eventname, event, event_entry);
--
--      /* 4th:  filename <= 255 + \'0' delimiter */
--      if (len > TCG_EVENT_NAME_LEN_MAX)
--              len = TCG_EVENT_NAME_LEN_MAX;
--
--      for (i = 0; i < len; i++)
--              seq_putc(m, eventname[i]);
--
--      /* 5th: delimiter */
--      seq_putc(m, '\0');
--
-       return 0;
- }
- 
-@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
-       /* 4th: eventname <= max + \'0' delimiter */
-       seq_printf(m, " %s\n", eventname);
- 
-+      kfree(eventname);
-       return 0;
- }
- 
-@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
-       struct acpi_tcpa *buff;
-       acpi_status status;
-       struct acpi_table_header *virt;
-+      u64 len, start;
- 
-       if (log->bios_event_log != NULL) {
-               printk(KERN_ERR
-@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
-               return -EIO;
-       }
- 
--      if (buff->log_max_len == 0) {
-+      switch(buff->platform_class) {
-+      case BIOS_SERVER:
-+              len = buff->server.log_max_len;
-+              start = buff->server.log_start_addr;
-+              break;
-+      case BIOS_CLIENT:
-+      default:
-+              len = buff->client.log_max_len;
-+              start = buff->client.log_start_addr;
-+              break;
-+      }
-+      if (!len) {
-               printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
-               return -EIO;
-       }
- 
-       /* malloc EventLog space */
--      log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
-+      log->bios_event_log = kmalloc(len, GFP_KERNEL);
-       if (!log->bios_event_log) {
--              printk
--                  ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
--                   __func__);
-+              printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
-+                      __func__);
-               return -ENOMEM;
-       }
- 
--      log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
-+      log->bios_event_log_end = log->bios_event_log + len;
- 
--      acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) 
&virt);
-+      acpi_os_map_memory(start, len, (void *) &virt);
- 
--      memcpy(log->bios_event_log, virt, buff->log_max_len);
-+      memcpy(log->bios_event_log, virt, len);
- 
--      acpi_os_unmap_memory(virt, buff->log_max_len);
-+      acpi_os_unmap_memory(virt, len);
-       return 0;
- }
- 
-diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_infineon.c 
./drivers/char/tpm/tpm_infineon.c
---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_infineon.c    2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/char/tpm/tpm_infineon.c  2006-09-19 14:05:52.000000000 +0100
-@@ -15,6 +15,7 @@
-  * License.
-  */
- 
-+#include <linux/init.h>
- #include <linux/pnp.h>
- #include "tpm.h"
- 
-@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
- 
-       if (clear_wrfifo) {
-               for (i = 0; i < 4096; i++) {
--                      status = inb(chip->vendor->base + WRFIFO);
-+                      status = inb(chip->vendor.base + WRFIFO);
-                       if (status == 0xff) {
-                               if (check == 5)
-                                       break;
-@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
-        */
-       i = 0;
-       do {
--              status = inb(chip->vendor->base + RDFIFO);
--              status = inb(chip->vendor->base + STAT);
-+              status = inb(chip->vendor.base + RDFIFO);
-+              status = inb(chip->vendor.base + STAT);
-               i++;
-               if (i == TPM_MAX_TRIES)
-                       return -EIO;
-@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
-       int status;
-       int i;
-       for (i = 0; i < TPM_MAX_TRIES; i++) {
--              status = inb(chip->vendor->base + STAT);
-+              status = inb(chip->vendor.base + STAT);
-               /* check the status-register if wait_for_bit is set */
-               if (status & 1 << wait_for_bit)
-                       break;
-@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
- static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
- {
-       wait(chip, STAT_XFE);
--      outb(sendbyte, chip->vendor->base + WRFIFO);
-+      outb(sendbyte, chip->vendor.base + WRFIFO);
- }
- 
-     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
-@@ -204,7 +205,7 @@ recv_begin:
-               ret = wait(chip, STAT_RDA);
-               if (ret)
-                       return -EIO;
--              buf[i] = inb(chip->vendor->base + RDFIFO);
-+              buf[i] = inb(chip->vendor.base + RDFIFO);
-       }
- 
-       if (buf[0] != TPM_VL_VER) {
-@@ -219,7 +220,7 @@ recv_begin:
- 
-               for (i = 0; i < size; i++) {
-                       wait(chip, STAT_RDA);
--                      buf[i] = inb(chip->vendor->base + RDFIFO);
-+                      buf[i] = inb(chip->vendor.base + RDFIFO);
-               }
- 
-               if ((size == 0x6D00) && (buf[1] == 0x80)) {
-@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
-       u8 count_high, count_low, count_4, count_3, count_2, count_1;
- 
-       /* Disabling Reset, LP and IRQC */
--      outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
-+      outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
- 
-       ret = empty_fifo(chip, 1);
-       if (ret) {
-@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
- 
- static u8 tpm_inf_status(struct tpm_chip *chip)
- {
--      return inb(chip->vendor->base + STAT);
-+      return inb(chip->vendor.base + STAT);
- }
- 
- static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
-@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
-       .release = tpm_release,
- };
- 
--static struct tpm_vendor_specific tpm_inf = {
-+static const struct tpm_vendor_specific tpm_inf = {
-       .recv = tpm_inf_recv,
-       .send = tpm_inf_send,
-       .cancel = tpm_inf_cancel,
-@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
-       int version[2];
-       int productid[2];
-       char chipname[20];
-+      struct tpm_chip *chip;
- 
-       /* read IO-ports through PnP */
-       if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
-@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
-                       goto err_last;
-               }
-               /* publish my base address and request region */
--              tpm_inf.base = TPM_INF_BASE;
-               if (request_region
--                  (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
-+                  (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
-                       rc = -EINVAL;
-                       goto err_last;
-               }
--              if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
--                              "tpm_infineon0") == NULL) {
-+              if (request_region
-+                  (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
-                       rc = -EINVAL;
-                       goto err_last;
-               }
-@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
- 
-               /* configure TPM with IO-ports */
-               outb(IOLIMH, TPM_INF_ADDR);
--              outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
-+              outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
-               outb(IOLIML, TPM_INF_ADDR);
--              outb((tpm_inf.base & 0xff), TPM_INF_DATA);
-+              outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
- 
-               /* control if IO-ports are set correctly */
-               outb(IOLIMH, TPM_INF_ADDR);
-@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
-               outb(IOLIML, TPM_INF_ADDR);
-               iol = inb(TPM_INF_DATA);
- 
--              if ((ioh << 8 | iol) != tpm_inf.base) {
-+              if ((ioh << 8 | iol) != TPM_INF_BASE) {
-                       dev_err(&dev->dev,
--                              "Could not set IO-ports to 0x%lx\n",
--                              tpm_inf.base);
-+                              "Could not set IO-ports to 0x%x\n",
-+                              TPM_INF_BASE);
-                       rc = -EIO;
-                       goto err_release_region;
-               }
-@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
-               outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
- 
-               /* disable RESET, LP and IRQC */
--              outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
-+              outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
- 
-               /* Finally, we're done, print some infos */
-               dev_info(&dev->dev, "TPM found: "
-                        "config base 0x%x, "
-                        "io base 0x%x, "
--                       "chip version %02x%02x, "
--                       "vendor id %x%x (Infineon), "
--                       "product id %02x%02x"
-+                       "chip version 0x%02x%02x, "
-+                       "vendor id 0x%x%x (Infineon), "
-+                       "product id 0x%02x%02x"
-                        "%s\n",
-                        TPM_INF_ADDR,
-                        TPM_INF_BASE,
-@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
-                        vendorid[0], vendorid[1],
-                        productid[0], productid[1], chipname);
- 
--              rc = tpm_register_hardware(&dev->dev, &tpm_inf);
--              if (rc < 0) {
--                      rc = -ENODEV;
-+              if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
-                       goto err_release_region;
-               }
-+              chip->vendor.base = TPM_INF_BASE;
-               return 0;
-       } else {
-               rc = -ENODEV;
-@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
-       }
- 
- err_release_region:
--      release_region(tpm_inf.base, TPM_INF_PORT_LEN);
-+      release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
-       release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
- 
- err_last:
-@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
-       struct tpm_chip *chip = pnp_get_drvdata(dev);
- 
-       if (chip) {
--              release_region(chip->vendor->base, TPM_INF_PORT_LEN);
-+              release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
-+              release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
-               tpm_remove_hardware(chip->dev);
-       }
- }
-@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
-       },
-       .id_table = tpm_pnp_tbl,
-       .probe = tpm_inf_pnp_probe,
--      .remove = tpm_inf_pnp_remove,
-+      .remove = __devexit_p(tpm_inf_pnp_remove),
- };
- 
- static int __init init_inf(void)
-@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
- 
- MODULE_AUTHOR("Marcel Selhorst <selhorst@xxxxxxxxxxxxx>");
- MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 
1.2");
--MODULE_VERSION("1.7");
-+MODULE_VERSION("1.8");
- MODULE_LICENSE("GPL");
-diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_nsc.c 
./drivers/char/tpm/tpm_nsc.c
---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_nsc.c 2006-09-12 
19:02:10.000000000 +0100
-+++ ./drivers/char/tpm/tpm_nsc.c       2006-09-19 14:05:52.000000000 +0100
-@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
-       unsigned long stop;
- 
-       /* status immediately available check */
--      *data = inb(chip->vendor->base + NSC_STATUS);
-+      *data = inb(chip->vendor.base + NSC_STATUS);
-       if ((*data & mask) == val)
-               return 0;
- 
-@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
-       stop = jiffies + 10 * HZ;
-       do {
-               msleep(TPM_TIMEOUT);
--              *data = inb(chip->vendor->base + 1);
-+              *data = inb(chip->vendor.base + 1);
-               if ((*data & mask) == val)
-                       return 0;
-       }
-@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
-       unsigned long stop;
- 
-       /* status immediately available check */
--      status = inb(chip->vendor->base + NSC_STATUS);
-+      status = inb(chip->vendor.base + NSC_STATUS);
-       if (status & NSC_STATUS_OBF)
--              status = inb(chip->vendor->base + NSC_DATA);
-+              status = inb(chip->vendor.base + NSC_DATA);
-       if (status & NSC_STATUS_RDY)
-               return 0;
- 
-@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
-       stop = jiffies + 100;
-       do {
-               msleep(TPM_TIMEOUT);
--              status = inb(chip->vendor->base + NSC_STATUS);
-+              status = inb(chip->vendor.base + NSC_STATUS);
-               if (status & NSC_STATUS_OBF)
--                      status = inb(chip->vendor->base + NSC_DATA);
-+                      status = inb(chip->vendor.base + NSC_DATA);
-               if (status & NSC_STATUS_RDY)
-                       return 0;
-       }
-@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
-               return -EIO;
-       }
-       if ((data =
--           inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
-+           inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
-               dev_err(chip->dev, "not in normal mode (0x%x)\n",
-                       data);
-               return -EIO;
-@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
-               }
-               if (data & NSC_STATUS_F0)
-                       break;
--              *p = inb(chip->vendor->base + NSC_DATA);
-+              *p = inb(chip->vendor.base + NSC_DATA);
-       }
- 
-       if ((data & NSC_STATUS_F0) == 0 &&
-@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
-               dev_err(chip->dev, "F0 not set\n");
-               return -EIO;
-       }
--      if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
-+      if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
-               dev_err(chip->dev,
-                       "expected end of command(0x%x)\n", data);
-               return -EIO;
-@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
-        * fix it. Not sure why this is needed, we followed the flow
-        * chart in the manual to the letter.
-        */
--      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
- 
-       if (nsc_wait_for_ready(chip) != 0)
-               return -EIO;
-@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
-               return -EIO;
-       }
- 
--      outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
-       if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
-               dev_err(chip->dev, "IBR timeout\n");
-               return -EIO;
-@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
-                               "IBF timeout (while writing data)\n");
-                       return -EIO;
-               }
--              outb(buf[i], chip->vendor->base + NSC_DATA);
-+              outb(buf[i], chip->vendor.base + NSC_DATA);
-       }
- 
-       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-               dev_err(chip->dev, "IBF timeout\n");
-               return -EIO;
-       }
--      outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
- 
-       return count;
- }
- 
- static void tpm_nsc_cancel(struct tpm_chip *chip)
- {
--      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
- }
- 
- static u8 tpm_nsc_status(struct tpm_chip *chip)
- {
--      return inb(chip->vendor->base + NSC_STATUS);
-+      return inb(chip->vendor.base + NSC_STATUS);
- }
- 
- static struct file_operations nsc_ops = {
-@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
- 
- static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
- 
--static struct tpm_vendor_specific tpm_nsc = {
-+static const struct tpm_vendor_specific tpm_nsc = {
-       .recv = tpm_nsc_recv,
-       .send = tpm_nsc_send,
-       .cancel = tpm_nsc_cancel,
-@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
- {
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if ( chip ) {
--              release_region(chip->vendor->base, 2);
-+              release_region(chip->vendor.base, 2);
-               tpm_remove_hardware(chip->dev);
-       }
- }
-@@ -286,7 +286,8 @@ static int __init init_nsc(void)
-       int rc = 0;
-       int lo, hi;
-       int nscAddrBase = TPM_ADDR;
--
-+      struct tpm_chip *chip;
-+      unsigned long base;
- 
-       /* verify that it is a National part (SID) */
-       if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
-@@ -300,7 +301,7 @@ static int __init init_nsc(void)
- 
-       hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
-       lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
--      tpm_nsc.base = (hi<<8) | lo;
-+      base = (hi<<8) | lo;
- 
-       /* enable the DPM module */
-       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
-@@ -320,13 +321,15 @@ static int __init init_nsc(void)
-       if ((rc = platform_device_register(pdev)) < 0)
-               goto err_free_dev;
- 
--      if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
-+      if (request_region(base, 2, "tpm_nsc0") == NULL ) {
-               rc = -EBUSY;
-               goto err_unreg_dev;
-       }
- 
--      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
-+      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
-+              rc = -ENODEV;
-               goto err_rel_reg;
-+      }
- 
-       dev_dbg(&pdev->dev, "NSC TPM detected\n");
-       dev_dbg(&pdev->dev,
-@@ -361,10 +364,12 @@ static int __init init_nsc(void)
-                "NSC TPM revision %d\n",
-                tpm_read_index(nscAddrBase, 0x27) & 0x1F);
- 
-+      chip->vendor.base = base;
-+
-       return 0;
- 
- err_rel_reg:
--      release_region(tpm_nsc.base, 2);
-+      release_region(base, 2);
- err_unreg_dev:
-       platform_device_unregister(pdev);
- err_free_dev:
-diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_tis.c 
./drivers/char/tpm/tpm_tis.c
---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_tis.c 1970-01-01 
01:00:00.000000000 +0100
-+++ ./drivers/char/tpm/tpm_tis.c       2006-09-19 14:05:52.000000000 +0100
-@@ -0,0 +1,665 @@
-+/*
-+ * Copyright (C) 2005, 2006 IBM Corporation
-+ *
-+ * Authors:
-+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
-+ * Kylene Hall <kjhall@xxxxxxxxxx>
-+ *
-+ * Device driver for TCG/TCPA TPM (trusted platform module).
-+ * Specifications at www.trustedcomputinggroup.org
-+ *
-+ * This device driver implements the TPM interface as defined in
-+ * the TCG TPM Interface Spec version 1.2, revision 1.0.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/pnp.h>
-+#include <linux/interrupt.h>
-+#include <linux/wait.h>
-+#include "tpm.h"
-+
-+#define TPM_HEADER_SIZE 10
-+
-+enum tis_access {
-+      TPM_ACCESS_VALID = 0x80,
-+      TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
-+      TPM_ACCESS_REQUEST_PENDING = 0x04,
-+      TPM_ACCESS_REQUEST_USE = 0x02,
-+};
-+
-+enum tis_status {
-+      TPM_STS_VALID = 0x80,
-+      TPM_STS_COMMAND_READY = 0x40,
-+      TPM_STS_GO = 0x20,
-+      TPM_STS_DATA_AVAIL = 0x10,
-+      TPM_STS_DATA_EXPECT = 0x08,
-+};
-+
-+enum tis_int_flags {
-+      TPM_GLOBAL_INT_ENABLE = 0x80000000,
-+      TPM_INTF_BURST_COUNT_STATIC = 0x100,
-+      TPM_INTF_CMD_READY_INT = 0x080,
-+      TPM_INTF_INT_EDGE_FALLING = 0x040,
-+      TPM_INTF_INT_EDGE_RISING = 0x020,
-+      TPM_INTF_INT_LEVEL_LOW = 0x010,
-+      TPM_INTF_INT_LEVEL_HIGH = 0x008,
-+      TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
-+      TPM_INTF_STS_VALID_INT = 0x002,
-+      TPM_INTF_DATA_AVAIL_INT = 0x001,
-+};
-+
-+enum tis_defaults {
-+      TIS_MEM_BASE = 0xFED40000,
-+      TIS_MEM_LEN = 0x5000,
-+      TIS_SHORT_TIMEOUT = 750,        /* ms */
-+      TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
-+};
-+
-+#define       TPM_ACCESS(l)                   (0x0000 | ((l) << 12))
-+#define       TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
-+#define       TPM_INT_VECTOR(l)               (0x000C | ((l) << 12))
-+#define       TPM_INT_STATUS(l)               (0x0010 | ((l) << 12))
-+#define       TPM_INTF_CAPS(l)                (0x0014 | ((l) << 12))
-+#define       TPM_STS(l)                      (0x0018 | ((l) << 12))
-+#define       TPM_DATA_FIFO(l)                (0x0024 | ((l) << 12))
-+
-+#define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
-+#define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
-+
-+static LIST_HEAD(tis_chips);
-+static DEFINE_SPINLOCK(tis_lock);
-+
-+static int check_locality(struct tpm_chip *chip, int l)
-+{
-+      if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
-+           (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
-+          (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
-+              return chip->vendor.locality = l;
-+
-+      return -1;
-+}
-+
-+static void release_locality(struct tpm_chip *chip, int l, int force)
-+{
-+      if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
-+                    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
-+          (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
-+              iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
-+                       chip->vendor.iobase + TPM_ACCESS(l));
-+}
-+
-+static int request_locality(struct tpm_chip *chip, int l)
-+{
-+      unsigned long stop;
-+      long rc;
-+
-+      if (check_locality(chip, l) >= 0)
-+              return l;
-+
-+      iowrite8(TPM_ACCESS_REQUEST_USE,
-+               chip->vendor.iobase + TPM_ACCESS(l));
-+
-+      if (chip->vendor.irq) {
-+              rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
-+                                                    (check_locality
-+                                                     (chip, l) >= 0),
-+                                                    chip->vendor.timeout_a);
-+              if (rc > 0)
-+                      return l;
-+
-+      } else {
-+              /* wait for burstcount */
-+              stop = jiffies + chip->vendor.timeout_a;
-+              do {
-+                      if (check_locality(chip, l) >= 0)
-+                              return l;
-+                      msleep(TPM_TIMEOUT);
-+              }
-+              while (time_before(jiffies, stop));
-+      }
-+      return -1;
-+}
-+
-+static u8 tpm_tis_status(struct tpm_chip *chip)
-+{
-+      return ioread8(chip->vendor.iobase +
-+                     TPM_STS(chip->vendor.locality));
-+}
-+
-+static void tpm_tis_ready(struct tpm_chip *chip)
-+{
-+      /* this causes the current command to be aborted */
-+      iowrite8(TPM_STS_COMMAND_READY,
-+               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
-+}
-+
-+static int get_burstcount(struct tpm_chip *chip)
-+{
-+      unsigned long stop;
-+      int burstcnt;
-+
-+      /* wait for burstcount */
-+      /* which timeout value, spec has 2 answers (c & d) */
-+      stop = jiffies + chip->vendor.timeout_d;
-+      do {
-+              burstcnt = ioread8(chip->vendor.iobase +
-+                                 TPM_STS(chip->vendor.locality) + 1);
-+              burstcnt += ioread8(chip->vendor.iobase +
-+                                  TPM_STS(chip->vendor.locality) +
-+                                  2) << 8;
-+              if (burstcnt)
-+                      return burstcnt;
-+              msleep(TPM_TIMEOUT);
-+      } while (time_before(jiffies, stop));
-+      return -EBUSY;
-+}
-+
-+static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long 
timeout,
-+                       wait_queue_head_t *queue)
-+{
-+      unsigned long stop;
-+      long rc;
-+      u8 status;
-+
-+      /* check current status */
-+      status = tpm_tis_status(chip);
-+      if ((status & mask) == mask)
-+              return 0;
-+
-+      if (chip->vendor.irq) {
-+              rc = wait_event_interruptible_timeout(*queue,
-+                                                    ((tpm_tis_status
-+                                                      (chip) & mask) ==
-+                                                     mask), timeout);
-+              if (rc > 0)
-+                      return 0;
-+      } else {
-+              stop = jiffies + timeout;
-+              do {
-+                      msleep(TPM_TIMEOUT);
-+                      status = tpm_tis_status(chip);
-+                      if ((status & mask) == mask)
-+                              return 0;
-+              } while (time_before(jiffies, stop));
-+      }
-+      return -ETIME;
-+}
-+
-+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
-+{
-+      int size = 0, burstcnt;
-+      while (size < count &&
-+             wait_for_stat(chip,
-+                           TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+                           chip->vendor.timeout_c,
-+                           &chip->vendor.read_queue)
-+             == 0) {
-+              burstcnt = get_burstcount(chip);
-+              for (; burstcnt > 0 && size < count; burstcnt--)
-+                      buf[size++] = ioread8(chip->vendor.iobase +
-+                                            TPM_DATA_FIFO(chip->vendor.
-+                                                          locality));
-+      }
-+      return size;
-+}
-+
-+static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
-+{
-+      int size = 0;
-+      int expected, status;
-+
-+      if (count < TPM_HEADER_SIZE) {
-+              size = -EIO;
-+              goto out;
-+      }
-+
-+      /* read first 10 bytes, including tag, paramsize, and result */
-+      if ((size =
-+           recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
-+              dev_err(chip->dev, "Unable to read header\n");
-+              goto out;
-+      }
-+
-+      expected = be32_to_cpu(*(__be32 *) (buf + 2));
-+      if (expected > count) {
-+              size = -EIO;
-+              goto out;
-+      }
-+
-+      if ((size +=
-+           recv_data(chip, &buf[TPM_HEADER_SIZE],
-+                     expected - TPM_HEADER_SIZE)) < expected) {
-+              dev_err(chip->dev, "Unable to read remainder of result\n");
-+              size = -ETIME;
-+              goto out;
-+      }
-+
-+      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
-+                    &chip->vendor.int_queue);
-+      status = tpm_tis_status(chip);
-+      if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
-+              dev_err(chip->dev, "Error left over data\n");
-+              size = -EIO;
-+              goto out;
-+      }
-+
-+out:
-+      tpm_tis_ready(chip);
-+      release_locality(chip, chip->vendor.locality, 0);
-+      return size;
-+}
-+
-+/*
-+ * If interrupts are used (signaled by an irq set in the vendor structure)
-+ * tpm.c can skip polling for the data to be available as the interrupt is
-+ * waited for here
-+ */
-+static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
-+{
-+      int rc, status, burstcnt;
-+      size_t count = 0;
-+      u32 ordinal;
-+
-+      if (request_locality(chip, 0) < 0)
-+              return -EBUSY;
-+
-+      status = tpm_tis_status(chip);
-+      if ((status & TPM_STS_COMMAND_READY) == 0) {
-+              tpm_tis_ready(chip);
-+              if (wait_for_stat
-+                  (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
-+                   &chip->vendor.int_queue) < 0) {
-+                      rc = -ETIME;
-+                      goto out_err;
-+              }
-+      }
-+
-+      while (count < len - 1) {
-+              burstcnt = get_burstcount(chip);
-+              for (; burstcnt > 0 && count < len - 1; burstcnt--) {
-+                      iowrite8(buf[count], chip->vendor.iobase +
-+                               TPM_DATA_FIFO(chip->vendor.locality));
-+                      count++;
-+              }
-+
-+              wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
-+                            &chip->vendor.int_queue);
-+              status = tpm_tis_status(chip);
-+              if ((status & TPM_STS_DATA_EXPECT) == 0) {
-+                      rc = -EIO;
-+                      goto out_err;
-+              }
-+      }
-+
-+      /* write last byte */
-+      iowrite8(buf[count],
-+               chip->vendor.iobase +
-+               TPM_DATA_FIFO(chip->vendor.locality));
-+      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
-+                    &chip->vendor.int_queue);
-+      status = tpm_tis_status(chip);
-+      if ((status & TPM_STS_DATA_EXPECT) != 0) {
-+              rc = -EIO;
-+              goto out_err;
-+      }
-+
-+      /* go and do it */
-+      iowrite8(TPM_STS_GO,
-+               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
-+
-+      if (chip->vendor.irq) {
-+              ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
-+              if (wait_for_stat
-+                  (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+                   tpm_calc_ordinal_duration(chip, ordinal),
-+                   &chip->vendor.read_queue) < 0) {
-+                      rc = -ETIME;
-+                      goto out_err;
-+              }
-+      }
-+      return len;
-+out_err:
-+      tpm_tis_ready(chip);
-+      release_locality(chip, chip->vendor.locality, 0);
-+      return rc;
-+}
-+
-+static struct file_operations tis_ops = {
-+      .owner = THIS_MODULE,
-+      .llseek = no_llseek,
-+      .open = tpm_open,
-+      .read = tpm_read,
-+      .write = tpm_write,
-+      .release = tpm_release,
-+};
-+
-+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
-+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
-+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
-+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
-+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
-+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
-+                 NULL);
-+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
-+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
-+
-+static struct attribute *tis_attrs[] = {
-+      &dev_attr_pubek.attr,
-+      &dev_attr_pcrs.attr,
-+      &dev_attr_enabled.attr,
-+      &dev_attr_active.attr,
-+      &dev_attr_owned.attr,
-+      &dev_attr_temp_deactivated.attr,
-+      &dev_attr_caps.attr,
-+      &dev_attr_cancel.attr, NULL,
-+};
-+
-+static struct attribute_group tis_attr_grp = {
-+      .attrs = tis_attrs
-+};
-+
-+static struct tpm_vendor_specific tpm_tis = {
-+      .status = tpm_tis_status,
-+      .recv = tpm_tis_recv,
-+      .send = tpm_tis_send,
-+      .cancel = tpm_tis_ready,
-+      .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+      .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+      .req_canceled = TPM_STS_COMMAND_READY,
-+      .attr_group = &tis_attr_grp,
-+      .miscdev = {
-+                  .fops = &tis_ops,},
-+};
-+
-+static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
-+      u32 interrupt;
-+
-+      interrupt = ioread32(chip->vendor.iobase +
-+                           TPM_INT_STATUS(chip->vendor.locality));
-+
-+      if (interrupt == 0)
-+              return IRQ_NONE;
-+
-+      chip->vendor.irq = irq;
-+
-+      /* Clear interrupts handled with TPM_EOI */
-+      iowrite32(interrupt,
-+                chip->vendor.iobase +
-+                TPM_INT_STATUS(chip->vendor.locality));
-+      return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs 
*regs)
-+{
-+      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
-+      u32 interrupt;
-+      int i;
-+
-+      interrupt = ioread32(chip->vendor.iobase +
-+                           TPM_INT_STATUS(chip->vendor.locality));
-+
-+      if (interrupt == 0)
-+              return IRQ_NONE;
-+
-+      if (interrupt & TPM_INTF_DATA_AVAIL_INT)
-+              wake_up_interruptible(&chip->vendor.read_queue);
-+      if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
-+              for (i = 0; i < 5; i++)
-+                      if (check_locality(chip, i) >= 0)
-+                              break;
-+      if (interrupt &
-+          (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
-+           TPM_INTF_CMD_READY_INT))
-+              wake_up_interruptible(&chip->vendor.int_queue);
-+
-+      /* Clear interrupts handled with TPM_EOI */
-+      iowrite32(interrupt,
-+                chip->vendor.iobase +
-+                TPM_INT_STATUS(chip->vendor.locality));
-+      return IRQ_HANDLED;
-+}
-+
-+static int interrupts = 1;
-+module_param(interrupts, bool, 0444);
-+MODULE_PARM_DESC(interrupts, "Enable interrupts");
-+
-+static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
-+                                    const struct pnp_device_id *pnp_id)
-+{
-+      u32 vendor, intfcaps, intmask;
-+      int rc, i;
-+      unsigned long start, len;
-+      struct tpm_chip *chip;
-+
-+      start = pnp_mem_start(pnp_dev, 0);
-+      len = pnp_mem_len(pnp_dev, 0);
-+
-+      if (!start)
-+              start = TIS_MEM_BASE;
-+      if (!len)
-+              len = TIS_MEM_LEN;
-+
-+      if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
-+              return -ENODEV;
-+
-+      chip->vendor.iobase = ioremap(start, len);
-+      if (!chip->vendor.iobase) {
-+              rc = -EIO;
-+              goto out_err;
-+      }
-+
-+      vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
-+
-+      /* Default timeouts */
-+      chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-+      chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
-+      chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-+      chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-+
-+      dev_info(&pnp_dev->dev,
-+               "1.2 TPM (device-id 0x%X, rev-id %d)\n",
-+               vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
-+
-+      /* Figure out the capabilities */
-+      intfcaps =
-+          ioread32(chip->vendor.iobase +
-+                   TPM_INTF_CAPS(chip->vendor.locality));
-+      dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
-+              intfcaps);
-+      if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
-+              dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
-+      if (intfcaps & TPM_INTF_CMD_READY_INT)
-+              dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
-+      if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
-+      if (intfcaps & TPM_INTF_INT_EDGE_RISING)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
-+      if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
-+      if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
-+      if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
-+              dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
-+      if (intfcaps & TPM_INTF_STS_VALID_INT)
-+              dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
-+      if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
-+              dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
-+
-+      if (request_locality(chip, 0) != 0) {
-+              rc = -ENODEV;
-+              goto out_err;
-+      }
-+
-+      /* INTERRUPT Setup */
-+      init_waitqueue_head(&chip->vendor.read_queue);
-+      init_waitqueue_head(&chip->vendor.int_queue);
-+
-+      intmask =
-+          ioread32(chip->vendor.iobase +
-+                   TPM_INT_ENABLE(chip->vendor.locality));
-+
-+      intmask |= TPM_INTF_CMD_READY_INT
-+          | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
-+          | TPM_INTF_STS_VALID_INT;
-+
-+      iowrite32(intmask,
-+                chip->vendor.iobase +
-+                TPM_INT_ENABLE(chip->vendor.locality));
-+      if (interrupts) {
-+              chip->vendor.irq =
-+                  ioread8(chip->vendor.iobase +
-+                          TPM_INT_VECTOR(chip->vendor.locality));
-+
-+              for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
-+                      iowrite8(i, chip->vendor.iobase +
-+                                  TPM_INT_VECTOR(chip->vendor.locality));
-+                      if (request_irq
-+                          (i, tis_int_probe, SA_SHIRQ,
-+                           chip->vendor.miscdev.name, chip) != 0) {
-+                              dev_info(chip->dev,
-+                                       "Unable to request irq: %d for 
probe\n",
-+                                       i);
-+                              continue;
-+                      }
-+
-+                      /* Clear all existing */
-+                      iowrite32(ioread32
-+                                (chip->vendor.iobase +
-+                                 TPM_INT_STATUS(chip->vendor.locality)),
-+                                chip->vendor.iobase +
-+                                TPM_INT_STATUS(chip->vendor.locality));
-+
-+                      /* Turn on */
-+                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
-+                                chip->vendor.iobase +
-+                                TPM_INT_ENABLE(chip->vendor.locality));
-+
-+                      /* Generate Interrupts */
-+                      tpm_gen_interrupt(chip);
-+
-+                      /* Turn off */
-+                      iowrite32(intmask,
-+                                chip->vendor.iobase +
-+                                TPM_INT_ENABLE(chip->vendor.locality));
-+                      free_irq(i, chip);
-+              }
-+      }
-+      if (chip->vendor.irq) {
-+              iowrite8(chip->vendor.irq,
-+                       chip->vendor.iobase +
-+                       TPM_INT_VECTOR(chip->vendor.locality));
-+              if (request_irq
-+                  (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
-+                   chip->vendor.miscdev.name, chip) != 0) {
-+                      dev_info(chip->dev,
-+                               "Unable to request irq: %d for use\n",
-+                               chip->vendor.irq);
-+                      chip->vendor.irq = 0;
-+              } else {
-+                      /* Clear all existing */
-+                      iowrite32(ioread32
-+                                (chip->vendor.iobase +
-+                                 TPM_INT_STATUS(chip->vendor.locality)),
-+                                chip->vendor.iobase +
-+                                TPM_INT_STATUS(chip->vendor.locality));
-+
-+                      /* Turn on */
-+                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
-+                                chip->vendor.iobase +
-+                                TPM_INT_ENABLE(chip->vendor.locality));
-+              }
-+      }
-+
-+      INIT_LIST_HEAD(&chip->vendor.list);
-+      spin_lock(&tis_lock);
-+      list_add(&chip->vendor.list, &tis_chips);
-+      spin_unlock(&tis_lock);
-+
-+      tpm_get_timeouts(chip);
-+      tpm_continue_selftest(chip);
-+
-+      return 0;
-+out_err:
-+      if (chip->vendor.iobase)
-+              iounmap(chip->vendor.iobase);
-+      tpm_remove_hardware(chip->dev);
-+      return rc;
-+}
-+
-+static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
-+{
-+      return tpm_pm_suspend(&dev->dev, msg);
-+}
-+
-+static int tpm_tis_pnp_resume(struct pnp_dev *dev)
-+{
-+      return tpm_pm_resume(&dev->dev);
-+}
-+
-+static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
-+      {"PNP0C31", 0},         /* TPM */
-+      {"ATM1200", 0},         /* Atmel */
-+      {"IFX0102", 0},         /* Infineon */
-+      {"BCM0101", 0},         /* Broadcom */
-+      {"NSC1200", 0},         /* National */
-+      /* Add new here */
-+      {"", 0},                /* User Specified */
-+      {"", 0}                 /* Terminator */
-+};
-+
-+static struct pnp_driver tis_pnp_driver = {
-+      .name = "tpm_tis",
-+      .id_table = tpm_pnp_tbl,
-+      .probe = tpm_tis_pnp_init,
-+      .suspend = tpm_tis_pnp_suspend,
-+      .resume = tpm_tis_pnp_resume,
-+};
-+
-+#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
-+module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
-+                  sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
-+MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-+
-+static int __init init_tis(void)
-+{
-+      return pnp_register_driver(&tis_pnp_driver);
-+}
-+
-+static void __exit cleanup_tis(void)
-+{
-+      struct tpm_vendor_specific *i, *j;
-+      struct tpm_chip *chip;
-+      spin_lock(&tis_lock);
-+      list_for_each_entry_safe(i, j, &tis_chips, list) {
-+              chip = to_tpm_chip(i);
-+              iowrite32(~TPM_GLOBAL_INT_ENABLE &
-+                        ioread32(chip->vendor.iobase +
-+                                 TPM_INT_ENABLE(chip->vendor.
-+                                                locality)),
-+                        chip->vendor.iobase +
-+                        TPM_INT_ENABLE(chip->vendor.locality));
-+              release_locality(chip, chip->vendor.locality, 1);
-+              if (chip->vendor.irq)
-+                      free_irq(chip->vendor.irq, chip);
-+              iounmap(i->iobase);
-+              list_del(&i->list);
-+              tpm_remove_hardware(chip->dev);
-+      }
-+      spin_unlock(&tis_lock);
-+      pnp_unregister_driver(&tis_pnp_driver);
-+}
-+
-+module_init(init_tis);
-+module_exit(cleanup_tis);
-+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
-+MODULE_DESCRIPTION("TPM Driver");
-+MODULE_VERSION("2.0");
-+MODULE_LICENSE("GPL");
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/vsnprintf.patch
--- a/patches/linux-2.6.16.33/vsnprintf.patch   Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-commit f796937a062c7aeb44cd0e75e1586c8543634a7d
-Author: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx>
-Date:   Sun Jun 25 05:49:17 2006 -0700
-
-    [PATCH] Fix bounds check in vsnprintf, to allow for a 0 size and NULL 
buffer
-    
-    This change allows callers to use a 0-byte buffer and a NULL buffer pointer
-    with vsnprintf, so it can be used to determine how large the resulting
-    formatted string will be.
-    
-    Previously the code effectively treated a size of 0 as a size of 4G (on
-    32-bit systems), with other checks preventing it from actually trying to
-    emit the string - but the terminal \0 would still be written, which would
-    crash if the buffer is NULL.
-    
-    This change changes the boundary check so that 'end' points to the putative
-    location of the terminal '\0', which is only written if size > 0.
-    
-    vsnprintf still allows the buffer size to be set very large, to allow
-    unbounded buffer sizes (to implement sprintf, etc).
-    
-    [akpm@xxxxxxxx: fix long-vs-longlong confusion]
-    Signed-off-by: Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx>
-    Signed-off-by: Chris Wright <chrisw@xxxxxxxxxxxx>
-    Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
-    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxx>
-
-diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index b07db5c..f595947 100644
---- a/lib/vsprintf.c
-+++ b/lib/vsprintf.c
-@@ -187,49 +187,49 @@ static char * number(char * buf, char *
-       size -= precision;
-       if (!(type&(ZEROPAD+LEFT))) {
-               while(size-->0) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = ' ';
-                       ++buf;
-               }
-       }
-       if (sign) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = sign;
-               ++buf;
-       }
-       if (type & SPECIAL) {
-               if (base==8) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = '0';
-                       ++buf;
-               } else if (base==16) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = '0';
-                       ++buf;
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = digits[33];
-                       ++buf;
-               }
-       }
-       if (!(type & LEFT)) {
-               while (size-- > 0) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = c;
-                       ++buf;
-               }
-       }
-       while (i < precision--) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = '0';
-               ++buf;
-       }
-       while (i-- > 0) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = tmp[i];
-               ++buf;
-       }
-       while (size-- > 0) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = ' ';
-               ++buf;
-       }
-@@ -272,7 +272,8 @@ int vsnprintf(char *buf, size_t size, co
-                               /* 'z' changed to 'Z' --davidm 1/25/99 */
-                               /* 't' added for ptrdiff_t */
- 
--      /* Reject out-of-range values early */
-+      /* Reject out-of-range values early.  Large positive sizes are
-+         used for unknown buffer sizes. */
-       if (unlikely((int) size < 0)) {
-               /* There can be only one.. */
-               static int warn = 1;
-@@ -282,16 +283,17 @@ int vsnprintf(char *buf, size_t size, co
-       }
- 
-       str = buf;
--      end = buf + size - 1;
-+      end = buf + size;
- 
--      if (end < buf - 1) {
--              end = ((void *) -1);
--              size = end - buf + 1;
-+      /* Make sure end is always >= buf */
-+      if (end < buf) {
-+              end = ((void *)-1);
-+              size = end - buf;
-       }
- 
-       for (; *fmt ; ++fmt) {
-               if (*fmt != '%') {
--                      if (str <= end)
-+                      if (str < end)
-                               *str = *fmt;
-                       ++str;
-                       continue;
-@@ -357,17 +359,17 @@ int vsnprintf(char *buf, size_t size, co
-                       case 'c':
-                               if (!(flags & LEFT)) {
-                                       while (--field_width > 0) {
--                                              if (str <= end)
-+                                              if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               c = (unsigned char) va_arg(args, int);
--                              if (str <= end)
-+                              if (str < end)
-                                       *str = c;
-                               ++str;
-                               while (--field_width > 0) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-@@ -382,18 +384,18 @@ int vsnprintf(char *buf, size_t size, co
- 
-                               if (!(flags & LEFT)) {
-                                       while (len < field_width--) {
--                                              if (str <= end)
-+                                              if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               for (i = 0; i < len; ++i) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = *s;
-                                       ++str; ++s;
-                               }
-                               while (len < field_width--) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-@@ -426,7 +428,7 @@ int vsnprintf(char *buf, size_t size, co
-                               continue;
- 
-                       case '%':
--                              if (str <= end)
-+                              if (str < end)
-                                       *str = '%';
-                               ++str;
-                               continue;
-@@ -449,11 +451,11 @@ int vsnprintf(char *buf, size_t size, co
-                               break;
- 
-                       default:
--                              if (str <= end)
-+                              if (str < end)
-                                       *str = '%';
-                               ++str;
-                               if (*fmt) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = *fmt;
-                                       ++str;
-                               } else {
-@@ -483,14 +485,13 @@ int vsnprintf(char *buf, size_t size, co
-               str = number(str, end, num, base,
-                               field_width, precision, flags);
-       }
--      if (str <= end)
--              *str = '\0';
--      else if (size > 0)
--              /* don't write out a null byte if the buf size is zero */
--              *end = '\0';
--      /* the trailing null byte doesn't count towards the total
--      * ++str;
--      */
-+      if (size > 0) {
-+              if (str < end)
-+                      *str = '\0';
-+              else
-+                      end[-1] = '\0';
-+      }
-+      /* the trailing null byte doesn't count towards the total */
-       return str-buf;
- }
- 
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/x86-elfnote-as-preprocessor-macro.patch
--- a/patches/linux-2.6.16.33/x86-elfnote-as-preprocessor-macro.patch   Tue Jan 
23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/include/linux/elfnote.h 
./include/linux/elfnote.h
---- ../orig-linux-2.6.16.29/include/linux/elfnote.h    2006-09-19 
14:06:10.000000000 +0100
-+++ ./include/linux/elfnote.h  2006-09-19 14:06:20.000000000 +0100
-@@ -31,22 +31,24 @@
- /*
-  * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
-  * turn out to be the same size and shape), followed by the name and
-- * desc data with appropriate padding.  The 'desc' argument includes
-- * the assembler pseudo op defining the type of the data: .asciz
-- * "hello, world"
-+ * desc data with appropriate padding.  The 'desctype' argument is the
-+ * assembler pseudo op defining the type of the data e.g. .asciz while
-+ * 'descdata' is the data itself e.g.  "hello, world".
-+ *
-+ * e.g. ELFNOTE(XYZCo, 42, .asciz, "forty-two")
-+ *      ELFNOTE(XYZCo, 12, .long, 0xdeadbeef)
-  */
--.macro ELFNOTE name type desc:vararg
--.pushsection ".note.\name"
--  .align 4
--  .long 2f - 1f                       /* namesz */
--  .long 4f - 3f                       /* descsz */
--  .long \type
--1:.asciz "\name"
--2:.align 4
--3:\desc
--4:.align 4
--.popsection
--.endm
-+#define ELFNOTE(name, type, desctype, descdata)       \
-+.pushsection .note.name                       ;       \
-+  .align 4                            ;       \
-+  .long 2f - 1f               /* namesz */    ;       \
-+  .long 4f - 3f               /* descsz */    ;       \
-+  .long type                          ;       \
-+1:.asciz "name"                               ;       \
-+2:.align 4                            ;       \
-+3:desctype descdata                   ;       \
-+4:.align 4                            ;       \
-+.popsection                           ;
- #else /* !__ASSEMBLER__ */
- #include <linux/elf.h>
- /*
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/x86-increase-interrupt-vector-range.patch
--- a/patches/linux-2.6.16.33/x86-increase-interrupt-vector-range.patch Tue Jan 
23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S 
./arch/i386/kernel/entry.S
---- ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S   2006-09-19 
14:05:44.000000000 +0100
-+++ ./arch/i386/kernel/entry.S 2006-09-19 14:05:56.000000000 +0100
-@@ -406,7 +406,7 @@ vector=0
- ENTRY(irq_entries_start)
- .rept NR_IRQS
-       ALIGN
--1:    pushl $vector-256
-+1:    pushl $~(vector)
-       jmp common_interrupt
- .data
-       .long 1b
-@@ -423,7 +423,7 @@ common_interrupt:
- 
- #define BUILD_INTERRUPT(name, nr)     \
- ENTRY(name)                           \
--      pushl $nr-256;                  \
-+      pushl $~(nr);                   \
-       SAVE_ALL                        \
-       movl %esp,%eax;                 \
-       call smp_/**/name;              \
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/irq.c 
./arch/i386/kernel/irq.c
---- ../orig-linux-2.6.16.29/arch/i386/kernel/irq.c     2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/i386/kernel/irq.c   2006-09-19 14:05:56.000000000 +0100
-@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
-  */
- fastcall unsigned int do_IRQ(struct pt_regs *regs)
- {     
--      /* high bits used in ret_from_ code */
--      int irq = regs->orig_eax & 0xff;
-+      /* high bit used in ret_from_ code */
-+      int irq = ~regs->orig_eax;
- #ifdef CONFIG_4KSTACKS
-       union irq_ctx *curctx, *irqctx;
-       u32 *isp;
-diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/entry.S 
./arch/x86_64/kernel/entry.S
---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/entry.S 2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/x86_64/kernel/entry.S       2006-09-19 14:05:56.000000000 +0100
-@@ -596,7 +596,7 @@ retint_kernel:     
-  */           
-       .macro apicinterrupt num,func
-       INTR_FRAME
--      pushq $\num-256
-+      pushq $~(\num)
-       CFI_ADJUST_CFA_OFFSET 8
-       interrupt \func
-       jmp ret_from_intr
-diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/irq.c 
./arch/x86_64/kernel/irq.c
---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/irq.c   2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/x86_64/kernel/irq.c 2006-09-19 14:05:56.000000000 +0100
-@@ -96,8 +96,8 @@ skip:
-  */
- asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
- {     
--      /* high bits used in ret_from_ code  */
--      unsigned irq = regs->orig_rax & 0xff;
-+      /* high bit used in ret_from_ code  */
-+      unsigned irq = ~regs->orig_rax;
- 
-       exit_idle();
-       irq_enter();
-diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/smp.c 
./arch/x86_64/kernel/smp.c
---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/smp.c   2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/x86_64/kernel/smp.c 2006-09-19 14:05:56.000000000 +0100
-@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
- 
-       cpu = smp_processor_id();
-       /*
--       * orig_rax contains the interrupt vector - 256.
-+       * orig_rax contains the negated interrupt vector.
-        * Use that to determine where the sender put the data.
-        */
--      sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
-+      sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
-       f = &per_cpu(flush_state, sender);
- 
-       if (!cpu_isset(cpu, f->flush_cpumask))
-diff -pruN ../orig-linux-2.6.16.29/include/asm-x86_64/hw_irq.h 
./include/asm-x86_64/hw_irq.h
---- ../orig-linux-2.6.16.29/include/asm-x86_64/hw_irq.h        2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-x86_64/hw_irq.h      2006-09-19 14:05:56.000000000 +0100
-@@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \
- __asm__( \
- "\n.p2align\n" \
- "IRQ" #nr "_interrupt:\n\t" \
--      "push $" #nr "-256 ; " \
-+      "push $~(" #nr ") ; " \
-       "jmp common_interrupt");
- 
- #if defined(CONFIG_X86_IO_APIC)
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
--- 
a/patches/linux-2.6.16.33/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
     Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S 
./arch/i386/kernel/vmlinux.lds.S
---- ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S     2006-09-19 
14:05:48.000000000 +0100
-+++ ./arch/i386/kernel/vmlinux.lds.S   2006-09-19 14:06:10.000000000 +0100
-@@ -12,6 +12,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386"
- OUTPUT_ARCH(i386)
- ENTRY(phys_startup_32)
- jiffies = jiffies_64;
-+
-+PHDRS {
-+      text PT_LOAD FLAGS(5);  /* R_E */
-+      data PT_LOAD FLAGS(7);  /* RWE */
-+      note PT_NOTE FLAGS(4);  /* R__ */
-+}
- SECTIONS
- {
-   . = __KERNEL_START;
-@@ -25,7 +31,7 @@ SECTIONS
-       KPROBES_TEXT
-       *(.fixup)
-       *(.gnu.warning)
--      } = 0x9090
-+      } :text = 0x9090
- 
-   _etext = .;                 /* End of text section */
- 
-@@ -47,7 +53,7 @@ SECTIONS
-   .data : AT(ADDR(.data) - LOAD_OFFSET) {     /* Data */
-       *(.data)
-       CONSTRUCTORS
--      }
-+      } :data
- 
-   . = ALIGN(4096);
-   __nosave_begin = .;
-@@ -154,4 +160,6 @@ SECTIONS
-   STABS_DEBUG
- 
-   DWARF_DEBUG
-+
-+  NOTES
- }
-diff -pruN ../orig-linux-2.6.16.29/include/asm-generic/vmlinux.lds.h 
./include/asm-generic/vmlinux.lds.h
---- ../orig-linux-2.6.16.29/include/asm-generic/vmlinux.lds.h  2006-09-12 
19:02:10.000000000 +0100
-+++ ./include/asm-generic/vmlinux.lds.h        2006-09-19 14:06:10.000000000 
+0100
-@@ -152,3 +152,6 @@
-               .stab.index 0 : { *(.stab.index) }                      \
-               .stab.indexstr 0 : { *(.stab.indexstr) }                \
-               .comment 0 : { *(.comment) }
-+
-+#define NOTES                                                         \
-+              .notes : { *(.note.*) } :note
-diff -pruN ../orig-linux-2.6.16.29/include/linux/elfnote.h 
./include/linux/elfnote.h
---- ../orig-linux-2.6.16.29/include/linux/elfnote.h    1970-01-01 
01:00:00.000000000 +0100
-+++ ./include/linux/elfnote.h  2006-09-19 14:06:10.000000000 +0100
-@@ -0,0 +1,88 @@
-+#ifndef _LINUX_ELFNOTE_H
-+#define _LINUX_ELFNOTE_H
-+/*
-+ * Helper macros to generate ELF Note structures, which are put into a
-+ * PT_NOTE segment of the final vmlinux image.  These are useful for
-+ * including name-value pairs of metadata into the kernel binary (or
-+ * modules?) for use by external programs.
-+ *
-+ * Each note has three parts: a name, a type and a desc.  The name is
-+ * intended to distinguish the note's originator, so it would be a
-+ * company, project, subsystem, etc; it must be in a suitable form for
-+ * use in a section name.  The type is an integer which is used to tag
-+ * the data, and is considered to be within the "name" namespace (so
-+ * "FooCo"'s type 42 is distinct from "BarProj"'s type 42).  The
-+ * "desc" field is the actual data.  There are no constraints on the
-+ * desc field's contents, though typically they're fairly small.
-+ *
-+ * All notes from a given NAME are put into a section named
-+ * .note.NAME.  When the kernel image is finally linked, all the notes
-+ * are packed into a single .notes section, which is mapped into the
-+ * PT_NOTE segment.  Because notes for a given name are grouped into
-+ * the same section, they'll all be adjacent the output file.
-+ *
-+ * This file defines macros for both C and assembler use.  Their
-+ * syntax is slightly different, but they're semantically similar.
-+ *
-+ * See the ELF specification for more detail about ELF notes.
-+ */
-+
-+#ifdef __ASSEMBLER__
-+/*
-+ * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
-+ * turn out to be the same size and shape), followed by the name and
-+ * desc data with appropriate padding.  The 'desc' argument includes
-+ * the assembler pseudo op defining the type of the data: .asciz
-+ * "hello, world"
-+ */
-+.macro ELFNOTE name type desc:vararg
-+.pushsection ".note.\name"
-+  .align 4
-+  .long 2f - 1f                       /* namesz */
-+  .long 4f - 3f                       /* descsz */
-+  .long \type
-+1:.asciz "\name"
-+2:.align 4
-+3:\desc
-+4:.align 4
-+.popsection
-+.endm
-+#else /* !__ASSEMBLER__ */
-+#include <linux/elf.h>
-+/*
-+ * Use an anonymous structure which matches the shape of
-+ * Elf{32,64}_Nhdr, but includes the name and desc data.  The size and
-+ * type of name and desc depend on the macro arguments.  "name" must
-+ * be a literal string, and "desc" must be passed by value.  You may
-+ * only define one note per line, since __LINE__ is used to generate
-+ * unique symbols.
-+ */
-+#define _ELFNOTE_PASTE(a,b)   a##b
-+#define _ELFNOTE(size, name, unique, type, desc)                      \
-+      static const struct {                                           \
-+              struct elf##size##_note _nhdr;                          \
-+              unsigned char _name[sizeof(name)]                       \
-+              __attribute__((aligned(sizeof(Elf##size##_Word))));     \
-+              typeof(desc) _desc                                      \
-+                           
__attribute__((aligned(sizeof(Elf##size##_Word)))); \
-+      } _ELFNOTE_PASTE(_note_, unique)                                \
-+              __attribute_used__                                      \
-+              __attribute__((section(".note." name),                  \
-+                             aligned(sizeof(Elf##size##_Word)),       \
-+                             unused)) = {                             \
-+              {                                                       \
-+                      sizeof(name),                                   \
-+                      sizeof(desc),                                   \
-+                      type,                                           \
-+              },                                                      \
-+              name,                                                   \
-+              desc                                                    \
-+      }
-+#define ELFNOTE(size, name, type, desc)               \
-+      _ELFNOTE(size, name, __LINE__, type, desc)
-+
-+#define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc)
-+#define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc)
-+#endif        /* __ASSEMBLER__ */
-+
-+#endif /* _LINUX_ELFNOTE_H */
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
--- 
a/patches/linux-2.6.16.33/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
  Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/vmlinux.lds.S 
./arch/x86_64/kernel/vmlinux.lds.S
---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/vmlinux.lds.S   2006-09-12 
19:02:10.000000000 +0100
-+++ ./arch/x86_64/kernel/vmlinux.lds.S 2006-09-19 14:06:15.000000000 +0100
-@@ -14,6 +14,12 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86
- OUTPUT_ARCH(i386:x86-64)
- ENTRY(phys_startup_64)
- jiffies_64 = jiffies;
-+PHDRS {
-+      text PT_LOAD FLAGS(5);  /* R_E */
-+      data PT_LOAD FLAGS(7);  /* RWE */
-+      user PT_LOAD FLAGS(7);  /* RWE */
-+      note PT_NOTE FLAGS(4);  /* R__ */
-+}
- SECTIONS
- {
-   . = __START_KERNEL;
-@@ -26,7 +32,7 @@ SECTIONS
-       KPROBES_TEXT
-       *(.fixup)
-       *(.gnu.warning)
--      } = 0x9090
-+      } :text = 0x9090
-                               /* out-of-line lock text */
-   .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
- 
-@@ -43,17 +49,10 @@ SECTIONS
-   .data : AT(ADDR(.data) - LOAD_OFFSET) {
-       *(.data)
-       CONSTRUCTORS
--      }
-+      } :data
- 
-   _edata = .;                 /* End of data section */
- 
--  __bss_start = .;            /* BSS */
--  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
--      *(.bss.page_aligned)    
--      *(.bss)
--      }
--  __bss_stop = .;
--
-   . = ALIGN(PAGE_SIZE);
-   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-@@ -75,7 +74,7 @@ SECTIONS
- #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
- 
-   . = VSYSCALL_ADDR;
--  .vsyscall_0 :        AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) }
-+  .vsyscall_0 :        AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
-   __vsyscall_0 = VSYSCALL_VIRT_ADDR;
- 
-   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-@@ -118,7 +117,7 @@ SECTIONS
-   . = ALIGN(8192);            /* init_task */
-   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-       *(.data.init_task)
--  }
-+  } :data
- 
-   . = ALIGN(4096);
-   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-@@ -188,6 +187,14 @@ SECTIONS
-   . = ALIGN(4096);
-   __nosave_end = .;
- 
-+  __bss_start = .;            /* BSS */
-+  . = ALIGN(4096);
-+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-+      *(.bss.page_aligned)
-+      *(.bss)
-+      }
-+  __bss_stop = .;
-+
-   _end = . ;
- 
-   /* Sections to be discarded */
-@@ -201,4 +208,6 @@ SECTIONS
-   STABS_DEBUG
- 
-   DWARF_DEBUG
-+
-+  NOTES
- }
diff -r 18f30d7ef2b8 -r 4be85bb2f54d patches/linux-2.6.16.33/xen-hotplug.patch
--- a/patches/linux-2.6.16.33/xen-hotplug.patch Tue Jan 23 19:06:31 2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/fs/proc/proc_misc.c ./fs/proc/proc_misc.c
---- ../orig-linux-2.6.16.29/fs/proc/proc_misc.c        2006-09-12 
19:02:10.000000000 +0100
-+++ ./fs/proc/proc_misc.c      2006-09-19 14:06:00.000000000 +0100
-@@ -433,7 +433,7 @@ static int show_stat(struct seq_file *p,
-               (unsigned long long)cputime64_to_clock_t(irq),
-               (unsigned long long)cputime64_to_clock_t(softirq),
-               (unsigned long long)cputime64_to_clock_t(steal));
--      for_each_online_cpu(i) {
-+      for_each_cpu(i) {
- 
-               /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
-               user = kstat_cpu(i).cpustat.user;
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.33/xenoprof-generic.patch
--- a/patches/linux-2.6.16.33/xenoprof-generic.patch    Tue Jan 23 19:06:31 
2007 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,662 +0,0 @@
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c 
./drivers/oprofile/buffer_sync.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c     2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/buffer_sync.c   2006-11-06 15:16:52.000000000 -0800
-@@ -6,6 +6,10 @@
-  *
-  * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
-  *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
-  * This is the core of the buffer management. Each
-  * CPU buffer is processed and entered into the
-  * global event buffer. Such processing is necessary
-@@ -38,6 +42,7 @@ static cpumask_t marked_cpus = CPU_MASK_
- static DEFINE_SPINLOCK(task_mortuary);
- static void process_task_mortuary(void);
- 
-+static int cpu_current_domain[NR_CPUS];
- 
- /* Take ownership of the task struct and place it on the
-  * list for processing. Only after two full buffer syncs
-@@ -146,6 +151,11 @@ static void end_sync(void)
- int sync_start(void)
- {
-       int err;
-+      int i;
-+
-+      for (i = 0; i < NR_CPUS; i++) {
-+              cpu_current_domain[i] = COORDINATOR_DOMAIN;
-+      }
- 
-       start_cpu_work();
- 
-@@ -275,15 +285,31 @@ static void add_cpu_switch(int i)
-       last_cookie = INVALID_COOKIE;
- }
- 
--static void add_kernel_ctx_switch(unsigned int in_kernel)
-+static void add_cpu_mode_switch(unsigned int cpu_mode)
- {
-       add_event_entry(ESCAPE_CODE);
--      if (in_kernel)
--              add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
--      else
--              add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
-+      switch (cpu_mode) {
-+      case CPU_MODE_USER:
-+              add_event_entry(USER_ENTER_SWITCH_CODE);
-+              break;
-+      case CPU_MODE_KERNEL:
-+              add_event_entry(KERNEL_ENTER_SWITCH_CODE);
-+              break;
-+      case CPU_MODE_XEN:
-+              add_event_entry(XEN_ENTER_SWITCH_CODE);
-+              break;
-+      default:
-+              break;
-+      }
- }
-- 
-+
-+static void add_domain_switch(unsigned long domain_id)
-+{
-+      add_event_entry(ESCAPE_CODE);
-+      add_event_entry(DOMAIN_SWITCH_CODE);
-+      add_event_entry(domain_id);
-+}
-+
- static void
- add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
- {
-@@ -348,9 +374,9 @@ static int add_us_sample(struct mm_struc
-  * for later lookup from userspace.
-  */
- static int
--add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
-+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
- {
--      if (in_kernel) {
-+      if (cpu_mode >= CPU_MODE_KERNEL) {
-               add_sample_entry(s->eip, s->event);
-               return 1;
-       } else if (mm) {
-@@ -496,15 +522,21 @@ void sync_buffer(int cpu)
-       struct mm_struct *mm = NULL;
-       struct task_struct * new;
-       unsigned long cookie = 0;
--      int in_kernel = 1;
-+      int cpu_mode = 1;
-       unsigned int i;
-       sync_buffer_state state = sb_buffer_start;
-       unsigned long available;
-+      int domain_switch = 0;
- 
-       down(&buffer_sem);
-  
-       add_cpu_switch(cpu);
- 
-+      /* We need to assign the first samples in this CPU buffer to the
-+         same domain that we were processing at the last sync_buffer */
-+      if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
-+              add_domain_switch(cpu_current_domain[cpu]);
-+      }
-       /* Remember, only we can modify tail_pos */
- 
-       available = get_slots(cpu_buf);
-@@ -512,16 +544,18 @@ void sync_buffer(int cpu)
-       for (i = 0; i < available; ++i) {
-               struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
-  
--              if (is_code(s->eip)) {
--                      if (s->event <= CPU_IS_KERNEL) {
--                              /* kernel/userspace switch */
--                              in_kernel = s->event;
-+              if (is_code(s->eip) && !domain_switch) {
-+                      if (s->event <= CPU_MODE_XEN) {
-+                              /* xen/kernel/userspace switch */
-+                              cpu_mode = s->event;
-                               if (state == sb_buffer_start)
-                                       state = sb_sample_start;
--                              add_kernel_ctx_switch(s->event);
-+                              add_cpu_mode_switch(s->event);
-                       } else if (s->event == CPU_TRACE_BEGIN) {
-                               state = sb_bt_start;
-                               add_trace_begin();
-+                      } else if (s->event == CPU_DOMAIN_SWITCH) {
-+                                      domain_switch = 1;                      
        
-                       } else {
-                               struct mm_struct * oldmm = mm;
- 
-@@ -535,11 +569,21 @@ void sync_buffer(int cpu)
-                               add_user_ctx_switch(new, cookie);
-                       }
-               } else {
--                      if (state >= sb_bt_start &&
--                          !add_sample(mm, s, in_kernel)) {
--                              if (state == sb_bt_start) {
--                                      state = sb_bt_ignore;
--                                      
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+                      if (domain_switch) {
-+                              cpu_current_domain[cpu] = s->eip;
-+                              add_domain_switch(s->eip);
-+                              domain_switch = 0;
-+                      } else {
-+                              if (cpu_current_domain[cpu] !=
-+                                  COORDINATOR_DOMAIN) {
-+                                      add_sample_entry(s->eip, s->event);
-+                              }
-+                              else  if (state >= sb_bt_start &&
-+                                  !add_sample(mm, s, cpu_mode)) {
-+                                      if (state == sb_bt_start) {
-+                                              state = sb_bt_ignore;
-+                                              
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+                                      }
-                               }
-                       }
-               }
-@@ -548,6 +592,11 @@ void sync_buffer(int cpu)
-       }
-       release_mm(mm);
- 
-+      /* We reset domain to COORDINATOR at each CPU switch */
-+      if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
-+              add_domain_switch(COORDINATOR_DOMAIN);
-+      }
-+
-       mark_done(cpu);
- 
-       up(&buffer_sem);
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c      2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/cpu_buffer.c    2006-11-06 14:47:55.000000000 -0800
-@@ -6,6 +6,10 @@
-  *
-  * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
-  *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
-  * Each CPU has a local buffer that stores PC value/event
-  * pairs. We also log context switches when we notice them.
-  * Eventually each CPU's buffer is processed into the global
-@@ -34,6 +38,8 @@ static void wq_sync_buffer(void *);
- #define DEFAULT_TIMER_EXPIRE (HZ / 10)
- static int work_enabled;
- 
-+static int32_t current_domain = COORDINATOR_DOMAIN;
-+
- void free_cpu_buffers(void)
- {
-       int i;
-@@ -58,7 +64,7 @@ int alloc_cpu_buffers(void)
-                       goto fail;
-  
-               b->last_task = NULL;
--              b->last_is_kernel = -1;
-+              b->last_cpu_mode = -1;
-               b->tracing = 0;
-               b->buffer_size = buffer_size;
-               b->tail_pos = 0;
-@@ -114,7 +120,7 @@ void cpu_buffer_reset(struct oprofile_cp
-        * collected will populate the buffer with proper
-        * values to initialize the buffer
-        */
--      cpu_buf->last_is_kernel = -1;
-+      cpu_buf->last_cpu_mode = -1;
-       cpu_buf->last_task = NULL;
- }
- 
-@@ -164,13 +170,13 @@ add_code(struct oprofile_cpu_buffer * bu
-  * because of the head/tail separation of the writer and reader
-  * of the CPU buffer.
-  *
-- * is_kernel is needed because on some architectures you cannot
-+ * cpu_mode is needed because on some architectures you cannot
-  * tell if you are in kernel or user space simply by looking at
-- * pc. We tag this in the buffer by generating kernel enter/exit
-- * events whenever is_kernel changes
-+ * pc. We tag this in the buffer by generating kernel/user (and xen)
-+ *  enter events whenever cpu_mode changes
-  */
- static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
--                    int is_kernel, unsigned long event)
-+                    int cpu_mode, unsigned long event)
- {
-       struct task_struct * task;
- 
-@@ -181,18 +187,18 @@ static int log_sample(struct oprofile_cp
-               return 0;
-       }
- 
--      is_kernel = !!is_kernel;
--
-       task = current;
- 
-       /* notice a switch from user->kernel or vice versa */
--      if (cpu_buf->last_is_kernel != is_kernel) {
--              cpu_buf->last_is_kernel = is_kernel;
--              add_code(cpu_buf, is_kernel);
-+      if (cpu_buf->last_cpu_mode != cpu_mode) {
-+              cpu_buf->last_cpu_mode = cpu_mode;
-+              add_code(cpu_buf, cpu_mode);
-       }
--
-+      
-       /* notice a task switch */
--      if (cpu_buf->last_task != task) {
-+      /* if not processing other domain samples */
-+      if ((cpu_buf->last_task != task) &&
-+          (current_domain == COORDINATOR_DOMAIN)) {
-               cpu_buf->last_task = task;
-               add_code(cpu_buf, (unsigned long)task);
-       }
-@@ -269,6 +275,25 @@ void oprofile_add_trace(unsigned long pc
-       add_sample(cpu_buf, pc, 0);
- }
- 
-+int oprofile_add_domain_switch(int32_t domain_id)
-+{
-+      struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
-+
-+      /* should have space for switching into and out of domain 
-+         (2 slots each) plus one sample and one cpu mode switch */
-+      if (((nr_available_slots(cpu_buf) < 6) && 
-+           (domain_id != COORDINATOR_DOMAIN)) ||
-+          (nr_available_slots(cpu_buf) < 2))
-+              return 0;
-+
-+      add_code(cpu_buf, CPU_DOMAIN_SWITCH);
-+      add_sample(cpu_buf, domain_id, 0);
-+
-+      current_domain = domain_id;
-+
-+      return 1;
-+}
-+
- /*
-  * This serves to avoid cpu buffer overflow, and makes sure
-  * the task mortuary progresses
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h 
./drivers/oprofile/cpu_buffer.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h      2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/cpu_buffer.h    2006-11-06 14:47:55.000000000 -0800
-@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
-       volatile unsigned long tail_pos;
-       unsigned long buffer_size;
-       struct task_struct * last_task;
--      int last_is_kernel;
-+      int last_cpu_mode;
-       int tracing;
-       struct op_sample * buffer;
-       unsigned long sample_received;
-@@ -51,7 +51,10 @@ extern struct oprofile_cpu_buffer cpu_bu
- void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
- 
- /* transient events for the CPU buffer -> event buffer */
--#define CPU_IS_KERNEL 1
--#define CPU_TRACE_BEGIN 2
-+#define CPU_MODE_USER           0
-+#define CPU_MODE_KERNEL         1
-+#define CPU_MODE_XEN            2
-+#define CPU_TRACE_BEGIN         3
-+#define CPU_DOMAIN_SWITCH       4
- 
- #endif /* OPROFILE_CPU_BUFFER_H */
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h 
./drivers/oprofile/event_buffer.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h    2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/event_buffer.h  2006-11-06 14:47:55.000000000 -0800
-@@ -29,15 +29,20 @@ void wake_up_buffer_waiter(void);
- #define CPU_SWITCH_CODE               2
- #define COOKIE_SWITCH_CODE            3
- #define KERNEL_ENTER_SWITCH_CODE      4
--#define KERNEL_EXIT_SWITCH_CODE               5
-+#define USER_ENTER_SWITCH_CODE                5
- #define MODULE_LOADED_CODE            6
- #define CTX_TGID_CODE                 7
- #define TRACE_BEGIN_CODE              8
- #define TRACE_END_CODE                        9
-+#define XEN_ENTER_SWITCH_CODE         10
-+#define DOMAIN_SWITCH_CODE            11
-  
- #define INVALID_COOKIE ~0UL
- #define NO_COOKIE 0UL
- 
-+/* Constant used to refer to coordinator domain (Xen) */
-+#define COORDINATOR_DOMAIN -1
-+
- /* add data to the event buffer */
- void add_event_entry(unsigned long data);
-  
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c 
./drivers/oprofile/oprof.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c   2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/oprof.c 2006-11-06 14:47:55.000000000 -0800
-@@ -5,6 +5,10 @@
-  * @remark Read the file COPYING
-  *
-  * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
-+ *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-  */
- 
- #include <linux/kernel.h>
-@@ -19,7 +23,7 @@
- #include "cpu_buffer.h"
- #include "buffer_sync.h"
- #include "oprofile_stats.h"
-- 
-+
- struct oprofile_operations oprofile_ops;
- 
- unsigned long oprofile_started;
-@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
-  */
- static int timer = 0;
- 
-+int oprofile_set_active(int active_domains[], unsigned int adomains)
-+{
-+      int err;
-+
-+      if (!oprofile_ops.set_active)
-+              return -EINVAL;
-+
-+      down(&start_sem);
-+      err = oprofile_ops.set_active(active_domains, adomains);
-+      up(&start_sem);
-+      return err;
-+}
-+
-+int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
-+{
-+      int err;
-+
-+      if (!oprofile_ops.set_passive)
-+              return -EINVAL;
-+
-+      down(&start_sem);
-+      err = oprofile_ops.set_passive(passive_domains, pdomains);
-+      up(&start_sem);
-+      return err;
-+}
-+
- int oprofile_setup(void)
- {
-       int err;
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h 
./drivers/oprofile/oprof.h
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h   2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/oprof.h 2006-11-06 14:47:55.000000000 -0800
-@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
- void oprofile_timer_init(struct oprofile_operations * ops);
- 
- int oprofile_set_backtrace(unsigned long depth);
-+
-+int oprofile_set_active(int active_domains[], unsigned int adomains);
-+int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
-  
- #endif /* OPROF_H */
-diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c 
./drivers/oprofile/oprofile_files.c
---- ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c  2006-11-06 
14:46:52.000000000 -0800
-+++ ./drivers/oprofile/oprofile_files.c        2006-11-06 14:47:55.000000000 
-0800
-@@ -5,15 +5,21 @@
-  * @remark Read the file COPYING
-  *
-  * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
-+ *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.     
-  */
- 
- #include <linux/fs.h>
- #include <linux/oprofile.h>
-+#include <asm/uaccess.h>
-+#include <linux/ctype.h>
- 
- #include "event_buffer.h"
- #include "oprofile_stats.h"
- #include "oprof.h"
-- 
-+
- unsigned long fs_buffer_size = 131072;
- unsigned long fs_cpu_buffer_size = 8192;
- unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file * 
- static struct file_operations dump_fops = {
-       .write          = dump_write,
- };
-- 
-+
-+#define TMPBUFSIZE 512
-+
-+static unsigned int adomains = 0;
-+static int active_domains[MAX_OPROF_DOMAINS + 1];
-+static DEFINE_MUTEX(adom_mutex);
-+
-+static ssize_t adomain_write(struct file * file, char const __user * buf, 
-+                           size_t count, loff_t * offset)
-+{
-+      char *tmpbuf;
-+      char *startp, *endp;
-+      int i;
-+      unsigned long val;
-+      ssize_t retval = count;
-+      
-+      if (*offset)
-+              return -EINVAL; 
-+      if (count > TMPBUFSIZE - 1)
-+              return -EINVAL;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      if (copy_from_user(tmpbuf, buf, count)) {
-+              kfree(tmpbuf);
-+              return -EFAULT;
-+      }
-+      tmpbuf[count] = 0;
-+
-+      mutex_lock(&adom_mutex);
-+
-+      startp = tmpbuf;
-+      /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
-+      for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
-+              val = simple_strtoul(startp, &endp, 0);
-+              if (endp == startp)
-+                      break;
-+              while (ispunct(*endp) || isspace(*endp))
-+                      endp++;
-+              active_domains[i] = val;
-+              if (active_domains[i] != val)
-+                      /* Overflow, force error below */
-+                      i = MAX_OPROF_DOMAINS + 1;
-+              startp = endp;
-+      }
-+      /* Force error on trailing junk */
-+      adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
-+
-+      kfree(tmpbuf);
-+
-+      if (adomains > MAX_OPROF_DOMAINS
-+          || oprofile_set_active(active_domains, adomains)) {
-+              adomains = 0;
-+              retval = -EINVAL;
-+      }
-+
-+      mutex_unlock(&adom_mutex);
-+      return retval;
-+}
-+
-+static ssize_t adomain_read(struct file * file, char __user * buf, 
-+                          size_t count, loff_t * offset)
-+{
-+      char * tmpbuf;
-+      size_t len;
-+      int i;
-+      ssize_t retval;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      mutex_lock(&adom_mutex);
-+
-+      len = 0;
-+      for (i = 0; i < adomains; i++)
-+              len += snprintf(tmpbuf + len,
-+                              len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
-+                              "%u ", active_domains[i]);
-+      WARN_ON(len > TMPBUFSIZE);
-+      if (len != 0 && len <= TMPBUFSIZE)
-+              tmpbuf[len-1] = '\n';
-+
-+      mutex_unlock(&adom_mutex);
-+
-+      retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
-+
-+      kfree(tmpbuf);
-+      return retval;
-+}
-+
-+
-+static struct file_operations active_domain_ops = {
-+      .read           = adomain_read,
-+      .write          = adomain_write,
-+};
-+
-+static unsigned int pdomains = 0;
-+static int passive_domains[MAX_OPROF_DOMAINS];
-+static DEFINE_MUTEX(pdom_mutex);
-+
-+static ssize_t pdomain_write(struct file * file, char const __user * buf, 
-+                           size_t count, loff_t * offset)
-+{
-+      char *tmpbuf;
-+      char *startp, *endp;
-+      int i;
-+      unsigned long val;
-+      ssize_t retval = count;
-+      
-+      if (*offset)
-+              return -EINVAL; 
-+      if (count > TMPBUFSIZE - 1)
-+              return -EINVAL;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      if (copy_from_user(tmpbuf, buf, count)) {
-+              kfree(tmpbuf);
-+              return -EFAULT;
-+      }
-+      tmpbuf[count] = 0;
-+
-+      mutex_lock(&pdom_mutex);
-+
-+      startp = tmpbuf;
-+      /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
-+      for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
-+              val = simple_strtoul(startp, &endp, 0);
-+              if (endp == startp)
-+                      break;
-+              while (ispunct(*endp) || isspace(*endp))
-+                      endp++;
-+              passive_domains[i] = val;
-+              if (passive_domains[i] != val)
-+                      /* Overflow, force error below */
-+                      i = MAX_OPROF_DOMAINS + 1;
-+              startp = endp;
-+      }
-+      /* Force error on trailing junk */
-+      pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
-+
-+      kfree(tmpbuf);
-+
-+      if (pdomains > MAX_OPROF_DOMAINS
-+          || oprofile_set_passive(passive_domains, pdomains)) {
-+              pdomains = 0;
-+              retval = -EINVAL;
-+      }
-+
-+      mutex_unlock(&pdom_mutex);
-+      return retval;
-+}
-+
-+static ssize_t pdomain_read(struct file * file, char __user * buf, 
-+                          size_t count, loff_t * offset)
-+{
-+      char * tmpbuf;
-+      size_t len;
-+      int i;
-+      ssize_t retval;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      mutex_lock(&pdom_mutex);
-+
-+      len = 0;
-+      for (i = 0; i < pdomains; i++)
-+              len += snprintf(tmpbuf + len,
-+                              len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
-+                              "%u ", passive_domains[i]);
-+      WARN_ON(len > TMPBUFSIZE);
-+      if (len != 0 && len <= TMPBUFSIZE)
-+              tmpbuf[len-1] = '\n';
-+
-+      mutex_unlock(&pdom_mutex);
-+
-+      retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
-+
-+      kfree(tmpbuf);
-+      return retval;
-+}
-+
-+static struct file_operations passive_domain_ops = {
-+      .read           = pdomain_read,
-+      .write          = pdomain_write,
-+};
-+
- void oprofile_create_files(struct super_block * sb, struct dentry * root)
- {
-       oprofilefs_create_file(sb, root, "enable", &enable_fops);
-       oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
-+      oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
-+      oprofilefs_create_file(sb, root, "passive_domains", 
&passive_domain_ops);
-       oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
-       oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
-       oprofilefs_create_ulong(sb, root, "buffer_watershed", 
&fs_buffer_watershed);
-diff -pruN ../orig-linux-2.6.16.29/include/linux/oprofile.h 
./include/linux/oprofile.h
---- ../orig-linux-2.6.16.29/include/linux/oprofile.h   2006-11-06 
14:46:42.000000000 -0800
-+++ ./include/linux/oprofile.h 2006-11-06 14:47:55.000000000 -0800
-@@ -16,6 +16,8 @@
- #include <linux/types.h>
- #include <linux/spinlock.h>
- #include <asm/atomic.h>
-+
-+#include <xen/interface/xenoprof.h>
-  
- struct super_block;
- struct dentry;
-@@ -27,6 +29,11 @@ struct oprofile_operations {
-       /* create any necessary configuration files in the oprofile fs.
-        * Optional. */
-       int (*create_files)(struct super_block * sb, struct dentry * root);
-+      /* setup active domains with Xen */
-+      int (*set_active)(int *active_domains, unsigned int adomains);
-+        /* setup passive domains with Xen */
-+        int (*set_passive)(int *passive_domains, unsigned int pdomains);
-+      
-       /* Do any necessary interrupt setup. Optional. */
-       int (*setup)(void);
-       /* Do any necessary interrupt shutdown. Optional. */
-@@ -68,6 +75,8 @@ void oprofile_add_pc(unsigned long pc, i
- /* add a backtrace entry, to be called from the ->backtrace callback */
- void oprofile_add_trace(unsigned long eip);
- 
-+/* add a domain switch entry */
-+int oprofile_add_domain_switch(int32_t domain_id);
- 
- /**
-  * Create a file of the given name as a child of the given root, with
diff -r 18f30d7ef2b8 -r 4be85bb2f54d 
patches/linux-2.6.16.38/blktap-aio-16_03_06.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.38/blktap-aio-16_03_06.patch Mon Jan 29 10:00:33 
2007 +0000
@@ -0,0 +1,294 @@
+diff -pruN ../orig-linux-2.6.16.29/fs/aio.c ./fs/aio.c
+--- ../orig-linux-2.6.16.29/fs/aio.c   2006-09-12 19:02:10.000000000 +0100
++++ ./fs/aio.c 2006-09-19 13:58:49.000000000 +0100
+@@ -34,6 +34,11 @@
+ #include <asm/uaccess.h>
+ #include <asm/mmu_context.h>
+ 
++#ifdef CONFIG_EPOLL
++#include <linux/poll.h>
++#include <linux/eventpoll.h>
++#endif
++
+ #if DEBUG > 1
+ #define dprintk               printk
+ #else
+@@ -1016,6 +1021,10 @@ put_rq:
+       if (waitqueue_active(&ctx->wait))
+               wake_up(&ctx->wait);
+ 
++#ifdef CONFIG_EPOLL
++      if (ctx->file && waitqueue_active(&ctx->poll_wait))
++              wake_up(&ctx->poll_wait);
++#endif
+       if (ret)
+               put_ioctx(ctx);
+ 
+@@ -1025,6 +1034,8 @@ put_rq:
+ /* aio_read_evt
+  *    Pull an event off of the ioctx's event ring.  Returns the number of 
+  *    events fetched (0 or 1 ;-)
++ *    If ent parameter is 0, just returns the number of events that would
++ *    be fetched.
+  *    FIXME: make this use cmpxchg.
+  *    TODO: make the ringbuffer user mmap()able (requires FIXME).
+  */
+@@ -1047,13 +1058,18 @@ static int aio_read_evt(struct kioctx *i
+ 
+       head = ring->head % info->nr;
+       if (head != ring->tail) {
+-              struct io_event *evp = aio_ring_event(info, head, KM_USER1);
+-              *ent = *evp;
+-              head = (head + 1) % info->nr;
+-              smp_mb(); /* finish reading the event before updatng the head */
+-              ring->head = head;
+-              ret = 1;
+-              put_aio_ring_event(evp, KM_USER1);
++              if (ent) { /* event requested */
++                      struct io_event *evp =
++                              aio_ring_event(info, head, KM_USER1);
++                      *ent = *evp;
++                      head = (head + 1) % info->nr;
++                      /* finish reading the event before updatng the head */
++                      smp_mb();
++                      ring->head = head;
++                      ret = 1;
++                      put_aio_ring_event(evp, KM_USER1);
++              } else /* only need to know availability */
++                      ret = 1;
+       }
+       spin_unlock(&info->ring_lock);
+ 
+@@ -1236,9 +1252,78 @@ static void io_destroy(struct kioctx *io

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.0.4-testing] [LINUX] Update to 2.6.16.38 point release., Xen patchbot-3.0.4-testing <=