]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'linus' into tmp.x86.mpparse.new
authorIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 08:32:56 +0000 (10:32 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 08:32:56 +0000 (10:32 +0200)
14 files changed:
1  2 
Documentation/kernel-parameters.txt
arch/x86/Kconfig
arch/x86/Kconfig.debug
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic_64.c
arch/x86/kernel/head_32.S
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/smpboot.c
arch/x86/lguest/boot.c
arch/x86/xen/enlighten.c
include/linux/mm.h
mm/page_alloc.c

index 2000977af7763eb51eda1581865a2639e5a2bad0,b52f47d588b40fea417bf4bca4ffdbfef4d02152..e53ff097557383dab01943be2af06eaf848b6e91
@@@ -295,7 -295,7 +295,7 @@@ and is between 256 and 4096 characters
                        when initialising the APIC and IO-APIC components.
  
        apm=            [APM] Advanced Power Management
-                       See header of arch/i386/kernel/apm.c.
+                       See header of arch/x86/kernel/apm_32.c.
  
        arcrimi=        [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
                        Format: <io>,<irq>,<nodeID>
                        See drivers/char/README.epca and
                        Documentation/digiepca.txt.
  
 +      disable_mtrr_cleanup [X86]
 +      enable_mtrr_cleanup [X86]
 +                      The kernel tries to adjust MTRR layout from continuous
 +                      to discrete, to make X server driver able to add WB
 +                      entry later. This parameter enables/disables that.
 +
 +      mtrr_chunk_size=nn[KMG] [X86]
 +                      used for mtrr cleanup. It is largest continous chunk
 +                      that could hold holes aka. UC entries.
 +
 +      mtrr_gran_size=nn[KMG] [X86]
 +                      Used for mtrr cleanup. It is granularity of mtrr block.
 +                      Default is 1.
 +                      Large value could prevent small alignment from
 +                      using up MTRRs.
 +
 +      mtrr_spare_reg_nr=n [X86]
 +                      Format: <integer>
 +                      Range: 0,7 : spare reg number
 +                      Default : 1
 +                      Used for mtrr cleanup. It is spare mtrr entries number.
 +                      Set to 2 or more if your graphical card needs more.
 +
        disable_mtrr_trim [X86, Intel and AMD only]
                        By default the kernel will trim any uncacheable
                        memory out of your available memory pool based on
  
        elanfreq=       [X86-32]
                        See comment before function elanfreq_setup() in
-                       arch/i386/kernel/cpu/cpufreq/elanfreq.c.
+                       arch/x86/kernel/cpu/cpufreq/elanfreq.c.
  
        elevator=       [IOSCHED]
                        Format: {"anticipatory" | "cfq" | "deadline" | "noop"}
                        Format: <reboot_mode>[,<reboot_mode2>[,...]]
                        See arch/*/kernel/reboot.c or arch/*/kernel/process.c                   
  
+       relax_domain_level=
+                       [KNL, SMP] Set scheduler's default relax_domain_level.
+                       See Documentation/cpusets.txt.
        reserve=        [KNL,BUGS] Force the kernel to ignore some iomem area
  
        reservetop=     [X86-32]
diff --combined arch/x86/Kconfig
index 8b89810fe3f2bb3f122b29b4f9ebde2a21630b15,bf07b6f50fa178268f9d81388a615a7a8abff32b..07276ac01c2055f95df5ab5a93f3b58c50870292
@@@ -26,17 -26,10 +26,10 @@@ config X8
        select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
        select HAVE_ARCH_KGDB if !X86_VOYAGER
  
- config DEFCONFIG_LIST
+ config ARCH_DEFCONFIG
        string
-       depends on X86_32
-       option defconfig_list
-       default "arch/x86/configs/i386_defconfig"
- config DEFCONFIG_LIST
-       string
-       depends on X86_64
-       option defconfig_list
-       default "arch/x86/configs/x86_64_defconfig"
+       default "arch/x86/configs/i386_defconfig" if X86_32
+       default "arch/x86/configs/x86_64_defconfig" if X86_64
  
  
  config GENERIC_LOCKBREAK
@@@ -268,6 -261,36 +261,6 @@@ config X86_VOYAGE
          If you do not specifically know you have a Voyager based machine,
          say N here, otherwise the kernel you build will not be bootable.
  
 -config X86_NUMAQ
 -      bool "NUMAQ (IBM/Sequent)"
 -      depends on SMP && X86_32
 -      select NUMA
 -      help
 -        This option is used for getting Linux to run on a (IBM/Sequent) NUMA
 -        multiquad box. This changes the way that processors are bootstrapped,
 -        and uses Clustered Logical APIC addressing mode instead of Flat Logical.
 -        You will need a new lynxer.elf file to flash your firmware with - send
 -        email to <Martin.Bligh@us.ibm.com>.
 -
 -config X86_SUMMIT
 -      bool "Summit/EXA (IBM x440)"
 -      depends on X86_32 && SMP
 -      help
 -        This option is needed for IBM systems that use the Summit/EXA chipset.
 -        In particular, it is needed for the x440.
 -
 -        If you don't have one of these computers, you should say N here.
 -        If you want to build a NUMA kernel, you must select ACPI.
 -
 -config X86_BIGSMP
 -      bool "Support for other sub-arch SMP systems with more than 8 CPUs"
 -      depends on X86_32 && SMP
 -      help
 -        This option is needed for the systems that have more than 8 CPUs
 -        and if the system is not of any sub-arch type above.
 -
 -        If you don't have such a system, you should say N here.
 -
  config X86_VISWS
        bool "SGI 320/540 (Visual Workstation)"
        depends on X86_32
          and vice versa. See <file:Documentation/sgi-visws.txt> for details.
  
  config X86_GENERICARCH
 -       bool "Generic architecture (Summit, bigsmp, ES7000, default)"
 +       bool "Generic architecture"
        depends on X86_32
         help
 -          This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
 -        It is intended for a generic binary kernel.
 -        If you want a NUMA kernel, select ACPI.   We need SRAT for NUMA.
 +          This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
 +        subarchitectures.  It is intended for a generic binary kernel.
 +        if you select them all, kernel will probe it one by one. and will
 +        fallback to default.
 +
 +if X86_GENERICARCH
 +
 +config X86_NUMAQ
 +      bool "NUMAQ (IBM/Sequent)"
 +      depends on SMP && X86_32
 +      select NUMA
 +      help
 +        This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
 +        NUMA multiquad box. This changes the way that processors are
 +        bootstrapped, and uses Clustered Logical APIC addressing mode instead
 +        of Flat Logical.  You will need a new lynxer.elf file to flash your
 +        firmware with - send email to <Martin.Bligh@us.ibm.com>.
 +
 +config X86_SUMMIT
 +      bool "Summit/EXA (IBM x440)"
 +      depends on X86_32 && SMP
 +      help
 +        This option is needed for IBM systems that use the Summit/EXA chipset.
 +        In particular, it is needed for the x440.
  
  config X86_ES7000
        bool "Support for Unisys ES7000 IA32 series"
        help
          Support for Unisys ES7000 systems.  Say 'Y' here if this kernel is
          supposed to run on an IA32-based Unisys ES7000 system.
 -        Only choose this option if you have such a system, otherwise you
 -        should say N here.
 +
 +config X86_BIGSMP
 +      bool "Support for big SMP systems with more than 8 CPUs"
 +      depends on X86_32 && SMP
 +      help
 +        This option is needed for the systems that have more than 8 CPUs
 +        and if the system is not of any sub-arch type above.
 +
 +endif
  
  config X86_RDC321X
        bool "RDC R-321x SoC"
@@@ -388,6 -383,7 +381,7 @@@ config VM
  config KVM_CLOCK
        bool "KVM paravirtualized clock"
        select PARAVIRT
+       select PARAVIRT_CLOCK
        depends on !(X86_VISWS || X86_VOYAGER)
        help
          Turning on this option will allow you to run a paravirtualized clock
@@@ -415,6 -411,10 +409,10 @@@ config PARAVIR
          over full virtualization.  However, when run without a hypervisor
          the kernel is theoretically slower and slightly larger.
  
+ config PARAVIRT_CLOCK
+       bool
+       default n
  endif
  
  config MEMTEST_BOOTPARAM
@@@ -911,9 -911,9 +909,9 @@@ config X86_PA
  config NUMA
        bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)"
        depends on SMP
 -      depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL)
 +      depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || X86_SUMMIT && ACPI) && EXPERIMENTAL)
        default n if X86_PC
 -      default y if (X86_NUMAQ || X86_SUMMIT)
 +      default y if (X86_NUMAQ || X86_SUMMIT || X86_GENERICARCH)
        help
          Enable NUMA (Non Uniform Memory Access) support.
          The kernel will try to allocate memory used by a CPU on the
@@@ -966,8 -966,8 +964,8 @@@ config NUMA_EM
          number of nodes. This is only useful for debugging.
  
  config NODES_SHIFT
-       int "Max num nodes shift(1-15)"
-       range 1 15  if X86_64
+       int "Max num nodes shift(1-9)"
+       range 1 9  if X86_64
        default "6" if X86_64
        default "4" if X86_NUMAQ
        default "3"
