Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 7 Apr 2010 18:02:23 +0000 (11:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 7 Apr 2010 18:02:23 +0000 (11:02 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-tip:
  x86: Fix double enable_IR_x2apic() call on SMP kernel on !SMP boards
  x86: Increase CONFIG_NODES_SHIFT max to 10
  ibft, x86: Change reserve_ibft_region() to find_ibft_region()
  x86, hpet: Fix bug in RTC emulation
  x86, hpet: Erratum workaround for read after write of HPET comparator
  bootmem, x86: Fix 32bit numa system without RAM on node 0
  nobootmem, x86: Fix 32bit numa system without RAM on node 0
  x86: Handle overlapping mptables
  x86: Make e820_remove_range to handle all covered case
  x86-32, resume: do a global tlb flush in S4 resume

1  2 
arch/x86/kernel/hpet.c
arch/x86/kernel/setup.c
drivers/firmware/iscsi_ibft_find.c
mm/bootmem.c

diff --combined arch/x86/kernel/hpet.c
@@@ -4,7 -4,6 +4,7 @@@
  #include <linux/sysdev.h>
  #include <linux/delay.h>
  #include <linux/errno.h>
 +#include <linux/slab.h>
  #include <linux/hpet.h>
  #include <linux/init.h>
  #include <linux/cpu.h>
@@@ -400,9 -399,15 +400,15 @@@ static int hpet_next_event(unsigned lon
         * then we might have a real hardware problem. We can not do
         * much about it here, but at least alert the user/admin with
         * a prominent warning.
+        * An erratum on some chipsets (ICH9,..), results in comparator read
+        * immediately following a write returning old value. Workaround
+        * for this is to read this value second time, when first
+        * read returns old value.
         */
-       WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+       if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
+               WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
                  KERN_WARNING "hpet: compare register read back failed.\n");
+       }
  
        return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
  }
@@@ -1144,6 -1149,7 +1150,7 @@@ int hpet_set_periodic_freq(unsigned lon
                do_div(clc, freq);
                clc >>= hpet_clockevent.shift;
                hpet_pie_delta = clc;
+               hpet_pie_limit = 0;
        }
        return 1;
  }
diff --combined arch/x86/kernel/setup.c
@@@ -55,6 -55,7 +55,6 @@@
  #include <linux/stddef.h>
  #include <linux/unistd.h>
  #include <linux/ptrace.h>
 -#include <linux/slab.h>
  #include <linux/user.h>
  #include <linux/delay.h>
  
@@@ -607,6 -608,16 +607,16 @@@ static int __init setup_elfcorehdr(cha
  early_param("elfcorehdr", setup_elfcorehdr);
  #endif
  
+ static __init void reserve_ibft_region(void)
+ {
+       unsigned long addr, size = 0;
+       addr = find_ibft_region(&size);
+       if (size)
+               reserve_early_overlap_ok(addr, addr + size, "ibft");
+ }
  #ifdef CONFIG_X86_RESERVE_LOW_64K
  static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
  {
@@@ -909,6 -920,8 +919,8 @@@ void __init setup_arch(char **cmdline_p
         */
        find_smp_config();
  
+       reserve_ibft_region();
        reserve_trampoline_memory();
  
  #ifdef CONFIG_ACPI_SLEEP
  
        dma32_reserve_bootmem();
  
-       reserve_ibft_region();
  #ifdef CONFIG_KVM_CLOCK
        kvmclock_init();
  #endif
@@@ -27,6 -27,7 +27,6 @@@
  #include <linux/limits.h>
  #include <linux/module.h>
  #include <linux/pci.h>
 -#include <linux/slab.h>
  #include <linux/stat.h>
  #include <linux/string.h>
  #include <linux/types.h>
@@@ -51,7 -52,7 +51,7 @@@ EXPORT_SYMBOL_GPL(ibft_addr)
   * Routine used to find the iSCSI Boot Format Table. The logical
   * kernel address is set in the ibft_addr global variable.
   */
void __init reserve_ibft_region(void)
unsigned long __init find_ibft_region(unsigned long *sizep)
  {
        unsigned long pos;
        unsigned int len = 0;
                        }
                }
        }
-       if (ibft_addr)
-               reserve_bootmem(pos, PAGE_ALIGN(len), BOOTMEM_DEFAULT);
+       if (ibft_addr) {
+               *sizep = PAGE_ALIGN(len);
+               return pos;
+       }
+       *sizep = 0;
+       return 0;
  }
diff --combined mm/bootmem.c
@@@ -10,7 -10,6 +10,7 @@@
   */
  #include <linux/init.h>
  #include <linux/pfn.h>
 +#include <linux/slab.h>
  #include <linux/bootmem.h>
  #include <linux/module.h>
  #include <linux/kmemleak.h>
@@@ -304,9 -303,22 +304,22 @@@ unsigned long __init free_all_bootmem_n
  unsigned long __init free_all_bootmem(void)
  {
  #ifdef CONFIG_NO_BOOTMEM
-       return free_all_memory_core_early(NODE_DATA(0)->node_id);
+       /*
+        * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
+        *  because in some case like Node0 doesnt have RAM installed
+        *  low ram will be on Node1
+        * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
+        *  will be used instead of only Node0 related
+        */
+       return free_all_memory_core_early(MAX_NUMNODES);
  #else
-       return free_all_bootmem_core(NODE_DATA(0)->bdata);
+       unsigned long total_pages = 0;
+       bootmem_data_t *bdata;
+       list_for_each_entry(bdata, &bdata_list, list)
+               total_pages += free_all_bootmem_core(bdata);
+       return total_pages;
  #endif
  }