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

[Xen-changelog] [xen-3.0.4-testing] [LINUX] Update to 2.6.16.38 point release.



# 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


 


Rackspace

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