@@@ -1090,40 -1090,6 +1088,40 @@@ config MTR
  
          See <file:Documentation/mtrr.txt> for more information.
  
 +config MTRR_SANITIZER
 +      def_bool y
 +      prompt "MTRR cleanup support"
 +      depends on MTRR
 +      help
 +        Convert MTRR layout from continuous to discrete, so some X driver
 +        could add WB entries.
 +
 +        Say N here if you see bootup problems (boot crash, boot hang,
 +        spontaneous reboots).
 +
 +        Could be disabled with disable_mtrr_cleanup. Also mtrr_chunk_size
 +        could be used to send largest mtrr entry size for continuous block
 +        to hold holes (aka. UC entries)
 +
 +        If unsure, say Y.
 +
 +config MTRR_SANITIZER_ENABLE_DEFAULT
 +      int "MTRR cleanup enable value (0-1)"
 +      range 0 1
 +      default "0"
 +      depends on MTRR_SANITIZER
 +      help
 +        Enable mtrr cleanup default value
 +
 +config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT
 +      int "MTRR cleanup spare reg num (0-7)"
 +      range 0 7
 +      default "1"
 +      depends on MTRR_SANITIZER
 +      help
 +        mtrr cleanup spare entries default, it can be changed via
 +        mtrr_spare_reg_nr=
 +
  config X86_PAT
        bool
        prompt "x86 PAT support"
@@@ -1547,13 -1513,13 +1545,13 @@@ config PCI_GOMMCONFI
  config PCI_GODIRECT
        bool "Direct"
  
- config PCI_GOANY
-       bool "Any"
  config PCI_GOOLPC
        bool "OLPC"
        depends on OLPC
  
+ config PCI_GOANY
+       bool "Any"
  endchoice
  
  config PCI_BIOS
@@@ -1570,9 -1536,8 +1568,8 @@@ config PCI_MMCONFI
        depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
  
  config PCI_OLPC
-       bool
-       depends on PCI && PCI_GOOLPC
-       default y
+       def_bool y
+       depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY)
  
  config PCI_DOMAINS
        def_bool y
diff --combined arch/x86/Kconfig.debug
index d5b364b43a0256064336e540b2f77ba24eb66e8d,18363374d51a9a57b39b6fb8d3f87a054b4b4aa5..253e7a5706d36391fc9ac2b3a52f7be4dced66c0
@@@ -6,15 -6,19 +6,19 @@@ config TRACE_IRQFLAGS_SUPPOR
  source "lib/Kconfig.debug"
  
  config NONPROMISC_DEVMEM
-       bool "Disable promiscuous /dev/mem"
+       bool "Filter access to /dev/mem"
        help
-         The /dev/mem file by default only allows userspace access to PCI
-         space and the BIOS code and data regions. This is sufficient for
-         dosemu and X and all common users of /dev/mem. With this config
-         option, you allow userspace access to all of memory, including
-         kernel and userspace memory. Accidental access to this is
-         obviously disasterous, but specific access can be used by people
-         debugging the kernel.
+         If this option is left off, you allow userspace access to all
+         of memory, including kernel and userspace memory. Accidental
+         access to this is obviously disastrous, but specific access can
+         be used by people debugging the kernel.
+         If this option is switched on, the /dev/mem file only allows
+         userspace access to PCI space and the BIOS code and data regions.
+         This is sufficient for dosemu and X and all common users of
+         /dev/mem.
+         If in doubt, say Y.
  
  config EARLY_PRINTK
        bool "Early printk" if EMBEDDED
@@@ -127,7 -131,7 +131,7 @@@ config 4KSTACK
  
  config X86_FIND_SMP_CONFIG
        def_bool y
 -      depends on X86_LOCAL_APIC || X86_VOYAGER
 +      depends on X86_MPPARSE || X86_VOYAGER || X86_VISWS
        depends on X86_32
  
  config X86_MPPARSE
diff --combined arch/x86/kernel/Makefile
index 7e01ce39c8366b605d1fac52fbd732026574af15,77807d4769c99c455237a810fe0edd0f996fb31f..dc3c636d113e1f6e050801cc395a21e56e14364d
@@@ -2,7 -2,7 +2,7 @@@
  # Makefile for the linux kernel.
  #
  
 -extra-y                := head_$(BITS).o head$(BITS).o init_task.o vmlinux.lds
 +extra-y                := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinux.lds
  
  CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
  
