WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] Update to Linux 2.6.16-rc4.

# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 1c7145a5bb434413204a3ce4114de7f58fbb9029
# Parent  a05e56904e7e5e86aae5a2e022621caaf7b3a6f5
Update to Linux 2.6.16-rc4.

Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r a05e56904e7e -r 1c7145a5bb43 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen     Mon Feb 20 23:01:50 2006
+++ b/buildconfigs/mk.linux-2.6-xen     Tue Feb 21 11:19:13 2006
@@ -2,8 +2,8 @@
 OS           = linux
 
 LINUX_SERIES = 2.6
-LINUX_VER    = 2.6.16-rc3
-LINUX_SRCS = linux-2.6.15.tar.bz2 patch-2.6.16-rc3.bz2
+LINUX_VER    = 2.6.16-rc4
+LINUX_SRCS = linux-2.6.15.tar.bz2 patch-2.6.16-rc4.bz2
 LINUX_PDIR = linux-$(LINUX_VER)
 
 EXTRAVERSION ?= xen
@@ -34,7 +34,7 @@
        touch $(@D)/.hgskip
        touch $@
 
-pristine-linux-%.16-rc3/.valid-pristine: pristine-$(LINUX_PDIR)/.valid-srcs
+pristine-linux-%.16-rc4/.valid-pristine: pristine-$(LINUX_PDIR)/.valid-srcs
        touch $@ # update timestamp to avoid rebuild
 
 $(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
diff -r a05e56904e7e -r 1c7145a5bb43 
linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c     Mon Feb 20 
23:01:50 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c     Tue Feb 21 
11:19:13 2006
@@ -30,6 +30,9 @@
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
 #include <linux/sysdev.h>
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+#endif
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -309,6 +312,8 @@
    Can be overwritten with "apic"
 
    And another hack to disable the IOMMU on VIA chipsets.
+
+   ... and others. Really should move this somewhere else.
 
    Kludge-O-Rama. */
 void __init check_ioapic(void) 
@@ -358,6 +363,17 @@
 #ifndef CONFIG_XEN
                                        if (apic_runs_main_timer != 0)
                                                break;
+#ifdef CONFIG_ACPI
+                                       /* Don't do this for laptops right
+                                          right now because their timer
+                                          doesn't necessarily tick in C2/3 */
+                                       if (acpi_fadt.revision >= 3 &&
+                       (acpi_fadt.plvl2_lat + acpi_fadt.plvl3_lat) < 1100) {
+                                               printk(KERN_INFO
+"ATI board detected, but seems to be a laptop. Timer might be shakey, 
sorry\n");
+                                               break;
+                                       }
+#endif                                 
                                        printk(KERN_INFO
             "ATI board detected. Using APIC/PM timer.\n");
                                        apic_runs_main_timer = 1;
diff -r a05e56904e7e -r 1c7145a5bb43 
linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c     Mon Feb 20 
23:01:50 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c     Tue Feb 21 
11:19:13 2006
@@ -295,9 +295,9 @@
 
        memcpy(str,mpc->mpc_productid,12);
        str[12]=0;
-       printk(KERN_INFO "Product ID: %s ",str);
-
-       printk(KERN_INFO "APIC at: 0x%X\n",mpc->mpc_lapic);
+       printk("Product ID: %s ",str);
+
+       printk("APIC at: 0x%X\n",mpc->mpc_lapic);
 
        /* save the local APIC address, it might be non-default */
        if (!acpi_lapic)
diff -r a05e56904e7e -r 1c7145a5bb43 linux-2.6-xen-sparse/drivers/char/tty_io.c
--- a/linux-2.6-xen-sparse/drivers/char/tty_io.c        Mon Feb 20 23:01:50 2006
+++ b/linux-2.6-xen-sparse/drivers/char/tty_io.c        Tue Feb 21 11:19:13 2006
@@ -1843,7 +1843,6 @@
                tty_closing = tty->count <= 1;
                o_tty_closing = o_tty &&
                        (o_tty->count <= (pty_master ? 1 : 0));
-               up(&tty_sem);
                do_sleep = 0;
 
                if (tty_closing) {
@@ -1871,6 +1870,7 @@
 
                printk(KERN_WARNING "release_dev: %s: read/write wait queue "
                                    "active!\n", tty_name(tty, buf));
+               up(&tty_sem);
                schedule();
        }       
 
@@ -1879,8 +1879,6 @@
         * both sides, and we've completed the last operation that could 
         * block, so it's safe to proceed with closing.
         */
-        
-       down(&tty_sem);
        if (pty_master) {
                if (--o_tty->count < 0) {
                        printk(KERN_WARNING "release_dev: bad pty slave count "
@@ -1894,7 +1892,6 @@
                       tty->count, tty_name(tty, buf));
                tty->count = 0;
        }
-       up(&tty_sem);
        
        /*
         * We've decremented tty->count, so we need to remove this file
@@ -1938,6 +1935,8 @@
                        } while_each_task_pid(o_tty->session, PIDTYPE_SID, p);
                read_unlock(&tasklist_lock);
        }
+
+       up(&tty_sem);
 
        /* check whether both sides are closing ... */
        if (!tty_closing || (o_tty && !o_tty_closing))
diff -r a05e56904e7e -r 1c7145a5bb43 linux-2.6-xen-sparse/drivers/serial/Kconfig
--- a/linux-2.6-xen-sparse/drivers/serial/Kconfig       Mon Feb 20 23:01:50 2006
+++ b/linux-2.6-xen-sparse/drivers/serial/Kconfig       Tue Feb 21 11:19:13 2006
@@ -903,8 +903,8 @@
          something like this to connect more than two modems to your Linux
          box, for instance in order to become a dial-in server. This driver
          supports PCI boards only.
-         If you have a card like this, say Y here and read the file
-         <file:Documentation/jsm.txt>.
+
+         If you have a card like this, say Y here, otherwise say N.
 
          To compile this driver as a module, choose M here: the
          module will be called jsm.
diff -r a05e56904e7e -r 1c7145a5bb43 linux-2.6-xen-sparse/include/linux/mm.h
--- a/linux-2.6-xen-sparse/include/linux/mm.h   Mon Feb 20 23:01:50 2006
+++ b/linux-2.6-xen-sparse/include/linux/mm.h   Tue Feb 21 11:19:13 2006
@@ -1064,5 +1064,7 @@
 void drop_pagecache(void);
 void drop_slab(void);
 
+extern int randomize_va_space;
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff -r a05e56904e7e -r 1c7145a5bb43 linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Mon Feb 20 23:01:50 2006
+++ b/linux-2.6-xen-sparse/mm/memory.c  Tue Feb 21 11:19:13 2006
@@ -81,6 +81,16 @@
 EXPORT_SYMBOL(num_physpages);
 EXPORT_SYMBOL(high_memory);
 EXPORT_SYMBOL(vmalloc_earlyreserve);
+
+int randomize_va_space __read_mostly = 1;
+
+static int __init disable_randmaps(char *s)
+{
+       randomize_va_space = 0;
+       return 0;
+}
+__setup("norandmaps", disable_randmaps);
+
 
 /*
  * If a p?d_bad entry is found while walking page tables, report
diff -r a05e56904e7e -r 1c7145a5bb43 linux-2.6-xen-sparse/mm/page_alloc.c
--- a/linux-2.6-xen-sparse/mm/page_alloc.c      Mon Feb 20 23:01:50 2006
+++ b/linux-2.6-xen-sparse/mm/page_alloc.c      Tue Feb 21 11:19:13 2006
@@ -56,6 +56,7 @@
 int percpu_pagelist_fraction;
 
 static void fastcall free_hot_cold_page(struct page *page, int cold);
+static void __free_pages_ok(struct page *page, unsigned int order);
 
 /*
  * results with 256, 32 in the lowmem_reserve sysctl:
@@ -169,20 +170,23 @@
  * All pages have PG_compound set.  All pages have their ->private pointing at
  * the head page (even the head page has this).
  *
- * The first tail page's ->mapping, if non-zero, holds the address of the
- * compound page's put_page() function.
- *
- * The order of the allocation is stored in the first tail page's ->index
- * This is only for debug at present.  This usage means that zero-order pages
- * may not be compound.
- */
+ * The first tail page's ->lru.next holds the address of the compound page's
+ * put_page() function.  Its ->lru.prev holds the order of allocation.
+ * This usage means that zero-order pages may not be compound.
+ */
+
+static void free_compound_page(struct page *page)
+{
+       __free_pages_ok(page, (unsigned long)page[1].lru.prev);
+}
+
 static void prep_compound_page(struct page *page, unsigned long order)
 {
        int i;
        int nr_pages = 1 << order;
 
-       page[1].mapping = NULL;
-       page[1].index = order;
+       page[1].lru.next = (void *)free_compound_page;  /* set dtor */
+       page[1].lru.prev = (void *)order;
        for (i = 0; i < nr_pages; i++) {
                struct page *p = page + i;
 
@@ -196,7 +200,7 @@
        int i;
        int nr_pages = 1 << order;
 
-       if (unlikely(page[1].index != order))
+       if (unlikely((unsigned long)page[1].lru.prev != order))
                bad_page(page);
 
        for (i = 0; i < nr_pages; i++) {
@@ -1539,28 +1543,28 @@
  */
 static int __init find_next_best_node(int node, nodemask_t *used_node_mask)
 {
-       int i, n, val;
+       int n, val;
        int min_val = INT_MAX;
        int best_node = -1;
 
-       for_each_online_node(i) {
+       /* Use the local node if we haven't already */
+       if (!node_isset(node, *used_node_mask)) {
+               node_set(node, *used_node_mask);
+               return node;
+       }
+
+       for_each_online_node(n) {
                cpumask_t tmp;
-
-               /* Start from local node */
-               n = (node+i) % num_online_nodes();
 
                /* Don't want a node to appear more than once */
                if (node_isset(n, *used_node_mask))
                        continue;
 
-               /* Use the local node if we haven't already */
-               if (!node_isset(node, *used_node_mask)) {
-                       best_node = node;
-                       break;
-               }
-
                /* Use the distance array to find the distance */
                val = node_distance(node, n);
+
+               /* Penalize nodes under us ("prefer the next node") */
+               val += (n < node);
 
                /* Give preference to headless and unused nodes */
                tmp = node_to_cpumask(n);
diff -r a05e56904e7e -r 1c7145a5bb43 
patches/linux-2.6.16-rc4/i386-mach-io-check-nmi.patch
--- /dev/null   Mon Feb 20 23:01:50 2006
+++ b/patches/linux-2.6.16-rc4/i386-mach-io-check-nmi.patch     Tue Feb 21 
11:19:13 2006
@@ -0,0 +1,45 @@
+diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/traps.c 
./arch/i386/kernel/traps.c
+--- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/traps.c      2006-02-15 
20:38:51.000000000 +0000
++++ ./arch/i386/kernel/traps.c 2006-02-15 20:40:43.000000000 +0000
+@@ -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 
../pristine-linux-2.6.16-rc3/include/asm-i386/mach-default/mach_traps.h 
./include/asm-i386/mach-default/mach_traps.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/mach-default/mach_traps.h    
2006-01-03 03:21:10.000000000 +0000
++++ ./include/asm-i386/mach-default/mach_traps.h       2006-02-15 
20:40:43.000000000 +0000
+@@ -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 a05e56904e7e -r 1c7145a5bb43 patches/linux-2.6.16-rc4/net-csum.patch
--- /dev/null   Mon Feb 20 23:01:50 2006
+++ b/patches/linux-2.6.16-rc4/net-csum.patch   Tue Feb 21 11:19:13 2006
@@ -0,0 +1,41 @@
+diff -pruN 
../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c 
./net/ipv4/netfilter/ip_nat_proto_tcp.c
+--- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c    
2006-02-02 17:39:51.000000000 +0000
++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c    2006-02-02 17:44:18.000000000 
+0000
+@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
+       if (hdrsize < sizeof(*hdr))
+               return 1;
+ 
+-      hdr->check = ip_nat_cheat_check(~oldip, newip,
++      if ((*pskb)->proto_csum_blank) {
++              hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
++      } else {
++              hdr->check = ip_nat_cheat_check(~oldip, newip,
+                                       ip_nat_cheat_check(oldport ^ 0xFFFF,
+                                                          newport,
+                                                          hdr->check));
++      }
+       return 1;
+ }
+
+diff -pruN 
../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c 
./net/ipv4/netfilter/ip_nat_proto_udp.c
+--- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c    
2006-02-02 17:39:51.000000000 +0000
++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c    2006-02-02 17:44:18.000000000 
+0000
+@@ -113,11 +113,16 @@ 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 */
++              if ((*pskb)->proto_csum_blank) {
++                      hdr->check = ip_nat_cheat_check(oldip, ~newip, 
hdr->check);
++              } else {
++                      hdr->check = ip_nat_cheat_check(~oldip, newip,
+                                       ip_nat_cheat_check(*portptr ^ 0xFFFF,
+                                                          newport,
+                                                          hdr->check));
++              }
++      }
+       *portptr = newport;
+       return 1;
+ }
diff -r a05e56904e7e -r 1c7145a5bb43 patches/linux-2.6.16-rc4/pmd-shared.patch
--- /dev/null   Mon Feb 20 23:01:50 2006
+++ b/patches/linux-2.6.16-rc4/pmd-shared.patch Tue Feb 21 11:19:13 2006
@@ -0,0 +1,111 @@
+diff -pruN ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pageattr.c 
./arch/i386/mm/pageattr.c
+--- ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pageattr.c  2006-02-02 
17:39:29.000000000 +0000
++++ ./arch/i386/mm/pageattr.c  2006-02-02 17:45:14.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pgtable.c 
./arch/i386/mm/pgtable.c
+--- ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pgtable.c   2006-01-03 
03:21:10.000000000 +0000
++++ ./arch/i386/mm/pgtable.c   2006-02-02 17:45:14.000000000 +0000
+@@ -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 
../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-2level-defs.h 
./include/asm-i386/pgtable-2level-defs.h
+--- ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-2level-defs.h   
2006-01-03 03:21:10.000000000 +0000
++++ ./include/asm-i386/pgtable-2level-defs.h   2006-02-02 17:45:14.000000000 
+0000
+@@ -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 
../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-3level-defs.h 
./include/asm-i386/pgtable-3level-defs.h
+--- ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-3level-defs.h   
2006-01-03 03:21:10.000000000 +0000
++++ ./include/asm-i386/pgtable-3level-defs.h   2006-02-02 17:45:14.000000000 
+0000
+@@ -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 a05e56904e7e -r 1c7145a5bb43 patches/linux-2.6.16-rc4/smp-alts.patch
--- /dev/null   Mon Feb 20 23:01:50 2006
+++ b/patches/linux-2.6.16-rc4/smp-alts.patch   Tue Feb 21 11:19:13 2006
@@ -0,0 +1,591 @@
+diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/Kconfig ./arch/i386/Kconfig
+--- ../pristine-linux-2.6.16-rc3/arch/i386/Kconfig     2006-02-15 
20:38:51.000000000 +0000
++++ ./arch/i386/Kconfig        2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/Makefile 
./arch/i386/kernel/Makefile
+--- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/Makefile     2006-02-15 
20:38:51.000000000 +0000
++++ ./arch/i386/kernel/Makefile        2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpalts.c 
./arch/i386/kernel/smpalts.c
+--- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpalts.c    1970-01-01 
01:00:00.000000000 +0100
++++ ./arch/i386/kernel/smpalts.c       2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpboot.c 
./arch/i386/kernel/smpboot.c
+--- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpboot.c    2006-02-15 
20:38:51.000000000 +0000
++++ ./arch/i386/kernel/smpboot.c       2006-02-15 20:45:57.000000000 +0000
+@@ -1214,6 +1214,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);
+@@ -1392,6 +1397,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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/vmlinux.lds.S 
./arch/i386/kernel/vmlinux.lds.S
+--- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/vmlinux.lds.S        
2006-01-03 03:21:10.000000000 +0000
++++ ./arch/i386/kernel/vmlinux.lds.S   2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/atomic.h 
./include/asm-i386/atomic.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/atomic.h     2006-02-15 
20:38:57.000000000 +0000
++++ ./include/asm-i386/atomic.h        2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/bitops.h 
./include/asm-i386/bitops.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/bitops.h     2006-02-15 
20:38:57.000000000 +0000
++++ ./include/asm-i386/bitops.h        2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/futex.h 
./include/asm-i386/futex.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/futex.h      2006-02-15 
20:38:57.000000000 +0000
++++ ./include/asm-i386/futex.h 2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/rwsem.h 
./include/asm-i386/rwsem.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/rwsem.h      2006-01-03 
03:21:10.000000000 +0000
++++ ./include/asm-i386/rwsem.h 2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/smp_alt.h 
./include/asm-i386/smp_alt.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/smp_alt.h    1970-01-01 
01:00:00.000000000 +0100
++++ ./include/asm-i386/smp_alt.h       2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/spinlock.h 
./include/asm-i386/spinlock.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/spinlock.h   2006-01-03 
03:21:10.000000000 +0000
++++ ./include/asm-i386/spinlock.h      2006-02-15 20:45:57.000000000 +0000
+@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/system.h 
./include/asm-i386/system.h
+--- ../pristine-linux-2.6.16-rc3/include/asm-i386/system.h     2006-02-15 
20:38:57.000000000 +0000
++++ ./include/asm-i386/system.h        2006-02-15 20:45:57.000000000 +0000
+@@ -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 a05e56904e7e -r 1c7145a5bb43 
patches/linux-2.6.16-rc3/i386-mach-io-check-nmi.patch
--- a/patches/linux-2.6.16-rc3/i386-mach-io-check-nmi.patch     Mon Feb 20 
23:01:50 2006
+++ /dev/null   Tue Feb 21 11:19:13 2006
@@ -1,45 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/kernel/traps.c 
./arch/i386/kernel/traps.c
---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/traps.c      2006-02-15 
20:38:51.000000000 +0000
-+++ ./arch/i386/kernel/traps.c 2006-02-15 20:40:43.000000000 +0000
-@@ -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 
../pristine-linux-2.6.16-rc3/include/asm-i386/mach-default/mach_traps.h 
./include/asm-i386/mach-default/mach_traps.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/mach-default/mach_traps.h    
2006-01-03 03:21:10.000000000 +0000
-+++ ./include/asm-i386/mach-default/mach_traps.h       2006-02-15 
20:40:43.000000000 +0000
-@@ -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 a05e56904e7e -r 1c7145a5bb43 patches/linux-2.6.16-rc3/net-csum.patch
--- a/patches/linux-2.6.16-rc3/net-csum.patch   Mon Feb 20 23:01:50 2006
+++ /dev/null   Tue Feb 21 11:19:13 2006
@@ -1,41 +0,0 @@
-diff -pruN 
../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c 
./net/ipv4/netfilter/ip_nat_proto_tcp.c
---- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c    
2006-02-02 17:39:51.000000000 +0000
-+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c    2006-02-02 17:44:18.000000000 
+0000
-@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
-       if (hdrsize < sizeof(*hdr))
-               return 1;
- 
--      hdr->check = ip_nat_cheat_check(~oldip, newip,
-+      if ((*pskb)->proto_csum_blank) {
-+              hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+      } else {
-+              hdr->check = ip_nat_cheat_check(~oldip, newip,
-                                       ip_nat_cheat_check(oldport ^ 0xFFFF,
-                                                          newport,
-                                                          hdr->check));
-+      }
-       return 1;
- }
-
-diff -pruN 
../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c 
./net/ipv4/netfilter/ip_nat_proto_udp.c
---- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c    
2006-02-02 17:39:51.000000000 +0000
-+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c    2006-02-02 17:44:18.000000000 
+0000
-@@ -113,11 +113,16 @@ 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 */
-+              if ((*pskb)->proto_csum_blank) {
-+                      hdr->check = ip_nat_cheat_check(oldip, ~newip, 
hdr->check);
-+              } else {
-+                      hdr->check = ip_nat_cheat_check(~oldip, newip,
-                                       ip_nat_cheat_check(*portptr ^ 0xFFFF,
-                                                          newport,
-                                                          hdr->check));
-+              }
-+      }
-       *portptr = newport;
-       return 1;
- }
diff -r a05e56904e7e -r 1c7145a5bb43 patches/linux-2.6.16-rc3/pmd-shared.patch
--- a/patches/linux-2.6.16-rc3/pmd-shared.patch Mon Feb 20 23:01:50 2006
+++ /dev/null   Tue Feb 21 11:19:13 2006
@@ -1,111 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pageattr.c 
./arch/i386/mm/pageattr.c
---- ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pageattr.c  2006-02-02 
17:39:29.000000000 +0000
-+++ ./arch/i386/mm/pageattr.c  2006-02-02 17:45:14.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pgtable.c 
./arch/i386/mm/pgtable.c
---- ../pristine-linux-2.6.16-rc1-git4/arch/i386/mm/pgtable.c   2006-01-03 
03:21:10.000000000 +0000
-+++ ./arch/i386/mm/pgtable.c   2006-02-02 17:45:14.000000000 +0000
-@@ -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 
../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-2level-defs.h 
./include/asm-i386/pgtable-2level-defs.h
---- ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-2level-defs.h   
2006-01-03 03:21:10.000000000 +0000
-+++ ./include/asm-i386/pgtable-2level-defs.h   2006-02-02 17:45:14.000000000 
+0000
-@@ -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 
../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-3level-defs.h 
./include/asm-i386/pgtable-3level-defs.h
---- ../pristine-linux-2.6.16-rc1-git4/include/asm-i386/pgtable-3level-defs.h   
2006-01-03 03:21:10.000000000 +0000
-+++ ./include/asm-i386/pgtable-3level-defs.h   2006-02-02 17:45:14.000000000 
+0000
-@@ -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 a05e56904e7e -r 1c7145a5bb43 patches/linux-2.6.16-rc3/smp-alts.patch
--- a/patches/linux-2.6.16-rc3/smp-alts.patch   Mon Feb 20 23:01:50 2006
+++ /dev/null   Tue Feb 21 11:19:13 2006
@@ -1,591 +0,0 @@
-diff -pruN ../pristine-linux-2.6.16-rc3/arch/i386/Kconfig ./arch/i386/Kconfig
---- ../pristine-linux-2.6.16-rc3/arch/i386/Kconfig     2006-02-15 
20:38:51.000000000 +0000
-+++ ./arch/i386/Kconfig        2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/Makefile 
./arch/i386/kernel/Makefile
---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/Makefile     2006-02-15 
20:38:51.000000000 +0000
-+++ ./arch/i386/kernel/Makefile        2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpalts.c 
./arch/i386/kernel/smpalts.c
---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpalts.c    1970-01-01 
01:00:00.000000000 +0100
-+++ ./arch/i386/kernel/smpalts.c       2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpboot.c 
./arch/i386/kernel/smpboot.c
---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/smpboot.c    2006-02-15 
20:38:51.000000000 +0000
-+++ ./arch/i386/kernel/smpboot.c       2006-02-15 20:45:57.000000000 +0000
-@@ -1214,6 +1214,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);
-@@ -1392,6 +1397,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 ../pristine-linux-2.6.16-rc3/arch/i386/kernel/vmlinux.lds.S 
./arch/i386/kernel/vmlinux.lds.S
---- ../pristine-linux-2.6.16-rc3/arch/i386/kernel/vmlinux.lds.S        
2006-01-03 03:21:10.000000000 +0000
-+++ ./arch/i386/kernel/vmlinux.lds.S   2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/atomic.h 
./include/asm-i386/atomic.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/atomic.h     2006-02-15 
20:38:57.000000000 +0000
-+++ ./include/asm-i386/atomic.h        2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/bitops.h 
./include/asm-i386/bitops.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/bitops.h     2006-02-15 
20:38:57.000000000 +0000
-+++ ./include/asm-i386/bitops.h        2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/futex.h 
./include/asm-i386/futex.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/futex.h      2006-02-15 
20:38:57.000000000 +0000
-+++ ./include/asm-i386/futex.h 2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/rwsem.h 
./include/asm-i386/rwsem.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/rwsem.h      2006-01-03 
03:21:10.000000000 +0000
-+++ ./include/asm-i386/rwsem.h 2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/smp_alt.h 
./include/asm-i386/smp_alt.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/smp_alt.h    1970-01-01 
01:00:00.000000000 +0100
-+++ ./include/asm-i386/smp_alt.h       2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/spinlock.h 
./include/asm-i386/spinlock.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/spinlock.h   2006-01-03 
03:21:10.000000000 +0000
-+++ ./include/asm-i386/spinlock.h      2006-02-15 20:45:57.000000000 +0000
-@@ -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 ../pristine-linux-2.6.16-rc3/include/asm-i386/system.h 
./include/asm-i386/system.h
---- ../pristine-linux-2.6.16-rc3/include/asm-i386/system.h     2006-02-15 
20:38:57.000000000 +0000
-+++ ./include/asm-i386/system.h        2006-02-15 20:45:57.000000000 +0000
-@@ -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()

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Update to Linux 2.6.16-rc4., Xen patchbot -unstable <=