Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 May 2016 22:54:01 +0000 (15:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 May 2016 22:54:01 +0000 (15:54 -0700)
Pull x86 boot updates from Ingo Molnar:
 "The biggest changes in this cycle were:

   - prepare for more KASLR related changes, by restructuring, cleaning
     up and fixing the existing boot code.  (Kees Cook, Baoquan He,
     Yinghai Lu)

   - simplifly/concentrate subarch handling code, eliminate
     paravirt_enabled() usage.  (Luis R Rodriguez)"

* 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (50 commits)
  x86/KASLR: Clarify purpose of each get_random_long()
  x86/KASLR: Add virtual address choosing function
  x86/KASLR: Return earliest overlap when avoiding regions
  x86/KASLR: Add 'struct slot_area' to manage random_addr slots
  x86/boot: Add missing file header comments
  x86/KASLR: Initialize mapping_info every time
  x86/boot: Comment what finalize_identity_maps() does
  x86/KASLR: Build identity mappings on demand
  x86/boot: Split out kernel_ident_mapping_init()
  x86/boot: Clean up indenting for asm/boot.h
  x86/KASLR: Improve comments around the mem_avoid[] logic
  x86/boot: Simplify pointer casting in choose_random_location()
  x86/KASLR: Consolidate mem_avoid[] entries
  x86/boot: Clean up pointer casting
  x86/boot: Warn on future overlapping memcpy() use
  x86/boot: Extract error reporting functions
  x86/boot: Correctly bounds-check relocations
  x86/KASLR: Clean up unused code from old 'run_size' and rename it to 'kernel_total_size'
  x86/boot: Fix "run_size" calculation
  x86/boot: Calculate decompression size during boot not build
  ...

1  2 
arch/x86/Kconfig
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/processor.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/kvm.c
arch/x86/kernel/paravirt.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/xen/enlighten.c

diff --combined arch/x86/Kconfig
index a494fa34713aa846ae89d307f83870f22bfea32c,5892d549596d602ed4512c606b9d5a72dc0f483e..7bb15747fea251ff5470085ed454655398f9d60f
@@@ -164,6 -164,10 +164,6 @@@ config INSTRUCTION_DECODE
        def_bool y
        depends on KPROBES || PERF_EVENTS || UPROBES
  
 -config PERF_EVENTS_INTEL_UNCORE
 -      def_bool y
 -      depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
 -
  config OUTPUT_FORMAT
        string
        default "elf32-i386" if X86_32
@@@ -1042,8 -1046,6 +1042,8 @@@ config X86_THERMAL_VECTO
        def_bool y
        depends on X86_MCE_INTEL
  
 +source "arch/x86/events/Kconfig"
 +
  config X86_LEGACY_VM86
        bool "Legacy VM86 support"
        default n
@@@ -1208,6 -1210,15 +1208,6 @@@ config MICROCODE_OLD_INTERFAC
        def_bool y
        depends on MICROCODE
  
 -config PERF_EVENTS_AMD_POWER
 -      depends on PERF_EVENTS && CPU_SUP_AMD
 -      tristate "AMD Processor Power Reporting Mechanism"
 -      ---help---
 -        Provide power reporting mechanism support for AMD processors.
 -        Currently, it leverages X86_FEATURE_ACC_POWER
 -        (CPUID Fn8000_0007_EDX[12]) interface to calculate the
 -        average power consumption on Family 15h processors.
 -
  config X86_MSR
        tristate "/dev/cpu/*/msr - Model-specific register support"
        ---help---
@@@ -1921,54 -1932,38 +1921,38 @@@ config RELOCATABL
          (CONFIG_PHYSICAL_START) is used as the minimum location.
  
  config RANDOMIZE_BASE
-       bool "Randomize the address of the kernel image"
+       bool "Randomize the address of the kernel image (KASLR)"
        depends on RELOCATABLE
        default n
        ---help---
-          Randomizes the physical and virtual address at which the
-          kernel image is decompressed, as a security feature that
-          deters exploit attempts relying on knowledge of the location
-          of kernel internals.
+         In support of Kernel Address Space Layout Randomization (KASLR),
+         this randomizes the physical address at which the kernel image
+         is decompressed and the virtual address where the kernel
+         image is mapped, as a security feature that deters exploit
+         attempts relying on knowledge of the location of kernel
+         code internals.
+         The kernel physical and virtual address can be randomized
+         from 16MB up to 1GB on 64-bit and 512MB on 32-bit. (Note that
+         using RANDOMIZE_BASE reduces the memory space available to
+         kernel modules from 1.5GB to 1GB.)
+         Entropy is generated using the RDRAND instruction if it is
+         supported. If RDTSC is supported, its value is mixed into
+         the entropy pool as well. If neither RDRAND nor RDTSC are
+         supported, then entropy is read from the i8254 timer.
+         Since the kernel is built using 2GB addressing, and
+         PHYSICAL_ALIGN must be at a minimum of 2MB, only 10 bits of
+         entropy is theoretically possible. Currently, with the
+         default value for PHYSICAL_ALIGN and due to page table
+         layouts, 64-bit uses 9 bits of entropy and 32-bit uses 8 bits.
+         If CONFIG_HIBERNATE is also enabled, KASLR is disabled at boot
+         time. To enable it, boot with "kaslr" on the kernel command
+         line (which will also disable hibernation).
  
-          Entropy is generated using the RDRAND instruction if it is
-          supported. If RDTSC is supported, it is used as well. If
-          neither RDRAND nor RDTSC are supported, then randomness is
-          read from the i8254 timer.
-          The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET,
-          and aligned according to PHYSICAL_ALIGN. Since the kernel is
-          built using 2GiB addressing, and PHYSICAL_ALGIN must be at a
-          minimum of 2MiB, only 10 bits of entropy is theoretically
-          possible. At best, due to page table layouts, 64-bit can use
-          9 bits of entropy and 32-bit uses 8 bits.
-          If unsure, say N.
- config RANDOMIZE_BASE_MAX_OFFSET
-       hex "Maximum kASLR offset allowed" if EXPERT
-       depends on RANDOMIZE_BASE
-       range 0x0 0x20000000 if X86_32
-       default "0x20000000" if X86_32
-       range 0x0 0x40000000 if X86_64
-       default "0x40000000" if X86_64
-       ---help---
-         The lesser of RANDOMIZE_BASE_MAX_OFFSET and available physical
-         memory is used to determine the maximal offset in bytes that will
-         be applied to the kernel when kernel Address Space Layout
-         Randomization (kASLR) is active. This must be a multiple of
-         PHYSICAL_ALIGN.
-         On 32-bit this is limited to 512MiB by page table layouts. The
-         default is 512MiB.
-         On 64-bit this is limited by how the kernel fixmap page table is
-         positioned, so this cannot be larger than 1GiB currently. Without
-         RANDOMIZE_BASE, there is a 512MiB to 1.5GiB split between kernel
-         and modules. When RANDOMIZE_BASE_MAX_OFFSET is above 512MiB, the
-         modules area will shrink to compensate, up to the current maximum
-         1GiB to 1GiB split. The default is 1GiB.
-         If unsure, leave at the default value.
+         If unsure, say N.
  
  # Relocation on x86 needs some additional build support
  config X86_NEED_RELOCS
index 3c731413f1dee40a1d07202c524f31aa1d01dea9,dff26bc91b172a7e2a3fbb644442f1fd75b491f3..2970d22d77663f5299a8d49af690c3cf1aa7df60
  #include <linux/cpumask.h>
  #include <asm/frame.h>
  
- static inline int paravirt_enabled(void)
- {
-       return pv_info.paravirt_enabled;
- }
- static inline int paravirt_has_feature(unsigned int feature)
- {
-       WARN_ON_ONCE(!pv_info.paravirt_enabled);
-       return (pv_info.features & feature);
- }
  static inline void load_sp0(struct tss_struct *tss,
                             struct thread_struct *thread)
  {
@@@ -130,31 -119,21 +119,31 @@@ static inline void wbinvd(void
  
  #define get_kernel_rpl()  (pv_info.kernel_rpl)
  
 -static inline u64 paravirt_read_msr(unsigned msr, int *err)
 +static inline u64 paravirt_read_msr(unsigned msr)
  {
 -      return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
 +      return PVOP_CALL1(u64, pv_cpu_ops.read_msr, msr);
  }
  
 -static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 +static inline void paravirt_write_msr(unsigned msr,
 +                                    unsigned low, unsigned high)
  {
 -      return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
 +      return PVOP_VCALL3(pv_cpu_ops.write_msr, msr, low, high);
 +}
 +
 +static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
 +{
 +      return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err);
 +}
 +
 +static inline int paravirt_write_msr_safe(unsigned msr,
 +                                        unsigned low, unsigned high)
 +{
 +      return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
  }
  
 -/* These should all do BUG_ON(_err), but our headers are too tangled. */
  #define rdmsr(msr, val1, val2)                        \
  do {                                          \
 -      int _err;                               \
 -      u64 _l = paravirt_read_msr(msr, &_err); \
 +      u64 _l = paravirt_read_msr(msr);        \
        val1 = (u32)_l;                         \
        val2 = _l >> 32;                        \
  } while (0)
@@@ -166,7 -145,8 +155,7 @@@ do {                                               
  
  #define rdmsrl(msr, val)                      \
  do {                                          \
 -      int _err;                               \
 -      val = paravirt_read_msr(msr, &_err);    \
 +      val = paravirt_read_msr(msr);           \
  } while (0)
  
  static inline void wrmsrl(unsigned msr, u64 val)
        wrmsr(msr, (u32)val, (u32)(val>>32));
  }
  
 -#define wrmsr_safe(msr, a, b) paravirt_write_msr(msr, a, b)
 +#define wrmsr_safe(msr, a, b) paravirt_write_msr_safe(msr, a, b)
  
  /* rdmsr with exception handling */
 -#define rdmsr_safe(msr, a, b)                 \
 -({                                            \
 -      int _err;                               \
 -      u64 _l = paravirt_read_msr(msr, &_err); \
 -      (*a) = (u32)_l;                         \
 -      (*b) = _l >> 32;                        \
 -      _err;                                   \
 +#define rdmsr_safe(msr, a, b)                         \
 +({                                                    \
 +      int _err;                                       \
 +      u64 _l = paravirt_read_msr_safe(msr, &_err);    \
 +      (*a) = (u32)_l;                                 \
 +      (*b) = _l >> 32;                                \
 +      _err;                                           \
  })
  
  static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
  {
        int err;
  
 -      *p = paravirt_read_msr(msr, &err);
 +      *p = paravirt_read_msr_safe(msr, &err);
        return err;
  }
  
index b4a23eafa1b95e2e0d63f42a54c8725732e99df8,7fedf24bd81185b579f1cd9e429b4c3b330dd0bc..7fa9e7740ba3db18d04c8405f549183edf60e8a5
@@@ -69,15 -69,9 +69,9 @@@ struct pv_info 
        u16 extra_user_64bit_cs;  /* __USER_CS if none */
  #endif
  
-       int paravirt_enabled;
-       unsigned int features;    /* valid only if paravirt_enabled is set */
        const char *name;
  };
  
- #define paravirt_has(x) paravirt_has_feature(PV_SUPPORTED_##x)
- /* Supported features */
- #define PV_SUPPORTED_RTC        (1<<0)
  struct pv_init_ops {
        /*
         * Patch may replace one of the defined code sequences with
@@@ -155,16 -149,10 +149,16 @@@ struct pv_cpu_ops 
        void (*cpuid)(unsigned int *eax, unsigned int *ebx,
                      unsigned int *ecx, unsigned int *edx);
  
 -      /* MSR, PMC and TSR operations.
 -         err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
 -      u64 (*read_msr)(unsigned int msr, int *err);
 -      int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
 +      /* Unsafe MSR operations.  These will warn or panic on failure. */
 +      u64 (*read_msr)(unsigned int msr);
 +      void (*write_msr)(unsigned int msr, unsigned low, unsigned high);
 +
 +      /*
 +       * Safe MSR operations.
 +       * read sets err to 0 or -EIO.  write returns 0 or -EIO.
 +       */
 +      u64 (*read_msr_safe)(unsigned int msr, int *err);
 +      int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
  
        u64 (*read_pmc)(int counter);
  
index 9251aa9627216c3a58dbd46efd1b1ca9298d6331,8d326e822cb8513ee0788d04e19c6cc088868c41..62c6cc3cc5d32f5490b56e4b6590fbdf74af76d9
@@@ -388,16 -388,9 +388,16 @@@ struct thread_struct 
        unsigned long           ip;
  #endif
  #ifdef CONFIG_X86_64
 -      unsigned long           fs;
 +      unsigned long           fsbase;
 +      unsigned long           gsbase;
 +#else
 +      /*
 +       * XXX: this could presumably be unsigned short.  Alternatively,
 +       * 32-bit kernels could be taught to use fsindex instead.
 +       */
 +      unsigned long fs;
 +      unsigned long gs;
  #endif
 -      unsigned long           gs;
  
        /* Save middle states of ptrace breakpoints */
        struct perf_event       *ptrace_bps[HBP_NUM];
@@@ -480,8 -473,6 +480,6 @@@ static inline unsigned long current_top
  #include <asm/paravirt.h>
  #else
  #define __cpuid                       native_cpuid
- #define paravirt_enabled()    0
- #define paravirt_has(x)       0
  
  static inline void load_sp0(struct tss_struct *tss,
                            struct thread_struct *thread)
index 2522e564269e240604dc4af7cf5a20fc8c86e175,c9a06e573fa51754bde0c7bc5c5b05007a83b9ae..f115a58f7c8438c70a0cad71ec92bb29a1e0ab85
@@@ -136,7 -136,7 +136,7 @@@ static int __init acpi_parse_madt(struc
  {
        struct acpi_table_madt *madt = NULL;
  
 -      if (!cpu_has_apic)
 +      if (!boot_cpu_has(X86_FEATURE_APIC))
                return -EINVAL;
  
        madt = (struct acpi_table_madt *)table;
@@@ -913,6 -913,15 +913,15 @@@ late_initcall(hpet_insert_resource)
  
  static int __init acpi_parse_fadt(struct acpi_table_header *table)
  {
+       if (!(acpi_gbl_FADT.boot_flags & ACPI_FADT_LEGACY_DEVICES)) {
+               pr_debug("ACPI: no legacy devices present\n");
+               x86_platform.legacy.devices.pnpbios = 0;
+       }
+       if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) {
+               pr_debug("ACPI: not registering RTC platform device\n");
+               x86_platform.legacy.rtc = 0;
+       }
  
  #ifdef CONFIG_X86_PM_TIMER
        /* detect the location of the ACPI PM Timer */
@@@ -951,7 -960,7 +960,7 @@@ static int __init early_acpi_parse_madt
  {
        int count;
  
 -      if (!cpu_has_apic)
 +      if (!boot_cpu_has(X86_FEATURE_APIC))
                return -ENODEV;
  
        /*
@@@ -979,7 -988,7 +988,7 @@@ static int __init acpi_parse_madt_lapic
        int ret;
        struct acpi_subtable_proc madt_proc[2];
  
 -      if (!cpu_has_apic)
 +      if (!boot_cpu_has(X86_FEATURE_APIC))
                return -ENODEV;
  
        /*
@@@ -1125,7 -1134,7 +1134,7 @@@ static int __init acpi_parse_madt_ioapi
        if (acpi_disabled || acpi_noirq)
                return -ENODEV;
  
 -      if (!cpu_has_apic)
 +      if (!boot_cpu_has(X86_FEATURE_APIC))
                return -ENODEV;
  
        /*
index b18f4706e607ab9f6f570223187cec6205ee78de,016b3d9ffa7d7658051df26cb58f2dda12aa4049..8dae51fd3db1c802278ac2647beb44a2fe0cccb0
@@@ -152,9 -152,9 +152,9 @@@ static void early_init_intel(struct cpu
         *  the TLB when any changes are made to any of the page table entries.
         *  The operating system must reload CR3 to cause the TLB to be flushed"
         *
 -       * As a result cpu_has_pge() in arch/x86/include/asm/tlbflush.h should
 -       * be false so that __flush_tlb_all() causes CR3 insted of CR4.PGE
 -       * to be modified
 +       * As a result, boot_cpu_has(X86_FEATURE_PGE) in arch/x86/include/asm/tlbflush.h
 +       * should be false so that __flush_tlb_all() causes CR3 insted of CR4.PGE
 +       * to be modified.
         */
        if (c->x86 == 5 && c->x86_model == 9) {
                pr_info("Disabling PGE capability bit\n");
@@@ -233,7 -233,7 +233,7 @@@ static void intel_workarounds(struct cp
         * The Quark is also family 5, but does not have the same bug.
         */
        clear_cpu_bug(c, X86_BUG_F00F);
-       if (!paravirt_enabled() && c->x86 == 5 && c->x86_model < 9) {
+       if (c->x86 == 5 && c->x86_model < 9) {
                static int f00f_workaround_enabled;
  
                set_cpu_bug(c, X86_BUG_F00F);
         * integrated APIC (see 11AP erratum in "Pentium Processor
         * Specification Update").
         */
 -      if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
 +      if (boot_cpu_has(X86_FEATURE_APIC) && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
            (c->x86_mask < 0x6 || c->x86_mask == 0xb))
                set_cpu_bug(c, X86_BUG_11AP);
  
@@@ -336,7 -336,7 +336,7 @@@ static int intel_num_cpu_cores(struct c
  {
        unsigned int eax, ebx, ecx, edx;
  
 -      if (c->cpuid_level < 4)
 +      if (!IS_ENABLED(CONFIG_SMP) || c->cpuid_level < 4)
                return 1;
  
        /* Intel has a non-standard dependency on %ecx for this CPUID level. */
@@@ -456,7 -456,7 +456,7 @@@ static void init_intel(struct cpuinfo_x
                        set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
        }
  
 -      if (cpu_has_xmm2)
 +      if (cpu_has(c, X86_FEATURE_XMM2))
                set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
  
        if (boot_cpu_has(X86_FEATURE_DS)) {
                        set_cpu_cap(c, X86_FEATURE_PEBS);
        }
  
 -      if (c->x86 == 6 && cpu_has_clflush &&
 +      if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_CLFLUSH) &&
            (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
                set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR);
  
diff --combined arch/x86/kernel/kvm.c
index dc1207e2f19390a7f3dbe5efa967ac008f19da58,c66546f29b819bf7cce2a1369258b0ca06aed244..eea2a6f72b31c089d1b100eaefff32d1c6be4a87
@@@ -285,14 -285,6 +285,6 @@@ static void __init paravirt_ops_setup(v
  {
        pv_info.name = "KVM";
  
-       /*
-        * KVM isn't paravirt in the sense of paravirt_enabled.  A KVM
-        * guest kernel works like a bare metal kernel with additional
-        * features, and paravirt_enabled is about features that are
-        * missing.
-        */
-       pv_info.paravirt_enabled = 0;
        if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
                pv_cpu_ops.io_delay = kvm_io_delay;
  
@@@ -522,7 -514,7 +514,7 @@@ static noinline uint32_t __kvm_cpuid_ba
        if (boot_cpu_data.cpuid_level < 0)
                return 0;       /* So we don't blow up on old processors */
  
 -      if (cpu_has_hypervisor)
 +      if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
                return hypervisor_cpuid_base("KVMKVMKVM\0\0\0", 0);
  
        return 0;
index f9583917c7c4f440456074efff1179e54b38e558,71a2d8a05a663bd1c83ebd84b9182b9d0249089c..7b3b3f24c3eac994f5c23c1ac8fa9f6420ef86fe
@@@ -294,7 -294,6 +294,6 @@@ enum paravirt_lazy_mode paravirt_get_la
  
  struct pv_info pv_info = {
        .name = "bare hardware",
-       .paravirt_enabled = 0,
        .kernel_rpl = 0,
        .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
  
@@@ -339,10 -338,8 +338,10 @@@ __visible struct pv_cpu_ops pv_cpu_ops 
        .write_cr8 = native_write_cr8,
  #endif
        .wbinvd = native_wbinvd,
 -      .read_msr = native_read_msr_safe,
 -      .write_msr = native_write_msr_safe,
 +      .read_msr = native_read_msr,
 +      .write_msr = native_write_msr,
 +      .read_msr_safe = native_read_msr_safe,
 +      .write_msr_safe = native_write_msr_safe,
        .read_pmc = native_read_pmc,
        .load_tr_desc = native_load_tr_desc,
        .set_ldt = native_set_ldt,
diff --combined arch/x86/mm/init_32.c
index 85af914e3d27582bd29449fae698a4f0bfd4a85e,f2ee42d61894d54645172faedfa866162d4b5044..84df150ee77e7073366799c695cdda8aa04896f8
@@@ -284,7 -284,7 +284,7 @@@ kernel_physical_mapping_init(unsigned l
         */
        mapping_iter = 1;
  
 -      if (!cpu_has_pse)
 +      if (!boot_cpu_has(X86_FEATURE_PSE))
                use_pse = 0;
  
  repeat:
@@@ -804,9 -804,6 +804,6 @@@ void __init mem_init(void
        BUILD_BUG_ON(VMALLOC_START                      >= VMALLOC_END);
  #undef high_memory
  #undef __FIXADDR_TOP
- #ifdef CONFIG_RANDOMIZE_BASE
-       BUILD_BUG_ON(CONFIG_RANDOMIZE_BASE_MAX_OFFSET > KERNEL_IMAGE_SIZE);
- #endif
  
  #ifdef CONFIG_HIGHMEM
        BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE        > FIXADDR_START);
diff --combined arch/x86/mm/init_64.c
index 89d97477c1d926ada477ff41516f3bcda8c4b76e,65cfbeefbec4bd414502772083918e34ada8d544..bce2e5d9edd458cf28f44ac921f91cc790d11a52
  
  #include "mm_internal.h"
  
- static void ident_pmd_init(unsigned long pmd_flag, pmd_t *pmd_page,
-                          unsigned long addr, unsigned long end)
- {
-       addr &= PMD_MASK;
-       for (; addr < end; addr += PMD_SIZE) {
-               pmd_t *pmd = pmd_page + pmd_index(addr);
-               if (!pmd_present(*pmd))
-                       set_pmd(pmd, __pmd(addr | pmd_flag));
-       }
- }
- static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page,
-                         unsigned long addr, unsigned long end)
- {
-       unsigned long next;
-       for (; addr < end; addr = next) {
-               pud_t *pud = pud_page + pud_index(addr);
-               pmd_t *pmd;
-               next = (addr & PUD_MASK) + PUD_SIZE;
-               if (next > end)
-                       next = end;
-               if (pud_present(*pud)) {
-                       pmd = pmd_offset(pud, 0);
-                       ident_pmd_init(info->pmd_flag, pmd, addr, next);
-                       continue;
-               }
-               pmd = (pmd_t *)info->alloc_pgt_page(info->context);
-               if (!pmd)
-                       return -ENOMEM;
-               ident_pmd_init(info->pmd_flag, pmd, addr, next);
-               set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
-       }
-       return 0;
- }
- int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page,
-                             unsigned long addr, unsigned long end)
- {
-       unsigned long next;
-       int result;
-       int off = info->kernel_mapping ? pgd_index(__PAGE_OFFSET) : 0;
-       for (; addr < end; addr = next) {
-               pgd_t *pgd = pgd_page + pgd_index(addr) + off;
-               pud_t *pud;
-               next = (addr & PGDIR_MASK) + PGDIR_SIZE;
-               if (next > end)
-                       next = end;
-               if (pgd_present(*pgd)) {
-                       pud = pud_offset(pgd, 0);
-                       result = ident_pud_init(info, pud, addr, next);
-                       if (result)
-                               return result;
-                       continue;
-               }
-               pud = (pud_t *)info->alloc_pgt_page(info->context);
-               if (!pud)
-                       return -ENOMEM;
-               result = ident_pud_init(info, pud, addr, next);
-               if (result)
-                       return result;
-               set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE));
-       }
-       return 0;
- }
+ #include "ident_map.c"
  
  /*
   * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
@@@ -1295,7 -1223,7 +1223,7 @@@ int __meminit vmemmap_populate(unsigne
        struct vmem_altmap *altmap = to_vmem_altmap(start);
        int err;
  
 -      if (cpu_has_pse)
 +      if (boot_cpu_has(X86_FEATURE_PSE))
                err = vmemmap_populate_hugepages(start, end, node, altmap);
        else if (altmap) {
                pr_err_once("%s: no cpu support for altmap allocations\n",
@@@ -1338,7 -1266,7 +1266,7 @@@ void register_page_bootmem_memmap(unsig
                }
                get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
  
 -              if (!cpu_has_pse) {
 +              if (!boot_cpu_has(X86_FEATURE_PSE)) {
                        next = (addr + PAGE_SIZE) & PAGE_MASK;
                        pmd = pmd_offset(pud, addr);
                        if (pmd_none(*pmd))
diff --combined arch/x86/xen/enlighten.c
index 6ab672233ac9861d35d5ee53aebcf84286f46f0c,5fc20a1108c7729b7b21ceb77b725cdc09f34a4b..760789ae8562af21932adc93e56dca10717915ab
@@@ -75,6 -75,7 +75,6 @@@
  #include <asm/mach_traps.h>
  #include <asm/mwait.h>
  #include <asm/pci_x86.h>
 -#include <asm/pat.h>
  #include <asm/cpu.h>
  
  #ifdef CONFIG_ACPI
@@@ -1092,26 -1093,6 +1092,26 @@@ static int xen_write_msr_safe(unsigned 
        return ret;
  }
  
 +static u64 xen_read_msr(unsigned int msr)
 +{
 +      /*
 +       * This will silently swallow a #GP from RDMSR.  It may be worth
 +       * changing that.
 +       */
 +      int err;
 +
 +      return xen_read_msr_safe(msr, &err);
 +}
 +
 +static void xen_write_msr(unsigned int msr, unsigned low, unsigned high)
 +{
 +      /*
 +       * This will silently swallow a #GP from WRMSR.  It may be worth
 +       * changing that.
 +       */
 +      xen_write_msr_safe(msr, low, high);
 +}
 +
  void xen_setup_shared_info(void)
  {
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@@ -1206,13 -1187,11 +1206,11 @@@ static unsigned xen_patch(u8 type, u16 
  }
  
  static const struct pv_info xen_info __initconst = {
-       .paravirt_enabled = 1,
        .shared_kernel_pmd = 0,
  
  #ifdef CONFIG_X86_64
        .extra_user_64bit_cs = FLAT_USER_CS64,
  #endif
-       .features = 0,
        .name = "Xen",
  };
  
@@@ -1242,11 -1221,8 +1240,11 @@@ static const struct pv_cpu_ops xen_cpu_
  
        .wbinvd = native_wbinvd,
  
 -      .read_msr = xen_read_msr_safe,
 -      .write_msr = xen_write_msr_safe,
 +      .read_msr = xen_read_msr,
 +      .write_msr = xen_write_msr,
 +
 +      .read_msr_safe = xen_read_msr_safe,
 +      .write_msr_safe = xen_write_msr_safe,
  
        .read_pmc = xen_read_pmc,
  
@@@ -1491,10 -1467,10 +1489,10 @@@ static void xen_pvh_set_cr_flags(int cp
         * For BSP, PSE PGE are set in probe_page_size_mask(), for APs
         * set them here. For all, OSFXSR OSXMMEXCPT are set in fpu__init_cpu().
        */
 -      if (cpu_has_pse)
 +      if (boot_cpu_has(X86_FEATURE_PSE))
                cr4_set_bits_and_update_boot(X86_CR4_PSE);
  
 -      if (cpu_has_pge)
 +      if (boot_cpu_has(X86_FEATURE_PGE))
                cr4_set_bits_and_update_boot(X86_CR4_PGE);
  }
  
@@@ -1528,11 -1504,17 +1526,16 @@@ static void __init xen_pvh_early_guest_
  }
  #endif    /* CONFIG_XEN_PVH */
  
+ static void __init xen_dom0_set_legacy_features(void)
+ {
+       x86_platform.legacy.rtc = 1;
+ }
  /* First C function to be called on Xen boot */
  asmlinkage __visible void __init xen_start_kernel(void)
  {
        struct physdev_set_iopl set_iopl;
        unsigned long initrd_start = 0;
 -      u64 pat;
        int rc;
  
        if (!xen_start_info)
  
        /* Install Xen paravirt ops */
        pv_info = xen_info;
-       if (xen_initial_domain())
-               pv_info.features |= PV_SUPPORTED_RTC;
        pv_init_ops = xen_init_ops;
        if (!xen_pvh_domain()) {
                pv_cpu_ops = xen_cpu_ops;
                                   xen_start_info->nr_pages);
        xen_reserve_special_pages();
  
 -      /*
 -       * Modify the cache mode translation tables to match Xen's PAT
 -       * configuration.
 -       */
 -      rdmsrl(MSR_IA32_CR_PAT, pat);
 -      pat_init_cache_modes(pat);
 -
        /* keep using Xen gdt for now; no urgent need to change it */
  
  #ifdef CONFIG_X86_32
        boot_params.hdr.ramdisk_image = initrd_start;
        boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
        boot_params.hdr.cmd_line_ptr = __pa(xen_start_info->cmd_line);
+       boot_params.hdr.hardware_subarch = X86_SUBARCH_XEN;
  
        if (!xen_initial_domain()) {
                add_preferred_console("xenboot", 0, NULL);
                        .u.firmware_info.type = XEN_FW_KBD_SHIFT_FLAGS,
                };
  
+               x86_platform.set_legacy_features =
+                               xen_dom0_set_legacy_features;
                xen_init_vga(info, xen_start_info->console.dom0.info_size);
                xen_start_info->console.domU.mfn = 0;
                xen_start_info->console.domU.evtchn = 0;