@@@ -22,7 -22,7 +22,7 @@@ obj-y                 += setup_$(BITS).o i8259_$(BITS
  obj-$(CONFIG_X86_32)  += sys_i386_32.o i386_ksyms_32.o
  obj-$(CONFIG_X86_64)  += sys_x86_64.o x8664_ksyms_64.o
  obj-$(CONFIG_X86_64)  += syscall_64.o vsyscall_64.o setup64.o
 -obj-y                 += bootflag.o e820_$(BITS).o
 +obj-y                 += bootflag.o e820_$(BITS).o e820.o
  obj-y                 += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
  obj-y                 += alternative.o i8253.o pci-nommu.o
  obj-$(CONFIG_X86_64)  += bugs_64.o
@@@ -82,6 -82,7 +82,7 @@@ obj-$(CONFIG_VMI)             += vmi_32.o vmiclock
  obj-$(CONFIG_KVM_GUEST)               += kvm.o
  obj-$(CONFIG_KVM_CLOCK)               += kvmclock.o
  obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirt_patch_$(BITS).o
+ obj-$(CONFIG_PARAVIRT_CLOCK)  += pvclock.o
  
  obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
  
index 7dc2130046d995e29492f4ad2bfe95f020960bf7,33c5216fd3e1f5137b0b8c52fa8178ac328d630a..caf4ed7ca069f73c7a5e81f88f4bb77416fb4413
@@@ -242,12 -242,19 +242,19 @@@ static int __init acpi_parse_madt(struc
  
  static void __cpuinit acpi_register_lapic(int id, u8 enabled)
  {
+       unsigned int ver = 0;
        if (!enabled) {
                ++disabled_cpus;
                return;
        }
  
-       generic_processor_info(id, 0);
+ #ifdef CONFIG_X86_32
+       if (boot_cpu_physical_apicid != -1U)
+               ver = apic_version[boot_cpu_physical_apicid];
+ #endif
+       generic_processor_info(id, ver);
  }
  
  static int __init
@@@ -331,6 -338,8 +338,6 @@@ acpi_parse_lapic_nmi(struct acpi_subtab
  
  #ifdef CONFIG_X86_IO_APIC
  
 -struct mp_ioapic_routing mp_ioapic_routing[MAX_IO_APICS];
 -
  static int __init
  acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
  {
@@@ -765,8 -774,13 +772,13 @@@ static void __init acpi_register_lapic_
        mp_lapic_addr = address;
  
        set_fixmap_nocache(FIX_APIC_BASE, address);
-       if (boot_cpu_physical_apicid == -1U)
+       if (boot_cpu_physical_apicid == -1U) {
                boot_cpu_physical_apicid  = GET_APIC_ID(read_apic_id());
+ #ifdef CONFIG_X86_32
+               apic_version[boot_cpu_physical_apicid] =
+                        GET_APIC_VERSION(apic_read(APIC_LVR));
+ #endif
+       }
  }
  
  static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
@@@ -846,336 -860,6 +858,336 @@@ static int __init acpi_parse_madt_lapic
  #endif                                /* CONFIG_X86_LOCAL_APIC */
  
  #ifdef        CONFIG_X86_IO_APIC
 +#define MP_ISA_BUS            0
 +
 +#ifdef CONFIG_X86_ES7000
 +extern int es7000_plat;
 +#endif
 +
 +static struct {
 +      int apic_id;
 +      int gsi_base;
 +      int gsi_end;
 +      DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
 +} mp_ioapic_routing[MAX_IO_APICS];
 +
 +static int mp_find_ioapic(int gsi)
 +{
 +      int i = 0;
 +
 +      /* Find the IOAPIC that manages this GSI. */
 +      for (i = 0; i < nr_ioapics; i++) {
 +              if ((gsi >= mp_ioapic_routing[i].gsi_base)
 +                  && (gsi <= mp_ioapic_routing[i].gsi_end))
 +                      return i;
 +      }
 +
 +      printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
 +      return -1;
 +}
 +
 +static u8 __init uniq_ioapic_id(u8 id)
 +{
 +#ifdef CONFIG_X86_32
 +      if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
 +          !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
 +              return io_apic_get_unique_id(nr_ioapics, id);
 +      else
 +              return id;
 +#else
 +      int i;
 +      DECLARE_BITMAP(used, 256);
 +      bitmap_zero(used, 256);
 +      for (i = 0; i < nr_ioapics; i++) {
 +              struct mp_config_ioapic *ia = &mp_ioapics[i];
 +              __set_bit(ia->mp_apicid, used);
 +      }
 +      if (!test_bit(id, used))
 +              return id;
 +      return find_first_zero_bit(used, 256);
 +#endif
 +}
 +
 +static int bad_ioapic(unsigned long address)
 +{
 +      if (nr_ioapics >= MAX_IO_APICS) {
 +              printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
 +                     "(found %d)\n", MAX_IO_APICS, nr_ioapics);
 +              panic("Recompile kernel with bigger MAX_IO_APICS!\n");
 +      }
 +      if (!address) {
 +              printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
 +                     " found in table, skipping!\n");
 +              return 1;
 +      }
 +      return 0;
 +}
 +
 +void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 +{
 +      int idx = 0;
 +
 +      if (bad_ioapic(address))
 +              return;
 +
 +      idx = nr_ioapics;
 +
 +      mp_ioapics[idx].mp_type = MP_IOAPIC;
 +      mp_ioapics[idx].mp_flags = MPC_APIC_USABLE;
 +      mp_ioapics[idx].mp_apicaddr = address;
 +
 +      set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
 +      mp_ioapics[idx].mp_apicid = uniq_ioapic_id(id);
 +#ifdef CONFIG_X86_32
 +      mp_ioapics[idx].mp_apicver = io_apic_get_version(idx);
 +#else
 +      mp_ioapics[idx].mp_apicver = 0;
 +#endif
 +      /*
 +       * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 +       * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 +       */
 +      mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mp_apicid;
 +      mp_ioapic_routing[idx].gsi_base = gsi_base;
 +      mp_ioapic_routing[idx].gsi_end = gsi_base +
 +          io_apic_get_redir_entries(idx);
 +
 +      printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
 +             "GSI %d-%d\n", idx, mp_ioapics[idx].mp_apicid,
 +             mp_ioapics[idx].mp_apicver, mp_ioapics[idx].mp_apicaddr,
 +             mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
 +
 +      nr_ioapics++;
 +}
 +
 +void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
 +{
 +      int ioapic = -1;
 +      int pin = -1;
 +
 +      /*
 +       * Convert 'gsi' to 'ioapic.pin'.
 +       */
 +      ioapic = mp_find_ioapic(gsi);
 +      if (ioapic < 0)
 +              return;
 +      pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
 +
 +      /*
 +       * TBD: This check is for faulty timer entries, where the override
 +       *      erroneously sets the trigger to level, resulting in a HUGE
 +       *      increase of timer interrupts!
 +       */
 +      if ((bus_irq == 0) && (trigger == 3))
 +              trigger = 1;
 +
 +      mp_irqs[mp_irq_entries].mp_type = MP_INTSRC;
 +      mp_irqs[mp_irq_entries].mp_irqtype = mp_INT;
 +      mp_irqs[mp_irq_entries].mp_irqflag = (trigger << 2) | polarity;
 +      mp_irqs[mp_irq_entries].mp_srcbus = MP_ISA_BUS;
 +      mp_irqs[mp_irq_entries].mp_srcbusirq = bus_irq; /* IRQ */
 +      mp_irqs[mp_irq_entries].mp_dstapic =
 +                      mp_ioapics[ioapic].mp_apicid;   /* APIC ID */
 +      mp_irqs[mp_irq_entries].mp_dstirq = pin;        /* INTIN# */
 +
 +      if (++mp_irq_entries == MAX_IRQ_SOURCES)
 +              panic("Max # of irq sources exceeded!!\n");
 +
 +}
 +
 +void __init mp_config_acpi_legacy_irqs(void)
 +{
 +      int i = 0;
 +      int ioapic = -1;
 +
 +#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
 +      /*
 +       * Fabricate the legacy ISA bus (bus #31).
 +       */
 +      mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
 +#endif
 +      set_bit(MP_ISA_BUS, mp_bus_not_pci);
 +      Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
 +
 +#ifdef CONFIG_X86_ES7000
 +      /*
 +       * Older generations of ES7000 have no legacy identity mappings
 +       */
 +      if (es7000_plat == 1)
 +              return;
 +#endif
 +
 +      /*
 +       * Locate the IOAPIC that manages the ISA IRQs (0-15).
 +       */
 +      ioapic = mp_find_ioapic(0);
 +      if (ioapic < 0)
 +              return;
 +
 +      /*
 +       * Use the default configuration for the IRQs 0-15.  Unless
 +       * overridden by (MADT) interrupt source override entries.
 +       */
 +      for (i = 0; i < 16; i++) {
 +              int idx;
 +
 +              mp_irqs[mp_irq_entries].mp_type = MP_INTSRC;
 +              mp_irqs[mp_irq_entries].mp_irqflag = 0; /* Conforming */
 +              mp_irqs[mp_irq_entries].mp_srcbus = MP_ISA_BUS;
 +              mp_irqs[mp_irq_entries].mp_dstapic = mp_ioapics[ioapic].mp_apicid;
 +
 +              for (idx = 0; idx < mp_irq_entries; idx++) {
 +                      struct mp_config_intsrc *irq = mp_irqs + idx;
 +
 +                      /* Do we already have a mapping for this ISA IRQ? */
 +                      if (irq->mp_srcbus == MP_ISA_BUS
 +                          && irq->mp_srcbusirq == i)
 +                              break;
 +
 +                      /* Do we already have a mapping for this IOAPIC pin */
 +                      if ((irq->mp_dstapic ==
 +                              mp_irqs[mp_irq_entries].mp_dstapic) &&
 +                          (irq->mp_dstirq == i))
 +                              break;
 +              }
 +
 +              if (idx != mp_irq_entries) {
 +                      printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
 +                      continue;       /* IRQ already used */
 +              }
 +
 +              mp_irqs[mp_irq_entries].mp_irqtype = mp_INT;
 +              mp_irqs[mp_irq_entries].mp_srcbusirq = i;       /* Identity mapped */
 +              mp_irqs[mp_irq_entries].mp_dstirq = i;
 +
 +              if (++mp_irq_entries == MAX_IRQ_SOURCES)
 +                      panic("Max # of irq sources exceeded!!\n");
 +      }
 +}
 +
 +int mp_register_gsi(u32 gsi, int triggering, int polarity)
 +{
 +      int ioapic;
 +      int ioapic_pin;
 +#ifdef CONFIG_X86_32
 +#define MAX_GSI_NUM   4096
 +#define IRQ_COMPRESSION_START 64
 +
 +      static int pci_irq = IRQ_COMPRESSION_START;
 +      /*
 +       * Mapping between Global System Interrupts, which
 +       * represent all possible interrupts, and IRQs
 +       * assigned to actual devices.
 +       */
 +      static int gsi_to_irq[MAX_GSI_NUM];
 +#else
 +
 +      if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
 +              return gsi;
 +#endif
 +
 +      /* Don't set up the ACPI SCI because it's already set up */
 +      if (acpi_gbl_FADT.sci_interrupt == gsi)
 +              return gsi;
 +
 +      ioapic = mp_find_ioapic(gsi);
 +      if (ioapic < 0) {
 +              printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
 +              return gsi;
 +      }
 +
 +      ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
 +
 +#ifdef CONFIG_X86_32
 +      if (ioapic_renumber_irq)
 +              gsi = ioapic_renumber_irq(ioapic, gsi);
 +#endif
 +
 +      /*
 +       * Avoid pin reprogramming.  PRTs typically include entries
 +       * with redundant pin->gsi mappings (but unique PCI devices);
 +       * we only program the IOAPIC on the first.
 +       */
 +      if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 +              printk(KERN_ERR "Invalid reference to IOAPIC pin "
 +                     "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
 +                     ioapic_pin);
 +              return gsi;
 +      }
 +      if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
 +              Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
 +                      mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
 +#ifdef CONFIG_X86_32
 +              return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
 +#else
 +              return gsi;
 +#endif
 +      }
 +
 +      set_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed);
 +#ifdef CONFIG_X86_32
 +      /*
 +       * For GSI >= 64, use IRQ compression
 +       */
 +      if ((gsi >= IRQ_COMPRESSION_START)
 +          && (triggering == ACPI_LEVEL_SENSITIVE)) {
 +              /*
 +               * For PCI devices assign IRQs in order, avoiding gaps
 +               * due to unused I/O APIC pins.
 +               */
 +              int irq = gsi;
 +              if (gsi < MAX_GSI_NUM) {
 +                      /*
 +                       * Retain the VIA chipset work-around (gsi > 15), but
 +                       * avoid a problem where the 8254 timer (IRQ0) is setup
 +                       * via an override (so it's not on pin 0 of the ioapic),
 +                       * and at the same time, the pin 0 interrupt is a PCI
 +                       * type.  The gsi > 15 test could cause these two pins
 +                       * to be shared as IRQ0, and they are not shareable.
 +                       * So test for this condition, and if necessary, avoid
 +                       * the pin collision.
 +                       */
 +                      gsi = pci_irq++;
 +                      /*
 +                       * Don't assign IRQ used by ACPI SCI
 +                       */
 +                      if (gsi == acpi_gbl_FADT.sci_interrupt)
 +                              gsi = pci_irq++;
 +                      gsi_to_irq[irq] = gsi;
 +              } else {
 +                      printk(KERN_ERR "GSI %u is too high\n", gsi);
 +                      return gsi;
 +              }
 +      }
 +#endif
 +      io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
 +                              triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
 +                              polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
 +      return gsi;
 +}
 +
 +int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
 +                      u32 gsi, int triggering, int polarity)
 +{
 +      struct mpc_config_intsrc intsrc;
 +      int ioapic;
 +
 +      /* print the entry should happen on mptable identically */
 +      intsrc.mpc_type = MP_INTSRC;
 +      intsrc.mpc_irqtype = mp_INT;
 +      intsrc.mpc_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
 +                              (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
 +      intsrc.mpc_srcbus = number;
 +      intsrc.mpc_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
 +      ioapic = mp_find_ioapic(gsi);
 +      intsrc.mpc_dstapic = mp_ioapic_routing[ioapic].apic_id;
 +      intsrc.mpc_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;
 +
 +      MP_intsrc_info(&intsrc);
 +
 +      return 0;
 +}
 +
  /*
   * Parse IOAPIC related entries in MADT
   * returns 0 on success, < 0 on error
index 1872555b98a32be8d57d0504d7741852eb24856f,0633cfd0dc291a1310f0632e1012cf663b5e89a9..a4bd8fbb78a98d0a4171eb599f3ccfdbf52b9a41
@@@ -56,9 -56,6 +56,9 @@@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_o
   */
  int apic_verbosity;
  
 +/* Have we found an MP table */
 +int smp_found_config;
 +
  static struct resource lapic_resource = {
        .name = "Local APIC",
        .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
@@@ -537,7 -534,7 +537,7 @@@ int setup_profiling_timer(unsigned int 
   */
  void clear_local_APIC(void)
  {
-       int maxlvt = lapic_get_maxlvt();
+       int maxlvt;
        u32 v;
  
        /* APIC hasn't been mapped yet */
@@@ -1093,9 -1090,6 +1093,9 @@@ void __cpuinit generic_processor_info(i
                 */
                cpu = 0;
        }
 +      if (apicid > max_physical_apicid)
 +              max_physical_apicid = apicid;
 +
        /* are we being called early in kernel startup? */
        if (x86_cpu_to_apicid_early_ptr) {
                u16 *cpu_to_apicid = x86_cpu_to_apicid_early_ptr;
index ac7002fdd637e889f7dab03ae18c06d7518a0bb9,f7357cc0162c2f1c4786b3208e8524b51837fef8..b98b338aae1a536639186611dc915ce82ee02366
@@@ -189,12 -189,11 +189,12 @@@ default_entry
         * this stage.
         */
  
- #define KPMDS ((0x100000000-__PAGE_OFFSET) >> 30) /* Number of kernel PMDs */
+ #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
  
        xorl %ebx,%ebx                          /* %ebx is kept at zero */
  
        movl $pa(pg0), %edi
 +      movl %edi, pa(init_pg_tables_start)
        movl $pa(swapper_pg_pmd), %edx
        movl $PTE_ATTR, %eax
  10:
        jb 10b
  1:
        movl %edi,pa(init_pg_tables_end)
 +      shrl $12, %eax
 +      movl %eax, pa(max_pfn_mapped)
  
        /* Do early initialization of the fixmap area */
        movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
  page_pde_offset = (__PAGE_OFFSET >> 20);
  
        movl $pa(pg0), %edi
 +      movl %edi, pa(init_pg_tables_start)
        movl $pa(swapper_pg_dir), %edx
        movl $PTE_ATTR, %eax
  10:
        cmpl %ebp,%eax
        jb 10b
        movl %edi,pa(init_pg_tables_end)
 +      shrl $12, %eax
 +      movl %eax, pa(max_pfn_mapped)
  
        /* Do early initialization of the fixmap area */
        movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
index 97e62a01f1e2966197dc7ba2590f236617f447da,4dc8600d9d2072ed5ed79ee3884f70afd2281636..0662817d61bfdd61f189fb7576ada934fdbfbedb
@@@ -72,21 -72,15 +72,21 @@@ int sis_apic_bug = -1
  int nr_ioapic_registers[MAX_IO_APICS];
  
  /* I/O APIC entries */
 -struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
 +struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
  int nr_ioapics;
  
  /* MP IRQ source entries */
 -struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
 +struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
  
  /* # of MP IRQ source entries */
  int mp_irq_entries;
  
 +#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
 +int mp_bus_id_to_type[MAX_MP_BUSSES];
 +#endif
 +
 +DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 +
  static int disable_timer_pin_1 __initdata;
  
  /*
@@@ -116,7 -110,7 +116,7 @@@ struct io_apic 
  static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
  {
        return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
 -              + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);
 +              + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK);
  }
  
  static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
@@@ -807,10 -801,10 +807,10 @@@ static int find_irq_entry(int apic, in
        int i;
  
        for (i = 0; i < mp_irq_entries; i++)
 -              if (mp_irqs[i].mpc_irqtype == type &&
 -                  (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid ||
 -                   mp_irqs[i].mpc_dstapic == MP_APIC_ALL) &&
 -                  mp_irqs[i].mpc_dstirq == pin)
 +              if (mp_irqs[i].mp_irqtype == type &&
 +                  (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid ||
 +                   mp_irqs[i].mp_dstapic == MP_APIC_ALL) &&
 +                  mp_irqs[i].mp_dstirq == pin)
                        return i;
  
        return -1;
@@@ -824,13 -818,13 +824,13 @@@ static int __init find_isa_irq_pin(int 
        int i;
  
        for (i = 0; i < mp_irq_entries; i++) {
 -              int lbus = mp_irqs[i].mpc_srcbus;
 +              int lbus = mp_irqs[i].mp_srcbus;
  
                if (test_bit(lbus, mp_bus_not_pci) &&
 -                  (mp_irqs[i].mpc_irqtype == type) &&
 -                  (mp_irqs[i].mpc_srcbusirq == irq))
 +                  (mp_irqs[i].mp_irqtype == type) &&
 +                  (mp_irqs[i].mp_srcbusirq == irq))
  
 -                      return mp_irqs[i].mpc_dstirq;
 +                      return mp_irqs[i].mp_dstirq;
        }
        return -1;
  }
@@@ -840,17 -834,17 +840,17 @@@ static int __init find_isa_irq_apic(in
        int i;
  
        for (i = 0; i < mp_irq_entries; i++) {
 -              int lbus = mp_irqs[i].mpc_srcbus;
 +              int lbus = mp_irqs[i].mp_srcbus;
  
                if (test_bit(lbus, mp_bus_not_pci) &&
 -                  (mp_irqs[i].mpc_irqtype == type) &&
 -                  (mp_irqs[i].mpc_srcbusirq == irq))
 +                  (mp_irqs[i].mp_irqtype == type) &&
 +                  (mp_irqs[i].mp_srcbusirq == irq))
                        break;
        }
        if (i < mp_irq_entries) {
                int apic;
                for(apic = 0; apic < nr_ioapics; apic++) {
 -                      if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
 +                      if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
                                return apic;
                }
        }
@@@ -870,28 -864,28 +870,28 @@@ int IO_APIC_get_PCI_irq_vector(int bus
  
        apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, "
                "slot:%d, pin:%d.\n", bus, slot, pin);
 -      if (mp_bus_id_to_pci_bus[bus] == -1) {
 +      if (test_bit(bus, mp_bus_not_pci)) {
                printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
                return -1;
        }
        for (i = 0; i < mp_irq_entries; i++) {
 -              int lbus = mp_irqs[i].mpc_srcbus;
 +              int lbus = mp_irqs[i].mp_srcbus;
  
                for (apic = 0; apic < nr_ioapics; apic++)
 -                      if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic ||
 -                          mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
 +                      if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic ||
 +                          mp_irqs[i].mp_dstapic == MP_APIC_ALL)
                                break;
  
                if (!test_bit(lbus, mp_bus_not_pci) &&
 -                  !mp_irqs[i].mpc_irqtype &&
 +                  !mp_irqs[i].mp_irqtype &&
                    (bus == lbus) &&
 -                  (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
 -                      int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
 +                  (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
 +                      int irq = pin_2_irq(i,apic,mp_irqs[i].mp_dstirq);
  
                        if (!(apic || IO_APIC_IRQ(irq)))
                                continue;
  
 -                      if (pin == (mp_irqs[i].mpc_srcbusirq & 3))
 +                      if (pin == (mp_irqs[i].mp_srcbusirq & 3))
                                return irq;
                        /*
                         * Use the first all-but-pin matching entry as a
@@@ -958,7 -952,7 +958,7 @@@ static int EISA_ELCR(unsigned int irq
   * EISA conforming in the MP table, that means its trigger type must
   * be read in from the ELCR */
  
 -#define default_EISA_trigger(idx)     (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
 +#define default_EISA_trigger(idx)     (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
  #define default_EISA_polarity(idx)    default_ISA_polarity(idx)
  
  /* PCI interrupts are always polarity one level triggered,
  
  static int MPBIOS_polarity(int idx)
  {
 -      int bus = mp_irqs[idx].mpc_srcbus;
 +      int bus = mp_irqs[idx].mp_srcbus;
        int polarity;
  
        /*
         * Determine IRQ line polarity (high active or low active):
         */
 -      switch (mp_irqs[idx].mpc_irqflag & 3)
 +      switch (mp_irqs[idx].mp_irqflag & 3)
        {
                case 0: /* conforms, ie. bus-type dependent polarity */
                {
  
  static int MPBIOS_trigger(int idx)
  {
 -      int bus = mp_irqs[idx].mpc_srcbus;
 +      int bus = mp_irqs[idx].mp_srcbus;
        int trigger;
  
        /*
         * Determine IRQ trigger mode (edge or level sensitive):
         */
 -      switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
 +      switch ((mp_irqs[idx].mp_irqflag>>2) & 3)
        {
                case 0: /* conforms, ie. bus-type dependent */
                {
@@@ -1103,16 -1097,16 +1103,16 @@@ static inline int irq_trigger(int idx
  static int pin_2_irq(int idx, int apic, int pin)
  {
        int irq, i;
 -      int bus = mp_irqs[idx].mpc_srcbus;
 +      int bus = mp_irqs[idx].mp_srcbus;
  
        /*
         * Debugging check, we are in big trouble if this message pops up!
         */
 -      if (mp_irqs[idx].mpc_dstirq != pin)
 +      if (mp_irqs[idx].mp_dstirq != pin)
                printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
  
        if (test_bit(bus, mp_bus_not_pci))
 -              irq = mp_irqs[idx].mpc_srcbusirq;
 +              irq = mp_irqs[idx].mp_srcbusirq;
        else {
                /*
                 * PCI IRQs are mapped in order
@@@ -1256,12 -1250,12 +1256,12 @@@ static void __init setup_IO_APIC_irqs(v
                        if (first_notcon) {
                                apic_printk(APIC_VERBOSE, KERN_DEBUG
                                                " IO-APIC (apicid-pin) %d-%d",
 -                                              mp_ioapics[apic].mpc_apicid,
 +                                              mp_ioapics[apic].mp_apicid,
                                                pin);
                                first_notcon = 0;
                        } else
                                apic_printk(APIC_VERBOSE, ", %d-%d",
 -                                      mp_ioapics[apic].mpc_apicid, pin);
 +                                      mp_ioapics[apic].mp_apicid, pin);
                        continue;
                }
  
@@@ -1363,7 -1357,7 +1363,7 @@@ void __init print_IO_APIC(void
        printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
        for (i = 0; i < nr_ioapics; i++)
                printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
 -                     mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
 +                     mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
  
        /*
         * We are a bit conservative about what we expect.  We have to
                reg_03.raw = io_apic_read(apic, 3);
        spin_unlock_irqrestore(&ioapic_lock, flags);
  
 -      printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
 +      printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
        printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
        printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
        printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
@@@ -1722,6 -1716,7 +1722,6 @@@ void disable_IO_APIC(void
   * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
   */
  
 -#ifndef CONFIG_X86_NUMAQ
  static void __init setup_ioapic_ids_from_mpc(void)
  {
        union IO_APIC_reg_00 reg_00;
        unsigned char old_id;
        unsigned long flags;
  
 +#ifdef CONFIG_X86_NUMAQ
 +      if (found_numaq)
 +              return;
 +#endif
 +
        /*
         * Don't check I/O APIC IDs for xAPIC systems.  They have
         * no meaning without the serial APIC bus.
                reg_00.raw = io_apic_read(apic, 0);
                spin_unlock_irqrestore(&ioapic_lock, flags);
                
 -              old_id = mp_ioapics[apic].mpc_apicid;
 +              old_id = mp_ioapics[apic].mp_apicid;
  
 -              if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) {
 +              if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
 -                              apic, mp_ioapics[apic].mpc_apicid);
 +                              apic, mp_ioapics[apic].mp_apicid);
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                reg_00.bits.ID);
 -                      mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
 +                      mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
                }
  
                /*
                 * 'stuck on smp_invalidate_needed IPI wait' messages.
                 */
                if (check_apicid_used(phys_id_present_map,
 -                                      mp_ioapics[apic].mpc_apicid)) {
 +                                      mp_ioapics[apic].mp_apicid)) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
 -                              apic, mp_ioapics[apic].mpc_apicid);
 +                              apic, mp_ioapics[apic].mp_apicid);
                        for (i = 0; i < get_physical_broadcast(); i++)
                                if (!physid_isset(i, phys_id_present_map))
                                        break;
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                i);
                        physid_set(i, phys_id_present_map);
 -                      mp_ioapics[apic].mpc_apicid = i;
 +                      mp_ioapics[apic].mp_apicid = i;
                } else {
                        physid_mask_t tmp;
 -                      tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
 +                      tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
                        apic_printk(APIC_VERBOSE, "Setting %d in the "
                                        "phys_id_present_map\n",
 -                                      mp_ioapics[apic].mpc_apicid);
 +                                      mp_ioapics[apic].mp_apicid);
                        physids_or(phys_id_present_map, phys_id_present_map, tmp);
                }
  
                 * We need to adjust the IRQ routing table
                 * if the ID changed.
                 */
 -              if (old_id != mp_ioapics[apic].mpc_apicid)
 +              if (old_id != mp_ioapics[apic].mp_apicid)
                        for (i = 0; i < mp_irq_entries; i++)
 -                              if (mp_irqs[i].mpc_dstapic == old_id)
 -                                      mp_irqs[i].mpc_dstapic
 -                                              = mp_ioapics[apic].mpc_apicid;
 +                              if (mp_irqs[i].mp_dstapic == old_id)
 +                                      mp_irqs[i].mp_dstapic
 +                                              = mp_ioapics[apic].mp_apicid;
  
                /*
                 * Read the right value from the MPC table and
                 */
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "...changing IO-APIC physical APIC ID to %d ...",
 -                      mp_ioapics[apic].mpc_apicid);
 +                      mp_ioapics[apic].mp_apicid);
  
 -              reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
 +              reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
                spin_lock_irqsave(&ioapic_lock, flags);
                io_apic_write(apic, 0, reg_00.raw);
                spin_unlock_irqrestore(&ioapic_lock, flags);
                spin_lock_irqsave(&ioapic_lock, flags);
                reg_00.raw = io_apic_read(apic, 0);
                spin_unlock_irqrestore(&ioapic_lock, flags);
 -              if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
 +              if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
                        printk("could not set ID!\n");
                else
                        apic_printk(APIC_VERBOSE, " ok.\n");
        }
  }
 -#else
 -static void __init setup_ioapic_ids_from_mpc(void) { }
 -#endif
  
  int no_timer_check __initdata;
  
@@@ -2137,14 -2130,10 +2137,10 @@@ static inline void __init check_timer(v
  {
        int apic1, pin1, apic2, pin2;
        int vector;
-       unsigned int ver;
        unsigned long flags;
  
        local_irq_save(flags);
  
-       ver = apic_read(APIC_LVR);
-       ver = GET_APIC_VERSION(ver);
        /*
         * get/set the timer IRQ vector:
         */
         * mode for the 8259A whenever interrupts are routed
         * through I/O APICs.  Also IRQ0 has to be enabled in
         * the 8259A which implies the virtual wire has to be
-        * disabled in the local APIC.  Finally timer interrupts
-        * need to be acknowledged manually in the 8259A for
-        * timer_interrupt() and for the i82489DX when using
-        * the NMI watchdog.
+        * disabled in the local APIC.
         */
        apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
        init_8259A(1);
-       timer_ack = !cpu_has_tsc;
-       timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
+       timer_ack = 1;
        if (timer_over_8254 > 0)
                enable_8259A_irq(0);
  
@@@ -2362,8 -2347,8 +2354,8 @@@ static int ioapic_resume(struct sys_dev
  
        spin_lock_irqsave(&ioapic_lock, flags);
        reg_00.raw = io_apic_read(dev->id, 0);
 -      if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
 -              reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
 +      if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) {
 +              reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid;
                io_apic_write(dev->id, 0, reg_00.raw);
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
@@@ -2796,7 -2781,7 +2788,7 @@@ int io_apic_set_pci_routing (int ioapic
  
        apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
                "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
 -              mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
 +              mp_ioapics[ioapic].mp_apicid, pin, entry.vector, irq,
                edge_level, active_high_low);
  
        ioapic_register_intr(irq, entry.vector, edge_level);
@@@ -2817,8 -2802,8 +2809,8 @@@ int acpi_get_override_irq(int bus_irq, 
                return -1;
  
        for (i = 0; i < mp_irq_entries; i++)
 -              if (mp_irqs[i].mpc_irqtype == mp_INT &&
 -                  mp_irqs[i].mpc_srcbusirq == bus_irq)
 +              if (mp_irqs[i].mp_irqtype == mp_INT &&
 +                  mp_irqs[i].mp_srcbusirq == bus_irq)
                        break;
        if (i >= mp_irq_entries)
                return -1;
index 4fa9f6c4542be3464747b800e3119798430ffed5,5a2f8e0638875a348fcf415bef070fbece342fa5..1d4be07e15e545fdf767fd679653bacf33772a81
  #include <asm/bios_ebda.h>
  #include <asm/cacheflush.h>
  #include <asm/processor.h>
 +#include <asm/efi.h>
  
  /* This value is set up by the early boot code to point to the value
     immediately after the boot time page tables.  It contains a *physical*
     address, and must not be in the .bss segment! */
 +unsigned long init_pg_tables_start __initdata = ~0UL;
  unsigned long init_pg_tables_end __initdata = ~0UL;
  
  /*
@@@ -239,6 -237,42 +239,6 @@@ static inline void copy_edd(void
  }
  #endif
  
 -int __initdata user_defined_memmap;
 -
 -/*
 - * "mem=nopentium" disables the 4MB page tables.
 - * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
 - * to <mem>, overriding the bios size.
 - * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
 - * <start> to <start>+<mem>, overriding the bios size.
 - *
 - * HPA tells me bootloaders need to parse mem=, so no new
 - * option should be mem=  [also see Documentation/i386/boot.txt]
 - */
 -static int __init parse_mem(char *arg)
 -{
 -      if (!arg)
 -              return -EINVAL;
 -
 -      if (strcmp(arg, "nopentium") == 0) {
 -              setup_clear_cpu_cap(X86_FEATURE_PSE);
 -      } else {
 -              /* If the user specifies memory size, we
 -               * limit the BIOS-provided memory map to
 -               * that size. exactmap can be used to specify
 -               * the exact map. mem=number can be used to
 -               * trim the existing memory map.
 -               */
 -              unsigned long long mem_size;
 -
 -              mem_size = memparse(arg, &arg);
 -              limit_regions(mem_size);
 -              user_defined_memmap = 1;
 -      }
 -      return 0;
 -}
 -early_param("mem", parse_mem);
 -
  #ifdef CONFIG_PROC_VMCORE
  /* elfcorehdr= specifies the location of elf core header
   * stored by the crashed kernel.
@@@ -361,6 -395,56 +361,6 @@@ unsigned long __init find_max_low_pfn(v
        return max_low_pfn;
  }
  
 -#define BIOS_LOWMEM_KILOBYTES 0x413
 -
 -/*
 - * The BIOS places the EBDA/XBDA at the top of conventional
 - * memory, and usually decreases the reported amount of
 - * conventional memory (int 0x12) too. This also contains a
 - * workaround for Dell systems that neglect to reserve EBDA.
 - * The same workaround also avoids a problem with the AMD768MPX
 - * chipset: reserve a page before VGA to prevent PCI prefetch
 - * into it (errata #56). Usually the page is reserved anyways,
 - * unless you have no PS/2 mouse plugged in.
 - */
 -static void __init reserve_ebda_region(void)
 -{
 -      unsigned int lowmem, ebda_addr;
 -
 -      /* To determine the position of the EBDA and the */
 -      /* end of conventional memory, we need to look at */
 -      /* the BIOS data area. In a paravirtual environment */
 -      /* that area is absent. We'll just have to assume */
 -      /* that the paravirt case can handle memory setup */
 -      /* correctly, without our help. */
 -      if (paravirt_enabled())
 -              return;
 -
 -      /* end of low (conventional) memory */
 -      lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES);
 -      lowmem <<= 10;
 -
 -      /* start of EBDA area */
 -      ebda_addr = get_bios_ebda();
 -
 -      /* Fixup: bios puts an EBDA in the top 64K segment */
 -      /* of conventional memory, but does not adjust lowmem. */
 -      if ((lowmem - ebda_addr) <= 0x10000)
 -              lowmem = ebda_addr;
 -
 -      /* Fixup: bios does not report an EBDA at all. */
 -      /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */
 -      if ((ebda_addr == 0) && (lowmem >= 0x9f000))
 -              lowmem = 0x9f000;
 -
 -      /* Paranoia: should never happen, but... */
 -      if ((lowmem == 0) || (lowmem >= 0x100000))
 -              lowmem = 0x9f000;
 -
 -      /* reserve all memory between lowmem and the 1MB mark */
 -      reserve_bootmem(lowmem, 0x100000 - lowmem, BOOTMEM_DEFAULT);
 -}
 -
  #ifndef CONFIG_NEED_MULTIPLE_NODES
  static void __init setup_bootmem_allocator(void);
  static unsigned long __init setup_memory(void)
        if (max_pfn > max_low_pfn) {
                highstart_pfn = max_low_pfn;
        }
 +      memory_present(0, 0, highend_pfn);
        printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
                pages_to_mb(highend_pfn - highstart_pfn));
        num_physpages = highend_pfn;
        high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
  #else
 +      memory_present(0, 0, max_low_pfn);
        num_physpages = max_low_pfn;
        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
  #endif
@@@ -406,12 -488,11 +406,12 @@@ static void __init zone_sizes_init(void
        max_zone_pfns[ZONE_DMA] =
                virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 +      remove_all_active_ranges();
  #ifdef CONFIG_HIGHMEM
        max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
 -      add_active_range(0, 0, highend_pfn);
 +      e820_register_active_regions(0, 0, highend_pfn);
  #else
 -      add_active_range(0, 0, max_low_pfn);
 +      e820_register_active_regions(0, 0, max_low_pfn);
  #endif
  
        free_area_init_nodes(max_zone_pfns);
@@@ -451,10 -532,16 +451,16 @@@ static void __init reserve_crashkernel(
                                        (unsigned long)(crash_size >> 20),
                                        (unsigned long)(crash_base >> 20),
                                        (unsigned long)(total_mem >> 20));
+                       if (reserve_bootmem(crash_base, crash_size,
+                                       BOOTMEM_EXCLUSIVE) < 0) {
+                               printk(KERN_INFO "crashkernel reservation "
+                                       "failed - memory is in use\n");
+                               return;
+                       }
                        crashk_res.start = crash_base;
                        crashk_res.end   = crash_base + crash_size - 1;
-                       reserve_bootmem(crash_base, crash_size,
-                                       BOOTMEM_DEFAULT);
                } else
                        printk(KERN_INFO "crashkernel reservation failed - "
                                        "you have to specify a base address\n");
@@@ -471,57 -558,44 +477,57 @@@ static bool do_relocate_initrd = false
  
  static void __init reserve_initrd(void)
  {
 -      unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
 -      unsigned long ramdisk_size  = boot_params.hdr.ramdisk_size;
 -      unsigned long ramdisk_end   = ramdisk_image + ramdisk_size;
 -      unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
 -      unsigned long ramdisk_here;
 -
 -      initrd_start = 0;
 +      u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 +      u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
 +      u64 ramdisk_end   = ramdisk_image + ramdisk_size;
 +      u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
 +      u64 ramdisk_here;
  
        if (!boot_params.hdr.type_of_loader ||
            !ramdisk_image || !ramdisk_size)
                return;         /* No initrd provided by bootloader */
  
 -      if (ramdisk_end < ramdisk_image) {
 -              printk(KERN_ERR "initrd wraps around end of memory, "
 -                     "disabling initrd\n");
 -              return;
 -      }
 +      initrd_start = 0;
 +
        if (ramdisk_size >= end_of_lowmem/2) {
 +              free_early(ramdisk_image, ramdisk_end);
                printk(KERN_ERR "initrd too large to handle, "
                       "disabling initrd\n");
                return;
        }
 +
 +      printk(KERN_INFO "old RAMDISK: %08llx - %08llx\n", ramdisk_image,
 +                      ramdisk_end);
 +
 +
        if (ramdisk_end <= end_of_lowmem) {
                /* All in lowmem, easy case */
 -              reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT);
 +              /*
 +               * don't need to reserve again, already reserved early
 +               * in i386_start_kernel
 +               */
                initrd_start = ramdisk_image + PAGE_OFFSET;
                initrd_end = initrd_start+ramdisk_size;
                return;
        }
  
        /* We need to move the initrd down into lowmem */
 -      ramdisk_here = (end_of_lowmem - ramdisk_size) & PAGE_MASK;
 +      ramdisk_here = find_e820_area(min_low_pfn<<PAGE_SHIFT,
 +                               end_of_lowmem, ramdisk_size,
 +                               PAGE_SIZE);
 +
 +      if (ramdisk_here == -1ULL)
 +              panic("Cannot find place for new RAMDISK of size %lld\n",
 +                       ramdisk_size);
  
        /* Note: this includes all the lowmem currently occupied by
           the initrd, we rely on that fact to keep the data intact. */
 -      reserve_bootmem(ramdisk_here, ramdisk_size, BOOTMEM_DEFAULT);
 +      reserve_early(ramdisk_here, ramdisk_here + ramdisk_size,
 +                       "NEW RAMDISK");
        initrd_start = ramdisk_here + PAGE_OFFSET;
        initrd_end   = initrd_start + ramdisk_size;
 +      printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n",
 +                       ramdisk_here, ramdisk_here + ramdisk_size);
  
        do_relocate_initrd = true;
  }
  
  static void __init relocate_initrd(void)
  {
 -      unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
 -      unsigned long ramdisk_size  = boot_params.hdr.ramdisk_size;
 -      unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
 -      unsigned long ramdisk_here;
 +      u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 +      u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
 +      u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
 +      u64 ramdisk_here;
        unsigned long slop, clen, mapaddr;
        char *p, *q;
  
                p = (char *)__va(ramdisk_image);
                memcpy(q, p, clen);
                q += clen;
 +              /* need to free these low pages...*/
 +              printk(KERN_INFO "Freeing old partial RAMDISK %08llx-%08llx\n",
 +                       ramdisk_image, ramdisk_image + clen - 1);
 +              free_bootmem(ramdisk_image, clen);
                ramdisk_image += clen;
                ramdisk_size  -= clen;
        }
                ramdisk_image += clen;
                ramdisk_size  -= clen;
        }
 +      /* high pages is not converted by early_res_to_bootmem */
 +      ramdisk_image = boot_params.hdr.ramdisk_image;
 +      ramdisk_size  = boot_params.hdr.ramdisk_size;
 +      printk(KERN_INFO "Copied RAMDISK from %016llx - %016llx to %08llx - %08llx\n",
 +              ramdisk_image, ramdisk_image + ramdisk_size - 1,
 +              ramdisk_here, ramdisk_here + ramdisk_size - 1);
  }
  
  #endif /* CONFIG_BLK_DEV_INITRD */
  
  void __init setup_bootmem_allocator(void)
  {
 -      unsigned long bootmap_size;
 +      int i;
 +      unsigned long bootmap_size, bootmap;
        /*
         * Initialize the boot-time allocator (with low memory only):
         */
 -      bootmap_size = init_bootmem(min_low_pfn, max_low_pfn);
 -
 -      register_bootmem_low_pages(max_low_pfn);
 -
 -      /*
 -       * Reserve the bootmem bitmap itself as well. We do this in two
 -       * steps (first step was init_bootmem()) because this catches
 -       * the (very unlikely) case of us accidentally initializing the
 -       * bootmem allocator with an invalid RAM area.
 -       */
 -      reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
 -                       bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
 -                       BOOTMEM_DEFAULT);
 -
 -      /*
 -       * reserve physical page 0 - it's a special BIOS page on many boxes,
 -       * enabling clean reboots, SMP operation, laptop functions.
 -       */
 -      reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
 -
 -      /* reserve EBDA region */
 -      reserve_ebda_region();
 -
 -#ifdef CONFIG_SMP
 -      /*
 -       * But first pinch a few for the stack/trampoline stuff
 -       * FIXME: Don't need the extra page at 4K, but need to fix
 -       * trampoline before removing it. (see the GDT stuff)
 -       */
 -      reserve_bootmem(PAGE_SIZE, PAGE_SIZE, BOOTMEM_DEFAULT);
 +      bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT;
 +      bootmap = find_e820_area(min_low_pfn<<PAGE_SHIFT,
 +                               max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
 +                               PAGE_SIZE);
 +      if (bootmap == -1L)
 +              panic("Cannot find bootmem map of size %ld\n", bootmap_size);
 +      reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
 +#ifdef CONFIG_BLK_DEV_INITRD
 +      reserve_initrd();
  #endif
 +      bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn);
 +      printk(KERN_INFO "  mapped low ram: 0 - %08lx\n",
 +               max_pfn_mapped<<PAGE_SHIFT);
 +      printk(KERN_INFO "  low ram: %08lx - %08lx\n",
 +               min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT);
 +      printk(KERN_INFO "  bootmap %08lx - %08lx\n",
 +               bootmap, bootmap + bootmap_size);
 +      for_each_online_node(i)
 +              free_bootmem_with_active_regions(i, max_low_pfn);
 +      early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
 +
  #ifdef CONFIG_ACPI_SLEEP
        /*
         * Reserve low memory region for sleep support.
         */
        find_smp_config();
  #endif
 -#ifdef CONFIG_BLK_DEV_INITRD
 -      reserve_initrd();
 -#endif
 -      numa_kva_reserve();
        reserve_crashkernel();
  
        reserve_ibft_region();
@@@ -654,6 -731,12 +660,6 @@@ static void set_mca_bus(int x
  static void set_mca_bus(int x) { }
  #endif
  
 -/* Overridden in paravirt.c if CONFIG_PARAVIRT */
 -char * __init __attribute__((weak)) memory_setup(void)
 -{
 -      return machine_specific_memory_setup();
 -}
 -
  #ifdef CONFIG_NUMA
  /*
   * In the golden day, when everything among i386 and x86_64 will be
@@@ -681,14 -764,11 +687,14 @@@ void __init setup_arch(char **cmdline_p
        pre_setup_arch_hook();
        early_cpu_init();
        early_ioremap_init();
 +      reserve_setup_data();
  
  #ifdef CONFIG_EFI
        if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
 -                   "EL32", 4))
 +                   "EL32", 4)) {
                efi_enabled = 1;
 +              efi_reserve_early();
 +      }
  #endif
  
        ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
  #endif
        ARCH_SETUP
  
 -      printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 -      print_memory_map(memory_setup());
 +      setup_memory_map();
  
        copy_edd();
  
        bss_resource.start = virt_to_phys(&__bss_start);
        bss_resource.end = virt_to_phys(&__bss_stop)-1;
  
 +      parse_setup_data();
 +
        parse_early_param();
  
 -      if (user_defined_memmap) {
 -              printk(KERN_INFO "user-defined physical RAM map:\n");
 -              print_memory_map("user");
 -      }
 +      finish_e820_parsing();
  
        strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
        if (efi_enabled)
                efi_init();
  
 +      e820_register_active_regions(0, 0, -1UL);
 +      /*
 +       * partially used pages are not usable - thus
 +       * we are rounding upwards:
 +       */
 +      max_pfn = e820_end_of_ram();
 +
 +      /* preallocate 4k for mptable mpc */
 +      early_reserve_e820_mpc_new();
        /* update e820 for memory not covered by WB MTRRs */
 -      propagate_e820_map();
        mtrr_bp_init();
 -      if (mtrr_trim_uncached_memory(max_pfn))
 -              propagate_e820_map();
 +      if (mtrr_trim_uncached_memory(max_pfn)) {
 +              remove_all_active_ranges();
 +              e820_register_active_regions(0, 0, -1UL);
 +              max_pfn = e820_end_of_ram();
 +      }
  
        max_low_pfn = setup_memory();
  
         * not to exceed the 8Mb limit.
         */
  
 -#ifdef CONFIG_SMP
 -      smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 -#endif
        paging_init();
  
        /*
  
  #ifdef CONFIG_ACPI
        acpi_boot_init();
 -
 +#endif
 +#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
 +      if (smp_found_config)
 +              get_smp_config();
 +#endif
  #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
        if (def_to_bigsmp)
                printk(KERN_WARNING "More than 8 CPUs detected and "
                        "CONFIG_X86_PC cannot handle it.\nUse "
                        "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
  #endif
 -#endif
 -#ifdef CONFIG_X86_LOCAL_APIC
 -      if (smp_found_config)
 -              get_smp_config();
 -#endif
  
 -      e820_register_memory();
 -      e820_mark_nosave_regions();
 +      e820_setup_gap();
 +      e820_mark_nosave_regions(max_low_pfn);
  
  #ifdef CONFIG_VT
  #if defined(CONFIG_VGA_CONSOLE)
index 843722e2b79e6ece26039c0b37f04d23d0a532ff,3e1cecedde42747261c94053a53191ffa7291107..83e62137911be188f9b75a592ddd304d806dddc6
@@@ -555,6 -555,23 +555,6 @@@ cpumask_t cpu_coregroup_map(int cpu
                return c->llc_shared_map;
  }
  
 -#ifdef CONFIG_X86_32
 -/*
 - * We are called very early to get the low memory for the
 - * SMP bootup trampoline page.
 - */
 -void __init smp_alloc_memory(void)
 -{
 -      trampoline_base = alloc_bootmem_low_pages(PAGE_SIZE);
 -      /*
 -       * Has to be in very low memory so we can execute
 -       * real-mode AP code.
 -       */
 -      if (__pa(trampoline_base) >= 0x9F000)
 -              BUG();
 -}
 -#endif
 -
  static void impress_friends(void)
  {
        int cpu;
@@@ -979,7 -996,6 +979,6 @@@ do_rest
  #endif
                cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */
                cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
-               cpu_clear(cpu, cpu_possible_map);
                cpu_clear(cpu, cpu_present_map);
                per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
        }
@@@ -1173,6 -1189,7 +1172,7 @@@ static void __init smp_cpu_index_defaul
   */
  void __init native_smp_prepare_cpus(unsigned int max_cpus)
  {
+       preempt_disable();
        nmi_watchdog_default();
        smp_cpu_index_default();
        current_cpu_data = boot_cpu_data;
        if (smp_sanity_check(max_cpus) < 0) {
                printk(KERN_INFO "SMP disabled\n");
                disable_smp();
-               return;
+               goto out;
        }
  
        preempt_disable();
        printk(KERN_INFO "CPU%d: ", 0);
        print_cpu_info(&cpu_data(0));
        setup_boot_clock();
+ out:
+       preempt_enable();
  }
  /*
   * Early setup to make printk work.
diff --combined arch/x86/lguest/boot.c
index bf7c34a3aaebfcf97bea4bbf748c14ad09d44bae,5c7e2fd52075be167680311b13d5e7c9d120bbe4..5e4772907c6e3d629793092a21cfab78dfee066b
@@@ -582,8 -582,9 +582,9 @@@ static void __init lguest_init_IRQ(void
                int vector = FIRST_EXTERNAL_VECTOR + i;
                if (vector != SYSCALL_VECTOR) {
                        set_intr_gate(vector, interrupt[i]);
-                       set_irq_chip_and_handler(i, &lguest_irq_controller,
-                                                handle_level_irq);
+                       set_irq_chip_and_handler_name(i, &lguest_irq_controller,
+                                                     handle_level_irq,
+                                                     "level");
                }
        }
        /* This call is required to set up for 4k stacks, where we have
@@@ -1011,7 -1012,6 +1012,7 @@@ __init void lguest_init(void
         * clobbered.  The Launcher places our initial pagetables somewhere at
         * the top of our physical memory, so we don't need extra space: set
         * init_pg_tables_end to the end of the kernel. */
 +      init_pg_tables_start = __pa(pg0);
        init_pg_tables_end = __pa(pg0);
  
        /* Load the %fs segment register (the per-cpu segment register) with
        pm_power_off = lguest_power_off;
        machine_ops.restart = lguest_restart;
  
 -      /* Now we're set up, call start_kernel() in init/main.c and we proceed
 +      /* Now we're set up, call i386_start_kernel() in head32.c and we proceed
         * to boot as normal.  It never returns. */
 -      start_kernel();
 +      i386_start_kernel();
  }
  /*
   * This marks the end of stage II of our journey, The Guest.
diff --combined arch/x86/xen/enlighten.c
index ccc7b84ddabf6b94962d307aaa8ea253d05cfa86,f09c1c69c37a1498da07524c477e98bfc397ebe6..275163f81464d452dc75f3f9a5af5d3a7b51a38b
@@@ -785,38 -785,35 +785,35 @@@ static __init void xen_set_pte_init(pte
  static __init void xen_pagetable_setup_start(pgd_t *base)
  {
        pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
+       int i;
  
        /* special set_pte for pagetable initialization */
        pv_mmu_ops.set_pte = xen_set_pte_init;
  
        init_mm.pgd = base;
        /*
-        * copy top-level of Xen-supplied pagetable into place.  For
-        * !PAE we can use this as-is, but for PAE it is a stand-in
-        * while we copy the pmd pages.
+        * copy top-level of Xen-supplied pagetable into place.  This
+        * is a stand-in while we copy the pmd pages.
         */
        memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
  
-       if (PTRS_PER_PMD > 1) {
-               int i;
-               /*
-                * For PAE, need to allocate new pmds, rather than
-                * share Xen's, since Xen doesn't like pmd's being
-                * shared between address spaces.
-                */
-               for (i = 0; i < PTRS_PER_PGD; i++) {
-                       if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
-                               pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+       /*
+        * For PAE, need to allocate new pmds, rather than
+        * share Xen's, since Xen doesn't like pmd's being
+        * shared between address spaces.
+        */
+       for (i = 0; i < PTRS_PER_PGD; i++) {
+               if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
+                       pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
  
-                               memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
-                                      PAGE_SIZE);
+                       memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
+                              PAGE_SIZE);
  
-                               make_lowmem_page_readonly(pmd);
+                       make_lowmem_page_readonly(pmd);
  
-                               set_pgd(&base[i], __pgd(1 + __pa(pmd)));
-                       } else
-                               pgd_clear(&base[i]);
-               }
+                       set_pgd(&base[i], __pgd(1 + __pa(pmd)));
+               } else
+                       pgd_clear(&base[i]);
        }
  
        /* make sure zero_page is mapped RO so we can use it in pagetables */
@@@ -873,17 -870,7 +870,7 @@@ static __init void xen_pagetable_setup_
  
        /* Actually pin the pagetable down, but we can't set PG_pinned
           yet because the page structures don't exist yet. */
-       {
-               unsigned level;
- #ifdef CONFIG_X86_PAE
-               level = MMUEXT_PIN_L3_TABLE;
- #else
-               level = MMUEXT_PIN_L2_TABLE;
- #endif
-               pin_pagetable_pfn(level, PFN_DOWN(__pa(base)));
-       }
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
  }
  
  /* This is called once we have the cpu_possible_map */
@@@ -1093,7 -1080,6 +1080,6 @@@ static const struct pv_mmu_ops xen_mmu_
        .make_pte = xen_make_pte,
        .make_pgd = xen_make_pgd,
  
- #ifdef CONFIG_X86_PAE
        .set_pte_atomic = xen_set_pte_atomic,
        .set_pte_present = xen_set_pte_at,
        .set_pud = xen_set_pud,
  
        .make_pmd = xen_make_pmd,
        .pmd_val = xen_pmd_val,
- #endif        /* PAE */
  
        .activate_mm = xen_activate_mm,
        .dup_mmap = xen_dup_mmap,
@@@ -1211,7 -1196,6 +1196,7 @@@ asmlinkage void __init xen_start_kernel
  
        pgd = (pgd_t *)xen_start_info->pt_base;
  
 +      init_pg_tables_start = __pa(pgd);
        init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
  
        init_mm.pgd = pgd; /* use the Xen pagetables to start */
        if (xen_feature(XENFEAT_supervisor_mode_kernel))
                pv_info.kernel_rpl = 0;
  
+       /* Prevent unwanted bits from being set in PTEs. */
+       __supported_pte_mask &= ~_PAGE_GLOBAL;
+       if (!is_initial_xendomain())
+               __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
        /* set the limit of our address space */
        xen_reserve_top();
  
                add_preferred_console("hvc", 0, NULL);
  
        /* Start the world */
 -      start_kernel();
 +      i386_start_kernel();
  }
diff --combined include/linux/mm.h
index 7cbd949f25169036fdbbdb21c6b71eb0707297cf,586a943cab018647da208582bc1f19e0dc485f1d..ce8e397a61f69a5836109214c54f99bdda25117a
@@@ -760,16 -760,17 +760,17 @@@ unsigned long unmap_vmas(struct mmu_gat
   * (see walk_page_range for more details)
   */
  struct mm_walk {
-       int (*pgd_entry)(pgd_t *, unsigned long, unsigned long, void *);
-       int (*pud_entry)(pud_t *, unsigned long, unsigned long, void *);
-       int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, void *);
-       int (*pte_entry)(pte_t *, unsigned long, unsigned long, void *);
-       int (*pte_hole)(unsigned long, unsigned long, void *);
+       int (*pgd_entry)(pgd_t *, unsigned long, unsigned long, struct mm_walk *);
+       int (*pud_entry)(pud_t *, unsigned long, unsigned long, struct mm_walk *);
+       int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *);
+       int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *);
+       int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *);
+       struct mm_struct *mm;
+       void *private;
  };
  
- int walk_page_range(const struct mm_struct *, unsigned long addr,
-                   unsigned long end, const struct mm_walk *walk,
-                   void *private);
+ int walk_page_range(unsigned long addr, unsigned long end,
+               struct mm_walk *walk);
  void free_pgd_range(struct mmu_gather **tlb, unsigned long addr,
                unsigned long end, unsigned long floor, unsigned long ceiling);
  void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *start_vma,
@@@ -997,7 -998,8 +998,7 @@@ extern void free_area_init_node(int nid
  extern void free_area_init_nodes(unsigned long *max_zone_pfn);
  extern void add_active_range(unsigned int nid, unsigned long start_pfn,
                                        unsigned long end_pfn);
 -extern void shrink_active_range(unsigned int nid, unsigned long old_end_pfn,
 -                                              unsigned long new_end_pfn);
 +extern void shrink_active_range(unsigned int nid, unsigned long new_end_pfn);
  extern void push_node_boundaries(unsigned int nid, unsigned long start_pfn,
                                        unsigned long end_pfn);
  extern void remove_all_active_ranges(void);
diff --combined mm/page_alloc.c
index 2154086840762d382574cba64c596751cbdd2eb3,f32fae3121f07461f846911ee6963ce679828780..eee5ba7509c17b9ed521bea99aca23bbdc5444c9
@@@ -237,16 -237,7 +237,7 @@@ static void bad_page(struct page *page
        printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n"
                KERN_EMERG "Backtrace:\n");
        dump_stack();
-       page->flags &= ~(1 << PG_lru    |
-                       1 << PG_private |
-                       1 << PG_locked  |
-                       1 << PG_active  |
-                       1 << PG_dirty   |
-                       1 << PG_reclaim |
-                       1 << PG_slab    |
-                       1 << PG_swapcache |
-                       1 << PG_writeback |
-                       1 << PG_buddy );
+       page->flags &= ~PAGE_FLAGS_CLEAR_WHEN_BAD;
        set_page_count(page, 0);
        reset_page_mapcount(page);
        page->mapping = NULL;
@@@ -463,16 -454,7 +454,7 @@@ static inline int free_pages_check(stru
                (page->mapping != NULL)  |
                (page_get_page_cgroup(page) != NULL) |
                (page_count(page) != 0)  |
-               (page->flags & (
-                       1 << PG_lru     |
-                       1 << PG_private |
-                       1 << PG_locked  |
-                       1 << PG_active  |
-                       1 << PG_slab    |
-                       1 << PG_swapcache |
-                       1 << PG_writeback |
-                       1 << PG_reserved |
-                       1 << PG_buddy ))))
+               (page->flags & PAGE_FLAGS_CHECK_AT_FREE)))
                bad_page(page);
        if (PageDirty(page))
                __ClearPageDirty(page);
@@@ -616,17 -598,7 +598,7 @@@ static int prep_new_page(struct page *p
                (page->mapping != NULL)  |
                (page_get_page_cgroup(page) != NULL) |
                (page_count(page) != 0)  |
-               (page->flags & (
-                       1 << PG_lru     |
-                       1 << PG_private |
-                       1 << PG_locked  |
-                       1 << PG_active  |
-                       1 << PG_dirty   |
-                       1 << PG_slab    |
-                       1 << PG_swapcache |
-                       1 << PG_writeback |
-                       1 << PG_reserved |
-                       1 << PG_buddy ))))
+               (page->flags & PAGE_FLAGS_CHECK_AT_PREP)))
                bad_page(page);
  
        /*
@@@ -1396,6 -1368,9 +1368,9 @@@ get_page_from_freelist(gfp_t gfp_mask, 
  
        (void)first_zones_zonelist(zonelist, high_zoneidx, nodemask,
                                                        &preferred_zone);
+       if (!preferred_zone)
+               return NULL;
        classzone_idx = zone_idx(preferred_zone);
  
  zonelist_scan:
@@@ -2353,7 -2328,6 +2328,6 @@@ static void build_zonelists(pg_data_t *
  static void build_zonelist_cache(pg_data_t *pgdat)
  {
        pgdat->node_zonelists[0].zlcache_ptr = NULL;
-       pgdat->node_zonelists[1].zlcache_ptr = NULL;
  }
  
  #endif        /* CONFIG_NUMA */
@@@ -2804,7 -2778,7 +2778,7 @@@ int zone_wait_table_init(struct zone *z
        alloc_size = zone->wait_table_hash_nr_entries
                                        * sizeof(wait_queue_head_t);
  
-       if (system_state == SYSTEM_BOOTING) {
+       if (!slab_is_available()) {
                zone->wait_table = (wait_queue_head_t *)
                        alloc_bootmem_node(pgdat, alloc_size);
        } else {
@@@ -3378,7 -3352,8 +3352,8 @@@ static void __paginginit free_area_init
                 * is used by this zone for memmap. This affects the watermark
                 * and per-cpu initialisations
                 */
-               memmap_pages = (size * sizeof(struct page)) >> PAGE_SHIFT;
+               memmap_pages =
+                       PAGE_ALIGN(size * sizeof(struct page)) >> PAGE_SHIFT;
                if (realsize >= memmap_pages) {
                        realsize -= memmap_pages;
                        printk(KERN_DEBUG
@@@ -3486,11 -3461,6 +3461,11 @@@ void __paginginit free_area_init_node(i
        calculate_node_totalpages(pgdat, zones_size, zholes_size);
  
        alloc_node_mem_map(pgdat);
 +#ifdef CONFIG_FLAT_NODE_MEM_MAP
 +      printk(KERN_DEBUG "free_area_init_node: node %d, pgdat %08lx, node_mem_map %08lx\n",
 +              nid, (unsigned long)pgdat,
 +              (unsigned long)pgdat->node_mem_map);
 +#endif
  
        free_area_init_core(pgdat, zones_size, zholes_size);
  }
@@@ -3579,49 -3549,25 +3554,49 @@@ void __init add_active_range(unsigned i
  /**
   * shrink_active_range - Shrink an existing registered range of PFNs
   * @nid: The node id the range is on that should be shrunk
 - * @old_end_pfn: The old end PFN of the range
   * @new_end_pfn: The new PFN of the range
   *
   * i386 with NUMA use alloc_remap() to store a node_mem_map on a local node.
 - * The map is kept at the end physical page range that has already been
 - * registered with add_active_range(). This function allows an arch to shrink
 - * an existing registered range.
 + * The map is kept near the end physical page range that has already been
 + * registered. This function allows an arch to shrink an existing registered
 + * range.
   */
 -void __init shrink_active_range(unsigned int nid, unsigned long old_end_pfn,
 -                                              unsigned long new_end_pfn)
 +void __init shrink_active_range(unsigned int nid, unsigned long new_end_pfn)
  {
 -      int i;
 +      int i, j;
 +      int removed = 0;
  
        /* Find the old active region end and shrink */
 -      for_each_active_range_index_in_nid(i, nid)
 -              if (early_node_map[i].end_pfn == old_end_pfn) {
 +      for_each_active_range_index_in_nid(i, nid) {
 +              if (early_node_map[i].start_pfn >= new_end_pfn) {
 +                      /* clear it */
 +                      early_node_map[i].end_pfn = 0;
 +                      removed = 1;
 +                      continue;
 +              }
 +              if (early_node_map[i].end_pfn > new_end_pfn) {
                        early_node_map[i].end_pfn = new_end_pfn;
 -                      break;
 +                      continue;
                }
 +      }
 +
 +      if (!removed)
 +              return;
 +
 +      /* remove the blank ones */
 +      for (i = nr_nodemap_entries - 1; i > 0; i--) {
 +              if (early_node_map[i].nid != nid)
 +                      continue;
 +              if (early_node_map[i].end_pfn)
 +                      continue;
 +              /* we found it, get rid of it */
 +              for (j = i; j < nr_nodemap_entries - 1; j++)
 +                      memcpy(&early_node_map[j], &early_node_map[j+1],
 +                              sizeof(early_node_map[j]));
 +              j = nr_nodemap_entries - 1;
 +              memset(&early_node_map[j], 0, sizeof(early_node_map[j]));
 +              nr_nodemap_entries--;
 +      }
  }
  
  /**