]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.25/patches.xen/xen3-patch-2.6.25
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / xen3-patch-2.6.25
similarity index 96%
rename from src/patches/60034_xen3-patch-2.6.25.patch1
rename to src/patches/suse-2.6.27.25/patches.xen/xen3-patch-2.6.25
index f7fd197026b9cc423516c3896d4741bb5a3fb516..750959062a3b4612246129c2db4499bfdaf08370 100644 (file)
@@ -6,194 +6,8 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 
 Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches.py
 
----
- arch/x86/Kconfig                              |   18 
- arch/x86/Kconfig.debug                        |    1 
- arch/x86/ia32/ia32entry-xen.S                 |   12 
- arch/x86/kernel/Makefile                      |    3 
- arch/x86/kernel/acpi/boot.c                   |    3 
- arch/x86/kernel/acpi/sleep-xen.c              |   95 +
- arch/x86/kernel/acpi/sleep_32-xen.c           |  117 --
- arch/x86/kernel/acpi/sleep_64-xen.c           |  125 --
- arch/x86/kernel/apic_32-xen.c                 |    2 
- arch/x86/kernel/apic_64-xen.c                 |   73 -
- arch/x86/kernel/asm-offsets_32.c              |    2 
- arch/x86/kernel/cpu/common-xen.c              |  214 +--
- arch/x86/kernel/cpu/mtrr/main-xen.c           |   19 
- arch/x86/kernel/e820_32-xen.c                 |  275 -----
- arch/x86/kernel/e820_64-xen.c                 |  485 +++++---
- arch/x86/kernel/early_printk-xen.c            |    2 
- arch/x86/kernel/entry_32-xen.S                |  195 +++
- arch/x86/kernel/entry_64-xen.S                |   91 -
- arch/x86/kernel/fixup.c                       |    2 
- arch/x86/kernel/genapic_64-xen.c              |   15 
- arch/x86/kernel/head64-xen.c                  |   63 +
- arch/x86/kernel/head_32-xen.S                 |    3 
- arch/x86/kernel/init_task-xen.c               |    2 
- arch/x86/kernel/io_apic_32-xen.c              |   15 
- arch/x86/kernel/io_apic_64-xen.c              |  110 +-
- arch/x86/kernel/ioport-xen.c                  |  112 ++
- arch/x86/kernel/ioport_32-xen.c               |  121 --
- arch/x86/kernel/ioport_64-xen.c               |   99 -
- arch/x86/kernel/irq_32-xen.c                  |   22 
- arch/x86/kernel/irq_64-xen.c                  |   43 
- arch/x86/kernel/ldt-xen.c                     |  272 +++++
- arch/x86/kernel/ldt_32-xen.c                  |  265 ----
- arch/x86/kernel/ldt_64-xen.c                  |  271 ----
- arch/x86/kernel/machine_kexec_64.c            |    2 
- arch/x86/kernel/microcode-xen.c               |    2 
- arch/x86/kernel/mpparse_32-xen.c              |   49 
- arch/x86/kernel/mpparse_64-xen.c              |   30 
- arch/x86/kernel/pci-dma-xen.c                 |   20 
- arch/x86/kernel/process_32-xen.c              |  438 ++------
- arch/x86/kernel/process_64-xen.c              |  303 ++---
- arch/x86/kernel/quirks-xen.c                  |   82 -
- arch/x86/kernel/rtc.c                         |    8 
- arch/x86/kernel/setup64-xen.c                 |   70 +
- arch/x86/kernel/setup_32-xen.c                |  311 ++++-
- arch/x86/kernel/setup_64-xen.c                |  686 ++++++------
- arch/x86/kernel/smp_32-xen.c                  |    5 
- arch/x86/kernel/smp_64-xen.c                  |   91 -
- arch/x86/kernel/time_32-xen.c                 |  136 --
- arch/x86/kernel/traps_32-xen.c                |  320 +++--
- arch/x86/kernel/traps_64-xen.c                |  371 +++---
- arch/x86/kernel/vsyscall_64-xen.c             |   60 -
- arch/x86/kernel/xen_entry_64.S                |   36 
- arch/x86/mach-xen/setup.c                     |   11 
- arch/x86/mm/fault-xen.c                       | 1026 ++++++++++++++++++
- arch/x86/mm/fault_32-xen.c                    |  757 -------------
- arch/x86/mm/fault_64-xen.c                    |  686 ------------
- arch/x86/mm/highmem_32-xen.c                  |   45 
- arch/x86/mm/hypervisor.c                      |   10 
- arch/x86/mm/init_32-xen.c                     |  464 +++-----
- arch/x86/mm/init_64-xen.c                     |  517 ++++-----
- arch/x86/mm/ioremap-xen.c                     |  685 ++++++++++++
- arch/x86/mm/ioremap_32-xen.c                  |  445 --------
- arch/x86/mm/pageattr-xen.c                    | 1412 ++++++++++++++++++++++++++
- arch/x86/mm/pageattr_64-xen.c                 |  542 ---------
- arch/x86/mm/pgtable_32-xen.c                  |  672 ++----------
- arch/x86/pci/irq-xen.c                        |   24 
- arch/x86/vdso/Makefile                        |    1 
- arch/x86/vdso/vdso32-setup-xen.c              |  506 +++++++++
- arch/x86/vdso/vdso32-setup.c                  |   34 
- arch/x86/vdso/vdso32.S                        |   12 
- arch/x86/vdso/vdso32/syscall.S                |    2 
- drivers/pci/msi-xen.c                         |   98 -
- drivers/pci/pci.c                             |    5 
- drivers/xen/balloon/sysfs.c                   |    2 
- drivers/xen/blkback/blkback.c                 |    5 
- drivers/xen/blkfront/blkfront.c               |    9 
- drivers/xen/blktap/blktap.c                   |    8 
- drivers/xen/core/Makefile                     |    1 
- drivers/xen/core/evtchn.c                     |   46 
- drivers/xen/core/hypervisor_sysfs.c           |    2 
- drivers/xen/core/smpboot.c                    |   29 
- drivers/xen/core/spinlock.c                   |  161 ++
- drivers/xen/core/xen_sysfs.c                  |   30 
- drivers/xen/gntdev/gntdev.c                   |    4 
- drivers/xen/scsifront/scsifront.c             |   49 
- drivers/xen/xenoprof/xenoprofile.c            |    2 
- include/asm-x86/mach-xen/asm/agp.h            |    9 
- include/asm-x86/mach-xen/asm/desc.h           |  403 +++++++
- include/asm-x86/mach-xen/asm/desc_32.h        |  262 ----
- include/asm-x86/mach-xen/asm/desc_64.h        |  228 ----
- include/asm-x86/mach-xen/asm/dma-mapping_32.h |   18 
- include/asm-x86/mach-xen/asm/fixmap_32.h      |   24 
- include/asm-x86/mach-xen/asm/fixmap_64.h      |   25 
- include/asm-x86/mach-xen/asm/highmem.h        |   10 
- include/asm-x86/mach-xen/asm/hypervisor.h     |   19 
- include/asm-x86/mach-xen/asm/io_32.h          |   69 -
- include/asm-x86/mach-xen/asm/io_64.h          |   62 -
- include/asm-x86/mach-xen/asm/irqflags.h       |  248 ++++
- include/asm-x86/mach-xen/asm/irqflags_32.h    |  212 ---
- include/asm-x86/mach-xen/asm/irqflags_64.h    |  178 ---
- include/asm-x86/mach-xen/asm/maddr_32.h       |   21 
- include/asm-x86/mach-xen/asm/maddr_64.h       |   19 
- include/asm-x86/mach-xen/asm/mmu_context_32.h |    2 
- include/asm-x86/mach-xen/asm/mmu_context_64.h |   12 
- include/asm-x86/mach-xen/asm/page.h           |  238 ++++
- include/asm-x86/mach-xen/asm/page_64.h        |  196 ---
- include/asm-x86/mach-xen/asm/pci.h            |   17 
- include/asm-x86/mach-xen/asm/pci_64.h         |    1 
- include/asm-x86/mach-xen/asm/pgalloc_32.h     |  116 +-
- include/asm-x86/mach-xen/asm/pgalloc_64.h     |   87 -
- include/asm-x86/mach-xen/asm/pgtable-3level.h |  107 -
- include/asm-x86/mach-xen/asm/pgtable.h        |  449 ++++++++
- include/asm-x86/mach-xen/asm/pgtable_32.h     |  361 ------
- include/asm-x86/mach-xen/asm/pgtable_64.h     |  400 +------
- include/asm-x86/mach-xen/asm/processor.h      |  792 ++++++++++++++
- include/asm-x86/mach-xen/asm/processor_32.h   |  751 -------------
- include/asm-x86/mach-xen/asm/processor_64.h   |  461 --------
- include/asm-x86/mach-xen/asm/segment.h        |  203 +++
- include/asm-x86/mach-xen/asm/segment_32.h     |  150 --
- include/asm-x86/mach-xen/asm/smp_32.h         |  125 +-
- include/asm-x86/mach-xen/asm/smp_64.h         |  138 --
- include/asm-x86/mach-xen/asm/spinlock.h       |  333 ++++++
- include/asm-x86/mach-xen/asm/system.h         |  392 +++++++
- include/asm-x86/mach-xen/asm/system_32.h      |  312 -----
- include/asm-x86/mach-xen/asm/system_64.h      |  159 --
- include/asm-x86/mach-xen/asm/tlbflush.h       |  105 +
- include/asm-x86/mach-xen/asm/tlbflush_32.h    |   99 -
- include/asm-x86/mach-xen/asm/tlbflush_64.h    |   97 -
- include/asm-x86/mach-xen/irq_vectors.h        |    3 
- include/asm-x86/mmu.h                         |    2 
- include/asm-x86/ptrace.h                      |    4 
- include/asm-x86/thread_info.h                 |   12 
- include/asm-x86/time.h                        |    6 
- include/linux/page-flags.h                    |    4 
- include/linux/pci.h                           |    3 
- include/xen/evtchn.h                          |   25 
- kernel/sysctl_check.c                         |    2 
- lib/swiotlb-xen.c                             |   35 
- 138 files changed, 11322 insertions(+), 11153 deletions(-)
-
---- a/arch/x86/ia32/ia32entry-xen.S
-+++ b/arch/x86/ia32/ia32entry-xen.S
-@@ -12,7 +12,6 @@
- #include <asm/ia32_unistd.h>  
- #include <asm/thread_info.h>  
- #include <asm/segment.h>
--#include <asm/vsyscall32.h>
- #include <asm/irqflags.h>
- #include <linux/linkage.h>
-@@ -99,10 +98,11 @@ ENTRY(ia32_sysenter_target)
-       CFI_RESTORE     rcx
-       movl    %ebp,%ebp               /* zero extension */
-       movl    %eax,%eax
-+      movl    48-THREAD_SIZE+threadinfo_sysenter_return(%rsp),%r10d
-       movl    $__USER32_DS,40(%rsp)
-       movq    %rbp,32(%rsp)
-       movl    $__USER32_CS,16(%rsp)
--      movl    $VSYSCALL32_SYSEXIT,8(%rsp)
-+      movq    %r10,8(%rsp)
-       movq    %rax,(%rsp)
-       cld
-       SAVE_ARGS 0,0,1
-@@ -582,8 +582,8 @@ ia32_sys_call_table:
-       .quad compat_sys_futex          /* 240 */
-       .quad compat_sys_sched_setaffinity
-       .quad compat_sys_sched_getaffinity
--      .quad sys32_set_thread_area
--      .quad sys32_get_thread_area
-+      .quad sys_set_thread_area
-+      .quad sys_get_thread_area
-       .quad compat_sys_io_setup       /* 245 */
-       .quad sys_io_destroy
-       .quad compat_sys_io_getevents
-@@ -661,7 +661,9 @@ ia32_sys_call_table:
-       .quad sys_epoll_pwait
-       .quad compat_sys_utimensat      /* 320 */
-       .quad compat_sys_signalfd
--      .quad compat_sys_timerfd
-+      .quad sys_timerfd_create
-       .quad sys_eventfd
-       .quad sys32_fallocate
-+      .quad compat_sys_timerfd_settime        /* 325 */
-+      .quad compat_sys_timerfd_gettime
- ia32_syscall_end:
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
+--- sle11-2009-05-14.orig/arch/x86/Kconfig     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/Kconfig  2009-03-16 16:33:40.000000000 +0100
 @@ -27,7 +27,7 @@ config X86
        select HAVE_KRETPROBES
        select HAVE_DYNAMIC_FTRACE
@@ -203,7 +17,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        select HAVE_ARCH_KGDB if !X86_VOYAGER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_GENERIC_DMA_COHERENT if X86_32
-@@ -208,14 +208,12 @@ config X86_TRAMPOLINE
+@@ -211,14 +211,12 @@ config X86_TRAMPOLINE
        default y
  
  config X86_NO_TSS
@@ -220,7 +34,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  config KTIME_SCALAR
        def_bool X86_32
-@@ -724,9 +722,8 @@ config X86_VISWS_APIC
+@@ -728,9 +726,8 @@ config X86_VISWS_APIC
        depends on X86_32 && X86_VISWS
  
  config X86_XEN_GENAPIC
@@ -231,7 +45,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  config X86_MCE
        bool "Machine Check Exception"
-@@ -1113,7 +1110,7 @@ config ARCH_DISCONTIGMEM_DEFAULT
+@@ -1117,7 +1114,7 @@ config ARCH_DISCONTIGMEM_DEFAULT
  
  config ARCH_SPARSEMEM_DEFAULT
        def_bool y
@@ -240,7 +54,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  config ARCH_SPARSEMEM_ENABLE
        def_bool y
-@@ -1743,10 +1740,10 @@ config PCI_MMCONFIG
+@@ -1747,10 +1744,10 @@ config PCI_MMCONFIG
        depends on X86_64 && PCI && ACPI
  
  config XEN_PCIDEV_FRONTEND
@@ -253,7 +67,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        help
          The PCI device frontend driver allows the kernel to import arbitrary
          PCI devices from a PCI backend to support PCI driver domains.
-@@ -1754,7 +1751,6 @@ config XEN_PCIDEV_FRONTEND
+@@ -1758,7 +1755,6 @@ config XEN_PCIDEV_FRONTEND
  config XEN_PCIDEV_FE_DEBUG
        bool "Xen PCI Frontend Debugging"
        depends on XEN_PCIDEV_FRONTEND
@@ -261,9 +75,9 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        help
          Enables some debug statements within the PCI Frontend.
  
---- a/arch/x86/Kconfig.debug
-+++ b/arch/x86/Kconfig.debug
-@@ -266,6 +266,7 @@ config DEBUG_BOOT_PARAMS
+--- sle11-2009-05-14.orig/arch/x86/Kconfig.debug       2009-02-02 09:40:56.000000000 +0100
++++ sle11-2009-05-14/arch/x86/Kconfig.debug    2009-03-16 16:33:40.000000000 +0100
+@@ -279,6 +279,7 @@ config DEBUG_BOOT_PARAMS
        bool "Debug boot parameters"
        depends on DEBUG_KERNEL
        depends on DEBUG_FS
@@ -271,8 +85,68 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        help
          This option will cause struct boot_params to be exported via debugfs.
  
---- a/arch/x86/kernel/acpi/boot.c
-+++ b/arch/x86/kernel/acpi/boot.c
+--- sle11-2009-05-14.orig/arch/x86/ia32/ia32entry-xen.S        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/ia32/ia32entry-xen.S     2009-03-16 16:33:40.000000000 +0100
+@@ -12,7 +12,6 @@
+ #include <asm/ia32_unistd.h>  
+ #include <asm/thread_info.h>  
+ #include <asm/segment.h>
+-#include <asm/vsyscall32.h>
+ #include <asm/irqflags.h>
+ #include <linux/linkage.h>
+@@ -99,10 +98,11 @@ ENTRY(ia32_sysenter_target)
+       CFI_RESTORE     rcx
+       movl    %ebp,%ebp               /* zero extension */
+       movl    %eax,%eax
++      movl    48-THREAD_SIZE+threadinfo_sysenter_return(%rsp),%r10d
+       movl    $__USER32_DS,40(%rsp)
+       movq    %rbp,32(%rsp)
+       movl    $__USER32_CS,16(%rsp)
+-      movl    $VSYSCALL32_SYSEXIT,8(%rsp)
++      movq    %r10,8(%rsp)
+       movq    %rax,(%rsp)
+       cld
+       SAVE_ARGS 0,0,1
+@@ -582,8 +582,8 @@ ia32_sys_call_table:
+       .quad compat_sys_futex          /* 240 */
+       .quad compat_sys_sched_setaffinity
+       .quad compat_sys_sched_getaffinity
+-      .quad sys32_set_thread_area
+-      .quad sys32_get_thread_area
++      .quad sys_set_thread_area
++      .quad sys_get_thread_area
+       .quad compat_sys_io_setup       /* 245 */
+       .quad sys_io_destroy
+       .quad compat_sys_io_getevents
+@@ -661,7 +661,9 @@ ia32_sys_call_table:
+       .quad sys_epoll_pwait
+       .quad compat_sys_utimensat      /* 320 */
+       .quad compat_sys_signalfd
+-      .quad compat_sys_timerfd
++      .quad sys_timerfd_create
+       .quad sys_eventfd
+       .quad sys32_fallocate
++      .quad compat_sys_timerfd_settime        /* 325 */
++      .quad compat_sys_timerfd_gettime
+ ia32_syscall_end:
+--- sle11-2009-05-14.orig/arch/x86/kernel/Makefile     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/Makefile  2009-03-16 16:33:40.000000000 +0100
+@@ -120,11 +120,10 @@ ifeq ($(CONFIG_X86_64),y)
+         obj-$(CONFIG_PCI_MMCONFIG)    += mmconf-fam10h_64.o
++      obj-$(CONFIG_XEN)               += nmi_64.o
+       time_64-$(CONFIG_XEN)           += time_32.o
+       pci-dma_64-$(CONFIG_XEN)        += pci-dma_32.o
+ endif
+ disabled-obj-$(CONFIG_XEN) := early-quirks.o hpet.o i8253.o i8259_$(BITS).o reboot.o \
+       smpboot_$(BITS).o tsc_$(BITS).o tsc_sync.o
+-disabled-obj-$(CONFIG_XEN_UNPRIVILEGED_GUEST) += mpparse_64.o
+-%/head_64.o %/head_64.s: asflags-$(CONFIG_XEN) :=
+--- sle11-2009-05-14.orig/arch/x86/kernel/acpi/boot.c  2008-12-01 11:11:08.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/acpi/boot.c       2009-03-16 16:33:40.000000000 +0100
 @@ -133,6 +133,9 @@ char *__init __acpi_map_table(unsigned l
  #ifndef CONFIG_XEN
        if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT))
@@ -283,8 +157,106 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  #endif
  
        offset = phys & (PAGE_SIZE - 1);
---- a/arch/x86/kernel/acpi/sleep_32-xen.c
-+++ /dev/null
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/kernel/acpi/sleep-xen.c  2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,95 @@
++/*
++ * sleep.c - x86-specific ACPI sleep support.
++ *
++ *  Copyright (C) 2001-2003 Patrick Mochel
++ *  Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
++ */
++
++#include <linux/acpi.h>
++#include <linux/bootmem.h>
++#include <linux/dmi.h>
++#include <linux/cpumask.h>
++
++#include <asm/smp.h>
++
++#ifndef CONFIG_ACPI_PV_SLEEP
++/* address in low memory of the wakeup routine. */
++unsigned long acpi_wakeup_address = 0;
++unsigned long acpi_realmode_flags;
++extern char wakeup_start, wakeup_end;
++
++extern unsigned long acpi_copy_wakeup_routine(unsigned long);
++#endif
++
++/**
++ * acpi_save_state_mem - save kernel state
++ *
++ * Create an identity mapped page table and copy the wakeup routine to
++ * low memory.
++ */
++int acpi_save_state_mem(void)
++{
++#ifndef CONFIG_ACPI_PV_SLEEP
++      if (!acpi_wakeup_address) {
++              printk(KERN_ERR "Could not allocate memory during boot, S3 disabled\n");
++              return -ENOMEM;
++      }
++      memcpy((void *)acpi_wakeup_address, &wakeup_start,
++             &wakeup_end - &wakeup_start);
++      acpi_copy_wakeup_routine(acpi_wakeup_address);
++#endif
++
++      return 0;
++}
++
++/*
++ * acpi_restore_state - undo effects of acpi_save_state_mem
++ */
++void acpi_restore_state_mem(void)
++{
++}
++
++
++/**
++ * acpi_reserve_bootmem - do _very_ early ACPI initialisation
++ *
++ * We allocate a page from the first 1MB of memory for the wakeup
++ * routine for when we come back from a sleep state. The
++ * runtime allocator allows specification of <16MB pages, but not
++ * <1MB pages.
++ */
++void __init acpi_reserve_bootmem(void)
++{
++#ifndef CONFIG_ACPI_PV_SLEEP
++      if ((&wakeup_end - &wakeup_start) > PAGE_SIZE*2) {
++              printk(KERN_ERR
++                     "ACPI: Wakeup code way too big, S3 disabled.\n");
++              return;
++      }
++
++      acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2);
++      if (!acpi_wakeup_address)
++              printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
++#endif
++}
++
++
++#ifndef CONFIG_ACPI_PV_SLEEP
++static int __init acpi_sleep_setup(char *str)
++{
++      while ((str != NULL) && (*str != '\0')) {
++              if (strncmp(str, "s3_bios", 7) == 0)
++                      acpi_realmode_flags |= 1;
++              if (strncmp(str, "s3_mode", 7) == 0)
++                      acpi_realmode_flags |= 2;
++              if (strncmp(str, "s3_beep", 7) == 0)
++                      acpi_realmode_flags |= 4;
++              str = strchr(str, ',');
++              if (str != NULL)
++                      str += strspn(str, ", \t");
++      }
++      return 1;
++}
++
++__setup("acpi_sleep=", acpi_sleep_setup);
++#endif /* CONFIG_ACPI_PV_SLEEP */
+--- sle11-2009-05-14.orig/arch/x86/kernel/acpi/sleep_32-xen.c  2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
 @@ -1,117 +0,0 @@
 -/*
 - * sleep.c - x86-specific ACPI sleep support.
@@ -403,8 +375,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -
 -core_initcall(acpisleep_dmi_init);
 -#endif /* CONFIG_ACPI_PV_SLEEP */
---- a/arch/x86/kernel/acpi/sleep_64-xen.c
-+++ /dev/null
+--- sle11-2009-05-14.orig/arch/x86/kernel/acpi/sleep_64-xen.c  2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
 @@ -1,125 +0,0 @@
 -/*
 - *  acpi.c - Architecture-Specific Low-Level ACPI Support
@@ -531,154 +503,56 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -__setup("acpi_sleep=", acpi_sleep_setup);
 -#endif                                /* CONFIG_ACPI_PV_SLEEP */
 -
---- /dev/null
-+++ b/arch/x86/kernel/acpi/sleep-xen.c
-@@ -0,0 +1,95 @@
+--- sle11-2009-05-14.orig/arch/x86/kernel/apic_32-xen.c        2008-12-15 11:27:22.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/apic_32-xen.c     2009-03-16 16:33:40.000000000 +0100
+@@ -86,7 +86,7 @@ int setup_profiling_timer(unsigned int m
+  * This initializes the IO-APIC and APIC hardware if this is
+  * a UP kernel.
+  */
+-int __init APIC_init_uniprocessor (void)
++int __init APIC_init_uniprocessor(void)
+ {
+ #ifdef CONFIG_X86_IO_APIC
+       if (smp_found_config)
+--- sle11-2009-05-14.orig/arch/x86/kernel/apic_64-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/apic_64-xen.c     2009-03-16 16:33:40.000000000 +0100
+@@ -34,34 +34,17 @@
+ #include <asm/hpet.h>
+ #include <asm/idle.h>
+-int apic_verbosity;
++int disable_apic;
+ /*
+- * 'what should we do if we get a hw irq event on an illegal vector'.
+- * each architecture has to answer this themselves.
++ * Debug level, exported for io_apic.c
+  */
+-void ack_bad_irq(unsigned int irq)
+-{
+-      printk("unexpected IRQ trap at irq %02x\n", irq);
+-      /*
+-       * Currently unexpected vectors happen only on SMP and APIC.
+-       * We _must_ ack these because every local APIC has only N
+-       * irq slots per priority level, and a 'hanging, unacked' IRQ
+-       * holds up an irq slot - in excessive cases (when multiple
+-       * unexpected vectors occur) that might lock up the APIC
+-       * completely.
+-       * But don't ack when the APIC is disabled. -AK
+-       */
+-      if (!disable_apic)
+-              ack_APIC_irq();
+-}
+-
+-int setup_profiling_timer(unsigned int multiplier)
+-{
+-      return -EINVAL;
+-}
++int apic_verbosity;
+-void smp_local_timer_interrupt(void)
 +/*
-+ * sleep.c - x86-specific ACPI sleep support.
-+ *
-+ *  Copyright (C) 2001-2003 Patrick Mochel
-+ *  Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
-+ */
-+
-+#include <linux/acpi.h>
-+#include <linux/bootmem.h>
-+#include <linux/dmi.h>
-+#include <linux/cpumask.h>
-+
-+#include <asm/smp.h>
-+
-+#ifndef CONFIG_ACPI_PV_SLEEP
-+/* address in low memory of the wakeup routine. */
-+unsigned long acpi_wakeup_address = 0;
-+unsigned long acpi_realmode_flags;
-+extern char wakeup_start, wakeup_end;
-+
-+extern unsigned long acpi_copy_wakeup_routine(unsigned long);
-+#endif
-+
-+/**
-+ * acpi_save_state_mem - save kernel state
-+ *
-+ * Create an identity mapped page table and copy the wakeup routine to
-+ * low memory.
-+ */
-+int acpi_save_state_mem(void)
-+{
-+#ifndef CONFIG_ACPI_PV_SLEEP
-+      if (!acpi_wakeup_address) {
-+              printk(KERN_ERR "Could not allocate memory during boot, S3 disabled\n");
-+              return -ENOMEM;
-+      }
-+      memcpy((void *)acpi_wakeup_address, &wakeup_start,
-+             &wakeup_end - &wakeup_start);
-+      acpi_copy_wakeup_routine(acpi_wakeup_address);
-+#endif
-+
-+      return 0;
-+}
-+
-+/*
-+ * acpi_restore_state - undo effects of acpi_save_state_mem
-+ */
-+void acpi_restore_state_mem(void)
-+{
-+}
-+
-+
-+/**
-+ * acpi_reserve_bootmem - do _very_ early ACPI initialisation
-+ *
-+ * We allocate a page from the first 1MB of memory for the wakeup
-+ * routine for when we come back from a sleep state. The
-+ * runtime allocator allows specification of <16MB pages, but not
-+ * <1MB pages.
-+ */
-+void __init acpi_reserve_bootmem(void)
-+{
-+#ifndef CONFIG_ACPI_PV_SLEEP
-+      if ((&wakeup_end - &wakeup_start) > PAGE_SIZE*2) {
-+              printk(KERN_ERR
-+                     "ACPI: Wakeup code way too big, S3 disabled.\n");
-+              return;
-+      }
-+
-+      acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2);
-+      if (!acpi_wakeup_address)
-+              printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
-+#endif
-+}
-+
-+
-+#ifndef CONFIG_ACPI_PV_SLEEP
-+static int __init acpi_sleep_setup(char *str)
-+{
-+      while ((str != NULL) && (*str != '\0')) {
-+              if (strncmp(str, "s3_bios", 7) == 0)
-+                      acpi_realmode_flags |= 1;
-+              if (strncmp(str, "s3_mode", 7) == 0)
-+                      acpi_realmode_flags |= 2;
-+              if (strncmp(str, "s3_beep", 7) == 0)
-+                      acpi_realmode_flags |= 4;
-+              str = strchr(str, ',');
-+              if (str != NULL)
-+                      str += strspn(str, ", \t");
-+      }
-+      return 1;
-+}
-+
-+__setup("acpi_sleep=", acpi_sleep_setup);
-+#endif /* CONFIG_ACPI_PV_SLEEP */
---- a/arch/x86/kernel/apic_32-xen.c
-+++ b/arch/x86/kernel/apic_32-xen.c
-@@ -86,7 +86,7 @@ int setup_profiling_timer(unsigned int m
-  * This initializes the IO-APIC and APIC hardware if this is
-  * a UP kernel.
-  */
--int __init APIC_init_uniprocessor (void)
-+int __init APIC_init_uniprocessor(void)
- {
- #ifdef CONFIG_X86_IO_APIC
-       if (smp_found_config)
---- a/arch/x86/kernel/apic_64-xen.c
-+++ b/arch/x86/kernel/apic_64-xen.c
-@@ -34,34 +34,17 @@
- #include <asm/hpet.h>
- #include <asm/idle.h>
--int apic_verbosity;
-+int disable_apic;
- /*
-- * 'what should we do if we get a hw irq event on an illegal vector'.
-- * each architecture has to answer this themselves.
-+ * Debug level, exported for io_apic.c
-  */
--void ack_bad_irq(unsigned int irq)
--{
--      printk("unexpected IRQ trap at irq %02x\n", irq);
--      /*
--       * Currently unexpected vectors happen only on SMP and APIC.
--       * We _must_ ack these because every local APIC has only N
--       * irq slots per priority level, and a 'hanging, unacked' IRQ
--       * holds up an irq slot - in excessive cases (when multiple
--       * unexpected vectors occur) that might lock up the APIC
--       * completely.
--       * But don't ack when the APIC is disabled. -AK
--       */
--      if (!disable_apic)
--              ack_APIC_irq();
--}
--
--int setup_profiling_timer(unsigned int multiplier)
--{
--      return -EINVAL;
--}
-+int apic_verbosity;
--void smp_local_timer_interrupt(void)
-+/*
-+ * The guts of the apic timer interrupt
++ * The guts of the apic timer interrupt
 + */
 +static void local_apic_timer_interrupt(void)
  {
@@ -748,8 +622,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -
 -      return 1;
 -}
---- a/arch/x86/kernel/asm-offsets_32.c
-+++ b/arch/x86/kernel/asm-offsets_32.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/asm-offsets_32.c     2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/asm-offsets_32.c  2009-03-16 16:33:40.000000000 +0100
 @@ -23,8 +23,10 @@
  #include <xen/interface/xen.h>
  #endif
@@ -761,8 +635,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  /* workaround for a warning with -Wmissing-prototypes */
  void foo(void);
---- a/arch/x86/kernel/cpu/common-xen.c
-+++ b/arch/x86/kernel/cpu/common-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/cpu/common-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/cpu/common-xen.c  2009-03-16 16:33:40.000000000 +0100
 @@ -27,45 +27,50 @@
  #include "cpu.h"
  
@@ -1164,8 +1038,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
        load_LDT(&init_mm.context);
  
---- a/arch/x86/kernel/cpu/mtrr/main-xen.c
-+++ b/arch/x86/kernel/cpu/mtrr/main-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/cpu/mtrr/main-xen.c  2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/cpu/mtrr/main-xen.c       2009-03-16 16:33:40.000000000 +0100
 @@ -33,7 +33,7 @@ struct mtrr_ops generic_mtrr_ops = {
  
  struct mtrr_ops *mtrr_if = &generic_mtrr_ops;
@@ -1227,8 +1101,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
                op.cmd = XENPF_del_memtype;
                op.u.del_memtype.handle = 0;
                op.u.del_memtype.reg    = reg;
---- a/arch/x86/kernel/e820_32-xen.c
-+++ b/arch/x86/kernel/e820_32-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/e820_32-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/e820_32-xen.c     2009-03-16 16:33:40.000000000 +0100
 @@ -7,7 +7,6 @@
  #include <linux/kexec.h>
  #include <linux/module.h>
@@ -1599,8 +1473,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +      print_memory_map("modified");
 +}
 +#endif
---- a/arch/x86/kernel/e820_64-xen.c
-+++ b/arch/x86/kernel/e820_64-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/e820_64-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/e820_64-xen.c     2009-03-16 16:33:40.000000000 +0100
 @@ -1,4 +1,4 @@
 -/* 
 +/*
@@ -2397,8 +2271,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  }
  
  int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
---- a/arch/x86/kernel/early_printk-xen.c
-+++ b/arch/x86/kernel/early_printk-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/early_printk-xen.c   2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/early_printk-xen.c        2009-03-16 16:33:40.000000000 +0100
 @@ -222,7 +222,7 @@ static struct console simnow_console = {
  };
  
@@ -2408,8 +2282,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  static int early_console_initialized = 0;
  
  void early_printk(const char *fmt, ...)
---- a/arch/x86/kernel/entry_32-xen.S
-+++ b/arch/x86/kernel/entry_32-xen.S
+--- sle11-2009-05-14.orig/arch/x86/kernel/entry_32-xen.S       2009-05-14 11:18:18.000000000 +0200
++++ sle11-2009-05-14/arch/x86/kernel/entry_32-xen.S    2009-05-14 11:18:32.000000000 +0200
 @@ -59,7 +59,7 @@
   * for paravirtualization.  The following will never clobber any registers:
   *   INTERRUPT_RETURN (aka. "iret")
@@ -2524,7 +2398,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  ENTRY(interrupt)
  .text
  
-@@ -959,7 +961,7 @@ END(device_not_available)
+@@ -963,7 +965,7 @@ END(device_not_available)
   * that sets up the real kernel stack. Check here, since we can't
   * allow the wrong stack to be used.
   *
@@ -2533,7 +2407,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
   * already pushed 3 words if it hits on the sysenter instruction:
   * eflags, cs and eip.
   *
-@@ -971,7 +973,7 @@ END(device_not_available)
+@@ -975,7 +977,7 @@ END(device_not_available)
        cmpw $__KERNEL_CS,4(%esp);              \
        jne ok;                                 \
  label:                                                \
@@ -2542,7 +2416,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        CFI_DEF_CFA esp, 0;                     \
        CFI_UNDEFINED eip;                      \
        pushfl;                                 \
-@@ -986,7 +988,7 @@ label:                                             \
+@@ -990,7 +992,7 @@ label:                                             \
  KPROBE_ENTRY(debug)
        RING0_INT_FRAME
  #ifndef CONFIG_XEN
@@ -2551,7 +2425,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        jne debug_stack_correct
        FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
  debug_stack_correct:
-@@ -1019,7 +1021,7 @@ KPROBE_ENTRY(nmi)
+@@ -1023,7 +1025,7 @@ KPROBE_ENTRY(nmi)
        popl %eax
        CFI_ADJUST_CFA_OFFSET -4
        je nmi_espfix_stack
@@ -2560,7 +2434,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        je nmi_stack_fixup
        pushl %eax
        CFI_ADJUST_CFA_OFFSET 4
-@@ -1032,7 +1034,7 @@ KPROBE_ENTRY(nmi)
+@@ -1036,7 +1038,7 @@ KPROBE_ENTRY(nmi)
        popl %eax
        CFI_ADJUST_CFA_OFFSET -4
        jae nmi_stack_correct
@@ -2569,7 +2443,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        je nmi_debug_stack_check
  nmi_stack_correct:
        /* We have a RING0_INT_FRAME here */
-@@ -1085,12 +1087,8 @@ nmi_espfix_stack:
+@@ -1089,12 +1091,8 @@ nmi_espfix_stack:
        RESTORE_REGS
        lss 12+4(%esp), %esp            # back to espfix stack
        CFI_ADJUST_CFA_OFFSET -24
@@ -2583,7 +2457,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  #else
  KPROBE_ENTRY(nmi)
        RING0_INT_FRAME
-@@ -1108,17 +1106,17 @@ KPROBE_END(nmi)
+@@ -1112,17 +1110,17 @@ KPROBE_END(nmi)
  
  #ifdef CONFIG_PARAVIRT
  ENTRY(native_iret)
@@ -2605,7 +2479,7 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  #endif
  
  KPROBE_ENTRY(int3)
-@@ -1267,7 +1265,144 @@ ENTRY(kernel_thread_helper)
+@@ -1271,7 +1269,144 @@ ENTRY(kernel_thread_helper)
        CFI_ENDPROC
  ENDPROC(kernel_thread_helper)
  
@@ -2750,8 +2624,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +#undef        sys_fork
 +#undef        sys_clone
 +#undef        sys_vfork
---- a/arch/x86/kernel/entry_64-xen.S
-+++ b/arch/x86/kernel/entry_64-xen.S
+--- sle11-2009-05-14.orig/arch/x86/kernel/entry_64-xen.S       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/entry_64-xen.S    2009-03-16 16:33:40.000000000 +0100
 @@ -54,17 +54,22 @@
  #include <asm/page.h>
  #include <asm/irqflags.h>
@@ -3065,8 +2939,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        TRACE_IRQS_OFF
        GET_THREAD_INFO(%rcx)
        jmp  retint_restore_args
---- a/arch/x86/kernel/fixup.c
-+++ b/arch/x86/kernel/fixup.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/fixup.c      2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/arch/x86/kernel/fixup.c   2009-03-16 16:33:40.000000000 +0100
 @@ -36,7 +36,7 @@
  
  #define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
@@ -3076,8 +2950,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  {
        static unsigned long printed = 0;
        char info[100];
---- a/arch/x86/kernel/genapic_64-xen.c
-+++ b/arch/x86/kernel/genapic_64-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/genapic_64-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/genapic_64-xen.c  2009-03-16 16:33:40.000000000 +0100
 @@ -24,20 +24,13 @@
  #include <acpi/acpi_bus.h>
  #endif
@@ -3103,27 +2977,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
  
  #ifndef CONFIG_XEN
---- a/arch/x86/kernel/head_32-xen.S
-+++ b/arch/x86/kernel/head_32-xen.S
-@@ -3,6 +3,7 @@
- .text
- #include <linux/elfnote.h>
- #include <linux/threads.h>
-+#include <linux/init.h>
- #include <linux/linkage.h>
- #include <asm/segment.h>
- #include <asm/page.h>
-@@ -88,7 +89,7 @@ ENTRY(_stext)
-  */
- .section ".bss.page_aligned","wa"
-       .align PAGE_SIZE_asm
--ENTRY(swapper_pg_pmd)
-+ENTRY(swapper_pg_fixmap)
-       .fill 1024,4,0
- ENTRY(empty_zero_page)
-       .fill 4096,1,0
---- a/arch/x86/kernel/head64-xen.c
-+++ b/arch/x86/kernel/head64-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/head64-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/head64-xen.c      2009-03-16 16:33:40.000000000 +0100
 @@ -16,6 +16,7 @@
  #include <linux/kernel.h>
  #include <linux/string.h>
@@ -3229,8 +3084,27 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +
        start_kernel();
  }
---- a/arch/x86/kernel/init_task-xen.c
-+++ b/arch/x86/kernel/init_task-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/head_32-xen.S        2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/head_32-xen.S     2009-03-16 16:33:40.000000000 +0100
+@@ -3,6 +3,7 @@
+ .text
+ #include <linux/elfnote.h>
+ #include <linux/threads.h>
++#include <linux/init.h>
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+ #include <asm/page.h>
+@@ -88,7 +89,7 @@ ENTRY(_stext)
+  */
+ .section ".bss.page_aligned","wa"
+       .align PAGE_SIZE_asm
+-ENTRY(swapper_pg_pmd)
++ENTRY(swapper_pg_fixmap)
+       .fill 1024,4,0
+ ENTRY(empty_zero_page)
+       .fill 4096,1,0
+--- sle11-2009-05-14.orig/arch/x86/kernel/init_task-xen.c      2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/init_task-xen.c   2009-03-16 16:33:40.000000000 +0100
 @@ -19,7 +19,7 @@ static struct sighand_struct init_sighan
  #endif
  struct mm_struct init_mm = INIT_MM(init_mm);
@@ -3240,8 +3114,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  /*
   * Initial thread structure.
---- a/arch/x86/kernel/io_apic_32-xen.c
-+++ b/arch/x86/kernel/io_apic_32-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/io_apic_32-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/io_apic_32-xen.c  2009-03-16 16:33:40.000000000 +0100
 @@ -35,6 +35,7 @@
  #include <linux/htirq.h>
  #include <linux/freezer.h>
@@ -3313,8 +3187,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        .suspend = ioapic_suspend,
        .resume = ioapic_resume,
  };
---- a/arch/x86/kernel/io_apic_64-xen.c
-+++ b/arch/x86/kernel/io_apic_64-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/io_apic_64-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/io_apic_64-xen.c  2009-03-16 16:33:40.000000000 +0100
 @@ -32,9 +32,11 @@
  #include <linux/msi.h>
  #include <linux/htirq.h>
@@ -3503,104 +3377,219 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 + * IO APICS that are mapped in on a BAR in PCI space. */
 +late_initcall(ioapic_insert_resources);
 +#endif /* !CONFIG_XEN */
---- a/arch/x86/kernel/ioport_32-xen.c
-+++ /dev/null
-@@ -1,121 +0,0 @@
--/*
-- * This contains the io-permission bitmap code - written by obz, with changes
-- * by Linus.
-- */
--
--#include <linux/sched.h>
--#include <linux/kernel.h>
--#include <linux/capability.h>
--#include <linux/errno.h>
--#include <linux/types.h>
--#include <linux/ioport.h>
--#include <linux/smp.h>
--#include <linux/stddef.h>
--#include <linux/slab.h>
--#include <linux/thread_info.h>
--#include <linux/syscalls.h>
--#include <xen/interface/physdev.h>
--
--/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
--static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
--{
--      unsigned long mask;
--      unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG);
--      unsigned int low_index = base & (BITS_PER_LONG-1);
--      int length = low_index + extent;
--
--      if (low_index != 0) {
--              mask = (~0UL << low_index);
--              if (length < BITS_PER_LONG)
--                      mask &= ~(~0UL << length);
--              if (new_value)
--                      *bitmap_base++ |= mask;
--              else
--                      *bitmap_base++ &= ~mask;
--              length -= BITS_PER_LONG;
--      }
--
--      mask = (new_value ? ~0UL : 0UL);
--      while (length >= BITS_PER_LONG) {
--              *bitmap_base++ = mask;
--              length -= BITS_PER_LONG;
--      }
--
--      if (length > 0) {
--              mask = ~(~0UL << length);
--              if (new_value)
--                      *bitmap_base++ |= mask;
--              else
--                      *bitmap_base++ &= ~mask;
--      }
--}
--
--
--/*
-- * this changes the io permissions bitmap in the current task.
-- */
--asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
--{
--      struct thread_struct * t = &current->thread;
--      unsigned long *bitmap;
--      struct physdev_set_iobitmap set_iobitmap;
--
--      if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
--              return -EINVAL;
--      if (turn_on && !capable(CAP_SYS_RAWIO))
--              return -EPERM;
--
--      /*
--       * If it's the first ioperm() call in this thread's lifetime, set the
--       * IO bitmap up. ioperm() is much less timing critical than clone(),
--       * this is why we delay this operation until now:
--       */
--      if (!t->io_bitmap_ptr) {
--              bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
--              if (!bitmap)
--                      return -ENOMEM;
--
--              memset(bitmap, 0xff, IO_BITMAP_BYTES);
--              t->io_bitmap_ptr = bitmap;
--              set_thread_flag(TIF_IO_BITMAP);
--
--              set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
--              set_iobitmap.nr_ports = IO_BITMAP_BITS;
--              WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
--                                            &set_iobitmap));
--      }
--
--      set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
--
--      return 0;
--}
--
--/*
-- * sys_iopl has to be used when you want to access the IO ports
-- * beyond the 0x3ff range: to get the full 65536 ports bitmapped
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/kernel/ioport-xen.c      2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,112 @@
++/*
++ * This contains the io-permission bitmap code - written by obz, with changes
++ * by Linus. 32/64 bits code unification by Miguel Botón.
++ */
++
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/capability.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/ioport.h>
++#include <linux/smp.h>
++#include <linux/stddef.h>
++#include <linux/slab.h>
++#include <linux/thread_info.h>
++#include <linux/syscalls.h>
++#include <xen/interface/physdev.h>
++
++/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
++static void set_bitmap(unsigned long *bitmap, unsigned int base,
++                     unsigned int extent, int new_value)
++{
++      unsigned int i;
++
++      for (i = base; i < base + extent; i++) {
++              if (new_value)
++                      __set_bit(i, bitmap);
++              else
++                      __clear_bit(i, bitmap);
++      }
++}
++
++/*
++ * this changes the io permissions bitmap in the current task.
++ */
++asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
++{
++      struct thread_struct * t = &current->thread;
++      struct physdev_set_iobitmap set_iobitmap;
++
++      if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
++              return -EINVAL;
++      if (turn_on && !capable(CAP_SYS_RAWIO))
++              return -EPERM;
++
++      /*
++       * If it's the first ioperm() call in this thread's lifetime, set the
++       * IO bitmap up. ioperm() is much less timing critical than clone(),
++       * this is why we delay this operation until now:
++       */
++      if (!t->io_bitmap_ptr) {
++              unsigned long *bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
++
++              if (!bitmap)
++                      return -ENOMEM;
++
++              memset(bitmap, 0xff, IO_BITMAP_BYTES);
++              t->io_bitmap_ptr = bitmap;
++              set_thread_flag(TIF_IO_BITMAP);
++
++              set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
++              set_iobitmap.nr_ports = IO_BITMAP_BITS;
++              WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
++                                            &set_iobitmap));
++      }
++
++      set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
++
++      return 0;
++}
++
++/*
++ * sys_iopl has to be used when you want to access the IO ports
++ * beyond the 0x3ff range: to get the full 65536 ports bitmapped
++ * you'd need 8kB of bitmaps/process, which is a bit excessive.
++ */
++static int do_iopl(unsigned int level, struct thread_struct *t)
++{
++      unsigned int old = t->iopl >> 12;
++
++      if (level > 3)
++              return -EINVAL;
++      /* Trying to gain more privileges? */
++      if (level > old) {
++              if (!capable(CAP_SYS_RAWIO))
++                      return -EPERM;
++      }
++
++      return 0;
++}
++
++#ifdef CONFIG_X86_32
++asmlinkage long sys_iopl(unsigned long regsp)
++{
++      struct pt_regs *regs = (struct pt_regs *)&regsp;
++      unsigned int level = regs->bx;
++#else
++asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
++{
++#endif
++      struct thread_struct *t = &current->thread;
++      int rc;
++
++      rc = do_iopl(level, t);
++      if (rc < 0)
++              goto out;
++
++      t->iopl = level << 12;
++      set_iopl_mask(t->iopl);
++out:
++      return rc;
++}
+--- sle11-2009-05-14.orig/arch/x86/kernel/ioport_32-xen.c      2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,121 +0,0 @@
+-/*
+- * This contains the io-permission bitmap code - written by obz, with changes
+- * by Linus.
+- */
+-
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/capability.h>
+-#include <linux/errno.h>
+-#include <linux/types.h>
+-#include <linux/ioport.h>
+-#include <linux/smp.h>
+-#include <linux/stddef.h>
+-#include <linux/slab.h>
+-#include <linux/thread_info.h>
+-#include <linux/syscalls.h>
+-#include <xen/interface/physdev.h>
+-
+-/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
+-static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
+-{
+-      unsigned long mask;
+-      unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG);
+-      unsigned int low_index = base & (BITS_PER_LONG-1);
+-      int length = low_index + extent;
+-
+-      if (low_index != 0) {
+-              mask = (~0UL << low_index);
+-              if (length < BITS_PER_LONG)
+-                      mask &= ~(~0UL << length);
+-              if (new_value)
+-                      *bitmap_base++ |= mask;
+-              else
+-                      *bitmap_base++ &= ~mask;
+-              length -= BITS_PER_LONG;
+-      }
+-
+-      mask = (new_value ? ~0UL : 0UL);
+-      while (length >= BITS_PER_LONG) {
+-              *bitmap_base++ = mask;
+-              length -= BITS_PER_LONG;
+-      }
+-
+-      if (length > 0) {
+-              mask = ~(~0UL << length);
+-              if (new_value)
+-                      *bitmap_base++ |= mask;
+-              else
+-                      *bitmap_base++ &= ~mask;
+-      }
+-}
+-
+-
+-/*
+- * this changes the io permissions bitmap in the current task.
+- */
+-asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
+-{
+-      struct thread_struct * t = &current->thread;
+-      unsigned long *bitmap;
+-      struct physdev_set_iobitmap set_iobitmap;
+-
+-      if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
+-              return -EINVAL;
+-      if (turn_on && !capable(CAP_SYS_RAWIO))
+-              return -EPERM;
+-
+-      /*
+-       * If it's the first ioperm() call in this thread's lifetime, set the
+-       * IO bitmap up. ioperm() is much less timing critical than clone(),
+-       * this is why we delay this operation until now:
+-       */
+-      if (!t->io_bitmap_ptr) {
+-              bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+-              if (!bitmap)
+-                      return -ENOMEM;
+-
+-              memset(bitmap, 0xff, IO_BITMAP_BYTES);
+-              t->io_bitmap_ptr = bitmap;
+-              set_thread_flag(TIF_IO_BITMAP);
+-
+-              set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
+-              set_iobitmap.nr_ports = IO_BITMAP_BITS;
+-              WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
+-                                            &set_iobitmap));
+-      }
+-
+-      set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
+-
+-      return 0;
+-}
+-
+-/*
+- * sys_iopl has to be used when you want to access the IO ports
+- * beyond the 0x3ff range: to get the full 65536 ports bitmapped
 - * you'd need 8kB of bitmaps/process, which is a bit excessive.
 - *
 - * Here we just change the eflags value on the stack: we allow
@@ -3627,8 +3616,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -      set_iopl_mask(t->iopl);
 -      return 0;
 -}
---- a/arch/x86/kernel/ioport_64-xen.c
-+++ /dev/null
+--- sle11-2009-05-14.orig/arch/x86/kernel/ioport_64-xen.c      2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
 @@ -1,99 +0,0 @@
 -/*
 - * This contains the io-permission bitmap code - written by obz, with changes
@@ -3729,123 +3718,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -
 -      return 0;
 -}
---- /dev/null
-+++ b/arch/x86/kernel/ioport-xen.c
-@@ -0,0 +1,112 @@
-+/*
-+ * This contains the io-permission bitmap code - written by obz, with changes
-+ * by Linus. 32/64 bits code unification by Miguel Botón.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/capability.h>
-+#include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/ioport.h>
-+#include <linux/smp.h>
-+#include <linux/stddef.h>
-+#include <linux/slab.h>
-+#include <linux/thread_info.h>
-+#include <linux/syscalls.h>
-+#include <xen/interface/physdev.h>
-+
-+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
-+static void set_bitmap(unsigned long *bitmap, unsigned int base,
-+                     unsigned int extent, int new_value)
-+{
-+      unsigned int i;
-+
-+      for (i = base; i < base + extent; i++) {
-+              if (new_value)
-+                      __set_bit(i, bitmap);
-+              else
-+                      __clear_bit(i, bitmap);
-+      }
-+}
-+
-+/*
-+ * this changes the io permissions bitmap in the current task.
-+ */
-+asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
-+{
-+      struct thread_struct * t = &current->thread;
-+      struct physdev_set_iobitmap set_iobitmap;
-+
-+      if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
-+              return -EINVAL;
-+      if (turn_on && !capable(CAP_SYS_RAWIO))
-+              return -EPERM;
-+
-+      /*
-+       * If it's the first ioperm() call in this thread's lifetime, set the
-+       * IO bitmap up. ioperm() is much less timing critical than clone(),
-+       * this is why we delay this operation until now:
-+       */
-+      if (!t->io_bitmap_ptr) {
-+              unsigned long *bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
-+
-+              if (!bitmap)
-+                      return -ENOMEM;
-+
-+              memset(bitmap, 0xff, IO_BITMAP_BYTES);
-+              t->io_bitmap_ptr = bitmap;
-+              set_thread_flag(TIF_IO_BITMAP);
-+
-+              set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
-+              set_iobitmap.nr_ports = IO_BITMAP_BITS;
-+              WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
-+                                            &set_iobitmap));
-+      }
-+
-+      set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
-+
-+      return 0;
-+}
-+
-+/*
-+ * sys_iopl has to be used when you want to access the IO ports
-+ * beyond the 0x3ff range: to get the full 65536 ports bitmapped
-+ * you'd need 8kB of bitmaps/process, which is a bit excessive.
-+ */
-+static int do_iopl(unsigned int level, struct thread_struct *t)
-+{
-+      unsigned int old = t->iopl >> 12;
-+
-+      if (level > 3)
-+              return -EINVAL;
-+      /* Trying to gain more privileges? */
-+      if (level > old) {
-+              if (!capable(CAP_SYS_RAWIO))
-+                      return -EPERM;
-+      }
-+
-+      return 0;
-+}
-+
-+#ifdef CONFIG_X86_32
-+asmlinkage long sys_iopl(unsigned long regsp)
-+{
-+      struct pt_regs *regs = (struct pt_regs *)&regsp;
-+      unsigned int level = regs->bx;
-+#else
-+asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
-+{
-+#endif
-+      struct thread_struct *t = &current->thread;
-+      int rc;
-+
-+      rc = do_iopl(level, t);
-+      if (rc < 0)
-+              goto out;
-+
-+      t->iopl = level << 12;
-+      set_iopl_mask(t->iopl);
-+out:
-+      return rc;
-+}
---- a/arch/x86/kernel/irq_32-xen.c
-+++ b/arch/x86/kernel/irq_32-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/irq_32-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/irq_32-xen.c      2009-03-16 16:33:40.000000000 +0100
 @@ -66,11 +66,11 @@ static union irq_ctx *softirq_ctx[NR_CPU
   * SMP cross-CPU interrupts have their own specific
   * handlers).
@@ -3902,8 +3776,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
                        :  "0" (irq),   "1" (desc),  "2" (isp),
                           "D" (desc->handle_irq)
                        : "memory", "cc"
---- a/arch/x86/kernel/irq_64-xen.c
-+++ b/arch/x86/kernel/irq_64-xen.c
+--- sle11-2009-05-14.orig/arch/x86/kernel/irq_64-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/irq_64-xen.c      2009-03-16 16:33:40.000000000 +0100
 @@ -20,6 +20,28 @@
  
  atomic_t irq_err_count;
@@ -3973,22314 +3847,20903 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -        printk("unexpected IRQ trap at irq %02x\n", irq);
 -}
 -#endif
---- a/arch/x86/kernel/ldt_32-xen.c
-+++ /dev/null
-@@ -1,265 +0,0 @@
--/*
-- * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
-- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-- */
--
--#include <linux/errno.h>
--#include <linux/sched.h>
--#include <linux/string.h>
--#include <linux/mm.h>
--#include <linux/smp.h>
--#include <linux/vmalloc.h>
--#include <linux/slab.h>
--
--#include <asm/uaccess.h>
--#include <asm/system.h>
--#include <asm/ldt.h>
--#include <asm/desc.h>
--#include <asm/mmu_context.h>
--
--#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
--static void flush_ldt(void *null)
--{
--      if (current->active_mm)
--              load_LDT(&current->active_mm->context);
--}
--#endif
--
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
--{
--      void *oldldt;
--      void *newldt;
--      int oldsize;
--
--      if (mincount <= pc->size)
--              return 0;
--      oldsize = pc->size;
--      mincount = (mincount+511)&(~511);
--      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
--              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
--      else
--              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
--
--      if (!newldt)
--              return -ENOMEM;
--
--      if (oldsize)
--              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
--      oldldt = pc->ldt;
--      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
--      pc->ldt = newldt;
--      wmb();
--      pc->size = mincount;
--      wmb();
--
--      if (reload) {
--#ifdef CONFIG_SMP
--              cpumask_t mask;
--              preempt_disable();
--#endif
--              make_pages_readonly(
--                      pc->ldt,
--                      (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
--                      XENFEAT_writable_descriptor_tables);
--              load_LDT(pc);
--#ifdef CONFIG_SMP
--              mask = cpumask_of_cpu(smp_processor_id());
--              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
--                      smp_call_function(flush_ldt, NULL, 1, 1);
--              preempt_enable();
--#endif
--      }
--      if (oldsize) {
--              make_pages_writable(
--                      oldldt,
--                      (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
--                      XENFEAT_writable_descriptor_tables);
--              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
--                      vfree(oldldt);
--              else
--                      kfree(oldldt);
--      }
--      return 0;
--}
--
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
--{
--      int err = alloc_ldt(new, old->size, 0);
--      if (err < 0)
--              return err;
--      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
--      make_pages_readonly(
--              new->ldt,
--              (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
--              XENFEAT_writable_descriptor_tables);
--      return 0;
--}
--
--/*
-- * we do not have to muck with descriptors here, that is
-- * done in switch_mm() as needed.
-- */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
--{
--      struct mm_struct * old_mm;
--      int retval = 0;
--
--      mutex_init(&mm->context.lock);
--      mm->context.size = 0;
--      mm->context.has_foreign_mappings = 0;
--      old_mm = current->mm;
--      if (old_mm && old_mm->context.size > 0) {
--              mutex_lock(&old_mm->context.lock);
--              retval = copy_ldt(&mm->context, &old_mm->context);
--              mutex_unlock(&old_mm->context.lock);
--      }
--      return retval;
--}
--
--/*
-- * No need to lock the MM as we are the last user
-- */
--void destroy_context(struct mm_struct *mm)
--{
--      if (mm->context.size) {
--              if (mm == current->active_mm)
--                      clear_LDT();
--              make_pages_writable(
--                      mm->context.ldt,
--                      (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
--                      XENFEAT_writable_descriptor_tables);
--              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
--                      vfree(mm->context.ldt);
--              else
--                      kfree(mm->context.ldt);
--              mm->context.size = 0;
--      }
--}
--
--static int read_ldt(void __user * ptr, unsigned long bytecount)
--{
--      int err;
--      unsigned long size;
--      struct mm_struct * mm = current->mm;
--
--      if (!mm->context.size)
--              return 0;
--      if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
--              bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
--
--      mutex_lock(&mm->context.lock);
--      size = mm->context.size*LDT_ENTRY_SIZE;
--      if (size > bytecount)
--              size = bytecount;
--
--      err = 0;
--      if (copy_to_user(ptr, mm->context.ldt, size))
--              err = -EFAULT;
--      mutex_unlock(&mm->context.lock);
--      if (err < 0)
--              goto error_return;
--      if (size != bytecount) {
--              /* zero-fill the rest */
--              if (clear_user(ptr+size, bytecount-size) != 0) {
--                      err = -EFAULT;
--                      goto error_return;
--              }
--      }
--      return bytecount;
--error_return:
--      return err;
--}
--
--static int read_default_ldt(void __user * ptr, unsigned long bytecount)
--{
--      int err;
--      unsigned long size;
--
--      err = 0;
--      size = 5*sizeof(struct desc_struct);
--      if (size > bytecount)
--              size = bytecount;
--
--      err = size;
--      if (clear_user(ptr, size))
--              err = -EFAULT;
--
--      return err;
--}
--
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
--{
--      struct mm_struct * mm = current->mm;
--      __u32 entry_1, entry_2;
--      int error;
--      struct user_desc ldt_info;
--
--      error = -EINVAL;
--      if (bytecount != sizeof(ldt_info))
--              goto out;
--      error = -EFAULT;        
--      if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
--              goto out;
--
--      error = -EINVAL;
--      if (ldt_info.entry_number >= LDT_ENTRIES)
--              goto out;
--      if (ldt_info.contents == 3) {
--              if (oldmode)
--                      goto out;
--              if (ldt_info.seg_not_present == 0)
--                      goto out;
--      }
--
--      mutex_lock(&mm->context.lock);
--      if (ldt_info.entry_number >= mm->context.size) {
--              error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
--              if (error < 0)
--                      goto out_unlock;
--      }
--
--      /* Allow LDTs to be cleared by the user. */
--      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
--              if (oldmode || LDT_empty(&ldt_info)) {
--                      entry_1 = 0;
--                      entry_2 = 0;
--                      goto install;
--              }
--      }
--
--      entry_1 = LDT_entry_a(&ldt_info);
--      entry_2 = LDT_entry_b(&ldt_info);
--      if (oldmode)
--              entry_2 &= ~(1 << 20);
--
--      /* Install the new entry ...  */
--install:
--      error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number,
--                              entry_1, entry_2);
--
--out_unlock:
--      mutex_unlock(&mm->context.lock);
--out:
--      return error;
--}
--
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
--{
--      int ret = -ENOSYS;
--
--      switch (func) {
--      case 0:
--              ret = read_ldt(ptr, bytecount);
--              break;
--      case 1:
--              ret = write_ldt(ptr, bytecount, 1);
--              break;
--      case 2:
--              ret = read_default_ldt(ptr, bytecount);
--              break;
--      case 0x11:
--              ret = write_ldt(ptr, bytecount, 0);
--              break;
--      }
--      return ret;
--}
---- a/arch/x86/kernel/ldt_64-xen.c
-+++ /dev/null
-@@ -1,271 +0,0 @@
--/*
-- * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
-- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-- * Copyright (C) 2002 Andi Kleen
-- * 
-- * This handles calls from both 32bit and 64bit mode.
-- */
--
--#include <linux/errno.h>
--#include <linux/sched.h>
--#include <linux/string.h>
--#include <linux/mm.h>
--#include <linux/smp.h>
--#include <linux/vmalloc.h>
--#include <linux/slab.h>
--
--#include <asm/uaccess.h>
--#include <asm/system.h>
--#include <asm/ldt.h>
--#include <asm/desc.h>
--#include <asm/proto.h>
--#include <asm/pgalloc.h>
--
--#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
--static void flush_ldt(void *null)
--{
--      if (current->active_mm)
--               load_LDT(&current->active_mm->context);
--}
--#endif
--
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
--{
--      void *oldldt;
--      void *newldt;
--      unsigned oldsize;
--
--      if (mincount <= (unsigned)pc->size)
--              return 0;
--      oldsize = pc->size;
--      mincount = (mincount+511)&(~511);
--      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
--              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
--      else
--              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
--
--      if (!newldt)
--              return -ENOMEM;
--
--      if (oldsize)
--              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
--      oldldt = pc->ldt;
--      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
--      wmb();
--      pc->ldt = newldt;
--      wmb();
--      pc->size = mincount;
--      wmb();
--      if (reload) {
--#ifdef CONFIG_SMP
--              cpumask_t mask;
--
--              preempt_disable();
--#endif
--              make_pages_readonly(
--                      pc->ldt,
--                      (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
--                      XENFEAT_writable_descriptor_tables);
--              load_LDT(pc);
--#ifdef CONFIG_SMP
--              mask = cpumask_of_cpu(smp_processor_id());
--              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
--                      smp_call_function(flush_ldt, NULL, 1, 1);
--              preempt_enable();
--#endif
--      }
--      if (oldsize) {
--              make_pages_writable(
--                      oldldt,
--                      (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
--                      XENFEAT_writable_descriptor_tables);
--              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
--                      vfree(oldldt);
--              else
--                      kfree(oldldt);
--      }
--      return 0;
--}
--
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
--{
--      int err = alloc_ldt(new, old->size, 0);
--      if (err < 0)
--              return err;
--      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
--      make_pages_readonly(
--              new->ldt,
--              (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
--              XENFEAT_writable_descriptor_tables);
--      return 0;
--}
--
--/*
-- * we do not have to muck with descriptors here, that is
-- * done in switch_mm() as needed.
-- */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
--{
--      struct mm_struct * old_mm;
--      int retval = 0;
--
--      memset(&mm->context, 0, sizeof(mm->context));
--      mutex_init(&mm->context.lock);
--      old_mm = current->mm;
--      if (old_mm)
--              mm->context.vdso = old_mm->context.vdso;
--      if (old_mm && old_mm->context.size > 0) {
--              mutex_lock(&old_mm->context.lock);
--              retval = copy_ldt(&mm->context, &old_mm->context);
--              mutex_unlock(&old_mm->context.lock);
--      }
--      return retval;
--}
--
--/*
-- * 
-- * Don't touch the LDT register - we're already in the next thread.
-- */
--void destroy_context(struct mm_struct *mm)
--{
--      if (mm->context.size) {
--              if (mm == current->active_mm)
--                      clear_LDT();
--              make_pages_writable(
--                      mm->context.ldt,
--                      (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
--                      XENFEAT_writable_descriptor_tables);
--              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
--                      vfree(mm->context.ldt);
--              else
--                      kfree(mm->context.ldt);
--              mm->context.size = 0;
--      }
--}
--
--static int read_ldt(void __user * ptr, unsigned long bytecount)
--{
--      int err;
--      unsigned long size;
--      struct mm_struct * mm = current->mm;
--
--      if (!mm->context.size)
--              return 0;
--      if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
--              bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
--
--      mutex_lock(&mm->context.lock);
--      size = mm->context.size*LDT_ENTRY_SIZE;
--      if (size > bytecount)
--              size = bytecount;
--
--      err = 0;
--      if (copy_to_user(ptr, mm->context.ldt, size))
--              err = -EFAULT;
--      mutex_unlock(&mm->context.lock);
--      if (err < 0)
--              goto error_return;
--      if (size != bytecount) {
--              /* zero-fill the rest */
--              if (clear_user(ptr+size, bytecount-size) != 0) {
--                      err = -EFAULT;
--                      goto error_return;
--              }
--      }
--      return bytecount;
--error_return:
--      return err;
--}
--
--static int read_default_ldt(void __user * ptr, unsigned long bytecount)
--{
--      /* Arbitrary number */ 
--      /* x86-64 default LDT is all zeros */
--      if (bytecount > 128) 
--              bytecount = 128;        
--      if (clear_user(ptr, bytecount))
--              return -EFAULT;
--      return bytecount; 
--}
--
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
--{
--      struct task_struct *me = current;
--      struct mm_struct * mm = me->mm;
--      __u32 entry_1, entry_2, *lp;
--      unsigned long mach_lp;
--      int error;
--      struct user_desc ldt_info;
--
--      error = -EINVAL;
--
--      if (bytecount != sizeof(ldt_info))
--              goto out;
--      error = -EFAULT;        
--      if (copy_from_user(&ldt_info, ptr, bytecount))
--              goto out;
--
--      error = -EINVAL;
--      if (ldt_info.entry_number >= LDT_ENTRIES)
--              goto out;
--      if (ldt_info.contents == 3) {
--              if (oldmode)
--                      goto out;
--              if (ldt_info.seg_not_present == 0)
--                      goto out;
--      }
--
--      mutex_lock(&mm->context.lock);
--      if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--              error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
--              if (error < 0)
--                      goto out_unlock;
--      }
--
--      lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
--      mach_lp = arbitrary_virt_to_machine(lp);
--
--      /* Allow LDTs to be cleared by the user. */
--      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
--              if (oldmode || LDT_empty(&ldt_info)) {
--                      entry_1 = 0;
--                      entry_2 = 0;
--                      goto install;
--              }
--      }
--
--      entry_1 = LDT_entry_a(&ldt_info);
--      entry_2 = LDT_entry_b(&ldt_info);
--      if (oldmode)
--              entry_2 &= ~(1 << 20);
--
--      /* Install the new entry ...  */
--install:
--      error = HYPERVISOR_update_descriptor(mach_lp, (unsigned long)((entry_1 | (unsigned long) entry_2 << 32)));
--
--out_unlock:
--      mutex_unlock(&mm->context.lock);
--out:
--      return error;
--}
--
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
--{
--      int ret = -ENOSYS;
--
--      switch (func) {
--      case 0:
--              ret = read_ldt(ptr, bytecount);
--              break;
--      case 1:
--              ret = write_ldt(ptr, bytecount, 1);
--              break;
--      case 2:
--              ret = read_default_ldt(ptr, bytecount);
--              break;
--      case 0x11:
--              ret = write_ldt(ptr, bytecount, 0);
--              break;
--      }
--      return ret;
--}
---- /dev/null
-+++ b/arch/x86/kernel/ldt-xen.c
-@@ -0,0 +1,272 @@
-+/*
-+ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
-+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-+ * Copyright (C) 2002 Andi Kleen
-+ *
-+ * This handles calls from both 32bit and 64bit mode.
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/vmalloc.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/ldt.h>
-+#include <asm/desc.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_SMP
-+static void flush_ldt(void *null)
-+{
-+      if (current->active_mm)
-+              load_LDT(&current->active_mm->context);
-+}
-+#endif
-+
-+static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+{
-+      void *oldldt, *newldt;
-+      int oldsize;
-+
-+      if (mincount <= pc->size)
-+              return 0;
-+      oldsize = pc->size;
-+      mincount = (mincount + (PAGE_SIZE / LDT_ENTRY_SIZE - 1)) &
-+                      (~(PAGE_SIZE / LDT_ENTRY_SIZE - 1));
-+      if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE)
-+              newldt = vmalloc(mincount * LDT_ENTRY_SIZE);
-+      else
-+              newldt = (void *)__get_free_page(GFP_KERNEL);
-+
-+      if (!newldt)
-+              return -ENOMEM;
-+
-+      if (oldsize)
-+              memcpy(newldt, pc->ldt, oldsize * LDT_ENTRY_SIZE);
-+      oldldt = pc->ldt;
-+      memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,
-+             (mincount - oldsize) * LDT_ENTRY_SIZE);
-+
-+#ifdef CONFIG_X86_64
-+      /* CHECKME: Do we really need this ? */
-+      wmb();
-+#endif
-+      pc->ldt = newldt;
-+      wmb();
-+      pc->size = mincount;
-+      wmb();
-+
-+      if (reload) {
-+#ifdef CONFIG_SMP
-+              cpumask_t mask;
-+
-+              preempt_disable();
-+#endif
-+              make_pages_readonly(newldt,
-+                                  (mincount * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                                  XENFEAT_writable_descriptor_tables);
-+              load_LDT(pc);
-+#ifdef CONFIG_SMP
-+              mask = cpumask_of_cpu(smp_processor_id());
-+              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+                      smp_call_function(flush_ldt, NULL, 1, 1);
-+              preempt_enable();
-+#endif
-+      }
-+      if (oldsize) {
-+              make_pages_writable(oldldt,
-+                                  (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                                  XENFEAT_writable_descriptor_tables);
-+              if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
-+                      vfree(oldldt);
-+              else
-+                      put_page(virt_to_page(oldldt));
-+      }
-+      return 0;
-+}
-+
-+static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+{
-+      int err = alloc_ldt(new, old->size, 0);
-+
-+      if (err < 0)
-+              return err;
-+      memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE);
-+      make_pages_readonly(new->ldt,
-+                          (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                          XENFEAT_writable_descriptor_tables);
-+      return 0;
-+}
-+
-+/*
-+ * we do not have to muck with descriptors here, that is
-+ * done in switch_mm() as needed.
-+ */
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+      struct mm_struct *old_mm;
-+      int retval = 0;
-+
-+      memset(&mm->context, 0, sizeof(mm->context));
-+      mutex_init(&mm->context.lock);
-+      old_mm = current->mm;
-+      if (old_mm)
-+              mm->context.vdso = old_mm->context.vdso;
-+      if (old_mm && old_mm->context.size > 0) {
-+              mutex_lock(&old_mm->context.lock);
-+              retval = copy_ldt(&mm->context, &old_mm->context);
-+              mutex_unlock(&old_mm->context.lock);
-+      }
-+      return retval;
-+}
-+
-+/*
-+ * No need to lock the MM as we are the last user
-+ *
-+ * 64bit: Don't touch the LDT register - we're already in the next thread.
-+ */
-+void destroy_context(struct mm_struct *mm)
-+{
-+      if (mm->context.size) {
-+              /* CHECKME: Can this ever happen ? */
-+              if (mm == current->active_mm)
-+                      clear_LDT();
-+              make_pages_writable(mm->context.ldt,
-+                                  (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                                  XENFEAT_writable_descriptor_tables);
-+              if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
-+                      vfree(mm->context.ldt);
-+              else
-+                      put_page(virt_to_page(mm->context.ldt));
-+              mm->context.size = 0;
-+      }
-+}
-+
-+static int read_ldt(void __user *ptr, unsigned long bytecount)
-+{
-+      int err;
-+      unsigned long size;
-+      struct mm_struct *mm = current->mm;
-+
-+      if (!mm->context.size)
-+              return 0;
-+      if (bytecount > LDT_ENTRY_SIZE * LDT_ENTRIES)
-+              bytecount = LDT_ENTRY_SIZE * LDT_ENTRIES;
-+
-+      mutex_lock(&mm->context.lock);
-+      size = mm->context.size * LDT_ENTRY_SIZE;
-+      if (size > bytecount)
-+              size = bytecount;
-+
-+      err = 0;
-+      if (copy_to_user(ptr, mm->context.ldt, size))
-+              err = -EFAULT;
-+      mutex_unlock(&mm->context.lock);
-+      if (err < 0)
-+              goto error_return;
-+      if (size != bytecount) {
-+              /* zero-fill the rest */
-+              if (clear_user(ptr + size, bytecount - size) != 0) {
-+                      err = -EFAULT;
-+                      goto error_return;
-+              }
-+      }
-+      return bytecount;
-+error_return:
-+      return err;
-+}
-+
-+static int read_default_ldt(void __user *ptr, unsigned long bytecount)
-+{
-+      /* CHECKME: Can we use _one_ random number ? */
-+#ifdef CONFIG_X86_32
-+      unsigned long size = 5 * sizeof(struct desc_struct);
-+#else
-+      unsigned long size = 128;
-+#endif
-+      if (bytecount > size)
-+              bytecount = size;
-+      if (clear_user(ptr, bytecount))
-+              return -EFAULT;
-+      return bytecount;
-+}
-+
-+static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
-+{
-+      struct mm_struct *mm = current->mm;
-+      struct desc_struct ldt;
-+      int error;
-+      struct user_desc ldt_info;
-+
-+      error = -EINVAL;
-+      if (bytecount != sizeof(ldt_info))
-+              goto out;
-+      error = -EFAULT;
-+      if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
-+              goto out;
-+
-+      error = -EINVAL;
-+      if (ldt_info.entry_number >= LDT_ENTRIES)
-+              goto out;
-+      if (ldt_info.contents == 3) {
-+              if (oldmode)
-+                      goto out;
-+              if (ldt_info.seg_not_present == 0)
-+                      goto out;
-+      }
-+
-+      mutex_lock(&mm->context.lock);
-+      if (ldt_info.entry_number >= mm->context.size) {
-+              error = alloc_ldt(&current->mm->context,
-+                                ldt_info.entry_number + 1, 1);
-+              if (error < 0)
-+                      goto out_unlock;
-+      }
-+
-+      /* Allow LDTs to be cleared by the user. */
-+      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
-+              if (oldmode || LDT_empty(&ldt_info)) {
-+                      memset(&ldt, 0, sizeof(ldt));
-+                      goto install;
-+              }
-+      }
-+
-+      fill_ldt(&ldt, &ldt_info);
-+      if (oldmode)
-+              ldt.avl = 0;
-+
-+      /* Install the new entry ...  */
-+install:
-+      error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt);
-+
-+out_unlock:
-+      mutex_unlock(&mm->context.lock);
-+out:
-+      return error;
-+}
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr,
-+                            unsigned long bytecount)
-+{
-+      int ret = -ENOSYS;
-+
-+      switch (func) {
-+      case 0:
-+              ret = read_ldt(ptr, bytecount);
-+              break;
-+      case 1:
-+              ret = write_ldt(ptr, bytecount, 1);
-+              break;
-+      case 2:
-+              ret = read_default_ldt(ptr, bytecount);
-+              break;
-+      case 0x11:
-+              ret = write_ldt(ptr, bytecount, 0);
-+              break;
-+      }
-+      return ret;
-+}
---- a/arch/x86/kernel/machine_kexec_64.c
-+++ b/arch/x86/kernel/machine_kexec_64.c
-@@ -300,7 +300,9 @@ void machine_kexec(struct kimage *image)
- void arch_crash_save_vmcoreinfo(void)
- {
-+#ifndef CONFIG_XEN /* could really be CONFIG_RELOCATABLE */
-       VMCOREINFO_SYMBOL(phys_base);
-+#endif
-       VMCOREINFO_SYMBOL(init_level4_pgt);
- #ifdef CONFIG_NUMA
---- a/arch/x86/kernel/Makefile
-+++ b/arch/x86/kernel/Makefile
-@@ -120,11 +120,10 @@ ifeq ($(CONFIG_X86_64),y)
-         obj-$(CONFIG_PCI_MMCONFIG)    += mmconf-fam10h_64.o
-+      obj-$(CONFIG_XEN)               += nmi_64.o
-       time_64-$(CONFIG_XEN)           += time_32.o
-       pci-dma_64-$(CONFIG_XEN)        += pci-dma_32.o
- endif
- disabled-obj-$(CONFIG_XEN) := early-quirks.o hpet.o i8253.o i8259_$(BITS).o reboot.o \
-       smpboot_$(BITS).o tsc_$(BITS).o tsc_sync.o
--disabled-obj-$(CONFIG_XEN_UNPRIVILEGED_GUEST) += mpparse_64.o
--%/head_64.o %/head_64.s: asflags-$(CONFIG_XEN) :=
---- a/arch/x86/kernel/microcode-xen.c
-+++ b/arch/x86/kernel/microcode-xen.c
-@@ -167,7 +167,7 @@ static int request_microcode(void)
-       }
-       op.cmd = XENPF_microcode_update;
--      set_xen_guest_handle(op.u.microcode.data, (void *)firmware->data);
-+      set_xen_guest_handle(op.u.microcode.data, firmware->data);
-       op.u.microcode.length = firmware->size;
-       error = HYPERVISOR_platform_op(&op);
---- a/arch/x86/kernel/mpparse_32-xen.c
-+++ b/arch/x86/kernel/mpparse_32-xen.c
-@@ -68,7 +68,7 @@ unsigned int def_to_bigsmp = 0;
- /* Processor that is doing the boot up */
- unsigned int boot_cpu_physical_apicid = -1U;
- /* Internal processor count */
--unsigned int __cpuinitdata num_processors;
-+unsigned int num_processors;
- /* Bitmask of physically existing CPUs */
- physid_mask_t phys_cpu_present_map;
-@@ -265,7 +265,7 @@ static void __init MP_ioapic_info (struc
-       if (!(m->mpc_flags & MPC_APIC_USABLE))
-               return;
--      printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n",
-+      printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
-               m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
-       if (nr_ioapics >= MAX_IO_APICS) {
-               printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n",
-@@ -412,9 +412,9 @@ static int __init smp_read_mpc(struct mp
-       mps_oem_check(mpc, oem, str);
--      printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
-+      printk("APIC at: 0x%X\n", mpc->mpc_lapic);
--      /* 
-+      /*
-        * Save the local APIC address (it might be non-default) -- but only
-        * if we're not using ACPI.
-        */
-@@ -728,7 +728,7 @@ static int __init smp_scan_config (unsig
-       unsigned long *bp = isa_bus_to_virt(base);
-       struct intel_mp_floating *mpf;
--      Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
-+      printk(KERN_INFO "Scan SMP from %p for %ld bytes.\n", bp,length);
-       if (sizeof(*mpf) != 16)
-               printk("Error: MPF size\n");
-@@ -742,9 +742,10 @@ static int __init smp_scan_config (unsig
-                       smp_found_config = 1;
- #ifndef CONFIG_XEN
--                      printk(KERN_INFO "found SMP MP-table at %08lx\n",
--                                              virt_to_phys(mpf));
--                      reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
-+                      printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
-+                              mpf, virt_to_phys(mpf));
-+                      reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
-+                                      BOOTMEM_DEFAULT);
-                       if (mpf->mpf_physptr) {
-                               /*
-                                * We cannot access to MPC table to compute
-@@ -759,11 +760,12 @@ static int __init smp_scan_config (unsig
-                               unsigned long end = max_low_pfn * PAGE_SIZE;
-                               if (mpf->mpf_physptr + size > end)
-                                       size = end - mpf->mpf_physptr;
--                              reserve_bootmem(mpf->mpf_physptr, size);
-+                              reserve_bootmem(mpf->mpf_physptr, size,
-+                                              BOOTMEM_DEFAULT);
-                       }
- #else
--                      printk(KERN_INFO "found SMP MP-table at %08lx\n",
--                              ((unsigned long)bp - (unsigned long)isa_bus_to_virt(base)) + base);
-+                      printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
-+                              mpf, ((void *)bp - isa_bus_to_virt(base)) + base);
- #endif
-                       mpf_found = mpf;
-@@ -940,14 +942,14 @@ void __init mp_register_ioapic(u8 id, u3
-        */
-       mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
-       mp_ioapic_routing[idx].gsi_base = gsi_base;
--      mp_ioapic_routing[idx].gsi_end = gsi_base + 
-+      mp_ioapic_routing[idx].gsi_end = gsi_base +
-               io_apic_get_redir_entries(idx);
--      printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
--              "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
--              mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
--              mp_ioapic_routing[idx].gsi_base,
--              mp_ioapic_routing[idx].gsi_end);
-+      printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
-+             "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
-+             mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
-+             mp_ioapic_routing[idx].gsi_base,
-+             mp_ioapic_routing[idx].gsi_end);
- }
- void __init
-@@ -1063,15 +1065,16 @@ void __init mp_config_acpi_legacy_irqs (
- }
- #define MAX_GSI_NUM   4096
-+#define IRQ_COMPRESSION_START 64
- int mp_register_gsi(u32 gsi, int triggering, int polarity)
- {
-       int ioapic = -1;
-       int ioapic_pin = 0;
-       int idx, bit = 0;
--      static int pci_irq = 16;
-+      static int pci_irq = IRQ_COMPRESSION_START;
-       /*
--       * Mapping between Global System Interrups, which
-+       * Mapping between Global System Interrupts, which
-        * represent all possible interrupts, and IRQs
-        * assigned to actual devices.
-        */
-@@ -1108,12 +1111,16 @@ int mp_register_gsi(u32 gsi, int trigger
-       if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
-               Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
-                       mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
--              return gsi_to_irq[gsi];
-+              return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
-       }
-       mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
--      if (triggering == ACPI_LEVEL_SENSITIVE) {
-+      /*
-+       * 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.
---- a/arch/x86/kernel/mpparse_64-xen.c
-+++ b/arch/x86/kernel/mpparse_64-xen.c
-@@ -60,14 +60,20 @@ unsigned int boot_cpu_id = -1U;
- EXPORT_SYMBOL(boot_cpu_id);
- /* Internal processor count */
--unsigned int num_processors __cpuinitdata = 0;
-+unsigned int num_processors;
- unsigned disabled_cpus __cpuinitdata;
- /* Bitmask of physically existing CPUs */
- physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
--u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-+#ifndef CONFIG_XEN
-+u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
-+                              = { [0 ... NR_CPUS-1] = BAD_APICID };
-+void *x86_bios_cpu_apicid_early_ptr;
-+#endif
-+DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
-+EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
- /*
-@@ -119,24 +125,22 @@ static void __cpuinit MP_processor_info(
-       physid_set(m->mpc_apicid, phys_cpu_present_map);
-       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
-               /*
--               * bios_cpu_apicid is required to have processors listed
-+               * x86_bios_cpu_apicid is required to have processors listed
-                * in same order as logical cpu numbers. Hence the first
-                * entry is BSP, and so on.
-                */
-               cpu = 0;
-       }
--      bios_cpu_apicid[cpu] = m->mpc_apicid;
--      /*
--       * We get called early in the the start_kernel initialization
--       * process when the per_cpu data area is not yet setup, so we
--       * use a static array that is removed after the per_cpu data
--       * area is created.
--       */
--      if (x86_cpu_to_apicid_ptr) {
--              u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
--              x86_cpu_to_apicid[cpu] = m->mpc_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;
-+              u16 *bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr;
-+
-+              cpu_to_apicid[cpu] = m->mpc_apicid;
-+              bios_cpu_apicid[cpu] = m->mpc_apicid;
-       } else {
-               per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
-+              per_cpu(x86_bios_cpu_apicid, cpu) = m->mpc_apicid;
-       }
-       cpu_set(cpu, cpu_possible_map);
---- a/arch/x86/kernel/pci-dma-xen.c
-+++ b/arch/x86/kernel/pci-dma-xen.c
-@@ -434,3 +434,23 @@ dma_sync_single_for_device(struct device
-               swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
- }
- EXPORT_SYMBOL(dma_sync_single_for_device);
-+
-+void
-+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-+                  enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
-+      flush_write_buffers();
-+}
-+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-+
-+void
-+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-+                  enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
-+      flush_write_buffers();
-+}
-+EXPORT_SYMBOL(dma_sync_sg_for_device);
---- a/arch/x86/kernel/process_32-xen.c
-+++ b/arch/x86/kernel/process_32-xen.c
-@@ -23,7 +23,6 @@
- #include <linux/slab.h>
- #include <linux/vmalloc.h>
- #include <linux/user.h>
--#include <linux/a.out.h>
- #include <linux/interrupt.h>
- #include <linux/utsname.h>
- #include <linux/delay.h>
-@@ -59,8 +58,10 @@
- #include <asm/tlbflush.h>
- #include <asm/cpu.h>
-+#include <asm/kdebug.h>
- asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
-+asmlinkage void cstar_ret_from_fork(void) __asm__("cstar_ret_from_fork");
- static int hlt_counter;
-@@ -78,7 +79,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
-  */
- unsigned long thread_saved_pc(struct task_struct *tsk)
- {
--      return ((unsigned long *)tsk->thread.esp)[3];
-+      return ((unsigned long *)tsk->thread.sp)[3];
- }
- /*
-@@ -86,7 +87,6 @@ unsigned long thread_saved_pc(struct tas
-  */
- void (*pm_idle)(void);
- EXPORT_SYMBOL(pm_idle);
--static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
- void disable_hlt(void)
- {
-@@ -107,7 +107,7 @@ EXPORT_SYMBOL(enable_hlt);
-  * to poll the ->work.need_resched flag instead of waiting for the
-  * cross-CPU IPI to arrive. Use this option with caution.
-  */
--static void poll_idle (void)
-+static void poll_idle(void)
- {
-       cpu_relax();
- }
-@@ -122,10 +122,19 @@ static void xen_idle(void)
-       smp_mb();
-       local_irq_disable();
--      if (!need_resched())
-+      if (!need_resched()) {
-+              ktime_t t0, t1;
-+              u64 t0n, t1n;
-+
-+              t0 = ktime_get();
-+              t0n = ktime_to_ns(t0);
-               safe_halt();    /* enables interrupts racelessly */
--      else
--              local_irq_enable();
-+              local_irq_disable();
-+              t1 = ktime_get();
-+              t1n = ktime_to_ns(t1);
-+              sched_clock_idle_wakeup_event(t1n - t0n);
-+      }
-+      local_irq_enable();
-       current_thread_info()->status |= TS_POLLING;
- }
- #ifdef CONFIG_APM_MODULE
-@@ -168,13 +177,13 @@ void cpu_idle(void)
-               while (!need_resched()) {
-                       void (*idle)(void);
--                      if (__get_cpu_var(cpu_idle_state))
--                              __get_cpu_var(cpu_idle_state) = 0;
--
-                       check_pgt_cache();
-                       rmb();
-                       idle = xen_idle; /* no alternatives */
-+                      if (rcu_pending(cpu))
-+                              rcu_check_callbacks(cpu, 0);
-+
-                       if (cpu_is_offline(cpu))
-                               play_dead();
-@@ -192,40 +201,19 @@ static void do_nothing(void *unused)
- {
- }
-+/*
-+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
-+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
-+ * handler on SMP systems.
-+ *
-+ * Caller must have changed pm_idle to the new value before the call. Old
-+ * pm_idle value will not be used by any CPU after the return of this function.
-+ */
- void cpu_idle_wait(void)
- {
--      unsigned int cpu, this_cpu = get_cpu();
--      cpumask_t map, tmp = current->cpus_allowed;
--
--      set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
--      put_cpu();
--
--      cpus_clear(map);
--      for_each_online_cpu(cpu) {
--              per_cpu(cpu_idle_state, cpu) = 1;
--              cpu_set(cpu, map);
--      }
--
--      __get_cpu_var(cpu_idle_state) = 0;
--
--      wmb();
--      do {
--              ssleep(1);
--              for_each_online_cpu(cpu) {
--                      if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
--                              cpu_clear(cpu, map);
--              }
--              cpus_and(map, map, cpu_online_map);
--              /*
--               * We waited 1 sec, if a CPU still did not call idle
--               * it may be because it is in idle and not waking up
--               * because it has nothing to do.
--               * Give all the remaining CPUS a kick.
--               */
--              smp_call_function_mask(map, do_nothing, 0, 0);
--      } while (!cpus_empty(map));
--
--      set_cpus_allowed(current, tmp);
-+      smp_mb();
-+      /* kick all the CPUs so that they exit out of pm_idle */
-+      smp_call_function(do_nothing, NULL, 0, 1);
- }
- EXPORT_SYMBOL_GPL(cpu_idle_wait);
-@@ -251,15 +239,15 @@ void __show_registers(struct pt_regs *re
- {
-       unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
-       unsigned long d0, d1, d2, d3, d6, d7;
--      unsigned long esp;
-+      unsigned long sp;
-       unsigned short ss, gs;
-       if (user_mode_vm(regs)) {
--              esp = regs->esp;
--              ss = regs->xss & 0xffff;
-+              sp = regs->sp;
-+              ss = regs->ss & 0xffff;
-               savesegment(gs, gs);
-       } else {
--              esp = (unsigned long) (&regs->esp);
-+              sp = (unsigned long) (&regs->sp);
-               savesegment(ss, ss);
-               savesegment(gs, gs);
-       }
-@@ -272,17 +260,17 @@ void __show_registers(struct pt_regs *re
-                       init_utsname()->version);
-       printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
--                      0xffff & regs->xcs, regs->eip, regs->eflags,
-+                      0xffff & regs->cs, regs->ip, regs->flags,
-                       smp_processor_id());
--      print_symbol("EIP is at %s\n", regs->eip);
-+      print_symbol("EIP is at %s\n", regs->ip);
-       printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
--              regs->eax, regs->ebx, regs->ecx, regs->edx);
-+              regs->ax, regs->bx, regs->cx, regs->dx);
-       printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
--              regs->esi, regs->edi, regs->ebp, esp);
-+              regs->si, regs->di, regs->bp, sp);
-       printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
--             regs->xds & 0xffff, regs->xes & 0xffff,
--             regs->xfs & 0xffff, gs, ss);
-+             regs->ds & 0xffff, regs->es & 0xffff,
-+             regs->fs & 0xffff, gs, ss);
-       if (!all)
-               return;
-@@ -310,12 +298,12 @@ void __show_registers(struct pt_regs *re
- void show_regs(struct pt_regs *regs)
- {
-       __show_registers(regs, 1);
--      show_trace(NULL, regs, &regs->esp);
-+      show_trace(NULL, regs, &regs->sp, regs->bp);
- }
- /*
-- * This gets run with %ebx containing the
-- * function to call, and %edx containing
-+ * This gets run with %bx containing the
-+ * function to call, and %dx containing
-  * the "args".
-  */
- extern void kernel_thread_helper(void);
-@@ -329,16 +317,16 @@ int kernel_thread(int (*fn)(void *), voi
-       memset(&regs, 0, sizeof(regs));
--      regs.ebx = (unsigned long) fn;
--      regs.edx = (unsigned long) arg;
-+      regs.bx = (unsigned long) fn;
-+      regs.dx = (unsigned long) arg;
--      regs.xds = __USER_DS;
--      regs.xes = __USER_DS;
--      regs.xfs = __KERNEL_PERCPU;
--      regs.orig_eax = -1;
--      regs.eip = (unsigned long) kernel_thread_helper;
--      regs.xcs = __KERNEL_CS | get_kernel_rpl();
--      regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
-+      regs.ds = __USER_DS;
-+      regs.es = __USER_DS;
-+      regs.fs = __KERNEL_PERCPU;
-+      regs.orig_ax = -1;
-+      regs.ip = (unsigned long) kernel_thread_helper;
-+      regs.cs = __KERNEL_CS | get_kernel_rpl();
-+      regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-@@ -368,7 +356,12 @@ void flush_thread(void)
- {
-       struct task_struct *tsk = current;
--      memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
-+      tsk->thread.debugreg0 = 0;
-+      tsk->thread.debugreg1 = 0;
-+      tsk->thread.debugreg2 = 0;
-+      tsk->thread.debugreg3 = 0;
-+      tsk->thread.debugreg6 = 0;
-+      tsk->thread.debugreg7 = 0;
-       memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
-       clear_tsk_thread_flag(tsk, TIF_DEBUG);
-       /*
-@@ -393,7 +386,7 @@ void prepare_to_copy(struct task_struct 
-       unlazy_fpu(tsk);
- }
--int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
-+int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
-       unsigned long unused,
-       struct task_struct * p, struct pt_regs * regs)
- {
-@@ -403,17 +396,19 @@ int copy_thread(int nr, unsigned long cl
-       childregs = task_pt_regs(p);
-       *childregs = *regs;
--      childregs->eax = 0;
--      childregs->esp = esp;
-+      childregs->ax = 0;
-+      childregs->sp = sp;
--      p->thread.esp = (unsigned long) childregs;
--      p->thread.esp0 = (unsigned long) (childregs+1);
-+      p->thread.sp = (unsigned long) childregs;
-+      p->thread.sp0 = (unsigned long) (childregs+1);
--      p->thread.eip = (unsigned long) ret_from_fork;
-+      p->thread.ip = (unsigned long) ret_from_fork;
--      savesegment(gs,p->thread.gs);
-+      savesegment(gs, p->thread.gs);
-       tsk = current;
-+      if (test_tsk_thread_flag(tsk, TIF_CSTAR))
-+              p->thread.ip = (unsigned long) cstar_ret_from_fork;
-       if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
-               p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
-                                               IO_BITMAP_BYTES, GFP_KERNEL);
-@@ -424,34 +419,17 @@ int copy_thread(int nr, unsigned long cl
-               set_tsk_thread_flag(p, TIF_IO_BITMAP);
-       }
-+      err = 0;
-+
-       /*
-        * Set a new TLS for the child thread?
-        */
--      if (clone_flags & CLONE_SETTLS) {
--              struct desc_struct *desc;
--              struct user_desc info;
--              int idx;
--
--              err = -EFAULT;
--              if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
--                      goto out;
--              err = -EINVAL;
--              if (LDT_empty(&info))
--                      goto out;
--
--              idx = info.entry_number;
--              if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
--                      goto out;
--
--              desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
--              desc->a = LDT_entry_a(&info);
--              desc->b = LDT_entry_b(&info);
--      }
-+      if (clone_flags & CLONE_SETTLS)
-+              err = do_set_thread_area(p, -1,
-+                      (struct user_desc __user *)childregs->si, 0);
-       p->thread.iopl = current->thread.iopl;
--      err = 0;
-- out:
-       if (err && p->thread.io_bitmap_ptr) {
-               kfree(p->thread.io_bitmap_ptr);
-               p->thread.io_bitmap_max = 0;
-@@ -459,67 +437,8 @@ int copy_thread(int nr, unsigned long cl
-       return err;
- }
--/*
-- * fill in the user structure for a core dump..
-- */
--void dump_thread(struct pt_regs * regs, struct user * dump)
--{
--      int i;
--
--/* changed the size calculations - should hopefully work better. lbt */
--      dump->magic = CMAGIC;
--      dump->start_code = 0;
--      dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
--      dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
--      dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
--      dump->u_dsize -= dump->u_tsize;
--      dump->u_ssize = 0;
--      for (i = 0; i < 8; i++)
--              dump->u_debugreg[i] = current->thread.debugreg[i];  
--
--      if (dump->start_stack < TASK_SIZE)
--              dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
--
--      dump->regs.ebx = regs->ebx;
--      dump->regs.ecx = regs->ecx;
--      dump->regs.edx = regs->edx;
--      dump->regs.esi = regs->esi;
--      dump->regs.edi = regs->edi;
--      dump->regs.ebp = regs->ebp;
--      dump->regs.eax = regs->eax;
--      dump->regs.ds = regs->xds;
--      dump->regs.es = regs->xes;
--      dump->regs.fs = regs->xfs;
--      savesegment(gs,dump->regs.gs);
--      dump->regs.orig_eax = regs->orig_eax;
--      dump->regs.eip = regs->eip;
--      dump->regs.cs = regs->xcs;
--      dump->regs.eflags = regs->eflags;
--      dump->regs.esp = regs->esp;
--      dump->regs.ss = regs->xss;
--
--      dump->u_fpvalid = dump_fpu (regs, &dump->i387);
--}
--EXPORT_SYMBOL(dump_thread);
--
--/* 
-- * Capture the user space registers if the task is not running (in user space)
-- */
--int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
--{
--      struct pt_regs ptregs = *task_pt_regs(tsk);
--      ptregs.xcs &= 0xffff;
--      ptregs.xds &= 0xffff;
--      ptregs.xes &= 0xffff;
--      ptregs.xss &= 0xffff;
--
--      elf_core_copy_regs(regs, &ptregs);
--
--      return 1;
--}
--
- #ifdef CONFIG_SECCOMP
--void hard_disable_TSC(void)
-+static void hard_disable_TSC(void)
- {
-       write_cr4(read_cr4() | X86_CR4_TSD);
- }
-@@ -534,7 +453,7 @@ void disable_TSC(void)
-               hard_disable_TSC();
-       preempt_enable();
- }
--void hard_enable_TSC(void)
-+static void hard_enable_TSC(void)
- {
-       write_cr4(read_cr4() & ~X86_CR4_TSD);
- }
-@@ -543,18 +462,32 @@ void hard_enable_TSC(void)
- static noinline void
- __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
- {
--      struct thread_struct *next;
-+      struct thread_struct *prev, *next;
-+      unsigned long debugctl;
-+      prev = &prev_p->thread;
-       next = &next_p->thread;
-+      debugctl = prev->debugctlmsr;
-+      if (next->ds_area_msr != prev->ds_area_msr) {
-+              /* we clear debugctl to make sure DS
-+               * is not in use when we change it */
-+              debugctl = 0;
-+              wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
-+              wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
-+      }
-+
-+      if (next->debugctlmsr != debugctl)
-+              wrmsr(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr, 0);
-+
-       if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
--              set_debugreg(next->debugreg[0], 0);
--              set_debugreg(next->debugreg[1], 1);
--              set_debugreg(next->debugreg[2], 2);
--              set_debugreg(next->debugreg[3], 3);
-+              set_debugreg(next->debugreg0, 0);
-+              set_debugreg(next->debugreg1, 1);
-+              set_debugreg(next->debugreg2, 2);
-+              set_debugreg(next->debugreg3, 3);
-               /* no 4 and 5 */
--              set_debugreg(next->debugreg[6], 6);
--              set_debugreg(next->debugreg[7], 7);
-+              set_debugreg(next->debugreg6, 6);
-+              set_debugreg(next->debugreg7, 7);
-       }
- #ifdef CONFIG_SECCOMP
-@@ -567,6 +500,14 @@ __switch_to_xtra(struct task_struct *pre
-                       hard_enable_TSC();
-       }
- #endif
-+
-+#ifdef X86_BTS
-+      if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
-+              ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
-+
-+      if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
-+              ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
-+#endif
- }
- /*
-@@ -592,11 +533,11 @@ __switch_to_xtra(struct task_struct *pre
-  * More important, however, is the fact that this allows us much
-  * more flexibility.
-  *
-- * The return value (in %eax) will be the "prev" task after
-+ * The return value (in %ax) will be the "prev" task after
-  * the task-switch, and shows up in ret_from_fork in entry.S,
-  * for example.
-  */
--struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
-+struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
- {
-       struct thread_struct *prev = &prev_p->thread,
-                                *next = &next_p->thread;
-@@ -632,12 +573,12 @@ struct task_struct fastcall * __switch_t
- #endif
-       /*
--       * Reload esp0.
--       * This is load_esp0(tss, next) with a multicall.
-+       * Reload sp0.
-+       * This is load_sp0(tss, next) with a multicall.
-        */
-       mcl->op      = __HYPERVISOR_stack_switch;
-       mcl->args[0] = __KERNEL_DS;
--      mcl->args[1] = next->esp0;
-+      mcl->args[1] = next->sp0;
-       mcl++;
-       /*
-@@ -734,7 +675,7 @@ struct task_struct fastcall * __switch_t
- asmlinkage int sys_fork(struct pt_regs regs)
- {
--      return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
-+      return do_fork(SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
- }
- asmlinkage int sys_clone(struct pt_regs regs)
-@@ -743,12 +684,12 @@ asmlinkage int sys_clone(struct pt_regs 
-       unsigned long newsp;
-       int __user *parent_tidptr, *child_tidptr;
--      clone_flags = regs.ebx;
--      newsp = regs.ecx;
--      parent_tidptr = (int __user *)regs.edx;
--      child_tidptr = (int __user *)regs.edi;
-+      clone_flags = regs.bx;
-+      newsp = regs.cx;
-+      parent_tidptr = (int __user *)regs.dx;
-+      child_tidptr = (int __user *)regs.di;
-       if (!newsp)
--              newsp = regs.esp;
-+              newsp = regs.sp;
-       return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
- }
-@@ -764,7 +705,7 @@ asmlinkage int sys_clone(struct pt_regs 
-  */
- asmlinkage int sys_vfork(struct pt_regs regs)
- {
--      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
-+      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
- }
- /*
-@@ -775,18 +716,15 @@ asmlinkage int sys_execve(struct pt_regs
-       int error;
-       char * filename;
--      filename = getname((char __user *) regs.ebx);
-+      filename = getname((char __user *) regs.bx);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       error = do_execve(filename,
--                      (char __user * __user *) regs.ecx,
--                      (char __user * __user *) regs.edx,
-+                      (char __user * __user *) regs.cx,
-+                      (char __user * __user *) regs.dx,
-                       &regs);
-       if (error == 0) {
--              task_lock(current);
--              current->ptrace &= ~PT_DTRACE;
--              task_unlock(current);
-               /* Make sure we don't return using sysenter.. */
-               set_thread_flag(TIF_IRET);
-       }
-@@ -800,145 +738,37 @@ out:
- unsigned long get_wchan(struct task_struct *p)
- {
--      unsigned long ebp, esp, eip;
-+      unsigned long bp, sp, ip;
-       unsigned long stack_page;
-       int count = 0;
-       if (!p || p == current || p->state == TASK_RUNNING)
-               return 0;
-       stack_page = (unsigned long)task_stack_page(p);
--      esp = p->thread.esp;
--      if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
-+      sp = p->thread.sp;
-+      if (!stack_page || sp < stack_page || sp > top_esp+stack_page)
-               return 0;
--      /* include/asm-i386/system.h:switch_to() pushes ebp last. */
--      ebp = *(unsigned long *) esp;
-+      /* include/asm-i386/system.h:switch_to() pushes bp last. */
-+      bp = *(unsigned long *) sp;
-       do {
--              if (ebp < stack_page || ebp > top_ebp+stack_page)
-+              if (bp < stack_page || bp > top_ebp+stack_page)
-                       return 0;
--              eip = *(unsigned long *) (ebp+4);
--              if (!in_sched_functions(eip))
--                      return eip;
--              ebp = *(unsigned long *) ebp;
-+              ip = *(unsigned long *) (bp+4);
-+              if (!in_sched_functions(ip))
-+                      return ip;
-+              bp = *(unsigned long *) bp;
-       } while (count++ < 16);
-       return 0;
- }
--/*
-- * sys_alloc_thread_area: get a yet unused TLS descriptor index.
-- */
--static int get_free_idx(void)
--{
--      struct thread_struct *t = &current->thread;
--      int idx;
--
--      for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
--              if (desc_empty(t->tls_array + idx))
--                      return idx + GDT_ENTRY_TLS_MIN;
--      return -ESRCH;
--}
--
--/*
-- * Set a given TLS descriptor:
-- */
--asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
--{
--      struct thread_struct *t = &current->thread;
--      struct user_desc info;
--      struct desc_struct *desc;
--      int cpu, idx;
--
--      if (copy_from_user(&info, u_info, sizeof(info)))
--              return -EFAULT;
--      idx = info.entry_number;
--
--      /*
--       * index -1 means the kernel should try to find and
--       * allocate an empty descriptor:
--       */
--      if (idx == -1) {
--              idx = get_free_idx();
--              if (idx < 0)
--                      return idx;
--              if (put_user(idx, &u_info->entry_number))
--                      return -EFAULT;
--      }
--
--      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
--              return -EINVAL;
--
--      desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
--
--      /*
--       * We must not get preempted while modifying the TLS.
--       */
--      cpu = get_cpu();
--
--      if (LDT_empty(&info)) {
--              desc->a = 0;
--              desc->b = 0;
--      } else {
--              desc->a = LDT_entry_a(&info);
--              desc->b = LDT_entry_b(&info);
--      }
--      load_TLS(t, cpu);
--
--      put_cpu();
--
--      return 0;
--}
--
--/*
-- * Get the current Thread-Local Storage area:
-- */
--
--#define GET_BASE(desc) ( \
--      (((desc)->a >> 16) & 0x0000ffff) | \
--      (((desc)->b << 16) & 0x00ff0000) | \
--      ( (desc)->b        & 0xff000000)   )
--
--#define GET_LIMIT(desc) ( \
--      ((desc)->a & 0x0ffff) | \
--       ((desc)->b & 0xf0000) )
--      
--#define GET_32BIT(desc)               (((desc)->b >> 22) & 1)
--#define GET_CONTENTS(desc)    (((desc)->b >> 10) & 3)
--#define GET_WRITABLE(desc)    (((desc)->b >>  9) & 1)
--#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
--#define GET_PRESENT(desc)     (((desc)->b >> 15) & 1)
--#define GET_USEABLE(desc)     (((desc)->b >> 20) & 1)
--
--asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
--{
--      struct user_desc info;
--      struct desc_struct *desc;
--      int idx;
--
--      if (get_user(idx, &u_info->entry_number))
--              return -EFAULT;
--      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
--              return -EINVAL;
--
--      memset(&info, 0, sizeof(info));
--
--      desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
--
--      info.entry_number = idx;
--      info.base_addr = GET_BASE(desc);
--      info.limit = GET_LIMIT(desc);
--      info.seg_32bit = GET_32BIT(desc);
--      info.contents = GET_CONTENTS(desc);
--      info.read_exec_only = !GET_WRITABLE(desc);
--      info.limit_in_pages = GET_LIMIT_PAGES(desc);
--      info.seg_not_present = !GET_PRESENT(desc);
--      info.useable = GET_USEABLE(desc);
--
--      if (copy_to_user(u_info, &info, sizeof(info)))
--              return -EFAULT;
--      return 0;
--}
--
- unsigned long arch_align_stack(unsigned long sp)
- {
-       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
-               sp -= get_random_int() % 8192;
-       return sp & ~0xf;
- }
-+
-+unsigned long arch_randomize_brk(struct mm_struct *mm)
-+{
-+      unsigned long range_end = mm->brk + 0x02000000;
-+      return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
-+}
---- a/arch/x86/kernel/process_64-xen.c
-+++ b/arch/x86/kernel/process_64-xen.c
-@@ -3,7 +3,7 @@
-  *
-  *  Pentium III FXSR, SSE support
-  *    Gareth Hughes <gareth@valinux.com>, May 2000
-- * 
-+ *
-  *  X86-64 port
-  *    Andi Kleen.
-  *
-@@ -22,19 +22,18 @@
- #include <linux/cpu.h>
- #include <linux/errno.h>
- #include <linux/sched.h>
-+#include <linux/fs.h>
- #include <linux/kernel.h>
- #include <linux/mm.h>
--#include <linux/fs.h>
- #include <linux/elfcore.h>
- #include <linux/smp.h>
- #include <linux/slab.h>
- #include <linux/user.h>
--#include <linux/module.h>
--#include <linux/a.out.h>
- #include <linux/interrupt.h>
-+#include <linux/utsname.h>
- #include <linux/delay.h>
-+#include <linux/module.h>
- #include <linux/ptrace.h>
--#include <linux/utsname.h>
- #include <linux/random.h>
- #include <linux/notifier.h>
- #include <linux/kprobes.h>
-@@ -73,7 +72,6 @@ EXPORT_SYMBOL(boot_option_idle_override)
-  */
- void (*pm_idle)(void);
- EXPORT_SYMBOL(pm_idle);
--static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
- static ATOMIC_NOTIFIER_HEAD(idle_notifier);
-@@ -81,13 +79,6 @@ void idle_notifier_register(struct notif
- {
-       atomic_notifier_chain_register(&idle_notifier, n);
- }
--EXPORT_SYMBOL_GPL(idle_notifier_register);
--
--void idle_notifier_unregister(struct notifier_block *n)
--{
--      atomic_notifier_chain_unregister(&idle_notifier, n);
--}
--EXPORT_SYMBOL(idle_notifier_unregister);
- void enter_idle(void)
- {
-@@ -116,7 +107,7 @@ void exit_idle(void)
-  * to poll the ->need_resched flag instead of waiting for the
-  * cross-CPU IPI to arrive. Use this option with caution.
-  */
--static void poll_idle (void)
-+static void poll_idle(void)
- {
-       local_irq_enable();
-       cpu_relax();
-@@ -131,10 +122,19 @@ static void xen_idle(void)
-        */
-       smp_mb();
-       local_irq_disable();
--      if (!need_resched())
--              safe_halt();
--      else
--              local_irq_enable();
-+      if (!need_resched()) {
-+              ktime_t t0, t1;
-+              u64 t0n, t1n;
-+
-+              t0 = ktime_get();
-+              t0n = ktime_to_ns(t0);
-+              safe_halt();    /* enables interrupts racelessly */
-+              local_irq_disable();
-+              t1 = ktime_get();
-+              t1n = ktime_to_ns(t1);
-+              sched_clock_idle_wakeup_event(t1n - t0n);
-+      }
-+      local_irq_enable();
-       current_thread_info()->status |= TS_POLLING;
- }
-@@ -161,19 +161,15 @@ static inline void play_dead(void)
-  * low exit latency (ie sit in a loop waiting for
-  * somebody to say that they'd like to reschedule)
-  */
--void cpu_idle (void)
-+void cpu_idle(void)
- {
-       current_thread_info()->status |= TS_POLLING;
-       /* endless idle loop with no priority at all */
-       while (1) {
-+              tick_nohz_stop_sched_tick();
-               while (!need_resched()) {
-                       void (*idle)(void);
--                      if (__get_cpu_var(cpu_idle_state))
--                              __get_cpu_var(cpu_idle_state) = 0;
--
--                      tick_nohz_stop_sched_tick();
--
-                       rmb();
-                       idle = xen_idle; /* no alternatives */
-                       if (cpu_is_offline(smp_processor_id()))
-@@ -203,49 +199,27 @@ static void do_nothing(void *unused)
- {
- }
-+/*
-+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
-+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
-+ * handler on SMP systems.
-+ *
-+ * Caller must have changed pm_idle to the new value before the call. Old
-+ * pm_idle value will not be used by any CPU after the return of this function.
-+ */
- void cpu_idle_wait(void)
- {
--      unsigned int cpu, this_cpu = get_cpu();
--      cpumask_t map, tmp = current->cpus_allowed;
--
--      set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
--      put_cpu();
--
--      cpus_clear(map);
--      for_each_online_cpu(cpu) {
--              per_cpu(cpu_idle_state, cpu) = 1;
--              cpu_set(cpu, map);
--      }
--
--      __get_cpu_var(cpu_idle_state) = 0;
--
--      wmb();
--      do {
--              ssleep(1);
--              for_each_online_cpu(cpu) {
--                      if (cpu_isset(cpu, map) &&
--                                      !per_cpu(cpu_idle_state, cpu))
--                              cpu_clear(cpu, map);
--              }
--              cpus_and(map, map, cpu_online_map);
--              /*
--               * We waited 1 sec, if a CPU still did not call idle
--               * it may be because it is in idle and not waking up
--               * because it has nothing to do.
--               * Give all the remaining CPUS a kick.
--               */
--              smp_call_function_mask(map, do_nothing, 0, 0);
--      } while (!cpus_empty(map));
--
--      set_cpus_allowed(current, tmp);
-+      smp_mb();
-+      /* kick all the CPUs so that they exit out of pm_idle */
-+      smp_call_function(do_nothing, NULL, 0, 1);
- }
- EXPORT_SYMBOL_GPL(cpu_idle_wait);
--void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 
-+void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
- {
- }
--static int __init idle_setup (char *str)
-+static int __init idle_setup(char *str)
- {
-       if (!strcmp(str, "poll")) {
-               printk("using polling idle threads.\n");
-@@ -260,13 +234,13 @@ static int __init idle_setup (char *str)
- }
- early_param("idle", idle_setup);
--/* Prints also some state that isn't saved in the pt_regs */ 
-+/* Prints also some state that isn't saved in the pt_regs */
- void __show_regs(struct pt_regs * regs)
- {
-       unsigned long fs, gs, shadowgs;
-       unsigned long d0, d1, d2, d3, d6, d7;
--      unsigned int fsindex,gsindex;
--      unsigned int ds,cs,es; 
-+      unsigned int fsindex, gsindex;
-+      unsigned int ds, cs, es;
-       printk("\n");
-       print_modules();
-@@ -275,16 +249,16 @@ void __show_regs(struct pt_regs * regs)
-               init_utsname()->release,
-               (int)strcspn(init_utsname()->version, " "),
-               init_utsname()->version);
--      printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
--      printk_address(regs->rip); 
--      printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
--              regs->eflags);
-+      printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
-+      printk_address(regs->ip, 1);
-+      printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->sp,
-+              regs->flags);
-       printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
--             regs->rax, regs->rbx, regs->rcx);
-+             regs->ax, regs->bx, regs->cx);
-       printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
--             regs->rdx, regs->rsi, regs->rdi); 
-+             regs->dx, regs->si, regs->di);
-       printk("RBP: %016lx R08: %016lx R09: %016lx\n",
--             regs->rbp, regs->r8, regs->r9); 
-+             regs->bp, regs->r8, regs->r9);
-       printk("R10: %016lx R11: %016lx R12: %016lx\n",
-              regs->r10, regs->r11, regs->r12); 
-       printk("R13: %016lx R14: %016lx R15: %016lx\n",
-@@ -318,7 +292,7 @@ void show_regs(struct pt_regs *regs)
- {
-       printk("CPU %d:", smp_processor_id());
-       __show_regs(regs);
--      show_trace(NULL, regs, (void *)(regs + 1));
-+      show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
- }
- /*
-@@ -329,7 +303,7 @@ void exit_thread(void)
-       struct task_struct *me = current;
-       struct thread_struct *t = &me->thread;
--      if (me->thread.io_bitmap_ptr) { 
-+      if (me->thread.io_bitmap_ptr) {
- #ifndef CONFIG_X86_NO_TSS
-               struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
- #endif
-@@ -382,7 +356,7 @@ void flush_thread(void)
-       tsk->thread.debugreg3 = 0;
-       tsk->thread.debugreg6 = 0;
-       tsk->thread.debugreg7 = 0;
--      memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
-+      memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
-       /*
-        * Forget coprocessor state..
-        */
-@@ -405,26 +379,21 @@ void release_thread(struct task_struct *
- static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
- {
--      struct user_desc ud = { 
-+      struct user_desc ud = {
-               .base_addr = addr,
-               .limit = 0xfffff,
-               .seg_32bit = 1,
-               .limit_in_pages = 1,
-               .useable = 1,
-       };
--      struct n_desc_struct *desc = (void *)t->thread.tls_array;
-+      struct desc_struct *desc = t->thread.tls_array;
-       desc += tls;
--      desc->a = LDT_entry_a(&ud); 
--      desc->b = LDT_entry_b(&ud); 
-+      fill_ldt(desc, &ud);
- }
- static inline u32 read_32bit_tls(struct task_struct *t, int tls)
- {
--      struct desc_struct *desc = (void *)t->thread.tls_array;
--      desc += tls;
--      return desc->base0 | 
--              (((u32)desc->base1) << 16) | 
--              (((u32)desc->base2) << 24);
-+      return get_desc_base(&t->thread.tls_array[tls]);
- }
- /*
-@@ -436,7 +405,7 @@ void prepare_to_copy(struct task_struct 
-       unlazy_fpu(tsk);
- }
--int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, 
-+int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
-               unsigned long unused,
-       struct task_struct * p, struct pt_regs * regs)
- {
-@@ -448,14 +417,14 @@ int copy_thread(int nr, unsigned long cl
-                       (THREAD_SIZE + task_stack_page(p))) - 1;
-       *childregs = *regs;
--      childregs->rax = 0;
--      childregs->rsp = rsp;
--      if (rsp == ~0UL)
--              childregs->rsp = (unsigned long)childregs;
--
--      p->thread.rsp = (unsigned long) childregs;
--      p->thread.rsp0 = (unsigned long) (childregs+1);
--      p->thread.userrsp = me->thread.userrsp; 
-+      childregs->ax = 0;
-+      childregs->sp = sp;
-+      if (sp == ~0UL)
-+              childregs->sp = (unsigned long)childregs;
-+
-+      p->thread.sp = (unsigned long) childregs;
-+      p->thread.sp0 = (unsigned long) (childregs+1);
-+      p->thread.usersp = me->thread.usersp;
-       set_tsk_thread_flag(p, TIF_FORK);
-@@ -476,7 +445,7 @@ int copy_thread(int nr, unsigned long cl
-               memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
-                               IO_BITMAP_BYTES);
-               set_tsk_thread_flag(p, TIF_IO_BITMAP);
--      } 
-+      }
-       /*
-        * Set a new TLS for the child thread?
-@@ -484,7 +453,8 @@ int copy_thread(int nr, unsigned long cl
-       if (clone_flags & CLONE_SETTLS) {
- #ifdef CONFIG_IA32_EMULATION
-               if (test_thread_flag(TIF_IA32))
--                      err = ia32_child_tls(p, childregs); 
-+                      err = do_set_thread_area(p, -1,
-+                              (struct user_desc __user *)childregs->si, 0);
-               else                    
- #endif         
-                       err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 
-@@ -502,26 +472,32 @@ out:
-       return err;
- }
--static inline void __save_init_fpu( struct task_struct *tsk )
--{
--      asm volatile( "rex64 ; fxsave %0 ; fnclex"
--                    : "=m" (tsk->thread.i387.fxsave));
--      tsk->thread_info->status &= ~TS_USEDFPU;
--}
--
- /*
-  * This special macro can be used to load a debugging register
-  */
--#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r)
-+#define loaddebug(thread, r) set_debugreg(thread->debugreg ## r, r)
- static inline void __switch_to_xtra(struct task_struct *prev_p,
--                                  struct task_struct *next_p)
-+                                  struct task_struct *next_p)
- {
-       struct thread_struct *prev, *next;
-+      unsigned long debugctl;
-       prev = &prev_p->thread,
-       next = &next_p->thread;
-+      debugctl = prev->debugctlmsr;
-+      if (next->ds_area_msr != prev->ds_area_msr) {
-+              /* we clear debugctl to make sure DS
-+               * is not in use when we change it */
-+              debugctl = 0;
-+              wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
-+              wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr);
-+      }
-+
-+      if (next->debugctlmsr != debugctl)
-+              wrmsrl(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr);
-+
-       if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
-               loaddebug(next, 0);
-               loaddebug(next, 1);
-@@ -531,12 +507,20 @@ static inline void __switch_to_xtra(stru
-               loaddebug(next, 6);
-               loaddebug(next, 7);
-       }
-+
-+#ifdef X86_BTS
-+      if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
-+              ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
-+
-+      if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
-+              ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
-+#endif
- }
- /*
-  *    switch_to(x,y) should switch tasks from x to y.
-  *
-- * This could still be optimized: 
-+ * This could still be optimized:
-  * - fold all the options into a flag word and test it with a single test.
-  * - could test fs/gs bitsliced
-  *
-@@ -547,7 +531,7 @@ __switch_to(struct task_struct *prev_p, 
- {
-       struct thread_struct *prev = &prev_p->thread,
-                                *next = &next_p->thread;
--      int cpu = smp_processor_id();  
-+      int cpu = smp_processor_id();
- #ifndef CONFIG_X86_NO_TSS
-       struct tss_struct *tss = &per_cpu(init_tss, cpu);
- #endif
-@@ -581,11 +565,12 @@ __switch_to(struct task_struct *prev_p, 
-               prev_p->fpu_counter = 0;
-       /*
--       * Reload esp0, LDT and the page table pointer:
-+       * Reload sp0.
-+       * This is load_sp0(tss, next) with a multicall.
-        */
-       mcl->op      = __HYPERVISOR_stack_switch;
-       mcl->args[0] = __KERNEL_DS;
--      mcl->args[1] = next->rsp0;
-+      mcl->args[1] = next->sp0;
-       mcl++;
-       /*
-@@ -593,11 +578,12 @@ __switch_to(struct task_struct *prev_p, 
-        * This is load_TLS(next, cpu) with multicalls.
-        */
- #define C(i) do {                                                     \
--      if (unlikely(next->tls_array[i] != prev->tls_array[i])) {       \
-+      if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||    \
-+                   next->tls_array[i].b != prev->tls_array[i].b)) {   \
-               mcl->op      = __HYPERVISOR_update_descriptor;          \
-               mcl->args[0] = virt_to_machine(                         \
--                      &cpu_gdt(cpu)[GDT_ENTRY_TLS_MIN + i]);          \
--              mcl->args[1] = next->tls_array[i];                      \
-+                      &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\
-+              mcl->args[1] = *(u64 *)&next->tls_array[i];             \
-               mcl++;                                                  \
-       }                                                               \
- } while (0)
-@@ -605,7 +591,7 @@ __switch_to(struct task_struct *prev_p, 
- #undef C
-       if (unlikely(prev->iopl != next->iopl)) {
--              iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
-+              iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
- #if CONFIG_XEN_COMPAT > 0x030002
-               mcl->op      = __HYPERVISOR_physdev_op;
-               mcl->args[0] = PHYSDEVOP_set_iopl;
-@@ -669,8 +655,8 @@ __switch_to(struct task_struct *prev_p, 
-       /* 
-        * Switch the PDA context.
-        */
--      prev->userrsp = read_pda(oldrsp); 
--      write_pda(oldrsp, next->userrsp); 
-+      prev->usersp = read_pda(oldrsp);
-+      write_pda(oldrsp, next->usersp);
-       write_pda(pcurrent, next_p); 
-       write_pda(kernelstack,
-       (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
-@@ -687,7 +673,8 @@ __switch_to(struct task_struct *prev_p, 
-       /*
-        * Now maybe reload the debug registers
-        */
--      if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW))
-+      if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT ||
-+                   task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
-               __switch_to_xtra(prev_p, next_p);
-       /* If the task has used fpu the last 5 timeslices, just do a full
-@@ -702,23 +689,18 @@ __switch_to(struct task_struct *prev_p, 
- /*
-  * sys_execve() executes a new program.
-  */
--asmlinkage 
-+asmlinkage
- long sys_execve(char __user *name, char __user * __user *argv,
--              char __user * __user *envp, struct pt_regs regs)
-+              char __user * __user *envp, struct pt_regs *regs)
- {
-       long error;
-       char * filename;
-       filename = getname(name);
-       error = PTR_ERR(filename);
--      if (IS_ERR(filename)) 
-+      if (IS_ERR(filename))
-               return error;
--      error = do_execve(filename, argv, envp, &regs); 
--      if (error == 0) {
--              task_lock(current);
--              current->ptrace &= ~PT_DTRACE;
--              task_unlock(current);
--      }
-+      error = do_execve(filename, argv, envp, regs);
-       putname(filename);
-       return error;
- }
-@@ -728,18 +710,18 @@ void set_personality_64bit(void)
-       /* inherit personality from parent */
-       /* Make sure to be in 64bit mode */
--      clear_thread_flag(TIF_IA32); 
-+      clear_thread_flag(TIF_IA32);
-       /* TBD: overwrites user setup. Should have two bits.
-          But 64bit processes have always behaved this way,
-          so it's not too bad. The main problem is just that
--         32bit childs are affected again. */
-+         32bit childs are affected again. */
-       current->personality &= ~READ_IMPLIES_EXEC;
- }
- asmlinkage long sys_fork(struct pt_regs *regs)
- {
--      return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
-+      return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
- }
- asmlinkage long
-@@ -747,7 +729,7 @@ sys_clone(unsigned long clone_flags, uns
-         void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
- {
-       if (!newsp)
--              newsp = regs->rsp;
-+              newsp = regs->sp;
-       return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
- }
-@@ -763,29 +745,29 @@ sys_clone(unsigned long clone_flags, uns
-  */
- asmlinkage long sys_vfork(struct pt_regs *regs)
- {
--      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0,
-+      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
-                   NULL, NULL);
- }
- unsigned long get_wchan(struct task_struct *p)
- {
-       unsigned long stack;
--      u64 fp,rip;
-+      u64 fp,ip;
-       int count = 0;
-       if (!p || p == current || p->state==TASK_RUNNING)
-               return 0; 
-       stack = (unsigned long)task_stack_page(p);
--      if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE)
-+      if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
-               return 0;
--      fp = *(u64 *)(p->thread.rsp);
-+      fp = *(u64 *)(p->thread.sp);
-       do { 
-               if (fp < (unsigned long)stack ||
-                   fp > (unsigned long)stack+THREAD_SIZE)
-                       return 0; 
--              rip = *(u64 *)(fp+8); 
--              if (!in_sched_functions(rip))
--                      return rip; 
-+              ip = *(u64 *)(fp+8);
-+              if (!in_sched_functions(ip))
-+                      return ip;
-               fp = *(u64 *)fp; 
-       } while (count++ < 16); 
-       return 0;
-@@ -827,19 +809,19 @@ long do_arch_prctl(struct task_struct *t
-               /* Not strictly needed for fs, but do it for symmetry
-                  with gs */
-               if (addr >= TASK_SIZE_OF(task))
--                      return -EPERM; 
-+                      return -EPERM;
-               cpu = get_cpu();
--              /* handle small bases via the GDT because that's faster to 
-+              /* handle small bases via the GDT because that's faster to
-                  switch. */
--              if (addr <= 0xffffffff) { 
-+              if (addr <= 0xffffffff) {
-                       set_32bit_tls(task, FS_TLS, addr);
--                      if (doit) { 
--                              load_TLS(&task->thread, cpu); 
-+                      if (doit) {
-+                              load_TLS(&task->thread, cpu);
-                               asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
-                       }
-                       task->thread.fsindex = FS_TLS_SEL;
-                       task->thread.fs = 0;
--              } else { 
-+              } else {
-                       task->thread.fsindex = 0;
-                       task->thread.fs = addr;
-                       if (doit) {
-@@ -852,24 +834,24 @@ long do_arch_prctl(struct task_struct *t
-               }
-               put_cpu();
-               break;
--      case ARCH_GET_FS: { 
--              unsigned long base; 
-+      case ARCH_GET_FS: {
-+              unsigned long base;
-               if (task->thread.fsindex == FS_TLS_SEL)
-                       base = read_32bit_tls(task, FS_TLS);
-               else if (doit)
-                       rdmsrl(MSR_FS_BASE, base);
-               else
-                       base = task->thread.fs;
--              ret = put_user(base, (unsigned long __user *)addr); 
--              break; 
-+              ret = put_user(base, (unsigned long __user *)addr);
-+              break;
-       }
--      case ARCH_GET_GS: { 
-+      case ARCH_GET_GS: {
-               unsigned long base;
-               unsigned gsindex;
-               if (task->thread.gsindex == GS_TLS_SEL)
-                       base = read_32bit_tls(task, GS_TLS);
-               else if (doit) {
--                      asm("movl %%gs,%0" : "=r" (gsindex));
-+                      asm("movl %%gs,%0" : "=r" (gsindex));
-                       if (gsindex)
-                               rdmsrl(MSR_KERNEL_GS_BASE, base);
-                       else
-@@ -877,40 +859,21 @@ long do_arch_prctl(struct task_struct *t
-               }
-               else
-                       base = task->thread.gs;
--              ret = put_user(base, (unsigned long __user *)addr); 
-+              ret = put_user(base, (unsigned long __user *)addr);
-               break;
-       }
-       default:
-               ret = -EINVAL;
-               break;
--      } 
-+      }
--      return ret;     
--} 
-+      return ret;
-+}
- long sys_arch_prctl(int code, unsigned long addr)
- {
-       return do_arch_prctl(current, code, addr);
--} 
--
--/* 
-- * Capture the user space registers if the task is not running (in user space)
-- */
--int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
--{
--      struct pt_regs *pp, ptregs;
--
--      pp = task_pt_regs(tsk);
--
--      ptregs = *pp; 
--      ptregs.cs &= 0xffff;
--      ptregs.ss &= 0xffff;
--
--      elf_core_copy_regs(regs, &ptregs);
-- 
--        boot_option_idle_override = 1;
--      return 1;
- }
- unsigned long arch_align_stack(unsigned long sp)
-@@ -919,3 +882,9 @@ unsigned long arch_align_stack(unsigned 
-               sp -= get_random_int() % 8192;
-       return sp & ~0xf;
- }
-+
-+unsigned long arch_randomize_brk(struct mm_struct *mm)
-+{
-+      unsigned long range_end = mm->brk + 0x02000000;
-+      return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
-+}
---- a/arch/x86/kernel/quirks-xen.c
-+++ b/arch/x86/kernel/quirks-xen.c
-@@ -9,7 +9,7 @@
- static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
- {
-       u8 config, rev;
--      u32 word;
-+      u16 word;
-       /* BIOS may enable hardware IRQ balancing for
-        * E7520/E7320/E7525(revision ID 0x9 and below)
-@@ -24,14 +24,17 @@ static void __devinit quirk_intel_irqbal
-       pci_read_config_byte(dev, 0xf4, &config);
-       pci_write_config_byte(dev, 0xf4, config|0x2);
--      /* read xTPR register */
--      raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
-+      /*
-+       * read xTPR register.  We may not have a pci_dev for device 8
-+       * because it might be hidden until the above write.
-+       */
-+      pci_bus_read_config_word(dev->bus, PCI_DEVFN(8, 0), 0x4c, &word);
-       if (!(word & (1 << 13))) {
-               struct xen_platform_op op;
--              printk(KERN_INFO "Intel E7520/7320/7525 detected. "
--                      "Disabling irq balancing and affinity\n");
-+              dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
-+                      "disabling irq balancing and affinity\n");
-               op.cmd = XENPF_platform_quirk;
-               op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING;
-               WARN_ON(HYPERVISOR_platform_op(&op));
-@@ -102,14 +105,16 @@ static void ich_force_enable_hpet(struct
-       pci_read_config_dword(dev, 0xF0, &rcba);
-       rcba &= 0xFFFFC000;
-       if (rcba == 0) {
--              printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n");
-+              dev_printk(KERN_DEBUG, &dev->dev, "RCBA disabled; "
-+                      "cannot force enable HPET\n");
-               return;
-       }
-       /* use bits 31:14, 16 kB aligned */
-       rcba_base = ioremap_nocache(rcba, 0x4000);
-       if (rcba_base == NULL) {
--              printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n");
-+              dev_printk(KERN_DEBUG, &dev->dev, "ioremap failed; "
-+                      "cannot force enable HPET\n");
-               return;
-       }
-@@ -120,8 +125,8 @@ static void ich_force_enable_hpet(struct
-               /* HPET is enabled in HPTC. Just not reported by BIOS */
-               val = val & 0x3;
-               force_hpet_address = 0xFED00000 | (val << 12);
--              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
--                             force_hpet_address);
-+              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
-+                      "0x%lx\n", force_hpet_address);
-               iounmap(rcba_base);
-               return;
-       }
-@@ -140,11 +145,12 @@ static void ich_force_enable_hpet(struct
-       if (err) {
-               force_hpet_address = 0;
-               iounmap(rcba_base);
--              printk(KERN_DEBUG "Failed to force enable HPET\n");
-+              dev_printk(KERN_DEBUG, &dev->dev,
-+                      "Failed to force enable HPET\n");
-       } else {
-               force_hpet_resume_type = ICH_FORCE_HPET_RESUME;
--              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
--                             force_hpet_address);
-+              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
-+                      "0x%lx\n", force_hpet_address);
-       }
- }
-@@ -160,6 +166,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
-                        ich_force_enable_hpet);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
-                        ich_force_enable_hpet);
-+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7,
-+                       ich_force_enable_hpet);
- static struct pci_dev *cached_dev;
-@@ -204,8 +212,8 @@ static void old_ich_force_enable_hpet(st
-       if (val & 0x4) {
-               val &= 0x3;
-               force_hpet_address = 0xFED00000 | (val << 12);
--              printk(KERN_DEBUG "HPET at base address 0x%lx\n",
--                             force_hpet_address);
-+              dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
-+                      force_hpet_address);
-               return;
-       }
-@@ -225,14 +233,14 @@ static void old_ich_force_enable_hpet(st
-               /* HPET is enabled in HPTC. Just not reported by BIOS */
-               val &= 0x3;
-               force_hpet_address = 0xFED00000 | (val << 12);
--              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
--                             force_hpet_address);
-+              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
-+                      "0x%lx\n", force_hpet_address);
-               cached_dev = dev;
-               force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME;
-               return;
-       }
--      printk(KERN_DEBUG "Failed to force enable HPET\n");
-+      dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n");
- }
- /*
-@@ -290,8 +298,8 @@ static void vt8237_force_enable_hpet(str
-        */
-       if (val & 0x80) {
-               force_hpet_address = (val & ~0x3ff);
--              printk(KERN_DEBUG "HPET at base address 0x%lx\n",
--                             force_hpet_address);
-+              dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
-+                      force_hpet_address);
-               return;
-       }
-@@ -305,14 +313,14 @@ static void vt8237_force_enable_hpet(str
-       pci_read_config_dword(dev, 0x68, &val);
-       if (val & 0x80) {
-               force_hpet_address = (val & ~0x3ff);
--              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
--                             force_hpet_address);
-+              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
-+                      "0x%lx\n", force_hpet_address);
-               cached_dev = dev;
-               force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
-               return;
-       }
--      printk(KERN_DEBUG "Failed to force enable HPET\n");
-+      dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n");
- }
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
-@@ -340,7 +348,7 @@ static void nvidia_force_enable_hpet(str
-       pci_read_config_dword(dev, 0x44, &val);
-       force_hpet_address = val & 0xfffffffe;
-       force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME;
--      printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
-+      dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n",
-               force_hpet_address);
-       cached_dev = dev;
-       return;
-@@ -353,6 +361,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_N
-                       nvidia_force_enable_hpet);
- /* LPC bridges */
-+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0260,
-+                      nvidia_force_enable_hpet);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0360,
-                       nvidia_force_enable_hpet);
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0361,
-@@ -373,19 +383,19 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_N
- void force_hpet_resume(void)
- {
-       switch (force_hpet_resume_type) {
--          case ICH_FORCE_HPET_RESUME:
--              return ich_force_hpet_resume();
--
--          case OLD_ICH_FORCE_HPET_RESUME:
--              return old_ich_force_hpet_resume();
--
--          case VT8237_FORCE_HPET_RESUME:
--              return vt8237_force_hpet_resume();
--
--          case NVIDIA_FORCE_HPET_RESUME:
--              return nvidia_force_hpet_resume();
--
--          default:
-+      case ICH_FORCE_HPET_RESUME:
-+              ich_force_hpet_resume();
-+              return;
-+      case OLD_ICH_FORCE_HPET_RESUME:
-+              old_ich_force_hpet_resume();
-+              return;
-+      case VT8237_FORCE_HPET_RESUME:
-+              vt8237_force_hpet_resume();
-+              return;
-+      case NVIDIA_FORCE_HPET_RESUME:
-+              nvidia_force_hpet_resume();
-+              return;
-+      default:
-               break;
-       }
- }
---- a/arch/x86/kernel/rtc.c
-+++ b/arch/x86/kernel/rtc.c
-@@ -181,6 +181,10 @@ unsigned long read_persistent_clock(void
- {
-       unsigned long retval, flags;
-+#ifdef CONFIG_XEN
-+      if (!is_initial_xendomain())
-+              return xen_read_persistent_clock();
-+#endif
-       spin_lock_irqsave(&rtc_lock, flags);
-       retval = get_wallclock();
-       spin_unlock_irqrestore(&rtc_lock, flags);
-@@ -190,6 +194,10 @@ unsigned long read_persistent_clock(void
- int update_persistent_clock(struct timespec now)
- {
-+#ifdef CONFIG_XEN
-+      if (xen_update_persistent_clock() < 0 || xen_independent_wallclock())
-+              return 0;
-+#endif
-       return set_rtc_mmss(now.tv_sec);
- }
---- a/arch/x86/kernel/setup_32-xen.c
-+++ b/arch/x86/kernel/setup_32-xen.c
-@@ -47,9 +47,12 @@
- #include <linux/crash_dump.h>
- #include <linux/dmi.h>
- #include <linux/pfn.h>
-+#include <linux/pci.h>
-+#include <linux/init_ohci1394_dma.h>
- #include <video/edid.h>
-+#include <asm/mtrr.h>
- #include <asm/apic.h>
- #include <asm/e820.h>
- #include <asm/mpspec.h>
-@@ -79,14 +82,83 @@ static struct notifier_block xen_panic_b
-       xen_panic_event, NULL, 0 /* try to go last */
- };
--int disable_pse __cpuinitdata = 0;
--
- /*
-  * Machine setup..
-  */
--extern struct resource code_resource;
--extern struct resource data_resource;
--extern struct resource bss_resource;
-+static struct resource data_resource = {
-+      .name   = "Kernel data",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource code_resource = {
-+      .name   = "Kernel code",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource bss_resource = {
-+      .name   = "Kernel bss",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource video_ram_resource = {
-+      .name   = "Video RAM area",
-+      .start  = 0xa0000,
-+      .end    = 0xbffff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource standard_io_resources[] = { {
-+      .name   = "dma1",
-+      .start  = 0x0000,
-+      .end    = 0x001f,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "pic1",
-+      .start  = 0x0020,
-+      .end    = 0x0021,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "timer0",
-+      .start  = 0x0040,
-+      .end    = 0x0043,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "timer1",
-+      .start  = 0x0050,
-+      .end    = 0x0053,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "keyboard",
-+      .start  = 0x0060,
-+      .end    = 0x006f,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "dma page reg",
-+      .start  = 0x0080,
-+      .end    = 0x008f,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "pic2",
-+      .start  = 0x00a0,
-+      .end    = 0x00a1,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "dma2",
-+      .start  = 0x00c0,
-+      .end    = 0x00df,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "fpu",
-+      .start  = 0x00f0,
-+      .end    = 0x00ff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+} };
- /* cpu data as detected by the assembly code in head.S */
- struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
-@@ -94,13 +166,16 @@ struct cpuinfo_x86 new_cpu_data __cpuini
- struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
- EXPORT_SYMBOL(boot_cpu_data);
-+#ifndef CONFIG_X86_PAE
- unsigned long mmu_cr4_features;
-+#else
-+unsigned long mmu_cr4_features = X86_CR4_PAE;
-+#endif
- /* for MCA, but anyone else can use it if they want */
- unsigned int machine_id;
- unsigned int machine_submodel_id;
- unsigned int BIOS_revision;
--unsigned int mca_pentium_flag;
- /* Boot loader ID as an integer, for the benefit of proc_dointvec */
- int bootloader_type;
-@@ -131,13 +206,17 @@ extern int root_mountflags;
- unsigned long saved_videomode;
--#define RAMDISK_IMAGE_START_MASK      0x07FF
-+#define RAMDISK_IMAGE_START_MASK      0x07FF
- #define RAMDISK_PROMPT_FLAG           0x8000
--#define RAMDISK_LOAD_FLAG             0x4000  
-+#define RAMDISK_LOAD_FLAG             0x4000
- static char __initdata command_line[COMMAND_LINE_SIZE];
-+#ifndef CONFIG_DEBUG_BOOT_PARAMS
- struct boot_params __initdata boot_params;
-+#else
-+struct boot_params boot_params;
-+#endif
- /*
-  * Point at the empty zero page to start with. We map the real shared_info
-@@ -198,8 +277,7 @@ static int __init parse_mem(char *arg)
-               return -EINVAL;
-       if (strcmp(arg, "nopentium") == 0) {
--              clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
--              disable_pse = 1;
-+              setup_clear_cpu_cap(X86_FEATURE_PSE);
-       } else {
-               /* If the user specifies memory size, we
-                * limit the BIOS-provided memory map to
-@@ -208,7 +286,7 @@ static int __init parse_mem(char *arg)
-                * trim the existing memory map.
-                */
-               unsigned long long mem_size;
-- 
-+
-               mem_size = memparse(arg, &arg);
-               limit_regions(mem_size);
-               user_defined_memmap = 1;
-@@ -350,7 +428,7 @@ static void __init reserve_ebda_region(v
-       unsigned int addr;
-       addr = get_bios_ebda();
-       if (addr)
--              reserve_bootmem(addr, PAGE_SIZE);       
-+              reserve_bootmem(addr, PAGE_SIZE, BOOTMEM_DEFAULT);
- }
- #endif
-@@ -365,8 +443,6 @@ static unsigned long __init setup_memory
-       min_low_pfn = PFN_UP(__pa(xen_start_info->pt_base)) +
-               xen_start_info->nr_pt_frames;
--      find_max_pfn();
--
-       max_low_pfn = find_max_low_pfn();
- #ifdef CONFIG_HIGHMEM
-@@ -447,7 +523,8 @@ static void __init reserve_crashkernel(v
-                                       (unsigned long)(total_mem >> 20));
-                       crashk_res.start = crash_base;
-                       crashk_res.end   = crash_base + crash_size - 1;
--                      reserve_bootmem(crash_base, crash_size);
-+                      reserve_bootmem(crash_base, crash_size,
-+                                      BOOTMEM_DEFAULT);
-               } else
-                       printk(KERN_INFO "crashkernel reservation failed - "
-                                       "you have to specify a base address\n");
-@@ -461,6 +538,99 @@ static inline void __init reserve_crashk
- {}
- #endif
-+#ifdef CONFIG_BLK_DEV_INITRD
-+
-+static bool do_relocate_initrd = false;
-+
-+static void __init reserve_initrd(void)
-+{
-+      unsigned long ramdisk_image = __pa(xen_start_info->mod_start);
-+      unsigned long ramdisk_size  = xen_start_info->mod_len;
-+      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;
-+
-+      if (!xen_start_info->mod_start || !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;
-+      }
-+      if (ramdisk_size >= end_of_lowmem/2) {
-+              printk(KERN_ERR "initrd too large to handle, "
-+                     "disabling initrd\n");
-+              return;
-+      }
-+      if (ramdisk_end <= end_of_lowmem) {
-+              /* All in lowmem, easy case */
-+              reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT);
-+              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;
-+
-+      /* 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);
-+      initrd_start = ramdisk_here + PAGE_OFFSET;
-+      initrd_end   = initrd_start + ramdisk_size;
-+
-+      do_relocate_initrd = true;
-+}
-+
-+#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
-+
-+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;
-+      unsigned long slop, clen, mapaddr;
-+      char *p, *q;
-+
-+      if (!do_relocate_initrd)
-+              return;
-+
-+      ramdisk_here = initrd_start - PAGE_OFFSET;
-+
-+      q = (char *)initrd_start;
-+
-+      /* Copy any lowmem portion of the initrd */
-+      if (ramdisk_image < end_of_lowmem) {
-+              clen = end_of_lowmem - ramdisk_image;
-+              p = (char *)__va(ramdisk_image);
-+              memcpy(q, p, clen);
-+              q += clen;
-+              ramdisk_image += clen;
-+              ramdisk_size  -= clen;
-+      }
-+
-+      /* Copy the highmem portion of the initrd */
-+      while (ramdisk_size) {
-+              slop = ramdisk_image & ~PAGE_MASK;
-+              clen = ramdisk_size;
-+              if (clen > MAX_MAP_CHUNK-slop)
-+                      clen = MAX_MAP_CHUNK-slop;
-+              mapaddr = ramdisk_image & PAGE_MASK;
-+              p = early_ioremap(mapaddr, clen+slop);
-+              memcpy(q, p+slop, clen);
-+              early_iounmap(p, clen+slop);
-+              q += clen;
-+              ramdisk_image += clen;
-+              ramdisk_size  -= clen;
-+      }
-+}
-+
-+#endif /* CONFIG_BLK_DEV_INITRD */
-+
- void __init setup_bootmem_allocator(void)
- {
-       unsigned long bootmap_size;
-@@ -478,14 +648,15 @@ void __init setup_bootmem_allocator(void
-        * 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));
-+                       bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
-+                       BOOTMEM_DEFAULT);
- #ifndef CONFIG_XEN
-       /*
-        * 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);
-+      reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
-       /* reserve EBDA region, it's a 4K region */
-       reserve_ebda_region();
-@@ -495,7 +666,7 @@ void __init setup_bootmem_allocator(void
-        unless you have no PS/2 mouse plugged in. */
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-           boot_cpu_data.x86 == 6)
--           reserve_bootmem(0xa0000 - 4096, 4096);
-+           reserve_bootmem(0xa0000 - 4096, 4096, BOOTMEM_DEFAULT);
- #ifdef CONFIG_SMP
-       /*
-@@ -503,7 +674,7 @@ void __init setup_bootmem_allocator(void
-        * 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);
-+      reserve_bootmem(PAGE_SIZE, PAGE_SIZE, BOOTMEM_DEFAULT);
- #endif
- #ifdef CONFIG_ACPI_SLEEP
-       /*
-@@ -511,29 +682,12 @@ void __init setup_bootmem_allocator(void
-        */
-       acpi_reserve_bootmem();
- #endif
--      numa_kva_reserve();
- #endif /* !CONFIG_XEN */
- #ifdef CONFIG_BLK_DEV_INITRD
--      if (xen_start_info->mod_start) {
--              unsigned long ramdisk_image = __pa(xen_start_info->mod_start);
--              unsigned long ramdisk_size  = xen_start_info->mod_len;
--              unsigned long ramdisk_end   = ramdisk_image + ramdisk_size;
--              unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
--
--              if (ramdisk_end <= end_of_lowmem) {
--                      /*reserve_bootmem(ramdisk_image, ramdisk_size);*/
--                      initrd_start = ramdisk_image + PAGE_OFFSET;
--                      initrd_end = initrd_start+ramdisk_size;
--                      initrd_below_start_ok = 1;
--              } else {
--                      printk(KERN_ERR "initrd extends beyond end of memory "
--                             "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
--                             ramdisk_end, end_of_lowmem);
--                      initrd_start = 0;
--              }
--      }
-+      reserve_initrd();
- #endif
-+      numa_kva_reserve();
-       reserve_crashkernel();
- }
-@@ -600,20 +754,14 @@ void __init setup_arch(char **cmdline_p)
-       memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
-       pre_setup_arch_hook();
-       early_cpu_init();
-+      early_ioremap_init();
- #ifdef CONFIG_SMP
-       prefill_possible_map();
- #endif
--      /*
--       * FIXME: This isn't an official loader_type right
--       * now but does currently work with elilo.
--       * If we were configured as an EFI kernel, check to make
--       * sure that we were loaded correctly from elilo and that
--       * the system table is valid.  If not, then initialize normally.
--       */
- #ifdef CONFIG_EFI
--      if ((boot_params.hdr.type_of_loader == 0x50) &&
--          boot_params.efi_info.efi_systab)
-+      if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-+                   "EL32", 4))
-               efi_enabled = 1;
- #endif
-@@ -653,12 +801,9 @@ void __init setup_arch(char **cmdline_p)
- #endif
-       ARCH_SETUP
--      if (efi_enabled)
--              efi_init();
--      else {
--              printk(KERN_INFO "BIOS-provided physical RAM map:\n");
--              print_memory_map(memory_setup());
--      }
-+
-+      printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-+      print_memory_map(memory_setup());
-       copy_edd();
-@@ -691,6 +836,17 @@ void __init setup_arch(char **cmdline_p)
-       strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
-       *cmdline_p = command_line;
-+      if (efi_enabled)
-+              efi_init();
-+
-+      /* update e820 for memory not covered by WB MTRRs */
-+      find_max_pfn();
-+      mtrr_bp_init();
-+#ifndef CONFIG_XEN
-+      if (mtrr_trim_uncached_memory(max_pfn))
-+              find_max_pfn();
-+#endif
-+
-       max_low_pfn = setup_memory();
- #ifdef CONFIG_VMI
-@@ -715,6 +871,16 @@ void __init setup_arch(char **cmdline_p)
-       smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
- #endif
-       paging_init();
-+
-+      /*
-+       * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
-+       */
-+
-+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-+      if (init_ohci1394_dma_early)
-+              init_ohci1394_dma_on_all_controllers();
-+#endif
-+
-       remapped_pgdat_init();
-       sparse_init();
-       zone_sizes_init();
-@@ -800,16 +966,20 @@ void __init setup_arch(char **cmdline_p)
-        * NOTE: at this point the bootmem allocator is fully available.
-        */
-+#ifdef CONFIG_BLK_DEV_INITRD
-+      relocate_initrd();
-+#endif
-+
-       paravirt_post_allocator_init();
-       if (is_initial_xendomain())
-               dmi_scan_machine();
-+      io_delay_init();
-+
- #ifdef CONFIG_X86_GENERICARCH
-       generic_apic_probe();
--#endif        
--      if (efi_enabled)
--              efi_map_memmap();
-+#endif
-       set_iopl.iopl = 1;
-       WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl));
-@@ -827,7 +997,7 @@ void __init setup_arch(char **cmdline_p)
-       acpi_boot_table_init();
- #endif
--#if defined(CONFIG_PCI) && !defined(CONFIG_XEN)
-+#ifndef CONFIG_XEN
-       early_quirks();
- #endif
-@@ -873,3 +1043,30 @@ xen_panic_event(struct notifier_block *t
-       /* we're never actually going to get here... */
-       return NOTIFY_DONE;
- }
-+
-+/*
-+ * Request address space for all standard resources
-+ *
-+ * This is called just before pcibios_init(), which is also a
-+ * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
-+ */
-+static int __init request_standard_resources(void)
-+{
-+      int i;
-+
-+      /* Nothing to do if not running in dom0. */
-+      if (!is_initial_xendomain())
-+              return 0;
-+
-+      printk(KERN_INFO "Setting up standard PCI resources\n");
-+      init_iomem_resources(&code_resource, &data_resource, &bss_resource);
-+
-+      request_resource(&iomem_resource, &video_ram_resource);
-+
-+      /* request I/O space for devices used on all i[345]86 PCs */
-+      for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
-+              request_resource(&ioport_resource, &standard_io_resources[i]);
-+      return 0;
-+}
-+
-+subsys_initcall(request_standard_resources);
---- a/arch/x86/kernel/setup_64-xen.c
-+++ b/arch/x86/kernel/setup_64-xen.c
-@@ -15,7 +15,6 @@
- #include <linux/ptrace.h>
- #include <linux/slab.h>
- #include <linux/user.h>
--#include <linux/a.out.h>
- #include <linux/screen_info.h>
- #include <linux/ioport.h>
- #include <linux/delay.h>
-@@ -30,6 +29,7 @@
- #include <linux/crash_dump.h>
- #include <linux/root_dev.h>
- #include <linux/pci.h>
-+#include <linux/efi.h>
- #include <linux/acpi.h>
- #include <linux/kallsyms.h>
- #include <linux/edd.h>
-@@ -39,10 +39,13 @@
- #include <linux/dmi.h>
- #include <linux/dma-mapping.h>
- #include <linux/ctype.h>
-+#include <linux/uaccess.h>
-+#include <linux/init_ohci1394_dma.h>
- #include <asm/mtrr.h>
- #include <asm/uaccess.h>
- #include <asm/system.h>
-+#include <asm/vsyscall.h>
- #include <asm/io.h>
- #include <asm/smp.h>
- #include <asm/msr.h>
-@@ -50,6 +53,7 @@
- #include <video/edid.h>
- #include <asm/e820.h>
- #include <asm/dma.h>
-+#include <asm/gart.h>
- #include <asm/mpspec.h>
- #include <asm/mmu_context.h>
- #include <asm/proto.h>
-@@ -59,6 +63,9 @@
- #include <asm/sections.h>
- #include <asm/dmi.h>
- #include <asm/cacheflush.h>
-+#include <asm/mce.h>
-+#include <asm/ds.h>
-+#include <asm/topology.h>
- #ifdef CONFIG_XEN
- #include <linux/percpu.h>
- #include <xen/interface/physdev.h>
-@@ -108,6 +115,8 @@ EXPORT_SYMBOL(xen_start_info);
- struct cpuinfo_x86 boot_cpu_data __read_mostly;
- EXPORT_SYMBOL(boot_cpu_data);
-+__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
-+
- unsigned long mmu_cr4_features;
- /* Boot loader ID as an integer, for the benefit of proc_dointvec */
-@@ -117,7 +126,7 @@ unsigned long saved_video_mode;
- int force_mwait __cpuinitdata;
--/* 
-+/*
-  * Early DMI memory
-  */
- int dmi_alloc_index;
-@@ -163,25 +172,27 @@ struct resource standard_io_resources[] 
- #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
--struct resource data_resource = {
-+static struct resource data_resource = {
-       .name = "Kernel data",
-       .start = 0,
-       .end = 0,
-       .flags = IORESOURCE_RAM,
- };
--struct resource code_resource = {
-+static struct resource code_resource = {
-       .name = "Kernel code",
-       .start = 0,
-       .end = 0,
-       .flags = IORESOURCE_RAM,
- };
--struct resource bss_resource = {
-+static struct resource bss_resource = {
-       .name = "Kernel bss",
-       .start = 0,
-       .end = 0,
-       .flags = IORESOURCE_RAM,
- };
-+static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
-+
- #ifdef CONFIG_PROC_VMCORE
- /* elfcorehdr= specifies the location of elf core header
-  * stored by the crashed kernel. This option will be passed
-@@ -205,9 +216,10 @@ contig_initmem_init(unsigned long start_
-       unsigned long bootmap_size, bootmap;
-       bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
--      bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
-+      bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size,
-+                               PAGE_SIZE);
-       if (bootmap == -1L)
--              panic("Cannot find bootmem map of size %ld\n",bootmap_size);
-+              panic("Cannot find bootmem map of size %ld\n", bootmap_size);
-       bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
-       e820_register_active_regions(0, start_pfn, end_pfn);
- #ifdef CONFIG_XEN
-@@ -215,8 +227,8 @@ contig_initmem_init(unsigned long start_
- #else
-       free_bootmem_with_active_regions(0, end_pfn);
- #endif
--      reserve_bootmem(bootmap, bootmap_size);
--} 
-+      reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
-+}
- #endif
- #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-@@ -249,27 +261,35 @@ static inline void copy_edd(void)
- #ifndef CONFIG_XEN
- static void __init reserve_crashkernel(void)
- {
--      unsigned long long free_mem;
-+      unsigned long long total_mem;
-       unsigned long long crash_size, crash_base;
-       int ret;
--      free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
-+      total_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
--      ret = parse_crashkernel(boot_command_line, free_mem,
-+      ret = parse_crashkernel(boot_command_line, total_mem,
-                       &crash_size, &crash_base);
-       if (ret == 0 && crash_size) {
--              if (crash_base > 0) {
--                      printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
--                                      "for crashkernel (System RAM: %ldMB)\n",
--                                      (unsigned long)(crash_size >> 20),
--                                      (unsigned long)(crash_base >> 20),
--                                      (unsigned long)(free_mem >> 20));
--                      crashk_res.start = crash_base;
--                      crashk_res.end   = crash_base + crash_size - 1;
--                      reserve_bootmem(crash_base, crash_size);
--              } else
-+              if (crash_base <= 0) {
-                       printk(KERN_INFO "crashkernel reservation failed - "
-                                       "you have to specify a base address\n");
-+                      return;
-+              }
-+
-+              if (reserve_bootmem(crash_base, crash_size,
-+                                      BOOTMEM_EXCLUSIVE) < 0) {
-+                      printk(KERN_INFO "crashkernel reservation failed - "
-+                                      "memory is in use\n");
-+                      return;
-+              }
-+
-+              printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
-+                              "for crashkernel (System RAM: %ldMB)\n",
-+                              (unsigned long)(crash_size >> 20),
-+                              (unsigned long)(crash_base >> 20),
-+                              (unsigned long)(total_mem >> 20));
-+              crashk_res.start = crash_base;
-+              crashk_res.end   = crash_base + crash_size - 1;
-       }
- }
- #else
-@@ -280,37 +300,21 @@ static inline void __init reserve_crashk
- {}
- #endif
--#ifndef CONFIG_XEN
--#define EBDA_ADDR_POINTER 0x40E
--
--unsigned __initdata ebda_addr;
--unsigned __initdata ebda_size;
--
--static void discover_ebda(void)
-+/* Overridden in paravirt.c if CONFIG_PARAVIRT */
-+void __attribute__((weak)) __init memory_setup(void)
- {
--      /*
--       * there is a real-mode segmented pointer pointing to the 
--       * 4K EBDA area at 0x40E
--       */
--      ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
--      ebda_addr <<= 4;
--
--      ebda_size = *(unsigned short *)__va(ebda_addr);
--
--      /* Round EBDA up to pages */
--      if (ebda_size == 0)
--              ebda_size = 1;
--      ebda_size <<= 10;
--      ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
--      if (ebda_size > 64*1024)
--              ebda_size = 64*1024;
-+       machine_specific_memory_setup();
- }
--#else
--#define discover_ebda() ((void)0)
--#endif
-+/*
-+ * setup_arch - architecture-specific boot-time initializations
-+ *
-+ * Note: On x86_64, fixmaps are ready for use even before this is called.
-+ */
- void __init setup_arch(char **cmdline_p)
- {
-+      unsigned i;
-+
- #ifdef CONFIG_XEN
-       extern struct e820map machine_e820;
-@@ -319,6 +323,11 @@ void __init setup_arch(char **cmdline_p)
-       /* Register a call for panic conditions. */
-       atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
-+      WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
-+                                   VMASST_TYPE_writable_pagetables));
-+
-+      early_ioremap_init();
-+
-       ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); 
-       screen_info = boot_params.screen_info;
-@@ -335,11 +344,6 @@ void __init setup_arch(char **cmdline_p)
-               screen_info.orig_video_isVGA = 0;
-       copy_edid();
--
--      WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
--                                   VMASST_TYPE_writable_pagetables));
--
--      ARCH_SETUP
- #else
-       printk(KERN_INFO "Command line: %s\n", boot_command_line);
-@@ -355,7 +359,15 @@ void __init setup_arch(char **cmdline_p)
-       rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0);
-       rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
- #endif
--      setup_memory_region();
-+#ifdef CONFIG_EFI
-+      if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-+                   "EL64", 4))
-+              efi_enabled = 1;
-+#endif
-+
-+      ARCH_SETUP
-+
-+      memory_setup();
-       copy_edd();
-       if (!boot_params.hdr.root_flags)
-@@ -379,28 +391,51 @@ void __init setup_arch(char **cmdline_p)
-       parse_early_param();
-+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-+      if (init_ohci1394_dma_early)
-+              init_ohci1394_dma_on_all_controllers();
-+#endif
-+
-       finish_e820_parsing();
-+      early_gart_iommu_check();
-+
-       e820_register_active_regions(0, 0, -1UL);
-       /*
-        * partially used pages are not usable - thus
-        * we are rounding upwards:
-        */
-       end_pfn = e820_end_of_ram();
-+      /* update e820 for memory not covered by WB MTRRs */
-+      mtrr_bp_init();
-+#ifndef CONFIG_XEN
-+      if (mtrr_trim_uncached_memory(end_pfn)) {
-+              e820_register_active_regions(0, 0, -1UL);
-+              end_pfn = e820_end_of_ram();
-+      }
-+#endif
-+
-       num_physpages = end_pfn;
-+      max_mapnr = end_pfn;
-       check_efer();
--      discover_ebda();
--
-       init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
-+      if (efi_enabled)
-+              efi_init();
-       if (is_initial_xendomain())
-               dmi_scan_machine();
-+      io_delay_init();
-+
- #if defined(CONFIG_SMP) && !defined(CONFIG_XEN)
--      /* setup to use the static apicid table during kernel startup */
--      x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
-+      /* setup to use the early static init tables during kernel startup */
-+      x86_cpu_to_apicid_early_ptr = (void *)x86_cpu_to_apicid_init;
-+      x86_bios_cpu_apicid_early_ptr = (void *)x86_bios_cpu_apicid_init;
-+#ifdef CONFIG_NUMA
-+      x86_cpu_to_node_map_early_ptr = (void *)x86_cpu_to_node_map_init;
-+#endif
- #endif
-       /* How many end-of-memory variables you have, grandma! */
-@@ -419,54 +454,25 @@ void __init setup_arch(char **cmdline_p)
- #endif
- #ifdef CONFIG_NUMA
--      numa_initmem_init(0, end_pfn); 
-+      numa_initmem_init(0, end_pfn);
- #else
-       contig_initmem_init(0, end_pfn);
- #endif
--#ifdef CONFIG_XEN
--      /*
--       * Reserve kernel, physmap, start info, initial page tables, and
--       * direct mapping.
--       */
--      reserve_bootmem_generic(__pa_symbol(&_text),
--                              (table_end << PAGE_SHIFT) - __pa_symbol(&_text));
--#else
--      /* Reserve direct mapping */
--      reserve_bootmem_generic(table_start << PAGE_SHIFT, 
--                              (table_end - table_start) << PAGE_SHIFT);
--
--      /* reserve kernel */
--      reserve_bootmem_generic(__pa_symbol(&_text),
--                              __pa_symbol(&_end) - __pa_symbol(&_text));
-+      early_res_to_bootmem();
-+#ifndef CONFIG_XEN
-+#ifdef CONFIG_ACPI_SLEEP
-       /*
--       * reserve physical page 0 - it's a special BIOS page on many boxes,
--       * enabling clean reboots, SMP operation, laptop functions.
-+       * Reserve low memory region for sleep support.
-        */
--      reserve_bootmem_generic(0, PAGE_SIZE);
--
--      /* reserve ebda region */
--      if (ebda_addr)
--              reserve_bootmem_generic(ebda_addr, ebda_size);
--#ifdef CONFIG_NUMA
--      /* reserve nodemap region */
--      if (nodemap_addr)
--              reserve_bootmem_generic(nodemap_addr, nodemap_size);
-+       acpi_reserve_bootmem();
- #endif
--#ifdef CONFIG_SMP
--      /* Reserve SMP trampoline */
--      reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE);
--#endif
-+      if (efi_enabled)
-+              efi_reserve_bootmem();
- #endif
--#ifdef CONFIG_ACPI_SLEEP
--       /*
--        * Reserve low memory region for sleep support.
--        */
--       acpi_reserve_bootmem();
--#endif
- #ifdef CONFIG_BLK_DEV_INITRD
- #ifdef CONFIG_XEN
-       if (xen_start_info->mod_start) {
-@@ -490,6 +496,8 @@ void __init setup_arch(char **cmdline_p)
-                       initrd_below_start_ok = 1;
- #endif
-               } else {
-+                      /* Assumes everything on node 0 */
-+                      free_bootmem(ramdisk_image, ramdisk_size);
-                       printk(KERN_ERR "initrd extends beyond end of memory "
-                              "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-                              ramdisk_end, end_of_mem);
-@@ -499,10 +507,11 @@ void __init setup_arch(char **cmdline_p)
- #endif
-       reserve_crashkernel();
-       paging_init();
-+      map_vsyscall();
- #ifdef CONFIG_X86_LOCAL_APIC
-       /*
--       * Find and reserve possible boot-time SMP configuration:
--       */
-+      * Find and reserve possible boot-time SMP configuration:
-+      */
-       find_smp_config();
- #endif
- #ifdef CONFIG_XEN
-@@ -590,16 +599,10 @@ void __init setup_arch(char **cmdline_p)
- #endif
- #endif
--#if defined(CONFIG_PCI) && !defined(CONFIG_XEN)
-+#ifndef CONFIG_XEN
-       early_quirks();
- #endif
--      /*
--       * set this early, so we dont allocate cpu0
--       * if MADT list doesnt list BSP first
--       * mpparse.c/MP_processor_info() allocates logical cpu numbers.
--       */
--      cpu_set(0, cpu_present_map);
- #ifdef CONFIG_ACPI
-       /*
-        * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
-@@ -623,6 +626,7 @@ void __init setup_arch(char **cmdline_p)
-               get_smp_config();
- #ifndef CONFIG_XEN
-       init_apic_mappings();
-+      ioapic_init_mappings();
- #endif
- #endif
- #if defined(CONFIG_XEN) && defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
-@@ -634,18 +638,17 @@ void __init setup_arch(char **cmdline_p)
-        */
- #ifdef CONFIG_XEN
-       if (is_initial_xendomain())
--              e820_reserve_resources(machine_e820.map, machine_e820.nr_map);
-+              e820_reserve_resources(machine_e820.map, machine_e820.nr_map,
-+                                     &code_resource, &data_resource, &bss_resource);
- #else
--      e820_reserve_resources(e820.map, e820.nr_map);
-+      e820_reserve_resources(e820.map, e820.nr_map,
-+                             &code_resource, &data_resource, &bss_resource);
-       e820_mark_nosave_regions();
- #endif
--      {
--      unsigned i;
-       /* request I/O space for devices used on all i[345]86 PCs */
-       for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
-               request_resource(&ioport_resource, &standard_io_resources[i]);
--      }
- #ifdef CONFIG_XEN
-       if (is_initial_xendomain())
-@@ -679,7 +682,8 @@ void __init setup_arch(char **cmdline_p)
- #ifdef CONFIG_VT
- #if defined(CONFIG_VGA_CONSOLE)
--      conswitchp = &vga_con;
-+      if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
-+              conswitchp = &vga_con;
- #elif defined(CONFIG_DUMMY_CONSOLE)
-       conswitchp = &dummy_con;
- #endif
-@@ -723,9 +727,10 @@ static void __cpuinit display_cacheinfo(
-       if (n >= 0x80000005) {
-               cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
--              printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
--                      edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
--              c->x86_cache_size=(ecx>>24)+(edx>>24);
-+              printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), "
-+                     "D cache %dK (%d bytes/line)\n",
-+                     edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
-+              c->x86_cache_size = (ecx>>24) + (edx>>24);
-               /* On K8 L1 TLB is inclusive, so don't count it */
-               c->x86_tlbsize = 0;
-       }
-@@ -739,27 +744,25 @@ static void __cpuinit display_cacheinfo(
-               printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
-               c->x86_cache_size, ecx & 0xFF);
-       }
--
--      if (n >= 0x80000007)
--              cpuid(0x80000007, &dummy, &dummy, &dummy, &c->x86_power); 
-       if (n >= 0x80000008) {
--              cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); 
-+              cpuid(0x80000008, &eax, &dummy, &dummy, &dummy);
-               c->x86_virt_bits = (eax >> 8) & 0xff;
-               c->x86_phys_bits = eax & 0xff;
-       }
- }
- #ifdef CONFIG_NUMA
--static int nearby_node(int apicid)
-+static int __cpuinit nearby_node(int apicid)
- {
--      int i;
-+      int i, node;
-+
-       for (i = apicid - 1; i >= 0; i--) {
--              int node = apicid_to_node[i];
-+              node = apicid_to_node[i];
-               if (node != NUMA_NO_NODE && node_online(node))
-                       return node;
-       }
-       for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
--              int node = apicid_to_node[i];
-+              node = apicid_to_node[i];
-               if (node != NUMA_NO_NODE && node_online(node))
-                       return node;
-       }
-@@ -771,7 +774,7 @@ static int nearby_node(int apicid)
-  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
-  * Assumes number of cores is a power of two.
-  */
--static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
-+static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
- {
- #ifdef CONFIG_SMP
-       unsigned bits;
-@@ -780,7 +783,54 @@ static void __init amd_detect_cmp(struct
-       int node = 0;
-       unsigned apicid = hard_smp_processor_id();
- #endif
--      unsigned ecx = cpuid_ecx(0x80000008);
-+      bits = c->x86_coreid_bits;
-+
-+      /* Low order bits define the core id (index of core in socket) */
-+      c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
-+      /* Convert the APIC ID into the socket ID */
-+      c->phys_proc_id = phys_pkg_id(bits);
-+
-+#ifdef CONFIG_NUMA
-+      node = c->phys_proc_id;
-+      if (apicid_to_node[apicid] != NUMA_NO_NODE)
-+              node = apicid_to_node[apicid];
-+      if (!node_online(node)) {
-+              /* Two possibilities here:
-+                 - The CPU is missing memory and no node was created.
-+                 In that case try picking one from a nearby CPU
-+                 - The APIC IDs differ from the HyperTransport node IDs
-+                 which the K8 northbridge parsing fills in.
-+                 Assume they are all increased by a constant offset,
-+                 but in the same order as the HT nodeids.
-+                 If that doesn't result in a usable node fall back to the
-+                 path for the previous case.  */
-+
-+              int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
-+
-+              if (ht_nodeid >= 0 &&
-+                  apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
-+                      node = apicid_to_node[ht_nodeid];
-+              /* Pick a nearby node */
-+              if (!node_online(node))
-+                      node = nearby_node(apicid);
-+      }
-+      numa_set_node(cpu, node);
-+
-+      printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
-+#endif
-+#endif
-+}
-+
-+static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
-+{
-+#ifdef CONFIG_SMP
-+      unsigned bits, ecx;
-+
-+      /* Multi core CPU? */
-+      if (c->extended_cpuid_level < 0x80000008)
-+              return;
-+
-+      ecx = cpuid_ecx(0x80000008);
-       c->x86_max_cores = (ecx & 0xff) + 1;
-@@ -793,37 +843,8 @@ static void __init amd_detect_cmp(struct
-                       bits++;
-       }
--      /* Low order bits define the core id (index of core in socket) */
--      c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
--      /* Convert the APIC ID into the socket ID */
--      c->phys_proc_id = phys_pkg_id(bits);
--
--#ifdef CONFIG_NUMA
--      node = c->phys_proc_id;
--      if (apicid_to_node[apicid] != NUMA_NO_NODE)
--              node = apicid_to_node[apicid];
--      if (!node_online(node)) {
--              /* Two possibilities here:
--                 - The CPU is missing memory and no node was created.
--                 In that case try picking one from a nearby CPU
--                 - The APIC IDs differ from the HyperTransport node IDs
--                 which the K8 northbridge parsing fills in.
--                 Assume they are all increased by a constant offset,
--                 but in the same order as the HT nodeids.
--                 If that doesn't result in a usable node fall back to the
--                 path for the previous case.  */
--              int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
--              if (ht_nodeid >= 0 &&
--                  apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
--                      node = apicid_to_node[ht_nodeid];
--              /* Pick a nearby node */
--              if (!node_online(node))
--                      node = nearby_node(apicid);
--      }
--      numa_set_node(cpu, node);
-+      c->x86_coreid_bits = bits;
--      printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
--#endif
- #endif
- }
-@@ -840,8 +861,8 @@ static void __init amd_detect_cmp(struct
- /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
- static __cpuinit int amd_apic_timer_broken(void)
- {
--      u32 lo, hi;
--      u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
-+      u32 lo, hi, eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
-+
-       switch (eax & CPUID_XFAM) {
-       case CPUID_XFAM_K8:
-               if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
-@@ -860,6 +881,15 @@ static __cpuinit int amd_apic_timer_brok
- }
- #endif
-+static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
-+{
-+      early_init_amd_mc(c);
-+
-+      /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
-+      if (c->x86_power & (1<<8))
-+              set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
-+}
-+
- static void __cpuinit init_amd(struct cpuinfo_x86 *c)
- {
-       unsigned level;
-@@ -870,7 +900,7 @@ static void __cpuinit init_amd(struct cp
-       /*
-        * Disable TLB flush filter by setting HWCR.FFDIS on K8
-        * bit 6 of msr C001_0015
--       *
-+       *
-        * Errata 63 for SH-B3 steppings
-        * Errata 122 for all steppings (F+ have it disabled by default)
-        */
-@@ -883,35 +913,32 @@ static void __cpuinit init_amd(struct cp
-       /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
-          3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
--      clear_bit(0*32+31, &c->x86_capability);
--      
-+      clear_bit(0*32+31, (unsigned long *)&c->x86_capability);
-+
-       /* On C+ stepping K8 rep microcode works well for copy/memset */
-       level = cpuid_eax(1);
--      if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
--              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
-+      if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) ||
-+                           level >= 0x0f58))
-+              set_cpu_cap(c, X86_FEATURE_REP_GOOD);
-       if (c->x86 == 0x10 || c->x86 == 0x11)
--              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
-+              set_cpu_cap(c, X86_FEATURE_REP_GOOD);
-       /* Enable workaround for FXSAVE leak */
-       if (c->x86 >= 6)
--              set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
-+              set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK);
-       level = get_model_name(c);
-       if (!level) {
--              switch (c->x86) { 
-+              switch (c->x86) {
-               case 15:
-                       /* Should distinguish Models here, but this is only
-                          a fallback anyways. */
-                       strcpy(c->x86_model_id, "Hammer");
--                      break; 
--              } 
--      } 
-+                      break;
-+              }
-+      }
-       display_cacheinfo(c);
--      /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
--      if (c->x86_power & (1<<8))
--              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
--
-       /* Multi core CPU? */
-       if (c->extended_cpuid_level >= 0x80000008)
-               amd_detect_cmp(c);
-@@ -923,14 +950,10 @@ static void __cpuinit init_amd(struct cp
-               num_cache_leaves = 3;
-       if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11)
--              set_bit(X86_FEATURE_K8, &c->x86_capability);
--
--      /* RDTSC can be speculated around */
--      clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
-+              set_cpu_cap(c, X86_FEATURE_K8);
--      /* Family 10 doesn't support C states in MWAIT so don't use it */
--      if (c->x86 == 0x10 && !force_mwait)
--              clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);
-+      /* MFENCE stops RDTSC speculation */
-+      set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
- #ifndef CONFIG_XEN
-       if (amd_apic_timer_broken())
-@@ -938,28 +961,29 @@ static void __cpuinit init_amd(struct cp
- #endif
- }
--static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
-+void __cpuinit detect_ht(struct cpuinfo_x86 *c)
- {
- #ifdef CONFIG_SMP
--      u32     eax, ebx, ecx, edx;
--      int     index_msb, core_bits;
-+      u32 eax, ebx, ecx, edx;
-+      int index_msb, core_bits;
-       cpuid(1, &eax, &ebx, &ecx, &edx);
-       if (!cpu_has(c, X86_FEATURE_HT))
-               return;
--      if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
-+      if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
-               goto out;
-       smp_num_siblings = (ebx & 0xff0000) >> 16;
-       if (smp_num_siblings == 1) {
-               printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
--      } else if (smp_num_siblings > 1 ) {
-+      } else if (smp_num_siblings > 1) {
-               if (smp_num_siblings > NR_CPUS) {
--                      printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
-+                      printk(KERN_WARNING "CPU: Unsupported number of "
-+                             "siblings %d", smp_num_siblings);
-                       smp_num_siblings = 1;
-                       return;
-               }
-@@ -969,7 +993,7 @@ static void __cpuinit detect_ht(struct c
-               smp_num_siblings = smp_num_siblings / c->x86_max_cores;
--              index_msb = get_count_order(smp_num_siblings) ;
-+              index_msb = get_count_order(smp_num_siblings);
-               core_bits = get_count_order(c->x86_max_cores);
-@@ -978,8 +1002,10 @@ static void __cpuinit detect_ht(struct c
-       }
- out:
-       if ((c->x86_max_cores * smp_num_siblings) > 1) {
--              printk(KERN_INFO  "CPU: Physical Processor ID: %d\n", c->phys_proc_id);
--              printk(KERN_INFO  "CPU: Processor Core ID: %d\n", c->cpu_core_id);
-+              printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
-+                     c->phys_proc_id);
-+              printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
-+                     c->cpu_core_id);
-       }
- #endif
-@@ -1003,7 +1029,7 @@ static int __cpuinit intel_num_cpu_cores
-               return 1;
- }
--static void srat_detect_node(void)
-+static void __cpuinit srat_detect_node(void)
- {
- #ifdef CONFIG_NUMA
-       unsigned node;
-@@ -1013,7 +1039,7 @@ static void srat_detect_node(void)
-       /* Don't do the funky fallback heuristics the AMD version employs
-          for now. */
-       node = apicid_to_node[apicid];
--      if (node == NUMA_NO_NODE)
-+      if (node == NUMA_NO_NODE || !node_online(node))
-               node = first_node(node_online_map);
-       numa_set_node(cpu, node);
-@@ -1021,28 +1047,39 @@ static void srat_detect_node(void)
- #endif
- }
-+static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
-+{
-+      if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
-+          (c->x86 == 0x6 && c->x86_model >= 0x0e))
-+              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
-+}
-+
- static void __cpuinit init_intel(struct cpuinfo_x86 *c)
- {
-       /* Cache sizes */
-       unsigned n;
-       init_intel_cacheinfo(c);
--      if (c->cpuid_level > 9 ) {
-+      if (c->cpuid_level > 9) {
-               unsigned eax = cpuid_eax(10);
-               /* Check for version and the number of counters */
-               if ((eax & 0xff) && (((eax>>8) & 0xff) > 1))
--                      set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability);
-+                      set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
-       }
-       if (cpu_has_ds) {
-               unsigned int l1, l2;
-               rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
-               if (!(l1 & (1<<11)))
--                      set_bit(X86_FEATURE_BTS, c->x86_capability);
-+                      set_cpu_cap(c, X86_FEATURE_BTS);
-               if (!(l1 & (1<<12)))
--                      set_bit(X86_FEATURE_PEBS, c->x86_capability);
-+                      set_cpu_cap(c, X86_FEATURE_PEBS);
-       }
-+
-+      if (cpu_has_bts)
-+              ds_init_intel(c);
-+
-       n = c->extended_cpuid_level;
-       if (n >= 0x80000008) {
-               unsigned eax = cpuid_eax(0x80000008);
-@@ -1059,14 +1096,11 @@ static void __cpuinit init_intel(struct 
-               c->x86_cache_alignment = c->x86_clflush_size * 2;
-       if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
-           (c->x86 == 0x6 && c->x86_model >= 0x0e))
--              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
-+              set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
-       if (c->x86 == 6)
--              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
--      if (c->x86 == 15)
--              set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
--      else
--              clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
--      c->x86_max_cores = intel_num_cpu_cores(c);
-+              set_cpu_cap(c, X86_FEATURE_REP_GOOD);
-+      set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
-+      c->x86_max_cores = intel_num_cpu_cores(c);
-       srat_detect_node();
- }
-@@ -1083,18 +1117,12 @@ static void __cpuinit get_cpu_vendor(str
-               c->x86_vendor = X86_VENDOR_UNKNOWN;
- }
--struct cpu_model_info {
--      int vendor;
--      int family;
--      char *model_names[16];
--};
--
- /* Do some early cpuid on the boot CPU to get some parameter that are
-    needed before check_bugs. Everything advanced is in identify_cpu
-    below. */
--void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
-+static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
- {
--      u32 tfms;
-+      u32 tfms, xlvl;
-       c->loops_per_jiffy = loops_per_jiffy;
-       c->x86_cache_size = -1;
-@@ -1105,6 +1133,7 @@ void __cpuinit early_identify_cpu(struct
-       c->x86_clflush_size = 64;
-       c->x86_cache_alignment = c->x86_clflush_size;
-       c->x86_max_cores = 1;
-+      c->x86_coreid_bits = 0;
-       c->extended_cpuid_level = 0;
-       memset(&c->x86_capability, 0, sizeof c->x86_capability);
-@@ -1113,7 +1142,7 @@ void __cpuinit early_identify_cpu(struct
-             (unsigned int *)&c->x86_vendor_id[0],
-             (unsigned int *)&c->x86_vendor_id[8],
-             (unsigned int *)&c->x86_vendor_id[4]);
--              
-+
-       get_cpu_vendor(c);
-       /* Initialize the standard set of capabilities */
-@@ -1131,7 +1160,7 @@ void __cpuinit early_identify_cpu(struct
-                       c->x86 += (tfms >> 20) & 0xff;
-               if (c->x86 >= 0x6)
-                       c->x86_model += ((tfms >> 16) & 0xF) << 4;
--              if (c->x86_capability[0] & (1<<19)) 
-+              if (c->x86_capability[0] & (1<<19))
-                       c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
-       } else {
-               /* Have CPUID level 0 only - unheard of */
-@@ -1141,18 +1170,6 @@ void __cpuinit early_identify_cpu(struct
- #ifdef CONFIG_SMP
-       c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
- #endif
--}
--
--/*
-- * This does the hard work of actually picking apart the CPU stuff...
-- */
--void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
--{
--      int i;
--      u32 xlvl;
--
--      early_identify_cpu(c);
--
-       /* AMD-defined flags: level 0x80000001 */
-       xlvl = cpuid_eax(0x80000000);
-       c->extended_cpuid_level = xlvl;
-@@ -1173,6 +1190,30 @@ void __cpuinit identify_cpu(struct cpuin
-                       c->x86_capability[2] = cpuid_edx(0x80860001);
-       }
-+      c->extended_cpuid_level = cpuid_eax(0x80000000);
-+      if (c->extended_cpuid_level >= 0x80000007)
-+              c->x86_power = cpuid_edx(0x80000007);
-+
-+      switch (c->x86_vendor) {
-+      case X86_VENDOR_AMD:
-+              early_init_amd(c);
-+              break;
-+      case X86_VENDOR_INTEL:
-+              early_init_intel(c);
-+              break;
-+      }
-+
-+}
-+
-+/*
-+ * This does the hard work of actually picking apart the CPU stuff...
-+ */
-+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
-+{
-+      int i;
-+
-+      early_identify_cpu(c);
-+
-       init_scattered_cpuid_features(c);
-       c->apicid = phys_pkg_id(0);
-@@ -1202,8 +1243,7 @@ void __cpuinit identify_cpu(struct cpuin
-               break;
-       }
--      select_idle_routine(c);
--      detect_ht(c); 
-+      detect_ht(c);
-       /*
-        * On SMP, boot_cpu_data holds the common feature set between
-@@ -1213,31 +1253,55 @@ void __cpuinit identify_cpu(struct cpuin
-        */
-       if (c != &boot_cpu_data) {
-               /* AND the already accumulated flags with these */
--              for (i = 0 ; i < NCAPINTS ; i++)
-+              for (i = 0; i < NCAPINTS; i++)
-                       boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
-       }
-+      /* Clear all flags overriden by options */
-+      for (i = 0; i < NCAPINTS; i++)
-+              c->x86_capability[i] &= ~cleared_cpu_caps[i];
-+
- #ifdef CONFIG_X86_MCE
-       mcheck_init(c);
- #endif
-+      select_idle_routine(c);
-+
-       if (c != &boot_cpu_data)
-               mtrr_ap_init();
- #ifdef CONFIG_NUMA
-       numa_add_cpu(smp_processor_id());
- #endif
-+
- }
-- 
-+
-+static __init int setup_noclflush(char *arg)
-+{
-+      setup_clear_cpu_cap(X86_FEATURE_CLFLSH);
-+      return 1;
-+}
-+__setup("noclflush", setup_noclflush);
- void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
- {
-       if (c->x86_model_id[0])
--              printk("%s", c->x86_model_id);
-+              printk(KERN_CONT "%s", c->x86_model_id);
-+
-+      if (c->x86_mask || c->cpuid_level >= 0)
-+              printk(KERN_CONT " stepping %02x\n", c->x86_mask);
-+      else
-+              printk(KERN_CONT "\n");
-+}
--      if (c->x86_mask || c->cpuid_level >= 0) 
--              printk(" stepping %02x\n", c->x86_mask);
-+static __init int setup_disablecpuid(char *arg)
-+{
-+      int bit;
-+      if (get_option(&arg, &bit) && bit < NCAPINTS*32)
-+              setup_clear_cpu_cap(bit);
-       else
--              printk("\n");
-+              return 0;
-+      return 1;
- }
-+__setup("clearcpuid=", setup_disablecpuid);
- /*
-  *    Get CPU information for use by the procfs.
-@@ -1246,116 +1310,41 @@ void __cpuinit print_cpu_info(struct cpu
- static int show_cpuinfo(struct seq_file *m, void *v)
- {
-       struct cpuinfo_x86 *c = v;
--      int cpu = 0;
--
--      /* 
--       * These flag bits must match the definitions in <asm/cpufeature.h>.
--       * NULL means this bit is undefined or reserved; either way it doesn't
--       * have meaning as far as Linux is concerned.  Note that it's important
--       * to realize there is a difference between this table and CPUID -- if
--       * applications want to get the raw CPUID data, they should access
--       * /dev/cpu/<cpu_nr>/cpuid instead.
--       */
--      static const char *const x86_cap_flags[] = {
--              /* Intel-defined */
--              "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
--              "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
--              "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
--              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
--
--              /* AMD-defined */
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
--              NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
--              "3dnowext", "3dnow",
--
--              /* Transmeta-defined */
--              "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--
--              /* Other (Linux-defined) */
--              "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
--              NULL, NULL, NULL, NULL,
--              "constant_tsc", "up", NULL, "arch_perfmon",
--              "pebs", "bts", NULL, "sync_rdtsc",
--              "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--
--              /* Intel-defined (#2) */
--              "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
--              "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
--              NULL, NULL, "dca", "sse4_1", "sse4_2", NULL, NULL, "popcnt",
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--
--              /* VIA/Cyrix/Centaur-defined */
--              NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
--              "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--
--              /* AMD-defined (#2) */
--              "lahf_lm", "cmp_legacy", "svm", "extapic",
--              "cr8_legacy", "abm", "sse4a", "misalignsse",
--              "3dnowprefetch", "osvw", "ibs", "sse5",
--              "skinit", "wdt", NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--
--              /* Auxiliary (Linux-defined) */
--              "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--      };
--      static const char *const x86_power_flags[] = {
--              "ts",   /* temperature sensor */
--              "fid",  /* frequency id control */
--              "vid",  /* voltage id control */
--              "ttp",  /* thermal trip */
--              "tm",
--              "stc",
--              "100mhzsteps",
--              "hwpstate",
--              "",     /* tsc invariant mapped to constant_tsc */
--              /* nothing */
--      };
--
-+      int cpu = 0, i;
- #ifdef CONFIG_SMP
-       cpu = c->cpu_index;
- #endif
--      seq_printf(m,"processor\t: %u\n"
--                   "vendor_id\t: %s\n"
--                   "cpu family\t: %d\n"
--                   "model\t\t: %d\n"
--                   "model name\t: %s\n",
--                   (unsigned)cpu,
--                   c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
--                   c->x86,
--                   (int)c->x86_model,
--                   c->x86_model_id[0] ? c->x86_model_id : "unknown");
--      
-+      seq_printf(m, "processor\t: %u\n"
-+                 "vendor_id\t: %s\n"
-+                 "cpu family\t: %d\n"
-+                 "model\t\t: %d\n"
-+                 "model name\t: %s\n",
-+                 (unsigned)cpu,
-+                 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
-+                 c->x86,
-+                 (int)c->x86_model,
-+                 c->x86_model_id[0] ? c->x86_model_id : "unknown");
-+
-       if (c->x86_mask || c->cpuid_level >= 0)
-               seq_printf(m, "stepping\t: %d\n", c->x86_mask);
-       else
-               seq_printf(m, "stepping\t: unknown\n");
--      
--      if (cpu_has(c,X86_FEATURE_TSC)) {
-+
-+      if (cpu_has(c, X86_FEATURE_TSC)) {
-               unsigned int freq = cpufreq_quick_get((unsigned)cpu);
-+
-               if (!freq)
-                       freq = cpu_khz;
-               seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
--                           freq / 1000, (freq % 1000));
-+                         freq / 1000, (freq % 1000));
-       }
-       /* Cache size */
--      if (c->x86_cache_size >= 0) 
-+      if (c->x86_cache_size >= 0)
-               seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
--      
-+
- #ifdef CONFIG_SMP
-       if (smp_num_siblings * c->x86_max_cores > 1) {
-               seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
-@@ -1364,48 +1353,43 @@ static int show_cpuinfo(struct seq_file 
-               seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
-               seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
-       }
--#endif        
-+#endif
-       seq_printf(m,
--              "fpu\t\t: yes\n"
--              "fpu_exception\t: yes\n"
--              "cpuid level\t: %d\n"
--              "wp\t\t: yes\n"
--              "flags\t\t:",
-+                 "fpu\t\t: yes\n"
-+                 "fpu_exception\t: yes\n"
-+                 "cpuid level\t: %d\n"
-+                 "wp\t\t: yes\n"
-+                 "flags\t\t:",
-                  c->cpuid_level);
--      { 
--              int i; 
--              for ( i = 0 ; i < 32*NCAPINTS ; i++ )
--                      if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
--                              seq_printf(m, " %s", x86_cap_flags[i]);
--      }
--              
-+      for (i = 0; i < 32*NCAPINTS; i++)
-+              if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
-+                      seq_printf(m, " %s", x86_cap_flags[i]);
-+
-       seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
-                  c->loops_per_jiffy/(500000/HZ),
-                  (c->loops_per_jiffy/(5000/HZ)) % 100);
--      if (c->x86_tlbsize > 0) 
-+      if (c->x86_tlbsize > 0)
-               seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
-       seq_printf(m, "clflush size\t: %d\n", c->x86_clflush_size);
-       seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
--      seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", 
-+      seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
-                  c->x86_phys_bits, c->x86_virt_bits);
-       seq_printf(m, "power management:");
--      {
--              unsigned i;
--              for (i = 0; i < 32; i++) 
--                      if (c->x86_power & (1 << i)) {
--                              if (i < ARRAY_SIZE(x86_power_flags) &&
--                                      x86_power_flags[i])
--                                      seq_printf(m, "%s%s",
--                                              x86_power_flags[i][0]?" ":"",
--                                              x86_power_flags[i]);
--                              else
--                                      seq_printf(m, " [%d]", i);
--                      }
-+      for (i = 0; i < 32; i++) {
-+              if (c->x86_power & (1 << i)) {
-+                      if (i < ARRAY_SIZE(x86_power_flags) &&
-+                          x86_power_flags[i])
-+                              seq_printf(m, "%s%s",
-+                                         x86_power_flags[i][0]?" ":"",
-+                                         x86_power_flags[i]);
-+                      else
-+                              seq_printf(m, " [%d]", i);
-+              }
-       }
-       seq_printf(m, "\n\n");
-@@ -1432,8 +1416,8 @@ static void c_stop(struct seq_file *m, v
- {
- }
--struct seq_operations cpuinfo_op = {
--      .start =c_start,
-+const struct seq_operations cpuinfo_op = {
-+      .start = c_start,
-       .next = c_next,
-       .stop = c_stop,
-       .show = show_cpuinfo,
---- a/arch/x86/kernel/setup64-xen.c
-+++ b/arch/x86/kernel/setup64-xen.c
-@@ -31,7 +31,11 @@
- #include <asm/hypervisor.h>
- #endif
-+#ifndef CONFIG_DEBUG_BOOT_PARAMS
- struct boot_params __initdata boot_params;
-+#else
-+struct boot_params boot_params;
-+#endif
- cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
-@@ -47,6 +51,7 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
- unsigned long __supported_pte_mask __read_mostly = ~0UL;
- EXPORT_SYMBOL(__supported_pte_mask);
-+
- static int do_not_nx __cpuinitdata = 0;
- /* noexec=on|off
-@@ -90,6 +95,45 @@ static int __init nonx32_setup(char *str
- __setup("noexec32=", nonx32_setup);
- /*
-+ * Copy data used in early init routines from the initial arrays to the
-+ * per cpu data areas.  These arrays then become expendable and the
-+ * *_early_ptr's are zeroed indicating that the static arrays are gone.
-+ */
-+static void __init setup_per_cpu_maps(void)
-+{
-+#ifndef CONFIG_XEN
-+      int cpu;
-+
-+      for_each_possible_cpu(cpu) {
-+#ifdef CONFIG_SMP
-+              if (per_cpu_offset(cpu)) {
-+#endif
-+                      per_cpu(x86_cpu_to_apicid, cpu) =
-+                                              x86_cpu_to_apicid_init[cpu];
-+                      per_cpu(x86_bios_cpu_apicid, cpu) =
-+                                              x86_bios_cpu_apicid_init[cpu];
-+#ifdef CONFIG_NUMA
-+                      per_cpu(x86_cpu_to_node_map, cpu) =
-+                                              x86_cpu_to_node_map_init[cpu];
-+#endif
-+#ifdef CONFIG_SMP
-+              }
-+              else
-+                      printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n",
-+                                                                      cpu);
-+#endif
-+      }
-+
-+      /* indicate the early static arrays will soon be gone */
-+      x86_cpu_to_apicid_early_ptr = NULL;
-+      x86_bios_cpu_apicid_early_ptr = NULL;
-+#ifdef CONFIG_NUMA
-+      x86_cpu_to_node_map_early_ptr = NULL;
-+#endif
-+#endif
-+}
-+
-+/*
-  * Great future plan:
-  * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
-  * Always point %gs to its beginning
-@@ -109,19 +153,24 @@ void __init setup_per_cpu_areas(void)
-       printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size);
-       for_each_cpu_mask (i, cpu_possible_map) {
-               char *ptr;
-+#ifndef CONFIG_NEED_MULTIPLE_NODES
-+              ptr = alloc_bootmem_pages(size);
-+#else
-+              int node = early_cpu_to_node(i);
--              if (!NODE_DATA(cpu_to_node(i))) {
--                      printk("cpu with no node %d, num_online_nodes %d\n",
--                             i, num_online_nodes());
-+              if (!node_online(node) || !NODE_DATA(node))
-                       ptr = alloc_bootmem_pages(size);
--              } else { 
--                      ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size);
--              }
-+              else
-+                      ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
-+#endif
-               if (!ptr)
-                       panic("Cannot allocate cpu data for CPU %d\n", i);
-               cpu_pda(i)->data_offset = ptr - __per_cpu_start;
-               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-       }
-+
-+      /* setup percpu data maps early */
-+      setup_per_cpu_maps();
- } 
- #ifdef CONFIG_XEN
-@@ -224,7 +273,8 @@ void syscall_init(void)
-       wrmsrl(MSR_CSTAR, ignore_sysret);
-       /* Flags to clear on syscall */
--      wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 
-+      wrmsrl(MSR_SYSCALL_MASK,
-+             X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL);
- #endif
- #ifdef CONFIG_IA32_EMULATION                  
-       syscall32_cpu_init ();
-@@ -303,7 +353,7 @@ void __cpuinit cpu_init (void)
-        */
- #ifndef CONFIG_XEN 
-       if (cpu)
--              memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
-+              memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
- #endif
-       cpu_gdt_descr[cpu].size = GDT_SIZE;
-@@ -334,10 +384,10 @@ void __cpuinit cpu_init (void)
-                                     v, cpu); 
-               }
-               estacks += PAGE_SIZE << order[v];
--              orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks;
-+              orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks;
-       }
--      t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
-+      t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
-       /*
-        * <= is required because the CPU will access up to
-        * 8 bits beyond the end of the IO permission bitmap.
---- a/arch/x86/kernel/smp_32-xen.c
-+++ b/arch/x86/kernel/smp_32-xen.c
-@@ -168,7 +168,7 @@ void __send_IPI_shortcut(unsigned int sh
-       }
- }
--void fastcall send_IPI_self(int vector)
-+void send_IPI_self(int vector)
- {
-       __send_IPI_shortcut(APIC_DEST_SELF, vector);
- }
-@@ -224,13 +224,14 @@ static DEFINE_SPINLOCK(tlbstate_lock);
-  * We need to reload %cr3 since the page tables may be going
-  * away from under us..
-  */
--void leave_mm(unsigned long cpu)
-+void leave_mm(int cpu)
- {
-       if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
-               BUG();
-       cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
-       load_cr3(swapper_pg_dir);
- }
-+EXPORT_SYMBOL_GPL(leave_mm);
- /*
-  *
---- a/arch/x86/kernel/smp_64-xen.c
-+++ b/arch/x86/kernel/smp_64-xen.c
-@@ -33,7 +33,7 @@
- #ifndef CONFIG_XEN
- /*
-- *    Smarter SMP flushing macros. 
-+ *    Smarter SMP flushing macros.
-  *            c/o Linus Torvalds.
-  *
-  *    These mean you can really definitely utterly forget about
-@@ -41,15 +41,15 @@
-  *
-  *    Optimizations Manfred Spraul <manfred@colorfullife.com>
-  *
-- *    More scalable flush, from Andi Kleen
-+ *    More scalable flush, from Andi Kleen
-  *
-- *    To avoid global state use 8 different call vectors.
-- *    Each CPU uses a specific vector to trigger flushes on other
-- *    CPUs. Depending on the received vector the target CPUs look into
-+ *    To avoid global state use 8 different call vectors.
-+ *    Each CPU uses a specific vector to trigger flushes on other
-+ *    CPUs. Depending on the received vector the target CPUs look into
-  *    the right per cpu variable for the flush data.
-  *
-- *    With more than 8 CPUs they are hashed to the 8 available
-- *    vectors. The limited global vector space forces us to this right now.
-+ *    With more than 8 CPUs they are hashed to the 8 available
-+ *    vectors. The limited global vector space forces us to this right now.
-  *    In future when interrupts are split into per CPU domains this could be
-  *    fixed, at the cost of triggering multiple IPIs in some cases.
-  */
-@@ -59,7 +59,6 @@ union smp_flush_state {
-               cpumask_t flush_cpumask;
-               struct mm_struct *flush_mm;
-               unsigned long flush_va;
--#define FLUSH_ALL     -1ULL
-               spinlock_t tlbstate_lock;
-       };
-       char pad[SMP_CACHE_BYTES];
-@@ -71,16 +70,17 @@ union smp_flush_state {
- static DEFINE_PER_CPU(union smp_flush_state, flush_state);
- /*
-- * We cannot call mmdrop() because we are in interrupt context, 
-+ * We cannot call mmdrop() because we are in interrupt context,
-  * instead update mm->cpu_vm_mask.
-  */
--static inline void leave_mm(unsigned long cpu)
-+void leave_mm(int cpu)
- {
-       if (read_pda(mmu_state) == TLBSTATE_OK)
-               BUG();
-       cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
-       load_cr3(swapper_pg_dir);
- }
-+EXPORT_SYMBOL_GPL(leave_mm);
- /*
-  *
-@@ -89,25 +89,25 @@ static inline void leave_mm(unsigned lon
-  * 1) switch_mm() either 1a) or 1b)
-  * 1a) thread switch to a different mm
-  * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
-- *    Stop ipi delivery for the old mm. This is not synchronized with
-- *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
-- *    for the wrong mm, and in the worst case we perform a superfluous
-- *    tlb flush.
-+ *    Stop ipi delivery for the old mm. This is not synchronized with
-+ *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
-+ *    for the wrong mm, and in the worst case we perform a superfluous
-+ *    tlb flush.
-  * 1a2) set cpu mmu_state to TLBSTATE_OK
-- *    Now the smp_invalidate_interrupt won't call leave_mm if cpu0
-+ *    Now the smp_invalidate_interrupt won't call leave_mm if cpu0
-  *    was in lazy tlb mode.
-  * 1a3) update cpu active_mm
-- *    Now cpu0 accepts tlb flushes for the new mm.
-+ *    Now cpu0 accepts tlb flushes for the new mm.
-  * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
-- *    Now the other cpus will send tlb flush ipis.
-+ *    Now the other cpus will send tlb flush ipis.
-  * 1a4) change cr3.
-  * 1b) thread switch without mm change
-  *    cpu active_mm is correct, cpu0 already handles
-  *    flush ipis.
-  * 1b1) set cpu mmu_state to TLBSTATE_OK
-  * 1b2) test_and_set the cpu bit in cpu_vm_mask.
-- *    Atomically set the bit [other cpus will start sending flush ipis],
-- *    and test the bit.
-+ *    Atomically set the bit [other cpus will start sending flush ipis],
-+ *    and test the bit.
-  * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
-  * 2) switch %%esp, ie current
-  *
-@@ -141,12 +141,12 @@ asmlinkage void smp_invalidate_interrupt
-        * orig_rax contains the negated interrupt vector.
-        * Use that to determine where the sender put the data.
-        */
--      sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
-+      sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
-       f = &per_cpu(flush_state, sender);
-       if (!cpu_isset(cpu, f->flush_cpumask))
-               goto out;
--              /* 
-+              /*
-                * This was a BUG() but until someone can quote me the
-                * line from the intel manual that guarantees an IPI to
-                * multiple CPUs is retried _only_ on the erroring CPUs
-@@ -154,10 +154,10 @@ asmlinkage void smp_invalidate_interrupt
-                *
-                * BUG();
-                */
--               
-+
-       if (f->flush_mm == read_pda(active_mm)) {
-               if (read_pda(mmu_state) == TLBSTATE_OK) {
--                      if (f->flush_va == FLUSH_ALL)
-+                      if (f->flush_va == TLB_FLUSH_ALL)
-                               local_flush_tlb();
-                       else
-                               __flush_tlb_one(f->flush_va);
-@@ -170,19 +170,22 @@ out:
-       add_pda(irq_tlb_count, 1);
- }
--static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
--                                              unsigned long va)
-+void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
-+                           unsigned long va)
- {
-       int sender;
-       union smp_flush_state *f;
-+      cpumask_t cpumask = *cpumaskp;
-       /* Caller has disabled preemption */
-       sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
-       f = &per_cpu(flush_state, sender);
--      /* Could avoid this lock when
--         num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
--         probably not worth checking this for a cache-hot lock. */
-+      /*
-+       * Could avoid this lock when
-+       * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
-+       * probably not worth checking this for a cache-hot lock.
-+       */
-       spin_lock(&f->tlbstate_lock);
-       f->flush_mm = mm;
-@@ -206,14 +209,14 @@ static void flush_tlb_others(cpumask_t c
- int __cpuinit init_smp_flush(void)
- {
-       int i;
-+
-       for_each_cpu_mask(i, cpu_possible_map) {
-               spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock);
-       }
-       return 0;
- }
--
- core_initcall(init_smp_flush);
--      
-+
- void flush_tlb_current_task(void)
- {
-       struct mm_struct *mm = current->mm;
-@@ -225,10 +228,9 @@ void flush_tlb_current_task(void)
-       local_flush_tlb();
-       if (!cpus_empty(cpu_mask))
--              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+              flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-       preempt_enable();
- }
--EXPORT_SYMBOL(flush_tlb_current_task);
- void flush_tlb_mm (struct mm_struct * mm)
- {
-@@ -245,11 +247,10 @@ void flush_tlb_mm (struct mm_struct * mm
-                       leave_mm(smp_processor_id());
-       }
-       if (!cpus_empty(cpu_mask))
--              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+              flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-       preempt_enable();
- }
--EXPORT_SYMBOL(flush_tlb_mm);
- void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
- {
-@@ -263,8 +264,8 @@ void flush_tlb_page(struct vm_area_struc
-       if (current->active_mm == mm) {
-               if(current->mm)
-                       __flush_tlb_one(va);
--               else
--                      leave_mm(smp_processor_id());
-+              else
-+                      leave_mm(smp_processor_id());
-       }
-       if (!cpus_empty(cpu_mask))
-@@ -272,7 +273,6 @@ void flush_tlb_page(struct vm_area_struc
-       preempt_enable();
- }
--EXPORT_SYMBOL(flush_tlb_page);
- static void do_flush_tlb_all(void* info)
- {
-@@ -330,11 +330,9 @@ void unlock_ipi_call_lock(void)
-  * this function sends a 'generic call function' IPI to all other CPU
-  * of the system defined in the mask.
-  */
--
--static int
--__smp_call_function_mask(cpumask_t mask,
--                       void (*func)(void *), void *info,
--                       int wait)
-+static int __smp_call_function_mask(cpumask_t mask,
-+                                  void (*func)(void *), void *info,
-+                                  int wait)
- {
-       struct call_data_struct data;
-       cpumask_t allbutself;
-@@ -422,11 +420,10 @@ EXPORT_SYMBOL(smp_call_function_mask);
-  */
- int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
--      int nonatomic, int wait)
-+                            int nonatomic, int wait)
- {
-       /* prevent preemption and reschedule on another processor */
--      int ret;
--      int me = get_cpu();
-+      int ret, me = get_cpu();
-       /* Can deadlock when called with interrupts disabled */
-       WARN_ON(irqs_disabled());
-@@ -476,9 +473,9 @@ static void stop_this_cpu(void *dummy)
-        */
-       cpu_clear(smp_processor_id(), cpu_online_map);
-       disable_all_local_evtchn();
--      for (;;) 
-+      for (;;)
-               halt();
--} 
-+}
- void smp_send_stop(void)
- {
---- a/arch/x86/kernel/time_32-xen.c
-+++ b/arch/x86/kernel/time_32-xen.c
-@@ -28,21 +28,9 @@
-  *    serialize accesses to xtime/lost_ticks).
-  */
--#include <linux/errno.h>
--#include <linux/sched.h>
--#include <linux/kernel.h>
--#include <linux/param.h>
--#include <linux/string.h>
--#include <linux/mm.h>
-+#include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/time.h>
--#include <linux/delay.h>
--#include <linux/init.h>
--#include <linux/smp.h>
--#include <linux/module.h>
--#include <linux/sysdev.h>
--#include <linux/bcd.h>
--#include <linux/efi.h>
- #include <linux/mca.h>
- #include <linux/sysctl.h>
- #include <linux/percpu.h>
-@@ -50,26 +38,10 @@
- #include <linux/posix-timers.h>
- #include <linux/cpufreq.h>
- #include <linux/clocksource.h>
-+#include <linux/sysdev.h>
--#include <asm/io.h>
--#include <asm/smp.h>
--#include <asm/irq.h>
--#include <asm/msr.h>
- #include <asm/delay.h>
--#include <asm/mpspec.h>
--#include <asm/uaccess.h>
--#include <asm/processor.h>
--#include <asm/timer.h>
- #include <asm/time.h>
--#include <asm/sections.h>
--
--#include "mach_time.h"
--
--#include <linux/timex.h>
--
--#include <asm/hpet.h>
--
--#include <asm/arch_hooks.h>
- #include <xen/evtchn.h>
- #include <xen/sysctl.h>
-@@ -89,9 +61,6 @@ volatile unsigned long __jiffies __secti
- unsigned int cpu_khz; /* Detected as we calibrate the TSC */
- EXPORT_SYMBOL(cpu_khz);
--DEFINE_SPINLOCK(rtc_lock);
--EXPORT_SYMBOL(rtc_lock);
--
- /* These are peridically updated in shared_info, and then copied here. */
- struct shadow_time_info {
-       u64 tsc_timestamp;     /* TSC at last update of time vals.  */
-@@ -154,6 +123,11 @@ static int __init __independent_wallcloc
- }
- __setup("independent_wallclock", __independent_wallclock);
-+int xen_independent_wallclock(void)
-+{
-+      return independent_wallclock;
-+}
-+
- /* Permitted clock jitter, in nsecs, beyond which a warning will be printed. */
- static unsigned long permitted_clock_jitter = 10000000UL; /* 10ms */
- static int __init __permitted_clock_jitter(char *str)
-@@ -223,7 +197,6 @@ static inline u64 get64(volatile u64 *pt
-       return cmpxchg64(ptr, 0, 0);
- #else
-       return *ptr;
--#define cmpxchg64 cmpxchg
- #endif
- }
-@@ -233,7 +206,6 @@ static inline u64 get64_local(volatile u
-       return cmpxchg64_local(ptr, 0, 0);
- #else
-       return *ptr;
--#define cmpxchg64_local cmpxchg_local
- #endif
- }
-@@ -341,35 +313,6 @@ static inline int time_values_up_to_date
-       return (dst->version == src->version);
- }
--/*
-- * This is a special lock that is owned by the CPU and holds the index
-- * register we are working with.  It is required for NMI access to the
-- * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
-- */
--volatile unsigned long cmos_lock = 0;
--EXPORT_SYMBOL(cmos_lock);
--
--/* Routines for accessing the CMOS RAM/RTC. */
--unsigned char rtc_cmos_read(unsigned char addr)
--{
--      unsigned char val;
--      lock_cmos_prefix(addr);
--      outb_p(addr, RTC_PORT(0));
--      val = inb_p(RTC_PORT(1));
--      lock_cmos_suffix(addr);
--      return val;
--}
--EXPORT_SYMBOL(rtc_cmos_read);
--
--void rtc_cmos_write(unsigned char val, unsigned char addr)
--{
--      lock_cmos_prefix(addr);
--      outb_p(addr, RTC_PORT(0));
--      outb_p(val, RTC_PORT(1));
--      lock_cmos_suffix(addr);
--}
--EXPORT_SYMBOL(rtc_cmos_write);
--
- static void sync_xen_wallclock(unsigned long dummy);
- static DEFINE_TIMER(sync_xen_wallclock_timer, sync_xen_wallclock, 0, 0);
- static void sync_xen_wallclock(unsigned long dummy)
-@@ -378,7 +321,8 @@ static void sync_xen_wallclock(unsigned 
-       s64 nsec;
-       struct xen_platform_op op;
--      if (!ntp_synced() || independent_wallclock || !is_initial_xendomain())
-+      BUG_ON(!is_initial_xendomain());
-+      if (!ntp_synced() || independent_wallclock)
-               return;
-       write_seqlock_irq(&xtime_lock);
-@@ -401,23 +345,6 @@ static void sync_xen_wallclock(unsigned 
-       mod_timer(&sync_xen_wallclock_timer, jiffies + 60*HZ);
- }
--static int set_rtc_mmss(unsigned long nowtime)
--{
--      int retval;
--      unsigned long flags;
--
--      if (independent_wallclock || !is_initial_xendomain())
--              return 0;
--
--      /* gets recalled with irq locally disabled */
--      /* XXX - does irqsave resolve this? -johnstul */
--      spin_lock_irqsave(&rtc_lock, flags);
--      retval = set_wallclock(nowtime);
--      spin_unlock_irqrestore(&rtc_lock, flags);
--
--      return retval;
--}
--
- static unsigned long long local_clock(void)
- {
-       unsigned int cpu = get_cpu();
-@@ -500,28 +427,24 @@ unsigned long profile_pc(struct pt_regs 
- #if defined(CONFIG_SMP) || defined(__x86_64__)
- # ifdef __i386__
--      if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs)
-+      if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs)
- # else
-       if (!user_mode(regs)
- # endif
-           && in_lock_functions(pc)) {
- # ifdef CONFIG_FRAME_POINTER
--#  ifdef __i386__
--              return ((unsigned long *)regs->ebp)[1];
--#  else
--              return ((unsigned long *)regs->rbp)[1];
--#  endif
-+              return ((unsigned long *)regs->bp)[1];
- # else
- #  ifdef __i386__
--              unsigned long *sp = (unsigned long *)&regs->esp;
-+              unsigned long *sp = (unsigned long *)&regs->sp;
- #  else
--              unsigned long *sp = (unsigned long *)regs->rsp;
-+              unsigned long *sp = (unsigned long *)regs->sp;
- #  endif
-               /* Return address is either directly at stack pointer
--                 or above a saved eflags. Eflags has bits 22-31 zero,
-+                 or above a saved flags. Eflags has bits 22-31 zero,
-                  kernel addresses don't. */
--              if (sp[0] >> 22)
-+              if (sp[0] >> 22)
-                       return sp[0];
-               if (sp[1] >> 22)
-                       return sp[1];
-@@ -750,25 +673,32 @@ static void init_missing_ticks_accountin
-               runstate->time[RUNSTATE_offline];
- }
--/* not static: needed by APM */
--unsigned long read_persistent_clock(void)
-+unsigned long xen_read_persistent_clock(void)
- {
--      unsigned long retval;
--      unsigned long flags;
--
--      spin_lock_irqsave(&rtc_lock, flags);
-+      const shared_info_t *s = HYPERVISOR_shared_info;
-+      u32 version, sec, nsec;
-+      u64 delta;
--      retval = get_wallclock();
-+      do {
-+              version = s->wc_version;
-+              rmb();
-+              sec     = s->wc_sec;
-+              nsec    = s->wc_nsec;
-+              rmb();
-+      } while ((s->wc_version & 1) | (version ^ s->wc_version));
--      spin_unlock_irqrestore(&rtc_lock, flags);
-+      delta = local_clock() + (u64)sec * NSEC_PER_SEC + nsec;
-+      do_div(delta, NSEC_PER_SEC);
--      return retval;
-+      return delta;
- }
--int update_persistent_clock(struct timespec now)
-+int xen_update_persistent_clock(void)
- {
-+      if (!is_initial_xendomain())
-+              return -1;
-       mod_timer(&sync_xen_wallclock_timer, jiffies + 1);
--      return set_rtc_mmss(now.tv_sec);
-+      return 0;
- }
- extern void (*late_time_init)(void);
---- a/arch/x86/kernel/traps_32-xen.c
-+++ b/arch/x86/kernel/traps_32-xen.c
-@@ -79,7 +79,8 @@ char ignore_fpu_irq = 0;
-  * F0 0F bug workaround.. We have a special link segment
-  * for this.
-  */
--struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
-+gate_desc idt_table[256]
-+      __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
- #endif
- asmlinkage void divide_error(void);
-@@ -109,6 +110,34 @@ asmlinkage void machine_check(void);
- int kstack_depth_to_print = 24;
- static unsigned int code_bytes = 64;
-+void printk_address(unsigned long address, int reliable)
-+{
-+#ifdef CONFIG_KALLSYMS
-+      unsigned long offset = 0, symsize;
-+      const char *symname;
-+      char *modname;
-+      char *delim = ":";
-+      char namebuf[128];
-+      char reliab[4] = "";
-+
-+      symname = kallsyms_lookup(address, &symsize, &offset,
-+                                      &modname, namebuf);
-+      if (!symname) {
-+              printk(" [<%08lx>]\n", address);
-+              return;
-+      }
-+      if (!reliable)
-+              strcpy(reliab, "? ");
-+
-+      if (!modname)
-+              modname = delim = "";
-+      printk(" [<%08lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
-+              address, reliab, delim, modname, delim, symname, offset, symsize);
-+#else
-+      printk(" [<%08lx>]\n", address);
-+#endif
-+}
-+
- static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size)
- {
-       return  p > (void *)tinfo &&
-@@ -122,48 +151,35 @@ struct stack_frame {
- };
- static inline unsigned long print_context_stack(struct thread_info *tinfo,
--                              unsigned long *stack, unsigned long ebp,
-+                              unsigned long *stack, unsigned long bp,
-                               const struct stacktrace_ops *ops, void *data)
- {
--#ifdef        CONFIG_FRAME_POINTER
--      struct stack_frame *frame = (struct stack_frame *)ebp;
--      while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) {
--              struct stack_frame *next;
--              unsigned long addr;
-+      struct stack_frame *frame = (struct stack_frame *)bp;
--              addr = frame->return_address;
--              ops->address(data, addr);
--              /*
--               * break out of recursive entries (such as
--               * end_of_stack_stop_unwind_function). Also,
--               * we can never allow a frame pointer to
--               * move downwards!
--               */
--              next = frame->next_frame;
--              if (next <= frame)
--                      break;
--              frame = next;
--      }
--#else
-       while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {
-               unsigned long addr;
--              addr = *stack++;
--              if (__kernel_text_address(addr))
--                      ops->address(data, addr);
-+              addr = *stack;
-+              if (__kernel_text_address(addr)) {
-+                      if ((unsigned long) stack == bp + 4) {
-+                              ops->address(data, addr, 1);
-+                              frame = frame->next_frame;
-+                              bp = (unsigned long) frame;
-+                      } else {
-+                              ops->address(data, addr, bp == 0);
-+                      }
-+              }
-+              stack++;
-       }
--#endif
--      return ebp;
-+      return bp;
- }
- #define MSG(msg) ops->warning(data, msg)
- void dump_trace(struct task_struct *task, struct pt_regs *regs,
--              unsigned long *stack,
-+              unsigned long *stack, unsigned long bp,
-               const struct stacktrace_ops *ops, void *data)
- {
--      unsigned long ebp = 0;
--
-       if (!task)
-               task = current;
-@@ -171,17 +187,17 @@ void dump_trace(struct task_struct *task
-               unsigned long dummy;
-               stack = &dummy;
-               if (task != current)
--                      stack = (unsigned long *)task->thread.esp;
-+                      stack = (unsigned long *)task->thread.sp;
-       }
- #ifdef CONFIG_FRAME_POINTER
--      if (!ebp) {
-+      if (!bp) {
-               if (task == current) {
--                      /* Grab ebp right from our regs */
--                      asm ("movl %%ebp, %0" : "=r" (ebp) : );
-+                      /* Grab bp right from our regs */
-+                      asm ("movl %%ebp, %0" : "=r" (bp) : );
-               } else {
--                      /* ebp is the last reg pushed by switch_to */
--                      ebp = *(unsigned long *) task->thread.esp;
-+                      /* bp is the last reg pushed by switch_to */
-+                      bp = *(unsigned long *) task->thread.sp;
-               }
-       }
- #endif
-@@ -190,7 +206,7 @@ void dump_trace(struct task_struct *task
-               struct thread_info *context;
-               context = (struct thread_info *)
-                       ((unsigned long)stack & (~(THREAD_SIZE - 1)));
--              ebp = print_context_stack(context, stack, ebp, ops, data);
-+              bp = print_context_stack(context, stack, bp, ops, data);
-               /* Should be after the line below, but somewhere
-                  in early boot context comes out corrupted and we
-                  can't reference it -AK */
-@@ -225,9 +241,11 @@ static int print_trace_stack(void *data,
- /*
-  * Print one address/symbol entries per line.
-  */
--static void print_trace_address(void *data, unsigned long addr)
-+static void print_trace_address(void *data, unsigned long addr, int reliable)
- {
-       printk("%s [<%08lx>] ", (char *)data, addr);
-+      if (!reliable)
-+              printk("? ");
-       print_symbol("%s\n", addr);
-       touch_nmi_watchdog();
- }
-@@ -241,32 +259,32 @@ static const struct stacktrace_ops print
- static void
- show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
--                 unsigned long * stack, char *log_lvl)
-+              unsigned long *stack, unsigned long bp, char *log_lvl)
- {
--      dump_trace(task, regs, stack, &print_trace_ops, log_lvl);
-+      dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
-       printk("%s =======================\n", log_lvl);
- }
- void show_trace(struct task_struct *task, struct pt_regs *regs,
--              unsigned long * stack)
-+              unsigned long *stack, unsigned long bp)
- {
--      show_trace_log_lvl(task, regs, stack, "");
-+      show_trace_log_lvl(task, regs, stack, bp, "");
- }
- static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
--                             unsigned long *esp, char *log_lvl)
-+                     unsigned long *sp, unsigned long bp, char *log_lvl)
- {
-       unsigned long *stack;
-       int i;
--      if (esp == NULL) {
-+      if (sp == NULL) {
-               if (task)
--                      esp = (unsigned long*)task->thread.esp;
-+                      sp = (unsigned long*)task->thread.sp;
-               else
--                      esp = (unsigned long *)&esp;
-+                      sp = (unsigned long *)&sp;
-       }
--      stack = esp;
-+      stack = sp;
-       for(i = 0; i < kstack_depth_to_print; i++) {
-               if (kstack_end(stack))
-                       break;
-@@ -275,13 +293,13 @@ static void show_stack_log_lvl(struct ta
-               printk("%08lx ", *stack++);
-       }
-       printk("\n%sCall Trace:\n", log_lvl);
--      show_trace_log_lvl(task, regs, esp, log_lvl);
-+      show_trace_log_lvl(task, regs, sp, bp, log_lvl);
- }
--void show_stack(struct task_struct *task, unsigned long *esp)
-+void show_stack(struct task_struct *task, unsigned long *sp)
- {
-       printk("       ");
--      show_stack_log_lvl(task, NULL, esp, "");
-+      show_stack_log_lvl(task, NULL, sp, 0, "");
- }
- /*
-@@ -290,13 +308,19 @@ void show_stack(struct task_struct *task
- void dump_stack(void)
- {
-       unsigned long stack;
-+      unsigned long bp = 0;
-+
-+#ifdef CONFIG_FRAME_POINTER
-+      if (!bp)
-+              asm("movl %%ebp, %0" : "=r" (bp):);
-+#endif
-       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
-               current->pid, current->comm, print_tainted(),
-               init_utsname()->release,
-               (int)strcspn(init_utsname()->version, " "),
-               init_utsname()->version);
--      show_trace(current, NULL, &stack);
-+      show_trace(current, NULL, &stack, bp);
- }
- EXPORT_SYMBOL(dump_stack);
-@@ -315,30 +339,30 @@ void show_registers(struct pt_regs *regs
-        * time of the fault..
-        */
-       if (!user_mode_vm(regs)) {
--              u8 *eip;
-+              u8 *ip;
-               unsigned int code_prologue = code_bytes * 43 / 64;
-               unsigned int code_len = code_bytes;
-               unsigned char c;
-               printk("\n" KERN_EMERG "Stack: ");
--              show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
-+              show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
-               printk(KERN_EMERG "Code: ");
--              eip = (u8 *)regs->eip - code_prologue;
--              if (eip < (u8 *)PAGE_OFFSET ||
--                      probe_kernel_address(eip, c)) {
-+              ip = (u8 *)regs->ip - code_prologue;
-+              if (ip < (u8 *)PAGE_OFFSET ||
-+                      probe_kernel_address(ip, c)) {
-                       /* try starting at EIP */
--                      eip = (u8 *)regs->eip;
-+                      ip = (u8 *)regs->ip;
-                       code_len = code_len - code_prologue + 1;
-               }
--              for (i = 0; i < code_len; i++, eip++) {
--                      if (eip < (u8 *)PAGE_OFFSET ||
--                              probe_kernel_address(eip, c)) {
-+              for (i = 0; i < code_len; i++, ip++) {
-+                      if (ip < (u8 *)PAGE_OFFSET ||
-+                              probe_kernel_address(ip, c)) {
-                               printk(" Bad EIP value.");
-                               break;
-                       }
--                      if (eip == (u8 *)regs->eip)
-+                      if (ip == (u8 *)regs->ip)
-                               printk("<%02x> ", c);
-                       else
-                               printk("%02x ", c);
-@@ -347,18 +371,57 @@ void show_registers(struct pt_regs *regs
-       printk("\n");
- }     
--int is_valid_bugaddr(unsigned long eip)
-+int is_valid_bugaddr(unsigned long ip)
- {
-       unsigned short ud2;
--      if (eip < PAGE_OFFSET)
-+      if (ip < PAGE_OFFSET)
-               return 0;
--      if (probe_kernel_address((unsigned short *)eip, ud2))
-+      if (probe_kernel_address((unsigned short *)ip, ud2))
-               return 0;
-       return ud2 == 0x0b0f;
- }
-+static int die_counter;
-+
-+int __kprobes __die(const char * str, struct pt_regs * regs, long err)
-+{
-+      unsigned long sp;
-+      unsigned short ss;
-+
-+      printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
-+#ifdef CONFIG_PREEMPT
-+      printk("PREEMPT ");
-+#endif
-+#ifdef CONFIG_SMP
-+      printk("SMP ");
-+#endif
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+      printk("DEBUG_PAGEALLOC");
-+#endif
-+      printk("\n");
-+
-+      if (notify_die(DIE_OOPS, str, regs, err,
-+                              current->thread.trap_no, SIGSEGV) !=
-+                      NOTIFY_STOP) {
-+              show_registers(regs);
-+              /* Executive summary in case the oops scrolled away */
-+              sp = (unsigned long) (&regs->sp);
-+              savesegment(ss, ss);
-+              if (user_mode(regs)) {
-+                      sp = regs->sp;
-+                      ss = regs->ss & 0xffff;
-+              }
-+              printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
-+              print_symbol("%s", regs->ip);
-+              printk(" SS:ESP %04x:%08lx\n", ss, sp);
-+              return 0;
-+      } else {
-+              return 1;
-+      }
-+}
-+
- /*
-  * This is gone through when something in the kernel has done something bad and
-  * is about to be terminated.
-@@ -374,7 +437,6 @@ void die(const char * str, struct pt_reg
-               .lock_owner =           -1,
-               .lock_owner_depth =     0
-       };
--      static int die_counter;
-       unsigned long flags;
-       oops_enter();
-@@ -390,43 +452,13 @@ void die(const char * str, struct pt_reg
-               raw_local_irq_save(flags);
-       if (++die.lock_owner_depth < 3) {
--              unsigned long esp;
--              unsigned short ss;
--
--              report_bug(regs->eip, regs);
--
--              printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
--                     ++die_counter);
--#ifdef CONFIG_PREEMPT
--              printk("PREEMPT ");
--#endif
--#ifdef CONFIG_SMP
--              printk("SMP ");
--#endif
--#ifdef CONFIG_DEBUG_PAGEALLOC
--              printk("DEBUG_PAGEALLOC");
--#endif
--              printk("\n");
-+              report_bug(regs->ip, regs);
--              if (notify_die(DIE_OOPS, str, regs, err,
--                                      current->thread.trap_no, SIGSEGV) !=
--                              NOTIFY_STOP) {
--                      show_registers(regs);
--                      /* Executive summary in case the oops scrolled away */
--                      esp = (unsigned long) (&regs->esp);
--                      savesegment(ss, ss);
--                      if (user_mode(regs)) {
--                              esp = regs->esp;
--                              ss = regs->xss & 0xffff;
--                      }
--                      printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip);
--                      print_symbol("%s", regs->eip);
--                      printk(" SS:ESP %04x:%08lx\n", ss, esp);
--              }
--              else
-+              if (__die(str, regs, err))
-                       regs = NULL;
--      } else
-+      } else {
-               printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
-+      }
-       bust_spinlocks(0);
-       die.lock_owner = -1;
-@@ -462,7 +494,7 @@ static void __kprobes do_trap(int trapnr
- {
-       struct task_struct *tsk = current;
--      if (regs->eflags & VM_MASK) {
-+      if (regs->flags & VM_MASK) {
-               if (vm86)
-                       goto vm86_trap;
-               goto trap_signal;
-@@ -508,7 +540,7 @@ static void __kprobes do_trap(int trapnr
- }
- #define DO_ERROR(trapnr, signr, str, name) \
--fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+void do_##name(struct pt_regs * regs, long error_code) \
- { \
-       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-                                               == NOTIFY_STOP) \
-@@ -517,7 +549,7 @@ fastcall void do_##name(struct pt_regs *
- }
- #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \
--fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+void do_##name(struct pt_regs * regs, long error_code) \
- { \
-       siginfo_t info; \
-       if (irq) \
-@@ -533,7 +565,7 @@ fastcall void do_##name(struct pt_regs *
- }
- #define DO_VM86_ERROR(trapnr, signr, str, name) \
--fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+void do_##name(struct pt_regs * regs, long error_code) \
- { \
-       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-                                               == NOTIFY_STOP) \
-@@ -542,7 +574,7 @@ fastcall void do_##name(struct pt_regs *
- }
- #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
--fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+void do_##name(struct pt_regs * regs, long error_code) \
- { \
-       siginfo_t info; \
-       info.si_signo = signr; \
-@@ -556,13 +588,13 @@ fastcall void do_##name(struct pt_regs *
-       do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
- }
--DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
-+DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->ip)
- #ifndef CONFIG_KPROBES
- DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
- #endif
- DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
- DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
--DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip, 0)
-+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
- DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
- DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
- DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
-@@ -570,10 +602,10 @@ DO_ERROR(12, SIGBUS,  "stack segment", s
- DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
- DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1)
--fastcall void __kprobes do_general_protection(struct pt_regs * regs,
-+void __kprobes do_general_protection(struct pt_regs * regs,
-                                             long error_code)
- {
--      if (regs->eflags & VM_MASK)
-+      if (regs->flags & VM_MASK)
-               goto gp_in_vm86;
-       if (!user_mode(regs))
-@@ -582,11 +614,14 @@ fastcall void __kprobes do_general_prote
-       current->thread.error_code = error_code;
-       current->thread.trap_no = 13;
-       if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
--          printk_ratelimit())
-+          printk_ratelimit()) {
-               printk(KERN_INFO
--                  "%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
-+                  "%s[%d] general protection ip:%lx sp:%lx error:%lx",
-                   current->comm, task_pid_nr(current),
--                  regs->eip, regs->esp, error_code);
-+                  regs->ip, regs->sp, error_code);
-+              print_vma_addr(" in ", regs->ip);
-+              printk("\n");
-+      }
-       force_sig(SIGSEGV, current);
-       return;
-@@ -675,8 +710,8 @@ void __kprobes die_nmi(struct pt_regs *r
-       */
-       bust_spinlocks(1);
-       printk(KERN_EMERG "%s", msg);
--      printk(" on CPU%d, eip %08lx, registers:\n",
--              smp_processor_id(), regs->eip);
-+      printk(" on CPU%d, ip %08lx, registers:\n",
-+              smp_processor_id(), regs->ip);
-       show_registers(regs);
-       console_silent();
-       spin_unlock(&nmi_print_lock);
-@@ -733,7 +768,7 @@ static __kprobes void default_do_nmi(str
- static int ignore_nmis;
--fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
-+__kprobes void do_nmi(struct pt_regs * regs, long error_code)
- {
-       int cpu;
-@@ -762,7 +797,7 @@ void restart_nmi(void)
- }
- #ifdef CONFIG_KPROBES
--fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
-+void __kprobes do_int3(struct pt_regs *regs, long error_code)
- {
-       trace_hardirqs_fixup();
-@@ -798,7 +833,7 @@ fastcall void __kprobes do_int3(struct p
-  * find every occurrence of the TF bit that could be saved away even
-  * by user code)
-  */
--fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
-+void __kprobes do_debug(struct pt_regs * regs, long error_code)
- {
-       unsigned int condition;
-       struct task_struct *tsk = current;
-@@ -807,24 +842,30 @@ fastcall void __kprobes do_debug(struct 
-       get_debugreg(condition, 6);
-+      /*
-+       * The processor cleared BTF, so don't mark that we need it set.
-+       */
-+      clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
-+      tsk->thread.debugctlmsr = 0;
-+
-       if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
-                                       SIGTRAP) == NOTIFY_STOP)
-               return;
-       /* It's safe to allow irq's after DR6 has been saved */
--      if (regs->eflags & X86_EFLAGS_IF)
-+      if (regs->flags & X86_EFLAGS_IF)
-               local_irq_enable();
-       /* Mask out spurious debug traps due to lazy DR7 setting */
-       if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
--              if (!tsk->thread.debugreg[7])
-+              if (!tsk->thread.debugreg7)
-                       goto clear_dr7;
-       }
--      if (regs->eflags & VM_MASK)
-+      if (regs->flags & VM_MASK)
-               goto debug_vm86;
-       /* Save debug status register where ptrace can see it */
--      tsk->thread.debugreg[6] = condition;
-+      tsk->thread.debugreg6 = condition;
-       /*
-        * Single-stepping through TF: make sure we ignore any events in
-@@ -856,7 +897,7 @@ debug_vm86:
- clear_TF_reenable:
-       set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
--      regs->eflags &= ~TF_MASK;
-+      regs->flags &= ~TF_MASK;
-       return;
- }
-@@ -865,7 +906,7 @@ clear_TF_reenable:
-  * the correct behaviour even in the presence of the asynchronous
-  * IRQ13 behaviour
-  */
--void math_error(void __user *eip)
-+void math_error(void __user *ip)
- {
-       struct task_struct * task;
-       siginfo_t info;
-@@ -881,7 +922,7 @@ void math_error(void __user *eip)
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
--      info.si_addr = eip;
-+      info.si_addr = ip;
-       /*
-        * (~cwd & swd) will mask out exceptions that are not set to unmasked
-        * status.  0x3f is the exception bits in these regs, 0x200 is the
-@@ -924,13 +965,13 @@ void math_error(void __user *eip)
-       force_sig_info(SIGFPE, &info, task);
- }
--fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code)
-+void do_coprocessor_error(struct pt_regs * regs, long error_code)
- {
-       ignore_fpu_irq = 1;
--      math_error((void __user *)regs->eip);
-+      math_error((void __user *)regs->ip);
- }
--static void simd_math_error(void __user *eip)
-+static void simd_math_error(void __user *ip)
- {
-       struct task_struct * task;
-       siginfo_t info;
-@@ -946,7 +987,7 @@ static void simd_math_error(void __user 
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
--      info.si_addr = eip;
-+      info.si_addr = ip;
-       /*
-        * The SIMD FPU exceptions are handled a little differently, as there
-        * is only a single status/control register.  Thus, to determine which
-@@ -978,19 +1019,19 @@ static void simd_math_error(void __user 
-       force_sig_info(SIGFPE, &info, task);
- }
--fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
-+void do_simd_coprocessor_error(struct pt_regs * regs,
-                                         long error_code)
- {
-       if (cpu_has_xmm) {
-               /* Handle SIMD FPU exceptions on PIII+ processors. */
-               ignore_fpu_irq = 1;
--              simd_math_error((void __user *)regs->eip);
-+              simd_math_error((void __user *)regs->ip);
-       } else {
-               /*
-                * Handle strange cache flush from user space exception
-                * in all other cases.  This is undocumented behaviour.
-                */
--              if (regs->eflags & VM_MASK) {
-+              if (regs->flags & VM_MASK) {
-                       handle_vm86_fault((struct kernel_vm86_regs *)regs,
-                                         error_code);
-                       return;
-@@ -1003,7 +1044,7 @@ fastcall void do_simd_coprocessor_error(
- }
- #ifndef CONFIG_XEN
--fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
-+void do_spurious_interrupt_bug(struct pt_regs * regs,
-                                         long error_code)
- {
- #if 0
-@@ -1012,7 +1053,7 @@ fastcall void do_spurious_interrupt_bug(
- #endif
- }
--fastcall unsigned long patch_espfix_desc(unsigned long uesp,
-+unsigned long patch_espfix_desc(unsigned long uesp,
-                                         unsigned long kesp)
- {
-       struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
-@@ -1072,7 +1113,7 @@ asmlinkage void math_emulate(long arg)
-  * NB. All these are "trap gates" (i.e. events_mask isn't set) except
-  * for those that specify <dpl>|4 in the second field.
-  */
--static trap_info_t __cpuinitdata trap_table[] = {
-+static const trap_info_t __cpuinitconst trap_table[] = {
-       {  0, 0, __KERNEL_CS, (unsigned long)divide_error               },
-       {  1, 0|4, __KERNEL_CS, (unsigned long)debug                    },
-       {  3, 3|4, __KERNEL_CS, (unsigned long)int3                     },
-@@ -1105,17 +1146,12 @@ void __init trap_init(void)
-       if (ret)
-               printk("HYPERVISOR_set_trap_table failed: error %d\n", ret);
-+      /*
-+       * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
-+       * Generate a build-time error if the alignment is wrong.
-+       */
-+      BUILD_BUG_ON(offsetof(struct task_struct, thread.i387.fxsave) & 15);
-       if (cpu_has_fxsr) {
--              /*
--               * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
--               * Generates a compile-time "error: zero width for bit-field" if
--               * the alignment is wrong.
--               */
--              struct fxsrAlignAssert {
--                      int _:!(offsetof(struct task_struct,
--                                      thread.i387.fxsave) & 15);
--              };
--
-               printk(KERN_INFO "Enabling fast FPU save and restore... ");
-               set_in_cr4(X86_CR4_OSFXSR);
-               printk("done.\n");
---- a/arch/x86/kernel/traps_64-xen.c
-+++ b/arch/x86/kernel/traps_64-xen.c
-@@ -74,38 +74,41 @@ asmlinkage void alignment_check(void);
- asmlinkage void machine_check(void);
- asmlinkage void spurious_interrupt_bug(void);
-+static unsigned int code_bytes = 64;
-+
- static inline void conditional_sti(struct pt_regs *regs)
- {
--      if (regs->eflags & X86_EFLAGS_IF)
-+      if (regs->flags & X86_EFLAGS_IF)
-               local_irq_enable();
- }
- static inline void preempt_conditional_sti(struct pt_regs *regs)
- {
--      preempt_disable();
--      if (regs->eflags & X86_EFLAGS_IF)
-+      inc_preempt_count();
-+      if (regs->flags & X86_EFLAGS_IF)
-               local_irq_enable();
- }
- static inline void preempt_conditional_cli(struct pt_regs *regs)
- {
--      if (regs->eflags & X86_EFLAGS_IF)
-+      if (regs->flags & X86_EFLAGS_IF)
-               local_irq_disable();
-       /* Make sure to not schedule here because we could be running
-          on an exception stack. */
--      preempt_enable_no_resched();
-+      dec_preempt_count();
- }
- int kstack_depth_to_print = 12;
--#ifdef CONFIG_KALLSYMS
--void printk_address(unsigned long address)
-+void printk_address(unsigned long address, int reliable)
- {
-+#ifdef CONFIG_KALLSYMS
-       unsigned long offset = 0, symsize;
-       const char *symname;
-       char *modname;
-       char *delim = ":";
--      char namebuf[128];
-+      char namebuf[KSYM_NAME_LEN];
-+      char reliab[4] = "";
-       symname = kallsyms_lookup(address, &symsize, &offset,
-                                       &modname, namebuf);
-@@ -113,17 +116,17 @@ void printk_address(unsigned long addres
-               printk(" [<%016lx>]\n", address);
-               return;
-       }
-+      if (!reliable)
-+              strcpy(reliab, "? ");
-+
-       if (!modname)
--              modname = delim = "";           
--      printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n",
--              address, delim, modname, delim, symname, offset, symsize);
--}
-+              modname = delim = "";
-+      printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
-+              address, reliab, delim, modname, delim, symname, offset, symsize);
- #else
--void printk_address(unsigned long address)
--{
-       printk(" [<%016lx>]\n", address);
--}
- #endif
-+}
- static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
-                                       unsigned *usedp, char **idp)
-@@ -210,14 +213,53 @@ static unsigned long *in_exception_stack
-  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
-  */
--static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
-+static inline int valid_stack_ptr(struct thread_info *tinfo,
-+                      void *p, unsigned int size, void *end)
- {
--      void *t = (void *)tinfo;
--        return p > t && p < t + THREAD_SIZE - 3;
-+      void *t = tinfo;
-+      if (end) {
-+              if (p < end && p >= (end-THREAD_SIZE))
-+                      return 1;
-+              else
-+                      return 0;
-+      }
-+      return p > t && p < t + THREAD_SIZE - size;
-+}
-+
-+/* The form of the top of the frame on the stack */
-+struct stack_frame {
-+      struct stack_frame *next_frame;
-+      unsigned long return_address;
-+};
-+
-+
-+static inline unsigned long print_context_stack(struct thread_info *tinfo,
-+                              unsigned long *stack, unsigned long bp,
-+                              const struct stacktrace_ops *ops, void *data,
-+                              unsigned long *end)
-+{
-+      struct stack_frame *frame = (struct stack_frame *)bp;
-+
-+      while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
-+              unsigned long addr;
-+
-+              addr = *stack;
-+              if (__kernel_text_address(addr)) {
-+                      if ((unsigned long) stack == bp + 8) {
-+                              ops->address(data, addr, 1);
-+                              frame = frame->next_frame;
-+                              bp = (unsigned long) frame;
-+                      } else {
-+                              ops->address(data, addr, bp == 0);
-+                      }
-+              }
-+              stack++;
-+      }
-+      return bp;
- }
- void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
--              unsigned long *stack,
-+              unsigned long *stack, unsigned long bp,
-               const struct stacktrace_ops *ops, void *data)
- {
-       const unsigned cpu = get_cpu();
-@@ -227,36 +269,28 @@ void dump_trace(struct task_struct *tsk,
-       if (!tsk)
-               tsk = current;
-+      tinfo = task_thread_info(tsk);
-       if (!stack) {
-               unsigned long dummy;
-               stack = &dummy;
-               if (tsk && tsk != current)
--                      stack = (unsigned long *)tsk->thread.rsp;
-+                      stack = (unsigned long *)tsk->thread.sp;
-       }
--      /*
--       * Print function call entries within a stack. 'cond' is the
--       * "end of stackframe" condition, that the 'stack++'
--       * iteration will eventually trigger.
--       */
--#define HANDLE_STACK(cond) \
--      do while (cond) { \
--              unsigned long addr = *stack++; \
--              /* Use unlocked access here because except for NMIs     \
--                 we should be already protected against module unloads */ \
--              if (__kernel_text_address(addr)) { \
--                      /* \
--                       * If the address is either in the text segment of the \
--                       * kernel, or in the region which contains vmalloc'ed \
--                       * memory, it *may* be the address of a calling \
--                       * routine; if so, print it so that someone tracing \
--                       * down the cause of the crash will be able to figure \
--                       * out the call path that was taken. \
--                       */ \
--                      ops->address(data, addr);   \
--              } \
--      } while (0)
-+#ifdef CONFIG_FRAME_POINTER
-+      if (!bp) {
-+              if (tsk == current) {
-+                      /* Grab bp right from our regs */
-+                      asm("movq %%rbp, %0" : "=r" (bp):);
-+              } else {
-+                      /* bp is the last reg pushed by switch_to */
-+                      bp = *(unsigned long *) tsk->thread.sp;
-+              }
-+      }
-+#endif
-+
-+
-       /*
-        * Print function call entries in all stacks, starting at the
-@@ -272,7 +306,9 @@ void dump_trace(struct task_struct *tsk,
-               if (estack_end) {
-                       if (ops->stack(data, id) < 0)
-                               break;
--                      HANDLE_STACK (stack < estack_end);
-+
-+                      bp = print_context_stack(tinfo, stack, bp, ops,
-+                                                      data, estack_end);
-                       ops->stack(data, "<EOE>");
-                       /*
-                        * We link to the next stack via the
-@@ -290,7 +326,8 @@ void dump_trace(struct task_struct *tsk,
-                       if (stack >= irqstack && stack < irqstack_end) {
-                               if (ops->stack(data, "IRQ") < 0)
-                                       break;
--                              HANDLE_STACK (stack < irqstack_end);
-+                              bp = print_context_stack(tinfo, stack, bp,
-+                                              ops, data, irqstack_end);
-                               /*
-                                * We link to the next stack (which would be
-                                * the process stack normally) the last
-@@ -308,9 +345,7 @@ void dump_trace(struct task_struct *tsk,
-       /*
-        * This handles the process stack:
-        */
--      tinfo = task_thread_info(tsk);
--      HANDLE_STACK (valid_stack_ptr(tinfo, stack));
--#undef HANDLE_STACK
-+      bp = print_context_stack(tinfo, stack, bp, ops, data, NULL);
-       put_cpu();
- }
- EXPORT_SYMBOL(dump_trace);
-@@ -333,10 +368,10 @@ static int print_trace_stack(void *data,
-       return 0;
- }
--static void print_trace_address(void *data, unsigned long addr)
-+static void print_trace_address(void *data, unsigned long addr, int reliable)
- {
-       touch_nmi_watchdog();
--      printk_address(addr);
-+      printk_address(addr, reliable);
- }
- static const struct stacktrace_ops print_trace_ops = {
-@@ -347,15 +382,17 @@ static const struct stacktrace_ops print
- };
- void
--show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack)
-+show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
-+              unsigned long bp)
- {
-       printk("\nCall Trace:\n");
--      dump_trace(tsk, regs, stack, &print_trace_ops, NULL);
-+      dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL);
-       printk("\n");
- }
- static void
--_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
-+_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp,
-+                                                      unsigned long bp)
- {
-       unsigned long *stack;
-       int i;
-@@ -366,14 +403,14 @@ _show_stack(struct task_struct *tsk, str
-       // debugging aid: "show_stack(NULL, NULL);" prints the
-       // back trace for this cpu.
--      if (rsp == NULL) {
-+      if (sp == NULL) {
-               if (tsk)
--                      rsp = (unsigned long *)tsk->thread.rsp;
-+                      sp = (unsigned long *)tsk->thread.sp;
-               else
--                      rsp = (unsigned long *)&rsp;
-+                      sp = (unsigned long *)&sp;
-       }
--      stack = rsp;
-+      stack = sp;
-       for(i=0; i < kstack_depth_to_print; i++) {
-               if (stack >= irqstack && stack <= irqstack_end) {
-                       if (stack == irqstack_end) {
-@@ -389,12 +426,12 @@ _show_stack(struct task_struct *tsk, str
-               printk(" %016lx", *stack++);
-               touch_nmi_watchdog();
-       }
--      show_trace(tsk, regs, rsp);
-+      show_trace(tsk, regs, sp, bp);
- }
--void show_stack(struct task_struct *tsk, unsigned long * rsp)
-+void show_stack(struct task_struct *tsk, unsigned long * sp)
- {
--      _show_stack(tsk, NULL, rsp);
-+      _show_stack(tsk, NULL, sp, 0);
- }
- /*
-@@ -403,13 +440,19 @@ void show_stack(struct task_struct *tsk,
- void dump_stack(void)
- {
-       unsigned long dummy;
-+      unsigned long bp = 0;
-+
-+#ifdef CONFIG_FRAME_POINTER
-+      if (!bp)
-+              asm("movq %%rbp, %0" : "=r" (bp):);
-+#endif
-       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
-               current->pid, current->comm, print_tainted(),
-               init_utsname()->release,
-               (int)strcspn(init_utsname()->version, " "),
-               init_utsname()->version);
--      show_trace(NULL, NULL, &dummy);
-+      show_trace(NULL, NULL, &dummy, bp);
- }
- EXPORT_SYMBOL(dump_stack);
-@@ -417,12 +460,15 @@ EXPORT_SYMBOL(dump_stack);
- void show_registers(struct pt_regs *regs)
- {
-       int i;
--      int in_kernel = !user_mode(regs);
--      unsigned long rsp;
-+      unsigned long sp;
-       const int cpu = smp_processor_id();
-       struct task_struct *cur = cpu_pda(cpu)->pcurrent;
-+      u8 *ip;
-+      unsigned int code_prologue = code_bytes * 43 / 64;
-+      unsigned int code_len = code_bytes;
--      rsp = regs->rsp;
-+      sp = regs->sp;
-+      ip = (u8 *) regs->ip - code_prologue;
-       printk("CPU %d ", cpu);
-       __show_regs(regs);
-       printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
-@@ -432,45 +478,43 @@ void show_registers(struct pt_regs *regs
-        * When in-kernel, we also print out the stack and code at the
-        * time of the fault..
-        */
--      if (in_kernel) {
-+      if (!user_mode(regs)) {
-+              unsigned char c;
-               printk("Stack: ");
--              _show_stack(NULL, regs, (unsigned long*)rsp);
-+              _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
-+              printk("\n");
--              printk("\nCode: ");
--              if (regs->rip < PAGE_OFFSET)
--                      goto bad;
--
--              for (i=0; i<20; i++) {
--                      unsigned char c;
--                      if (__get_user(c, &((unsigned char*)regs->rip)[i])) {
--bad:
-+              printk(KERN_EMERG "Code: ");
-+              if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
-+                      /* try starting at RIP */
-+                      ip = (u8 *) regs->ip;
-+                      code_len = code_len - code_prologue + 1;
-+              }
-+              for (i = 0; i < code_len; i++, ip++) {
-+                      if (ip < (u8 *)PAGE_OFFSET ||
-+                                      probe_kernel_address(ip, c)) {
-                               printk(" Bad RIP value.");
-                               break;
-                       }
--                      printk("%02x ", c);
-+                      if (ip == (u8 *)regs->ip)
-+                              printk("<%02x> ", c);
-+                      else
-+                              printk("%02x ", c);
-               }
-       }
-       printk("\n");
- }     
--int is_valid_bugaddr(unsigned long rip)
-+int is_valid_bugaddr(unsigned long ip)
- {
-       unsigned short ud2;
--      if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2)))
-+      if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
-               return 0;
-       return ud2 == 0x0b0f;
- }
--#ifdef CONFIG_BUG
--void out_of_line_bug(void)
--{ 
--      BUG(); 
--} 
--EXPORT_SYMBOL(out_of_line_bug);
--#endif
--
- static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
- static int die_owner = -1;
- static unsigned int die_nest_count;
-@@ -498,7 +542,7 @@ unsigned __kprobes long oops_begin(void)
-       return flags;
- }
--void __kprobes oops_end(unsigned long flags)
-+void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
- { 
-       die_owner = -1;
-       bust_spinlocks(0);
-@@ -507,12 +551,17 @@ void __kprobes oops_end(unsigned long fl
-               /* Nest count reaches zero, release the lock. */
-               __raw_spin_unlock(&die_lock);
-       raw_local_irq_restore(flags);
-+      if (!regs) {
-+              oops_exit();
-+              return;
-+      }
-       if (panic_on_oops)
-               panic("Fatal exception");
-       oops_exit();
-+      do_exit(signr);
- }
--void __kprobes __die(const char * str, struct pt_regs * regs, long err)
-+int __kprobes __die(const char * str, struct pt_regs * regs, long err)
- {
-       static int die_counter;
-       printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
-@@ -526,15 +575,17 @@ void __kprobes __die(const char * str, s
-       printk("DEBUG_PAGEALLOC");
- #endif
-       printk("\n");
--      notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
-+      if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
-+              return 1;
-       show_registers(regs);
-       add_taint(TAINT_DIE);
-       /* Executive summary in case the oops scrolled away */
-       printk(KERN_ALERT "RIP ");
--      printk_address(regs->rip); 
--      printk(" RSP <%016lx>\n", regs->rsp); 
-+      printk_address(regs->ip, 1);
-+      printk(" RSP <%016lx>\n", regs->sp);
-       if (kexec_should_crash(current))
-               crash_kexec(regs);
-+      return 0;
- }
- void die(const char * str, struct pt_regs * regs, long err)
-@@ -542,11 +593,11 @@ void die(const char * str, struct pt_reg
-       unsigned long flags = oops_begin();
-       if (!user_mode(regs))
--              report_bug(regs->rip, regs);
-+              report_bug(regs->ip, regs);
--      __die(str, regs, err);
--      oops_end(flags);
--      do_exit(SIGSEGV); 
-+      if (__die(str, regs, err))
-+              regs = NULL;
-+      oops_end(flags, regs, SIGSEGV);
- }
- #if defined(CONFIG_X86_LOCAL_APIC) || defined(CONFIG_SYSCTL)
-@@ -564,10 +615,10 @@ void __kprobes die_nmi(char *str, struct
-               crash_kexec(regs);
-       if (do_panic || panic_on_oops)
-               panic("Non maskable interrupt");
--      oops_end(flags);
-+      oops_end(flags, NULL, SIGBUS);
-       nmi_exit();
-       local_irq_enable();
--      do_exit(SIGSEGV);
-+      do_exit(SIGBUS);
- }
- #endif
-@@ -592,11 +643,14 @@ static void __kprobes do_trap(int trapnr
-               tsk->thread.trap_no = trapnr;
-               if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
--                  printk_ratelimit())
-+                  printk_ratelimit()) {
-                       printk(KERN_INFO
--                             "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
-+                             "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
-                              tsk->comm, tsk->pid, str,
--                             regs->rip, regs->rsp, error_code); 
-+                             regs->ip, regs->sp, error_code);
-+                      print_vma_addr(" in ", regs->ip);
-+                      printk("\n");
-+              }
-               if (info)
-                       force_sig_info(signr, info, tsk);
-@@ -606,19 +660,12 @@ static void __kprobes do_trap(int trapnr
-       }
--      /* kernel trap */ 
--      {            
--              const struct exception_table_entry *fixup;
--              fixup = search_exception_tables(regs->rip);
--              if (fixup)
--                      regs->rip = fixup->fixup;
--              else {
--                      tsk->thread.error_code = error_code;
--                      tsk->thread.trap_no = trapnr;
--                      die(str, regs, error_code);
--              }
--              return;
-+      if (!fixup_exception(regs)) {
-+              tsk->thread.error_code = error_code;
-+              tsk->thread.trap_no = trapnr;
-+              die(str, regs, error_code);
-       }
-+      return;
- }
- #define DO_ERROR(trapnr, signr, str, name) \
-@@ -647,10 +694,10 @@ asmlinkage void do_##name(struct pt_regs
-       do_trap(trapnr, signr, str, regs, error_code, &info); \
- }
--DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->rip)
-+DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->ip)
- DO_ERROR( 4, SIGSEGV, "overflow", overflow)
- DO_ERROR( 5, SIGSEGV, "bounds", bounds)
--DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->rip)
-+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip)
- DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
- DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
- DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
-@@ -698,32 +745,28 @@ asmlinkage void __kprobes do_general_pro
-               tsk->thread.trap_no = 13;
-               if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
--                  printk_ratelimit())
-+                  printk_ratelimit()) {
-                       printk(KERN_INFO
--                     "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
-+                     "%s[%d] general protection ip:%lx sp:%lx error:%lx",
-                              tsk->comm, tsk->pid,
--                             regs->rip, regs->rsp, error_code); 
-+                             regs->ip, regs->sp, error_code);
-+                      print_vma_addr(" in ", regs->ip);
-+                      printk("\n");
-+              }
-               force_sig(SIGSEGV, tsk);
-               return;
-       } 
--      /* kernel gp */
--      {
--              const struct exception_table_entry *fixup;
--              fixup = search_exception_tables(regs->rip);
--              if (fixup) {
--                      regs->rip = fixup->fixup;
--                      return;
--              }
-+      if (fixup_exception(regs))
-+              return;
--              tsk->thread.error_code = error_code;
--              tsk->thread.trap_no = 13;
--              if (notify_die(DIE_GPF, "general protection fault", regs,
--                                      error_code, 13, SIGSEGV) == NOTIFY_STOP)
--                      return;
--              die("general protection fault", regs, error_code);
--      }
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = 13;
-+      if (notify_die(DIE_GPF, "general protection fault", regs,
-+                              error_code, 13, SIGSEGV) == NOTIFY_STOP)
-+              return;
-+      die("general protection fault", regs, error_code);
- }
- static __kprobes void
-@@ -833,15 +876,15 @@ asmlinkage __kprobes struct pt_regs *syn
- {
-       struct pt_regs *regs = eregs;
-       /* Did already sync */
--      if (eregs == (struct pt_regs *)eregs->rsp)
-+      if (eregs == (struct pt_regs *)eregs->sp)
-               ;
-       /* Exception from user space */
-       else if (user_mode(eregs))
-               regs = task_pt_regs(current);
-       /* Exception from kernel and interrupts are enabled. Move to
-          kernel process stack. */
--      else if (eregs->eflags & X86_EFLAGS_IF)
--              regs = (struct pt_regs *)(eregs->rsp -= sizeof(struct pt_regs));
-+      else if (eregs->flags & X86_EFLAGS_IF)
-+              regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
-       if (eregs != regs)
-               *regs = *eregs;
-       return regs;
-@@ -859,6 +902,12 @@ asmlinkage void __kprobes do_debug(struc
-       get_debugreg(condition, 6);
-+      /*
-+       * The processor cleared BTF, so don't mark that we need it set.
-+       */
-+      clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
-+      tsk->thread.debugctlmsr = 0;
-+
-       if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
-                                               SIGTRAP) == NOTIFY_STOP)
-               return;
-@@ -874,27 +923,14 @@ asmlinkage void __kprobes do_debug(struc
-       tsk->thread.debugreg6 = condition;
--      /* Mask out spurious TF errors due to lazy TF clearing */
-+
-+      /*
-+       * Single-stepping through TF: make sure we ignore any events in
-+       * kernel space (but re-enable TF when returning to user mode).
-+       */
-       if (condition & DR_STEP) {
--              /*
--               * The TF error should be masked out only if the current
--               * process is not traced and if the TRAP flag has been set
--               * previously by a tracing process (condition detected by
--               * the PT_DTRACE flag); remember that the i386 TRAP flag
--               * can be modified by the process itself in user mode,
--               * allowing programs to debug themselves without the ptrace()
--               * interface.
--               */
-                 if (!user_mode(regs))
-                        goto clear_TF_reenable;
--              /*
--               * Was the TF flag set by a debugger? If so, clear it now,
--               * so that register information is correct.
--               */
--              if (tsk->ptrace & PT_DTRACE) {
--                      regs->eflags &= ~TF_MASK;
--                      tsk->ptrace &= ~PT_DTRACE;
--              }
-       }
-       /* Ok, finally something we can handle */
-@@ -903,7 +939,7 @@ asmlinkage void __kprobes do_debug(struc
-       info.si_signo = SIGTRAP;
-       info.si_errno = 0;
-       info.si_code = TRAP_BRKPT;
--      info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
-+      info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
-       force_sig_info(SIGTRAP, &info, tsk);
- clear_dr7:
-@@ -913,18 +949,15 @@ clear_dr7:
- clear_TF_reenable:
-       set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
--      regs->eflags &= ~TF_MASK;
-+      regs->flags &= ~X86_EFLAGS_TF;
-       preempt_conditional_cli(regs);
- }
- static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
- {
--      const struct exception_table_entry *fixup;
--      fixup = search_exception_tables(regs->rip);
--      if (fixup) {
--              regs->rip = fixup->fixup;
-+      if (fixup_exception(regs))
-               return 1;
--      }
-+
-       notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
-       /* Illegal floating point operation in the kernel */
-       current->thread.trap_no = trapnr;
-@@ -939,7 +972,7 @@ static int kernel_math_error(struct pt_r
-  */
- asmlinkage void do_coprocessor_error(struct pt_regs *regs)
- {
--      void __user *rip = (void __user *)(regs->rip);
-+      void __user *ip = (void __user *)(regs->ip);
-       struct task_struct * task;
-       siginfo_t info;
-       unsigned short cwd, swd;
-@@ -959,7 +992,7 @@ asmlinkage void do_coprocessor_error(str
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
--      info.si_addr = rip;
-+      info.si_addr = ip;
-       /*
-        * (~cwd & swd) will mask out exceptions that are not set to unmasked
-        * status.  0x3f is the exception bits in these regs, 0x200 is the
-@@ -1008,7 +1041,7 @@ asmlinkage void bad_intr(void)
- asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
- {
--      void __user *rip = (void __user *)(regs->rip);
-+      void __user *ip = (void __user *)(regs->ip);
-       struct task_struct * task;
-       siginfo_t info;
-       unsigned short mxcsr;
-@@ -1028,7 +1061,7 @@ asmlinkage void do_simd_coprocessor_erro
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
--      info.si_addr = rip;
-+      info.si_addr = ip;
-       /*
-        * The SIMD FPU exceptions are handled a little differently, as there
-        * is only a single status/control register.  Thus, to determine which
-@@ -1092,13 +1125,14 @@ asmlinkage void math_state_restore(void)
-       task_thread_info(me)->status |= TS_USEDFPU;
-       me->fpu_counter++;
- }
-+EXPORT_SYMBOL_GPL(math_state_restore);
- /*
-  * NB. All these are "interrupt gates" (i.e. events_mask is set) because we
-  * specify <dpl>|4 in the second field.
-  */
--static trap_info_t __cpuinitdata trap_table[] = {
-+static const trap_info_t __cpuinitconst trap_table[] = {
-         {  0, 0|4, __KERNEL_CS, (unsigned long)divide_error               },
-         {  1, 0|4, __KERNEL_CS, (unsigned long)debug                      },
-         {  3, 3|4, __KERNEL_CS, (unsigned long)int3                       },
-@@ -1169,3 +1203,14 @@ static int __init kstack_setup(char *s)
-       return 0;
- }
- early_param("kstack", kstack_setup);
-+
-+
-+static int __init code_bytes_setup(char *s)
-+{
-+      code_bytes = simple_strtoul(s, NULL, 0);
-+      if (code_bytes > 8192)
-+              code_bytes = 8192;
-+
-+      return 1;
-+}
-+__setup("code_bytes=", code_bytes_setup);
---- a/arch/x86/kernel/vsyscall_64-xen.c
-+++ b/arch/x86/kernel/vsyscall_64-xen.c
-@@ -43,12 +43,7 @@
- #include <asm/vgtod.h>
- #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
--#define __syscall_clobber "r11","rcx","memory"
--#define __pa_vsymbol(x)                       \
--      ({unsigned long v;              \
--      extern char __vsyscall_0;       \
--        asm("" : "=r" (v) : "0" (x)); \
--        ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
-+#define __syscall_clobber "r11","cx","memory"
- /*
-  * vsyscall_gtod_data contains data that is :
-@@ -102,7 +97,7 @@ static __always_inline void do_get_tz(st
- static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
- {
-       int ret;
--      asm volatile("vsysc2: syscall"
-+      asm volatile("syscall"
-               : "=a" (ret)
-               : "0" (__NR_gettimeofday),"D" (tv),"S" (tz)
-               : __syscall_clobber );
-@@ -112,7 +107,7 @@ static __always_inline int gettimeofday(
- static __always_inline long time_syscall(long *t)
- {
-       long secs;
--      asm volatile("vsysc1: syscall"
-+      asm volatile("syscall"
-               : "=a" (secs)
-               : "0" (__NR_time),"D" (t) : __syscall_clobber);
-       return secs;
-@@ -190,7 +185,7 @@ time_t __vsyscall(1) vtime(time_t *t)
- long __vsyscall(2)
- vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
- {
--      unsigned int dummy, p;
-+      unsigned int p;
-       unsigned long j = 0;
-       /* Fast cache - only recompute value once per jiffies and avoid
-@@ -205,7 +200,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s
-               p = tcache->blob[1];
-       } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
-               /* Load per CPU data from RDTSCP */
--              rdtscp(dummy, dummy, p);
-+              native_read_tscp(&p);
-       } else {
-               /* Load per CPU data from GDT */
-               asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
-@@ -228,42 +223,11 @@ long __vsyscall(3) venosys_1(void)
- #ifdef CONFIG_SYSCTL
--#define SYSCALL 0x050f
--#define NOP2    0x9090
--
--/*
-- * NOP out syscall in vsyscall page when not needed.
-- */
--static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
--                        void __user *buffer, size_t *lenp, loff_t *ppos)
-+static int
-+vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
-+                     void __user *buffer, size_t *lenp, loff_t *ppos)
- {
--      extern u16 vsysc1, vsysc2;
--      u16 __iomem *map1;
--      u16 __iomem *map2;
--      int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
--      if (!write)
--              return ret;
--      /* gcc has some trouble with __va(__pa()), so just do it this
--         way. */
--      map1 = ioremap(__pa_vsymbol(&vsysc1), 2);
--      if (!map1)
--              return -ENOMEM;
--      map2 = ioremap(__pa_vsymbol(&vsysc2), 2);
--      if (!map2) {
--              ret = -ENOMEM;
--              goto out;
--      }
--      if (!vsyscall_gtod_data.sysctl_enabled) {
--              writew(SYSCALL, map1);
--              writew(SYSCALL, map2);
--      } else {
--              writew(NOP2, map1);
--              writew(NOP2, map2);
--      }
--      iounmap(map2);
--out:
--      iounmap(map1);
--      return ret;
-+      return proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
- }
- static ctl_table kernel_table2[] = {
-@@ -279,7 +243,6 @@ static ctl_table kernel_root_table2[] = 
-         .child = kernel_table2 },
-       {}
- };
--
- #endif
- /* Assume __initcall executes before all user space. Hopefully kmod
-@@ -301,7 +264,7 @@ static void __cpuinit vsyscall_set_cpu(i
-       d |= cpu;
-       d |= (node & 0xf) << 12;
-       d |= (node >> 4) << 48;
--      if (HYPERVISOR_update_descriptor(virt_to_machine(cpu_gdt(cpu)
-+      if (HYPERVISOR_update_descriptor(virt_to_machine(get_cpu_gdt_table(cpu)
-                                                        + GDT_ENTRY_PER_CPU),
-                                        d))
-               BUG();
-@@ -322,7 +285,7 @@ cpu_vsyscall_notifier(struct notifier_bl
-       return NOTIFY_DONE;
- }
--static void __init map_vsyscall(void)
-+void __init map_vsyscall(void)
- {
-       extern char __vsyscall_0;
-       unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0);
-@@ -338,7 +301,6 @@ static int __init vsyscall_init(void)
-       BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
-       BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
-       BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu));
--      map_vsyscall();
- #ifdef CONFIG_XEN
-       vsyscall_gtod_data.sysctl_enabled = 0; /* disable vgettimeofay() */
-       if (boot_cpu_has(X86_FEATURE_RDTSCP))
---- a/arch/x86/kernel/xen_entry_64.S
-+++ /dev/null
-@@ -1,36 +0,0 @@
--/*
-- * Copied from arch/xen/i386/kernel/entry.S
-- */                        
--/* Offsets into shared_info_t. */                
--#define evtchn_upcall_pending         /* 0 */
--#define evtchn_upcall_mask            1
--
--#define sizeof_vcpu_shift             6
--
--#ifdef CONFIG_SMP
--//#define preempt_disable(reg)        incl threadinfo_preempt_count(reg)
--//#define preempt_enable(reg) decl threadinfo_preempt_count(reg)
--#define preempt_disable(reg)
--#define preempt_enable(reg)
--#define XEN_GET_VCPU_INFO(reg)        preempt_disable(%rbp)                   ; \
--                              movq %gs:pda_cpunumber,reg              ; \
--                              shl  $32, reg                           ; \
--                              shr  $32-sizeof_vcpu_shift,reg          ; \
--                              addq HYPERVISOR_shared_info,reg
--#define XEN_PUT_VCPU_INFO(reg)        preempt_enable(%rbp)                    ; \
--#define XEN_PUT_VCPU_INFO_fixup .byte 0xff,0xff,0xff
--#else
--#define XEN_GET_VCPU_INFO(reg)        movq HYPERVISOR_shared_info,reg
--#define XEN_PUT_VCPU_INFO(reg)
--#define XEN_PUT_VCPU_INFO_fixup
--#endif
--
--#define XEN_LOCKED_BLOCK_EVENTS(reg)  movb $1,evtchn_upcall_mask(reg)
--#define XEN_LOCKED_UNBLOCK_EVENTS(reg)        movb $0,evtchn_upcall_mask(reg)
--#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg)                  ; \
--                              XEN_LOCKED_BLOCK_EVENTS(reg)            ; \
--                              XEN_PUT_VCPU_INFO(reg)
--#define XEN_UNBLOCK_EVENTS(reg)       XEN_GET_VCPU_INFO(reg)                  ; \
--                              XEN_LOCKED_UNBLOCK_EVENTS(reg)          ; \
--                              XEN_PUT_VCPU_INFO(reg)
--#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
---- a/arch/x86/mach-xen/setup.c
-+++ b/arch/x86/mach-xen/setup.c
-@@ -161,15 +161,12 @@ void __init machine_specific_arch_setup(
-       /* Do an early initialization of the fixmap area */
-       {
--              extern pte_t swapper_pg_pmd[PTRS_PER_PTE];
-+              extern pte_t swapper_pg_fixmap[PTRS_PER_PTE];
-               unsigned long addr = __fix_to_virt(FIX_EARLYCON_MEM_BASE);
--              pgd_t *pgd = (pgd_t *)xen_start_info->pt_base;
--              pud_t *pud = pud_offset(pgd + pgd_index(addr), addr);
-+              pud_t *pud = pud_offset(swapper_pg_dir + pgd_index(addr), addr);
-               pmd_t *pmd = pmd_offset(pud, addr);
--              swapper_pg_dir = pgd;
--              init_mm.pgd    = pgd;
--              make_lowmem_page_readonly(swapper_pg_pmd, XENFEAT_writable_page_tables);
--              set_pmd(pmd, __pmd(__pa_symbol(swapper_pg_pmd) | _PAGE_TABLE));
-+              make_lowmem_page_readonly(swapper_pg_fixmap, XENFEAT_writable_page_tables);
-+              set_pmd(pmd, __pmd(__pa_symbol(swapper_pg_fixmap) | _PAGE_TABLE));
-       }
- }
---- a/arch/x86/mm/fault_32-xen.c
-+++ /dev/null
-@@ -1,757 +0,0 @@
--/*
-- *  linux/arch/i386/mm/fault.c
-- *
-- *  Copyright (C) 1995  Linus Torvalds
-- */
--
--#include <linux/signal.h>
--#include <linux/sched.h>
--#include <linux/kernel.h>
--#include <linux/errno.h>
--#include <linux/string.h>
--#include <linux/types.h>
--#include <linux/ptrace.h>
--#include <linux/mman.h>
--#include <linux/mm.h>
--#include <linux/smp.h>
--#include <linux/interrupt.h>
--#include <linux/init.h>
--#include <linux/tty.h>
--#include <linux/vt_kern.h>            /* For unblank_screen() */
--#include <linux/highmem.h>
--#include <linux/bootmem.h>            /* for max_low_pfn */
--#include <linux/vmalloc.h>
--#include <linux/module.h>
--#include <linux/kprobes.h>
--#include <linux/uaccess.h>
--#include <linux/kdebug.h>
--#include <linux/kprobes.h>
--
--#include <asm/system.h>
--#include <asm/desc.h>
--#include <asm/segment.h>
--
--extern void die(const char *,struct pt_regs *,long);
--
--#ifdef CONFIG_KPROBES
--static inline int notify_page_fault(struct pt_regs *regs)
--{
--      int ret = 0;
--
--      /* kprobe_running() needs smp_processor_id() */
--      if (!user_mode_vm(regs)) {
--              preempt_disable();
--              if (kprobe_running() && kprobe_fault_handler(regs, 14))
--                      ret = 1;
--              preempt_enable();
--      }
--
--      return ret;
--}
--#else
--static inline int notify_page_fault(struct pt_regs *regs)
--{
--      return 0;
--}
--#endif
--
--/*
-- * Return EIP plus the CS segment base.  The segment limit is also
-- * adjusted, clamped to the kernel/user address space (whichever is
-- * appropriate), and returned in *eip_limit.
-- *
-- * The segment is checked, because it might have been changed by another
-- * task between the original faulting instruction and here.
-- *
-- * If CS is no longer a valid code segment, or if EIP is beyond the
-- * limit, or if it is a kernel address when CS is not a kernel segment,
-- * then the returned value will be greater than *eip_limit.
-- * 
-- * This is slow, but is very rarely executed.
-- */
--static inline unsigned long get_segment_eip(struct pt_regs *regs,
--                                          unsigned long *eip_limit)
--{
--      unsigned long eip = regs->eip;
--      unsigned seg = regs->xcs & 0xffff;
--      u32 seg_ar, seg_limit, base, *desc;
--
--      /* Unlikely, but must come before segment checks. */
--      if (unlikely(regs->eflags & VM_MASK)) {
--              base = seg << 4;
--              *eip_limit = base + 0xffff;
--              return base + (eip & 0xffff);
--      }
--
--      /* The standard kernel/user address space limit. */
--      *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg;
--      
--      /* By far the most common cases. */
--      if (likely(SEGMENT_IS_FLAT_CODE(seg)))
--              return eip;
--
--      /* Check the segment exists, is within the current LDT/GDT size,
--         that kernel/user (ring 0..3) has the appropriate privilege,
--         that it's a code segment, and get the limit. */
--      __asm__ ("larl %3,%0; lsll %3,%1"
--               : "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg));
--      if ((~seg_ar & 0x9800) || eip > seg_limit) {
--              *eip_limit = 0;
--              return 1;        /* So that returned eip > *eip_limit. */
--      }
--
--      /* Get the GDT/LDT descriptor base. 
--         When you look for races in this code remember that
--         LDT and other horrors are only used in user space. */
--      if (seg & (1<<2)) {
--              /* Must lock the LDT while reading it. */
--              mutex_lock(&current->mm->context.lock);
--              desc = current->mm->context.ldt;
--              desc = (void *)desc + (seg & ~7);
--      } else {
--              /* Must disable preemption while reading the GDT. */
--              desc = (u32 *)get_cpu_gdt_table(get_cpu());
--              desc = (void *)desc + (seg & ~7);
--      }
--
--      /* Decode the code segment base from the descriptor */
--      base = get_desc_base((unsigned long *)desc);
--
--      if (seg & (1<<2)) { 
--              mutex_unlock(&current->mm->context.lock);
--      } else
--              put_cpu();
--
--      /* Adjust EIP and segment limit, and clamp at the kernel limit.
--         It's legitimate for segments to wrap at 0xffffffff. */
--      seg_limit += base;
--      if (seg_limit < *eip_limit && seg_limit >= base)
--              *eip_limit = seg_limit;
--      return eip + base;
--}
--
--/* 
-- * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
-- * Check that here and ignore it.
-- */
--static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
--{ 
--      unsigned long limit;
--      unsigned char *instr = (unsigned char *)get_segment_eip (regs, &limit);
--      int scan_more = 1;
--      int prefetch = 0; 
--      int i;
--
--      for (i = 0; scan_more && i < 15; i++) { 
--              unsigned char opcode;
--              unsigned char instr_hi;
--              unsigned char instr_lo;
--
--              if (instr > (unsigned char *)limit)
--                      break;
--              if (probe_kernel_address(instr, opcode))
--                      break; 
--
--              instr_hi = opcode & 0xf0; 
--              instr_lo = opcode & 0x0f; 
--              instr++;
--
--              switch (instr_hi) { 
--              case 0x20:
--              case 0x30:
--                      /* Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. */
--                      scan_more = ((instr_lo & 7) == 0x6);
--                      break;
--                      
--              case 0x60:
--                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
--                      scan_more = (instr_lo & 0xC) == 0x4;
--                      break;          
--              case 0xF0:
--                      /* 0xF0, 0xF2, and 0xF3 are valid prefixes */
--                      scan_more = !instr_lo || (instr_lo>>1) == 1;
--                      break;                  
--              case 0x00:
--                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
--                      scan_more = 0;
--                      if (instr > (unsigned char *)limit)
--                              break;
--                      if (probe_kernel_address(instr, opcode))
--                              break;
--                      prefetch = (instr_lo == 0xF) &&
--                              (opcode == 0x0D || opcode == 0x18);
--                      break;                  
--              default:
--                      scan_more = 0;
--                      break;
--              } 
--      }
--      return prefetch;
--}
--
--static inline int is_prefetch(struct pt_regs *regs, unsigned long addr,
--                            unsigned long error_code)
--{
--      if (unlikely(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
--                   boot_cpu_data.x86 >= 6)) {
--              /* Catch an obscure case of prefetch inside an NX page. */
--              if (nx_enabled && (error_code & 16))
--                      return 0;
--              return __is_prefetch(regs, addr);
--      }
--      return 0;
--} 
--
--static noinline void force_sig_info_fault(int si_signo, int si_code,
--      unsigned long address, struct task_struct *tsk)
--{
--      siginfo_t info;
--
--      info.si_signo = si_signo;
--      info.si_errno = 0;
--      info.si_code = si_code;
--      info.si_addr = (void __user *)address;
--      force_sig_info(si_signo, &info, tsk);
--}
--
--fastcall void do_invalid_op(struct pt_regs *, unsigned long);
--
--#ifdef CONFIG_X86_PAE
--static void dump_fault_path(unsigned long address)
--{
--      unsigned long *p, page;
--      unsigned long mfn; 
--
--      page = read_cr3();
--      p  = (unsigned long *)__va(page);
--      p += (address >> 30) * 2;
--      printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
--      if (p[0] & _PAGE_PRESENT) {
--              mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
--              page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
--              p  = (unsigned long *)__va(page);
--              address &= 0x3fffffff;
--              p += (address >> 21) * 2;
--              printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", 
--                     page, p[1], p[0]);
--              mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
--#ifdef CONFIG_HIGHPTE
--              if (mfn_to_pfn(mfn) >= highstart_pfn)
--                      return;
--#endif
--              if ((p[0] & _PAGE_PRESENT) && !(p[0] & _PAGE_PSE)) {
--                      page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
--                      p  = (unsigned long *) __va(page);
--                      address &= 0x001fffff;
--                      p += (address >> 12) * 2;
--                      printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n",
--                             page, p[1], p[0]);
--              }
--      }
--}
--#else
--static void dump_fault_path(unsigned long address)
--{
--      unsigned long page;
--
--      page = read_cr3();
--      page = ((unsigned long *) __va(page))[address >> PGDIR_SHIFT];
--      printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
--             machine_to_phys(page));
--      /*
--       * We must not directly access the pte in the highpte
--       * case if the page table is located in highmem.
--       * And lets rather not kmap-atomic the pte, just in case
--       * it's allocated already.
--       */
--      if ((machine_to_phys(page) >> PAGE_SHIFT) < max_low_pfn
--          && (page & _PAGE_PRESENT)
--          && !(page & _PAGE_PSE)) {
--              page = machine_to_phys(page & PAGE_MASK);
--              page = ((unsigned long *) __va(page))[(address >> PAGE_SHIFT)
--                                                    & (PTRS_PER_PTE - 1)];
--              printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page,
--                     machine_to_phys(page));
--      }
--}
--#endif
--
--static int spurious_fault(struct pt_regs *regs,
--                        unsigned long address,
--                        unsigned long error_code)
--{
--      pgd_t *pgd;
--      pud_t *pud;
--      pmd_t *pmd;
--      pte_t *pte;
--
--      /* Reserved-bit violation or user access to kernel space? */
--      if (error_code & 0x0c)
--              return 0;
--
--      pgd = init_mm.pgd + pgd_index(address);
--      if (!pgd_present(*pgd))
--              return 0;
--
--      pud = pud_offset(pgd, address);
--      if (!pud_present(*pud))
--              return 0;
--
--      pmd = pmd_offset(pud, address);
--      if (!pmd_present(*pmd))
--              return 0;
--
--      pte = pte_offset_kernel(pmd, address);
--      if (!pte_present(*pte))
--              return 0;
--      if ((error_code & 0x02) && !pte_write(*pte))
--              return 0;
--#ifdef CONFIG_X86_PAE
--      if ((error_code & 0x10) && (__pte_val(*pte) & _PAGE_NX))
--              return 0;
--#endif
--
--      return 1;
--}
--
--static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
--{
--      unsigned index = pgd_index(address);
--      pgd_t *pgd_k;
--      pud_t *pud, *pud_k;
--      pmd_t *pmd, *pmd_k;
--
--      pgd += index;
--      pgd_k = init_mm.pgd + index;
--
--      if (!pgd_present(*pgd_k))
--              return NULL;
--
--      /*
--       * set_pgd(pgd, *pgd_k); here would be useless on PAE
--       * and redundant with the set_pmd() on non-PAE. As would
--       * set_pud.
--       */
--
--      pud = pud_offset(pgd, address);
--      pud_k = pud_offset(pgd_k, address);
--      if (!pud_present(*pud_k))
--              return NULL;
--
--      pmd = pmd_offset(pud, address);
--      pmd_k = pmd_offset(pud_k, address);
--      if (!pmd_present(*pmd_k))
--              return NULL;
--      if (!pmd_present(*pmd)) {
--              bool lazy = x86_read_percpu(xen_lazy_mmu);
--
--              x86_write_percpu(xen_lazy_mmu, false);
--#if CONFIG_XEN_COMPAT > 0x030002
--              set_pmd(pmd, *pmd_k);
--#else
--              /*
--               * When running on older Xen we must launder *pmd_k through
--               * pmd_val() to ensure that _PAGE_PRESENT is correctly set.
--               */
--              set_pmd(pmd, __pmd(pmd_val(*pmd_k)));
--#endif
--              x86_write_percpu(xen_lazy_mmu, lazy);
--      } else
--              BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
--      return pmd_k;
--}
--
--/*
-- * Handle a fault on the vmalloc or module mapping area
-- *
-- * This assumes no large pages in there.
-- */
--static inline int vmalloc_fault(unsigned long address)
--{
--      unsigned long pgd_paddr;
--      pmd_t *pmd_k;
--      pte_t *pte_k;
--      /*
--       * Synchronize this task's top level page-table
--       * with the 'reference' page table.
--       *
--       * Do _not_ use "current" here. We might be inside
--       * an interrupt in the middle of a task switch..
--       */
--      pgd_paddr = read_cr3();
--      pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
--      if (!pmd_k)
--              return -1;
--      pte_k = pte_offset_kernel(pmd_k, address);
--      if (!pte_present(*pte_k))
--              return -1;
--      return 0;
--}
--
--int show_unhandled_signals = 1;
--
--/*
-- * This routine handles page faults.  It determines the address,
-- * and the problem, and then passes it off to one of the appropriate
-- * routines.
-- *
-- * error_code:
-- *    bit 0 == 0 means no page found, 1 means protection fault
-- *    bit 1 == 0 means read, 1 means write
-- *    bit 2 == 0 means kernel, 1 means user-mode
-- *    bit 3 == 1 means use of reserved bit detected
-- *    bit 4 == 1 means fault was an instruction fetch
-- */
--fastcall void __kprobes do_page_fault(struct pt_regs *regs,
--                                    unsigned long error_code)
--{
--      struct task_struct *tsk;
--      struct mm_struct *mm;
--      struct vm_area_struct * vma;
--      unsigned long address;
--      int write, si_code;
--      int fault;
--
--      /*
--       * We can fault from pretty much anywhere, with unknown IRQ state.
--       */
--      trace_hardirqs_fixup();
--
--      /* get the address */
--        address = read_cr2();
--
--      /* Set the "privileged fault" bit to something sane. */
--      error_code &= ~4;
--      error_code |= (regs->xcs & 2) << 1;
--      if (regs->eflags & X86_EFLAGS_VM)
--              error_code |= 4;
--
--      tsk = current;
--
--      si_code = SEGV_MAPERR;
--
--      /*
--       * We fault-in kernel-space virtual memory on-demand. The
--       * 'reference' page table is init_mm.pgd.
--       *
--       * NOTE! We MUST NOT take any locks for this case. We may
--       * be in an interrupt or a critical region, and should
--       * only copy the information from the master page table,
--       * nothing more.
--       *
--       * This verifies that the fault happens in kernel space
--       * (error_code & 4) == 0, and that the fault was not a
--       * protection error (error_code & 9) == 0.
--       */
--      if (unlikely(address >= TASK_SIZE)) {
--#ifdef CONFIG_XEN
--              /* Faults in hypervisor area can never be patched up. */
--              if (address >= hypervisor_virt_start)
--                      goto bad_area_nosemaphore;
--#endif
--              if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0)
--                      return;
--              /* Can take a spurious fault if mapping changes R/O -> R/W. */
--              if (spurious_fault(regs, address, error_code))
--                      return;
--              if (notify_page_fault(regs))
--                      return;
--              /* 
--               * Don't take the mm semaphore here. If we fixup a prefetch
--               * fault we could otherwise deadlock.
--               */
--              goto bad_area_nosemaphore;
--      }
--
--      if (notify_page_fault(regs))
--              return;
--
--      /* It's safe to allow irq's after cr2 has been saved and the vmalloc
--         fault has been handled. */
--      if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
--              local_irq_enable();
--
--      mm = tsk->mm;
--
--      /*
--       * If we're in an interrupt, have no user context or are running in an
--       * atomic region then we must not take the fault..
--       */
--      if (in_atomic() || !mm)
--              goto bad_area_nosemaphore;
--
--      /* When running in the kernel we expect faults to occur only to
--       * addresses in user space.  All other faults represent errors in the
--       * kernel and should generate an OOPS.  Unfortunately, in the case of an
--       * erroneous fault occurring in a code path which already holds mmap_sem
--       * we will deadlock attempting to validate the fault against the
--       * address space.  Luckily the kernel only validly references user
--       * space from well defined areas of code, which are listed in the
--       * exceptions table.
--       *
--       * As the vast majority of faults will be valid we will only perform
--       * the source reference check when there is a possibility of a deadlock.
--       * Attempt to lock the address space, if we cannot we then validate the
--       * source.  If this is invalid we can skip the address space check,
--       * thus avoiding the deadlock.
--       */
--      if (!down_read_trylock(&mm->mmap_sem)) {
--              if ((error_code & 4) == 0 &&
--                  !search_exception_tables(regs->eip))
--                      goto bad_area_nosemaphore;
--              down_read(&mm->mmap_sem);
--      }
--
--      vma = find_vma(mm, address);
--      if (!vma)
--              goto bad_area;
--      if (vma->vm_start <= address)
--              goto good_area;
--      if (!(vma->vm_flags & VM_GROWSDOWN))
--              goto bad_area;
--      if (error_code & 4) {
--              /*
--               * Accessing the stack below %esp is always a bug.
--               * The large cushion allows instructions like enter
--               * and pusha to work.  ("enter $65535,$31" pushes
--               * 32 pointers and then decrements %esp by 65535.)
--               */
--              if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
--                      goto bad_area;
--      }
--      if (expand_stack(vma, address))
--              goto bad_area;
--/*
-- * Ok, we have a good vm_area for this memory access, so
-- * we can handle it..
-- */
--good_area:
--      si_code = SEGV_ACCERR;
--      write = 0;
--      switch (error_code & 3) {
--              default:        /* 3: write, present */
--                              /* fall through */
--              case 2:         /* write, not present */
--                      if (!(vma->vm_flags & VM_WRITE))
--                              goto bad_area;
--                      write++;
--                      break;
--              case 1:         /* read, present */
--                      goto bad_area;
--              case 0:         /* read, not present */
--                      if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
--                              goto bad_area;
--      }
--
-- survive:
--      /*
--       * If for any reason at all we couldn't handle the fault,
--       * make sure we exit gracefully rather than endlessly redo
--       * the fault.
--       */
--      fault = handle_mm_fault(mm, vma, address, write);
--      if (unlikely(fault & VM_FAULT_ERROR)) {
--              if (fault & VM_FAULT_OOM)
--                      goto out_of_memory;
--              else if (fault & VM_FAULT_SIGBUS)
--                      goto do_sigbus;
--              BUG();
--      }
--      if (fault & VM_FAULT_MAJOR)
--              tsk->maj_flt++;
--      else
--              tsk->min_flt++;
--
--      /*
--       * Did it hit the DOS screen memory VA from vm86 mode?
--       */
--      if (regs->eflags & VM_MASK) {
--              unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
--              if (bit < 32)
--                      tsk->thread.screen_bitmap |= 1 << bit;
--      }
--      up_read(&mm->mmap_sem);
--      return;
--
--/*
-- * Something tried to access memory that isn't in our memory map..
-- * Fix it, but check if it's kernel or user first..
-- */
--bad_area:
--      up_read(&mm->mmap_sem);
--
--bad_area_nosemaphore:
--      /* User mode accesses just cause a SIGSEGV */
--      if (error_code & 4) {
--              /*
--               * It's possible to have interrupts off here.
--               */
--              local_irq_enable();
--
--              /* 
--               * Valid to do another page fault here because this one came 
--               * from user space.
--               */
--              if (is_prefetch(regs, address, error_code))
--                      return;
--
--              if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
--                  printk_ratelimit()) {
--                      printk("%s%s[%d]: segfault at %08lx eip %08lx "
--                          "esp %08lx error %lx\n",
--                          task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
--                          tsk->comm, task_pid_nr(tsk), address, regs->eip,
--                          regs->esp, error_code);
--              }
--              tsk->thread.cr2 = address;
--              /* Kernel addresses are always protection faults */
--              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
--              tsk->thread.trap_no = 14;
--              force_sig_info_fault(SIGSEGV, si_code, address, tsk);
--              return;
--      }
--
--#ifdef CONFIG_X86_F00F_BUG
--      /*
--       * Pentium F0 0F C7 C8 bug workaround.
--       */
--      if (boot_cpu_data.f00f_bug) {
--              unsigned long nr;
--              
--              nr = (address - idt_descr.address) >> 3;
--
--              if (nr == 6) {
--                      do_invalid_op(regs, 0);
--                      return;
--              }
--      }
--#endif
--
--no_context:
--      /* Are we prepared to handle this kernel fault?  */
--      if (fixup_exception(regs))
--              return;
--
--      /* 
--       * Valid to do another page fault here, because if this fault
--       * had been triggered by is_prefetch fixup_exception would have 
--       * handled it.
--       */
--      if (is_prefetch(regs, address, error_code))
--              return;
--
--/*
-- * Oops. The kernel tried to access some bad page. We'll have to
-- * terminate things with extreme prejudice.
-- */
--
--      bust_spinlocks(1);
--
--      if (oops_may_print()) {
--#ifdef CONFIG_X86_PAE
--              if (error_code & 16) {
--                      pte_t *pte = lookup_address(address);
--
--                      if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
--                              printk(KERN_CRIT "kernel tried to execute "
--                                      "NX-protected page - exploit attempt? "
--                                      "(uid: %d)\n", current->uid);
--              }
--#endif
--              if (address < PAGE_SIZE)
--                      printk(KERN_ALERT "BUG: unable to handle kernel NULL "
--                                      "pointer dereference");
--              else
--                      printk(KERN_ALERT "BUG: unable to handle kernel paging"
--                                      " request");
--              printk(" at virtual address %08lx\n",address);
--              printk(KERN_ALERT "printing eip: %08lx\n", regs->eip);
--              dump_fault_path(address);
--      }
--      tsk->thread.cr2 = address;
--      tsk->thread.trap_no = 14;
--      tsk->thread.error_code = error_code;
--      die("Oops", regs, error_code);
--      bust_spinlocks(0);
--      do_exit(SIGKILL);
--
--/*
-- * We ran out of memory, or some other thing happened to us that made
-- * us unable to handle the page fault gracefully.
-- */
--out_of_memory:
--      up_read(&mm->mmap_sem);
--      if (is_global_init(tsk)) {
--              yield();
--              down_read(&mm->mmap_sem);
--              goto survive;
--      }
--      printk("VM: killing process %s\n", tsk->comm);
--      if (error_code & 4)
--              do_group_exit(SIGKILL);
--      goto no_context;
--
--do_sigbus:
--      up_read(&mm->mmap_sem);
--
--      /* Kernel mode? Handle exceptions or die */
--      if (!(error_code & 4))
--              goto no_context;
--
--      /* User space => ok to do another page fault */
--      if (is_prefetch(regs, address, error_code))
--              return;
--
--      tsk->thread.cr2 = address;
--      tsk->thread.error_code = error_code;
--      tsk->thread.trap_no = 14;
--      force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
--}
--
--void vmalloc_sync_all(void)
--{
--      /*
--       * Note that races in the updates of insync and start aren't
--       * problematic: insync can only get set bits added, and updates to
--       * start are only improving performance (without affecting correctness
--       * if undone).
--       * XEN: To work on PAE, we need to iterate over PMDs rather than PGDs.
--       *      This change works just fine with 2-level paging too.
--       */
--#define sync_index(a) ((a) >> PMD_SHIFT)
--      static DECLARE_BITMAP(insync, PTRS_PER_PGD*PTRS_PER_PMD);
--      static unsigned long start = TASK_SIZE;
--      unsigned long address;
--
--      if (SHARED_KERNEL_PMD)
--              return;
--
--      BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK);
--      for (address = start;
--           address >= TASK_SIZE && address < hypervisor_virt_start;
--           address += 1UL << PMD_SHIFT) {
--              if (!test_bit(sync_index(address), insync)) {
--                      unsigned long flags;
--                      struct page *page;
--
--                      spin_lock_irqsave(&pgd_lock, flags);
--                      /* XEN: failure path assumes non-empty pgd_list. */
--                      if (unlikely(!pgd_list)) {
--                              spin_unlock_irqrestore(&pgd_lock, flags);
--                              return;
--                      }
--                      for (page = pgd_list; page; page =
--                                      (struct page *)page->index)
--                              if (!vmalloc_sync_one(page_address(page),
--                                                              address)) {
--                                      BUG_ON(page != pgd_list);
--                                      break;
--                              }
--                      spin_unlock_irqrestore(&pgd_lock, flags);
--                      if (!page)
--                              set_bit(sync_index(address), insync);
--              }
--              if (address == start && test_bit(sync_index(address), insync))
--                      start = address + (1UL << PMD_SHIFT);
--      }
--}
---- a/arch/x86/mm/fault_64-xen.c
-+++ /dev/null
-@@ -1,686 +0,0 @@
--/*
-- *  linux/arch/x86-64/mm/fault.c
-- *
-- *  Copyright (C) 1995  Linus Torvalds
-- *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
-- */
--
--#include <linux/signal.h>
--#include <linux/sched.h>
--#include <linux/kernel.h>
--#include <linux/errno.h>
--#include <linux/string.h>
--#include <linux/types.h>
--#include <linux/ptrace.h>
--#include <linux/mman.h>
--#include <linux/mm.h>
--#include <linux/smp.h>
--#include <linux/interrupt.h>
--#include <linux/init.h>
--#include <linux/tty.h>
--#include <linux/vt_kern.h>            /* For unblank_screen() */
--#include <linux/compiler.h>
--#include <linux/vmalloc.h>
--#include <linux/module.h>
--#include <linux/kprobes.h>
--#include <linux/uaccess.h>
--#include <linux/kdebug.h>
--#include <linux/kprobes.h>
--
--#include <asm/system.h>
--#include <asm/pgalloc.h>
--#include <asm/smp.h>
--#include <asm/tlbflush.h>
--#include <asm/proto.h>
--#include <asm-generic/sections.h>
--
--/* Page fault error code bits */
--#define PF_PROT       (1<<0)          /* or no page found */
--#define PF_WRITE      (1<<1)
--#define PF_USER       (1<<2)
--#define PF_RSVD       (1<<3)
--#define PF_INSTR      (1<<4)
--
--#ifdef CONFIG_KPROBES
--static inline int notify_page_fault(struct pt_regs *regs)
--{
--      int ret = 0;
--
--      /* kprobe_running() needs smp_processor_id() */
--      if (!user_mode(regs)) {
--              preempt_disable();
--              if (kprobe_running() && kprobe_fault_handler(regs, 14))
--                      ret = 1;
--              preempt_enable();
--      }
--
--      return ret;
--}
--#else
--static inline int notify_page_fault(struct pt_regs *regs)
--{
--      return 0;
--}
--#endif
--
--/* Sometimes the CPU reports invalid exceptions on prefetch.
--   Check that here and ignore.
--   Opcode checker based on code by Richard Brunner */
--static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
--                              unsigned long error_code)
--{ 
--      unsigned char *instr;
--      int scan_more = 1;
--      int prefetch = 0; 
--      unsigned char *max_instr;
--
--      /* If it was a exec fault ignore */
--      if (error_code & PF_INSTR)
--              return 0;
--      
--      instr = (unsigned char __user *)convert_rip_to_linear(current, regs);
--      max_instr = instr + 15;
--
--      if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
--              return 0;
--
--      while (scan_more && instr < max_instr) { 
--              unsigned char opcode;
--              unsigned char instr_hi;
--              unsigned char instr_lo;
--
--              if (probe_kernel_address(instr, opcode))
--                      break; 
--
--              instr_hi = opcode & 0xf0; 
--              instr_lo = opcode & 0x0f; 
--              instr++;
--
--              switch (instr_hi) { 
--              case 0x20:
--              case 0x30:
--                      /* Values 0x26,0x2E,0x36,0x3E are valid x86
--                         prefixes.  In long mode, the CPU will signal
--                         invalid opcode if some of these prefixes are
--                         present so we will never get here anyway */
--                      scan_more = ((instr_lo & 7) == 0x6);
--                      break;
--                      
--              case 0x40:
--                      /* In AMD64 long mode, 0x40 to 0x4F are valid REX prefixes
--                         Need to figure out under what instruction mode the
--                         instruction was issued ... */
--                      /* Could check the LDT for lm, but for now it's good
--                         enough to assume that long mode only uses well known
--                         segments or kernel. */
--                      scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
--                      break;
--                      
--              case 0x60:
--                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
--                      scan_more = (instr_lo & 0xC) == 0x4;
--                      break;          
--              case 0xF0:
--                      /* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
--                      scan_more = !instr_lo || (instr_lo>>1) == 1;
--                      break;                  
--              case 0x00:
--                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
--                      scan_more = 0;
--                      if (probe_kernel_address(instr, opcode))
--                              break;
--                      prefetch = (instr_lo == 0xF) &&
--                              (opcode == 0x0D || opcode == 0x18);
--                      break;                  
--              default:
--                      scan_more = 0;
--                      break;
--              } 
--      }
--      return prefetch;
--}
--
--static int bad_address(void *p) 
--{ 
--      unsigned long dummy;
--      return probe_kernel_address((unsigned long *)p, dummy);
--} 
--
--void dump_pagetable(unsigned long address)
--{
--      pgd_t *pgd;
--      pud_t *pud;
--      pmd_t *pmd;
--      pte_t *pte;
--
--      pgd = (pgd_t *)read_cr3();
--
--      pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
--      pgd += pgd_index(address);
--      if (bad_address(pgd)) goto bad;
--      printk("PGD %lx ", pgd_val(*pgd));
--      if (!pgd_present(*pgd)) goto ret; 
--
--      pud = pud_offset(pgd, address);
--      if (bad_address(pud)) goto bad;
--      printk("PUD %lx ", pud_val(*pud));
--      if (!pud_present(*pud)) goto ret;
--
--      pmd = pmd_offset(pud, address);
--      if (bad_address(pmd)) goto bad;
--      printk("PMD %lx ", pmd_val(*pmd));
--      if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
--
--      pte = pte_offset_kernel(pmd, address);
--      if (bad_address(pte)) goto bad;
--      printk("PTE %lx", pte_val(*pte)); 
--ret:
--      printk("\n");
--      return;
--bad:
--      printk("BAD\n");
--}
--
--static const char errata93_warning[] = 
--KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
--KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
--KERN_ERR "******* Please consider a BIOS update.\n"
--KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
--
--/* Workaround for K8 erratum #93 & buggy BIOS.
--   BIOS SMM functions are required to use a specific workaround
--   to avoid corruption of the 64bit RIP register on C stepping K8. 
--   A lot of BIOS that didn't get tested properly miss this. 
--   The OS sees this as a page fault with the upper 32bits of RIP cleared.
--   Try to work around it here.
--   Note we only handle faults in kernel here. */
--
--static int is_errata93(struct pt_regs *regs, unsigned long address) 
--{
--      static int warned;
--      if (address != regs->rip)
--              return 0;
--      if ((address >> 32) != 0) 
--              return 0;
--      address |= 0xffffffffUL << 32;
--      if ((address >= (u64)_stext && address <= (u64)_etext) || 
--          (address >= MODULES_VADDR && address <= MODULES_END)) { 
--              if (!warned) {
--                      printk(errata93_warning);               
--                      warned = 1;
--              }
--              regs->rip = address;
--              return 1;
--      }
--      return 0;
--} 
--
--static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
--                               unsigned long error_code)
--{
--      unsigned long flags = oops_begin();
--      struct task_struct *tsk;
--
--      printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
--             current->comm, address);
--      dump_pagetable(address);
--      tsk = current;
--      tsk->thread.cr2 = address;
--      tsk->thread.trap_no = 14;
--      tsk->thread.error_code = error_code;
--      __die("Bad pagetable", regs, error_code);
--      oops_end(flags);
--      do_exit(SIGKILL);
--}
--
--/*
-- * Handle a fault on the vmalloc area
-- *
-- * This assumes no large pages in there.
-- */
--static int vmalloc_fault(unsigned long address)
--{
--      pgd_t *pgd, *pgd_ref;
--      pud_t *pud, *pud_ref;
--      pmd_t *pmd, *pmd_ref;
--      pte_t *pte, *pte_ref;
--
--      /* Copy kernel mappings over when needed. This can also
--         happen within a race in page table update. In the later
--         case just flush. */
--
--      /* On Xen the line below does not always work. Needs investigating! */
--      /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
--      pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
--      pgd += pgd_index(address);
--      pgd_ref = pgd_offset_k(address);
--      if (pgd_none(*pgd_ref))
--              return -1;
--      if (pgd_none(*pgd))
--              set_pgd(pgd, *pgd_ref);
--      else
--              BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
--
--      /* Below here mismatches are bugs because these lower tables
--         are shared */
--
--      pud = pud_offset(pgd, address);
--      pud_ref = pud_offset(pgd_ref, address);
--      if (pud_none(*pud_ref))
--              return -1;
--      if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
--              BUG();
--      pmd = pmd_offset(pud, address);
--      pmd_ref = pmd_offset(pud_ref, address);
--      if (pmd_none(*pmd_ref))
--              return -1;
--      if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
--              BUG();
--      pte_ref = pte_offset_kernel(pmd_ref, address);
--      if (!pte_present(*pte_ref))
--              return -1;
--      pte = pte_offset_kernel(pmd, address);
--      /* Don't use pte_page here, because the mappings can point
--         outside mem_map, and the NUMA hash lookup cannot handle
--         that. */
--      if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
--              BUG();
--      return 0;
--}
--
--int show_unhandled_signals = 1;
--
--
--#define MEM_VERBOSE 1
--
--#ifdef MEM_VERBOSE
--#define MEM_LOG(_f, _a...)                    \
--      printk("fault.c:[%d]-> " _f "\n",       \
--      __LINE__ , ## _a )
--#else
--#define MEM_LOG(_f, _a...) ((void)0)
--#endif
--
--static int spurious_fault(struct pt_regs *regs,
--                        unsigned long address,
--                        unsigned long error_code)
--{
--      pgd_t *pgd;
--      pud_t *pud;
--      pmd_t *pmd;
--      pte_t *pte;
--
--#ifdef CONFIG_XEN
--      /* Faults in hypervisor area are never spurious. */
--      if ((address >= HYPERVISOR_VIRT_START) &&
--          (address < HYPERVISOR_VIRT_END))
--              return 0;
--#endif
--
--      /* Reserved-bit violation or user access to kernel space? */
--      if (error_code & (PF_RSVD|PF_USER))
--              return 0;
--
--      pgd = init_mm.pgd + pgd_index(address);
--      if (!pgd_present(*pgd))
--              return 0;
--
--      pud = pud_offset(pgd, address);
--      if (!pud_present(*pud))
--              return 0;
--
--      pmd = pmd_offset(pud, address);
--      if (!pmd_present(*pmd))
--              return 0;
--
--      pte = pte_offset_kernel(pmd, address);
--      if (!pte_present(*pte))
--              return 0;
--      if ((error_code & PF_WRITE) && !pte_write(*pte))
--              return 0;
--      if ((error_code & PF_INSTR) && (__pte_val(*pte) & _PAGE_NX))
--              return 0;
--
--      return 1;
--}
--
--/*
-- * This routine handles page faults.  It determines the address,
-- * and the problem, and then passes it off to one of the appropriate
-- * routines.
-- */
--asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
--                                      unsigned long error_code)
--{
--      struct task_struct *tsk;
--      struct mm_struct *mm;
--      struct vm_area_struct * vma;
--      unsigned long address;
--      const struct exception_table_entry *fixup;
--      int write, fault;
--      unsigned long flags;
--      siginfo_t info;
--
--      if (!user_mode(regs))
--              error_code &= ~PF_USER; /* means kernel */
--
--      /*
--       * We can fault from pretty much anywhere, with unknown IRQ state.
--       */
--      trace_hardirqs_fixup();
--
--      tsk = current;
--      mm = tsk->mm;
--      prefetchw(&mm->mmap_sem);
--
--      /* get the address */
--      address = read_cr2();
--
--      info.si_code = SEGV_MAPERR;
--
--
--      /*
--       * We fault-in kernel-space virtual memory on-demand. The
--       * 'reference' page table is init_mm.pgd.
--       *
--       * NOTE! We MUST NOT take any locks for this case. We may
--       * be in an interrupt or a critical region, and should
--       * only copy the information from the master page table,
--       * nothing more.
--       *
--       * This verifies that the fault happens in kernel space
--       * (error_code & 4) == 0, and that the fault was not a
--       * protection error (error_code & 9) == 0.
--       */
--      if (unlikely(address >= TASK_SIZE64)) {
--              /*
--               * Don't check for the module range here: its PML4
--               * is always initialized because it's shared with the main
--               * kernel text. Only vmalloc may need PML4 syncups.
--               */
--              if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
--                    ((address >= VMALLOC_START && address < VMALLOC_END))) {
--                      if (vmalloc_fault(address) >= 0)
--                              return;
--              }
--              /* Can take a spurious fault if mapping changes R/O -> R/W. */
--              if (spurious_fault(regs, address, error_code))
--                      return;
--              if (notify_page_fault(regs))
--                      return;
--              /*
--               * Don't take the mm semaphore here. If we fixup a prefetch
--               * fault we could otherwise deadlock.
--               */
--              goto bad_area_nosemaphore;
--      }
--
--      if (notify_page_fault(regs))
--              return;
--
--      if (likely(regs->eflags & X86_EFLAGS_IF))
--              local_irq_enable();
--
--      if (unlikely(error_code & PF_RSVD))
--              pgtable_bad(address, regs, error_code);
--
--      /*
--       * If we're in an interrupt or have no user
--       * context, we must not take the fault..
--       */
--      if (unlikely(in_atomic() || !mm))
--              goto bad_area_nosemaphore;
--
--      /*
--       * User-mode registers count as a user access even for any
--       * potential system fault or CPU buglet.
--       */
--      if (user_mode_vm(regs))
--              error_code |= PF_USER;
--
-- again:
--      /* When running in the kernel we expect faults to occur only to
--       * addresses in user space.  All other faults represent errors in the
--       * kernel and should generate an OOPS.  Unfortunately, in the case of an
--       * erroneous fault occurring in a code path which already holds mmap_sem
--       * we will deadlock attempting to validate the fault against the
--       * address space.  Luckily the kernel only validly references user
--       * space from well defined areas of code, which are listed in the
--       * exceptions table.
--       *
--       * As the vast majority of faults will be valid we will only perform
--       * the source reference check when there is a possibility of a deadlock.
--       * Attempt to lock the address space, if we cannot we then validate the
--       * source.  If this is invalid we can skip the address space check,
--       * thus avoiding the deadlock.
--       */
--      if (!down_read_trylock(&mm->mmap_sem)) {
--              if ((error_code & PF_USER) == 0 &&
--                  !search_exception_tables(regs->rip))
--                      goto bad_area_nosemaphore;
--              down_read(&mm->mmap_sem);
--      }
--
--      vma = find_vma(mm, address);
--      if (!vma)
--              goto bad_area;
--      if (likely(vma->vm_start <= address))
--              goto good_area;
--      if (!(vma->vm_flags & VM_GROWSDOWN))
--              goto bad_area;
--      if (error_code & 4) {
--              /* Allow userspace just enough access below the stack pointer
--               * to let the 'enter' instruction work.
--               */
--              if (address + 65536 + 32 * sizeof(unsigned long) < regs->rsp)
--                      goto bad_area;
--      }
--      if (expand_stack(vma, address))
--              goto bad_area;
--/*
-- * Ok, we have a good vm_area for this memory access, so
-- * we can handle it..
-- */
--good_area:
--      info.si_code = SEGV_ACCERR;
--      write = 0;
--      switch (error_code & (PF_PROT|PF_WRITE)) {
--              default:        /* 3: write, present */
--                      /* fall through */
--              case PF_WRITE:          /* write, not present */
--                      if (!(vma->vm_flags & VM_WRITE))
--                              goto bad_area;
--                      write++;
--                      break;
--              case PF_PROT:           /* read, present */
--                      goto bad_area;
--              case 0:                 /* read, not present */
--                      if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
--                              goto bad_area;
--      }
--
--      /*
--       * If for any reason at all we couldn't handle the fault,
--       * make sure we exit gracefully rather than endlessly redo
--       * the fault.
--       */
--      fault = handle_mm_fault(mm, vma, address, write);
--      if (unlikely(fault & VM_FAULT_ERROR)) {
--              if (fault & VM_FAULT_OOM)
--                      goto out_of_memory;
--              else if (fault & VM_FAULT_SIGBUS)
--                      goto do_sigbus;
--              BUG();
--      }
--      if (fault & VM_FAULT_MAJOR)
--              tsk->maj_flt++;
--      else
--              tsk->min_flt++;
--      up_read(&mm->mmap_sem);
--      return;
--
--/*
-- * Something tried to access memory that isn't in our memory map..
-- * Fix it, but check if it's kernel or user first..
-- */
--bad_area:
--      up_read(&mm->mmap_sem);
--
--bad_area_nosemaphore:
--      /* User mode accesses just cause a SIGSEGV */
--      if (error_code & PF_USER) {
--
--              /*
--               * It's possible to have interrupts off here.
--               */
--              local_irq_enable();
--
--              if (is_prefetch(regs, address, error_code))
--                      return;
--
--              /* Work around K8 erratum #100 K8 in compat mode
--                 occasionally jumps to illegal addresses >4GB.  We
--                 catch this here in the page fault handler because
--                 these addresses are not reachable. Just detect this
--                 case and return.  Any code segment in LDT is
--                 compatibility mode. */
--              if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
--                  (address >> 32))
--                      return;
--
--              if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
--                  printk_ratelimit()) {
--                      printk(
--                     "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
--                                      tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
--                                      tsk->comm, tsk->pid, address, regs->rip,
--                                      regs->rsp, error_code);
--              }
--       
--              tsk->thread.cr2 = address;
--              /* Kernel addresses are always protection faults */
--              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
--              tsk->thread.trap_no = 14;
--              info.si_signo = SIGSEGV;
--              info.si_errno = 0;
--              /* info.si_code has been set above */
--              info.si_addr = (void __user *)address;
--              force_sig_info(SIGSEGV, &info, tsk);
--              return;
--      }
--
--no_context:
--      
--      /* Are we prepared to handle this kernel fault?  */
--      fixup = search_exception_tables(regs->rip);
--      if (fixup) {
--              regs->rip = fixup->fixup;
--              return;
--      }
--
--      /* 
--       * Hall of shame of CPU/BIOS bugs.
--       */
--
--      if (is_prefetch(regs, address, error_code))
--              return;
--
--      if (is_errata93(regs, address))
--              return; 
--
--/*
-- * Oops. The kernel tried to access some bad page. We'll have to
-- * terminate things with extreme prejudice.
-- */
--
--      flags = oops_begin();
--
--      if (address < PAGE_SIZE)
--              printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
--      else
--              printk(KERN_ALERT "Unable to handle kernel paging request");
--      printk(" at %016lx RIP: \n" KERN_ALERT,address);
--      printk_address(regs->rip);
--      dump_pagetable(address);
--      tsk->thread.cr2 = address;
--      tsk->thread.trap_no = 14;
--      tsk->thread.error_code = error_code;
--      __die("Oops", regs, error_code);
--      /* Executive summary in case the body of the oops scrolled away */
--      printk(KERN_EMERG "CR2: %016lx\n", address);
--      oops_end(flags);
--      do_exit(SIGKILL);
--
--/*
-- * We ran out of memory, or some other thing happened to us that made
-- * us unable to handle the page fault gracefully.
-- */
--out_of_memory:
--      up_read(&mm->mmap_sem);
--      if (is_global_init(current)) {
--              yield();
--              goto again;
--      }
--      printk("VM: killing process %s\n", tsk->comm);
--      if (error_code & 4)
--              do_group_exit(SIGKILL);
--      goto no_context;
--
--do_sigbus:
--      up_read(&mm->mmap_sem);
--
--      /* Kernel mode? Handle exceptions or die */
--      if (!(error_code & PF_USER))
--              goto no_context;
--
--      tsk->thread.cr2 = address;
--      tsk->thread.error_code = error_code;
--      tsk->thread.trap_no = 14;
--      info.si_signo = SIGBUS;
--      info.si_errno = 0;
--      info.si_code = BUS_ADRERR;
--      info.si_addr = (void __user *)address;
--      force_sig_info(SIGBUS, &info, tsk);
--      return;
--}
--
--DEFINE_SPINLOCK(pgd_lock);
--LIST_HEAD(pgd_list);
--
--void vmalloc_sync_all(void)
--{
--      /* Note that races in the updates of insync and start aren't 
--         problematic:
--         insync can only get set bits added, and updates to start are only
--         improving performance (without affecting correctness if undone). */
--      static DECLARE_BITMAP(insync, PTRS_PER_PGD);
--      static unsigned long start = VMALLOC_START & PGDIR_MASK;
--      unsigned long address;
--
--      for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
--              if (!test_bit(pgd_index(address), insync)) {
--                      const pgd_t *pgd_ref = pgd_offset_k(address);
--                      struct page *page;
--
--                      if (pgd_none(*pgd_ref))
--                              continue;
--                      spin_lock(&pgd_lock);
--                      list_for_each_entry(page, &pgd_list, lru) {
--                              pgd_t *pgd;
--                              pgd = (pgd_t *)page_address(page) + pgd_index(address);
--                              if (pgd_none(*pgd))
--                                      set_pgd(pgd, *pgd_ref);
--                              else
--                                      BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
--                      }
--                      spin_unlock(&pgd_lock);
--                      set_bit(pgd_index(address), insync);
--              }
--              if (address == start)
--                      start = address + PGDIR_SIZE;
--      }
--      /* Check that there is no need to do the same for the modules area. */
--      BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
--      BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == 
--                              (__START_KERNEL & PGDIR_MASK)));
--}
---- /dev/null
-+++ b/arch/x86/mm/fault-xen.c
-@@ -0,0 +1,1026 @@
-+/*
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
-+ */
-+
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ptrace.h>
-+#include <linux/mman.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/tty.h>
-+#include <linux/vt_kern.h>            /* For unblank_screen() */
-+#include <linux/compiler.h>
-+#include <linux/highmem.h>
-+#include <linux/bootmem.h>            /* for max_low_pfn */
-+#include <linux/vmalloc.h>
-+#include <linux/module.h>
-+#include <linux/kprobes.h>
-+#include <linux/uaccess.h>
-+#include <linux/kdebug.h>
-+
-+#include <asm/system.h>
-+#include <asm/desc.h>
-+#include <asm/segment.h>
-+#include <asm/pgalloc.h>
-+#include <asm/smp.h>
-+#include <asm/tlbflush.h>
-+#include <asm/proto.h>
-+#include <asm-generic/sections.h>
-+
-+/*
-+ * Page fault error code bits
-+ *    bit 0 == 0 means no page found, 1 means protection fault
-+ *    bit 1 == 0 means read, 1 means write
-+ *    bit 2 == 0 means kernel, 1 means user-mode
-+ *    bit 3 == 1 means use of reserved bit detected
-+ *    bit 4 == 1 means fault was an instruction fetch
-+ */
-+#define PF_PROT               (1<<0)
-+#define PF_WRITE      (1<<1)
-+#define PF_USER               (1<<2)
-+#define PF_RSVD               (1<<3)
-+#define PF_INSTR      (1<<4)
-+
-+static inline int notify_page_fault(struct pt_regs *regs)
-+{
-+#ifdef CONFIG_KPROBES
-+      int ret = 0;
-+
-+      /* kprobe_running() needs smp_processor_id() */
-+#ifdef CONFIG_X86_32
-+      if (!user_mode_vm(regs)) {
-+#else
-+      if (!user_mode(regs)) {
-+#endif
-+              preempt_disable();
-+              if (kprobe_running() && kprobe_fault_handler(regs, 14))
-+                      ret = 1;
-+              preempt_enable();
-+      }
-+
-+      return ret;
-+#else
-+      return 0;
-+#endif
-+}
-+
-+/*
-+ * X86_32
-+ * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
-+ * Check that here and ignore it.
-+ *
-+ * X86_64
-+ * Sometimes the CPU reports invalid exceptions on prefetch.
-+ * Check that here and ignore it.
-+ *
-+ * Opcode checker based on code by Richard Brunner
-+ */
-+static int is_prefetch(struct pt_regs *regs, unsigned long addr,
-+                     unsigned long error_code)
-+{
-+      unsigned char *instr;
-+      int scan_more = 1;
-+      int prefetch = 0;
-+      unsigned char *max_instr;
-+
-+      /*
-+       * If it was a exec (instruction fetch) fault on NX page, then
-+       * do not ignore the fault:
-+       */
-+      if (error_code & PF_INSTR)
-+              return 0;
-+
-+      instr = (unsigned char *)convert_ip_to_linear(current, regs);
-+      max_instr = instr + 15;
-+
-+      if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
-+              return 0;
-+
-+      while (scan_more && instr < max_instr) {
-+              unsigned char opcode;
-+              unsigned char instr_hi;
-+              unsigned char instr_lo;
-+
-+              if (probe_kernel_address(instr, opcode))
-+                      break;
-+
-+              instr_hi = opcode & 0xf0;
-+              instr_lo = opcode & 0x0f;
-+              instr++;
-+
-+              switch (instr_hi) {
-+              case 0x20:
-+              case 0x30:
-+                      /*
-+                       * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
-+                       * In X86_64 long mode, the CPU will signal invalid
-+                       * opcode if some of these prefixes are present so
-+                       * X86_64 will never get here anyway
-+                       */
-+                      scan_more = ((instr_lo & 7) == 0x6);
-+                      break;
-+#ifdef CONFIG_X86_64
-+              case 0x40:
-+                      /*
-+                       * In AMD64 long mode 0x40..0x4F are valid REX prefixes
-+                       * Need to figure out under what instruction mode the
-+                       * instruction was issued. Could check the LDT for lm,
-+                       * but for now it's good enough to assume that long
-+                       * mode only uses well known segments or kernel.
-+                       */
-+                      scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
-+                      break;
-+#endif
-+              case 0x60:
-+                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
-+                      scan_more = (instr_lo & 0xC) == 0x4;
-+                      break;
-+              case 0xF0:
-+                      /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
-+                      scan_more = !instr_lo || (instr_lo>>1) == 1;
-+                      break;
-+              case 0x00:
-+                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
-+                      scan_more = 0;
-+
-+                      if (probe_kernel_address(instr, opcode))
-+                              break;
-+                      prefetch = (instr_lo == 0xF) &&
-+                              (opcode == 0x0D || opcode == 0x18);
-+                      break;
-+              default:
-+                      scan_more = 0;
-+                      break;
-+              }
-+      }
-+      return prefetch;
-+}
-+
-+static void force_sig_info_fault(int si_signo, int si_code,
-+      unsigned long address, struct task_struct *tsk)
-+{
-+      siginfo_t info;
-+
-+      info.si_signo = si_signo;
-+      info.si_errno = 0;
-+      info.si_code = si_code;
-+      info.si_addr = (void __user *)address;
-+      force_sig_info(si_signo, &info, tsk);
-+}
-+
-+#ifdef CONFIG_X86_64
-+static int bad_address(void *p)
-+{
-+      unsigned long dummy;
-+      return probe_kernel_address((unsigned long *)p, dummy);
-+}
-+#endif
-+
-+static void dump_pagetable(unsigned long address)
-+{
-+#ifdef CONFIG_X86_32
-+      __typeof__(pte_val(__pte(0))) page;
-+
-+      page = read_cr3();
-+      page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
-+#ifdef CONFIG_X86_PAE
-+      printk("*pdpt = %016Lx ", page);
-+      if ((page & _PAGE_PRESENT)
-+          && mfn_to_local_pfn(page >> PAGE_SHIFT) < max_low_pfn) {
-+              page = mfn_to_pfn(page >> PAGE_SHIFT);
-+              page <<= PAGE_SHIFT;
-+              page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
-+                                                       & (PTRS_PER_PMD - 1)];
-+              printk(KERN_CONT "*pde = %016Lx ", page);
-+              page &= ~_PAGE_NX;
-+      }
-+#else
-+      printk("*pde = %08lx ", page);
-+#endif
-+
-+      /*
-+       * We must not directly access the pte in the highpte
-+       * case if the page table is located in highmem.
-+       * And let's rather not kmap-atomic the pte, just in case
-+       * it's allocated already.
-+       */
-+      if ((page & _PAGE_PRESENT)
-+          && mfn_to_local_pfn(page >> PAGE_SHIFT) < max_low_pfn
-+          && !(page & _PAGE_PSE)) {
-+              page = mfn_to_pfn(page >> PAGE_SHIFT);
-+              page <<= PAGE_SHIFT;
-+              page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
-+                                                       & (PTRS_PER_PTE - 1)];
-+              printk(KERN_CONT "*pte = %0*Lx ", sizeof(page)*2, (u64)page);
-+      }
-+
-+      printk(KERN_CONT "\n");
-+#else /* CONFIG_X86_64 */
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+      pgd = (pgd_t *)read_cr3();
-+
-+      pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
-+      pgd += pgd_index(address);
-+      if (bad_address(pgd)) goto bad;
-+      printk("PGD %lx ", pgd_val(*pgd));
-+      if (!pgd_present(*pgd)) goto ret;
-+
-+      pud = pud_offset(pgd, address);
-+      if (bad_address(pud)) goto bad;
-+      printk(KERN_CONT "PUD %lx ", pud_val(*pud));
-+      if (!pud_present(*pud) || pud_large(*pud))
-+              goto ret;
-+
-+      pmd = pmd_offset(pud, address);
-+      if (bad_address(pmd)) goto bad;
-+      printk(KERN_CONT "PMD %lx ", pmd_val(*pmd));
-+      if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
-+
-+      pte = pte_offset_kernel(pmd, address);
-+      if (bad_address(pte)) goto bad;
-+      printk(KERN_CONT "PTE %lx", pte_val(*pte));
-+ret:
-+      printk(KERN_CONT "\n");
-+      return;
-+bad:
-+      printk("BAD\n");
-+#endif
-+}
-+
-+#ifdef CONFIG_X86_32
-+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
-+{
-+      unsigned index = pgd_index(address);
-+      pgd_t *pgd_k;
-+      pud_t *pud, *pud_k;
-+      pmd_t *pmd, *pmd_k;
-+
-+      pgd += index;
-+      pgd_k = init_mm.pgd + index;
-+
-+      if (!pgd_present(*pgd_k))
-+              return NULL;
-+
-+      /*
-+       * set_pgd(pgd, *pgd_k); here would be useless on PAE
-+       * and redundant with the set_pmd() on non-PAE. As would
-+       * set_pud.
-+       */
-+
-+      pud = pud_offset(pgd, address);
-+      pud_k = pud_offset(pgd_k, address);
-+      if (!pud_present(*pud_k))
-+              return NULL;
-+
-+      pmd = pmd_offset(pud, address);
-+      pmd_k = pmd_offset(pud_k, address);
-+      if (!pmd_present(*pmd_k))
-+              return NULL;
-+      if (!pmd_present(*pmd)) {
-+              bool lazy = x86_read_percpu(xen_lazy_mmu);
-+
-+              x86_write_percpu(xen_lazy_mmu, false);
-+#if CONFIG_XEN_COMPAT > 0x030002
-+              set_pmd(pmd, *pmd_k);
-+#else
-+              /*
-+               * When running on older Xen we must launder *pmd_k through
-+               * pmd_val() to ensure that _PAGE_PRESENT is correctly set.
-+               */
-+              set_pmd(pmd, __pmd(pmd_val(*pmd_k)));
-+#endif
-+              x86_write_percpu(xen_lazy_mmu, lazy);
-+      } else
-+              BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
-+      return pmd_k;
-+}
-+#endif
-+
-+#ifdef CONFIG_X86_64
-+static const char errata93_warning[] =
-+KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
-+KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
-+KERN_ERR "******* Please consider a BIOS update.\n"
-+KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
-+#endif
-+
-+/* Workaround for K8 erratum #93 & buggy BIOS.
-+   BIOS SMM functions are required to use a specific workaround
-+   to avoid corruption of the 64bit RIP register on C stepping K8.
-+   A lot of BIOS that didn't get tested properly miss this.
-+   The OS sees this as a page fault with the upper 32bits of RIP cleared.
-+   Try to work around it here.
-+   Note we only handle faults in kernel here.
-+   Does nothing for X86_32
-+ */
-+static int is_errata93(struct pt_regs *regs, unsigned long address)
-+{
-+#ifdef CONFIG_X86_64
-+      static int warned;
-+      if (address != regs->ip)
-+              return 0;
-+      if ((address >> 32) != 0)
-+              return 0;
-+      address |= 0xffffffffUL << 32;
-+      if ((address >= (u64)_stext && address <= (u64)_etext) ||
-+          (address >= MODULES_VADDR && address <= MODULES_END)) {
-+              if (!warned) {
-+                      printk(errata93_warning);
-+                      warned = 1;
-+              }
-+              regs->ip = address;
-+              return 1;
-+      }
-+#endif
-+      return 0;
-+}
-+
-+/*
-+ * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal
-+ * addresses >4GB.  We catch this in the page fault handler because these
-+ * addresses are not reachable. Just detect this case and return.  Any code
-+ * segment in LDT is compatibility mode.
-+ */
-+static int is_errata100(struct pt_regs *regs, unsigned long address)
-+{
-+#ifdef CONFIG_X86_64
-+      if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
-+          (address >> 32))
-+              return 1;
-+#endif
-+      return 0;
-+}
-+
-+void do_invalid_op(struct pt_regs *, unsigned long);
-+
-+static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
-+{
-+#ifdef CONFIG_X86_F00F_BUG
-+      unsigned long nr;
-+      /*
-+       * Pentium F0 0F C7 C8 bug workaround.
-+       */
-+      if (boot_cpu_data.f00f_bug) {
-+              nr = (address - idt_descr.address) >> 3;
-+
-+              if (nr == 6) {
-+                      do_invalid_op(regs, 0);
-+                      return 1;
-+              }
-+      }
-+#endif
-+      return 0;
-+}
-+
-+static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
-+                          unsigned long address)
-+{
-+#ifdef CONFIG_X86_32
-+      if (!oops_may_print())
-+              return;
-+#endif
-+
-+#ifdef CONFIG_X86_PAE
-+      if (error_code & PF_INSTR) {
-+              unsigned int level;
-+              pte_t *pte = lookup_address(address, &level);
-+
-+              if (pte && pte_present(*pte) && !pte_exec(*pte))
-+                      printk(KERN_CRIT "kernel tried to execute "
-+                              "NX-protected page - exploit attempt? "
-+                              "(uid: %d)\n", current->uid);
-+      }
-+#endif
-+
-+      printk(KERN_ALERT "BUG: unable to handle kernel ");
-+      if (address < PAGE_SIZE)
-+              printk(KERN_CONT "NULL pointer dereference");
-+      else
-+              printk(KERN_CONT "paging request");
-+#ifdef CONFIG_X86_32
-+      printk(KERN_CONT " at %08lx\n", address);
-+#else
-+      printk(KERN_CONT " at %016lx\n", address);
-+#endif
-+      printk(KERN_ALERT "IP:");
-+      printk_address(regs->ip, 1);
-+      dump_pagetable(address);
-+}
-+
-+#ifdef CONFIG_X86_64
-+static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
-+                               unsigned long error_code)
-+{
-+      unsigned long flags = oops_begin();
-+      struct task_struct *tsk;
-+
-+      printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
-+             current->comm, address);
-+      dump_pagetable(address);
-+      tsk = current;
-+      tsk->thread.cr2 = address;
-+      tsk->thread.trap_no = 14;
-+      tsk->thread.error_code = error_code;
-+      if (__die("Bad pagetable", regs, error_code))
-+              regs = NULL;
-+      oops_end(flags, regs, SIGKILL);
-+}
-+#endif
-+
-+static int spurious_fault_check(unsigned long error_code, pte_t *pte)
-+{
-+      if ((error_code & PF_WRITE) && !pte_write(*pte))
-+              return 0;
-+      if ((error_code & PF_INSTR) && !pte_exec(*pte))
-+              return 0;
-+
-+      return 1;
-+}
-+
-+/*
-+ * Handle a spurious fault caused by a stale TLB entry.  This allows
-+ * us to lazily refresh the TLB when increasing the permissions of a
-+ * kernel page (RO -> RW or NX -> X).  Doing it eagerly is very
-+ * expensive since that implies doing a full cross-processor TLB
-+ * flush, even if no stale TLB entries exist on other processors.
-+ * There are no security implications to leaving a stale TLB when
-+ * increasing the permissions on a page.
-+ */
-+static int spurious_fault(unsigned long address,
-+                        unsigned long error_code)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+      /* Reserved-bit violation or user access to kernel space? */
-+      if (error_code & (PF_USER | PF_RSVD))
-+              return 0;
-+
-+      pgd = init_mm.pgd + pgd_index(address);
-+      if (!pgd_present(*pgd))
-+              return 0;
-+
-+      pud = pud_offset(pgd, address);
-+      if (!pud_present(*pud))
-+              return 0;
-+
-+      if (pud_large(*pud))
-+              return spurious_fault_check(error_code, (pte_t *) pud);
-+
-+      pmd = pmd_offset(pud, address);
-+      if (!pmd_present(*pmd))
-+              return 0;
-+
-+      if (pmd_large(*pmd))
-+              return spurious_fault_check(error_code, (pte_t *) pmd);
-+
-+      pte = pte_offset_kernel(pmd, address);
-+      if (!pte_present(*pte))
-+              return 0;
-+
-+      return spurious_fault_check(error_code, pte);
-+}
-+
-+/*
-+ * X86_32
-+ * Handle a fault on the vmalloc or module mapping area
-+ *
-+ * X86_64
-+ * Handle a fault on the vmalloc area
-+ *
-+ * This assumes no large pages in there.
-+ */
-+static int vmalloc_fault(unsigned long address)
-+{
-+#ifdef CONFIG_X86_32
-+      unsigned long pgd_paddr;
-+      pmd_t *pmd_k;
-+      pte_t *pte_k;
-+      /*
-+       * Synchronize this task's top level page-table
-+       * with the 'reference' page table.
-+       *
-+       * Do _not_ use "current" here. We might be inside
-+       * an interrupt in the middle of a task switch..
-+       */
-+      pgd_paddr = read_cr3();
-+      pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
-+      if (!pmd_k)
-+              return -1;
-+      pte_k = pte_offset_kernel(pmd_k, address);
-+      if (!pte_present(*pte_k))
-+              return -1;
-+      return 0;
-+#else
-+      pgd_t *pgd, *pgd_ref;
-+      pud_t *pud, *pud_ref;
-+      pmd_t *pmd, *pmd_ref;
-+      pte_t *pte, *pte_ref;
-+
-+      /* Make sure we are in vmalloc area */
-+      if (!(address >= VMALLOC_START && address < VMALLOC_END))
-+              return -1;
-+
-+      /* Copy kernel mappings over when needed. This can also
-+         happen within a race in page table update. In the later
-+         case just flush. */
-+
-+      /* On Xen the line below does not always work. Needs investigating! */
-+      /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
-+      pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
-+      pgd += pgd_index(address);
-+      pgd_ref = pgd_offset_k(address);
-+      if (pgd_none(*pgd_ref))
-+              return -1;
-+      if (pgd_none(*pgd))
-+              set_pgd(pgd, *pgd_ref);
-+      else
-+              BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
-+
-+      /* Below here mismatches are bugs because these lower tables
-+         are shared */
-+
-+      pud = pud_offset(pgd, address);
-+      pud_ref = pud_offset(pgd_ref, address);
-+      if (pud_none(*pud_ref))
-+              return -1;
-+      if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
-+              BUG();
-+      pmd = pmd_offset(pud, address);
-+      pmd_ref = pmd_offset(pud_ref, address);
-+      if (pmd_none(*pmd_ref))
-+              return -1;
-+      if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
-+              BUG();
-+      pte_ref = pte_offset_kernel(pmd_ref, address);
-+      if (!pte_present(*pte_ref))
-+              return -1;
-+      pte = pte_offset_kernel(pmd, address);
-+      /* Don't use pte_page here, because the mappings can point
-+         outside mem_map, and the NUMA hash lookup cannot handle
-+         that. */
-+      if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
-+              BUG();
-+      return 0;
-+#endif
-+}
-+
-+int show_unhandled_signals = 1;
-+
-+/*
-+ * This routine handles page faults.  It determines the address,
-+ * and the problem, and then passes it off to one of the appropriate
-+ * routines.
-+ */
-+#ifdef CONFIG_X86_64
-+asmlinkage
-+#endif
-+void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
-+{
-+      struct task_struct *tsk;
-+      struct mm_struct *mm;
-+      struct vm_area_struct *vma;
-+      unsigned long address;
-+      int write, si_code;
-+      int fault;
-+#ifdef CONFIG_X86_64
-+      unsigned long flags;
-+#endif
-+
-+      /*
-+       * We can fault from pretty much anywhere, with unknown IRQ state.
-+       */
-+      trace_hardirqs_fixup();
-+
-+      /* Set the "privileged fault" bit to something sane. */
-+      if (user_mode_vm(regs))
-+              error_code |= PF_USER;
-+      else
-+              error_code &= ~PF_USER;
-+
-+      tsk = current;
-+      mm = tsk->mm;
-+      prefetchw(&mm->mmap_sem);
-+
-+      /* get the address */
-+      address = read_cr2();
-+
-+      si_code = SEGV_MAPERR;
-+
-+      if (notify_page_fault(regs))
-+              return;
-+
-+      /*
-+       * We fault-in kernel-space virtual memory on-demand. The
-+       * 'reference' page table is init_mm.pgd.
-+       *
-+       * NOTE! We MUST NOT take any locks for this case. We may
-+       * be in an interrupt or a critical region, and should
-+       * only copy the information from the master page table,
-+       * nothing more.
-+       *
-+       * This verifies that the fault happens in kernel space
-+       * (error_code & 4) == 0, and that the fault was not a
-+       * protection error (error_code & 9) == 0.
-+       */
-+#ifdef CONFIG_X86_32
-+      if (unlikely(address >= TASK_SIZE)) {
-+#else
-+      if (unlikely(address >= TASK_SIZE64)) {
-+#endif
-+              /* Faults in hypervisor area can never be patched up. */
-+#if defined(CONFIG_X86_XEN)
-+              if (address >= hypervisor_virt_start)
-+                      goto bad_area_nosemaphore;
-+#elif defined(CONFIG_X86_64_XEN)
-+              /* Faults in hypervisor area are never spurious. */
-+              if (address >= HYPERVISOR_VIRT_START
-+                  && address < HYPERVISOR_VIRT_END)
-+                      goto bad_area_nosemaphore;
-+#endif
-+              if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
-+                  vmalloc_fault(address) >= 0)
-+                      return;
-+
-+              /* Can handle a stale RO->RW TLB */
-+              if (spurious_fault(address, error_code))
-+                      return;
-+
-+              /*
-+               * Don't take the mm semaphore here. If we fixup a prefetch
-+               * fault we could otherwise deadlock.
-+               */
-+              goto bad_area_nosemaphore;
-+      }
-+
-+
-+#ifdef CONFIG_X86_32
-+      /* It's safe to allow irq's after cr2 has been saved and the vmalloc
-+         fault has been handled. */
-+      if (regs->flags & (X86_EFLAGS_IF|VM_MASK))
-+              local_irq_enable();
-+
-+      /*
-+       * If we're in an interrupt, have no user context or are running in an
-+       * atomic region then we must not take the fault.
-+       */
-+      if (in_atomic() || !mm)
-+              goto bad_area_nosemaphore;
-+#else /* CONFIG_X86_64 */
-+      if (likely(regs->flags & X86_EFLAGS_IF))
-+              local_irq_enable();
-+
-+      if (unlikely(error_code & PF_RSVD))
-+              pgtable_bad(address, regs, error_code);
-+
-+      /*
-+       * If we're in an interrupt, have no user context or are running in an
-+       * atomic region then we must not take the fault.
-+       */
-+      if (unlikely(in_atomic() || !mm))
-+              goto bad_area_nosemaphore;
-+
-+      /*
-+       * User-mode registers count as a user access even for any
-+       * potential system fault or CPU buglet.
-+       */
-+      if (user_mode_vm(regs))
-+              error_code |= PF_USER;
-+again:
-+#endif
-+      /* When running in the kernel we expect faults to occur only to
-+       * addresses in user space.  All other faults represent errors in the
-+       * kernel and should generate an OOPS.  Unfortunately, in the case of an
-+       * erroneous fault occurring in a code path which already holds mmap_sem
-+       * we will deadlock attempting to validate the fault against the
-+       * address space.  Luckily the kernel only validly references user
-+       * space from well defined areas of code, which are listed in the
-+       * exceptions table.
-+       *
-+       * As the vast majority of faults will be valid we will only perform
-+       * the source reference check when there is a possibility of a deadlock.
-+       * Attempt to lock the address space, if we cannot we then validate the
-+       * source.  If this is invalid we can skip the address space check,
-+       * thus avoiding the deadlock.
-+       */
-+      if (!down_read_trylock(&mm->mmap_sem)) {
-+              if ((error_code & PF_USER) == 0 &&
-+                  !search_exception_tables(regs->ip))
-+                      goto bad_area_nosemaphore;
-+              down_read(&mm->mmap_sem);
-+      }
-+
-+      vma = find_vma(mm, address);
-+      if (!vma)
-+              goto bad_area;
-+      if (vma->vm_start <= address)
-+              goto good_area;
-+      if (!(vma->vm_flags & VM_GROWSDOWN))
-+              goto bad_area;
-+      if (error_code & PF_USER) {
-+              /*
-+               * Accessing the stack below %sp is always a bug.
-+               * The large cushion allows instructions like enter
-+               * and pusha to work.  ("enter $65535,$31" pushes
-+               * 32 pointers and then decrements %sp by 65535.)
-+               */
-+              if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
-+                      goto bad_area;
-+      }
-+      if (expand_stack(vma, address))
-+              goto bad_area;
-+/*
-+ * Ok, we have a good vm_area for this memory access, so
-+ * we can handle it..
-+ */
-+good_area:
-+      si_code = SEGV_ACCERR;
-+      write = 0;
-+      switch (error_code & (PF_PROT|PF_WRITE)) {
-+      default:        /* 3: write, present */
-+              /* fall through */
-+      case PF_WRITE:          /* write, not present */
-+              if (!(vma->vm_flags & VM_WRITE))
-+                      goto bad_area;
-+              write++;
-+              break;
-+      case PF_PROT:           /* read, present */
-+              goto bad_area;
-+      case 0:                 /* read, not present */
-+              if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-+                      goto bad_area;
-+      }
-+
-+#ifdef CONFIG_X86_32
-+survive:
-+#endif
-+      /*
-+       * If for any reason at all we couldn't handle the fault,
-+       * make sure we exit gracefully rather than endlessly redo
-+       * the fault.
-+       */
-+      fault = handle_mm_fault(mm, vma, address, write);
-+      if (unlikely(fault & VM_FAULT_ERROR)) {
-+              if (fault & VM_FAULT_OOM)
-+                      goto out_of_memory;
-+              else if (fault & VM_FAULT_SIGBUS)
-+                      goto do_sigbus;
-+              BUG();
-+      }
-+      if (fault & VM_FAULT_MAJOR)
-+              tsk->maj_flt++;
-+      else
-+              tsk->min_flt++;
-+
-+#ifdef CONFIG_X86_32
-+      /*
-+       * Did it hit the DOS screen memory VA from vm86 mode?
-+       */
-+      if (v8086_mode(regs)) {
-+              unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
-+              if (bit < 32)
-+                      tsk->thread.screen_bitmap |= 1 << bit;
-+      }
-+#endif
-+      up_read(&mm->mmap_sem);
-+      return;
-+
-+/*
-+ * Something tried to access memory that isn't in our memory map..
-+ * Fix it, but check if it's kernel or user first..
-+ */
-+bad_area:
-+      up_read(&mm->mmap_sem);
-+
-+bad_area_nosemaphore:
-+      /* User mode accesses just cause a SIGSEGV */
-+      if (error_code & PF_USER) {
-+              /*
-+               * It's possible to have interrupts off here.
-+               */
-+              local_irq_enable();
-+
-+              /*
-+               * Valid to do another page fault here because this one came
-+               * from user space.
-+               */
-+              if (is_prefetch(regs, address, error_code))
-+                      return;
-+
-+              if (is_errata100(regs, address))
-+                      return;
-+
-+              if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
-+                  printk_ratelimit()) {
-+                      printk(
-+#ifdef CONFIG_X86_32
-+                      "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
-+#else
-+                      "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
-+#endif
-+                      task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
-+                      tsk->comm, task_pid_nr(tsk), address, regs->ip,
-+                      regs->sp, error_code);
-+                      print_vma_addr(" in ", regs->ip);
-+                      printk("\n");
-+              }
-+
-+              tsk->thread.cr2 = address;
-+              /* Kernel addresses are always protection faults */
-+              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-+              tsk->thread.trap_no = 14;
-+              force_sig_info_fault(SIGSEGV, si_code, address, tsk);
-+              return;
-+      }
-+
-+      if (is_f00f_bug(regs, address))
-+              return;
-+
-+no_context:
-+      /* Are we prepared to handle this kernel fault?  */
-+      if (fixup_exception(regs))
-+              return;
-+
-+      /*
-+       * X86_32
-+       * Valid to do another page fault here, because if this fault
-+       * had been triggered by is_prefetch fixup_exception would have
-+       * handled it.
-+       *
-+       * X86_64
-+       * Hall of shame of CPU/BIOS bugs.
-+       */
-+      if (is_prefetch(regs, address, error_code))
-+              return;
-+
-+      if (is_errata93(regs, address))
-+              return;
-+
-+/*
-+ * Oops. The kernel tried to access some bad page. We'll have to
-+ * terminate things with extreme prejudice.
-+ */
-+#ifdef CONFIG_X86_32
-+      bust_spinlocks(1);
-+#else
-+      flags = oops_begin();
-+#endif
-+
-+      show_fault_oops(regs, error_code, address);
-+
-+      tsk->thread.cr2 = address;
-+      tsk->thread.trap_no = 14;
-+      tsk->thread.error_code = error_code;
-+
-+#ifdef CONFIG_X86_32
-+      die("Oops", regs, error_code);
-+      bust_spinlocks(0);
-+      do_exit(SIGKILL);
-+#else
-+      if (__die("Oops", regs, error_code))
-+              regs = NULL;
-+      /* Executive summary in case the body of the oops scrolled away */
-+      printk(KERN_EMERG "CR2: %016lx\n", address);
-+      oops_end(flags, regs, SIGKILL);
-+#endif
-+
-+/*
-+ * We ran out of memory, or some other thing happened to us that made
-+ * us unable to handle the page fault gracefully.
-+ */
-+out_of_memory:
-+      up_read(&mm->mmap_sem);
-+      if (is_global_init(tsk)) {
-+              yield();
-+#ifdef CONFIG_X86_32
-+              down_read(&mm->mmap_sem);
-+              goto survive;
-+#else
-+              goto again;
-+#endif
-+      }
-+
-+      printk("VM: killing process %s\n", tsk->comm);
-+      if (error_code & PF_USER)
-+              do_group_exit(SIGKILL);
-+      goto no_context;
-+
-+do_sigbus:
-+      up_read(&mm->mmap_sem);
-+
-+      /* Kernel mode? Handle exceptions or die */
-+      if (!(error_code & PF_USER))
-+              goto no_context;
-+#ifdef CONFIG_X86_32
-+      /* User space => ok to do another page fault */
-+      if (is_prefetch(regs, address, error_code))
-+              return;
-+#endif
-+      tsk->thread.cr2 = address;
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = 14;
-+      force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
-+}
-+
-+DEFINE_SPINLOCK(pgd_lock);
-+LIST_HEAD(pgd_list);
-+
-+void vmalloc_sync_all(void)
-+{
-+#ifdef CONFIG_X86_32
-+      /*
-+       * Note that races in the updates of insync and start aren't
-+       * problematic: insync can only get set bits added, and updates to
-+       * start are only improving performance (without affecting correctness
-+       * if undone).
-+       * XEN: To work on PAE, we need to iterate over PMDs rather than PGDs.
-+       *      This change works just fine with 2-level paging too.
-+       */
-+#define sync_index(a) ((a) >> PMD_SHIFT)
-+      static DECLARE_BITMAP(insync, PTRS_PER_PGD*PTRS_PER_PMD);
-+      static unsigned long start = TASK_SIZE;
-+      unsigned long address;
-+
-+      if (SHARED_KERNEL_PMD)
-+              return;
-+
-+      BUILD_BUG_ON(TASK_SIZE & ~PMD_MASK);
-+      for (address = start;
-+           address < hypervisor_virt_start;
-+           address += PMD_SIZE) {
-+              if (!test_bit(sync_index(address), insync)) {
-+                      unsigned long flags;
-+                      struct page *page;
-+
-+                      spin_lock_irqsave(&pgd_lock, flags);
-+                      /* XEN: failure path assumes non-empty pgd_list. */
-+                      if (unlikely(list_empty(&pgd_list))) {
-+                              spin_unlock_irqrestore(&pgd_lock, flags);
-+                              return;
-+                      }
-+                      list_for_each_entry(page, &pgd_list, lru) {
-+                              if (!vmalloc_sync_one(page_address(page),
-+                                                    address))
-+                                      break;
-+                      }
-+                      spin_unlock_irqrestore(&pgd_lock, flags);
-+                      if (!page)
-+                              set_bit(sync_index(address), insync);
-+              }
-+              if (address == start && test_bit(sync_index(address), insync))
-+                      start = address + PMD_SIZE;
-+      }
-+#else /* CONFIG_X86_64 */
-+      /*
-+       * Note that races in the updates of insync and start aren't
-+       * problematic: insync can only get set bits added, and updates to
-+       * start are only improving performance (without affecting correctness
-+       * if undone).
-+       */
-+      static DECLARE_BITMAP(insync, PTRS_PER_PGD);
-+      static unsigned long start = VMALLOC_START & PGDIR_MASK;
-+      unsigned long address;
-+
-+      for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
-+              if (!test_bit(pgd_index(address), insync)) {
-+                      const pgd_t *pgd_ref = pgd_offset_k(address);
-+                      unsigned long flags;
-+                      struct page *page;
-+
-+                      if (pgd_none(*pgd_ref))
-+                              continue;
-+                      spin_lock_irqsave(&pgd_lock, flags);
-+                      list_for_each_entry(page, &pgd_list, lru) {
-+                              pgd_t *pgd;
-+                              pgd = (pgd_t *)page_address(page) + pgd_index(address);
-+                              if (pgd_none(*pgd))
-+                                      set_pgd(pgd, *pgd_ref);
-+                              else
-+                                      BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
-+                      }
-+                      spin_unlock_irqrestore(&pgd_lock, flags);
-+                      set_bit(pgd_index(address), insync);
-+              }
-+              if (address == start)
-+                      start = address + PGDIR_SIZE;
-+      }
-+      /* Check that there is no need to do the same for the modules area. */
-+      BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
-+      BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
-+                              (__START_KERNEL & PGDIR_MASK)));
-+#endif
-+}
---- a/arch/x86/mm/highmem_32-xen.c
-+++ b/arch/x86/mm/highmem_32-xen.c
-@@ -18,6 +18,49 @@ void kunmap(struct page *page)
-       kunmap_high(page);
- }
-+static void debug_kmap_atomic_prot(enum km_type type)
-+{
-+#ifdef CONFIG_DEBUG_HIGHMEM
-+      static unsigned warn_count = 10;
-+
-+      if (unlikely(warn_count == 0))
-+              return;
-+
-+      if (unlikely(in_interrupt())) {
-+              if (in_irq()) {
-+                      if (type != KM_IRQ0 && type != KM_IRQ1 &&
-+                          type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
-+                          type != KM_BOUNCE_READ) {
-+                              WARN_ON(1);
-+                              warn_count--;
-+                      }
-+              } else if (!irqs_disabled()) {  /* softirq */
-+                      if (type != KM_IRQ0 && type != KM_IRQ1 &&
-+                          type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
-+                          type != KM_SKB_SUNRPC_DATA &&
-+                          type != KM_SKB_DATA_SOFTIRQ &&
-+                          type != KM_BOUNCE_READ) {
-+                              WARN_ON(1);
-+                              warn_count--;
-+                      }
-+              }
-+      }
-+
-+      if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
-+                      type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
-+              if (!irqs_disabled()) {
-+                      WARN_ON(1);
-+                      warn_count--;
-+              }
-+      } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
-+              if (irq_count() == 0 && !irqs_disabled()) {
-+                      WARN_ON(1);
-+                      warn_count--;
-+              }
-+      }
-+#endif
-+}
-+
- /*
-  * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
-  * no global lock is needed and because the kmap code must perform a global TLB
-@@ -37,6 +80,8 @@ void *kmap_atomic_prot(struct page *page
-       if (!PageHighMem(page))
-               return page_address(page);
-+      debug_kmap_atomic_prot(type);
-+
-       idx = type + KM_TYPE_NR*smp_processor_id();
-       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-       BUG_ON(!pte_none(*(kmap_pte-idx)));
---- a/arch/x86/mm/hypervisor.c
-+++ b/arch/x86/mm/hypervisor.c
-@@ -831,15 +831,11 @@ int xen_limit_pages_to_max_mfn(
- }
- EXPORT_SYMBOL_GPL(xen_limit_pages_to_max_mfn);
--#ifdef __i386__
--int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
-+int write_ldt_entry(struct desc_struct *ldt, int entry, const void *desc)
- {
--      __u32 *lp = (__u32 *)((char *)ldt + entry * 8);
--      maddr_t mach_lp = arbitrary_virt_to_machine(lp);
--      return HYPERVISOR_update_descriptor(
--              mach_lp, (u64)entry_a | ((u64)entry_b<<32));
-+      maddr_t mach_lp = arbitrary_virt_to_machine(ldt + entry);
-+      return HYPERVISOR_update_descriptor(mach_lp, *(const u64*)desc);
- }
--#endif
- #define MAX_BATCHED_FULL_PTES 32
---- a/arch/x86/mm/init_32-xen.c
-+++ b/arch/x86/mm/init_32-xen.c
-@@ -27,13 +27,13 @@
- #include <linux/bootmem.h>
- #include <linux/slab.h>
- #include <linux/proc_fs.h>
--#include <linux/efi.h>
- #include <linux/memory_hotplug.h>
- #include <linux/initrd.h>
- #include <linux/cpumask.h>
- #include <linux/dma-mapping.h>
- #include <linux/scatterlist.h>
-+#include <asm/asm.h>
- #include <asm/processor.h>
- #include <asm/system.h>
- #include <asm/uaccess.h>
-@@ -42,18 +42,22 @@
- #include <asm/fixmap.h>
- #include <asm/e820.h>
- #include <asm/apic.h>
-+#include <asm/bugs.h>
- #include <asm/tlb.h>
- #include <asm/tlbflush.h>
-+#include <asm/pgalloc.h>
- #include <asm/sections.h>
- #include <asm/hypervisor.h>
- #include <asm/swiotlb.h>
-+#include <asm/setup.h>
-+#include <asm/cacheflush.h>
- unsigned int __VMALLOC_RESERVE = 128 << 20;
- DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
- unsigned long highstart_pfn, highend_pfn;
--static int noinline do_test_wp_bit(void);
-+static noinline int do_test_wp_bit(void);
- /*
-  * Creates a middle page table and puts a pointer to it in the
-@@ -64,17 +68,16 @@ static pmd_t * __init one_md_table_init(
- {
-       pud_t *pud;
-       pmd_t *pmd_table;
--              
-+
- #ifdef CONFIG_X86_PAE
-       if (!(__pgd_val(*pgd) & _PAGE_PRESENT)) {
-               pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
--              paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
-+              paravirt_alloc_pd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
-               make_lowmem_page_readonly(pmd_table, XENFEAT_writable_page_tables);
-               set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
-               pud = pud_offset(pgd, 0);
--              if (pmd_table != pmd_offset(pud, 0))
--                      BUG();
-+              BUG_ON(pmd_table != pmd_offset(pud, 0));
-       }
- #endif
-       pud = pud_offset(pgd, 0);
-@@ -85,7 +88,7 @@ static pmd_t * __init one_md_table_init(
- /*
-  * Create a page table and place a pointer to it in a middle page
-- * directory entry.
-+ * directory entry:
-  */
- static pte_t * __init one_page_table_init(pmd_t *pmd)
- {
-@@ -99,9 +102,10 @@ static pte_t * __init one_page_table_ini
- #ifdef CONFIG_DEBUG_PAGEALLOC
-               page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
- #endif
--              if (!page_table)
-+              if (!page_table) {
-                       page_table =
-                               (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
-+              }
-               paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
-               make_lowmem_page_readonly(page_table,
-@@ -114,22 +118,21 @@ static pte_t * __init one_page_table_ini
- }
- /*
-- * This function initializes a certain range of kernel virtual memory 
-+ * This function initializes a certain range of kernel virtual memory
-  * with new bootmem page tables, everywhere page tables are missing in
-  * the given range.
-- */
--
--/*
-- * NOTE: The pagetables are allocated contiguous on the physical space 
-- * so we can cache the place of the first one and move around without 
-+ *
-+ * NOTE: The pagetables are allocated contiguous on the physical space
-+ * so we can cache the place of the first one and move around without
-  * checking the pgd every time.
-  */
--static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
-+static void __init
-+page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base)
- {
--      pgd_t *pgd;
--      pmd_t *pmd;
-       int pgd_idx, pmd_idx;
-       unsigned long vaddr;
-+      pgd_t *pgd;
-+      pmd_t *pmd;
-       vaddr = start;
-       pgd_idx = pgd_index(vaddr);
-@@ -139,7 +142,8 @@ static void __init page_table_range_init
-       for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
-               pmd = one_md_table_init(pgd);
-               pmd = pmd + pmd_index(vaddr);
--              for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
-+              for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
-+                                                      pmd++, pmd_idx++) {
-                       if (vaddr < hypervisor_virt_start)
-                               one_page_table_init(pmd);
-@@ -157,17 +161,17 @@ static inline int is_kernel_text(unsigne
- }
- /*
-- * This maps the physical memory to kernel virtual address space, a total 
-- * of max_low_pfn pages, by creating page tables starting from address 
-- * PAGE_OFFSET.
-+ * This maps the physical memory to kernel virtual address space, a total
-+ * of max_low_pfn pages, by creating page tables starting from address
-+ * PAGE_OFFSET:
-  */
- static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
- {
-+      int pgd_idx, pmd_idx, pte_ofs;
-       unsigned long pfn;
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *pte;
--      int pgd_idx, pmd_idx, pte_ofs;
-       unsigned long max_ram_pfn = xen_start_info->nr_pages;
-       if (max_ram_pfn > max_low_pfn)
-@@ -195,36 +199,49 @@ static void __init kernel_physical_mappi
-               if (pfn >= max_low_pfn)
-                       continue;
-               pmd += pmd_idx;
--              for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
--                      unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
--                      if (address >= hypervisor_virt_start)
-+              for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
-+                   pmd++, pmd_idx++) {
-+                      unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
-+
-+                      if (addr >= hypervisor_virt_start)
-                               continue;
--                      /* Map with big pages if possible, otherwise create normal page tables. */
-+                      /*
-+                       * Map with big pages if possible, otherwise
-+                       * create normal page tables:
-+                       */
-                       if (cpu_has_pse) {
--                              unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
--                              if (is_kernel_text(address) || is_kernel_text(address2))
--                                      set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
--                              else
--                                      set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
-+                              unsigned int addr2;
-+                              pgprot_t prot = PAGE_KERNEL_LARGE;
-+
-+                              addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
-+                                      PAGE_OFFSET + PAGE_SIZE-1;
-+
-+                              if (is_kernel_text(addr) ||
-+                                  is_kernel_text(addr2))
-+                                      prot = PAGE_KERNEL_LARGE_EXEC;
-+
-+                              set_pmd(pmd, pfn_pmd(pfn, prot));
-                               pfn += PTRS_PER_PTE;
--                      } else {
--                              pte = one_page_table_init(pmd);
-+                              continue;
-+                      }
-+                      pte = one_page_table_init(pmd);
-+
-+                      for (pte += pte_ofs;
-+                           pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
-+                           pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
-+                              pgprot_t prot = PAGE_KERNEL;
-+
-+                              /* XEN: Only map initial RAM allocation. */
-+                              if ((pfn >= max_ram_pfn) || pte_present(*pte))
-+                                      continue;
-+                              if (is_kernel_text(addr))
-+                                      prot = PAGE_KERNEL_EXEC;
--                              for (pte += pte_ofs;
--                                   pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
--                                   pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
--                                      /* XEN: Only map initial RAM allocation. */
--                                      if ((pfn >= max_ram_pfn) || pte_present(*pte))
--                                              continue;
--                                      if (is_kernel_text(address))
--                                              set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
--                                      else
--                                              set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
--                              }
--                              pte_ofs = 0;
-+                              set_pte(pte, pfn_pte(pfn, prot));
-                       }
-+                      pte_ofs = 0;
-               }
-               pmd_idx = 0;
-       }
-@@ -245,57 +262,23 @@ static inline int page_kills_ppro(unsign
- #endif
--int page_is_ram(unsigned long pagenr)
--{
--      int i;
--      unsigned long addr, end;
--
--      if (efi_enabled) {
--              efi_memory_desc_t *md;
--              void *p;
--
--              for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
--                      md = p;
--                      if (!is_available_memory(md))
--                              continue;
--                      addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
--                      end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
--
--                      if ((pagenr >= addr) && (pagenr < end))
--                              return 1;
--              }
--              return 0;
--      }
--
--      for (i = 0; i < e820.nr_map; i++) {
--
--              if (e820.map[i].type != E820_RAM)       /* not usable memory */
--                      continue;
--              /*
--               *      !!!FIXME!!! Some BIOSen report areas as RAM that
--               *      are not. Notably the 640->1Mb area. We need a sanity
--               *      check here.
--               */
--              addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
--              end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
--              if  ((pagenr >= addr) && (pagenr < end))
--                      return 1;
--      }
--      return 0;
--}
--
- #ifdef CONFIG_HIGHMEM
- pte_t *kmap_pte;
- pgprot_t kmap_prot;
--#define kmap_get_fixmap_pte(vaddr)                                    \
--      pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr))
-+static inline pte_t *kmap_get_fixmap_pte(unsigned long vaddr)
-+{
-+      return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
-+                      vaddr), vaddr), vaddr);
-+}
- static void __init kmap_init(void)
- {
-       unsigned long kmap_vstart;
--      /* cache the first kmap pte */
-+      /*
-+       * Cache the first kmap pte:
-+       */
-       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
-       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
-@@ -304,11 +287,11 @@ static void __init kmap_init(void)
- static void __init permanent_kmaps_init(pgd_t *pgd_base)
- {
-+      unsigned long vaddr;
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
--      unsigned long vaddr;
-       vaddr = PKMAP_BASE;
-       page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
-@@ -317,7 +300,7 @@ static void __init permanent_kmaps_init(
-       pud = pud_offset(pgd, vaddr);
-       pmd = pmd_offset(pud, vaddr);
-       pte = pte_offset_kernel(pmd, vaddr);
--      pkmap_page_table = pte; 
-+      pkmap_page_table = pte;
- }
- static void __meminit free_new_highpage(struct page *page, int pfn)
-@@ -337,7 +320,8 @@ void __init add_one_highpage_init(struct
-               SetPageReserved(page);
- }
--static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long pfn)
-+static int __meminit
-+add_one_highpage_hotplug(struct page *page, unsigned long pfn)
- {
-       free_new_highpage(page, pfn);
-       totalram_pages++;
-@@ -345,6 +329,7 @@ static int __meminit add_one_highpage_ho
-       max_mapnr = max(pfn, max_mapnr);
- #endif
-       num_physpages++;
-+
-       return 0;
- }
-@@ -352,7 +337,7 @@ static int __meminit add_one_highpage_ho
-  * Not currently handling the NUMA case.
-  * Assuming single node and all memory that
-  * has been added dynamically that would be
-- * onlined here is in HIGHMEM
-+ * onlined here is in HIGHMEM.
-  */
- void __meminit online_page(struct page *page)
- {
-@@ -360,13 +345,11 @@ void __meminit online_page(struct page *
-       add_one_highpage_hotplug(page, page_to_pfn(page));
- }
--
--#ifdef CONFIG_NUMA
--extern void set_highmem_pages_init(int);
--#else
-+#ifndef CONFIG_NUMA
- static void __init set_highmem_pages_init(int bad_ppro)
- {
-       int pfn;
-+
-       for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) {
-               /*
-                * Holes under sparsemem might not have no mem_map[]:
-@@ -376,23 +359,18 @@ static void __init set_highmem_pages_ini
-       }
-       totalram_pages += totalhigh_pages;
- }
--#endif /* CONFIG_FLATMEM */
-+#endif /* !CONFIG_NUMA */
- #else
--#define kmap_init() do { } while (0)
--#define permanent_kmaps_init(pgd_base) do { } while (0)
--#define set_highmem_pages_init(bad_ppro) do { } while (0)
-+# define kmap_init()                          do { } while (0)
-+# define permanent_kmaps_init(pgd_base)               do { } while (0)
-+# define set_highmem_pages_init(bad_ppro)     do { } while (0)
- #endif /* CONFIG_HIGHMEM */
--unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
-+pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
- EXPORT_SYMBOL(__PAGE_KERNEL);
--unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
--#ifdef CONFIG_NUMA
--extern void __init remap_numa_kva(void);
--#else
--#define remap_numa_kva() do {} while (0)
--#endif
-+pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
- pgd_t *swapper_pg_dir;
-@@ -410,9 +388,8 @@ static void __init xen_pagetable_setup_d
-  * the boot process.
-  *
-  * If we're booting on native hardware, this will be a pagetable
-- * constructed in arch/i386/kernel/head.S, and not running in PAE mode
-- * (even if we'll end up running in PAE).  The root of the pagetable
-- * will be swapper_pg_dir.
-+ * constructed in arch/x86/kernel/head_32.S.  The root of the
-+ * pagetable will be swapper_pg_dir.
-  *
-  * If we're booting paravirtualized under a hypervisor, then there are
-  * more options: we may already be running PAE, and the pagetable may
-@@ -424,10 +401,10 @@ static void __init xen_pagetable_setup_d
-  * be partially populated, and so it avoids stomping on any existing
-  * mappings.
-  */
--static void __init pagetable_init (void)
-+static void __init pagetable_init(void)
- {
--      unsigned long vaddr, end;
-       pgd_t *pgd_base = (pgd_t *)xen_start_info->pt_base;
-+      unsigned long vaddr, end;
-       xen_pagetable_setup_start(pgd_base);
-@@ -449,34 +426,36 @@ static void __init pagetable_init (void)
-        * Fixed mappings, only the page table structure has to be
-        * created - mappings will be set by set_fixmap():
-        */
-+      early_ioremap_clear();
-       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-       end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
-       page_table_range_init(vaddr, end, pgd_base);
-+      early_ioremap_reset();
-       permanent_kmaps_init(pgd_base);
-       xen_pagetable_setup_done(pgd_base);
- }
--#if defined(CONFIG_HIBERNATION) || defined(CONFIG_ACPI)
-+#if defined(CONFIG_ACPI_SLEEP) && !defined(CONFIG_XEN)
- /*
-- * Swap suspend & friends need this for resume because things like the intel-agp
-+ * ACPI suspend needs this for resume, because things like the intel-agp
-  * driver might have split up a kernel 4MB mapping.
-  */
--char __nosavedata swsusp_pg_dir[PAGE_SIZE]
--      __attribute__ ((aligned (PAGE_SIZE)));
-+char swsusp_pg_dir[PAGE_SIZE]
-+      __attribute__ ((aligned(PAGE_SIZE)));
- static inline void save_pg_dir(void)
- {
-       memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
- }
--#else
-+#else /* !CONFIG_ACPI_SLEEP */
- static inline void save_pg_dir(void)
- {
- }
--#endif
-+#endif /* !CONFIG_ACPI_SLEEP */
--void zap_low_mappings (void)
-+void zap_low_mappings(void)
- {
-       int i;
-@@ -488,22 +467,24 @@ void zap_low_mappings (void)
-        * Note that "pgd_clear()" doesn't do it for
-        * us, because pgd_clear() is a no-op on i386.
-        */
--      for (i = 0; i < USER_PTRS_PER_PGD; i++)
-+      for (i = 0; i < USER_PTRS_PER_PGD; i++) {
- #if defined(CONFIG_X86_PAE) && !defined(CONFIG_XEN)
-               set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
- #else
-               set_pgd(swapper_pg_dir+i, __pgd(0));
- #endif
-+      }
-       flush_tlb_all();
- }
--int nx_enabled = 0;
-+int nx_enabled;
-+
-+pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
-+EXPORT_SYMBOL_GPL(__supported_pte_mask);
- #ifdef CONFIG_X86_PAE
--static int disable_nx __initdata = 0;
--u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
--EXPORT_SYMBOL_GPL(__supported_pte_mask);
-+static int disable_nx __initdata;
- /*
-  * noexec = on|off
-@@ -520,11 +501,14 @@ static int __init noexec_setup(char *str
-                       __supported_pte_mask |= _PAGE_NX;
-                       disable_nx = 0;
-               }
--      } else if (!strcmp(str,"off")) {
--              disable_nx = 1;
--              __supported_pte_mask &= ~_PAGE_NX;
--      } else
--              return -EINVAL;
-+      } else {
-+              if (!strcmp(str, "off")) {
-+                      disable_nx = 1;
-+                      __supported_pte_mask &= ~_PAGE_NX;
-+              } else {
-+                      return -EINVAL;
-+              }
-+      }
-       return 0;
- }
-@@ -536,6 +520,7 @@ static void __init set_nx(void)
-       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
-               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
-+
-               if ((v[3] & (1 << 20)) && !disable_nx) {
-                       rdmsr(MSR_EFER, l, h);
-                       l |= EFER_NX;
-@@ -545,35 +530,6 @@ static void __init set_nx(void)
-               }
-       }
- }
--
--/*
-- * Enables/disables executability of a given kernel page and
-- * returns the previous setting.
-- */
--int __init set_kernel_exec(unsigned long vaddr, int enable)
--{
--      pte_t *pte;
--      int ret = 1;
--
--      if (!nx_enabled)
--              goto out;
--
--      pte = lookup_address(vaddr);
--      BUG_ON(!pte);
--
--      if (!pte_exec_kernel(*pte))
--              ret = 0;
--
--      if (enable)
--              pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
--      else
--              pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);
--      pte_update_defer(&init_mm, vaddr, pte);
--      __flush_tlb_all();
--out:
--      return ret;
--}
--
- #endif
- /*
-@@ -590,21 +546,10 @@ void __init paging_init(void)
- #ifdef CONFIG_X86_PAE
-       set_nx();
-       if (nx_enabled)
--              printk("NX (Execute Disable) protection: active\n");
-+              printk(KERN_INFO "NX (Execute Disable) protection: active\n");
- #endif
--
-       pagetable_init();
--#if defined(CONFIG_X86_PAE) && !defined(CONFIG_XEN)
--      /*
--       * We will bail out later - printk doesn't work right now so
--       * the user would just see a hanging kernel.
--       * when running as xen domain we are already in PAE mode at
--       * this point.
--       */
--      if (cpu_has_pae)
--              set_in_cr4(X86_CR4_PAE);
--#endif
-       __flush_tlb_all();
-       kmap_init();
-@@ -631,10 +576,10 @@ void __init paging_init(void)
-  * used to involve black magic jumps to work around some nasty CPU bugs,
-  * but fortunately the switch to using exceptions got rid of all that.
-  */
--
- static void __init test_wp_bit(void)
- {
--      printk("Checking if this processor honours the WP bit even in supervisor mode... ");
-+      printk(KERN_INFO
-+  "Checking if this processor honours the WP bit even in supervisor mode...");
-       /* Any page-aligned address will do, the test is non-destructive */
-       __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY);
-@@ -642,23 +587,22 @@ static void __init test_wp_bit(void)
-       clear_fixmap(FIX_WP_TEST);
-       if (!boot_cpu_data.wp_works_ok) {
--              printk("No.\n");
-+              printk(KERN_CONT "No.\n");
- #ifdef CONFIG_X86_WP_WORKS_OK
--              panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
-+              panic(
-+  "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
- #endif
-       } else {
--              printk("Ok.\n");
-+              printk(KERN_CONT "Ok.\n");
-       }
- }
--static struct kcore_list kcore_mem, kcore_vmalloc; 
-+static struct kcore_list kcore_mem, kcore_vmalloc;
- void __init mem_init(void)
- {
--      extern int ppro_with_ram_bug(void);
-       int codesize, reservedpages, datasize, initsize;
--      int tmp;
--      int bad_ppro;
-+      int tmp, bad_ppro;
-       unsigned long pfn;
- #if defined(CONFIG_SWIOTLB)
-@@ -668,19 +612,19 @@ void __init mem_init(void)
- #ifdef CONFIG_FLATMEM
-       BUG_ON(!mem_map);
- #endif
--      
-       bad_ppro = ppro_with_ram_bug();
- #ifdef CONFIG_HIGHMEM
-       /* check that fixmap and pkmap do not overlap */
--      if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
--              printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");
-+      if (PKMAP_BASE + LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
-+              printk(KERN_ERR
-+                      "fixmap and kmap areas overlap - this will crash\n");
-               printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
--                              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);
-+                              PKMAP_BASE, PKMAP_BASE + LAST_PKMAP*PAGE_SIZE,
-+                              FIXADDR_START);
-               BUG();
-       }
- #endif
-- 
-       /* this will put all low memory onto the freelists */
-       totalram_pages += free_all_bootmem();
-       /* XEN: init and count low-mem pages outside initial allocation. */
-@@ -693,7 +637,7 @@ void __init mem_init(void)
-       reservedpages = 0;
-       for (tmp = 0; tmp < max_low_pfn; tmp++)
-               /*
--               * Only count reserved RAM pages
-+               * Only count reserved RAM pages:
-                */
-               if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
-                       reservedpages++;
-@@ -704,11 +648,12 @@ void __init mem_init(void)
-       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
--      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
--      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
-+      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-+      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END-VMALLOC_START);
--      printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
-+      printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
-+                      "%dk reserved, %dk data, %dk init, %ldk highmem)\n",
-               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-               num_physpages << (PAGE_SHIFT-10),
-               codesize >> 10,
-@@ -719,54 +664,53 @@ void __init mem_init(void)
-              );
- #if 1 /* double-sanity-check paranoia */
--      printk("virtual kernel memory layout:\n"
--             "    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-+      printk(KERN_INFO "virtual kernel memory layout:\n"
-+              "    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
- #ifdef CONFIG_HIGHMEM
--             "    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-+              "    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
- #endif
--             "    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
--             "    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
--             "      .init : 0x%08lx - 0x%08lx   (%4ld kB)\n"
--             "      .data : 0x%08lx - 0x%08lx   (%4ld kB)\n"
--             "      .text : 0x%08lx - 0x%08lx   (%4ld kB)\n",
--             FIXADDR_START, FIXADDR_TOP,
--             (FIXADDR_TOP - FIXADDR_START) >> 10,
-+              "    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
-+              "    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
-+              "      .init : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-+              "      .data : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-+              "      .text : 0x%08lx - 0x%08lx   (%4ld kB)\n",
-+              FIXADDR_START, FIXADDR_TOP,
-+              (FIXADDR_TOP - FIXADDR_START) >> 10,
- #ifdef CONFIG_HIGHMEM
--             PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
--             (LAST_PKMAP*PAGE_SIZE) >> 10,
-+              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
-+              (LAST_PKMAP*PAGE_SIZE) >> 10,
- #endif
--             VMALLOC_START, VMALLOC_END,
--             (VMALLOC_END - VMALLOC_START) >> 20,
-+              VMALLOC_START, VMALLOC_END,
-+              (VMALLOC_END - VMALLOC_START) >> 20,
--             (unsigned long)__va(0), (unsigned long)high_memory,
--             ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
-+              (unsigned long)__va(0), (unsigned long)high_memory,
-+              ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
--             (unsigned long)&__init_begin, (unsigned long)&__init_end,
--             ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
-+              (unsigned long)&__init_begin, (unsigned long)&__init_end,
-+              ((unsigned long)&__init_end -
-+               (unsigned long)&__init_begin) >> 10,
--             (unsigned long)&_etext, (unsigned long)&_edata,
--             ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
-+              (unsigned long)&_etext, (unsigned long)&_edata,
-+              ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
--             (unsigned long)&_text, (unsigned long)&_etext,
--             ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
-+              (unsigned long)&_text, (unsigned long)&_etext,
-+              ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
- #ifdef CONFIG_HIGHMEM
--      BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
--      BUG_ON(VMALLOC_END                     > PKMAP_BASE);
-+      BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE        > FIXADDR_START);
-+      BUG_ON(VMALLOC_END                              > PKMAP_BASE);
- #endif
--      BUG_ON(VMALLOC_START                   > VMALLOC_END);
--      BUG_ON((unsigned long)high_memory      > VMALLOC_START);
-+      BUG_ON(VMALLOC_START                            > VMALLOC_END);
-+      BUG_ON((unsigned long)high_memory               > VMALLOC_START);
- #endif /* double-sanity-check paranoia */
--#ifdef CONFIG_X86_PAE
--      if (!cpu_has_pae)
--              panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
--#endif
-       if (boot_cpu_data.wp_works_ok < 0)
-               test_wp_bit();
-+      cpa_init();
-+
-       /*
-        * Subtle. SMP is doing it's boot stuff late (because it has to
-        * fork idle threads) - but it also needs low mappings for the
-@@ -790,49 +734,35 @@ int arch_add_memory(int nid, u64 start, 
-       return __add_pages(zone, start_pfn, nr_pages);
- }
--
- #endif
--struct kmem_cache *pmd_cache;
--
--void __init pgtable_cache_init(void)
--{
--      if (PTRS_PER_PMD > 1)
--              pmd_cache = kmem_cache_create("pmd",
--                                            PTRS_PER_PMD*sizeof(pmd_t),
--                                            PTRS_PER_PMD*sizeof(pmd_t),
--                                            SLAB_PANIC,
--                                            pmd_ctor);
--}
--
- /*
-  * This function cannot be __init, since exceptions don't work in that
-  * section.  Put this after the callers, so that it cannot be inlined.
-  */
--static int noinline do_test_wp_bit(void)
-+static noinline int do_test_wp_bit(void)
- {
-       char tmp_reg;
-       int flag;
-       __asm__ __volatile__(
--              "       movb %0,%1      \n"
--              "1:     movb %1,%0      \n"
--              "       xorl %2,%2      \n"
-+              "       movb %0, %1     \n"
-+              "1:     movb %1, %0     \n"
-+              "       xorl %2, %2     \n"
-               "2:                     \n"
--              ".section __ex_table,\"a\"\n"
--              "       .align 4        \n"
--              "       .long 1b,2b     \n"
--              ".previous              \n"
-+              _ASM_EXTABLE(1b,2b)
-               :"=m" (*(char *)fix_to_virt(FIX_WP_TEST)),
-                "=q" (tmp_reg),
-                "=r" (flag)
-               :"2" (1)
-               :"memory");
--      
-+
-       return flag;
- }
- #ifdef CONFIG_DEBUG_RODATA
-+const int rodata_test_data = 0xC3;
-+EXPORT_SYMBOL_GPL(rodata_test_data);
- void mark_rodata_ro(void)
- {
-@@ -845,32 +775,58 @@ void mark_rodata_ro(void)
-       if (num_possible_cpus() <= 1)
- #endif
-       {
--              change_page_attr(virt_to_page(start),
--                               size >> PAGE_SHIFT, PAGE_KERNEL_RX);
--              printk("Write protecting the kernel text: %luk\n", size >> 10);
-+              set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
-+              printk(KERN_INFO "Write protecting the kernel text: %luk\n",
-+                      size >> 10);
-+
-+#ifdef CONFIG_CPA_DEBUG
-+              printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
-+                      start, start+size);
-+              set_pages_rw(virt_to_page(start), size>>PAGE_SHIFT);
-+
-+              printk(KERN_INFO "Testing CPA: write protecting again\n");
-+              set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
-+#endif
-       }
- #endif
-       start += size;
-       size = (unsigned long)__end_rodata - start;
--      change_page_attr(virt_to_page(start),
--                       size >> PAGE_SHIFT, PAGE_KERNEL_RO);
--      printk("Write protecting the kernel read-only data: %luk\n",
--             size >> 10);
-+      set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
-+      printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
-+              size >> 10);
-+      rodata_test();
-+
-+#ifdef CONFIG_CPA_DEBUG
-+      printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, start + size);
-+      set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
--      /*
--       * change_page_attr() requires a global_flush_tlb() call after it.
--       * We do this after the printk so that if something went wrong in the
--       * change, the printk gets out at least to give a better debug hint
--       * of who is the culprit.
--       */
--      global_flush_tlb();
-+      printk(KERN_INFO "Testing CPA: write protecting again\n");
-+      set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
-+#endif
- }
- #endif
- void free_init_pages(char *what, unsigned long begin, unsigned long end)
- {
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+      /*
-+       * If debugging page accesses then do not free this memory but
-+       * mark them not present - any buggy init-section access will
-+       * create a kernel page fault:
-+       */
-+      printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-+              begin, PAGE_ALIGN(end));
-+      set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-+#else
-       unsigned long addr;
-+      /*
-+       * We just marked the kernel text read only above, now that
-+       * we are going to free part of that, we need to make that
-+       * writeable first.
-+       */
-+      set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
-+
-       for (addr = begin; addr < end; addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               init_page_count(virt_to_page(addr));
-@@ -879,6 +835,7 @@ void free_init_pages(char *what, unsigne
-               totalram_pages++;
-       }
-       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
-+#endif
- }
- void free_initmem(void)
-@@ -894,4 +851,3 @@ void free_initrd_mem(unsigned long start
-       free_init_pages("initrd memory", start, end);
- }
- #endif
--
---- a/arch/x86/mm/init_64-xen.c
-+++ b/arch/x86/mm/init_64-xen.c
-@@ -46,14 +46,13 @@
- #include <asm/proto.h>
- #include <asm/smp.h>
- #include <asm/sections.h>
-+#include <asm/kdebug.h>
-+#include <asm/numa.h>
-+#include <asm/cacheflush.h>
- #include <xen/features.h>
--#ifndef Dprintk
--#define Dprintk(x...)
--#endif
--
--const struct dma_mapping_ops* dma_ops;
-+const struct dma_mapping_ops *dma_ops;
- EXPORT_SYMBOL(dma_ops);
- #if CONFIG_XEN_COMPAT <= 0x030002
-@@ -80,7 +79,21 @@ extern pte_t level1_fixmap_pgt[PTRS_PER_
-       (((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +   \
-       __START_KERNEL_map)))
--static void __meminit early_make_page_readonly(void *va, unsigned int feature)
-+pmd_t *__init early_get_pmd(unsigned long va)
-+{
-+      unsigned long addr;
-+      unsigned long *page = (unsigned long *)init_level4_pgt;
-+
-+      addr = page[pgd_index(va)];
-+      addr_to_page(addr, page);
-+
-+      addr = page[pud_index(va)];
-+      addr_to_page(addr, page);
-+
-+      return (pmd_t *)&page[pmd_index(va)];
-+}
-+
-+void __meminit early_make_page_readonly(void *va, unsigned int feature)
- {
-       unsigned long addr, _va = (unsigned long)va;
-       pte_t pte, *ptep;
-@@ -107,76 +120,6 @@ static void __meminit early_make_page_re
-               BUG();
- }
--static void __make_page_readonly(void *va)
--{
--      pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
--      unsigned long addr = (unsigned long) va;
--
--      pgd = pgd_offset_k(addr);
--      pud = pud_offset(pgd, addr);
--      pmd = pmd_offset(pud, addr);
--      ptep = pte_offset_kernel(pmd, addr);
--
--      pte.pte = ptep->pte & ~_PAGE_RW;
--      if (HYPERVISOR_update_va_mapping(addr, pte, 0))
--              xen_l1_entry_update(ptep, pte); /* fallback */
--
--      if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
--              __make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT));
--}
--
--static void __make_page_writable(void *va)
--{
--      pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
--      unsigned long addr = (unsigned long) va;
--
--      pgd = pgd_offset_k(addr);
--      pud = pud_offset(pgd, addr);
--      pmd = pmd_offset(pud, addr);
--      ptep = pte_offset_kernel(pmd, addr);
--
--      pte.pte = ptep->pte | _PAGE_RW;
--      if (HYPERVISOR_update_va_mapping(addr, pte, 0))
--              xen_l1_entry_update(ptep, pte); /* fallback */
--
--      if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
--              __make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT));
--}
--
--void make_page_readonly(void *va, unsigned int feature)
--{
--      if (!xen_feature(feature))
--              __make_page_readonly(va);
--}
--
--void make_page_writable(void *va, unsigned int feature)
--{
--      if (!xen_feature(feature))
--              __make_page_writable(va);
--}
--
--void make_pages_readonly(void *va, unsigned nr, unsigned int feature)
--{
--      if (xen_feature(feature))
--              return;
--
--      while (nr-- != 0) {
--              __make_page_readonly(va);
--              va = (void*)((unsigned long)va + PAGE_SIZE);
--      }
--}
--
--void make_pages_writable(void *va, unsigned nr, unsigned int feature)
--{
--      if (xen_feature(feature))
--              return;
--
--      while (nr-- != 0) {
--              __make_page_writable(va);
--              va = (void*)((unsigned long)va + PAGE_SIZE);
--      }
--}
--
- /*
-  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
-  * physical space so we can cache the place of the first one and move
-@@ -187,22 +130,26 @@ void show_mem(void)
- {
-       long i, total = 0, reserved = 0;
-       long shared = 0, cached = 0;
--      pg_data_t *pgdat;
-       struct page *page;
-+      pg_data_t *pgdat;
-       printk(KERN_INFO "Mem-info:\n");
-       show_free_areas();
--      printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-+      printk(KERN_INFO "Free swap:       %6ldkB\n",
-+              nr_swap_pages << (PAGE_SHIFT-10));
-       for_each_online_pgdat(pgdat) {
--               for (i = 0; i < pgdat->node_spanned_pages; ++i) {
--                      /* this loop can take a while with 256 GB and 4k pages
--                         so update the NMI watchdog */
--                      if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) {
-+              for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-+                      /*
-+                       * This loop can take a while with 256 GB and
-+                       * 4k pages so defer the NMI watchdog:
-+                       */
-+                      if (unlikely(i % MAX_ORDER_NR_PAGES == 0))
-                               touch_nmi_watchdog();
--                      }
-+
-                       if (!pfn_valid(pgdat->node_start_pfn + i))
-                               continue;
-+
-                       page = pfn_to_page(pgdat->node_start_pfn + i);
-                       total++;
-                       if (PageReserved(page))
-@@ -211,58 +158,67 @@ void show_mem(void)
-                               cached++;
-                       else if (page_count(page))
-                               shared += page_count(page) - 1;
--               }
-+              }
-       }
--      printk(KERN_INFO "%lu pages of RAM\n", total);
--      printk(KERN_INFO "%lu reserved pages\n",reserved);
--      printk(KERN_INFO "%lu pages shared\n",shared);
--      printk(KERN_INFO "%lu pages swap cached\n",cached);
-+      printk(KERN_INFO "%lu pages of RAM\n",          total);
-+      printk(KERN_INFO "%lu reserved pages\n",        reserved);
-+      printk(KERN_INFO "%lu pages shared\n",          shared);
-+      printk(KERN_INFO "%lu pages swap cached\n",     cached);
- }
-+static unsigned long __meminitdata table_start;
-+static unsigned long __meminitdata table_end;
- static __init void *spp_getpage(void)
--{ 
-+{
-       void *ptr;
-+
-       if (after_bootmem)
--              ptr = (void *) get_zeroed_page(GFP_ATOMIC); 
-+              ptr = (void *) get_zeroed_page(GFP_ATOMIC);
-       else if (start_pfn < table_end) {
-               ptr = __va(start_pfn << PAGE_SHIFT);
-               start_pfn++;
-               memset(ptr, 0, PAGE_SIZE);
-       } else
-               ptr = alloc_bootmem_pages(PAGE_SIZE);
--      if (!ptr || ((unsigned long)ptr & ~PAGE_MASK))
--              panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
--      Dprintk("spp_getpage %p\n", ptr);
-+      if (!ptr || ((unsigned long)ptr & ~PAGE_MASK)) {
-+              panic("set_pte_phys: cannot allocate page data %s\n",
-+                      after_bootmem ? "after bootmem" : "");
-+      }
-+
-+      pr_debug("spp_getpage %p\n", ptr);
-+
-       return ptr;
--} 
-+}
- #define pgd_offset_u(address) (__user_pgd(init_level4_pgt) + pgd_index(address))
- #define pud_offset_u(address) (level3_user_pgt + pud_index(address))
--static __init void set_pte_phys(unsigned long vaddr,
--                       unsigned long phys, pgprot_t prot, int user_mode)
-+static __init void
-+set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot, int user_mode)
- {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte, new_pte;
--      Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
-+      pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
-       pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
-       if (pgd_none(*pgd)) {
--              printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
-+              printk(KERN_ERR
-+                      "PGD FIXMAP MISSING, it should be setup in head.S!\n");
-               return;
-       }
-       pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
-       if (pud_none(*pud)) {
--              pmd = (pmd_t *) spp_getpage(); 
-+              pmd = (pmd_t *) spp_getpage();
-               make_page_readonly(pmd, XENFEAT_writable_page_tables);
-               set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-               if (pmd != pmd_offset(pud, 0)) {
--                      printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
-+                      printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
-+                              pmd, pmd_offset(pud, 0));
-                       return;
-               }
-       }
-@@ -272,7 +228,7 @@ static __init void set_pte_phys(unsigned
-               make_page_readonly(pte, XENFEAT_writable_page_tables);
-               set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
-               if (pte != pte_offset_kernel(pmd, 0)) {
--                      printk("PAGETABLE BUG #02!\n");
-+                      printk(KERN_ERR "PAGETABLE BUG #02!\n");
-                       return;
-               }
-       }
-@@ -294,30 +250,30 @@ static __init void set_pte_phys(unsigned
-       __flush_tlb_one(vaddr);
- }
--static __init void set_pte_phys_ma(unsigned long vaddr,
--                                 unsigned long phys, pgprot_t prot)
-+static __init void
-+set_pte_phys_ma(unsigned long vaddr, unsigned long phys, pgprot_t prot)
- {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte, new_pte;
--      Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
-+      pr_debug("set_pte_phys_ma %lx to %lx\n", vaddr, phys);
-       pgd = pgd_offset_k(vaddr);
-       if (pgd_none(*pgd)) {
--              printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
-+              printk(KERN_ERR
-+                      "PGD FIXMAP MISSING, it should be setup in head.S!\n");
-               return;
-       }
-       pud = pud_offset(pgd, vaddr);
-       if (pud_none(*pud)) {
--
--              pmd = (pmd_t *) spp_getpage(); 
-+              pmd = (pmd_t *) spp_getpage();
-               make_page_readonly(pmd, XENFEAT_writable_page_tables);
-               set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-               if (pmd != pmd_offset(pud, 0)) {
--                      printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
--                      return;
-+                      printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
-+                              pmd, pmd_offset(pud, 0));
-               }
-       }
-       pmd = pmd_offset(pud, vaddr);
-@@ -326,7 +282,7 @@ static __init void set_pte_phys_ma(unsig
-               make_page_readonly(pte, XENFEAT_writable_page_tables);
-               set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
-               if (pte != pte_offset_kernel(pmd, 0)) {
--                      printk("PAGETABLE BUG #02!\n");
-+                      printk(KERN_ERR "PAGETABLE BUG #02!\n");
-                       return;
-               }
-       }
-@@ -350,14 +306,44 @@ static __init void set_pte_phys_ma(unsig
-       __flush_tlb_one(vaddr);
- }
-+#ifndef CONFIG_XEN
-+/*
-+ * The head.S code sets up the kernel high mapping:
-+ *
-+ *   from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
-+ *
-+ * phys_addr holds the negative offset to the kernel, which is added
-+ * to the compile time generated pmds. This results in invalid pmds up
-+ * to the point where we hit the physaddr 0 mapping.
-+ *
-+ * We limit the mappings to the region from _text to _end.  _end is
-+ * rounded up to the 2MB boundary. This catches the invalid pmds as
-+ * well, as they are located before _text:
-+ */
-+void __init cleanup_highmap(void)
-+{
-+      unsigned long vaddr = __START_KERNEL_map;
-+      unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1;
-+      pmd_t *pmd = level2_kernel_pgt;
-+      pmd_t *last_pmd = pmd + PTRS_PER_PMD;
-+
-+      for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) {
-+              if (!pmd_present(*pmd))
-+                      continue;
-+              if (vaddr < (unsigned long) _text || vaddr > end)
-+                      set_pmd(pmd, __pmd(0));
-+      }
-+}
-+#endif
-+
- /* NOTE: this is meant to be run only at boot */
--void __init 
--__set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
-+void __init
-+__set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
- {
-       unsigned long address = __fix_to_virt(idx);
-       if (idx >= __end_of_fixed_addresses) {
--              printk("Invalid __set_fixmap\n");
-+              printk(KERN_ERR "Invalid __set_fixmap\n");
-               return;
-       }
-       switch (idx) {
-@@ -375,16 +361,14 @@ __set_fixmap (enum fixed_addresses idx, 
-       }
- }
--unsigned long __meminitdata table_start, table_end;
--
- static __meminit void *alloc_static_page(unsigned long *phys)
- {
-       unsigned long va = (start_pfn << PAGE_SHIFT) + __START_KERNEL_map;
-       if (after_bootmem) {
-               void *adr = (void *)get_zeroed_page(GFP_ATOMIC);
--
-               *phys = __pa(adr);
-+
-               return adr;
-       }
-@@ -396,7 +380,7 @@ static __meminit void *alloc_static_page
- #define PTE_SIZE PAGE_SIZE
--static inline int make_readonly(unsigned long paddr)
-+static inline int __meminit make_readonly(unsigned long paddr)
- {
-       extern char __vsyscall_0;
-       int readonly = 0;
-@@ -430,33 +414,38 @@ static inline int make_readonly(unsigned
- /* Must run before zap_low_mappings */
- __meminit void *early_ioremap(unsigned long addr, unsigned long size)
- {
--      unsigned long vaddr;
-       pmd_t *pmd, *last_pmd;
-+      unsigned long vaddr;
-       int i, pmds;
-       pmds = ((addr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE;
-       vaddr = __START_KERNEL_map;
-       pmd = level2_kernel_pgt;
-       last_pmd = level2_kernel_pgt + PTRS_PER_PMD - 1;
-+
-       for (; pmd <= last_pmd; pmd++, vaddr += PMD_SIZE) {
-               for (i = 0; i < pmds; i++) {
-                       if (pmd_present(pmd[i]))
--                              goto next;
-+                              goto continue_outer_loop;
-               }
-               vaddr += addr & ~PMD_MASK;
-               addr &= PMD_MASK;
-+
-               for (i = 0; i < pmds; i++, addr += PMD_SIZE)
--                      set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE));
--              __flush_tlb();
-+                      set_pmd(pmd+i, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
-+              __flush_tlb_all();
-+
-               return (void *)vaddr;
--      next:
-+continue_outer_loop:
-               ;
-       }
-       printk("early_ioremap(0x%lx, %lu) failed\n", addr, size);
-       return NULL;
- }
--/* To avoid virtual aliases later */
-+/*
-+ * To avoid virtual aliases later:
-+ */
- __meminit void early_iounmap(void *addr, unsigned long size)
- {
-       unsigned long vaddr;
-@@ -466,9 +455,11 @@ __meminit void early_iounmap(void *addr,
-       vaddr = (unsigned long)addr;
-       pmds = ((vaddr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE;
-       pmd = level2_kernel_pgt + pmd_index(vaddr);
-+
-       for (i = 0; i < pmds; i++)
-               pmd_clear(pmd + i);
--      __flush_tlb();
-+
-+      __flush_tlb_all();
- }
- #endif
-@@ -517,18 +508,19 @@ phys_pmd_init(pmd_t *pmd_page, unsigned 
- static void __meminit
- phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
- {
--      pmd_t *pmd = pmd_offset(pud,0);
-+      pmd_t *pmd = pmd_offset(pud, 0);
-       spin_lock(&init_mm.page_table_lock);
-       phys_pmd_init(pmd, address, end);
-       spin_unlock(&init_mm.page_table_lock);
-       __flush_tlb_all();
- }
--static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
--{ 
-+static void __meminit
-+phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
-+{
-       int i = pud_index(addr);
--      for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) {
-+      for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE) {
-               unsigned long pmd_phys;
-               pud_t *pud = pud_page + pud_index(addr);
-               pmd_t *pmd;
-@@ -550,8 +542,8 @@ static void __meminit phys_pud_init(pud_
-               early_make_page_readonly(pmd, XENFEAT_writable_page_tables);
-       }
--      __flush_tlb();
--} 
-+      __flush_tlb_all();
-+}
- void __init xen_init_pt(void)
- {
-@@ -632,6 +624,7 @@ void __init xen_init_pt(void)
- static void __init extend_init_mapping(unsigned long tables_space)
- {
-       unsigned long va = __START_KERNEL_map;
-+      unsigned long start = start_pfn;
-       unsigned long phys, addr, *pte_page;
-       pmd_t *pmd;
-       pte_t *pte, new_pte;
-@@ -682,6 +675,10 @@ static void __init extend_init_mapping(u
-                       BUG();
-               va += PAGE_SIZE;
-       }
-+
-+      if (start_pfn > start)
-+              reserve_early(start << PAGE_SHIFT,
-+                            start_pfn << PAGE_SHIFT, "INITMAP");
- }
- static void __init find_early_table_space(unsigned long end)
-@@ -706,7 +703,7 @@ static void __init find_early_table_spac
-               (table_start << PAGE_SHIFT) + tables);
- }
--static void xen_finish_init_mapping(void)
-+static void __init xen_finish_init_mapping(void)
- {
-       unsigned long i, start, end;
-@@ -742,8 +739,10 @@ static void xen_finish_init_mapping(void
-        * Prefetch pte's for the bt_ioremap() area. It gets used before the
-        * boot-time allocator is online, so allocate-on-demand would fail.
-        */
-+      early_ioremap_clear();
-       for (i = FIX_BTMAP_END; i <= FIX_BTMAP_BEGIN; i++)
-               __set_fixmap(i, 0, __pgprot(0));
-+      early_ioremap_reset();
-       /* Switch to the real shared_info page, and clear the dummy page. */
-       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-@@ -764,20 +763,23 @@ static void xen_finish_init_mapping(void
-       table_end = start_pfn;
- }
--/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
--   This runs before bootmem is initialized and gets pages directly from the 
--   physical memory. To access them they are temporarily mapped. */
-+/*
-+ * Setup the direct mapping of the physical memory at PAGE_OFFSET.
-+ * This runs before bootmem is initialized and gets pages directly from
-+ * the physical memory. To access them they are temporarily mapped.
-+ */
- void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
--{ 
-+{
-       unsigned long next;
--      Dprintk("init_memory_mapping\n");
-+      pr_debug("init_memory_mapping\n");
--      /* 
-+      /*
-        * Find space for the kernel direct mapping tables.
--       * Later we should allocate these tables in the local node of the memory
--       * mapped.  Unfortunately this is done currently before the nodes are 
--       * discovered.
-+       *
-+       * Later we should allocate these tables in the local node of the
-+       * memory mapped. Unfortunately this is done currently before the
-+       * nodes are discovered.
-        */
-       if (!after_bootmem)
-               find_early_table_space(end);
-@@ -786,8 +788,8 @@ void __init_refok init_memory_mapping(un
-       end = (unsigned long)__va(end);
-       for (; start < end; start = next) {
--              unsigned long pud_phys; 
-               pgd_t *pgd = pgd_offset_k(start);
-+              unsigned long pud_phys;
-               pud_t *pud;
-               if (after_bootmem)
-@@ -795,8 +797,8 @@ void __init_refok init_memory_mapping(un
-               else
-                       pud = alloc_static_page(&pud_phys);
-               next = start + PGDIR_SIZE;
--              if (next > end) 
--                      next = end; 
-+              if (next > end)
-+                      next = end;
-               phys_pud_init(pud, __pa(start), __pa(next));
-               if (!after_bootmem) {
-                       early_make_page_readonly(pud, XENFEAT_writable_page_tables);
-@@ -810,12 +812,17 @@ void __init_refok init_memory_mapping(un
-       }
-       __flush_tlb_all();
-+
-+      if (!after_bootmem)
-+              reserve_early(table_start << PAGE_SHIFT,
-+                            table_end << PAGE_SHIFT, "PGTABLE");
- }
- #ifndef CONFIG_NUMA
- void __init paging_init(void)
- {
-       unsigned long max_zone_pfns[MAX_NR_ZONES];
-+
-       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-       max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
-       max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
-@@ -829,40 +836,6 @@ void __init paging_init(void)
- }
- #endif
--/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
--   from the CPU leading to inconsistent cache lines. address and size
--   must be aligned to 2MB boundaries. 
--   Does nothing when the mapping doesn't exist. */
--void __init clear_kernel_mapping(unsigned long address, unsigned long size) 
--{
--      unsigned long end = address + size;
--
--      BUG_ON(address & ~LARGE_PAGE_MASK);
--      BUG_ON(size & ~LARGE_PAGE_MASK); 
--      
--      for (; address < end; address += LARGE_PAGE_SIZE) { 
--              pgd_t *pgd = pgd_offset_k(address);
--              pud_t *pud;
--              pmd_t *pmd;
--              if (pgd_none(*pgd))
--                      continue;
--              pud = pud_offset(pgd, address);
--              if (pud_none(*pud))
--                      continue; 
--              pmd = pmd_offset(pud, address);
--              if (!pmd || pmd_none(*pmd))
--                      continue; 
--              if (0 == (__pmd_val(*pmd) & _PAGE_PSE)) {
--                      /* Could handle this, but it should not happen currently. */
--                      printk(KERN_ERR 
--             "clear_kernel_mapping: mapping has been split. will leak memory\n"); 
--                      pmd_ERROR(*pmd); 
--              }
--              set_pmd(pmd, __pmd(0));                 
--      }
--      __flush_tlb_all();
--} 
--
- /*
-  * Memory hotplug specific functions
-  */
-@@ -888,16 +861,12 @@ int arch_add_memory(int nid, u64 start, 
-       unsigned long nr_pages = size >> PAGE_SHIFT;
-       int ret;
--      init_memory_mapping(start, (start + size -1));
-+      init_memory_mapping(start, start + size-1);
-       ret = __add_pages(zone, start_pfn, nr_pages);
--      if (ret)
--              goto error;
-+      WARN_ON(1);
-       return ret;
--error:
--      printk("%s: Problem encountered in __add_pages!\n", __func__);
--      return ret;
- }
- EXPORT_SYMBOL_GPL(arch_add_memory);
-@@ -911,36 +880,8 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
- #endif /* CONFIG_MEMORY_HOTPLUG */
--#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
--/*
-- * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
-- * just online the pages.
-- */
--int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
--{
--      int err = -EIO;
--      unsigned long pfn;
--      unsigned long total = 0, mem = 0;
--      for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
--              if (pfn_valid(pfn)) {
--                      online_page(pfn_to_page(pfn));
--                      err = 0;
--                      mem++;
--              }
--              total++;
--      }
--      if (!err) {
--              z->spanned_pages += total;
--              z->present_pages += mem;
--              z->zone_pgdat->node_spanned_pages += total;
--              z->zone_pgdat->node_present_pages += mem;
--      }
--      return err;
--}
--#endif
--
--static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
--                       kcore_vsyscall;
-+static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
-+                       kcore_modules, kcore_vsyscall;
- void __init mem_init(void)
- {
-@@ -949,8 +890,7 @@ void __init mem_init(void)
-       pci_iommu_alloc();
--      /* clear the zero-page */
--      memset(empty_zero_page, 0, PAGE_SIZE);
-+      /* clear_bss() already clear the empty_zero_page */
-       reservedpages = 0;
-@@ -968,7 +908,6 @@ void __init mem_init(void)
-       }
-       reservedpages = end_pfn - totalram_pages -
-                                       absent_pages_in_range(0, end_pfn);
--
-       after_bootmem = 1;
-       codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-@@ -976,46 +915,64 @@ void __init mem_init(void)
-       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-       /* Register memory areas for /proc/kcore */
--      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
--      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
-+      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-+      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END-VMALLOC_START);
-       kclist_add(&kcore_kernel, &_stext, _end - _stext);
-       kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
--      kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, 
-+      kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
-                                VSYSCALL_END - VSYSCALL_START);
--      printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n",
-+      printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
-+                              "%ldk reserved, %ldk data, %ldk init)\n",
-               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-               end_pfn << (PAGE_SHIFT-10),
-               codesize >> 10,
-               reservedpages << (PAGE_SHIFT-10),
-               datasize >> 10,
-               initsize >> 10);
-+
-+      cpa_init();
- }
- void free_init_pages(char *what, unsigned long begin, unsigned long end)
- {
--      unsigned long addr;
-+      unsigned long addr = begin;
--      if (begin >= end)
-+      if (addr >= end)
-               return;
-+      /*
-+       * If debugging page accesses then do not free this memory but
-+       * mark them not present - any buggy init-section access will
-+       * create a kernel page fault:
-+       */
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+      printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-+              begin, PAGE_ALIGN(end));
-+      set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-+#else
-       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
--      for (addr = begin; addr < end; addr += PAGE_SIZE) {
-+
-+      for (; addr < end; addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               init_page_count(virt_to_page(addr));
-               memset((void *)(addr & ~(PAGE_SIZE-1)),
-                      POISON_FREE_INITMEM, PAGE_SIZE); 
-               if (addr >= __START_KERNEL_map) {
-                       /* make_readonly() reports all kernel addresses. */
--                      __make_page_writable(__va(__pa(addr)));
--                      change_page_attr_addr(addr, 1, __pgprot(0));
-+                      if (HYPERVISOR_update_va_mapping((unsigned long)__va(__pa(addr)),
-+                                                       pfn_pte(__pa(addr) >> PAGE_SHIFT,
-+                                                               PAGE_KERNEL),
-+                                                       0))
-+                              BUG();
-+                      if (HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
-+                              BUG();
-               }
-               free_page(addr);
-               totalram_pages++;
-       }
--      if (addr > __START_KERNEL_map)
--              global_flush_tlb();
-+#endif
- }
- void free_initmem(void)
-@@ -1026,6 +983,8 @@ void free_initmem(void)
- }
- #ifdef CONFIG_DEBUG_RODATA
-+const int rodata_test_data = 0xC3;
-+EXPORT_SYMBOL_GPL(rodata_test_data);
- void mark_rodata_ro(void)
- {
-@@ -1047,18 +1006,27 @@ void mark_rodata_ro(void)
-       if (end <= start)
-               return;
--      change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO);
-       printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
-              (end - start) >> 10);
-+      set_memory_ro(start, (end - start) >> PAGE_SHIFT);
-       /*
--       * change_page_attr_addr() requires a global_flush_tlb() call after it.
--       * We do this after the printk so that if something went wrong in the
--       * change, the printk gets out at least to give a better debug hint
--       * of who is the culprit.
-+       * The rodata section (but not the kernel text!) should also be
-+       * not-executable.
-        */
--      global_flush_tlb();
-+      start = ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
-+      set_memory_nx(start, (end - start) >> PAGE_SHIFT);
-+
-+      rodata_test();
-+
-+#ifdef CONFIG_CPA_DEBUG
-+      printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, end);
-+      set_memory_rw(start, (end-start) >> PAGE_SHIFT);
-+
-+      printk(KERN_INFO "Testing CPA: again\n");
-+      set_memory_ro(start, (end-start) >> PAGE_SHIFT);
-+#endif
- }
- #endif
-@@ -1069,17 +1037,21 @@ void free_initrd_mem(unsigned long start
- }
- #endif
--void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 
--{ 
-+void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
-+{
- #ifdef CONFIG_NUMA
-       int nid = phys_to_nid(phys);
- #endif
-       unsigned long pfn = phys >> PAGE_SHIFT;
-+
-       if (pfn >= end_pfn) {
--              /* This can happen with kdump kernels when accessing firmware
--                 tables. */
-+              /*
-+               * This can happen with kdump kernels when accessing
-+               * firmware tables:
-+               */
-               if (pfn < end_pfn_map)
-                       return;
-+
-               printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n",
-                               phys, len);
-               return;
-@@ -1087,9 +1059,9 @@ void __init reserve_bootmem_generic(unsi
-       /* Should check here against the e820 map to avoid double free */
- #ifdef CONFIG_NUMA
--      reserve_bootmem_node(NODE_DATA(nid), phys, len);
--#else                 
--      reserve_bootmem(phys, len);    
-+      reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT);
-+#else
-+      reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
- #endif
- #ifndef CONFIG_XEN
-       if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
-@@ -1101,46 +1073,49 @@ void __init reserve_bootmem_generic(unsi
- #endif
- }
--int kern_addr_valid(unsigned long addr) 
--{ 
-+int kern_addr_valid(unsigned long addr)
-+{
-       unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
--       pgd_t *pgd;
--       pud_t *pud;
--       pmd_t *pmd;
--       pte_t *pte;
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-       if (above != 0 && above != -1UL)
--              return 0; 
--      
-+              return 0;
-+
-       pgd = pgd_offset_k(addr);
-       if (pgd_none(*pgd))
-               return 0;
-       pud = pud_offset(pgd, addr);
-       if (pud_none(*pud))
--              return 0; 
-+              return 0;
-       pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd))
-               return 0;
-+
-       if (pmd_large(*pmd))
-               return pfn_valid(pmd_pfn(*pmd));
-       pte = pte_offset_kernel(pmd, addr);
-       if (pte_none(*pte))
-               return 0;
-+
-       return pfn_valid(pte_pfn(*pte));
- }
--/* A pseudo VMA to allow ptrace access for the vsyscall page.  This only
--   covers the 64bit vsyscall page now. 32bit has a real VMA now and does
--   not need special handling anymore. */
--
-+/*
-+ * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
-+ * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
-+ * not need special handling anymore:
-+ */
- static struct vm_area_struct gate_vma = {
--      .vm_start = VSYSCALL_START,
--      .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES << PAGE_SHIFT),
--      .vm_page_prot = PAGE_READONLY_EXEC,
--      .vm_flags = VM_READ | VM_EXEC
-+      .vm_start       = VSYSCALL_START,
-+      .vm_end         = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
-+      .vm_page_prot   = PAGE_READONLY_EXEC,
-+      .vm_flags       = VM_READ | VM_EXEC
- };
- struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
-@@ -1155,14 +1130,17 @@ struct vm_area_struct *get_gate_vma(stru
- int in_gate_area(struct task_struct *task, unsigned long addr)
- {
-       struct vm_area_struct *vma = get_gate_vma(task);
-+
-       if (!vma)
-               return 0;
-+
-       return (addr >= vma->vm_start) && (addr < vma->vm_end);
- }
--/* Use this when you have no reliable task/vma, typically from interrupt
-- * context.  It is less reliable than using the task's vma and may give
-- * false positives.
-+/*
-+ * Use this when you have no reliable task/vma, typically from interrupt
-+ * context. It is less reliable than using the task's vma and may give
-+ * false positives:
-  */
- int in_gate_area_no_task(unsigned long addr)
- {
-@@ -1182,8 +1160,8 @@ const char *arch_vma_name(struct vm_area
- /*
-  * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
-  */
--int __meminit vmemmap_populate(struct page *start_page,
--                                              unsigned long size, int node)
-+int __meminit
-+vmemmap_populate(struct page *start_page, unsigned long size, int node)
- {
-       unsigned long addr = (unsigned long)start_page;
-       unsigned long end = (unsigned long)(start_page + size);
-@@ -1198,6 +1176,7 @@ int __meminit vmemmap_populate(struct pa
-               pgd = vmemmap_pgd_populate(addr, node);
-               if (!pgd)
-                       return -ENOMEM;
-+
-               pud = vmemmap_pud_populate(pgd, addr, node);
-               if (!pud)
-                       return -ENOMEM;
-@@ -1205,20 +1184,22 @@ int __meminit vmemmap_populate(struct pa
-               pmd = pmd_offset(pud, addr);
-               if (pmd_none(*pmd)) {
-                       pte_t entry;
--                      void *p = vmemmap_alloc_block(PMD_SIZE, node);
-+                      void *p;
-+
-+                      p = vmemmap_alloc_block(PMD_SIZE, node);
-                       if (!p)
-                               return -ENOMEM;
--                      entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
--                      mk_pte_huge(entry);
--                      set_pmd(pmd, __pmd(pte_val(entry)));
-+                      entry = pfn_pte(__pa(p) >> PAGE_SHIFT,
-+                                                      PAGE_KERNEL_LARGE);
-+                      set_pmd(pmd, __pmd_ma(__pte_val(entry)));
-                       printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n",
-                               addr, addr + PMD_SIZE - 1, p, node);
--              } else
-+              } else {
-                       vmemmap_verify((pte_t *)pmd, node, addr, next);
-+              }
-       }
--
-       return 0;
- }
- #endif
---- a/arch/x86/mm/ioremap_32-xen.c
-+++ /dev/null
-@@ -1,445 +0,0 @@
--/*
-- * arch/i386/mm/ioremap.c
-- *
-- * Re-map IO memory to kernel address space so that we can access it.
-- * This is needed for high PCI addresses that aren't mapped in the
-- * 640k-1MB IO memory area on PC's
-- *
-- * (C) Copyright 1995 1996 Linus Torvalds
-- */
--
--#include <linux/vmalloc.h>
--#include <linux/init.h>
--#include <linux/slab.h>
--#include <linux/module.h>
--#include <linux/io.h>
--#include <linux/sched.h>
--#include <asm/fixmap.h>
--#include <asm/cacheflush.h>
--#include <asm/tlbflush.h>
--#include <asm/pgtable.h>
--#include <asm/pgalloc.h>
--
--#define ISA_START_ADDRESS     0x0
--#define ISA_END_ADDRESS               0x100000
--
--static int direct_remap_area_pte_fn(pte_t *pte, 
--                                  struct page *pmd_page,
--                                  unsigned long address, 
--                                  void *data)
--{
--      mmu_update_t **v = (mmu_update_t **)data;
--
--      BUG_ON(!pte_none(*pte));
--
--      (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
--                   PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
--      (*v)++;
--
--      return 0;
--}
--
--static int __direct_remap_pfn_range(struct mm_struct *mm,
--                                  unsigned long address, 
--                                  unsigned long mfn,
--                                  unsigned long size, 
--                                  pgprot_t prot,
--                                  domid_t  domid)
--{
--      int rc;
--      unsigned long i, start_address;
--      mmu_update_t *u, *v, *w;
--
--      u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
--      if (u == NULL)
--              return -ENOMEM;
--
--      start_address = address;
--
--      flush_cache_all();
--
--      for (i = 0; i < size; i += PAGE_SIZE) {
--              if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
--                      /* Flush a full batch after filling in the PTE ptrs. */
--                      rc = apply_to_page_range(mm, start_address, 
--                                               address - start_address,
--                                               direct_remap_area_pte_fn, &w);
--                      if (rc)
--                              goto out;
--                      rc = -EFAULT;
--                      if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
--                              goto out;
--                      v = w = u;
--                      start_address = address;
--              }
--
--              /*
--               * Fill in the machine address: PTE ptr is done later by
--               * apply_to_page_range(). 
--               */
--              v->val = __pte_val(pfn_pte_ma(mfn, prot)) | _PAGE_IO;
--
--              mfn++;
--              address += PAGE_SIZE; 
--              v++;
--      }
--
--      if (v != u) {
--              /* Final batch. */
--              rc = apply_to_page_range(mm, start_address,
--                                       address - start_address,
--                                       direct_remap_area_pte_fn, &w);
--              if (rc)
--                      goto out;
--              rc = -EFAULT;
--              if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
--                      goto out;
--      }
--
--      rc = 0;
--
-- out:
--      flush_tlb_all();
--
--      free_page((unsigned long)u);
--
--      return rc;
--}
--
--int direct_remap_pfn_range(struct vm_area_struct *vma,
--                         unsigned long address, 
--                         unsigned long mfn,
--                         unsigned long size, 
--                         pgprot_t prot,
--                         domid_t  domid)
--{
--      if (xen_feature(XENFEAT_auto_translated_physmap))
--              return remap_pfn_range(vma, address, mfn, size, prot);
--
--      if (domid == DOMID_SELF)
--              return -EINVAL;
--
--      vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
--
--      vma->vm_mm->context.has_foreign_mappings = 1;
--
--      return __direct_remap_pfn_range(
--              vma->vm_mm, address, mfn, size, prot, domid);
--}
--EXPORT_SYMBOL(direct_remap_pfn_range);
--
--int direct_kernel_remap_pfn_range(unsigned long address, 
--                                unsigned long mfn,
--                                unsigned long size, 
--                                pgprot_t prot,
--                                domid_t  domid)
--{
--      return __direct_remap_pfn_range(
--              &init_mm, address, mfn, size, prot, domid);
--}
--EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
--
--static int lookup_pte_fn(
--      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
--{
--      uint64_t *ptep = (uint64_t *)data;
--      if (ptep)
--              *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
--                       PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
--      return 0;
--}
--
--int create_lookup_pte_addr(struct mm_struct *mm, 
--                         unsigned long address,
--                         uint64_t *ptep)
--{
--      return apply_to_page_range(mm, address, PAGE_SIZE,
--                                 lookup_pte_fn, ptep);
--}
--
--EXPORT_SYMBOL(create_lookup_pte_addr);
--
--static int noop_fn(
--      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
--{
--      return 0;
--}
--
--int touch_pte_range(struct mm_struct *mm,
--                  unsigned long address,
--                  unsigned long size)
--{
--      return apply_to_page_range(mm, address, size, noop_fn, NULL);
--} 
--
--EXPORT_SYMBOL(touch_pte_range);
--
--/*
-- * Does @address reside within a non-highmem page that is local to this virtual
-- * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
-- * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
-- * why this works.
-- */
--static inline int is_local_lowmem(unsigned long address)
--{
--      extern unsigned long max_low_pfn;
--      return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
--}
--
--/*
-- * Generic mapping function (not visible outside):
-- */
--
--/*
-- * Remap an arbitrary physical address space into the kernel virtual
-- * address space. Needed when the kernel wants to access high addresses
-- * directly.
-- *
-- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
-- * have to convert them into an offset in a page-aligned mapping, but the
-- * caller shouldn't need to know that small detail.
-- */
--void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
--{
--      void __iomem * addr;
--      struct vm_struct * area;
--      unsigned long offset, last_addr;
--      pgprot_t prot;
--      domid_t domid = DOMID_IO;
--
--      /* Don't allow wraparound or zero size */
--      last_addr = phys_addr + size - 1;
--      if (!size || last_addr < phys_addr)
--              return NULL;
--
--      /*
--       * Don't remap the low PCI/ISA area, it's always mapped..
--       */
--      if (is_initial_xendomain() &&
--          phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
--              return (void __iomem *) isa_bus_to_virt(phys_addr);
--
--      /*
--       * Don't allow anybody to remap normal RAM that we're using..
--       */
--      if (is_local_lowmem(phys_addr)) {
--              char *t_addr, *t_end;
--              struct page *page;
--
--              t_addr = bus_to_virt(phys_addr);
--              t_end = t_addr + (size - 1);
--         
--              for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
--                      if(!PageReserved(page))
--                              return NULL;
--
--              domid = DOMID_SELF;
--      }
--
--      prot = __pgprot(_KERNPG_TABLE | flags);
--
--      /*
--       * Mappings have to be page-aligned
--       */
--      offset = phys_addr & ~PAGE_MASK;
--      phys_addr &= PAGE_MASK;
--      size = PAGE_ALIGN(last_addr+1) - phys_addr;
--
--      /*
--       * Ok, go for it..
--       */
--      area = get_vm_area(size, VM_IOREMAP | (flags << 20));
--      if (!area)
--              return NULL;
--      area->phys_addr = phys_addr;
--      addr = (void __iomem *) area->addr;
--      if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
--                                   phys_addr>>PAGE_SHIFT,
--                                   size, prot, domid)) {
--              vunmap((void __force *) addr);
--              return NULL;
--      }
--      return (void __iomem *) (offset + (char __iomem *)addr);
--}
--EXPORT_SYMBOL(__ioremap);
--
--/**
-- * ioremap_nocache     -   map bus memory into CPU space
-- * @offset:    bus address of the memory
-- * @size:      size of the resource to map
-- *
-- * ioremap_nocache performs a platform specific sequence of operations to
-- * make bus memory CPU accessible via the readb/readw/readl/writeb/
-- * writew/writel functions and the other mmio helpers. The returned
-- * address is not guaranteed to be usable directly as a virtual
-- * address. 
-- *
-- * This version of ioremap ensures that the memory is marked uncachable
-- * on the CPU as well as honouring existing caching rules from things like
-- * the PCI bus. Note that there are other caches and buffers on many 
-- * busses. In particular driver authors should read up on PCI writes
-- *
-- * It's useful if some control registers are in such an area and
-- * write combining or read caching is not desirable:
-- * 
-- * Must be freed with iounmap.
-- */
--
--void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
--{
--      unsigned long last_addr;
--      void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
--      if (!p) 
--              return p; 
--
--      /* Guaranteed to be > phys_addr, as per __ioremap() */
--      last_addr = phys_addr + size - 1;
--
--      if (is_local_lowmem(last_addr)) { 
--              struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
--              unsigned long npages;
--
--              phys_addr &= PAGE_MASK;
--
--              /* This might overflow and become zero.. */
--              last_addr = PAGE_ALIGN(last_addr);
--
--              /* .. but that's ok, because modulo-2**n arithmetic will make
--              * the page-aligned "last - first" come out right.
--              */
--              npages = (last_addr - phys_addr) >> PAGE_SHIFT;
--
--              if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) { 
--                      iounmap(p); 
--                      p = NULL;
--              }
--              global_flush_tlb();
--      }
--
--      return p;                                       
--}
--EXPORT_SYMBOL(ioremap_nocache);
--
--/**
-- * iounmap - Free a IO remapping
-- * @addr: virtual address from ioremap_*
-- *
-- * Caller must ensure there is only one unmapping for the same pointer.
-- */
--void iounmap(volatile void __iomem *addr)
--{
--      struct vm_struct *p, *o;
--
--      if ((void __force *)addr <= high_memory)
--              return;
--
--      /*
--       * __ioremap special-cases the PCI/ISA range by not instantiating a
--       * vm_area and by simply returning an address into the kernel mapping
--       * of ISA space.   So handle that here.
--       */
--      if ((unsigned long) addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
--              return;
--
--      addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
--
--      /* Use the vm area unlocked, assuming the caller
--         ensures there isn't another iounmap for the same address
--         in parallel. Reuse of the virtual address is prevented by
--         leaving it in the global lists until we're done with it.
--         cpa takes care of the direct mappings. */
--      read_lock(&vmlist_lock);
--      for (p = vmlist; p; p = p->next) {
--              if (p->addr == addr)
--                      break;
--      }
--      read_unlock(&vmlist_lock);
--
--      if (!p) {
--              printk("iounmap: bad address %p\n", addr);
--              dump_stack();
--              return;
--      }
--
--      /* Reset the direct mapping. Can block */
--      if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) {
--              change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
--                               get_vm_area_size(p) >> PAGE_SHIFT,
--                               PAGE_KERNEL);
--              global_flush_tlb();
--      } 
--
--      /* Finally remove it */
--      o = remove_vm_area((void *)addr);
--      BUG_ON(p != o || o == NULL);
--      kfree(p); 
--}
--EXPORT_SYMBOL(iounmap);
--
--void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
--{
--      unsigned long offset, last_addr;
--      unsigned int nrpages;
--      enum fixed_addresses idx;
--
--      /* Don't allow wraparound or zero size */
--      last_addr = phys_addr + size - 1;
--      if (!size || last_addr < phys_addr)
--              return NULL;
--
--      /*
--       * Don't remap the low PCI/ISA area, it's always mapped..
--       */
--      if (is_initial_xendomain() &&
--          phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
--              return isa_bus_to_virt(phys_addr);
--
--      /*
--       * Mappings have to be page-aligned
--       */
--      offset = phys_addr & ~PAGE_MASK;
--      phys_addr &= PAGE_MASK;
--      size = PAGE_ALIGN(last_addr) - phys_addr;
--
--      /*
--       * Mappings have to fit in the FIX_BTMAP area.
--       */
--      nrpages = size >> PAGE_SHIFT;
--      if (nrpages > NR_FIX_BTMAPS)
--              return NULL;
--
--      /*
--       * Ok, go for it..
--       */
--      idx = FIX_BTMAP_BEGIN;
--      while (nrpages > 0) {
--              set_fixmap(idx, phys_addr);
--              phys_addr += PAGE_SIZE;
--              --idx;
--              --nrpages;
--      }
--      return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
--}
--
--void __init bt_iounmap(void *addr, unsigned long size)
--{
--      unsigned long virt_addr;
--      unsigned long offset;
--      unsigned int nrpages;
--      enum fixed_addresses idx;
--
--      virt_addr = (unsigned long)addr;
--      if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
--              return;
--      if (virt_addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
--              return;
--      offset = virt_addr & ~PAGE_MASK;
--      nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
--
--      idx = FIX_BTMAP_BEGIN;
--      while (nrpages > 0) {
--              clear_fixmap(idx);
--              --idx;
--              --nrpages;
--      }
--}
---- /dev/null
-+++ b/arch/x86/mm/ioremap-xen.c
-@@ -0,0 +1,685 @@
-+/*
-+ * Re-map IO memory to kernel address space so that we can access it.
-+ * This is needed for high PCI addresses that aren't mapped in the
-+ * 640k-1MB IO memory area on PC's
-+ *
-+ * (C) Copyright 1995 1996 Linus Torvalds
-+ */
-+
-+#include <linux/bootmem.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/pfn.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+
-+#include <asm/cacheflush.h>
-+#include <asm/e820.h>
-+#include <asm/fixmap.h>
-+#include <asm/pgtable.h>
-+#include <asm/tlbflush.h>
-+#include <asm/pgalloc.h>
-+
-+enum ioremap_mode {
-+      IOR_MODE_UNCACHED,
-+      IOR_MODE_CACHED,
-+};
-+
-+#if defined(CONFIG_X86_64) && !defined(CONFIG_XEN)
-+
-+unsigned long __phys_addr(unsigned long x)
-+{
-+      if (x >= __START_KERNEL_map)
-+              return x - __START_KERNEL_map + phys_base;
-+      return x - PAGE_OFFSET;
-+}
-+EXPORT_SYMBOL(__phys_addr);
-+
-+#endif
-+
-+static int direct_remap_area_pte_fn(pte_t *pte,
-+                                  struct page *pmd_page,
-+                                  unsigned long address,
-+                                  void *data)
-+{
-+      mmu_update_t **v = (mmu_update_t **)data;
-+
-+      BUG_ON(!pte_none(*pte));
-+
-+      (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
-+                   PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
-+      (*v)++;
-+
-+      return 0;
-+}
-+
-+static int __direct_remap_pfn_range(struct mm_struct *mm,
-+                                  unsigned long address,
-+                                  unsigned long mfn,
-+                                  unsigned long size,
-+                                  pgprot_t prot,
-+                                  domid_t  domid)
-+{
-+      int rc;
-+      unsigned long i, start_address;
-+      mmu_update_t *u, *v, *w;
-+
-+      u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-+      if (u == NULL)
-+              return -ENOMEM;
-+
-+      start_address = address;
-+
-+      flush_cache_all();
-+
-+      for (i = 0; i < size; i += PAGE_SIZE) {
-+              if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
-+                      /* Flush a full batch after filling in the PTE ptrs. */
-+                      rc = apply_to_page_range(mm, start_address,
-+                                               address - start_address,
-+                                               direct_remap_area_pte_fn, &w);
-+                      if (rc)
-+                              goto out;
-+                      rc = -EFAULT;
-+                      if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
-+                              goto out;
-+                      v = w = u;
-+                      start_address = address;
-+              }
-+
-+              /*
-+               * Fill in the machine address: PTE ptr is done later by
-+               * apply_to_page_range().
-+               */
-+              v->val = __pte_val(pfn_pte_ma(mfn, prot)) | _PAGE_IO;
-+
-+              mfn++;
-+              address += PAGE_SIZE;
-+              v++;
-+      }
-+
-+      if (v != u) {
-+              /* Final batch. */
-+              rc = apply_to_page_range(mm, start_address,
-+                                       address - start_address,
-+                                       direct_remap_area_pte_fn, &w);
-+              if (rc)
-+                      goto out;
-+              rc = -EFAULT;
-+              if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
-+                      goto out;
-+      }
-+
-+      rc = 0;
-+
-+ out:
-+      flush_tlb_all();
-+
-+      free_page((unsigned long)u);
-+
-+      return rc;
-+}
-+
-+int direct_remap_pfn_range(struct vm_area_struct *vma,
-+                         unsigned long address,
-+                         unsigned long mfn,
-+                         unsigned long size,
-+                         pgprot_t prot,
-+                         domid_t  domid)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return remap_pfn_range(vma, address, mfn, size, prot);
-+
-+      if (domid == DOMID_SELF)
-+              return -EINVAL;
-+
-+      vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-+
-+      vma->vm_mm->context.has_foreign_mappings = 1;
-+
-+      return __direct_remap_pfn_range(
-+              vma->vm_mm, address, mfn, size, prot, domid);
-+}
-+EXPORT_SYMBOL(direct_remap_pfn_range);
-+
-+int direct_kernel_remap_pfn_range(unsigned long address,
-+                                unsigned long mfn,
-+                                unsigned long size,
-+                                pgprot_t prot,
-+                                domid_t  domid)
-+{
-+      return __direct_remap_pfn_range(
-+              &init_mm, address, mfn, size, prot, domid);
-+}
-+EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
-+
-+static int lookup_pte_fn(
-+      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
-+{
-+      uint64_t *ptep = (uint64_t *)data;
-+      if (ptep)
-+              *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
-+                       PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
-+      return 0;
-+}
-+
-+int create_lookup_pte_addr(struct mm_struct *mm,
-+                         unsigned long address,
-+                         uint64_t *ptep)
-+{
-+      return apply_to_page_range(mm, address, PAGE_SIZE,
-+                                 lookup_pte_fn, ptep);
-+}
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/kernel/ldt-xen.c 2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,272 @@
++/*
++ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
++ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
++ * Copyright (C) 2002 Andi Kleen
++ *
++ * This handles calls from both 32bit and 64bit mode.
++ */
 +
-+EXPORT_SYMBOL(create_lookup_pte_addr);
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/vmalloc.h>
 +
-+static int noop_fn(
-+      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
-+{
-+      return 0;
-+}
++#include <asm/uaccess.h>
++#include <asm/system.h>
++#include <asm/ldt.h>
++#include <asm/desc.h>
++#include <asm/mmu_context.h>
 +
-+int touch_pte_range(struct mm_struct *mm,
-+                  unsigned long address,
-+                  unsigned long size)
++#ifdef CONFIG_SMP
++static void flush_ldt(void *null)
 +{
-+      return apply_to_page_range(mm, address, size, noop_fn, NULL);
++      if (current->active_mm)
++              load_LDT(&current->active_mm->context);
 +}
++#endif
 +
-+EXPORT_SYMBOL(touch_pte_range);
-+
-+#ifdef CONFIG_X86_32
-+int page_is_ram(unsigned long pagenr)
++static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
 +{
-+      unsigned long addr, end;
-+      int i;
-+
-+#ifndef CONFIG_XEN
-+      /*
-+       * A special case is the first 4Kb of memory;
-+       * This is a BIOS owned area, not kernel ram, but generally
-+       * not listed as such in the E820 table.
-+       */
-+      if (pagenr == 0)
-+              return 0;
++      void *oldldt, *newldt;
++      int oldsize;
 +
-+      /*
-+       * Second special case: Some BIOSen report the PC BIOS
-+       * area (640->1Mb) as ram even though it is not.
-+       */
-+      if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
-+                  pagenr < (BIOS_END >> PAGE_SHIFT))
++      if (mincount <= pc->size)
 +              return 0;
-+#endif
++      oldsize = pc->size;
++      mincount = (mincount + (PAGE_SIZE / LDT_ENTRY_SIZE - 1)) &
++                      (~(PAGE_SIZE / LDT_ENTRY_SIZE - 1));
++      if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE)
++              newldt = vmalloc(mincount * LDT_ENTRY_SIZE);
++      else
++              newldt = (void *)__get_free_page(GFP_KERNEL);
 +
-+      for (i = 0; i < e820.nr_map; i++) {
-+              /*
-+               * Not usable memory:
-+               */
-+              if (e820.map[i].type != E820_RAM)
-+                      continue;
-+              addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT;
-+              end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
++      if (!newldt)
++              return -ENOMEM;
 +
++      if (oldsize)
++              memcpy(newldt, pc->ldt, oldsize * LDT_ENTRY_SIZE);
++      oldldt = pc->ldt;
++      memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,
++             (mincount - oldsize) * LDT_ENTRY_SIZE);
 +
-+              if ((pagenr >= addr) && (pagenr < end))
-+                      return 1;
-+      }
-+      return 0;
-+}
++#ifdef CONFIG_X86_64
++      /* CHECKME: Do we really need this ? */
++      wmb();
 +#endif
++      pc->ldt = newldt;
++      wmb();
++      pc->size = mincount;
++      wmb();
 +
-+/*
-+ * Fix up the linear direct mapping of the kernel to avoid cache attribute
-+ * conflicts.
-+ */
-+static int ioremap_change_attr(unsigned long vaddr, unsigned long size,
-+                             enum ioremap_mode mode)
-+{
-+      unsigned long nrpages = size >> PAGE_SHIFT;
-+      int err;
-+
-+      switch (mode) {
-+      case IOR_MODE_UNCACHED:
-+      default:
-+              err = set_memory_uc(vaddr, nrpages);
-+              break;
-+      case IOR_MODE_CACHED:
-+              err = set_memory_wb(vaddr, nrpages);
-+              break;
-+      }
-+
-+      return err;
-+}
-+
-+/*
-+ * Remap an arbitrary physical address space into the kernel virtual
-+ * address space. Needed when the kernel wants to access high addresses
-+ * directly.
-+ *
-+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
-+ * have to convert them into an offset in a page-aligned mapping, but the
-+ * caller shouldn't need to know that small detail.
-+ */
-+static void __iomem *__ioremap(resource_size_t phys_addr, unsigned long size,
-+                             enum ioremap_mode mode)
-+{
-+      unsigned long mfn, offset, last_addr, vaddr;
-+      struct vm_struct *area;
-+      pgprot_t prot;
-+      domid_t domid = DOMID_IO;
-+
-+      /* Don't allow wraparound or zero size */
-+      last_addr = phys_addr + size - 1;
-+      if (!size || last_addr < phys_addr)
-+              return NULL;
-+
-+      /*
-+       * Don't remap the low PCI/ISA area, it's always mapped..
-+       */
-+      if (is_initial_xendomain() && last_addr < ISA_END_ADDRESS)
-+              return (__force void __iomem *)isa_bus_to_virt((unsigned long)phys_addr);
-+
-+      /*
-+       * Don't allow anybody to remap normal RAM that we're using..
-+       */
-+      for (mfn = PFN_DOWN(phys_addr); mfn < PFN_UP(last_addr); mfn++) {
-+              unsigned long pfn = mfn_to_local_pfn(mfn);
-+
-+              if (pfn >= max_pfn)
-+                      continue;
-+
-+              domid = DOMID_SELF;
-+
-+              if (pfn >= max_pfn_mapped) /* bogus */
-+                      continue;
-+
-+              if (pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
-+                      return NULL;
-+      }
-+
-+      switch (mode) {
-+      case IOR_MODE_UNCACHED:
-+      default:
-+              /*
-+               * FIXME: we will use UC MINUS for now, as video fb drivers
-+               * depend on it. Upcoming ioremap_wc() will fix this behavior.
-+               */
-+              prot = PAGE_KERNEL_UC_MINUS;
-+              break;
-+      case IOR_MODE_CACHED:
-+              prot = PAGE_KERNEL;
-+              break;
-+      }
-+
-+      /*
-+       * Mappings have to be page-aligned
-+       */
-+      offset = phys_addr & ~PAGE_MASK;
-+      phys_addr &= PAGE_MASK;
-+      size = PAGE_ALIGN(last_addr+1) - phys_addr;
++      if (reload) {
++#ifdef CONFIG_SMP
++              cpumask_t mask;
 +
-+      /*
-+       * Ok, go for it..
-+       */
-+      area = get_vm_area(size, VM_IOREMAP | (mode << 20));
-+      if (!area)
-+              return NULL;
-+      area->phys_addr = phys_addr;
-+      vaddr = (unsigned long) area->addr;
-+      if (__direct_remap_pfn_range(&init_mm, vaddr, PFN_DOWN(phys_addr),
-+                                   size, prot, domid)) {
-+              free_vm_area(area);
-+              return NULL;
++              preempt_disable();
++#endif
++              make_pages_readonly(newldt,
++                                  (mincount * LDT_ENTRY_SIZE) / PAGE_SIZE,
++                                  XENFEAT_writable_descriptor_tables);
++              load_LDT(pc);
++#ifdef CONFIG_SMP
++              mask = cpumask_of_cpu(smp_processor_id());
++              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
++                      smp_call_function(flush_ldt, NULL, 1, 1);
++              preempt_enable();
++#endif
 +      }
-+
-+      if (ioremap_change_attr(vaddr, size, mode) < 0) {
-+              iounmap((void __iomem *) vaddr);
-+              return NULL;
++      if (oldsize) {
++              make_pages_writable(oldldt,
++                                  (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
++                                  XENFEAT_writable_descriptor_tables);
++              if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
++                      vfree(oldldt);
++              else
++                      put_page(virt_to_page(oldldt));
 +      }
-+
-+      return (void __iomem *) (vaddr + offset);
++      return 0;
 +}
 +
-+/**
-+ * ioremap_nocache     -   map bus memory into CPU space
-+ * @offset:    bus address of the memory
-+ * @size:      size of the resource to map
-+ *
-+ * ioremap_nocache performs a platform specific sequence of operations to
-+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
-+ * writew/writel functions and the other mmio helpers. The returned
-+ * address is not guaranteed to be usable directly as a virtual
-+ * address.
-+ *
-+ * This version of ioremap ensures that the memory is marked uncachable
-+ * on the CPU as well as honouring existing caching rules from things like
-+ * the PCI bus. Note that there are other caches and buffers on many
-+ * busses. In particular driver authors should read up on PCI writes
-+ *
-+ * It's useful if some control registers are in such an area and
-+ * write combining or read caching is not desirable:
-+ *
-+ * Must be freed with iounmap.
-+ */
-+void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
++static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
 +{
-+      return __ioremap(phys_addr, size, IOR_MODE_UNCACHED);
++      int err = alloc_ldt(new, old->size, 0);
++
++      if (err < 0)
++              return err;
++      memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE);
++      make_pages_readonly(new->ldt,
++                          (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
++                          XENFEAT_writable_descriptor_tables);
++      return 0;
 +}
-+EXPORT_SYMBOL(ioremap_nocache);
 +
-+void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
++/*
++ * we do not have to muck with descriptors here, that is
++ * done in switch_mm() as needed.
++ */
++int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 +{
-+      return __ioremap(phys_addr, size, IOR_MODE_CACHED);
++      struct mm_struct *old_mm;
++      int retval = 0;
++
++      memset(&mm->context, 0, sizeof(mm->context));
++      mutex_init(&mm->context.lock);
++      old_mm = current->mm;
++      if (old_mm)
++              mm->context.vdso = old_mm->context.vdso;
++      if (old_mm && old_mm->context.size > 0) {
++              mutex_lock(&old_mm->context.lock);
++              retval = copy_ldt(&mm->context, &old_mm->context);
++              mutex_unlock(&old_mm->context.lock);
++      }
++      return retval;
 +}
-+EXPORT_SYMBOL(ioremap_cache);
 +
-+/**
-+ * iounmap - Free a IO remapping
-+ * @addr: virtual address from ioremap_*
++/*
++ * No need to lock the MM as we are the last user
 + *
-+ * Caller must ensure there is only one unmapping for the same pointer.
++ * 64bit: Don't touch the LDT register - we're already in the next thread.
 + */
-+void iounmap(volatile void __iomem *addr)
++void destroy_context(struct mm_struct *mm)
 +{
-+      struct vm_struct *p, *o;
++      if (mm->context.size) {
++              /* CHECKME: Can this ever happen ? */
++              if (mm == current->active_mm)
++                      clear_LDT();
++              make_pages_writable(mm->context.ldt,
++                                  (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
++                                  XENFEAT_writable_descriptor_tables);
++              if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
++                      vfree(mm->context.ldt);
++              else
++                      put_page(virt_to_page(mm->context.ldt));
++              mm->context.size = 0;
++      }
++}
 +
-+      if ((void __force *)addr <= high_memory)
-+              return;
++static int read_ldt(void __user *ptr, unsigned long bytecount)
++{
++      int err;
++      unsigned long size;
++      struct mm_struct *mm = current->mm;
 +
-+      /*
-+       * __ioremap special-cases the PCI/ISA range by not instantiating a
-+       * vm_area and by simply returning an address into the kernel mapping
-+       * of ISA space.   So handle that here.
-+       */
-+      if ((unsigned long)addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
-+              return;
++      if (!mm->context.size)
++              return 0;
++      if (bytecount > LDT_ENTRY_SIZE * LDT_ENTRIES)
++              bytecount = LDT_ENTRY_SIZE * LDT_ENTRIES;
 +
-+      addr = (volatile void __iomem *)
-+              (PAGE_MASK & (unsigned long __force)addr);
++      mutex_lock(&mm->context.lock);
++      size = mm->context.size * LDT_ENTRY_SIZE;
++      if (size > bytecount)
++              size = bytecount;
 +
-+      /* Use the vm area unlocked, assuming the caller
-+         ensures there isn't another iounmap for the same address
-+         in parallel. Reuse of the virtual address is prevented by
-+         leaving it in the global lists until we're done with it.
-+         cpa takes care of the direct mappings. */
-+      read_lock(&vmlist_lock);
-+      for (p = vmlist; p; p = p->next) {
-+              if (p->addr == addr)
-+                      break;
++      err = 0;
++      if (copy_to_user(ptr, mm->context.ldt, size))
++              err = -EFAULT;
++      mutex_unlock(&mm->context.lock);
++      if (err < 0)
++              goto error_return;
++      if (size != bytecount) {
++              /* zero-fill the rest */
++              if (clear_user(ptr + size, bytecount - size) != 0) {
++                      err = -EFAULT;
++                      goto error_return;
++              }
 +      }
-+      read_unlock(&vmlist_lock);
++      return bytecount;
++error_return:
++      return err;
++}
 +
-+      if (!p) {
-+              printk(KERN_ERR "iounmap: bad address %p\n", addr);
-+              dump_stack();
-+              return;
-+      }
++static int read_default_ldt(void __user *ptr, unsigned long bytecount)
++{
++      /* CHECKME: Can we use _one_ random number ? */
++#ifdef CONFIG_X86_32
++      unsigned long size = 5 * sizeof(struct desc_struct);
++#else
++      unsigned long size = 128;
++#endif
++      if (bytecount > size)
++              bytecount = size;
++      if (clear_user(ptr, bytecount))
++              return -EFAULT;
++      return bytecount;
++}
 +
-+      if ((p->flags >> 20) != IOR_MODE_CACHED) {
-+              unsigned long n = get_vm_area_size(p) >> PAGE_SHIFT;
-+              unsigned long mfn = p->phys_addr;
-+              unsigned long va = (unsigned long)addr;
++static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
++{
++      struct mm_struct *mm = current->mm;
++      struct desc_struct ldt;
++      int error;
++      struct user_desc ldt_info;
 +
-+              for (; n > 0; n--, mfn++, va += PAGE_SIZE)
-+                      if (mfn_to_local_pfn(mfn) < max_pfn)
-+                              set_memory_wb(va, 1);
++      error = -EINVAL;
++      if (bytecount != sizeof(ldt_info))
++              goto out;
++      error = -EFAULT;
++      if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
++              goto out;
++
++      error = -EINVAL;
++      if (ldt_info.entry_number >= LDT_ENTRIES)
++              goto out;
++      if (ldt_info.contents == 3) {
++              if (oldmode)
++                      goto out;
++              if (ldt_info.seg_not_present == 0)
++                      goto out;
 +      }
 +
-+      /* Finally remove it */
-+      o = remove_vm_area((void *)addr);
-+      BUG_ON(p != o || o == NULL);
-+      kfree(p);
-+}
-+EXPORT_SYMBOL(iounmap);
++      mutex_lock(&mm->context.lock);
++      if (ldt_info.entry_number >= mm->context.size) {
++              error = alloc_ldt(&current->mm->context,
++                                ldt_info.entry_number + 1, 1);
++              if (error < 0)
++                      goto out_unlock;
++      }
 +
-+int __initdata early_ioremap_debug;
++      /* Allow LDTs to be cleared by the user. */
++      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
++              if (oldmode || LDT_empty(&ldt_info)) {
++                      memset(&ldt, 0, sizeof(ldt));
++                      goto install;
++              }
++      }
 +
-+static int __init early_ioremap_debug_setup(char *str)
-+{
-+      early_ioremap_debug = 1;
++      fill_ldt(&ldt, &ldt_info);
++      if (oldmode)
++              ldt.avl = 0;
 +
-+      return 0;
-+}
-+early_param("early_ioremap_debug", early_ioremap_debug_setup);
++      /* Install the new entry ...  */
++install:
++      error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt);
 +
-+static __initdata int after_paging_init;
-+static __initdata pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)]
-+                              __attribute__((aligned(PAGE_SIZE)));
++out_unlock:
++      mutex_unlock(&mm->context.lock);
++out:
++      return error;
++}
 +
-+#ifdef CONFIG_X86_32
-+static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
++asmlinkage int sys_modify_ldt(int func, void __user *ptr,
++                            unsigned long bytecount)
 +{
-+      /* Don't assume we're using swapper_pg_dir at this point */
-+      pgd_t *base = __va(read_cr3());
-+      pgd_t *pgd = &base[pgd_index(addr)];
-+      pud_t *pud = pud_offset(pgd, addr);
-+      pmd_t *pmd = pmd_offset(pud, addr);
++      int ret = -ENOSYS;
 +
-+      return pmd;
++      switch (func) {
++      case 0:
++              ret = read_ldt(ptr, bytecount);
++              break;
++      case 1:
++              ret = write_ldt(ptr, bytecount, 1);
++              break;
++      case 2:
++              ret = read_default_ldt(ptr, bytecount);
++              break;
++      case 0x11:
++              ret = write_ldt(ptr, bytecount, 0);
++              break;
++      }
++      return ret;
 +}
-+#else
-+#define early_ioremap_pmd early_get_pmd
-+#define make_lowmem_page_readonly early_make_page_readonly
-+#define make_lowmem_page_writable make_page_writable
+--- sle11-2009-05-14.orig/arch/x86/kernel/ldt_32-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,265 +0,0 @@
+-/*
+- * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/vmalloc.h>
+-#include <linux/slab.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <asm/ldt.h>
+-#include <asm/desc.h>
+-#include <asm/mmu_context.h>
+-
+-#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+-static void flush_ldt(void *null)
+-{
+-      if (current->active_mm)
+-              load_LDT(&current->active_mm->context);
+-}
+-#endif
+-
+-static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+-{
+-      void *oldldt;
+-      void *newldt;
+-      int oldsize;
+-
+-      if (mincount <= pc->size)
+-              return 0;
+-      oldsize = pc->size;
+-      mincount = (mincount+511)&(~511);
+-      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+-              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+-      else
+-              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+-
+-      if (!newldt)
+-              return -ENOMEM;
+-
+-      if (oldsize)
+-              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+-      oldldt = pc->ldt;
+-      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+-      pc->ldt = newldt;
+-      wmb();
+-      pc->size = mincount;
+-      wmb();
+-
+-      if (reload) {
+-#ifdef CONFIG_SMP
+-              cpumask_t mask;
+-              preempt_disable();
+-#endif
+-              make_pages_readonly(
+-                      pc->ldt,
+-                      (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-                      XENFEAT_writable_descriptor_tables);
+-              load_LDT(pc);
+-#ifdef CONFIG_SMP
+-              mask = cpumask_of_cpu(smp_processor_id());
+-              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
+-                      smp_call_function(flush_ldt, NULL, 1, 1);
+-              preempt_enable();
+-#endif
+-      }
+-      if (oldsize) {
+-              make_pages_writable(
+-                      oldldt,
+-                      (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-                      XENFEAT_writable_descriptor_tables);
+-              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+-                      vfree(oldldt);
+-              else
+-                      kfree(oldldt);
+-      }
+-      return 0;
+-}
+-
+-static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+-{
+-      int err = alloc_ldt(new, old->size, 0);
+-      if (err < 0)
+-              return err;
+-      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
+-      make_pages_readonly(
+-              new->ldt,
+-              (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-              XENFEAT_writable_descriptor_tables);
+-      return 0;
+-}
+-
+-/*
+- * we do not have to muck with descriptors here, that is
+- * done in switch_mm() as needed.
+- */
+-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+-{
+-      struct mm_struct * old_mm;
+-      int retval = 0;
+-
+-      mutex_init(&mm->context.lock);
+-      mm->context.size = 0;
+-      mm->context.has_foreign_mappings = 0;
+-      old_mm = current->mm;
+-      if (old_mm && old_mm->context.size > 0) {
+-              mutex_lock(&old_mm->context.lock);
+-              retval = copy_ldt(&mm->context, &old_mm->context);
+-              mutex_unlock(&old_mm->context.lock);
+-      }
+-      return retval;
+-}
+-
+-/*
+- * No need to lock the MM as we are the last user
+- */
+-void destroy_context(struct mm_struct *mm)
+-{
+-      if (mm->context.size) {
+-              if (mm == current->active_mm)
+-                      clear_LDT();
+-              make_pages_writable(
+-                      mm->context.ldt,
+-                      (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-                      XENFEAT_writable_descriptor_tables);
+-              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+-                      vfree(mm->context.ldt);
+-              else
+-                      kfree(mm->context.ldt);
+-              mm->context.size = 0;
+-      }
+-}
+-
+-static int read_ldt(void __user * ptr, unsigned long bytecount)
+-{
+-      int err;
+-      unsigned long size;
+-      struct mm_struct * mm = current->mm;
+-
+-      if (!mm->context.size)
+-              return 0;
+-      if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+-              bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+-
+-      mutex_lock(&mm->context.lock);
+-      size = mm->context.size*LDT_ENTRY_SIZE;
+-      if (size > bytecount)
+-              size = bytecount;
+-
+-      err = 0;
+-      if (copy_to_user(ptr, mm->context.ldt, size))
+-              err = -EFAULT;
+-      mutex_unlock(&mm->context.lock);
+-      if (err < 0)
+-              goto error_return;
+-      if (size != bytecount) {
+-              /* zero-fill the rest */
+-              if (clear_user(ptr+size, bytecount-size) != 0) {
+-                      err = -EFAULT;
+-                      goto error_return;
+-              }
+-      }
+-      return bytecount;
+-error_return:
+-      return err;
+-}
+-
+-static int read_default_ldt(void __user * ptr, unsigned long bytecount)
+-{
+-      int err;
+-      unsigned long size;
+-
+-      err = 0;
+-      size = 5*sizeof(struct desc_struct);
+-      if (size > bytecount)
+-              size = bytecount;
+-
+-      err = size;
+-      if (clear_user(ptr, size))
+-              err = -EFAULT;
+-
+-      return err;
+-}
+-
+-static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
+-{
+-      struct mm_struct * mm = current->mm;
+-      __u32 entry_1, entry_2;
+-      int error;
+-      struct user_desc ldt_info;
+-
+-      error = -EINVAL;
+-      if (bytecount != sizeof(ldt_info))
+-              goto out;
+-      error = -EFAULT;        
+-      if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
+-              goto out;
+-
+-      error = -EINVAL;
+-      if (ldt_info.entry_number >= LDT_ENTRIES)
+-              goto out;
+-      if (ldt_info.contents == 3) {
+-              if (oldmode)
+-                      goto out;
+-              if (ldt_info.seg_not_present == 0)
+-                      goto out;
+-      }
+-
+-      mutex_lock(&mm->context.lock);
+-      if (ldt_info.entry_number >= mm->context.size) {
+-              error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
+-              if (error < 0)
+-                      goto out_unlock;
+-      }
+-
+-      /* Allow LDTs to be cleared by the user. */
+-      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+-              if (oldmode || LDT_empty(&ldt_info)) {
+-                      entry_1 = 0;
+-                      entry_2 = 0;
+-                      goto install;
+-              }
+-      }
+-
+-      entry_1 = LDT_entry_a(&ldt_info);
+-      entry_2 = LDT_entry_b(&ldt_info);
+-      if (oldmode)
+-              entry_2 &= ~(1 << 20);
+-
+-      /* Install the new entry ...  */
+-install:
+-      error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number,
+-                              entry_1, entry_2);
+-
+-out_unlock:
+-      mutex_unlock(&mm->context.lock);
+-out:
+-      return error;
+-}
+-
+-asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+-{
+-      int ret = -ENOSYS;
+-
+-      switch (func) {
+-      case 0:
+-              ret = read_ldt(ptr, bytecount);
+-              break;
+-      case 1:
+-              ret = write_ldt(ptr, bytecount, 1);
+-              break;
+-      case 2:
+-              ret = read_default_ldt(ptr, bytecount);
+-              break;
+-      case 0x11:
+-              ret = write_ldt(ptr, bytecount, 0);
+-              break;
+-      }
+-      return ret;
+-}
+--- sle11-2009-05-14.orig/arch/x86/kernel/ldt_64-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,271 +0,0 @@
+-/*
+- * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+- * Copyright (C) 2002 Andi Kleen
+- * 
+- * This handles calls from both 32bit and 64bit mode.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/vmalloc.h>
+-#include <linux/slab.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <asm/ldt.h>
+-#include <asm/desc.h>
+-#include <asm/proto.h>
+-#include <asm/pgalloc.h>
+-
+-#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+-static void flush_ldt(void *null)
+-{
+-      if (current->active_mm)
+-               load_LDT(&current->active_mm->context);
+-}
+-#endif
+-
+-static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
+-{
+-      void *oldldt;
+-      void *newldt;
+-      unsigned oldsize;
+-
+-      if (mincount <= (unsigned)pc->size)
+-              return 0;
+-      oldsize = pc->size;
+-      mincount = (mincount+511)&(~511);
+-      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+-              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+-      else
+-              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+-
+-      if (!newldt)
+-              return -ENOMEM;
+-
+-      if (oldsize)
+-              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+-      oldldt = pc->ldt;
+-      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+-      wmb();
+-      pc->ldt = newldt;
+-      wmb();
+-      pc->size = mincount;
+-      wmb();
+-      if (reload) {
+-#ifdef CONFIG_SMP
+-              cpumask_t mask;
+-
+-              preempt_disable();
+-#endif
+-              make_pages_readonly(
+-                      pc->ldt,
+-                      (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-                      XENFEAT_writable_descriptor_tables);
+-              load_LDT(pc);
+-#ifdef CONFIG_SMP
+-              mask = cpumask_of_cpu(smp_processor_id());
+-              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
+-                      smp_call_function(flush_ldt, NULL, 1, 1);
+-              preempt_enable();
+-#endif
+-      }
+-      if (oldsize) {
+-              make_pages_writable(
+-                      oldldt,
+-                      (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-                      XENFEAT_writable_descriptor_tables);
+-              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+-                      vfree(oldldt);
+-              else
+-                      kfree(oldldt);
+-      }
+-      return 0;
+-}
+-
+-static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+-{
+-      int err = alloc_ldt(new, old->size, 0);
+-      if (err < 0)
+-              return err;
+-      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
+-      make_pages_readonly(
+-              new->ldt,
+-              (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-              XENFEAT_writable_descriptor_tables);
+-      return 0;
+-}
+-
+-/*
+- * we do not have to muck with descriptors here, that is
+- * done in switch_mm() as needed.
+- */
+-int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+-{
+-      struct mm_struct * old_mm;
+-      int retval = 0;
+-
+-      memset(&mm->context, 0, sizeof(mm->context));
+-      mutex_init(&mm->context.lock);
+-      old_mm = current->mm;
+-      if (old_mm)
+-              mm->context.vdso = old_mm->context.vdso;
+-      if (old_mm && old_mm->context.size > 0) {
+-              mutex_lock(&old_mm->context.lock);
+-              retval = copy_ldt(&mm->context, &old_mm->context);
+-              mutex_unlock(&old_mm->context.lock);
+-      }
+-      return retval;
+-}
+-
+-/*
+- * 
+- * Don't touch the LDT register - we're already in the next thread.
+- */
+-void destroy_context(struct mm_struct *mm)
+-{
+-      if (mm->context.size) {
+-              if (mm == current->active_mm)
+-                      clear_LDT();
+-              make_pages_writable(
+-                      mm->context.ldt,
+-                      (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
+-                      XENFEAT_writable_descriptor_tables);
+-              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+-                      vfree(mm->context.ldt);
+-              else
+-                      kfree(mm->context.ldt);
+-              mm->context.size = 0;
+-      }
+-}
+-
+-static int read_ldt(void __user * ptr, unsigned long bytecount)
+-{
+-      int err;
+-      unsigned long size;
+-      struct mm_struct * mm = current->mm;
+-
+-      if (!mm->context.size)
+-              return 0;
+-      if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+-              bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+-
+-      mutex_lock(&mm->context.lock);
+-      size = mm->context.size*LDT_ENTRY_SIZE;
+-      if (size > bytecount)
+-              size = bytecount;
+-
+-      err = 0;
+-      if (copy_to_user(ptr, mm->context.ldt, size))
+-              err = -EFAULT;
+-      mutex_unlock(&mm->context.lock);
+-      if (err < 0)
+-              goto error_return;
+-      if (size != bytecount) {
+-              /* zero-fill the rest */
+-              if (clear_user(ptr+size, bytecount-size) != 0) {
+-                      err = -EFAULT;
+-                      goto error_return;
+-              }
+-      }
+-      return bytecount;
+-error_return:
+-      return err;
+-}
+-
+-static int read_default_ldt(void __user * ptr, unsigned long bytecount)
+-{
+-      /* Arbitrary number */ 
+-      /* x86-64 default LDT is all zeros */
+-      if (bytecount > 128) 
+-              bytecount = 128;        
+-      if (clear_user(ptr, bytecount))
+-              return -EFAULT;
+-      return bytecount; 
+-}
+-
+-static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
+-{
+-      struct task_struct *me = current;
+-      struct mm_struct * mm = me->mm;
+-      __u32 entry_1, entry_2, *lp;
+-      unsigned long mach_lp;
+-      int error;
+-      struct user_desc ldt_info;
+-
+-      error = -EINVAL;
+-
+-      if (bytecount != sizeof(ldt_info))
+-              goto out;
+-      error = -EFAULT;        
+-      if (copy_from_user(&ldt_info, ptr, bytecount))
+-              goto out;
+-
+-      error = -EINVAL;
+-      if (ldt_info.entry_number >= LDT_ENTRIES)
+-              goto out;
+-      if (ldt_info.contents == 3) {
+-              if (oldmode)
+-                      goto out;
+-              if (ldt_info.seg_not_present == 0)
+-                      goto out;
+-      }
+-
+-      mutex_lock(&mm->context.lock);
+-      if (ldt_info.entry_number >= (unsigned)mm->context.size) {
+-              error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
+-              if (error < 0)
+-                      goto out_unlock;
+-      }
+-
+-      lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
+-      mach_lp = arbitrary_virt_to_machine(lp);
+-
+-      /* Allow LDTs to be cleared by the user. */
+-      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+-              if (oldmode || LDT_empty(&ldt_info)) {
+-                      entry_1 = 0;
+-                      entry_2 = 0;
+-                      goto install;
+-              }
+-      }
+-
+-      entry_1 = LDT_entry_a(&ldt_info);
+-      entry_2 = LDT_entry_b(&ldt_info);
+-      if (oldmode)
+-              entry_2 &= ~(1 << 20);
+-
+-      /* Install the new entry ...  */
+-install:
+-      error = HYPERVISOR_update_descriptor(mach_lp, (unsigned long)((entry_1 | (unsigned long) entry_2 << 32)));
+-
+-out_unlock:
+-      mutex_unlock(&mm->context.lock);
+-out:
+-      return error;
+-}
+-
+-asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+-{
+-      int ret = -ENOSYS;
+-
+-      switch (func) {
+-      case 0:
+-              ret = read_ldt(ptr, bytecount);
+-              break;
+-      case 1:
+-              ret = write_ldt(ptr, bytecount, 1);
+-              break;
+-      case 2:
+-              ret = read_default_ldt(ptr, bytecount);
+-              break;
+-      case 0x11:
+-              ret = write_ldt(ptr, bytecount, 0);
+-              break;
+-      }
+-      return ret;
+-}
+--- sle11-2009-05-14.orig/arch/x86/kernel/machine_kexec_64.c   2008-11-25 12:35:54.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/machine_kexec_64.c        2009-03-16 16:33:40.000000000 +0100
+@@ -300,7 +300,9 @@ void machine_kexec(struct kimage *image)
+ void arch_crash_save_vmcoreinfo(void)
+ {
++#ifndef CONFIG_XEN /* could really be CONFIG_RELOCATABLE */
+       VMCOREINFO_SYMBOL(phys_base);
 +#endif
-+
-+static inline pte_t * __init early_ioremap_pte(unsigned long addr)
-+{
-+      return &bm_pte[pte_index(addr)];
-+}
-+
-+void __init early_ioremap_init(void)
-+{
-+      pmd_t *pmd;
-+
-+      if (early_ioremap_debug)
-+              printk(KERN_INFO "early_ioremap_init()\n");
-+
-+      pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
-+      memset(bm_pte, 0, sizeof(bm_pte));
-+      make_lowmem_page_readonly(bm_pte, XENFEAT_writable_page_tables);
-+      pmd_populate_kernel(&init_mm, pmd, bm_pte);
-+
+       VMCOREINFO_SYMBOL(init_level4_pgt);
+ #ifdef CONFIG_NUMA
+--- sle11-2009-05-14.orig/arch/x86/kernel/microcode-xen.c      2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/microcode-xen.c   2009-03-16 16:33:40.000000000 +0100
+@@ -167,7 +167,7 @@ static int request_microcode(void)
+       }
+       op.cmd = XENPF_microcode_update;
+-      set_xen_guest_handle(op.u.microcode.data, (void *)firmware->data);
++      set_xen_guest_handle(op.u.microcode.data, firmware->data);
+       op.u.microcode.length = firmware->size;
+       error = HYPERVISOR_platform_op(&op);
+--- sle11-2009-05-14.orig/arch/x86/kernel/mpparse_32-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/mpparse_32-xen.c  2009-03-16 16:33:40.000000000 +0100
+@@ -68,7 +68,7 @@ unsigned int def_to_bigsmp = 0;
+ /* Processor that is doing the boot up */
+ unsigned int boot_cpu_physical_apicid = -1U;
+ /* Internal processor count */
+-unsigned int __cpuinitdata num_processors;
++unsigned int num_processors;
+ /* Bitmask of physically existing CPUs */
+ physid_mask_t phys_cpu_present_map;
+@@ -265,7 +265,7 @@ static void __init MP_ioapic_info (struc
+       if (!(m->mpc_flags & MPC_APIC_USABLE))
+               return;
+-      printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n",
++      printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
+               m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
+       if (nr_ioapics >= MAX_IO_APICS) {
+               printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n",
+@@ -412,9 +412,9 @@ static int __init smp_read_mpc(struct mp
+       mps_oem_check(mpc, oem, str);
+-      printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
++      printk("APIC at: 0x%X\n", mpc->mpc_lapic);
+-      /* 
 +      /*
-+       * The boot-ioremap range spans multiple pmds, for which
-+       * we are not prepared:
-+       */
-+      if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
-+              WARN_ON(1);
-+              printk(KERN_WARNING "pmd %p != %p\n",
-+                     pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
-+              printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
-+                      fix_to_virt(FIX_BTMAP_BEGIN));
-+              printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END):   %08lx\n",
-+                      fix_to_virt(FIX_BTMAP_END));
-+
-+              printk(KERN_WARNING "FIX_BTMAP_END:       %d\n", FIX_BTMAP_END);
-+              printk(KERN_WARNING "FIX_BTMAP_BEGIN:     %d\n",
-+                     FIX_BTMAP_BEGIN);
-+      }
-+}
-+
-+void __init early_ioremap_clear(void)
-+{
-+      pmd_t *pmd;
-+
-+      if (early_ioremap_debug)
-+              printk(KERN_INFO "early_ioremap_clear()\n");
-+
-+      pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
-+      pmd_clear(pmd);
-+      make_lowmem_page_writable(bm_pte, XENFEAT_writable_page_tables);
-+      /* paravirt_release_pt(__pa(bm_pte) >> PAGE_SHIFT); */
-+      __flush_tlb_all();
-+}
-+
-+void __init early_ioremap_reset(void)
-+{
-+      enum fixed_addresses idx;
-+      unsigned long addr, phys;
-+      pte_t *pte;
-+
-+      after_paging_init = 1;
-+      for (idx = FIX_BTMAP_BEGIN; idx >= FIX_BTMAP_END; idx--) {
-+              addr = fix_to_virt(idx);
-+              pte = early_ioremap_pte(addr);
-+              if (pte_present(*pte)) {
-+                      phys = __pte_val(*pte) & PAGE_MASK;
-+                      set_fixmap(idx, phys);
-+              }
-+      }
-+}
-+
-+static void __init __early_set_fixmap(enum fixed_addresses idx,
-+                                 unsigned long phys, pgprot_t flags)
-+{
-+      unsigned long addr = __fix_to_virt(idx);
-+      pte_t *pte;
-+
-+      if (idx >= __end_of_fixed_addresses) {
-+              BUG();
-+              return;
-+      }
-+      pte = early_ioremap_pte(addr);
-+      if (pgprot_val(flags))
-+              set_pte(pte, pfn_pte_ma(phys >> PAGE_SHIFT, flags));
-+      else
-+              pte_clear(NULL, addr, pte);
-+      __flush_tlb_one(addr);
-+}
+        * Save the local APIC address (it might be non-default) -- but only
+        * if we're not using ACPI.
+        */
+@@ -728,7 +728,7 @@ static int __init smp_scan_config (unsig
+       unsigned long *bp = isa_bus_to_virt(base);
+       struct intel_mp_floating *mpf;
+-      Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
++      printk(KERN_INFO "Scan SMP from %p for %ld bytes.\n", bp,length);
+       if (sizeof(*mpf) != 16)
+               printk("Error: MPF size\n");
+@@ -742,9 +742,10 @@ static int __init smp_scan_config (unsig
+                       smp_found_config = 1;
+ #ifndef CONFIG_XEN
+-                      printk(KERN_INFO "found SMP MP-table at %08lx\n",
+-                                              virt_to_phys(mpf));
+-                      reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
++                      printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
++                              mpf, virt_to_phys(mpf));
++                      reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
++                                      BOOTMEM_DEFAULT);
+                       if (mpf->mpf_physptr) {
+                               /*
+                                * We cannot access to MPC table to compute
+@@ -759,11 +760,12 @@ static int __init smp_scan_config (unsig
+                               unsigned long end = max_low_pfn * PAGE_SIZE;
+                               if (mpf->mpf_physptr + size > end)
+                                       size = end - mpf->mpf_physptr;
+-                              reserve_bootmem(mpf->mpf_physptr, size);
++                              reserve_bootmem(mpf->mpf_physptr, size,
++                                              BOOTMEM_DEFAULT);
+                       }
+ #else
+-                      printk(KERN_INFO "found SMP MP-table at %08lx\n",
+-                              ((unsigned long)bp - (unsigned long)isa_bus_to_virt(base)) + base);
++                      printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
++                              mpf, ((void *)bp - isa_bus_to_virt(base)) + base);
+ #endif
+                       mpf_found = mpf;
+@@ -940,14 +942,14 @@ void __init mp_register_ioapic(u8 id, u3
+        */
+       mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
+       mp_ioapic_routing[idx].gsi_base = gsi_base;
+-      mp_ioapic_routing[idx].gsi_end = gsi_base + 
++      mp_ioapic_routing[idx].gsi_end = gsi_base +
+               io_apic_get_redir_entries(idx);
+-      printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
+-              "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
+-              mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
+-              mp_ioapic_routing[idx].gsi_base,
+-              mp_ioapic_routing[idx].gsi_end);
++      printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
++             "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
++             mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
++             mp_ioapic_routing[idx].gsi_base,
++             mp_ioapic_routing[idx].gsi_end);
+ }
+ void __init
+@@ -1063,15 +1065,16 @@ void __init mp_config_acpi_legacy_irqs (
+ }
+ #define MAX_GSI_NUM   4096
++#define IRQ_COMPRESSION_START 64
+ int mp_register_gsi(u32 gsi, int triggering, int polarity)
+ {
+       int ioapic = -1;
+       int ioapic_pin = 0;
+       int idx, bit = 0;
+-      static int pci_irq = 16;
++      static int pci_irq = IRQ_COMPRESSION_START;
+       /*
+-       * Mapping between Global System Interrups, which
++       * Mapping between Global System Interrupts, which
+        * represent all possible interrupts, and IRQs
+        * assigned to actual devices.
+        */
+@@ -1108,12 +1111,16 @@ int mp_register_gsi(u32 gsi, int trigger
+       if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+               Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
+                       mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+-              return gsi_to_irq[gsi];
++              return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
+       }
+       mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+-      if (triggering == ACPI_LEVEL_SENSITIVE) {
++      /*
++       * 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.
+--- sle11-2009-05-14.orig/arch/x86/kernel/mpparse_64-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/mpparse_64-xen.c  2009-03-16 16:33:40.000000000 +0100
+@@ -60,14 +60,20 @@ unsigned int boot_cpu_id = -1U;
+ EXPORT_SYMBOL(boot_cpu_id);
+ /* Internal processor count */
+-unsigned int num_processors __cpuinitdata = 0;
++unsigned int num_processors;
+ unsigned disabled_cpus __cpuinitdata;
+ /* Bitmask of physically existing CPUs */
+ physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
+-u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
++#ifndef CONFIG_XEN
++u16 x86_bios_cpu_apicid_init[NR_CPUS] __initdata
++                              = { [0 ... NR_CPUS-1] = BAD_APICID };
++void *x86_bios_cpu_apicid_early_ptr;
++#endif
++DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
++EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
+ /*
+@@ -119,24 +125,22 @@ static void __cpuinit MP_processor_info(
+       physid_set(m->mpc_apicid, phys_cpu_present_map);
+       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
+               /*
+-               * bios_cpu_apicid is required to have processors listed
++               * x86_bios_cpu_apicid is required to have processors listed
+                * in same order as logical cpu numbers. Hence the first
+                * entry is BSP, and so on.
+                */
+               cpu = 0;
+       }
+-      bios_cpu_apicid[cpu] = m->mpc_apicid;
+-      /*
+-       * We get called early in the the start_kernel initialization
+-       * process when the per_cpu data area is not yet setup, so we
+-       * use a static array that is removed after the per_cpu data
+-       * area is created.
+-       */
+-      if (x86_cpu_to_apicid_ptr) {
+-              u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
+-              x86_cpu_to_apicid[cpu] = m->mpc_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;
++              u16 *bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr;
 +
-+static inline void __init early_set_fixmap(enum fixed_addresses idx,
-+                                      unsigned long phys)
-+{
-+      if (after_paging_init)
-+              set_fixmap(idx, phys);
-+      else
-+              __early_set_fixmap(idx, phys, PAGE_KERNEL);
-+}
++              cpu_to_apicid[cpu] = m->mpc_apicid;
++              bios_cpu_apicid[cpu] = m->mpc_apicid;
+       } else {
+               per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
++              per_cpu(x86_bios_cpu_apicid, cpu) = m->mpc_apicid;
+       }
+       cpu_set(cpu, cpu_possible_map);
+--- sle11-2009-05-14.orig/arch/x86/kernel/pci-dma-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/pci-dma-xen.c     2009-03-16 16:33:40.000000000 +0100
+@@ -434,3 +434,23 @@ dma_sync_single_for_device(struct device
+               swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
+ }
+ EXPORT_SYMBOL(dma_sync_single_for_device);
 +
-+static inline void __init early_clear_fixmap(enum fixed_addresses idx)
++void
++dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
++                  enum dma_data_direction direction)
 +{
-+      if (after_paging_init)
-+              clear_fixmap(idx);
-+      else
-+              __early_set_fixmap(idx, 0, __pgprot(0));
++      if (swiotlb)
++              swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
++      flush_write_buffers();
 +}
++EXPORT_SYMBOL(dma_sync_sg_for_cpu);
 +
-+
-+int __initdata early_ioremap_nested;
-+
-+static int __init check_early_ioremap_leak(void)
++void
++dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
++                  enum dma_data_direction direction)
 +{
-+      if (!early_ioremap_nested)
-+              return 0;
-+
-+      printk(KERN_WARNING
-+             "Debug warning: early ioremap leak of %d areas detected.\n",
-+             early_ioremap_nested);
-+      printk(KERN_WARNING
-+             "please boot with early_ioremap_debug and report the dmesg.\n");
-+      WARN_ON(1);
-+
-+      return 1;
++      if (swiotlb)
++              swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
++      flush_write_buffers();
 +}
-+late_initcall(check_early_ioremap_leak);
-+
-+void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
-+{
-+      unsigned long offset, last_addr;
-+      unsigned int nrpages, nesting;
-+      enum fixed_addresses idx0, idx;
-+
-+      WARN_ON(system_state != SYSTEM_BOOTING);
-+
-+      nesting = early_ioremap_nested;
-+      if (early_ioremap_debug) {
-+              printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
-+                     phys_addr, size, nesting);
-+              dump_stack();
-+      }
-+
-+      /* Don't allow wraparound or zero size */
-+      last_addr = phys_addr + size - 1;
-+      if (!size || last_addr < phys_addr) {
-+              WARN_ON(1);
-+              return NULL;
-+      }
++EXPORT_SYMBOL(dma_sync_sg_for_device);
+--- sle11-2009-05-14.orig/arch/x86/kernel/process_32-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/process_32-xen.c  2009-03-16 16:33:40.000000000 +0100
+@@ -23,7 +23,6 @@
+ #include <linux/slab.h>
+ #include <linux/vmalloc.h>
+ #include <linux/user.h>
+-#include <linux/a.out.h>
+ #include <linux/interrupt.h>
+ #include <linux/utsname.h>
+ #include <linux/delay.h>
+@@ -59,8 +58,10 @@
+ #include <asm/tlbflush.h>
+ #include <asm/cpu.h>
++#include <asm/kdebug.h>
+ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
++asmlinkage void cstar_ret_from_fork(void) __asm__("cstar_ret_from_fork");
+ static int hlt_counter;
+@@ -78,7 +79,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
+  */
+ unsigned long thread_saved_pc(struct task_struct *tsk)
+ {
+-      return ((unsigned long *)tsk->thread.esp)[3];
++      return ((unsigned long *)tsk->thread.sp)[3];
+ }
+ /*
+@@ -86,7 +87,6 @@ unsigned long thread_saved_pc(struct tas
+  */
+ void (*pm_idle)(void);
+ EXPORT_SYMBOL(pm_idle);
+-static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
+ void disable_hlt(void)
+ {
+@@ -107,7 +107,7 @@ EXPORT_SYMBOL(enable_hlt);
+  * to poll the ->work.need_resched flag instead of waiting for the
+  * cross-CPU IPI to arrive. Use this option with caution.
+  */
+-static void poll_idle (void)
++static void poll_idle(void)
+ {
+       cpu_relax();
+ }
+@@ -122,10 +122,19 @@ static void xen_idle(void)
+       smp_mb();
+       local_irq_disable();
+-      if (!need_resched())
++      if (!need_resched()) {
++              ktime_t t0, t1;
++              u64 t0n, t1n;
 +
-+      if (nesting >= FIX_BTMAPS_NESTING) {
-+              WARN_ON(1);
-+              return NULL;
++              t0 = ktime_get();
++              t0n = ktime_to_ns(t0);
+               safe_halt();    /* enables interrupts racelessly */
+-      else
+-              local_irq_enable();
++              local_irq_disable();
++              t1 = ktime_get();
++              t1n = ktime_to_ns(t1);
++              sched_clock_idle_wakeup_event(t1n - t0n);
 +      }
-+      early_ioremap_nested++;
-+      /*
-+       * Mappings have to be page-aligned
-+       */
-+      offset = phys_addr & ~PAGE_MASK;
-+      phys_addr &= PAGE_MASK;
-+      size = PAGE_ALIGN(last_addr) - phys_addr;
++      local_irq_enable();
+       current_thread_info()->status |= TS_POLLING;
+ }
+ #ifdef CONFIG_APM_MODULE
+@@ -168,13 +177,13 @@ void cpu_idle(void)
+               while (!need_resched()) {
+                       void (*idle)(void);
+-                      if (__get_cpu_var(cpu_idle_state))
+-                              __get_cpu_var(cpu_idle_state) = 0;
+-
+                       check_pgt_cache();
+                       rmb();
+                       idle = xen_idle; /* no alternatives */
++                      if (rcu_pending(cpu))
++                              rcu_check_callbacks(cpu, 0);
 +
-+      /*
-+       * Mappings have to fit in the FIX_BTMAP area.
-+       */
-+      nrpages = size >> PAGE_SHIFT;
-+      if (nrpages > NR_FIX_BTMAPS) {
-+              WARN_ON(1);
-+              return NULL;
-+      }
+                       if (cpu_is_offline(cpu))
+                               play_dead();
+@@ -192,40 +201,19 @@ static void do_nothing(void *unused)
+ {
+ }
++/*
++ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
++ * pm_idle and update to new pm_idle value. Required while changing pm_idle
++ * handler on SMP systems.
++ *
++ * Caller must have changed pm_idle to the new value before the call. Old
++ * pm_idle value will not be used by any CPU after the return of this function.
++ */
+ void cpu_idle_wait(void)
+ {
+-      unsigned int cpu, this_cpu = get_cpu();
+-      cpumask_t map, tmp = current->cpus_allowed;
+-
+-      set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
+-      put_cpu();
+-
+-      cpus_clear(map);
+-      for_each_online_cpu(cpu) {
+-              per_cpu(cpu_idle_state, cpu) = 1;
+-              cpu_set(cpu, map);
+-      }
+-
+-      __get_cpu_var(cpu_idle_state) = 0;
+-
+-      wmb();
+-      do {
+-              ssleep(1);
+-              for_each_online_cpu(cpu) {
+-                      if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
+-                              cpu_clear(cpu, map);
+-              }
+-              cpus_and(map, map, cpu_online_map);
+-              /*
+-               * We waited 1 sec, if a CPU still did not call idle
+-               * it may be because it is in idle and not waking up
+-               * because it has nothing to do.
+-               * Give all the remaining CPUS a kick.
+-               */
+-              smp_call_function_mask(map, do_nothing, 0, 0);
+-      } while (!cpus_empty(map));
+-
+-      set_cpus_allowed(current, tmp);
++      smp_mb();
++      /* kick all the CPUs so that they exit out of pm_idle */
++      smp_call_function(do_nothing, NULL, 0, 1);
+ }
+ EXPORT_SYMBOL_GPL(cpu_idle_wait);
+@@ -251,15 +239,15 @@ void __show_registers(struct pt_regs *re
+ {
+       unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
+       unsigned long d0, d1, d2, d3, d6, d7;
+-      unsigned long esp;
++      unsigned long sp;
+       unsigned short ss, gs;
+       if (user_mode_vm(regs)) {
+-              esp = regs->esp;
+-              ss = regs->xss & 0xffff;
++              sp = regs->sp;
++              ss = regs->ss & 0xffff;
+               savesegment(gs, gs);
+       } else {
+-              esp = (unsigned long) (&regs->esp);
++              sp = (unsigned long) (&regs->sp);
+               savesegment(ss, ss);
+               savesegment(gs, gs);
+       }
+@@ -272,17 +260,17 @@ void __show_registers(struct pt_regs *re
+                       init_utsname()->version);
+       printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
+-                      0xffff & regs->xcs, regs->eip, regs->eflags,
++                      0xffff & regs->cs, regs->ip, regs->flags,
+                       smp_processor_id());
+-      print_symbol("EIP is at %s\n", regs->eip);
++      print_symbol("EIP is at %s\n", regs->ip);
+       printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+-              regs->eax, regs->ebx, regs->ecx, regs->edx);
++              regs->ax, regs->bx, regs->cx, regs->dx);
+       printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
+-              regs->esi, regs->edi, regs->ebp, esp);
++              regs->si, regs->di, regs->bp, sp);
+       printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
+-             regs->xds & 0xffff, regs->xes & 0xffff,
+-             regs->xfs & 0xffff, gs, ss);
++             regs->ds & 0xffff, regs->es & 0xffff,
++             regs->fs & 0xffff, gs, ss);
+       if (!all)
+               return;
+@@ -310,12 +298,12 @@ void __show_registers(struct pt_regs *re
+ void show_regs(struct pt_regs *regs)
+ {
+       __show_registers(regs, 1);
+-      show_trace(NULL, regs, &regs->esp);
++      show_trace(NULL, regs, &regs->sp, regs->bp);
+ }
+ /*
+- * This gets run with %ebx containing the
+- * function to call, and %edx containing
++ * This gets run with %bx containing the
++ * function to call, and %dx containing
+  * the "args".
+  */
+ extern void kernel_thread_helper(void);
+@@ -329,16 +317,16 @@ int kernel_thread(int (*fn)(void *), voi
+       memset(&regs, 0, sizeof(regs));
+-      regs.ebx = (unsigned long) fn;
+-      regs.edx = (unsigned long) arg;
++      regs.bx = (unsigned long) fn;
++      regs.dx = (unsigned long) arg;
+-      regs.xds = __USER_DS;
+-      regs.xes = __USER_DS;
+-      regs.xfs = __KERNEL_PERCPU;
+-      regs.orig_eax = -1;
+-      regs.eip = (unsigned long) kernel_thread_helper;
+-      regs.xcs = __KERNEL_CS | get_kernel_rpl();
+-      regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
++      regs.ds = __USER_DS;
++      regs.es = __USER_DS;
++      regs.fs = __KERNEL_PERCPU;
++      regs.orig_ax = -1;
++      regs.ip = (unsigned long) kernel_thread_helper;
++      regs.cs = __KERNEL_CS | get_kernel_rpl();
++      regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
+       /* Ok, create the new process.. */
+       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+@@ -368,7 +356,12 @@ void flush_thread(void)
+ {
+       struct task_struct *tsk = current;
+-      memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
++      tsk->thread.debugreg0 = 0;
++      tsk->thread.debugreg1 = 0;
++      tsk->thread.debugreg2 = 0;
++      tsk->thread.debugreg3 = 0;
++      tsk->thread.debugreg6 = 0;
++      tsk->thread.debugreg7 = 0;
+       memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
+       clear_tsk_thread_flag(tsk, TIF_DEBUG);
+       /*
+@@ -393,7 +386,7 @@ void prepare_to_copy(struct task_struct 
+       unlazy_fpu(tsk);
+ }
+-int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
++int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+       unsigned long unused,
+       struct task_struct * p, struct pt_regs * regs)
+ {
+@@ -403,17 +396,19 @@ int copy_thread(int nr, unsigned long cl
+       childregs = task_pt_regs(p);
+       *childregs = *regs;
+-      childregs->eax = 0;
+-      childregs->esp = esp;
++      childregs->ax = 0;
++      childregs->sp = sp;
+-      p->thread.esp = (unsigned long) childregs;
+-      p->thread.esp0 = (unsigned long) (childregs+1);
++      p->thread.sp = (unsigned long) childregs;
++      p->thread.sp0 = (unsigned long) (childregs+1);
+-      p->thread.eip = (unsigned long) ret_from_fork;
++      p->thread.ip = (unsigned long) ret_from_fork;
+-      savesegment(gs,p->thread.gs);
++      savesegment(gs, p->thread.gs);
+       tsk = current;
++      if (test_tsk_thread_flag(tsk, TIF_CSTAR))
++              p->thread.ip = (unsigned long) cstar_ret_from_fork;
+       if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
+               p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
+                                               IO_BITMAP_BYTES, GFP_KERNEL);
+@@ -424,34 +419,17 @@ int copy_thread(int nr, unsigned long cl
+               set_tsk_thread_flag(p, TIF_IO_BITMAP);
+       }
++      err = 0;
 +
-+      /*
-+       * Ok, go for it..
-+       */
-+      idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting;
-+      idx = idx0;
-+      while (nrpages > 0) {
-+              early_set_fixmap(idx, phys_addr);
-+              phys_addr += PAGE_SIZE;
-+              --idx;
-+              --nrpages;
+       /*
+        * Set a new TLS for the child thread?
+        */
+-      if (clone_flags & CLONE_SETTLS) {
+-              struct desc_struct *desc;
+-              struct user_desc info;
+-              int idx;
+-
+-              err = -EFAULT;
+-              if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
+-                      goto out;
+-              err = -EINVAL;
+-              if (LDT_empty(&info))
+-                      goto out;
+-
+-              idx = info.entry_number;
+-              if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+-                      goto out;
+-
+-              desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
+-              desc->a = LDT_entry_a(&info);
+-              desc->b = LDT_entry_b(&info);
+-      }
++      if (clone_flags & CLONE_SETTLS)
++              err = do_set_thread_area(p, -1,
++                      (struct user_desc __user *)childregs->si, 0);
+       p->thread.iopl = current->thread.iopl;
+-      err = 0;
+- out:
+       if (err && p->thread.io_bitmap_ptr) {
+               kfree(p->thread.io_bitmap_ptr);
+               p->thread.io_bitmap_max = 0;
+@@ -459,67 +437,8 @@ int copy_thread(int nr, unsigned long cl
+       return err;
+ }
+-/*
+- * fill in the user structure for a core dump..
+- */
+-void dump_thread(struct pt_regs * regs, struct user * dump)
+-{
+-      int i;
+-
+-/* changed the size calculations - should hopefully work better. lbt */
+-      dump->magic = CMAGIC;
+-      dump->start_code = 0;
+-      dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
+-      dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+-      dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
+-      dump->u_dsize -= dump->u_tsize;
+-      dump->u_ssize = 0;
+-      for (i = 0; i < 8; i++)
+-              dump->u_debugreg[i] = current->thread.debugreg[i];  
+-
+-      if (dump->start_stack < TASK_SIZE)
+-              dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+-
+-      dump->regs.ebx = regs->ebx;
+-      dump->regs.ecx = regs->ecx;
+-      dump->regs.edx = regs->edx;
+-      dump->regs.esi = regs->esi;
+-      dump->regs.edi = regs->edi;
+-      dump->regs.ebp = regs->ebp;
+-      dump->regs.eax = regs->eax;
+-      dump->regs.ds = regs->xds;
+-      dump->regs.es = regs->xes;
+-      dump->regs.fs = regs->xfs;
+-      savesegment(gs,dump->regs.gs);
+-      dump->regs.orig_eax = regs->orig_eax;
+-      dump->regs.eip = regs->eip;
+-      dump->regs.cs = regs->xcs;
+-      dump->regs.eflags = regs->eflags;
+-      dump->regs.esp = regs->esp;
+-      dump->regs.ss = regs->xss;
+-
+-      dump->u_fpvalid = dump_fpu (regs, &dump->i387);
+-}
+-EXPORT_SYMBOL(dump_thread);
+-
+-/* 
+- * Capture the user space registers if the task is not running (in user space)
+- */
+-int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
+-{
+-      struct pt_regs ptregs = *task_pt_regs(tsk);
+-      ptregs.xcs &= 0xffff;
+-      ptregs.xds &= 0xffff;
+-      ptregs.xes &= 0xffff;
+-      ptregs.xss &= 0xffff;
+-
+-      elf_core_copy_regs(regs, &ptregs);
+-
+-      return 1;
+-}
+-
+ #ifdef CONFIG_SECCOMP
+-void hard_disable_TSC(void)
++static void hard_disable_TSC(void)
+ {
+       write_cr4(read_cr4() | X86_CR4_TSD);
+ }
+@@ -534,7 +453,7 @@ void disable_TSC(void)
+               hard_disable_TSC();
+       preempt_enable();
+ }
+-void hard_enable_TSC(void)
++static void hard_enable_TSC(void)
+ {
+       write_cr4(read_cr4() & ~X86_CR4_TSD);
+ }
+@@ -543,18 +462,32 @@ void hard_enable_TSC(void)
+ static noinline void
+ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
+ {
+-      struct thread_struct *next;
++      struct thread_struct *prev, *next;
++      unsigned long debugctl;
++      prev = &prev_p->thread;
+       next = &next_p->thread;
++      debugctl = prev->debugctlmsr;
++      if (next->ds_area_msr != prev->ds_area_msr) {
++              /* we clear debugctl to make sure DS
++               * is not in use when we change it */
++              debugctl = 0;
++              wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
++              wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
 +      }
-+      if (early_ioremap_debug)
-+              printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
-+
-+      return (void *) (offset + fix_to_virt(idx0));
-+}
-+
-+void __init early_iounmap(void *addr, unsigned long size)
-+{
-+      unsigned long virt_addr;
-+      unsigned long offset;
-+      unsigned int nrpages;
-+      enum fixed_addresses idx;
-+      unsigned int nesting;
-+
-+      nesting = --early_ioremap_nested;
-+      WARN_ON(nesting < 0);
 +
-+      if (early_ioremap_debug) {
-+              printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr,
-+                     size, nesting);
-+              dump_stack();
-+      }
++      if (next->debugctlmsr != debugctl)
++              wrmsr(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr, 0);
 +
-+      virt_addr = (unsigned long)addr;
-+      if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN)) {
-+              WARN_ON(1);
-+              return;
-+      }
-+      offset = virt_addr & ~PAGE_MASK;
-+      nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
+       if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
+-              set_debugreg(next->debugreg[0], 0);
+-              set_debugreg(next->debugreg[1], 1);
+-              set_debugreg(next->debugreg[2], 2);
+-              set_debugreg(next->debugreg[3], 3);
++              set_debugreg(next->debugreg0, 0);
++              set_debugreg(next->debugreg1, 1);
++              set_debugreg(next->debugreg2, 2);
++              set_debugreg(next->debugreg3, 3);
+               /* no 4 and 5 */
+-              set_debugreg(next->debugreg[6], 6);
+-              set_debugreg(next->debugreg[7], 7);
++              set_debugreg(next->debugreg6, 6);
++              set_debugreg(next->debugreg7, 7);
+       }
+ #ifdef CONFIG_SECCOMP
+@@ -567,6 +500,14 @@ __switch_to_xtra(struct task_struct *pre
+                       hard_enable_TSC();
+       }
+ #endif
 +
-+      idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting;
-+      while (nrpages > 0) {
-+              early_clear_fixmap(idx);
-+              --idx;
-+              --nrpages;
-+      }
-+}
++#ifdef X86_BTS
++      if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
++              ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
 +
-+void __this_fixmap_does_not_exist(void)
-+{
-+      WARN_ON(1);
-+}
---- a/arch/x86/mm/pageattr_64-xen.c
-+++ /dev/null
-@@ -1,542 +0,0 @@
--/* 
-- * Copyright 2002 Andi Kleen, SuSE Labs. 
-- * Thanks to Ben LaHaise for precious feedback.
-- */ 
++      if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
++              ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
++#endif
+ }
+ /*
+@@ -592,11 +533,11 @@ __switch_to_xtra(struct task_struct *pre
+  * More important, however, is the fact that this allows us much
+  * more flexibility.
+  *
+- * The return value (in %eax) will be the "prev" task after
++ * The return value (in %ax) will be the "prev" task after
+  * the task-switch, and shows up in ret_from_fork in entry.S,
+  * for example.
+  */
+-struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
++struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+ {
+       struct thread_struct *prev = &prev_p->thread,
+                                *next = &next_p->thread;
+@@ -632,12 +573,12 @@ struct task_struct fastcall * __switch_t
+ #endif
+       /*
+-       * Reload esp0.
+-       * This is load_esp0(tss, next) with a multicall.
++       * Reload sp0.
++       * This is load_sp0(tss, next) with a multicall.
+        */
+       mcl->op      = __HYPERVISOR_stack_switch;
+       mcl->args[0] = __KERNEL_DS;
+-      mcl->args[1] = next->esp0;
++      mcl->args[1] = next->sp0;
+       mcl++;
+       /*
+@@ -734,7 +675,7 @@ struct task_struct fastcall * __switch_t
+ asmlinkage int sys_fork(struct pt_regs regs)
+ {
+-      return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
++      return do_fork(SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
+ }
+ asmlinkage int sys_clone(struct pt_regs regs)
+@@ -743,12 +684,12 @@ asmlinkage int sys_clone(struct pt_regs 
+       unsigned long newsp;
+       int __user *parent_tidptr, *child_tidptr;
+-      clone_flags = regs.ebx;
+-      newsp = regs.ecx;
+-      parent_tidptr = (int __user *)regs.edx;
+-      child_tidptr = (int __user *)regs.edi;
++      clone_flags = regs.bx;
++      newsp = regs.cx;
++      parent_tidptr = (int __user *)regs.dx;
++      child_tidptr = (int __user *)regs.di;
+       if (!newsp)
+-              newsp = regs.esp;
++              newsp = regs.sp;
+       return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
+ }
+@@ -764,7 +705,7 @@ asmlinkage int sys_clone(struct pt_regs 
+  */
+ asmlinkage int sys_vfork(struct pt_regs regs)
+ {
+-      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
++      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
+ }
+ /*
+@@ -775,18 +716,15 @@ asmlinkage int sys_execve(struct pt_regs
+       int error;
+       char * filename;
+-      filename = getname((char __user *) regs.ebx);
++      filename = getname((char __user *) regs.bx);
+       error = PTR_ERR(filename);
+       if (IS_ERR(filename))
+               goto out;
+       error = do_execve(filename,
+-                      (char __user * __user *) regs.ecx,
+-                      (char __user * __user *) regs.edx,
++                      (char __user * __user *) regs.cx,
++                      (char __user * __user *) regs.dx,
+                       &regs);
+       if (error == 0) {
+-              task_lock(current);
+-              current->ptrace &= ~PT_DTRACE;
+-              task_unlock(current);
+               /* Make sure we don't return using sysenter.. */
+               set_thread_flag(TIF_IRET);
+       }
+@@ -800,145 +738,37 @@ out:
+ unsigned long get_wchan(struct task_struct *p)
+ {
+-      unsigned long ebp, esp, eip;
++      unsigned long bp, sp, ip;
+       unsigned long stack_page;
+       int count = 0;
+       if (!p || p == current || p->state == TASK_RUNNING)
+               return 0;
+       stack_page = (unsigned long)task_stack_page(p);
+-      esp = p->thread.esp;
+-      if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
++      sp = p->thread.sp;
++      if (!stack_page || sp < stack_page || sp > top_esp+stack_page)
+               return 0;
+-      /* include/asm-i386/system.h:switch_to() pushes ebp last. */
+-      ebp = *(unsigned long *) esp;
++      /* include/asm-i386/system.h:switch_to() pushes bp last. */
++      bp = *(unsigned long *) sp;
+       do {
+-              if (ebp < stack_page || ebp > top_ebp+stack_page)
++              if (bp < stack_page || bp > top_ebp+stack_page)
+                       return 0;
+-              eip = *(unsigned long *) (ebp+4);
+-              if (!in_sched_functions(eip))
+-                      return eip;
+-              ebp = *(unsigned long *) ebp;
++              ip = *(unsigned long *) (bp+4);
++              if (!in_sched_functions(ip))
++                      return ip;
++              bp = *(unsigned long *) bp;
+       } while (count++ < 16);
+       return 0;
+ }
+-/*
+- * sys_alloc_thread_area: get a yet unused TLS descriptor index.
+- */
+-static int get_free_idx(void)
+-{
+-      struct thread_struct *t = &current->thread;
+-      int idx;
 -
--#include <linux/mm.h>
--#include <linux/sched.h>
--#include <linux/highmem.h>
--#include <linux/module.h>
--#include <linux/slab.h>
--#include <asm/uaccess.h>
--#include <asm/processor.h>
--#include <asm/tlbflush.h>
--#include <asm/io.h>
+-      for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
+-              if (desc_empty(t->tls_array + idx))
+-                      return idx + GDT_ENTRY_TLS_MIN;
+-      return -ESRCH;
+-}
 -
--#ifdef CONFIG_XEN
--#include <asm/pgalloc.h>
--#include <asm/mmu_context.h>
+-/*
+- * Set a given TLS descriptor:
+- */
+-asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
+-{
+-      struct thread_struct *t = &current->thread;
+-      struct user_desc info;
+-      struct desc_struct *desc;
+-      int cpu, idx;
 -
--static void _pin_lock(struct mm_struct *mm, int lock) {
--      if (lock)
--              spin_lock(&mm->page_table_lock);
--#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
--      /* While mm->page_table_lock protects us against insertions and
--       * removals of higher level page table pages, it doesn't protect
--       * against updates of pte-s. Such updates, however, require the
--       * pte pages to be in consistent state (unpinned+writable or
--       * pinned+readonly). The pinning and attribute changes, however
--       * cannot be done atomically, which is why such updates must be
--       * prevented from happening concurrently.
--       * Note that no pte lock can ever elsewhere be acquired nesting
--       * with an already acquired one in the same mm, or with the mm's
--       * page_table_lock already acquired, as that would break in the
--       * non-split case (where all these are actually resolving to the
--       * one page_table_lock). Thus acquiring all of them here is not
--       * going to result in dead locks, and the order of acquires
--       * doesn't matter.
+-      if (copy_from_user(&info, u_info, sizeof(info)))
+-              return -EFAULT;
+-      idx = info.entry_number;
+-
+-      /*
+-       * index -1 means the kernel should try to find and
+-       * allocate an empty descriptor:
 -       */
--      {
--              pgd_t *pgd = mm->pgd;
--              unsigned g;
+-      if (idx == -1) {
+-              idx = get_free_idx();
+-              if (idx < 0)
+-                      return idx;
+-              if (put_user(idx, &u_info->entry_number))
+-                      return -EFAULT;
+-      }
 -
--              for (g = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
--                      pud_t *pud;
--                      unsigned u;
+-      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+-              return -EINVAL;
 -
--                      if (pgd_none(*pgd))
--                              continue;
--                      pud = pud_offset(pgd, 0);
--                      for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
--                              pmd_t *pmd;
--                              unsigned m;
+-      desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
 -
--                              if (pud_none(*pud))
--                                      continue;
--                              pmd = pmd_offset(pud, 0);
--                              for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
--                                      spinlock_t *ptl;
+-      /*
+-       * We must not get preempted while modifying the TLS.
+-       */
+-      cpu = get_cpu();
 -
--                                      if (pmd_none(*pmd))
--                                              continue;
--                                      ptl = pte_lockptr(0, pmd);
--                                      if (lock)
--                                              spin_lock(ptl);
--                                      else
--                                              spin_unlock(ptl);
--                              }
--                      }
--              }
+-      if (LDT_empty(&info)) {
+-              desc->a = 0;
+-              desc->b = 0;
+-      } else {
+-              desc->a = LDT_entry_a(&info);
+-              desc->b = LDT_entry_b(&info);
 -      }
--#endif
--      if (!lock)
--              spin_unlock(&mm->page_table_lock);
+-      load_TLS(t, cpu);
+-
+-      put_cpu();
+-
+-      return 0;
 -}
--#define pin_lock(mm) _pin_lock(mm, 1)
--#define pin_unlock(mm) _pin_lock(mm, 0)
 -
--#define PIN_BATCH 8
--static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl);
+-/*
+- * Get the current Thread-Local Storage area:
+- */
 -
--static inline unsigned int pgd_walk_set_prot(void *pt, pgprot_t flags,
--                                           unsigned int cpu, unsigned int seq)
+-#define GET_BASE(desc) ( \
+-      (((desc)->a >> 16) & 0x0000ffff) | \
+-      (((desc)->b << 16) & 0x00ff0000) | \
+-      ( (desc)->b        & 0xff000000)   )
+-
+-#define GET_LIMIT(desc) ( \
+-      ((desc)->a & 0x0ffff) | \
+-       ((desc)->b & 0xf0000) )
+-      
+-#define GET_32BIT(desc)               (((desc)->b >> 22) & 1)
+-#define GET_CONTENTS(desc)    (((desc)->b >> 10) & 3)
+-#define GET_WRITABLE(desc)    (((desc)->b >>  9) & 1)
+-#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
+-#define GET_PRESENT(desc)     (((desc)->b >> 15) & 1)
+-#define GET_USEABLE(desc)     (((desc)->b >> 20) & 1)
+-
+-asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
 -{
--      struct page *page = virt_to_page(pt);
--      unsigned long pfn = page_to_pfn(page);
+-      struct user_desc info;
+-      struct desc_struct *desc;
+-      int idx;
 -
--      MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
--              (unsigned long)__va(pfn << PAGE_SHIFT),
--              pfn_pte(pfn, flags), 0);
--      if (unlikely(++seq == PIN_BATCH)) {
--              if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
--                                                      PIN_BATCH, NULL)))
--                      BUG();
--              seq = 0;
--      }
+-      if (get_user(idx, &u_info->entry_number))
+-              return -EFAULT;
+-      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+-              return -EINVAL;
 -
--      return seq;
+-      memset(&info, 0, sizeof(info));
+-
+-      desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
+-
+-      info.entry_number = idx;
+-      info.base_addr = GET_BASE(desc);
+-      info.limit = GET_LIMIT(desc);
+-      info.seg_32bit = GET_32BIT(desc);
+-      info.contents = GET_CONTENTS(desc);
+-      info.read_exec_only = !GET_WRITABLE(desc);
+-      info.limit_in_pages = GET_LIMIT_PAGES(desc);
+-      info.seg_not_present = !GET_PRESENT(desc);
+-      info.useable = GET_USEABLE(desc);
+-
+-      if (copy_to_user(u_info, &info, sizeof(info)))
+-              return -EFAULT;
+-      return 0;
 -}
 -
--static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
--{
--      pgd_t       *pgd = pgd_base;
--      pud_t       *pud;
--      pmd_t       *pmd;
--      pte_t       *pte;
--      int          g,u,m;
--      unsigned int cpu, seq;
--      multicall_entry_t *mcl;
+ unsigned long arch_align_stack(unsigned long sp)
+ {
+       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+               sp -= get_random_int() % 8192;
+       return sp & ~0xf;
+ }
++
++unsigned long arch_randomize_brk(struct mm_struct *mm)
++{
++      unsigned long range_end = mm->brk + 0x02000000;
++      return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
++}
+--- sle11-2009-05-14.orig/arch/x86/kernel/process_64-xen.c     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/process_64-xen.c  2009-03-16 16:33:40.000000000 +0100
+@@ -3,7 +3,7 @@
+  *
+  *  Pentium III FXSR, SSE support
+  *    Gareth Hughes <gareth@valinux.com>, May 2000
+- * 
++ *
+  *  X86-64 port
+  *    Andi Kleen.
+  *
+@@ -22,19 +22,18 @@
+ #include <linux/cpu.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
++#include <linux/fs.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+-#include <linux/fs.h>
+ #include <linux/elfcore.h>
+ #include <linux/smp.h>
+ #include <linux/slab.h>
+ #include <linux/user.h>
+-#include <linux/module.h>
+-#include <linux/a.out.h>
+ #include <linux/interrupt.h>
++#include <linux/utsname.h>
+ #include <linux/delay.h>
++#include <linux/module.h>
+ #include <linux/ptrace.h>
+-#include <linux/utsname.h>
+ #include <linux/random.h>
+ #include <linux/notifier.h>
+ #include <linux/kprobes.h>
+@@ -73,7 +72,6 @@ EXPORT_SYMBOL(boot_option_idle_override)
+  */
+ void (*pm_idle)(void);
+ EXPORT_SYMBOL(pm_idle);
+-static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
+ static ATOMIC_NOTIFIER_HEAD(idle_notifier);
+@@ -81,13 +79,6 @@ void idle_notifier_register(struct notif
+ {
+       atomic_notifier_chain_register(&idle_notifier, n);
+ }
+-EXPORT_SYMBOL_GPL(idle_notifier_register);
 -
--      cpu = get_cpu();
+-void idle_notifier_unregister(struct notifier_block *n)
+-{
+-      atomic_notifier_chain_unregister(&idle_notifier, n);
+-}
+-EXPORT_SYMBOL(idle_notifier_unregister);
+ void enter_idle(void)
+ {
+@@ -116,7 +107,7 @@ void exit_idle(void)
+  * to poll the ->need_resched flag instead of waiting for the
+  * cross-CPU IPI to arrive. Use this option with caution.
+  */
+-static void poll_idle (void)
++static void poll_idle(void)
+ {
+       local_irq_enable();
+       cpu_relax();
+@@ -131,10 +122,19 @@ static void xen_idle(void)
+        */
+       smp_mb();
+       local_irq_disable();
+-      if (!need_resched())
+-              safe_halt();
+-      else
+-              local_irq_enable();
++      if (!need_resched()) {
++              ktime_t t0, t1;
++              u64 t0n, t1n;
++
++              t0 = ktime_get();
++              t0n = ktime_to_ns(t0);
++              safe_halt();    /* enables interrupts racelessly */
++              local_irq_disable();
++              t1 = ktime_get();
++              t1n = ktime_to_ns(t1);
++              sched_clock_idle_wakeup_event(t1n - t0n);
++      }
++      local_irq_enable();
+       current_thread_info()->status |= TS_POLLING;
+ }
+@@ -161,19 +161,15 @@ static inline void play_dead(void)
+  * low exit latency (ie sit in a loop waiting for
+  * somebody to say that they'd like to reschedule)
+  */
+-void cpu_idle (void)
++void cpu_idle(void)
+ {
+       current_thread_info()->status |= TS_POLLING;
+       /* endless idle loop with no priority at all */
+       while (1) {
++              tick_nohz_stop_sched_tick();
+               while (!need_resched()) {
+                       void (*idle)(void);
+-                      if (__get_cpu_var(cpu_idle_state))
+-                              __get_cpu_var(cpu_idle_state) = 0;
 -
--      /*
--       * Cannot iterate up to USER_PTRS_PER_PGD as these pagetables may not
--       * be the 'current' task's pagetables (e.g., current may be 32-bit,
--       * but the pagetables may be for a 64-bit task).
--       * Subtracting 1 from TASK_SIZE64 means the loop limit is correct
--       * regardless of whether TASK_SIZE64 is a multiple of PGDIR_SIZE.
--       */
--      for (g = 0, seq = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
--              if (pgd_none(*pgd))
--                      continue;
--              pud = pud_offset(pgd, 0);
--              if (PTRS_PER_PUD > 1) /* not folded */ 
--                      seq = pgd_walk_set_prot(pud,flags,cpu,seq);
--              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
--                      if (pud_none(*pud))
--                              continue;
--                      pmd = pmd_offset(pud, 0);
--                      if (PTRS_PER_PMD > 1) /* not folded */ 
--                              seq = pgd_walk_set_prot(pmd,flags,cpu,seq);
--                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
--                              if (pmd_none(*pmd))
--                                      continue;
--                              pte = pte_offset_kernel(pmd,0);
--                              seq = pgd_walk_set_prot(pte,flags,cpu,seq);
--                      }
--              }
--      }
+-                      tick_nohz_stop_sched_tick();
 -
--      mcl = per_cpu(pb_mcl, cpu);
--      if (unlikely(seq > PIN_BATCH - 2)) {
--              if (unlikely(HYPERVISOR_multicall_check(mcl, seq, NULL)))
--                      BUG();
--              seq = 0;
--      }
--      MULTI_update_va_mapping(mcl + seq,
--             (unsigned long)__user_pgd(pgd_base),
--             pfn_pte(virt_to_phys(__user_pgd(pgd_base))>>PAGE_SHIFT, flags),
--             0);
--      MULTI_update_va_mapping(mcl + seq + 1,
--             (unsigned long)pgd_base,
--             pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
--             UVMF_TLB_FLUSH);
--      if (unlikely(HYPERVISOR_multicall_check(mcl, seq + 2, NULL)))
--              BUG();
+                       rmb();
+                       idle = xen_idle; /* no alternatives */
+                       if (cpu_is_offline(smp_processor_id()))
+@@ -203,49 +199,27 @@ static void do_nothing(void *unused)
+ {
+ }
++/*
++ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
++ * pm_idle and update to new pm_idle value. Required while changing pm_idle
++ * handler on SMP systems.
++ *
++ * Caller must have changed pm_idle to the new value before the call. Old
++ * pm_idle value will not be used by any CPU after the return of this function.
++ */
+ void cpu_idle_wait(void)
+ {
+-      unsigned int cpu, this_cpu = get_cpu();
+-      cpumask_t map, tmp = current->cpus_allowed;
 -
+-      set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
 -      put_cpu();
--}
--
--static void __pgd_pin(pgd_t *pgd)
--{
--      pgd_walk(pgd, PAGE_KERNEL_RO);
--      xen_pgd_pin(__pa(pgd)); /* kernel */
--      xen_pgd_pin(__pa(__user_pgd(pgd))); /* user */
--      SetPagePinned(virt_to_page(pgd));
--}
 -
--static void __pgd_unpin(pgd_t *pgd)
--{
--      xen_pgd_unpin(__pa(pgd));
--      xen_pgd_unpin(__pa(__user_pgd(pgd)));
--      pgd_walk(pgd, PAGE_KERNEL);
--      ClearPagePinned(virt_to_page(pgd));
--}
+-      cpus_clear(map);
+-      for_each_online_cpu(cpu) {
+-              per_cpu(cpu_idle_state, cpu) = 1;
+-              cpu_set(cpu, map);
+-      }
 -
--void pgd_test_and_unpin(pgd_t *pgd)
--{
--      if (PagePinned(virt_to_page(pgd)))
--              __pgd_unpin(pgd);
--}
+-      __get_cpu_var(cpu_idle_state) = 0;
 -
--void mm_pin(struct mm_struct *mm)
--{
--      if (xen_feature(XENFEAT_writable_page_tables))
--              return;
+-      wmb();
+-      do {
+-              ssleep(1);
+-              for_each_online_cpu(cpu) {
+-                      if (cpu_isset(cpu, map) &&
+-                                      !per_cpu(cpu_idle_state, cpu))
+-                              cpu_clear(cpu, map);
+-              }
+-              cpus_and(map, map, cpu_online_map);
+-              /*
+-               * We waited 1 sec, if a CPU still did not call idle
+-               * it may be because it is in idle and not waking up
+-               * because it has nothing to do.
+-               * Give all the remaining CPUS a kick.
+-               */
+-              smp_call_function_mask(map, do_nothing, 0, 0);
+-      } while (!cpus_empty(map));
 -
--      pin_lock(mm);
--      __pgd_pin(mm->pgd);
--      pin_unlock(mm);
--}
+-      set_cpus_allowed(current, tmp);
++      smp_mb();
++      /* kick all the CPUs so that they exit out of pm_idle */
++      smp_call_function(do_nothing, NULL, 0, 1);
+ }
+ EXPORT_SYMBOL_GPL(cpu_idle_wait);
+-void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 
++void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
+ {
+ }
+-static int __init idle_setup (char *str)
++static int __init idle_setup(char *str)
+ {
+       if (!strcmp(str, "poll")) {
+               printk("using polling idle threads.\n");
+@@ -260,13 +234,13 @@ static int __init idle_setup (char *str)
+ }
+ early_param("idle", idle_setup);
+-/* Prints also some state that isn't saved in the pt_regs */ 
++/* Prints also some state that isn't saved in the pt_regs */
+ void __show_regs(struct pt_regs * regs)
+ {
+       unsigned long fs, gs, shadowgs;
+       unsigned long d0, d1, d2, d3, d6, d7;
+-      unsigned int fsindex,gsindex;
+-      unsigned int ds,cs,es; 
++      unsigned int fsindex, gsindex;
++      unsigned int ds, cs, es;
+       printk("\n");
+       print_modules();
+@@ -275,16 +249,16 @@ void __show_regs(struct pt_regs * regs)
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
+-      printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
+-      printk_address(regs->rip); 
+-      printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
+-              regs->eflags);
++      printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
++      printk_address(regs->ip, 1);
++      printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->sp,
++              regs->flags);
+       printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+-             regs->rax, regs->rbx, regs->rcx);
++             regs->ax, regs->bx, regs->cx);
+       printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+-             regs->rdx, regs->rsi, regs->rdi); 
++             regs->dx, regs->si, regs->di);
+       printk("RBP: %016lx R08: %016lx R09: %016lx\n",
+-             regs->rbp, regs->r8, regs->r9); 
++             regs->bp, regs->r8, regs->r9);
+       printk("R10: %016lx R11: %016lx R12: %016lx\n",
+              regs->r10, regs->r11, regs->r12); 
+       printk("R13: %016lx R14: %016lx R15: %016lx\n",
+@@ -318,7 +292,7 @@ void show_regs(struct pt_regs *regs)
+ {
+       printk("CPU %d:", smp_processor_id());
+       __show_regs(regs);
+-      show_trace(NULL, regs, (void *)(regs + 1));
++      show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
+ }
+ /*
+@@ -329,7 +303,7 @@ void exit_thread(void)
+       struct task_struct *me = current;
+       struct thread_struct *t = &me->thread;
+-      if (me->thread.io_bitmap_ptr) { 
++      if (me->thread.io_bitmap_ptr) {
+ #ifndef CONFIG_X86_NO_TSS
+               struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
+ #endif
+@@ -382,7 +356,7 @@ void flush_thread(void)
+       tsk->thread.debugreg3 = 0;
+       tsk->thread.debugreg6 = 0;
+       tsk->thread.debugreg7 = 0;
+-      memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
++      memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
+       /*
+        * Forget coprocessor state..
+        */
+@@ -405,26 +379,21 @@ void release_thread(struct task_struct *
+ static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
+ {
+-      struct user_desc ud = { 
++      struct user_desc ud = {
+               .base_addr = addr,
+               .limit = 0xfffff,
+               .seg_32bit = 1,
+               .limit_in_pages = 1,
+               .useable = 1,
+       };
+-      struct n_desc_struct *desc = (void *)t->thread.tls_array;
++      struct desc_struct *desc = t->thread.tls_array;
+       desc += tls;
+-      desc->a = LDT_entry_a(&ud); 
+-      desc->b = LDT_entry_b(&ud); 
++      fill_ldt(desc, &ud);
+ }
+ static inline u32 read_32bit_tls(struct task_struct *t, int tls)
+ {
+-      struct desc_struct *desc = (void *)t->thread.tls_array;
+-      desc += tls;
+-      return desc->base0 | 
+-              (((u32)desc->base1) << 16) | 
+-              (((u32)desc->base2) << 24);
++      return get_desc_base(&t->thread.tls_array[tls]);
+ }
+ /*
+@@ -436,7 +405,7 @@ void prepare_to_copy(struct task_struct 
+       unlazy_fpu(tsk);
+ }
+-int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, 
++int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+               unsigned long unused,
+       struct task_struct * p, struct pt_regs * regs)
+ {
+@@ -448,14 +417,14 @@ int copy_thread(int nr, unsigned long cl
+                       (THREAD_SIZE + task_stack_page(p))) - 1;
+       *childregs = *regs;
+-      childregs->rax = 0;
+-      childregs->rsp = rsp;
+-      if (rsp == ~0UL)
+-              childregs->rsp = (unsigned long)childregs;
 -
--void mm_unpin(struct mm_struct *mm)
+-      p->thread.rsp = (unsigned long) childregs;
+-      p->thread.rsp0 = (unsigned long) (childregs+1);
+-      p->thread.userrsp = me->thread.userrsp; 
++      childregs->ax = 0;
++      childregs->sp = sp;
++      if (sp == ~0UL)
++              childregs->sp = (unsigned long)childregs;
++
++      p->thread.sp = (unsigned long) childregs;
++      p->thread.sp0 = (unsigned long) (childregs+1);
++      p->thread.usersp = me->thread.usersp;
+       set_tsk_thread_flag(p, TIF_FORK);
+@@ -476,7 +445,7 @@ int copy_thread(int nr, unsigned long cl
+               memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
+                               IO_BITMAP_BYTES);
+               set_tsk_thread_flag(p, TIF_IO_BITMAP);
+-      } 
++      }
+       /*
+        * Set a new TLS for the child thread?
+@@ -484,7 +453,8 @@ int copy_thread(int nr, unsigned long cl
+       if (clone_flags & CLONE_SETTLS) {
+ #ifdef CONFIG_IA32_EMULATION
+               if (test_thread_flag(TIF_IA32))
+-                      err = ia32_child_tls(p, childregs); 
++                      err = do_set_thread_area(p, -1,
++                              (struct user_desc __user *)childregs->si, 0);
+               else                    
+ #endif         
+                       err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 
+@@ -502,26 +472,32 @@ out:
+       return err;
+ }
+-static inline void __save_init_fpu( struct task_struct *tsk )
 -{
--      if (xen_feature(XENFEAT_writable_page_tables))
--              return;
--
--      pin_lock(mm);
--      __pgd_unpin(mm->pgd);
--      pin_unlock(mm);
+-      asm volatile( "rex64 ; fxsave %0 ; fnclex"
+-                    : "=m" (tsk->thread.i387.fxsave));
+-      tsk->thread_info->status &= ~TS_USEDFPU;
 -}
 -
--void mm_pin_all(void)
--{
--      struct page *page;
--      unsigned long flags;
--
--      if (xen_feature(XENFEAT_writable_page_tables))
--              return;
--
--      /*
--       * Allow uninterrupted access to the pgd_list. Also protects
--       * __pgd_pin() by disabling preemption.
--       * All other CPUs must be at a safe point (e.g., in stop_machine
--       * or offlined entirely).
--       */
--      spin_lock_irqsave(&pgd_lock, flags);
--      list_for_each_entry(page, &pgd_list, lru) {
--              if (!PagePinned(page))
--                      __pgd_pin((pgd_t *)page_address(page));
+ /*
+  * This special macro can be used to load a debugging register
+  */
+-#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r)
++#define loaddebug(thread, r) set_debugreg(thread->debugreg ## r, r)
+ static inline void __switch_to_xtra(struct task_struct *prev_p,
+-                                  struct task_struct *next_p)
++                                  struct task_struct *next_p)
+ {
+       struct thread_struct *prev, *next;
++      unsigned long debugctl;
+       prev = &prev_p->thread,
+       next = &next_p->thread;
++      debugctl = prev->debugctlmsr;
++      if (next->ds_area_msr != prev->ds_area_msr) {
++              /* we clear debugctl to make sure DS
++               * is not in use when we change it */
++              debugctl = 0;
++              wrmsrl(MSR_IA32_DEBUGCTLMSR, 0);
++              wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr);
++      }
++
++      if (next->debugctlmsr != debugctl)
++              wrmsrl(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr);
++
+       if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
+               loaddebug(next, 0);
+               loaddebug(next, 1);
+@@ -531,12 +507,20 @@ static inline void __switch_to_xtra(stru
+               loaddebug(next, 6);
+               loaddebug(next, 7);
+       }
++
++#ifdef X86_BTS
++      if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
++              ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
++
++      if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
++              ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
++#endif
+ }
+ /*
+  *    switch_to(x,y) should switch tasks from x to y.
+  *
+- * This could still be optimized: 
++ * This could still be optimized:
+  * - fold all the options into a flag word and test it with a single test.
+  * - could test fs/gs bitsliced
+  *
+@@ -547,7 +531,7 @@ __switch_to(struct task_struct *prev_p, 
+ {
+       struct thread_struct *prev = &prev_p->thread,
+                                *next = &next_p->thread;
+-      int cpu = smp_processor_id();  
++      int cpu = smp_processor_id();
+ #ifndef CONFIG_X86_NO_TSS
+       struct tss_struct *tss = &per_cpu(init_tss, cpu);
+ #endif
+@@ -581,11 +565,12 @@ __switch_to(struct task_struct *prev_p, 
+               prev_p->fpu_counter = 0;
+       /*
+-       * Reload esp0, LDT and the page table pointer:
++       * Reload sp0.
++       * This is load_sp0(tss, next) with a multicall.
+        */
+       mcl->op      = __HYPERVISOR_stack_switch;
+       mcl->args[0] = __KERNEL_DS;
+-      mcl->args[1] = next->rsp0;
++      mcl->args[1] = next->sp0;
+       mcl++;
+       /*
+@@ -593,11 +578,12 @@ __switch_to(struct task_struct *prev_p, 
+        * This is load_TLS(next, cpu) with multicalls.
+        */
+ #define C(i) do {                                                     \
+-      if (unlikely(next->tls_array[i] != prev->tls_array[i])) {       \
++      if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||    \
++                   next->tls_array[i].b != prev->tls_array[i].b)) {   \
+               mcl->op      = __HYPERVISOR_update_descriptor;          \
+               mcl->args[0] = virt_to_machine(                         \
+-                      &cpu_gdt(cpu)[GDT_ENTRY_TLS_MIN + i]);          \
+-              mcl->args[1] = next->tls_array[i];                      \
++                      &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\
++              mcl->args[1] = *(u64 *)&next->tls_array[i];             \
+               mcl++;                                                  \
+       }                                                               \
+ } while (0)
+@@ -605,7 +591,7 @@ __switch_to(struct task_struct *prev_p, 
+ #undef C
+       if (unlikely(prev->iopl != next->iopl)) {
+-              iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
++              iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
+ #if CONFIG_XEN_COMPAT > 0x030002
+               mcl->op      = __HYPERVISOR_physdev_op;
+               mcl->args[0] = PHYSDEVOP_set_iopl;
+@@ -669,8 +655,8 @@ __switch_to(struct task_struct *prev_p, 
+       /* 
+        * Switch the PDA context.
+        */
+-      prev->userrsp = read_pda(oldrsp); 
+-      write_pda(oldrsp, next->userrsp); 
++      prev->usersp = read_pda(oldrsp);
++      write_pda(oldrsp, next->usersp);
+       write_pda(pcurrent, next_p); 
+       write_pda(kernelstack,
+       (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
+@@ -687,7 +673,8 @@ __switch_to(struct task_struct *prev_p, 
+       /*
+        * Now maybe reload the debug registers
+        */
+-      if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW))
++      if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT ||
++                   task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
+               __switch_to_xtra(prev_p, next_p);
+       /* If the task has used fpu the last 5 timeslices, just do a full
+@@ -702,23 +689,18 @@ __switch_to(struct task_struct *prev_p, 
+ /*
+  * sys_execve() executes a new program.
+  */
+-asmlinkage 
++asmlinkage
+ long sys_execve(char __user *name, char __user * __user *argv,
+-              char __user * __user *envp, struct pt_regs regs)
++              char __user * __user *envp, struct pt_regs *regs)
+ {
+       long error;
+       char * filename;
+       filename = getname(name);
+       error = PTR_ERR(filename);
+-      if (IS_ERR(filename)) 
++      if (IS_ERR(filename))
+               return error;
+-      error = do_execve(filename, argv, envp, &regs); 
+-      if (error == 0) {
+-              task_lock(current);
+-              current->ptrace &= ~PT_DTRACE;
+-              task_unlock(current);
 -      }
--      spin_unlock_irqrestore(&pgd_lock, flags);
--}
++      error = do_execve(filename, argv, envp, regs);
+       putname(filename);
+       return error;
+ }
+@@ -728,18 +710,18 @@ void set_personality_64bit(void)
+       /* inherit personality from parent */
+       /* Make sure to be in 64bit mode */
+-      clear_thread_flag(TIF_IA32); 
++      clear_thread_flag(TIF_IA32);
+       /* TBD: overwrites user setup. Should have two bits.
+          But 64bit processes have always behaved this way,
+          so it's not too bad. The main problem is just that
+-         32bit childs are affected again. */
++         32bit childs are affected again. */
+       current->personality &= ~READ_IMPLIES_EXEC;
+ }
+ asmlinkage long sys_fork(struct pt_regs *regs)
+ {
+-      return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
++      return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+ }
+ asmlinkage long
+@@ -747,7 +729,7 @@ sys_clone(unsigned long clone_flags, uns
+         void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
+ {
+       if (!newsp)
+-              newsp = regs->rsp;
++              newsp = regs->sp;
+       return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+ }
+@@ -763,29 +745,29 @@ sys_clone(unsigned long clone_flags, uns
+  */
+ asmlinkage long sys_vfork(struct pt_regs *regs)
+ {
+-      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0,
++      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
+                   NULL, NULL);
+ }
+ unsigned long get_wchan(struct task_struct *p)
+ {
+       unsigned long stack;
+-      u64 fp,rip;
++      u64 fp,ip;
+       int count = 0;
+       if (!p || p == current || p->state==TASK_RUNNING)
+               return 0; 
+       stack = (unsigned long)task_stack_page(p);
+-      if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE)
++      if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
+               return 0;
+-      fp = *(u64 *)(p->thread.rsp);
++      fp = *(u64 *)(p->thread.sp);
+       do { 
+               if (fp < (unsigned long)stack ||
+                   fp > (unsigned long)stack+THREAD_SIZE)
+                       return 0; 
+-              rip = *(u64 *)(fp+8); 
+-              if (!in_sched_functions(rip))
+-                      return rip; 
++              ip = *(u64 *)(fp+8);
++              if (!in_sched_functions(ip))
++                      return ip;
+               fp = *(u64 *)fp; 
+       } while (count++ < 16); 
+       return 0;
+@@ -827,19 +809,19 @@ long do_arch_prctl(struct task_struct *t
+               /* Not strictly needed for fs, but do it for symmetry
+                  with gs */
+               if (addr >= TASK_SIZE_OF(task))
+-                      return -EPERM; 
++                      return -EPERM;
+               cpu = get_cpu();
+-              /* handle small bases via the GDT because that's faster to 
++              /* handle small bases via the GDT because that's faster to
+                  switch. */
+-              if (addr <= 0xffffffff) { 
++              if (addr <= 0xffffffff) {
+                       set_32bit_tls(task, FS_TLS, addr);
+-                      if (doit) { 
+-                              load_TLS(&task->thread, cpu); 
++                      if (doit) {
++                              load_TLS(&task->thread, cpu);
+                               asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
+                       }
+                       task->thread.fsindex = FS_TLS_SEL;
+                       task->thread.fs = 0;
+-              } else { 
++              } else {
+                       task->thread.fsindex = 0;
+                       task->thread.fs = addr;
+                       if (doit) {
+@@ -852,24 +834,24 @@ long do_arch_prctl(struct task_struct *t
+               }
+               put_cpu();
+               break;
+-      case ARCH_GET_FS: { 
+-              unsigned long base; 
++      case ARCH_GET_FS: {
++              unsigned long base;
+               if (task->thread.fsindex == FS_TLS_SEL)
+                       base = read_32bit_tls(task, FS_TLS);
+               else if (doit)
+                       rdmsrl(MSR_FS_BASE, base);
+               else
+                       base = task->thread.fs;
+-              ret = put_user(base, (unsigned long __user *)addr); 
+-              break; 
++              ret = put_user(base, (unsigned long __user *)addr);
++              break;
+       }
+-      case ARCH_GET_GS: { 
++      case ARCH_GET_GS: {
+               unsigned long base;
+               unsigned gsindex;
+               if (task->thread.gsindex == GS_TLS_SEL)
+                       base = read_32bit_tls(task, GS_TLS);
+               else if (doit) {
+-                      asm("movl %%gs,%0" : "=r" (gsindex));
++                      asm("movl %%gs,%0" : "=r" (gsindex));
+                       if (gsindex)
+                               rdmsrl(MSR_KERNEL_GS_BASE, base);
+                       else
+@@ -877,40 +859,21 @@ long do_arch_prctl(struct task_struct *t
+               }
+               else
+                       base = task->thread.gs;
+-              ret = put_user(base, (unsigned long __user *)addr); 
++              ret = put_user(base, (unsigned long __user *)addr);
+               break;
+       }
+       default:
+               ret = -EINVAL;
+               break;
+-      } 
++      }
+-      return ret;     
+-} 
++      return ret;
++}
+ long sys_arch_prctl(int code, unsigned long addr)
+ {
+       return do_arch_prctl(current, code, addr);
+-} 
 -
--void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
+-/* 
+- * Capture the user space registers if the task is not running (in user space)
+- */
+-int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
 -{
--      if (!PagePinned(virt_to_page(mm->pgd)))
--              mm_pin(mm);
--}
+-      struct pt_regs *pp, ptregs;
 -
--void arch_exit_mmap(struct mm_struct *mm)
--{
--      struct task_struct *tsk = current;
+-      pp = task_pt_regs(tsk);
 -
--      task_lock(tsk);
+-      ptregs = *pp; 
+-      ptregs.cs &= 0xffff;
+-      ptregs.ss &= 0xffff;
 -
--      /*
--       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
--       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
--       */
--      if (tsk->active_mm == mm) {
--              tsk->active_mm = &init_mm;
--              atomic_inc(&init_mm.mm_count);
+-      elf_core_copy_regs(regs, &ptregs);
+- 
+-        boot_option_idle_override = 1;
+-      return 1;
+ }
+ unsigned long arch_align_stack(unsigned long sp)
+@@ -919,3 +882,9 @@ unsigned long arch_align_stack(unsigned 
+               sp -= get_random_int() % 8192;
+       return sp & ~0xf;
+ }
++
++unsigned long arch_randomize_brk(struct mm_struct *mm)
++{
++      unsigned long range_end = mm->brk + 0x02000000;
++      return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
++}
+--- sle11-2009-05-14.orig/arch/x86/kernel/quirks-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/quirks-xen.c      2009-03-16 16:33:40.000000000 +0100
+@@ -9,7 +9,7 @@
+ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
+ {
+       u8 config, rev;
+-      u32 word;
++      u16 word;
+       /* BIOS may enable hardware IRQ balancing for
+        * E7520/E7320/E7525(revision ID 0x9 and below)
+@@ -24,14 +24,17 @@ static void __devinit quirk_intel_irqbal
+       pci_read_config_byte(dev, 0xf4, &config);
+       pci_write_config_byte(dev, 0xf4, config|0x2);
+-      /* read xTPR register */
+-      raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
++      /*
++       * read xTPR register.  We may not have a pci_dev for device 8
++       * because it might be hidden until the above write.
++       */
++      pci_bus_read_config_word(dev->bus, PCI_DEVFN(8, 0), 0x4c, &word);
+       if (!(word & (1 << 13))) {
+               struct xen_platform_op op;
+-              printk(KERN_INFO "Intel E7520/7320/7525 detected. "
+-                      "Disabling irq balancing and affinity\n");
++              dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
++                      "disabling irq balancing and affinity\n");
+               op.cmd = XENPF_platform_quirk;
+               op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING;
+               WARN_ON(HYPERVISOR_platform_op(&op));
+@@ -102,14 +105,16 @@ static void ich_force_enable_hpet(struct
+       pci_read_config_dword(dev, 0xF0, &rcba);
+       rcba &= 0xFFFFC000;
+       if (rcba == 0) {
+-              printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n");
++              dev_printk(KERN_DEBUG, &dev->dev, "RCBA disabled; "
++                      "cannot force enable HPET\n");
+               return;
+       }
+       /* use bits 31:14, 16 kB aligned */
+       rcba_base = ioremap_nocache(rcba, 0x4000);
+       if (rcba_base == NULL) {
+-              printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n");
++              dev_printk(KERN_DEBUG, &dev->dev, "ioremap failed; "
++                      "cannot force enable HPET\n");
+               return;
+       }
+@@ -120,8 +125,8 @@ static void ich_force_enable_hpet(struct
+               /* HPET is enabled in HPTC. Just not reported by BIOS */
+               val = val & 0x3;
+               force_hpet_address = 0xFED00000 | (val << 12);
+-              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+-                             force_hpet_address);
++              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
++                      "0x%lx\n", force_hpet_address);
+               iounmap(rcba_base);
+               return;
+       }
+@@ -140,11 +145,12 @@ static void ich_force_enable_hpet(struct
+       if (err) {
+               force_hpet_address = 0;
+               iounmap(rcba_base);
+-              printk(KERN_DEBUG "Failed to force enable HPET\n");
++              dev_printk(KERN_DEBUG, &dev->dev,
++                      "Failed to force enable HPET\n");
+       } else {
+               force_hpet_resume_type = ICH_FORCE_HPET_RESUME;
+-              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+-                             force_hpet_address);
++              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
++                      "0x%lx\n", force_hpet_address);
+       }
+ }
+@@ -160,6 +166,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
+                        ich_force_enable_hpet);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
+                        ich_force_enable_hpet);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7,
++                       ich_force_enable_hpet);
+ static struct pci_dev *cached_dev;
+@@ -204,8 +212,8 @@ static void old_ich_force_enable_hpet(st
+       if (val & 0x4) {
+               val &= 0x3;
+               force_hpet_address = 0xFED00000 | (val << 12);
+-              printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+-                             force_hpet_address);
++              dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
++                      force_hpet_address);
+               return;
+       }
+@@ -225,14 +233,14 @@ static void old_ich_force_enable_hpet(st
+               /* HPET is enabled in HPTC. Just not reported by BIOS */
+               val &= 0x3;
+               force_hpet_address = 0xFED00000 | (val << 12);
+-              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+-                             force_hpet_address);
++              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
++                      "0x%lx\n", force_hpet_address);
+               cached_dev = dev;
+               force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME;
+               return;
+       }
+-      printk(KERN_DEBUG "Failed to force enable HPET\n");
++      dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n");
+ }
+ /*
+@@ -290,8 +298,8 @@ static void vt8237_force_enable_hpet(str
+        */
+       if (val & 0x80) {
+               force_hpet_address = (val & ~0x3ff);
+-              printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+-                             force_hpet_address);
++              dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
++                      force_hpet_address);
+               return;
+       }
+@@ -305,14 +313,14 @@ static void vt8237_force_enable_hpet(str
+       pci_read_config_dword(dev, 0x68, &val);
+       if (val & 0x80) {
+               force_hpet_address = (val & ~0x3ff);
+-              printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+-                             force_hpet_address);
++              dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
++                      "0x%lx\n", force_hpet_address);
+               cached_dev = dev;
+               force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
+               return;
+       }
+-      printk(KERN_DEBUG "Failed to force enable HPET\n");
++      dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n");
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
+@@ -340,7 +348,7 @@ static void nvidia_force_enable_hpet(str
+       pci_read_config_dword(dev, 0x44, &val);
+       force_hpet_address = val & 0xfffffffe;
+       force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME;
+-      printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
++      dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n",
+               force_hpet_address);
+       cached_dev = dev;
+       return;
+@@ -353,6 +361,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_N
+                       nvidia_force_enable_hpet);
+ /* LPC bridges */
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0260,
++                      nvidia_force_enable_hpet);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0360,
+                       nvidia_force_enable_hpet);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0361,
+@@ -373,19 +383,19 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_N
+ void force_hpet_resume(void)
+ {
+       switch (force_hpet_resume_type) {
+-          case ICH_FORCE_HPET_RESUME:
+-              return ich_force_hpet_resume();
 -
--              switch_mm(mm, &init_mm, tsk);
+-          case OLD_ICH_FORCE_HPET_RESUME:
+-              return old_ich_force_hpet_resume();
 -
--              atomic_dec(&mm->mm_count);
--              BUG_ON(atomic_read(&mm->mm_count) == 0);
--      }
+-          case VT8237_FORCE_HPET_RESUME:
+-              return vt8237_force_hpet_resume();
 -
--      task_unlock(tsk);
+-          case NVIDIA_FORCE_HPET_RESUME:
+-              return nvidia_force_hpet_resume();
 -
--      if (PagePinned(virt_to_page(mm->pgd))
--          && (atomic_read(&mm->mm_count) == 1)
--          && !mm->context.has_foreign_mappings)
--              mm_unpin(mm);
--}
+-          default:
++      case ICH_FORCE_HPET_RESUME:
++              ich_force_hpet_resume();
++              return;
++      case OLD_ICH_FORCE_HPET_RESUME:
++              old_ich_force_hpet_resume();
++              return;
++      case VT8237_FORCE_HPET_RESUME:
++              vt8237_force_hpet_resume();
++              return;
++      case NVIDIA_FORCE_HPET_RESUME:
++              nvidia_force_hpet_resume();
++              return;
++      default:
+               break;
+       }
+ }
+--- sle11-2009-05-14.orig/arch/x86/kernel/rtc.c        2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/arch/x86/kernel/rtc.c     2009-03-16 16:33:40.000000000 +0100
+@@ -181,6 +181,10 @@ unsigned long read_persistent_clock(void
+ {
+       unsigned long retval, flags;
++#ifdef CONFIG_XEN
++      if (!is_initial_xendomain())
++              return xen_read_persistent_clock();
++#endif
+       spin_lock_irqsave(&rtc_lock, flags);
+       retval = get_wallclock();
+       spin_unlock_irqrestore(&rtc_lock, flags);
+@@ -190,6 +194,10 @@ unsigned long read_persistent_clock(void
+ int update_persistent_clock(struct timespec now)
+ {
++#ifdef CONFIG_XEN
++      if (xen_update_persistent_clock() < 0 || xen_independent_wallclock())
++              return 0;
++#endif
+       return set_rtc_mmss(now.tv_sec);
+ }
+--- sle11-2009-05-14.orig/arch/x86/kernel/setup64-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/setup64-xen.c     2009-03-16 16:33:40.000000000 +0100
+@@ -31,7 +31,11 @@
+ #include <asm/hypervisor.h>
+ #endif
++#ifndef CONFIG_DEBUG_BOOT_PARAMS
+ struct boot_params __initdata boot_params;
++#else
++struct boot_params boot_params;
++#endif
+ cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
+@@ -47,6 +51,7 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
+ unsigned long __supported_pte_mask __read_mostly = ~0UL;
+ EXPORT_SYMBOL(__supported_pte_mask);
++
+ static int do_not_nx __cpuinitdata = 0;
+ /* noexec=on|off
+@@ -90,6 +95,45 @@ static int __init nonx32_setup(char *str
+ __setup("noexec32=", nonx32_setup);
+ /*
++ * Copy data used in early init routines from the initial arrays to the
++ * per cpu data areas.  These arrays then become expendable and the
++ * *_early_ptr's are zeroed indicating that the static arrays are gone.
++ */
++static void __init setup_per_cpu_maps(void)
++{
++#ifndef CONFIG_XEN
++      int cpu;
++
++      for_each_possible_cpu(cpu) {
++#ifdef CONFIG_SMP
++              if (per_cpu_offset(cpu)) {
++#endif
++                      per_cpu(x86_cpu_to_apicid, cpu) =
++                                              x86_cpu_to_apicid_init[cpu];
++                      per_cpu(x86_bios_cpu_apicid, cpu) =
++                                              x86_bios_cpu_apicid_init[cpu];
++#ifdef CONFIG_NUMA
++                      per_cpu(x86_cpu_to_node_map, cpu) =
++                                              x86_cpu_to_node_map_init[cpu];
++#endif
++#ifdef CONFIG_SMP
++              }
++              else
++                      printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n",
++                                                                      cpu);
++#endif
++      }
++
++      /* indicate the early static arrays will soon be gone */
++      x86_cpu_to_apicid_early_ptr = NULL;
++      x86_bios_cpu_apicid_early_ptr = NULL;
++#ifdef CONFIG_NUMA
++      x86_cpu_to_node_map_early_ptr = NULL;
++#endif
++#endif
++}
++
++/*
+  * Great future plan:
+  * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
+  * Always point %gs to its beginning
+@@ -109,19 +153,24 @@ void __init setup_per_cpu_areas(void)
+       printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size);
+       for_each_cpu_mask (i, cpu_possible_map) {
+               char *ptr;
++#ifndef CONFIG_NEED_MULTIPLE_NODES
++              ptr = alloc_bootmem_pages(size);
++#else
++              int node = early_cpu_to_node(i);
+-              if (!NODE_DATA(cpu_to_node(i))) {
+-                      printk("cpu with no node %d, num_online_nodes %d\n",
+-                             i, num_online_nodes());
++              if (!node_online(node) || !NODE_DATA(node))
+                       ptr = alloc_bootmem_pages(size);
+-              } else { 
+-                      ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size);
+-              }
++              else
++                      ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
++#endif
+               if (!ptr)
+                       panic("Cannot allocate cpu data for CPU %d\n", i);
+               cpu_pda(i)->data_offset = ptr - __per_cpu_start;
+               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+       }
++
++      /* setup percpu data maps early */
++      setup_per_cpu_maps();
+ } 
+ #ifdef CONFIG_XEN
+@@ -224,7 +273,8 @@ void syscall_init(void)
+       wrmsrl(MSR_CSTAR, ignore_sysret);
+       /* Flags to clear on syscall */
+-      wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 
++      wrmsrl(MSR_SYSCALL_MASK,
++             X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL);
+ #endif
+ #ifdef CONFIG_IA32_EMULATION                  
+       syscall32_cpu_init ();
+@@ -303,7 +353,7 @@ void __cpuinit cpu_init (void)
+        */
+ #ifndef CONFIG_XEN 
+       if (cpu)
+-              memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
++              memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
+ #endif
+       cpu_gdt_descr[cpu].size = GDT_SIZE;
+@@ -334,10 +384,10 @@ void __cpuinit cpu_init (void)
+                                     v, cpu); 
+               }
+               estacks += PAGE_SIZE << order[v];
+-              orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks;
++              orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks;
+       }
+-      t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
++      t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
+       /*
+        * <= is required because the CPU will access up to
+        * 8 bits beyond the end of the IO permission bitmap.
+--- sle11-2009-05-14.orig/arch/x86/kernel/setup_32-xen.c       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/setup_32-xen.c    2009-03-16 16:33:40.000000000 +0100
+@@ -47,9 +47,12 @@
+ #include <linux/crash_dump.h>
+ #include <linux/dmi.h>
+ #include <linux/pfn.h>
++#include <linux/pci.h>
++#include <linux/init_ohci1394_dma.h>
+ #include <video/edid.h>
++#include <asm/mtrr.h>
+ #include <asm/apic.h>
+ #include <asm/e820.h>
+ #include <asm/mpspec.h>
+@@ -79,14 +82,83 @@ static struct notifier_block xen_panic_b
+       xen_panic_event, NULL, 0 /* try to go last */
+ };
+-int disable_pse __cpuinitdata = 0;
 -
--static void _pte_free(struct page *page, unsigned int order)
--{
--      BUG_ON(order);
--      pte_free(page);
--}
+ /*
+  * Machine setup..
+  */
+-extern struct resource code_resource;
+-extern struct resource data_resource;
+-extern struct resource bss_resource;
++static struct resource data_resource = {
++      .name   = "Kernel data",
++      .start  = 0,
++      .end    = 0,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++static struct resource code_resource = {
++      .name   = "Kernel code",
++      .start  = 0,
++      .end    = 0,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++static struct resource bss_resource = {
++      .name   = "Kernel bss",
++      .start  = 0,
++      .end    = 0,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++static struct resource video_ram_resource = {
++      .name   = "Video RAM area",
++      .start  = 0xa0000,
++      .end    = 0xbffff,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++static struct resource standard_io_resources[] = { {
++      .name   = "dma1",
++      .start  = 0x0000,
++      .end    = 0x001f,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "pic1",
++      .start  = 0x0020,
++      .end    = 0x0021,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "timer0",
++      .start  = 0x0040,
++      .end    = 0x0043,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "timer1",
++      .start  = 0x0050,
++      .end    = 0x0053,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "keyboard",
++      .start  = 0x0060,
++      .end    = 0x006f,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "dma page reg",
++      .start  = 0x0080,
++      .end    = 0x008f,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "pic2",
++      .start  = 0x00a0,
++      .end    = 0x00a1,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "dma2",
++      .start  = 0x00c0,
++      .end    = 0x00df,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++}, {
++      .name   = "fpu",
++      .start  = 0x00f0,
++      .end    = 0x00ff,
++      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
++} };
+ /* cpu data as detected by the assembly code in head.S */
+ struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+@@ -94,13 +166,16 @@ struct cpuinfo_x86 new_cpu_data __cpuini
+ struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+ EXPORT_SYMBOL(boot_cpu_data);
++#ifndef CONFIG_X86_PAE
+ unsigned long mmu_cr4_features;
++#else
++unsigned long mmu_cr4_features = X86_CR4_PAE;
++#endif
+ /* for MCA, but anyone else can use it if they want */
+ unsigned int machine_id;
+ unsigned int machine_submodel_id;
+ unsigned int BIOS_revision;
+-unsigned int mca_pentium_flag;
+ /* Boot loader ID as an integer, for the benefit of proc_dointvec */
+ int bootloader_type;
+@@ -131,13 +206,17 @@ extern int root_mountflags;
+ unsigned long saved_videomode;
+-#define RAMDISK_IMAGE_START_MASK      0x07FF
++#define RAMDISK_IMAGE_START_MASK      0x07FF
+ #define RAMDISK_PROMPT_FLAG           0x8000
+-#define RAMDISK_LOAD_FLAG             0x4000  
++#define RAMDISK_LOAD_FLAG             0x4000
+ static char __initdata command_line[COMMAND_LINE_SIZE];
++#ifndef CONFIG_DEBUG_BOOT_PARAMS
+ struct boot_params __initdata boot_params;
++#else
++struct boot_params boot_params;
++#endif
+ /*
+  * Point at the empty zero page to start with. We map the real shared_info
+@@ -198,8 +277,7 @@ static int __init parse_mem(char *arg)
+               return -EINVAL;
+       if (strcmp(arg, "nopentium") == 0) {
+-              clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
+-              disable_pse = 1;
++              setup_clear_cpu_cap(X86_FEATURE_PSE);
+       } else {
+               /* If the user specifies memory size, we
+                * limit the BIOS-provided memory map to
+@@ -208,7 +286,7 @@ static int __init parse_mem(char *arg)
+                * trim the existing memory map.
+                */
+               unsigned long long mem_size;
+- 
++
+               mem_size = memparse(arg, &arg);
+               limit_regions(mem_size);
+               user_defined_memmap = 1;
+@@ -350,7 +428,7 @@ static void __init reserve_ebda_region(v
+       unsigned int addr;
+       addr = get_bios_ebda();
+       if (addr)
+-              reserve_bootmem(addr, PAGE_SIZE);       
++              reserve_bootmem(addr, PAGE_SIZE, BOOTMEM_DEFAULT);
+ }
+ #endif
+@@ -365,8 +443,6 @@ static unsigned long __init setup_memory
+       min_low_pfn = PFN_UP(__pa(xen_start_info->pt_base)) +
+               xen_start_info->nr_pt_frames;
+-      find_max_pfn();
 -
--struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
--{
--      struct page *pte;
+       max_low_pfn = find_max_low_pfn();
+ #ifdef CONFIG_HIGHMEM
+@@ -447,7 +523,8 @@ static void __init reserve_crashkernel(v
+                                       (unsigned long)(total_mem >> 20));
+                       crashk_res.start = crash_base;
+                       crashk_res.end   = crash_base + crash_size - 1;
+-                      reserve_bootmem(crash_base, crash_size);
++                      reserve_bootmem(crash_base, crash_size,
++                                      BOOTMEM_DEFAULT);
+               } else
+                       printk(KERN_INFO "crashkernel reservation failed - "
+                                       "you have to specify a base address\n");
+@@ -461,6 +538,99 @@ static inline void __init reserve_crashk
+ {}
+ #endif
++#ifdef CONFIG_BLK_DEV_INITRD
++
++static bool do_relocate_initrd = false;
++
++static void __init reserve_initrd(void)
++{
++      unsigned long ramdisk_image = __pa(xen_start_info->mod_start);
++      unsigned long ramdisk_size  = xen_start_info->mod_len;
++      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;
++
++      if (!xen_start_info->mod_start || !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;
++      }
++      if (ramdisk_size >= end_of_lowmem/2) {
++              printk(KERN_ERR "initrd too large to handle, "
++                     "disabling initrd\n");
++              return;
++      }
++      if (ramdisk_end <= end_of_lowmem) {
++              /* All in lowmem, easy case */
++              reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT);
++              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;
++
++      /* 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);
++      initrd_start = ramdisk_here + PAGE_OFFSET;
++      initrd_end   = initrd_start + ramdisk_size;
++
++      do_relocate_initrd = true;
++}
++
++#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
++
++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;
++      unsigned long slop, clen, mapaddr;
++      char *p, *q;
++
++      if (!do_relocate_initrd)
++              return;
++
++      ramdisk_here = initrd_start - PAGE_OFFSET;
++
++      q = (char *)initrd_start;
++
++      /* Copy any lowmem portion of the initrd */
++      if (ramdisk_image < end_of_lowmem) {
++              clen = end_of_lowmem - ramdisk_image;
++              p = (char *)__va(ramdisk_image);
++              memcpy(q, p, clen);
++              q += clen;
++              ramdisk_image += clen;
++              ramdisk_size  -= clen;
++      }
++
++      /* Copy the highmem portion of the initrd */
++      while (ramdisk_size) {
++              slop = ramdisk_image & ~PAGE_MASK;
++              clen = ramdisk_size;
++              if (clen > MAX_MAP_CHUNK-slop)
++                      clen = MAX_MAP_CHUNK-slop;
++              mapaddr = ramdisk_image & PAGE_MASK;
++              p = early_ioremap(mapaddr, clen+slop);
++              memcpy(q, p+slop, clen);
++              early_iounmap(p, clen+slop);
++              q += clen;
++              ramdisk_image += clen;
++              ramdisk_size  -= clen;
++      }
++}
++
++#endif /* CONFIG_BLK_DEV_INITRD */
++
+ void __init setup_bootmem_allocator(void)
+ {
+       unsigned long bootmap_size;
+@@ -478,14 +648,15 @@ void __init setup_bootmem_allocator(void
+        * 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));
++                       bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
++                       BOOTMEM_DEFAULT);
+ #ifndef CONFIG_XEN
+       /*
+        * 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);
++      reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
+       /* reserve EBDA region, it's a 4K region */
+       reserve_ebda_region();
+@@ -495,7 +666,7 @@ void __init setup_bootmem_allocator(void
+        unless you have no PS/2 mouse plugged in. */
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+           boot_cpu_data.x86 == 6)
+-           reserve_bootmem(0xa0000 - 4096, 4096);
++           reserve_bootmem(0xa0000 - 4096, 4096, BOOTMEM_DEFAULT);
+ #ifdef CONFIG_SMP
+       /*
+@@ -503,7 +674,7 @@ void __init setup_bootmem_allocator(void
+        * 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);
++      reserve_bootmem(PAGE_SIZE, PAGE_SIZE, BOOTMEM_DEFAULT);
+ #endif
+ #ifdef CONFIG_ACPI_SLEEP
+       /*
+@@ -511,29 +682,12 @@ void __init setup_bootmem_allocator(void
+        */
+       acpi_reserve_bootmem();
+ #endif
+-      numa_kva_reserve();
+ #endif /* !CONFIG_XEN */
+ #ifdef CONFIG_BLK_DEV_INITRD
+-      if (xen_start_info->mod_start) {
+-              unsigned long ramdisk_image = __pa(xen_start_info->mod_start);
+-              unsigned long ramdisk_size  = xen_start_info->mod_len;
+-              unsigned long ramdisk_end   = ramdisk_image + ramdisk_size;
+-              unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
 -
--      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
--      if (pte) {
--              SetPageForeign(pte, _pte_free);
--              init_page_count(pte);
+-              if (ramdisk_end <= end_of_lowmem) {
+-                      /*reserve_bootmem(ramdisk_image, ramdisk_size);*/
+-                      initrd_start = ramdisk_image + PAGE_OFFSET;
+-                      initrd_end = initrd_start+ramdisk_size;
+-                      initrd_below_start_ok = 1;
+-              } else {
+-                      printk(KERN_ERR "initrd extends beyond end of memory "
+-                             "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+-                             ramdisk_end, end_of_lowmem);
+-                      initrd_start = 0;
+-              }
 -      }
--      return pte;
--}
--
--void pte_free(struct page *pte)
--{
--      unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
--
--      if (!pte_write(*virt_to_ptep(va)))
--              if (HYPERVISOR_update_va_mapping(
--                      va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0))
--                      BUG();
--
--      ClearPageForeign(pte);
--      init_page_count(pte);
--
--      __free_page(pte);
--}
--#endif        /* CONFIG_XEN */
--
--pte_t *lookup_address(unsigned long address) 
--{ 
--      pgd_t *pgd = pgd_offset_k(address);
--      pud_t *pud;
--      pmd_t *pmd;
--      pte_t *pte;
--      if (pgd_none(*pgd))
--              return NULL;
--      pud = pud_offset(pgd, address);
--      if (!pud_present(*pud))
--              return NULL; 
--      pmd = pmd_offset(pud, address);
--      if (!pmd_present(*pmd))
--              return NULL; 
--      if (pmd_large(*pmd))
--              return (pte_t *)pmd;
--      pte = pte_offset_kernel(pmd, address);
--      if (pte && !pte_present(*pte))
--              pte = NULL; 
--      return pte;
--} 
--
--static struct page *split_large_page(unsigned long address, pgprot_t prot,
--                                   pgprot_t ref_prot)
--{ 
--      int i; 
--      unsigned long addr;
--      struct page *base = alloc_pages(GFP_KERNEL, 0);
--      pte_t *pbase;
--      if (!base) 
--              return NULL;
++      reserve_initrd();
+ #endif
++      numa_kva_reserve();
+       reserve_crashkernel();
+ }
+@@ -600,20 +754,14 @@ void __init setup_arch(char **cmdline_p)
+       memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
+       pre_setup_arch_hook();
+       early_cpu_init();
++      early_ioremap_init();
+ #ifdef CONFIG_SMP
+       prefill_possible_map();
+ #endif
 -      /*
--       * page_private is used to track the number of entries in
--       * the page table page have non standard attributes.
+-       * FIXME: This isn't an official loader_type right
+-       * now but does currently work with elilo.
+-       * If we were configured as an EFI kernel, check to make
+-       * sure that we were loaded correctly from elilo and that
+-       * the system table is valid.  If not, then initialize normally.
 -       */
--      SetPagePrivate(base);
--      page_private(base) = 0;
--
--      address = __pa(address);
--      addr = address & LARGE_PAGE_MASK; 
--      pbase = (pte_t *)page_address(base);
--      for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
--              pbase[i] = pfn_pte(addr >> PAGE_SHIFT, 
--                                 addr == address ? prot : ref_prot);
--      }
--      return base;
--} 
--
--void clflush_cache_range(void *adr, int size)
--{
--      int i;
--      for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
--              clflush(adr+i);
--}
--
--static void flush_kernel_map(void *arg)
--{
--      struct list_head *l = (struct list_head *)arg;
--      struct page *pg;
--
--      /* When clflush is available always use it because it is
--         much cheaper than WBINVD. */
--      /* clflush is still broken. Disable for now. */
--      if (1 || !cpu_has_clflush)
--              asm volatile("wbinvd" ::: "memory");
--      else list_for_each_entry(pg, l, lru) {
--              void *adr = page_address(pg);
--              clflush_cache_range(adr, PAGE_SIZE);
--      }
--      __flush_tlb_all();
--}
--
--static inline void flush_map(struct list_head *l)
--{     
--      on_each_cpu(flush_kernel_map, l, 1, 1);
--}
--
--static LIST_HEAD(deferred_pages); /* protected by init_mm.mmap_sem */
--
--static inline void save_page(struct page *fpage)
--{
--      if (!test_and_set_bit(PG_arch_1, &fpage->flags))
--              list_add(&fpage->lru, &deferred_pages);
--}
--
+ #ifdef CONFIG_EFI
+-      if ((boot_params.hdr.type_of_loader == 0x50) &&
+-          boot_params.efi_info.efi_systab)
++      if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
++                   "EL32", 4))
+               efi_enabled = 1;
+ #endif
+@@ -653,12 +801,9 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+       ARCH_SETUP
+-      if (efi_enabled)
+-              efi_init();
+-      else {
+-              printk(KERN_INFO "BIOS-provided physical RAM map:\n");
+-              print_memory_map(memory_setup());
+-      }
++
++      printk(KERN_INFO "BIOS-provided physical RAM map:\n");
++      print_memory_map(memory_setup());
+       copy_edd();
+@@ -691,6 +836,17 @@ void __init setup_arch(char **cmdline_p)
+       strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+       *cmdline_p = command_line;
++      if (efi_enabled)
++              efi_init();
++
++      /* update e820 for memory not covered by WB MTRRs */
++      find_max_pfn();
++      mtrr_bp_init();
++#ifndef CONFIG_XEN
++      if (mtrr_trim_uncached_memory(max_pfn))
++              find_max_pfn();
++#endif
++
+       max_low_pfn = setup_memory();
+ #ifdef CONFIG_VMI
+@@ -715,6 +871,16 @@ void __init setup_arch(char **cmdline_p)
+       smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+ #endif
+       paging_init();
++
++      /*
++       * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
++       */
++
++#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
++      if (init_ohci1394_dma_early)
++              init_ohci1394_dma_on_all_controllers();
++#endif
++
+       remapped_pgdat_init();
+       sparse_init();
+       zone_sizes_init();
+@@ -800,16 +966,20 @@ void __init setup_arch(char **cmdline_p)
+        * NOTE: at this point the bootmem allocator is fully available.
+        */
++#ifdef CONFIG_BLK_DEV_INITRD
++      relocate_initrd();
++#endif
++
+       paravirt_post_allocator_init();
+       if (is_initial_xendomain())
+               dmi_scan_machine();
++      io_delay_init();
++
+ #ifdef CONFIG_X86_GENERICARCH
+       generic_apic_probe();
+-#endif        
+-      if (efi_enabled)
+-              efi_map_memmap();
++#endif
+       set_iopl.iopl = 1;
+       WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl));
+@@ -827,7 +997,7 @@ void __init setup_arch(char **cmdline_p)
+       acpi_boot_table_init();
+ #endif
+-#if defined(CONFIG_PCI) && !defined(CONFIG_XEN)
++#ifndef CONFIG_XEN
+       early_quirks();
+ #endif
+@@ -873,3 +1043,30 @@ xen_panic_event(struct notifier_block *t
+       /* we're never actually going to get here... */
+       return NOTIFY_DONE;
+ }
++
++/*
++ * Request address space for all standard resources
++ *
++ * This is called just before pcibios_init(), which is also a
++ * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
++ */
++static int __init request_standard_resources(void)
++{
++      int i;
++
++      /* Nothing to do if not running in dom0. */
++      if (!is_initial_xendomain())
++              return 0;
++
++      printk(KERN_INFO "Setting up standard PCI resources\n");
++      init_iomem_resources(&code_resource, &data_resource, &bss_resource);
++
++      request_resource(&iomem_resource, &video_ram_resource);
++
++      /* request I/O space for devices used on all i[345]86 PCs */
++      for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
++              request_resource(&ioport_resource, &standard_io_resources[i]);
++      return 0;
++}
++
++subsys_initcall(request_standard_resources);
+--- sle11-2009-05-14.orig/arch/x86/kernel/setup_64-xen.c       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/setup_64-xen.c    2009-03-16 16:33:40.000000000 +0100
+@@ -15,7 +15,6 @@
+ #include <linux/ptrace.h>
+ #include <linux/slab.h>
+ #include <linux/user.h>
+-#include <linux/a.out.h>
+ #include <linux/screen_info.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+@@ -30,6 +29,7 @@
+ #include <linux/crash_dump.h>
+ #include <linux/root_dev.h>
+ #include <linux/pci.h>
++#include <linux/efi.h>
+ #include <linux/acpi.h>
+ #include <linux/kallsyms.h>
+ #include <linux/edd.h>
+@@ -39,10 +39,13 @@
+ #include <linux/dmi.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/ctype.h>
++#include <linux/uaccess.h>
++#include <linux/init_ohci1394_dma.h>
+ #include <asm/mtrr.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
++#include <asm/vsyscall.h>
+ #include <asm/io.h>
+ #include <asm/smp.h>
+ #include <asm/msr.h>
+@@ -50,6 +53,7 @@
+ #include <video/edid.h>
+ #include <asm/e820.h>
+ #include <asm/dma.h>
++#include <asm/gart.h>
+ #include <asm/mpspec.h>
+ #include <asm/mmu_context.h>
+ #include <asm/proto.h>
+@@ -59,6 +63,9 @@
+ #include <asm/sections.h>
+ #include <asm/dmi.h>
+ #include <asm/cacheflush.h>
++#include <asm/mce.h>
++#include <asm/ds.h>
++#include <asm/topology.h>
+ #ifdef CONFIG_XEN
+ #include <linux/percpu.h>
+ #include <xen/interface/physdev.h>
+@@ -108,6 +115,8 @@ EXPORT_SYMBOL(xen_start_info);
+ struct cpuinfo_x86 boot_cpu_data __read_mostly;
+ EXPORT_SYMBOL(boot_cpu_data);
++__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
++
+ unsigned long mmu_cr4_features;
+ /* Boot loader ID as an integer, for the benefit of proc_dointvec */
+@@ -117,7 +126,7 @@ unsigned long saved_video_mode;
+ int force_mwait __cpuinitdata;
 -/* 
-- * No more special protections in this 2/4MB area - revert to a
-- * large page again. 
-- */
--static void revert_page(unsigned long address, pgprot_t ref_prot)
--{
--      pgd_t *pgd;
--      pud_t *pud;
--      pmd_t *pmd;
--      pte_t large_pte;
--      unsigned long pfn;
--
--      pgd = pgd_offset_k(address);
--      BUG_ON(pgd_none(*pgd));
--      pud = pud_offset(pgd,address);
--      BUG_ON(pud_none(*pud));
--      pmd = pmd_offset(pud, address);
--      BUG_ON(__pmd_val(*pmd) & _PAGE_PSE);
--      pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
--      large_pte = pfn_pte(pfn, ref_prot);
--      large_pte = pte_mkhuge(large_pte);
--      set_pte((pte_t *)pmd, large_pte);
--}      
--
--static int
--__change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
--                                 pgprot_t ref_prot)
--{ 
--      pte_t *kpte; 
--      struct page *kpte_page;
--      pgprot_t ref_prot2;
++/*
+  * Early DMI memory
+  */
+ int dmi_alloc_index;
+@@ -163,25 +172,27 @@ struct resource standard_io_resources[] 
+ #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
+-struct resource data_resource = {
++static struct resource data_resource = {
+       .name = "Kernel data",
+       .start = 0,
+       .end = 0,
+       .flags = IORESOURCE_RAM,
+ };
+-struct resource code_resource = {
++static struct resource code_resource = {
+       .name = "Kernel code",
+       .start = 0,
+       .end = 0,
+       .flags = IORESOURCE_RAM,
+ };
+-struct resource bss_resource = {
++static struct resource bss_resource = {
+       .name = "Kernel bss",
+       .start = 0,
+       .end = 0,
+       .flags = IORESOURCE_RAM,
+ };
++static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c);
++
+ #ifdef CONFIG_PROC_VMCORE
+ /* elfcorehdr= specifies the location of elf core header
+  * stored by the crashed kernel. This option will be passed
+@@ -205,9 +216,10 @@ contig_initmem_init(unsigned long start_
+       unsigned long bootmap_size, bootmap;
+       bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
+-      bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
++      bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size,
++                               PAGE_SIZE);
+       if (bootmap == -1L)
+-              panic("Cannot find bootmem map of size %ld\n",bootmap_size);
++              panic("Cannot find bootmem map of size %ld\n", bootmap_size);
+       bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
+       e820_register_active_regions(0, start_pfn, end_pfn);
+ #ifdef CONFIG_XEN
+@@ -215,8 +227,8 @@ contig_initmem_init(unsigned long start_
+ #else
+       free_bootmem_with_active_regions(0, end_pfn);
+ #endif
+-      reserve_bootmem(bootmap, bootmap_size);
+-} 
++      reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT);
++}
+ #endif
+ #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+@@ -249,27 +261,35 @@ static inline void copy_edd(void)
+ #ifndef CONFIG_XEN
+ static void __init reserve_crashkernel(void)
+ {
+-      unsigned long long free_mem;
++      unsigned long long total_mem;
+       unsigned long long crash_size, crash_base;
+       int ret;
+-      free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
++      total_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+-      ret = parse_crashkernel(boot_command_line, free_mem,
++      ret = parse_crashkernel(boot_command_line, total_mem,
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size) {
+-              if (crash_base > 0) {
+-                      printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+-                                      "for crashkernel (System RAM: %ldMB)\n",
+-                                      (unsigned long)(crash_size >> 20),
+-                                      (unsigned long)(crash_base >> 20),
+-                                      (unsigned long)(free_mem >> 20));
+-                      crashk_res.start = crash_base;
+-                      crashk_res.end   = crash_base + crash_size - 1;
+-                      reserve_bootmem(crash_base, crash_size);
+-              } else
++              if (crash_base <= 0) {
+                       printk(KERN_INFO "crashkernel reservation failed - "
+                                       "you have to specify a base address\n");
++                      return;
++              }
++
++              if (reserve_bootmem(crash_base, crash_size,
++                                      BOOTMEM_EXCLUSIVE) < 0) {
++                      printk(KERN_INFO "crashkernel reservation failed - "
++                                      "memory is in use\n");
++                      return;
++              }
++
++              printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
++                              "for crashkernel (System RAM: %ldMB)\n",
++                              (unsigned long)(crash_size >> 20),
++                              (unsigned long)(crash_base >> 20),
++                              (unsigned long)(total_mem >> 20));
++              crashk_res.start = crash_base;
++              crashk_res.end   = crash_base + crash_size - 1;
+       }
+ }
+ #else
+@@ -280,37 +300,21 @@ static inline void __init reserve_crashk
+ {}
+ #endif
+-#ifndef CONFIG_XEN
+-#define EBDA_ADDR_POINTER 0x40E
 -
--      kpte = lookup_address(address);
--      if (!kpte) return 0;
--      kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
--      BUG_ON(PageLRU(kpte_page));
--      BUG_ON(PageCompound(kpte_page));
--      if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
--              if (!pte_huge(*kpte)) {
--                      set_pte(kpte, pfn_pte(pfn, prot));
--              } else {
--                      /*
--                       * split_large_page will take the reference for this
--                       * change_page_attr on the split page.
--                       */
--                      struct page *split;
--                      ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
--                      split = split_large_page(address, prot, ref_prot2);
--                      if (!split)
--                              return -ENOMEM;
--                      pgprot_val(ref_prot2) &= ~_PAGE_NX;
--                      set_pte(kpte, mk_pte(split, ref_prot2));
--                      kpte_page = split;
--              }
--              page_private(kpte_page)++;
--      } else if (!pte_huge(*kpte)) {
--              set_pte(kpte, pfn_pte(pfn, ref_prot));
--              BUG_ON(page_private(kpte_page) == 0);
--              page_private(kpte_page)--;
--      } else
--              BUG();
+-unsigned __initdata ebda_addr;
+-unsigned __initdata ebda_size;
 -
--      /* on x86-64 the direct mapping set at boot is not using 4k pages */
+-static void discover_ebda(void)
++/* Overridden in paravirt.c if CONFIG_PARAVIRT */
++void __attribute__((weak)) __init memory_setup(void)
+ {
 -      /*
--       * ..., but the XEN guest kernels (currently) do:
--       * If the pte was reserved, it means it was created at boot
--       * time (not via split_large_page) and in turn we must not
--       * replace it with a large page.
+-       * there is a real-mode segmented pointer pointing to the 
+-       * 4K EBDA area at 0x40E
 -       */
--#ifndef CONFIG_XEN
--      BUG_ON(PageReserved(kpte_page));
--#else
--      if (PageReserved(kpte_page))
--              return 0;
--#endif
--
--      save_page(kpte_page);
--      if (page_private(kpte_page) == 0)
--              revert_page(address, ref_prot);
--      return 0;
--} 
--
--/*
-- * Change the page attributes of an page in the linear mapping.
-- *
-- * This should be used when a page is mapped with a different caching policy
-- * than write-back somewhere - some CPUs do not like it when mappings with
-- * different caching policies exist. This changes the page attributes of the
-- * in kernel linear mapping too.
-- * 
-- * The caller needs to ensure that there are no conflicting mappings elsewhere.
-- * This function only deals with the kernel linear map.
-- * 
-- * Caller must call global_flush_tlb() after this.
-- */
--int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
--{
--      int err = 0, kernel_map = 0;
--      int i; 
--
--      if (address >= __START_KERNEL_map
--          && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) {
--              address = (unsigned long)__va(__pa(address));
--              kernel_map = 1;
--      }
+-      ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
+-      ebda_addr <<= 4;
 -
--      down_write(&init_mm.mmap_sem);
--      for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
--              unsigned long pfn = __pa(address) >> PAGE_SHIFT;
+-      ebda_size = *(unsigned short *)__va(ebda_addr);
 -
--              if (!kernel_map || pte_present(pfn_pte(0, prot))) {
--                      err = __change_page_attr(address, pfn, prot, PAGE_KERNEL);
--                      if (err)
--                              break;
--              }
--              /* Handle kernel mapping too which aliases part of the
--               * lowmem */
--              if (__pa(address) < KERNEL_TEXT_SIZE) {
--                      unsigned long addr2;
--                      pgprot_t prot2;
--                      addr2 = __START_KERNEL_map + __pa(address);
--                      /* Make sure the kernel mappings stay executable */
--                      prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
--                      err = __change_page_attr(addr2, pfn, prot2,
--                                               PAGE_KERNEL_EXEC);
--              } 
--      }       
--      up_write(&init_mm.mmap_sem); 
--      return err;
--}
+-      /* Round EBDA up to pages */
+-      if (ebda_size == 0)
+-              ebda_size = 1;
+-      ebda_size <<= 10;
+-      ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
+-      if (ebda_size > 64*1024)
+-              ebda_size = 64*1024;
++       machine_specific_memory_setup();
+ }
+-#else
+-#define discover_ebda() ((void)0)
+-#endif
++/*
++ * setup_arch - architecture-specific boot-time initializations
++ *
++ * Note: On x86_64, fixmaps are ready for use even before this is called.
++ */
+ void __init setup_arch(char **cmdline_p)
+ {
++      unsigned i;
++
+ #ifdef CONFIG_XEN
+       extern struct e820map machine_e820;
+@@ -319,6 +323,11 @@ void __init setup_arch(char **cmdline_p)
+       /* Register a call for panic conditions. */
+       atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
++      WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
++                                   VMASST_TYPE_writable_pagetables));
++
++      early_ioremap_init();
++
+       ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); 
+       screen_info = boot_params.screen_info;
+@@ -335,11 +344,6 @@ void __init setup_arch(char **cmdline_p)
+               screen_info.orig_video_isVGA = 0;
+       copy_edid();
 -
--/* Don't call this for MMIO areas that may not have a mem_map entry */
--int change_page_attr(struct page *page, int numpages, pgprot_t prot)
--{
--      unsigned long addr = (unsigned long)page_address(page);
--      return change_page_attr_addr(addr, numpages, prot);
--}
+-      WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
+-                                   VMASST_TYPE_writable_pagetables));
 -
--void global_flush_tlb(void)
--{ 
--      struct page *pg, *next;
--      struct list_head l;
+-      ARCH_SETUP
+ #else
+       printk(KERN_INFO "Command line: %s\n", boot_command_line);
+@@ -355,7 +359,15 @@ void __init setup_arch(char **cmdline_p)
+       rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0);
+       rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
+ #endif
+-      setup_memory_region();
++#ifdef CONFIG_EFI
++      if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
++                   "EL64", 4))
++              efi_enabled = 1;
++#endif
++
++      ARCH_SETUP
++
++      memory_setup();
+       copy_edd();
+       if (!boot_params.hdr.root_flags)
+@@ -379,28 +391,51 @@ void __init setup_arch(char **cmdline_p)
+       parse_early_param();
++#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
++      if (init_ohci1394_dma_early)
++              init_ohci1394_dma_on_all_controllers();
++#endif
++
+       finish_e820_parsing();
++      early_gart_iommu_check();
++
+       e820_register_active_regions(0, 0, -1UL);
+       /*
+        * partially used pages are not usable - thus
+        * we are rounding upwards:
+        */
+       end_pfn = e820_end_of_ram();
++      /* update e820 for memory not covered by WB MTRRs */
++      mtrr_bp_init();
++#ifndef CONFIG_XEN
++      if (mtrr_trim_uncached_memory(end_pfn)) {
++              e820_register_active_regions(0, 0, -1UL);
++              end_pfn = e820_end_of_ram();
++      }
++#endif
++
+       num_physpages = end_pfn;
++      max_mapnr = end_pfn;
+       check_efer();
+-      discover_ebda();
 -
+       init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
++      if (efi_enabled)
++              efi_init();
+       if (is_initial_xendomain())
+               dmi_scan_machine();
++      io_delay_init();
++
+ #if defined(CONFIG_SMP) && !defined(CONFIG_XEN)
+-      /* setup to use the static apicid table during kernel startup */
+-      x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
++      /* setup to use the early static init tables during kernel startup */
++      x86_cpu_to_apicid_early_ptr = (void *)x86_cpu_to_apicid_init;
++      x86_bios_cpu_apicid_early_ptr = (void *)x86_bios_cpu_apicid_init;
++#ifdef CONFIG_NUMA
++      x86_cpu_to_node_map_early_ptr = (void *)x86_cpu_to_node_map_init;
++#endif
+ #endif
+       /* How many end-of-memory variables you have, grandma! */
+@@ -419,54 +454,25 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ #ifdef CONFIG_NUMA
+-      numa_initmem_init(0, end_pfn); 
++      numa_initmem_init(0, end_pfn);
+ #else
+       contig_initmem_init(0, end_pfn);
+ #endif
+-#ifdef CONFIG_XEN
 -      /*
--       * Write-protect the semaphore, to exclude two contexts
--       * doing a list_replace_init() call in parallel and to
--       * exclude new additions to the deferred_pages list:
+-       * Reserve kernel, physmap, start info, initial page tables, and
+-       * direct mapping.
 -       */
--      down_write(&init_mm.mmap_sem);
--      list_replace_init(&deferred_pages, &l);
--      up_write(&init_mm.mmap_sem);
+-      reserve_bootmem_generic(__pa_symbol(&_text),
+-                              (table_end << PAGE_SHIFT) - __pa_symbol(&_text));
+-#else
+-      /* Reserve direct mapping */
+-      reserve_bootmem_generic(table_start << PAGE_SHIFT, 
+-                              (table_end - table_start) << PAGE_SHIFT);
 -
--      flush_map(&l);
+-      /* reserve kernel */
+-      reserve_bootmem_generic(__pa_symbol(&_text),
+-                              __pa_symbol(&_end) - __pa_symbol(&_text));
++      early_res_to_bootmem();
++#ifndef CONFIG_XEN
++#ifdef CONFIG_ACPI_SLEEP
+       /*
+-       * reserve physical page 0 - it's a special BIOS page on many boxes,
+-       * enabling clean reboots, SMP operation, laptop functions.
++       * Reserve low memory region for sleep support.
+        */
+-      reserve_bootmem_generic(0, PAGE_SIZE);
 -
--      list_for_each_entry_safe(pg, next, &l, lru) {
--              list_del(&pg->lru);
--              clear_bit(PG_arch_1, &pg->flags);
--              if (page_private(pg) != 0)
--                      continue;
--              ClearPagePrivate(pg);
--              __free_page(pg);
--      } 
--} 
+-      /* reserve ebda region */
+-      if (ebda_addr)
+-              reserve_bootmem_generic(ebda_addr, ebda_size);
+-#ifdef CONFIG_NUMA
+-      /* reserve nodemap region */
+-      if (nodemap_addr)
+-              reserve_bootmem_generic(nodemap_addr, nodemap_size);
++       acpi_reserve_bootmem();
+ #endif
+-#ifdef CONFIG_SMP
+-      /* Reserve SMP trampoline */
+-      reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE);
+-#endif
++      if (efi_enabled)
++              efi_reserve_bootmem();
+ #endif
+-#ifdef CONFIG_ACPI_SLEEP
+-       /*
+-        * Reserve low memory region for sleep support.
+-        */
+-       acpi_reserve_bootmem();
+-#endif
+ #ifdef CONFIG_BLK_DEV_INITRD
+ #ifdef CONFIG_XEN
+       if (xen_start_info->mod_start) {
+@@ -490,6 +496,8 @@ void __init setup_arch(char **cmdline_p)
+                       initrd_below_start_ok = 1;
+ #endif
+               } else {
++                      /* Assumes everything on node 0 */
++                      free_bootmem(ramdisk_image, ramdisk_size);
+                       printk(KERN_ERR "initrd extends beyond end of memory "
+                              "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+                              ramdisk_end, end_of_mem);
+@@ -499,10 +507,11 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+       reserve_crashkernel();
+       paging_init();
++      map_vsyscall();
+ #ifdef CONFIG_X86_LOCAL_APIC
+       /*
+-       * Find and reserve possible boot-time SMP configuration:
+-       */
++      * Find and reserve possible boot-time SMP configuration:
++      */
+       find_smp_config();
+ #endif
+ #ifdef CONFIG_XEN
+@@ -590,16 +599,10 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ #endif
+-#if defined(CONFIG_PCI) && !defined(CONFIG_XEN)
++#ifndef CONFIG_XEN
+       early_quirks();
+ #endif
+-      /*
+-       * set this early, so we dont allocate cpu0
+-       * if MADT list doesnt list BSP first
+-       * mpparse.c/MP_processor_info() allocates logical cpu numbers.
+-       */
+-      cpu_set(0, cpu_present_map);
+ #ifdef CONFIG_ACPI
+       /*
+        * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
+@@ -623,6 +626,7 @@ void __init setup_arch(char **cmdline_p)
+               get_smp_config();
+ #ifndef CONFIG_XEN
+       init_apic_mappings();
++      ioapic_init_mappings();
+ #endif
+ #endif
+ #if defined(CONFIG_XEN) && defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
+@@ -634,18 +638,17 @@ void __init setup_arch(char **cmdline_p)
+        */
+ #ifdef CONFIG_XEN
+       if (is_initial_xendomain())
+-              e820_reserve_resources(machine_e820.map, machine_e820.nr_map);
++              e820_reserve_resources(machine_e820.map, machine_e820.nr_map,
++                                     &code_resource, &data_resource, &bss_resource);
+ #else
+-      e820_reserve_resources(e820.map, e820.nr_map);
++      e820_reserve_resources(e820.map, e820.nr_map,
++                             &code_resource, &data_resource, &bss_resource);
+       e820_mark_nosave_regions();
+ #endif
+-      {
+-      unsigned i;
+       /* request I/O space for devices used on all i[345]86 PCs */
+       for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
+               request_resource(&ioport_resource, &standard_io_resources[i]);
+-      }
+ #ifdef CONFIG_XEN
+       if (is_initial_xendomain())
+@@ -679,7 +682,8 @@ void __init setup_arch(char **cmdline_p)
+ #ifdef CONFIG_VT
+ #if defined(CONFIG_VGA_CONSOLE)
+-      conswitchp = &vga_con;
++      if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
++              conswitchp = &vga_con;
+ #elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+ #endif
+@@ -723,9 +727,10 @@ static void __cpuinit display_cacheinfo(
+       if (n >= 0x80000005) {
+               cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
+-              printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
+-                      edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
+-              c->x86_cache_size=(ecx>>24)+(edx>>24);
++              printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), "
++                     "D cache %dK (%d bytes/line)\n",
++                     edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
++              c->x86_cache_size = (ecx>>24) + (edx>>24);
+               /* On K8 L1 TLB is inclusive, so don't count it */
+               c->x86_tlbsize = 0;
+       }
+@@ -739,27 +744,25 @@ static void __cpuinit display_cacheinfo(
+               printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
+               c->x86_cache_size, ecx & 0xFF);
+       }
 -
--EXPORT_SYMBOL(change_page_attr);
--EXPORT_SYMBOL(global_flush_tlb);
---- /dev/null
-+++ b/arch/x86/mm/pageattr-xen.c
-@@ -0,0 +1,1412 @@
-+/*
-+ * Copyright 2002 Andi Kleen, SuSE Labs.
-+ * Thanks to Ben LaHaise for precious feedback.
-+ */
-+#include <linux/highmem.h>
-+#include <linux/bootmem.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/mm.h>
-+#include <linux/interrupt.h>
+-      if (n >= 0x80000007)
+-              cpuid(0x80000007, &dummy, &dummy, &dummy, &c->x86_power); 
+       if (n >= 0x80000008) {
+-              cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); 
++              cpuid(0x80000008, &eax, &dummy, &dummy, &dummy);
+               c->x86_virt_bits = (eax >> 8) & 0xff;
+               c->x86_phys_bits = eax & 0xff;
+       }
+ }
+ #ifdef CONFIG_NUMA
+-static int nearby_node(int apicid)
++static int __cpuinit nearby_node(int apicid)
+ {
+-      int i;
++      int i, node;
++
+       for (i = apicid - 1; i >= 0; i--) {
+-              int node = apicid_to_node[i];
++              node = apicid_to_node[i];
+               if (node != NUMA_NO_NODE && node_online(node))
+                       return node;
+       }
+       for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
+-              int node = apicid_to_node[i];
++              node = apicid_to_node[i];
+               if (node != NUMA_NO_NODE && node_online(node))
+                       return node;
+       }
+@@ -771,7 +774,7 @@ static int nearby_node(int apicid)
+  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
+  * Assumes number of cores is a power of two.
+  */
+-static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
++static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
+ {
+ #ifdef CONFIG_SMP
+       unsigned bits;
+@@ -780,7 +783,54 @@ static void __init amd_detect_cmp(struct
+       int node = 0;
+       unsigned apicid = hard_smp_processor_id();
+ #endif
+-      unsigned ecx = cpuid_ecx(0x80000008);
++      bits = c->x86_coreid_bits;
 +
-+#include <asm/e820.h>
-+#include <asm/processor.h>
-+#include <asm/tlbflush.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/pgalloc.h>
-+#include <asm/proto.h>
-+#include <asm/mmu_context.h>
++      /* Low order bits define the core id (index of core in socket) */
++      c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
++      /* Convert the APIC ID into the socket ID */
++      c->phys_proc_id = phys_pkg_id(bits);
 +
-+#ifndef CONFIG_X86_64
-+#define TASK_SIZE64 TASK_SIZE
++#ifdef CONFIG_NUMA
++      node = c->phys_proc_id;
++      if (apicid_to_node[apicid] != NUMA_NO_NODE)
++              node = apicid_to_node[apicid];
++      if (!node_online(node)) {
++              /* Two possibilities here:
++                 - The CPU is missing memory and no node was created.
++                 In that case try picking one from a nearby CPU
++                 - The APIC IDs differ from the HyperTransport node IDs
++                 which the K8 northbridge parsing fills in.
++                 Assume they are all increased by a constant offset,
++                 but in the same order as the HT nodeids.
++                 If that doesn't result in a usable node fall back to the
++                 path for the previous case.  */
++
++              int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
++
++              if (ht_nodeid >= 0 &&
++                  apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
++                      node = apicid_to_node[ht_nodeid];
++              /* Pick a nearby node */
++              if (!node_online(node))
++                      node = nearby_node(apicid);
++      }
++      numa_set_node(cpu, node);
++
++      printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
++#endif
 +#endif
++}
 +
-+static void _pin_lock(struct mm_struct *mm, int lock) {
-+      if (lock)
-+              spin_lock(&mm->page_table_lock);
-+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
-+      /* While mm->page_table_lock protects us against insertions and
-+       * removals of higher level page table pages, it doesn't protect
-+       * against updates of pte-s. Such updates, however, require the
-+       * pte pages to be in consistent state (unpinned+writable or
-+       * pinned+readonly). The pinning and attribute changes, however
-+       * cannot be done atomically, which is why such updates must be
-+       * prevented from happening concurrently.
-+       * Note that no pte lock can ever elsewhere be acquired nesting
-+       * with an already acquired one in the same mm, or with the mm's
-+       * page_table_lock already acquired, as that would break in the
-+       * non-split case (where all these are actually resolving to the
-+       * one page_table_lock). Thus acquiring all of them here is not
-+       * going to result in dead locks, and the order of acquires
-+       * doesn't matter.
-+       */
-+      {
-+              pgd_t *pgd = mm->pgd;
-+              unsigned g;
++static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
++{
++#ifdef CONFIG_SMP
++      unsigned bits, ecx;
 +
-+              for (g = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
-+                      pud_t *pud;
-+                      unsigned u;
++      /* Multi core CPU? */
++      if (c->extended_cpuid_level < 0x80000008)
++              return;
 +
-+                      if (pgd_none(*pgd))
-+                              continue;
-+                      pud = pud_offset(pgd, 0);
-+                      for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
-+                              pmd_t *pmd;
-+                              unsigned m;
++      ecx = cpuid_ecx(0x80000008);
+       c->x86_max_cores = (ecx & 0xff) + 1;
+@@ -793,37 +843,8 @@ static void __init amd_detect_cmp(struct
+                       bits++;
+       }
+-      /* Low order bits define the core id (index of core in socket) */
+-      c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
+-      /* Convert the APIC ID into the socket ID */
+-      c->phys_proc_id = phys_pkg_id(bits);
+-
+-#ifdef CONFIG_NUMA
+-      node = c->phys_proc_id;
+-      if (apicid_to_node[apicid] != NUMA_NO_NODE)
+-              node = apicid_to_node[apicid];
+-      if (!node_online(node)) {
+-              /* Two possibilities here:
+-                 - The CPU is missing memory and no node was created.
+-                 In that case try picking one from a nearby CPU
+-                 - The APIC IDs differ from the HyperTransport node IDs
+-                 which the K8 northbridge parsing fills in.
+-                 Assume they are all increased by a constant offset,
+-                 but in the same order as the HT nodeids.
+-                 If that doesn't result in a usable node fall back to the
+-                 path for the previous case.  */
+-              int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
+-              if (ht_nodeid >= 0 &&
+-                  apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
+-                      node = apicid_to_node[ht_nodeid];
+-              /* Pick a nearby node */
+-              if (!node_online(node))
+-                      node = nearby_node(apicid);
+-      }
+-      numa_set_node(cpu, node);
++      c->x86_coreid_bits = bits;
+-      printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
+-#endif
+ #endif
+ }
+@@ -840,8 +861,8 @@ static void __init amd_detect_cmp(struct
+ /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
+ static __cpuinit int amd_apic_timer_broken(void)
+ {
+-      u32 lo, hi;
+-      u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
++      u32 lo, hi, eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 +
-+                              if (pud_none(*pud))
-+                                      continue;
-+                              pmd = pmd_offset(pud, 0);
-+                              for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
-+                                      spinlock_t *ptl;
+       switch (eax & CPUID_XFAM) {
+       case CPUID_XFAM_K8:
+               if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
+@@ -860,6 +881,15 @@ static __cpuinit int amd_apic_timer_brok
+ }
+ #endif
++static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
++{
++      early_init_amd_mc(c);
 +
-+                                      if (pmd_none(*pmd))
-+                                              continue;
-+                                      ptl = pte_lockptr(0, pmd);
-+                                      if (lock)
-+                                              spin_lock(ptl);
-+                                      else
-+                                              spin_unlock(ptl);
-+                              }
-+                      }
-+              }
-+      }
-+#endif
-+      if (!lock)
-+              spin_unlock(&mm->page_table_lock);
++      /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
++      if (c->x86_power & (1<<8))
++              set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 +}
-+#define pin_lock(mm) _pin_lock(mm, 1)
-+#define pin_unlock(mm) _pin_lock(mm, 0)
 +
-+#define PIN_BATCH sizeof(void *)
-+static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl);
+ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
+ {
+       unsigned level;
+@@ -870,7 +900,7 @@ static void __cpuinit init_amd(struct cp
+       /*
+        * Disable TLB flush filter by setting HWCR.FFDIS on K8
+        * bit 6 of msr C001_0015
+-       *
++       *
+        * Errata 63 for SH-B3 steppings
+        * Errata 122 for all steppings (F+ have it disabled by default)
+        */
+@@ -883,35 +913,32 @@ static void __cpuinit init_amd(struct cp
+       /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+          3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
+-      clear_bit(0*32+31, &c->x86_capability);
+-      
++      clear_bit(0*32+31, (unsigned long *)&c->x86_capability);
 +
-+static inline unsigned int pgd_walk_set_prot(struct page *page, pgprot_t flags,
-+                                           unsigned int cpu, unsigned int seq)
+       /* On C+ stepping K8 rep microcode works well for copy/memset */
+       level = cpuid_eax(1);
+-      if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
+-              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
++      if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) ||
++                           level >= 0x0f58))
++              set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+       if (c->x86 == 0x10 || c->x86 == 0x11)
+-              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
++              set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+       /* Enable workaround for FXSAVE leak */
+       if (c->x86 >= 6)
+-              set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
++              set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK);
+       level = get_model_name(c);
+       if (!level) {
+-              switch (c->x86) { 
++              switch (c->x86) {
+               case 15:
+                       /* Should distinguish Models here, but this is only
+                          a fallback anyways. */
+                       strcpy(c->x86_model_id, "Hammer");
+-                      break; 
+-              } 
+-      } 
++                      break;
++              }
++      }
+       display_cacheinfo(c);
+-      /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
+-      if (c->x86_power & (1<<8))
+-              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+-
+       /* Multi core CPU? */
+       if (c->extended_cpuid_level >= 0x80000008)
+               amd_detect_cmp(c);
+@@ -923,14 +950,10 @@ static void __cpuinit init_amd(struct cp
+               num_cache_leaves = 3;
+       if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11)
+-              set_bit(X86_FEATURE_K8, &c->x86_capability);
+-
+-      /* RDTSC can be speculated around */
+-      clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
++              set_cpu_cap(c, X86_FEATURE_K8);
+-      /* Family 10 doesn't support C states in MWAIT so don't use it */
+-      if (c->x86 == 0x10 && !force_mwait)
+-              clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);
++      /* MFENCE stops RDTSC speculation */
++      set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
+ #ifndef CONFIG_XEN
+       if (amd_apic_timer_broken())
+@@ -938,28 +961,29 @@ static void __cpuinit init_amd(struct cp
+ #endif
+ }
+-static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
++void __cpuinit detect_ht(struct cpuinfo_x86 *c)
+ {
+ #ifdef CONFIG_SMP
+-      u32     eax, ebx, ecx, edx;
+-      int     index_msb, core_bits;
++      u32 eax, ebx, ecx, edx;
++      int index_msb, core_bits;
+       cpuid(1, &eax, &ebx, &ecx, &edx);
+       if (!cpu_has(c, X86_FEATURE_HT))
+               return;
+-      if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
++      if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
+               goto out;
+       smp_num_siblings = (ebx & 0xff0000) >> 16;
+       if (smp_num_siblings == 1) {
+               printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
+-      } else if (smp_num_siblings > 1 ) {
++      } else if (smp_num_siblings > 1) {
+               if (smp_num_siblings > NR_CPUS) {
+-                      printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
++                      printk(KERN_WARNING "CPU: Unsupported number of "
++                             "siblings %d", smp_num_siblings);
+                       smp_num_siblings = 1;
+                       return;
+               }
+@@ -969,7 +993,7 @@ static void __cpuinit detect_ht(struct c
+               smp_num_siblings = smp_num_siblings / c->x86_max_cores;
+-              index_msb = get_count_order(smp_num_siblings) ;
++              index_msb = get_count_order(smp_num_siblings);
+               core_bits = get_count_order(c->x86_max_cores);
+@@ -978,8 +1002,10 @@ static void __cpuinit detect_ht(struct c
+       }
+ out:
+       if ((c->x86_max_cores * smp_num_siblings) > 1) {
+-              printk(KERN_INFO  "CPU: Physical Processor ID: %d\n", c->phys_proc_id);
+-              printk(KERN_INFO  "CPU: Processor Core ID: %d\n", c->cpu_core_id);
++              printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
++                     c->phys_proc_id);
++              printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
++                     c->cpu_core_id);
+       }
+ #endif
+@@ -1003,7 +1029,7 @@ static int __cpuinit intel_num_cpu_cores
+               return 1;
+ }
+-static void srat_detect_node(void)
++static void __cpuinit srat_detect_node(void)
+ {
+ #ifdef CONFIG_NUMA
+       unsigned node;
+@@ -1013,7 +1039,7 @@ static void srat_detect_node(void)
+       /* Don't do the funky fallback heuristics the AMD version employs
+          for now. */
+       node = apicid_to_node[apicid];
+-      if (node == NUMA_NO_NODE)
++      if (node == NUMA_NO_NODE || !node_online(node))
+               node = first_node(node_online_map);
+       numa_set_node(cpu, node);
+@@ -1021,28 +1047,39 @@ static void srat_detect_node(void)
+ #endif
+ }
++static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
 +{
-+      unsigned long pfn = page_to_pfn(page);
-+
-+      if (PageHighMem(page)) {
-+              if (pgprot_val(flags) & _PAGE_RW)
-+                      ClearPagePinned(page);
-+              else
-+                      SetPagePinned(page);
-+      } else {
-+              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
-+                                      (unsigned long)__va(pfn << PAGE_SHIFT),
-+                                      pfn_pte(pfn, flags), 0);
-+              if (unlikely(++seq == PIN_BATCH)) {
-+                      if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
-+                                                              PIN_BATCH, NULL)))
-+                              BUG();
-+                      seq = 0;
-+              }
-+      }
-+
-+      return seq;
++      if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
++          (c->x86 == 0x6 && c->x86_model >= 0x0e))
++              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
 +}
 +
-+static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
-+{
-+      pgd_t       *pgd = pgd_base;
-+      pud_t       *pud;
-+      pmd_t       *pmd;
-+      int          g,u,m;
-+      unsigned int cpu, seq;
-+      multicall_entry_t *mcl;
+ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
+ {
+       /* Cache sizes */
+       unsigned n;
+       init_intel_cacheinfo(c);
+-      if (c->cpuid_level > 9 ) {
++      if (c->cpuid_level > 9) {
+               unsigned eax = cpuid_eax(10);
+               /* Check for version and the number of counters */
+               if ((eax & 0xff) && (((eax>>8) & 0xff) > 1))
+-                      set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability);
++                      set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
+       }
+       if (cpu_has_ds) {
+               unsigned int l1, l2;
+               rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
+               if (!(l1 & (1<<11)))
+-                      set_bit(X86_FEATURE_BTS, c->x86_capability);
++                      set_cpu_cap(c, X86_FEATURE_BTS);
+               if (!(l1 & (1<<12)))
+-                      set_bit(X86_FEATURE_PEBS, c->x86_capability);
++                      set_cpu_cap(c, X86_FEATURE_PEBS);
+       }
 +
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return;
++      if (cpu_has_bts)
++              ds_init_intel(c);
 +
-+      cpu = get_cpu();
+       n = c->extended_cpuid_level;
+       if (n >= 0x80000008) {
+               unsigned eax = cpuid_eax(0x80000008);
+@@ -1059,14 +1096,11 @@ static void __cpuinit init_intel(struct 
+               c->x86_cache_alignment = c->x86_clflush_size * 2;
+       if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
+           (c->x86 == 0x6 && c->x86_model >= 0x0e))
+-              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
++              set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+       if (c->x86 == 6)
+-              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
+-      if (c->x86 == 15)
+-              set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
+-      else
+-              clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
+-      c->x86_max_cores = intel_num_cpu_cores(c);
++              set_cpu_cap(c, X86_FEATURE_REP_GOOD);
++      set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
++      c->x86_max_cores = intel_num_cpu_cores(c);
+       srat_detect_node();
+ }
+@@ -1083,18 +1117,12 @@ static void __cpuinit get_cpu_vendor(str
+               c->x86_vendor = X86_VENDOR_UNKNOWN;
+ }
+-struct cpu_model_info {
+-      int vendor;
+-      int family;
+-      char *model_names[16];
+-};
+-
+ /* Do some early cpuid on the boot CPU to get some parameter that are
+    needed before check_bugs. Everything advanced is in identify_cpu
+    below. */
+-void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
++static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
+ {
+-      u32 tfms;
++      u32 tfms, xlvl;
+       c->loops_per_jiffy = loops_per_jiffy;
+       c->x86_cache_size = -1;
+@@ -1105,6 +1133,7 @@ void __cpuinit early_identify_cpu(struct
+       c->x86_clflush_size = 64;
+       c->x86_cache_alignment = c->x86_clflush_size;
+       c->x86_max_cores = 1;
++      c->x86_coreid_bits = 0;
+       c->extended_cpuid_level = 0;
+       memset(&c->x86_capability, 0, sizeof c->x86_capability);
+@@ -1113,7 +1142,7 @@ void __cpuinit early_identify_cpu(struct
+             (unsigned int *)&c->x86_vendor_id[0],
+             (unsigned int *)&c->x86_vendor_id[8],
+             (unsigned int *)&c->x86_vendor_id[4]);
+-              
 +
-+      /*
-+       * Cannot iterate up to USER_PTRS_PER_PGD on x86-64 as these pagetables
-+       * may not be the 'current' task's pagetables (e.g., current may be
-+       * 32-bit, but the pagetables may be for a 64-bit task).
-+       * Subtracting 1 from TASK_SIZE64 means the loop limit is correct
-+       * regardless of whether TASK_SIZE64 is a multiple of PGDIR_SIZE.
-+       */
-+      for (g = 0, seq = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
-+              if (pgd_none(*pgd))
-+                      continue;
-+              pud = pud_offset(pgd, 0);
-+              if (PTRS_PER_PUD > 1) /* not folded */
-+                      seq = pgd_walk_set_prot(virt_to_page(pud),flags,cpu,seq);
-+              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
-+                      if (pud_none(*pud))
-+                              continue;
-+                      pmd = pmd_offset(pud, 0);
-+                      if (PTRS_PER_PMD > 1) /* not folded */
-+                              seq = pgd_walk_set_prot(virt_to_page(pmd),flags,cpu,seq);
-+                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
-+                              if (pmd_none(*pmd))
-+                                      continue;
-+                              seq = pgd_walk_set_prot(pmd_page(*pmd),flags,cpu,seq);
-+                      }
-+              }
-+      }
+       get_cpu_vendor(c);
+       /* Initialize the standard set of capabilities */
+@@ -1131,7 +1160,7 @@ void __cpuinit early_identify_cpu(struct
+                       c->x86 += (tfms >> 20) & 0xff;
+               if (c->x86 >= 0x6)
+                       c->x86_model += ((tfms >> 16) & 0xF) << 4;
+-              if (c->x86_capability[0] & (1<<19)) 
++              if (c->x86_capability[0] & (1<<19))
+                       c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
+       } else {
+               /* Have CPUID level 0 only - unheard of */
+@@ -1141,18 +1170,6 @@ void __cpuinit early_identify_cpu(struct
+ #ifdef CONFIG_SMP
+       c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
+ #endif
+-}
+-
+-/*
+- * This does the hard work of actually picking apart the CPU stuff...
+- */
+-void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
+-{
+-      int i;
+-      u32 xlvl;
+-
+-      early_identify_cpu(c);
+-
+       /* AMD-defined flags: level 0x80000001 */
+       xlvl = cpuid_eax(0x80000000);
+       c->extended_cpuid_level = xlvl;
+@@ -1173,6 +1190,30 @@ void __cpuinit identify_cpu(struct cpuin
+                       c->x86_capability[2] = cpuid_edx(0x80860001);
+       }
++      c->extended_cpuid_level = cpuid_eax(0x80000000);
++      if (c->extended_cpuid_level >= 0x80000007)
++              c->x86_power = cpuid_edx(0x80000007);
 +
-+      mcl = per_cpu(pb_mcl, cpu);
-+#ifdef CONFIG_X86_64
-+      if (unlikely(seq > PIN_BATCH - 2)) {
-+              if (unlikely(HYPERVISOR_multicall_check(mcl, seq, NULL)))
-+                      BUG();
-+              seq = 0;
++      switch (c->x86_vendor) {
++      case X86_VENDOR_AMD:
++              early_init_amd(c);
++              break;
++      case X86_VENDOR_INTEL:
++              early_init_intel(c);
++              break;
 +      }
-+      MULTI_update_va_mapping(mcl + seq,
-+             (unsigned long)__user_pgd(pgd_base),
-+             pfn_pte(virt_to_phys(__user_pgd(pgd_base))>>PAGE_SHIFT, flags),
-+             0);
-+      MULTI_update_va_mapping(mcl + seq + 1,
-+             (unsigned long)pgd_base,
-+             pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
-+             UVMF_TLB_FLUSH);
-+      if (unlikely(HYPERVISOR_multicall_check(mcl, seq + 2, NULL)))
-+              BUG();
-+#else
-+      if (likely(seq != 0)) {
-+              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
-+                      (unsigned long)pgd_base,
-+                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
-+                      UVMF_TLB_FLUSH);
-+              if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
-+                                                      seq + 1, NULL)))
-+                      BUG();
-+      } else if(HYPERVISOR_update_va_mapping((unsigned long)pgd_base,
-+                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
-+                      UVMF_TLB_FLUSH))
-+              BUG();
-+#endif
 +
-+      put_cpu();
 +}
 +
-+static void __pgd_pin(pgd_t *pgd)
++/*
++ * This does the hard work of actually picking apart the CPU stuff...
++ */
++void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 +{
-+      pgd_walk(pgd, PAGE_KERNEL_RO);
-+      kmap_flush_unused();
-+      xen_pgd_pin(__pa(pgd)); /* kernel */
-+#ifdef CONFIG_X86_64
-+      xen_pgd_pin(__pa(__user_pgd(pgd))); /* user */
-+#endif
-+      SetPagePinned(virt_to_page(pgd));
-+}
++      int i;
 +
-+static void __pgd_unpin(pgd_t *pgd)
-+{
-+      xen_pgd_unpin(__pa(pgd));
-+#ifdef CONFIG_X86_64
-+      xen_pgd_unpin(__pa(__user_pgd(pgd)));
-+#endif
-+      pgd_walk(pgd, PAGE_KERNEL);
-+      ClearPagePinned(virt_to_page(pgd));
-+}
++      early_identify_cpu(c);
 +
-+void pgd_test_and_unpin(pgd_t *pgd)
-+{
-+      if (PagePinned(virt_to_page(pgd)))
-+              __pgd_unpin(pgd);
-+}
+       init_scattered_cpuid_features(c);
+       c->apicid = phys_pkg_id(0);
+@@ -1202,8 +1243,7 @@ void __cpuinit identify_cpu(struct cpuin
+               break;
+       }
+-      select_idle_routine(c);
+-      detect_ht(c); 
++      detect_ht(c);
+       /*
+        * On SMP, boot_cpu_data holds the common feature set between
+@@ -1213,31 +1253,55 @@ void __cpuinit identify_cpu(struct cpuin
+        */
+       if (c != &boot_cpu_data) {
+               /* AND the already accumulated flags with these */
+-              for (i = 0 ; i < NCAPINTS ; i++)
++              for (i = 0; i < NCAPINTS; i++)
+                       boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
+       }
++      /* Clear all flags overriden by options */
++      for (i = 0; i < NCAPINTS; i++)
++              c->x86_capability[i] &= ~cleared_cpu_caps[i];
 +
-+void mm_pin(struct mm_struct *mm)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
+ #ifdef CONFIG_X86_MCE
+       mcheck_init(c);
+ #endif
++      select_idle_routine(c);
 +
-+      pin_lock(mm);
-+      __pgd_pin(mm->pgd);
-+      pin_unlock(mm);
-+}
+       if (c != &boot_cpu_data)
+               mtrr_ap_init();
+ #ifdef CONFIG_NUMA
+       numa_add_cpu(smp_processor_id());
+ #endif
 +
-+void mm_unpin(struct mm_struct *mm)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
+ }
+- 
 +
-+      pin_lock(mm);
-+      __pgd_unpin(mm->pgd);
-+      pin_unlock(mm);
++static __init int setup_noclflush(char *arg)
++{
++      setup_clear_cpu_cap(X86_FEATURE_CLFLSH);
++      return 1;
 +}
++__setup("noclflush", setup_noclflush);
+ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
+ {
+       if (c->x86_model_id[0])
+-              printk("%s", c->x86_model_id);
++              printk(KERN_CONT "%s", c->x86_model_id);
 +
-+void mm_pin_all(void)
++      if (c->x86_mask || c->cpuid_level >= 0)
++              printk(KERN_CONT " stepping %02x\n", c->x86_mask);
++      else
++              printk(KERN_CONT "\n");
++}
+-      if (c->x86_mask || c->cpuid_level >= 0) 
+-              printk(" stepping %02x\n", c->x86_mask);
++static __init int setup_disablecpuid(char *arg)
 +{
-+      struct page *page;
-+      unsigned long flags;
++      int bit;
++      if (get_option(&arg, &bit) && bit < NCAPINTS*32)
++              setup_clear_cpu_cap(bit);
+       else
+-              printk("\n");
++              return 0;
++      return 1;
+ }
++__setup("clearcpuid=", setup_disablecpuid);
+ /*
+  *    Get CPU information for use by the procfs.
+@@ -1246,116 +1310,41 @@ void __cpuinit print_cpu_info(struct cpu
+ static int show_cpuinfo(struct seq_file *m, void *v)
+ {
+       struct cpuinfo_x86 *c = v;
+-      int cpu = 0;
+-
+-      /* 
+-       * These flag bits must match the definitions in <asm/cpufeature.h>.
+-       * NULL means this bit is undefined or reserved; either way it doesn't
+-       * have meaning as far as Linux is concerned.  Note that it's important
+-       * to realize there is a difference between this table and CPUID -- if
+-       * applications want to get the raw CPUID data, they should access
+-       * /dev/cpu/<cpu_nr>/cpuid instead.
+-       */
+-      static const char *const x86_cap_flags[] = {
+-              /* Intel-defined */
+-              "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+-              "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+-              "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
+-              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
+-
+-              /* AMD-defined */
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
+-              NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
+-              "3dnowext", "3dnow",
+-
+-              /* Transmeta-defined */
+-              "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-
+-              /* Other (Linux-defined) */
+-              "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+-              NULL, NULL, NULL, NULL,
+-              "constant_tsc", "up", NULL, "arch_perfmon",
+-              "pebs", "bts", NULL, "sync_rdtsc",
+-              "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-
+-              /* Intel-defined (#2) */
+-              "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
+-              "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
+-              NULL, NULL, "dca", "sse4_1", "sse4_2", NULL, NULL, "popcnt",
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-
+-              /* VIA/Cyrix/Centaur-defined */
+-              NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
+-              "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-
+-              /* AMD-defined (#2) */
+-              "lahf_lm", "cmp_legacy", "svm", "extapic",
+-              "cr8_legacy", "abm", "sse4a", "misalignsse",
+-              "3dnowprefetch", "osvw", "ibs", "sse5",
+-              "skinit", "wdt", NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-
+-              /* Auxiliary (Linux-defined) */
+-              "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-      };
+-      static const char *const x86_power_flags[] = {
+-              "ts",   /* temperature sensor */
+-              "fid",  /* frequency id control */
+-              "vid",  /* voltage id control */
+-              "ttp",  /* thermal trip */
+-              "tm",
+-              "stc",
+-              "100mhzsteps",
+-              "hwpstate",
+-              "",     /* tsc invariant mapped to constant_tsc */
+-              /* nothing */
+-      };
+-
++      int cpu = 0, i;
+ #ifdef CONFIG_SMP
+       cpu = c->cpu_index;
+ #endif
+-      seq_printf(m,"processor\t: %u\n"
+-                   "vendor_id\t: %s\n"
+-                   "cpu family\t: %d\n"
+-                   "model\t\t: %d\n"
+-                   "model name\t: %s\n",
+-                   (unsigned)cpu,
+-                   c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
+-                   c->x86,
+-                   (int)c->x86_model,
+-                   c->x86_model_id[0] ? c->x86_model_id : "unknown");
+-      
++      seq_printf(m, "processor\t: %u\n"
++                 "vendor_id\t: %s\n"
++                 "cpu family\t: %d\n"
++                 "model\t\t: %d\n"
++                 "model name\t: %s\n",
++                 (unsigned)cpu,
++                 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
++                 c->x86,
++                 (int)c->x86_model,
++                 c->x86_model_id[0] ? c->x86_model_id : "unknown");
 +
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
+       if (c->x86_mask || c->cpuid_level >= 0)
+               seq_printf(m, "stepping\t: %d\n", c->x86_mask);
+       else
+               seq_printf(m, "stepping\t: unknown\n");
+-      
+-      if (cpu_has(c,X86_FEATURE_TSC)) {
 +
-+      /*
-+       * Allow uninterrupted access to the pgd_list. Also protects
-+       * __pgd_pin() by disabling preemption.
-+       * All other CPUs must be at a safe point (e.g., in stop_machine
-+       * or offlined entirely).
-+       */
-+      spin_lock_irqsave(&pgd_lock, flags);
-+      list_for_each_entry(page, &pgd_list, lru) {
-+              if (!PagePinned(page))
-+                      __pgd_pin((pgd_t *)page_address(page));
-+      }
-+      spin_unlock_irqrestore(&pgd_lock, flags);
-+}
++      if (cpu_has(c, X86_FEATURE_TSC)) {
+               unsigned int freq = cpufreq_quick_get((unsigned)cpu);
 +
-+void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
-+{
-+      if (!PagePinned(virt_to_page(mm->pgd)))
-+              mm_pin(mm);
-+}
+               if (!freq)
+                       freq = cpu_khz;
+               seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
+-                           freq / 1000, (freq % 1000));
++                         freq / 1000, (freq % 1000));
+       }
+       /* Cache size */
+-      if (c->x86_cache_size >= 0) 
++      if (c->x86_cache_size >= 0)
+               seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
+-      
 +
-+void arch_exit_mmap(struct mm_struct *mm)
-+{
-+      struct task_struct *tsk = current;
+ #ifdef CONFIG_SMP
+       if (smp_num_siblings * c->x86_max_cores > 1) {
+               seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
+@@ -1364,48 +1353,43 @@ static int show_cpuinfo(struct seq_file 
+               seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
+               seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
+       }
+-#endif        
++#endif
+       seq_printf(m,
+-              "fpu\t\t: yes\n"
+-              "fpu_exception\t: yes\n"
+-              "cpuid level\t: %d\n"
+-              "wp\t\t: yes\n"
+-              "flags\t\t:",
++                 "fpu\t\t: yes\n"
++                 "fpu_exception\t: yes\n"
++                 "cpuid level\t: %d\n"
++                 "wp\t\t: yes\n"
++                 "flags\t\t:",
+                  c->cpuid_level);
+-      { 
+-              int i; 
+-              for ( i = 0 ; i < 32*NCAPINTS ; i++ )
+-                      if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
+-                              seq_printf(m, " %s", x86_cap_flags[i]);
+-      }
+-              
++      for (i = 0; i < 32*NCAPINTS; i++)
++              if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
++                      seq_printf(m, " %s", x86_cap_flags[i]);
 +
-+      task_lock(tsk);
+       seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
+                  c->loops_per_jiffy/(500000/HZ),
+                  (c->loops_per_jiffy/(5000/HZ)) % 100);
+-      if (c->x86_tlbsize > 0) 
++      if (c->x86_tlbsize > 0)
+               seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
+       seq_printf(m, "clflush size\t: %d\n", c->x86_clflush_size);
+       seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
+-      seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", 
++      seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
+                  c->x86_phys_bits, c->x86_virt_bits);
+       seq_printf(m, "power management:");
+-      {
+-              unsigned i;
+-              for (i = 0; i < 32; i++) 
+-                      if (c->x86_power & (1 << i)) {
+-                              if (i < ARRAY_SIZE(x86_power_flags) &&
+-                                      x86_power_flags[i])
+-                                      seq_printf(m, "%s%s",
+-                                              x86_power_flags[i][0]?" ":"",
+-                                              x86_power_flags[i]);
+-                              else
+-                                      seq_printf(m, " [%d]", i);
+-                      }
++      for (i = 0; i < 32; i++) {
++              if (c->x86_power & (1 << i)) {
++                      if (i < ARRAY_SIZE(x86_power_flags) &&
++                          x86_power_flags[i])
++                              seq_printf(m, "%s%s",
++                                         x86_power_flags[i][0]?" ":"",
++                                         x86_power_flags[i]);
++                      else
++                              seq_printf(m, " [%d]", i);
++              }
+       }
+       seq_printf(m, "\n\n");
+@@ -1432,8 +1416,8 @@ static void c_stop(struct seq_file *m, v
+ {
+ }
+-struct seq_operations cpuinfo_op = {
+-      .start =c_start,
++const struct seq_operations cpuinfo_op = {
++      .start = c_start,
+       .next = c_next,
+       .stop = c_stop,
+       .show = show_cpuinfo,
+--- sle11-2009-05-14.orig/arch/x86/kernel/smp_32-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/smp_32-xen.c      2009-03-16 16:33:40.000000000 +0100
+@@ -168,7 +168,7 @@ void __send_IPI_shortcut(unsigned int sh
+       }
+ }
+-void fastcall send_IPI_self(int vector)
++void send_IPI_self(int vector)
+ {
+       __send_IPI_shortcut(APIC_DEST_SELF, vector);
+ }
+@@ -224,13 +224,14 @@ static DEFINE_SPINLOCK(tlbstate_lock);
+  * We need to reload %cr3 since the page tables may be going
+  * away from under us..
+  */
+-void leave_mm(unsigned long cpu)
++void leave_mm(int cpu)
+ {
+       if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
+               BUG();
+       cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
+       load_cr3(swapper_pg_dir);
+ }
++EXPORT_SYMBOL_GPL(leave_mm);
+ /*
+  *
+--- sle11-2009-05-14.orig/arch/x86/kernel/smp_64-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/smp_64-xen.c      2009-03-16 16:33:40.000000000 +0100
+@@ -33,7 +33,7 @@
+ #ifndef CONFIG_XEN
+ /*
+- *    Smarter SMP flushing macros. 
++ *    Smarter SMP flushing macros.
+  *            c/o Linus Torvalds.
+  *
+  *    These mean you can really definitely utterly forget about
+@@ -41,15 +41,15 @@
+  *
+  *    Optimizations Manfred Spraul <manfred@colorfullife.com>
+  *
+- *    More scalable flush, from Andi Kleen
++ *    More scalable flush, from Andi Kleen
+  *
+- *    To avoid global state use 8 different call vectors.
+- *    Each CPU uses a specific vector to trigger flushes on other
+- *    CPUs. Depending on the received vector the target CPUs look into
++ *    To avoid global state use 8 different call vectors.
++ *    Each CPU uses a specific vector to trigger flushes on other
++ *    CPUs. Depending on the received vector the target CPUs look into
+  *    the right per cpu variable for the flush data.
+  *
+- *    With more than 8 CPUs they are hashed to the 8 available
+- *    vectors. The limited global vector space forces us to this right now.
++ *    With more than 8 CPUs they are hashed to the 8 available
++ *    vectors. The limited global vector space forces us to this right now.
+  *    In future when interrupts are split into per CPU domains this could be
+  *    fixed, at the cost of triggering multiple IPIs in some cases.
+  */
+@@ -59,7 +59,6 @@ union smp_flush_state {
+               cpumask_t flush_cpumask;
+               struct mm_struct *flush_mm;
+               unsigned long flush_va;
+-#define FLUSH_ALL     -1ULL
+               spinlock_t tlbstate_lock;
+       };
+       char pad[SMP_CACHE_BYTES];
+@@ -71,16 +70,17 @@ union smp_flush_state {
+ static DEFINE_PER_CPU(union smp_flush_state, flush_state);
+ /*
+- * We cannot call mmdrop() because we are in interrupt context, 
++ * We cannot call mmdrop() because we are in interrupt context,
+  * instead update mm->cpu_vm_mask.
+  */
+-static inline void leave_mm(unsigned long cpu)
++void leave_mm(int cpu)
+ {
+       if (read_pda(mmu_state) == TLBSTATE_OK)
+               BUG();
+       cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
+       load_cr3(swapper_pg_dir);
+ }
++EXPORT_SYMBOL_GPL(leave_mm);
+ /*
+  *
+@@ -89,25 +89,25 @@ static inline void leave_mm(unsigned lon
+  * 1) switch_mm() either 1a) or 1b)
+  * 1a) thread switch to a different mm
+  * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
+- *    Stop ipi delivery for the old mm. This is not synchronized with
+- *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
+- *    for the wrong mm, and in the worst case we perform a superfluous
+- *    tlb flush.
++ *    Stop ipi delivery for the old mm. This is not synchronized with
++ *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
++ *    for the wrong mm, and in the worst case we perform a superfluous
++ *    tlb flush.
+  * 1a2) set cpu mmu_state to TLBSTATE_OK
+- *    Now the smp_invalidate_interrupt won't call leave_mm if cpu0
++ *    Now the smp_invalidate_interrupt won't call leave_mm if cpu0
+  *    was in lazy tlb mode.
+  * 1a3) update cpu active_mm
+- *    Now cpu0 accepts tlb flushes for the new mm.
++ *    Now cpu0 accepts tlb flushes for the new mm.
+  * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
+- *    Now the other cpus will send tlb flush ipis.
++ *    Now the other cpus will send tlb flush ipis.
+  * 1a4) change cr3.
+  * 1b) thread switch without mm change
+  *    cpu active_mm is correct, cpu0 already handles
+  *    flush ipis.
+  * 1b1) set cpu mmu_state to TLBSTATE_OK
+  * 1b2) test_and_set the cpu bit in cpu_vm_mask.
+- *    Atomically set the bit [other cpus will start sending flush ipis],
+- *    and test the bit.
++ *    Atomically set the bit [other cpus will start sending flush ipis],
++ *    and test the bit.
+  * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
+  * 2) switch %%esp, ie current
+  *
+@@ -141,12 +141,12 @@ asmlinkage void smp_invalidate_interrupt
+        * orig_rax contains the negated interrupt vector.
+        * Use that to determine where the sender put the data.
+        */
+-      sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
++      sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
+       f = &per_cpu(flush_state, sender);
+       if (!cpu_isset(cpu, f->flush_cpumask))
+               goto out;
+-              /* 
++              /*
+                * This was a BUG() but until someone can quote me the
+                * line from the intel manual that guarantees an IPI to
+                * multiple CPUs is retried _only_ on the erroring CPUs
+@@ -154,10 +154,10 @@ asmlinkage void smp_invalidate_interrupt
+                *
+                * BUG();
+                */
+-               
 +
+       if (f->flush_mm == read_pda(active_mm)) {
+               if (read_pda(mmu_state) == TLBSTATE_OK) {
+-                      if (f->flush_va == FLUSH_ALL)
++                      if (f->flush_va == TLB_FLUSH_ALL)
+                               local_flush_tlb();
+                       else
+                               __flush_tlb_one(f->flush_va);
+@@ -170,19 +170,22 @@ out:
+       add_pda(irq_tlb_count, 1);
+ }
+-static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+-                                              unsigned long va)
++void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
++                           unsigned long va)
+ {
+       int sender;
+       union smp_flush_state *f;
++      cpumask_t cpumask = *cpumaskp;
+       /* Caller has disabled preemption */
+       sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
+       f = &per_cpu(flush_state, sender);
+-      /* Could avoid this lock when
+-         num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
+-         probably not worth checking this for a cache-hot lock. */
 +      /*
-+       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
-+       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
++       * Could avoid this lock when
++       * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
++       * probably not worth checking this for a cache-hot lock.
 +       */
-+      if (tsk->active_mm == mm) {
-+              tsk->active_mm = &init_mm;
-+              atomic_inc(&init_mm.mm_count);
-+
-+              switch_mm(mm, &init_mm, tsk);
-+
-+              atomic_dec(&mm->mm_count);
-+              BUG_ON(atomic_read(&mm->mm_count) == 0);
-+      }
-+
-+      task_unlock(tsk);
-+
-+      if (PagePinned(virt_to_page(mm->pgd))
-+          && atomic_read(&mm->mm_count) == 1
-+          && !mm->context.has_foreign_mappings)
-+              mm_unpin(mm);
-+}
-+
-+static void _pte_free(struct page *page, unsigned int order)
-+{
-+      BUG_ON(order);
-+      __pte_free(page);
-+}
-+
-+pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
-+{
-+      struct page *pte;
-+
-+#ifdef CONFIG_HIGHPTE
-+      pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
-+#else
-+      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
-+#endif
-+      if (pte) {
-+              pgtable_page_ctor(pte);
-+              SetPageForeign(pte, _pte_free);
-+              init_page_count(pte);
-+      }
-+      return pte;
-+}
-+
-+void __pte_free(pgtable_t pte)
-+{
-+      if (!PageHighMem(pte)) {
-+              unsigned long va = (unsigned long)page_address(pte);
-+              unsigned int level;
-+              pte_t *ptep = lookup_address(va, &level);
-+
-+              BUG_ON(!ptep || level != PG_LEVEL_4K || !pte_present(*ptep));
-+              if (!pte_write(*ptep)
-+                  && HYPERVISOR_update_va_mapping(va,
-+                                                  mk_pte(pte, PAGE_KERNEL),
-+                                                  0))
-+                      BUG();
-+      } else
-+#ifdef CONFIG_HIGHPTE
-+              ClearPagePinned(pte);
-+#else
-+              BUG();
-+#endif
+       spin_lock(&f->tlbstate_lock);
+       f->flush_mm = mm;
+@@ -206,14 +209,14 @@ static void flush_tlb_others(cpumask_t c
+ int __cpuinit init_smp_flush(void)
+ {
+       int i;
 +
-+      ClearPageForeign(pte);
-+      init_page_count(pte);
-+      pgtable_page_dtor(pte);
-+      __free_page(pte);
-+}
+       for_each_cpu_mask(i, cpu_possible_map) {
+               spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock);
+       }
+       return 0;
+ }
+-
+ core_initcall(init_smp_flush);
+-      
 +
-+#if PAGETABLE_LEVELS >= 3
-+static void _pmd_free(struct page *page, unsigned int order)
-+{
-+      BUG_ON(order);
-+      __pmd_free(page);
+ void flush_tlb_current_task(void)
+ {
+       struct mm_struct *mm = current->mm;
+@@ -225,10 +228,9 @@ void flush_tlb_current_task(void)
+       local_flush_tlb();
+       if (!cpus_empty(cpu_mask))
+-              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
++              flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
+       preempt_enable();
+ }
+-EXPORT_SYMBOL(flush_tlb_current_task);
+ void flush_tlb_mm (struct mm_struct * mm)
+ {
+@@ -245,11 +247,10 @@ void flush_tlb_mm (struct mm_struct * mm
+                       leave_mm(smp_processor_id());
+       }
+       if (!cpus_empty(cpu_mask))
+-              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
++              flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
+       preempt_enable();
+ }
+-EXPORT_SYMBOL(flush_tlb_mm);
+ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
+ {
+@@ -263,8 +264,8 @@ void flush_tlb_page(struct vm_area_struc
+       if (current->active_mm == mm) {
+               if(current->mm)
+                       __flush_tlb_one(va);
+-               else
+-                      leave_mm(smp_processor_id());
++              else
++                      leave_mm(smp_processor_id());
+       }
+       if (!cpus_empty(cpu_mask))
+@@ -272,7 +273,6 @@ void flush_tlb_page(struct vm_area_struc
+       preempt_enable();
+ }
+-EXPORT_SYMBOL(flush_tlb_page);
+ static void do_flush_tlb_all(void* info)
+ {
+@@ -330,11 +330,9 @@ void unlock_ipi_call_lock(void)
+  * this function sends a 'generic call function' IPI to all other CPU
+  * of the system defined in the mask.
+  */
+-
+-static int
+-__smp_call_function_mask(cpumask_t mask,
+-                       void (*func)(void *), void *info,
+-                       int wait)
++static int __smp_call_function_mask(cpumask_t mask,
++                                  void (*func)(void *), void *info,
++                                  int wait)
+ {
+       struct call_data_struct data;
+       cpumask_t allbutself;
+@@ -422,11 +420,10 @@ EXPORT_SYMBOL(smp_call_function_mask);
+  */
+ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
+-      int nonatomic, int wait)
++                            int nonatomic, int wait)
+ {
+       /* prevent preemption and reschedule on another processor */
+-      int ret;
+-      int me = get_cpu();
++      int ret, me = get_cpu();
+       /* Can deadlock when called with interrupts disabled */
+       WARN_ON(irqs_disabled());
+@@ -476,9 +473,9 @@ static void stop_this_cpu(void *dummy)
+        */
+       cpu_clear(smp_processor_id(), cpu_online_map);
+       disable_all_local_evtchn();
+-      for (;;) 
++      for (;;)
+               halt();
+-} 
 +}
-+
-+pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+ void smp_send_stop(void)
+ {
+--- sle11-2009-05-14.orig/arch/x86/kernel/time_32-xen.c        2009-03-24 10:12:35.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/time_32-xen.c     2009-03-24 10:12:48.000000000 +0100
+@@ -28,21 +28,9 @@
+  *    serialize accesses to xtime/lost_ticks).
+  */
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
++#include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/time.h>
+-#include <linux/delay.h>
+-#include <linux/init.h>
+-#include <linux/smp.h>
+-#include <linux/module.h>
+-#include <linux/sysdev.h>
+-#include <linux/bcd.h>
+-#include <linux/efi.h>
+ #include <linux/mca.h>
+ #include <linux/sysctl.h>
+ #include <linux/percpu.h>
+@@ -50,26 +38,10 @@
+ #include <linux/posix-timers.h>
+ #include <linux/cpufreq.h>
+ #include <linux/clocksource.h>
++#include <linux/sysdev.h>
+-#include <asm/io.h>
+-#include <asm/smp.h>
+-#include <asm/irq.h>
+-#include <asm/msr.h>
+ #include <asm/delay.h>
+-#include <asm/mpspec.h>
+-#include <asm/uaccess.h>
+-#include <asm/processor.h>
+-#include <asm/timer.h>
+ #include <asm/time.h>
+-#include <asm/sections.h>
+-
+-#include "mach_time.h"
+-
+-#include <linux/timex.h>
+-
+-#include <asm/hpet.h>
+-
+-#include <asm/arch_hooks.h>
+ #include <xen/evtchn.h>
+ #include <xen/sysctl.h>
+@@ -89,9 +61,6 @@ volatile unsigned long __jiffies __secti
+ unsigned int cpu_khz; /* Detected as we calibrate the TSC */
+ EXPORT_SYMBOL(cpu_khz);
+-DEFINE_SPINLOCK(rtc_lock);
+-EXPORT_SYMBOL(rtc_lock);
+-
+ /* These are peridically updated in shared_info, and then copied here. */
+ struct shadow_time_info {
+       u64 tsc_timestamp;     /* TSC at last update of time vals.  */
+@@ -154,6 +123,11 @@ static int __init __independent_wallcloc
+ }
+ __setup("independent_wallclock", __independent_wallclock);
++int xen_independent_wallclock(void)
 +{
-+      struct page *pmd;
-+
-+      pmd = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
-+      if (!pmd)
-+              return NULL;
-+      SetPageForeign(pmd, _pmd_free);
-+      init_page_count(pmd);
-+      return page_address(pmd);
++      return independent_wallclock;
 +}
 +
-+void __pmd_free(pgtable_t pmd)
+ /* Permitted clock jitter, in nsecs, beyond which a warning will be printed. */
+ static unsigned long permitted_clock_jitter = 10000000UL; /* 10ms */
+ static int __init __permitted_clock_jitter(char *str)
+@@ -223,7 +197,6 @@ static inline u64 get64(volatile u64 *pt
+       return cmpxchg64(ptr, 0, 0);
+ #else
+       return *ptr;
+-#define cmpxchg64 cmpxchg
+ #endif
+ }
+@@ -233,7 +206,6 @@ static inline u64 get64_local(volatile u
+       return cmpxchg64_local(ptr, 0, 0);
+ #else
+       return *ptr;
+-#define cmpxchg64_local cmpxchg_local
+ #endif
+ }
+@@ -339,35 +311,6 @@ static inline int time_values_up_to_date
+       return (dst->version == src->version);
+ }
+-/*
+- * This is a special lock that is owned by the CPU and holds the index
+- * register we are working with.  It is required for NMI access to the
+- * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
+- */
+-volatile unsigned long cmos_lock = 0;
+-EXPORT_SYMBOL(cmos_lock);
+-
+-/* Routines for accessing the CMOS RAM/RTC. */
+-unsigned char rtc_cmos_read(unsigned char addr)
+-{
+-      unsigned char val;
+-      lock_cmos_prefix(addr);
+-      outb_p(addr, RTC_PORT(0));
+-      val = inb_p(RTC_PORT(1));
+-      lock_cmos_suffix(addr);
+-      return val;
+-}
+-EXPORT_SYMBOL(rtc_cmos_read);
+-
+-void rtc_cmos_write(unsigned char val, unsigned char addr)
+-{
+-      lock_cmos_prefix(addr);
+-      outb_p(addr, RTC_PORT(0));
+-      outb_p(val, RTC_PORT(1));
+-      lock_cmos_suffix(addr);
+-}
+-EXPORT_SYMBOL(rtc_cmos_write);
+-
+ static void sync_xen_wallclock(unsigned long dummy);
+ static DEFINE_TIMER(sync_xen_wallclock_timer, sync_xen_wallclock, 0, 0);
+ static void sync_xen_wallclock(unsigned long dummy)
+@@ -376,7 +319,8 @@ static void sync_xen_wallclock(unsigned 
+       s64 nsec;
+       struct xen_platform_op op;
+-      if (!ntp_synced() || independent_wallclock || !is_initial_xendomain())
++      BUG_ON(!is_initial_xendomain());
++      if (!ntp_synced() || independent_wallclock)
+               return;
+       write_seqlock_irq(&xtime_lock);
+@@ -399,23 +343,6 @@ static void sync_xen_wallclock(unsigned 
+       mod_timer(&sync_xen_wallclock_timer, jiffies + 60*HZ);
+ }
+-static int set_rtc_mmss(unsigned long nowtime)
+-{
+-      int retval;
+-      unsigned long flags;
+-
+-      if (independent_wallclock || !is_initial_xendomain())
+-              return 0;
+-
+-      /* gets recalled with irq locally disabled */
+-      /* XXX - does irqsave resolve this? -johnstul */
+-      spin_lock_irqsave(&rtc_lock, flags);
+-      retval = set_wallclock(nowtime);
+-      spin_unlock_irqrestore(&rtc_lock, flags);
+-
+-      return retval;
+-}
+-
+ static unsigned long long local_clock(void)
+ {
+       unsigned int cpu = get_cpu();
+@@ -498,28 +425,24 @@ unsigned long profile_pc(struct pt_regs 
+ #if defined(CONFIG_SMP) || defined(__x86_64__)
+ # ifdef __i386__
+-      if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs)
++      if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs)
+ # else
+       if (!user_mode(regs)
+ # endif
+           && in_lock_functions(pc)) {
+ # ifdef CONFIG_FRAME_POINTER
+-#  ifdef __i386__
+-              return ((unsigned long *)regs->ebp)[1];
+-#  else
+-              return ((unsigned long *)regs->rbp)[1];
+-#  endif
++              return ((unsigned long *)regs->bp)[1];
+ # else
+ #  ifdef __i386__
+-              unsigned long *sp = (unsigned long *)&regs->esp;
++              unsigned long *sp = (unsigned long *)&regs->sp;
+ #  else
+-              unsigned long *sp = (unsigned long *)regs->rsp;
++              unsigned long *sp = (unsigned long *)regs->sp;
+ #  endif
+               /* Return address is either directly at stack pointer
+-                 or above a saved eflags. Eflags has bits 22-31 zero,
++                 or above a saved flags. Eflags has bits 22-31 zero,
+                  kernel addresses don't. */
+-              if (sp[0] >> 22)
++              if (sp[0] >> 22)
+                       return sp[0];
+               if (sp[1] >> 22)
+                       return sp[1];
+@@ -748,25 +671,32 @@ static void init_missing_ticks_accountin
+               runstate->time[RUNSTATE_offline];
+ }
+-/* not static: needed by APM */
+-unsigned long read_persistent_clock(void)
++unsigned long xen_read_persistent_clock(void)
+ {
+-      unsigned long retval;
+-      unsigned long flags;
+-
+-      spin_lock_irqsave(&rtc_lock, flags);
++      const shared_info_t *s = HYPERVISOR_shared_info;
++      u32 version, sec, nsec;
++      u64 delta;
+-      retval = get_wallclock();
++      do {
++              version = s->wc_version;
++              rmb();
++              sec     = s->wc_sec;
++              nsec    = s->wc_nsec;
++              rmb();
++      } while ((s->wc_version & 1) | (version ^ s->wc_version));
+-      spin_unlock_irqrestore(&rtc_lock, flags);
++      delta = local_clock() + (u64)sec * NSEC_PER_SEC + nsec;
++      do_div(delta, NSEC_PER_SEC);
+-      return retval;
++      return delta;
+ }
+-int update_persistent_clock(struct timespec now)
++int xen_update_persistent_clock(void)
+ {
++      if (!is_initial_xendomain())
++              return -1;
+       mod_timer(&sync_xen_wallclock_timer, jiffies + 1);
+-      return set_rtc_mmss(now.tv_sec);
++      return 0;
+ }
+ extern void (*late_time_init)(void);
+--- sle11-2009-05-14.orig/arch/x86/kernel/traps_32-xen.c       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/traps_32-xen.c    2009-03-16 16:33:40.000000000 +0100
+@@ -79,7 +79,8 @@ char ignore_fpu_irq = 0;
+  * F0 0F bug workaround.. We have a special link segment
+  * for this.
+  */
+-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
++gate_desc idt_table[256]
++      __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
+ #endif
+ asmlinkage void divide_error(void);
+@@ -109,6 +110,34 @@ asmlinkage void machine_check(void);
+ int kstack_depth_to_print = 24;
+ static unsigned int code_bytes = 64;
++void printk_address(unsigned long address, int reliable)
 +{
-+      unsigned long va = (unsigned long)page_address(pmd);
-+      unsigned int level;
-+      pte_t *ptep = lookup_address(va, &level);
++#ifdef CONFIG_KALLSYMS
++      unsigned long offset = 0, symsize;
++      const char *symname;
++      char *modname;
++      char *delim = ":";
++      char namebuf[128];
++      char reliab[4] = "";
 +
-+      BUG_ON(!ptep || level != PG_LEVEL_4K || !pte_present(*ptep));
-+      if (!pte_write(*ptep)
-+          && HYPERVISOR_update_va_mapping(va, mk_pte(pmd, PAGE_KERNEL), 0))
-+              BUG();
++      symname = kallsyms_lookup(address, &symsize, &offset,
++                                      &modname, namebuf);
++      if (!symname) {
++              printk(" [<%08lx>]\n", address);
++              return;
++      }
++      if (!reliable)
++              strcpy(reliab, "? ");
 +
-+      ClearPageForeign(pmd);
-+      init_page_count(pmd);
-+      __free_page(pmd);
-+}
++      if (!modname)
++              modname = delim = "";
++      printk(" [<%08lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
++              address, reliab, delim, modname, delim, symname, offset, symsize);
++#else
++      printk(" [<%08lx>]\n", address);
 +#endif
-+
-+/* blktap and gntdev need this, as otherwise they would implicitly (and
-+ * needlessly, as they never use it) reference init_mm. */
-+pte_t xen_ptep_get_and_clear_full(struct vm_area_struct *vma,
-+                                unsigned long addr, pte_t *ptep, int full)
-+{
-+      return ptep_get_and_clear_full(vma->vm_mm, addr, ptep, full);
 +}
-+EXPORT_SYMBOL_GPL(xen_ptep_get_and_clear_full);
-+
-+/*
-+ * The current flushing context - we pass it instead of 5 arguments:
-+ */
-+struct cpa_data {
-+      unsigned long   vaddr;
-+      pgprot_t        mask_set;
-+      pgprot_t        mask_clr;
-+      int             numpages;
-+      int             flushtlb;
-+      unsigned long   pfn;
-+};
 +
-+#ifdef CONFIG_X86_64
+ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size)
+ {
+       return  p > (void *)tinfo &&
+@@ -122,48 +151,35 @@ struct stack_frame {
+ };
+ static inline unsigned long print_context_stack(struct thread_info *tinfo,
+-                              unsigned long *stack, unsigned long ebp,
++                              unsigned long *stack, unsigned long bp,
+                               const struct stacktrace_ops *ops, void *data)
+ {
+-#ifdef        CONFIG_FRAME_POINTER
+-      struct stack_frame *frame = (struct stack_frame *)ebp;
+-      while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) {
+-              struct stack_frame *next;
+-              unsigned long addr;
++      struct stack_frame *frame = (struct stack_frame *)bp;
+-              addr = frame->return_address;
+-              ops->address(data, addr);
+-              /*
+-               * break out of recursive entries (such as
+-               * end_of_stack_stop_unwind_function). Also,
+-               * we can never allow a frame pointer to
+-               * move downwards!
+-               */
+-              next = frame->next_frame;
+-              if (next <= frame)
+-                      break;
+-              frame = next;
+-      }
+-#else
+       while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {
+               unsigned long addr;
+-              addr = *stack++;
+-              if (__kernel_text_address(addr))
+-                      ops->address(data, addr);
++              addr = *stack;
++              if (__kernel_text_address(addr)) {
++                      if ((unsigned long) stack == bp + 4) {
++                              ops->address(data, addr, 1);
++                              frame = frame->next_frame;
++                              bp = (unsigned long) frame;
++                      } else {
++                              ops->address(data, addr, bp == 0);
++                      }
++              }
++              stack++;
+       }
+-#endif
+-      return ebp;
++      return bp;
+ }
+ #define MSG(msg) ops->warning(data, msg)
+ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+-              unsigned long *stack,
++              unsigned long *stack, unsigned long bp,
+               const struct stacktrace_ops *ops, void *data)
+ {
+-      unsigned long ebp = 0;
+-
+       if (!task)
+               task = current;
+@@ -171,17 +187,17 @@ void dump_trace(struct task_struct *task
+               unsigned long dummy;
+               stack = &dummy;
+               if (task != current)
+-                      stack = (unsigned long *)task->thread.esp;
++                      stack = (unsigned long *)task->thread.sp;
+       }
+ #ifdef CONFIG_FRAME_POINTER
+-      if (!ebp) {
++      if (!bp) {
+               if (task == current) {
+-                      /* Grab ebp right from our regs */
+-                      asm ("movl %%ebp, %0" : "=r" (ebp) : );
++                      /* Grab bp right from our regs */
++                      asm ("movl %%ebp, %0" : "=r" (bp) : );
+               } else {
+-                      /* ebp is the last reg pushed by switch_to */
+-                      ebp = *(unsigned long *) task->thread.esp;
++                      /* bp is the last reg pushed by switch_to */
++                      bp = *(unsigned long *) task->thread.sp;
+               }
+       }
+ #endif
+@@ -190,7 +206,7 @@ void dump_trace(struct task_struct *task
+               struct thread_info *context;
+               context = (struct thread_info *)
+                       ((unsigned long)stack & (~(THREAD_SIZE - 1)));
+-              ebp = print_context_stack(context, stack, ebp, ops, data);
++              bp = print_context_stack(context, stack, bp, ops, data);
+               /* Should be after the line below, but somewhere
+                  in early boot context comes out corrupted and we
+                  can't reference it -AK */
+@@ -225,9 +241,11 @@ static int print_trace_stack(void *data,
+ /*
+  * Print one address/symbol entries per line.
+  */
+-static void print_trace_address(void *data, unsigned long addr)
++static void print_trace_address(void *data, unsigned long addr, int reliable)
+ {
+       printk("%s [<%08lx>] ", (char *)data, addr);
++      if (!reliable)
++              printk("? ");
+       print_symbol("%s\n", addr);
+       touch_nmi_watchdog();
+ }
+@@ -241,32 +259,32 @@ static const struct stacktrace_ops print
+ static void
+ show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+-                 unsigned long * stack, char *log_lvl)
++              unsigned long *stack, unsigned long bp, char *log_lvl)
+ {
+-      dump_trace(task, regs, stack, &print_trace_ops, log_lvl);
++      dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
+       printk("%s =======================\n", log_lvl);
+ }
+ void show_trace(struct task_struct *task, struct pt_regs *regs,
+-              unsigned long * stack)
++              unsigned long *stack, unsigned long bp)
+ {
+-      show_trace_log_lvl(task, regs, stack, "");
++      show_trace_log_lvl(task, regs, stack, bp, "");
+ }
+ static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+-                             unsigned long *esp, char *log_lvl)
++                     unsigned long *sp, unsigned long bp, char *log_lvl)
+ {
+       unsigned long *stack;
+       int i;
+-      if (esp == NULL) {
++      if (sp == NULL) {
+               if (task)
+-                      esp = (unsigned long*)task->thread.esp;
++                      sp = (unsigned long*)task->thread.sp;
+               else
+-                      esp = (unsigned long *)&esp;
++                      sp = (unsigned long *)&sp;
+       }
+-      stack = esp;
++      stack = sp;
+       for(i = 0; i < kstack_depth_to_print; i++) {
+               if (kstack_end(stack))
+                       break;
+@@ -275,13 +293,13 @@ static void show_stack_log_lvl(struct ta
+               printk("%08lx ", *stack++);
+       }
+       printk("\n%sCall Trace:\n", log_lvl);
+-      show_trace_log_lvl(task, regs, esp, log_lvl);
++      show_trace_log_lvl(task, regs, sp, bp, log_lvl);
+ }
+-void show_stack(struct task_struct *task, unsigned long *esp)
++void show_stack(struct task_struct *task, unsigned long *sp)
+ {
+       printk("       ");
+-      show_stack_log_lvl(task, NULL, esp, "");
++      show_stack_log_lvl(task, NULL, sp, 0, "");
+ }
+ /*
+@@ -290,13 +308,19 @@ void show_stack(struct task_struct *task
+ void dump_stack(void)
+ {
+       unsigned long stack;
++      unsigned long bp = 0;
 +
-+static inline unsigned long highmap_start_pfn(void)
-+{
-+      return __pa(_text) >> PAGE_SHIFT;
-+}
++#ifdef CONFIG_FRAME_POINTER
++      if (!bp)
++              asm("movl %%ebp, %0" : "=r" (bp):);
++#endif
+       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+               current->pid, current->comm, print_tainted(),
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
+-      show_trace(current, NULL, &stack);
++      show_trace(current, NULL, &stack, bp);
+ }
+ EXPORT_SYMBOL(dump_stack);
+@@ -315,30 +339,30 @@ void show_registers(struct pt_regs *regs
+        * time of the fault..
+        */
+       if (!user_mode_vm(regs)) {
+-              u8 *eip;
++              u8 *ip;
+               unsigned int code_prologue = code_bytes * 43 / 64;
+               unsigned int code_len = code_bytes;
+               unsigned char c;
+               printk("\n" KERN_EMERG "Stack: ");
+-              show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
++              show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
+               printk(KERN_EMERG "Code: ");
+-              eip = (u8 *)regs->eip - code_prologue;
+-              if (eip < (u8 *)PAGE_OFFSET ||
+-                      probe_kernel_address(eip, c)) {
++              ip = (u8 *)regs->ip - code_prologue;
++              if (ip < (u8 *)PAGE_OFFSET ||
++                      probe_kernel_address(ip, c)) {
+                       /* try starting at EIP */
+-                      eip = (u8 *)regs->eip;
++                      ip = (u8 *)regs->ip;
+                       code_len = code_len - code_prologue + 1;
+               }
+-              for (i = 0; i < code_len; i++, eip++) {
+-                      if (eip < (u8 *)PAGE_OFFSET ||
+-                              probe_kernel_address(eip, c)) {
++              for (i = 0; i < code_len; i++, ip++) {
++                      if (ip < (u8 *)PAGE_OFFSET ||
++                              probe_kernel_address(ip, c)) {
+                               printk(" Bad EIP value.");
+                               break;
+                       }
+-                      if (eip == (u8 *)regs->eip)
++                      if (ip == (u8 *)regs->ip)
+                               printk("<%02x> ", c);
+                       else
+                               printk("%02x ", c);
+@@ -347,18 +371,57 @@ void show_registers(struct pt_regs *regs
+       printk("\n");
+ }     
+-int is_valid_bugaddr(unsigned long eip)
++int is_valid_bugaddr(unsigned long ip)
+ {
+       unsigned short ud2;
+-      if (eip < PAGE_OFFSET)
++      if (ip < PAGE_OFFSET)
+               return 0;
+-      if (probe_kernel_address((unsigned short *)eip, ud2))
++      if (probe_kernel_address((unsigned short *)ip, ud2))
+               return 0;
+       return ud2 == 0x0b0f;
+ }
++static int die_counter;
 +
-+static inline unsigned long highmap_end_pfn(void)
++int __kprobes __die(const char * str, struct pt_regs * regs, long err)
 +{
-+      return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
-+}
++      unsigned long sp;
++      unsigned short ss;
 +
++      printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
++#ifdef CONFIG_PREEMPT
++      printk("PREEMPT ");
++#endif
++#ifdef CONFIG_SMP
++      printk("SMP ");
 +#endif
-+
 +#ifdef CONFIG_DEBUG_PAGEALLOC
-+# define debug_pagealloc 1
-+#else
-+# define debug_pagealloc 0
++      printk("DEBUG_PAGEALLOC");
 +#endif
++      printk("\n");
 +
-+static inline int
-+within(unsigned long addr, unsigned long start, unsigned long end)
-+{
-+      return addr >= start && addr < end;
-+}
-+
-+/*
-+ * Flushing functions
-+ */
-+
-+/**
-+ * clflush_cache_range - flush a cache range with clflush
-+ * @addr:     virtual start address
-+ * @size:     number of bytes to flush
-+ *
-+ * clflush is an unordered instruction which needs fencing with mfence
-+ * to avoid ordering issues.
-+ */
-+void clflush_cache_range(void *vaddr, unsigned int size)
-+{
-+      void *vend = vaddr + size - 1;
-+
-+      mb();
-+
-+      for (; vaddr < vend; vaddr += boot_cpu_data.x86_clflush_size)
-+              clflush(vaddr);
-+      /*
-+       * Flush any possible final partial cacheline:
-+       */
-+      clflush(vend);
-+
-+      mb();
-+}
-+
-+static void __cpa_flush_all(void *arg)
-+{
-+      unsigned long cache = (unsigned long)arg;
-+
-+      /*
-+       * Flush all to work around Errata in early athlons regarding
-+       * large page flushing.
-+       */
-+      __flush_tlb_all();
-+
-+      if (cache && boot_cpu_data.x86_model >= 4)
-+              wbinvd();
-+}
-+
-+static void cpa_flush_all(unsigned long cache)
-+{
-+      BUG_ON(irqs_disabled());
-+
-+      on_each_cpu(__cpa_flush_all, (void *) cache, 1, 1);
-+}
-+
-+static void __cpa_flush_range(void *arg)
-+{
-+      /*
-+       * We could optimize that further and do individual per page
-+       * tlb invalidates for a low number of pages. Caveat: we must
-+       * flush the high aliases on 64bit as well.
-+       */
-+      __flush_tlb_all();
++      if (notify_die(DIE_OOPS, str, regs, err,
++                              current->thread.trap_no, SIGSEGV) !=
++                      NOTIFY_STOP) {
++              show_registers(regs);
++              /* Executive summary in case the oops scrolled away */
++              sp = (unsigned long) (&regs->sp);
++              savesegment(ss, ss);
++              if (user_mode(regs)) {
++                      sp = regs->sp;
++                      ss = regs->ss & 0xffff;
++              }
++              printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
++              print_symbol("%s", regs->ip);
++              printk(" SS:ESP %04x:%08lx\n", ss, sp);
++              return 0;
++      } else {
++              return 1;
++      }
 +}
 +
-+static void cpa_flush_range(unsigned long start, int numpages, int cache)
-+{
-+      unsigned int i, level;
-+      unsigned long addr;
-+
-+      BUG_ON(irqs_disabled());
-+      WARN_ON(PAGE_ALIGN(start) != start);
-+
-+      on_each_cpu(__cpa_flush_range, NULL, 1, 1);
-+
-+      if (!cache)
-+              return;
-+
-+      /*
-+       * We only need to flush on one CPU,
-+       * clflush is a MESI-coherent instruction that
-+       * will cause all other CPUs to flush the same
-+       * cachelines:
-+       */
-+      for (i = 0, addr = start; i < numpages; i++, addr += PAGE_SIZE) {
-+              pte_t *pte = lookup_address(addr, &level);
-+
-+              /*
-+               * Only flush present addresses:
-+               */
-+              if (pte && (__pte_val(*pte) & _PAGE_PRESENT))
-+                      clflush_cache_range((void *) addr, PAGE_SIZE);
+ /*
+  * This is gone through when something in the kernel has done something bad and
+  * is about to be terminated.
+@@ -374,7 +437,6 @@ void die(const char * str, struct pt_reg
+               .lock_owner =           -1,
+               .lock_owner_depth =     0
+       };
+-      static int die_counter;
+       unsigned long flags;
+       oops_enter();
+@@ -390,43 +452,13 @@ void die(const char * str, struct pt_reg
+               raw_local_irq_save(flags);
+       if (++die.lock_owner_depth < 3) {
+-              unsigned long esp;
+-              unsigned short ss;
+-
+-              report_bug(regs->eip, regs);
+-
+-              printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
+-                     ++die_counter);
+-#ifdef CONFIG_PREEMPT
+-              printk("PREEMPT ");
+-#endif
+-#ifdef CONFIG_SMP
+-              printk("SMP ");
+-#endif
+-#ifdef CONFIG_DEBUG_PAGEALLOC
+-              printk("DEBUG_PAGEALLOC");
+-#endif
+-              printk("\n");
++              report_bug(regs->ip, regs);
+-              if (notify_die(DIE_OOPS, str, regs, err,
+-                                      current->thread.trap_no, SIGSEGV) !=
+-                              NOTIFY_STOP) {
+-                      show_registers(regs);
+-                      /* Executive summary in case the oops scrolled away */
+-                      esp = (unsigned long) (&regs->esp);
+-                      savesegment(ss, ss);
+-                      if (user_mode(regs)) {
+-                              esp = regs->esp;
+-                              ss = regs->xss & 0xffff;
+-                      }
+-                      printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip);
+-                      print_symbol("%s", regs->eip);
+-                      printk(" SS:ESP %04x:%08lx\n", ss, esp);
+-              }
+-              else
++              if (__die(str, regs, err))
+                       regs = NULL;
+-      } else
++      } else {
+               printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
++      }
+       bust_spinlocks(0);
+       die.lock_owner = -1;
+@@ -462,7 +494,7 @@ static void __kprobes do_trap(int trapnr
+ {
+       struct task_struct *tsk = current;
+-      if (regs->eflags & VM_MASK) {
++      if (regs->flags & VM_MASK) {
+               if (vm86)
+                       goto vm86_trap;
+               goto trap_signal;
+@@ -508,7 +540,7 @@ static void __kprobes do_trap(int trapnr
+ }
+ #define DO_ERROR(trapnr, signr, str, name) \
+-fastcall void do_##name(struct pt_regs * regs, long error_code) \
++void do_##name(struct pt_regs * regs, long error_code) \
+ { \
+       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
+                                               == NOTIFY_STOP) \
+@@ -517,7 +549,7 @@ fastcall void do_##name(struct pt_regs *
+ }
+ #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \
+-fastcall void do_##name(struct pt_regs * regs, long error_code) \
++void do_##name(struct pt_regs * regs, long error_code) \
+ { \
+       siginfo_t info; \
+       if (irq) \
+@@ -533,7 +565,7 @@ fastcall void do_##name(struct pt_regs *
+ }
+ #define DO_VM86_ERROR(trapnr, signr, str, name) \
+-fastcall void do_##name(struct pt_regs * regs, long error_code) \
++void do_##name(struct pt_regs * regs, long error_code) \
+ { \
+       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
+                                               == NOTIFY_STOP) \
+@@ -542,7 +574,7 @@ fastcall void do_##name(struct pt_regs *
+ }
+ #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
+-fastcall void do_##name(struct pt_regs * regs, long error_code) \
++void do_##name(struct pt_regs * regs, long error_code) \
+ { \
+       siginfo_t info; \
+       info.si_signo = signr; \
+@@ -556,13 +588,13 @@ fastcall void do_##name(struct pt_regs *
+       do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
+ }
+-DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
++DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->ip)
+ #ifndef CONFIG_KPROBES
+ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
+ #endif
+ DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
+ DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
+-DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip, 0)
++DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
+ DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
+ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
+ DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
+@@ -570,10 +602,10 @@ DO_ERROR(12, SIGBUS,  "stack segment", s
+ DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
+ DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1)
+-fastcall void __kprobes do_general_protection(struct pt_regs * regs,
++void __kprobes do_general_protection(struct pt_regs * regs,
+                                             long error_code)
+ {
+-      if (regs->eflags & VM_MASK)
++      if (regs->flags & VM_MASK)
+               goto gp_in_vm86;
+       if (!user_mode(regs))
+@@ -582,11 +614,14 @@ fastcall void __kprobes do_general_prote
+       current->thread.error_code = error_code;
+       current->thread.trap_no = 13;
+       if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
+-          printk_ratelimit())
++          printk_ratelimit()) {
+               printk(KERN_INFO
+-                  "%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
++                  "%s[%d] general protection ip:%lx sp:%lx error:%lx",
+                   current->comm, task_pid_nr(current),
+-                  regs->eip, regs->esp, error_code);
++                  regs->ip, regs->sp, error_code);
++              print_vma_addr(" in ", regs->ip);
++              printk("\n");
 +      }
-+}
-+
-+/*
-+ * Certain areas of memory on x86 require very specific protection flags,
-+ * for example the BIOS area or kernel text. Callers don't always get this
-+ * right (again, ioremap() on BIOS memory is not uncommon) so this function
-+ * checks and fixes these known static required protection bits.
-+ */
-+static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
-+                                 unsigned long pfn)
-+{
-+      pgprot_t forbidden = __pgprot(0);
-+
-+#ifndef CONFIG_XEN
-+      /*
-+       * The BIOS area between 640k and 1Mb needs to be executable for
-+       * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
-+       */
-+      if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
-+              pgprot_val(forbidden) |= _PAGE_NX;
-+#endif
-+
+       force_sig(SIGSEGV, current);
+       return;
+@@ -675,8 +710,8 @@ void __kprobes die_nmi(struct pt_regs *r
+       */
+       bust_spinlocks(1);
+       printk(KERN_EMERG "%s", msg);
+-      printk(" on CPU%d, eip %08lx, registers:\n",
+-              smp_processor_id(), regs->eip);
++      printk(" on CPU%d, ip %08lx, registers:\n",
++              smp_processor_id(), regs->ip);
+       show_registers(regs);
+       console_silent();
+       spin_unlock(&nmi_print_lock);
+@@ -733,7 +768,7 @@ static __kprobes void default_do_nmi(str
+ static int ignore_nmis;
+-fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
++__kprobes void do_nmi(struct pt_regs * regs, long error_code)
+ {
+       int cpu;
+@@ -762,7 +797,7 @@ void restart_nmi(void)
+ }
+ #ifdef CONFIG_KPROBES
+-fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
++void __kprobes do_int3(struct pt_regs *regs, long error_code)
+ {
+       trace_hardirqs_fixup();
+@@ -798,7 +833,7 @@ fastcall void __kprobes do_int3(struct p
+  * find every occurrence of the TF bit that could be saved away even
+  * by user code)
+  */
+-fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
++void __kprobes do_debug(struct pt_regs * regs, long error_code)
+ {
+       unsigned int condition;
+       struct task_struct *tsk = current;
+@@ -807,24 +842,30 @@ fastcall void __kprobes do_debug(struct 
+       get_debugreg(condition, 6);
 +      /*
-+       * The kernel text needs to be executable for obvious reasons
-+       * Does not cover __inittext since that is gone later on. On
-+       * 64bit we do not enforce !NX on the low mapping
++       * The processor cleared BTF, so don't mark that we need it set.
 +       */
-+      if (within(address, (unsigned long)_text, (unsigned long)_etext))
-+              pgprot_val(forbidden) |= _PAGE_NX;
++      clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
++      tsk->thread.debugctlmsr = 0;
 +
+       if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
+                                       SIGTRAP) == NOTIFY_STOP)
+               return;
+       /* It's safe to allow irq's after DR6 has been saved */
+-      if (regs->eflags & X86_EFLAGS_IF)
++      if (regs->flags & X86_EFLAGS_IF)
+               local_irq_enable();
+       /* Mask out spurious debug traps due to lazy DR7 setting */
+       if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
+-              if (!tsk->thread.debugreg[7])
++              if (!tsk->thread.debugreg7)
+                       goto clear_dr7;
+       }
+-      if (regs->eflags & VM_MASK)
++      if (regs->flags & VM_MASK)
+               goto debug_vm86;
+       /* Save debug status register where ptrace can see it */
+-      tsk->thread.debugreg[6] = condition;
++      tsk->thread.debugreg6 = condition;
+       /*
+        * Single-stepping through TF: make sure we ignore any events in
+@@ -856,7 +897,7 @@ debug_vm86:
+ clear_TF_reenable:
+       set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+-      regs->eflags &= ~TF_MASK;
++      regs->flags &= ~TF_MASK;
+       return;
+ }
+@@ -865,7 +906,7 @@ clear_TF_reenable:
+  * the correct behaviour even in the presence of the asynchronous
+  * IRQ13 behaviour
+  */
+-void math_error(void __user *eip)
++void math_error(void __user *ip)
+ {
+       struct task_struct * task;
+       siginfo_t info;
+@@ -881,7 +922,7 @@ void math_error(void __user *eip)
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_code = __SI_FAULT;
+-      info.si_addr = eip;
++      info.si_addr = ip;
+       /*
+        * (~cwd & swd) will mask out exceptions that are not set to unmasked
+        * status.  0x3f is the exception bits in these regs, 0x200 is the
+@@ -924,13 +965,13 @@ void math_error(void __user *eip)
+       force_sig_info(SIGFPE, &info, task);
+ }
+-fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code)
++void do_coprocessor_error(struct pt_regs * regs, long error_code)
+ {
+       ignore_fpu_irq = 1;
+-      math_error((void __user *)regs->eip);
++      math_error((void __user *)regs->ip);
+ }
+-static void simd_math_error(void __user *eip)
++static void simd_math_error(void __user *ip)
+ {
+       struct task_struct * task;
+       siginfo_t info;
+@@ -946,7 +987,7 @@ static void simd_math_error(void __user 
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_code = __SI_FAULT;
+-      info.si_addr = eip;
++      info.si_addr = ip;
+       /*
+        * The SIMD FPU exceptions are handled a little differently, as there
+        * is only a single status/control register.  Thus, to determine which
+@@ -978,19 +1019,19 @@ static void simd_math_error(void __user 
+       force_sig_info(SIGFPE, &info, task);
+ }
+-fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
++void do_simd_coprocessor_error(struct pt_regs * regs,
+                                         long error_code)
+ {
+       if (cpu_has_xmm) {
+               /* Handle SIMD FPU exceptions on PIII+ processors. */
+               ignore_fpu_irq = 1;
+-              simd_math_error((void __user *)regs->eip);
++              simd_math_error((void __user *)regs->ip);
+       } else {
+               /*
+                * Handle strange cache flush from user space exception
+                * in all other cases.  This is undocumented behaviour.
+                */
+-              if (regs->eflags & VM_MASK) {
++              if (regs->flags & VM_MASK) {
+                       handle_vm86_fault((struct kernel_vm86_regs *)regs,
+                                         error_code);
+                       return;
+@@ -1003,7 +1044,7 @@ fastcall void do_simd_coprocessor_error(
+ }
+ #ifndef CONFIG_XEN
+-fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
++void do_spurious_interrupt_bug(struct pt_regs * regs,
+                                         long error_code)
+ {
+ #if 0
+@@ -1012,7 +1053,7 @@ fastcall void do_spurious_interrupt_bug(
+ #endif
+ }
+-fastcall unsigned long patch_espfix_desc(unsigned long uesp,
++unsigned long patch_espfix_desc(unsigned long uesp,
+                                         unsigned long kesp)
+ {
+       struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
+@@ -1072,7 +1113,7 @@ asmlinkage void math_emulate(long arg)
+  * NB. All these are "trap gates" (i.e. events_mask isn't set) except
+  * for those that specify <dpl>|4 in the second field.
+  */
+-static trap_info_t __cpuinitdata trap_table[] = {
++static const trap_info_t __cpuinitconst trap_table[] = {
+       {  0, 0, __KERNEL_CS, (unsigned long)divide_error               },
+       {  1, 0|4, __KERNEL_CS, (unsigned long)debug                    },
+       {  3, 3|4, __KERNEL_CS, (unsigned long)int3                     },
+@@ -1105,17 +1146,12 @@ void __init trap_init(void)
+       if (ret)
+               printk("HYPERVISOR_set_trap_table failed: error %d\n", ret);
 +      /*
-+       * The .rodata section needs to be read-only. Using the pfn
-+       * catches all aliases.
++       * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
++       * Generate a build-time error if the alignment is wrong.
 +       */
-+      if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
-+                 __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
-+              pgprot_val(forbidden) |= _PAGE_RW;
++      BUILD_BUG_ON(offsetof(struct task_struct, thread.i387.fxsave) & 15);
+       if (cpu_has_fxsr) {
+-              /*
+-               * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
+-               * Generates a compile-time "error: zero width for bit-field" if
+-               * the alignment is wrong.
+-               */
+-              struct fxsrAlignAssert {
+-                      int _:!(offsetof(struct task_struct,
+-                                      thread.i387.fxsave) & 15);
+-              };
+-
+               printk(KERN_INFO "Enabling fast FPU save and restore... ");
+               set_in_cr4(X86_CR4_OSFXSR);
+               printk("done.\n");
+--- sle11-2009-05-14.orig/arch/x86/kernel/traps_64-xen.c       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/traps_64-xen.c    2009-03-16 16:33:40.000000000 +0100
+@@ -74,38 +74,41 @@ asmlinkage void alignment_check(void);
+ asmlinkage void machine_check(void);
+ asmlinkage void spurious_interrupt_bug(void);
++static unsigned int code_bytes = 64;
 +
-+      prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
+ static inline void conditional_sti(struct pt_regs *regs)
+ {
+-      if (regs->eflags & X86_EFLAGS_IF)
++      if (regs->flags & X86_EFLAGS_IF)
+               local_irq_enable();
+ }
+ static inline void preempt_conditional_sti(struct pt_regs *regs)
+ {
+-      preempt_disable();
+-      if (regs->eflags & X86_EFLAGS_IF)
++      inc_preempt_count();
++      if (regs->flags & X86_EFLAGS_IF)
+               local_irq_enable();
+ }
+ static inline void preempt_conditional_cli(struct pt_regs *regs)
+ {
+-      if (regs->eflags & X86_EFLAGS_IF)
++      if (regs->flags & X86_EFLAGS_IF)
+               local_irq_disable();
+       /* Make sure to not schedule here because we could be running
+          on an exception stack. */
+-      preempt_enable_no_resched();
++      dec_preempt_count();
+ }
+ int kstack_depth_to_print = 12;
+-#ifdef CONFIG_KALLSYMS
+-void printk_address(unsigned long address)
++void printk_address(unsigned long address, int reliable)
+ {
++#ifdef CONFIG_KALLSYMS
+       unsigned long offset = 0, symsize;
+       const char *symname;
+       char *modname;
+       char *delim = ":";
+-      char namebuf[128];
++      char namebuf[KSYM_NAME_LEN];
++      char reliab[4] = "";
+       symname = kallsyms_lookup(address, &symsize, &offset,
+                                       &modname, namebuf);
+@@ -113,17 +116,17 @@ void printk_address(unsigned long addres
+               printk(" [<%016lx>]\n", address);
+               return;
+       }
++      if (!reliable)
++              strcpy(reliab, "? ");
 +
-+      return prot;
+       if (!modname)
+-              modname = delim = "";           
+-      printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n",
+-              address, delim, modname, delim, symname, offset, symsize);
+-}
++              modname = delim = "";
++      printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
++              address, reliab, delim, modname, delim, symname, offset, symsize);
+ #else
+-void printk_address(unsigned long address)
+-{
+       printk(" [<%016lx>]\n", address);
+-}
+ #endif
++}
+ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
+                                       unsigned *usedp, char **idp)
+@@ -210,14 +213,53 @@ static unsigned long *in_exception_stack
+  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
+  */
+-static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
++static inline int valid_stack_ptr(struct thread_info *tinfo,
++                      void *p, unsigned int size, void *end)
+ {
+-      void *t = (void *)tinfo;
+-        return p > t && p < t + THREAD_SIZE - 3;
++      void *t = tinfo;
++      if (end) {
++              if (p < end && p >= (end-THREAD_SIZE))
++                      return 1;
++              else
++                      return 0;
++      }
++      return p > t && p < t + THREAD_SIZE - size;
 +}
 +
-+/*
-+ * Lookup the page table entry for a virtual address. Return a pointer
-+ * to the entry and the level of the mapping.
-+ *
-+ * Note: We return pud and pmd either when the entry is marked large
-+ * or when the present bit is not set. Otherwise we would return a
-+ * pointer to a nonexisting mapping.
-+ */
-+pte_t *lookup_address(unsigned long address, unsigned int *level)
-+{
-+      pgd_t *pgd = pgd_offset_k(address);
-+      pud_t *pud;
-+      pmd_t *pmd;
-+
-+      *level = PG_LEVEL_NONE;
-+
-+      if (pgd_none(*pgd))
-+              return NULL;
-+
-+      pud = pud_offset(pgd, address);
-+      if (pud_none(*pud))
-+              return NULL;
-+
-+      *level = PG_LEVEL_1G;
-+      if (pud_large(*pud) || !pud_present(*pud))
-+              return (pte_t *)pud;
-+
-+      pmd = pmd_offset(pud, address);
-+      if (pmd_none(*pmd))
-+              return NULL;
-+
-+      *level = PG_LEVEL_2M;
-+      if (pmd_large(*pmd) || !pmd_present(*pmd))
-+              return (pte_t *)pmd;
-+
-+      *level = PG_LEVEL_4K;
++/* The form of the top of the frame on the stack */
++struct stack_frame {
++      struct stack_frame *next_frame;
++      unsigned long return_address;
++};
 +
-+      return pte_offset_kernel(pmd, address);
-+}
 +
-+/*
-+ * Set the new pmd in all the pgds we know about:
-+ */
-+static void __set_pmd_pte(pte_t *kpte, unsigned long address,
-+                        unsigned int level, pte_t pte)
++static inline unsigned long print_context_stack(struct thread_info *tinfo,
++                              unsigned long *stack, unsigned long bp,
++                              const struct stacktrace_ops *ops, void *data,
++                              unsigned long *end)
 +{
-+      /* change init_mm */
-+      switch(level) {
-+      case PG_LEVEL_2M:
-+              xen_l2_entry_update((pmd_t *)kpte, __pmd_ma(__pte_val(pte)));
-+              break;
-+#ifdef CONFIG_X86_64
-+      case PG_LEVEL_1G:
-+              xen_l3_entry_update((pud_t *)kpte, __pud_ma(__pte_val(pte)));
-+              break;
-+#endif
-+      default:
-+              BUG();
-+      }
-+#ifdef CONFIG_X86_32
-+      if (!SHARED_KERNEL_PMD) {
-+              struct page *page;
++      struct stack_frame *frame = (struct stack_frame *)bp;
 +
-+              list_for_each_entry(page, &pgd_list, lru) {
-+                      pgd_t *pgd;
-+                      pud_t *pud;
-+                      pmd_t *pmd;
++      while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
++              unsigned long addr;
 +
-+                      pgd = (pgd_t *)page_address(page) + pgd_index(address);
-+                      pud = pud_offset(pgd, address);
-+                      pmd = pmd_offset(pud, address);
-+                      xen_l2_entry_update(pmd, __pmd_ma(__pte_val(pte)));
++              addr = *stack;
++              if (__kernel_text_address(addr)) {
++                      if ((unsigned long) stack == bp + 8) {
++                              ops->address(data, addr, 1);
++                              frame = frame->next_frame;
++                              bp = (unsigned long) frame;
++                      } else {
++                              ops->address(data, addr, bp == 0);
++                      }
++              }
++              stack++;
++      }
++      return bp;
+ }
+ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+-              unsigned long *stack,
++              unsigned long *stack, unsigned long bp,
+               const struct stacktrace_ops *ops, void *data)
+ {
+       const unsigned cpu = get_cpu();
+@@ -227,36 +269,28 @@ void dump_trace(struct task_struct *tsk,
+       if (!tsk)
+               tsk = current;
++      tinfo = task_thread_info(tsk);
+       if (!stack) {
+               unsigned long dummy;
+               stack = &dummy;
+               if (tsk && tsk != current)
+-                      stack = (unsigned long *)tsk->thread.rsp;
++                      stack = (unsigned long *)tsk->thread.sp;
+       }
+-      /*
+-       * Print function call entries within a stack. 'cond' is the
+-       * "end of stackframe" condition, that the 'stack++'
+-       * iteration will eventually trigger.
+-       */
+-#define HANDLE_STACK(cond) \
+-      do while (cond) { \
+-              unsigned long addr = *stack++; \
+-              /* Use unlocked access here because except for NMIs     \
+-                 we should be already protected against module unloads */ \
+-              if (__kernel_text_address(addr)) { \
+-                      /* \
+-                       * If the address is either in the text segment of the \
+-                       * kernel, or in the region which contains vmalloc'ed \
+-                       * memory, it *may* be the address of a calling \
+-                       * routine; if so, print it so that someone tracing \
+-                       * down the cause of the crash will be able to figure \
+-                       * out the call path that was taken. \
+-                       */ \
+-                      ops->address(data, addr);   \
+-              } \
+-      } while (0)
++#ifdef CONFIG_FRAME_POINTER
++      if (!bp) {
++              if (tsk == current) {
++                      /* Grab bp right from our regs */
++                      asm("movq %%rbp, %0" : "=r" (bp):);
++              } else {
++                      /* bp is the last reg pushed by switch_to */
++                      bp = *(unsigned long *) tsk->thread.sp;
 +              }
 +      }
 +#endif
-+}
 +
-+static int
-+try_preserve_large_page(pte_t *kpte, unsigned long address,
-+                      struct cpa_data *cpa)
-+{
-+      unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn;
-+      pte_t new_pte, old_pte, *tmp;
-+      pgprot_t old_prot, new_prot;
-+      int i, do_split = 1;
-+      unsigned int level;
 +
-+      spin_lock_irqsave(&pgd_lock, flags);
-+      /*
-+       * Check for races, another CPU might have split this page
-+       * up already:
-+       */
-+      tmp = lookup_address(address, &level);
-+      if (tmp != kpte)
-+              goto out_unlock;
+       /*
+        * Print function call entries in all stacks, starting at the
+@@ -272,7 +306,9 @@ void dump_trace(struct task_struct *tsk,
+               if (estack_end) {
+                       if (ops->stack(data, id) < 0)
+                               break;
+-                      HANDLE_STACK (stack < estack_end);
 +
-+      switch (level) {
-+      case PG_LEVEL_2M:
-+              psize = PMD_PAGE_SIZE;
-+              pmask = PMD_PAGE_MASK;
-+              break;
-+#ifdef CONFIG_X86_64
-+      case PG_LEVEL_1G:
-+              psize = PUD_PAGE_SIZE;
-+              pmask = PUD_PAGE_MASK;
-+              break;
++                      bp = print_context_stack(tinfo, stack, bp, ops,
++                                                      data, estack_end);
+                       ops->stack(data, "<EOE>");
+                       /*
+                        * We link to the next stack via the
+@@ -290,7 +326,8 @@ void dump_trace(struct task_struct *tsk,
+                       if (stack >= irqstack && stack < irqstack_end) {
+                               if (ops->stack(data, "IRQ") < 0)
+                                       break;
+-                              HANDLE_STACK (stack < irqstack_end);
++                              bp = print_context_stack(tinfo, stack, bp,
++                                              ops, data, irqstack_end);
+                               /*
+                                * We link to the next stack (which would be
+                                * the process stack normally) the last
+@@ -308,9 +345,7 @@ void dump_trace(struct task_struct *tsk,
+       /*
+        * This handles the process stack:
+        */
+-      tinfo = task_thread_info(tsk);
+-      HANDLE_STACK (valid_stack_ptr(tinfo, stack));
+-#undef HANDLE_STACK
++      bp = print_context_stack(tinfo, stack, bp, ops, data, NULL);
+       put_cpu();
+ }
+ EXPORT_SYMBOL(dump_trace);
+@@ -333,10 +368,10 @@ static int print_trace_stack(void *data,
+       return 0;
+ }
+-static void print_trace_address(void *data, unsigned long addr)
++static void print_trace_address(void *data, unsigned long addr, int reliable)
+ {
+       touch_nmi_watchdog();
+-      printk_address(addr);
++      printk_address(addr, reliable);
+ }
+ static const struct stacktrace_ops print_trace_ops = {
+@@ -347,15 +382,17 @@ static const struct stacktrace_ops print
+ };
+ void
+-show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack)
++show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
++              unsigned long bp)
+ {
+       printk("\nCall Trace:\n");
+-      dump_trace(tsk, regs, stack, &print_trace_ops, NULL);
++      dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL);
+       printk("\n");
+ }
+ static void
+-_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
++_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp,
++                                                      unsigned long bp)
+ {
+       unsigned long *stack;
+       int i;
+@@ -366,14 +403,14 @@ _show_stack(struct task_struct *tsk, str
+       // debugging aid: "show_stack(NULL, NULL);" prints the
+       // back trace for this cpu.
+-      if (rsp == NULL) {
++      if (sp == NULL) {
+               if (tsk)
+-                      rsp = (unsigned long *)tsk->thread.rsp;
++                      sp = (unsigned long *)tsk->thread.sp;
+               else
+-                      rsp = (unsigned long *)&rsp;
++                      sp = (unsigned long *)&sp;
+       }
+-      stack = rsp;
++      stack = sp;
+       for(i=0; i < kstack_depth_to_print; i++) {
+               if (stack >= irqstack && stack <= irqstack_end) {
+                       if (stack == irqstack_end) {
+@@ -389,12 +426,12 @@ _show_stack(struct task_struct *tsk, str
+               printk(" %016lx", *stack++);
+               touch_nmi_watchdog();
+       }
+-      show_trace(tsk, regs, rsp);
++      show_trace(tsk, regs, sp, bp);
+ }
+-void show_stack(struct task_struct *tsk, unsigned long * rsp)
++void show_stack(struct task_struct *tsk, unsigned long * sp)
+ {
+-      _show_stack(tsk, NULL, rsp);
++      _show_stack(tsk, NULL, sp, 0);
+ }
+ /*
+@@ -403,13 +440,19 @@ void show_stack(struct task_struct *tsk,
+ void dump_stack(void)
+ {
+       unsigned long dummy;
++      unsigned long bp = 0;
++
++#ifdef CONFIG_FRAME_POINTER
++      if (!bp)
++              asm("movq %%rbp, %0" : "=r" (bp):);
 +#endif
-+      default:
-+              do_split = -EINVAL;
-+              goto out_unlock;
+       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+               current->pid, current->comm, print_tainted(),
+               init_utsname()->release,
+               (int)strcspn(init_utsname()->version, " "),
+               init_utsname()->version);
+-      show_trace(NULL, NULL, &dummy);
++      show_trace(NULL, NULL, &dummy, bp);
+ }
+ EXPORT_SYMBOL(dump_stack);
+@@ -417,12 +460,15 @@ EXPORT_SYMBOL(dump_stack);
+ void show_registers(struct pt_regs *regs)
+ {
+       int i;
+-      int in_kernel = !user_mode(regs);
+-      unsigned long rsp;
++      unsigned long sp;
+       const int cpu = smp_processor_id();
+       struct task_struct *cur = cpu_pda(cpu)->pcurrent;
++      u8 *ip;
++      unsigned int code_prologue = code_bytes * 43 / 64;
++      unsigned int code_len = code_bytes;
+-      rsp = regs->rsp;
++      sp = regs->sp;
++      ip = (u8 *) regs->ip - code_prologue;
+       printk("CPU %d ", cpu);
+       __show_regs(regs);
+       printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
+@@ -432,45 +478,43 @@ void show_registers(struct pt_regs *regs
+        * When in-kernel, we also print out the stack and code at the
+        * time of the fault..
+        */
+-      if (in_kernel) {
++      if (!user_mode(regs)) {
++              unsigned char c;
+               printk("Stack: ");
+-              _show_stack(NULL, regs, (unsigned long*)rsp);
++              _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
++              printk("\n");
+-              printk("\nCode: ");
+-              if (regs->rip < PAGE_OFFSET)
+-                      goto bad;
+-
+-              for (i=0; i<20; i++) {
+-                      unsigned char c;
+-                      if (__get_user(c, &((unsigned char*)regs->rip)[i])) {
+-bad:
++              printk(KERN_EMERG "Code: ");
++              if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
++                      /* try starting at RIP */
++                      ip = (u8 *) regs->ip;
++                      code_len = code_len - code_prologue + 1;
++              }
++              for (i = 0; i < code_len; i++, ip++) {
++                      if (ip < (u8 *)PAGE_OFFSET ||
++                                      probe_kernel_address(ip, c)) {
+                               printk(" Bad RIP value.");
+                               break;
+                       }
+-                      printk("%02x ", c);
++                      if (ip == (u8 *)regs->ip)
++                              printk("<%02x> ", c);
++                      else
++                              printk("%02x ", c);
+               }
+       }
+       printk("\n");
+ }     
+-int is_valid_bugaddr(unsigned long rip)
++int is_valid_bugaddr(unsigned long ip)
+ {
+       unsigned short ud2;
+-      if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2)))
++      if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
+               return 0;
+       return ud2 == 0x0b0f;
+ }
+-#ifdef CONFIG_BUG
+-void out_of_line_bug(void)
+-{ 
+-      BUG(); 
+-} 
+-EXPORT_SYMBOL(out_of_line_bug);
+-#endif
+-
+ static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
+ static int die_owner = -1;
+ static unsigned int die_nest_count;
+@@ -498,7 +542,7 @@ unsigned __kprobes long oops_begin(void)
+       return flags;
+ }
+-void __kprobes oops_end(unsigned long flags)
++void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
+ { 
+       die_owner = -1;
+       bust_spinlocks(0);
+@@ -507,12 +551,17 @@ void __kprobes oops_end(unsigned long fl
+               /* Nest count reaches zero, release the lock. */
+               __raw_spin_unlock(&die_lock);
+       raw_local_irq_restore(flags);
++      if (!regs) {
++              oops_exit();
++              return;
 +      }
-+
-+      /*
-+       * Calculate the number of pages, which fit into this large
-+       * page starting at address:
-+       */
-+      nextpage_addr = (address + psize) & pmask;
-+      numpages = (nextpage_addr - address) >> PAGE_SHIFT;
-+      if (numpages < cpa->numpages)
-+              cpa->numpages = numpages;
-+
-+      /*
-+       * We are safe now. Check whether the new pgprot is the same:
-+       */
-+      old_pte = *kpte;
-+      old_prot = new_prot = pte_pgprot(old_pte);
-+
-+      pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
-+      pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
-+
-+      /*
-+       * old_pte points to the large page base address. So we need
-+       * to add the offset of the virtual address:
-+       */
-+      pfn = pte_pfn(old_pte) + ((address & (psize - 1)) >> PAGE_SHIFT);
-+      cpa->pfn = pfn;
-+
-+      new_prot = static_protections(new_prot, address, pfn);
-+
-+      /*
-+       * We need to check the full range, whether
-+       * static_protection() requires a different pgprot for one of
-+       * the pages in the range we try to preserve:
-+       */
-+      if (pfn < max_mapnr) {
-+              addr = address + PAGE_SIZE;
-+              for (i = 1; i < cpa->numpages && ++pfn < max_mapnr;
-+                   i++, addr += PAGE_SIZE) {
-+                      pgprot_t chk_prot = static_protections(new_prot, addr, pfn);
-+
-+                      if (pgprot_val(chk_prot) != pgprot_val(new_prot))
-+                              goto out_unlock;
+       if (panic_on_oops)
+               panic("Fatal exception");
+       oops_exit();
++      do_exit(signr);
+ }
+-void __kprobes __die(const char * str, struct pt_regs * regs, long err)
++int __kprobes __die(const char * str, struct pt_regs * regs, long err)
+ {
+       static int die_counter;
+       printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
+@@ -526,15 +575,17 @@ void __kprobes __die(const char * str, s
+       printk("DEBUG_PAGEALLOC");
+ #endif
+       printk("\n");
+-      notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
++      if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
++              return 1;
+       show_registers(regs);
+       add_taint(TAINT_DIE);
+       /* Executive summary in case the oops scrolled away */
+       printk(KERN_ALERT "RIP ");
+-      printk_address(regs->rip); 
+-      printk(" RSP <%016lx>\n", regs->rsp); 
++      printk_address(regs->ip, 1);
++      printk(" RSP <%016lx>\n", regs->sp);
+       if (kexec_should_crash(current))
+               crash_kexec(regs);
++      return 0;
+ }
+ void die(const char * str, struct pt_regs * regs, long err)
+@@ -542,11 +593,11 @@ void die(const char * str, struct pt_reg
+       unsigned long flags = oops_begin();
+       if (!user_mode(regs))
+-              report_bug(regs->rip, regs);
++              report_bug(regs->ip, regs);
+-      __die(str, regs, err);
+-      oops_end(flags);
+-      do_exit(SIGSEGV); 
++      if (__die(str, regs, err))
++              regs = NULL;
++      oops_end(flags, regs, SIGSEGV);
+ }
+ #if defined(CONFIG_X86_LOCAL_APIC) || defined(CONFIG_SYSCTL)
+@@ -564,10 +615,10 @@ void __kprobes die_nmi(char *str, struct
+               crash_kexec(regs);
+       if (do_panic || panic_on_oops)
+               panic("Non maskable interrupt");
+-      oops_end(flags);
++      oops_end(flags, NULL, SIGBUS);
+       nmi_exit();
+       local_irq_enable();
+-      do_exit(SIGSEGV);
++      do_exit(SIGBUS);
+ }
+ #endif
+@@ -592,11 +643,14 @@ static void __kprobes do_trap(int trapnr
+               tsk->thread.trap_no = trapnr;
+               if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
+-                  printk_ratelimit())
++                  printk_ratelimit()) {
+                       printk(KERN_INFO
+-                             "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
++                             "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
+                              tsk->comm, tsk->pid, str,
+-                             regs->rip, regs->rsp, error_code); 
++                             regs->ip, regs->sp, error_code);
++                      print_vma_addr(" in ", regs->ip);
++                      printk("\n");
 +              }
-+      }
-+
-+      /*
-+       * If there are no changes, return. maxpages has been updated
-+       * above:
-+       */
-+      if (pgprot_val(new_prot) == pgprot_val(old_prot)) {
-+              do_split = 0;
-+              goto out_unlock;
-+      }
-+
-+      /*
-+       * We need to change the attributes. Check, whether we can
-+       * change the large page in one go. We request a split, when
-+       * the address is not aligned and the number of pages is
-+       * smaller than the number of pages in the large page. Note
-+       * that we limited the number of possible pages already to
-+       * the number of pages in the large page.
-+       */
-+      if (address == (nextpage_addr - psize) && cpa->numpages == numpages) {
-+              /*
-+               * The address is aligned and the number of pages
-+               * covers the full page.
-+               */
-+              new_pte = pfn_pte_ma(__pte_mfn(old_pte), canon_pgprot(new_prot));
-+              __set_pmd_pte(kpte, address, level, new_pte);
-+              cpa->flushtlb = 1;
-+              do_split = 0;
-+      }
-+
-+out_unlock:
-+      spin_unlock_irqrestore(&pgd_lock, flags);
-+
-+      return do_split;
-+}
-+
-+static LIST_HEAD(page_pool);
-+static unsigned long pool_size, pool_pages, pool_low;
-+static unsigned long pool_used, pool_failed;
-+
-+static void cpa_fill_pool(struct page **ret)
-+{
-+      gfp_t gfp = GFP_KERNEL;
-+      unsigned long flags;
-+      struct page *p;
-+
+               if (info)
+                       force_sig_info(signr, info, tsk);
+@@ -606,19 +660,12 @@ static void __kprobes do_trap(int trapnr
+       }
+-      /* kernel trap */ 
+-      {            
+-              const struct exception_table_entry *fixup;
+-              fixup = search_exception_tables(regs->rip);
+-              if (fixup)
+-                      regs->rip = fixup->fixup;
+-              else {
+-                      tsk->thread.error_code = error_code;
+-                      tsk->thread.trap_no = trapnr;
+-                      die(str, regs, error_code);
+-              }
+-              return;
++      if (!fixup_exception(regs)) {
++              tsk->thread.error_code = error_code;
++              tsk->thread.trap_no = trapnr;
++              die(str, regs, error_code);
+       }
++      return;
+ }
+ #define DO_ERROR(trapnr, signr, str, name) \
+@@ -647,10 +694,10 @@ asmlinkage void do_##name(struct pt_regs
+       do_trap(trapnr, signr, str, regs, error_code, &info); \
+ }
+-DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->rip)
++DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->ip)
+ DO_ERROR( 4, SIGSEGV, "overflow", overflow)
+ DO_ERROR( 5, SIGSEGV, "bounds", bounds)
+-DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->rip)
++DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip)
+ DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
+ DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
+ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
+@@ -698,32 +745,28 @@ asmlinkage void __kprobes do_general_pro
+               tsk->thread.trap_no = 13;
+               if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+-                  printk_ratelimit())
++                  printk_ratelimit()) {
+                       printk(KERN_INFO
+-                     "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
++                     "%s[%d] general protection ip:%lx sp:%lx error:%lx",
+                              tsk->comm, tsk->pid,
+-                             regs->rip, regs->rsp, error_code); 
++                             regs->ip, regs->sp, error_code);
++                      print_vma_addr(" in ", regs->ip);
++                      printk("\n");
++              }
+               force_sig(SIGSEGV, tsk);
+               return;
+       } 
+-      /* kernel gp */
+-      {
+-              const struct exception_table_entry *fixup;
+-              fixup = search_exception_tables(regs->rip);
+-              if (fixup) {
+-                      regs->rip = fixup->fixup;
+-                      return;
+-              }
++      if (fixup_exception(regs))
++              return;
+-              tsk->thread.error_code = error_code;
+-              tsk->thread.trap_no = 13;
+-              if (notify_die(DIE_GPF, "general protection fault", regs,
+-                                      error_code, 13, SIGSEGV) == NOTIFY_STOP)
+-                      return;
+-              die("general protection fault", regs, error_code);
+-      }
++      tsk->thread.error_code = error_code;
++      tsk->thread.trap_no = 13;
++      if (notify_die(DIE_GPF, "general protection fault", regs,
++                              error_code, 13, SIGSEGV) == NOTIFY_STOP)
++              return;
++      die("general protection fault", regs, error_code);
+ }
+ static __kprobes void
+@@ -833,15 +876,15 @@ asmlinkage __kprobes struct pt_regs *syn
+ {
+       struct pt_regs *regs = eregs;
+       /* Did already sync */
+-      if (eregs == (struct pt_regs *)eregs->rsp)
++      if (eregs == (struct pt_regs *)eregs->sp)
+               ;
+       /* Exception from user space */
+       else if (user_mode(eregs))
+               regs = task_pt_regs(current);
+       /* Exception from kernel and interrupts are enabled. Move to
+          kernel process stack. */
+-      else if (eregs->eflags & X86_EFLAGS_IF)
+-              regs = (struct pt_regs *)(eregs->rsp -= sizeof(struct pt_regs));
++      else if (eregs->flags & X86_EFLAGS_IF)
++              regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
+       if (eregs != regs)
+               *regs = *eregs;
+       return regs;
+@@ -859,6 +902,12 @@ asmlinkage void __kprobes do_debug(struc
+       get_debugreg(condition, 6);
 +      /*
-+       * Avoid recursion (on debug-pagealloc) and also signal
-+       * our priority to get to these pagetables:
++       * The processor cleared BTF, so don't mark that we need it set.
 +       */
-+      if (current->flags & PF_MEMALLOC)
-+              return;
-+      current->flags |= PF_MEMALLOC;
++      clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
++      tsk->thread.debugctlmsr = 0;
++
+       if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
+                                               SIGTRAP) == NOTIFY_STOP)
+               return;
+@@ -874,27 +923,14 @@ asmlinkage void __kprobes do_debug(struc
+       tsk->thread.debugreg6 = condition;
+-      /* Mask out spurious TF errors due to lazy TF clearing */
 +
 +      /*
-+       * Allocate atomically from atomic contexts:
++       * Single-stepping through TF: make sure we ignore any events in
++       * kernel space (but re-enable TF when returning to user mode).
 +       */
-+      if (in_atomic() || irqs_disabled() || debug_pagealloc)
-+              gfp =  GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
+       if (condition & DR_STEP) {
+-              /*
+-               * The TF error should be masked out only if the current
+-               * process is not traced and if the TRAP flag has been set
+-               * previously by a tracing process (condition detected by
+-               * the PT_DTRACE flag); remember that the i386 TRAP flag
+-               * can be modified by the process itself in user mode,
+-               * allowing programs to debug themselves without the ptrace()
+-               * interface.
+-               */
+                 if (!user_mode(regs))
+                        goto clear_TF_reenable;
+-              /*
+-               * Was the TF flag set by a debugger? If so, clear it now,
+-               * so that register information is correct.
+-               */
+-              if (tsk->ptrace & PT_DTRACE) {
+-                      regs->eflags &= ~TF_MASK;
+-                      tsk->ptrace &= ~PT_DTRACE;
+-              }
+       }
+       /* Ok, finally something we can handle */
+@@ -903,7 +939,7 @@ asmlinkage void __kprobes do_debug(struc
+       info.si_signo = SIGTRAP;
+       info.si_errno = 0;
+       info.si_code = TRAP_BRKPT;
+-      info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
++      info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
+       force_sig_info(SIGTRAP, &info, tsk);
+ clear_dr7:
+@@ -913,18 +949,15 @@ clear_dr7:
+ clear_TF_reenable:
+       set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+-      regs->eflags &= ~TF_MASK;
++      regs->flags &= ~X86_EFLAGS_TF;
+       preempt_conditional_cli(regs);
+ }
+ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
+ {
+-      const struct exception_table_entry *fixup;
+-      fixup = search_exception_tables(regs->rip);
+-      if (fixup) {
+-              regs->rip = fixup->fixup;
++      if (fixup_exception(regs))
+               return 1;
+-      }
 +
-+      while (pool_pages < pool_size || (ret && !*ret)) {
-+              p = alloc_pages(gfp, 0);
-+              if (!p) {
-+                      pool_failed++;
-+                      break;
-+              }
-+              /*
-+               * If the call site needs a page right now, provide it:
-+               */
-+              if (ret && !*ret) {
-+                      *ret = p;
-+                      continue;
-+              }
-+              spin_lock_irqsave(&pgd_lock, flags);
-+              list_add(&p->lru, &page_pool);
-+              pool_pages++;
-+              spin_unlock_irqrestore(&pgd_lock, flags);
-+      }
+       notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
+       /* Illegal floating point operation in the kernel */
+       current->thread.trap_no = trapnr;
+@@ -939,7 +972,7 @@ static int kernel_math_error(struct pt_r
+  */
+ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
+ {
+-      void __user *rip = (void __user *)(regs->rip);
++      void __user *ip = (void __user *)(regs->ip);
+       struct task_struct * task;
+       siginfo_t info;
+       unsigned short cwd, swd;
+@@ -959,7 +992,7 @@ asmlinkage void do_coprocessor_error(str
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_code = __SI_FAULT;
+-      info.si_addr = rip;
++      info.si_addr = ip;
+       /*
+        * (~cwd & swd) will mask out exceptions that are not set to unmasked
+        * status.  0x3f is the exception bits in these regs, 0x200 is the
+@@ -1008,7 +1041,7 @@ asmlinkage void bad_intr(void)
+ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
+ {
+-      void __user *rip = (void __user *)(regs->rip);
++      void __user *ip = (void __user *)(regs->ip);
+       struct task_struct * task;
+       siginfo_t info;
+       unsigned short mxcsr;
+@@ -1028,7 +1061,7 @@ asmlinkage void do_simd_coprocessor_erro
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_code = __SI_FAULT;
+-      info.si_addr = rip;
++      info.si_addr = ip;
+       /*
+        * The SIMD FPU exceptions are handled a little differently, as there
+        * is only a single status/control register.  Thus, to determine which
+@@ -1092,13 +1125,14 @@ asmlinkage void math_state_restore(void)
+       task_thread_info(me)->status |= TS_USEDFPU;
+       me->fpu_counter++;
+ }
++EXPORT_SYMBOL_GPL(math_state_restore);
+ /*
+  * NB. All these are "interrupt gates" (i.e. events_mask is set) because we
+  * specify <dpl>|4 in the second field.
+  */
+-static trap_info_t __cpuinitdata trap_table[] = {
++static const trap_info_t __cpuinitconst trap_table[] = {
+         {  0, 0|4, __KERNEL_CS, (unsigned long)divide_error               },
+         {  1, 0|4, __KERNEL_CS, (unsigned long)debug                      },
+         {  3, 3|4, __KERNEL_CS, (unsigned long)int3                       },
+@@ -1169,3 +1203,14 @@ static int __init kstack_setup(char *s)
+       return 0;
+ }
+ early_param("kstack", kstack_setup);
 +
-+      current->flags &= ~PF_MEMALLOC;
-+}
 +
-+#define SHIFT_MB              (20 - PAGE_SHIFT)
-+#define ROUND_MB_GB           ((1 << 10) - 1)
-+#define SHIFT_MB_GB           10
-+#define POOL_PAGES_PER_GB     16
++static int __init code_bytes_setup(char *s)
++{
++      code_bytes = simple_strtoul(s, NULL, 0);
++      if (code_bytes > 8192)
++              code_bytes = 8192;
++
++      return 1;
++}
++__setup("code_bytes=", code_bytes_setup);
+--- sle11-2009-05-14.orig/arch/x86/kernel/vsyscall_64-xen.c    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/kernel/vsyscall_64-xen.c 2009-03-16 16:33:40.000000000 +0100
+@@ -43,12 +43,7 @@
+ #include <asm/vgtod.h>
+ #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
+-#define __syscall_clobber "r11","rcx","memory"
+-#define __pa_vsymbol(x)                       \
+-      ({unsigned long v;              \
+-      extern char __vsyscall_0;       \
+-        asm("" : "=r" (v) : "0" (x)); \
+-        ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
++#define __syscall_clobber "r11","cx","memory"
+ /*
+  * vsyscall_gtod_data contains data that is :
+@@ -102,7 +97,7 @@ static __always_inline void do_get_tz(st
+ static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
+ {
+       int ret;
+-      asm volatile("vsysc2: syscall"
++      asm volatile("syscall"
+               : "=a" (ret)
+               : "0" (__NR_gettimeofday),"D" (tv),"S" (tz)
+               : __syscall_clobber );
+@@ -112,7 +107,7 @@ static __always_inline int gettimeofday(
+ static __always_inline long time_syscall(long *t)
+ {
+       long secs;
+-      asm volatile("vsysc1: syscall"
++      asm volatile("syscall"
+               : "=a" (secs)
+               : "0" (__NR_time),"D" (t) : __syscall_clobber);
+       return secs;
+@@ -190,7 +185,7 @@ time_t __vsyscall(1) vtime(time_t *t)
+ long __vsyscall(2)
+ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
+ {
+-      unsigned int dummy, p;
++      unsigned int p;
+       unsigned long j = 0;
+       /* Fast cache - only recompute value once per jiffies and avoid
+@@ -205,7 +200,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s
+               p = tcache->blob[1];
+       } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
+               /* Load per CPU data from RDTSCP */
+-              rdtscp(dummy, dummy, p);
++              native_read_tscp(&p);
+       } else {
+               /* Load per CPU data from GDT */
+               asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
+@@ -228,42 +223,11 @@ long __vsyscall(3) venosys_1(void)
+ #ifdef CONFIG_SYSCTL
+-#define SYSCALL 0x050f
+-#define NOP2    0x9090
+-
+-/*
+- * NOP out syscall in vsyscall page when not needed.
+- */
+-static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
+-                        void __user *buffer, size_t *lenp, loff_t *ppos)
++static int
++vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
++                     void __user *buffer, size_t *lenp, loff_t *ppos)
+ {
+-      extern u16 vsysc1, vsysc2;
+-      u16 __iomem *map1;
+-      u16 __iomem *map2;
+-      int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
+-      if (!write)
+-              return ret;
+-      /* gcc has some trouble with __va(__pa()), so just do it this
+-         way. */
+-      map1 = ioremap(__pa_vsymbol(&vsysc1), 2);
+-      if (!map1)
+-              return -ENOMEM;
+-      map2 = ioremap(__pa_vsymbol(&vsysc2), 2);
+-      if (!map2) {
+-              ret = -ENOMEM;
+-              goto out;
+-      }
+-      if (!vsyscall_gtod_data.sysctl_enabled) {
+-              writew(SYSCALL, map1);
+-              writew(SYSCALL, map2);
+-      } else {
+-              writew(NOP2, map1);
+-              writew(NOP2, map2);
+-      }
+-      iounmap(map2);
+-out:
+-      iounmap(map1);
+-      return ret;
++      return proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
+ }
+ static ctl_table kernel_table2[] = {
+@@ -279,7 +243,6 @@ static ctl_table kernel_root_table2[] = 
+         .child = kernel_table2 },
+       {}
+ };
+-
+ #endif
+ /* Assume __initcall executes before all user space. Hopefully kmod
+@@ -301,7 +264,7 @@ static void __cpuinit vsyscall_set_cpu(i
+       d |= cpu;
+       d |= (node & 0xf) << 12;
+       d |= (node >> 4) << 48;
+-      if (HYPERVISOR_update_descriptor(virt_to_machine(cpu_gdt(cpu)
++      if (HYPERVISOR_update_descriptor(virt_to_machine(get_cpu_gdt_table(cpu)
+                                                        + GDT_ENTRY_PER_CPU),
+                                        d))
+               BUG();
+@@ -322,7 +285,7 @@ cpu_vsyscall_notifier(struct notifier_bl
+       return NOTIFY_DONE;
+ }
+-static void __init map_vsyscall(void)
++void __init map_vsyscall(void)
+ {
+       extern char __vsyscall_0;
+       unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0);
+@@ -338,7 +301,6 @@ static int __init vsyscall_init(void)
+       BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
+       BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
+       BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu));
+-      map_vsyscall();
+ #ifdef CONFIG_XEN
+       vsyscall_gtod_data.sysctl_enabled = 0; /* disable vgettimeofay() */
+       if (boot_cpu_has(X86_FEATURE_RDTSCP))
+--- sle11-2009-05-14.orig/arch/x86/kernel/xen_entry_64.S       2009-05-14 10:56:29.000000000 +0200
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,36 +0,0 @@
+-/*
+- * Copied from arch/xen/i386/kernel/entry.S
+- */                        
+-/* Offsets into shared_info_t. */                
+-#define evtchn_upcall_pending         /* 0 */
+-#define evtchn_upcall_mask            1
+-
+-#define sizeof_vcpu_shift             6
+-
+-#ifdef CONFIG_SMP
+-//#define preempt_disable(reg)        incl threadinfo_preempt_count(reg)
+-//#define preempt_enable(reg) decl threadinfo_preempt_count(reg)
+-#define preempt_disable(reg)
+-#define preempt_enable(reg)
+-#define XEN_GET_VCPU_INFO(reg)        preempt_disable(%rbp)                   ; \
+-                              movq %gs:pda_cpunumber,reg              ; \
+-                              shl  $32, reg                           ; \
+-                              shr  $32-sizeof_vcpu_shift,reg          ; \
+-                              addq HYPERVISOR_shared_info,reg
+-#define XEN_PUT_VCPU_INFO(reg)        preempt_enable(%rbp)                    ; \
+-#define XEN_PUT_VCPU_INFO_fixup .byte 0xff,0xff,0xff
+-#else
+-#define XEN_GET_VCPU_INFO(reg)        movq HYPERVISOR_shared_info,reg
+-#define XEN_PUT_VCPU_INFO(reg)
+-#define XEN_PUT_VCPU_INFO_fixup
+-#endif
+-
+-#define XEN_LOCKED_BLOCK_EVENTS(reg)  movb $1,evtchn_upcall_mask(reg)
+-#define XEN_LOCKED_UNBLOCK_EVENTS(reg)        movb $0,evtchn_upcall_mask(reg)
+-#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg)                  ; \
+-                              XEN_LOCKED_BLOCK_EVENTS(reg)            ; \
+-                              XEN_PUT_VCPU_INFO(reg)
+-#define XEN_UNBLOCK_EVENTS(reg)       XEN_GET_VCPU_INFO(reg)                  ; \
+-                              XEN_LOCKED_UNBLOCK_EVENTS(reg)          ; \
+-                              XEN_PUT_VCPU_INFO(reg)
+-#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
+--- sle11-2009-05-14.orig/arch/x86/mach-xen/setup.c    2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/arch/x86/mach-xen/setup.c 2009-03-16 16:33:40.000000000 +0100
+@@ -161,15 +161,12 @@ void __init machine_specific_arch_setup(
+       /* Do an early initialization of the fixmap area */
+       {
+-              extern pte_t swapper_pg_pmd[PTRS_PER_PTE];
++              extern pte_t swapper_pg_fixmap[PTRS_PER_PTE];
+               unsigned long addr = __fix_to_virt(FIX_EARLYCON_MEM_BASE);
+-              pgd_t *pgd = (pgd_t *)xen_start_info->pt_base;
+-              pud_t *pud = pud_offset(pgd + pgd_index(addr), addr);
++              pud_t *pud = pud_offset(swapper_pg_dir + pgd_index(addr), addr);
+               pmd_t *pmd = pmd_offset(pud, addr);
+-              swapper_pg_dir = pgd;
+-              init_mm.pgd    = pgd;
+-              make_lowmem_page_readonly(swapper_pg_pmd, XENFEAT_writable_page_tables);
+-              set_pmd(pmd, __pmd(__pa_symbol(swapper_pg_pmd) | _PAGE_TABLE));
++              make_lowmem_page_readonly(swapper_pg_fixmap, XENFEAT_writable_page_tables);
++              set_pmd(pmd, __pmd(__pa_symbol(swapper_pg_fixmap) | _PAGE_TABLE));
+       }
+ }
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/mm/fault-xen.c   2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,1025 @@
++/*
++ *  Copyright (C) 1995  Linus Torvalds
++ *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
++ */
 +
-+void __init cpa_init(void)
-+{
-+      struct sysinfo si;
-+      unsigned long gb;
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/ptrace.h>
++#include <linux/mman.h>
++#include <linux/mm.h>
++#include <linux/smp.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/tty.h>
++#include <linux/vt_kern.h>            /* For unblank_screen() */
++#include <linux/compiler.h>
++#include <linux/highmem.h>
++#include <linux/bootmem.h>            /* for max_low_pfn */
++#include <linux/vmalloc.h>
++#include <linux/module.h>
++#include <linux/kprobes.h>
++#include <linux/uaccess.h>
++#include <linux/kdebug.h>
 +
-+      si_meminfo(&si);
-+      /*
-+       * Calculate the number of pool pages:
-+       *
-+       * Convert totalram (nr of pages) to MiB and round to the next
-+       * GiB. Shift MiB to Gib and multiply the result by
-+       * POOL_PAGES_PER_GB:
-+       */
-+      if (debug_pagealloc) {
-+              gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
-+              pool_size = POOL_PAGES_PER_GB * gb;
-+      } else {
-+              pool_size = 1;
-+      }
-+      pool_low = pool_size;
++#include <asm/system.h>
++#include <asm/desc.h>
++#include <asm/segment.h>
++#include <asm/pgalloc.h>
++#include <asm/smp.h>
++#include <asm/tlbflush.h>
++#include <asm/proto.h>
++#include <asm-generic/sections.h>
 +
-+      cpa_fill_pool(NULL);
-+      printk(KERN_DEBUG
-+             "CPA: page pool initialized %lu of %lu pages preallocated\n",
-+             pool_pages, pool_size);
-+}
++/*
++ * Page fault error code bits
++ *    bit 0 == 0 means no page found, 1 means protection fault
++ *    bit 1 == 0 means read, 1 means write
++ *    bit 2 == 0 means kernel, 1 means user-mode
++ *    bit 3 == 1 means use of reserved bit detected
++ *    bit 4 == 1 means fault was an instruction fetch
++ */
++#define PF_PROT               (1<<0)
++#define PF_WRITE      (1<<1)
++#define PF_USER               (1<<2)
++#define PF_RSVD               (1<<3)
++#define PF_INSTR      (1<<4)
 +
-+static int split_large_page(pte_t *kpte, unsigned long address)
++static inline int notify_page_fault(struct pt_regs *regs)
 +{
-+      unsigned long flags, mfn, mfninc = 1;
-+      unsigned int i, level;
-+      pte_t *pbase, *tmp;
-+      pgprot_t ref_prot;
-+      struct page *base;
-+
-+      /*
-+       * Get a page from the pool. The pool list is protected by the
-+       * pgd_lock, which we have to take anyway for the split
-+       * operation:
-+       */
-+      spin_lock_irqsave(&pgd_lock, flags);
-+      if (list_empty(&page_pool)) {
-+              spin_unlock_irqrestore(&pgd_lock, flags);
-+              base = NULL;
-+              cpa_fill_pool(&base);
-+              if (!base)
-+                      return -ENOMEM;
-+              spin_lock_irqsave(&pgd_lock, flags);
-+      } else {
-+              base = list_first_entry(&page_pool, struct page, lru);
-+              list_del(&base->lru);
-+              pool_pages--;
-+
-+              if (pool_pages < pool_low)
-+                      pool_low = pool_pages;
-+      }
-+
-+      /*
-+       * Check for races, another CPU might have split this page
-+       * up for us already:
-+       */
-+      tmp = lookup_address(address, &level);
-+      if (tmp != kpte)
-+              goto out_unlock;
++#ifdef CONFIG_KPROBES
++      int ret = 0;
 +
-+      pbase = (pte_t *)page_address(base);
++      /* kprobe_running() needs smp_processor_id() */
 +#ifdef CONFIG_X86_32
-+      paravirt_alloc_pt(&init_mm, page_to_pfn(base));
++      if (!user_mode_vm(regs)) {
++#else
++      if (!user_mode(regs)) {
 +#endif
-+      ref_prot = pte_pgprot(pte_clrhuge(*kpte));
-+
-+#ifdef CONFIG_X86_64
-+      if (level == PG_LEVEL_1G) {
-+              mfninc = PMD_PAGE_SIZE >> PAGE_SHIFT;
-+              pgprot_val(ref_prot) |= _PAGE_PSE;
++              preempt_disable();
++              if (kprobe_running() && kprobe_fault_handler(regs, 14))
++                      ret = 1;
++              preempt_enable();
 +      }
++
++      return ret;
++#else
++      return 0;
 +#endif
++}
++
++/*
++ * X86_32
++ * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
++ * Check that here and ignore it.
++ *
++ * X86_64
++ * Sometimes the CPU reports invalid exceptions on prefetch.
++ * Check that here and ignore it.
++ *
++ * Opcode checker based on code by Richard Brunner
++ */
++static int is_prefetch(struct pt_regs *regs, unsigned long addr,
++                     unsigned long error_code)
++{
++      unsigned char *instr;
++      int scan_more = 1;
++      int prefetch = 0;
++      unsigned char *max_instr;
 +
 +      /*
-+       * Get the target mfn from the original entry:
++       * If it was a exec (instruction fetch) fault on NX page, then
++       * do not ignore the fault:
 +       */
-+      mfn = __pte_mfn(*kpte);
-+      for (i = 0; i < PTRS_PER_PTE; i++, mfn += mfninc)
-+              set_pte(&pbase[i], pfn_pte_ma(mfn, ref_prot));
++      if (error_code & PF_INSTR)
++              return 0;
 +
-+      /*
-+       * Install the new, split up pagetable. Important details here:
-+       *
-+       * On Intel the NX bit of all levels must be cleared to make a
-+       * page executable. See section 4.13.2 of Intel 64 and IA-32
-+       * Architectures Software Developer's Manual).
-+       *
-+       * Mark the entry present. The current mapping might be
-+       * set to not present, which we preserved above.
-+       */
-+      if (HYPERVISOR_update_va_mapping((unsigned long)pbase,
-+                                       mk_pte(base, PAGE_KERNEL_RO), 0))
-+              BUG();
-+      ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte)));
-+      pgprot_val(ref_prot) |= _PAGE_PRESENT;
-+      __set_pmd_pte(kpte, address, level, mk_pte(base, ref_prot));
-+      base = NULL;
++      instr = (unsigned char *)convert_ip_to_linear(current, regs);
++      max_instr = instr + 15;
 +
-+out_unlock:
-+      /*
-+       * If we dropped out via the lookup_address check under
-+       * pgd_lock then stick the page back into the pool:
-+       */
-+      if (base) {
-+              list_add(&base->lru, &page_pool);
-+              pool_pages++;
-+      } else
-+              pool_used++;
-+      spin_unlock_irqrestore(&pgd_lock, flags);
++      if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
++              return 0;
 +
-+      return 0;
-+}
++      while (scan_more && instr < max_instr) {
++              unsigned char opcode;
++              unsigned char instr_hi;
++              unsigned char instr_lo;
 +
-+static int __change_page_attr(struct cpa_data *cpa, int primary)
-+{
-+      unsigned long address = cpa->vaddr;
-+      int do_split, err;
-+      unsigned int level;
-+      pte_t *kpte, old_pte;
++              if (probe_kernel_address(instr, opcode))
++                      break;
 +
-+repeat:
-+      kpte = lookup_address(address, &level);
-+      if (!kpte)
-+              return primary ? -EINVAL : 0;
++              instr_hi = opcode & 0xf0;
++              instr_lo = opcode & 0x0f;
++              instr++;
 +
-+      old_pte = *kpte;
-+      if (!__pte_val(old_pte)) {
-+              if (!primary)
-+                      return 0;
-+              printk(KERN_WARNING "CPA: called for zero pte. "
-+                     "vaddr = %lx cpa->vaddr = %lx\n", address,
-+                     cpa->vaddr);
-+              WARN_ON(1);
-+              return -EINVAL;
++              switch (instr_hi) {
++              case 0x20:
++              case 0x30:
++                      /*
++                       * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
++                       * In X86_64 long mode, the CPU will signal invalid
++                       * opcode if some of these prefixes are present so
++                       * X86_64 will never get here anyway
++                       */
++                      scan_more = ((instr_lo & 7) == 0x6);
++                      break;
++#ifdef CONFIG_X86_64
++              case 0x40:
++                      /*
++                       * In AMD64 long mode 0x40..0x4F are valid REX prefixes
++                       * Need to figure out under what instruction mode the
++                       * instruction was issued. Could check the LDT for lm,
++                       * but for now it's good enough to assume that long
++                       * mode only uses well known segments or kernel.
++                       */
++                      scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
++                      break;
++#endif
++              case 0x60:
++                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
++                      scan_more = (instr_lo & 0xC) == 0x4;
++                      break;
++              case 0xF0:
++                      /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
++                      scan_more = !instr_lo || (instr_lo>>1) == 1;
++                      break;
++              case 0x00:
++                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
++                      scan_more = 0;
++
++                      if (probe_kernel_address(instr, opcode))
++                              break;
++                      prefetch = (instr_lo == 0xF) &&
++                              (opcode == 0x0D || opcode == 0x18);
++                      break;
++              default:
++                      scan_more = 0;
++                      break;
++              }
 +      }
++      return prefetch;
++}
 +
-+      if (level == PG_LEVEL_4K) {
-+              pte_t new_pte;
-+              pgprot_t new_prot = pte_pgprot(old_pte);
-+              unsigned long mfn = __pte_mfn(old_pte);
++static void force_sig_info_fault(int si_signo, int si_code,
++      unsigned long address, struct task_struct *tsk)
++{
++      siginfo_t info;
 +
-+              pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
-+              pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
++      info.si_signo = si_signo;
++      info.si_errno = 0;
++      info.si_code = si_code;
++      info.si_addr = (void __user *)address;
++      force_sig_info(si_signo, &info, tsk);
++}
 +
-+              new_prot = static_protections(new_prot, address,
-+                                            mfn_to_local_pfn(mfn));
++#ifdef CONFIG_X86_64
++static int bad_address(void *p)
++{
++      unsigned long dummy;
++      return probe_kernel_address((unsigned long *)p, dummy);
++}
++#endif
 +
-+              /*
-+               * We need to keep the mfn from the existing PTE,
-+               * after all we're only going to change it's attributes
-+               * not the memory it points to
-+               */
-+              new_pte = pfn_pte_ma(mfn, canon_pgprot(new_prot));
-+              cpa->pfn = mfn_to_local_pfn(mfn);
-+              /*
-+               * Do we really change anything ?
-+               */
-+              if (__pte_val(old_pte) != __pte_val(new_pte)) {
-+                      set_pte_atomic(kpte, new_pte);
-+                      cpa->flushtlb = 1;
-+              }
-+              cpa->numpages = 1;
-+              return 0;
-+      }
++static void dump_pagetable(unsigned long address)
++{
++#ifdef CONFIG_X86_32
++      __typeof__(pte_val(__pte(0))) page;
 +
-+      /*
-+       * Check, whether we can keep the large page intact
-+       * and just change the pte:
-+       */
-+      do_split = try_preserve_large_page(kpte, address, cpa);
-+      /*
-+       * When the range fits into the existing large page,
-+       * return. cp->numpages and cpa->tlbflush have been updated in
-+       * try_large_page:
-+       */
-+      if (do_split <= 0)
-+              return do_split;
++      page = read_cr3();
++      page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
++#ifdef CONFIG_X86_PAE
++      printk("*pdpt = %016Lx ", page);
++      if ((page & _PAGE_PRESENT)
++          && mfn_to_local_pfn(page >> PAGE_SHIFT) < max_low_pfn) {
++              page = mfn_to_pfn(page >> PAGE_SHIFT);
++              page <<= PAGE_SHIFT;
++              page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
++                                                       & (PTRS_PER_PMD - 1)];
++              printk(KERN_CONT "*pde = %016Lx ", page);
++              page &= ~_PAGE_NX;
++      }
++#else
++      printk("*pde = %08lx ", page);
++#endif
 +
 +      /*
-+       * We have to split the large page:
++       * We must not directly access the pte in the highpte
++       * case if the page table is located in highmem.
++       * And let's rather not kmap-atomic the pte, just in case
++       * it's allocated already.
 +       */
-+      err = split_large_page(kpte, address);
-+      if (!err) {
-+              cpa->flushtlb = 1;
-+              goto repeat;
++      if ((page & _PAGE_PRESENT)
++          && mfn_to_local_pfn(page >> PAGE_SHIFT) < max_low_pfn
++          && !(page & _PAGE_PSE)) {
++              page = mfn_to_pfn(page >> PAGE_SHIFT);
++              page <<= PAGE_SHIFT;
++              page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
++                                                       & (PTRS_PER_PTE - 1)];
++              printk(KERN_CONT "*pte = %0*Lx ", sizeof(page)*2, (u64)page);
 +      }
 +
-+      return err;
-+}
++      printk(KERN_CONT "\n");
++#else /* CONFIG_X86_64 */
++      pgd_t *pgd;
++      pud_t *pud;
++      pmd_t *pmd;
++      pte_t *pte;
 +
-+static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias);
++      pgd = (pgd_t *)read_cr3();
 +
-+static int cpa_process_alias(struct cpa_data *cpa)
-+{
-+      struct cpa_data alias_cpa;
-+      int ret = 0;
++      pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
++      pgd += pgd_index(address);
++      if (bad_address(pgd)) goto bad;
++      printk("PGD %lx ", pgd_val(*pgd));
++      if (!pgd_present(*pgd)) goto ret;
 +
-+      if (cpa->pfn > max_pfn_mapped)
-+              return 0;
++      pud = pud_offset(pgd, address);
++      if (bad_address(pud)) goto bad;
++      printk(KERN_CONT "PUD %lx ", pud_val(*pud));
++      if (!pud_present(*pud) || pud_large(*pud))
++              goto ret;
 +
-+      /*
-+       * No need to redo, when the primary call touched the direct
-+       * mapping already:
-+       */
-+      if (!within(cpa->vaddr, PAGE_OFFSET,
-+                  PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
++      pmd = pmd_offset(pud, address);
++      if (bad_address(pmd)) goto bad;
++      printk(KERN_CONT "PMD %lx ", pmd_val(*pmd));
++      if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
++
++      pte = pte_offset_kernel(pmd, address);
++      if (bad_address(pte)) goto bad;
++      printk(KERN_CONT "PTE %lx", pte_val(*pte));
++ret:
++      printk(KERN_CONT "\n");
++      return;
++bad:
++      printk("BAD\n");
++#endif
++}
 +
-+              alias_cpa = *cpa;
-+              alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
++#ifdef CONFIG_X86_32
++static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
++{
++      unsigned index = pgd_index(address);
++      pgd_t *pgd_k;
++      pud_t *pud, *pud_k;
++      pmd_t *pmd, *pmd_k;
 +
-+              ret = __change_page_attr_set_clr(&alias_cpa, 0);
-+      }
++      pgd += index;
++      pgd_k = init_mm.pgd + index;
 +
-+#ifdef CONFIG_X86_64
-+      if (ret)
-+              return ret;
-+      /*
-+       * No need to redo, when the primary call touched the high
-+       * mapping already:
-+       */
-+      if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end))
-+              return 0;
++      if (!pgd_present(*pgd_k))
++              return NULL;
 +
 +      /*
-+       * If the physical address is inside the kernel map, we need
-+       * to touch the high mapped kernel as well:
++       * set_pgd(pgd, *pgd_k); here would be useless on PAE
++       * and redundant with the set_pmd() on non-PAE. As would
++       * set_pud.
 +       */
-+      if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn()))
-+              return 0;
-+
-+      alias_cpa = *cpa;
-+      alias_cpa.vaddr =
-+              (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map;
 +
-+      /*
-+       * The high mapping range is imprecise, so ignore the return value.
-+       */
-+      __change_page_attr_set_clr(&alias_cpa, 0);
-+#endif
-+      return ret;
-+}
++      pud = pud_offset(pgd, address);
++      pud_k = pud_offset(pgd_k, address);
++      if (!pud_present(*pud_k))
++              return NULL;
 +
-+static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
-+{
-+      int ret, numpages = cpa->numpages;
++      pmd = pmd_offset(pud, address);
++      pmd_k = pmd_offset(pud_k, address);
++      if (!pmd_present(*pmd_k))
++              return NULL;
++      if (!pmd_present(*pmd)) {
++              bool lazy = x86_read_percpu(xen_lazy_mmu);
 +
-+      while (numpages) {
++              x86_write_percpu(xen_lazy_mmu, false);
++#if CONFIG_XEN_COMPAT > 0x030002
++              set_pmd(pmd, *pmd_k);
++#else
 +              /*
-+               * Store the remaining nr of pages for the large page
-+               * preservation check.
++               * When running on older Xen we must launder *pmd_k through
++               * pmd_val() to ensure that _PAGE_PRESENT is correctly set.
 +               */
-+              cpa->numpages = numpages;
++              set_pmd(pmd, __pmd(pmd_val(*pmd_k)));
++#endif
++              x86_write_percpu(xen_lazy_mmu, lazy);
++      } else
++              BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
++      return pmd_k;
++}
++#endif
 +
-+              ret = __change_page_attr(cpa, checkalias);
-+              if (ret)
-+                      return ret;
++#ifdef CONFIG_X86_64
++static const char errata93_warning[] =
++KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
++KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
++KERN_ERR "******* Please consider a BIOS update.\n"
++KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
++#endif
 +
-+              if (checkalias) {
-+                      ret = cpa_process_alias(cpa);
-+                      if (ret)
-+                              return ret;
++/* Workaround for K8 erratum #93 & buggy BIOS.
++   BIOS SMM functions are required to use a specific workaround
++   to avoid corruption of the 64bit RIP register on C stepping K8.
++   A lot of BIOS that didn't get tested properly miss this.
++   The OS sees this as a page fault with the upper 32bits of RIP cleared.
++   Try to work around it here.
++   Note we only handle faults in kernel here.
++   Does nothing for X86_32
++ */
++static int is_errata93(struct pt_regs *regs, unsigned long address)
++{
++#ifdef CONFIG_X86_64
++      static int warned;
++      if (address != regs->ip)
++              return 0;
++      if ((address >> 32) != 0)
++              return 0;
++      address |= 0xffffffffUL << 32;
++      if ((address >= (u64)_stext && address <= (u64)_etext) ||
++          (address >= MODULES_VADDR && address <= MODULES_END)) {
++              if (!warned) {
++                      printk(errata93_warning);
++                      warned = 1;
 +              }
-+
-+              /*
-+               * Adjust the number of pages with the result of the
-+               * CPA operation. Either a large page has been
-+               * preserved or a single page update happened.
-+               */
-+              BUG_ON(cpa->numpages > numpages);
-+              numpages -= cpa->numpages;
-+              cpa->vaddr += cpa->numpages * PAGE_SIZE;
++              regs->ip = address;
++              return 1;
 +      }
++#endif
 +      return 0;
 +}
 +
-+static inline int cache_attr(pgprot_t attr)
++/*
++ * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal
++ * addresses >4GB.  We catch this in the page fault handler because these
++ * addresses are not reachable. Just detect this case and return.  Any code
++ * segment in LDT is compatibility mode.
++ */
++static int is_errata100(struct pt_regs *regs, unsigned long address)
 +{
-+      return pgprot_val(attr) &
-+              (_PAGE_PAT | _PAGE_PAT_LARGE | _PAGE_PWT | _PAGE_PCD);
++#ifdef CONFIG_X86_64
++      if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
++          (address >> 32))
++              return 1;
++#endif
++      return 0;
 +}
 +
-+static int change_page_attr_set_clr(unsigned long addr, int numpages,
-+                                  pgprot_t mask_set, pgprot_t mask_clr)
-+{
-+      struct cpa_data cpa;
-+      int ret, cache, checkalias;
++void do_invalid_op(struct pt_regs *, unsigned long);
 +
++static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
++{
++#ifdef CONFIG_X86_F00F_BUG
++      unsigned long nr;
 +      /*
-+       * Check, if we are requested to change a not supported
-+       * feature:
++       * Pentium F0 0F C7 C8 bug workaround.
 +       */
-+      mask_set = canon_pgprot(mask_set);
-+      mask_clr = canon_pgprot(mask_clr);
-+      if (!pgprot_val(mask_set) && !pgprot_val(mask_clr))
-+              return 0;
++      if (boot_cpu_data.f00f_bug) {
++              nr = (address - idt_descr.address) >> 3;
 +
-+      /* Ensure we are PAGE_SIZE aligned */
-+      if (addr & ~PAGE_MASK) {
-+              addr &= PAGE_MASK;
-+              /*
-+               * People should not be passing in unaligned addresses:
-+               */
-+              WARN_ON_ONCE(1);
++              if (nr == 6) {
++                      do_invalid_op(regs, 0);
++                      return 1;
++              }
 +      }
++#endif
++      return 0;
++}
 +
-+      cpa.vaddr = addr;
-+      cpa.numpages = numpages;
-+      cpa.mask_set = mask_set;
-+      cpa.mask_clr = mask_clr;
-+      cpa.flushtlb = 0;
-+
-+      /* No alias checking for _NX bit modifications */
-+      checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
-+
-+      ret = __change_page_attr_set_clr(&cpa, checkalias);
++static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
++                          unsigned long address)
++{
++#ifdef CONFIG_X86_32
++      if (!oops_may_print())
++              return;
++#endif
 +
-+      /*
-+       * Check whether we really changed something:
-+       */
-+      if (!cpa.flushtlb)
-+              goto out;
++#ifdef CONFIG_X86_PAE
++      if (error_code & PF_INSTR) {
++              unsigned int level;
++              pte_t *pte = lookup_address(address, &level);
 +
-+      /*
-+       * No need to flush, when we did not set any of the caching
-+       * attributes:
-+       */
-+      cache = cache_attr(mask_set);
++              if (pte && pte_present(*pte) && !pte_exec(*pte))
++                      printk(KERN_CRIT "kernel tried to execute "
++                              "NX-protected page - exploit attempt? "
++                              "(uid: %d)\n", current->uid);
++      }
++#endif
 +
-+      /*
-+       * On success we use clflush, when the CPU supports it to
-+       * avoid the wbindv. If the CPU does not support it and in the
-+       * error case we fall back to cpa_flush_all (which uses
-+       * wbindv):
-+       */
-+      if (!ret && cpu_has_clflush)
-+              cpa_flush_range(addr, numpages, cache);
++      printk(KERN_ALERT "BUG: unable to handle kernel ");
++      if (address < PAGE_SIZE)
++              printk(KERN_CONT "NULL pointer dereference");
 +      else
-+              cpa_flush_all(cache);
-+
-+out:
-+      cpa_fill_pool(NULL);
-+
-+      return ret;
++              printk(KERN_CONT "paging request");
++#ifdef CONFIG_X86_32
++      printk(KERN_CONT " at %08lx\n", address);
++#else
++      printk(KERN_CONT " at %016lx\n", address);
++#endif
++      printk(KERN_ALERT "IP:");
++      printk_address(regs->ip, 1);
++      dump_pagetable(address);
 +}
 +
-+static inline int change_page_attr_set(unsigned long addr, int numpages,
-+                                     pgprot_t mask)
++#ifdef CONFIG_X86_64
++static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
++                               unsigned long error_code)
 +{
-+      return change_page_attr_set_clr(addr, numpages, mask, __pgprot(0));
++      unsigned long flags = oops_begin();
++      struct task_struct *tsk;
++
++      printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
++             current->comm, address);
++      dump_pagetable(address);
++      tsk = current;
++      tsk->thread.cr2 = address;
++      tsk->thread.trap_no = 14;
++      tsk->thread.error_code = error_code;
++      if (__die("Bad pagetable", regs, error_code))
++              regs = NULL;
++      oops_end(flags, regs, SIGKILL);
 +}
++#endif
 +
-+static inline int change_page_attr_clear(unsigned long addr, int numpages,
-+                                       pgprot_t mask)
++static int spurious_fault_check(unsigned long error_code, pte_t *pte)
 +{
-+      return change_page_attr_set_clr(addr, numpages, __pgprot(0), mask);
-+}
++      if ((error_code & PF_WRITE) && !pte_write(*pte))
++              return 0;
++      if ((error_code & PF_INSTR) && !pte_exec(*pte))
++              return 0;
 +
-+int set_memory_uc(unsigned long addr, int numpages)
-+{
-+      return change_page_attr_set(addr, numpages,
-+                                  __pgprot(_PAGE_PCD));
++      return 1;
 +}
-+EXPORT_SYMBOL(set_memory_uc);
 +
-+int set_memory_wb(unsigned long addr, int numpages)
++/*
++ * Handle a spurious fault caused by a stale TLB entry.  This allows
++ * us to lazily refresh the TLB when increasing the permissions of a
++ * kernel page (RO -> RW or NX -> X).  Doing it eagerly is very
++ * expensive since that implies doing a full cross-processor TLB
++ * flush, even if no stale TLB entries exist on other processors.
++ * There are no security implications to leaving a stale TLB when
++ * increasing the permissions on a page.
++ */
++static int spurious_fault(unsigned long address,
++                        unsigned long error_code)
 +{
-+      return change_page_attr_clear(addr, numpages,
-+                                    __pgprot(_PAGE_PCD | _PAGE_PWT));
-+}
-+EXPORT_SYMBOL(set_memory_wb);
++      pgd_t *pgd;
++      pud_t *pud;
++      pmd_t *pmd;
++      pte_t *pte;
 +
-+int set_memory_x(unsigned long addr, int numpages)
-+{
-+      return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_NX));
-+}
-+EXPORT_SYMBOL(set_memory_x);
++      /* Reserved-bit violation or user access to kernel space? */
++      if (error_code & (PF_USER | PF_RSVD))
++              return 0;
 +
-+int set_memory_nx(unsigned long addr, int numpages)
-+{
-+      return change_page_attr_set(addr, numpages, __pgprot(_PAGE_NX));
-+}
-+EXPORT_SYMBOL(set_memory_nx);
++      pgd = init_mm.pgd + pgd_index(address);
++      if (!pgd_present(*pgd))
++              return 0;
 +
-+int set_memory_ro(unsigned long addr, int numpages)
-+{
-+      return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
-+}
++      pud = pud_offset(pgd, address);
++      if (!pud_present(*pud))
++              return 0;
 +
-+int set_memory_rw(unsigned long addr, int numpages)
-+{
-+      return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
-+}
++      if (pud_large(*pud))
++              return spurious_fault_check(error_code, (pte_t *) pud);
 +
-+int set_memory_np(unsigned long addr, int numpages)
-+{
-+      return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_PRESENT));
-+}
++      pmd = pmd_offset(pud, address);
++      if (!pmd_present(*pmd))
++              return 0;
 +
-+int set_pages_uc(struct page *page, int numpages)
-+{
-+      unsigned long addr = (unsigned long)page_address(page);
++      if (pmd_large(*pmd))
++              return spurious_fault_check(error_code, (pte_t *) pmd);
 +
-+      return set_memory_uc(addr, numpages);
++      pte = pte_offset_kernel(pmd, address);
++      if (!pte_present(*pte))
++              return 0;
++
++      return spurious_fault_check(error_code, pte);
 +}
-+EXPORT_SYMBOL(set_pages_uc);
 +
-+int set_pages_wb(struct page *page, int numpages)
++/*
++ * X86_32
++ * Handle a fault on the vmalloc or module mapping area
++ *
++ * X86_64
++ * Handle a fault on the vmalloc area
++ *
++ * This assumes no large pages in there.
++ */
++static int vmalloc_fault(unsigned long address)
 +{
-+      unsigned long addr = (unsigned long)page_address(page);
++#ifdef CONFIG_X86_32
++      unsigned long pgd_paddr;
++      pmd_t *pmd_k;
++      pte_t *pte_k;
++      /*
++       * Synchronize this task's top level page-table
++       * with the 'reference' page table.
++       *
++       * Do _not_ use "current" here. We might be inside
++       * an interrupt in the middle of a task switch..
++       */
++      pgd_paddr = read_cr3();
++      pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
++      if (!pmd_k)
++              return -1;
++      pte_k = pte_offset_kernel(pmd_k, address);
++      if (!pte_present(*pte_k))
++              return -1;
++      return 0;
++#else
++      pgd_t *pgd, *pgd_ref;
++      pud_t *pud, *pud_ref;
++      pmd_t *pmd, *pmd_ref;
++      pte_t *pte, *pte_ref;
 +
-+      return set_memory_wb(addr, numpages);
-+}
-+EXPORT_SYMBOL(set_pages_wb);
++      /* Make sure we are in vmalloc area */
++      if (!(address >= VMALLOC_START && address < VMALLOC_END))
++              return -1;
 +
-+int set_pages_x(struct page *page, int numpages)
-+{
-+      unsigned long addr = (unsigned long)page_address(page);
++      /* Copy kernel mappings over when needed. This can also
++         happen within a race in page table update. In the later
++         case just flush. */
 +
-+      return set_memory_x(addr, numpages);
-+}
-+EXPORT_SYMBOL(set_pages_x);
++      /* On Xen the line below does not always work. Needs investigating! */
++      /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
++      pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
++      pgd += pgd_index(address);
++      pgd_ref = pgd_offset_k(address);
++      if (pgd_none(*pgd_ref))
++              return -1;
++      if (pgd_none(*pgd))
++              set_pgd(pgd, *pgd_ref);
++      else
++              BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
 +
-+int set_pages_nx(struct page *page, int numpages)
-+{
-+      unsigned long addr = (unsigned long)page_address(page);
++      /* Below here mismatches are bugs because these lower tables
++         are shared */
 +
-+      return set_memory_nx(addr, numpages);
++      pud = pud_offset(pgd, address);
++      pud_ref = pud_offset(pgd_ref, address);
++      if (pud_none(*pud_ref))
++              return -1;
++      if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
++              BUG();
++      pmd = pmd_offset(pud, address);
++      pmd_ref = pmd_offset(pud_ref, address);
++      if (pmd_none(*pmd_ref))
++              return -1;
++      if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
++              BUG();
++      pte_ref = pte_offset_kernel(pmd_ref, address);
++      if (!pte_present(*pte_ref))
++              return -1;
++      pte = pte_offset_kernel(pmd, address);
++      /* Don't use pte_page here, because the mappings can point
++         outside mem_map, and the NUMA hash lookup cannot handle
++         that. */
++      if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
++              BUG();
++      return 0;
++#endif
 +}
-+EXPORT_SYMBOL(set_pages_nx);
 +
-+int set_pages_ro(struct page *page, int numpages)
++int show_unhandled_signals = 1;
++
++/*
++ * This routine handles page faults.  It determines the address,
++ * and the problem, and then passes it off to one of the appropriate
++ * routines.
++ */
++#ifdef CONFIG_X86_64
++asmlinkage
++#endif
++void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
 +{
-+      unsigned long addr = (unsigned long)page_address(page);
++      struct task_struct *tsk;
++      struct mm_struct *mm;
++      struct vm_area_struct *vma;
++      unsigned long address;
++      int write, si_code;
++      int fault;
++#ifdef CONFIG_X86_64
++      unsigned long flags;
++#endif
 +
-+      return set_memory_ro(addr, numpages);
-+}
++      /*
++       * We can fault from pretty much anywhere, with unknown IRQ state.
++       */
++      trace_hardirqs_fixup();
 +
-+int set_pages_rw(struct page *page, int numpages)
-+{
-+      unsigned long addr = (unsigned long)page_address(page);
++      /* Set the "privileged fault" bit to something sane. */
++      if (user_mode_vm(regs))
++              error_code |= PF_USER;
++      else
++              error_code &= ~PF_USER;
 +
-+      return set_memory_rw(addr, numpages);
-+}
++      tsk = current;
++      mm = tsk->mm;
++      prefetchw(&mm->mmap_sem);
++
++      /* get the address */
++      address = read_cr2();
++
++      si_code = SEGV_MAPERR;
++
++      if (notify_page_fault(regs))
++              return;
++
++      /*
++       * We fault-in kernel-space virtual memory on-demand. The
++       * 'reference' page table is init_mm.pgd.
++       *
++       * NOTE! We MUST NOT take any locks for this case. We may
++       * be in an interrupt or a critical region, and should
++       * only copy the information from the master page table,
++       * nothing more.
++       *
++       * This verifies that the fault happens in kernel space
++       * (error_code & 4) == 0, and that the fault was not a
++       * protection error (error_code & 9) == 0.
++       */
++#ifdef CONFIG_X86_32
++      if (unlikely(address >= TASK_SIZE)) {
++#else
++      if (unlikely(address >= TASK_SIZE64)) {
++#endif
++              /* Faults in hypervisor area can never be patched up. */
++#if defined(CONFIG_X86_XEN)
++              if (address >= hypervisor_virt_start)
++                      goto bad_area_nosemaphore;
++#elif defined(CONFIG_X86_64_XEN)
++              if (address >= HYPERVISOR_VIRT_START
++                  && address < HYPERVISOR_VIRT_END)
++                      goto bad_area_nosemaphore;
++#endif
++              if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
++                  vmalloc_fault(address) >= 0)
++                      return;
 +
-+#ifdef CONFIG_DEBUG_PAGEALLOC
++              /* Can handle a stale RO->RW TLB */
++              if (spurious_fault(address, error_code))
++                      return;
 +
-+static int __set_pages_p(struct page *page, int numpages)
-+{
-+      struct cpa_data cpa = { .vaddr = (unsigned long) page_address(page),
-+                              .numpages = numpages,
-+                              .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
-+                              .mask_clr = __pgprot(0)};
++              /*
++               * Don't take the mm semaphore here. If we fixup a prefetch
++               * fault we could otherwise deadlock.
++               */
++              goto bad_area_nosemaphore;
++      }
 +
-+      return __change_page_attr_set_clr(&cpa, 1);
-+}
 +
-+static int __set_pages_np(struct page *page, int numpages)
-+{
-+      struct cpa_data cpa = { .vaddr = (unsigned long) page_address(page),
-+                              .numpages = numpages,
-+                              .mask_set = __pgprot(0),
-+                              .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW)};
++#ifdef CONFIG_X86_32
++      /* It's safe to allow irq's after cr2 has been saved and the vmalloc
++         fault has been handled. */
++      if (regs->flags & (X86_EFLAGS_IF|VM_MASK))
++              local_irq_enable();
 +
-+      return __change_page_attr_set_clr(&cpa, 1);
-+}
++      /*
++       * If we're in an interrupt, have no user context or are running in an
++       * atomic region then we must not take the fault.
++       */
++      if (in_atomic() || !mm)
++              goto bad_area_nosemaphore;
++#else /* CONFIG_X86_64 */
++      if (likely(regs->flags & X86_EFLAGS_IF))
++              local_irq_enable();
 +
-+void kernel_map_pages(struct page *page, int numpages, int enable)
-+{
-+      if (PageHighMem(page))
-+              return;
-+      if (!enable) {
-+              debug_check_no_locks_freed(page_address(page),
-+                                         numpages * PAGE_SIZE);
-+      }
++      if (unlikely(error_code & PF_RSVD))
++              pgtable_bad(address, regs, error_code);
 +
 +      /*
-+       * If page allocator is not up yet then do not call c_p_a():
++       * If we're in an interrupt, have no user context or are running in an
++       * atomic region then we must not take the fault.
 +       */
-+      if (!debug_pagealloc_enabled)
-+              return;
++      if (unlikely(in_atomic() || !mm))
++              goto bad_area_nosemaphore;
 +
 +      /*
-+       * The return value is ignored as the calls cannot fail.
-+       * Large pages are kept enabled at boot time, and are
-+       * split up quickly with DEBUG_PAGEALLOC. If a splitup
-+       * fails here (due to temporary memory shortage) no damage
-+       * is done because we just keep the largepage intact up
-+       * to the next attempt when it will likely be split up:
++       * User-mode registers count as a user access even for any
++       * potential system fault or CPU buglet.
 +       */
-+      if (enable)
-+              __set_pages_p(page, numpages);
-+      else
-+              __set_pages_np(page, numpages);
++      if (user_mode_vm(regs))
++              error_code |= PF_USER;
++again:
++#endif
++      /* When running in the kernel we expect faults to occur only to
++       * addresses in user space.  All other faults represent errors in the
++       * kernel and should generate an OOPS.  Unfortunately, in the case of an
++       * erroneous fault occurring in a code path which already holds mmap_sem
++       * we will deadlock attempting to validate the fault against the
++       * address space.  Luckily the kernel only validly references user
++       * space from well defined areas of code, which are listed in the
++       * exceptions table.
++       *
++       * As the vast majority of faults will be valid we will only perform
++       * the source reference check when there is a possibility of a deadlock.
++       * Attempt to lock the address space, if we cannot we then validate the
++       * source.  If this is invalid we can skip the address space check,
++       * thus avoiding the deadlock.
++       */
++      if (!down_read_trylock(&mm->mmap_sem)) {
++              if ((error_code & PF_USER) == 0 &&
++                  !search_exception_tables(regs->ip))
++                      goto bad_area_nosemaphore;
++              down_read(&mm->mmap_sem);
++      }
++
++      vma = find_vma(mm, address);
++      if (!vma)
++              goto bad_area;
++      if (vma->vm_start <= address)
++              goto good_area;
++      if (!(vma->vm_flags & VM_GROWSDOWN))
++              goto bad_area;
++      if (error_code & PF_USER) {
++              /*
++               * Accessing the stack below %sp is always a bug.
++               * The large cushion allows instructions like enter
++               * and pusha to work.  ("enter $65535,$31" pushes
++               * 32 pointers and then decrements %sp by 65535.)
++               */
++              if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
++                      goto bad_area;
++      }
++      if (expand_stack(vma, address))
++              goto bad_area;
++/*
++ * Ok, we have a good vm_area for this memory access, so
++ * we can handle it..
++ */
++good_area:
++      si_code = SEGV_ACCERR;
++      write = 0;
++      switch (error_code & (PF_PROT|PF_WRITE)) {
++      default:        /* 3: write, present */
++              /* fall through */
++      case PF_WRITE:          /* write, not present */
++              if (!(vma->vm_flags & VM_WRITE))
++                      goto bad_area;
++              write++;
++              break;
++      case PF_PROT:           /* read, present */
++              goto bad_area;
++      case 0:                 /* read, not present */
++              if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
++                      goto bad_area;
++      }
 +
++#ifdef CONFIG_X86_32
++survive:
++#endif
 +      /*
-+       * We should perform an IPI and flush all tlbs,
-+       * but that can deadlock->flush only current cpu:
++       * If for any reason at all we couldn't handle the fault,
++       * make sure we exit gracefully rather than endlessly redo
++       * the fault.
 +       */
-+      __flush_tlb_all();
++      fault = handle_mm_fault(mm, vma, address, write);
++      if (unlikely(fault & VM_FAULT_ERROR)) {
++              if (fault & VM_FAULT_OOM)
++                      goto out_of_memory;
++              else if (fault & VM_FAULT_SIGBUS)
++                      goto do_sigbus;
++              BUG();
++      }
++      if (fault & VM_FAULT_MAJOR)
++              tsk->maj_flt++;
++      else
++              tsk->min_flt++;
 +
++#ifdef CONFIG_X86_32
 +      /*
-+       * Try to refill the page pool here. We can do this only after
-+       * the tlb flush.
++       * Did it hit the DOS screen memory VA from vm86 mode?
 +       */
-+      cpa_fill_pool(NULL);
-+}
++      if (v8086_mode(regs)) {
++              unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
++              if (bit < 32)
++                      tsk->thread.screen_bitmap |= 1 << bit;
++      }
++#endif
++      up_read(&mm->mmap_sem);
++      return;
 +
-+#ifdef CONFIG_HIBERNATION
++/*
++ * Something tried to access memory that isn't in our memory map..
++ * Fix it, but check if it's kernel or user first..
++ */
++bad_area:
++      up_read(&mm->mmap_sem);
 +
-+bool kernel_page_present(struct page *page)
-+{
-+      unsigned int level;
-+      pte_t *pte;
++bad_area_nosemaphore:
++      /* User mode accesses just cause a SIGSEGV */
++      if (error_code & PF_USER) {
++              /*
++               * It's possible to have interrupts off here.
++               */
++              local_irq_enable();
 +
-+      if (PageHighMem(page))
-+              return false;
++              /*
++               * Valid to do another page fault here because this one came
++               * from user space.
++               */
++              if (is_prefetch(regs, address, error_code))
++                      return;
 +
-+      pte = lookup_address((unsigned long)page_address(page), &level);
-+      return (__pte_val(*pte) & _PAGE_PRESENT);
-+}
++              if (is_errata100(regs, address))
++                      return;
 +
-+#endif /* CONFIG_HIBERNATION */
++              if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
++                  printk_ratelimit()) {
++                      printk(
++#ifdef CONFIG_X86_32
++                      "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx",
++#else
++                      "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx",
++#endif
++                      task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
++                      tsk->comm, task_pid_nr(tsk), address, regs->ip,
++                      regs->sp, error_code);
++                      print_vma_addr(" in ", regs->ip);
++                      printk("\n");
++              }
 +
-+#endif /* CONFIG_DEBUG_PAGEALLOC */
++              tsk->thread.cr2 = address;
++              /* Kernel addresses are always protection faults */
++              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
++              tsk->thread.trap_no = 14;
++              force_sig_info_fault(SIGSEGV, si_code, address, tsk);
++              return;
++      }
 +
-+static inline int in_secondary_range(unsigned long va)
-+{
-+#ifdef CONFIG_X86_64
-+      return va >= VMALLOC_START && va < VMALLOC_END;
++      if (is_f00f_bug(regs, address))
++              return;
++
++no_context:
++      /* Are we prepared to handle this kernel fault?  */
++      if (fixup_exception(regs))
++              return;
++
++      /*
++       * X86_32
++       * Valid to do another page fault here, because if this fault
++       * had been triggered by is_prefetch fixup_exception would have
++       * handled it.
++       *
++       * X86_64
++       * Hall of shame of CPU/BIOS bugs.
++       */
++      if (is_prefetch(regs, address, error_code))
++              return;
++
++      if (is_errata93(regs, address))
++              return;
++
++/*
++ * Oops. The kernel tried to access some bad page. We'll have to
++ * terminate things with extreme prejudice.
++ */
++#ifdef CONFIG_X86_32
++      bust_spinlocks(1);
 +#else
-+      return va >= (unsigned long)high_memory;
++      flags = oops_begin();
 +#endif
-+}
 +
-+static void __make_page_readonly(unsigned long va)
-+{
-+      pte_t *pte;
-+      unsigned int level;
++      show_fault_oops(regs, error_code, address);
 +
-+      pte = lookup_address(va, &level);
-+      BUG_ON(!pte || level != PG_LEVEL_4K);
-+      if (HYPERVISOR_update_va_mapping(va, pte_wrprotect(*pte), 0))
-+              BUG();
-+      if (in_secondary_range(va)) {
-+              unsigned long pfn = pte_pfn(*pte);
++      tsk->thread.cr2 = address;
++      tsk->thread.trap_no = 14;
++      tsk->thread.error_code = error_code;
 +
-+#ifdef CONFIG_HIGHMEM
-+              if (pfn >= highstart_pfn)
-+                      kmap_flush_unused(); /* flush stale writable kmaps */
-+              else
++#ifdef CONFIG_X86_32
++      die("Oops", regs, error_code);
++      bust_spinlocks(0);
++      do_exit(SIGKILL);
++#else
++      if (__die("Oops", regs, error_code))
++              regs = NULL;
++      /* Executive summary in case the body of the oops scrolled away */
++      printk(KERN_EMERG "CR2: %016lx\n", address);
++      oops_end(flags, regs, SIGKILL);
++#endif
++
++/*
++ * We ran out of memory, or some other thing happened to us that made
++ * us unable to handle the page fault gracefully.
++ */
++out_of_memory:
++      up_read(&mm->mmap_sem);
++      if (is_global_init(tsk)) {
++              yield();
++#ifdef CONFIG_X86_32
++              down_read(&mm->mmap_sem);
++              goto survive;
++#else
++              goto again;
 +#endif
-+                      __make_page_readonly((unsigned long)__va(pfn << PAGE_SHIFT));
 +      }
-+}
 +
-+static void __make_page_writable(unsigned long va)
-+{
-+      pte_t *pte;
-+      unsigned int level;
++      printk("VM: killing process %s\n", tsk->comm);
++      if (error_code & PF_USER)
++              do_group_exit(SIGKILL);
++      goto no_context;
 +
-+      pte = lookup_address(va, &level);
-+      BUG_ON(!pte || level != PG_LEVEL_4K);
-+      if (HYPERVISOR_update_va_mapping(va, pte_mkwrite(*pte), 0))
-+              BUG();
-+      if (in_secondary_range(va)) {
-+              unsigned long pfn = pte_pfn(*pte);
++do_sigbus:
++      up_read(&mm->mmap_sem);
 +
-+#ifdef CONFIG_HIGHMEM
-+              if (pfn < highstart_pfn)
++      /* Kernel mode? Handle exceptions or die */
++      if (!(error_code & PF_USER))
++              goto no_context;
++#ifdef CONFIG_X86_32
++      /* User space => ok to do another page fault */
++      if (is_prefetch(regs, address, error_code))
++              return;
 +#endif
-+                      __make_page_writable((unsigned long)__va(pfn << PAGE_SHIFT));
-+      }
-+}
-+
-+void make_page_readonly(void *va, unsigned int feature)
-+{
-+      if (!xen_feature(feature))
-+              __make_page_readonly((unsigned long)va);
++      tsk->thread.cr2 = address;
++      tsk->thread.error_code = error_code;
++      tsk->thread.trap_no = 14;
++      force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
 +}
 +
-+void make_page_writable(void *va, unsigned int feature)
-+{
-+      if (!xen_feature(feature))
-+              __make_page_writable((unsigned long)va);
-+}
++DEFINE_SPINLOCK(pgd_lock);
++LIST_HEAD(pgd_list);
 +
-+void make_pages_readonly(void *va, unsigned int nr, unsigned int feature)
++void vmalloc_sync_all(void)
 +{
-+      unsigned long addr;
++#ifdef CONFIG_X86_32
++      /*
++       * Note that races in the updates of insync and start aren't
++       * problematic: insync can only get set bits added, and updates to
++       * start are only improving performance (without affecting correctness
++       * if undone).
++       * XEN: To work on PAE, we need to iterate over PMDs rather than PGDs.
++       *      This change works just fine with 2-level paging too.
++       */
++#define sync_index(a) ((a) >> PMD_SHIFT)
++      static DECLARE_BITMAP(insync, PTRS_PER_PGD*PTRS_PER_PMD);
++      static unsigned long start = TASK_SIZE;
++      unsigned long address;
 +
-+      if (xen_feature(feature))
++      if (SHARED_KERNEL_PMD)
 +              return;
 +
-+      for (addr = (unsigned long)va; nr--; addr += PAGE_SIZE)
-+              __make_page_readonly(addr);
-+}
-+
-+void make_pages_writable(void *va, unsigned int nr, unsigned int feature)
-+{
-+      unsigned long addr;
++      BUILD_BUG_ON(TASK_SIZE & ~PMD_MASK);
++      for (address = start;
++           address < hypervisor_virt_start;
++           address += PMD_SIZE) {
++              if (!test_bit(sync_index(address), insync)) {
++                      unsigned long flags;
++                      struct page *page;
 +
-+      if (xen_feature(feature))
-+              return;
++                      spin_lock_irqsave(&pgd_lock, flags);
++                      /* XEN: failure path assumes non-empty pgd_list. */
++                      if (unlikely(list_empty(&pgd_list))) {
++                              spin_unlock_irqrestore(&pgd_lock, flags);
++                              return;
++                      }
++                      list_for_each_entry(page, &pgd_list, lru) {
++                              if (!vmalloc_sync_one(page_address(page),
++                                                    address))
++                                      break;
++                      }
++                      spin_unlock_irqrestore(&pgd_lock, flags);
++                      if (!page)
++                              set_bit(sync_index(address), insync);
++              }
++              if (address == start && test_bit(sync_index(address), insync))
++                      start = address + PMD_SIZE;
++      }
++#else /* CONFIG_X86_64 */
++      /*
++       * Note that races in the updates of insync and start aren't
++       * problematic: insync can only get set bits added, and updates to
++       * start are only improving performance (without affecting correctness
++       * if undone).
++       */
++      static DECLARE_BITMAP(insync, PTRS_PER_PGD);
++      static unsigned long start = VMALLOC_START & PGDIR_MASK;
++      unsigned long address;
 +
-+      for (addr = (unsigned long)va; nr--; addr += PAGE_SIZE)
-+              __make_page_writable(addr);
-+}
++      for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
++              if (!test_bit(pgd_index(address), insync)) {
++                      const pgd_t *pgd_ref = pgd_offset_k(address);
++                      unsigned long flags;
++                      struct page *page;
 +
-+/*
-+ * The testcases use internal knowledge of the implementation that shouldn't
-+ * be exposed to the rest of the kernel. Include these directly here.
-+ */
-+#ifdef CONFIG_CPA_DEBUG
-+#include "pageattr-test.c"
++                      if (pgd_none(*pgd_ref))
++                              continue;
++                      spin_lock_irqsave(&pgd_lock, flags);
++                      list_for_each_entry(page, &pgd_list, lru) {
++                              pgd_t *pgd;
++                              pgd = (pgd_t *)page_address(page) + pgd_index(address);
++                              if (pgd_none(*pgd))
++                                      set_pgd(pgd, *pgd_ref);
++                              else
++                                      BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
++                      }
++                      spin_unlock_irqrestore(&pgd_lock, flags);
++                      set_bit(pgd_index(address), insync);
++              }
++              if (address == start)
++                      start = address + PGDIR_SIZE;
++      }
++      /* Check that there is no need to do the same for the modules area. */
++      BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
++      BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
++                              (__START_KERNEL & PGDIR_MASK)));
 +#endif
---- a/arch/x86/mm/pgtable_32-xen.c
-+++ b/arch/x86/mm/pgtable_32-xen.c
-@@ -29,8 +29,6 @@
- #include <xen/features.h>
- #include <asm/hypervisor.h>
--static void pgd_test_and_unpin(pgd_t *pgd);
++}
+--- sle11-2009-05-14.orig/arch/x86/mm/fault_32-xen.c   2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,757 +0,0 @@
+-/*
+- *  linux/arch/i386/mm/fault.c
+- *
+- *  Copyright (C) 1995  Linus Torvalds
+- */
+-
+-#include <linux/signal.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/string.h>
+-#include <linux/types.h>
+-#include <linux/ptrace.h>
+-#include <linux/mman.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/interrupt.h>
+-#include <linux/init.h>
+-#include <linux/tty.h>
+-#include <linux/vt_kern.h>            /* For unblank_screen() */
+-#include <linux/highmem.h>
+-#include <linux/bootmem.h>            /* for max_low_pfn */
+-#include <linux/vmalloc.h>
+-#include <linux/module.h>
+-#include <linux/kprobes.h>
+-#include <linux/uaccess.h>
+-#include <linux/kdebug.h>
+-#include <linux/kprobes.h>
+-
+-#include <asm/system.h>
+-#include <asm/desc.h>
+-#include <asm/segment.h>
+-
+-extern void die(const char *,struct pt_regs *,long);
+-
+-#ifdef CONFIG_KPROBES
+-static inline int notify_page_fault(struct pt_regs *regs)
+-{
+-      int ret = 0;
+-
+-      /* kprobe_running() needs smp_processor_id() */
+-      if (!user_mode_vm(regs)) {
+-              preempt_disable();
+-              if (kprobe_running() && kprobe_fault_handler(regs, 14))
+-                      ret = 1;
+-              preempt_enable();
+-      }
+-
+-      return ret;
+-}
+-#else
+-static inline int notify_page_fault(struct pt_regs *regs)
+-{
+-      return 0;
+-}
+-#endif
+-
+-/*
+- * Return EIP plus the CS segment base.  The segment limit is also
+- * adjusted, clamped to the kernel/user address space (whichever is
+- * appropriate), and returned in *eip_limit.
+- *
+- * The segment is checked, because it might have been changed by another
+- * task between the original faulting instruction and here.
+- *
+- * If CS is no longer a valid code segment, or if EIP is beyond the
+- * limit, or if it is a kernel address when CS is not a kernel segment,
+- * then the returned value will be greater than *eip_limit.
+- * 
+- * This is slow, but is very rarely executed.
+- */
+-static inline unsigned long get_segment_eip(struct pt_regs *regs,
+-                                          unsigned long *eip_limit)
+-{
+-      unsigned long eip = regs->eip;
+-      unsigned seg = regs->xcs & 0xffff;
+-      u32 seg_ar, seg_limit, base, *desc;
+-
+-      /* Unlikely, but must come before segment checks. */
+-      if (unlikely(regs->eflags & VM_MASK)) {
+-              base = seg << 4;
+-              *eip_limit = base + 0xffff;
+-              return base + (eip & 0xffff);
+-      }
+-
+-      /* The standard kernel/user address space limit. */
+-      *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg;
+-      
+-      /* By far the most common cases. */
+-      if (likely(SEGMENT_IS_FLAT_CODE(seg)))
+-              return eip;
+-
+-      /* Check the segment exists, is within the current LDT/GDT size,
+-         that kernel/user (ring 0..3) has the appropriate privilege,
+-         that it's a code segment, and get the limit. */
+-      __asm__ ("larl %3,%0; lsll %3,%1"
+-               : "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg));
+-      if ((~seg_ar & 0x9800) || eip > seg_limit) {
+-              *eip_limit = 0;
+-              return 1;        /* So that returned eip > *eip_limit. */
+-      }
+-
+-      /* Get the GDT/LDT descriptor base. 
+-         When you look for races in this code remember that
+-         LDT and other horrors are only used in user space. */
+-      if (seg & (1<<2)) {
+-              /* Must lock the LDT while reading it. */
+-              mutex_lock(&current->mm->context.lock);
+-              desc = current->mm->context.ldt;
+-              desc = (void *)desc + (seg & ~7);
+-      } else {
+-              /* Must disable preemption while reading the GDT. */
+-              desc = (u32 *)get_cpu_gdt_table(get_cpu());
+-              desc = (void *)desc + (seg & ~7);
+-      }
+-
+-      /* Decode the code segment base from the descriptor */
+-      base = get_desc_base((unsigned long *)desc);
+-
+-      if (seg & (1<<2)) { 
+-              mutex_unlock(&current->mm->context.lock);
+-      } else
+-              put_cpu();
+-
+-      /* Adjust EIP and segment limit, and clamp at the kernel limit.
+-         It's legitimate for segments to wrap at 0xffffffff. */
+-      seg_limit += base;
+-      if (seg_limit < *eip_limit && seg_limit >= base)
+-              *eip_limit = seg_limit;
+-      return eip + base;
+-}
+-
+-/* 
+- * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
+- * Check that here and ignore it.
+- */
+-static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
+-{ 
+-      unsigned long limit;
+-      unsigned char *instr = (unsigned char *)get_segment_eip (regs, &limit);
+-      int scan_more = 1;
+-      int prefetch = 0; 
+-      int i;
+-
+-      for (i = 0; scan_more && i < 15; i++) { 
+-              unsigned char opcode;
+-              unsigned char instr_hi;
+-              unsigned char instr_lo;
+-
+-              if (instr > (unsigned char *)limit)
+-                      break;
+-              if (probe_kernel_address(instr, opcode))
+-                      break; 
+-
+-              instr_hi = opcode & 0xf0; 
+-              instr_lo = opcode & 0x0f; 
+-              instr++;
+-
+-              switch (instr_hi) { 
+-              case 0x20:
+-              case 0x30:
+-                      /* Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. */
+-                      scan_more = ((instr_lo & 7) == 0x6);
+-                      break;
+-                      
+-              case 0x60:
+-                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
+-                      scan_more = (instr_lo & 0xC) == 0x4;
+-                      break;          
+-              case 0xF0:
+-                      /* 0xF0, 0xF2, and 0xF3 are valid prefixes */
+-                      scan_more = !instr_lo || (instr_lo>>1) == 1;
+-                      break;                  
+-              case 0x00:
+-                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
+-                      scan_more = 0;
+-                      if (instr > (unsigned char *)limit)
+-                              break;
+-                      if (probe_kernel_address(instr, opcode))
+-                              break;
+-                      prefetch = (instr_lo == 0xF) &&
+-                              (opcode == 0x0D || opcode == 0x18);
+-                      break;                  
+-              default:
+-                      scan_more = 0;
+-                      break;
+-              } 
+-      }
+-      return prefetch;
+-}
+-
+-static inline int is_prefetch(struct pt_regs *regs, unsigned long addr,
+-                            unsigned long error_code)
+-{
+-      if (unlikely(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+-                   boot_cpu_data.x86 >= 6)) {
+-              /* Catch an obscure case of prefetch inside an NX page. */
+-              if (nx_enabled && (error_code & 16))
+-                      return 0;
+-              return __is_prefetch(regs, addr);
+-      }
+-      return 0;
+-} 
+-
+-static noinline void force_sig_info_fault(int si_signo, int si_code,
+-      unsigned long address, struct task_struct *tsk)
+-{
+-      siginfo_t info;
+-
+-      info.si_signo = si_signo;
+-      info.si_errno = 0;
+-      info.si_code = si_code;
+-      info.si_addr = (void __user *)address;
+-      force_sig_info(si_signo, &info, tsk);
+-}
+-
+-fastcall void do_invalid_op(struct pt_regs *, unsigned long);
+-
+-#ifdef CONFIG_X86_PAE
+-static void dump_fault_path(unsigned long address)
+-{
+-      unsigned long *p, page;
+-      unsigned long mfn; 
+-
+-      page = read_cr3();
+-      p  = (unsigned long *)__va(page);
+-      p += (address >> 30) * 2;
+-      printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
+-      if (p[0] & _PAGE_PRESENT) {
+-              mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
+-              page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
+-              p  = (unsigned long *)__va(page);
+-              address &= 0x3fffffff;
+-              p += (address >> 21) * 2;
+-              printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", 
+-                     page, p[1], p[0]);
+-              mfn  = (p[0] >> PAGE_SHIFT) | (p[1] << 20);
+-#ifdef CONFIG_HIGHPTE
+-              if (mfn_to_pfn(mfn) >= highstart_pfn)
+-                      return;
+-#endif
+-              if ((p[0] & _PAGE_PRESENT) && !(p[0] & _PAGE_PSE)) {
+-                      page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
+-                      p  = (unsigned long *) __va(page);
+-                      address &= 0x001fffff;
+-                      p += (address >> 12) * 2;
+-                      printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n",
+-                             page, p[1], p[0]);
+-              }
+-      }
+-}
+-#else
+-static void dump_fault_path(unsigned long address)
+-{
+-      unsigned long page;
+-
+-      page = read_cr3();
+-      page = ((unsigned long *) __va(page))[address >> PGDIR_SHIFT];
+-      printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
+-             machine_to_phys(page));
+-      /*
+-       * We must not directly access the pte in the highpte
+-       * case if the page table is located in highmem.
+-       * And lets rather not kmap-atomic the pte, just in case
+-       * it's allocated already.
+-       */
+-      if ((machine_to_phys(page) >> PAGE_SHIFT) < max_low_pfn
+-          && (page & _PAGE_PRESENT)
+-          && !(page & _PAGE_PSE)) {
+-              page = machine_to_phys(page & PAGE_MASK);
+-              page = ((unsigned long *) __va(page))[(address >> PAGE_SHIFT)
+-                                                    & (PTRS_PER_PTE - 1)];
+-              printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page,
+-                     machine_to_phys(page));
+-      }
+-}
+-#endif
+-
+-static int spurious_fault(struct pt_regs *regs,
+-                        unsigned long address,
+-                        unsigned long error_code)
+-{
+-      pgd_t *pgd;
+-      pud_t *pud;
+-      pmd_t *pmd;
+-      pte_t *pte;
+-
+-      /* Reserved-bit violation or user access to kernel space? */
+-      if (error_code & 0x0c)
+-              return 0;
+-
+-      pgd = init_mm.pgd + pgd_index(address);
+-      if (!pgd_present(*pgd))
+-              return 0;
+-
+-      pud = pud_offset(pgd, address);
+-      if (!pud_present(*pud))
+-              return 0;
+-
+-      pmd = pmd_offset(pud, address);
+-      if (!pmd_present(*pmd))
+-              return 0;
+-
+-      pte = pte_offset_kernel(pmd, address);
+-      if (!pte_present(*pte))
+-              return 0;
+-      if ((error_code & 0x02) && !pte_write(*pte))
+-              return 0;
+-#ifdef CONFIG_X86_PAE
+-      if ((error_code & 0x10) && (__pte_val(*pte) & _PAGE_NX))
+-              return 0;
+-#endif
+-
+-      return 1;
+-}
+-
+-static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
+-{
+-      unsigned index = pgd_index(address);
+-      pgd_t *pgd_k;
+-      pud_t *pud, *pud_k;
+-      pmd_t *pmd, *pmd_k;
+-
+-      pgd += index;
+-      pgd_k = init_mm.pgd + index;
+-
+-      if (!pgd_present(*pgd_k))
+-              return NULL;
+-
+-      /*
+-       * set_pgd(pgd, *pgd_k); here would be useless on PAE
+-       * and redundant with the set_pmd() on non-PAE. As would
+-       * set_pud.
+-       */
+-
+-      pud = pud_offset(pgd, address);
+-      pud_k = pud_offset(pgd_k, address);
+-      if (!pud_present(*pud_k))
+-              return NULL;
+-
+-      pmd = pmd_offset(pud, address);
+-      pmd_k = pmd_offset(pud_k, address);
+-      if (!pmd_present(*pmd_k))
+-              return NULL;
+-      if (!pmd_present(*pmd)) {
+-              bool lazy = x86_read_percpu(xen_lazy_mmu);
+-
+-              x86_write_percpu(xen_lazy_mmu, false);
+-#if CONFIG_XEN_COMPAT > 0x030002
+-              set_pmd(pmd, *pmd_k);
+-#else
+-              /*
+-               * When running on older Xen we must launder *pmd_k through
+-               * pmd_val() to ensure that _PAGE_PRESENT is correctly set.
+-               */
+-              set_pmd(pmd, __pmd(pmd_val(*pmd_k)));
+-#endif
+-              x86_write_percpu(xen_lazy_mmu, lazy);
+-      } else
+-              BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+-      return pmd_k;
+-}
+-
+-/*
+- * Handle a fault on the vmalloc or module mapping area
+- *
+- * This assumes no large pages in there.
+- */
+-static inline int vmalloc_fault(unsigned long address)
+-{
+-      unsigned long pgd_paddr;
+-      pmd_t *pmd_k;
+-      pte_t *pte_k;
+-      /*
+-       * Synchronize this task's top level page-table
+-       * with the 'reference' page table.
+-       *
+-       * Do _not_ use "current" here. We might be inside
+-       * an interrupt in the middle of a task switch..
+-       */
+-      pgd_paddr = read_cr3();
+-      pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
+-      if (!pmd_k)
+-              return -1;
+-      pte_k = pte_offset_kernel(pmd_k, address);
+-      if (!pte_present(*pte_k))
+-              return -1;
+-      return 0;
+-}
+-
+-int show_unhandled_signals = 1;
+-
+-/*
+- * This routine handles page faults.  It determines the address,
+- * and the problem, and then passes it off to one of the appropriate
+- * routines.
+- *
+- * error_code:
+- *    bit 0 == 0 means no page found, 1 means protection fault
+- *    bit 1 == 0 means read, 1 means write
+- *    bit 2 == 0 means kernel, 1 means user-mode
+- *    bit 3 == 1 means use of reserved bit detected
+- *    bit 4 == 1 means fault was an instruction fetch
+- */
+-fastcall void __kprobes do_page_fault(struct pt_regs *regs,
+-                                    unsigned long error_code)
+-{
+-      struct task_struct *tsk;
+-      struct mm_struct *mm;
+-      struct vm_area_struct * vma;
+-      unsigned long address;
+-      int write, si_code;
+-      int fault;
+-
+-      /*
+-       * We can fault from pretty much anywhere, with unknown IRQ state.
+-       */
+-      trace_hardirqs_fixup();
+-
+-      /* get the address */
+-        address = read_cr2();
+-
+-      /* Set the "privileged fault" bit to something sane. */
+-      error_code &= ~4;
+-      error_code |= (regs->xcs & 2) << 1;
+-      if (regs->eflags & X86_EFLAGS_VM)
+-              error_code |= 4;
+-
+-      tsk = current;
+-
+-      si_code = SEGV_MAPERR;
+-
+-      /*
+-       * We fault-in kernel-space virtual memory on-demand. The
+-       * 'reference' page table is init_mm.pgd.
+-       *
+-       * NOTE! We MUST NOT take any locks for this case. We may
+-       * be in an interrupt or a critical region, and should
+-       * only copy the information from the master page table,
+-       * nothing more.
+-       *
+-       * This verifies that the fault happens in kernel space
+-       * (error_code & 4) == 0, and that the fault was not a
+-       * protection error (error_code & 9) == 0.
+-       */
+-      if (unlikely(address >= TASK_SIZE)) {
+-#ifdef CONFIG_XEN
+-              /* Faults in hypervisor area can never be patched up. */
+-              if (address >= hypervisor_virt_start)
+-                      goto bad_area_nosemaphore;
+-#endif
+-              if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0)
+-                      return;
+-              /* Can take a spurious fault if mapping changes R/O -> R/W. */
+-              if (spurious_fault(regs, address, error_code))
+-                      return;
+-              if (notify_page_fault(regs))
+-                      return;
+-              /* 
+-               * Don't take the mm semaphore here. If we fixup a prefetch
+-               * fault we could otherwise deadlock.
+-               */
+-              goto bad_area_nosemaphore;
+-      }
+-
+-      if (notify_page_fault(regs))
+-              return;
+-
+-      /* It's safe to allow irq's after cr2 has been saved and the vmalloc
+-         fault has been handled. */
+-      if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
+-              local_irq_enable();
+-
+-      mm = tsk->mm;
+-
+-      /*
+-       * If we're in an interrupt, have no user context or are running in an
+-       * atomic region then we must not take the fault..
+-       */
+-      if (in_atomic() || !mm)
+-              goto bad_area_nosemaphore;
+-
+-      /* When running in the kernel we expect faults to occur only to
+-       * addresses in user space.  All other faults represent errors in the
+-       * kernel and should generate an OOPS.  Unfortunately, in the case of an
+-       * erroneous fault occurring in a code path which already holds mmap_sem
+-       * we will deadlock attempting to validate the fault against the
+-       * address space.  Luckily the kernel only validly references user
+-       * space from well defined areas of code, which are listed in the
+-       * exceptions table.
+-       *
+-       * As the vast majority of faults will be valid we will only perform
+-       * the source reference check when there is a possibility of a deadlock.
+-       * Attempt to lock the address space, if we cannot we then validate the
+-       * source.  If this is invalid we can skip the address space check,
+-       * thus avoiding the deadlock.
+-       */
+-      if (!down_read_trylock(&mm->mmap_sem)) {
+-              if ((error_code & 4) == 0 &&
+-                  !search_exception_tables(regs->eip))
+-                      goto bad_area_nosemaphore;
+-              down_read(&mm->mmap_sem);
+-      }
+-
+-      vma = find_vma(mm, address);
+-      if (!vma)
+-              goto bad_area;
+-      if (vma->vm_start <= address)
+-              goto good_area;
+-      if (!(vma->vm_flags & VM_GROWSDOWN))
+-              goto bad_area;
+-      if (error_code & 4) {
+-              /*
+-               * Accessing the stack below %esp is always a bug.
+-               * The large cushion allows instructions like enter
+-               * and pusha to work.  ("enter $65535,$31" pushes
+-               * 32 pointers and then decrements %esp by 65535.)
+-               */
+-              if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
+-                      goto bad_area;
+-      }
+-      if (expand_stack(vma, address))
+-              goto bad_area;
+-/*
+- * Ok, we have a good vm_area for this memory access, so
+- * we can handle it..
+- */
+-good_area:
+-      si_code = SEGV_ACCERR;
+-      write = 0;
+-      switch (error_code & 3) {
+-              default:        /* 3: write, present */
+-                              /* fall through */
+-              case 2:         /* write, not present */
+-                      if (!(vma->vm_flags & VM_WRITE))
+-                              goto bad_area;
+-                      write++;
+-                      break;
+-              case 1:         /* read, present */
+-                      goto bad_area;
+-              case 0:         /* read, not present */
+-                      if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
+-                              goto bad_area;
+-      }
+-
+- survive:
+-      /*
+-       * If for any reason at all we couldn't handle the fault,
+-       * make sure we exit gracefully rather than endlessly redo
+-       * the fault.
+-       */
+-      fault = handle_mm_fault(mm, vma, address, write);
+-      if (unlikely(fault & VM_FAULT_ERROR)) {
+-              if (fault & VM_FAULT_OOM)
+-                      goto out_of_memory;
+-              else if (fault & VM_FAULT_SIGBUS)
+-                      goto do_sigbus;
+-              BUG();
+-      }
+-      if (fault & VM_FAULT_MAJOR)
+-              tsk->maj_flt++;
+-      else
+-              tsk->min_flt++;
+-
+-      /*
+-       * Did it hit the DOS screen memory VA from vm86 mode?
+-       */
+-      if (regs->eflags & VM_MASK) {
+-              unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
+-              if (bit < 32)
+-                      tsk->thread.screen_bitmap |= 1 << bit;
+-      }
+-      up_read(&mm->mmap_sem);
+-      return;
+-
+-/*
+- * Something tried to access memory that isn't in our memory map..
+- * Fix it, but check if it's kernel or user first..
+- */
+-bad_area:
+-      up_read(&mm->mmap_sem);
+-
+-bad_area_nosemaphore:
+-      /* User mode accesses just cause a SIGSEGV */
+-      if (error_code & 4) {
+-              /*
+-               * It's possible to have interrupts off here.
+-               */
+-              local_irq_enable();
+-
+-              /* 
+-               * Valid to do another page fault here because this one came 
+-               * from user space.
+-               */
+-              if (is_prefetch(regs, address, error_code))
+-                      return;
+-
+-              if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+-                  printk_ratelimit()) {
+-                      printk("%s%s[%d]: segfault at %08lx eip %08lx "
+-                          "esp %08lx error %lx\n",
+-                          task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+-                          tsk->comm, task_pid_nr(tsk), address, regs->eip,
+-                          regs->esp, error_code);
+-              }
+-              tsk->thread.cr2 = address;
+-              /* Kernel addresses are always protection faults */
+-              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
+-              tsk->thread.trap_no = 14;
+-              force_sig_info_fault(SIGSEGV, si_code, address, tsk);
+-              return;
+-      }
+-
+-#ifdef CONFIG_X86_F00F_BUG
+-      /*
+-       * Pentium F0 0F C7 C8 bug workaround.
+-       */
+-      if (boot_cpu_data.f00f_bug) {
+-              unsigned long nr;
+-              
+-              nr = (address - idt_descr.address) >> 3;
+-
+-              if (nr == 6) {
+-                      do_invalid_op(regs, 0);
+-                      return;
+-              }
+-      }
+-#endif
+-
+-no_context:
+-      /* Are we prepared to handle this kernel fault?  */
+-      if (fixup_exception(regs))
+-              return;
+-
+-      /* 
+-       * Valid to do another page fault here, because if this fault
+-       * had been triggered by is_prefetch fixup_exception would have 
+-       * handled it.
+-       */
+-      if (is_prefetch(regs, address, error_code))
+-              return;
+-
+-/*
+- * Oops. The kernel tried to access some bad page. We'll have to
+- * terminate things with extreme prejudice.
+- */
+-
+-      bust_spinlocks(1);
+-
+-      if (oops_may_print()) {
+-#ifdef CONFIG_X86_PAE
+-              if (error_code & 16) {
+-                      pte_t *pte = lookup_address(address);
+-
+-                      if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
+-                              printk(KERN_CRIT "kernel tried to execute "
+-                                      "NX-protected page - exploit attempt? "
+-                                      "(uid: %d)\n", current->uid);
+-              }
+-#endif
+-              if (address < PAGE_SIZE)
+-                      printk(KERN_ALERT "BUG: unable to handle kernel NULL "
+-                                      "pointer dereference");
+-              else
+-                      printk(KERN_ALERT "BUG: unable to handle kernel paging"
+-                                      " request");
+-              printk(" at virtual address %08lx\n",address);
+-              printk(KERN_ALERT "printing eip: %08lx\n", regs->eip);
+-              dump_fault_path(address);
+-      }
+-      tsk->thread.cr2 = address;
+-      tsk->thread.trap_no = 14;
+-      tsk->thread.error_code = error_code;
+-      die("Oops", regs, error_code);
+-      bust_spinlocks(0);
+-      do_exit(SIGKILL);
+-
+-/*
+- * We ran out of memory, or some other thing happened to us that made
+- * us unable to handle the page fault gracefully.
+- */
+-out_of_memory:
+-      up_read(&mm->mmap_sem);
+-      if (is_global_init(tsk)) {
+-              yield();
+-              down_read(&mm->mmap_sem);
+-              goto survive;
+-      }
+-      printk("VM: killing process %s\n", tsk->comm);
+-      if (error_code & 4)
+-              do_group_exit(SIGKILL);
+-      goto no_context;
+-
+-do_sigbus:
+-      up_read(&mm->mmap_sem);
+-
+-      /* Kernel mode? Handle exceptions or die */
+-      if (!(error_code & 4))
+-              goto no_context;
+-
+-      /* User space => ok to do another page fault */
+-      if (is_prefetch(regs, address, error_code))
+-              return;
+-
+-      tsk->thread.cr2 = address;
+-      tsk->thread.error_code = error_code;
+-      tsk->thread.trap_no = 14;
+-      force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
+-}
+-
+-void vmalloc_sync_all(void)
+-{
+-      /*
+-       * Note that races in the updates of insync and start aren't
+-       * problematic: insync can only get set bits added, and updates to
+-       * start are only improving performance (without affecting correctness
+-       * if undone).
+-       * XEN: To work on PAE, we need to iterate over PMDs rather than PGDs.
+-       *      This change works just fine with 2-level paging too.
+-       */
+-#define sync_index(a) ((a) >> PMD_SHIFT)
+-      static DECLARE_BITMAP(insync, PTRS_PER_PGD*PTRS_PER_PMD);
+-      static unsigned long start = TASK_SIZE;
+-      unsigned long address;
+-
+-      if (SHARED_KERNEL_PMD)
+-              return;
+-
+-      BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK);
+-      for (address = start;
+-           address >= TASK_SIZE && address < hypervisor_virt_start;
+-           address += 1UL << PMD_SHIFT) {
+-              if (!test_bit(sync_index(address), insync)) {
+-                      unsigned long flags;
+-                      struct page *page;
+-
+-                      spin_lock_irqsave(&pgd_lock, flags);
+-                      /* XEN: failure path assumes non-empty pgd_list. */
+-                      if (unlikely(!pgd_list)) {
+-                              spin_unlock_irqrestore(&pgd_lock, flags);
+-                              return;
+-                      }
+-                      for (page = pgd_list; page; page =
+-                                      (struct page *)page->index)
+-                              if (!vmalloc_sync_one(page_address(page),
+-                                                              address)) {
+-                                      BUG_ON(page != pgd_list);
+-                                      break;
+-                              }
+-                      spin_unlock_irqrestore(&pgd_lock, flags);
+-                      if (!page)
+-                              set_bit(sync_index(address), insync);
+-              }
+-              if (address == start && test_bit(sync_index(address), insync))
+-                      start = address + (1UL << PMD_SHIFT);
+-      }
+-}
+--- sle11-2009-05-14.orig/arch/x86/mm/fault_64-xen.c   2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,686 +0,0 @@
+-/*
+- *  linux/arch/x86-64/mm/fault.c
+- *
+- *  Copyright (C) 1995  Linus Torvalds
+- *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
+- */
+-
+-#include <linux/signal.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/string.h>
+-#include <linux/types.h>
+-#include <linux/ptrace.h>
+-#include <linux/mman.h>
+-#include <linux/mm.h>
+-#include <linux/smp.h>
+-#include <linux/interrupt.h>
+-#include <linux/init.h>
+-#include <linux/tty.h>
+-#include <linux/vt_kern.h>            /* For unblank_screen() */
+-#include <linux/compiler.h>
+-#include <linux/vmalloc.h>
+-#include <linux/module.h>
+-#include <linux/kprobes.h>
+-#include <linux/uaccess.h>
+-#include <linux/kdebug.h>
+-#include <linux/kprobes.h>
+-
+-#include <asm/system.h>
+-#include <asm/pgalloc.h>
+-#include <asm/smp.h>
+-#include <asm/tlbflush.h>
+-#include <asm/proto.h>
+-#include <asm-generic/sections.h>
+-
+-/* Page fault error code bits */
+-#define PF_PROT       (1<<0)          /* or no page found */
+-#define PF_WRITE      (1<<1)
+-#define PF_USER       (1<<2)
+-#define PF_RSVD       (1<<3)
+-#define PF_INSTR      (1<<4)
+-
+-#ifdef CONFIG_KPROBES
+-static inline int notify_page_fault(struct pt_regs *regs)
+-{
+-      int ret = 0;
+-
+-      /* kprobe_running() needs smp_processor_id() */
+-      if (!user_mode(regs)) {
+-              preempt_disable();
+-              if (kprobe_running() && kprobe_fault_handler(regs, 14))
+-                      ret = 1;
+-              preempt_enable();
+-      }
+-
+-      return ret;
+-}
+-#else
+-static inline int notify_page_fault(struct pt_regs *regs)
+-{
+-      return 0;
+-}
+-#endif
+-
+-/* Sometimes the CPU reports invalid exceptions on prefetch.
+-   Check that here and ignore.
+-   Opcode checker based on code by Richard Brunner */
+-static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
+-                              unsigned long error_code)
+-{ 
+-      unsigned char *instr;
+-      int scan_more = 1;
+-      int prefetch = 0; 
+-      unsigned char *max_instr;
+-
+-      /* If it was a exec fault ignore */
+-      if (error_code & PF_INSTR)
+-              return 0;
+-      
+-      instr = (unsigned char __user *)convert_rip_to_linear(current, regs);
+-      max_instr = instr + 15;
+-
+-      if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
+-              return 0;
+-
+-      while (scan_more && instr < max_instr) { 
+-              unsigned char opcode;
+-              unsigned char instr_hi;
+-              unsigned char instr_lo;
+-
+-              if (probe_kernel_address(instr, opcode))
+-                      break; 
+-
+-              instr_hi = opcode & 0xf0; 
+-              instr_lo = opcode & 0x0f; 
+-              instr++;
+-
+-              switch (instr_hi) { 
+-              case 0x20:
+-              case 0x30:
+-                      /* Values 0x26,0x2E,0x36,0x3E are valid x86
+-                         prefixes.  In long mode, the CPU will signal
+-                         invalid opcode if some of these prefixes are
+-                         present so we will never get here anyway */
+-                      scan_more = ((instr_lo & 7) == 0x6);
+-                      break;
+-                      
+-              case 0x40:
+-                      /* In AMD64 long mode, 0x40 to 0x4F are valid REX prefixes
+-                         Need to figure out under what instruction mode the
+-                         instruction was issued ... */
+-                      /* Could check the LDT for lm, but for now it's good
+-                         enough to assume that long mode only uses well known
+-                         segments or kernel. */
+-                      scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
+-                      break;
+-                      
+-              case 0x60:
+-                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
+-                      scan_more = (instr_lo & 0xC) == 0x4;
+-                      break;          
+-              case 0xF0:
+-                      /* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
+-                      scan_more = !instr_lo || (instr_lo>>1) == 1;
+-                      break;                  
+-              case 0x00:
+-                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
+-                      scan_more = 0;
+-                      if (probe_kernel_address(instr, opcode))
+-                              break;
+-                      prefetch = (instr_lo == 0xF) &&
+-                              (opcode == 0x0D || opcode == 0x18);
+-                      break;                  
+-              default:
+-                      scan_more = 0;
+-                      break;
+-              } 
+-      }
+-      return prefetch;
+-}
+-
+-static int bad_address(void *p) 
+-{ 
+-      unsigned long dummy;
+-      return probe_kernel_address((unsigned long *)p, dummy);
+-} 
+-
+-void dump_pagetable(unsigned long address)
+-{
+-      pgd_t *pgd;
+-      pud_t *pud;
+-      pmd_t *pmd;
+-      pte_t *pte;
+-
+-      pgd = (pgd_t *)read_cr3();
+-
+-      pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
+-      pgd += pgd_index(address);
+-      if (bad_address(pgd)) goto bad;
+-      printk("PGD %lx ", pgd_val(*pgd));
+-      if (!pgd_present(*pgd)) goto ret; 
+-
+-      pud = pud_offset(pgd, address);
+-      if (bad_address(pud)) goto bad;
+-      printk("PUD %lx ", pud_val(*pud));
+-      if (!pud_present(*pud)) goto ret;
+-
+-      pmd = pmd_offset(pud, address);
+-      if (bad_address(pmd)) goto bad;
+-      printk("PMD %lx ", pmd_val(*pmd));
+-      if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
+-
+-      pte = pte_offset_kernel(pmd, address);
+-      if (bad_address(pte)) goto bad;
+-      printk("PTE %lx", pte_val(*pte)); 
+-ret:
+-      printk("\n");
+-      return;
+-bad:
+-      printk("BAD\n");
+-}
+-
+-static const char errata93_warning[] = 
+-KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
+-KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
+-KERN_ERR "******* Please consider a BIOS update.\n"
+-KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
+-
+-/* Workaround for K8 erratum #93 & buggy BIOS.
+-   BIOS SMM functions are required to use a specific workaround
+-   to avoid corruption of the 64bit RIP register on C stepping K8. 
+-   A lot of BIOS that didn't get tested properly miss this. 
+-   The OS sees this as a page fault with the upper 32bits of RIP cleared.
+-   Try to work around it here.
+-   Note we only handle faults in kernel here. */
+-
+-static int is_errata93(struct pt_regs *regs, unsigned long address) 
+-{
+-      static int warned;
+-      if (address != regs->rip)
+-              return 0;
+-      if ((address >> 32) != 0) 
+-              return 0;
+-      address |= 0xffffffffUL << 32;
+-      if ((address >= (u64)_stext && address <= (u64)_etext) || 
+-          (address >= MODULES_VADDR && address <= MODULES_END)) { 
+-              if (!warned) {
+-                      printk(errata93_warning);               
+-                      warned = 1;
+-              }
+-              regs->rip = address;
+-              return 1;
+-      }
+-      return 0;
+-} 
+-
+-static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
+-                               unsigned long error_code)
+-{
+-      unsigned long flags = oops_begin();
+-      struct task_struct *tsk;
+-
+-      printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
+-             current->comm, address);
+-      dump_pagetable(address);
+-      tsk = current;
+-      tsk->thread.cr2 = address;
+-      tsk->thread.trap_no = 14;
+-      tsk->thread.error_code = error_code;
+-      __die("Bad pagetable", regs, error_code);
+-      oops_end(flags);
+-      do_exit(SIGKILL);
+-}
+-
+-/*
+- * Handle a fault on the vmalloc area
+- *
+- * This assumes no large pages in there.
+- */
+-static int vmalloc_fault(unsigned long address)
+-{
+-      pgd_t *pgd, *pgd_ref;
+-      pud_t *pud, *pud_ref;
+-      pmd_t *pmd, *pmd_ref;
+-      pte_t *pte, *pte_ref;
+-
+-      /* Copy kernel mappings over when needed. This can also
+-         happen within a race in page table update. In the later
+-         case just flush. */
+-
+-      /* On Xen the line below does not always work. Needs investigating! */
+-      /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
+-      pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
+-      pgd += pgd_index(address);
+-      pgd_ref = pgd_offset_k(address);
+-      if (pgd_none(*pgd_ref))
+-              return -1;
+-      if (pgd_none(*pgd))
+-              set_pgd(pgd, *pgd_ref);
+-      else
+-              BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+-
+-      /* Below here mismatches are bugs because these lower tables
+-         are shared */
+-
+-      pud = pud_offset(pgd, address);
+-      pud_ref = pud_offset(pgd_ref, address);
+-      if (pud_none(*pud_ref))
+-              return -1;
+-      if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
+-              BUG();
+-      pmd = pmd_offset(pud, address);
+-      pmd_ref = pmd_offset(pud_ref, address);
+-      if (pmd_none(*pmd_ref))
+-              return -1;
+-      if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
+-              BUG();
+-      pte_ref = pte_offset_kernel(pmd_ref, address);
+-      if (!pte_present(*pte_ref))
+-              return -1;
+-      pte = pte_offset_kernel(pmd, address);
+-      /* Don't use pte_page here, because the mappings can point
+-         outside mem_map, and the NUMA hash lookup cannot handle
+-         that. */
+-      if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
+-              BUG();
+-      return 0;
+-}
+-
+-int show_unhandled_signals = 1;
+-
+-
+-#define MEM_VERBOSE 1
+-
+-#ifdef MEM_VERBOSE
+-#define MEM_LOG(_f, _a...)                    \
+-      printk("fault.c:[%d]-> " _f "\n",       \
+-      __LINE__ , ## _a )
+-#else
+-#define MEM_LOG(_f, _a...) ((void)0)
+-#endif
+-
+-static int spurious_fault(struct pt_regs *regs,
+-                        unsigned long address,
+-                        unsigned long error_code)
+-{
+-      pgd_t *pgd;
+-      pud_t *pud;
+-      pmd_t *pmd;
+-      pte_t *pte;
+-
+-#ifdef CONFIG_XEN
+-      /* Faults in hypervisor area are never spurious. */
+-      if ((address >= HYPERVISOR_VIRT_START) &&
+-          (address < HYPERVISOR_VIRT_END))
+-              return 0;
+-#endif
+-
+-      /* Reserved-bit violation or user access to kernel space? */
+-      if (error_code & (PF_RSVD|PF_USER))
+-              return 0;
+-
+-      pgd = init_mm.pgd + pgd_index(address);
+-      if (!pgd_present(*pgd))
+-              return 0;
 -
- void show_mem(void)
- {
-       int total = 0, reserved = 0;
-@@ -167,53 +165,6 @@ pte_t *pte_alloc_one_kernel(struct mm_st
-       return pte;
- }
--static void _pte_free(struct page *page, unsigned int order)
--{
--      BUG_ON(order);
--      pte_free(page);
+-      pud = pud_offset(pgd, address);
+-      if (!pud_present(*pud))
+-              return 0;
+-
+-      pmd = pmd_offset(pud, address);
+-      if (!pmd_present(*pmd))
+-              return 0;
+-
+-      pte = pte_offset_kernel(pmd, address);
+-      if (!pte_present(*pte))
+-              return 0;
+-      if ((error_code & PF_WRITE) && !pte_write(*pte))
+-              return 0;
+-      if ((error_code & PF_INSTR) && (__pte_val(*pte) & _PAGE_NX))
+-              return 0;
+-
+-      return 1;
 -}
 -
--struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+-/*
+- * This routine handles page faults.  It determines the address,
+- * and the problem, and then passes it off to one of the appropriate
+- * routines.
+- */
+-asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
+-                                      unsigned long error_code)
 -{
--      struct page *pte;
+-      struct task_struct *tsk;
+-      struct mm_struct *mm;
+-      struct vm_area_struct * vma;
+-      unsigned long address;
+-      const struct exception_table_entry *fixup;
+-      int write, fault;
+-      unsigned long flags;
+-      siginfo_t info;
 -
--#ifdef CONFIG_HIGHPTE
--      pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
--#else
--      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
--#endif
--      if (pte) {
--              SetPageForeign(pte, _pte_free);
--              init_page_count(pte);
+-      if (!user_mode(regs))
+-              error_code &= ~PF_USER; /* means kernel */
+-
+-      /*
+-       * We can fault from pretty much anywhere, with unknown IRQ state.
+-       */
+-      trace_hardirqs_fixup();
+-
+-      tsk = current;
+-      mm = tsk->mm;
+-      prefetchw(&mm->mmap_sem);
+-
+-      /* get the address */
+-      address = read_cr2();
+-
+-      info.si_code = SEGV_MAPERR;
+-
+-
+-      /*
+-       * We fault-in kernel-space virtual memory on-demand. The
+-       * 'reference' page table is init_mm.pgd.
+-       *
+-       * NOTE! We MUST NOT take any locks for this case. We may
+-       * be in an interrupt or a critical region, and should
+-       * only copy the information from the master page table,
+-       * nothing more.
+-       *
+-       * This verifies that the fault happens in kernel space
+-       * (error_code & 4) == 0, and that the fault was not a
+-       * protection error (error_code & 9) == 0.
+-       */
+-      if (unlikely(address >= TASK_SIZE64)) {
+-              /*
+-               * Don't check for the module range here: its PML4
+-               * is always initialized because it's shared with the main
+-               * kernel text. Only vmalloc may need PML4 syncups.
+-               */
+-              if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
+-                    ((address >= VMALLOC_START && address < VMALLOC_END))) {
+-                      if (vmalloc_fault(address) >= 0)
+-                              return;
+-              }
+-              /* Can take a spurious fault if mapping changes R/O -> R/W. */
+-              if (spurious_fault(regs, address, error_code))
+-                      return;
+-              if (notify_page_fault(regs))
+-                      return;
+-              /*
+-               * Don't take the mm semaphore here. If we fixup a prefetch
+-               * fault we could otherwise deadlock.
+-               */
+-              goto bad_area_nosemaphore;
 -      }
--      return pte;
--}
 -
--void pte_free(struct page *pte)
--{
--      unsigned long pfn = page_to_pfn(pte);
+-      if (notify_page_fault(regs))
+-              return;
 -
--      if (!PageHighMem(pte)) {
--              unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
+-      if (likely(regs->eflags & X86_EFLAGS_IF))
+-              local_irq_enable();
 -
--              if (!pte_write(*virt_to_ptep(va)))
--                      if (HYPERVISOR_update_va_mapping(
--                              va, pfn_pte(pfn, PAGE_KERNEL), 0))
--                              BUG();
--      } else
--              ClearPagePinned(pte);
+-      if (unlikely(error_code & PF_RSVD))
+-              pgtable_bad(address, regs, error_code);
 -
--      ClearPageForeign(pte);
--      init_page_count(pte);
+-      /*
+-       * If we're in an interrupt or have no user
+-       * context, we must not take the fault..
+-       */
+-      if (unlikely(in_atomic() || !mm))
+-              goto bad_area_nosemaphore;
+-
+-      /*
+-       * User-mode registers count as a user access even for any
+-       * potential system fault or CPU buglet.
+-       */
+-      if (user_mode_vm(regs))
+-              error_code |= PF_USER;
+-
+- again:
+-      /* When running in the kernel we expect faults to occur only to
+-       * addresses in user space.  All other faults represent errors in the
+-       * kernel and should generate an OOPS.  Unfortunately, in the case of an
+-       * erroneous fault occurring in a code path which already holds mmap_sem
+-       * we will deadlock attempting to validate the fault against the
+-       * address space.  Luckily the kernel only validly references user
+-       * space from well defined areas of code, which are listed in the
+-       * exceptions table.
+-       *
+-       * As the vast majority of faults will be valid we will only perform
+-       * the source reference check when there is a possibility of a deadlock.
+-       * Attempt to lock the address space, if we cannot we then validate the
+-       * source.  If this is invalid we can skip the address space check,
+-       * thus avoiding the deadlock.
+-       */
+-      if (!down_read_trylock(&mm->mmap_sem)) {
+-              if ((error_code & PF_USER) == 0 &&
+-                  !search_exception_tables(regs->rip))
+-                      goto bad_area_nosemaphore;
+-              down_read(&mm->mmap_sem);
+-      }
+-
+-      vma = find_vma(mm, address);
+-      if (!vma)
+-              goto bad_area;
+-      if (likely(vma->vm_start <= address))
+-              goto good_area;
+-      if (!(vma->vm_flags & VM_GROWSDOWN))
+-              goto bad_area;
+-      if (error_code & 4) {
+-              /* Allow userspace just enough access below the stack pointer
+-               * to let the 'enter' instruction work.
+-               */
+-              if (address + 65536 + 32 * sizeof(unsigned long) < regs->rsp)
+-                      goto bad_area;
+-      }
+-      if (expand_stack(vma, address))
+-              goto bad_area;
+-/*
+- * Ok, we have a good vm_area for this memory access, so
+- * we can handle it..
+- */
+-good_area:
+-      info.si_code = SEGV_ACCERR;
+-      write = 0;
+-      switch (error_code & (PF_PROT|PF_WRITE)) {
+-              default:        /* 3: write, present */
+-                      /* fall through */
+-              case PF_WRITE:          /* write, not present */
+-                      if (!(vma->vm_flags & VM_WRITE))
+-                              goto bad_area;
+-                      write++;
+-                      break;
+-              case PF_PROT:           /* read, present */
+-                      goto bad_area;
+-              case 0:                 /* read, not present */
+-                      if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
+-                              goto bad_area;
+-      }
+-
+-      /*
+-       * If for any reason at all we couldn't handle the fault,
+-       * make sure we exit gracefully rather than endlessly redo
+-       * the fault.
+-       */
+-      fault = handle_mm_fault(mm, vma, address, write);
+-      if (unlikely(fault & VM_FAULT_ERROR)) {
+-              if (fault & VM_FAULT_OOM)
+-                      goto out_of_memory;
+-              else if (fault & VM_FAULT_SIGBUS)
+-                      goto do_sigbus;
+-              BUG();
+-      }
+-      if (fault & VM_FAULT_MAJOR)
+-              tsk->maj_flt++;
+-      else
+-              tsk->min_flt++;
+-      up_read(&mm->mmap_sem);
+-      return;
+-
+-/*
+- * Something tried to access memory that isn't in our memory map..
+- * Fix it, but check if it's kernel or user first..
+- */
+-bad_area:
+-      up_read(&mm->mmap_sem);
+-
+-bad_area_nosemaphore:
+-      /* User mode accesses just cause a SIGSEGV */
+-      if (error_code & PF_USER) {
+-
+-              /*
+-               * It's possible to have interrupts off here.
+-               */
+-              local_irq_enable();
+-
+-              if (is_prefetch(regs, address, error_code))
+-                      return;
+-
+-              /* Work around K8 erratum #100 K8 in compat mode
+-                 occasionally jumps to illegal addresses >4GB.  We
+-                 catch this here in the page fault handler because
+-                 these addresses are not reachable. Just detect this
+-                 case and return.  Any code segment in LDT is
+-                 compatibility mode. */
+-              if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
+-                  (address >> 32))
+-                      return;
+-
+-              if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+-                  printk_ratelimit()) {
+-                      printk(
+-                     "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
+-                                      tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
+-                                      tsk->comm, tsk->pid, address, regs->rip,
+-                                      regs->rsp, error_code);
+-              }
+-       
+-              tsk->thread.cr2 = address;
+-              /* Kernel addresses are always protection faults */
+-              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
+-              tsk->thread.trap_no = 14;
+-              info.si_signo = SIGSEGV;
+-              info.si_errno = 0;
+-              /* info.si_code has been set above */
+-              info.si_addr = (void __user *)address;
+-              force_sig_info(SIGSEGV, &info, tsk);
+-              return;
+-      }
 -
--      __free_page(pte);
--}
+-no_context:
+-      
+-      /* Are we prepared to handle this kernel fault?  */
+-      fixup = search_exception_tables(regs->rip);
+-      if (fixup) {
+-              regs->rip = fixup->fixup;
+-              return;
+-      }
 -
--void pmd_ctor(struct kmem_cache *cache, void *pmd)
--{
--      memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
--}
+-      /* 
+-       * Hall of shame of CPU/BIOS bugs.
+-       */
 -
- /*
-  * List of all pgd's needed for non-PAE so it can invalidate entries
-  * in both cached and uncached pgd's; not needed for PAE since the
-@@ -224,224 +175,191 @@ void pmd_ctor(struct kmem_cache *cache, 
-  * vmalloc faults work because attached pagetables are never freed.
-  * -- wli
-  */
--DEFINE_SPINLOCK(pgd_lock);
--struct page *pgd_list;
+-      if (is_prefetch(regs, address, error_code))
+-              return;
 -
- static inline void pgd_list_add(pgd_t *pgd)
- {
-       struct page *page = virt_to_page(pgd);
--      page->index = (unsigned long)pgd_list;
--      if (pgd_list)
--              set_page_private(pgd_list, (unsigned long)&page->index);
--      pgd_list = page;
--      set_page_private(page, (unsigned long)&pgd_list);
-+
-+      list_add(&page->lru, &pgd_list);
- }
- static inline void pgd_list_del(pgd_t *pgd)
- {
--      struct page *next, **pprev, *page = virt_to_page(pgd);
--      next = (struct page *)page->index;
--      pprev = (struct page **)page_private(page);
--      *pprev = next;
--      if (next)
--              set_page_private(next, (unsigned long)pprev);
--}
-+      struct page *page = virt_to_page(pgd);
-+      list_del(&page->lru);
-+}
-+#define UNSHARED_PTRS_PER_PGD                         \
-+      (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD)
--#if (PTRS_PER_PMD == 1)
--/* Non-PAE pgd constructor */
--static void pgd_ctor(void *pgd)
-+static void pgd_ctor(void *p)
- {
-+      pgd_t *pgd = p;
-       unsigned long flags;
--      /* !PAE, no pagetable sharing */
-+      pgd_test_and_unpin(pgd);
-+
-+      /* Clear usermode parts of PGD */
-       memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
-       spin_lock_irqsave(&pgd_lock, flags);
--      /* must happen under lock */
--      clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
--                      swapper_pg_dir + USER_PTRS_PER_PGD,
--                      KERNEL_PGD_PTRS);
+-      if (is_errata93(regs, address))
+-              return; 
 -
--      paravirt_alloc_pd_clone(__pa(pgd) >> PAGE_SHIFT,
--                              __pa(swapper_pg_dir) >> PAGE_SHIFT,
--                              USER_PTRS_PER_PGD,
--                              KERNEL_PGD_PTRS);
--      pgd_list_add(pgd);
--      spin_unlock_irqrestore(&pgd_lock, flags);
--}
--#else  /* PTRS_PER_PMD > 1 */
--/* PAE pgd constructor */
--static void pgd_ctor(void *pgd)
--{
--      /* PAE, kernel PMD may be shared */
+-/*
+- * Oops. The kernel tried to access some bad page. We'll have to
+- * terminate things with extreme prejudice.
+- */
 -
--      if (SHARED_KERNEL_PMD) {
--              clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-+      /* If the pgd points to a shared pagetable level (either the
-+         ptes in non-PAE, or shared PMD in PAE), then just copy the
-+         references from swapper_pg_dir. */
-+      if (PAGETABLE_LEVELS == 2 ||
-+          (PAGETABLE_LEVELS == 3 && SHARED_KERNEL_PMD)) {
-+              clone_pgd_range(pgd + USER_PTRS_PER_PGD,
-                               swapper_pg_dir + USER_PTRS_PER_PGD,
-                               KERNEL_PGD_PTRS);
--      } else {
--              memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
-+              paravirt_alloc_pd_clone(__pa(pgd) >> PAGE_SHIFT,
-+                                      __pa(swapper_pg_dir) >> PAGE_SHIFT,
-+                                      USER_PTRS_PER_PGD,
-+                                      KERNEL_PGD_PTRS);
-       }
-+
-+      /* list required to sync kernel mapping updates */
-+      if (PAGETABLE_LEVELS == 2)
-+              pgd_list_add(pgd);
-+
-+      spin_unlock_irqrestore(&pgd_lock, flags);
- }
--#endif        /* PTRS_PER_PMD */
- static void pgd_dtor(void *pgd)
- {
-       unsigned long flags; /* can be called from interrupt context */
--      if (SHARED_KERNEL_PMD)
--              return;
+-      flags = oops_begin();
 -
--      paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT);
--      spin_lock_irqsave(&pgd_lock, flags);
--      pgd_list_del(pgd);
--      spin_unlock_irqrestore(&pgd_lock, flags);
-+      if (!SHARED_KERNEL_PMD) {
-+              spin_lock_irqsave(&pgd_lock, flags);
-+              pgd_list_del(pgd);
-+              spin_unlock_irqrestore(&pgd_lock, flags);
-+      }
-       pgd_test_and_unpin(pgd);
- }
--#define UNSHARED_PTRS_PER_PGD                         \
--      (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD)
+-      if (address < PAGE_SIZE)
+-              printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+-      else
+-              printk(KERN_ALERT "Unable to handle kernel paging request");
+-      printk(" at %016lx RIP: \n" KERN_ALERT,address);
+-      printk_address(regs->rip);
+-      dump_pagetable(address);
+-      tsk->thread.cr2 = address;
+-      tsk->thread.trap_no = 14;
+-      tsk->thread.error_code = error_code;
+-      __die("Oops", regs, error_code);
+-      /* Executive summary in case the body of the oops scrolled away */
+-      printk(KERN_EMERG "CR2: %016lx\n", address);
+-      oops_end(flags);
+-      do_exit(SIGKILL);
 -
--/* If we allocate a pmd for part of the kernel address space, then
--   make sure its initialized with the appropriate kernel mappings.
--   Otherwise use a cached zeroed pmd.  */
--static pmd_t *pmd_cache_alloc(int idx)
-+#ifdef CONFIG_X86_PAE
-+/*
-+ * Mop up any pmd pages which may still be attached to the pgd.
-+ * Normally they will be freed by munmap/exit_mmap, but any pmd we
-+ * preallocate which never got a corresponding vma will need to be
-+ * freed manually.
-+ */
-+static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
- {
--      pmd_t *pmd;
-+      int i;
--      if (idx >= USER_PTRS_PER_PGD) {
--              pmd = (pmd_t *)__get_free_page(GFP_KERNEL);
-+      for(i = 0; i < UNSHARED_PTRS_PER_PGD; i++) {
-+              pgd_t pgd = pgdp[i];
--#ifndef CONFIG_XEN
--              if (pmd)
--                      memcpy(pmd,
--                             (void *)pgd_page_vaddr(swapper_pg_dir[idx]),
--                             sizeof(pmd_t) * PTRS_PER_PMD);
--#endif
--      } else
--              pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-+              if (__pgd_val(pgd) != 0) {
-+                      pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
--      return pmd;
--}
-+                      pgdp[i] = xen_make_pgd(0);
--static void pmd_cache_free(pmd_t *pmd, int idx)
--{
--      if (idx >= USER_PTRS_PER_PGD) {
--              make_lowmem_page_writable(pmd, XENFEAT_writable_page_tables);
--              memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
--              free_page((unsigned long)pmd);
--      } else
--              kmem_cache_free(pmd_cache, pmd);
-+                      paravirt_release_pd(pgd_val(pgd) >> PAGE_SHIFT);
-+                      pmd_free(mm, pmd);
-+              }
-+      }
- }
--pgd_t *pgd_alloc(struct mm_struct *mm)
-+/*
-+ * In PAE mode, we need to do a cr3 reload (=tlb flush) when
-+ * updating the top-level pagetable entries to guarantee the
-+ * processor notices the update.  Since this is expensive, and
-+ * all 4 top-level entries are used almost immediately in a
-+ * new process's life, we just pre-populate them here.
-+ *
-+ * Also, if we're in a paravirt environment where the kernel pmd is
-+ * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
-+ * and initialize the kernel pmds here.
-+ */
-+static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
- {
-+      pud_t *pud;
-+      pmd_t *pmds[UNSHARED_PTRS_PER_PGD];
-+      unsigned long addr, flags;
-       int i;
--      pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor);
--      pmd_t **pmds = NULL;
--      unsigned long flags;
+-/*
+- * We ran out of memory, or some other thing happened to us that made
+- * us unable to handle the page fault gracefully.
+- */
+-out_of_memory:
+-      up_read(&mm->mmap_sem);
+-      if (is_global_init(current)) {
+-              yield();
+-              goto again;
+-      }
+-      printk("VM: killing process %s\n", tsk->comm);
+-      if (error_code & 4)
+-              do_group_exit(SIGKILL);
+-      goto no_context;
 -
--      pgd_test_and_unpin(pgd);
+-do_sigbus:
+-      up_read(&mm->mmap_sem);
 -
--      if (PTRS_PER_PMD == 1 || !pgd)
--              return pgd;
+-      /* Kernel mode? Handle exceptions or die */
+-      if (!(error_code & PF_USER))
+-              goto no_context;
 -
--#ifdef CONFIG_XEN
--      if (!SHARED_KERNEL_PMD) {
--              /*
--               * We can race save/restore (if we sleep during a GFP_KERNEL memory
--               * allocation). We therefore store virtual addresses of pmds as they
--               * do not change across save/restore, and poke the machine addresses
--               * into the pgdir under the pgd_lock.
--               */
--              pmds = kmalloc(PTRS_PER_PGD * sizeof(pmd_t *), GFP_KERNEL);
--              if (!pmds) {
--                      quicklist_free(0, pgd_dtor, pgd);
--                      return NULL;
--              }
--      }
--#endif
--      /* Allocate pmds, remember virtual addresses. */
--      for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) {
--              pmd_t *pmd = pmd_cache_alloc(i);
+-      tsk->thread.cr2 = address;
+-      tsk->thread.error_code = error_code;
+-      tsk->thread.trap_no = 14;
+-      info.si_signo = SIGBUS;
+-      info.si_errno = 0;
+-      info.si_code = BUS_ADRERR;
+-      info.si_addr = (void __user *)address;
+-      force_sig_info(SIGBUS, &info, tsk);
+-      return;
+-}
 -
--              if (!pmd)
-+      /*
-+       * We can race save/restore (if we sleep during a GFP_KERNEL memory
-+       * allocation). We therefore store virtual addresses of pmds as they
-+       * do not change across save/restore, and poke the machine addresses
-+       * into the pgdir under the pgd_lock.
-+       */
-+      for (addr = i = 0; i < UNSHARED_PTRS_PER_PGD; i++, addr += PUD_SIZE) {
-+              pmds[i] = pmd_alloc_one(mm, addr);
-+              if (!pmds[i])
-                       goto out_oom;
+-DEFINE_SPINLOCK(pgd_lock);
+-LIST_HEAD(pgd_list);
 -
--              paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
--              if (pmds)
--                      pmds[i] = pmd;
--              else
--                      set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
-       }
--#ifdef CONFIG_XEN
--      if (SHARED_KERNEL_PMD)
--              return pgd;
+-void vmalloc_sync_all(void)
+-{
+-      /* Note that races in the updates of insync and start aren't 
+-         problematic:
+-         insync can only get set bits added, and updates to start are only
+-         improving performance (without affecting correctness if undone). */
+-      static DECLARE_BITMAP(insync, PTRS_PER_PGD);
+-      static unsigned long start = VMALLOC_START & PGDIR_MASK;
+-      unsigned long address;
 -
-       spin_lock_irqsave(&pgd_lock, flags);
-       /* Protect against save/restore: move below 4GB under pgd_lock. */
--      if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) {
--              int rc = xen_create_contiguous_region(
--                      (unsigned long)pgd, 0, 32);
--              if (rc) {
--                      spin_unlock_irqrestore(&pgd_lock, flags);
--                      goto out_oom;
+-      for (address = start; address <= VMALLOC_END; address += PGDIR_SIZE) {
+-              if (!test_bit(pgd_index(address), insync)) {
+-                      const pgd_t *pgd_ref = pgd_offset_k(address);
+-                      struct page *page;
+-
+-                      if (pgd_none(*pgd_ref))
+-                              continue;
+-                      spin_lock(&pgd_lock);
+-                      list_for_each_entry(page, &pgd_list, lru) {
+-                              pgd_t *pgd;
+-                              pgd = (pgd_t *)page_address(page) + pgd_index(address);
+-                              if (pgd_none(*pgd))
+-                                      set_pgd(pgd, *pgd_ref);
+-                              else
+-                                      BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+-                      }
+-                      spin_unlock(&pgd_lock);
+-                      set_bit(pgd_index(address), insync);
 -              }
-+      if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)
-+          && xen_create_contiguous_region((unsigned long)pgd, 0, 32)) {
-+              spin_unlock_irqrestore(&pgd_lock, flags);
-+out_oom:
-+              while (i--)
-+                      pmd_free(mm, pmds[i]);
-+              return 0;
-       }
-       /* Copy kernel pmd contents and write-protect the new pmds. */
--      for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
--              memcpy(pmds[i],
--                     (void *)pgd_page_vaddr(swapper_pg_dir[i]),
--                     sizeof(pmd_t) * PTRS_PER_PMD);
--              make_lowmem_page_readonly(
--                      pmds[i], XENFEAT_writable_page_tables);
+-              if (address == start)
+-                      start = address + PGDIR_SIZE;
 -      }
-+      pud = pud_offset(pgd, 0);
-+      for (addr = i = 0; i < UNSHARED_PTRS_PER_PGD;
-+           i++, pud++, addr += PUD_SIZE) {
-+              if (i >= USER_PTRS_PER_PGD) {
-+                      memcpy(pmds[i],
-+                             (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
-+                             sizeof(pmd_t) * PTRS_PER_PMD);
-+                      make_lowmem_page_readonly(
-+                              pmds[i], XENFEAT_writable_page_tables);
-+              }
--      /* It is safe to poke machine addresses of pmds under the pmd_lock. */
--      for (i = 0; i < PTRS_PER_PGD; i++)
--              set_pgd(&pgd[i], __pgd(1 + __pa(pmds[i])));
-+              /* It is safe to poke machine addresses of pmds under the pgd_lock. */
-+              pud_populate(mm, pud, pmds[i]);
-+      }
--      /* Ensure this pgd gets picked up and pinned on save/restore. */
-+      /* List required to sync kernel mapping updates and
-+       * to pin/unpin on save/restore. */
-       pgd_list_add(pgd);
-       spin_unlock_irqrestore(&pgd_lock, flags);
--      kfree(pmds);
--#endif
-+      return 1;
-+}
-+#else  /* !CONFIG_X86_PAE */
-+/* No need to prepopulate any pagetable entries in non-PAE modes. */
-+static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
-+{
-+      return 1;
-+}
--      return pgd;
-+static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
-+{
-+}
-+#endif        /* CONFIG_X86_PAE */
+-      /* Check that there is no need to do the same for the modules area. */
+-      BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
+-      BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == 
+-                              (__START_KERNEL & PGDIR_MASK)));
+-}
+--- sle11-2009-05-14.orig/arch/x86/mm/highmem_32-xen.c 2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/arch/x86/mm/highmem_32-xen.c      2009-03-16 16:33:40.000000000 +0100
+@@ -18,6 +18,49 @@ void kunmap(struct page *page)
+       kunmap_high(page);
+ }
  
--out_oom:
--      if (!pmds) {
--              for (i--; i >= 0; i--) {
--                      pgd_t pgdent = pgd[i];
--                      void* pmd = (void *)__va(pgd_val(pgdent)-1);
--                      paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
--                      pmd_cache_free(pmd, i);
--              }
--      } else {
--              for (i--; i >= 0; i--) {
--                      paravirt_release_pd(__pa(pmds[i]) >> PAGE_SHIFT);
--                      pmd_cache_free(pmds[i], i);
--              }
--              kfree(pmds);
-+pgd_t *pgd_alloc(struct mm_struct *mm)
++static void debug_kmap_atomic_prot(enum km_type type)
 +{
-+      pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
++#ifdef CONFIG_DEBUG_HIGHMEM
++      static unsigned warn_count = 10;
 +
-+      /* so that alloc_pd can use it */
-+      mm->pgd = pgd;
-+      if (pgd)
-+              pgd_ctor(pgd);
++      if (unlikely(warn_count == 0))
++              return;
 +
-+      if (pgd && !pgd_prepopulate_pmd(mm, pgd)) {
-+              free_page((unsigned long)pgd);
-+              pgd = NULL;
-       }
--      quicklist_free(0, pgd_dtor, pgd);
--      return NULL;
++      if (unlikely(in_interrupt())) {
++              if (in_irq()) {
++                      if (type != KM_IRQ0 && type != KM_IRQ1 &&
++                          type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
++                          type != KM_BOUNCE_READ) {
++                              WARN_ON(1);
++                              warn_count--;
++                      }
++              } else if (!irqs_disabled()) {  /* softirq */
++                      if (type != KM_IRQ0 && type != KM_IRQ1 &&
++                          type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
++                          type != KM_SKB_SUNRPC_DATA &&
++                          type != KM_SKB_DATA_SOFTIRQ &&
++                          type != KM_BOUNCE_READ) {
++                              WARN_ON(1);
++                              warn_count--;
++                      }
++              }
++      }
 +
-+      return pgd;
- }
--void pgd_free(pgd_t *pgd)
-+void pgd_free(struct mm_struct *mm, pgd_t *pgd)
- {
--      int i;
--
-       /*
-        * After this the pgd should not be pinned for the duration of this
-        * function's execution. We should never sleep and thus never race:
-@@ -450,39 +368,43 @@ void pgd_free(pgd_t *pgd)
-        *  2. The machine addresses in PGD entries will not become invalid
-        *     due to a concurrent save/restore.
-        */
--      pgd_test_and_unpin(pgd);
-+      pgd_dtor(pgd);
--      /* in the PAE case user pgd entries are overwritten before usage */
--      if (PTRS_PER_PMD > 1) {
--              for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) {
--                      pgd_t pgdent = pgd[i];
--                      void* pmd = (void *)__va(pgd_val(pgdent)-1);
--                      paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
--                      pmd_cache_free(pmd, i);
--              }
-+      if (PTRS_PER_PMD > 1 && !xen_feature(XENFEAT_pae_pgdir_above_4gb))
-+              xen_destroy_contiguous_region((unsigned long)pgd, 0);
--              if (!xen_feature(XENFEAT_pae_pgdir_above_4gb))
--                      xen_destroy_contiguous_region((unsigned long)pgd, 0);
--      }
-+      pgd_mop_up_pmds(mm, pgd);
-+      free_page((unsigned long)pgd);
++      if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
++                      type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
++              if (!irqs_disabled()) {
++                      WARN_ON(1);
++                      warn_count--;
++              }
++      } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
++              if (irq_count() == 0 && !irqs_disabled()) {
++                      WARN_ON(1);
++                      warn_count--;
++              }
++      }
++#endif
 +}
++
+ /*
+  * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
+  * no global lock is needed and because the kmap code must perform a global TLB
+@@ -37,6 +80,8 @@ void *kmap_atomic_prot(struct page *page
+       if (!PageHighMem(page))
+               return page_address(page);
  
--      /* in the non-PAE case, free_pgtables() clears user pgd entries */
--      quicklist_free(0, pgd_dtor, pgd);
-+void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
-+{
-+      pgtable_page_dtor(pte);
-+      paravirt_release_pt(page_to_pfn(pte));
-+      tlb_remove_page(tlb, pte);
++      debug_kmap_atomic_prot(type);
++
+       idx = type + KM_TYPE_NR*smp_processor_id();
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       BUG_ON(!pte_none(*(kmap_pte-idx)));
+--- sle11-2009-05-14.orig/arch/x86/mm/hypervisor.c     2009-05-06 10:23:43.000000000 +0200
++++ sle11-2009-05-14/arch/x86/mm/hypervisor.c  2009-05-14 11:18:39.000000000 +0200
+@@ -869,15 +869,11 @@ int xen_limit_pages_to_max_mfn(
  }
+ EXPORT_SYMBOL_GPL(xen_limit_pages_to_max_mfn);
  
--void check_pgt_cache(void)
-+#ifdef CONFIG_X86_PAE
-+
-+void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+-#ifdef __i386__
+-int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
++int write_ldt_entry(struct desc_struct *ldt, int entry, const void *desc)
  {
--      quicklist_trim(0, pgd_dtor, 25, 16);
-+      paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
-+      tlb_remove_page(tlb, virt_to_page(pmd));
+-      __u32 *lp = (__u32 *)((char *)ldt + entry * 8);
+-      maddr_t mach_lp = arbitrary_virt_to_machine(lp);
+-      return HYPERVISOR_update_descriptor(
+-              mach_lp, (u64)entry_a | ((u64)entry_b<<32));
++      maddr_t mach_lp = arbitrary_virt_to_machine(ldt + entry);
++      return HYPERVISOR_update_descriptor(mach_lp, *(const u64*)desc);
  }
+-#endif
  
-+#endif
-+
- void make_lowmem_page_readonly(void *va, unsigned int feature)
- {
-       pte_t *pte;
-+      unsigned int level;
-       int rc;
+ #define MAX_BATCHED_FULL_PTES 32
  
-       if (xen_feature(feature))
-               return;
+--- sle11-2009-05-14.orig/arch/x86/mm/init_32-xen.c    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/mm/init_32-xen.c 2009-03-16 16:33:40.000000000 +0100
+@@ -27,13 +27,13 @@
+ #include <linux/bootmem.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
+-#include <linux/efi.h>
+ #include <linux/memory_hotplug.h>
+ #include <linux/initrd.h>
+ #include <linux/cpumask.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/scatterlist.h>
  
--      pte = virt_to_ptep(va);
-+      pte = lookup_address((unsigned long)va, &level);
-+      BUG_ON(!pte || level != PG_LEVEL_4K || !pte_present(*pte));
-       rc = HYPERVISOR_update_va_mapping(
-               (unsigned long)va, pte_wrprotect(*pte), 0);
-       BUG_ON(rc);
-@@ -491,313 +413,15 @@ void make_lowmem_page_readonly(void *va,
- void make_lowmem_page_writable(void *va, unsigned int feature)
++#include <asm/asm.h>
+ #include <asm/processor.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -42,18 +42,22 @@
+ #include <asm/fixmap.h>
+ #include <asm/e820.h>
+ #include <asm/apic.h>
++#include <asm/bugs.h>
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
++#include <asm/pgalloc.h>
+ #include <asm/sections.h>
+ #include <asm/hypervisor.h>
+ #include <asm/swiotlb.h>
++#include <asm/setup.h>
++#include <asm/cacheflush.h>
+ unsigned int __VMALLOC_RESERVE = 128 << 20;
+ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+ unsigned long highstart_pfn, highend_pfn;
+-static int noinline do_test_wp_bit(void);
++static noinline int do_test_wp_bit(void);
+ /*
+  * Creates a middle page table and puts a pointer to it in the
+@@ -64,17 +68,16 @@ static pmd_t * __init one_md_table_init(
  {
-       pte_t *pte;
-+      unsigned int level;
-       int rc;
+       pud_t *pud;
+       pmd_t *pmd_table;
+-              
++
+ #ifdef CONFIG_X86_PAE
+       if (!(__pgd_val(*pgd) & _PAGE_PRESENT)) {
+               pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  
-       if (xen_feature(feature))
-               return;
+-              paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
++              paravirt_alloc_pd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
+               make_lowmem_page_readonly(pmd_table, XENFEAT_writable_page_tables);
+               set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
+               pud = pud_offset(pgd, 0);
+-              if (pmd_table != pmd_offset(pud, 0))
+-                      BUG();
++              BUG_ON(pmd_table != pmd_offset(pud, 0));
+       }
+ #endif
+       pud = pud_offset(pgd, 0);
+@@ -85,7 +88,7 @@ static pmd_t * __init one_md_table_init(
  
--      pte = virt_to_ptep(va);
-+      pte = lookup_address((unsigned long)va, &level);
-+      BUG_ON(!pte || level != PG_LEVEL_4K || !pte_present(*pte));
-       rc = HYPERVISOR_update_va_mapping(
-               (unsigned long)va, pte_mkwrite(*pte), 0);
-       BUG_ON(rc);
- }
--
--void make_page_readonly(void *va, unsigned int feature)
--{
--      pte_t *pte;
--      int rc;
--
--      if (xen_feature(feature))
--              return;
--
--      pte = virt_to_ptep(va);
--      rc = HYPERVISOR_update_va_mapping(
--              (unsigned long)va, pte_wrprotect(*pte), 0);
--      if (rc) /* fallback? */
--              xen_l1_entry_update(pte, pte_wrprotect(*pte));
--      if ((unsigned long)va >= (unsigned long)high_memory) {
--              unsigned long pfn = pte_pfn(*pte);
--#ifdef CONFIG_HIGHMEM
--              if (pfn >= highstart_pfn)
--                      kmap_flush_unused(); /* flush stale writable kmaps */
--              else
--#endif
--                      make_lowmem_page_readonly(
--                              phys_to_virt(pfn << PAGE_SHIFT), feature); 
--      }
--}
--
--void make_page_writable(void *va, unsigned int feature)
--{
--      pte_t *pte;
--      int rc;
--
--      if (xen_feature(feature))
--              return;
--
--      pte = virt_to_ptep(va);
--      rc = HYPERVISOR_update_va_mapping(
--              (unsigned long)va, pte_mkwrite(*pte), 0);
--      if (rc) /* fallback? */
--              xen_l1_entry_update(pte, pte_mkwrite(*pte));
--      if ((unsigned long)va >= (unsigned long)high_memory) {
--              unsigned long pfn = pte_pfn(*pte); 
--#ifdef CONFIG_HIGHMEM
--              if (pfn < highstart_pfn)
--#endif
--                      make_lowmem_page_writable(
--                              phys_to_virt(pfn << PAGE_SHIFT), feature);
--      }
--}
--
--void make_pages_readonly(void *va, unsigned int nr, unsigned int feature)
--{
--      if (xen_feature(feature))
--              return;
--
--      while (nr-- != 0) {
--              make_page_readonly(va, feature);
--              va = (void *)((unsigned long)va + PAGE_SIZE);
--      }
--}
--
--void make_pages_writable(void *va, unsigned int nr, unsigned int feature)
--{
--      if (xen_feature(feature))
--              return;
--
--      while (nr-- != 0) {
--              make_page_writable(va, feature);
--              va = (void *)((unsigned long)va + PAGE_SIZE);
--      }
--}
--
--static void _pin_lock(struct mm_struct *mm, int lock) {
--      if (lock)
--              spin_lock(&mm->page_table_lock);
--#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
--      /* While mm->page_table_lock protects us against insertions and
--       * removals of higher level page table pages, it doesn't protect
--       * against updates of pte-s. Such updates, however, require the
--       * pte pages to be in consistent state (unpinned+writable or
--       * pinned+readonly). The pinning and attribute changes, however
--       * cannot be done atomically, which is why such updates must be
--       * prevented from happening concurrently.
--       * Note that no pte lock can ever elsewhere be acquired nesting
--       * with an already acquired one in the same mm, or with the mm's
--       * page_table_lock already acquired, as that would break in the
--       * non-split case (where all these are actually resolving to the
--       * one page_table_lock). Thus acquiring all of them here is not
--       * going to result in dead locks, and the order of acquires
--       * doesn't matter.
--       */
--      {
--              pgd_t *pgd = mm->pgd;
--              unsigned g;
--
--              for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
--                      pud_t *pud;
--                      unsigned u;
--
--                      if (pgd_none(*pgd))
--                              continue;
--                      pud = pud_offset(pgd, 0);
--                      for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
--                              pmd_t *pmd;
--                              unsigned m;
--
--                              if (pud_none(*pud))
--                                      continue;
--                              pmd = pmd_offset(pud, 0);
--                              for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
--                                      spinlock_t *ptl;
+ /*
+  * Create a page table and place a pointer to it in a middle page
+- * directory entry.
++ * directory entry:
+  */
+ static pte_t * __init one_page_table_init(pmd_t *pmd)
+ {
+@@ -99,9 +102,10 @@ static pte_t * __init one_page_table_ini
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+               page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
+ #endif
+-              if (!page_table)
++              if (!page_table) {
+                       page_table =
+                               (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
++              }
+               paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
+               make_lowmem_page_readonly(page_table,
+@@ -114,22 +118,21 @@ static pte_t * __init one_page_table_ini
+ }
+ /*
+- * This function initializes a certain range of kernel virtual memory 
++ * This function initializes a certain range of kernel virtual memory
+  * with new bootmem page tables, everywhere page tables are missing in
+  * the given range.
+- */
 -
--                                      if (pmd_none(*pmd))
+-/*
+- * NOTE: The pagetables are allocated contiguous on the physical space 
+- * so we can cache the place of the first one and move around without 
++ *
++ * NOTE: The pagetables are allocated contiguous on the physical space
++ * so we can cache the place of the first one and move around without
+  * checking the pgd every time.
+  */
+-static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
++static void __init
++page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base)
+ {
+-      pgd_t *pgd;
+-      pmd_t *pmd;
+       int pgd_idx, pmd_idx;
+       unsigned long vaddr;
++      pgd_t *pgd;
++      pmd_t *pmd;
+       vaddr = start;
+       pgd_idx = pgd_index(vaddr);
+@@ -139,7 +142,8 @@ static void __init page_table_range_init
+       for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+               pmd = one_md_table_init(pgd);
+               pmd = pmd + pmd_index(vaddr);
+-              for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
++              for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
++                                                      pmd++, pmd_idx++) {
+                       if (vaddr < hypervisor_virt_start)
+                               one_page_table_init(pmd);
+@@ -157,17 +161,17 @@ static inline int is_kernel_text(unsigne
+ }
+ /*
+- * This maps the physical memory to kernel virtual address space, a total 
+- * of max_low_pfn pages, by creating page tables starting from address 
+- * PAGE_OFFSET.
++ * This maps the physical memory to kernel virtual address space, a total
++ * of max_low_pfn pages, by creating page tables starting from address
++ * PAGE_OFFSET:
+  */
+ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+ {
++      int pgd_idx, pmd_idx, pte_ofs;
+       unsigned long pfn;
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
+-      int pgd_idx, pmd_idx, pte_ofs;
+       unsigned long max_ram_pfn = xen_start_info->nr_pages;
+       if (max_ram_pfn > max_low_pfn)
+@@ -195,36 +199,49 @@ static void __init kernel_physical_mappi
+               if (pfn >= max_low_pfn)
+                       continue;
+               pmd += pmd_idx;
+-              for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
+-                      unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
+-                      if (address >= hypervisor_virt_start)
++              for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
++                   pmd++, pmd_idx++) {
++                      unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
++
++                      if (addr >= hypervisor_virt_start)
+                               continue;
+-                      /* Map with big pages if possible, otherwise create normal page tables. */
++                      /*
++                       * Map with big pages if possible, otherwise
++                       * create normal page tables:
++                       */
+                       if (cpu_has_pse) {
+-                              unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
+-                              if (is_kernel_text(address) || is_kernel_text(address2))
+-                                      set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
+-                              else
+-                                      set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
++                              unsigned int addr2;
++                              pgprot_t prot = PAGE_KERNEL_LARGE;
++
++                              addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
++                                      PAGE_OFFSET + PAGE_SIZE-1;
++
++                              if (is_kernel_text(addr) ||
++                                  is_kernel_text(addr2))
++                                      prot = PAGE_KERNEL_LARGE_EXEC;
++
++                              set_pmd(pmd, pfn_pmd(pfn, prot));
+                               pfn += PTRS_PER_PTE;
+-                      } else {
+-                              pte = one_page_table_init(pmd);
++                              continue;
++                      }
++                      pte = one_page_table_init(pmd);
++
++                      for (pte += pte_ofs;
++                           pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
++                           pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
++                              pgprot_t prot = PAGE_KERNEL;
++
++                              /* XEN: Only map initial RAM allocation. */
++                              if ((pfn >= max_ram_pfn) || pte_present(*pte))
++                                      continue;
++                              if (is_kernel_text(addr))
++                                      prot = PAGE_KERNEL_EXEC;
+-                              for (pte += pte_ofs;
+-                                   pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
+-                                   pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
+-                                      /* XEN: Only map initial RAM allocation. */
+-                                      if ((pfn >= max_ram_pfn) || pte_present(*pte))
 -                                              continue;
--                                      ptl = pte_lockptr(0, pmd);
--                                      if (lock)
--                                              spin_lock(ptl);
+-                                      if (is_kernel_text(address))
+-                                              set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
 -                                      else
--                                              spin_unlock(ptl);
+-                                              set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
 -                              }
--                      }
--              }
--      }
--#endif
--      if (!lock)
--              spin_unlock(&mm->page_table_lock);
--}
--#define pin_lock(mm) _pin_lock(mm, 1)
--#define pin_unlock(mm) _pin_lock(mm, 0)
--
--#define PIN_BATCH 4
--static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl);
--
--static inline unsigned int pgd_walk_set_prot(struct page *page, pgprot_t flags,
--                                             unsigned int cpu, unsigned seq)
--{
--      unsigned long pfn = page_to_pfn(page);
--
--      if (PageHighMem(page)) {
--              if (pgprot_val(flags) & _PAGE_RW)
--                      ClearPagePinned(page);
--              else
--                      SetPagePinned(page);
--      } else {
--              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
--                              (unsigned long)__va(pfn << PAGE_SHIFT),
--                              pfn_pte(pfn, flags), 0);
--              if (unlikely(++seq == PIN_BATCH)) {
--                      if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
--                                                              PIN_BATCH, NULL)))
--                              BUG();
--                      seq = 0;
--              }
--      }
--
--      return seq;
--}
--
--static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
--{
--      pgd_t *pgd = pgd_base;
--      pud_t *pud;
--      pmd_t *pmd;
--      int    g, u, m;
--      unsigned int cpu, seq;
--
--      if (xen_feature(XENFEAT_auto_translated_physmap))
--              return;
--
--      cpu = get_cpu();
--
--      for (g = 0, seq = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
--              if (pgd_none(*pgd))
--                      continue;
--              pud = pud_offset(pgd, 0);
--              if (PTRS_PER_PUD > 1) /* not folded */
--                      seq = pgd_walk_set_prot(virt_to_page(pud),flags,cpu,seq);
--              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
--                      if (pud_none(*pud))
--                              continue;
--                      pmd = pmd_offset(pud, 0);
--                      if (PTRS_PER_PMD > 1) /* not folded */
--                              seq = pgd_walk_set_prot(virt_to_page(pmd),flags,cpu,seq);
--                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
--                              if (pmd_none(*pmd))
--                                      continue;
--                              seq = pgd_walk_set_prot(pmd_page(*pmd),flags,cpu,seq);
--                      }
--              }
--      }
--
--      if (likely(seq != 0)) {
--              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
--                      (unsigned long)pgd_base,
--                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
--                      UVMF_TLB_FLUSH);
--              if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
--                                                      seq + 1, NULL)))
--                      BUG();
--      } else if(HYPERVISOR_update_va_mapping((unsigned long)pgd_base,
--                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
--                      UVMF_TLB_FLUSH))
--              BUG();
--
--      put_cpu();
--}
--
--static void __pgd_pin(pgd_t *pgd)
--{
--      pgd_walk(pgd, PAGE_KERNEL_RO);
--      kmap_flush_unused();
--      xen_pgd_pin(__pa(pgd));
--      SetPagePinned(virt_to_page(pgd));
--}
--
--static void __pgd_unpin(pgd_t *pgd)
--{
--      xen_pgd_unpin(__pa(pgd));
--      pgd_walk(pgd, PAGE_KERNEL);
--      ClearPagePinned(virt_to_page(pgd));
--}
--
--static void pgd_test_and_unpin(pgd_t *pgd)
--{
--      if (PagePinned(virt_to_page(pgd)))
--              __pgd_unpin(pgd);
--}
--
--void mm_pin(struct mm_struct *mm)
--{
--      if (xen_feature(XENFEAT_writable_page_tables))
--              return;
--      pin_lock(mm);
--      __pgd_pin(mm->pgd);
--      pin_unlock(mm);
--}
--
--void mm_unpin(struct mm_struct *mm)
+-                              pte_ofs = 0;
++                              set_pte(pte, pfn_pte(pfn, prot));
+                       }
++                      pte_ofs = 0;
+               }
+               pmd_idx = 0;
+       }
+@@ -245,57 +262,23 @@ static inline int page_kills_ppro(unsign
+ #endif
+-int page_is_ram(unsigned long pagenr)
 -{
--      if (xen_feature(XENFEAT_writable_page_tables))
--              return;
--      pin_lock(mm);
--      __pgd_unpin(mm->pgd);
--      pin_unlock(mm);
--}
+-      int i;
+-      unsigned long addr, end;
 -
--void mm_pin_all(void)
--{
--      struct page *page;
--      unsigned long flags;
+-      if (efi_enabled) {
+-              efi_memory_desc_t *md;
+-              void *p;
 -
--      if (xen_feature(XENFEAT_writable_page_tables))
--              return;
+-              for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+-                      md = p;
+-                      if (!is_available_memory(md))
+-                              continue;
+-                      addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
+-                      end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
 -
--      /*
--       * Allow uninterrupted access to the pgd_list. Also protects
--       * __pgd_pin() by disabling preemption.
--       * All other CPUs must be at a safe point (e.g., in stop_machine
--       * or offlined entirely).
--       */
--      spin_lock_irqsave(&pgd_lock, flags);
--      for (page = pgd_list; page; page = (struct page *)page->index) {
--              if (!PagePinned(page))
--                      __pgd_pin((pgd_t *)page_address(page));
+-                      if ((pagenr >= addr) && (pagenr < end))
+-                              return 1;
+-              }
+-              return 0;
 -      }
--      spin_unlock_irqrestore(&pgd_lock, flags);
--}
--
--void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
--{
--      if (!PagePinned(virt_to_page(mm->pgd)))
--              mm_pin(mm);
--}
--
--void arch_exit_mmap(struct mm_struct *mm)
--{
--      struct task_struct *tsk = current;
--
--      task_lock(tsk);
--
--      /*
--       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
--       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
--       */
--      if (tsk->active_mm == mm) {
--              tsk->active_mm = &init_mm;
--              atomic_inc(&init_mm.mm_count);
 -
--              switch_mm(mm, &init_mm, tsk);
+-      for (i = 0; i < e820.nr_map; i++) {
 -
--              atomic_dec(&mm->mm_count);
--              BUG_ON(atomic_read(&mm->mm_count) == 0);
+-              if (e820.map[i].type != E820_RAM)       /* not usable memory */
+-                      continue;
+-              /*
+-               *      !!!FIXME!!! Some BIOSen report areas as RAM that
+-               *      are not. Notably the 640->1Mb area. We need a sanity
+-               *      check here.
+-               */
+-              addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
+-              end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
+-              if  ((pagenr >= addr) && (pagenr < end))
+-                      return 1;
 -      }
--
--      task_unlock(tsk);
--
--      if (PagePinned(virt_to_page(mm->pgd)) &&
--          (atomic_read(&mm->mm_count) == 1) &&
--          !mm->context.has_foreign_mappings)
--              mm_unpin(mm);
+-      return 0;
 -}
---- a/arch/x86/pci/irq-xen.c
-+++ b/arch/x86/pci/irq-xen.c
-@@ -204,6 +204,7 @@ static int pirq_ali_get(struct pci_dev *
- {
-       static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
+-
+ #ifdef CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+ pgprot_t kmap_prot;
  
-+      WARN_ON_ONCE(pirq >= 16);
-       return irqmap[read_config_nybble(router, 0x48, pirq-1)];
- }
+-#define kmap_get_fixmap_pte(vaddr)                                    \
+-      pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr))
++static inline pte_t *kmap_get_fixmap_pte(unsigned long vaddr)
++{
++      return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
++                      vaddr), vaddr), vaddr);
++}
  
-@@ -211,7 +212,8 @@ static int pirq_ali_set(struct pci_dev *
+ static void __init kmap_init(void)
  {
-       static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
-       unsigned int val = irqmap[irq];
--              
-+
-+      WARN_ON_ONCE(pirq >= 16);
-       if (val) {
-               write_config_nybble(router, 0x48, pirq-1, val);
-               return 1;
-@@ -261,12 +263,16 @@ static int pirq_via_set(struct pci_dev *
- static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+       unsigned long kmap_vstart;
+-      /* cache the first kmap pte */
++      /*
++       * Cache the first kmap pte:
++       */
+       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+@@ -304,11 +287,11 @@ static void __init kmap_init(void)
+ static void __init permanent_kmaps_init(pgd_t *pgd_base)
  {
-       static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
-+
-+      WARN_ON_ONCE(pirq >= 5);
-       return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
++      unsigned long vaddr;
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte;
+-      unsigned long vaddr;
+       vaddr = PKMAP_BASE;
+       page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+@@ -317,7 +300,7 @@ static void __init permanent_kmaps_init(
+       pud = pud_offset(pgd, vaddr);
+       pmd = pmd_offset(pud, vaddr);
+       pte = pte_offset_kernel(pmd, vaddr);
+-      pkmap_page_table = pte; 
++      pkmap_page_table = pte;
  }
  
- static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+ static void __meminit free_new_highpage(struct page *page, int pfn)
+@@ -337,7 +320,8 @@ void __init add_one_highpage_init(struct
+               SetPageReserved(page);
+ }
+-static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long pfn)
++static int __meminit
++add_one_highpage_hotplug(struct page *page, unsigned long pfn)
  {
-       static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
+       free_new_highpage(page, pfn);
+       totalram_pages++;
+@@ -345,6 +329,7 @@ static int __meminit add_one_highpage_ho
+       max_mapnr = max(pfn, max_mapnr);
+ #endif
+       num_physpages++;
 +
-+      WARN_ON_ONCE(pirq >= 5);
-       write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
-       return 1;
+       return 0;
  }
-@@ -279,12 +285,16 @@ static int pirq_via586_set(struct pci_de
- static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+@@ -352,7 +337,7 @@ static int __meminit add_one_highpage_ho
+  * Not currently handling the NUMA case.
+  * Assuming single node and all memory that
+  * has been added dynamically that would be
+- * onlined here is in HIGHMEM
++ * onlined here is in HIGHMEM.
+  */
+ void __meminit online_page(struct page *page)
  {
-       static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
-+
-+      WARN_ON_ONCE(pirq >= 4);
-       return read_config_nybble(router,0x43, pirqmap[pirq-1]);
+@@ -360,13 +345,11 @@ void __meminit online_page(struct page *
+       add_one_highpage_hotplug(page, page_to_pfn(page));
  }
  
- static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+-
+-#ifdef CONFIG_NUMA
+-extern void set_highmem_pages_init(int);
+-#else
++#ifndef CONFIG_NUMA
+ static void __init set_highmem_pages_init(int bad_ppro)
  {
-       static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
+       int pfn;
 +
-+      WARN_ON_ONCE(pirq >= 4);
-       write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
-       return 1;
+       for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) {
+               /*
+                * Holes under sparsemem might not have no mem_map[]:
+@@ -376,23 +359,18 @@ static void __init set_highmem_pages_ini
+       }
+       totalram_pages += totalhigh_pages;
  }
-@@ -423,6 +433,7 @@ static int pirq_sis_set(struct pci_dev *
+-#endif /* CONFIG_FLATMEM */
++#endif /* !CONFIG_NUMA */
  
- static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
- {
-+      WARN_ON_ONCE(pirq >= 9);
-       if (pirq > 8) {
-               printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
-               return 0;
-@@ -432,6 +443,7 @@ static int pirq_vlsi_get(struct pci_dev 
+ #else
+-#define kmap_init() do { } while (0)
+-#define permanent_kmaps_init(pgd_base) do { } while (0)
+-#define set_highmem_pages_init(bad_ppro) do { } while (0)
++# define kmap_init()                          do { } while (0)
++# define permanent_kmaps_init(pgd_base)               do { } while (0)
++# define set_highmem_pages_init(bad_ppro)     do { } while (0)
+ #endif /* CONFIG_HIGHMEM */
  
- static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
- {
-+      WARN_ON_ONCE(pirq >= 9);
-       if (pirq > 8) {
-               printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
-               return 0;
-@@ -453,14 +465,14 @@ static int pirq_vlsi_set(struct pci_dev 
+-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
++pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
+ EXPORT_SYMBOL(__PAGE_KERNEL);
+-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
+-#ifdef CONFIG_NUMA
+-extern void __init remap_numa_kva(void);
+-#else
+-#define remap_numa_kva() do {} while (0)
+-#endif
++pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
+ pgd_t *swapper_pg_dir;
+@@ -410,9 +388,8 @@ static void __init xen_pagetable_setup_d
+  * the boot process.
+  *
+  * If we're booting on native hardware, this will be a pagetable
+- * constructed in arch/i386/kernel/head.S, and not running in PAE mode
+- * (even if we'll end up running in PAE).  The root of the pagetable
+- * will be swapper_pg_dir.
++ * constructed in arch/x86/kernel/head_32.S.  The root of the
++ * pagetable will be swapper_pg_dir.
+  *
+  * If we're booting paravirtualized under a hypervisor, then there are
+  * more options: we may already be running PAE, and the pagetable may
+@@ -424,10 +401,10 @@ static void __init xen_pagetable_setup_d
+  * be partially populated, and so it avoids stomping on any existing
+  * mappings.
   */
- static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+-static void __init pagetable_init (void)
++static void __init pagetable_init(void)
  {
--      outb_p(pirq, 0xc00);
-+      outb(pirq, 0xc00);
-       return inb(0xc01) & 0xf;
- }
+-      unsigned long vaddr, end;
+       pgd_t *pgd_base = (pgd_t *)xen_start_info->pt_base;
++      unsigned long vaddr, end;
  
- static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
- {
--      outb_p(pirq, 0xc00);
--      outb_p(irq, 0xc01);
-+      outb(pirq, 0xc00);
-+      outb(irq, 0xc01);
-       return 1;
- }
+       xen_pagetable_setup_start(pgd_base);
  
-@@ -575,6 +587,10 @@ static __init int intel_router_probe(str
-               case PCI_DEVICE_ID_INTEL_ICH9_4:
-               case PCI_DEVICE_ID_INTEL_ICH9_5:
-               case PCI_DEVICE_ID_INTEL_TOLAPAI_0:
-+              case PCI_DEVICE_ID_INTEL_ICH10_0:
-+              case PCI_DEVICE_ID_INTEL_ICH10_1:
-+              case PCI_DEVICE_ID_INTEL_ICH10_2:
-+              case PCI_DEVICE_ID_INTEL_ICH10_3:
-                       r->name = "PIIX/ICH";
-                       r->get = pirq_piix_get;
-                       r->set = pirq_piix_set;
---- a/arch/x86/vdso/Makefile
-+++ b/arch/x86/vdso/Makefile
-@@ -66,6 +66,7 @@ vdso32.so-$(VDSO32-y)                += int80
- vdso32.so-$(CONFIG_COMPAT)    += syscall
- vdso32.so-$(VDSO32-y)         += sysenter
- xen-vdso32-$(subst 1,$(CONFIG_COMPAT),$(shell expr $(CONFIG_XEN_COMPAT)0 '<' 0x0302000)) += int80
-+xen-vdso32-$(CONFIG_X86_32)   += syscall
- vdso32.so-$(CONFIG_XEN)               += $(xen-vdso32-y)
+@@ -449,34 +426,36 @@ static void __init pagetable_init (void)
+        * Fixed mappings, only the page table structure has to be
+        * created - mappings will be set by set_fixmap():
+        */
++      early_ioremap_clear();
+       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+       end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
+       page_table_range_init(vaddr, end, pgd_base);
++      early_ioremap_reset();
  
- vdso32-images                 = $(vdso32.so-y:%=vdso32-%.so)
---- a/arch/x86/vdso/vdso32.S
-+++ b/arch/x86/vdso/vdso32.S
-@@ -19,4 +19,16 @@ vdso32_sysenter_start:
-       .incbin "arch/x86/vdso/vdso32-sysenter.so"
- vdso32_sysenter_end:
+       permanent_kmaps_init(pgd_base);
  
-+#if defined(CONFIG_X86_64_XEN) && CONFIG_XEN_COMPAT < 0x030200
-+      .globl vdso32_int80_start, vdso32_int80_end
-+vdso32_int80_start:
-+      .incbin "arch/x86/vdso/vdso32-int80.so"
-+vdso32_int80_end:
-+#elif defined(CONFIG_X86_XEN)
-+      .globl vdso32_syscall_start, vdso32_syscall_end
-+vdso32_syscall_start:
-+      .incbin "arch/x86/vdso/vdso32-syscall.so"
-+vdso32_syscall_end:
-+#endif
-+
- __FINIT
---- a/arch/x86/vdso/vdso32-setup.c
-+++ b/arch/x86/vdso/vdso32-setup.c
-@@ -26,10 +26,6 @@
- #include <asm/vdso.h>
- #include <asm/proto.h>
+       xen_pagetable_setup_done(pgd_base);
+ }
  
--#ifdef CONFIG_XEN
--#include <xen/interface/callback.h>
--#endif
--
- enum {
-       VDSO_DISABLED = 0,
-       VDSO_ENABLED = 1,
-@@ -229,7 +225,6 @@ static inline void map_compat_vdso(int m
+-#if defined(CONFIG_HIBERNATION) || defined(CONFIG_ACPI)
++#if defined(CONFIG_ACPI_SLEEP) && !defined(CONFIG_XEN)
+ /*
+- * Swap suspend & friends need this for resume because things like the intel-agp
++ * ACPI suspend needs this for resume, because things like the intel-agp
+  * driver might have split up a kernel 4MB mapping.
+  */
+-char __nosavedata swsusp_pg_dir[PAGE_SIZE]
+-      __attribute__ ((aligned (PAGE_SIZE)));
++char swsusp_pg_dir[PAGE_SIZE]
++      __attribute__ ((aligned(PAGE_SIZE)));
  
void enable_sep_cpu(void)
static inline void save_pg_dir(void)
  {
--#ifndef CONFIG_XEN
-       int cpu = get_cpu();
-       struct tss_struct *tss = &per_cpu(init_tss, cpu);
-@@ -244,35 +239,6 @@ void enable_sep_cpu(void)
-       wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.sp1, 0);
-       wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0);
-       put_cpu();      
+       memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
+ }
 -#else
--      extern asmlinkage void ia32pv_sysenter_target(void);
--      static struct callback_register sysenter = {
--              .type = CALLBACKTYPE_sysenter,
--              .address = { __KERNEL_CS, (unsigned long)ia32pv_sysenter_target },
--      };
--
--      if (!boot_cpu_has(X86_FEATURE_SEP))
--              return;
--
--      get_cpu();
--
--      if (xen_feature(XENFEAT_supervisor_mode_kernel))
--              sysenter.address.eip = (unsigned long)ia32_sysenter_target;
--
--      switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) {
--      case 0:
--              break;
--#if CONFIG_XEN_COMPAT < 0x030200
--      case -ENOSYS:
--              sysenter.type = CALLBACKTYPE_sysenter_deprecated;
--              if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0)
--                      break;
--#endif
--      default:
--              clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
--              break;
--      }
--#endif
++#else /* !CONFIG_ACPI_SLEEP */
+ static inline void save_pg_dir(void)
+ {
  }
+-#endif
++#endif /* !CONFIG_ACPI_SLEEP */
  
- static struct vm_area_struct gate_vma;
---- /dev/null
-+++ b/arch/x86/vdso/vdso32-setup-xen.c
-@@ -0,0 +1,506 @@
-+/*
-+ * (C) Copyright 2002 Linus Torvalds
-+ * Portions based on the vdso-randomization code from exec-shield:
-+ * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
-+ *
-+ * This file contains the needed initializations to support sysenter.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/smp.h>
-+#include <linux/thread_info.h>
-+#include <linux/sched.h>
-+#include <linux/gfp.h>
-+#include <linux/string.h>
-+#include <linux/elf.h>
-+#include <linux/mm.h>
-+#include <linux/err.h>
-+#include <linux/module.h>
-+
-+#include <asm/cpufeature.h>
-+#include <asm/msr.h>
-+#include <asm/pgtable.h>
-+#include <asm/unistd.h>
-+#include <asm/elf.h>
-+#include <asm/tlbflush.h>
-+#include <asm/vdso.h>
-+#include <asm/proto.h>
-+
-+#include <xen/interface/callback.h>
-+
-+enum {
-+      VDSO_DISABLED = 0,
-+      VDSO_ENABLED = 1,
-+      VDSO_COMPAT = 2,
-+};
-+
-+#ifdef CONFIG_COMPAT_VDSO
-+#define VDSO_DEFAULT  VDSO_COMPAT
-+#else
-+#define VDSO_DEFAULT  VDSO_ENABLED
-+#endif
-+
-+#ifdef CONFIG_X86_64
-+#define vdso_enabled                  sysctl_vsyscall32
-+#define arch_setup_additional_pages   syscall32_setup_pages
-+#endif
-+
-+/*
-+ * This is the difference between the prelinked addresses in the vDSO images
-+ * and the VDSO_HIGH_BASE address where CONFIG_COMPAT_VDSO places the vDSO
-+ * in the user address space.
-+ */
-+#define VDSO_ADDR_ADJUST      (VDSO_HIGH_BASE - (unsigned long)VDSO32_PRELINK)
-+
-+/*
-+ * Should the kernel map a VDSO page into processes and pass its
-+ * address down to glibc upon exec()?
-+ */
-+unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT;
-+
-+static int __init vdso_setup(char *s)
-+{
-+      vdso_enabled = simple_strtoul(s, NULL, 0);
-+
-+      return 1;
-+}
-+
-+/*
-+ * For consistency, the argument vdso32=[012] affects the 32-bit vDSO
-+ * behavior on both 64-bit and 32-bit kernels.
-+ * On 32-bit kernels, vdso=[012] means the same thing.
-+ */
-+__setup("vdso32=", vdso_setup);
-+
-+#ifdef CONFIG_X86_32
-+__setup_param("vdso=", vdso32_setup, vdso_setup, 0);
-+
-+EXPORT_SYMBOL_GPL(vdso_enabled);
-+#endif
-+
-+static __init void reloc_symtab(Elf32_Ehdr *ehdr,
-+                              unsigned offset, unsigned size)
-+{
-+      Elf32_Sym *sym = (void *)ehdr + offset;
-+      unsigned nsym = size / sizeof(*sym);
-+      unsigned i;
-+
-+      for(i = 0; i < nsym; i++, sym++) {
-+              if (sym->st_shndx == SHN_UNDEF ||
-+                  sym->st_shndx == SHN_ABS)
-+                      continue;  /* skip */
-+
-+              if (sym->st_shndx > SHN_LORESERVE) {
-+                      printk(KERN_INFO "VDSO: unexpected st_shndx %x\n",
-+                             sym->st_shndx);
-+                      continue;
-+              }
-+
-+              switch(ELF_ST_TYPE(sym->st_info)) {
-+              case STT_OBJECT:
-+              case STT_FUNC:
-+              case STT_SECTION:
-+              case STT_FILE:
-+                      sym->st_value += VDSO_ADDR_ADJUST;
-+              }
+-void zap_low_mappings (void)
++void zap_low_mappings(void)
+ {
+       int i;
+@@ -488,22 +467,24 @@ void zap_low_mappings (void)
+        * Note that "pgd_clear()" doesn't do it for
+        * us, because pgd_clear() is a no-op on i386.
+        */
+-      for (i = 0; i < USER_PTRS_PER_PGD; i++)
++      for (i = 0; i < USER_PTRS_PER_PGD; i++) {
+ #if defined(CONFIG_X86_PAE) && !defined(CONFIG_XEN)
+               set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
+ #else
+               set_pgd(swapper_pg_dir+i, __pgd(0));
+ #endif
 +      }
-+}
-+
-+static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset)
-+{
-+      Elf32_Dyn *dyn = (void *)ehdr + offset;
-+
-+      for(; dyn->d_tag != DT_NULL; dyn++)
-+              switch(dyn->d_tag) {
-+              case DT_PLTGOT:
-+              case DT_HASH:
-+              case DT_STRTAB:
-+              case DT_SYMTAB:
-+              case DT_RELA:
-+              case DT_INIT:
-+              case DT_FINI:
-+              case DT_REL:
-+              case DT_DEBUG:
-+              case DT_JMPREL:
-+              case DT_VERSYM:
-+              case DT_VERDEF:
-+              case DT_VERNEED:
-+              case DT_ADDRRNGLO ... DT_ADDRRNGHI:
-+                      /* definitely pointers needing relocation */
-+                      dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
-+                      break;
-+
-+              case DT_ENCODING ... OLD_DT_LOOS-1:
-+              case DT_LOOS ... DT_HIOS-1:
-+                      /* Tags above DT_ENCODING are pointers if
-+                         they're even */
-+                      if (dyn->d_tag >= DT_ENCODING &&
-+                          (dyn->d_tag & 1) == 0)
-+                              dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
-+                      break;
-+
-+              case DT_VERDEFNUM:
-+              case DT_VERNEEDNUM:
-+              case DT_FLAGS_1:
-+              case DT_RELACOUNT:
-+              case DT_RELCOUNT:
-+              case DT_VALRNGLO ... DT_VALRNGHI:
-+                      /* definitely not pointers */
-+                      break;
+       flush_tlb_all();
+ }
+-int nx_enabled = 0;
++int nx_enabled;
 +
-+              case OLD_DT_LOOS ... DT_LOOS-1:
-+              case DT_HIOS ... DT_VALRNGLO-1:
-+              default:
-+                      if (dyn->d_tag > DT_ENCODING)
-+                              printk(KERN_INFO "VDSO: unexpected DT_tag %x\n",
-+                                     dyn->d_tag);
-+                      break;
++pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
++EXPORT_SYMBOL_GPL(__supported_pte_mask);
+ #ifdef CONFIG_X86_PAE
+-static int disable_nx __initdata = 0;
+-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
+-EXPORT_SYMBOL_GPL(__supported_pte_mask);
++static int disable_nx __initdata;
+ /*
+  * noexec = on|off
+@@ -520,11 +501,14 @@ static int __init noexec_setup(char *str
+                       __supported_pte_mask |= _PAGE_NX;
+                       disable_nx = 0;
+               }
+-      } else if (!strcmp(str,"off")) {
+-              disable_nx = 1;
+-              __supported_pte_mask &= ~_PAGE_NX;
+-      } else
+-              return -EINVAL;
++      } else {
++              if (!strcmp(str, "off")) {
++                      disable_nx = 1;
++                      __supported_pte_mask &= ~_PAGE_NX;
++              } else {
++                      return -EINVAL;
 +              }
-+}
-+
-+static __init void relocate_vdso(Elf32_Ehdr *ehdr)
-+{
-+      Elf32_Phdr *phdr;
-+      Elf32_Shdr *shdr;
-+      int i;
-+
-+      BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 ||
-+             !elf_check_arch_ia32(ehdr) ||
-+             ehdr->e_type != ET_DYN);
-+
-+      ehdr->e_entry += VDSO_ADDR_ADJUST;
-+
-+      /* rebase phdrs */
-+      phdr = (void *)ehdr + ehdr->e_phoff;
-+      for (i = 0; i < ehdr->e_phnum; i++) {
-+              phdr[i].p_vaddr += VDSO_ADDR_ADJUST;
-+
-+              /* relocate dynamic stuff */
-+              if (phdr[i].p_type == PT_DYNAMIC)
-+                      reloc_dyn(ehdr, phdr[i].p_offset);
-+      }
-+
-+      /* rebase sections */
-+      shdr = (void *)ehdr + ehdr->e_shoff;
-+      for(i = 0; i < ehdr->e_shnum; i++) {
-+              if (!(shdr[i].sh_flags & SHF_ALLOC))
-+                      continue;
-+
-+              shdr[i].sh_addr += VDSO_ADDR_ADJUST;
-+
-+              if (shdr[i].sh_type == SHT_SYMTAB ||
-+                  shdr[i].sh_type == SHT_DYNSYM)
-+                      reloc_symtab(ehdr, shdr[i].sh_offset,
-+                                   shdr[i].sh_size);
 +      }
-+}
-+
-+/*
-+ * These symbols are defined by vdso32.S to mark the bounds
-+ * of the ELF DSO images included therein.
-+ */
-+extern const char vdso32_default_start, vdso32_default_end;
-+extern const char vdso32_sysenter_start, vdso32_sysenter_end;
-+static struct page *vdso32_pages[1];
-+
-+#ifdef CONFIG_X86_64
-+
-+#if CONFIG_XEN_COMPAT < 0x030200
-+static int use_int80 = 1;
-+#endif
-+static int use_sysenter __read_mostly = -1;
-+
-+#define       vdso32_sysenter()       (use_sysenter > 0)
-+
-+/* May not be __init: called during resume */
-+void syscall32_cpu_init(void)
-+{
-+      static const struct callback_register cstar = {
-+              .type = CALLBACKTYPE_syscall32,
-+              .address = (unsigned long)ia32_cstar_target
-+      };
-+      static const struct callback_register sysenter = {
-+              .type = CALLBACKTYPE_sysenter,
-+              .address = (unsigned long)ia32_sysenter_target
-+      };
-+
-+      if ((HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0) ||
-+          (HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) < 0))
-+#if CONFIG_XEN_COMPAT < 0x030200
-+              return;
-+      use_int80 = 0;
-+#else
-+              BUG();
-+#endif
-+
-+      if (use_sysenter < 0)
-+              use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
-+}
-+
-+#define compat_uses_vma               1
-+
-+static inline void map_compat_vdso(int map)
-+{
-+}
-+
-+#else  /* CONFIG_X86_32 */
-+
-+#define vdso32_sysenter()     (boot_cpu_has(X86_FEATURE_SEP))
-+
-+extern asmlinkage void ia32pv_cstar_target(void);
-+static /*const*/ struct callback_register __cpuinitdata cstar = {
-+      .type = CALLBACKTYPE_syscall32,
-+      .address = { __KERNEL_CS, (unsigned long)ia32pv_cstar_target },
-+};
+       return 0;
+ }
+@@ -536,6 +520,7 @@ static void __init set_nx(void)
+       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
+               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
 +
-+void __cpuinit enable_sep_cpu(void)
-+{
-+      extern asmlinkage void ia32pv_sysenter_target(void);
-+      static struct callback_register __cpuinitdata sysenter = {
-+              .type = CALLBACKTYPE_sysenter,
-+              .address = { __KERNEL_CS, (unsigned long)ia32pv_sysenter_target },
-+      };
+               if ((v[3] & (1 << 20)) && !disable_nx) {
+                       rdmsr(MSR_EFER, l, h);
+                       l |= EFER_NX;
+@@ -545,35 +530,6 @@ static void __init set_nx(void)
+               }
+       }
+ }
+-
+-/*
+- * Enables/disables executability of a given kernel page and
+- * returns the previous setting.
+- */
+-int __init set_kernel_exec(unsigned long vaddr, int enable)
+-{
+-      pte_t *pte;
+-      int ret = 1;
+-
+-      if (!nx_enabled)
+-              goto out;
+-
+-      pte = lookup_address(vaddr);
+-      BUG_ON(!pte);
+-
+-      if (!pte_exec_kernel(*pte))
+-              ret = 0;
+-
+-      if (enable)
+-              pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
+-      else
+-              pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);
+-      pte_update_defer(&init_mm, vaddr, pte);
+-      __flush_tlb_all();
+-out:
+-      return ret;
+-}
+-
+ #endif
+ /*
+@@ -590,21 +546,10 @@ void __init paging_init(void)
+ #ifdef CONFIG_X86_PAE
+       set_nx();
+       if (nx_enabled)
+-              printk("NX (Execute Disable) protection: active\n");
++              printk(KERN_INFO "NX (Execute Disable) protection: active\n");
+ #endif
+-
+       pagetable_init();
+-#if defined(CONFIG_X86_PAE) && !defined(CONFIG_XEN)
+-      /*
+-       * We will bail out later - printk doesn't work right now so
+-       * the user would just see a hanging kernel.
+-       * when running as xen domain we are already in PAE mode at
+-       * this point.
+-       */
+-      if (cpu_has_pae)
+-              set_in_cr4(X86_CR4_PAE);
+-#endif
+       __flush_tlb_all();
+       kmap_init();
+@@ -631,10 +576,10 @@ void __init paging_init(void)
+  * used to involve black magic jumps to work around some nasty CPU bugs,
+  * but fortunately the switch to using exceptions got rid of all that.
+  */
+-
+ static void __init test_wp_bit(void)
+ {
+-      printk("Checking if this processor honours the WP bit even in supervisor mode... ");
++      printk(KERN_INFO
++  "Checking if this processor honours the WP bit even in supervisor mode...");
+       /* Any page-aligned address will do, the test is non-destructive */
+       __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY);
+@@ -642,23 +587,22 @@ static void __init test_wp_bit(void)
+       clear_fixmap(FIX_WP_TEST);
+       if (!boot_cpu_data.wp_works_ok) {
+-              printk("No.\n");
++              printk(KERN_CONT "No.\n");
+ #ifdef CONFIG_X86_WP_WORKS_OK
+-              panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
++              panic(
++  "This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
+ #endif
+       } else {
+-              printk("Ok.\n");
++              printk(KERN_CONT "Ok.\n");
+       }
+ }
+-static struct kcore_list kcore_mem, kcore_vmalloc; 
++static struct kcore_list kcore_mem, kcore_vmalloc;
+ void __init mem_init(void)
+ {
+-      extern int ppro_with_ram_bug(void);
+       int codesize, reservedpages, datasize, initsize;
+-      int tmp;
+-      int bad_ppro;
++      int tmp, bad_ppro;
+       unsigned long pfn;
+ #if defined(CONFIG_SWIOTLB)
+@@ -668,19 +612,19 @@ void __init mem_init(void)
+ #ifdef CONFIG_FLATMEM
+       BUG_ON(!mem_map);
+ #endif
+-      
+       bad_ppro = ppro_with_ram_bug();
+ #ifdef CONFIG_HIGHMEM
+       /* check that fixmap and pkmap do not overlap */
+-      if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
+-              printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");
++      if (PKMAP_BASE + LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
++              printk(KERN_ERR
++                      "fixmap and kmap areas overlap - this will crash\n");
+               printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
+-                              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);
++                              PKMAP_BASE, PKMAP_BASE + LAST_PKMAP*PAGE_SIZE,
++                              FIXADDR_START);
+               BUG();
+       }
+ #endif
+- 
+       /* this will put all low memory onto the freelists */
+       totalram_pages += free_all_bootmem();
+       /* XEN: init and count low-mem pages outside initial allocation. */
+@@ -693,7 +637,7 @@ void __init mem_init(void)
+       reservedpages = 0;
+       for (tmp = 0; tmp < max_low_pfn; tmp++)
+               /*
+-               * Only count reserved RAM pages
++               * Only count reserved RAM pages:
+                */
+               if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
+                       reservedpages++;
+@@ -704,11 +648,12 @@ void __init mem_init(void)
+       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+-      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
+-      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
++      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
++      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
+                  VMALLOC_END-VMALLOC_START);
+-      printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
++      printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
++                      "%dk reserved, %dk data, %dk init, %ldk highmem)\n",
+               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+               num_physpages << (PAGE_SHIFT-10),
+               codesize >> 10,
+@@ -719,54 +664,53 @@ void __init mem_init(void)
+              );
+ #if 1 /* double-sanity-check paranoia */
+-      printk("virtual kernel memory layout:\n"
+-             "    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
++      printk(KERN_INFO "virtual kernel memory layout:\n"
++              "    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+ #ifdef CONFIG_HIGHMEM
+-             "    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
++              "    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+ #endif
+-             "    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+-             "    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+-             "      .init : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+-             "      .data : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+-             "      .text : 0x%08lx - 0x%08lx   (%4ld kB)\n",
+-             FIXADDR_START, FIXADDR_TOP,
+-             (FIXADDR_TOP - FIXADDR_START) >> 10,
++              "    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
++              "    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
++              "      .init : 0x%08lx - 0x%08lx   (%4ld kB)\n"
++              "      .data : 0x%08lx - 0x%08lx   (%4ld kB)\n"
++              "      .text : 0x%08lx - 0x%08lx   (%4ld kB)\n",
++              FIXADDR_START, FIXADDR_TOP,
++              (FIXADDR_TOP - FIXADDR_START) >> 10,
+ #ifdef CONFIG_HIGHMEM
+-             PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
+-             (LAST_PKMAP*PAGE_SIZE) >> 10,
++              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
++              (LAST_PKMAP*PAGE_SIZE) >> 10,
+ #endif
+-             VMALLOC_START, VMALLOC_END,
+-             (VMALLOC_END - VMALLOC_START) >> 20,
++              VMALLOC_START, VMALLOC_END,
++              (VMALLOC_END - VMALLOC_START) >> 20,
+-             (unsigned long)__va(0), (unsigned long)high_memory,
+-             ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
++              (unsigned long)__va(0), (unsigned long)high_memory,
++              ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
+-             (unsigned long)&__init_begin, (unsigned long)&__init_end,
+-             ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
++              (unsigned long)&__init_begin, (unsigned long)&__init_end,
++              ((unsigned long)&__init_end -
++               (unsigned long)&__init_begin) >> 10,
+-             (unsigned long)&_etext, (unsigned long)&_edata,
+-             ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
++              (unsigned long)&_etext, (unsigned long)&_edata,
++              ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
+-             (unsigned long)&_text, (unsigned long)&_etext,
+-             ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
++              (unsigned long)&_text, (unsigned long)&_etext,
++              ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
+ #ifdef CONFIG_HIGHMEM
+-      BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
+-      BUG_ON(VMALLOC_END                     > PKMAP_BASE);
++      BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE        > FIXADDR_START);
++      BUG_ON(VMALLOC_END                              > PKMAP_BASE);
+ #endif
+-      BUG_ON(VMALLOC_START                   > VMALLOC_END);
+-      BUG_ON((unsigned long)high_memory      > VMALLOC_START);
++      BUG_ON(VMALLOC_START                            > VMALLOC_END);
++      BUG_ON((unsigned long)high_memory               > VMALLOC_START);
+ #endif /* double-sanity-check paranoia */
+-#ifdef CONFIG_X86_PAE
+-      if (!cpu_has_pae)
+-              panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
+-#endif
+       if (boot_cpu_data.wp_works_ok < 0)
+               test_wp_bit();
++      cpa_init();
 +
-+      if (boot_cpu_has(X86_FEATURE_SYSCALL)) {
-+              if (HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) != 0)
-+                      BUG();
-+              return;
-+      }
+       /*
+        * Subtle. SMP is doing it's boot stuff late (because it has to
+        * fork idle threads) - but it also needs low mappings for the
+@@ -790,49 +734,35 @@ int arch_add_memory(int nid, u64 start, 
+       return __add_pages(zone, start_pfn, nr_pages);
+ }
+-
+ #endif
+-struct kmem_cache *pmd_cache;
+-
+-void __init pgtable_cache_init(void)
+-{
+-      if (PTRS_PER_PMD > 1)
+-              pmd_cache = kmem_cache_create("pmd",
+-                                            PTRS_PER_PMD*sizeof(pmd_t),
+-                                            PTRS_PER_PMD*sizeof(pmd_t),
+-                                            SLAB_PANIC,
+-                                            pmd_ctor);
+-}
+-
+ /*
+  * This function cannot be __init, since exceptions don't work in that
+  * section.  Put this after the callers, so that it cannot be inlined.
+  */
+-static int noinline do_test_wp_bit(void)
++static noinline int do_test_wp_bit(void)
+ {
+       char tmp_reg;
+       int flag;
+       __asm__ __volatile__(
+-              "       movb %0,%1      \n"
+-              "1:     movb %1,%0      \n"
+-              "       xorl %2,%2      \n"
++              "       movb %0, %1     \n"
++              "1:     movb %1, %0     \n"
++              "       xorl %2, %2     \n"
+               "2:                     \n"
+-              ".section __ex_table,\"a\"\n"
+-              "       .align 4        \n"
+-              "       .long 1b,2b     \n"
+-              ".previous              \n"
++              _ASM_EXTABLE(1b,2b)
+               :"=m" (*(char *)fix_to_virt(FIX_WP_TEST)),
+                "=q" (tmp_reg),
+                "=r" (flag)
+               :"2" (1)
+               :"memory");
+-      
 +
-+      if (!boot_cpu_has(X86_FEATURE_SEP))
-+              return;
+       return flag;
+ }
+ #ifdef CONFIG_DEBUG_RODATA
++const int rodata_test_data = 0xC3;
++EXPORT_SYMBOL_GPL(rodata_test_data);
+ void mark_rodata_ro(void)
+ {
+@@ -845,32 +775,58 @@ void mark_rodata_ro(void)
+       if (num_possible_cpus() <= 1)
+ #endif
+       {
+-              change_page_attr(virt_to_page(start),
+-                               size >> PAGE_SHIFT, PAGE_KERNEL_RX);
+-              printk("Write protecting the kernel text: %luk\n", size >> 10);
++              set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
++              printk(KERN_INFO "Write protecting the kernel text: %luk\n",
++                      size >> 10);
 +
-+      if (xen_feature(XENFEAT_supervisor_mode_kernel))
-+              sysenter.address.eip = (unsigned long)ia32_sysenter_target;
++#ifdef CONFIG_CPA_DEBUG
++              printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
++                      start, start+size);
++              set_pages_rw(virt_to_page(start), size>>PAGE_SHIFT);
 +
-+      switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) {
-+      case 0:
-+              break;
-+#if CONFIG_XEN_COMPAT < 0x030200
-+      case -ENOSYS:
-+              sysenter.type = CALLBACKTYPE_sysenter_deprecated;
-+              if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0)
-+                      break;
++              printk(KERN_INFO "Testing CPA: write protecting again\n");
++              set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
 +#endif
-+      default:
-+              setup_clear_cpu_cap(X86_FEATURE_SEP);
-+              break;
-+      }
-+}
-+
-+static struct vm_area_struct gate_vma;
+       }
+ #endif
+       start += size;
+       size = (unsigned long)__end_rodata - start;
+-      change_page_attr(virt_to_page(start),
+-                       size >> PAGE_SHIFT, PAGE_KERNEL_RO);
+-      printk("Write protecting the kernel read-only data: %luk\n",
+-             size >> 10);
++      set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
++      printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
++              size >> 10);
++      rodata_test();
 +
-+static int __init gate_vma_init(void)
-+{
-+      gate_vma.vm_mm = NULL;
-+      gate_vma.vm_start = FIXADDR_USER_START;
-+      gate_vma.vm_end = FIXADDR_USER_END;
-+      gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
-+      gate_vma.vm_page_prot = __P101;
++#ifdef CONFIG_CPA_DEBUG
++      printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, start + size);
++      set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
+-      /*
+-       * change_page_attr() requires a global_flush_tlb() call after it.
+-       * We do this after the printk so that if something went wrong in the
+-       * change, the printk gets out at least to give a better debug hint
+-       * of who is the culprit.
+-       */
+-      global_flush_tlb();
++      printk(KERN_INFO "Testing CPA: write protecting again\n");
++      set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
++#endif
+ }
+ #endif
+ void free_init_pages(char *what, unsigned long begin, unsigned long end)
+ {
++#ifdef CONFIG_DEBUG_PAGEALLOC
 +      /*
-+       * Make sure the vDSO gets into every core dump.
-+       * Dumping its contents makes post-mortem fully interpretable later
-+       * without matching up the same kernel and hardware config to see
-+       * what PC values meant.
++       * If debugging page accesses then do not free this memory but
++       * mark them not present - any buggy init-section access will
++       * create a kernel page fault:
 +       */
-+      gate_vma.vm_flags |= VM_ALWAYSDUMP;
-+      return 0;
-+}
-+
-+#define compat_uses_vma               0
-+
-+static void map_compat_vdso(int map)
-+{
-+      static int vdso_mapped;
-+
-+      if (map == vdso_mapped)
-+              return;
-+
-+      vdso_mapped = map;
-+
-+      __set_fixmap(FIX_VDSO, page_to_pfn(vdso32_pages[0]) << PAGE_SHIFT,
-+                   map ? PAGE_READONLY_EXEC : PAGE_NONE);
-+
-+      /* flush stray tlbs */
-+      flush_tlb_all();
-+}
-+
-+#endif        /* CONFIG_X86_64 */
-+
-+int __init sysenter_setup(void)
-+{
-+      void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
-+      const void *vsyscall;
-+      size_t vsyscall_len;
-+
-+      vdso32_pages[0] = virt_to_page(syscall_page);
-+
-+#ifdef CONFIG_X86_32
-+      gate_vma_init();
++      printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
++              begin, PAGE_ALIGN(end));
++      set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
++#else
+       unsigned long addr;
++      /*
++       * We just marked the kernel text read only above, now that
++       * we are going to free part of that, we need to make that
++       * writeable first.
++       */
++      set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
 +
-+      printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
+       for (addr = begin; addr < end; addr += PAGE_SIZE) {
+               ClearPageReserved(virt_to_page(addr));
+               init_page_count(virt_to_page(addr));
+@@ -879,6 +835,7 @@ void free_init_pages(char *what, unsigne
+               totalram_pages++;
+       }
+       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
 +#endif
+ }
+ void free_initmem(void)
+@@ -894,4 +851,3 @@ void free_initrd_mem(unsigned long start
+       free_init_pages("initrd memory", start, end);
+ }
+ #endif
+-
+--- sle11-2009-05-14.orig/arch/x86/mm/init_64-xen.c    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/mm/init_64-xen.c 2009-03-16 16:33:40.000000000 +0100
+@@ -46,14 +46,13 @@
+ #include <asm/proto.h>
+ #include <asm/smp.h>
+ #include <asm/sections.h>
++#include <asm/kdebug.h>
++#include <asm/numa.h>
++#include <asm/cacheflush.h>
+ #include <xen/features.h>
+-#ifndef Dprintk
+-#define Dprintk(x...)
+-#endif
+-
+-const struct dma_mapping_ops* dma_ops;
++const struct dma_mapping_ops *dma_ops;
+ EXPORT_SYMBOL(dma_ops);
+ #if CONFIG_XEN_COMPAT <= 0x030002
+@@ -80,7 +79,21 @@ extern pte_t level1_fixmap_pgt[PTRS_PER_
+       (((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +   \
+       __START_KERNEL_map)))
+-static void __meminit early_make_page_readonly(void *va, unsigned int feature)
++pmd_t *__init early_get_pmd(unsigned long va)
++{
++      unsigned long addr;
++      unsigned long *page = (unsigned long *)init_level4_pgt;
 +
-+#if defined(CONFIG_X86_64) && CONFIG_XEN_COMPAT < 0x030200
-+      if (use_int80) {
-+              extern const char vdso32_int80_start, vdso32_int80_end;
-+
-+              vsyscall = &vdso32_int80_start;
-+              vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
-+      } else
-+#elif defined(CONFIG_X86_32)
-+      if (boot_cpu_has(X86_FEATURE_SYSCALL)
-+          && (boot_cpu_data.x86_vendor != X86_VENDOR_AMD
-+              || HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) != 0))
-+              setup_clear_cpu_cap(X86_FEATURE_SYSCALL);
-+      barrier(); /* until clear_bit()'s constraints are correct ... */
-+      if (boot_cpu_has(X86_FEATURE_SYSCALL)) {
-+              extern const char vdso32_syscall_start, vdso32_syscall_end;
-+
-+              vsyscall = &vdso32_syscall_start;
-+              vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
-+      } else
-+#endif
-+      if (!vdso32_sysenter()) {
-+              vsyscall = &vdso32_default_start;
-+              vsyscall_len = &vdso32_default_end - &vdso32_default_start;
-+      } else {
-+              vsyscall = &vdso32_sysenter_start;
-+              vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
-+      }
++      addr = page[pgd_index(va)];
++      addr_to_page(addr, page);
 +
-+      memcpy(syscall_page, vsyscall, vsyscall_len);
-+      relocate_vdso(syscall_page);
++      addr = page[pud_index(va)];
++      addr_to_page(addr, page);
 +
-+      return 0;
++      return (pmd_t *)&page[pmd_index(va)];
 +}
 +
-+/* Setup a VMA at program startup for the vsyscall page */
-+int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
-+{
-+      struct mm_struct *mm = current->mm;
-+      unsigned long addr;
-+      int ret = 0;
-+      bool compat;
-+
-+      down_write(&mm->mmap_sem);
-+
-+      /* Test compat mode once here, in case someone
-+         changes it via sysctl */
-+      compat = (vdso_enabled == VDSO_COMPAT);
++void __meminit early_make_page_readonly(void *va, unsigned int feature)
+ {
+       unsigned long addr, _va = (unsigned long)va;
+       pte_t pte, *ptep;
+@@ -107,76 +120,6 @@ static void __meminit early_make_page_re
+               BUG();
+ }
+-static void __make_page_readonly(void *va)
+-{
+-      pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
+-      unsigned long addr = (unsigned long) va;
+-
+-      pgd = pgd_offset_k(addr);
+-      pud = pud_offset(pgd, addr);
+-      pmd = pmd_offset(pud, addr);
+-      ptep = pte_offset_kernel(pmd, addr);
+-
+-      pte.pte = ptep->pte & ~_PAGE_RW;
+-      if (HYPERVISOR_update_va_mapping(addr, pte, 0))
+-              xen_l1_entry_update(ptep, pte); /* fallback */
+-
+-      if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
+-              __make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT));
+-}
+-
+-static void __make_page_writable(void *va)
+-{
+-      pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
+-      unsigned long addr = (unsigned long) va;
+-
+-      pgd = pgd_offset_k(addr);
+-      pud = pud_offset(pgd, addr);
+-      pmd = pmd_offset(pud, addr);
+-      ptep = pte_offset_kernel(pmd, addr);
+-
+-      pte.pte = ptep->pte | _PAGE_RW;
+-      if (HYPERVISOR_update_va_mapping(addr, pte, 0))
+-              xen_l1_entry_update(ptep, pte); /* fallback */
+-
+-      if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
+-              __make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT));
+-}
+-
+-void make_page_readonly(void *va, unsigned int feature)
+-{
+-      if (!xen_feature(feature))
+-              __make_page_readonly(va);
+-}
+-
+-void make_page_writable(void *va, unsigned int feature)
+-{
+-      if (!xen_feature(feature))
+-              __make_page_writable(va);
+-}
+-
+-void make_pages_readonly(void *va, unsigned nr, unsigned int feature)
+-{
+-      if (xen_feature(feature))
+-              return;
+-
+-      while (nr-- != 0) {
+-              __make_page_readonly(va);
+-              va = (void*)((unsigned long)va + PAGE_SIZE);
+-      }
+-}
+-
+-void make_pages_writable(void *va, unsigned nr, unsigned int feature)
+-{
+-      if (xen_feature(feature))
+-              return;
+-
+-      while (nr-- != 0) {
+-              __make_page_writable(va);
+-              va = (void*)((unsigned long)va + PAGE_SIZE);
+-      }
+-}
+-
+ /*
+  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
+  * physical space so we can cache the place of the first one and move
+@@ -187,22 +130,26 @@ void show_mem(void)
+ {
+       long i, total = 0, reserved = 0;
+       long shared = 0, cached = 0;
+-      pg_data_t *pgdat;
+       struct page *page;
++      pg_data_t *pgdat;
+       printk(KERN_INFO "Mem-info:\n");
+       show_free_areas();
+-      printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
++      printk(KERN_INFO "Free swap:       %6ldkB\n",
++              nr_swap_pages << (PAGE_SHIFT-10));
+       for_each_online_pgdat(pgdat) {
+-               for (i = 0; i < pgdat->node_spanned_pages; ++i) {
+-                      /* this loop can take a while with 256 GB and 4k pages
+-                         so update the NMI watchdog */
+-                      if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) {
++              for (i = 0; i < pgdat->node_spanned_pages; ++i) {
++                      /*
++                       * This loop can take a while with 256 GB and
++                       * 4k pages so defer the NMI watchdog:
++                       */
++                      if (unlikely(i % MAX_ORDER_NR_PAGES == 0))
+                               touch_nmi_watchdog();
+-                      }
 +
-+      map_compat_vdso(compat);
+                       if (!pfn_valid(pgdat->node_start_pfn + i))
+                               continue;
 +
-+      if (compat)
-+              addr = VDSO_HIGH_BASE;
-+      else {
-+              addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
-+              if (IS_ERR_VALUE(addr)) {
-+                      ret = addr;
-+                      goto up_fail;
+                       page = pfn_to_page(pgdat->node_start_pfn + i);
+                       total++;
+                       if (PageReserved(page))
+@@ -211,58 +158,67 @@ void show_mem(void)
+                               cached++;
+                       else if (page_count(page))
+                               shared += page_count(page) - 1;
+-               }
 +              }
-+      }
-+
-+      if (compat_uses_vma || !compat) {
-+              /*
-+               * MAYWRITE to allow gdb to COW and set breakpoints
-+               *
-+               * Make sure the vDSO gets into every core dump.
-+               * Dumping its contents makes post-mortem fully
-+               * interpretable later without matching up the same
-+               * kernel and hardware config to see what PC values
-+               * meant.
-+               */
-+              ret = install_special_mapping(mm, addr, PAGE_SIZE,
-+                                            VM_READ|VM_EXEC|
-+                                            VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-+                                            VM_ALWAYSDUMP,
-+                                            vdso32_pages);
+       }
+-      printk(KERN_INFO "%lu pages of RAM\n", total);
+-      printk(KERN_INFO "%lu reserved pages\n",reserved);
+-      printk(KERN_INFO "%lu pages shared\n",shared);
+-      printk(KERN_INFO "%lu pages swap cached\n",cached);
++      printk(KERN_INFO "%lu pages of RAM\n",          total);
++      printk(KERN_INFO "%lu reserved pages\n",        reserved);
++      printk(KERN_INFO "%lu pages shared\n",          shared);
++      printk(KERN_INFO "%lu pages swap cached\n",     cached);
+ }
++static unsigned long __meminitdata table_start;
++static unsigned long __meminitdata table_end;
+ static __init void *spp_getpage(void)
+-{ 
++{
+       void *ptr;
 +
-+              if (ret)
-+                      goto up_fail;
+       if (after_bootmem)
+-              ptr = (void *) get_zeroed_page(GFP_ATOMIC); 
++              ptr = (void *) get_zeroed_page(GFP_ATOMIC);
+       else if (start_pfn < table_end) {
+               ptr = __va(start_pfn << PAGE_SHIFT);
+               start_pfn++;
+               memset(ptr, 0, PAGE_SIZE);
+       } else
+               ptr = alloc_bootmem_pages(PAGE_SIZE);
+-      if (!ptr || ((unsigned long)ptr & ~PAGE_MASK))
+-              panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
+-      Dprintk("spp_getpage %p\n", ptr);
++      if (!ptr || ((unsigned long)ptr & ~PAGE_MASK)) {
++              panic("set_pte_phys: cannot allocate page data %s\n",
++                      after_bootmem ? "after bootmem" : "");
 +      }
 +
-+      current->mm->context.vdso = (void *)addr;
-+      current_thread_info()->sysenter_return =
-+              VDSO32_SYMBOL(addr, SYSENTER_RETURN);
-+
-+  up_fail:
-+      up_write(&mm->mmap_sem);
++      pr_debug("spp_getpage %p\n", ptr);
 +
-+      return ret;
+       return ptr;
+-} 
 +}
-+
-+#ifdef CONFIG_X86_64
-+
-+/*
-+ * This must be done early in case we have an initrd containing 32-bit
-+ * binaries (e.g., hotplug). This could be pushed upstream.
-+ */
-+core_initcall(sysenter_setup);
-+
-+#ifdef CONFIG_SYSCTL
-+/* Register vsyscall32 into the ABI table */
-+#include <linux/sysctl.h>
-+
-+static ctl_table abi_table2[] = {
-+      {
-+              .procname       = "vsyscall32",
-+              .data           = &sysctl_vsyscall32,
-+              .maxlen         = sizeof(int),
-+              .mode           = 0644,
-+              .proc_handler   = proc_dointvec
-+      },
-+      {}
-+};
-+
-+static ctl_table abi_root_table2[] = {
-+      {
-+              .ctl_name = CTL_ABI,
-+              .procname = "abi",
-+              .mode = 0555,
-+              .child = abi_table2
-+      },
-+      {}
-+};
-+
-+static __init int ia32_binfmt_init(void)
+ #define pgd_offset_u(address) (__user_pgd(init_level4_pgt) + pgd_index(address))
+ #define pud_offset_u(address) (level3_user_pgt + pud_index(address))
+-static __init void set_pte_phys(unsigned long vaddr,
+-                       unsigned long phys, pgprot_t prot, int user_mode)
++static __init void
++set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot, int user_mode)
+ {
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte, new_pte;
+-      Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
++      pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
+       pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
+       if (pgd_none(*pgd)) {
+-              printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
++              printk(KERN_ERR
++                      "PGD FIXMAP MISSING, it should be setup in head.S!\n");
+               return;
+       }
+       pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
+       if (pud_none(*pud)) {
+-              pmd = (pmd_t *) spp_getpage(); 
++              pmd = (pmd_t *) spp_getpage();
+               make_page_readonly(pmd, XENFEAT_writable_page_tables);
+               set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
+               if (pmd != pmd_offset(pud, 0)) {
+-                      printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
++                      printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
++                              pmd, pmd_offset(pud, 0));
+                       return;
+               }
+       }
+@@ -272,7 +228,7 @@ static __init void set_pte_phys(unsigned
+               make_page_readonly(pte, XENFEAT_writable_page_tables);
+               set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
+               if (pte != pte_offset_kernel(pmd, 0)) {
+-                      printk("PAGETABLE BUG #02!\n");
++                      printk(KERN_ERR "PAGETABLE BUG #02!\n");
+                       return;
+               }
+       }
+@@ -294,30 +250,30 @@ static __init void set_pte_phys(unsigned
+       __flush_tlb_one(vaddr);
+ }
+-static __init void set_pte_phys_ma(unsigned long vaddr,
+-                                 unsigned long phys, pgprot_t prot)
++static __init void
++set_pte_phys_ma(unsigned long vaddr, unsigned long phys, pgprot_t prot)
+ {
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte, new_pte;
+-      Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
++      pr_debug("set_pte_phys_ma %lx to %lx\n", vaddr, phys);
+       pgd = pgd_offset_k(vaddr);
+       if (pgd_none(*pgd)) {
+-              printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
++              printk(KERN_ERR
++                      "PGD FIXMAP MISSING, it should be setup in head.S!\n");
+               return;
+       }
+       pud = pud_offset(pgd, vaddr);
+       if (pud_none(*pud)) {
+-
+-              pmd = (pmd_t *) spp_getpage(); 
++              pmd = (pmd_t *) spp_getpage();
+               make_page_readonly(pmd, XENFEAT_writable_page_tables);
+               set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
+               if (pmd != pmd_offset(pud, 0)) {
+-                      printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
+-                      return;
++                      printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
++                              pmd, pmd_offset(pud, 0));
+               }
+       }
+       pmd = pmd_offset(pud, vaddr);
+@@ -326,7 +282,7 @@ static __init void set_pte_phys_ma(unsig
+               make_page_readonly(pte, XENFEAT_writable_page_tables);
+               set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
+               if (pte != pte_offset_kernel(pmd, 0)) {
+-                      printk("PAGETABLE BUG #02!\n");
++                      printk(KERN_ERR "PAGETABLE BUG #02!\n");
+                       return;
+               }
+       }
+@@ -350,14 +306,44 @@ static __init void set_pte_phys_ma(unsig
+       __flush_tlb_one(vaddr);
+ }
++#ifndef CONFIG_XEN
++/*
++ * The head.S code sets up the kernel high mapping:
++ *
++ *   from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
++ *
++ * phys_addr holds the negative offset to the kernel, which is added
++ * to the compile time generated pmds. This results in invalid pmds up
++ * to the point where we hit the physaddr 0 mapping.
++ *
++ * We limit the mappings to the region from _text to _end.  _end is
++ * rounded up to the 2MB boundary. This catches the invalid pmds as
++ * well, as they are located before _text:
++ */
++void __init cleanup_highmap(void)
 +{
-+      register_sysctl_table(abi_root_table2);
-+      return 0;
-+}
-+__initcall(ia32_binfmt_init);
-+#endif
-+
-+#else  /* CONFIG_X86_32 */
++      unsigned long vaddr = __START_KERNEL_map;
++      unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1;
++      pmd_t *pmd = level2_kernel_pgt;
++      pmd_t *last_pmd = pmd + PTRS_PER_PMD;
 +
-+const char *arch_vma_name(struct vm_area_struct *vma)
-+{
-+      if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
-+              return "[vdso]";
-+      return NULL;
++      for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) {
++              if (!pmd_present(*pmd))
++                      continue;
++              if (vaddr < (unsigned long) _text || vaddr > end)
++                      set_pmd(pmd, __pmd(0));
++      }
 +}
++#endif
 +
-+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
-+{
-+      struct mm_struct *mm = tsk->mm;
-+
-+      /* Check to see if this task was created in compat vdso mode */
-+      if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
-+              return &gate_vma;
-+      return NULL;
-+}
+ /* NOTE: this is meant to be run only at boot */
+-void __init 
+-__set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
++void __init
++__set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+ {
+       unsigned long address = __fix_to_virt(idx);
+       if (idx >= __end_of_fixed_addresses) {
+-              printk("Invalid __set_fixmap\n");
++              printk(KERN_ERR "Invalid __set_fixmap\n");
+               return;
+       }
+       switch (idx) {
+@@ -375,16 +361,14 @@ __set_fixmap (enum fixed_addresses idx, 
+       }
+ }
+-unsigned long __meminitdata table_start, table_end;
+-
+ static __meminit void *alloc_static_page(unsigned long *phys)
+ {
+       unsigned long va = (start_pfn << PAGE_SHIFT) + __START_KERNEL_map;
+       if (after_bootmem) {
+               void *adr = (void *)get_zeroed_page(GFP_ATOMIC);
+-
+               *phys = __pa(adr);
 +
-+int in_gate_area(struct task_struct *task, unsigned long addr)
-+{
-+      const struct vm_area_struct *vma = get_gate_vma(task);
+               return adr;
+       }
+@@ -396,7 +380,7 @@ static __meminit void *alloc_static_page
+ #define PTE_SIZE PAGE_SIZE
+-static inline int make_readonly(unsigned long paddr)
++static inline int __meminit make_readonly(unsigned long paddr)
+ {
+       extern char __vsyscall_0;
+       int readonly = 0;
+@@ -430,33 +414,38 @@ static inline int make_readonly(unsigned
+ /* Must run before zap_low_mappings */
+ __meminit void *early_ioremap(unsigned long addr, unsigned long size)
+ {
+-      unsigned long vaddr;
+       pmd_t *pmd, *last_pmd;
++      unsigned long vaddr;
+       int i, pmds;
+       pmds = ((addr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE;
+       vaddr = __START_KERNEL_map;
+       pmd = level2_kernel_pgt;
+       last_pmd = level2_kernel_pgt + PTRS_PER_PMD - 1;
 +
-+      return vma && addr >= vma->vm_start && addr < vma->vm_end;
-+}
+       for (; pmd <= last_pmd; pmd++, vaddr += PMD_SIZE) {
+               for (i = 0; i < pmds; i++) {
+                       if (pmd_present(pmd[i]))
+-                              goto next;
++                              goto continue_outer_loop;
+               }
+               vaddr += addr & ~PMD_MASK;
+               addr &= PMD_MASK;
 +
-+int in_gate_area_no_task(unsigned long addr)
-+{
-+      return 0;
-+}
+               for (i = 0; i < pmds; i++, addr += PMD_SIZE)
+-                      set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE));
+-              __flush_tlb();
++                      set_pmd(pmd+i, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
++              __flush_tlb_all();
 +
-+#endif        /* CONFIG_X86_64 */
---- a/arch/x86/vdso/vdso32/syscall.S
-+++ b/arch/x86/vdso/vdso32/syscall.S
-@@ -19,8 +19,10 @@ __kernel_vsyscall:
- .Lpush_ebp:
-       movl    %ecx, %ebp
-       syscall
-+#ifndef CONFIG_XEN
-       movl    $__USER32_DS, %ecx
-       movl    %ecx, %ss
-+#endif
-       movl    %ebp, %ecx
-       popl    %ebp
- .Lpop_ebp:
---- a/drivers/pci/msi-xen.c
-+++ b/drivers/pci/msi-xen.c
-@@ -43,6 +43,53 @@ struct msi_pirq_entry {
-       int entry_nr;
- };
+               return (void *)vaddr;
+-      next:
++continue_outer_loop:
+               ;
+       }
+       printk("early_ioremap(0x%lx, %lu) failed\n", addr, size);
+       return NULL;
+ }
  
-+/* Arch hooks */
+-/* To avoid virtual aliases later */
++/*
++ * To avoid virtual aliases later:
++ */
+ __meminit void early_iounmap(void *addr, unsigned long size)
+ {
+       unsigned long vaddr;
+@@ -466,9 +455,11 @@ __meminit void early_iounmap(void *addr,
+       vaddr = (unsigned long)addr;
+       pmds = ((vaddr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE;
+       pmd = level2_kernel_pgt + pmd_index(vaddr);
 +
-+int __attribute__ ((weak))
-+arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
-+{
-+      return 0;
-+}
+       for (i = 0; i < pmds; i++)
+               pmd_clear(pmd + i);
+-      __flush_tlb();
 +
-+#ifndef CONFIG_XEN
-+int __attribute__ ((weak))
-+arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
++      __flush_tlb_all();
+ }
+ #endif
+@@ -517,18 +508,19 @@ phys_pmd_init(pmd_t *pmd_page, unsigned 
+ static void __meminit
+ phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
+ {
+-      pmd_t *pmd = pmd_offset(pud,0);
++      pmd_t *pmd = pmd_offset(pud, 0);
+       spin_lock(&init_mm.page_table_lock);
+       phys_pmd_init(pmd, address, end);
+       spin_unlock(&init_mm.page_table_lock);
+       __flush_tlb_all();
+ }
+-static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
+-{ 
++static void __meminit
++phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
 +{
-+      return 0;
+       int i = pud_index(addr);
+-      for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) {
++      for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE) {
+               unsigned long pmd_phys;
+               pud_t *pud = pud_page + pud_index(addr);
+               pmd_t *pmd;
+@@ -550,8 +542,8 @@ static void __meminit phys_pud_init(pud_
+               early_make_page_readonly(pmd, XENFEAT_writable_page_tables);
+       }
+-      __flush_tlb();
+-} 
++      __flush_tlb_all();
 +}
+ void __init xen_init_pt(void)
+ {
+@@ -632,6 +624,7 @@ void __init xen_init_pt(void)
+ static void __init extend_init_mapping(unsigned long tables_space)
+ {
+       unsigned long va = __START_KERNEL_map;
++      unsigned long start = start_pfn;
+       unsigned long phys, addr, *pte_page;
+       pmd_t *pmd;
+       pte_t *pte, new_pte;
+@@ -682,6 +675,10 @@ static void __init extend_init_mapping(u
+                       BUG();
+               va += PAGE_SIZE;
+       }
 +
-+int __attribute__ ((weak))
-+arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
++      if (start_pfn > start)
++              reserve_early(start << PAGE_SHIFT,
++                            start_pfn << PAGE_SHIFT, "INITMAP");
+ }
+ static void __init find_early_table_space(unsigned long end)
+@@ -706,7 +703,7 @@ static void __init find_early_table_spac
+               (table_start << PAGE_SHIFT) + tables);
+ }
+-static void xen_finish_init_mapping(void)
++static void __init xen_finish_init_mapping(void)
+ {
+       unsigned long i, start, end;
+@@ -738,13 +735,6 @@ static void xen_finish_init_mapping(void
+       /* Allocate pte's for initial fixmaps from 'start_pfn' allocator. */
+       table_end = ~0UL;
+-      /*
+-       * Prefetch pte's for the bt_ioremap() area. It gets used before the
+-       * boot-time allocator is online, so allocate-on-demand would fail.
+-       */
+-      for (i = FIX_BTMAP_END; i <= FIX_BTMAP_BEGIN; i++)
+-              __set_fixmap(i, 0, __pgprot(0));
+-
+       /* Switch to the real shared_info page, and clear the dummy page. */
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+@@ -764,20 +754,23 @@ static void xen_finish_init_mapping(void
+       table_end = start_pfn;
+ }
+-/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
+-   This runs before bootmem is initialized and gets pages directly from the 
+-   physical memory. To access them they are temporarily mapped. */
++/*
++ * Setup the direct mapping of the physical memory at PAGE_OFFSET.
++ * This runs before bootmem is initialized and gets pages directly from
++ * the physical memory. To access them they are temporarily mapped.
++ */
+ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
+-{ 
 +{
-+      struct msi_desc *entry;
-+      int ret;
-+
-+      list_for_each_entry(entry, &dev->msi_list, list) {
-+              ret = arch_setup_msi_irq(dev, entry);
-+              if (ret)
-+                      return ret;
-+      }
+       unsigned long next;
+-      Dprintk("init_memory_mapping\n");
++      pr_debug("init_memory_mapping\n");
+-      /* 
++      /*
+        * Find space for the kernel direct mapping tables.
+-       * Later we should allocate these tables in the local node of the memory
+-       * mapped.  Unfortunately this is done currently before the nodes are 
+-       * discovered.
++       *
++       * Later we should allocate these tables in the local node of the
++       * memory mapped. Unfortunately this is done currently before the
++       * nodes are discovered.
+        */
+       if (!after_bootmem)
+               find_early_table_space(end);
+@@ -786,8 +779,8 @@ void __init_refok init_memory_mapping(un
+       end = (unsigned long)__va(end);
+       for (; start < end; start = next) {
+-              unsigned long pud_phys; 
+               pgd_t *pgd = pgd_offset_k(start);
++              unsigned long pud_phys;
+               pud_t *pud;
+               if (after_bootmem)
+@@ -795,8 +788,8 @@ void __init_refok init_memory_mapping(un
+               else
+                       pud = alloc_static_page(&pud_phys);
+               next = start + PGDIR_SIZE;
+-              if (next > end) 
+-                      next = end; 
++              if (next > end)
++                      next = end;
+               phys_pud_init(pud, __pa(start), __pa(next));
+               if (!after_bootmem) {
+                       early_make_page_readonly(pud, XENFEAT_writable_page_tables);
+@@ -810,12 +803,17 @@ void __init_refok init_memory_mapping(un
+       }
+       __flush_tlb_all();
 +
-+      return 0;
-+}
++      if (!after_bootmem)
++              reserve_early(table_start << PAGE_SHIFT,
++                            table_end << PAGE_SHIFT, "PGTABLE");
+ }
+ #ifndef CONFIG_NUMA
+ void __init paging_init(void)
+ {
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
 +
-+void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
-+{
-+      return;
-+}
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+       max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
+       max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+@@ -829,40 +827,6 @@ void __init paging_init(void)
+ }
+ #endif
+-/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
+-   from the CPU leading to inconsistent cache lines. address and size
+-   must be aligned to 2MB boundaries. 
+-   Does nothing when the mapping doesn't exist. */
+-void __init clear_kernel_mapping(unsigned long address, unsigned long size) 
+-{
+-      unsigned long end = address + size;
+-
+-      BUG_ON(address & ~LARGE_PAGE_MASK);
+-      BUG_ON(size & ~LARGE_PAGE_MASK); 
+-      
+-      for (; address < end; address += LARGE_PAGE_SIZE) { 
+-              pgd_t *pgd = pgd_offset_k(address);
+-              pud_t *pud;
+-              pmd_t *pmd;
+-              if (pgd_none(*pgd))
+-                      continue;
+-              pud = pud_offset(pgd, address);
+-              if (pud_none(*pud))
+-                      continue; 
+-              pmd = pmd_offset(pud, address);
+-              if (!pmd || pmd_none(*pmd))
+-                      continue; 
+-              if (0 == (__pmd_val(*pmd) & _PAGE_PSE)) {
+-                      /* Could handle this, but it should not happen currently. */
+-                      printk(KERN_ERR 
+-             "clear_kernel_mapping: mapping has been split. will leak memory\n"); 
+-                      pmd_ERROR(*pmd); 
+-              }
+-              set_pmd(pmd, __pmd(0));                 
+-      }
+-      __flush_tlb_all();
+-} 
+-
+ /*
+  * Memory hotplug specific functions
+  */
+@@ -888,16 +852,12 @@ int arch_add_memory(int nid, u64 start, 
+       unsigned long nr_pages = size >> PAGE_SHIFT;
+       int ret;
+-      init_memory_mapping(start, (start + size -1));
++      init_memory_mapping(start, start + size-1);
+       ret = __add_pages(zone, start_pfn, nr_pages);
+-      if (ret)
+-              goto error;
++      WARN_ON(1);
+       return ret;
+-error:
+-      printk("%s: Problem encountered in __add_pages!\n", __func__);
+-      return ret;
+ }
+ EXPORT_SYMBOL_GPL(arch_add_memory);
+@@ -911,36 +871,8 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
+ #endif /* CONFIG_MEMORY_HOTPLUG */
+-#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
+-/*
+- * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
+- * just online the pages.
+- */
+-int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
+-{
+-      int err = -EIO;
+-      unsigned long pfn;
+-      unsigned long total = 0, mem = 0;
+-      for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
+-              if (pfn_valid(pfn)) {
+-                      online_page(pfn_to_page(pfn));
+-                      err = 0;
+-                      mem++;
+-              }
+-              total++;
+-      }
+-      if (!err) {
+-              z->spanned_pages += total;
+-              z->present_pages += mem;
+-              z->zone_pgdat->node_spanned_pages += total;
+-              z->zone_pgdat->node_present_pages += mem;
+-      }
+-      return err;
+-}
+-#endif
+-
+-static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
+-                       kcore_vsyscall;
++static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
++                       kcore_modules, kcore_vsyscall;
+ void __init mem_init(void)
+ {
+@@ -949,8 +881,7 @@ void __init mem_init(void)
+       pci_iommu_alloc();
+-      /* clear the zero-page */
+-      memset(empty_zero_page, 0, PAGE_SIZE);
++      /* clear_bss() already clear the empty_zero_page */
+       reservedpages = 0;
+@@ -968,7 +899,6 @@ void __init mem_init(void)
+       }
+       reservedpages = end_pfn - totalram_pages -
+                                       absent_pages_in_range(0, end_pfn);
+-
+       after_bootmem = 1;
+       codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+@@ -976,46 +906,64 @@ void __init mem_init(void)
+       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+       /* Register memory areas for /proc/kcore */
+-      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
+-      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
++      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
++      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
+                  VMALLOC_END-VMALLOC_START);
+       kclist_add(&kcore_kernel, &_stext, _end - _stext);
+       kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
+-      kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, 
++      kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
+                                VSYSCALL_END - VSYSCALL_START);
+-      printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n",
++      printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
++                              "%ldk reserved, %ldk data, %ldk init)\n",
+               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+               end_pfn << (PAGE_SHIFT-10),
+               codesize >> 10,
+               reservedpages << (PAGE_SHIFT-10),
+               datasize >> 10,
+               initsize >> 10);
 +
-+void __attribute__ ((weak))
-+arch_teardown_msi_irqs(struct pci_dev *dev)
-+{
-+      struct msi_desc *entry;
++      cpa_init();
+ }
+ void free_init_pages(char *what, unsigned long begin, unsigned long end)
+ {
+-      unsigned long addr;
++      unsigned long addr = begin;
+-      if (begin >= end)
++      if (addr >= end)
+               return;
++      /*
++       * If debugging page accesses then do not free this memory but
++       * mark them not present - any buggy init-section access will
++       * create a kernel page fault:
++       */
++#ifdef CONFIG_DEBUG_PAGEALLOC
++      printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
++              begin, PAGE_ALIGN(end));
++      set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
++#else
+       printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
+-      for (addr = begin; addr < end; addr += PAGE_SIZE) {
 +
-+      list_for_each_entry(entry, &dev->msi_list, list) {
-+              if (entry->irq != 0)
-+                      arch_teardown_msi_irq(entry->irq);
-+      }
-+}
++      for (; addr < end; addr += PAGE_SIZE) {
+               ClearPageReserved(virt_to_page(addr));
+               init_page_count(virt_to_page(addr));
+               memset((void *)(addr & ~(PAGE_SIZE-1)),
+                      POISON_FREE_INITMEM, PAGE_SIZE); 
+               if (addr >= __START_KERNEL_map) {
+                       /* make_readonly() reports all kernel addresses. */
+-                      __make_page_writable(__va(__pa(addr)));
+-                      change_page_attr_addr(addr, 1, __pgprot(0));
++                      if (HYPERVISOR_update_va_mapping((unsigned long)__va(__pa(addr)),
++                                                       pfn_pte(__pa(addr) >> PAGE_SHIFT,
++                                                               PAGE_KERNEL),
++                                                       0))
++                              BUG();
++                      if (HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
++                              BUG();
+               }
+               free_page(addr);
+               totalram_pages++;
+       }
+-      if (addr > __START_KERNEL_map)
+-              global_flush_tlb();
 +#endif
-+
- static void msi_set_enable(struct pci_dev *dev, int enable)
- {
-       int pos;
-@@ -270,7 +317,6 @@ static void pci_intx_for_msi(struct pci_
-               pci_intx(dev, enable);
  }
  
--#ifdef CONFIG_PM
- static void __pci_restore_msi_state(struct pci_dev *dev)
- {
-       int pirq;
-@@ -328,7 +374,7 @@ void pci_restore_msi_state(struct pci_de
-       __pci_restore_msi_state(dev);
-       __pci_restore_msix_state(dev);
+ void free_initmem(void)
+@@ -1026,6 +974,8 @@ void free_initmem(void)
  }
--#endif        /* CONFIG_PM */
-+EXPORT_SYMBOL_GPL(pci_restore_msi_state);
  
- /**
-  * msi_capability_init - configure device's MSI capability structure
-@@ -760,51 +806,3 @@ void pci_msi_init_pci_dev(struct pci_dev
-       INIT_LIST_HEAD(&dev->msi_list);
- #endif
- }
--
--
--/* Arch hooks */
--
--int __attribute__ ((weak))
--arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
--{
--      return 0;
--}
--
--#ifndef CONFIG_XEN
--int __attribute__ ((weak))
--arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
--{
--      return 0;
--}
--
--int __attribute__ ((weak))
--arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
--{
--      struct msi_desc *entry;
--      int ret;
--
--      list_for_each_entry(entry, &dev->msi_list, list) {
--              ret = arch_setup_msi_irq(dev, entry);
--              if (ret)
--                      return ret;
--      }
--
--      return 0;
--}
--
--void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
--{
--      return;
--}
--
--void __attribute__ ((weak))
--arch_teardown_msi_irqs(struct pci_dev *dev)
--{
--      struct msi_desc *entry;
--
--      list_for_each_entry(entry, &dev->msi_list, list) {
--              if (entry->irq != 0)
--                      arch_teardown_msi_irq(entry->irq);
--      }
--}
--#endif
---- a/drivers/pci/pci.c
-+++ b/drivers/pci/pci.c
-@@ -353,7 +353,12 @@ pci_find_parent_resource(const struct pc
-  * Restore the BAR values for a given device, so as to make it
-  * accessible by its driver.
-  */
-+#ifndef CONFIG_XEN
- static void
-+#else
-+EXPORT_SYMBOL_GPL(pci_restore_bars);
-+void
-+#endif
- pci_restore_bars(struct pci_dev *dev)
+ #ifdef CONFIG_DEBUG_RODATA
++const int rodata_test_data = 0xC3;
++EXPORT_SYMBOL_GPL(rodata_test_data);
+ void mark_rodata_ro(void)
  {
-       int i, numres;
---- a/drivers/xen/balloon/sysfs.c
-+++ b/drivers/xen/balloon/sysfs.c
-@@ -108,7 +108,7 @@ static struct attribute_group balloon_in
- };
+@@ -1047,18 +997,27 @@ void mark_rodata_ro(void)
+       if (end <= start)
+               return;
  
- static struct sysdev_class balloon_sysdev_class = {
--      set_kset_name(BALLOON_CLASS_NAME),
-+      .name = BALLOON_CLASS_NAME,
- };
+-      change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO);
  
- static struct sys_device balloon_sysdev;
---- a/drivers/xen/blkback/blkback.c
-+++ b/drivers/xen/blkback/blkback.c
-@@ -148,7 +148,7 @@ static void unplug_queue(blkif_t *blkif)
-               return;
-       if (blkif->plug->unplug_fn)
-               blkif->plug->unplug_fn(blkif->plug);
--      blk_put_queue(blkif->plug);
-+      kobject_put(&blkif->plug->kobj);
-       blkif->plug = NULL;
- }
+       printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
+              (end - start) >> 10);
++      set_memory_ro(start, (end - start) >> PAGE_SHIFT);
  
-@@ -159,7 +159,8 @@ static void plug_queue(blkif_t *blkif, s
-       if (q == blkif->plug)
-               return;
-       unplug_queue(blkif);
--      blk_get_queue(q);
-+      WARN_ON(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags));
-+      kobject_get(&q->kobj);
-       blkif->plug = q;
+       /*
+-       * change_page_attr_addr() requires a global_flush_tlb() call after it.
+-       * We do this after the printk so that if something went wrong in the
+-       * change, the printk gets out at least to give a better debug hint
+-       * of who is the culprit.
++       * The rodata section (but not the kernel text!) should also be
++       * not-executable.
+        */
+-      global_flush_tlb();
++      start = ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
++      set_memory_nx(start, (end - start) >> PAGE_SHIFT);
++
++      rodata_test();
++
++#ifdef CONFIG_CPA_DEBUG
++      printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, end);
++      set_memory_rw(start, (end-start) >> PAGE_SHIFT);
++
++      printk(KERN_INFO "Testing CPA: again\n");
++      set_memory_ro(start, (end-start) >> PAGE_SHIFT);
++#endif
  }
+ #endif
  
---- a/drivers/xen/blkfront/blkfront.c
-+++ b/drivers/xen/blkfront/blkfront.c
-@@ -716,7 +716,6 @@ static irqreturn_t blkif_int(int irq, vo
-       RING_IDX i, rp;
-       unsigned long flags;
-       struct blkfront_info *info = (struct blkfront_info *)dev_id;
--      int uptodate;
-       spin_lock_irqsave(&blkif_io_lock, flags);
+@@ -1069,17 +1028,21 @@ void free_initrd_mem(unsigned long start
+ }
+ #endif
  
-@@ -741,13 +740,13 @@ static irqreturn_t blkif_int(int irq, vo
+-void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 
+-{ 
++void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
++{
+ #ifdef CONFIG_NUMA
+       int nid = phys_to_nid(phys);
+ #endif
+       unsigned long pfn = phys >> PAGE_SHIFT;
++
+       if (pfn >= end_pfn) {
+-              /* This can happen with kdump kernels when accessing firmware
+-                 tables. */
++              /*
++               * This can happen with kdump kernels when accessing
++               * firmware tables:
++               */
+               if (pfn < end_pfn_map)
+                       return;
++
+               printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n",
+                               phys, len);
+               return;
+@@ -1087,9 +1050,9 @@ void __init reserve_bootmem_generic(unsi
  
-               ADD_ID_TO_FREELIST(info, id);
+       /* Should check here against the e820 map to avoid double free */
+ #ifdef CONFIG_NUMA
+-      reserve_bootmem_node(NODE_DATA(nid), phys, len);
+-#else                 
+-      reserve_bootmem(phys, len);    
++      reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT);
++#else
++      reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
+ #endif
+ #ifndef CONFIG_XEN
+       if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
+@@ -1099,46 +1062,49 @@ void __init reserve_bootmem_generic(unsi
+ #endif
+ }
  
--              uptodate = (bret->status == BLKIF_RSP_OKAY);
-+              ret = bret->status == BLKIF_RSP_OKAY ? 0 : -EIO;
-               switch (bret->operation) {
-               case BLKIF_OP_WRITE_BARRIER:
-                       if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
-                               printk("blkfront: %s: write barrier op failed\n",
-                                      info->gd->disk_name);
--                              uptodate = -EOPNOTSUPP;
-+                              ret = -EOPNOTSUPP;
-                               info->feature_barrier = 0;
-                               xlvbd_barrier(info);
-                       }
-@@ -758,10 +757,8 @@ static irqreturn_t blkif_int(int irq, vo
-                               DPRINTK("Bad return from blkdev data "
-                                       "request: %x\n", bret->status);
+-int kern_addr_valid(unsigned long addr) 
+-{ 
++int kern_addr_valid(unsigned long addr)
++{
+       unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
+-       pgd_t *pgd;
+-       pud_t *pud;
+-       pmd_t *pmd;
+-       pte_t *pte;
++      pgd_t *pgd;
++      pud_t *pud;
++      pmd_t *pmd;
++      pte_t *pte;
  
--                      ret = end_that_request_first(req, uptodate,
--                              req->hard_nr_sectors);
-+                      ret = __blk_end_request(req, ret, blk_rq_bytes(req));
-                       BUG_ON(ret);
--                      end_that_request_last(req, uptodate);
-                       break;
-               default:
-                       BUG();
---- a/drivers/xen/blktap/blktap.c
-+++ b/drivers/xen/blktap/blktap.c
-@@ -327,8 +327,8 @@ static pte_t blktap_clear_pte(struct vm_
-        * if vm_file is NULL (meaning mmap failed and we have nothing to do)
-        */
-       if (uvaddr < uvstart || vma->vm_file == NULL)
--              return ptep_get_and_clear_full(vma->vm_mm, uvaddr, 
--                                             ptep, is_fullmm);
-+              return xen_ptep_get_and_clear_full(vma, uvaddr, ptep,
-+                                                 is_fullmm);
+       if (above != 0 && above != -1UL)
+-              return 0; 
+-      
++              return 0;
++
+       pgd = pgd_offset_k(addr);
+       if (pgd_none(*pgd))
+               return 0;
  
-       info = vma->vm_file->private_data;
-       map = vma->vm_private_data;
-@@ -375,8 +375,8 @@ static pte_t blktap_clear_pte(struct vm_
-               BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap));
+       pud = pud_offset(pgd, addr);
+       if (pud_none(*pud))
+-              return 0; 
++              return 0;
  
-               /* USING SHADOW PAGE TABLES. */
--              copy = ptep_get_and_clear_full(vma->vm_mm, uvaddr, ptep,
--                                             is_fullmm);
-+              copy = xen_ptep_get_and_clear_full(vma, uvaddr, ptep,
-+                                                 is_fullmm);
-       }
+       pmd = pmd_offset(pud, addr);
+       if (pmd_none(*pmd))
+               return 0;
++
+       if (pmd_large(*pmd))
+               return pfn_valid(pmd_pfn(*pmd));
  
-       if (count) {
---- a/drivers/xen/core/evtchn.c
-+++ b/drivers/xen/core/evtchn.c
-@@ -193,7 +193,7 @@ static inline unsigned int cpu_from_evtc
+       pte = pte_offset_kernel(pmd, addr);
+       if (pte_none(*pte))
+               return 0;
++
+       return pfn_valid(pte_pfn(*pte));
+ }
  
- /* Upcall to generic IRQ layer. */
- #ifdef CONFIG_X86
--extern fastcall unsigned int do_IRQ(struct pt_regs *regs);
-+extern unsigned int do_IRQ(struct pt_regs *regs);
- void __init xen_init_IRQ(void);
- void __init init_IRQ(void)
+-/* A pseudo VMA to allow ptrace access for the vsyscall page.  This only
+-   covers the 64bit vsyscall page now. 32bit has a real VMA now and does
+-   not need special handling anymore. */
+-
++/*
++ * A pseudo VMA to allow ptrace access for the vsyscall page.  This only
++ * covers the 64bit vsyscall page now. 32bit has a real VMA now and does
++ * not need special handling anymore:
++ */
+ static struct vm_area_struct gate_vma = {
+-      .vm_start = VSYSCALL_START,
+-      .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES << PAGE_SHIFT),
+-      .vm_page_prot = PAGE_READONLY_EXEC,
+-      .vm_flags = VM_READ | VM_EXEC
++      .vm_start       = VSYSCALL_START,
++      .vm_end         = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
++      .vm_page_prot   = PAGE_READONLY_EXEC,
++      .vm_flags       = VM_READ | VM_EXEC
+ };
+ struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
+@@ -1153,14 +1119,17 @@ struct vm_area_struct *get_gate_vma(stru
+ int in_gate_area(struct task_struct *task, unsigned long addr)
  {
-@@ -202,13 +202,11 @@ void __init init_IRQ(void)
+       struct vm_area_struct *vma = get_gate_vma(task);
++
+       if (!vma)
+               return 0;
++
+       return (addr >= vma->vm_start) && (addr < vma->vm_end);
  }
- #if defined (__i386__)
- static inline void exit_idle(void) {}
--#define IRQ_REG orig_eax
- #elif defined (__x86_64__)
- #include <asm/idle.h>
--#define IRQ_REG orig_rax
- #endif
- #define do_IRQ(irq, regs) do {                \
--      (regs)->IRQ_REG = ~(irq);       \
-+      (regs)->orig_ax = ~(irq);       \
-       do_IRQ((regs));                 \
- } while (0)
- #endif
-@@ -669,13 +667,12 @@ static void set_affinity_irq(unsigned in
- int resend_irq_on_evtchn(unsigned int irq)
- {
-       int masked, evtchn = evtchn_from_irq(irq);
--      shared_info_t *s = HYPERVISOR_shared_info;
  
-       if (!VALID_EVTCHN(evtchn))
-               return 1;
+-/* Use this when you have no reliable task/vma, typically from interrupt
+- * context.  It is less reliable than using the task's vma and may give
+- * false positives.
++/*
++ * Use this when you have no reliable task/vma, typically from interrupt
++ * context. It is less reliable than using the task's vma and may give
++ * false positives:
+  */
+ int in_gate_area_no_task(unsigned long addr)
+ {
+@@ -1180,8 +1149,8 @@ const char *arch_vma_name(struct vm_area
+ /*
+  * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
+  */
+-int __meminit vmemmap_populate(struct page *start_page,
+-                                              unsigned long size, int node)
++int __meminit
++vmemmap_populate(struct page *start_page, unsigned long size, int node)
+ {
+       unsigned long addr = (unsigned long)start_page;
+       unsigned long end = (unsigned long)(start_page + size);
+@@ -1196,6 +1165,7 @@ int __meminit vmemmap_populate(struct pa
+               pgd = vmemmap_pgd_populate(addr, node);
+               if (!pgd)
+                       return -ENOMEM;
++
+               pud = vmemmap_pud_populate(pgd, addr, node);
+               if (!pud)
+                       return -ENOMEM;
+@@ -1203,20 +1173,22 @@ int __meminit vmemmap_populate(struct pa
+               pmd = pmd_offset(pud, addr);
+               if (pmd_none(*pmd)) {
+                       pte_t entry;
+-                      void *p = vmemmap_alloc_block(PMD_SIZE, node);
++                      void *p;
++
++                      p = vmemmap_alloc_block(PMD_SIZE, node);
+                       if (!p)
+                               return -ENOMEM;
  
-       masked = test_and_set_evtchn_mask(evtchn);
--      synch_set_bit(evtchn, s->evtchn_pending);
-+      set_evtchn(evtchn);
-       if (!masked)
-               unmask_evtchn(evtchn);
+-                      entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
+-                      mk_pte_huge(entry);
+-                      set_pmd(pmd, __pmd(pte_val(entry)));
++                      entry = pfn_pte(__pa(p) >> PAGE_SHIFT,
++                                                      PAGE_KERNEL_LARGE);
++                      set_pmd(pmd, __pmd_ma(__pte_val(entry)));
  
-@@ -968,6 +965,43 @@ void disable_all_local_evtchn(void)
-                       synch_set_bit(i, &s->evtchn_mask[0]);
+                       printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n",
+                               addr, addr + PMD_SIZE - 1, p, node);
+-              } else
++              } else {
+                       vmemmap_verify((pte_t *)pmd, node, addr, next);
++              }
+       }
+-
+       return 0;
  }
-+/* Clear an irq's pending state, in preparation for polling on it. */
-+void xen_clear_irq_pending(int irq)
+ #endif
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/mm/ioremap-xen.c 2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,687 @@
++/*
++ * Re-map IO memory to kernel address space so that we can access it.
++ * This is needed for high PCI addresses that aren't mapped in the
++ * 640k-1MB IO memory area on PC's
++ *
++ * (C) Copyright 1995 1996 Linus Torvalds
++ */
++
++#include <linux/bootmem.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/pfn.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++
++#include <asm/cacheflush.h>
++#include <asm/e820.h>
++#include <asm/fixmap.h>
++#include <asm/pgtable.h>
++#include <asm/tlbflush.h>
++#include <asm/pgalloc.h>
++
++enum ioremap_mode {
++      IOR_MODE_UNCACHED,
++      IOR_MODE_CACHED,
++};
++
++#if defined(CONFIG_X86_64) && !defined(CONFIG_XEN)
++
++unsigned long __phys_addr(unsigned long x)
 +{
-+      int evtchn = evtchn_from_irq(irq);
++      if (x >= __START_KERNEL_map)
++              return x - __START_KERNEL_map + phys_base;
++      return x - PAGE_OFFSET;
++}
++EXPORT_SYMBOL(__phys_addr);
++
++#endif
++
++static int direct_remap_area_pte_fn(pte_t *pte,
++                                  struct page *pmd_page,
++                                  unsigned long address,
++                                  void *data)
++{
++      mmu_update_t **v = (mmu_update_t **)data;
++
++      BUG_ON(!pte_none(*pte));
++
++      (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
++                   PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
++      (*v)++;
++
++      return 0;
++}
++
++static int __direct_remap_pfn_range(struct mm_struct *mm,
++                                  unsigned long address,
++                                  unsigned long mfn,
++                                  unsigned long size,
++                                  pgprot_t prot,
++                                  domid_t  domid)
++{
++      int rc;
++      unsigned long i, start_address;
++      mmu_update_t *u, *v, *w;
++
++      u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
++      if (u == NULL)
++              return -ENOMEM;
++
++      start_address = address;
++
++      flush_cache_all();
++
++      for (i = 0; i < size; i += PAGE_SIZE) {
++              if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
++                      /* Flush a full batch after filling in the PTE ptrs. */
++                      rc = apply_to_page_range(mm, start_address,
++                                               address - start_address,
++                                               direct_remap_area_pte_fn, &w);
++                      if (rc)
++                              goto out;
++                      rc = -EFAULT;
++                      if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
++                              goto out;
++                      v = w = u;
++                      start_address = address;
++              }
++
++              /*
++               * Fill in the machine address: PTE ptr is done later by
++               * apply_to_page_range().
++               */
++              v->val = __pte_val(pfn_pte_ma(mfn, prot)) | _PAGE_IO;
++
++              mfn++;
++              address += PAGE_SIZE;
++              v++;
++      }
++
++      if (v != u) {
++              /* Final batch. */
++              rc = apply_to_page_range(mm, start_address,
++                                       address - start_address,
++                                       direct_remap_area_pte_fn, &w);
++              if (rc)
++                      goto out;
++              rc = -EFAULT;
++              if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
++                      goto out;
++      }
++
++      rc = 0;
++
++ out:
++      flush_tlb_all();
++
++      free_page((unsigned long)u);
++
++      return rc;
++}
++
++int direct_remap_pfn_range(struct vm_area_struct *vma,
++                         unsigned long address,
++                         unsigned long mfn,
++                         unsigned long size,
++                         pgprot_t prot,
++                         domid_t  domid)
++{
++      if (xen_feature(XENFEAT_auto_translated_physmap))
++              return remap_pfn_range(vma, address, mfn, size, prot);
++
++      if (domid == DOMID_SELF)
++              return -EINVAL;
 +
-+      if (VALID_EVTCHN(evtchn))
-+              clear_evtchn(evtchn);
++      vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
++
++      vma->vm_mm->context.has_foreign_mappings = 1;
++
++      return __direct_remap_pfn_range(
++              vma->vm_mm, address, mfn, size, prot, domid);
 +}
++EXPORT_SYMBOL(direct_remap_pfn_range);
 +
-+/* Set an irq's pending state, to avoid blocking on it. */
-+void xen_set_irq_pending(int irq)
++int direct_kernel_remap_pfn_range(unsigned long address,
++                                unsigned long mfn,
++                                unsigned long size,
++                                pgprot_t prot,
++                                domid_t  domid)
 +{
-+      int evtchn = evtchn_from_irq(irq);
++      return __direct_remap_pfn_range(
++              &init_mm, address, mfn, size, prot, domid);
++}
++EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
 +
-+      if (VALID_EVTCHN(evtchn))
-+              set_evtchn(evtchn);
++static int lookup_pte_fn(
++      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
++{
++      uint64_t *ptep = (uint64_t *)data;
++      if (ptep)
++              *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
++                       PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
++      return 0;
 +}
 +
-+/* Test an irq's pending state. */
-+int xen_test_irq_pending(int irq)
++int create_lookup_pte_addr(struct mm_struct *mm,
++                         unsigned long address,
++                         uint64_t *ptep)
 +{
-+      int evtchn = evtchn_from_irq(irq);
++      return apply_to_page_range(mm, address, PAGE_SIZE,
++                                 lookup_pte_fn, ptep);
++}
 +
-+      return VALID_EVTCHN(evtchn) && test_evtchn(evtchn);
++EXPORT_SYMBOL(create_lookup_pte_addr);
++
++static int noop_fn(
++      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
++{
++      return 0;
 +}
 +
-+/* Poll waiting for an irq to become pending.  In the usual case, the
-+   irq will be disabled so it won't deliver an interrupt. */
-+void xen_poll_irq(int irq)
++int touch_pte_range(struct mm_struct *mm,
++                  unsigned long address,
++                  unsigned long size)
 +{
-+      evtchn_port_t evtchn = evtchn_from_irq(irq);
++      return apply_to_page_range(mm, address, size, noop_fn, NULL);
++}
 +
-+      if (VALID_EVTCHN(evtchn)
-+          && HYPERVISOR_poll_no_timeout(&evtchn, 1))
-+              BUG();
++EXPORT_SYMBOL(touch_pte_range);
++
++#ifdef CONFIG_X86_32
++int page_is_ram(unsigned long pagenr)
++{
++      unsigned long addr, end;
++      int i;
++
++#ifndef CONFIG_XEN
++      /*
++       * A special case is the first 4Kb of memory;
++       * This is a BIOS owned area, not kernel ram, but generally
++       * not listed as such in the E820 table.
++       */
++      if (pagenr == 0)
++              return 0;
++
++      /*
++       * Second special case: Some BIOSen report the PC BIOS
++       * area (640->1Mb) as ram even though it is not.
++       */
++      if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
++                  pagenr < (BIOS_END >> PAGE_SHIFT))
++              return 0;
++#endif
++
++      for (i = 0; i < e820.nr_map; i++) {
++              /*
++               * Not usable memory:
++               */
++              if (e820.map[i].type != E820_RAM)
++                      continue;
++              addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT;
++              end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT;
++
++
++              if ((pagenr >= addr) && (pagenr < end))
++                      return 1;
++      }
++      return 0;
 +}
++#endif
 +
- static void restore_cpu_virqs(unsigned int cpu)
- {
-       struct evtchn_bind_virq bind_virq;
---- a/drivers/xen/core/hypervisor_sysfs.c
-+++ b/drivers/xen/core/hypervisor_sysfs.c
-@@ -50,7 +50,7 @@ static int __init hypervisor_subsys_init
-       if (!is_running_on_xen())
-               return -ENODEV;
--      hypervisor_subsys.kobj.ktype = &hyp_sysfs_kobj_type;
-+      hypervisor_kobj->ktype = &hyp_sysfs_kobj_type;
-       return 0;
- }
---- a/drivers/xen/core/Makefile
-+++ b/drivers/xen/core/Makefile
-@@ -10,5 +10,6 @@ obj-$(CONFIG_SYS_HYPERVISOR) += hypervis
- obj-$(CONFIG_HOTPLUG_CPU)     += cpu_hotplug.o
- obj-$(CONFIG_XEN_SYSFS)               += xen_sysfs.o
- obj-$(CONFIG_XEN_SMPBOOT)     += smpboot.o
-+obj-$(CONFIG_X86_SMP)         += spinlock.o
- obj-$(CONFIG_KEXEC)           += machine_kexec.o
- obj-$(CONFIG_XEN_XENCOMM)     += xencomm.o
---- a/drivers/xen/core/smpboot.c
-+++ b/drivers/xen/core/smpboot.c
-@@ -139,6 +139,10 @@ static int __cpuinit xen_smp_intr_init(u
-               goto fail;
-       per_cpu(callfunc_irq, cpu) = rc;
-+      rc = xen_spinlock_init(cpu);
-+      if (rc < 0)
-+              goto fail;
++/*
++ * Fix up the linear direct mapping of the kernel to avoid cache attribute
++ * conflicts.
++ */
++static int ioremap_change_attr(unsigned long vaddr, unsigned long size,
++                             enum ioremap_mode mode)
++{
++      unsigned long nrpages = size >> PAGE_SHIFT;
++      int err;
++
++      switch (mode) {
++      case IOR_MODE_UNCACHED:
++      default:
++              err = set_memory_uc(vaddr, nrpages);
++              break;
++      case IOR_MODE_CACHED:
++              err = set_memory_wb(vaddr, nrpages);
++              break;
++      }
++
++      return err;
++}
 +
-       if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0))
-               goto fail;
-@@ -149,6 +153,7 @@ static int __cpuinit xen_smp_intr_init(u
-               unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
-       if (per_cpu(callfunc_irq, cpu) >= 0)
-               unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
-+      xen_spinlock_cleanup(cpu);
-       return rc;
- }
-@@ -160,6 +165,7 @@ static void xen_smp_intr_exit(unsigned i
-       unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
-       unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
-+      xen_spinlock_cleanup(cpu);
- }
- #endif
-@@ -212,36 +218,25 @@ static void __cpuinit cpu_initialize_con
-       smp_trap_init(ctxt.trap_ctxt);
-       ctxt.ldt_ents = 0;
--      ctxt.gdt_ents = GDT_SIZE / 8;
--
--#ifdef __i386__
-       ctxt.gdt_frames[0] = virt_to_mfn(get_cpu_gdt_table(cpu));
-+      ctxt.gdt_ents = GDT_SIZE / 8;
-       ctxt.user_regs.cs = __KERNEL_CS;
--      ctxt.user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
-+      ctxt.user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
-       ctxt.kernel_ss = __KERNEL_DS;
--      ctxt.kernel_sp = idle->thread.esp0;
-+      ctxt.kernel_sp = idle->thread.sp0;
--      ctxt.event_callback_cs     = __KERNEL_CS;
-       ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
--      ctxt.failsafe_callback_cs  = __KERNEL_CS;
-       ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
-+#ifdef __i386__
-+      ctxt.event_callback_cs     = __KERNEL_CS;
-+      ctxt.failsafe_callback_cs  = __KERNEL_CS;
-       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
-       ctxt.user_regs.fs = __KERNEL_PERCPU;
- #else /* __x86_64__ */
--      ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[cpu].address);
--
--      ctxt.user_regs.cs = __KERNEL_CS;
--      ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
--
--      ctxt.kernel_ss = __KERNEL_DS;
--      ctxt.kernel_sp = idle->thread.rsp0;
--
--      ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
--      ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
-       ctxt.syscall_callback_eip  = (unsigned long)system_call;
-       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
---- /dev/null
-+++ b/drivers/xen/core/spinlock.c
-@@ -0,0 +1,161 @@
 +/*
-+ *    Xen spinlock functions
++ * Remap an arbitrary physical address space into the kernel virtual
++ * address space. Needed when the kernel wants to access high addresses
++ * directly.
 + *
-+ *    See arch/x86/xen/smp.c for copyright and credits for derived
-+ *    portions of this file.
++ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
++ * have to convert them into an offset in a page-aligned mapping, but the
++ * caller shouldn't need to know that small detail.
 + */
++static void __iomem *__ioremap(resource_size_t phys_addr, unsigned long size,
++                             enum ioremap_mode mode)
++{
++      unsigned long mfn, offset, last_addr, vaddr;
++      struct vm_struct *area;
++      pgprot_t prot;
++      domid_t domid = DOMID_IO;
 +
-+#include <linux/init.h>
-+#include <linux/irq.h>
-+#include <linux/kernel.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/module.h>
-+#include <xen/evtchn.h>
++      /* Don't allow wraparound or zero size */
++      last_addr = phys_addr + size - 1;
++      if (!size || last_addr < phys_addr)
++              return NULL;
 +
-+extern irqreturn_t smp_reschedule_interrupt(int, void *);
++      /*
++       * Don't remap the low PCI/ISA area, it's always mapped..
++       */
++      if (is_initial_xendomain() && last_addr < ISA_END_ADDRESS)
++              return (__force void __iomem *)isa_bus_to_virt((unsigned long)phys_addr);
 +
-+static DEFINE_PER_CPU(int, spinlock_irq) = -1;
-+static char spinlock_name[NR_CPUS][15];
++      /*
++       * Don't allow anybody to remap normal RAM that we're using..
++       */
++      for (mfn = PFN_DOWN(phys_addr); mfn < PFN_UP(last_addr); mfn++) {
++              unsigned long pfn = mfn_to_local_pfn(mfn);
++
++              if (pfn >= max_pfn)
++                      continue;
++
++              domid = DOMID_SELF;
++
++              if (pfn >= max_pfn_mapped) /* bogus */
++                      continue;
 +
-+struct spinning {
-+      raw_spinlock_t *lock;
-+      unsigned int ticket;
-+      struct spinning *prev;
-+};
-+static DEFINE_PER_CPU(struct spinning *, spinning);
-+/*
-+ * Protect removal of objects: Addition can be done lockless, and even
-+ * removal itself doesn't need protection - what needs to be prevented is
-+ * removed objects going out of scope (as they're allocated on the stack.
-+ */
-+static DEFINE_PER_CPU(raw_rwlock_t, spinning_rm_lock) = __RAW_RW_LOCK_UNLOCKED;
++              if (pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
++                      return NULL;
++      }
 +
-+int __cpuinit xen_spinlock_init(unsigned int cpu)
-+{
-+      int rc;
++      switch (mode) {
++      case IOR_MODE_UNCACHED:
++      default:
++              /*
++               * FIXME: we will use UC MINUS for now, as video fb drivers
++               * depend on it. Upcoming ioremap_wc() will fix this behavior.
++               */
++              prot = PAGE_KERNEL_UC_MINUS;
++              break;
++      case IOR_MODE_CACHED:
++              prot = PAGE_KERNEL;
++              break;
++      }
 +
-+      sprintf(spinlock_name[cpu], "spinlock%u", cpu);
-+      rc = bind_ipi_to_irqhandler(SPIN_UNLOCK_VECTOR,
-+                                  cpu,
-+                                  smp_reschedule_interrupt,
-+                                  IRQF_DISABLED|IRQF_NOBALANCING,
-+                                  spinlock_name[cpu],
-+                                  NULL);
-+      if (rc < 0)
-+              return rc;
++      /*
++       * Mappings have to be page-aligned
++       */
++      offset = phys_addr & ~PAGE_MASK;
++      phys_addr &= PAGE_MASK;
++      size = PAGE_ALIGN(last_addr+1) - phys_addr;
 +
-+      disable_irq(rc); /* make sure it's never delivered */
-+      per_cpu(spinlock_irq, cpu) = rc;
++      /*
++       * Ok, go for it..
++       */
++      area = get_vm_area(size, VM_IOREMAP | (mode << 20));
++      if (!area)
++              return NULL;
++      area->phys_addr = phys_addr;
++      vaddr = (unsigned long) area->addr;
++      if (__direct_remap_pfn_range(&init_mm, vaddr, PFN_DOWN(phys_addr),
++                                   size, prot, domid)) {
++              free_vm_area(area);
++              return NULL;
++      }
 +
-+      return 0;
++      if (ioremap_change_attr(vaddr, size, mode) < 0) {
++              iounmap((void __iomem *) vaddr);
++              return NULL;
++      }
++
++      return (void __iomem *) (vaddr + offset);
 +}
 +
-+void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
++/**
++ * ioremap_nocache     -   map bus memory into CPU space
++ * @offset:    bus address of the memory
++ * @size:      size of the resource to map
++ *
++ * ioremap_nocache performs a platform specific sequence of operations to
++ * make bus memory CPU accessible via the readb/readw/readl/writeb/
++ * writew/writel functions and the other mmio helpers. The returned
++ * address is not guaranteed to be usable directly as a virtual
++ * address.
++ *
++ * This version of ioremap ensures that the memory is marked uncachable
++ * on the CPU as well as honouring existing caching rules from things like
++ * the PCI bus. Note that there are other caches and buffers on many
++ * busses. In particular driver authors should read up on PCI writes
++ *
++ * It's useful if some control registers are in such an area and
++ * write combining or read caching is not desirable:
++ *
++ * Must be freed with iounmap.
++ */
++void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
 +{
-+      if (per_cpu(spinlock_irq, cpu) >= 0)
-+              unbind_from_irqhandler(per_cpu(spinlock_irq, cpu), NULL);
-+      per_cpu(spinlock_irq, cpu) = -1;
++      return __ioremap(phys_addr, size, IOR_MODE_UNCACHED);
 +}
++EXPORT_SYMBOL(ioremap_nocache);
 +
-+int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
++void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
 +{
-+      int rc = 0, irq = __get_cpu_var(spinlock_irq);
-+      raw_rwlock_t *rm_lock;
-+      unsigned long flags;
-+      struct spinning spinning;
++      return __ioremap(phys_addr, size, IOR_MODE_CACHED);
++}
++EXPORT_SYMBOL(ioremap_cache);
 +
-+      /* If kicker interrupt not initialized yet, just spin. */
-+      if (unlikely(irq < 0))
-+              return 0;
++/**
++ * iounmap - Free a IO remapping
++ * @addr: virtual address from ioremap_*
++ *
++ * Caller must ensure there is only one unmapping for the same pointer.
++ */
++void iounmap(volatile void __iomem *addr)
++{
++      struct vm_struct *p, *o;
 +
-+      token >>= TICKET_SHIFT;
++      if ((void __force *)addr <= high_memory)
++              return;
 +
-+      /* announce we're spinning */
-+      spinning.ticket = token;
-+      spinning.lock = lock;
-+      spinning.prev = __get_cpu_var(spinning);
-+      smp_wmb();
-+      __get_cpu_var(spinning) = &spinning;
++      /*
++       * __ioremap special-cases the PCI/ISA range by not instantiating a
++       * vm_area and by simply returning an address into the kernel mapping
++       * of ISA space.   So handle that here.
++       */
++      if ((unsigned long)addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
++              return;
 +
-+      /* clear pending */
-+      xen_clear_irq_pending(irq);
++      addr = (volatile void __iomem *)
++              (PAGE_MASK & (unsigned long __force)addr);
 +
-+      do {
-+              /* Check again to make sure it didn't become free while
-+               * we weren't looking. */
-+              if ((lock->slock & ((1U << TICKET_SHIFT) - 1)) == token) {
-+                      /* If we interrupted another spinlock while it was
-+                       * blocking, make sure it doesn't block (again)
-+                       * without rechecking the lock. */
-+                      if (spinning.prev)
-+                              xen_set_irq_pending(irq);
-+                      rc = 1;
++      /* Use the vm area unlocked, assuming the caller
++         ensures there isn't another iounmap for the same address
++         in parallel. Reuse of the virtual address is prevented by
++         leaving it in the global lists until we're done with it.
++         cpa takes care of the direct mappings. */
++      read_lock(&vmlist_lock);
++      for (p = vmlist; p; p = p->next) {
++              if (p->addr == addr)
 +                      break;
-+              }
++      }
++      read_unlock(&vmlist_lock);
 +
-+              /* block until irq becomes pending */
-+              xen_poll_irq(irq);
-+      } while (!xen_test_irq_pending(irq));
++      if (!p) {
++              printk(KERN_ERR "iounmap: bad address %p\n", addr);
++              dump_stack();
++              return;
++      }
 +
-+      /* Leave the irq pending so that any interrupted blocker will
-+       * re-check. */
-+      kstat_this_cpu.irqs[irq] += !rc;
++      if ((p->flags >> 20) != IOR_MODE_CACHED) {
++              unsigned long n = get_vm_area_size(p) >> PAGE_SHIFT;
++              unsigned long mfn = p->phys_addr;
++              unsigned long va = (unsigned long)addr;
 +
-+      /* announce we're done */
-+      __get_cpu_var(spinning) = spinning.prev;
-+      rm_lock = &__get_cpu_var(spinning_rm_lock);
-+      raw_local_irq_save(flags);
-+      __raw_write_lock(rm_lock);
-+      __raw_write_unlock(rm_lock);
-+      raw_local_irq_restore(flags);
++              for (; n > 0; n--, mfn++, va += PAGE_SIZE)
++                      if (mfn_to_local_pfn(mfn) < max_pfn)
++                              set_memory_wb(va, 1);
++      }
 +
-+      return rc;
++      /* Finally remove it */
++      o = remove_vm_area((void *)addr);
++      BUG_ON(p != o || o == NULL);
++      kfree(p);
 +}
-+EXPORT_SYMBOL(xen_spin_wait);
++EXPORT_SYMBOL(iounmap);
 +
-+unsigned int xen_spin_adjust(raw_spinlock_t *lock, unsigned int token)
++int __initdata early_ioremap_debug;
++
++static int __init early_ioremap_debug_setup(char *str)
 +{
-+      return token;//todo
++      early_ioremap_debug = 1;
++
++      return 0;
 +}
-+EXPORT_SYMBOL(xen_spin_adjust);
++early_param("early_ioremap_debug", early_ioremap_debug_setup);
 +
-+int xen_spin_wait_flags(raw_spinlock_t *lock, unsigned int *token,
-+                        unsigned int flags)
++static __initdata int after_paging_init;
++static __initdata pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)]
++                              __attribute__((aligned(PAGE_SIZE)));
++
++#ifdef CONFIG_X86_32
++static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
 +{
-+      return xen_spin_wait(lock, *token);//todo
++      /* Don't assume we're using swapper_pg_dir at this point */
++      pgd_t *base = __va(read_cr3());
++      pgd_t *pgd = &base[pgd_index(addr)];
++      pud_t *pud = pud_offset(pgd, addr);
++      pmd_t *pmd = pmd_offset(pud, addr);
++
++      return pmd;
 +}
-+EXPORT_SYMBOL(xen_spin_wait_flags);
++#else
++#define early_ioremap_pmd early_get_pmd
++#define make_lowmem_page_readonly early_make_page_readonly
++#define make_lowmem_page_writable make_page_writable
++#endif
 +
-+void xen_spin_kick(raw_spinlock_t *lock, unsigned int token)
++static inline pte_t * __init early_ioremap_pte(unsigned long addr)
 +{
-+      unsigned int cpu;
++      return &bm_pte[pte_index(addr)];
++}
 +
-+      token &= (1U << TICKET_SHIFT) - 1;
-+      for_each_online_cpu(cpu) {
-+              raw_rwlock_t *rm_lock;
-+              unsigned long flags;
-+              struct spinning *spinning;
++void __init early_ioremap_init(void)
++{
++      pmd_t *pmd;
++
++      if (early_ioremap_debug)
++              printk(KERN_INFO "early_ioremap_init()\n");
++
++      pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
++      memset(bm_pte, 0, sizeof(bm_pte));
++      make_lowmem_page_readonly(bm_pte, XENFEAT_writable_page_tables);
++      pmd_populate_kernel(&init_mm, pmd, bm_pte);
++
++      /*
++       * The boot-ioremap range spans multiple pmds, for which
++       * we are not prepared:
++       */
++      if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
++              WARN_ON(1);
++              printk(KERN_WARNING "pmd %p != %p\n",
++                     pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
++              printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
++                      fix_to_virt(FIX_BTMAP_BEGIN));
++              printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END):   %08lx\n",
++                      fix_to_virt(FIX_BTMAP_END));
 +
-+              if (cpu == raw_smp_processor_id())
-+                      continue;
++              printk(KERN_WARNING "FIX_BTMAP_END:       %d\n", FIX_BTMAP_END);
++              printk(KERN_WARNING "FIX_BTMAP_BEGIN:     %d\n",
++                     FIX_BTMAP_BEGIN);
++      }
++}
 +
-+              rm_lock = &per_cpu(spinning_rm_lock, cpu);
-+              raw_local_irq_save(flags);
-+              __raw_read_lock(rm_lock);
++#ifdef CONFIG_X86_32
++void __init early_ioremap_clear(void)
++{
++      pmd_t *pmd;
 +
-+              spinning = per_cpu(spinning, cpu);
-+              smp_rmb();
-+              if (spinning
-+                  && (spinning->lock != lock || spinning->ticket != token))
-+                      spinning = NULL;
++      if (early_ioremap_debug)
++              printk(KERN_INFO "early_ioremap_clear()\n");
 +
-+              __raw_read_unlock(rm_lock);
-+              raw_local_irq_restore(flags);
++      pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
++      pmd_clear(pmd);
++      make_lowmem_page_writable(bm_pte, XENFEAT_writable_page_tables);
++      /* paravirt_release_pt(__pa(bm_pte) >> PAGE_SHIFT); */
++      __flush_tlb_all();
++}
 +
-+              if (unlikely(spinning)) {
-+                      notify_remote_via_irq(per_cpu(spinlock_irq, cpu));
-+                      return;
++void __init early_ioremap_reset(void)
++{
++      enum fixed_addresses idx;
++      unsigned long addr, phys;
++      pte_t *pte;
++
++      after_paging_init = 1;
++      for (idx = FIX_BTMAP_BEGIN; idx >= FIX_BTMAP_END; idx--) {
++              addr = fix_to_virt(idx);
++              pte = early_ioremap_pte(addr);
++              if (pte_present(*pte)) {
++                      phys = __pte_val(*pte) & PAGE_MASK;
++                      set_fixmap(idx, phys);
 +              }
 +      }
 +}
-+EXPORT_SYMBOL(xen_spin_kick);
---- a/drivers/xen/core/xen_sysfs.c
-+++ b/drivers/xen/core/xen_sysfs.c
-@@ -29,12 +29,12 @@ HYPERVISOR_ATTR_RO(type);
- static int __init xen_sysfs_type_init(void)
- {
--      return sysfs_create_file(&hypervisor_subsys.kobj, &type_attr.attr);
-+      return sysfs_create_file(hypervisor_kobj, &type_attr.attr);
- }
- static void xen_sysfs_type_destroy(void)
- {
--      sysfs_remove_file(&hypervisor_subsys.kobj, &type_attr.attr);
-+      sysfs_remove_file(hypervisor_kobj, &type_attr.attr);
- }
- /* xen version attributes */
-@@ -90,13 +90,12 @@ static struct attribute_group version_gr
- static int __init xen_sysfs_version_init(void)
- {
--      return sysfs_create_group(&hypervisor_subsys.kobj,
--                                &version_group);
-+      return sysfs_create_group(hypervisor_kobj, &version_group);
- }
- static void xen_sysfs_version_destroy(void)
- {
--      sysfs_remove_group(&hypervisor_subsys.kobj, &version_group);
-+      sysfs_remove_group(hypervisor_kobj, &version_group);
- }
- /* UUID */
-@@ -126,12 +125,12 @@ HYPERVISOR_ATTR_RO(uuid);
- static int __init xen_sysfs_uuid_init(void)
- {
--      return sysfs_create_file(&hypervisor_subsys.kobj, &uuid_attr.attr);
-+      return sysfs_create_file(hypervisor_kobj, &uuid_attr.attr);
- }
- static void xen_sysfs_uuid_destroy(void)
- {
--      sysfs_remove_file(&hypervisor_subsys.kobj, &uuid_attr.attr);
-+      sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr);
- }
- /* xen compilation attributes */
-@@ -204,14 +203,12 @@ static struct attribute_group xen_compil
- int __init static xen_compilation_init(void)
- {
--      return sysfs_create_group(&hypervisor_subsys.kobj,
--                                &xen_compilation_group);
-+      return sysfs_create_group(hypervisor_kobj, &xen_compilation_group);
- }
- static void xen_compilation_destroy(void)
- {
--      sysfs_remove_group(&hypervisor_subsys.kobj,
--                         &xen_compilation_group);
-+      sysfs_remove_group(hypervisor_kobj, &xen_compilation_group);
- }
- /* xen properties info */
-@@ -325,14 +322,12 @@ static struct attribute_group xen_proper
- static int __init xen_properties_init(void)
- {
--      return sysfs_create_group(&hypervisor_subsys.kobj,
--                                &xen_properties_group);
-+      return sysfs_create_group(hypervisor_kobj, &xen_properties_group);
- }
- static void xen_properties_destroy(void)
- {
--      sysfs_remove_group(&hypervisor_subsys.kobj,
--                         &xen_properties_group);
-+      sysfs_remove_group(hypervisor_kobj, &xen_properties_group);
- }
- #ifdef CONFIG_KEXEC
-@@ -350,13 +345,12 @@ HYPERVISOR_ATTR_RO(vmcoreinfo);
- static int __init xen_sysfs_vmcoreinfo_init(void)
- {
--      return sysfs_create_file(&hypervisor_subsys.kobj,
--                               &vmcoreinfo_attr.attr);
-+      return sysfs_create_file(hypervisor_kobj, &vmcoreinfo_attr.attr);
- }
- static void xen_sysfs_vmcoreinfo_destroy(void)
- {
--      sysfs_remove_file(&hypervisor_subsys.kobj, &vmcoreinfo_attr.attr);
-+      sysfs_remove_file(hypervisor_kobj, &vmcoreinfo_attr.attr);
- }
- #endif
---- a/drivers/xen/gntdev/gntdev.c
-+++ b/drivers/xen/gntdev/gntdev.c
-@@ -782,7 +782,7 @@ static pte_t gntdev_clear_pte(struct vm_
-                                      op.status);
-               } else {
-                       /* USING SHADOW PAGE TABLES. */
--                      copy = ptep_get_and_clear_full(vma->vm_mm, addr, ptep, is_fullmm);
-+                      copy = xen_ptep_get_and_clear_full(vma, addr, ptep, is_fullmm);
-               }
-               /* Finally, we unmap the grant from kernel space. */
-@@ -810,7 +810,7 @@ static pte_t gntdev_clear_pte(struct vm_
-                                   >> PAGE_SHIFT, INVALID_P2M_ENTRY);
-       } else {
--              copy = ptep_get_and_clear_full(vma->vm_mm, addr, ptep, is_fullmm);
-+              copy = xen_ptep_get_and_clear_full(vma, addr, ptep, is_fullmm);
-       }
-       return copy;
---- a/drivers/xen/scsifront/scsifront.c
-+++ b/drivers/xen/scsifront/scsifront.c
-@@ -260,19 +260,19 @@ static int map_data_for_request(struct v
-               return -ENOMEM;
-       }
--      if (sc->use_sg) {
-+      if (scsi_bufflen(sc)) {
-               /* quoted scsi_lib.c/scsi_req_map_sg . */
--              struct scatterlist *sg, *sgl = (struct scatterlist *)sc->request_buffer;
--              unsigned int data_len = sc->request_bufflen;
-+              struct scatterlist *sg, *sgl = scsi_sglist(sc);
-+              unsigned int data_len = scsi_bufflen(sc);
--              nr_pages = (sc->request_bufflen + sgl->offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+              nr_pages = (data_len + sgl->offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-               if (nr_pages > VSCSIIF_SG_TABLESIZE) {
-                       printk(KERN_ERR "scsifront: Unable to map request_buffer for command!\n");
-                       ref_cnt = (-E2BIG);
-                       goto big_to_sg;
-               }
--              for_each_sg (sgl, sg, sc->use_sg, i) {
-+              for_each_sg (sgl, sg, scsi_sg_count(sc), i) {
-                       page = sg_page(sg);
-                       off = sg->offset;
-                       len = sg->length;
-@@ -306,45 +306,6 @@ static int map_data_for_request(struct v
-                               ref_cnt++;
-                       }
-               }
--      } else if (sc->request_bufflen) {
--              unsigned long end   = ((unsigned long)sc->request_buffer
--                                      + sc->request_bufflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
--              unsigned long start = (unsigned long)sc->request_buffer >> PAGE_SHIFT;
--
--              page = virt_to_page(sc->request_buffer);
--              nr_pages = end - start;
--              len = sc->request_bufflen;
--
--              if (nr_pages > VSCSIIF_SG_TABLESIZE) {
--                      ref_cnt = (-E2BIG);
--                      goto big_to_sg;
--              }
--
--              buffer_pfn = page_to_phys(page) >> PAGE_SHIFT;
--
--              off = offset_in_page((unsigned long)sc->request_buffer);
--              for (i = 0; i < nr_pages; i++) {
--                      bytes = PAGE_SIZE - off;
--
--                      if (bytes > len)
--                              bytes = len;
--
--                      ref = gnttab_claim_grant_reference(&gref_head);
--                      BUG_ON(ref == -ENOSPC);
--
--                      gnttab_grant_foreign_access_ref(ref, info->dev->otherend_id,
--                              buffer_pfn, write);
--
--                      info->shadow[id].gref[i] = ref;
--                      ring_req->seg[i].gref     = ref;
--                      ring_req->seg[i].offset   = (uint16_t)off;
--                      ring_req->seg[i].length   = (uint16_t)bytes;
--
--                      buffer_pfn++;
--                      len -= bytes;
--                      off = 0;
--                      ref_cnt++;
--              }
-       }
- big_to_sg:
---- a/drivers/xen/xenoprof/xenoprofile.c
-+++ b/drivers/xen/xenoprof/xenoprofile.c
-@@ -79,7 +79,7 @@ static int xenoprof_resume(struct sys_de
- static struct sysdev_class oprofile_sysclass = {
--      set_kset_name("oprofile"),
-+      .name           = "oprofile",
-       .resume         = xenoprof_resume,
-       .suspend        = xenoprof_suspend
- };
---- a/include/asm-x86/mach-xen/asm/agp.h
-+++ b/include/asm-x86/mach-xen/asm/agp.h
-@@ -13,18 +13,13 @@
-  * page. This avoids data corruption on some CPUs.
-  */
++#endif /* CONFIG_X86_32 */
++
++static void __init __early_set_fixmap(enum fixed_addresses idx,
++                                 unsigned long phys, pgprot_t flags)
++{
++      unsigned long addr = __fix_to_virt(idx);
++      pte_t *pte;
++
++      if (idx >= __end_of_fixed_addresses) {
++              BUG();
++              return;
++      }
++      pte = early_ioremap_pte(addr);
++      if (pgprot_val(flags))
++              set_pte(pte, pfn_pte_ma(phys >> PAGE_SHIFT, flags));
++      else
++              pte_clear(NULL, addr, pte);
++      __flush_tlb_one(addr);
++}
++
++static inline void __init early_set_fixmap(enum fixed_addresses idx,
++                                      unsigned long phys)
++{
++      if (after_paging_init)
++              set_fixmap(idx, phys);
++      else
++              __early_set_fixmap(idx, phys, PAGE_KERNEL);
++}
++
++static inline void __init early_clear_fixmap(enum fixed_addresses idx)
++{
++      if (after_paging_init)
++              clear_fixmap(idx);
++      else
++              __early_set_fixmap(idx, 0, __pgprot(0));
++}
++
++
++int __initdata early_ioremap_nested;
++
++static int __init check_early_ioremap_leak(void)
++{
++      if (!early_ioremap_nested)
++              return 0;
++
++      printk(KERN_WARNING
++             "Debug warning: early ioremap leak of %d areas detected.\n",
++             early_ioremap_nested);
++      printk(KERN_WARNING
++             "please boot with early_ioremap_debug and report the dmesg.\n");
++      WARN_ON(1);
++
++      return 1;
++}
++late_initcall(check_early_ioremap_leak);
++
++void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
++{
++      unsigned long offset, last_addr;
++      unsigned int nrpages, nesting;
++      enum fixed_addresses idx0, idx;
++
++      WARN_ON(system_state != SYSTEM_BOOTING);
++
++      nesting = early_ioremap_nested;
++      if (early_ioremap_debug) {
++              printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
++                     phys_addr, size, nesting);
++              dump_stack();
++      }
++
++      /* Don't allow wraparound or zero size */
++      last_addr = phys_addr + size - 1;
++      if (!size || last_addr < phys_addr) {
++              WARN_ON(1);
++              return NULL;
++      }
++
++      if (nesting >= FIX_BTMAPS_NESTING) {
++              WARN_ON(1);
++              return NULL;
++      }
++      early_ioremap_nested++;
++      /*
++       * Mappings have to be page-aligned
++       */
++      offset = phys_addr & ~PAGE_MASK;
++      phys_addr &= PAGE_MASK;
++      size = PAGE_ALIGN(last_addr) - phys_addr;
++
++      /*
++       * Mappings have to fit in the FIX_BTMAP area.
++       */
++      nrpages = size >> PAGE_SHIFT;
++      if (nrpages > NR_FIX_BTMAPS) {
++              WARN_ON(1);
++              return NULL;
++      }
++
++      /*
++       * Ok, go for it..
++       */
++      idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting;
++      idx = idx0;
++      while (nrpages > 0) {
++              early_set_fixmap(idx, phys_addr);
++              phys_addr += PAGE_SIZE;
++              --idx;
++              --nrpages;
++      }
++      if (early_ioremap_debug)
++              printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
++
++      return (void *) (offset + fix_to_virt(idx0));
++}
++
++void __init early_iounmap(void *addr, unsigned long size)
++{
++      unsigned long virt_addr;
++      unsigned long offset;
++      unsigned int nrpages;
++      enum fixed_addresses idx;
++      unsigned int nesting;
++
++      nesting = --early_ioremap_nested;
++      WARN_ON(nesting < 0);
++
++      if (early_ioremap_debug) {
++              printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr,
++                     size, nesting);
++              dump_stack();
++      }
++
++      virt_addr = (unsigned long)addr;
++      if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN)) {
++              WARN_ON(1);
++              return;
++      }
++      offset = virt_addr & ~PAGE_MASK;
++      nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
++
++      idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting;
++      while (nrpages > 0) {
++              early_clear_fixmap(idx);
++              --idx;
++              --nrpages;
++      }
++}
++
++void __this_fixmap_does_not_exist(void)
++{
++      WARN_ON(1);
++}
+--- sle11-2009-05-14.orig/arch/x86/mm/ioremap_32-xen.c 2009-02-16 16:17:21.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,445 +0,0 @@
 -/*
-- * Caller's responsibility to call global_flush_tlb() for performance
-- * reasons
+- * arch/i386/mm/ioremap.c
+- *
+- * Re-map IO memory to kernel address space so that we can access it.
+- * This is needed for high PCI addresses that aren't mapped in the
+- * 640k-1MB IO memory area on PC's
+- *
+- * (C) Copyright 1995 1996 Linus Torvalds
 - */
- #define map_page_into_agp(page) ( \
-       xen_create_contiguous_region((unsigned long)page_address(page), 0, 32) \
--      ?: change_page_attr(page, 1, PAGE_KERNEL_NOCACHE))
-+      ?: set_pages_uc(page, 1))
- #define unmap_page_from_agp(page) ( \
-       xen_destroy_contiguous_region((unsigned long)page_address(page), 0), \
-       /* only a fallback: xen_destroy_contiguous_region uses PAGE_KERNEL */ \
--      change_page_attr(page, 1, PAGE_KERNEL))
--#define flush_agp_mappings() global_flush_tlb()
-+      set_pages_wb(page, 1))
- /*
-  * Could use CLFLUSH here if the cpu supports it. But then it would
---- a/include/asm-x86/mach-xen/asm/desc_32.h
-+++ /dev/null
-@@ -1,262 +0,0 @@
--#ifndef __ARCH_DESC_H
--#define __ARCH_DESC_H
--
--#include <asm/ldt.h>
--#include <asm/segment.h>
--
--#ifndef __ASSEMBLY__
--
--#include <linux/preempt.h>
--#include <linux/smp.h>
 -
--#include <asm/mmu.h>
+-#include <linux/vmalloc.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/module.h>
+-#include <linux/io.h>
+-#include <linux/sched.h>
+-#include <asm/fixmap.h>
+-#include <asm/cacheflush.h>
+-#include <asm/tlbflush.h>
+-#include <asm/pgtable.h>
+-#include <asm/pgalloc.h>
 -
--struct Xgt_desc_struct {
--      unsigned short size;
--      unsigned long address __attribute__((packed));
--      unsigned short pad;
--} __attribute__ ((packed));
+-#define ISA_START_ADDRESS     0x0
+-#define ISA_END_ADDRESS               0x100000
 -
--struct gdt_page
+-static int direct_remap_area_pte_fn(pte_t *pte, 
+-                                  struct page *pmd_page,
+-                                  unsigned long address, 
+-                                  void *data)
 -{
--      struct desc_struct gdt[GDT_ENTRIES];
--} __attribute__((aligned(PAGE_SIZE)));
--DECLARE_PER_CPU(struct gdt_page, gdt_page);
+-      mmu_update_t **v = (mmu_update_t **)data;
 -
--static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
--{
--      return per_cpu(gdt_page, cpu).gdt;
--}
+-      BUG_ON(!pte_none(*pte));
 -
--extern struct Xgt_desc_struct idt_descr;
--extern struct desc_struct idt_table[];
--extern void set_intr_gate(unsigned int irq, void * addr);
+-      (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
+-                   PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
+-      (*v)++;
 -
--static inline void pack_descriptor(__u32 *a, __u32 *b,
--      unsigned long base, unsigned long limit, unsigned char type, unsigned char flags)
--{
--      *a = ((base & 0xffff) << 16) | (limit & 0xffff);
--      *b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
--              (limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20);
+-      return 0;
 -}
 -
--static inline void pack_gate(__u32 *a, __u32 *b,
--      unsigned long base, unsigned short seg, unsigned char type, unsigned char flags)
+-static int __direct_remap_pfn_range(struct mm_struct *mm,
+-                                  unsigned long address, 
+-                                  unsigned long mfn,
+-                                  unsigned long size, 
+-                                  pgprot_t prot,
+-                                  domid_t  domid)
 -{
--      *a = (seg << 16) | (base & 0xffff);
--      *b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff);
--}
--
--#define DESCTYPE_LDT  0x82    /* present, system, DPL-0, LDT */
--#define DESCTYPE_TSS  0x89    /* present, system, DPL-0, 32-bit TSS */
--#define DESCTYPE_TASK 0x85    /* present, system, DPL-0, task gate */
--#define DESCTYPE_INT  0x8e    /* present, system, DPL-0, interrupt gate */
--#define DESCTYPE_TRAP 0x8f    /* present, system, DPL-0, trap gate */
--#define DESCTYPE_DPL3 0x60    /* DPL-3 */
--#define DESCTYPE_S    0x10    /* !system */
+-      int rc;
+-      unsigned long i, start_address;
+-      mmu_update_t *u, *v, *w;
 -
--#ifndef CONFIG_XEN
--#define load_TR_desc() native_load_tr_desc()
--#define load_gdt(dtr) native_load_gdt(dtr)
--#define load_idt(dtr) native_load_idt(dtr)
--#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr))
--#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt))
+-      u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+-      if (u == NULL)
+-              return -ENOMEM;
 -
--#define store_gdt(dtr) native_store_gdt(dtr)
--#define store_idt(dtr) native_store_idt(dtr)
--#define store_tr(tr) (tr = native_store_tr())
--#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt))
+-      start_address = address;
 -
--#define load_TLS(t, cpu) native_load_tls(t, cpu)
--#define set_ldt native_set_ldt
+-      flush_cache_all();
 -
--#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
--#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
--#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
+-      for (i = 0; i < size; i += PAGE_SIZE) {
+-              if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
+-                      /* Flush a full batch after filling in the PTE ptrs. */
+-                      rc = apply_to_page_range(mm, start_address, 
+-                                               address - start_address,
+-                                               direct_remap_area_pte_fn, &w);
+-                      if (rc)
+-                              goto out;
+-                      rc = -EFAULT;
+-                      if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
+-                              goto out;
+-                      v = w = u;
+-                      start_address = address;
+-              }
 -
--static inline void write_dt_entry(struct desc_struct *dt,
--                                int entry, u32 entry_low, u32 entry_high)
--{
--      dt[entry].a = entry_low;
--      dt[entry].b = entry_high;
--}
+-              /*
+-               * Fill in the machine address: PTE ptr is done later by
+-               * apply_to_page_range(). 
+-               */
+-              v->val = __pte_val(pfn_pte_ma(mfn, prot)) | _PAGE_IO;
 -
--static inline void native_set_ldt(const void *addr, unsigned int entries)
--{
--      if (likely(entries == 0))
--              __asm__ __volatile__("lldt %w0"::"q" (0));
--      else {
--              unsigned cpu = smp_processor_id();
--              __u32 a, b;
+-              mfn++;
+-              address += PAGE_SIZE; 
+-              v++;
+-      }
 -
--              pack_descriptor(&a, &b, (unsigned long)addr,
--                              entries * sizeof(struct desc_struct) - 1,
--                              DESCTYPE_LDT, 0);
--              write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b);
--              __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
+-      if (v != u) {
+-              /* Final batch. */
+-              rc = apply_to_page_range(mm, start_address,
+-                                       address - start_address,
+-                                       direct_remap_area_pte_fn, &w);
+-              if (rc)
+-                      goto out;
+-              rc = -EFAULT;
+-              if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
+-                      goto out;
 -      }
--}
 -
+-      rc = 0;
 -
--static inline void native_load_tr_desc(void)
--{
--      asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
--}
+- out:
+-      flush_tlb_all();
 -
--static inline void native_load_gdt(const struct Xgt_desc_struct *dtr)
--{
--      asm volatile("lgdt %0"::"m" (*dtr));
--}
+-      free_page((unsigned long)u);
 -
--static inline void native_load_idt(const struct Xgt_desc_struct *dtr)
--{
--      asm volatile("lidt %0"::"m" (*dtr));
+-      return rc;
 -}
 -
--static inline void native_store_gdt(struct Xgt_desc_struct *dtr)
+-int direct_remap_pfn_range(struct vm_area_struct *vma,
+-                         unsigned long address, 
+-                         unsigned long mfn,
+-                         unsigned long size, 
+-                         pgprot_t prot,
+-                         domid_t  domid)
 -{
--      asm ("sgdt %0":"=m" (*dtr));
--}
+-      if (xen_feature(XENFEAT_auto_translated_physmap))
+-              return remap_pfn_range(vma, address, mfn, size, prot);
 -
--static inline void native_store_idt(struct Xgt_desc_struct *dtr)
--{
--      asm ("sidt %0":"=m" (*dtr));
--}
+-      if (domid == DOMID_SELF)
+-              return -EINVAL;
 -
--static inline unsigned long native_store_tr(void)
--{
--      unsigned long tr;
--      asm ("str %0":"=r" (tr));
--      return tr;
--}
+-      vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
 -
--static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
--{
--      unsigned int i;
--      struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+-      vma->vm_mm->context.has_foreign_mappings = 1;
 -
--      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
--              gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
+-      return __direct_remap_pfn_range(
+-              vma->vm_mm, address, mfn, size, prot, domid);
 -}
--#else
--#define load_TLS(t, cpu) xen_load_tls(t, cpu)
--#define set_ldt xen_set_ldt
--
--extern int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b);
--extern int write_gdt_entry(void *gdt, int entry, __u32 entry_a, __u32 entry_b);
+-EXPORT_SYMBOL(direct_remap_pfn_range);
 -
--static inline void xen_load_tls(struct thread_struct *t, unsigned int cpu)
+-int direct_kernel_remap_pfn_range(unsigned long address, 
+-                                unsigned long mfn,
+-                                unsigned long size, 
+-                                pgprot_t prot,
+-                                domid_t  domid)
 -{
--      unsigned int i;
--      struct desc_struct *gdt = get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN;
--
--      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
--              if (HYPERVISOR_update_descriptor(virt_to_machine(&gdt[i]),
--                                               *(u64 *)&t->tls_array[i]))
--                      BUG();
+-      return __direct_remap_pfn_range(
+-              &init_mm, address, mfn, size, prot, domid);
 -}
--#endif
+-EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
 -
--#ifndef CONFIG_X86_NO_IDT
--static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
+-static int lookup_pte_fn(
+-      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 -{
--      __u32 a, b;
--      pack_gate(&a, &b, (unsigned long)addr, seg, type, 0);
--      write_idt_entry(idt_table, gate, a, b);
+-      uint64_t *ptep = (uint64_t *)data;
+-      if (ptep)
+-              *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
+-                       PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
+-      return 0;
 -}
--#endif
 -
--#ifndef CONFIG_X86_NO_TSS
--static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
+-int create_lookup_pte_addr(struct mm_struct *mm, 
+-                         unsigned long address,
+-                         uint64_t *ptep)
 -{
--      __u32 a, b;
--      pack_descriptor(&a, &b, (unsigned long)addr,
--                      offsetof(struct tss_struct, __cacheline_filler) - 1,
--                      DESCTYPE_TSS, 0);
--      write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b);
+-      return apply_to_page_range(mm, address, PAGE_SIZE,
+-                                 lookup_pte_fn, ptep);
 -}
--#endif
--
--
--#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
 -
--#define LDT_entry_a(info) \
--      ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
--
--#define LDT_entry_b(info) \
--      (((info)->base_addr & 0xff000000) | \
--      (((info)->base_addr & 0x00ff0000) >> 16) | \
--      ((info)->limit & 0xf0000) | \
--      (((info)->read_exec_only ^ 1) << 9) | \
--      ((info)->contents << 10) | \
--      (((info)->seg_not_present ^ 1) << 15) | \
--      ((info)->seg_32bit << 22) | \
--      ((info)->limit_in_pages << 23) | \
--      ((info)->useable << 20) | \
--      0x7000)
--
--#define LDT_empty(info) (\
--      (info)->base_addr       == 0    && \
--      (info)->limit           == 0    && \
--      (info)->contents        == 0    && \
--      (info)->read_exec_only  == 1    && \
--      (info)->seg_32bit       == 0    && \
--      (info)->limit_in_pages  == 0    && \
--      (info)->seg_not_present == 1    && \
--      (info)->useable         == 0    )
+-EXPORT_SYMBOL(create_lookup_pte_addr);
 -
--static inline void clear_LDT(void)
+-static int noop_fn(
+-      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 -{
--      set_ldt(NULL, 0);
+-      return 0;
 -}
 -
--/*
-- * load one particular LDT into the current CPU
-- */
--static inline void load_LDT_nolock(mm_context_t *pc)
+-int touch_pte_range(struct mm_struct *mm,
+-                  unsigned long address,
+-                  unsigned long size)
 -{
--      set_ldt(pc->ldt, pc->size);
--}
+-      return apply_to_page_range(mm, address, size, noop_fn, NULL);
+-} 
 -
--static inline void load_LDT(mm_context_t *pc)
--{
--      preempt_disable();
--      load_LDT_nolock(pc);
--      preempt_enable();
--}
+-EXPORT_SYMBOL(touch_pte_range);
 -
--static inline unsigned long get_desc_base(unsigned long *desc)
+-/*
+- * Does @address reside within a non-highmem page that is local to this virtual
+- * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
+- * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
+- * why this works.
+- */
+-static inline int is_local_lowmem(unsigned long address)
 -{
--      unsigned long base;
--      base = ((desc[0] >> 16)  & 0x0000ffff) |
--              ((desc[1] << 16) & 0x00ff0000) |
--              (desc[1] & 0xff000000);
--      return base;
+-      extern unsigned long max_low_pfn;
+-      return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
 -}
 -
--#else /* __ASSEMBLY__ */
--
 -/*
-- * GET_DESC_BASE reads the descriptor base of the specified segment.
-- *
-- * Args:
-- *    idx - descriptor index
-- *    gdt - GDT pointer
-- *    base - 32bit register to which the base will be written
-- *    lo_w - lo word of the "base" register
-- *    lo_b - lo byte of the "base" register
-- *    hi_b - hi byte of the low word of the "base" register
-- *
-- * Example:
-- *    GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
-- *    Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax.
+- * Generic mapping function (not visible outside):
 - */
--#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \
--      movb idx*8+4(gdt), lo_b; \
--      movb idx*8+7(gdt), hi_b; \
--      shll $16, base; \
--      movw idx*8+2(gdt), lo_w;
--
--#endif /* !__ASSEMBLY__ */
--
--#endif
---- a/include/asm-x86/mach-xen/asm/desc_64.h
-+++ /dev/null
-@@ -1,228 +0,0 @@
--/* Written 2000 by Andi Kleen */ 
--#ifndef __ARCH_DESC_H
--#define __ARCH_DESC_H
 -
--#include <linux/threads.h>
--#include <asm/ldt.h>
--
--#ifndef __ASSEMBLY__
+-/*
+- * Remap an arbitrary physical address space into the kernel virtual
+- * address space. Needed when the kernel wants to access high addresses
+- * directly.
+- *
+- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+- * have to convert them into an offset in a page-aligned mapping, but the
+- * caller shouldn't need to know that small detail.
+- */
+-void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+-{
+-      void __iomem * addr;
+-      struct vm_struct * area;
+-      unsigned long offset, last_addr;
+-      pgprot_t prot;
+-      domid_t domid = DOMID_IO;
 -
--#include <linux/string.h>
--#include <linux/smp.h>
--#include <asm/desc_defs.h>
+-      /* Don't allow wraparound or zero size */
+-      last_addr = phys_addr + size - 1;
+-      if (!size || last_addr < phys_addr)
+-              return NULL;
 -
--#include <asm/segment.h>
--#include <asm/mmu.h>
+-      /*
+-       * Don't remap the low PCI/ISA area, it's always mapped..
+-       */
+-      if (is_initial_xendomain() &&
+-          phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
+-              return (void __iomem *) isa_bus_to_virt(phys_addr);
 -
--extern struct desc_ptr idt_descr, cpu_gdt_descr[NR_CPUS];
+-      /*
+-       * Don't allow anybody to remap normal RAM that we're using..
+-       */
+-      if (is_local_lowmem(phys_addr)) {
+-              char *t_addr, *t_end;
+-              struct page *page;
 -
--extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
+-              t_addr = bus_to_virt(phys_addr);
+-              t_end = t_addr + (size - 1);
+-         
+-              for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+-                      if(!PageReserved(page))
+-                              return NULL;
 -
--#define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8))
--#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
+-              domid = DOMID_SELF;
+-      }
 -
--static inline void clear_LDT(void)
--{
--      int cpu = get_cpu();
+-      prot = __pgprot(_KERNPG_TABLE | flags);
 -
 -      /*
--       * NB. We load the default_ldt for lcall7/27 handling on demand, as
--       * it slows down context switching. Noone uses it anyway.
+-       * Mappings have to be page-aligned
 -       */
--      cpu = cpu;              /* XXX avoid compiler warning */
--      xen_set_ldt(NULL, 0);
--      put_cpu();
--}
--
--#ifndef CONFIG_X86_NO_TSS
--static inline unsigned long __store_tr(void)
--{
--       unsigned long tr;
+-      offset = phys_addr & ~PAGE_MASK;
+-      phys_addr &= PAGE_MASK;
+-      size = PAGE_ALIGN(last_addr+1) - phys_addr;
 -
--       asm volatile ("str %w0":"=r" (tr));
--       return tr;
+-      /*
+-       * Ok, go for it..
+-       */
+-      area = get_vm_area(size, VM_IOREMAP | (flags << 20));
+-      if (!area)
+-              return NULL;
+-      area->phys_addr = phys_addr;
+-      addr = (void __iomem *) area->addr;
+-      if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
+-                                   phys_addr>>PAGE_SHIFT,
+-                                   size, prot, domid)) {
+-              vunmap((void __force *) addr);
+-              return NULL;
+-      }
+-      return (void __iomem *) (offset + (char __iomem *)addr);
 -}
+-EXPORT_SYMBOL(__ioremap);
 -
--#define store_tr(tr) (tr) = __store_tr()
--#endif
--
--/*
-- * This is the ldt that every process will get unless we need
-- * something other than this.
+-/**
+- * ioremap_nocache     -   map bus memory into CPU space
+- * @offset:    bus address of the memory
+- * @size:      size of the resource to map
+- *
+- * ioremap_nocache performs a platform specific sequence of operations to
+- * make bus memory CPU accessible via the readb/readw/readl/writeb/
+- * writew/writel functions and the other mmio helpers. The returned
+- * address is not guaranteed to be usable directly as a virtual
+- * address. 
+- *
+- * This version of ioremap ensures that the memory is marked uncachable
+- * on the CPU as well as honouring existing caching rules from things like
+- * the PCI bus. Note that there are other caches and buffers on many 
+- * busses. In particular driver authors should read up on PCI writes
+- *
+- * It's useful if some control registers are in such an area and
+- * write combining or read caching is not desirable:
+- * 
+- * Must be freed with iounmap.
 - */
--extern struct desc_struct default_ldt[];
--#ifndef CONFIG_X86_NO_IDT
--extern struct gate_struct idt_table[]; 
--#endif
--extern struct desc_ptr cpu_gdt_descr[];
--
--/* the cpu gdt accessor */
--#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
 -
--#ifndef CONFIG_XEN
--static inline void load_gdt(const struct desc_ptr *ptr)
+-void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
 -{
--      asm volatile("lgdt %w0"::"m" (*ptr));
--}
+-      unsigned long last_addr;
+-      void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
+-      if (!p) 
+-              return p; 
 -
--static inline void store_gdt(struct desc_ptr *ptr)
--{
--       asm("sgdt %w0":"=m" (*ptr));
--}
--#endif
+-      /* Guaranteed to be > phys_addr, as per __ioremap() */
+-      last_addr = phys_addr + size - 1;
 -
--static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
--{
--      struct gate_struct s;   
--      s.offset_low = PTR_LOW(func); 
--      s.segment = __KERNEL_CS;
--      s.ist = ist; 
--      s.p = 1;
--      s.dpl = dpl; 
--      s.zero0 = 0;
--      s.zero1 = 0; 
--      s.type = type; 
--      s.offset_middle = PTR_MIDDLE(func); 
--      s.offset_high = PTR_HIGH(func); 
--      /* does not need to be atomic because it is only done once at setup time */ 
--      memcpy(adr, &s, 16); 
--} 
+-      if (is_local_lowmem(last_addr)) { 
+-              struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
+-              unsigned long npages;
 -
--#ifndef CONFIG_X86_NO_IDT
--static inline void set_intr_gate(int nr, void *func) 
--{ 
--      BUG_ON((unsigned)nr > 0xFF);
--      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); 
--} 
+-              phys_addr &= PAGE_MASK;
 -
--static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) 
--{ 
--      BUG_ON((unsigned)nr > 0xFF);
--      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); 
--} 
+-              /* This might overflow and become zero.. */
+-              last_addr = PAGE_ALIGN(last_addr);
 -
--static inline void set_system_gate(int nr, void *func) 
--{ 
--      BUG_ON((unsigned)nr > 0xFF);
--      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
--} 
+-              /* .. but that's ok, because modulo-2**n arithmetic will make
+-              * the page-aligned "last - first" come out right.
+-              */
+-              npages = (last_addr - phys_addr) >> PAGE_SHIFT;
 -
--static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
--{
--      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
--}
+-              if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) { 
+-                      iounmap(p); 
+-                      p = NULL;
+-              }
+-              global_flush_tlb();
+-      }
 -
--static inline void load_idt(const struct desc_ptr *ptr)
--{
--      asm volatile("lidt %w0"::"m" (*ptr));
+-      return p;                                       
 -}
+-EXPORT_SYMBOL(ioremap_nocache);
 -
--static inline void store_idt(struct desc_ptr *dtr)
+-/**
+- * iounmap - Free a IO remapping
+- * @addr: virtual address from ioremap_*
+- *
+- * Caller must ensure there is only one unmapping for the same pointer.
+- */
+-void iounmap(volatile void __iomem *addr)
 -{
--       asm("sidt %w0":"=m" (*dtr));
--}
--#endif
+-      struct vm_struct *p, *o;
 -
--static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
--                                       unsigned size) 
--{ 
--      struct ldttss_desc d;
--      memset(&d,0,sizeof(d)); 
--      d.limit0 = size & 0xFFFF;
--      d.base0 = PTR_LOW(tss); 
--      d.base1 = PTR_MIDDLE(tss) & 0xFF; 
--      d.type = type;
--      d.p = 1; 
--      d.limit1 = (size >> 16) & 0xF;
--      d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; 
--      d.base3 = PTR_HIGH(tss); 
--      memcpy(ptr, &d, 16); 
--}
+-      if ((void __force *)addr <= high_memory)
+-              return;
 -
--#ifndef CONFIG_X86_NO_TSS
--static inline void set_tss_desc(unsigned cpu, void *addr)
--{ 
 -      /*
--       * sizeof(unsigned long) coming from an extra "long" at the end
--       * of the iobitmap. See tss_struct definition in processor.h
--       *
--       * -1? seg base+limit should be pointing to the address of the
--       * last valid byte
+-       * __ioremap special-cases the PCI/ISA range by not instantiating a
+-       * vm_area and by simply returning an address into the kernel mapping
+-       * of ISA space.   So handle that here.
 -       */
--      set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], 
--              (unsigned long)addr, DESC_TSS,
--              IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1);
--} 
--#endif
+-      if ((unsigned long) addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
+-              return;
 -
--static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
--{ 
--      set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr,
--                            DESC_LDT, size * 8 - 1);
--}
+-      addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
+-
+-      /* Use the vm area unlocked, assuming the caller
+-         ensures there isn't another iounmap for the same address
+-         in parallel. Reuse of the virtual address is prevented by
+-         leaving it in the global lists until we're done with it.
+-         cpa takes care of the direct mappings. */
+-      read_lock(&vmlist_lock);
+-      for (p = vmlist; p; p = p->next) {
+-              if (p->addr == addr)
+-                      break;
+-      }
+-      read_unlock(&vmlist_lock);
 -
--#define LDT_entry_a(info) \
--      ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
--/* Don't allow setting of the lm bit. It is useless anyways because 
--   64bit system calls require __USER_CS. */ 
--#define LDT_entry_b(info) \
--      (((info)->base_addr & 0xff000000) | \
--      (((info)->base_addr & 0x00ff0000) >> 16) | \
--      ((info)->limit & 0xf0000) | \
--      (((info)->read_exec_only ^ 1) << 9) | \
--      ((info)->contents << 10) | \
--      (((info)->seg_not_present ^ 1) << 15) | \
--      ((info)->seg_32bit << 22) | \
--      ((info)->limit_in_pages << 23) | \
--      ((info)->useable << 20) | \
--      /* ((info)->lm << 21) | */ \
--      0x7000)
+-      if (!p) {
+-              printk("iounmap: bad address %p\n", addr);
+-              dump_stack();
+-              return;
+-      }
 -
--#define LDT_empty(info) (\
--      (info)->base_addr       == 0    && \
--      (info)->limit           == 0    && \
--      (info)->contents        == 0    && \
--      (info)->read_exec_only  == 1    && \
--      (info)->seg_32bit       == 0    && \
--      (info)->limit_in_pages  == 0    && \
--      (info)->seg_not_present == 1    && \
--      (info)->useable         == 0    && \
--      (info)->lm              == 0)
+-      /* Reset the direct mapping. Can block */
+-      if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) {
+-              change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
+-                               get_vm_area_size(p) >> PAGE_SHIFT,
+-                               PAGE_KERNEL);
+-              global_flush_tlb();
+-      } 
 -
--static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
+-      /* Finally remove it */
+-      o = remove_vm_area((void *)addr);
+-      BUG_ON(p != o || o == NULL);
+-      kfree(p); 
+-}
+-EXPORT_SYMBOL(iounmap);
+-
+-void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
 -{
--      unsigned int i;
--      u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
+-      unsigned long offset, last_addr;
+-      unsigned int nrpages;
+-      enum fixed_addresses idx;
 -
--      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
--              if (HYPERVISOR_update_descriptor(virt_to_machine(&gdt[i]),
--                                               t->tls_array[i]))
--                      BUG();
--} 
+-      /* Don't allow wraparound or zero size */
+-      last_addr = phys_addr + size - 1;
+-      if (!size || last_addr < phys_addr)
+-              return NULL;
 -
--/*
-- * load one particular LDT into the current CPU
-- */
--static inline void load_LDT_nolock (mm_context_t *pc, int cpu)
--{
--      void *segments = pc->ldt;
--      int count = pc->size;
+-      /*
+-       * Don't remap the low PCI/ISA area, it's always mapped..
+-       */
+-      if (is_initial_xendomain() &&
+-          phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
+-              return isa_bus_to_virt(phys_addr);
 -
--      if (likely(!count))
--              segments = NULL;
+-      /*
+-       * Mappings have to be page-aligned
+-       */
+-      offset = phys_addr & ~PAGE_MASK;
+-      phys_addr &= PAGE_MASK;
+-      size = PAGE_ALIGN(last_addr) - phys_addr;
 -
--      xen_set_ldt(segments, count);
--}
+-      /*
+-       * Mappings have to fit in the FIX_BTMAP area.
+-       */
+-      nrpages = size >> PAGE_SHIFT;
+-      if (nrpages > NR_FIX_BTMAPS)
+-              return NULL;
 -
--static inline void load_LDT(mm_context_t *pc)
--{
--      int cpu = get_cpu();
--      load_LDT_nolock(pc, cpu);
--      put_cpu();
+-      /*
+-       * Ok, go for it..
+-       */
+-      idx = FIX_BTMAP_BEGIN;
+-      while (nrpages > 0) {
+-              set_fixmap(idx, phys_addr);
+-              phys_addr += PAGE_SIZE;
+-              --idx;
+-              --nrpages;
+-      }
+-      return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
 -}
 -
--extern struct desc_ptr idt_descr;
+-void __init bt_iounmap(void *addr, unsigned long size)
+-{
+-      unsigned long virt_addr;
+-      unsigned long offset;
+-      unsigned int nrpages;
+-      enum fixed_addresses idx;
 -
--#endif /* !__ASSEMBLY__ */
+-      virt_addr = (unsigned long)addr;
+-      if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
+-              return;
+-      if (virt_addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
+-              return;
+-      offset = virt_addr & ~PAGE_MASK;
+-      nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
 -
--#endif
---- a/include/asm-x86/mach-xen/asm/desc.h
-+++ b/include/asm-x86/mach-xen/asm/desc.h
-@@ -1,5 +1,404 @@
-+#ifndef _ASM_DESC_H_
-+#define _ASM_DESC_H_
+-      idx = FIX_BTMAP_BEGIN;
+-      while (nrpages > 0) {
+-              clear_fixmap(idx);
+-              --idx;
+-              --nrpages;
+-      }
+-}
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/mm/pageattr-xen.c        2009-03-16 16:37:14.000000000 +0100
+@@ -0,0 +1,1413 @@
++/*
++ * Copyright 2002 Andi Kleen, SuSE Labs.
++ * Thanks to Ben LaHaise for precious feedback.
++ */
++#include <linux/highmem.h>
++#include <linux/bootmem.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/interrupt.h>
++
++#include <asm/e820.h>
++#include <asm/processor.h>
++#include <asm/tlbflush.h>
++#include <asm/sections.h>
++#include <asm/uaccess.h>
++#include <asm/pgalloc.h>
++#include <asm/proto.h>
++#include <asm/mmu_context.h>
++
++#ifndef CONFIG_X86_64
++#define TASK_SIZE64 TASK_SIZE
++#endif
++
++static void _pin_lock(struct mm_struct *mm, int lock) {
++      if (lock)
++              spin_lock(&mm->page_table_lock);
++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
++      /* While mm->page_table_lock protects us against insertions and
++       * removals of higher level page table pages, it doesn't protect
++       * against updates of pte-s. Such updates, however, require the
++       * pte pages to be in consistent state (unpinned+writable or
++       * pinned+readonly). The pinning and attribute changes, however
++       * cannot be done atomically, which is why such updates must be
++       * prevented from happening concurrently.
++       * Note that no pte lock can ever elsewhere be acquired nesting
++       * with an already acquired one in the same mm, or with the mm's
++       * page_table_lock already acquired, as that would break in the
++       * non-split case (where all these are actually resolving to the
++       * one page_table_lock). Thus acquiring all of them here is not
++       * going to result in dead locks, and the order of acquires
++       * doesn't matter.
++       */
++      {
++              pgd_t *pgd = mm->pgd;
++              unsigned g;
++
++              for (g = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
++                      pud_t *pud;
++                      unsigned u;
++
++                      if (pgd_none(*pgd))
++                              continue;
++                      pud = pud_offset(pgd, 0);
++                      for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
++                              pmd_t *pmd;
++                              unsigned m;
++
++                              if (pud_none(*pud))
++                                      continue;
++                              pmd = pmd_offset(pud, 0);
++                              for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
++                                      spinlock_t *ptl;
++
++                                      if (pmd_none(*pmd))
++                                              continue;
++                                      ptl = pte_lockptr(0, pmd);
++                                      if (lock)
++                                              spin_lock(ptl);
++                                      else
++                                              spin_unlock(ptl);
++                              }
++                      }
++              }
++      }
++#endif
++      if (!lock)
++              spin_unlock(&mm->page_table_lock);
++}
++#define pin_lock(mm) _pin_lock(mm, 1)
++#define pin_unlock(mm) _pin_lock(mm, 0)
++
++#define PIN_BATCH sizeof(void *)
++static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl);
++
++static inline unsigned int pgd_walk_set_prot(struct page *page, pgprot_t flags,
++                                           unsigned int cpu, unsigned int seq)
++{
++      unsigned long pfn = page_to_pfn(page);
++
++      if (PageHighMem(page)) {
++              if (pgprot_val(flags) & _PAGE_RW)
++                      ClearPagePinned(page);
++              else
++                      SetPagePinned(page);
++      } else {
++              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
++                                      (unsigned long)__va(pfn << PAGE_SHIFT),
++                                      pfn_pte(pfn, flags), 0);
++              if (unlikely(++seq == PIN_BATCH)) {
++                      if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
++                                                              PIN_BATCH, NULL)))
++                              BUG();
++                      seq = 0;
++              }
++      }
++
++      return seq;
++}
++
++static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
++{
++      pgd_t       *pgd = pgd_base;
++      pud_t       *pud;
++      pmd_t       *pmd;
++      int          g,u,m;
++      unsigned int cpu, seq;
++      multicall_entry_t *mcl;
++
++      if (xen_feature(XENFEAT_auto_translated_physmap))
++              return;
++
++      cpu = get_cpu();
++
++      /*
++       * Cannot iterate up to USER_PTRS_PER_PGD on x86-64 as these pagetables
++       * may not be the 'current' task's pagetables (e.g., current may be
++       * 32-bit, but the pagetables may be for a 64-bit task).
++       * Subtracting 1 from TASK_SIZE64 means the loop limit is correct
++       * regardless of whether TASK_SIZE64 is a multiple of PGDIR_SIZE.
++       */
++      for (g = 0, seq = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
++              if (pgd_none(*pgd))
++                      continue;
++              pud = pud_offset(pgd, 0);
++              if (PTRS_PER_PUD > 1) /* not folded */
++                      seq = pgd_walk_set_prot(virt_to_page(pud),flags,cpu,seq);
++              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
++                      if (pud_none(*pud))
++                              continue;
++                      pmd = pmd_offset(pud, 0);
++                      if (PTRS_PER_PMD > 1) /* not folded */
++                              seq = pgd_walk_set_prot(virt_to_page(pmd),flags,cpu,seq);
++                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
++                              if (pmd_none(*pmd))
++                                      continue;
++                              seq = pgd_walk_set_prot(pmd_page(*pmd),flags,cpu,seq);
++                      }
++              }
++      }
++
++      mcl = per_cpu(pb_mcl, cpu);
++#ifdef CONFIG_X86_64
++      if (unlikely(seq > PIN_BATCH - 2)) {
++              if (unlikely(HYPERVISOR_multicall_check(mcl, seq, NULL)))
++                      BUG();
++              seq = 0;
++      }
++      MULTI_update_va_mapping(mcl + seq,
++             (unsigned long)__user_pgd(pgd_base),
++             pfn_pte(virt_to_phys(__user_pgd(pgd_base))>>PAGE_SHIFT, flags),
++             0);
++      MULTI_update_va_mapping(mcl + seq + 1,
++             (unsigned long)pgd_base,
++             pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
++             UVMF_TLB_FLUSH);
++      if (unlikely(HYPERVISOR_multicall_check(mcl, seq + 2, NULL)))
++              BUG();
++#else
++      if (likely(seq != 0)) {
++              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
++                      (unsigned long)pgd_base,
++                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
++                      UVMF_TLB_FLUSH);
++              if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
++                                                      seq + 1, NULL)))
++                      BUG();
++      } else if(HYPERVISOR_update_va_mapping((unsigned long)pgd_base,
++                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
++                      UVMF_TLB_FLUSH))
++              BUG();
++#endif
++
++      put_cpu();
++}
++
++static void __pgd_pin(pgd_t *pgd)
++{
++      pgd_walk(pgd, PAGE_KERNEL_RO);
++      kmap_flush_unused();
++      xen_pgd_pin(__pa(pgd)); /* kernel */
++#ifdef CONFIG_X86_64
++      xen_pgd_pin(__pa(__user_pgd(pgd))); /* user */
++#endif
++      SetPagePinned(virt_to_page(pgd));
++}
++
++static void __pgd_unpin(pgd_t *pgd)
++{
++      xen_pgd_unpin(__pa(pgd));
++#ifdef CONFIG_X86_64
++      xen_pgd_unpin(__pa(__user_pgd(pgd)));
++#endif
++      pgd_walk(pgd, PAGE_KERNEL);
++      ClearPagePinned(virt_to_page(pgd));
++}
++
++void pgd_test_and_unpin(pgd_t *pgd)
++{
++      if (PagePinned(virt_to_page(pgd)))
++              __pgd_unpin(pgd);
++}
++
++void mm_pin(struct mm_struct *mm)
++{
++      if (xen_feature(XENFEAT_writable_page_tables))
++              return;
++
++      pin_lock(mm);
++      __pgd_pin(mm->pgd);
++      pin_unlock(mm);
++}
++
++void mm_unpin(struct mm_struct *mm)
++{
++      if (xen_feature(XENFEAT_writable_page_tables))
++              return;
++
++      pin_lock(mm);
++      __pgd_unpin(mm->pgd);
++      pin_unlock(mm);
++}
++
++void mm_pin_all(void)
++{
++      struct page *page;
++      unsigned long flags;
++
++      if (xen_feature(XENFEAT_writable_page_tables))
++              return;
++
++      /*
++       * Allow uninterrupted access to the pgd_list. Also protects
++       * __pgd_pin() by disabling preemption.
++       * All other CPUs must be at a safe point (e.g., in stop_machine
++       * or offlined entirely).
++       */
++      spin_lock_irqsave(&pgd_lock, flags);
++      list_for_each_entry(page, &pgd_list, lru) {
++              if (!PagePinned(page))
++                      __pgd_pin((pgd_t *)page_address(page));
++      }
++      spin_unlock_irqrestore(&pgd_lock, flags);
++}
++
++void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
++{
++      if (!PagePinned(virt_to_page(mm->pgd)))
++              mm_pin(mm);
++}
++
++void arch_exit_mmap(struct mm_struct *mm)
++{
++      struct task_struct *tsk = current;
++
++      task_lock(tsk);
++
++      /*
++       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
++       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
++       */
++      if (tsk->active_mm == mm) {
++              tsk->active_mm = &init_mm;
++              atomic_inc(&init_mm.mm_count);
++
++              switch_mm(mm, &init_mm, tsk);
++
++              atomic_dec(&mm->mm_count);
++              BUG_ON(atomic_read(&mm->mm_count) == 0);
++      }
++
++      task_unlock(tsk);
++
++      if (PagePinned(virt_to_page(mm->pgd))
++          && atomic_read(&mm->mm_count) == 1
++          && !mm->context.has_foreign_mappings)
++              mm_unpin(mm);
++}
++
++static void _pte_free(struct page *page, unsigned int order)
++{
++      BUG_ON(order);
++      __pte_free(page);
++}
++
++pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
++{
++      struct page *pte;
++
++#ifdef CONFIG_HIGHPTE
++      pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
++#else
++      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
++#endif
++      if (pte) {
++              pgtable_page_ctor(pte);
++              SetPageForeign(pte, _pte_free);
++              init_page_count(pte);
++      }
++      return pte;
++}
++
++void __pte_free(pgtable_t pte)
++{
++      if (!PageHighMem(pte)) {
++              unsigned long va = (unsigned long)page_address(pte);
++              unsigned int level;
++              pte_t *ptep = lookup_address(va, &level);
++
++              BUG_ON(!ptep || level != PG_LEVEL_4K || !pte_present(*ptep));
++              if (!pte_write(*ptep)
++                  && HYPERVISOR_update_va_mapping(va,
++                                                  mk_pte(pte, PAGE_KERNEL),
++                                                  0))
++                      BUG();
++      } else
++#ifdef CONFIG_HIGHPTE
++              ClearPagePinned(pte);
++#else
++              BUG();
++#endif
++
++      ClearPageForeign(pte);
++      init_page_count(pte);
++      pgtable_page_dtor(pte);
++      __free_page(pte);
++}
++
++#if PAGETABLE_LEVELS >= 3
++static void _pmd_free(struct page *page, unsigned int order)
++{
++      BUG_ON(order);
++      __pmd_free(page);
++}
++
++pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
++{
++      struct page *pmd;
++
++      pmd = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
++      if (!pmd)
++              return NULL;
++      SetPageForeign(pmd, _pmd_free);
++      init_page_count(pmd);
++      return page_address(pmd);
++}
++
++void __pmd_free(pgtable_t pmd)
++{
++      unsigned long va = (unsigned long)page_address(pmd);
++      unsigned int level;
++      pte_t *ptep = lookup_address(va, &level);
++
++      BUG_ON(!ptep || level != PG_LEVEL_4K || !pte_present(*ptep));
++      if (!pte_write(*ptep)
++          && HYPERVISOR_update_va_mapping(va, mk_pte(pmd, PAGE_KERNEL), 0))
++              BUG();
++
++      ClearPageForeign(pmd);
++      init_page_count(pmd);
++      __free_page(pmd);
++}
++#endif
++
++/* blktap and gntdev need this, as otherwise they would implicitly (and
++ * needlessly, as they never use it) reference init_mm. */
++pte_t xen_ptep_get_and_clear_full(struct vm_area_struct *vma,
++                                unsigned long addr, pte_t *ptep, int full)
++{
++      return ptep_get_and_clear_full(vma->vm_mm, addr, ptep, full);
++}
++EXPORT_SYMBOL_GPL(xen_ptep_get_and_clear_full);
++
++/*
++ * The current flushing context - we pass it instead of 5 arguments:
++ */
++struct cpa_data {
++      unsigned long   vaddr;
++      pgprot_t        mask_set;
++      pgprot_t        mask_clr;
++      int             numpages;
++      int             flushtlb;
++      unsigned long   pfn;
++};
++
++#ifdef CONFIG_X86_64
++
++static inline unsigned long highmap_start_pfn(void)
++{
++      return __pa(_text) >> PAGE_SHIFT;
++}
++
++static inline unsigned long highmap_end_pfn(void)
++{
++      return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
++}
++
++#endif
++
++#ifdef CONFIG_DEBUG_PAGEALLOC
++# define debug_pagealloc 1
++#else
++# define debug_pagealloc 0
++#endif
++
++static inline int
++within(unsigned long addr, unsigned long start, unsigned long end)
++{
++      return addr >= start && addr < end;
++}
++
++/*
++ * Flushing functions
++ */
++
++/**
++ * clflush_cache_range - flush a cache range with clflush
++ * @addr:     virtual start address
++ * @size:     number of bytes to flush
++ *
++ * clflush is an unordered instruction which needs fencing with mfence
++ * to avoid ordering issues.
++ */
++void clflush_cache_range(void *vaddr, unsigned int size)
++{
++      void *vend = vaddr + size - 1;
++
++      mb();
++
++      for (; vaddr < vend; vaddr += boot_cpu_data.x86_clflush_size)
++              clflush(vaddr);
++      /*
++       * Flush any possible final partial cacheline:
++       */
++      clflush(vend);
++
++      mb();
++}
++
++static void __cpa_flush_all(void *arg)
++{
++      unsigned long cache = (unsigned long)arg;
++
++      /*
++       * Flush all to work around Errata in early athlons regarding
++       * large page flushing.
++       */
++      __flush_tlb_all();
++
++      if (cache && boot_cpu_data.x86_model >= 4)
++              wbinvd();
++}
++
++static void cpa_flush_all(unsigned long cache)
++{
++      BUG_ON(irqs_disabled());
++
++      on_each_cpu(__cpa_flush_all, (void *) cache, 1, 1);
++}
++
++static void __cpa_flush_range(void *arg)
++{
++      /*
++       * We could optimize that further and do individual per page
++       * tlb invalidates for a low number of pages. Caveat: we must
++       * flush the high aliases on 64bit as well.
++       */
++      __flush_tlb_all();
++}
++
++static void cpa_flush_range(unsigned long start, int numpages, int cache)
++{
++      unsigned int i, level;
++      unsigned long addr;
++
++      BUG_ON(irqs_disabled());
++      WARN_ON(PAGE_ALIGN(start) != start);
++
++      on_each_cpu(__cpa_flush_range, NULL, 1, 1);
++
++      if (!cache)
++              return;
++
++      /*
++       * We only need to flush on one CPU,
++       * clflush is a MESI-coherent instruction that
++       * will cause all other CPUs to flush the same
++       * cachelines:
++       */
++      for (i = 0, addr = start; i < numpages; i++, addr += PAGE_SIZE) {
++              pte_t *pte = lookup_address(addr, &level);
++
++              /*
++               * Only flush present addresses:
++               */
++              if (pte && (__pte_val(*pte) & _PAGE_PRESENT))
++                      clflush_cache_range((void *) addr, PAGE_SIZE);
++      }
++}
++
++/*
++ * Certain areas of memory on x86 require very specific protection flags,
++ * for example the BIOS area or kernel text. Callers don't always get this
++ * right (again, ioremap() on BIOS memory is not uncommon) so this function
++ * checks and fixes these known static required protection bits.
++ */
++static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
++                                 unsigned long pfn)
++{
++      pgprot_t forbidden = __pgprot(0);
++
++#ifndef CONFIG_XEN
++      /*
++       * The BIOS area between 640k and 1Mb needs to be executable for
++       * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support.
++       */
++      if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT))
++              pgprot_val(forbidden) |= _PAGE_NX;
++#endif
++
++      /*
++       * The kernel text needs to be executable for obvious reasons
++       * Does not cover __inittext since that is gone later on. On
++       * 64bit we do not enforce !NX on the low mapping
++       */
++      if (within(address, (unsigned long)_text, (unsigned long)_etext))
++              pgprot_val(forbidden) |= _PAGE_NX;
++
++      /*
++       * The .rodata section needs to be read-only. Using the pfn
++       * catches all aliases.
++       */
++      if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
++                 __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
++              pgprot_val(forbidden) |= _PAGE_RW;
++
++      prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
++
++      return prot;
++}
++
++/*
++ * Lookup the page table entry for a virtual address. Return a pointer
++ * to the entry and the level of the mapping.
++ *
++ * Note: We return pud and pmd either when the entry is marked large
++ * or when the present bit is not set. Otherwise we would return a
++ * pointer to a nonexisting mapping.
++ */
++pte_t *lookup_address(unsigned long address, unsigned int *level)
++{
++      pgd_t *pgd = pgd_offset_k(address);
++      pud_t *pud;
++      pmd_t *pmd;
++
++      *level = PG_LEVEL_NONE;
++
++      if (pgd_none(*pgd))
++              return NULL;
++
++      pud = pud_offset(pgd, address);
++      if (pud_none(*pud))
++              return NULL;
++
++      *level = PG_LEVEL_1G;
++      if (pud_large(*pud) || !pud_present(*pud))
++              return (pte_t *)pud;
++
++      pmd = pmd_offset(pud, address);
++      if (pmd_none(*pmd))
++              return NULL;
++
++      *level = PG_LEVEL_2M;
++      if (pmd_large(*pmd) || !pmd_present(*pmd))
++              return (pte_t *)pmd;
++
++      *level = PG_LEVEL_4K;
++
++      return pte_offset_kernel(pmd, address);
++}
++
++/*
++ * Set the new pmd in all the pgds we know about:
++ */
++static void __set_pmd_pte(pte_t *kpte, unsigned long address,
++                        unsigned int level, pte_t pte)
++{
++      /* change init_mm */
++      switch(level) {
++      case PG_LEVEL_2M:
++              xen_l2_entry_update((pmd_t *)kpte, __pmd_ma(__pte_val(pte)));
++              break;
++#ifdef CONFIG_X86_64
++      case PG_LEVEL_1G:
++              xen_l3_entry_update((pud_t *)kpte, __pud_ma(__pte_val(pte)));
++              break;
++#endif
++      default:
++              BUG();
++      }
++#ifdef CONFIG_X86_32
++      if (!SHARED_KERNEL_PMD) {
++              struct page *page;
++
++              list_for_each_entry(page, &pgd_list, lru) {
++                      pgd_t *pgd;
++                      pud_t *pud;
++                      pmd_t *pmd;
++
++                      pgd = (pgd_t *)page_address(page) + pgd_index(address);
++                      pud = pud_offset(pgd, address);
++                      pmd = pmd_offset(pud, address);
++                      xen_l2_entry_update(pmd, __pmd_ma(__pte_val(pte)));
++              }
++      }
++#endif
++}
++
++static int
++try_preserve_large_page(pte_t *kpte, unsigned long address,
++                      struct cpa_data *cpa)
++{
++      unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn;
++      pte_t new_pte, old_pte, *tmp;
++      pgprot_t old_prot, new_prot;
++      int i, do_split = 1;
++      unsigned int level;
++
++      spin_lock_irqsave(&pgd_lock, flags);
++      /*
++       * Check for races, another CPU might have split this page
++       * up already:
++       */
++      tmp = lookup_address(address, &level);
++      if (tmp != kpte)
++              goto out_unlock;
++
++      switch (level) {
++      case PG_LEVEL_2M:
++              psize = PMD_PAGE_SIZE;
++              pmask = PMD_PAGE_MASK;
++              break;
++#ifdef CONFIG_X86_64
++      case PG_LEVEL_1G:
++              psize = PUD_PAGE_SIZE;
++              pmask = PUD_PAGE_MASK;
++              break;
++#endif
++      default:
++              do_split = -EINVAL;
++              goto out_unlock;
++      }
++
++      /*
++       * Calculate the number of pages, which fit into this large
++       * page starting at address:
++       */
++      nextpage_addr = (address + psize) & pmask;
++      numpages = (nextpage_addr - address) >> PAGE_SHIFT;
++      if (numpages < cpa->numpages)
++              cpa->numpages = numpages;
++
++      /*
++       * We are safe now. Check whether the new pgprot is the same:
++       */
++      old_pte = *kpte;
++      old_prot = new_prot = pte_pgprot(old_pte);
++
++      pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
++      pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
++
++      /*
++       * old_pte points to the large page base address. So we need
++       * to add the offset of the virtual address:
++       */
++      pfn = pte_pfn(old_pte) + ((address & (psize - 1)) >> PAGE_SHIFT);
++      cpa->pfn = pfn;
++
++      new_prot = static_protections(new_prot, address, pfn);
++
++      /*
++       * We need to check the full range, whether
++       * static_protection() requires a different pgprot for one of
++       * the pages in the range we try to preserve:
++       */
++      if (pfn < max_mapnr) {
++              addr = address + PAGE_SIZE;
++              for (i = 1; i < cpa->numpages && ++pfn < max_mapnr;
++                   i++, addr += PAGE_SIZE) {
++                      pgprot_t chk_prot = static_protections(new_prot, addr, pfn);
++
++                      if (pgprot_val(chk_prot) != pgprot_val(new_prot))
++                              goto out_unlock;
++              }
++      }
++
++      /*
++       * If there are no changes, return. maxpages has been updated
++       * above:
++       */
++      if (pgprot_val(new_prot) == pgprot_val(old_prot)) {
++              do_split = 0;
++              goto out_unlock;
++      }
++
++      /*
++       * We need to change the attributes. Check, whether we can
++       * change the large page in one go. We request a split, when
++       * the address is not aligned and the number of pages is
++       * smaller than the number of pages in the large page. Note
++       * that we limited the number of possible pages already to
++       * the number of pages in the large page.
++       */
++      if (address == (nextpage_addr - psize) && cpa->numpages == numpages) {
++              /*
++               * The address is aligned and the number of pages
++               * covers the full page.
++               */
++              new_pte = pfn_pte_ma(__pte_mfn(old_pte), canon_pgprot(new_prot));
++              __set_pmd_pte(kpte, address, level, new_pte);
++              cpa->flushtlb = 1;
++              do_split = 0;
++      }
++
++out_unlock:
++      spin_unlock_irqrestore(&pgd_lock, flags);
++
++      return do_split;
++}
++
++static LIST_HEAD(page_pool);
++static unsigned long pool_size, pool_pages, pool_low;
++static unsigned long pool_used, pool_failed;
++
++static void cpa_fill_pool(struct page **ret)
++{
++      gfp_t gfp = GFP_KERNEL;
++      unsigned long flags;
++      struct page *p;
++
++      /*
++       * Avoid recursion (on debug-pagealloc) and also signal
++       * our priority to get to these pagetables:
++       */
++      if (current->flags & PF_MEMALLOC)
++              return;
++      current->flags |= PF_MEMALLOC;
++
++      /*
++       * Allocate atomically from atomic contexts:
++       */
++      if (in_atomic() || irqs_disabled() || debug_pagealloc)
++              gfp =  GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
++
++      while (pool_pages < pool_size || (ret && !*ret)) {
++              p = alloc_pages(gfp, 0);
++              if (!p) {
++                      pool_failed++;
++                      break;
++              }
++              /*
++               * If the call site needs a page right now, provide it:
++               */
++              if (ret && !*ret) {
++                      *ret = p;
++                      continue;
++              }
++              spin_lock_irqsave(&pgd_lock, flags);
++              list_add(&p->lru, &page_pool);
++              pool_pages++;
++              spin_unlock_irqrestore(&pgd_lock, flags);
++      }
++
++      current->flags &= ~PF_MEMALLOC;
++}
++
++#define SHIFT_MB              (20 - PAGE_SHIFT)
++#define ROUND_MB_GB           ((1 << 10) - 1)
++#define SHIFT_MB_GB           10
++#define POOL_PAGES_PER_GB     16
++
++void __init cpa_init(void)
++{
++      struct sysinfo si;
++      unsigned long gb;
++
++      si_meminfo(&si);
++      /*
++       * Calculate the number of pool pages:
++       *
++       * Convert totalram (nr of pages) to MiB and round to the next
++       * GiB. Shift MiB to Gib and multiply the result by
++       * POOL_PAGES_PER_GB:
++       */
++      if (debug_pagealloc) {
++              gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
++              pool_size = POOL_PAGES_PER_GB * gb;
++      } else {
++              pool_size = 1;
++      }
++      pool_low = pool_size;
++
++      cpa_fill_pool(NULL);
++      printk(KERN_DEBUG
++             "CPA: page pool initialized %lu of %lu pages preallocated\n",
++             pool_pages, pool_size);
++}
++
++static int split_large_page(pte_t *kpte, unsigned long address)
++{
++      unsigned long flags, mfn, mfninc = 1;
++      unsigned int i, level;
++      pte_t *pbase, *tmp;
++      pgprot_t ref_prot;
++      struct page *base;
++
++      /*
++       * Get a page from the pool. The pool list is protected by the
++       * pgd_lock, which we have to take anyway for the split
++       * operation:
++       */
++      spin_lock_irqsave(&pgd_lock, flags);
++      if (list_empty(&page_pool)) {
++              spin_unlock_irqrestore(&pgd_lock, flags);
++              base = NULL;
++              cpa_fill_pool(&base);
++              if (!base)
++                      return -ENOMEM;
++              spin_lock_irqsave(&pgd_lock, flags);
++      } else {
++              base = list_first_entry(&page_pool, struct page, lru);
++              list_del(&base->lru);
++              pool_pages--;
++
++              if (pool_pages < pool_low)
++                      pool_low = pool_pages;
++      }
++
++      /*
++       * Check for races, another CPU might have split this page
++       * up for us already:
++       */
++      tmp = lookup_address(address, &level);
++      if (tmp != kpte)
++              goto out_unlock;
++
++      pbase = (pte_t *)page_address(base);
++#ifdef CONFIG_X86_32
++      paravirt_alloc_pt(&init_mm, page_to_pfn(base));
++#endif
++      ref_prot = pte_pgprot(pte_clrhuge(*kpte));
++
++#ifdef CONFIG_X86_64
++      if (level == PG_LEVEL_1G) {
++              mfninc = PMD_PAGE_SIZE >> PAGE_SHIFT;
++              pgprot_val(ref_prot) |= _PAGE_PSE;
++      }
++#endif
++
++      /*
++       * Get the target mfn from the original entry:
++       */
++      mfn = __pte_mfn(*kpte);
++      for (i = 0; i < PTRS_PER_PTE; i++, mfn += mfninc)
++              set_pte(&pbase[i], pfn_pte_ma(mfn, ref_prot));
++
++      /*
++       * Install the new, split up pagetable. Important details here:
++       *
++       * On Intel the NX bit of all levels must be cleared to make a
++       * page executable. See section 4.13.2 of Intel 64 and IA-32
++       * Architectures Software Developer's Manual).
++       *
++       * Mark the entry present. The current mapping might be
++       * set to not present, which we preserved above.
++       */
++      if (!xen_feature(XENFEAT_writable_page_tables) &&
++          HYPERVISOR_update_va_mapping((unsigned long)pbase,
++                                       mk_pte(base, PAGE_KERNEL_RO), 0))
++              BUG();
++      ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte)));
++      pgprot_val(ref_prot) |= _PAGE_PRESENT;
++      __set_pmd_pte(kpte, address, level, mk_pte(base, ref_prot));
++      base = NULL;
 +
-+#ifndef __ASSEMBLY__
-+#include <asm/desc_defs.h>
-+#include <asm/ldt.h>
-+#include <asm/mmu.h>
-+#include <linux/smp.h>
++out_unlock:
++      /*
++       * If we dropped out via the lookup_address check under
++       * pgd_lock then stick the page back into the pool:
++       */
++      if (base) {
++              list_add(&base->lru, &page_pool);
++              pool_pages++;
++      } else
++              pool_used++;
++      spin_unlock_irqrestore(&pgd_lock, flags);
 +
-+static inline void fill_ldt(struct desc_struct *desc,
-+                          const struct user_desc *info)
++      return 0;
++}
++
++static int __change_page_attr(struct cpa_data *cpa, int primary)
 +{
-+      desc->limit0 = info->limit & 0x0ffff;
-+      desc->base0 = info->base_addr & 0x0000ffff;
++      unsigned long address = cpa->vaddr;
++      int do_split, err;
++      unsigned int level;
++      pte_t *kpte, old_pte;
 +
-+      desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
-+      desc->type = (info->read_exec_only ^ 1) << 1;
-+      desc->type |= info->contents << 2;
-+      desc->s = 1;
-+      desc->dpl = 0x3;
-+      desc->p = info->seg_not_present ^ 1;
-+      desc->limit = (info->limit & 0xf0000) >> 16;
-+      desc->avl = info->useable;
-+      desc->d = info->seg_32bit;
-+      desc->g = info->limit_in_pages;
-+      desc->base2 = (info->base_addr & 0xff000000) >> 24;
++repeat:
++      kpte = lookup_address(address, &level);
++      if (!kpte)
++              return primary ? -EINVAL : 0;
++
++      old_pte = *kpte;
++      if (!__pte_val(old_pte)) {
++              if (!primary)
++                      return 0;
++              printk(KERN_WARNING "CPA: called for zero pte. "
++                     "vaddr = %lx cpa->vaddr = %lx\n", address,
++                     cpa->vaddr);
++              WARN_ON(1);
++              return -EINVAL;
++      }
++
++      if (level == PG_LEVEL_4K) {
++              pte_t new_pte;
++              pgprot_t new_prot = pte_pgprot(old_pte);
++              unsigned long mfn = __pte_mfn(old_pte);
++
++              pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
++              pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
++
++              new_prot = static_protections(new_prot, address,
++                                            mfn_to_local_pfn(mfn));
++
++              /*
++               * We need to keep the mfn from the existing PTE,
++               * after all we're only going to change it's attributes
++               * not the memory it points to
++               */
++              new_pte = pfn_pte_ma(mfn, canon_pgprot(new_prot));
++              cpa->pfn = mfn_to_local_pfn(mfn);
++              /*
++               * Do we really change anything ?
++               */
++              if (__pte_val(old_pte) != __pte_val(new_pte)) {
++                      set_pte_atomic(kpte, new_pte);
++                      cpa->flushtlb = 1;
++              }
++              cpa->numpages = 1;
++              return 0;
++      }
++
++      /*
++       * Check, whether we can keep the large page intact
++       * and just change the pte:
++       */
++      do_split = try_preserve_large_page(kpte, address, cpa);
++      /*
++       * When the range fits into the existing large page,
++       * return. cp->numpages and cpa->tlbflush have been updated in
++       * try_large_page:
++       */
++      if (do_split <= 0)
++              return do_split;
++
++      /*
++       * We have to split the large page:
++       */
++      err = split_large_page(kpte, address);
++      if (!err) {
++              cpa->flushtlb = 1;
++              goto repeat;
++      }
++
++      return err;
++}
++
++static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias);
++
++static int cpa_process_alias(struct cpa_data *cpa)
++{
++      struct cpa_data alias_cpa;
++      int ret = 0;
++
++      if (cpa->pfn > max_pfn_mapped)
++              return 0;
++
++      /*
++       * No need to redo, when the primary call touched the direct
++       * mapping already:
++       */
++      if (!within(cpa->vaddr, PAGE_OFFSET,
++                  PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
++
++              alias_cpa = *cpa;
++              alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
++
++              ret = __change_page_attr_set_clr(&alias_cpa, 0);
++      }
++
++#ifdef CONFIG_X86_64
++      if (ret)
++              return ret;
++      /*
++       * No need to redo, when the primary call touched the high
++       * mapping already:
++       */
++      if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end))
++              return 0;
++
++      /*
++       * If the physical address is inside the kernel map, we need
++       * to touch the high mapped kernel as well:
++       */
++      if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn()))
++              return 0;
++
++      alias_cpa = *cpa;
++      alias_cpa.vaddr =
++              (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map;
++
++      /*
++       * The high mapping range is imprecise, so ignore the return value.
++       */
++      __change_page_attr_set_clr(&alias_cpa, 0);
++#endif
++      return ret;
++}
++
++static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
++{
++      int ret, numpages = cpa->numpages;
++
++      while (numpages) {
++              /*
++               * Store the remaining nr of pages for the large page
++               * preservation check.
++               */
++              cpa->numpages = numpages;
++
++              ret = __change_page_attr(cpa, checkalias);
++              if (ret)
++                      return ret;
++
++              if (checkalias) {
++                      ret = cpa_process_alias(cpa);
++                      if (ret)
++                              return ret;
++              }
++
++              /*
++               * Adjust the number of pages with the result of the
++               * CPA operation. Either a large page has been
++               * preserved or a single page update happened.
++               */
++              BUG_ON(cpa->numpages > numpages);
++              numpages -= cpa->numpages;
++              cpa->vaddr += cpa->numpages * PAGE_SIZE;
++      }
++      return 0;
++}
++
++static inline int cache_attr(pgprot_t attr)
++{
++      return pgprot_val(attr) &
++              (_PAGE_PAT | _PAGE_PAT_LARGE | _PAGE_PWT | _PAGE_PCD);
 +}
 +
-+#ifndef CONFIG_X86_NO_IDT
-+extern struct desc_ptr idt_descr;
-+extern gate_desc idt_table[];
-+#endif
++static int change_page_attr_set_clr(unsigned long addr, int numpages,
++                                  pgprot_t mask_set, pgprot_t mask_clr)
++{
++      struct cpa_data cpa;
++      int ret, cache, checkalias;
++
++      /*
++       * Check, if we are requested to change a not supported
++       * feature:
++       */
++      mask_set = canon_pgprot(mask_set);
++      mask_clr = canon_pgprot(mask_clr);
++      if (!pgprot_val(mask_set) && !pgprot_val(mask_clr))
++              return 0;
++
++      /* Ensure we are PAGE_SIZE aligned */
++      if (addr & ~PAGE_MASK) {
++              addr &= PAGE_MASK;
++              /*
++               * People should not be passing in unaligned addresses:
++               */
++              WARN_ON_ONCE(1);
++      }
++
++      cpa.vaddr = addr;
++      cpa.numpages = numpages;
++      cpa.mask_set = mask_set;
++      cpa.mask_clr = mask_clr;
++      cpa.flushtlb = 0;
++
++      /* No alias checking for _NX bit modifications */
++      checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
++
++      ret = __change_page_attr_set_clr(&cpa, checkalias);
++
++      /*
++       * Check whether we really changed something:
++       */
++      if (!cpa.flushtlb)
++              goto out;
++
++      /*
++       * No need to flush, when we did not set any of the caching
++       * attributes:
++       */
++      cache = cache_attr(mask_set);
++
++      /*
++       * On success we use clflush, when the CPU supports it to
++       * avoid the wbindv. If the CPU does not support it and in the
++       * error case we fall back to cpa_flush_all (which uses
++       * wbindv):
++       */
++      if (!ret && cpu_has_clflush)
++              cpa_flush_range(addr, numpages, cache);
++      else
++              cpa_flush_all(cache);
++
++out:
++      cpa_fill_pool(NULL);
 +
-+#ifdef CONFIG_X86_64
-+extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
-+extern struct desc_ptr cpu_gdt_descr[];
-+/* the cpu gdt accessor */
-+#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
++      return ret;
++}
 +
-+static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
-+                           unsigned dpl, unsigned ist, unsigned seg)
++static inline int change_page_attr_set(unsigned long addr, int numpages,
++                                     pgprot_t mask)
 +{
-+      gate->offset_low = PTR_LOW(func);
-+      gate->segment = __KERNEL_CS;
-+      gate->ist = ist;
-+      gate->p = 1;
-+      gate->dpl = dpl;
-+      gate->zero0 = 0;
-+      gate->zero1 = 0;
-+      gate->type = type;
-+      gate->offset_middle = PTR_MIDDLE(func);
-+      gate->offset_high = PTR_HIGH(func);
++      return change_page_attr_set_clr(addr, numpages, mask, __pgprot(0));
 +}
 +
-+#else
-+struct gdt_page {
-+      struct desc_struct gdt[GDT_ENTRIES];
-+} __attribute__((aligned(PAGE_SIZE)));
-+DECLARE_PER_CPU(struct gdt_page, gdt_page);
-+
-+static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
++static inline int change_page_attr_clear(unsigned long addr, int numpages,
++                                       pgprot_t mask)
 +{
-+      return per_cpu(gdt_page, cpu).gdt;
++      return change_page_attr_set_clr(addr, numpages, __pgprot(0), mask);
 +}
 +
-+static inline void pack_gate(gate_desc *gate, unsigned char type,
-+       unsigned long base, unsigned dpl, unsigned flags, unsigned short seg)
-+
++int set_memory_uc(unsigned long addr, int numpages)
 +{
-+      gate->a = (seg << 16) | (base & 0xffff);
-+      gate->b = (base & 0xffff0000) |
-+                (((0x80 | type | (dpl << 5)) & 0xff) << 8);
++      return change_page_attr_set(addr, numpages,
++                                  __pgprot(_PAGE_PCD));
 +}
++EXPORT_SYMBOL(set_memory_uc);
 +
-+#endif
-+
-+static inline int desc_empty(const void *ptr)
++int set_memory_wb(unsigned long addr, int numpages)
 +{
-+      const u32 *desc = ptr;
-+      return !(desc[0] | desc[1]);
++      return change_page_attr_clear(addr, numpages,
++                                    __pgprot(_PAGE_PCD | _PAGE_PWT));
 +}
++EXPORT_SYMBOL(set_memory_wb);
 +
-+#ifndef CONFIG_XEN
-+#define load_TR_desc() native_load_tr_desc()
-+#define load_gdt(dtr) native_load_gdt(dtr)
-+#define load_idt(dtr) native_load_idt(dtr)
-+#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr))
-+#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt))
-+
-+#define store_gdt(dtr) native_store_gdt(dtr)
-+#define store_idt(dtr) native_store_idt(dtr)
-+#define store_tr(tr) (tr = native_store_tr())
-+#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt))
-+
-+#define load_TLS(t, cpu) native_load_tls(t, cpu)
-+#define set_ldt native_set_ldt
-+
-+#define write_ldt_entry(dt, entry, desc) \
-+                              native_write_ldt_entry(dt, entry, desc)
-+#define write_gdt_entry(dt, entry, desc, type) \
-+                              native_write_gdt_entry(dt, entry, desc, type)
-+#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g)
-+
-+static inline void native_write_idt_entry(gate_desc *idt, int entry,
-+                                        const gate_desc *gate)
++int set_memory_x(unsigned long addr, int numpages)
 +{
-+      memcpy(&idt[entry], gate, sizeof(*gate));
++      return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_NX));
 +}
++EXPORT_SYMBOL(set_memory_x);
 +
-+static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
-+                                        const void *desc)
++int set_memory_nx(unsigned long addr, int numpages)
 +{
-+      memcpy(&ldt[entry], desc, 8);
++      return change_page_attr_set(addr, numpages, __pgprot(_PAGE_NX));
 +}
++EXPORT_SYMBOL(set_memory_nx);
 +
-+static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
-+                                        const void *desc, int type)
++int set_memory_ro(unsigned long addr, int numpages)
 +{
-+      unsigned int size;
-+      switch (type) {
-+      case DESC_TSS:
-+              size = sizeof(tss_desc);
-+              break;
-+      case DESC_LDT:
-+              size = sizeof(ldt_desc);
-+              break;
-+      default:
-+              size = sizeof(struct desc_struct);
-+              break;
-+      }
-+      memcpy(&gdt[entry], desc, size);
++      return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
 +}
-+#endif
 +
-+static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
-+                                 unsigned long limit, unsigned char type,
-+                                 unsigned char flags)
++int set_memory_rw(unsigned long addr, int numpages)
 +{
-+      desc->a = ((base & 0xffff) << 16) | (limit & 0xffff);
-+      desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
-+                (limit & 0x000f0000) | ((type & 0xff) << 8) |
-+                ((flags & 0xf) << 20);
-+      desc->p = 1;
++      return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
 +}
 +
-+
-+#ifndef CONFIG_XEN
-+static inline void set_tssldt_descriptor(void *d, unsigned long addr,
-+                                       unsigned type, unsigned size)
++int set_memory_np(unsigned long addr, int numpages)
 +{
-+#ifdef CONFIG_X86_64
-+      struct ldttss_desc64 *desc = d;
-+      memset(desc, 0, sizeof(*desc));
-+      desc->limit0 = size & 0xFFFF;
-+      desc->base0 = PTR_LOW(addr);
-+      desc->base1 = PTR_MIDDLE(addr) & 0xFF;
-+      desc->type = type;
-+      desc->p = 1;
-+      desc->limit1 = (size >> 16) & 0xF;
-+      desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF;
-+      desc->base3 = PTR_HIGH(addr);
-+#else
-+
-+      pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
-+#endif
++      return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_PRESENT));
 +}
 +
-+static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
++int set_pages_uc(struct page *page, int numpages)
 +{
-+      struct desc_struct *d = get_cpu_gdt_table(cpu);
-+      tss_desc tss;
++      unsigned long addr = (unsigned long)page_address(page);
 +
-+      /*
-+       * sizeof(unsigned long) coming from an extra "long" at the end
-+       * of the iobitmap. See tss_struct definition in processor.h
-+       *
-+       * -1? seg base+limit should be pointing to the address of the
-+       * last valid byte
-+       */
-+      set_tssldt_descriptor(&tss, (unsigned long)addr, DESC_TSS,
-+              IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1);
-+      write_gdt_entry(d, entry, &tss, DESC_TSS);
++      return set_memory_uc(addr, numpages);
 +}
++EXPORT_SYMBOL(set_pages_uc);
 +
-+#define set_tss_desc(cpu, addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
-+
-+static inline void native_set_ldt(const void *addr, unsigned int entries)
++int set_pages_wb(struct page *page, int numpages)
 +{
-+      if (likely(entries == 0))
-+              __asm__ __volatile__("lldt %w0"::"q" (0));
-+      else {
-+              unsigned cpu = smp_processor_id();
-+              ldt_desc ldt;
++      unsigned long addr = (unsigned long)page_address(page);
 +
-+              set_tssldt_descriptor(&ldt, (unsigned long)addr,
-+                                    DESC_LDT, entries * sizeof(ldt) - 1);
-+              write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
-+                              &ldt, DESC_LDT);
-+              __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
-+      }
++      return set_memory_wb(addr, numpages);
 +}
++EXPORT_SYMBOL(set_pages_wb);
 +
-+static inline void native_load_tr_desc(void)
++int set_pages_x(struct page *page, int numpages)
 +{
-+      asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
++      unsigned long addr = (unsigned long)page_address(page);
++
++      return set_memory_x(addr, numpages);
 +}
++EXPORT_SYMBOL(set_pages_x);
 +
-+static inline void native_load_gdt(const struct desc_ptr *dtr)
++int set_pages_nx(struct page *page, int numpages)
 +{
-+      asm volatile("lgdt %0"::"m" (*dtr));
++      unsigned long addr = (unsigned long)page_address(page);
++
++      return set_memory_nx(addr, numpages);
 +}
++EXPORT_SYMBOL(set_pages_nx);
 +
-+static inline void native_load_idt(const struct desc_ptr *dtr)
++int set_pages_ro(struct page *page, int numpages)
 +{
-+      asm volatile("lidt %0"::"m" (*dtr));
++      unsigned long addr = (unsigned long)page_address(page);
++
++      return set_memory_ro(addr, numpages);
 +}
 +
-+static inline void native_store_gdt(struct desc_ptr *dtr)
++int set_pages_rw(struct page *page, int numpages)
 +{
-+      asm volatile("sgdt %0":"=m" (*dtr));
++      unsigned long addr = (unsigned long)page_address(page);
++
++      return set_memory_rw(addr, numpages);
 +}
 +
-+static inline void native_store_idt(struct desc_ptr *dtr)
++#ifdef CONFIG_DEBUG_PAGEALLOC
++
++static int __set_pages_p(struct page *page, int numpages)
 +{
-+      asm volatile("sidt %0":"=m" (*dtr));
++      struct cpa_data cpa = { .vaddr = (unsigned long) page_address(page),
++                              .numpages = numpages,
++                              .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
++                              .mask_clr = __pgprot(0)};
++
++      return __change_page_attr_set_clr(&cpa, 1);
 +}
 +
-+static inline unsigned long native_store_tr(void)
++static int __set_pages_np(struct page *page, int numpages)
 +{
-+      unsigned long tr;
-+      asm volatile("str %0":"=r" (tr));
-+      return tr;
++      struct cpa_data cpa = { .vaddr = (unsigned long) page_address(page),
++                              .numpages = numpages,
++                              .mask_set = __pgprot(0),
++                              .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW)};
++
++      return __change_page_attr_set_clr(&cpa, 1);
 +}
 +
-+static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
++void kernel_map_pages(struct page *page, int numpages, int enable)
 +{
-+      unsigned int i;
-+      struct desc_struct *gdt = get_cpu_gdt_table(cpu);
++      if (PageHighMem(page))
++              return;
++      if (!enable) {
++              debug_check_no_locks_freed(page_address(page),
++                                         numpages * PAGE_SIZE);
++      }
++
++      /*
++       * If page allocator is not up yet then do not call c_p_a():
++       */
++      if (!debug_pagealloc_enabled)
++              return;
++
++      /*
++       * The return value is ignored as the calls cannot fail.
++       * Large pages are kept enabled at boot time, and are
++       * split up quickly with DEBUG_PAGEALLOC. If a splitup
++       * fails here (due to temporary memory shortage) no damage
++       * is done because we just keep the largepage intact up
++       * to the next attempt when it will likely be split up:
++       */
++      if (enable)
++              __set_pages_p(page, numpages);
++      else
++              __set_pages_np(page, numpages);
++
++      /*
++       * We should perform an IPI and flush all tlbs,
++       * but that can deadlock->flush only current cpu:
++       */
++      __flush_tlb_all();
 +
-+      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
-+              gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
++      /*
++       * Try to refill the page pool here. We can do this only after
++       * the tlb flush.
++       */
++      cpa_fill_pool(NULL);
 +}
-+#else
-+#define load_TLS(t, cpu) xen_load_tls(t, cpu)
-+#define set_ldt xen_set_ldt
 +
-+extern int write_ldt_entry(struct desc_struct *ldt, int entry,
-+                         const void *desc);
-+extern int write_gdt_entry(struct desc_struct *gdt, int entry,
-+                         const void *desc, int type);
++#ifdef CONFIG_HIBERNATION
 +
-+static inline void xen_load_tls(struct thread_struct *t, unsigned int cpu)
++bool kernel_page_present(struct page *page)
 +{
-+      unsigned int i;
-+      struct desc_struct *gdt = get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN;
++      unsigned int level;
++      pte_t *pte;
 +
-+      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
-+              if (HYPERVISOR_update_descriptor(virt_to_machine(&gdt[i]),
-+                                               *(u64 *)&t->tls_array[i]))
-+                      BUG();
++      if (PageHighMem(page))
++              return false;
++
++      pte = lookup_address((unsigned long)page_address(page), &level);
++      return (__pte_val(*pte) & _PAGE_PRESENT);
 +}
-+#endif
 +
-+#define _LDT_empty(info) (\
-+      (info)->base_addr       == 0    && \
-+      (info)->limit           == 0    && \
-+      (info)->contents        == 0    && \
-+      (info)->read_exec_only  == 1    && \
-+      (info)->seg_32bit       == 0    && \
-+      (info)->limit_in_pages  == 0    && \
-+      (info)->seg_not_present == 1    && \
-+      (info)->useable         == 0)
++#endif /* CONFIG_HIBERNATION */
++
++#endif /* CONFIG_DEBUG_PAGEALLOC */
 +
++static inline int in_secondary_range(unsigned long va)
++{
 +#ifdef CONFIG_X86_64
-+#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0))
++      return va >= VMALLOC_START && va < VMALLOC_END;
 +#else
-+#define LDT_empty(info) (_LDT_empty(info))
++      return va >= (unsigned long)high_memory;
 +#endif
-+
-+static inline void clear_LDT(void)
-+{
-+      set_ldt(NULL, 0);
 +}
 +
-+/*
-+ * load one particular LDT into the current CPU
-+ */
-+static inline void load_LDT_nolock(mm_context_t *pc)
++static void __make_page_readonly(unsigned long va)
 +{
-+      set_ldt(pc->ldt, pc->size);
-+}
++      pte_t *pte;
++      unsigned int level;
 +
-+static inline void load_LDT(mm_context_t *pc)
-+{
-+      preempt_disable();
-+      load_LDT_nolock(pc);
-+      preempt_enable();
-+}
++      pte = lookup_address(va, &level);
++      BUG_ON(!pte || level != PG_LEVEL_4K);
++      if (HYPERVISOR_update_va_mapping(va, pte_wrprotect(*pte), 0))
++              BUG();
++      if (in_secondary_range(va)) {
++              unsigned long pfn = pte_pfn(*pte);
 +
-+static inline unsigned long get_desc_base(const struct desc_struct *desc)
-+{
-+      return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
++#ifdef CONFIG_HIGHMEM
++              if (pfn >= highstart_pfn)
++                      kmap_flush_unused(); /* flush stale writable kmaps */
++              else
++#endif
++                      __make_page_readonly((unsigned long)__va(pfn << PAGE_SHIFT));
++      }
 +}
 +
-+static inline unsigned long get_desc_limit(const struct desc_struct *desc)
++static void __make_page_writable(unsigned long va)
 +{
-+      return desc->limit0 | (desc->limit << 16);
-+}
++      pte_t *pte;
++      unsigned int level;
 +
-+#ifndef CONFIG_X86_NO_IDT
-+static inline void _set_gate(int gate, unsigned type, void *addr,
-+                            unsigned dpl, unsigned ist, unsigned seg)
-+{
-+      gate_desc s;
-+      pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
-+      /*
-+       * does not need to be atomic because it is only done once at
-+       * setup time
-+       */
-+      write_idt_entry(idt_table, gate, &s);
-+}
++      pte = lookup_address(va, &level);
++      BUG_ON(!pte || level != PG_LEVEL_4K);
++      if (HYPERVISOR_update_va_mapping(va, pte_mkwrite(*pte), 0))
++              BUG();
++      if (in_secondary_range(va)) {
++              unsigned long pfn = pte_pfn(*pte);
 +
-+/*
-+ * This needs to use 'idt_table' rather than 'idt', and
-+ * thus use the _nonmapped_ version of the IDT, as the
-+ * Pentium F0 0F bugfix can have resulted in the mapped
-+ * IDT being write-protected.
-+ */
-+static inline void set_intr_gate(unsigned int n, void *addr)
-+{
-+      BUG_ON((unsigned)n > 0xFF);
-+      _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
++#ifdef CONFIG_HIGHMEM
++              if (pfn < highstart_pfn)
++#endif
++                      __make_page_writable((unsigned long)__va(pfn << PAGE_SHIFT));
++      }
 +}
 +
-+/*
-+ * This routine sets up an interrupt gate at directory privilege level 3.
-+ */
-+static inline void set_system_intr_gate(unsigned int n, void *addr)
++void make_page_readonly(void *va, unsigned int feature)
 +{
-+      BUG_ON((unsigned)n > 0xFF);
-+      _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
++      if (!xen_feature(feature))
++              __make_page_readonly((unsigned long)va);
 +}
 +
-+static inline void set_trap_gate(unsigned int n, void *addr)
++void make_page_writable(void *va, unsigned int feature)
 +{
-+      BUG_ON((unsigned)n > 0xFF);
-+      _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
++      if (!xen_feature(feature))
++              __make_page_writable((unsigned long)va);
 +}
 +
-+static inline void set_system_gate(unsigned int n, void *addr)
++void make_pages_readonly(void *va, unsigned int nr, unsigned int feature)
 +{
-+      BUG_ON((unsigned)n > 0xFF);
- #ifdef CONFIG_X86_32
--# include "desc_32.h"
-+      _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
-+#else
-+      _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
-+#endif
-+}
++      unsigned long addr;
 +
-+static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
-+{
-+      BUG_ON((unsigned)n > 0xFF);
-+      _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3));
-+}
++      if (xen_feature(feature))
++              return;
 +
-+static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
-+{
-+      BUG_ON((unsigned)n > 0xFF);
-+      _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
++      for (addr = (unsigned long)va; nr--; addr += PAGE_SIZE)
++              __make_page_readonly(addr);
 +}
 +
-+static inline void set_system_gate_ist(int n, void *addr, unsigned ist)
++void make_pages_writable(void *va, unsigned int nr, unsigned int feature)
 +{
-+      BUG_ON((unsigned)n > 0xFF);
-+      _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
++      unsigned long addr;
++
++      if (xen_feature(feature))
++              return;
++
++      for (addr = (unsigned long)va; nr--; addr += PAGE_SIZE)
++              __make_page_writable(addr);
 +}
-+#endif
 +
- #else
--# include "desc_64.h"
 +/*
-+ * GET_DESC_BASE reads the descriptor base of the specified segment.
-+ *
-+ * Args:
-+ *    idx - descriptor index
-+ *    gdt - GDT pointer
-+ *    base - 32bit register to which the base will be written
-+ *    lo_w - lo word of the "base" register
-+ *    lo_b - lo byte of the "base" register
-+ *    hi_b - hi byte of the low word of the "base" register
-+ *
-+ * Example:
-+ *    GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
-+ *    Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax.
++ * The testcases use internal knowledge of the implementation that shouldn't
++ * be exposed to the rest of the kernel. Include these directly here.
 + */
-+#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \
-+      movb idx*8+4(gdt), lo_b; \
-+      movb idx*8+7(gdt), hi_b; \
-+      shll $16, base; \
-+      movw idx*8+2(gdt), lo_w;
-+
-+
-+#endif /* __ASSEMBLY__ */
-+
- #endif
---- a/include/asm-x86/mach-xen/asm/dma-mapping_32.h
-+++ b/include/asm-x86/mach-xen/asm/dma-mapping_32.h
-@@ -84,23 +84,13 @@ dma_sync_single_range_for_device(struct 
-       dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
- }
--static inline void
-+extern void
- dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
--                  enum dma_data_direction direction)
++#ifdef CONFIG_CPA_DEBUG
++#include "pageattr-test.c"
++#endif
+--- sle11-2009-05-14.orig/arch/x86/mm/pageattr_64-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,542 +0,0 @@
+-/* 
+- * Copyright 2002 Andi Kleen, SuSE Labs. 
+- * Thanks to Ben LaHaise for precious feedback.
+- */ 
+-
+-#include <linux/mm.h>
+-#include <linux/sched.h>
+-#include <linux/highmem.h>
+-#include <linux/module.h>
+-#include <linux/slab.h>
+-#include <asm/uaccess.h>
+-#include <asm/processor.h>
+-#include <asm/tlbflush.h>
+-#include <asm/io.h>
+-
+-#ifdef CONFIG_XEN
+-#include <asm/pgalloc.h>
+-#include <asm/mmu_context.h>
+-
+-static void _pin_lock(struct mm_struct *mm, int lock) {
+-      if (lock)
+-              spin_lock(&mm->page_table_lock);
+-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+-      /* While mm->page_table_lock protects us against insertions and
+-       * removals of higher level page table pages, it doesn't protect
+-       * against updates of pte-s. Such updates, however, require the
+-       * pte pages to be in consistent state (unpinned+writable or
+-       * pinned+readonly). The pinning and attribute changes, however
+-       * cannot be done atomically, which is why such updates must be
+-       * prevented from happening concurrently.
+-       * Note that no pte lock can ever elsewhere be acquired nesting
+-       * with an already acquired one in the same mm, or with the mm's
+-       * page_table_lock already acquired, as that would break in the
+-       * non-split case (where all these are actually resolving to the
+-       * one page_table_lock). Thus acquiring all of them here is not
+-       * going to result in dead locks, and the order of acquires
+-       * doesn't matter.
+-       */
+-      {
+-              pgd_t *pgd = mm->pgd;
+-              unsigned g;
+-
+-              for (g = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
+-                      pud_t *pud;
+-                      unsigned u;
+-
+-                      if (pgd_none(*pgd))
+-                              continue;
+-                      pud = pud_offset(pgd, 0);
+-                      for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
+-                              pmd_t *pmd;
+-                              unsigned m;
+-
+-                              if (pud_none(*pud))
+-                                      continue;
+-                              pmd = pmd_offset(pud, 0);
+-                              for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
+-                                      spinlock_t *ptl;
+-
+-                                      if (pmd_none(*pmd))
+-                                              continue;
+-                                      ptl = pte_lockptr(0, pmd);
+-                                      if (lock)
+-                                              spin_lock(ptl);
+-                                      else
+-                                              spin_unlock(ptl);
+-                              }
+-                      }
+-              }
+-      }
+-#endif
+-      if (!lock)
+-              spin_unlock(&mm->page_table_lock);
+-}
+-#define pin_lock(mm) _pin_lock(mm, 1)
+-#define pin_unlock(mm) _pin_lock(mm, 0)
+-
+-#define PIN_BATCH 8
+-static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl);
+-
+-static inline unsigned int pgd_walk_set_prot(void *pt, pgprot_t flags,
+-                                           unsigned int cpu, unsigned int seq)
+-{
+-      struct page *page = virt_to_page(pt);
+-      unsigned long pfn = page_to_pfn(page);
+-
+-      MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
+-              (unsigned long)__va(pfn << PAGE_SHIFT),
+-              pfn_pte(pfn, flags), 0);
+-      if (unlikely(++seq == PIN_BATCH)) {
+-              if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
+-                                                      PIN_BATCH, NULL)))
+-                      BUG();
+-              seq = 0;
+-      }
+-
+-      return seq;
+-}
+-
+-static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
+-{
+-      pgd_t       *pgd = pgd_base;
+-      pud_t       *pud;
+-      pmd_t       *pmd;
+-      pte_t       *pte;
+-      int          g,u,m;
+-      unsigned int cpu, seq;
+-      multicall_entry_t *mcl;
+-
+-      cpu = get_cpu();
+-
+-      /*
+-       * Cannot iterate up to USER_PTRS_PER_PGD as these pagetables may not
+-       * be the 'current' task's pagetables (e.g., current may be 32-bit,
+-       * but the pagetables may be for a 64-bit task).
+-       * Subtracting 1 from TASK_SIZE64 means the loop limit is correct
+-       * regardless of whether TASK_SIZE64 is a multiple of PGDIR_SIZE.
+-       */
+-      for (g = 0, seq = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
+-              if (pgd_none(*pgd))
+-                      continue;
+-              pud = pud_offset(pgd, 0);
+-              if (PTRS_PER_PUD > 1) /* not folded */ 
+-                      seq = pgd_walk_set_prot(pud,flags,cpu,seq);
+-              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
+-                      if (pud_none(*pud))
+-                              continue;
+-                      pmd = pmd_offset(pud, 0);
+-                      if (PTRS_PER_PMD > 1) /* not folded */ 
+-                              seq = pgd_walk_set_prot(pmd,flags,cpu,seq);
+-                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
+-                              if (pmd_none(*pmd))
+-                                      continue;
+-                              pte = pte_offset_kernel(pmd,0);
+-                              seq = pgd_walk_set_prot(pte,flags,cpu,seq);
+-                      }
+-              }
+-      }
+-
+-      mcl = per_cpu(pb_mcl, cpu);
+-      if (unlikely(seq > PIN_BATCH - 2)) {
+-              if (unlikely(HYPERVISOR_multicall_check(mcl, seq, NULL)))
+-                      BUG();
+-              seq = 0;
+-      }
+-      MULTI_update_va_mapping(mcl + seq,
+-             (unsigned long)__user_pgd(pgd_base),
+-             pfn_pte(virt_to_phys(__user_pgd(pgd_base))>>PAGE_SHIFT, flags),
+-             0);
+-      MULTI_update_va_mapping(mcl + seq + 1,
+-             (unsigned long)pgd_base,
+-             pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
+-             UVMF_TLB_FLUSH);
+-      if (unlikely(HYPERVISOR_multicall_check(mcl, seq + 2, NULL)))
+-              BUG();
+-
+-      put_cpu();
+-}
+-
+-static void __pgd_pin(pgd_t *pgd)
+-{
+-      pgd_walk(pgd, PAGE_KERNEL_RO);
+-      xen_pgd_pin(__pa(pgd)); /* kernel */
+-      xen_pgd_pin(__pa(__user_pgd(pgd))); /* user */
+-      SetPagePinned(virt_to_page(pgd));
+-}
+-
+-static void __pgd_unpin(pgd_t *pgd)
+-{
+-      xen_pgd_unpin(__pa(pgd));
+-      xen_pgd_unpin(__pa(__user_pgd(pgd)));
+-      pgd_walk(pgd, PAGE_KERNEL);
+-      ClearPagePinned(virt_to_page(pgd));
+-}
+-
+-void pgd_test_and_unpin(pgd_t *pgd)
+-{
+-      if (PagePinned(virt_to_page(pgd)))
+-              __pgd_unpin(pgd);
+-}
+-
+-void mm_pin(struct mm_struct *mm)
+-{
+-      if (xen_feature(XENFEAT_writable_page_tables))
+-              return;
+-
+-      pin_lock(mm);
+-      __pgd_pin(mm->pgd);
+-      pin_unlock(mm);
+-}
+-
+-void mm_unpin(struct mm_struct *mm)
+-{
+-      if (xen_feature(XENFEAT_writable_page_tables))
+-              return;
+-
+-      pin_lock(mm);
+-      __pgd_unpin(mm->pgd);
+-      pin_unlock(mm);
+-}
+-
+-void mm_pin_all(void)
+-{
+-      struct page *page;
+-      unsigned long flags;
+-
+-      if (xen_feature(XENFEAT_writable_page_tables))
+-              return;
+-
+-      /*
+-       * Allow uninterrupted access to the pgd_list. Also protects
+-       * __pgd_pin() by disabling preemption.
+-       * All other CPUs must be at a safe point (e.g., in stop_machine
+-       * or offlined entirely).
+-       */
+-      spin_lock_irqsave(&pgd_lock, flags);
+-      list_for_each_entry(page, &pgd_list, lru) {
+-              if (!PagePinned(page))
+-                      __pgd_pin((pgd_t *)page_address(page));
+-      }
+-      spin_unlock_irqrestore(&pgd_lock, flags);
+-}
+-
+-void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
+-{
+-      if (!PagePinned(virt_to_page(mm->pgd)))
+-              mm_pin(mm);
+-}
+-
+-void arch_exit_mmap(struct mm_struct *mm)
+-{
+-      struct task_struct *tsk = current;
+-
+-      task_lock(tsk);
+-
+-      /*
+-       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
+-       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
+-       */
+-      if (tsk->active_mm == mm) {
+-              tsk->active_mm = &init_mm;
+-              atomic_inc(&init_mm.mm_count);
+-
+-              switch_mm(mm, &init_mm, tsk);
+-
+-              atomic_dec(&mm->mm_count);
+-              BUG_ON(atomic_read(&mm->mm_count) == 0);
+-      }
+-
+-      task_unlock(tsk);
+-
+-      if (PagePinned(virt_to_page(mm->pgd))
+-          && (atomic_read(&mm->mm_count) == 1)
+-          && !mm->context.has_foreign_mappings)
+-              mm_unpin(mm);
+-}
+-
+-static void _pte_free(struct page *page, unsigned int order)
+-{
+-      BUG_ON(order);
+-      pte_free(page);
+-}
+-
+-struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+-{
+-      struct page *pte;
+-
+-      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
+-      if (pte) {
+-              SetPageForeign(pte, _pte_free);
+-              init_page_count(pte);
+-      }
+-      return pte;
+-}
+-
+-void pte_free(struct page *pte)
+-{
+-      unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
+-
+-      if (!pte_write(*virt_to_ptep(va)))
+-              if (HYPERVISOR_update_va_mapping(
+-                      va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0))
+-                      BUG();
+-
+-      ClearPageForeign(pte);
+-      init_page_count(pte);
+-
+-      __free_page(pte);
+-}
+-#endif        /* CONFIG_XEN */
+-
+-pte_t *lookup_address(unsigned long address) 
+-{ 
+-      pgd_t *pgd = pgd_offset_k(address);
+-      pud_t *pud;
+-      pmd_t *pmd;
+-      pte_t *pte;
+-      if (pgd_none(*pgd))
+-              return NULL;
+-      pud = pud_offset(pgd, address);
+-      if (!pud_present(*pud))
+-              return NULL; 
+-      pmd = pmd_offset(pud, address);
+-      if (!pmd_present(*pmd))
+-              return NULL; 
+-      if (pmd_large(*pmd))
+-              return (pte_t *)pmd;
+-      pte = pte_offset_kernel(pmd, address);
+-      if (pte && !pte_present(*pte))
+-              pte = NULL; 
+-      return pte;
+-} 
+-
+-static struct page *split_large_page(unsigned long address, pgprot_t prot,
+-                                   pgprot_t ref_prot)
+-{ 
+-      int i; 
+-      unsigned long addr;
+-      struct page *base = alloc_pages(GFP_KERNEL, 0);
+-      pte_t *pbase;
+-      if (!base) 
+-              return NULL;
+-      /*
+-       * page_private is used to track the number of entries in
+-       * the page table page have non standard attributes.
+-       */
+-      SetPagePrivate(base);
+-      page_private(base) = 0;
+-
+-      address = __pa(address);
+-      addr = address & LARGE_PAGE_MASK; 
+-      pbase = (pte_t *)page_address(base);
+-      for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
+-              pbase[i] = pfn_pte(addr >> PAGE_SHIFT, 
+-                                 addr == address ? prot : ref_prot);
+-      }
+-      return base;
+-} 
+-
+-void clflush_cache_range(void *adr, int size)
 -{
--      if (swiotlb)
--              swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
--      flush_write_buffers();
+-      int i;
+-      for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
+-              clflush(adr+i);
 -}
-+                  enum dma_data_direction direction);
+-
+-static void flush_kernel_map(void *arg)
+-{
+-      struct list_head *l = (struct list_head *)arg;
+-      struct page *pg;
+-
+-      /* When clflush is available always use it because it is
+-         much cheaper than WBINVD. */
+-      /* clflush is still broken. Disable for now. */
+-      if (1 || !cpu_has_clflush)
+-              asm volatile("wbinvd" ::: "memory");
+-      else list_for_each_entry(pg, l, lru) {
+-              void *adr = page_address(pg);
+-              clflush_cache_range(adr, PAGE_SIZE);
+-      }
+-      __flush_tlb_all();
+-}
+-
+-static inline void flush_map(struct list_head *l)
+-{     
+-      on_each_cpu(flush_kernel_map, l, 1, 1);
+-}
+-
+-static LIST_HEAD(deferred_pages); /* protected by init_mm.mmap_sem */
+-
+-static inline void save_page(struct page *fpage)
+-{
+-      if (!test_and_set_bit(PG_arch_1, &fpage->flags))
+-              list_add(&fpage->lru, &deferred_pages);
+-}
+-
+-/* 
+- * No more special protections in this 2/4MB area - revert to a
+- * large page again. 
+- */
+-static void revert_page(unsigned long address, pgprot_t ref_prot)
+-{
+-      pgd_t *pgd;
+-      pud_t *pud;
+-      pmd_t *pmd;
+-      pte_t large_pte;
+-      unsigned long pfn;
+-
+-      pgd = pgd_offset_k(address);
+-      BUG_ON(pgd_none(*pgd));
+-      pud = pud_offset(pgd,address);
+-      BUG_ON(pud_none(*pud));
+-      pmd = pmd_offset(pud, address);
+-      BUG_ON(__pmd_val(*pmd) & _PAGE_PSE);
+-      pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
+-      large_pte = pfn_pte(pfn, ref_prot);
+-      large_pte = pte_mkhuge(large_pte);
+-      set_pte((pte_t *)pmd, large_pte);
+-}      
+-
+-static int
+-__change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
+-                                 pgprot_t ref_prot)
+-{ 
+-      pte_t *kpte; 
+-      struct page *kpte_page;
+-      pgprot_t ref_prot2;
+-
+-      kpte = lookup_address(address);
+-      if (!kpte) return 0;
+-      kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+-      BUG_ON(PageLRU(kpte_page));
+-      BUG_ON(PageCompound(kpte_page));
+-      if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
+-              if (!pte_huge(*kpte)) {
+-                      set_pte(kpte, pfn_pte(pfn, prot));
+-              } else {
+-                      /*
+-                       * split_large_page will take the reference for this
+-                       * change_page_attr on the split page.
+-                       */
+-                      struct page *split;
+-                      ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
+-                      split = split_large_page(address, prot, ref_prot2);
+-                      if (!split)
+-                              return -ENOMEM;
+-                      pgprot_val(ref_prot2) &= ~_PAGE_NX;
+-                      set_pte(kpte, mk_pte(split, ref_prot2));
+-                      kpte_page = split;
+-              }
+-              page_private(kpte_page)++;
+-      } else if (!pte_huge(*kpte)) {
+-              set_pte(kpte, pfn_pte(pfn, ref_prot));
+-              BUG_ON(page_private(kpte_page) == 0);
+-              page_private(kpte_page)--;
+-      } else
+-              BUG();
+-
+-      /* on x86-64 the direct mapping set at boot is not using 4k pages */
+-      /*
+-       * ..., but the XEN guest kernels (currently) do:
+-       * If the pte was reserved, it means it was created at boot
+-       * time (not via split_large_page) and in turn we must not
+-       * replace it with a large page.
+-       */
+-#ifndef CONFIG_XEN
+-      BUG_ON(PageReserved(kpte_page));
+-#else
+-      if (PageReserved(kpte_page))
+-              return 0;
+-#endif
+-
+-      save_page(kpte_page);
+-      if (page_private(kpte_page) == 0)
+-              revert_page(address, ref_prot);
+-      return 0;
+-} 
+-
+-/*
+- * Change the page attributes of an page in the linear mapping.
+- *
+- * This should be used when a page is mapped with a different caching policy
+- * than write-back somewhere - some CPUs do not like it when mappings with
+- * different caching policies exist. This changes the page attributes of the
+- * in kernel linear mapping too.
+- * 
+- * The caller needs to ensure that there are no conflicting mappings elsewhere.
+- * This function only deals with the kernel linear map.
+- * 
+- * Caller must call global_flush_tlb() after this.
+- */
+-int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
+-{
+-      int err = 0, kernel_map = 0;
+-      int i; 
+-
+-      if (address >= __START_KERNEL_map
+-          && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) {
+-              address = (unsigned long)__va(__pa(address));
+-              kernel_map = 1;
+-      }
+-
+-      down_write(&init_mm.mmap_sem);
+-      for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
+-              unsigned long pfn = __pa(address) >> PAGE_SHIFT;
+-
+-              if (!kernel_map || pte_present(pfn_pte(0, prot))) {
+-                      err = __change_page_attr(address, pfn, prot, PAGE_KERNEL);
+-                      if (err)
+-                              break;
+-              }
+-              /* Handle kernel mapping too which aliases part of the
+-               * lowmem */
+-              if (__pa(address) < KERNEL_TEXT_SIZE) {
+-                      unsigned long addr2;
+-                      pgprot_t prot2;
+-                      addr2 = __START_KERNEL_map + __pa(address);
+-                      /* Make sure the kernel mappings stay executable */
+-                      prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
+-                      err = __change_page_attr(addr2, pfn, prot2,
+-                                               PAGE_KERNEL_EXEC);
+-              } 
+-      }       
+-      up_write(&init_mm.mmap_sem); 
+-      return err;
+-}
+-
+-/* Don't call this for MMIO areas that may not have a mem_map entry */
+-int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+-{
+-      unsigned long addr = (unsigned long)page_address(page);
+-      return change_page_attr_addr(addr, numpages, prot);
+-}
+-
+-void global_flush_tlb(void)
+-{ 
+-      struct page *pg, *next;
+-      struct list_head l;
+-
+-      /*
+-       * Write-protect the semaphore, to exclude two contexts
+-       * doing a list_replace_init() call in parallel and to
+-       * exclude new additions to the deferred_pages list:
+-       */
+-      down_write(&init_mm.mmap_sem);
+-      list_replace_init(&deferred_pages, &l);
+-      up_write(&init_mm.mmap_sem);
+-
+-      flush_map(&l);
+-
+-      list_for_each_entry_safe(pg, next, &l, lru) {
+-              list_del(&pg->lru);
+-              clear_bit(PG_arch_1, &pg->flags);
+-              if (page_private(pg) != 0)
+-                      continue;
+-              ClearPagePrivate(pg);
+-              __free_page(pg);
+-      } 
+-} 
+-
+-EXPORT_SYMBOL(change_page_attr);
+-EXPORT_SYMBOL(global_flush_tlb);
+--- sle11-2009-05-14.orig/arch/x86/mm/pgtable_32-xen.c 2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/mm/pgtable_32-xen.c      2009-03-16 16:33:40.000000000 +0100
+@@ -29,8 +29,6 @@
+ #include <xen/features.h>
+ #include <asm/hypervisor.h>
+-static void pgd_test_and_unpin(pgd_t *pgd);
+-
+ void show_mem(void)
+ {
+       int total = 0, reserved = 0;
+@@ -167,53 +165,6 @@ pte_t *pte_alloc_one_kernel(struct mm_st
+       return pte;
+ }
  
--static inline void
-+extern void
- dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
--                  enum dma_data_direction direction)
+-static void _pte_free(struct page *page, unsigned int order)
 -{
--      if (swiotlb)
--              swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
--      flush_write_buffers();
+-      BUG_ON(order);
+-      pte_free(page);
 -}
-+                  enum dma_data_direction direction);
- extern int
- dma_mapping_error(dma_addr_t dma_addr);
---- a/include/asm-x86/mach-xen/asm/fixmap_32.h
-+++ b/include/asm-x86/mach-xen/asm/fixmap_32.h
-@@ -64,7 +64,7 @@ enum fixed_addresses {
- #endif
- #ifdef CONFIG_X86_VISWS_APIC
-       FIX_CO_CPU,     /* Cobalt timer */
--      FIX_CO_APIC,    /* Cobalt APIC Redirection Table */ 
-+      FIX_CO_APIC,    /* Cobalt APIC Redirection Table */
-       FIX_LI_PCIA,    /* Lithium PCI Bridge A */
-       FIX_LI_PCIB,    /* Lithium PCI Bridge B */
- #endif
-@@ -73,7 +73,7 @@ enum fixed_addresses {
- #endif
- #ifdef CONFIG_X86_CYCLONE_TIMER
-       FIX_CYCLONE_TIMER, /*cyclone timer register*/
--#endif 
-+#endif
- #ifdef CONFIG_HIGHMEM
-       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
-       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
-@@ -93,11 +93,23 @@ enum fixed_addresses {
-       FIX_ISAMAP_END,
-       FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
-       __end_of_permanent_fixed_addresses,
--      /* temporary boot-time mappings, used before ioremap() is functional */
--#define NR_FIX_BTMAPS 16
--      FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
--      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
-+      /*
-+       * 256 temporary boot-time mappings, used by early_ioremap(),
-+       * before ioremap() is functional.
-+       *
-+       * We round it up to the next 512 pages boundary so that we
-+       * can have a single pgd entry and a single pte table:
-+       */
-+#define NR_FIX_BTMAPS         64
-+#define FIX_BTMAPS_NESTING    4
-+      FIX_BTMAP_END =
-+              __end_of_permanent_fixed_addresses + 512 -
-+                      (__end_of_permanent_fixed_addresses & 511),
-+      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
-       FIX_WP_TEST,
-+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-+      FIX_OHCI1394_BASE,
-+#endif
-       __end_of_fixed_addresses
- };
---- a/include/asm-x86/mach-xen/asm/fixmap_64.h
-+++ b/include/asm-x86/mach-xen/asm/fixmap_64.h
-@@ -15,6 +15,7 @@
- #include <asm/apicdef.h>
- #include <asm/page.h>
- #include <asm/vsyscall.h>
-+#include <asm/efi.h>
- #include <asm/acpi.h>
- /*
-@@ -46,6 +47,10 @@ enum fixed_addresses {
-       FIX_IO_APIC_BASE_0,
-       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
- #endif
-+#ifdef CONFIG_EFI
-+      FIX_EFI_IO_MAP_LAST_PAGE,
-+      FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1,
-+#endif
- #ifdef CONFIG_ACPI
-       FIX_ACPI_BEGIN,
-       FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
-@@ -55,10 +60,22 @@ enum fixed_addresses {
-       FIX_ISAMAP_END,
-       FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
-       __end_of_permanent_fixed_addresses,
--      /* temporary boot-time mappings, used before ioremap() is functional */
--#define NR_FIX_BTMAPS 16
--      FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
--      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
-+      /*
-+       * 256 temporary boot-time mappings, used by early_ioremap(),
-+       * before ioremap() is functional.
-+       *
-+       * We round it up to the next 512 pages boundary so that we
-+       * can have a single pgd entry and a single pte table:
-+       */
-+#define NR_FIX_BTMAPS         64
-+#define FIX_BTMAPS_NESTING    4
-+      FIX_BTMAP_END =
-+              __end_of_permanent_fixed_addresses + 512 -
-+                      (__end_of_permanent_fixed_addresses & 511),
-+      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
-+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-+      FIX_OHCI1394_BASE,
-+#endif
-       __end_of_fixed_addresses
- };
---- a/include/asm-x86/mach-xen/asm/highmem.h
-+++ b/include/asm-x86/mach-xen/asm/highmem.h
-@@ -37,11 +37,6 @@ extern pte_t *pkmap_page_table;
-  * easily, subsequent pte tables have to be allocated in one physical
-  * chunk of RAM.
-  */
--#ifdef CONFIG_X86_PAE
--#define LAST_PKMAP 512
+-
+-struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+-{
+-      struct page *pte;
+-
+-#ifdef CONFIG_HIGHPTE
+-      pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
 -#else
--#define LAST_PKMAP 1024
+-      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 -#endif
+-      if (pte) {
+-              SetPageForeign(pte, _pte_free);
+-              init_page_count(pte);
+-      }
+-      return pte;
+-}
+-
+-void pte_free(struct page *pte)
+-{
+-      unsigned long pfn = page_to_pfn(pte);
+-
+-      if (!PageHighMem(pte)) {
+-              unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
+-
+-              if (!pte_write(*virt_to_ptep(va)))
+-                      if (HYPERVISOR_update_va_mapping(
+-                              va, pfn_pte(pfn, PAGE_KERNEL), 0))
+-                              BUG();
+-      } else
+-              ClearPagePinned(pte);
+-
+-      ClearPageForeign(pte);
+-      init_page_count(pte);
+-
+-      __free_page(pte);
+-}
+-
+-void pmd_ctor(struct kmem_cache *cache, void *pmd)
+-{
+-      memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+-}
+-
  /*
-  * Ordering is:
-  *
-@@ -57,13 +52,12 @@ extern pte_t *pkmap_page_table;
-  * VMALLOC_START
-  * high_memory
+  * List of all pgd's needed for non-PAE so it can invalidate entries
+  * in both cached and uncached pgd's; not needed for PAE since the
+@@ -224,224 +175,191 @@ void pmd_ctor(struct kmem_cache *cache, 
+  * vmalloc faults work because attached pagetables are never freed.
+  * -- wli
   */
--#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK )
- #define LAST_PKMAP_MASK (LAST_PKMAP-1)
- #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
- #define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+-DEFINE_SPINLOCK(pgd_lock);
+-struct page *pgd_list;
+-
+ static inline void pgd_list_add(pgd_t *pgd)
+ {
+       struct page *page = virt_to_page(pgd);
+-      page->index = (unsigned long)pgd_list;
+-      if (pgd_list)
+-              set_page_private(pgd_list, (unsigned long)&page->index);
+-      pgd_list = page;
+-      set_page_private(page, (unsigned long)&pgd_list);
++
++      list_add(&page->lru, &pgd_list);
+ }
  
--extern void * FASTCALL(kmap_high(struct page *page));
--extern void FASTCALL(kunmap_high(struct page *page));
-+extern void *kmap_high(struct page *page);
-+extern void kunmap_high(struct page *page);
+ static inline void pgd_list_del(pgd_t *pgd)
+ {
+-      struct page *next, **pprev, *page = virt_to_page(pgd);
+-      next = (struct page *)page->index;
+-      pprev = (struct page **)page_private(page);
+-      *pprev = next;
+-      if (next)
+-              set_page_private(next, (unsigned long)pprev);
+-}
++      struct page *page = virt_to_page(pgd);
  
- void *kmap(struct page *page);
- void kunmap(struct page *page);
---- a/include/asm-x86/mach-xen/asm/hypervisor.h
-+++ b/include/asm-x86/mach-xen/asm/hypervisor.h
-@@ -264,6 +264,25 @@ HYPERVISOR_poll(
-       return rc;
- }
++      list_del(&page->lru);
++}
  
-+static inline int __must_check
-+HYPERVISOR_poll_no_timeout(
-+      evtchn_port_t *ports, unsigned int nr_ports)
-+{
-+      int rc;
-+      struct sched_poll sched_poll = {
-+              .nr_ports = nr_ports
-+      };
-+      set_xen_guest_handle(sched_poll.ports, ports);
++#define UNSHARED_PTRS_PER_PGD                         \
++      (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD)
+-#if (PTRS_PER_PMD == 1)
+-/* Non-PAE pgd constructor */
+-static void pgd_ctor(void *pgd)
++static void pgd_ctor(void *p)
+ {
++      pgd_t *pgd = p;
+       unsigned long flags;
+-      /* !PAE, no pagetable sharing */
++      pgd_test_and_unpin(pgd);
 +
-+      rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
-+#if CONFIG_XEN_COMPAT <= 0x030002
-+      if (rc == -ENOSYS)
-+              rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
-+#endif
++      /* Clear usermode parts of PGD */
+       memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
+       spin_lock_irqsave(&pgd_lock, flags);
+-      /* must happen under lock */
+-      clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
+-                      swapper_pg_dir + USER_PTRS_PER_PGD,
+-                      KERNEL_PGD_PTRS);
+-
+-      paravirt_alloc_pd_clone(__pa(pgd) >> PAGE_SHIFT,
+-                              __pa(swapper_pg_dir) >> PAGE_SHIFT,
+-                              USER_PTRS_PER_PGD,
+-                              KERNEL_PGD_PTRS);
+-      pgd_list_add(pgd);
+-      spin_unlock_irqrestore(&pgd_lock, flags);
+-}
+-#else  /* PTRS_PER_PMD > 1 */
+-/* PAE pgd constructor */
+-static void pgd_ctor(void *pgd)
+-{
+-      /* PAE, kernel PMD may be shared */
+-
+-      if (SHARED_KERNEL_PMD) {
+-              clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
++      /* If the pgd points to a shared pagetable level (either the
++         ptes in non-PAE, or shared PMD in PAE), then just copy the
++         references from swapper_pg_dir. */
++      if (PAGETABLE_LEVELS == 2 ||
++          (PAGETABLE_LEVELS == 3 && SHARED_KERNEL_PMD)) {
++              clone_pgd_range(pgd + USER_PTRS_PER_PGD,
+                               swapper_pg_dir + USER_PTRS_PER_PGD,
+                               KERNEL_PGD_PTRS);
+-      } else {
+-              memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++              paravirt_alloc_pd_clone(__pa(pgd) >> PAGE_SHIFT,
++                                      __pa(swapper_pg_dir) >> PAGE_SHIFT,
++                                      USER_PTRS_PER_PGD,
++                                      KERNEL_PGD_PTRS);
+       }
 +
-+      return rc;
-+}
++      /* list required to sync kernel mapping updates */
++      if (PAGETABLE_LEVELS == 2)
++              pgd_list_add(pgd);
 +
- #ifdef CONFIG_XEN
++      spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+-#endif        /* PTRS_PER_PMD */
  
- static inline void
---- a/include/asm-x86/mach-xen/asm/io_32.h
-+++ b/include/asm-x86/mach-xen/asm/io_32.h
-@@ -113,8 +113,6 @@ static inline void * phys_to_virt(unsign
-        ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
-         bvec_to_pseudophys((vec2))))
+ static void pgd_dtor(void *pgd)
+ {
+       unsigned long flags; /* can be called from interrupt context */
  
--extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+-      if (SHARED_KERNEL_PMD)
+-              return;
 -
- /**
-  * ioremap     -   map bus memory into CPU space
-  * @offset:    bus address of the memory
-@@ -124,32 +122,39 @@ extern void __iomem * __ioremap(unsigned
-  * make bus memory CPU accessible via the readb/readw/readl/writeb/
-  * writew/writel functions and the other mmio helpers. The returned
-  * address is not guaranteed to be usable directly as a virtual
-- * address. 
-+ * address.
-  *
-  * If the area you are trying to map is a PCI BAR you should have a
-  * look at pci_iomap().
-  */
-+extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
-+extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
+-      paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT);
+-      spin_lock_irqsave(&pgd_lock, flags);
+-      pgd_list_del(pgd);
+-      spin_unlock_irqrestore(&pgd_lock, flags);
++      if (!SHARED_KERNEL_PMD) {
++              spin_lock_irqsave(&pgd_lock, flags);
++              pgd_list_del(pgd);
++              spin_unlock_irqrestore(&pgd_lock, flags);
++      }
  
--static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+       pgd_test_and_unpin(pgd);
+ }
+-#define UNSHARED_PTRS_PER_PGD                         \
+-      (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD)
+-
+-/* If we allocate a pmd for part of the kernel address space, then
+-   make sure its initialized with the appropriate kernel mappings.
+-   Otherwise use a cached zeroed pmd.  */
+-static pmd_t *pmd_cache_alloc(int idx)
++#ifdef CONFIG_X86_PAE
 +/*
-+ * The default ioremap() behavior is non-cached:
++ * Mop up any pmd pages which may still be attached to the pgd.
++ * Normally they will be freed by munmap/exit_mmap, but any pmd we
++ * preallocate which never got a corresponding vma will need to be
++ * freed manually.
 + */
-+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
++static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
  {
--      return __ioremap(offset, size, 0);
-+      return ioremap_nocache(offset, size);
+-      pmd_t *pmd;
++      int i;
+-      if (idx >= USER_PTRS_PER_PGD) {
+-              pmd = (pmd_t *)__get_free_page(GFP_KERNEL);
++      for(i = 0; i < UNSHARED_PTRS_PER_PGD; i++) {
++              pgd_t pgd = pgdp[i];
+-#ifndef CONFIG_XEN
+-              if (pmd)
+-                      memcpy(pmd,
+-                             (void *)pgd_page_vaddr(swapper_pg_dir[idx]),
+-                             sizeof(pmd_t) * PTRS_PER_PMD);
+-#endif
+-      } else
+-              pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
++              if (__pgd_val(pgd) != 0) {
++                      pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
+-      return pmd;
+-}
++                      pgdp[i] = xen_make_pgd(0);
+-static void pmd_cache_free(pmd_t *pmd, int idx)
+-{
+-      if (idx >= USER_PTRS_PER_PGD) {
+-              make_lowmem_page_writable(pmd, XENFEAT_writable_page_tables);
+-              memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+-              free_page((unsigned long)pmd);
+-      } else
+-              kmem_cache_free(pmd_cache, pmd);
++                      paravirt_release_pd(pgd_val(pgd) >> PAGE_SHIFT);
++                      pmd_free(mm, pmd);
++              }
++      }
  }
  
--extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
- extern void iounmap(volatile void __iomem *addr);
+-pgd_t *pgd_alloc(struct mm_struct *mm)
++/*
++ * In PAE mode, we need to do a cr3 reload (=tlb flush) when
++ * updating the top-level pagetable entries to guarantee the
++ * processor notices the update.  Since this is expensive, and
++ * all 4 top-level entries are used almost immediately in a
++ * new process's life, we just pre-populate them here.
++ *
++ * Also, if we're in a paravirt environment where the kernel pmd is
++ * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
++ * and initialize the kernel pmds here.
++ */
++static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
+ {
++      pud_t *pud;
++      pmd_t *pmds[UNSHARED_PTRS_PER_PGD];
++      unsigned long addr, flags;
+       int i;
+-      pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor);
+-      pmd_t **pmds = NULL;
+-      unsigned long flags;
+-
+-      pgd_test_and_unpin(pgd);
+-
+-      if (PTRS_PER_PMD == 1 || !pgd)
+-              return pgd;
+-
+-#ifdef CONFIG_XEN
+-      if (!SHARED_KERNEL_PMD) {
+-              /*
+-               * We can race save/restore (if we sleep during a GFP_KERNEL memory
+-               * allocation). We therefore store virtual addresses of pmds as they
+-               * do not change across save/restore, and poke the machine addresses
+-               * into the pgdir under the pgd_lock.
+-               */
+-              pmds = kmalloc(PTRS_PER_PGD * sizeof(pmd_t *), GFP_KERNEL);
+-              if (!pmds) {
+-                      quicklist_free(0, pgd_dtor, pgd);
+-                      return NULL;
+-              }
+-      }
+-#endif
+-      /* Allocate pmds, remember virtual addresses. */
+-      for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) {
+-              pmd_t *pmd = pmd_cache_alloc(i);
+-
+-              if (!pmd)
++      /*
++       * We can race save/restore (if we sleep during a GFP_KERNEL memory
++       * allocation). We therefore store virtual addresses of pmds as they
++       * do not change across save/restore, and poke the machine addresses
++       * into the pgdir under the pgd_lock.
++       */
++      for (addr = i = 0; i < UNSHARED_PTRS_PER_PGD; i++, addr += PUD_SIZE) {
++              pmds[i] = pmd_alloc_one(mm, addr);
++              if (!pmds[i])
+                       goto out_oom;
+-
+-              paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
+-              if (pmds)
+-                      pmds[i] = pmd;
+-              else
+-                      set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
+       }
  
- /*
-- * bt_ioremap() and bt_iounmap() are for temporary early boot-time
-+ * early_ioremap() and early_iounmap() are for temporary early boot-time
-  * mappings, before the real ioremap() is functional.
-  * A boot-time mapping is currently limited to at most 16 pages.
-  */
--extern void *bt_ioremap(unsigned long offset, unsigned long size);
--extern void bt_iounmap(void *addr, unsigned long size);
-+extern void early_ioremap_init(void);
-+extern void early_ioremap_clear(void);
-+extern void early_ioremap_reset(void);
-+extern void *early_ioremap(unsigned long offset, unsigned long size);
-+extern void early_iounmap(void *addr, unsigned long size);
- extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
- /* Use early IO mappings for DMI because it's initialized early */
--#define dmi_ioremap bt_ioremap
--#define dmi_iounmap bt_iounmap
-+#define dmi_ioremap early_ioremap
-+#define dmi_iounmap early_iounmap
- #define dmi_alloc alloc_bootmem
+-#ifdef CONFIG_XEN
+-      if (SHARED_KERNEL_PMD)
+-              return pgd;
+-
+       spin_lock_irqsave(&pgd_lock, flags);
  
- /*
-@@ -263,43 +268,21 @@ static inline void flush_write_buffers(v
+       /* Protect against save/restore: move below 4GB under pgd_lock. */
+-      if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) {
+-              int rc = xen_create_contiguous_region(
+-                      (unsigned long)pgd, 0, 32);
+-              if (rc) {
+-                      spin_unlock_irqrestore(&pgd_lock, flags);
+-                      goto out_oom;
+-              }
++      if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)
++          && xen_create_contiguous_region((unsigned long)pgd, 0, 32)) {
++              spin_unlock_irqrestore(&pgd_lock, flags);
++out_oom:
++              while (i--)
++                      pmd_free(mm, pmds[i]);
++              return 0;
+       }
  
- #endif /* __KERNEL__ */
+       /* Copy kernel pmd contents and write-protect the new pmds. */
+-      for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
+-              memcpy(pmds[i],
+-                     (void *)pgd_page_vaddr(swapper_pg_dir[i]),
+-                     sizeof(pmd_t) * PTRS_PER_PMD);
+-              make_lowmem_page_readonly(
+-                      pmds[i], XENFEAT_writable_page_tables);
+-      }
++      pud = pud_offset(pgd, 0);
++      for (addr = i = 0; i < UNSHARED_PTRS_PER_PGD;
++           i++, pud++, addr += PUD_SIZE) {
++              if (i >= USER_PTRS_PER_PGD) {
++                      memcpy(pmds[i],
++                             (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
++                             sizeof(pmd_t) * PTRS_PER_PMD);
++                      make_lowmem_page_readonly(
++                              pmds[i], XENFEAT_writable_page_tables);
++              }
  
--static inline void xen_io_delay(void)
--{
--      asm volatile("outb %%al,$0x80" : : : "memory");
--}
-+extern void xen_io_delay(void);
-+#define native_io_delay xen_io_delay
+-      /* It is safe to poke machine addresses of pmds under the pmd_lock. */
+-      for (i = 0; i < PTRS_PER_PGD; i++)
+-              set_pgd(&pgd[i], __pgd(1 + __pa(pmds[i])));
++              /* It is safe to poke machine addresses of pmds under the pgd_lock. */
++              pud_populate(mm, pud, pmds[i]);
++      }
+-      /* Ensure this pgd gets picked up and pinned on save/restore. */
++      /* List required to sync kernel mapping updates and
++       * to pin/unpin on save/restore. */
+       pgd_list_add(pgd);
+       spin_unlock_irqrestore(&pgd_lock, flags);
+-      kfree(pmds);
+-#endif
++      return 1;
++}
++#else  /* !CONFIG_X86_PAE */
++/* No need to prepopulate any pagetable entries in non-PAE modes. */
++static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
++{
++      return 1;
++}
+-      return pgd;
++static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
++{
++}
++#endif        /* CONFIG_X86_PAE */
+-out_oom:
+-      if (!pmds) {
+-              for (i--; i >= 0; i--) {
+-                      pgd_t pgdent = pgd[i];
+-                      void* pmd = (void *)__va(pgd_val(pgdent)-1);
+-                      paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
+-                      pmd_cache_free(pmd, i);
+-              }
+-      } else {
+-              for (i--; i >= 0; i--) {
+-                      paravirt_release_pd(__pa(pmds[i]) >> PAGE_SHIFT);
+-                      pmd_cache_free(pmds[i], i);
+-              }
+-              kfree(pmds);
++pgd_t *pgd_alloc(struct mm_struct *mm)
++{
++      pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 +
-+extern int io_delay_type;
-+extern void io_delay_init(void);
- static inline void slow_down_io(void) {
--      xen_io_delay();
-+      native_io_delay();
- #ifdef REALLY_SLOW_IO
--      xen_io_delay();
--      xen_io_delay();
--      xen_io_delay();
-+      native_io_delay();
-+      native_io_delay();
-+      native_io_delay();
- #endif
++      /* so that alloc_pd can use it */
++      mm->pgd = pgd;
++      if (pgd)
++              pgd_ctor(pgd);
++
++      if (pgd && !pgd_prepopulate_pmd(mm, pgd)) {
++              free_page((unsigned long)pgd);
++              pgd = NULL;
+       }
+-      quicklist_free(0, pgd_dtor, pgd);
+-      return NULL;
++
++      return pgd;
  }
  
--#ifdef CONFIG_X86_NUMAQ
--extern void *xquad_portio;    /* Where the IO area was mapped */
--#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
--#define __BUILDIO(bwl,bw,type) \
--static inline void out##bwl##_quad(unsigned type value, int port, int quad) { \
--      if (xquad_portio) \
--              write##bwl(value, XQUAD_PORT_ADDR(port, quad)); \
--      else \
--              out##bwl##_local(value, port); \
--} \
--static inline void out##bwl(unsigned type value, int port) { \
--      out##bwl##_quad(value, port, 0); \
--} \
--static inline unsigned type in##bwl##_quad(int port, int quad) { \
--      if (xquad_portio) \
--              return read##bwl(XQUAD_PORT_ADDR(port, quad)); \
--      else \
--              return in##bwl##_local(port); \
--} \
--static inline unsigned type in##bwl(int port) { \
--      return in##bwl##_quad(port, 0); \
--}
--#else
- #define __BUILDIO(bwl,bw,type) \
- static inline void out##bwl(unsigned type value, int port) { \
-       out##bwl##_local(value, port); \
-@@ -307,8 +290,6 @@ static inline void out##bwl(unsigned typ
- static inline unsigned type in##bwl(int port) { \
-       return in##bwl##_local(port); \
- }
--#endif
+-void pgd_free(pgd_t *pgd)
++void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+ {
+-      int i;
 -
+       /*
+        * After this the pgd should not be pinned for the duration of this
+        * function's execution. We should never sleep and thus never race:
+@@ -450,39 +368,43 @@ void pgd_free(pgd_t *pgd)
+        *  2. The machine addresses in PGD entries will not become invalid
+        *     due to a concurrent save/restore.
+        */
+-      pgd_test_and_unpin(pgd);
++      pgd_dtor(pgd);
  
- #define BUILDIO(bwl,bw,type) \
- static inline void out##bwl##_local(unsigned type value, int port) { \
---- a/include/asm-x86/mach-xen/asm/io_64.h
-+++ b/include/asm-x86/mach-xen/asm/io_64.h
-@@ -36,13 +36,21 @@
-   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-   */
+-      /* in the PAE case user pgd entries are overwritten before usage */
+-      if (PTRS_PER_PMD > 1) {
+-              for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) {
+-                      pgd_t pgdent = pgd[i];
+-                      void* pmd = (void *)__va(pgd_val(pgdent)-1);
+-                      paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
+-                      pmd_cache_free(pmd, i);
+-              }
++      if (PTRS_PER_PMD > 1 && !xen_feature(XENFEAT_pae_pgdir_above_4gb))
++              xen_destroy_contiguous_region((unsigned long)pgd, 0);
  
--#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
-+extern void xen_io_delay(void);
-+#define native_io_delay xen_io_delay
+-              if (!xen_feature(XENFEAT_pae_pgdir_above_4gb))
+-                      xen_destroy_contiguous_region((unsigned long)pgd, 0);
+-      }
++      pgd_mop_up_pmds(mm, pgd);
++      free_page((unsigned long)pgd);
++}
  
-+extern int io_delay_type;
-+extern void io_delay_init(void);
-+
-+static inline void slow_down_io(void)
+-      /* in the non-PAE case, free_pgtables() clears user pgd entries */
+-      quicklist_free(0, pgd_dtor, pgd);
++void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
 +{
-+      native_io_delay();
- #ifdef REALLY_SLOW_IO
--#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
--#else
--#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
-+      native_io_delay();
-+      native_io_delay();
-+      native_io_delay();
- #endif
-+}
++      pgtable_page_dtor(pte);
++      paravirt_release_pt(page_to_pfn(pte));
++      tlb_remove_page(tlb, pte);
+ }
  
- /*
-  * Talk about misusing macros..
-@@ -53,9 +61,15 @@ static inline void out##s(unsigned x val
- #define __OUT2(s,s1,s2) \
- __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
-+#ifndef REALLY_SLOW_IO
-+#define REALLY_SLOW_IO
-+#define UNSET_REALLY_SLOW_IO
-+#endif
+-void check_pgt_cache(void)
++#ifdef CONFIG_X86_PAE
 +
- #define __OUT(s,s1,x) \
- __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
--__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
-+__OUT1(s##_p, x) __OUT2(s, s1, "w") : : "a" (value), "Nd" (port)); \
-+              slow_down_io(); }
- #define __IN1(s) \
- static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
-@@ -64,8 +78,13 @@ static inline RETURN_TYPE in##s(unsigned
- __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
- #define __IN(s,s1,i...) \
--__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
--__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-+__IN1(s) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i); return _v; } \
-+__IN1(s##_p) __IN2(s, s1, "w") : "=a" (_v) : "Nd" (port), ##i);         \
-+                              slow_down_io(); return _v; }
-+
-+#ifdef UNSET_REALLY_SLOW_IO
-+#undef REALLY_SLOW_IO
++void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+ {
+-      quicklist_trim(0, pgd_dtor, 25, 16);
++      paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
++      tlb_remove_page(tlb, virt_to_page(pmd));
+ }
 +#endif
++
+ void make_lowmem_page_readonly(void *va, unsigned int feature)
+ {
+       pte_t *pte;
++      unsigned int level;
+       int rc;
+       if (xen_feature(feature))
+               return;
  
- #define __INS(s) \
- static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
-@@ -143,25 +162,30 @@ static inline void * phys_to_virt(unsign
+-      pte = virt_to_ptep(va);
++      pte = lookup_address((unsigned long)va, &level);
++      BUG_ON(!pte || level != PG_LEVEL_4K || !pte_present(*pte));
+       rc = HYPERVISOR_update_va_mapping(
+               (unsigned long)va, pte_wrprotect(*pte), 0);
+       BUG_ON(rc);
+@@ -491,313 +413,15 @@ void make_lowmem_page_readonly(void *va,
+ void make_lowmem_page_writable(void *va, unsigned int feature)
+ {
+       pte_t *pte;
++      unsigned int level;
+       int rc;
  
- #include <asm-generic/iomap.h>
+       if (xen_feature(feature))
+               return;
  
--extern void __iomem *__ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+-      pte = virt_to_ptep(va);
++      pte = lookup_address((unsigned long)va, &level);
++      BUG_ON(!pte || level != PG_LEVEL_4K || !pte_present(*pte));
+       rc = HYPERVISOR_update_va_mapping(
+               (unsigned long)va, pte_mkwrite(*pte), 0);
+       BUG_ON(rc);
+ }
 -
--static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+-void make_page_readonly(void *va, unsigned int feature)
 -{
--      return __ioremap(offset, size, 0);
+-      pte_t *pte;
+-      int rc;
+-
+-      if (xen_feature(feature))
+-              return;
+-
+-      pte = virt_to_ptep(va);
+-      rc = HYPERVISOR_update_va_mapping(
+-              (unsigned long)va, pte_wrprotect(*pte), 0);
+-      if (rc) /* fallback? */
+-              xen_l1_entry_update(pte, pte_wrprotect(*pte));
+-      if ((unsigned long)va >= (unsigned long)high_memory) {
+-              unsigned long pfn = pte_pfn(*pte);
+-#ifdef CONFIG_HIGHMEM
+-              if (pfn >= highstart_pfn)
+-                      kmap_flush_unused(); /* flush stale writable kmaps */
+-              else
+-#endif
+-                      make_lowmem_page_readonly(
+-                              phys_to_virt(pfn << PAGE_SHIFT), feature); 
+-      }
 -}
 -
--extern void *bt_ioremap(unsigned long addr, unsigned long size);
--extern void bt_iounmap(void *addr, unsigned long size);
--#define early_ioremap bt_ioremap
--#define early_iounmap bt_iounmap
-+extern void early_ioremap_init(void);
-+extern void early_ioremap_clear(void);
-+extern void early_ioremap_reset(void);
-+extern void *early_ioremap(unsigned long addr, unsigned long size);
-+extern void early_iounmap(void *addr, unsigned long size);
- /*
-  * This one maps high address device memory and turns off caching for that area.
-  * it's useful if some control registers are in such an area and write combining
-  * or read caching is not desirable:
-  */
--extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-+extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
-+extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
-+
-+/*
-+ * The default ioremap() behavior is non-cached:
-+ */
-+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
-+{
-+      return ioremap_nocache(offset, size);
-+}
-+
- extern void iounmap(volatile void __iomem *addr);
-+
- extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
- /*
---- a/include/asm-x86/mach-xen/asm/irqflags_32.h
-+++ /dev/null
-@@ -1,212 +0,0 @@
--/*
-- * include/asm-i386/irqflags.h
-- *
-- * IRQ flags handling
-- *
-- * This file gets included from lowlevel asm headers too, to provide
-- * wrapped versions of the local_irq_*() APIs, based on the
-- * raw_local_irq_*() functions from the lowlevel headers.
-- */
--#ifndef _ASM_IRQFLAGS_H
--#define _ASM_IRQFLAGS_H
+-void make_page_writable(void *va, unsigned int feature)
+-{
+-      pte_t *pte;
+-      int rc;
 -
--#ifndef __ASSEMBLY__
--#define xen_save_fl(void) (current_vcpu_info()->evtchn_upcall_mask)
+-      if (xen_feature(feature))
+-              return;
 -
--#define xen_restore_fl(f)                                     \
--do {                                                          \
--      vcpu_info_t *_vcpu;                                     \
--      barrier();                                              \
--      _vcpu = current_vcpu_info();                            \
--      if ((_vcpu->evtchn_upcall_mask = (f)) == 0) {           \
--              barrier(); /* unmask then check (avoid races) */\
--              if (unlikely(_vcpu->evtchn_upcall_pending))     \
--                      force_evtchn_callback();                \
--      }                                                       \
--} while (0)
+-      pte = virt_to_ptep(va);
+-      rc = HYPERVISOR_update_va_mapping(
+-              (unsigned long)va, pte_mkwrite(*pte), 0);
+-      if (rc) /* fallback? */
+-              xen_l1_entry_update(pte, pte_mkwrite(*pte));
+-      if ((unsigned long)va >= (unsigned long)high_memory) {
+-              unsigned long pfn = pte_pfn(*pte); 
+-#ifdef CONFIG_HIGHMEM
+-              if (pfn < highstart_pfn)
+-#endif
+-                      make_lowmem_page_writable(
+-                              phys_to_virt(pfn << PAGE_SHIFT), feature);
+-      }
+-}
+-
+-void make_pages_readonly(void *va, unsigned int nr, unsigned int feature)
+-{
+-      if (xen_feature(feature))
+-              return;
+-
+-      while (nr-- != 0) {
+-              make_page_readonly(va, feature);
+-              va = (void *)((unsigned long)va + PAGE_SIZE);
+-      }
+-}
+-
+-void make_pages_writable(void *va, unsigned int nr, unsigned int feature)
+-{
+-      if (xen_feature(feature))
+-              return;
+-
+-      while (nr-- != 0) {
+-              make_page_writable(va, feature);
+-              va = (void *)((unsigned long)va + PAGE_SIZE);
+-      }
+-}
+-
+-static void _pin_lock(struct mm_struct *mm, int lock) {
+-      if (lock)
+-              spin_lock(&mm->page_table_lock);
+-#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+-      /* While mm->page_table_lock protects us against insertions and
+-       * removals of higher level page table pages, it doesn't protect
+-       * against updates of pte-s. Such updates, however, require the
+-       * pte pages to be in consistent state (unpinned+writable or
+-       * pinned+readonly). The pinning and attribute changes, however
+-       * cannot be done atomically, which is why such updates must be
+-       * prevented from happening concurrently.
+-       * Note that no pte lock can ever elsewhere be acquired nesting
+-       * with an already acquired one in the same mm, or with the mm's
+-       * page_table_lock already acquired, as that would break in the
+-       * non-split case (where all these are actually resolving to the
+-       * one page_table_lock). Thus acquiring all of them here is not
+-       * going to result in dead locks, and the order of acquires
+-       * doesn't matter.
+-       */
+-      {
+-              pgd_t *pgd = mm->pgd;
+-              unsigned g;
+-
+-              for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
+-                      pud_t *pud;
+-                      unsigned u;
+-
+-                      if (pgd_none(*pgd))
+-                              continue;
+-                      pud = pud_offset(pgd, 0);
+-                      for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
+-                              pmd_t *pmd;
+-                              unsigned m;
+-
+-                              if (pud_none(*pud))
+-                                      continue;
+-                              pmd = pmd_offset(pud, 0);
+-                              for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
+-                                      spinlock_t *ptl;
+-
+-                                      if (pmd_none(*pmd))
+-                                              continue;
+-                                      ptl = pte_lockptr(0, pmd);
+-                                      if (lock)
+-                                              spin_lock(ptl);
+-                                      else
+-                                              spin_unlock(ptl);
+-                              }
+-                      }
+-              }
+-      }
+-#endif
+-      if (!lock)
+-              spin_unlock(&mm->page_table_lock);
+-}
+-#define pin_lock(mm) _pin_lock(mm, 1)
+-#define pin_unlock(mm) _pin_lock(mm, 0)
 -
--#define xen_irq_disable()                                     \
--do {                                                          \
--      current_vcpu_info()->evtchn_upcall_mask = 1;            \
--      barrier();                                              \
--} while (0)
+-#define PIN_BATCH 4
+-static DEFINE_PER_CPU(multicall_entry_t[PIN_BATCH], pb_mcl);
 -
--#define xen_irq_enable()                                      \
--do {                                                          \
--      vcpu_info_t *_vcpu;                                     \
--      barrier();                                              \
--      _vcpu = current_vcpu_info();                            \
--      _vcpu->evtchn_upcall_mask = 0;                          \
--      barrier(); /* unmask then check (avoid races) */        \
--      if (unlikely(_vcpu->evtchn_upcall_pending))             \
--              force_evtchn_callback();                        \
--} while (0)
+-static inline unsigned int pgd_walk_set_prot(struct page *page, pgprot_t flags,
+-                                             unsigned int cpu, unsigned seq)
+-{
+-      unsigned long pfn = page_to_pfn(page);
 -
--void xen_safe_halt(void);
+-      if (PageHighMem(page)) {
+-              if (pgprot_val(flags) & _PAGE_RW)
+-                      ClearPagePinned(page);
+-              else
+-                      SetPagePinned(page);
+-      } else {
+-              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
+-                              (unsigned long)__va(pfn << PAGE_SHIFT),
+-                              pfn_pte(pfn, flags), 0);
+-              if (unlikely(++seq == PIN_BATCH)) {
+-                      if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
+-                                                              PIN_BATCH, NULL)))
+-                              BUG();
+-                      seq = 0;
+-              }
+-      }
 -
--void xen_halt(void);
+-      return seq;
+-}
 -
--/* 
-- * The use of 'barrier' in the following reflects their use as local-lock
-- * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
-- * critical operations are executed. All critical operations must complete
-- * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
-- * includes these barriers, for example.
-- */
+-static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
+-{
+-      pgd_t *pgd = pgd_base;
+-      pud_t *pud;
+-      pmd_t *pmd;
+-      int    g, u, m;
+-      unsigned int cpu, seq;
 -
--#define __raw_local_save_flags() xen_save_fl()
+-      if (xen_feature(XENFEAT_auto_translated_physmap))
+-              return;
 -
--#define raw_local_irq_restore(flags) xen_restore_fl(flags)
+-      cpu = get_cpu();
 -
--#define raw_local_irq_disable()       xen_irq_disable()
+-      for (g = 0, seq = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
+-              if (pgd_none(*pgd))
+-                      continue;
+-              pud = pud_offset(pgd, 0);
+-              if (PTRS_PER_PUD > 1) /* not folded */
+-                      seq = pgd_walk_set_prot(virt_to_page(pud),flags,cpu,seq);
+-              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
+-                      if (pud_none(*pud))
+-                              continue;
+-                      pmd = pmd_offset(pud, 0);
+-                      if (PTRS_PER_PMD > 1) /* not folded */
+-                              seq = pgd_walk_set_prot(virt_to_page(pmd),flags,cpu,seq);
+-                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
+-                              if (pmd_none(*pmd))
+-                                      continue;
+-                              seq = pgd_walk_set_prot(pmd_page(*pmd),flags,cpu,seq);
+-                      }
+-              }
+-      }
 -
--#define raw_local_irq_enable() xen_irq_enable()
+-      if (likely(seq != 0)) {
+-              MULTI_update_va_mapping(per_cpu(pb_mcl, cpu) + seq,
+-                      (unsigned long)pgd_base,
+-                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
+-                      UVMF_TLB_FLUSH);
+-              if (unlikely(HYPERVISOR_multicall_check(per_cpu(pb_mcl, cpu),
+-                                                      seq + 1, NULL)))
+-                      BUG();
+-      } else if(HYPERVISOR_update_va_mapping((unsigned long)pgd_base,
+-                      pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
+-                      UVMF_TLB_FLUSH))
+-              BUG();
 -
--/*
-- * Used in the idle loop; sti takes one instruction cycle
-- * to complete:
-- */
--static inline void raw_safe_halt(void)
--{
--      xen_safe_halt();
+-      put_cpu();
 -}
 -
--/*
-- * Used when interrupts are already enabled or to
-- * shutdown the processor:
-- */
--static inline void halt(void)
+-static void __pgd_pin(pgd_t *pgd)
 -{
--      xen_halt();
+-      pgd_walk(pgd, PAGE_KERNEL_RO);
+-      kmap_flush_unused();
+-      xen_pgd_pin(__pa(pgd));
+-      SetPagePinned(virt_to_page(pgd));
 -}
 -
--/*
-- * For spinlocks, etc:
-- */
--#define __raw_local_irq_save()                                                \
--({                                                                    \
--      unsigned long flags = __raw_local_save_flags();                 \
--                                                                      \
--      raw_local_irq_disable();                                        \
--                                                                      \
--      flags;                                                          \
--})
--
--#else
--/* Offsets into shared_info_t. */
--#define evtchn_upcall_pending         /* 0 */
--#define evtchn_upcall_mask            1
+-static void __pgd_unpin(pgd_t *pgd)
+-{
+-      xen_pgd_unpin(__pa(pgd));
+-      pgd_walk(pgd, PAGE_KERNEL);
+-      ClearPagePinned(virt_to_page(pgd));
+-}
 -
--#define sizeof_vcpu_shift             6
+-static void pgd_test_and_unpin(pgd_t *pgd)
+-{
+-      if (PagePinned(virt_to_page(pgd)))
+-              __pgd_unpin(pgd);
+-}
 -
--#ifdef CONFIG_SMP
--#define GET_VCPU_INFO         movl TI_cpu(%ebp),%esi                  ; \
--                              shl  $sizeof_vcpu_shift,%esi            ; \
--                              addl HYPERVISOR_shared_info,%esi
--#else
--#define GET_VCPU_INFO         movl HYPERVISOR_shared_info,%esi
--#endif
+-void mm_pin(struct mm_struct *mm)
+-{
+-      if (xen_feature(XENFEAT_writable_page_tables))
+-              return;
+-      pin_lock(mm);
+-      __pgd_pin(mm->pgd);
+-      pin_unlock(mm);
+-}
 -
--#define __DISABLE_INTERRUPTS  movb $1,evtchn_upcall_mask(%esi)
--#define __ENABLE_INTERRUPTS   movb $0,evtchn_upcall_mask(%esi)
--#define __TEST_PENDING                testb $0xFF,evtchn_upcall_pending(%esi)
--#define DISABLE_INTERRUPTS(clb)       GET_VCPU_INFO                           ; \
--                              __DISABLE_INTERRUPTS
--#define ENABLE_INTERRUPTS(clb)        GET_VCPU_INFO                           ; \
--                              __ENABLE_INTERRUPTS
--#define ENABLE_INTERRUPTS_SYSEXIT __ENABLE_INTERRUPTS                 ; \
--sysexit_scrit:        /**** START OF SYSEXIT CRITICAL REGION ****/            ; \
--      __TEST_PENDING                                                  ; \
--      jnz  14f        /* process more events if necessary... */       ; \
--      movl PT_ESI(%esp), %esi                                         ; \
--      sysexit                                                         ; \
--14:   __DISABLE_INTERRUPTS                                            ; \
--      TRACE_IRQS_OFF                                                  ; \
--sysexit_ecrit:        /**** END OF SYSEXIT CRITICAL REGION ****/              ; \
--      push %esp                                                       ; \
--      call evtchn_do_upcall                                           ; \
--      add  $4,%esp                                                    ; \
--      jmp  ret_from_intr
--#define INTERRUPT_RETURN      iret
--#endif /* __ASSEMBLY__ */
+-void mm_unpin(struct mm_struct *mm)
+-{
+-      if (xen_feature(XENFEAT_writable_page_tables))
+-              return;
+-      pin_lock(mm);
+-      __pgd_unpin(mm->pgd);
+-      pin_unlock(mm);
+-}
 -
--#ifndef __ASSEMBLY__
--#define raw_local_save_flags(flags) \
--              do { (flags) = __raw_local_save_flags(); } while (0)
+-void mm_pin_all(void)
+-{
+-      struct page *page;
+-      unsigned long flags;
 -
--#define raw_local_irq_save(flags) \
--              do { (flags) = __raw_local_irq_save(); } while (0)
+-      if (xen_feature(XENFEAT_writable_page_tables))
+-              return;
 -
--static inline int raw_irqs_disabled_flags(unsigned long flags)
--{
--      return (flags != 0);
+-      /*
+-       * Allow uninterrupted access to the pgd_list. Also protects
+-       * __pgd_pin() by disabling preemption.
+-       * All other CPUs must be at a safe point (e.g., in stop_machine
+-       * or offlined entirely).
+-       */
+-      spin_lock_irqsave(&pgd_lock, flags);
+-      for (page = pgd_list; page; page = (struct page *)page->index) {
+-              if (!PagePinned(page))
+-                      __pgd_pin((pgd_t *)page_address(page));
+-      }
+-      spin_unlock_irqrestore(&pgd_lock, flags);
 -}
 -
--#define raw_irqs_disabled()                                           \
--({                                                                    \
--      unsigned long flags = __raw_local_save_flags();                 \
--                                                                      \
--      raw_irqs_disabled_flags(flags);                                 \
--})
--
--/*
-- * makes the traced hardirq state match with the machine state
-- *
-- * should be a rarely used function, only in places where its
-- * otherwise impossible to know the irq state, like in traps.
-- */
--static inline void trace_hardirqs_fixup_flags(unsigned long flags)
+-void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
 -{
--      if (raw_irqs_disabled_flags(flags))
--              trace_hardirqs_off();
--      else
--              trace_hardirqs_on();
+-      if (!PagePinned(virt_to_page(mm->pgd)))
+-              mm_pin(mm);
 -}
 -
--#define trace_hardirqs_fixup() \
--      trace_hardirqs_fixup_flags(__raw_local_save_flags())
--#endif /* __ASSEMBLY__ */
+-void arch_exit_mmap(struct mm_struct *mm)
+-{
+-      struct task_struct *tsk = current;
 -
--/*
-- * Do the CPU's IRQ-state tracing from assembly code. We call a
-- * C function, so save all the C-clobbered registers:
-- */
--#ifdef CONFIG_TRACE_IRQFLAGS
+-      task_lock(tsk);
 -
--# define TRACE_IRQS_ON                                \
--      pushl %eax;                             \
--      pushl %ecx;                             \
--      pushl %edx;                             \
--      call trace_hardirqs_on;                 \
--      popl %edx;                              \
--      popl %ecx;                              \
--      popl %eax;
+-      /*
+-       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
+-       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
+-       */
+-      if (tsk->active_mm == mm) {
+-              tsk->active_mm = &init_mm;
+-              atomic_inc(&init_mm.mm_count);
 -
--# define TRACE_IRQS_OFF                               \
--      pushl %eax;                             \
--      pushl %ecx;                             \
--      pushl %edx;                             \
--      call trace_hardirqs_off;                \
--      popl %edx;                              \
--      popl %ecx;                              \
--      popl %eax;
+-              switch_mm(mm, &init_mm, tsk);
 -
--#else
--# define TRACE_IRQS_ON
--# define TRACE_IRQS_OFF
--#endif
+-              atomic_dec(&mm->mm_count);
+-              BUG_ON(atomic_read(&mm->mm_count) == 0);
+-      }
 -
--#ifdef CONFIG_DEBUG_LOCK_ALLOC
--# define LOCKDEP_SYS_EXIT                     \
--      pushl %eax;                             \
--      pushl %ecx;                             \
--      pushl %edx;                             \
--      call lockdep_sys_exit;                  \
--      popl %edx;                              \
--      popl %ecx;                              \
--      popl %eax;
--#else
--# define LOCKDEP_SYS_EXIT
--#endif
+-      task_unlock(tsk);
 -
+-      if (PagePinned(virt_to_page(mm->pgd)) &&
+-          (atomic_read(&mm->mm_count) == 1) &&
+-          !mm->context.has_foreign_mappings)
+-              mm_unpin(mm);
+-}
+--- sle11-2009-05-14.orig/arch/x86/pci/irq-xen.c       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/arch/x86/pci/irq-xen.c    2009-03-16 16:33:40.000000000 +0100
+@@ -204,6 +204,7 @@ static int pirq_ali_get(struct pci_dev *
+ {
+       static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
++      WARN_ON_ONCE(pirq >= 16);
+       return irqmap[read_config_nybble(router, 0x48, pirq-1)];
+ }
+@@ -211,7 +212,8 @@ static int pirq_ali_set(struct pci_dev *
+ {
+       static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
+       unsigned int val = irqmap[irq];
+-              
++
++      WARN_ON_ONCE(pirq >= 16);
+       if (val) {
+               write_config_nybble(router, 0x48, pirq-1, val);
+               return 1;
+@@ -261,12 +263,16 @@ static int pirq_via_set(struct pci_dev *
+ static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+ {
+       static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
++
++      WARN_ON_ONCE(pirq >= 5);
+       return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
+ }
+ static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+ {
+       static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
++
++      WARN_ON_ONCE(pirq >= 5);
+       write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
+       return 1;
+ }
+@@ -279,12 +285,16 @@ static int pirq_via586_set(struct pci_de
+ static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+ {
+       static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
++
++      WARN_ON_ONCE(pirq >= 4);
+       return read_config_nybble(router,0x43, pirqmap[pirq-1]);
+ }
+ static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+ {
+       static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
++
++      WARN_ON_ONCE(pirq >= 4);
+       write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
+       return 1;
+ }
+@@ -423,6 +433,7 @@ static int pirq_sis_set(struct pci_dev *
+ static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+ {
++      WARN_ON_ONCE(pirq >= 9);
+       if (pirq > 8) {
+               printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
+               return 0;
+@@ -432,6 +443,7 @@ static int pirq_vlsi_get(struct pci_dev 
+ static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+ {
++      WARN_ON_ONCE(pirq >= 9);
+       if (pirq > 8) {
+               printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
+               return 0;
+@@ -453,14 +465,14 @@ static int pirq_vlsi_set(struct pci_dev 
+  */
+ static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+ {
+-      outb_p(pirq, 0xc00);
++      outb(pirq, 0xc00);
+       return inb(0xc01) & 0xf;
+ }
+ static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+ {
+-      outb_p(pirq, 0xc00);
+-      outb_p(irq, 0xc01);
++      outb(pirq, 0xc00);
++      outb(irq, 0xc01);
+       return 1;
+ }
+@@ -575,6 +587,10 @@ static __init int intel_router_probe(str
+               case PCI_DEVICE_ID_INTEL_ICH9_4:
+               case PCI_DEVICE_ID_INTEL_ICH9_5:
+               case PCI_DEVICE_ID_INTEL_TOLAPAI_0:
++              case PCI_DEVICE_ID_INTEL_ICH10_0:
++              case PCI_DEVICE_ID_INTEL_ICH10_1:
++              case PCI_DEVICE_ID_INTEL_ICH10_2:
++              case PCI_DEVICE_ID_INTEL_ICH10_3:
+                       r->name = "PIIX/ICH";
+                       r->get = pirq_piix_get;
+                       r->set = pirq_piix_set;
+--- sle11-2009-05-14.orig/arch/x86/vdso/Makefile       2008-11-25 12:35:54.000000000 +0100
++++ sle11-2009-05-14/arch/x86/vdso/Makefile    2009-03-16 16:33:40.000000000 +0100
+@@ -66,6 +66,7 @@ vdso32.so-$(VDSO32-y)                += int80
+ vdso32.so-$(CONFIG_COMPAT)    += syscall
+ vdso32.so-$(VDSO32-y)         += sysenter
+ xen-vdso32-$(subst 1,$(CONFIG_COMPAT),$(shell expr $(CONFIG_XEN_COMPAT)0 '<' 0x0302000)) += int80
++xen-vdso32-$(CONFIG_X86_32)   += syscall
+ vdso32.so-$(CONFIG_XEN)               += $(xen-vdso32-y)
+ vdso32-images                 = $(vdso32.so-y:%=vdso32-%.so)
+--- sle11-2009-05-14.orig/arch/x86/vdso/vdso32/syscall.S       2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/arch/x86/vdso/vdso32/syscall.S    2009-03-16 16:33:40.000000000 +0100
+@@ -19,8 +19,10 @@ __kernel_vsyscall:
+ .Lpush_ebp:
+       movl    %ecx, %ebp
+       syscall
++#ifndef CONFIG_XEN
+       movl    $__USER32_DS, %ecx
+       movl    %ecx, %ss
++#endif
+       movl    %ebp, %ecx
+       popl    %ebp
+ .Lpop_ebp:
+--- sle11-2009-05-14.orig/arch/x86/vdso/vdso32.S       2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/arch/x86/vdso/vdso32.S    2009-03-16 16:33:40.000000000 +0100
+@@ -19,4 +19,16 @@ vdso32_sysenter_start:
+       .incbin "arch/x86/vdso/vdso32-sysenter.so"
+ vdso32_sysenter_end:
++#if defined(CONFIG_X86_64_XEN) && CONFIG_XEN_COMPAT < 0x030200
++      .globl vdso32_int80_start, vdso32_int80_end
++vdso32_int80_start:
++      .incbin "arch/x86/vdso/vdso32-int80.so"
++vdso32_int80_end:
++#elif defined(CONFIG_X86_XEN)
++      .globl vdso32_syscall_start, vdso32_syscall_end
++vdso32_syscall_start:
++      .incbin "arch/x86/vdso/vdso32-syscall.so"
++vdso32_syscall_end:
++#endif
++
+ __FINIT
+--- sle11-2009-05-14.orig/arch/x86/vdso/vdso32-setup.c 2008-11-25 12:35:53.000000000 +0100
++++ sle11-2009-05-14/arch/x86/vdso/vdso32-setup.c      2009-03-16 16:33:40.000000000 +0100
+@@ -26,10 +26,6 @@
+ #include <asm/vdso.h>
+ #include <asm/proto.h>
+-#ifdef CONFIG_XEN
+-#include <xen/interface/callback.h>
 -#endif
---- a/include/asm-x86/mach-xen/asm/irqflags_64.h
-+++ /dev/null
-@@ -1,178 +0,0 @@
--/*
-- * include/asm-x86_64/irqflags.h
-- *
-- * IRQ flags handling
-- *
-- * This file gets included from lowlevel asm headers too, to provide
-- * wrapped versions of the local_irq_*() APIs, based on the
-- * raw_local_irq_*() functions from the lowlevel headers.
-- */
--#ifndef _ASM_IRQFLAGS_H
--#define _ASM_IRQFLAGS_H
--#include <asm/processor-flags.h>
 -
--#ifndef __ASSEMBLY__
--/*
-- * Interrupt control:
-- */
+ enum {
+       VDSO_DISABLED = 0,
+       VDSO_ENABLED = 1,
+@@ -229,7 +225,6 @@ static inline void map_compat_vdso(int m
+ void enable_sep_cpu(void)
+ {
+-#ifndef CONFIG_XEN
+       int cpu = get_cpu();
+       struct tss_struct *tss = &per_cpu(init_tss, cpu);
+@@ -244,35 +239,6 @@ void enable_sep_cpu(void)
+       wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.sp1, 0);
+       wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0);
+       put_cpu();      
+-#else
+-      extern asmlinkage void ia32pv_sysenter_target(void);
+-      static struct callback_register sysenter = {
+-              .type = CALLBACKTYPE_sysenter,
+-              .address = { __KERNEL_CS, (unsigned long)ia32pv_sysenter_target },
+-      };
 -
--/*
-- * The use of 'barrier' in the following reflects their use as local-lock
-- * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
-- * critical operations are executed. All critical operations must complete
-- * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
-- * includes these barriers, for example.
-- */
+-      if (!boot_cpu_has(X86_FEATURE_SEP))
+-              return;
 -
--#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
+-      get_cpu();
 -
--#define raw_local_save_flags(flags) \
--              do { (flags) = __raw_local_save_flags(); } while (0)
+-      if (xen_feature(XENFEAT_supervisor_mode_kernel))
+-              sysenter.address.eip = (unsigned long)ia32_sysenter_target;
 -
--#define raw_local_irq_restore(x)                                      \
--do {                                                                  \
--      vcpu_info_t *_vcpu;                                             \
--      barrier();                                                      \
--      _vcpu = current_vcpu_info();            \
--      if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
--              barrier(); /* unmask then check (avoid races) */        \
--              if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
--                      force_evtchn_callback();                        \
--      }                                                               \
--} while (0)
+-      switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) {
+-      case 0:
+-              break;
+-#if CONFIG_XEN_COMPAT < 0x030200
+-      case -ENOSYS:
+-              sysenter.type = CALLBACKTYPE_sysenter_deprecated;
+-              if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0)
+-                      break;
+-#endif
+-      default:
+-              clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
+-              break;
+-      }
+-#endif
+ }
+ static struct vm_area_struct gate_vma;
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/arch/x86/vdso/vdso32-setup-xen.c  2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,506 @@
++/*
++ * (C) Copyright 2002 Linus Torvalds
++ * Portions based on the vdso-randomization code from exec-shield:
++ * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
++ *
++ * This file contains the needed initializations to support sysenter.
++ */
++
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <linux/thread_info.h>
++#include <linux/sched.h>
++#include <linux/gfp.h>
++#include <linux/string.h>
++#include <linux/elf.h>
++#include <linux/mm.h>
++#include <linux/err.h>
++#include <linux/module.h>
++
++#include <asm/cpufeature.h>
++#include <asm/msr.h>
++#include <asm/pgtable.h>
++#include <asm/unistd.h>
++#include <asm/elf.h>
++#include <asm/tlbflush.h>
++#include <asm/vdso.h>
++#include <asm/proto.h>
++
++#include <xen/interface/callback.h>
++
++enum {
++      VDSO_DISABLED = 0,
++      VDSO_ENABLED = 1,
++      VDSO_COMPAT = 2,
++};
++
++#ifdef CONFIG_COMPAT_VDSO
++#define VDSO_DEFAULT  VDSO_COMPAT
++#else
++#define VDSO_DEFAULT  VDSO_ENABLED
++#endif
++
++#ifdef CONFIG_X86_64
++#define vdso_enabled                  sysctl_vsyscall32
++#define arch_setup_additional_pages   syscall32_setup_pages
++#endif
++
++/*
++ * This is the difference between the prelinked addresses in the vDSO images
++ * and the VDSO_HIGH_BASE address where CONFIG_COMPAT_VDSO places the vDSO
++ * in the user address space.
++ */
++#define VDSO_ADDR_ADJUST      (VDSO_HIGH_BASE - (unsigned long)VDSO32_PRELINK)
++
++/*
++ * Should the kernel map a VDSO page into processes and pass its
++ * address down to glibc upon exec()?
++ */
++unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT;
++
++static int __init vdso_setup(char *s)
++{
++      vdso_enabled = simple_strtoul(s, NULL, 0);
++
++      return 1;
++}
++
++/*
++ * For consistency, the argument vdso32=[012] affects the 32-bit vDSO
++ * behavior on both 64-bit and 32-bit kernels.
++ * On 32-bit kernels, vdso=[012] means the same thing.
++ */
++__setup("vdso32=", vdso_setup);
++
++#ifdef CONFIG_X86_32
++__setup_param("vdso=", vdso32_setup, vdso_setup, 0);
++
++EXPORT_SYMBOL_GPL(vdso_enabled);
++#endif
++
++static __init void reloc_symtab(Elf32_Ehdr *ehdr,
++                              unsigned offset, unsigned size)
++{
++      Elf32_Sym *sym = (void *)ehdr + offset;
++      unsigned nsym = size / sizeof(*sym);
++      unsigned i;
++
++      for(i = 0; i < nsym; i++, sym++) {
++              if (sym->st_shndx == SHN_UNDEF ||
++                  sym->st_shndx == SHN_ABS)
++                      continue;  /* skip */
++
++              if (sym->st_shndx > SHN_LORESERVE) {
++                      printk(KERN_INFO "VDSO: unexpected st_shndx %x\n",
++                             sym->st_shndx);
++                      continue;
++              }
++
++              switch(ELF_ST_TYPE(sym->st_info)) {
++              case STT_OBJECT:
++              case STT_FUNC:
++              case STT_SECTION:
++              case STT_FILE:
++                      sym->st_value += VDSO_ADDR_ADJUST;
++              }
++      }
++}
++
++static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset)
++{
++      Elf32_Dyn *dyn = (void *)ehdr + offset;
++
++      for(; dyn->d_tag != DT_NULL; dyn++)
++              switch(dyn->d_tag) {
++              case DT_PLTGOT:
++              case DT_HASH:
++              case DT_STRTAB:
++              case DT_SYMTAB:
++              case DT_RELA:
++              case DT_INIT:
++              case DT_FINI:
++              case DT_REL:
++              case DT_DEBUG:
++              case DT_JMPREL:
++              case DT_VERSYM:
++              case DT_VERDEF:
++              case DT_VERNEED:
++              case DT_ADDRRNGLO ... DT_ADDRRNGHI:
++                      /* definitely pointers needing relocation */
++                      dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
++                      break;
++
++              case DT_ENCODING ... OLD_DT_LOOS-1:
++              case DT_LOOS ... DT_HIOS-1:
++                      /* Tags above DT_ENCODING are pointers if
++                         they're even */
++                      if (dyn->d_tag >= DT_ENCODING &&
++                          (dyn->d_tag & 1) == 0)
++                              dyn->d_un.d_ptr += VDSO_ADDR_ADJUST;
++                      break;
++
++              case DT_VERDEFNUM:
++              case DT_VERNEEDNUM:
++              case DT_FLAGS_1:
++              case DT_RELACOUNT:
++              case DT_RELCOUNT:
++              case DT_VALRNGLO ... DT_VALRNGHI:
++                      /* definitely not pointers */
++                      break;
++
++              case OLD_DT_LOOS ... DT_LOOS-1:
++              case DT_HIOS ... DT_VALRNGLO-1:
++              default:
++                      if (dyn->d_tag > DT_ENCODING)
++                              printk(KERN_INFO "VDSO: unexpected DT_tag %x\n",
++                                     dyn->d_tag);
++                      break;
++              }
++}
++
++static __init void relocate_vdso(Elf32_Ehdr *ehdr)
++{
++      Elf32_Phdr *phdr;
++      Elf32_Shdr *shdr;
++      int i;
++
++      BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 ||
++             !elf_check_arch_ia32(ehdr) ||
++             ehdr->e_type != ET_DYN);
++
++      ehdr->e_entry += VDSO_ADDR_ADJUST;
++
++      /* rebase phdrs */
++      phdr = (void *)ehdr + ehdr->e_phoff;
++      for (i = 0; i < ehdr->e_phnum; i++) {
++              phdr[i].p_vaddr += VDSO_ADDR_ADJUST;
++
++              /* relocate dynamic stuff */
++              if (phdr[i].p_type == PT_DYNAMIC)
++                      reloc_dyn(ehdr, phdr[i].p_offset);
++      }
++
++      /* rebase sections */
++      shdr = (void *)ehdr + ehdr->e_shoff;
++      for(i = 0; i < ehdr->e_shnum; i++) {
++              if (!(shdr[i].sh_flags & SHF_ALLOC))
++                      continue;
++
++              shdr[i].sh_addr += VDSO_ADDR_ADJUST;
++
++              if (shdr[i].sh_type == SHT_SYMTAB ||
++                  shdr[i].sh_type == SHT_DYNSYM)
++                      reloc_symtab(ehdr, shdr[i].sh_offset,
++                                   shdr[i].sh_size);
++      }
++}
++
++/*
++ * These symbols are defined by vdso32.S to mark the bounds
++ * of the ELF DSO images included therein.
++ */
++extern const char vdso32_default_start, vdso32_default_end;
++extern const char vdso32_sysenter_start, vdso32_sysenter_end;
++static struct page *vdso32_pages[1];
++
++#ifdef CONFIG_X86_64
++
++#if CONFIG_XEN_COMPAT < 0x030200
++static int use_int80 = 1;
++#endif
++static int use_sysenter __read_mostly = -1;
++
++#define       vdso32_sysenter()       (use_sysenter > 0)
++
++/* May not be __init: called during resume */
++void syscall32_cpu_init(void)
++{
++      static const struct callback_register cstar = {
++              .type = CALLBACKTYPE_syscall32,
++              .address = (unsigned long)ia32_cstar_target
++      };
++      static const struct callback_register sysenter = {
++              .type = CALLBACKTYPE_sysenter,
++              .address = (unsigned long)ia32_sysenter_target
++      };
++
++      if ((HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0) ||
++          (HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) < 0))
++#if CONFIG_XEN_COMPAT < 0x030200
++              return;
++      use_int80 = 0;
++#else
++              BUG();
++#endif
++
++      if (use_sysenter < 0)
++              use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
++}
++
++#define compat_uses_vma               1
++
++static inline void map_compat_vdso(int map)
++{
++}
++
++#else  /* CONFIG_X86_32 */
++
++#define vdso32_sysenter()     (boot_cpu_has(X86_FEATURE_SEP))
++
++extern asmlinkage void ia32pv_cstar_target(void);
++static const struct callback_register __cpuinitconst cstar = {
++      .type = CALLBACKTYPE_syscall32,
++      .address = { __KERNEL_CS, (unsigned long)ia32pv_cstar_target },
++};
++
++void __cpuinit enable_sep_cpu(void)
++{
++      extern asmlinkage void ia32pv_sysenter_target(void);
++      static struct callback_register __cpuinitdata sysenter = {
++              .type = CALLBACKTYPE_sysenter,
++              .address = { __KERNEL_CS, (unsigned long)ia32pv_sysenter_target },
++      };
++
++      if (boot_cpu_has(X86_FEATURE_SYSCALL)) {
++              if (HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) != 0)
++                      BUG();
++              return;
++      }
++
++      if (!boot_cpu_has(X86_FEATURE_SEP))
++              return;
++
++      if (xen_feature(XENFEAT_supervisor_mode_kernel))
++              sysenter.address.eip = (unsigned long)ia32_sysenter_target;
++
++      switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) {
++      case 0:
++              break;
++#if CONFIG_XEN_COMPAT < 0x030200
++      case -ENOSYS:
++              sysenter.type = CALLBACKTYPE_sysenter_deprecated;
++              if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0)
++                      break;
++#endif
++      default:
++              setup_clear_cpu_cap(X86_FEATURE_SEP);
++              break;
++      }
++}
++
++static struct vm_area_struct gate_vma;
++
++static int __init gate_vma_init(void)
++{
++      gate_vma.vm_mm = NULL;
++      gate_vma.vm_start = FIXADDR_USER_START;
++      gate_vma.vm_end = FIXADDR_USER_END;
++      gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
++      gate_vma.vm_page_prot = __P101;
++      /*
++       * Make sure the vDSO gets into every core dump.
++       * Dumping its contents makes post-mortem fully interpretable later
++       * without matching up the same kernel and hardware config to see
++       * what PC values meant.
++       */
++      gate_vma.vm_flags |= VM_ALWAYSDUMP;
++      return 0;
++}
++
++#define compat_uses_vma               0
++
++static void map_compat_vdso(int map)
++{
++      static int vdso_mapped;
++
++      if (map == vdso_mapped)
++              return;
++
++      vdso_mapped = map;
++
++      __set_fixmap(FIX_VDSO, page_to_pfn(vdso32_pages[0]) << PAGE_SHIFT,
++                   map ? PAGE_READONLY_EXEC : PAGE_NONE);
++
++      /* flush stray tlbs */
++      flush_tlb_all();
++}
++
++#endif        /* CONFIG_X86_64 */
++
++int __init sysenter_setup(void)
++{
++      void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
++      const void *vsyscall;
++      size_t vsyscall_len;
++
++      vdso32_pages[0] = virt_to_page(syscall_page);
++
++#ifdef CONFIG_X86_32
++      gate_vma_init();
++
++      printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
++#endif
++
++#if defined(CONFIG_X86_64) && CONFIG_XEN_COMPAT < 0x030200
++      if (use_int80) {
++              extern const char vdso32_int80_start, vdso32_int80_end;
++
++              vsyscall = &vdso32_int80_start;
++              vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
++      } else
++#elif defined(CONFIG_X86_32)
++      if (boot_cpu_has(X86_FEATURE_SYSCALL)
++          && (boot_cpu_data.x86_vendor != X86_VENDOR_AMD
++              || HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) != 0))
++              setup_clear_cpu_cap(X86_FEATURE_SYSCALL);
++      barrier(); /* until clear_bit()'s constraints are correct ... */
++      if (boot_cpu_has(X86_FEATURE_SYSCALL)) {
++              extern const char vdso32_syscall_start, vdso32_syscall_end;
++
++              vsyscall = &vdso32_syscall_start;
++              vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
++      } else
++#endif
++      if (!vdso32_sysenter()) {
++              vsyscall = &vdso32_default_start;
++              vsyscall_len = &vdso32_default_end - &vdso32_default_start;
++      } else {
++              vsyscall = &vdso32_sysenter_start;
++              vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
++      }
++
++      memcpy(syscall_page, vsyscall, vsyscall_len);
++      relocate_vdso(syscall_page);
++
++      return 0;
++}
++
++/* Setup a VMA at program startup for the vsyscall page */
++int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
++{
++      struct mm_struct *mm = current->mm;
++      unsigned long addr;
++      int ret = 0;
++      bool compat;
++
++      down_write(&mm->mmap_sem);
++
++      /* Test compat mode once here, in case someone
++         changes it via sysctl */
++      compat = (vdso_enabled == VDSO_COMPAT);
++
++      map_compat_vdso(compat);
++
++      if (compat)
++              addr = VDSO_HIGH_BASE;
++      else {
++              addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
++              if (IS_ERR_VALUE(addr)) {
++                      ret = addr;
++                      goto up_fail;
++              }
++      }
++
++      if (compat_uses_vma || !compat) {
++              /*
++               * MAYWRITE to allow gdb to COW and set breakpoints
++               *
++               * Make sure the vDSO gets into every core dump.
++               * Dumping its contents makes post-mortem fully
++               * interpretable later without matching up the same
++               * kernel and hardware config to see what PC values
++               * meant.
++               */
++              ret = install_special_mapping(mm, addr, PAGE_SIZE,
++                                            VM_READ|VM_EXEC|
++                                            VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
++                                            VM_ALWAYSDUMP,
++                                            vdso32_pages);
++
++              if (ret)
++                      goto up_fail;
++      }
++
++      current->mm->context.vdso = (void *)addr;
++      current_thread_info()->sysenter_return =
++              VDSO32_SYMBOL(addr, SYSENTER_RETURN);
++
++  up_fail:
++      up_write(&mm->mmap_sem);
++
++      return ret;
++}
++
++#ifdef CONFIG_X86_64
++
++/*
++ * This must be done early in case we have an initrd containing 32-bit
++ * binaries (e.g., hotplug). This could be pushed upstream.
++ */
++core_initcall(sysenter_setup);
++
++#ifdef CONFIG_SYSCTL
++/* Register vsyscall32 into the ABI table */
++#include <linux/sysctl.h>
++
++static ctl_table abi_table2[] = {
++      {
++              .procname       = "vsyscall32",
++              .data           = &sysctl_vsyscall32,
++              .maxlen         = sizeof(int),
++              .mode           = 0644,
++              .proc_handler   = proc_dointvec
++      },
++      {}
++};
++
++static ctl_table abi_root_table2[] = {
++      {
++              .ctl_name = CTL_ABI,
++              .procname = "abi",
++              .mode = 0555,
++              .child = abi_table2
++      },
++      {}
++};
++
++static __init int ia32_binfmt_init(void)
++{
++      register_sysctl_table(abi_root_table2);
++      return 0;
++}
++__initcall(ia32_binfmt_init);
++#endif
++
++#else  /* CONFIG_X86_32 */
++
++const char *arch_vma_name(struct vm_area_struct *vma)
++{
++      if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
++              return "[vdso]";
++      return NULL;
++}
++
++struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
++{
++      struct mm_struct *mm = tsk->mm;
++
++      /* Check to see if this task was created in compat vdso mode */
++      if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
++              return &gate_vma;
++      return NULL;
++}
++
++int in_gate_area(struct task_struct *task, unsigned long addr)
++{
++      const struct vm_area_struct *vma = get_gate_vma(task);
++
++      return vma && addr >= vma->vm_start && addr < vma->vm_end;
++}
++
++int in_gate_area_no_task(unsigned long addr)
++{
++      return 0;
++}
++
++#endif        /* CONFIG_X86_64 */
+--- sle11-2009-05-14.orig/drivers/pci/msi-xen.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/drivers/pci/msi-xen.c     2009-03-16 16:33:40.000000000 +0100
+@@ -43,6 +43,53 @@ struct msi_pirq_entry {
+       int entry_nr;
+ };
++/* Arch hooks */
++
++int __attribute__ ((weak))
++arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
++{
++      return 0;
++}
++
++#ifndef CONFIG_XEN
++int __attribute__ ((weak))
++arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
++{
++      return 0;
++}
++
++int __attribute__ ((weak))
++arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
++{
++      struct msi_desc *entry;
++      int ret;
++
++      list_for_each_entry(entry, &dev->msi_list, list) {
++              ret = arch_setup_msi_irq(dev, entry);
++              if (ret)
++                      return ret;
++      }
++
++      return 0;
++}
++
++void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
++{
++      return;
++}
++
++void __attribute__ ((weak))
++arch_teardown_msi_irqs(struct pci_dev *dev)
++{
++      struct msi_desc *entry;
++
++      list_for_each_entry(entry, &dev->msi_list, list) {
++              if (entry->irq != 0)
++                      arch_teardown_msi_irq(entry->irq);
++      }
++}
++#endif
++
+ static void msi_set_enable(struct pci_dev *dev, int enable)
+ {
+       int pos;
+@@ -270,7 +317,6 @@ static void pci_intx_for_msi(struct pci_
+               pci_intx(dev, enable);
+ }
+-#ifdef CONFIG_PM
+ static void __pci_restore_msi_state(struct pci_dev *dev)
+ {
+       int pirq;
+@@ -328,7 +374,7 @@ void pci_restore_msi_state(struct pci_de
+       __pci_restore_msi_state(dev);
+       __pci_restore_msix_state(dev);
+ }
+-#endif        /* CONFIG_PM */
++EXPORT_SYMBOL_GPL(pci_restore_msi_state);
+ /**
+  * msi_capability_init - configure device's MSI capability structure
+@@ -755,51 +801,3 @@ void pci_msi_init_pci_dev(struct pci_dev
+       INIT_LIST_HEAD(&dev->msi_list);
+ #endif
+ }
 -
--#ifdef CONFIG_X86_VSMP
 -
--/*
-- * Interrupt control for the VSMP architecture:
-- */
+-/* Arch hooks */
 -
--static inline void raw_local_irq_disable(void)
+-int __attribute__ ((weak))
+-arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
 -{
--      unsigned long flags = __raw_local_save_flags();
--
--      raw_local_irq_restore((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
+-      return 0;
 -}
 -
--static inline void raw_local_irq_enable(void)
+-#ifndef CONFIG_XEN
+-int __attribute__ ((weak))
+-arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
 -{
--      unsigned long flags = __raw_local_save_flags();
--
--      raw_local_irq_restore((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
+-      return 0;
 -}
 -
--static inline int raw_irqs_disabled_flags(unsigned long flags)
+-int __attribute__ ((weak))
+-arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 -{
--      return !(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC);
--}
--
--#else /* CONFIG_X86_VSMP */
--
--#define raw_local_irq_disable()                                               \
--do {                                                                  \
--      current_vcpu_info()->evtchn_upcall_mask = 1;                                    \
--      barrier();                                                      \
--} while (0)
+-      struct msi_desc *entry;
+-      int ret;
 -
--#define raw_local_irq_enable()                                                \
--do {                                                                  \
--      vcpu_info_t *_vcpu;                                             \
--      barrier();                                                      \
--      _vcpu = current_vcpu_info();            \
--      _vcpu->evtchn_upcall_mask = 0;                                  \
--      barrier(); /* unmask then check (avoid races) */                \
--      if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
--              force_evtchn_callback();                                \
--} while (0)
+-      list_for_each_entry(entry, &dev->msi_list, list) {
+-              ret = arch_setup_msi_irq(dev, entry);
+-              if (ret)
+-                      return ret;
+-      }
 -
--static inline int raw_irqs_disabled_flags(unsigned long flags)
--{
--      return (flags != 0);
+-      return 0;
 -}
 -
--#endif
--
--/*
-- * For spinlocks, etc.:
-- */
--
--#define __raw_local_irq_save()                                                \
--({                                                                    \
--      unsigned long flags = __raw_local_save_flags();                 \
--                                                                      \
--      raw_local_irq_disable();                                        \
--                                                                      \
--      flags;                                                          \
--})
--
--#define raw_local_irq_save(flags) \
--              do { (flags) = __raw_local_irq_save(); } while (0)
--
--#define raw_irqs_disabled()                                           \
--({                                                                    \
--      unsigned long flags = __raw_local_save_flags();                 \
--                                                                      \
--      raw_irqs_disabled_flags(flags);                                 \
--})
--
--/*
-- * makes the traced hardirq state match with the machine state
-- *
-- * should be a rarely used function, only in places where its
-- * otherwise impossible to know the irq state, like in traps.
-- */
--static inline void trace_hardirqs_fixup_flags(unsigned long flags)
+-void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
 -{
--      if (raw_irqs_disabled_flags(flags))
--              trace_hardirqs_off();
--      else
--              trace_hardirqs_on();
+-      return;
 -}
 -
--#define trace_hardirqs_fixup() \
--      trace_hardirqs_fixup_flags(__raw_local_save_flags())
--/*
-- * Used in the idle loop; sti takes one instruction cycle
-- * to complete:
-- */
--void xen_safe_halt(void);
--static inline void raw_safe_halt(void)
+-void __attribute__ ((weak))
+-arch_teardown_msi_irqs(struct pci_dev *dev)
 -{
--      xen_safe_halt();
--}
+-      struct msi_desc *entry;
 -
--/*
-- * Used when interrupts are already enabled or to
-- * shutdown the processor:
-- */
--void xen_halt(void);
--static inline void halt(void)
--{
--      xen_halt();
+-      list_for_each_entry(entry, &dev->msi_list, list) {
+-              if (entry->irq != 0)
+-                      arch_teardown_msi_irq(entry->irq);
+-      }
 -}
--
--#else /* __ASSEMBLY__: */
--# ifdef CONFIG_TRACE_IRQFLAGS
--#  define TRACE_IRQS_ON               call trace_hardirqs_on_thunk
--#  define TRACE_IRQS_OFF      call trace_hardirqs_off_thunk
--# else
--#  define TRACE_IRQS_ON
--#  define TRACE_IRQS_OFF
--# endif
--# ifdef CONFIG_DEBUG_LOCK_ALLOC
--#  define LOCKDEP_SYS_EXIT    call lockdep_sys_exit_thunk
--#  define LOCKDEP_SYS_EXIT_IRQ        \
--      TRACE_IRQS_ON; \
--      sti; \
--      SAVE_REST; \
--      LOCKDEP_SYS_EXIT; \
--      RESTORE_REST; \
--      cli; \
--      TRACE_IRQS_OFF;
--# else
--#  define LOCKDEP_SYS_EXIT
--#  define LOCKDEP_SYS_EXIT_IRQ
--# endif
--#endif
--
 -#endif
---- a/include/asm-x86/mach-xen/asm/irqflags.h
-+++ b/include/asm-x86/mach-xen/asm/irqflags.h
-@@ -1,5 +1,247 @@
--#ifdef CONFIG_X86_32
--# include "irqflags_32.h"
-+#ifndef _X86_IRQFLAGS_H_
-+#define _X86_IRQFLAGS_H_
+--- sle11-2009-05-14.orig/drivers/pci/pci.c    2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/drivers/pci/pci.c 2009-03-16 16:33:40.000000000 +0100
+@@ -353,7 +353,12 @@ pci_find_parent_resource(const struct pc
+  * Restore the BAR values for a given device, so as to make it
+  * accessible by its driver.
+  */
++#ifndef CONFIG_XEN
+ static void
++#else
++EXPORT_SYMBOL_GPL(pci_restore_bars);
++void
++#endif
+ pci_restore_bars(struct pci_dev *dev)
+ {
+       int i, numres;
+--- sle11-2009-05-14.orig/drivers/xen/balloon/sysfs.c  2009-03-04 11:25:55.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/balloon/sysfs.c       2009-03-16 16:33:40.000000000 +0100
+@@ -108,7 +108,7 @@ static struct attribute_group balloon_in
+ };
+ static struct sysdev_class balloon_sysdev_class = {
+-      set_kset_name(BALLOON_CLASS_NAME),
++      .name = BALLOON_CLASS_NAME,
+ };
+ static struct sys_device balloon_sysdev;
+--- sle11-2009-05-14.orig/drivers/xen/blkback/blkback.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/blkback/blkback.c     2009-03-16 16:33:40.000000000 +0100
+@@ -148,7 +148,7 @@ static void unplug_queue(blkif_t *blkif)
+               return;
+       if (blkif->plug->unplug_fn)
+               blkif->plug->unplug_fn(blkif->plug);
+-      blk_put_queue(blkif->plug);
++      kobject_put(&blkif->plug->kobj);
+       blkif->plug = NULL;
+ }
+@@ -159,7 +159,8 @@ static void plug_queue(blkif_t *blkif, s
+       if (q == blkif->plug)
+               return;
+       unplug_queue(blkif);
+-      blk_get_queue(q);
++      WARN_ON(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags));
++      kobject_get(&q->kobj);
+       blkif->plug = q;
+ }
+--- sle11-2009-05-14.orig/drivers/xen/blkfront/blkfront.c      2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/blkfront/blkfront.c   2009-03-24 10:12:53.000000000 +0100
+@@ -713,7 +713,6 @@ static irqreturn_t blkif_int(int irq, vo
+       RING_IDX i, rp;
+       unsigned long flags;
+       struct blkfront_info *info = (struct blkfront_info *)dev_id;
+-      int uptodate;
+       spin_lock_irqsave(&blkif_io_lock, flags);
+@@ -738,13 +737,13 @@ static irqreturn_t blkif_int(int irq, vo
+               ADD_ID_TO_FREELIST(info, id);
+-              uptodate = (bret->status == BLKIF_RSP_OKAY);
++              ret = bret->status == BLKIF_RSP_OKAY ? 0 : -EIO;
+               switch (bret->operation) {
+               case BLKIF_OP_WRITE_BARRIER:
+                       if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
+                               printk("blkfront: %s: write barrier op failed\n",
+                                      info->gd->disk_name);
+-                              uptodate = -EOPNOTSUPP;
++                              ret = -EOPNOTSUPP;
+                               info->feature_barrier = 0;
+                               xlvbd_barrier(info);
+                       }
+@@ -755,10 +754,8 @@ static irqreturn_t blkif_int(int irq, vo
+                               DPRINTK("Bad return from blkdev data "
+                                       "request: %x\n", bret->status);
+-                      ret = end_that_request_first(req, uptodate,
+-                              req->hard_nr_sectors);
++                      ret = __blk_end_request(req, ret, blk_rq_bytes(req));
+                       BUG_ON(ret);
+-                      end_that_request_last(req, uptodate);
+                       break;
+               default:
+                       BUG();
+--- sle11-2009-05-14.orig/drivers/xen/blktap/blktap.c  2009-04-20 11:37:50.000000000 +0200
++++ sle11-2009-05-14/drivers/xen/blktap/blktap.c       2009-04-20 11:38:54.000000000 +0200
+@@ -331,8 +331,8 @@ static pte_t blktap_clear_pte(struct vm_
+        * if vm_file is NULL (meaning mmap failed and we have nothing to do)
+        */
+       if (uvaddr < uvstart || vma->vm_file == NULL)
+-              return ptep_get_and_clear_full(vma->vm_mm, uvaddr, 
+-                                             ptep, is_fullmm);
++              return xen_ptep_get_and_clear_full(vma, uvaddr, ptep,
++                                                 is_fullmm);
+       info = vma->vm_file->private_data;
+       priv = vma->vm_private_data;
+@@ -379,8 +379,8 @@ static pte_t blktap_clear_pte(struct vm_
+               BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap));
+               /* USING SHADOW PAGE TABLES. */
+-              copy = ptep_get_and_clear_full(vma->vm_mm, uvaddr, ptep,
+-                                             is_fullmm);
++              copy = xen_ptep_get_and_clear_full(vma, uvaddr, ptep,
++                                                 is_fullmm);
+       }
+       if (count) {
+--- sle11-2009-05-14.orig/drivers/xen/core/Makefile    2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/drivers/xen/core/Makefile 2009-03-16 16:33:40.000000000 +0100
+@@ -10,5 +10,6 @@ obj-$(CONFIG_SYS_HYPERVISOR) += hypervis
+ obj-$(CONFIG_HOTPLUG_CPU)     += cpu_hotplug.o
+ obj-$(CONFIG_XEN_SYSFS)               += xen_sysfs.o
+ obj-$(CONFIG_XEN_SMPBOOT)     += smpboot.o
++obj-$(CONFIG_X86_SMP)         += spinlock.o
+ obj-$(CONFIG_KEXEC)           += machine_kexec.o
+ obj-$(CONFIG_XEN_XENCOMM)     += xencomm.o
+--- sle11-2009-05-14.orig/drivers/xen/core/evtchn.c    2009-03-04 11:25:55.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/core/evtchn.c 2009-03-16 16:33:40.000000000 +0100
+@@ -194,7 +194,7 @@ static inline unsigned int cpu_from_evtc
+ /* Upcall to generic IRQ layer. */
+ #ifdef CONFIG_X86
+-extern fastcall unsigned int do_IRQ(struct pt_regs *regs);
++extern unsigned int do_IRQ(struct pt_regs *regs);
+ void __init xen_init_IRQ(void);
+ void __init init_IRQ(void)
+ {
+@@ -203,13 +203,11 @@ void __init init_IRQ(void)
+ }
+ #if defined (__i386__)
+ static inline void exit_idle(void) {}
+-#define IRQ_REG orig_eax
+ #elif defined (__x86_64__)
+ #include <asm/idle.h>
+-#define IRQ_REG orig_rax
+ #endif
+ #define do_IRQ(irq, regs) do {                \
+-      (regs)->IRQ_REG = ~(irq);       \
++      (regs)->orig_ax = ~(irq);       \
+       do_IRQ((regs));                 \
+ } while (0)
+ #endif
+@@ -670,13 +668,12 @@ static void set_affinity_irq(unsigned in
+ int resend_irq_on_evtchn(unsigned int irq)
+ {
+       int masked, evtchn = evtchn_from_irq(irq);
+-      shared_info_t *s = HYPERVISOR_shared_info;
+       if (!VALID_EVTCHN(evtchn))
+               return 1;
+       masked = test_and_set_evtchn_mask(evtchn);
+-      synch_set_bit(evtchn, s->evtchn_pending);
++      set_evtchn(evtchn);
+       if (!masked)
+               unmask_evtchn(evtchn);
+@@ -969,6 +966,43 @@ void disable_all_local_evtchn(void)
+                       synch_set_bit(i, &s->evtchn_mask[0]);
+ }
++/* Clear an irq's pending state, in preparation for polling on it. */
++void xen_clear_irq_pending(int irq)
++{
++      int evtchn = evtchn_from_irq(irq);
 +
-+#include <asm/processor-flags.h>
++      if (VALID_EVTCHN(evtchn))
++              clear_evtchn(evtchn);
++}
 +
-+#ifndef __ASSEMBLY__
-+/*
-+ * The use of 'barrier' in the following reflects their use as local-lock
-+ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
-+ * critical operations are executed. All critical operations must complete
-+ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
-+ * includes these barriers, for example.
-+ */
++/* Set an irq's pending state, to avoid blocking on it. */
++void xen_set_irq_pending(int irq)
++{
++      int evtchn = evtchn_from_irq(irq);
 +
-+#define xen_save_fl(void) (current_vcpu_info()->evtchn_upcall_mask)
++      if (VALID_EVTCHN(evtchn))
++              set_evtchn(evtchn);
++}
 +
-+#define xen_restore_fl(f)                                     \
-+do {                                                          \
-+      vcpu_info_t *_vcpu;                                     \
-+      barrier();                                              \
-+      _vcpu = current_vcpu_info();                            \
-+      if ((_vcpu->evtchn_upcall_mask = (f)) == 0) {           \
-+              barrier(); /* unmask then check (avoid races) */\
-+              if (unlikely(_vcpu->evtchn_upcall_pending))     \
-+                      force_evtchn_callback();                \
-+      }                                                       \
-+} while (0)
++/* Test an irq's pending state. */
++int xen_test_irq_pending(int irq)
++{
++      int evtchn = evtchn_from_irq(irq);
 +
-+#define xen_irq_disable()                                     \
-+do {                                                          \
-+      current_vcpu_info()->evtchn_upcall_mask = 1;            \
-+      barrier();                                              \
-+} while (0)
++      return VALID_EVTCHN(evtchn) && test_evtchn(evtchn);
++}
 +
-+#define xen_irq_enable()                                      \
-+do {                                                          \
-+      vcpu_info_t *_vcpu;                                     \
-+      barrier();                                              \
-+      _vcpu = current_vcpu_info();                            \
-+      _vcpu->evtchn_upcall_mask = 0;                          \
-+      barrier(); /* unmask then check (avoid races) */        \
-+      if (unlikely(_vcpu->evtchn_upcall_pending))             \
-+              force_evtchn_callback();                        \
-+} while (0)
++/* Poll waiting for an irq to become pending.  In the usual case, the
++   irq will be disabled so it won't deliver an interrupt. */
++void xen_poll_irq(int irq)
++{
++      evtchn_port_t evtchn = evtchn_from_irq(irq);
 +
-+void xen_safe_halt(void);
++      if (VALID_EVTCHN(evtchn)
++          && HYPERVISOR_poll_no_timeout(&evtchn, 1))
++              BUG();
++}
 +
-+void xen_halt(void);
+ static void restore_cpu_virqs(unsigned int cpu)
+ {
+       struct evtchn_bind_virq bind_virq;
+@@ -1022,8 +1056,8 @@ static void restore_cpu_ipis(unsigned in
+               bind_evtchn_to_cpu(evtchn, cpu);
+               /* Ready for use. */
+-              unmask_evtchn(evtchn);
+-
++              if (!(irq_desc[irq].status & IRQ_DISABLED))
++                      unmask_evtchn(evtchn);
+       }
+ }
+--- sle11-2009-05-14.orig/drivers/xen/core/hypervisor_sysfs.c  2008-12-15 11:27:22.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/core/hypervisor_sysfs.c       2009-03-16 16:33:40.000000000 +0100
+@@ -50,7 +50,7 @@ static int __init hypervisor_subsys_init
+       if (!is_running_on_xen())
+               return -ENODEV;
+-      hypervisor_subsys.kobj.ktype = &hyp_sysfs_kobj_type;
++      hypervisor_kobj->ktype = &hyp_sysfs_kobj_type;
+       return 0;
+ }
+--- sle11-2009-05-14.orig/drivers/xen/core/smpboot.c   2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/core/smpboot.c        2009-03-16 16:33:40.000000000 +0100
+@@ -135,6 +135,10 @@ static int __cpuinit xen_smp_intr_init(u
+               goto fail;
+       per_cpu(callfunc_irq, cpu) = rc;
++      rc = xen_spinlock_init(cpu);
++      if (rc < 0)
++              goto fail;
 +
-+#define __raw_local_save_flags() xen_save_fl()
+       if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0))
+               goto fail;
+@@ -145,6 +149,7 @@ static int __cpuinit xen_smp_intr_init(u
+               unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
+       if (per_cpu(callfunc_irq, cpu) >= 0)
+               unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
++      xen_spinlock_cleanup(cpu);
+       return rc;
+ }
+@@ -156,6 +161,7 @@ static void xen_smp_intr_exit(unsigned i
+       unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
+       unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
++      xen_spinlock_cleanup(cpu);
+ }
+ #endif
+@@ -208,36 +214,25 @@ static void __cpuinit cpu_initialize_con
+       smp_trap_init(ctxt.trap_ctxt);
+       ctxt.ldt_ents = 0;
+-      ctxt.gdt_ents = GDT_SIZE / 8;
+-
+-#ifdef __i386__
+       ctxt.gdt_frames[0] = virt_to_mfn(get_cpu_gdt_table(cpu));
++      ctxt.gdt_ents = GDT_SIZE / 8;
+       ctxt.user_regs.cs = __KERNEL_CS;
+-      ctxt.user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
++      ctxt.user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
+       ctxt.kernel_ss = __KERNEL_DS;
+-      ctxt.kernel_sp = idle->thread.esp0;
++      ctxt.kernel_sp = idle->thread.sp0;
+-      ctxt.event_callback_cs     = __KERNEL_CS;
+       ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
+-      ctxt.failsafe_callback_cs  = __KERNEL_CS;
+       ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
++#ifdef __i386__
++      ctxt.event_callback_cs     = __KERNEL_CS;
++      ctxt.failsafe_callback_cs  = __KERNEL_CS;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
+       ctxt.user_regs.fs = __KERNEL_PERCPU;
+ #else /* __x86_64__ */
+-      ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[cpu].address);
+-
+-      ctxt.user_regs.cs = __KERNEL_CS;
+-      ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
+-
+-      ctxt.kernel_ss = __KERNEL_DS;
+-      ctxt.kernel_sp = idle->thread.rsp0;
+-
+-      ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
+-      ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
+       ctxt.syscall_callback_eip  = (unsigned long)system_call;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/drivers/xen/core/spinlock.c       2009-03-16 16:33:40.000000000 +0100
+@@ -0,0 +1,161 @@
++/*
++ *    Xen spinlock functions
++ *
++ *    See arch/x86/xen/smp.c for copyright and credits for derived
++ *    portions of this file.
++ */
 +
-+#define raw_local_irq_restore(flags) xen_restore_fl(flags)
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/kernel_stat.h>
++#include <linux/module.h>
++#include <xen/evtchn.h>
 +
-+#define raw_local_irq_disable()       xen_irq_disable()
++extern irqreturn_t smp_reschedule_interrupt(int, void *);
 +
-+#define raw_local_irq_enable() xen_irq_enable()
++static DEFINE_PER_CPU(int, spinlock_irq) = -1;
++static char spinlock_name[NR_CPUS][15];
 +
++struct spinning {
++      raw_spinlock_t *lock;
++      unsigned int ticket;
++      struct spinning *prev;
++};
++static DEFINE_PER_CPU(struct spinning *, spinning);
 +/*
-+ * Used in the idle loop; sti takes one instruction cycle
-+ * to complete:
++ * Protect removal of objects: Addition can be done lockless, and even
++ * removal itself doesn't need protection - what needs to be prevented is
++ * removed objects going out of scope (as they're allocated on the stack.
 + */
-+static inline void raw_safe_halt(void)
++static DEFINE_PER_CPU(raw_rwlock_t, spinning_rm_lock) = __RAW_RW_LOCK_UNLOCKED;
++
++int __cpuinit xen_spinlock_init(unsigned int cpu)
 +{
-+      xen_safe_halt();
++      int rc;
++
++      sprintf(spinlock_name[cpu], "spinlock%u", cpu);
++      rc = bind_ipi_to_irqhandler(SPIN_UNLOCK_VECTOR,
++                                  cpu,
++                                  smp_reschedule_interrupt,
++                                  IRQF_DISABLED|IRQF_NOBALANCING,
++                                  spinlock_name[cpu],
++                                  NULL);
++      if (rc < 0)
++              return rc;
++
++      disable_irq(rc); /* make sure it's never delivered */
++      per_cpu(spinlock_irq, cpu) = rc;
++
++      return 0;
 +}
 +
-+/*
-+ * Used when interrupts are already enabled or to
-+ * shutdown the processor:
-+ */
-+static inline void halt(void)
++void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
 +{
-+      xen_halt();
++      if (per_cpu(spinlock_irq, cpu) >= 0)
++              unbind_from_irqhandler(per_cpu(spinlock_irq, cpu), NULL);
++      per_cpu(spinlock_irq, cpu) = -1;
 +}
 +
-+/*
-+ * For spinlocks, etc:
-+ */
-+#define __raw_local_irq_save()                                                \
-+({                                                                    \
-+      unsigned long flags = __raw_local_save_flags();                 \
-+                                                                      \
-+      raw_local_irq_disable();                                        \
-+                                                                      \
-+      flags;                                                          \
-+})
- #else
--# include "irqflags_64.h"
-+
-+/* Offsets into shared_info_t. */
-+#define evtchn_upcall_pending         /* 0 */
-+#define evtchn_upcall_mask            1
++int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
++{
++      int rc = 0, irq = __get_cpu_var(spinlock_irq);
++      raw_rwlock_t *rm_lock;
++      unsigned long flags;
++      struct spinning spinning;
 +
-+#define sizeof_vcpu_shift             6
++      /* If kicker interrupt not initialized yet, just spin. */
++      if (unlikely(irq < 0))
++              return 0;
 +
-+#ifdef CONFIG_X86_64
-+# define __REG_si %rsi
-+# define __CPU_num %gs:pda_cpunumber
-+#else
-+# define __REG_si %esi
-+# define __CPU_num TI_cpu(%ebp)
-+#endif
++      token >>= TICKET_SHIFT;
 +
-+#ifdef CONFIG_SMP
-+#define GET_VCPU_INFO         movl __CPU_num,%esi                     ; \
-+                              shl $sizeof_vcpu_shift,%esi             ; \
-+                              add HYPERVISOR_shared_info,__REG_si
-+#else
-+#define GET_VCPU_INFO         mov HYPERVISOR_shared_info,__REG_si
-+#endif
++      /* announce we're spinning */
++      spinning.ticket = token;
++      spinning.lock = lock;
++      spinning.prev = __get_cpu_var(spinning);
++      smp_wmb();
++      __get_cpu_var(spinning) = &spinning;
 +
-+#define __DISABLE_INTERRUPTS  movb $1,evtchn_upcall_mask(__REG_si)
-+#define __ENABLE_INTERRUPTS   movb $0,evtchn_upcall_mask(__REG_si)
-+#define __TEST_PENDING                testb $0xFF,evtchn_upcall_pending(__REG_si)
-+#define DISABLE_INTERRUPTS(clb)       GET_VCPU_INFO                           ; \
-+                              __DISABLE_INTERRUPTS
-+#define ENABLE_INTERRUPTS(clb)        GET_VCPU_INFO                           ; \
-+                              __ENABLE_INTERRUPTS
++      /* clear pending */
++      xen_clear_irq_pending(irq);
 +
-+#ifndef CONFIG_X86_64
-+#define INTERRUPT_RETURN              iret
-+#define ENABLE_INTERRUPTS_SYSCALL_RET __ENABLE_INTERRUPTS             ; \
-+sysexit_scrit:        /**** START OF SYSEXIT CRITICAL REGION ****/            ; \
-+      __TEST_PENDING                                                  ; \
-+      jnz  14f        /* process more events if necessary... */       ; \
-+      movl PT_ESI(%esp), %esi                                         ; \
-+      sysexit                                                         ; \
-+14:   __DISABLE_INTERRUPTS                                            ; \
-+      TRACE_IRQS_OFF                                                  ; \
-+sysexit_ecrit:        /**** END OF SYSEXIT CRITICAL REGION ****/              ; \
-+      push %esp                                                       ; \
-+      call evtchn_do_upcall                                           ; \
-+      add  $4,%esp                                                    ; \
-+      jmp  ret_from_intr
-+#endif
++      do {
++              /* Check again to make sure it didn't become free while
++               * we weren't looking. */
++              if ((lock->slock & ((1U << TICKET_SHIFT) - 1)) == token) {
++                      /* If we interrupted another spinlock while it was
++                       * blocking, make sure it doesn't block (again)
++                       * without rechecking the lock. */
++                      if (spinning.prev)
++                              xen_set_irq_pending(irq);
++                      rc = 1;
++                      break;
++              }
 +
++              /* block until irq becomes pending */
++              xen_poll_irq(irq);
++      } while (!xen_test_irq_pending(irq));
 +
-+#endif /* __ASSEMBLY__ */
++      /* Leave the irq pending so that any interrupted blocker will
++       * re-check. */
++      kstat_this_cpu.irqs[irq] += !rc;
 +
-+#ifndef __ASSEMBLY__
-+#define raw_local_save_flags(flags) \
-+              do { (flags) = __raw_local_save_flags(); } while (0)
++      /* announce we're done */
++      __get_cpu_var(spinning) = spinning.prev;
++      rm_lock = &__get_cpu_var(spinning_rm_lock);
++      raw_local_irq_save(flags);
++      __raw_write_lock(rm_lock);
++      __raw_write_unlock(rm_lock);
++      raw_local_irq_restore(flags);
 +
-+#define raw_local_irq_save(flags) \
-+              do { (flags) = __raw_local_irq_save(); } while (0)
++      return rc;
++}
++EXPORT_SYMBOL(xen_spin_wait);
 +
-+static inline int raw_irqs_disabled_flags(unsigned long flags)
++unsigned int xen_spin_adjust(raw_spinlock_t *lock, unsigned int token)
 +{
-+      return (flags != 0);
++      return token;//todo
 +}
++EXPORT_SYMBOL(xen_spin_adjust);
 +
-+#define raw_irqs_disabled()                                           \
-+({                                                                    \
-+      unsigned long flags = __raw_local_save_flags();                 \
-+                                                                      \
-+      raw_irqs_disabled_flags(flags);                                 \
-+})
-+
-+/*
-+ * makes the traced hardirq state match with the machine state
-+ *
-+ * should be a rarely used function, only in places where its
-+ * otherwise impossible to know the irq state, like in traps.
-+ */
-+static inline void trace_hardirqs_fixup_flags(unsigned long flags)
++int xen_spin_wait_flags(raw_spinlock_t *lock, unsigned int *token,
++                        unsigned int flags)
 +{
-+      if (raw_irqs_disabled_flags(flags))
-+              trace_hardirqs_off();
-+      else
-+              trace_hardirqs_on();
++      return xen_spin_wait(lock, *token);//todo
 +}
++EXPORT_SYMBOL(xen_spin_wait_flags);
 +
-+#define trace_hardirqs_fixup() \
-+      trace_hardirqs_fixup_flags(__raw_local_save_flags())
-+
-+#else
-+
-+#ifdef CONFIG_X86_64
-+/*
-+ * Currently paravirt can't handle swapgs nicely when we
-+ * don't have a stack we can rely on (such as a user space
-+ * stack).  So we either find a way around these or just fault
-+ * and emulate if a guest tries to call swapgs directly.
-+ *
-+ * Either way, this is a good way to document that we don't
-+ * have a reliable stack. x86_64 only.
-+ */
-+#define SWAPGS_UNSAFE_STACK   swapgs
-+#define ARCH_TRACE_IRQS_ON            call trace_hardirqs_on_thunk
-+#define ARCH_TRACE_IRQS_OFF           call trace_hardirqs_off_thunk
-+#define ARCH_LOCKDEP_SYS_EXIT         call lockdep_sys_exit_thunk
-+#define ARCH_LOCKDEP_SYS_EXIT_IRQ     \
-+      TRACE_IRQS_ON; \
-+      ENABLE_INTERRUPTS(CLBR_NONE); \
-+      SAVE_REST; \
-+      LOCKDEP_SYS_EXIT; \
-+      RESTORE_REST; \
-+      __DISABLE_INTERRUPTS; \
-+      TRACE_IRQS_OFF;
++void xen_spin_kick(raw_spinlock_t *lock, unsigned int token)
++{
++      unsigned int cpu;
 +
-+#else
-+#define ARCH_TRACE_IRQS_ON                    \
-+      pushl %eax;                             \
-+      pushl %ecx;                             \
-+      pushl %edx;                             \
-+      call trace_hardirqs_on;                 \
-+      popl %edx;                              \
-+      popl %ecx;                              \
-+      popl %eax;
++      token &= (1U << TICKET_SHIFT) - 1;
++      for_each_online_cpu(cpu) {
++              raw_rwlock_t *rm_lock;
++              unsigned long flags;
++              struct spinning *spinning;
 +
-+#define ARCH_TRACE_IRQS_OFF                   \
-+      pushl %eax;                             \
-+      pushl %ecx;                             \
-+      pushl %edx;                             \
-+      call trace_hardirqs_off;                \
-+      popl %edx;                              \
-+      popl %ecx;                              \
-+      popl %eax;
++              if (cpu == raw_smp_processor_id())
++                      continue;
 +
-+#define ARCH_LOCKDEP_SYS_EXIT                 \
-+      pushl %eax;                             \
-+      pushl %ecx;                             \
-+      pushl %edx;                             \
-+      call lockdep_sys_exit;                  \
-+      popl %edx;                              \
-+      popl %ecx;                              \
-+      popl %eax;
++              rm_lock = &per_cpu(spinning_rm_lock, cpu);
++              raw_local_irq_save(flags);
++              __raw_read_lock(rm_lock);
 +
-+#define ARCH_LOCKDEP_SYS_EXIT_IRQ
-+#endif
++              spinning = per_cpu(spinning, cpu);
++              smp_rmb();
++              if (spinning
++                  && (spinning->lock != lock || spinning->ticket != token))
++                      spinning = NULL;
 +
-+#ifdef CONFIG_TRACE_IRQFLAGS
-+#  define TRACE_IRQS_ON               ARCH_TRACE_IRQS_ON
-+#  define TRACE_IRQS_OFF      ARCH_TRACE_IRQS_OFF
-+#else
-+#  define TRACE_IRQS_ON
-+#  define TRACE_IRQS_OFF
-+#endif
-+#ifdef CONFIG_DEBUG_LOCK_ALLOC
-+#  define LOCKDEP_SYS_EXIT    ARCH_LOCKDEP_SYS_EXIT
-+#  define LOCKDEP_SYS_EXIT_IRQ        ARCH_LOCKDEP_SYS_EXIT_IRQ
-+# else
-+#  define LOCKDEP_SYS_EXIT
-+#  define LOCKDEP_SYS_EXIT_IRQ
-+# endif
++              __raw_read_unlock(rm_lock);
++              raw_local_irq_restore(flags);
 +
-+#endif /* __ASSEMBLY__ */
- #endif
---- a/include/asm-x86/mach-xen/asm/maddr_32.h
-+++ b/include/asm-x86/mach-xen/asm/maddr_32.h
-@@ -1,6 +1,7 @@
- #ifndef _I386_MADDR_H
- #define _I386_MADDR_H
-+#include <asm/bug.h>
- #include <xen/features.h>
- #include <xen/interface/xen.h>
++              if (unlikely(spinning)) {
++                      notify_remote_via_irq(per_cpu(spinlock_irq, cpu));
++                      return;
++              }
++      }
++}
++EXPORT_SYMBOL(xen_spin_kick);
+--- sle11-2009-05-14.orig/drivers/xen/core/xen_sysfs.c 2008-12-15 11:27:22.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/core/xen_sysfs.c      2009-03-16 16:33:40.000000000 +0100
+@@ -29,12 +29,12 @@ HYPERVISOR_ATTR_RO(type);
  
-@@ -151,25 +152,9 @@ static inline paddr_t pte_machine_to_phy
-       phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
-       return phys;
+ static int __init xen_sysfs_type_init(void)
+ {
+-      return sysfs_create_file(&hypervisor_subsys.kobj, &type_attr.attr);
++      return sysfs_create_file(hypervisor_kobj, &type_attr.attr);
  }
--#endif
--
--#ifdef CONFIG_X86_PAE
--#define __pte_ma(x)   ((pte_t) { (x), (maddr_t)(x) >> 32 } )
--extern unsigned long long __supported_pte_mask;
--static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
--{
--      pte_t pte;
--
--      pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
--                                      (pgprot_val(pgprot) >> 32);
--      pte.pte_high &= (__supported_pte_mask >> 32);
--      pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
--                                                      __supported_pte_mask;
--      return pte;
--}
- #else
--#define __pte_ma(x)   ((pte_t) { (x) } )
--#define pfn_pte_ma(pfn, prot) __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-+#define pte_phys_to_machine phys_to_machine
-+#define pte_machine_to_phys machine_to_phys
- #endif
- #else /* !CONFIG_XEN */
---- a/include/asm-x86/mach-xen/asm/maddr_64.h
-+++ b/include/asm-x86/mach-xen/asm/maddr_64.h
-@@ -1,6 +1,7 @@
- #ifndef _X86_64_MADDR_H
- #define _X86_64_MADDR_H
-+#include <asm/bug.h>
- #include <xen/features.h>
- #include <xen/interface/xen.h>
  
-@@ -16,6 +17,7 @@ typedef unsigned long maddr_t;
- #ifdef CONFIG_XEN
+ static void xen_sysfs_type_destroy(void)
+ {
+-      sysfs_remove_file(&hypervisor_subsys.kobj, &type_attr.attr);
++      sysfs_remove_file(hypervisor_kobj, &type_attr.attr);
+ }
  
- extern unsigned long *phys_to_machine_mapping;
-+extern unsigned long  max_mapnr;
+ /* xen version attributes */
+@@ -90,13 +90,12 @@ static struct attribute_group version_gr
  
- #undef machine_to_phys_mapping
- extern unsigned long *machine_to_phys_mapping;
-@@ -25,7 +27,7 @@ static inline unsigned long pfn_to_mfn(u
+ static int __init xen_sysfs_version_init(void)
  {
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return pfn;
--      BUG_ON(end_pfn && pfn >= end_pfn);
-+      BUG_ON(max_mapnr && pfn >= max_mapnr);
-       return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
+-      return sysfs_create_group(&hypervisor_subsys.kobj,
+-                                &version_group);
++      return sysfs_create_group(hypervisor_kobj, &version_group);
  }
  
-@@ -33,7 +35,7 @@ static inline int phys_to_machine_mappin
+ static void xen_sysfs_version_destroy(void)
  {
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return 1;
--      BUG_ON(end_pfn && pfn >= end_pfn);
-+      BUG_ON(max_mapnr && pfn >= max_mapnr);
-       return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+-      sysfs_remove_group(&hypervisor_subsys.kobj, &version_group);
++      sysfs_remove_group(hypervisor_kobj, &version_group);
  }
  
-@@ -45,7 +47,7 @@ static inline unsigned long mfn_to_pfn(u
-               return mfn;
-       if (unlikely((mfn >> machine_to_phys_order) != 0))
--              return end_pfn;
-+              return max_mapnr;
-       /* The array access can fail (e.g., device space beyond end of RAM). */
-       asm (
-@@ -60,7 +62,7 @@ static inline unsigned long mfn_to_pfn(u
-               "       .quad 1b,3b\n"
-               ".previous"
-               : "=r" (pfn)
--              : "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
-+              : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
+ /* UUID */
+@@ -126,12 +125,12 @@ HYPERVISOR_ATTR_RO(uuid);
  
-       return pfn;
- }
-@@ -88,16 +90,16 @@ static inline unsigned long mfn_to_pfn(u
- static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+ static int __init xen_sysfs_uuid_init(void)
  {
-       unsigned long pfn = mfn_to_pfn(mfn);
--      if ((pfn < end_pfn)
-+      if ((pfn < max_mapnr)
-           && !xen_feature(XENFEAT_auto_translated_physmap)
-           && (phys_to_machine_mapping[pfn] != mfn))
--              return end_pfn; /* force !pfn_valid() */
-+              return max_mapnr; /* force !pfn_valid() */
-       return pfn;
+-      return sysfs_create_file(&hypervisor_subsys.kobj, &uuid_attr.attr);
++      return sysfs_create_file(hypervisor_kobj, &uuid_attr.attr);
  }
  
- static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+ static void xen_sysfs_uuid_destroy(void)
  {
--      BUG_ON(end_pfn && pfn >= end_pfn);
-+      BUG_ON(max_mapnr && pfn >= max_mapnr);
-       if (xen_feature(XENFEAT_auto_translated_physmap)) {
-               BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
-               return;
-@@ -135,9 +137,6 @@ static inline paddr_t pte_machine_to_phy
-       return phys;
+-      sysfs_remove_file(&hypervisor_subsys.kobj, &uuid_attr.attr);
++      sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr);
  }
  
--#define __pte_ma(x)     ((pte_t) { (x) } )
--#define pfn_pte_ma(pfn, prot) __pte_ma((((pfn) << PAGE_SHIFT) | pgprot_val(prot)) & __supported_pte_mask)
--
- #else /* !CONFIG_XEN */
+ /* xen compilation attributes */
+@@ -204,14 +203,12 @@ static struct attribute_group xen_compil
  
#define pfn_to_mfn(pfn) (pfn)
---- a/include/asm-x86/mach-xen/asm/mmu_context_32.h
-+++ b/include/asm-x86/mach-xen/asm/mmu_context_32.h
-@@ -51,8 +51,6 @@ static inline void __prepare_arch_switch
-               : : "r" (0) );
int __init static xen_compilation_init(void)
+ {
+-      return sysfs_create_group(&hypervisor_subsys.kobj,
+-                                &xen_compilation_group);
++      return sysfs_create_group(hypervisor_kobj, &xen_compilation_group);
  }
  
--void leave_mm(unsigned long cpu);
--
- static inline void switch_mm(struct mm_struct *prev,
-                            struct mm_struct *next,
-                            struct task_struct *tsk)
---- a/include/asm-x86/mach-xen/asm/mmu_context_64.h
-+++ b/include/asm-x86/mach-xen/asm/mmu_context_64.h
-@@ -62,12 +62,6 @@ extern void mm_pin(struct mm_struct *mm)
- extern void mm_unpin(struct mm_struct *mm);
- void mm_pin_all(void);
--static inline void load_cr3(pgd_t *pgd)
--{
--      asm volatile("movq %0,%%cr3" :: "r" (phys_to_machine(__pa(pgd))) :
--                   "memory");
--}
--
- static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
-                            struct task_struct *tsk)
+ static void xen_compilation_destroy(void)
  {
-@@ -97,7 +91,7 @@ static inline void switch_mm(struct mm_s
-               op++;
-               
-               if (unlikely(next->context.ldt != prev->context.ldt)) {
--                      /* load_LDT_nolock(&next->context, cpu) */
-+                      /* load_LDT_nolock(&next->context) */
-                       op->cmd = MMUEXT_SET_LDT;
-                       op->arg1.linear_addr = (unsigned long)next->context.ldt;
-                       op->arg2.nr_ents     = next->context.size;
-@@ -110,7 +104,7 @@ static inline void switch_mm(struct mm_s
-       else {
-               write_pda(mmu_state, TLBSTATE_OK);
-               if (read_pda(active_mm) != next)
--                      out_of_line_bug();
-+                      BUG();
-               if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
-                       /* We were in lazy tlb mode and leave_mm disabled 
-                        * tlb flush IPI delivery. We must reload CR3
-@@ -118,7 +112,7 @@ static inline void switch_mm(struct mm_s
-                        */
-                         load_cr3(next->pgd);
-                         xen_new_user_pt(__pa(__user_pgd(next->pgd)));         
--                      load_LDT_nolock(&next->context, cpu);
-+                      load_LDT_nolock(&next->context);
-               }
-       }
- #endif
---- a/include/asm-x86/mach-xen/asm/page_64.h
-+++ b/include/asm-x86/mach-xen/asm/page_64.h
-@@ -1,37 +1,9 @@
- #ifndef _X86_64_PAGE_H
- #define _X86_64_PAGE_H
--/* #include <linux/string.h> */
--#ifndef __ASSEMBLY__
--#include <linux/kernel.h>
--#include <linux/types.h>
--#include <asm/bug.h>
--#endif
--#include <linux/const.h>
--#include <xen/interface/xen.h> 
--
--/*
-- * Need to repeat this here in order to not include pgtable.h (which in turn
-- * depends on definitions made here), but to be able to use the symbolic
-- * below. The preprocessor will warn if the two definitions aren't identical.
-- */
--#define _PAGE_PRESENT 0x001
--#define _PAGE_IO      0x200
--
--/* PAGE_SHIFT determines the page size */
--#define PAGE_SHIFT    12
--#define PAGE_SIZE     (_AC(1,UL) << PAGE_SHIFT)
--#define PAGE_MASK     (~(PAGE_SIZE-1))
--
--/* See Documentation/x86_64/mm.txt for a description of the memory map. */
--#define __PHYSICAL_MASK_SHIFT 46
--#define __PHYSICAL_MASK               ((_AC(1,UL) << __PHYSICAL_MASK_SHIFT) - 1)
--#define __VIRTUAL_MASK_SHIFT  48
--#define __VIRTUAL_MASK                ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
--
--#define PHYSICAL_PAGE_MASK    (~(PAGE_SIZE-1) & __PHYSICAL_MASK)
-+#define PAGETABLE_LEVELS      4
+-      sysfs_remove_group(&hypervisor_subsys.kobj,
+-                         &xen_compilation_group);
++      sysfs_remove_group(hypervisor_kobj, &xen_compilation_group);
+ }
  
--#define THREAD_ORDER 1 
-+#define THREAD_ORDER  1
- #define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)
- #define CURRENT_MASK (~(THREAD_SIZE-1))
+ /* xen properties info */
+@@ -325,14 +322,12 @@ static struct attribute_group xen_proper
  
-@@ -51,106 +23,10 @@
- #define MCE_STACK 5
- #define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
+ static int __init xen_properties_init(void)
+ {
+-      return sysfs_create_group(&hypervisor_subsys.kobj,
+-                                &xen_properties_group);
++      return sysfs_create_group(hypervisor_kobj, &xen_properties_group);
+ }
  
--#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
--#define LARGE_PAGE_SIZE (_AC(1,UL) << PMD_SHIFT)
--
--#define HPAGE_SHIFT PMD_SHIFT
--#define HPAGE_SIZE    (_AC(1,UL) << HPAGE_SHIFT)
--#define HPAGE_MASK    (~(HPAGE_SIZE - 1))
--#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
--
--#ifdef __KERNEL__
--#ifndef __ASSEMBLY__
--
--extern unsigned long end_pfn;
--
--#include <asm/maddr.h>
--
--void clear_page(void *);
--void copy_page(void *, void *);
--
--#define clear_user_page(page, vaddr, pg)      clear_page(page)
--#define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
--
--#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
--      alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
--#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
--
--/*
-- * These are used to make use of C type-checking..
-- */
--typedef struct { unsigned long pte; } pte_t;
--typedef struct { unsigned long pmd; } pmd_t;
--typedef struct { unsigned long pud; } pud_t;
--typedef struct { unsigned long pgd; } pgd_t;
--#define PTE_MASK      PHYSICAL_PAGE_MASK
--
--typedef struct { unsigned long pgprot; } pgprot_t;
--
--#define __pte_val(x) ((x).pte)
--#define pte_val(x) ((__pte_val(x) & (_PAGE_PRESENT|_PAGE_IO)) \
--                  == _PAGE_PRESENT ?                          \
--                  pte_machine_to_phys(__pte_val(x)) :         \
--                  __pte_val(x))
--
--#define __pmd_val(x) ((x).pmd)
--static inline unsigned long pmd_val(pmd_t x)
--{
--      unsigned long ret = __pmd_val(x);
--#if CONFIG_XEN_COMPAT <= 0x030002
--      if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
--#else
--      if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
--#endif
--      return ret;
--}
--
--#define __pud_val(x) ((x).pud)
--static inline unsigned long pud_val(pud_t x)
--{
--      unsigned long ret = __pud_val(x);
--      if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
--      return ret;
--}
--
--#define __pgd_val(x) ((x).pgd)
--static inline unsigned long pgd_val(pgd_t x)
--{
--      unsigned long ret = __pgd_val(x);
--      if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
--      return ret;
--}
--
--#define pgprot_val(x) ((x).pgprot)
--
--static inline pte_t __pte(unsigned long x)
--{
--      if ((x & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
--              x = pte_phys_to_machine(x);
--      return ((pte_t) { (x) });
--}
--
--static inline pmd_t __pmd(unsigned long x)
--{
--      if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
--      return ((pmd_t) { (x) });
--}
--
--static inline pud_t __pud(unsigned long x)
--{
--      if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
--      return ((pud_t) { (x) });
--}
--
--static inline pgd_t __pgd(unsigned long x)
--{
--      if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
--      return ((pgd_t) { (x) });
--}
--
--#define __pgprot(x)   ((pgprot_t) { (x) } )
-+#define PUD_PAGE_SIZE         (_AC(1, UL) << PUD_SHIFT)
-+#define PUD_PAGE_MASK         (~(PUD_PAGE_SIZE-1))
+ static void xen_properties_destroy(void)
+ {
+-      sysfs_remove_group(&hypervisor_subsys.kobj,
+-                         &xen_properties_group);
++      sysfs_remove_group(hypervisor_kobj, &xen_properties_group);
+ }
  
--#endif /* !__ASSEMBLY__ */
-+#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
+ #ifdef CONFIG_KEXEC
+@@ -350,13 +345,12 @@ HYPERVISOR_ATTR_RO(vmcoreinfo);
  
- #define __PHYSICAL_START      CONFIG_PHYSICAL_START
- #define __KERNEL_ALIGN                0x200000
-@@ -166,52 +42,58 @@ static inline pgd_t __pgd(unsigned long 
+ static int __init xen_sysfs_vmcoreinfo_init(void)
+ {
+-      return sysfs_create_file(&hypervisor_subsys.kobj,
+-                               &vmcoreinfo_attr.attr);
++      return sysfs_create_file(hypervisor_kobj, &vmcoreinfo_attr.attr);
+ }
  
- #define __START_KERNEL                (__START_KERNEL_map + __PHYSICAL_START)
- #define __START_KERNEL_map    _AC(0xffffffff80000000, UL)
--#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
+ static void xen_sysfs_vmcoreinfo_destroy(void)
+ {
+-      sysfs_remove_file(&hypervisor_subsys.kobj, &vmcoreinfo_attr.attr);
++      sysfs_remove_file(hypervisor_kobj, &vmcoreinfo_attr.attr);
+ }
  
- #if CONFIG_XEN_COMPAT <= 0x030002
- #undef LOAD_OFFSET
- #define LOAD_OFFSET           0
  #endif
+--- sle11-2009-05-14.orig/drivers/xen/gntdev/gntdev.c  2009-03-04 11:28:34.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/gntdev/gntdev.c       2009-03-16 16:33:40.000000000 +0100
+@@ -782,7 +782,7 @@ static pte_t gntdev_clear_pte(struct vm_
+                                      op.status);
+               } else {
+                       /* USING SHADOW PAGE TABLES. */
+-                      copy = ptep_get_and_clear_full(vma->vm_mm, addr, ptep, is_fullmm);
++                      copy = xen_ptep_get_and_clear_full(vma, addr, ptep, is_fullmm);
+               }
  
--/* to align the pointer to the (next) page boundary */
--#define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
--
--#define KERNEL_TEXT_SIZE  (40*1024*1024)
--#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL)
-+/* See Documentation/x86_64/mm.txt for a description of the memory map. */
-+#define __PHYSICAL_MASK_SHIFT 46
-+#define __VIRTUAL_MASK_SHIFT  48
+               /* Finally, we unmap the grant from kernel space. */
+@@ -810,7 +810,7 @@ static pte_t gntdev_clear_pte(struct vm_
+                                   >> PAGE_SHIFT, INVALID_P2M_ENTRY);
  
--#define PAGE_OFFSET           __PAGE_OFFSET
-+/*
-+ * Kernel image size is limited to 128 MB (see level2_kernel_pgt in
-+ * arch/x86/kernel/head_64.S), and it is mapped here:
-+ */
-+#define KERNEL_IMAGE_SIZE     (128*1024*1024)
-+#define KERNEL_IMAGE_START    _AC(0xffffffff80000000, UL)
+       } else {
+-              copy = ptep_get_and_clear_full(vma->vm_mm, addr, ptep, is_fullmm);
++              copy = xen_ptep_get_and_clear_full(vma, addr, ptep, is_fullmm);
+       }
  
- #ifndef __ASSEMBLY__
-+void clear_page(void *page);
-+void copy_page(void *to, void *from);
-+
-+extern unsigned long end_pfn;
-+extern unsigned long end_pfn_map;
-+
- static inline unsigned long __phys_addr(unsigned long x)
- {
--      return x - (x >= __START_KERNEL_map ? __START_KERNEL_map : PAGE_OFFSET);
-+      return x - (x >= __START_KERNEL_map ? __START_KERNEL_map : __PAGE_OFFSET);
- }
--#endif
+       return copy;
+--- sle11-2009-05-14.orig/drivers/xen/scsifront/scsifront.c    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/scsifront/scsifront.c 2009-03-16 16:33:40.000000000 +0100
+@@ -260,19 +260,19 @@ static int map_data_for_request(struct v
+               return -ENOMEM;
+       }
  
--#define __pa(x)               __phys_addr((unsigned long)(x))
--#define __pa_symbol(x)        __phys_addr((unsigned long)(x))
-+#define __phys_reloc_hide(x)  (x)
+-      if (sc->use_sg) {
++      if (scsi_bufflen(sc)) {
+               /* quoted scsi_lib.c/scsi_req_map_sg . */
+-              struct scatterlist *sg, *sgl = (struct scatterlist *)sc->request_buffer;
+-              unsigned int data_len = sc->request_bufflen;
++              struct scatterlist *sg, *sgl = scsi_sglist(sc);
++              unsigned int data_len = scsi_bufflen(sc);
  
--#define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
--#define __boot_va(x)          __va(x)
--#define __boot_pa(x)          __pa(x)
--#ifdef CONFIG_FLATMEM
--#define pfn_valid(pfn)                ((pfn) < end_pfn)
--#endif
-+/*
-+ * These are used to make use of C type-checking..
-+ */
-+typedef unsigned long pteval_t;
-+typedef unsigned long pmdval_t;
-+typedef unsigned long pudval_t;
-+typedef unsigned long pgdval_t;
-+typedef unsigned long pgprotval_t;
-+typedef unsigned long phys_addr_t;
+-              nr_pages = (sc->request_bufflen + sgl->offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
++              nr_pages = (data_len + sgl->offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
+               if (nr_pages > VSCSIIF_SG_TABLESIZE) {
+                       printk(KERN_ERR "scsifront: Unable to map request_buffer for command!\n");
+                       ref_cnt = (-E2BIG);
+                       goto big_to_sg;
+               }
  
--#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
--#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
--#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+-              for_each_sg (sgl, sg, sc->use_sg, i) {
++              for_each_sg (sgl, sg, scsi_sg_count(sc), i) {
+                       page = sg_page(sg);
+                       off = sg->offset;
+                       len = sg->length;
+@@ -306,45 +306,6 @@ static int map_data_for_request(struct v
+                               ref_cnt++;
+                       }
+               }
+-      } else if (sc->request_bufflen) {
+-              unsigned long end   = ((unsigned long)sc->request_buffer
+-                                      + sc->request_bufflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+-              unsigned long start = (unsigned long)sc->request_buffer >> PAGE_SHIFT;
+-
+-              page = virt_to_page(sc->request_buffer);
+-              nr_pages = end - start;
+-              len = sc->request_bufflen;
+-
+-              if (nr_pages > VSCSIIF_SG_TABLESIZE) {
+-                      ref_cnt = (-E2BIG);
+-                      goto big_to_sg;
+-              }
+-
+-              buffer_pfn = page_to_phys(page) >> PAGE_SHIFT;
+-
+-              off = offset_in_page((unsigned long)sc->request_buffer);
+-              for (i = 0; i < nr_pages; i++) {
+-                      bytes = PAGE_SIZE - off;
+-
+-                      if (bytes > len)
+-                              bytes = len;
+-
+-                      ref = gnttab_claim_grant_reference(&gref_head);
+-                      BUG_ON(ref == -ENOSPC);
+-
+-                      gnttab_grant_foreign_access_ref(ref, info->dev->otherend_id,
+-                              buffer_pfn, write);
 -
--#define VM_DATA_DEFAULT_FLAGS \
--      (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
--       VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-+typedef struct page *pgtable_t;
-+
-+typedef union { pteval_t pte; unsigned int pte_low; } pte_t;
+-                      info->shadow[id].gref[i] = ref;
+-                      ring_req->seg[i].gref     = ref;
+-                      ring_req->seg[i].offset   = (uint16_t)off;
+-                      ring_req->seg[i].length   = (uint16_t)bytes;
+-
+-                      buffer_pfn++;
+-                      len -= bytes;
+-                      off = 0;
+-                      ref_cnt++;
+-              }
+       }
  
--#define __HAVE_ARCH_GATE_AREA 1       
- #define vmemmap ((struct page *)VMEMMAP_START)
+ big_to_sg:
+--- sle11-2009-05-14.orig/drivers/xen/xenoprof/xenoprofile.c   2009-03-11 15:39:38.000000000 +0100
++++ sle11-2009-05-14/drivers/xen/xenoprof/xenoprofile.c        2009-03-16 16:33:40.000000000 +0100
+@@ -78,7 +78,7 @@ static int xenoprof_resume(struct sys_de
  
--#include <asm-generic/memory_model.h>
--#include <asm-generic/page.h>
-+#endif        /* !__ASSEMBLY__ */
-+
-+#ifdef CONFIG_FLATMEM
-+#define pfn_valid(pfn)          ((pfn) < max_mapnr)
+ static struct sysdev_class oprofile_sysclass = {
+-      set_kset_name("oprofile"),
++      .name           = "oprofile",
+       .resume         = xenoprof_resume,
+       .suspend        = xenoprof_suspend
+ };
+--- sle11-2009-05-14.orig/include/asm-x86/e820.h       2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/include/asm-x86/e820.h    2009-03-16 16:33:40.000000000 +0100
+@@ -127,7 +127,11 @@ extern char *memory_setup(void);
+ #endif /* __KERNEL__ */
+ #endif /* __ASSEMBLY__ */
++#ifndef CONFIG_XEN
+ #define ISA_START_ADDRESS     0xa0000
++#else
++#define ISA_START_ADDRESS     0
 +#endif
+ #define ISA_END_ADDRESS               0x100000
+ #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
  
--#endif /* __KERNEL__ */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/agp.h   2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/agp.h        2009-03-16 16:33:40.000000000 +0100
+@@ -13,18 +13,13 @@
+  * page. This avoids data corruption on some CPUs.
+  */
  
- #endif /* _X86_64_PAGE_H */
---- a/include/asm-x86/mach-xen/asm/page.h
-+++ b/include/asm-x86/mach-xen/asm/page.h
-@@ -1,13 +1,231 @@
-+#ifndef _ASM_X86_PAGE_H
-+#define _ASM_X86_PAGE_H
-+
-+#include <linux/const.h>
+-/*
+- * Caller's responsibility to call global_flush_tlb() for performance
+- * reasons
+- */
+ #define map_page_into_agp(page) ( \
+       xen_create_contiguous_region((unsigned long)page_address(page), 0, 32) \
+-      ?: change_page_attr(page, 1, PAGE_KERNEL_NOCACHE))
++      ?: set_pages_uc(page, 1))
+ #define unmap_page_from_agp(page) ( \
+       xen_destroy_contiguous_region((unsigned long)page_address(page), 0), \
+       /* only a fallback: xen_destroy_contiguous_region uses PAGE_KERNEL */ \
+-      change_page_attr(page, 1, PAGE_KERNEL))
+-#define flush_agp_mappings() global_flush_tlb()
++      set_pages_wb(page, 1))
+ /*
+  * Could use CLFLUSH here if the cpu supports it. But then it would
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/desc.h  2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/desc.h       2009-03-16 16:33:40.000000000 +0100
+@@ -1,5 +1,404 @@
++#ifndef _ASM_DESC_H_
++#define _ASM_DESC_H_
 +
-+/* PAGE_SHIFT determines the page size */
-+#define PAGE_SHIFT    12
-+#define PAGE_SIZE     (_AC(1,UL) << PAGE_SHIFT)
-+#define PAGE_MASK     (~(PAGE_SIZE-1))
++#ifndef __ASSEMBLY__
++#include <asm/desc_defs.h>
++#include <asm/ldt.h>
++#include <asm/mmu.h>
++#include <linux/smp.h>
 +
- #ifdef __KERNEL__
--# ifdef CONFIG_X86_32
--#  include "page_32.h"
--# else
--#  include "page_64.h"
--# endif
++static inline void fill_ldt(struct desc_struct *desc,
++                          const struct user_desc *info)
++{
++      desc->limit0 = info->limit & 0x0ffff;
++      desc->base0 = info->base_addr & 0x0000ffff;
 +
-+/*
-+ * Need to repeat this here in order to not include pgtable.h (which in turn
-+ * depends on definitions made here), but to be able to use the symbolics
-+ * below. The preprocessor will warn if the two definitions aren't identical.
-+ */
-+#define _PAGE_BIT_PRESENT     0
-+#define _PAGE_PRESENT         (_AC(1, L)<<_PAGE_BIT_PRESENT)
-+#define _PAGE_BIT_IO          9
-+#define _PAGE_IO              (_AC(1, L)<<_PAGE_BIT_IO)
++      desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
++      desc->type = (info->read_exec_only ^ 1) << 1;
++      desc->type |= info->contents << 2;
++      desc->s = 1;
++      desc->dpl = 0x3;
++      desc->p = info->seg_not_present ^ 1;
++      desc->limit = (info->limit & 0xf0000) >> 16;
++      desc->avl = info->useable;
++      desc->d = info->seg_32bit;
++      desc->g = info->limit_in_pages;
++      desc->base2 = (info->base_addr & 0xff000000) >> 24;
++}
 +
-+#define PHYSICAL_PAGE_MASK    (~(_AT(phys_addr_t, PAGE_SIZE) - 1) & __PHYSICAL_MASK)
-+#define PTE_MASK              _AT(pteval_t, PHYSICAL_PAGE_MASK)
++#ifndef CONFIG_X86_NO_IDT
++extern struct desc_ptr idt_descr;
++extern gate_desc idt_table[];
++#endif
 +
-+#define PMD_PAGE_SIZE         (_AC(1, UL) << PMD_SHIFT)
-+#define PMD_PAGE_MASK         (~(PMD_PAGE_SIZE-1))
++#ifdef CONFIG_X86_64
++extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
++extern struct desc_ptr cpu_gdt_descr[];
++/* the cpu gdt accessor */
++#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
 +
-+#define HPAGE_SHIFT           PMD_SHIFT
-+#define HPAGE_SIZE            (_AC(1,UL) << HPAGE_SHIFT)
-+#define HPAGE_MASK            (~(HPAGE_SIZE - 1))
-+#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
++static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
++                           unsigned dpl, unsigned ist, unsigned seg)
++{
++      gate->offset_low = PTR_LOW(func);
++      gate->segment = __KERNEL_CS;
++      gate->ist = ist;
++      gate->p = 1;
++      gate->dpl = dpl;
++      gate->zero0 = 0;
++      gate->zero1 = 0;
++      gate->type = type;
++      gate->offset_middle = PTR_MIDDLE(func);
++      gate->offset_high = PTR_HIGH(func);
++}
 +
-+/* to align the pointer to the (next) page boundary */
-+#define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
++#else
++struct gdt_page {
++      struct desc_struct gdt[GDT_ENTRIES];
++} __attribute__((aligned(PAGE_SIZE)));
++DECLARE_PER_CPU(struct gdt_page, gdt_page);
 +
-+#define __PHYSICAL_MASK               _AT(phys_addr_t, (_AC(1,ULL) << __PHYSICAL_MASK_SHIFT) - 1)
-+#define __VIRTUAL_MASK                ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
++static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
++{
++      return per_cpu(gdt_page, cpu).gdt;
++}
 +
-+#ifndef __ASSEMBLY__
-+#include <linux/types.h>
-+#endif
++static inline void pack_gate(gate_desc *gate, unsigned char type,
++       unsigned long base, unsigned dpl, unsigned flags, unsigned short seg)
 +
-+#ifdef CONFIG_X86_64
-+#include <asm/page_64.h>
-+#define max_pfn_mapped                end_pfn_map
-+#else
-+#include <asm/page_32.h>
-+#define max_pfn_mapped                max_low_pfn
-+#endif        /* CONFIG_X86_64 */
++{
++      gate->a = (seg << 16) | (base & 0xffff);
++      gate->b = (base & 0xffff0000) |
++                (((0x80 | type | (dpl << 5)) & 0xff) << 8);
++}
 +
-+#define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
++#endif
 +
-+#define VM_DATA_DEFAULT_FLAGS \
-+      (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
-+       VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++static inline int desc_empty(const void *ptr)
++{
++      const u32 *desc = ptr;
++      return !(desc[0] | desc[1]);
++}
 +
++#ifndef CONFIG_XEN
++#define load_TR_desc() native_load_tr_desc()
++#define load_gdt(dtr) native_load_gdt(dtr)
++#define load_idt(dtr) native_load_idt(dtr)
++#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr))
++#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt))
 +
-+#ifndef __ASSEMBLY__
++#define store_gdt(dtr) native_store_gdt(dtr)
++#define store_idt(dtr) native_store_idt(dtr)
++#define store_tr(tr) (tr = native_store_tr())
++#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt))
 +
-+extern int page_is_ram(unsigned long pagenr);
++#define load_TLS(t, cpu) native_load_tls(t, cpu)
++#define set_ldt native_set_ldt
 +
-+struct page;
++#define write_ldt_entry(dt, entry, desc) \
++                              native_write_ldt_entry(dt, entry, desc)
++#define write_gdt_entry(dt, entry, desc, type) \
++                              native_write_gdt_entry(dt, entry, desc, type)
++#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g)
 +
-+static inline void clear_user_page(void *page, unsigned long vaddr,
-+                              struct page *pg)
++static inline void native_write_idt_entry(gate_desc *idt, int entry,
++                                        const gate_desc *gate)
 +{
-+      clear_page(page);
++      memcpy(&idt[entry], gate, sizeof(*gate));
 +}
 +
-+static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
-+                              struct page *topage)
++static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
++                                        const void *desc)
 +{
-+      copy_page(to, from);
++      memcpy(&ldt[entry], desc, 8);
 +}
 +
-+#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
-+      alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
-+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
-+
-+typedef struct { pgprotval_t pgprot; } pgprot_t;
-+
-+#define pgprot_val(x) ((x).pgprot)
-+#define __pgprot(x)   ((pgprot_t) { (x) } )
-+
-+#include <asm/maddr.h>
-+
-+typedef struct { pgdval_t pgd; } pgd_t;
++static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
++                                        const void *desc, int type)
++{
++      unsigned int size;
++      switch (type) {
++      case DESC_TSS:
++              size = sizeof(tss_desc);
++              break;
++      case DESC_LDT:
++              size = sizeof(ldt_desc);
++              break;
++      default:
++              size = sizeof(struct desc_struct);
++              break;
++      }
++      memcpy(&gdt[entry], desc, size);
++}
++#endif
 +
-+#define __pgd_ma(x) ((pgd_t) { (x) } )
-+static inline pgd_t xen_make_pgd(pgdval_t val)
++static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
++                                 unsigned long limit, unsigned char type,
++                                 unsigned char flags)
 +{
-+      if (val & _PAGE_PRESENT)
-+              val = pte_phys_to_machine(val);
-+      return (pgd_t) { val };
++      desc->a = ((base & 0xffff) << 16) | (limit & 0xffff);
++      desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
++                (limit & 0x000f0000) | ((type & 0xff) << 8) |
++                ((flags & 0xf) << 20);
++      desc->p = 1;
 +}
 +
-+#define __pgd_val(x) ((x).pgd)
-+static inline pgdval_t xen_pgd_val(pgd_t pgd)
++
++#ifndef CONFIG_XEN
++static inline void set_tssldt_descriptor(void *d, unsigned long addr,
++                                       unsigned type, unsigned size)
 +{
-+      pgdval_t ret = __pgd_val(pgd);
-+#if PAGETABLE_LEVELS == 2 && CONFIG_XEN_COMPAT <= 0x030002
-+      if (ret)
-+              ret = machine_to_phys(ret) | _PAGE_PRESENT;
++#ifdef CONFIG_X86_64
++      struct ldttss_desc64 *desc = d;
++      memset(desc, 0, sizeof(*desc));
++      desc->limit0 = size & 0xFFFF;
++      desc->base0 = PTR_LOW(addr);
++      desc->base1 = PTR_MIDDLE(addr) & 0xFF;
++      desc->type = type;
++      desc->p = 1;
++      desc->limit1 = (size >> 16) & 0xF;
++      desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF;
++      desc->base3 = PTR_HIGH(addr);
 +#else
-+      if (ret & _PAGE_PRESENT)
-+              ret = pte_machine_to_phys(ret);
++
++      pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
 +#endif
-+      return ret;
 +}
 +
-+#if PAGETABLE_LEVELS >= 3
-+#if PAGETABLE_LEVELS == 4
-+typedef struct { pudval_t pud; } pud_t;
-+
-+#define __pud_ma(x) ((pud_t) { (x) } )
-+static inline pud_t xen_make_pud(pudval_t val)
++static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
 +{
-+      if (val & _PAGE_PRESENT)
-+              val = pte_phys_to_machine(val);
-+      return (pud_t) { val };
++      struct desc_struct *d = get_cpu_gdt_table(cpu);
++      tss_desc tss;
++
++      /*
++       * sizeof(unsigned long) coming from an extra "long" at the end
++       * of the iobitmap. See tss_struct definition in processor.h
++       *
++       * -1? seg base+limit should be pointing to the address of the
++       * last valid byte
++       */
++      set_tssldt_descriptor(&tss, (unsigned long)addr, DESC_TSS,
++              IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1);
++      write_gdt_entry(d, entry, &tss, DESC_TSS);
 +}
 +
-+#define __pud_val(x) ((x).pud)
-+static inline pudval_t xen_pud_val(pud_t pud)
++#define set_tss_desc(cpu, addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
++
++static inline void native_set_ldt(const void *addr, unsigned int entries)
 +{
-+      pudval_t ret = __pud_val(pud);
-+      if (ret & _PAGE_PRESENT)
-+              ret = pte_machine_to_phys(ret);
-+      return ret;
++      if (likely(entries == 0))
++              __asm__ __volatile__("lldt %w0"::"q" (0));
++      else {
++              unsigned cpu = smp_processor_id();
++              ldt_desc ldt;
++
++              set_tssldt_descriptor(&ldt, (unsigned long)addr,
++                                    DESC_LDT, entries * sizeof(ldt) - 1);
++              write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT,
++                              &ldt, DESC_LDT);
++              __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
++      }
 +}
-+#else /* PAGETABLE_LEVELS == 3 */
-+#include <asm-generic/pgtable-nopud.h>
 +
-+#define __pud_val(x) __pgd_val((x).pgd)
-+static inline pudval_t xen_pud_val(pud_t pud)
++static inline void native_load_tr_desc(void)
 +{
-+      return xen_pgd_val(pud.pgd);
++      asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
 +}
-+#endif        /* PAGETABLE_LEVELS == 4 */
-+
-+typedef struct { pmdval_t pmd; } pmd_t;
 +
-+#define __pmd_ma(x)   ((pmd_t) { (x) } )
-+static inline pmd_t xen_make_pmd(pmdval_t val)
++static inline void native_load_gdt(const struct desc_ptr *dtr)
 +{
-+      if (val & _PAGE_PRESENT)
-+              val = pte_phys_to_machine(val);
-+      return (pmd_t) { val };
++      asm volatile("lgdt %0"::"m" (*dtr));
 +}
 +
-+#define __pmd_val(x) ((x).pmd)
-+static inline pmdval_t xen_pmd_val(pmd_t pmd)
++static inline void native_load_idt(const struct desc_ptr *dtr)
 +{
-+      pmdval_t ret = __pmd_val(pmd);
-+#if CONFIG_XEN_COMPAT <= 0x030002
-+      if (ret)
-+              ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
- #else
--# ifdef __i386__
--#  include "page_32.h"
--# else
--#  include "page_64.h"
--# endif
-+      if (ret & _PAGE_PRESENT)
-+              ret = pte_machine_to_phys(ret);
-+#endif
-+      return ret;
++      asm volatile("lidt %0"::"m" (*dtr));
 +}
-+#else  /* PAGETABLE_LEVELS == 2 */
-+#include <asm-generic/pgtable-nopmd.h>
 +
-+#define __pmd_ma(x) ((pmd_t) { .pud.pgd = __pgd_ma(x) } )
-+#define __pmd_val(x) __pgd_val((x).pud.pgd)
-+static inline pmdval_t xen_pmd_val(pmd_t pmd)
++static inline void native_store_gdt(struct desc_ptr *dtr)
 +{
-+      return xen_pgd_val(pmd.pud.pgd);
++      asm volatile("sgdt %0":"=m" (*dtr));
 +}
-+#endif        /* PAGETABLE_LEVELS >= 3 */
 +
-+#define __pte_ma(x) ((pte_t) { .pte = (x) } )
-+static inline pte_t xen_make_pte(pteval_t val)
++static inline void native_store_idt(struct desc_ptr *dtr)
 +{
-+      if ((val & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
-+              val = pte_phys_to_machine(val);
-+      return (pte_t) { .pte = val };
++      asm volatile("sidt %0":"=m" (*dtr));
 +}
 +
-+#define __pte_val(x) ((x).pte)
-+static inline pteval_t xen_pte_val(pte_t pte)
++static inline unsigned long native_store_tr(void)
 +{
-+      pteval_t ret = __pte_val(pte);
-+      if ((pte.pte_low & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
-+              ret = pte_machine_to_phys(ret);
-+      return ret;
++      unsigned long tr;
++      asm volatile("str %0":"=r" (tr));
++      return tr;
 +}
 +
-+#define pgd_val(x)    xen_pgd_val(x)
-+#define __pgd(x)      xen_make_pgd(x)
-+
-+#ifndef __PAGETABLE_PUD_FOLDED
-+#define pud_val(x)    xen_pud_val(x)
-+#define __pud(x)      xen_make_pud(x)
-+#endif
-+
-+#ifndef __PAGETABLE_PMD_FOLDED
-+#define pmd_val(x)    xen_pmd_val(x)
-+#define __pmd(x)      xen_make_pmd(x)
- #endif
-+
-+#define pte_val(x)    xen_pte_val(x)
-+#define __pte(x)      xen_make_pte(x)
-+
-+#define __pa(x)               __phys_addr((unsigned long)(x))
-+/* __pa_symbol should be used for C visible symbols.
-+   This seems to be the official gcc blessed way to do such arithmetic. */
-+#define __pa_symbol(x)        __pa(__phys_reloc_hide((unsigned long)(x)))
-+
-+#define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
-+
-+#define __boot_va(x)          __va(x)
-+#define __boot_pa(x)          __pa(x)
-+
-+#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-+#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-+#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-+
-+#endif        /* __ASSEMBLY__ */
-+
-+#include <asm-generic/memory_model.h>
-+#include <asm-generic/page.h>
-+
-+#define __HAVE_ARCH_GATE_AREA 1
-+
-+#endif        /* __KERNEL__ */
-+#endif        /* _ASM_X86_PAGE_H */
---- a/include/asm-x86/mach-xen/asm/pci_64.h
-+++ b/include/asm-x86/mach-xen/asm/pci_64.h
-@@ -26,7 +26,6 @@ extern int (*pci_config_write)(int seg, 
- extern void pci_iommu_alloc(void);
--extern int iommu_setup(char *opt);
- /* The PCI address space does equal the physical memory
-  * address space.  The networking and block device layers use
---- a/include/asm-x86/mach-xen/asm/pci.h
-+++ b/include/asm-x86/mach-xen/asm/pci.h
-@@ -71,6 +71,7 @@ extern int pci_mmap_page_range(struct pc
- #ifdef CONFIG_PCI
-+extern void early_quirks(void);
- static inline void pci_dma_burst_advice(struct pci_dev *pdev,
-                                       enum pci_dma_burst_strategy *strat,
-                                       unsigned long *strategy_parameter)
-@@ -78,9 +79,10 @@ static inline void pci_dma_burst_advice(
-       *strat = PCI_DMA_BURST_INFINITY;
-       *strategy_parameter = ~0UL;
- }
-+#else
-+static inline void early_quirks(void) { }
- #endif
--
- #endif  /* __KERNEL__ */
- #ifdef CONFIG_X86_32
-@@ -95,6 +97,19 @@ static inline void pci_dma_burst_advice(
- /* generic pci stuff */
- #include <asm-generic/pci.h>
-+#ifdef CONFIG_NUMA
-+/* Returns the node based on pci bus */
-+static inline int __pcibus_to_node(struct pci_bus *bus)
++static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 +{
-+      struct pci_sysdata *sd = bus->sysdata;
++      unsigned int i;
++      struct desc_struct *gdt = get_cpu_gdt_table(cpu);
 +
-+      return sd->node;
-+}
-+static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
-+{
-+      return node_to_cpumask(__pcibus_to_node(bus));
++      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
++              gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
 +}
-+#endif
- #endif
---- a/include/asm-x86/mach-xen/asm/pgalloc_32.h
-+++ b/include/asm-x86/mach-xen/asm/pgalloc_32.h
-@@ -3,69 +3,109 @@
- #include <linux/threads.h>
- #include <linux/mm.h>         /* for struct page */
-+#include <linux/pagemap.h>
-+#include <asm/tlb.h>
-+#include <asm-generic/tlb.h>
- #include <asm/io.h>           /* for phys_to_virt and page_to_pseudophys */
- #define paravirt_alloc_pt(mm, pfn) do { } while (0)
--#define paravirt_alloc_pd(pfn) do { } while (0)
--#define paravirt_alloc_pd(pfn) do { } while (0)
-+#define paravirt_alloc_pd(mm, pfn) do { } while (0)
- #define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) do { } while (0)
- #define paravirt_release_pt(pfn) do { } while (0)
- #define paravirt_release_pd(pfn) do { } while (0)
--#define pmd_populate_kernel(mm, pmd, pte)                     \
--do {                                                          \
--      paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);         \
--      set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));           \
--} while (0)
--
--#define pmd_populate(mm, pmd, pte)                                    \
--do {                                                                  \
--      unsigned long pfn = page_to_pfn(pte);                           \
--      paravirt_alloc_pt(mm, pfn);                                     \
--      if (PagePinned(virt_to_page((mm)->pgd))) {                      \
--              if (!PageHighMem(pte))                                  \
--                      BUG_ON(HYPERVISOR_update_va_mapping(            \
--                        (unsigned long)__va(pfn << PAGE_SHIFT),       \
--                        pfn_pte(pfn, PAGE_KERNEL_RO), 0));            \
--              else if (!test_and_set_bit(PG_pinned, &pte->flags))     \
--                      kmap_flush_unused();                            \
--              set_pmd(pmd,                                            \
--                      __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT))); \
--      } else                                                  \
--              *(pmd) = __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT)); \
--} while (0)
-+static inline void pmd_populate_kernel(struct mm_struct *mm,
-+                                     pmd_t *pmd, pte_t *pte)
++#else
++#define load_TLS(t, cpu) xen_load_tls(t, cpu)
++#define set_ldt xen_set_ldt
++
++extern int write_ldt_entry(struct desc_struct *ldt, int entry,
++                         const void *desc);
++extern int write_gdt_entry(struct desc_struct *gdt, int entry,
++                         const void *desc, int type);
++
++static inline void xen_load_tls(struct thread_struct *t, unsigned int cpu)
 +{
-+      paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);
-+      set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
++      unsigned int i;
++      struct desc_struct *gdt = get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN;
++
++      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
++              if (HYPERVISOR_update_descriptor(virt_to_machine(&gdt[i]),
++                                               *(u64 *)&t->tls_array[i]))
++                      BUG();
 +}
++#endif
 +
-+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
++#define _LDT_empty(info) (\
++      (info)->base_addr       == 0    && \
++      (info)->limit           == 0    && \
++      (info)->contents        == 0    && \
++      (info)->read_exec_only  == 1    && \
++      (info)->seg_32bit       == 0    && \
++      (info)->limit_in_pages  == 0    && \
++      (info)->seg_not_present == 1    && \
++      (info)->useable         == 0)
++
++#ifdef CONFIG_X86_64
++#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0))
++#else
++#define LDT_empty(info) (_LDT_empty(info))
++#endif
++
++static inline void clear_LDT(void)
 +{
-+      unsigned long pfn = page_to_pfn(pte);
++      set_ldt(NULL, 0);
++}
 +
-+      paravirt_alloc_pt(mm, pfn);
-+      if (PagePinned(virt_to_page(mm->pgd))) {
-+              if (!PageHighMem(pte))
-+                      BUG_ON(HYPERVISOR_update_va_mapping(
-+                        (unsigned long)__va(pfn << PAGE_SHIFT),
-+                        pfn_pte(pfn, PAGE_KERNEL_RO), 0));
-+              else if (!test_and_set_bit(PG_pinned, &pte->flags))
-+                      kmap_flush_unused();
-+              set_pmd(pmd, __pmd(((pmdval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE));
-+      } else
-+              *pmd = __pmd(((pmdval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE);
++/*
++ * load one particular LDT into the current CPU
++ */
++static inline void load_LDT_nolock(mm_context_t *pc)
++{
++      set_ldt(pc->ldt, pc->size);
 +}
-+#define pmd_pgtable(pmd) pmd_page(pmd)
- /*
-  * Allocate and free page tables.
-  */
-+extern void pgd_test_and_unpin(pgd_t *);
- extern pgd_t *pgd_alloc(struct mm_struct *);
--extern void pgd_free(pgd_t *pgd);
-+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
- extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
--extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
-+extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
--static inline void pte_free_kernel(pte_t *pte)
-+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
- {
-       make_lowmem_page_writable(pte, XENFEAT_writable_page_tables);
-       free_page((unsigned long)pte);
- }
--extern void pte_free(struct page *pte);
-+extern void __pte_free(pgtable_t);
-+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
++
++static inline void load_LDT(mm_context_t *pc)
 +{
-+      __pte_free(pte);
++      preempt_disable();
++      load_LDT_nolock(pc);
++      preempt_enable();
 +}
 +
--#define __pte_free_tlb(tlb,pte)                                       \
--do {                                                                  \
--      paravirt_release_pt(page_to_pfn(pte));                          \
--      tlb_remove_page((tlb),(pte));                                   \
--} while (0)
-+extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
- #ifdef CONFIG_X86_PAE
- /*
-  * In the PAE case we free the pmds as part of the pgd.
-  */
--#define pmd_alloc_one(mm, addr)               ({ BUG(); ((pmd_t *)2); })
--#define pmd_free(x)                   do { } while (0)
--#define __pmd_free_tlb(tlb,x)         do { } while (0)
--#define pud_populate(mm, pmd, pte)    BUG()
--#endif
-+extern pmd_t *pmd_alloc_one(struct mm_struct *, unsigned long);
++static inline unsigned long get_desc_base(const struct desc_struct *desc)
++{
++      return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
++}
 +
-+extern void __pmd_free(pgtable_t);
-+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
++static inline unsigned long get_desc_limit(const struct desc_struct *desc)
 +{
-+      BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
-+      __pmd_free(virt_to_page(pmd));
++      return desc->limit0 | (desc->limit << 16);
 +}
 +
-+extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd);
++#ifndef CONFIG_X86_NO_IDT
++static inline void _set_gate(int gate, unsigned type, void *addr,
++                            unsigned dpl, unsigned ist, unsigned seg)
++{
++      gate_desc s;
++      pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
++      /*
++       * does not need to be atomic because it is only done once at
++       * setup time
++       */
++      write_idt_entry(idt_table, gate, &s);
++}
 +
-+static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
++/*
++ * This needs to use 'idt_table' rather than 'idt', and
++ * thus use the _nonmapped_ version of the IDT, as the
++ * Pentium F0 0F bugfix can have resulted in the mapped
++ * IDT being write-protected.
++ */
++static inline void set_intr_gate(unsigned int n, void *addr)
 +{
-+      struct page *page = virt_to_page(pmd);
-+      unsigned long pfn = page_to_pfn(page);
++      BUG_ON((unsigned)n > 0xFF);
++      _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
++}
 +
-+      paravirt_alloc_pd(mm, pfn);
++/*
++ * This routine sets up an interrupt gate at directory privilege level 3.
++ */
++static inline void set_system_intr_gate(unsigned int n, void *addr)
++{
++      BUG_ON((unsigned)n > 0xFF);
++      _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
++}
 +
-+      /* Note: almost everything apart from _PAGE_PRESENT is
-+         reserved at the pmd (PDPT) level. */
-+      if (PagePinned(virt_to_page(mm->pgd))) {
-+              BUG_ON(PageHighMem(page));
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                        (unsigned long)__va(pfn << PAGE_SHIFT),
-+                        pfn_pte(pfn, PAGE_KERNEL_RO), 0));
-+              set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT));
-+      } else
-+              *pudp = __pud(__pa(pmd) | _PAGE_PRESENT);
++static inline void set_trap_gate(unsigned int n, void *addr)
++{
++      BUG_ON((unsigned)n > 0xFF);
++      _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
++}
 +
-+      /*
-+       * According to Intel App note "TLBs, Paging-Structure Caches,
-+       * and Their Invalidation", April 2007, document 317080-001,
-+       * section 8.1: in PAE mode we explicitly have to flush the
-+       * TLB via cr3 if the top-level pgd is changed...
-+       */
-+      if (mm == current->active_mm)
-+              xen_tlb_flush();
++static inline void set_system_gate(unsigned int n, void *addr)
++{
++      BUG_ON((unsigned)n > 0xFF);
+ #ifdef CONFIG_X86_32
+-# include "desc_32.h"
++      _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
++#else
++      _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
++#endif
 +}
-+#endif        /* CONFIG_X86_PAE */
- #endif /* _I386_PGALLOC_H */
---- a/include/asm-x86/mach-xen/asm/pgalloc_64.h
-+++ b/include/asm-x86/mach-xen/asm/pgalloc_64.h
-@@ -6,30 +6,13 @@
- #include <linux/mm.h>
- #include <asm/io.h>           /* for phys_to_virt and page_to_pseudophys */
--#include <xen/features.h>
--void make_page_readonly(void *va, unsigned int feature);
--void make_page_writable(void *va, unsigned int feature);
--void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
--void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
-+pmd_t *early_get_pmd(unsigned long va);
-+void early_make_page_readonly(void *va, unsigned int feature);
- #define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
--static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
--{
--      set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)));
--}
--
--static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
--{
--      if (unlikely(PagePinned(virt_to_page((mm)->pgd)))) {
--              BUG_ON(HYPERVISOR_update_va_mapping(
--                             (unsigned long)__va(page_to_pfn(pte) << PAGE_SHIFT),
--                             pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));
--              set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
--      } else {
--              *(pmd) = __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT));
--      }
--}
-+#define pmd_populate_kernel(mm, pmd, pte) \
-+              set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
- static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
- {
-@@ -63,53 +46,58 @@ static inline void pgd_populate(struct m
-       }
- }
--extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
--extern void pte_free(struct page *pte);
-+#define pmd_pgtable(pmd) pmd_page(pmd)
--static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
- {
--      struct page *pg;
--
--      pg = pte_alloc_one(mm, addr);
--      return pg ? page_address(pg) : NULL;
-+      if (unlikely(PagePinned(virt_to_page((mm)->pgd)))) {
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                             (unsigned long)__va(page_to_pfn(pte) << PAGE_SHIFT),
-+                             pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));
-+              set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
-+      } else {
-+              *(pmd) = __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT));
-+      }
- }
--static inline void pmd_free(pmd_t *pmd)
-+extern void __pmd_free(pgtable_t);
-+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
- {
-       BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
--      pte_free(virt_to_page(pmd));
-+      __pmd_free(virt_to_page(pmd));
- }
-+extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr);
 +
- static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
- {
--      struct page *pg;
--
--      pg = pte_alloc_one(mm, addr);
--      return pg ? page_address(pg) : NULL;
-+      return (pud_t *)pmd_alloc_one(mm, addr);
- }
--static inline void pud_free(pud_t *pud)
-+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
- {
-       BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
--      pte_free(virt_to_page(pud));
-+      __pmd_free(virt_to_page(pud));
- }
- static inline void pgd_list_add(pgd_t *pgd)
- {
-       struct page *page = virt_to_page(pgd);
-+      unsigned long flags;
--      spin_lock(&pgd_lock);
-+      spin_lock_irqsave(&pgd_lock, flags);
-       list_add(&page->lru, &pgd_list);
--      spin_unlock(&pgd_lock);
-+      spin_unlock_irqrestore(&pgd_lock, flags);
- }
- static inline void pgd_list_del(pgd_t *pgd)
- {
-       struct page *page = virt_to_page(pgd);
-+      unsigned long flags;
--      spin_lock(&pgd_lock);
-+      spin_lock_irqsave(&pgd_lock, flags);
-       list_del(&page->lru);
--      spin_unlock(&pgd_lock);
-+      spin_unlock_irqrestore(&pgd_lock, flags);
- }
- extern void pgd_test_and_unpin(pgd_t *);
-@@ -145,7 +133,7 @@ static inline pgd_t *pgd_alloc(struct mm
-       return pgd;
- }
--static inline void pgd_free(pgd_t *pgd)
-+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
- {
-       pgd_test_and_unpin(pgd);
-       pgd_list_del(pgd);
-@@ -161,17 +149,30 @@ static inline pte_t *pte_alloc_one_kerne
-       return pte;
- }
-+extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
++static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
++{
++      BUG_ON((unsigned)n > 0xFF);
++      _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3));
++}
 +
- /* Should really implement gc for free page table pages. This could be
-    done with a reference count in struct page. */
--static inline void pte_free_kernel(pte_t *pte)
-+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
- {
-       BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
-       make_page_writable(pte, XENFEAT_writable_page_tables);
-       free_page((unsigned long)pte); 
- }
--#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
-+extern void __pte_free(pgtable_t);
-+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
++static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
 +{
-+      __pte_free(pte);
++      BUG_ON((unsigned)n > 0xFF);
++      _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
 +}
 +
-+#define __pte_free_tlb(tlb,pte)                               \
-+do {                                                  \
-+      pgtable_page_dtor((pte));                               \
-+      tlb_remove_page((tlb), (pte));                  \
-+} while (0)
++static inline void set_system_gate_ist(int n, void *addr, unsigned ist)
++{
++      BUG_ON((unsigned)n > 0xFF);
++      _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
++}
++#endif
 +
- #define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
- #define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
---- a/include/asm-x86/mach-xen/asm/pgtable_32.h
-+++ b/include/asm-x86/mach-xen/asm/pgtable_32.h
-@@ -1,8 +1,6 @@
- #ifndef _I386_PGTABLE_H
- #define _I386_PGTABLE_H
--#include <asm/hypervisor.h>
--
- /*
-  * The Linux memory management assumes a three-level page table setup. On
-  * the i386, we use that, but "fold" the mid level into the top-level page
-@@ -25,20 +23,10 @@
- struct vm_area_struct;
--/*
-- * ZERO_PAGE is a global shared page that is always zero: used
-- * for zero-mapped memory areas etc..
-- */
--#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
--extern unsigned long empty_zero_page[1024];
- extern pgd_t *swapper_pg_dir;
--extern struct kmem_cache *pmd_cache;
--extern spinlock_t pgd_lock;
--extern struct page *pgd_list;
--void check_pgt_cache(void);
--void pmd_ctor(struct kmem_cache *, void *);
--void pgtable_cache_init(void);
-+static inline void pgtable_cache_init(void) { }
-+static inline void check_pgt_cache(void) { }
- void paging_init(void);
-@@ -58,16 +46,9 @@ void paging_init(void);
- #define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
- #define PGDIR_MASK    (~(PGDIR_SIZE-1))
--#define USER_PTRS_PER_PGD     (TASK_SIZE/PGDIR_SIZE)
--#define FIRST_USER_ADDRESS    0
--
- #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
- #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
--#define TWOLEVEL_PGDIR_SHIFT  22
--#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
--#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
--
- /* Just any arbitrary offset to the start of the vmalloc VM area: the
-  * current 8MB value just means that there will be a 8MB "hole" after the
-  * physical memory until the kernel virtual memory starts.  That means that
-@@ -78,121 +59,19 @@ void paging_init(void);
- #define VMALLOC_OFFSET        (8*1024*1024)
- #define VMALLOC_START (((unsigned long) high_memory + \
-                       2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))
--#ifdef CONFIG_HIGHMEM
--# define VMALLOC_END  (PKMAP_BASE-2*PAGE_SIZE)
--#else
--# define VMALLOC_END  (FIXADDR_START-2*PAGE_SIZE)
--#endif
--
--/*
-- * _PAGE_PSE set in the page directory entry just means that
-- * the page directory entry points directly to a 4MB-aligned block of
-- * memory. 
-- */
--#define _PAGE_BIT_PRESENT     0
--#define _PAGE_BIT_RW          1
--#define _PAGE_BIT_USER                2
--#define _PAGE_BIT_PWT         3
--#define _PAGE_BIT_PCD         4
--#define _PAGE_BIT_ACCESSED    5
--#define _PAGE_BIT_DIRTY               6
--#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page, Pentium+, if present.. */
--#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
--/*#define _PAGE_BIT_UNUSED1   9*/     /* available for programmer */
--#define _PAGE_BIT_UNUSED2     10
--#define _PAGE_BIT_UNUSED3     11
--#define _PAGE_BIT_NX          63
--
--#define _PAGE_PRESENT 0x001
--#define _PAGE_RW      0x002
--#define _PAGE_USER    0x004
--#define _PAGE_PWT     0x008
--#define _PAGE_PCD     0x010
--#define _PAGE_ACCESSED        0x020
--#define _PAGE_DIRTY   0x040
--#define _PAGE_PSE     0x080   /* 4 MB (or 2MB) page, Pentium+, if present.. */
--#define _PAGE_GLOBAL  0x100   /* Global TLB entry PPro+ */
--/*#define _PAGE_UNUSED1       0x200*/ /* available for programmer */
--#define _PAGE_UNUSED2 0x400
--#define _PAGE_UNUSED3 0x800
--
--/* If _PAGE_PRESENT is clear, we use these: */
--#define _PAGE_FILE    0x040   /* nonlinear file mapping, saved PTE; unset:swap */
--#define _PAGE_PROTNONE        0x080   /* if the user mapped it with PROT_NONE;
--                                 pte_present gives true */
- #ifdef CONFIG_X86_PAE
--#define _PAGE_NX      (1ULL<<_PAGE_BIT_NX)
-+#define LAST_PKMAP 512
  #else
--#define _PAGE_NX      0
-+#define LAST_PKMAP 1024
- #endif
--/* Mapped page is I/O or foreign and has no associated page struct. */
--#define _PAGE_IO      0x200
-+#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK)
--#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
--
--#define PAGE_NONE \
--      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
--#define PAGE_SHARED \
--      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
--
--#define PAGE_SHARED_EXEC \
--      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
--#define PAGE_COPY_NOEXEC \
--      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
--#define PAGE_COPY_EXEC \
--      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
--#define PAGE_COPY \
--      PAGE_COPY_NOEXEC
--#define PAGE_READONLY \
--      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
--#define PAGE_READONLY_EXEC \
--      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
--
--#define _PAGE_KERNEL \
--      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
--#define _PAGE_KERNEL_EXEC \
--      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
--
--extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
--#define __PAGE_KERNEL_RO              (__PAGE_KERNEL & ~_PAGE_RW)
--#define __PAGE_KERNEL_RX              (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
--#define __PAGE_KERNEL_NOCACHE         (__PAGE_KERNEL | _PAGE_PCD)
--#define __PAGE_KERNEL_LARGE           (__PAGE_KERNEL | _PAGE_PSE)
--#define __PAGE_KERNEL_LARGE_EXEC      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
+-# include "desc_64.h"
++/*
++ * GET_DESC_BASE reads the descriptor base of the specified segment.
++ *
++ * Args:
++ *    idx - descriptor index
++ *    gdt - GDT pointer
++ *    base - 32bit register to which the base will be written
++ *    lo_w - lo word of the "base" register
++ *    lo_b - lo byte of the "base" register
++ *    hi_b - hi byte of the low word of the "base" register
++ *
++ * Example:
++ *    GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
++ *    Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax.
++ */
++#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \
++      movb idx*8+4(gdt), lo_b; \
++      movb idx*8+7(gdt), hi_b; \
++      shll $16, base; \
++      movw idx*8+2(gdt), lo_w;
++
++
++#endif /* __ASSEMBLY__ */
++
+ #endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/desc_32.h       2008-12-15 11:27:22.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,262 +0,0 @@
+-#ifndef __ARCH_DESC_H
+-#define __ARCH_DESC_H
 -
--#define PAGE_KERNEL           __pgprot(__PAGE_KERNEL)
--#define PAGE_KERNEL_RO                __pgprot(__PAGE_KERNEL_RO)
--#define PAGE_KERNEL_EXEC      __pgprot(__PAGE_KERNEL_EXEC)
--#define PAGE_KERNEL_RX                __pgprot(__PAGE_KERNEL_RX)
--#define PAGE_KERNEL_NOCACHE   __pgprot(__PAGE_KERNEL_NOCACHE)
--#define PAGE_KERNEL_LARGE     __pgprot(__PAGE_KERNEL_LARGE)
--#define PAGE_KERNEL_LARGE_EXEC        __pgprot(__PAGE_KERNEL_LARGE_EXEC)
+-#include <asm/ldt.h>
+-#include <asm/segment.h>
 -
--/*
-- * The i386 can't do page protection for execute, and considers that
-- * the same are read. Also, write permissions imply read permissions.
-- * This is the closest we can get..
-- */
--#define __P000        PAGE_NONE
--#define __P001        PAGE_READONLY
--#define __P010        PAGE_COPY
--#define __P011        PAGE_COPY
--#define __P100        PAGE_READONLY_EXEC
--#define __P101        PAGE_READONLY_EXEC
--#define __P110        PAGE_COPY_EXEC
--#define __P111        PAGE_COPY_EXEC
+-#ifndef __ASSEMBLY__
 -
--#define __S000        PAGE_NONE
--#define __S001        PAGE_READONLY
--#define __S010        PAGE_SHARED
--#define __S011        PAGE_SHARED
--#define __S100        PAGE_READONLY_EXEC
--#define __S101        PAGE_READONLY_EXEC
--#define __S110        PAGE_SHARED_EXEC
--#define __S111        PAGE_SHARED_EXEC
-+#ifdef CONFIG_HIGHMEM
-+# define VMALLOC_END  (PKMAP_BASE-2*PAGE_SIZE)
-+#else
-+# define VMALLOC_END  (FIXADDR_START-2*PAGE_SIZE)
-+#endif
- /*
-  * Define this if things work differently on an i386 and an i486:
-@@ -221,28 +100,6 @@ extern unsigned long pg0[];
- #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
--/*
-- * The following only work if pte_present() is true.
-- * Undefined behaviour if not..
-- */
--static inline int pte_dirty(pte_t pte)                { return (pte).pte_low & _PAGE_DIRTY; }
--static inline int pte_young(pte_t pte)                { return (pte).pte_low & _PAGE_ACCESSED; }
--static inline int pte_write(pte_t pte)                { return (pte).pte_low & _PAGE_RW; }
--static inline int pte_huge(pte_t pte)         { return (pte).pte_low & _PAGE_PSE; }
+-#include <linux/preempt.h>
+-#include <linux/smp.h>
 -
--/*
-- * The following only works if pte_present() is not true.
-- */
--static inline int pte_file(pte_t pte)         { return (pte).pte_low & _PAGE_FILE; }
+-#include <asm/mmu.h>
 -
--static inline pte_t pte_mkclean(pte_t pte)    { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
--static inline pte_t pte_mkold(pte_t pte)      { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
--static inline pte_t pte_wrprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_RW; return pte; }
--static inline pte_t pte_mkdirty(pte_t pte)    { (pte).pte_low |= _PAGE_DIRTY; return pte; }
--static inline pte_t pte_mkyoung(pte_t pte)    { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
--static inline pte_t pte_mkwrite(pte_t pte)    { (pte).pte_low |= _PAGE_RW; return pte; }
--static inline pte_t pte_mkhuge(pte_t pte)     { (pte).pte_low |= _PAGE_PSE; return pte; }
+-struct Xgt_desc_struct {
+-      unsigned short size;
+-      unsigned long address __attribute__((packed));
+-      unsigned short pad;
+-} __attribute__ ((packed));
 -
- #ifdef CONFIG_X86_PAE
- # include <asm/pgtable-3level.h>
- #else
-@@ -250,111 +107,6 @@ static inline pte_t pte_mkhuge(pte_t pte
- #endif
- /*
-- * Rules for using pte_update - it must be called after any PTE update which
-- * has not been done using the set_pte / clear_pte interfaces.  It is used by
-- * shadow mode hypervisors to resynchronize the shadow page tables.  Kernel PTE
-- * updates should either be sets, clears, or set_pte_atomic for P->P
-- * transitions, which means this hook should only be called for user PTEs.
-- * This hook implies a P->P protection or access change has taken place, which
-- * requires a subsequent TLB flush.  The notification can optionally be delayed
-- * until the TLB flush event by using the pte_update_defer form of the
-- * interface, but care must be taken to assure that the flush happens while
-- * still holding the same page table lock so that the shadow and primary pages
-- * do not become out of sync on SMP.
-- */
--#define pte_update(mm, addr, ptep)            do { } while (0)
--#define pte_update_defer(mm, addr, ptep)      do { } while (0)
+-struct gdt_page
+-{
+-      struct desc_struct gdt[GDT_ENTRIES];
+-} __attribute__((aligned(PAGE_SIZE)));
+-DECLARE_PER_CPU(struct gdt_page, gdt_page);
 -
--/* local pte updates need not use xchg for locking */
--static inline pte_t xen_local_ptep_get_and_clear(pte_t *ptep, pte_t res)
+-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
 -{
--      xen_set_pte(ptep, __pte(0));
--      return res;
+-      return per_cpu(gdt_page, cpu).gdt;
 -}
 -
--/*
-- * We only update the dirty/accessed state if we set
-- * the dirty bit by hand in the kernel, since the hardware
-- * will do the accessed bit for us, and we don't want to
-- * race with other CPU's that might be updating the dirty
-- * bit at the same time.
-- */
--#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
--#define ptep_set_access_flags(vma, address, ptep, entry, dirty)               \
--({                                                                    \
--      int __changed = !pte_same(*(ptep), entry);                      \
--      if (__changed && (dirty)) {                                     \
--              if ( likely((vma)->vm_mm == current->mm) ) {            \
--                      BUG_ON(HYPERVISOR_update_va_mapping(address,    \
--                              entry,                                  \
--                              (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
--                                      UVMF_INVLPG|UVMF_MULTI));       \
--              } else {                                                \
--                      xen_l1_entry_update(ptep, entry);               \
--                      flush_tlb_page(vma, address);                   \
--              }                                                       \
--      }                                                               \
--      __changed;                                                      \
--})
--
--#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
--#define ptep_test_and_clear_young(vma, addr, ptep) ({                 \
--      int __ret = 0;                                                  \
--      if (pte_young(*(ptep)))                                         \
--              __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,          \
--                                              &(ptep)->pte_low);      \
--      if (__ret)                                                      \
--              pte_update((vma)->vm_mm, addr, ptep);                   \
--      __ret;                                                          \
--})
+-extern struct Xgt_desc_struct idt_descr;
+-extern struct desc_struct idt_table[];
+-extern void set_intr_gate(unsigned int irq, void * addr);
 -
--#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
--#define ptep_clear_flush_young(vma, address, ptep)                    \
--({                                                                    \
--      pte_t __pte = *(ptep);                                          \
--      int __young = pte_young(__pte);                                 \
--      __pte = pte_mkold(__pte);                                       \
--      if (PagePinned(virt_to_page((vma)->vm_mm->pgd)))                \
--              (void)ptep_set_access_flags(vma, address, ptep, __pte, __young); \
--      else if (__young)                                               \
--              (ptep)->pte_low = __pte.pte_low;                        \
--      __young;                                                        \
--})
+-static inline void pack_descriptor(__u32 *a, __u32 *b,
+-      unsigned long base, unsigned long limit, unsigned char type, unsigned char flags)
+-{
+-      *a = ((base & 0xffff) << 16) | (limit & 0xffff);
+-      *b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
+-              (limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20);
+-}
 -
--#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
--static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+-static inline void pack_gate(__u32 *a, __u32 *b,
+-      unsigned long base, unsigned short seg, unsigned char type, unsigned char flags)
 -{
--      pte_t pte = *ptep;
--      if (!pte_none(pte)
--          && (mm != &init_mm
--              || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))) {
--              pte = xen_ptep_get_and_clear(ptep, pte);
--              pte_update(mm, addr, ptep);
--      }
--      return pte;
+-      *a = (seg << 16) | (base & 0xffff);
+-      *b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff);
 -}
 -
--#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
--#define ptep_get_and_clear_full(mm, addr, ptep, full)                 \
--      ((full) ? ({                                                    \
--              pte_t __res = *(ptep);                                  \
--              if (PagePinned(virt_to_page((mm)->pgd)))                \
--                      xen_l1_entry_update(ptep, __pte(0));            \
--              else                                                    \
--                      *(ptep) = __pte(0);                             \
--              __res;                                                  \
--       }) :                                                           \
--       ptep_get_and_clear(mm, addr, ptep))
+-#define DESCTYPE_LDT  0x82    /* present, system, DPL-0, LDT */
+-#define DESCTYPE_TSS  0x89    /* present, system, DPL-0, 32-bit TSS */
+-#define DESCTYPE_TASK 0x85    /* present, system, DPL-0, task gate */
+-#define DESCTYPE_INT  0x8e    /* present, system, DPL-0, interrupt gate */
+-#define DESCTYPE_TRAP 0x8f    /* present, system, DPL-0, trap gate */
+-#define DESCTYPE_DPL3 0x60    /* DPL-3 */
+-#define DESCTYPE_S    0x10    /* !system */
 -
--#define __HAVE_ARCH_PTEP_SET_WRPROTECT
--static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+-#ifndef CONFIG_XEN
+-#define load_TR_desc() native_load_tr_desc()
+-#define load_gdt(dtr) native_load_gdt(dtr)
+-#define load_idt(dtr) native_load_idt(dtr)
+-#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr))
+-#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt))
+-
+-#define store_gdt(dtr) native_store_gdt(dtr)
+-#define store_idt(dtr) native_store_idt(dtr)
+-#define store_tr(tr) (tr = native_store_tr())
+-#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt))
+-
+-#define load_TLS(t, cpu) native_load_tls(t, cpu)
+-#define set_ldt native_set_ldt
+-
+-#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
+-#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
+-#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
+-
+-static inline void write_dt_entry(struct desc_struct *dt,
+-                                int entry, u32 entry_low, u32 entry_high)
 -{
--      pte_t pte = *ptep;
--      if (pte_write(pte))
--              set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
+-      dt[entry].a = entry_low;
+-      dt[entry].b = entry_high;
 -}
 -
--/*
-  * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
-  *
-  *  dst - pointer to pgd range anwhere on a pgd page
-@@ -383,26 +135,6 @@ static inline void clone_pgd_range(pgd_t
- #define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
--static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+-static inline void native_set_ldt(const void *addr, unsigned int entries)
 -{
--      /*
--       * Since this might change the present bit (which controls whether
--       * a pte_t object has undergone p2m translation), we must use
--       * pte_val() on the input pte and __pte() for the return value.
--       */
--      paddr_t pteval = pte_val(pte);
+-      if (likely(entries == 0))
+-              __asm__ __volatile__("lldt %w0"::"q" (0));
+-      else {
+-              unsigned cpu = smp_processor_id();
+-              __u32 a, b;
 -
--      pteval &= _PAGE_CHG_MASK;
--      pteval |= pgprot_val(newprot);
--#ifdef CONFIG_X86_PAE
--      pteval &= __supported_pte_mask;
--#endif
--      return __pte(pteval);
+-              pack_descriptor(&a, &b, (unsigned long)addr,
+-                              entries * sizeof(struct desc_struct) - 1,
+-                              DESCTYPE_LDT, 0);
+-              write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b);
+-              __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8));
+-      }
 -}
 -
--#define pmd_large(pmd) \
--((__pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
--
- /*
-  * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
-  *
-@@ -424,6 +156,8 @@ static inline pte_t pte_modify(pte_t pte
-  */
- #define pgd_offset_k(address) pgd_offset(&init_mm, address)
-+static inline int pud_large(pud_t pud) { return 0; }
-+
- /*
-  * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
-  *
-@@ -449,26 +183,6 @@ static inline pte_t pte_modify(pte_t pte
- #define pmd_page_vaddr(pmd) \
-               ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
--/*
-- * Helper function that returns the kernel pagetable entry controlling
-- * the virtual address 'address'. NULL means no pagetable entry present.
-- * NOTE: the return type is pte_t but if the pmd is PSE then we return it
-- * as a pte too.
-- */
--extern pte_t *lookup_address(unsigned long address);
--
--/*
-- * Make a given kernel text page executable/non-executable.
-- * Returns the previous executability setting of that page (which
-- * is used to restore the previous state). Used by the SMP bootup code.
-- * NOTE: this is an __init function for security reasons.
-- */
--#ifdef CONFIG_X86_PAE
-- extern int set_kernel_exec(unsigned long vaddr, int enable);
--#else
-- static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;}
--#endif
 -
- #if defined(CONFIG_HIGHPTE)
- #define pte_offset_map(dir, address) \
-       ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
-@@ -496,59 +210,22 @@ extern pte_t *lookup_address(unsigned lo
-  */
- #define update_mmu_cache(vma,address,pte) do { } while (0)
--#include <xen/features.h>
- void make_lowmem_page_readonly(void *va, unsigned int feature);
- void make_lowmem_page_writable(void *va, unsigned int feature);
--void make_page_readonly(void *va, unsigned int feature);
--void make_page_writable(void *va, unsigned int feature);
--void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
--void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
+-static inline void native_load_tr_desc(void)
+-{
+-      asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
+-}
 -
--#define virt_to_ptep(va)                                              \
--({                                                                    \
--      pte_t *__ptep = lookup_address((unsigned long)(va));            \
--      BUG_ON(!__ptep || !pte_present(*__ptep));                       \
--      __ptep;                                                         \
--})
+-static inline void native_load_gdt(const struct Xgt_desc_struct *dtr)
+-{
+-      asm volatile("lgdt %0"::"m" (*dtr));
+-}
 -
--#define arbitrary_virt_to_machine(va)                                 \
--      (((maddr_t)pte_mfn(*virt_to_ptep(va)) << PAGE_SHIFT)            \
--       | ((unsigned long)(va) & (PAGE_SIZE - 1)))
- #endif /* !__ASSEMBLY__ */
-+/*
-+ * kern_addr_valid() is (1) for FLATMEM and (0) for
-+ * SPARSEMEM and DISCONTIGMEM
-+ */
- #ifdef CONFIG_FLATMEM
- #define kern_addr_valid(addr) (1)
--#endif /* CONFIG_FLATMEM */
+-static inline void native_load_idt(const struct Xgt_desc_struct *dtr)
+-{
+-      asm volatile("lidt %0"::"m" (*dtr));
+-}
 -
--int direct_remap_pfn_range(struct vm_area_struct *vma,
--                           unsigned long address, 
--                           unsigned long mfn,
--                           unsigned long size, 
--                           pgprot_t prot,
--                           domid_t  domid);
--int direct_kernel_remap_pfn_range(unsigned long address, 
--                                unsigned long mfn,
--                                unsigned long size, 
--                                pgprot_t prot,
--                                domid_t  domid);
--int create_lookup_pte_addr(struct mm_struct *mm,
--                           unsigned long address,
--                           uint64_t *ptep);
--int touch_pte_range(struct mm_struct *mm,
--                    unsigned long address,
--                    unsigned long size);
+-static inline void native_store_gdt(struct Xgt_desc_struct *dtr)
+-{
+-      asm ("sgdt %0":"=m" (*dtr));
+-}
 -
--int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
--              unsigned long addr, unsigned long end, pgprot_t newprot,
--              int dirty_accountable);
+-static inline void native_store_idt(struct Xgt_desc_struct *dtr)
+-{
+-      asm ("sidt %0":"=m" (*dtr));
+-}
 -
--#define arch_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable) \
--      xen_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable)
-+#else
-+#define kern_addr_valid(kaddr)        (0)
-+#endif
- #define io_remap_pfn_range(vma,from,pfn,size,prot) \
- direct_remap_pfn_range(vma,from,pfn,size,prot,DOMID_IO)
--#include <asm-generic/pgtable.h>
+-static inline unsigned long native_store_tr(void)
+-{
+-      unsigned long tr;
+-      asm ("str %0":"=r" (tr));
+-      return tr;
+-}
 -
- #endif /* _I386_PGTABLE_H */
---- a/include/asm-x86/mach-xen/asm/pgtable-3level.h
-+++ b/include/asm-x86/mach-xen/asm/pgtable-3level.h
-@@ -18,16 +18,18 @@
-       printk("%s:%d: bad pgd %p(%016Lx pfn %08Lx).\n", __FILE__, __LINE__, \
-              &(e), __pgd_val(e), (pgd_val(e) & PTE_MASK) >> PAGE_SHIFT)
--#define pud_none(pud)                         0
--#define pud_bad(pud)                          0
--#define pud_present(pud)                      1
--/*
-- * All present pages with !NX bit are kernel-executable:
-- */
--static inline int pte_exec_kernel(pte_t pte)
-+static inline int pud_none(pud_t pud)
-+{
-+      return __pud_val(pud) == 0;
-+}
-+static inline int pud_bad(pud_t pud)
- {
--      return !(__pte_val(pte) & _PAGE_NX);
-+      return (__pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
-+}
-+static inline int pud_present(pud_t pud)
-+{
-+      return __pud_val(pud) & _PAGE_PRESENT;
- }
- /* Rules for using set_pte: the pte being assigned *must* be
-@@ -44,14 +46,6 @@ static inline void xen_set_pte(pte_t *pt
-       ptep->pte_low = pte.pte_low;
- }
--static inline void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
--                                pte_t *ptep , pte_t pte)
+-static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 -{
--      if ((mm != current->mm && mm != &init_mm) ||
--          HYPERVISOR_update_va_mapping(addr, pte, 0))
--              xen_set_pte(ptep, pte);
+-      unsigned int i;
+-      struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+-
+-      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+-              gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
 -}
+-#else
+-#define load_TLS(t, cpu) xen_load_tls(t, cpu)
+-#define set_ldt xen_set_ldt
 -
- static inline void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
- {
-       set_64bit((unsigned long long *)(ptep),__pte_val(pte));
-@@ -70,14 +64,11 @@ static inline void xen_set_pud(pud_t *pu
-  * entry, so clear the bottom half first and enforce ordering with a compiler
-  * barrier.
-  */
--static inline void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-+static inline void __xen_pte_clear(pte_t *ptep)
- {
--      if ((mm != current->mm && mm != &init_mm)
--          || HYPERVISOR_update_va_mapping(addr, __pte(0), 0)) {
--              ptep->pte_low = 0;
--              smp_wmb();
--              ptep->pte_high = 0;
--      }
-+      ptep->pte_low = 0;
-+      smp_wmb();
-+      ptep->pte_high = 0;
- }
- static inline void xen_pmd_clear(pmd_t *pmd)
-@@ -85,21 +76,25 @@ static inline void xen_pmd_clear(pmd_t *
-       xen_l2_entry_update(pmd, __pmd(0));
- }
--#define set_pte(ptep, pte)                    xen_set_pte(ptep, pte)
--#define set_pte_at(mm, addr, ptep, pte)               xen_set_pte_at(mm, addr, ptep, pte)
--#define set_pte_atomic(ptep, pte)             xen_set_pte_atomic(ptep, pte)
--#define set_pmd(pmdp, pmd)                    xen_set_pmd(pmdp, pmd)
--#define set_pud(pudp, pud)                    xen_set_pud(pudp, pud)
--#define pte_clear(mm, addr, ptep)             xen_pte_clear(mm, addr, ptep)
--#define pmd_clear(pmd)                                xen_pmd_clear(pmd)
-+static inline void pud_clear(pud_t *pudp)
-+{
-+      pgdval_t pgd;
-+
-+      set_pud(pudp, __pud(0));
--/*
-- * Pentium-II erratum A13: in PAE mode we explicitly have to flush
-- * the TLB via cr3 if the top-level pgd is changed...
-- * We do not let the generic code free and clear pgd entries due to
-- * this erratum.
-- */
--static inline void pud_clear (pud_t * pud) { }
-+      /*
-+       * According to Intel App note "TLBs, Paging-Structure Caches,
-+       * and Their Invalidation", April 2007, document 317080-001,
-+       * section 8.1: in PAE mode we explicitly have to flush the
-+       * TLB via cr3 if the top-level pgd is changed...
-+       *
-+       * Make sure the pud entry we're updating is within the
-+       * current pgd to avoid unnecessary TLB flushes.
-+       */
-+      pgd = read_cr3();
-+      if (__pa(pudp) >= pgd && __pa(pudp) < (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
-+              xen_tlb_flush();
-+}
- #define pud_page(pud) \
- ((struct page *) __va(pud_val(pud) & PAGE_MASK))
-@@ -128,24 +123,6 @@ static inline pte_t xen_ptep_get_and_cle
- #define xen_ptep_get_and_clear(xp, pte) xen_local_ptep_get_and_clear(xp, pte)
- #endif
--#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
--#define ptep_clear_flush(vma, addr, ptep)                     \
--({                                                            \
--      pte_t *__ptep = (ptep);                                 \
--      pte_t __res = *__ptep;                                  \
--      if (!pte_none(__res) &&                                 \
--          ((vma)->vm_mm != current->mm ||                     \
--           HYPERVISOR_update_va_mapping(addr, __pte(0),       \
--                      (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
--                              UVMF_INVLPG|UVMF_MULTI))) {     \
--              __ptep->pte_low = 0;                            \
--              smp_wmb();                                      \
--              __ptep->pte_high = 0;                           \
--              flush_tlb_page(vma, addr);                      \
--      }                                                       \
--      __res;                                                  \
--})
+-extern int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b);
+-extern int write_gdt_entry(void *gdt, int entry, __u32 entry_a, __u32 entry_b);
 -
- #define __HAVE_ARCH_PTE_SAME
- static inline int pte_same(pte_t a, pte_t b)
- {
-@@ -168,26 +145,12 @@ static inline int pte_none(pte_t pte)
-                      mfn_to_local_pfn(__pte_mfn(_pte)) :      \
-                      __pte_mfn(_pte))
--extern unsigned long long __supported_pte_mask;
+-static inline void xen_load_tls(struct thread_struct *t, unsigned int cpu)
+-{
+-      unsigned int i;
+-      struct desc_struct *gdt = get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN;
 -
--static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
+-      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+-              if (HYPERVISOR_update_descriptor(virt_to_machine(&gdt[i]),
+-                                               *(u64 *)&t->tls_array[i]))
+-                      BUG();
+-}
+-#endif
+-
+-#ifndef CONFIG_X86_NO_IDT
+-static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
 -{
--      return __pte((((unsigned long long)page_nr << PAGE_SHIFT) |
--                    pgprot_val(pgprot)) & __supported_pte_mask);
+-      __u32 a, b;
+-      pack_gate(&a, &b, (unsigned long)addr, seg, type, 0);
+-      write_idt_entry(idt_table, gate, a, b);
 -}
+-#endif
 -
--static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
+-#ifndef CONFIG_X86_NO_TSS
+-static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr)
 -{
--      return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) |
--                    pgprot_val(pgprot)) & __supported_pte_mask);
+-      __u32 a, b;
+-      pack_descriptor(&a, &b, (unsigned long)addr,
+-                      offsetof(struct tss_struct, __cacheline_filler) - 1,
+-                      DESCTYPE_TSS, 0);
+-      write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b);
 -}
+-#endif
 -
- /*
-  * Bits 0, 6 and 7 are taken in the low part of the pte,
-  * put the 32 bits of offset into the high part.
-  */
- #define pte_to_pgoff(pte) ((pte).pte_high)
--#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
-+#define pgoff_to_pte(off) ((pte_t) { { .pte_low = _PAGE_FILE, .pte_high = (off) } })
- #define PTE_FILE_MAX_BITS       32
- /* Encode and de-code a swap entry */
-@@ -195,8 +158,6 @@ static inline pmd_t pfn_pmd(unsigned lon
- #define __swp_offset(x)                       ((x).val >> 5)
- #define __swp_entry(type, offset)     ((swp_entry_t){(type) | (offset) << 5})
- #define __pte_to_swp_entry(pte)               ((swp_entry_t){ (pte).pte_high })
--#define __swp_entry_to_pte(x)         ((pte_t){ 0, (x).val })
 -
--#define __pmd_free_tlb(tlb, x)                do { } while (0)
-+#define __swp_entry_to_pte(x)         ((pte_t){ { .pte_high = (x).val } })
- #endif /* _I386_PGTABLE_3LEVEL_H */
---- a/include/asm-x86/mach-xen/asm/pgtable_64.h
-+++ b/include/asm-x86/mach-xen/asm/pgtable_64.h
-@@ -13,47 +13,26 @@
- #include <linux/threads.h>
- #include <linux/sched.h>
- #include <asm/pda.h>
--#ifdef CONFIG_XEN
--#include <asm/hypervisor.h>
-+#ifdef CONFIG_XEN
- extern pud_t level3_user_pgt[512];
- extern void xen_init_pt(void);
+-#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
 -
--extern pte_t *lookup_address(unsigned long address);
+-#define LDT_entry_a(info) \
+-      ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
 -
--#define virt_to_ptep(va)                                              \
--({                                                                    \
--      pte_t *__ptep = lookup_address((unsigned long)(va));            \
--      BUG_ON(!__ptep || !pte_present(*__ptep));                       \
--      __ptep;                                                         \
--})
+-#define LDT_entry_b(info) \
+-      (((info)->base_addr & 0xff000000) | \
+-      (((info)->base_addr & 0x00ff0000) >> 16) | \
+-      ((info)->limit & 0xf0000) | \
+-      (((info)->read_exec_only ^ 1) << 9) | \
+-      ((info)->contents << 10) | \
+-      (((info)->seg_not_present ^ 1) << 15) | \
+-      ((info)->seg_32bit << 22) | \
+-      ((info)->limit_in_pages << 23) | \
+-      ((info)->useable << 20) | \
+-      0x7000)
 -
--#define arbitrary_virt_to_machine(va)                                 \
--      (((maddr_t)pte_mfn(*virt_to_ptep(va)) << PAGE_SHIFT)            \
--       | ((unsigned long)(va) & (PAGE_SIZE - 1)))
- #endif
- extern pud_t level3_kernel_pgt[512];
- extern pud_t level3_ident_pgt[512];
- extern pmd_t level2_kernel_pgt[512];
- extern pgd_t init_level4_pgt[];
--extern unsigned long __supported_pte_mask;
- #define swapper_pg_dir init_level4_pgt
- extern void paging_init(void);
--extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
+-#define LDT_empty(info) (\
+-      (info)->base_addr       == 0    && \
+-      (info)->limit           == 0    && \
+-      (info)->contents        == 0    && \
+-      (info)->read_exec_only  == 1    && \
+-      (info)->seg_32bit       == 0    && \
+-      (info)->limit_in_pages  == 0    && \
+-      (info)->seg_not_present == 1    && \
+-      (info)->useable         == 0    )
+-
+-static inline void clear_LDT(void)
+-{
+-      set_ldt(NULL, 0);
+-}
 -
 -/*
-- * ZERO_PAGE is a global shared page that is always zero: used
-- * for zero-mapped memory areas etc..
+- * load one particular LDT into the current CPU
 - */
--extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
--#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
- #endif /* !__ASSEMBLY__ */
-+#define SHARED_KERNEL_PMD     1
-+
- /*
-  * PGDIR_SHIFT determines what a top-level page table entry can map
-  */
-@@ -96,31 +75,63 @@ extern unsigned long empty_zero_page[PAG
- #define pgd_none(x)   (!__pgd_val(x))
- #define pud_none(x)   (!__pud_val(x))
--static inline void set_pte(pte_t *dst, pte_t val)
-+struct mm_struct;
-+
-+#define __xen_pte_clear(ptep) xen_set_pte(ptep, __pte(0))
-+
-+static inline void xen_set_pte(pte_t *ptep, pte_t pte)
-+{
-+      *ptep = pte;
-+}
-+
-+static inline void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
-+{
-+      xen_set_pte(ptep, pte);
-+}
-+
-+#ifdef CONFIG_SMP
-+static inline pte_t xen_ptep_get_and_clear(pte_t *xp, pte_t ret)
-+{
-+      return __pte_ma(xchg(&xp->pte, 0));
-+}
-+#else
-+#define xen_ptep_get_and_clear(xp, pte) xen_local_ptep_get_and_clear(xp, pte)
-+#endif
-+
-+static inline void xen_set_pmd(pmd_t *pmdp, pmd_t pmd)
- {
--      *dst = val;
-+      xen_l2_entry_update(pmdp, pmd);
- }
--#define set_pmd(pmdptr, pmdval) xen_l2_entry_update(pmdptr, (pmdval))
--#define set_pud(pudptr, pudval) xen_l3_entry_update(pudptr, (pudval))
--#define set_pgd(pgdptr, pgdval) xen_l4_entry_update(pgdptr, (pgdval))
-+static inline void xen_pmd_clear(pmd_t *pmd)
-+{
-+      xen_set_pmd(pmd, xen_make_pmd(0));
-+}
-+
-+static inline void xen_set_pud(pud_t *pudp, pud_t pud)
-+{
-+      xen_l3_entry_update(pudp, pud);
-+}
--static inline void pud_clear (pud_t * pud)
-+static inline void xen_pud_clear(pud_t *pud)
- {
--      set_pud(pud, __pud(0));
-+      xen_set_pud(pud, xen_make_pud(0));
- }
- #define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
--static inline void pgd_clear (pgd_t * pgd)
-+static inline void xen_set_pgd(pgd_t *pgdp, pgd_t pgd)
- {
--        set_pgd(pgd, __pgd(0));
--        set_pgd(__user_pgd(pgd), __pgd(0));
-+      xen_l4_entry_update(pgdp, pgd);
- }
--#define pte_same(a, b)                ((a).pte == (b).pte)
-+static inline void xen_pgd_clear(pgd_t * pgd)
-+{
-+      xen_set_pgd(pgd, xen_make_pgd(0));
-+      xen_set_pgd(__user_pgd(pgd), xen_make_pgd(0));
-+}
--#define pte_pgprot(a) (__pgprot((a).pte & ~PHYSICAL_PAGE_MASK))
-+#define pte_same(a, b)                ((a).pte == (b).pte)
- #endif /* !__ASSEMBLY__ */
-@@ -131,8 +142,6 @@ static inline void pgd_clear (pgd_t * pg
- #define PGDIR_SIZE    (_AC(1,UL) << PGDIR_SHIFT)
- #define PGDIR_MASK    (~(PGDIR_SIZE-1))
--#define USER_PTRS_PER_PGD     ((TASK_SIZE-1)/PGDIR_SIZE+1)
--#define FIRST_USER_ADDRESS    0
- #define MAXMEM                 _AC(0x3fffffffffff, UL)
- #define VMALLOC_START    _AC(0xffffc20000000000, UL)
-@@ -142,105 +151,6 @@ static inline void pgd_clear (pgd_t * pg
- #define MODULES_END      _AC(0xfffffffffff00000, UL)
- #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
--#define _PAGE_BIT_PRESENT     0
--#define _PAGE_BIT_RW          1
--#define _PAGE_BIT_USER                2
--#define _PAGE_BIT_PWT         3
--#define _PAGE_BIT_PCD         4
--#define _PAGE_BIT_ACCESSED    5
--#define _PAGE_BIT_DIRTY               6
--#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page */
--#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
--#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
+-static inline void load_LDT_nolock(mm_context_t *pc)
+-{
+-      set_ldt(pc->ldt, pc->size);
+-}
 -
--#define _PAGE_PRESENT 0x001
--#define _PAGE_RW      0x002
--#define _PAGE_USER    0x004
--#define _PAGE_PWT     0x008
--#define _PAGE_PCD     0x010
--#define _PAGE_ACCESSED        0x020
--#define _PAGE_DIRTY   0x040
--#define _PAGE_PSE     0x080   /* 2MB page */
--#define _PAGE_FILE    0x040   /* nonlinear file mapping, saved PTE; unset:swap */
--#define _PAGE_GLOBAL  0x100   /* Global TLB entry */
+-static inline void load_LDT(mm_context_t *pc)
+-{
+-      preempt_disable();
+-      load_LDT_nolock(pc);
+-      preempt_enable();
+-}
+-
+-static inline unsigned long get_desc_base(unsigned long *desc)
+-{
+-      unsigned long base;
+-      base = ((desc[0] >> 16)  & 0x0000ffff) |
+-              ((desc[1] << 16) & 0x00ff0000) |
+-              (desc[1] & 0xff000000);
+-      return base;
+-}
 -
--#define _PAGE_PROTNONE        0x080   /* If not present */
--#define _PAGE_NX        (_AC(1,UL)<<_PAGE_BIT_NX)
+-#else /* __ASSEMBLY__ */
 -
--/* Mapped page is I/O or foreign and has no associated page struct. */
--#define _PAGE_IO      0x200
+-/*
+- * GET_DESC_BASE reads the descriptor base of the specified segment.
+- *
+- * Args:
+- *    idx - descriptor index
+- *    gdt - GDT pointer
+- *    base - 32bit register to which the base will be written
+- *    lo_w - lo word of the "base" register
+- *    lo_b - lo byte of the "base" register
+- *    hi_b - hi byte of the low word of the "base" register
+- *
+- * Example:
+- *    GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
+- *    Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax.
+- */
+-#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \
+-      movb idx*8+4(gdt), lo_b; \
+-      movb idx*8+7(gdt), hi_b; \
+-      shll $16, base; \
+-      movw idx*8+2(gdt), lo_w;
+-
+-#endif /* !__ASSEMBLY__ */
 -
--#ifndef __ASSEMBLY__
--#if CONFIG_XEN_COMPAT <= 0x030002
--extern unsigned int __kernel_page_user;
--#else
--#define __kernel_page_user 0
--#endif
 -#endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/desc_64.h       2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,228 +0,0 @@
+-/* Written 2000 by Andi Kleen */ 
+-#ifndef __ARCH_DESC_H
+-#define __ARCH_DESC_H
 -
--#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
+-#include <linux/threads.h>
+-#include <asm/ldt.h>
 -
--#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
+-#ifndef __ASSEMBLY__
 -
--#define PAGE_NONE     __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
--#define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
--#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
--#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
--#define PAGE_COPY PAGE_COPY_NOEXEC
--#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
--#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
--#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
--#define __PAGE_KERNEL \
--      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
--#define __PAGE_KERNEL_EXEC \
--      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | __kernel_page_user)
--#define __PAGE_KERNEL_NOCACHE \
--      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
--#define __PAGE_KERNEL_RO \
--      (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
--#define __PAGE_KERNEL_VSYSCALL \
--      (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
--#define __PAGE_KERNEL_VSYSCALL_NOCACHE \
--      (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
--#define __PAGE_KERNEL_LARGE \
--      (__PAGE_KERNEL | _PAGE_PSE)
--#define __PAGE_KERNEL_LARGE_EXEC \
--      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
+-#include <linux/string.h>
+-#include <linux/smp.h>
+-#include <asm/desc_defs.h>
 -
--/*
-- * We don't support GLOBAL page in xenolinux64
-- */
--#define MAKE_GLOBAL(x) __pgprot((x))
+-#include <asm/segment.h>
+-#include <asm/mmu.h>
 -
--#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
--#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
--#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
--#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
--#define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
--#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
--#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
--#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
+-extern struct desc_ptr idt_descr, cpu_gdt_descr[NR_CPUS];
 -
--/*         xwr */
--#define __P000        PAGE_NONE
--#define __P001        PAGE_READONLY
--#define __P010        PAGE_COPY
--#define __P011        PAGE_COPY
--#define __P100        PAGE_READONLY_EXEC
--#define __P101        PAGE_READONLY_EXEC
--#define __P110        PAGE_COPY_EXEC
--#define __P111        PAGE_COPY_EXEC
+-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
 -
--#define __S000        PAGE_NONE
--#define __S001        PAGE_READONLY
--#define __S010        PAGE_SHARED
--#define __S011        PAGE_SHARED
--#define __S100        PAGE_READONLY_EXEC
--#define __S101        PAGE_READONLY_EXEC
--#define __S110        PAGE_SHARED_EXEC
--#define __S111        PAGE_SHARED_EXEC
+-#define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8))
+-#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
 -
- #ifndef __ASSEMBLY__
- static inline unsigned long pgd_bad(pgd_t pgd)
-@@ -258,119 +168,26 @@ static inline unsigned long pmd_bad(pmd_
-       return __pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
- }
--#define set_pte_at(_mm,addr,ptep,pteval) do {                         \
--      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
--          HYPERVISOR_update_va_mapping((addr), (pteval), 0))          \
--              set_pte((ptep), (pteval));                              \
--} while (0)
+-static inline void clear_LDT(void)
+-{
+-      int cpu = get_cpu();
 -
- #define pte_none(x)   (!(x).pte)
- #define pte_present(x)        ((x).pte & (_PAGE_PRESENT | _PAGE_PROTNONE))
--#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
--#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))       /* FIXME: is this right? */
- #define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
- #define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
-       __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
--#define pte_pfn(_pte) ((_pte).pte & _PAGE_IO ? end_pfn :      \
-+#define pte_pfn(_pte) ((_pte).pte & _PAGE_IO ? max_mapnr :    \
-                      (_pte).pte & _PAGE_PRESENT ?             \
-                      mfn_to_local_pfn(__pte_mfn(_pte)) :      \
-                      __pte_mfn(_pte))
- #define pte_page(x)   pfn_to_page(pte_pfn(x))
--static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
+-      /*
+-       * NB. We load the default_ldt for lcall7/27 handling on demand, as
+-       * it slows down context switching. Noone uses it anyway.
+-       */
+-      cpu = cpu;              /* XXX avoid compiler warning */
+-      xen_set_ldt(NULL, 0);
+-      put_cpu();
+-}
+-
+-#ifndef CONFIG_X86_NO_TSS
+-static inline unsigned long __store_tr(void)
 -{
--      unsigned long pte = page_nr << PAGE_SHIFT;
--      pte |= pgprot_val(pgprot);
--      pte &= __supported_pte_mask;
--      return __pte(pte);
+-       unsigned long tr;
+-
+-       asm volatile ("str %w0":"=r" (tr));
+-       return tr;
 -}
 -
--static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+-#define store_tr(tr) (tr) = __store_tr()
+-#endif
+-
+-/*
+- * This is the ldt that every process will get unless we need
+- * something other than this.
+- */
+-extern struct desc_struct default_ldt[];
+-#ifndef CONFIG_X86_NO_IDT
+-extern struct gate_struct idt_table[]; 
+-#endif
+-extern struct desc_ptr cpu_gdt_descr[];
+-
+-/* the cpu gdt accessor */
+-#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
+-
+-#ifndef CONFIG_XEN
+-static inline void load_gdt(const struct desc_ptr *ptr)
 -{
--      pte_t pte = *ptep;
--      if (!pte_none(pte)) {
--              if ((mm != &init_mm) ||
--                  HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
--                      pte = __pte_ma(xchg(&ptep->pte, 0));
--      }
--      return pte;
+-      asm volatile("lgdt %w0"::"m" (*ptr));
 -}
 -
--static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
+-static inline void store_gdt(struct desc_ptr *ptr)
 -{
--      if (full) {
--              pte_t pte = *ptep;
--              if (PagePinned(virt_to_page(mm->pgd)))
--                      xen_l1_entry_update(ptep, __pte(0));
--              else
--                      *ptep = __pte(0);
--              return pte;
--      }
--      return ptep_get_and_clear(mm, addr, ptep);
+-       asm("sgdt %w0":"=m" (*ptr));
 -}
+-#endif
 -
--#define ptep_clear_flush(vma, addr, ptep)                     \
--({                                                            \
--      pte_t *__ptep = (ptep);                                 \
--      pte_t __res = *__ptep;                                  \
--      if (!pte_none(__res) &&                                 \
--          ((vma)->vm_mm != current->mm ||                     \
--           HYPERVISOR_update_va_mapping(addr, __pte(0),       \
--                      (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
--                              UVMF_INVLPG|UVMF_MULTI))) {     \
--              __ptep->pte = 0;                                \
--              flush_tlb_page(vma, addr);                      \
--      }                                                       \
--      __res;                                                  \
--})
+-static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
+-{
+-      struct gate_struct s;   
+-      s.offset_low = PTR_LOW(func); 
+-      s.segment = __KERNEL_CS;
+-      s.ist = ist; 
+-      s.p = 1;
+-      s.dpl = dpl; 
+-      s.zero0 = 0;
+-      s.zero1 = 0; 
+-      s.type = type; 
+-      s.offset_middle = PTR_MIDDLE(func); 
+-      s.offset_high = PTR_HIGH(func); 
+-      /* does not need to be atomic because it is only done once at setup time */ 
+-      memcpy(adr, &s, 16); 
+-} 
 -
--/*
-- * The following only work if pte_present() is true.
-- * Undefined behaviour if not..
-- */
--#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
--static inline int pte_dirty(pte_t pte)                { return __pte_val(pte) & _PAGE_DIRTY; }
--static inline int pte_young(pte_t pte)                { return __pte_val(pte) & _PAGE_ACCESSED; }
--static inline int pte_write(pte_t pte)                { return __pte_val(pte) & _PAGE_RW; }
--static inline int pte_file(pte_t pte)         { return __pte_val(pte) & _PAGE_FILE; }
--static inline int pte_huge(pte_t pte)         { return __pte_val(pte) & _PAGE_PSE; }
+-#ifndef CONFIG_X86_NO_IDT
+-static inline void set_intr_gate(int nr, void *func) 
+-{ 
+-      BUG_ON((unsigned)nr > 0xFF);
+-      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); 
+-} 
+-
+-static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) 
+-{ 
+-      BUG_ON((unsigned)nr > 0xFF);
+-      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); 
+-} 
+-
+-static inline void set_system_gate(int nr, void *func) 
+-{ 
+-      BUG_ON((unsigned)nr > 0xFF);
+-      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
+-} 
 -
--static inline pte_t pte_mkclean(pte_t pte)    { __pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
--static inline pte_t pte_mkold(pte_t pte)      { __pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
--static inline pte_t pte_wrprotect(pte_t pte)  { __pte_val(pte) &= ~_PAGE_RW; return pte; }
--static inline pte_t pte_mkexec(pte_t pte)     { __pte_val(pte) &= ~_PAGE_NX; return pte; }
--static inline pte_t pte_mkdirty(pte_t pte)    { __pte_val(pte) |= _PAGE_DIRTY; return pte; }
--static inline pte_t pte_mkyoung(pte_t pte)    { __pte_val(pte) |= _PAGE_ACCESSED; return pte; }
--static inline pte_t pte_mkwrite(pte_t pte)    { __pte_val(pte) |= _PAGE_RW; return pte; }
--static inline pte_t pte_mkhuge(pte_t pte)     { __pte_val(pte) |= _PAGE_PSE; return pte; }
--static inline pte_t pte_clrhuge(pte_t pte)    { __pte_val(pte) &= ~_PAGE_PSE; return pte; }
+-static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
+-{
+-      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
+-}
 -
--static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+-static inline void load_idt(const struct desc_ptr *ptr)
 -{
--      if (!pte_young(*ptep))
--              return 0;
--      return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte);
+-      asm volatile("lidt %w0"::"m" (*ptr));
 -}
 -
--static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+-static inline void store_idt(struct desc_ptr *dtr)
 -{
--      pte_t pte = *ptep;
--      if (pte_write(pte))
--              set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
+-       asm("sidt %w0":"=m" (*dtr));
 -}
+-#endif
 -
- /*
-  * Macro to mark a page protection value as "uncacheable".
-  */
- #define pgprot_noncached(prot)        (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
--static inline int pmd_large(pmd_t pte) { 
--      return (__pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE;
--}     
+-static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
+-                                       unsigned size) 
+-{ 
+-      struct ldttss_desc d;
+-      memset(&d,0,sizeof(d)); 
+-      d.limit0 = size & 0xFFFF;
+-      d.base0 = PTR_LOW(tss); 
+-      d.base1 = PTR_MIDDLE(tss) & 0xFF; 
+-      d.type = type;
+-      d.p = 1; 
+-      d.limit1 = (size >> 16) & 0xF;
+-      d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; 
+-      d.base3 = PTR_HIGH(tss); 
+-      memcpy(ptr, &d, 16); 
+-}
 -
- /*
-  * Conversion functions: convert a page and protection to a page entry,
-@@ -386,6 +203,7 @@ static inline int pmd_large(pmd_t pte) {
- #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
- #define pgd_offset_k(address) (init_level4_pgt + pgd_index(address))
- #define pgd_present(pgd) (__pgd_val(pgd) & _PAGE_PRESENT)
-+static inline int pgd_large(pgd_t pgd) { return 0; }
- #define mk_kernel_pgd(address) __pgd((address) | _KERNPG_TABLE)
- /* PUD - Level3 access */
-@@ -396,6 +214,12 @@ static inline int pmd_large(pmd_t pte) {
- #define pud_offset(pgd, address) ((pud_t *) pgd_page_vaddr(*(pgd)) + pud_index(address))
- #define pud_present(pud) (__pud_val(pud) & _PAGE_PRESENT)
-+static inline int pud_large(pud_t pte)
-+{
-+      return (__pud_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) ==
-+              (_PAGE_PSE|_PAGE_PRESENT);
-+}
-+
- /* PMD  - Level 2 access */
- #define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK))
- #define pmd_page(pmd)         (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-@@ -411,36 +235,18 @@ static inline int pmd_large(pmd_t pte) {
- #else
- #define pmd_present(x)        (__pmd_val(x) & _PAGE_PRESENT)
- #endif
--#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
- #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
- #define pmd_pfn(x)  ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
- #define pte_to_pgoff(pte) ((__pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
--#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
-+#define pgoff_to_pte(off) ((pte_t) { .pte = ((off) << PAGE_SHIFT) | _PAGE_FILE })
- #define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT
- /* PTE - Level 1 access. */
- /* page, protection -> pte */
- #define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
--#define mk_pte_huge(entry) (__pte_val(entry) |= _PAGE_PRESENT | _PAGE_PSE)
-  
--/* Change flags of a PTE */
--static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+-#ifndef CONFIG_X86_NO_TSS
+-static inline void set_tss_desc(unsigned cpu, void *addr)
 -{ 
 -      /*
--       * Since this might change the present bit (which controls whether
--       * a pte_t object has undergone p2m translation), we must use
--       * pte_val() on the input pte and __pte() for the return value.
+-       * sizeof(unsigned long) coming from an extra "long" at the end
+-       * of the iobitmap. See tss_struct definition in processor.h
+-       *
+-       * -1? seg base+limit should be pointing to the address of the
+-       * last valid byte
 -       */
--      unsigned long pteval = pte_val(pte);
+-      set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], 
+-              (unsigned long)addr, DESC_TSS,
+-              IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1);
+-} 
+-#endif
 -
--      pteval &= _PAGE_CHG_MASK;
--      pteval |= pgprot_val(newprot);
--      pteval &= __supported_pte_mask;
--      return __pte(pteval);
+-static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
+-
+-      set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr,
+-                            DESC_LDT, size * 8 - 1);
 -}
 -
- #define pte_index(address) \
-               (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
- #define pte_offset_kernel(dir, address) ((pte_t *) pmd_page_vaddr(*(dir)) + \
-@@ -454,101 +260,21 @@ static inline pte_t pte_modify(pte_t pte
- #define update_mmu_cache(vma,address,pte) do { } while (0)
--/*
-- * Rules for using ptep_establish: the pte MUST be a user pte, and
-- * must be a present->present transition.
-- */
--#define __HAVE_ARCH_PTEP_ESTABLISH
--#define ptep_establish(vma, address, ptep, pteval)                    \
--      do {                                                            \
--              if ( likely((vma)->vm_mm == current->mm) ) {            \
--                      BUG_ON(HYPERVISOR_update_va_mapping(address,    \
--                              pteval,                                 \
--                              (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
--                                      UVMF_INVLPG|UVMF_MULTI));       \
--              } else {                                                \
--                      xen_l1_entry_update(ptep, pteval);              \
--                      flush_tlb_page(vma, address);                   \
--              }                                                       \
--      } while (0)
--
--/* We only update the dirty/accessed state if we set
-- * the dirty bit by hand in the kernel, since the hardware
-- * will do the accessed bit for us, and we don't want to
-- * race with other CPU's that might be updating the dirty
-- * bit at the same time. */
--#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
--#define ptep_set_access_flags(vma, address, ptep, entry, dirty)               \
--({                                                                    \
--      int __changed = !pte_same(*(ptep), entry);                      \
--      if (__changed && (dirty))                                       \
--              ptep_establish(vma, address, ptep, entry);              \
--      __changed;                                                      \
--})
--
--#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
--#define ptep_clear_flush_young(vma, address, ptep)                    \
--({                                                                    \
--      pte_t __pte = *(ptep);                                          \
--      int __young = pte_young(__pte);                                 \
--      __pte = pte_mkold(__pte);                                       \
--      if (PagePinned(virt_to_page((vma)->vm_mm->pgd)))                \
--              (void)ptep_set_access_flags(vma, address, ptep, __pte, __young); \
--      else if (__young)                                               \
--              set_pte(ptep, __pte);                                   \
--      __young;                                                        \
--})
--
- /* Encode and de-code a swap entry */
- #define __swp_type(x)                 (((x).val >> 1) & 0x3f)
- #define __swp_offset(x)                       ((x).val >> 8)
- #define __swp_entry(type, offset)     ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
- #define __pte_to_swp_entry(pte)               ((swp_entry_t) { __pte_val(pte) })
--#define __swp_entry_to_pte(x)         ((pte_t) { (x).val })
--
--extern spinlock_t pgd_lock;
--extern struct list_head pgd_list;
-+#define __swp_entry_to_pte(x)         ((pte_t) { .pte = (x).val })
- extern int kern_addr_valid(unsigned long addr); 
+-#define LDT_entry_a(info) \
+-      ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+-/* Don't allow setting of the lm bit. It is useless anyways because 
+-   64bit system calls require __USER_CS. */ 
+-#define LDT_entry_b(info) \
+-      (((info)->base_addr & 0xff000000) | \
+-      (((info)->base_addr & 0x00ff0000) >> 16) | \
+-      ((info)->limit & 0xf0000) | \
+-      (((info)->read_exec_only ^ 1) << 9) | \
+-      ((info)->contents << 10) | \
+-      (((info)->seg_not_present ^ 1) << 15) | \
+-      ((info)->seg_32bit << 22) | \
+-      ((info)->limit_in_pages << 23) | \
+-      ((info)->useable << 20) | \
+-      /* ((info)->lm << 21) | */ \
+-      0x7000)
 -
--#define DOMID_LOCAL (0xFFFFU)
+-#define LDT_empty(info) (\
+-      (info)->base_addr       == 0    && \
+-      (info)->limit           == 0    && \
+-      (info)->contents        == 0    && \
+-      (info)->read_exec_only  == 1    && \
+-      (info)->seg_32bit       == 0    && \
+-      (info)->limit_in_pages  == 0    && \
+-      (info)->seg_not_present == 1    && \
+-      (info)->useable         == 0    && \
+-      (info)->lm              == 0)
 -
--struct vm_area_struct;
+-static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
+-{
+-      unsigned int i;
+-      u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
 -
--int direct_remap_pfn_range(struct vm_area_struct *vma,
--                            unsigned long address,
--                            unsigned long mfn,
--                            unsigned long size,
--                            pgprot_t prot,
--                            domid_t  domid);
+-      for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+-              if (HYPERVISOR_update_descriptor(virt_to_machine(&gdt[i]),
+-                                               t->tls_array[i]))
+-                      BUG();
+-} 
 -
--int direct_kernel_remap_pfn_range(unsigned long address, 
--                                unsigned long mfn,
--                                unsigned long size, 
--                                pgprot_t prot,
--                                domid_t  domid);
+-/*
+- * load one particular LDT into the current CPU
+- */
+-static inline void load_LDT_nolock (mm_context_t *pc, int cpu)
+-{
+-      void *segments = pc->ldt;
+-      int count = pc->size;
 -
--int create_lookup_pte_addr(struct mm_struct *mm,
--                           unsigned long address,
--                           uint64_t *ptep);
+-      if (likely(!count))
+-              segments = NULL;
 -
--int touch_pte_range(struct mm_struct *mm,
--                    unsigned long address,
--                    unsigned long size);
+-      xen_set_ldt(segments, count);
+-}
 -
--int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
--              unsigned long addr, unsigned long end, pgprot_t newprot,
--              int dirty_accountable);
+-static inline void load_LDT(mm_context_t *pc)
+-{
+-      int cpu = get_cpu();
+-      load_LDT_nolock(pc, cpu);
+-      put_cpu();
+-}
 -
--#define arch_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable) \
--      xen_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable)
+-extern struct desc_ptr idt_descr;
 -
--pte_t *lookup_address(unsigned long addr);
-+extern void cleanup_highmap(void);
+-#endif /* !__ASSEMBLY__ */
+-
+-#endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/dma-mapping_32.h        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/dma-mapping_32.h     2009-03-16 16:33:40.000000000 +0100
+@@ -84,23 +84,13 @@ dma_sync_single_range_for_device(struct 
+       dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
+ }
  
- #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)               \
-               direct_remap_pfn_range(vma,vaddr,pfn,size,prot,DOMID_IO)
+-static inline void
++extern void
+ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+-                  enum dma_data_direction direction)
+-{
+-      if (swiotlb)
+-              swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
+-      flush_write_buffers();
+-}
++                  enum dma_data_direction direction);
  
- #define HAVE_ARCH_UNMAPPED_AREA
-+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+-static inline void
++extern void
+ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+-                  enum dma_data_direction direction)
+-{
+-      if (swiotlb)
+-              swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
+-      flush_write_buffers();
+-}
++                  enum dma_data_direction direction);
  
- #define pgtable_cache_init()   do { } while (0)
- #define check_pgt_cache()      do { } while (0)
-@@ -561,13 +287,7 @@ pte_t *lookup_address(unsigned long addr
- #define       kc_offset_to_vaddr(o) \
-    (((o) & (1UL << (__VIRTUAL_MASK_SHIFT-1))) ? ((o) | (~__VIRTUAL_MASK)) : (o))
+ extern int
+ dma_mapping_error(dma_addr_t dma_addr);
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/fixmap_32.h     2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/fixmap_32.h  2009-03-16 16:33:40.000000000 +0100
+@@ -64,7 +64,7 @@ enum fixed_addresses {
+ #endif
+ #ifdef CONFIG_X86_VISWS_APIC
+       FIX_CO_CPU,     /* Cobalt timer */
+-      FIX_CO_APIC,    /* Cobalt APIC Redirection Table */ 
++      FIX_CO_APIC,    /* Cobalt APIC Redirection Table */
+       FIX_LI_PCIA,    /* Lithium PCI Bridge A */
+       FIX_LI_PCIB,    /* Lithium PCI Bridge B */
+ #endif
+@@ -73,7 +73,7 @@ enum fixed_addresses {
+ #endif
+ #ifdef CONFIG_X86_CYCLONE_TIMER
+       FIX_CYCLONE_TIMER, /*cyclone timer register*/
+-#endif 
++#endif
+ #ifdef CONFIG_HIGHMEM
+       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+@@ -93,11 +93,23 @@ enum fixed_addresses {
+       FIX_ISAMAP_END,
+       FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
+       __end_of_permanent_fixed_addresses,
+-      /* temporary boot-time mappings, used before ioremap() is functional */
+-#define NR_FIX_BTMAPS 16
+-      FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+-      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
++      /*
++       * 256 temporary boot-time mappings, used by early_ioremap(),
++       * before ioremap() is functional.
++       *
++       * We round it up to the next 512 pages boundary so that we
++       * can have a single pgd entry and a single pte table:
++       */
++#define NR_FIX_BTMAPS         64
++#define FIX_BTMAPS_NESTING    4
++      FIX_BTMAP_END =
++              __end_of_permanent_fixed_addresses + 512 -
++                      (__end_of_permanent_fixed_addresses & 511),
++      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
+       FIX_WP_TEST,
++#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
++      FIX_OHCI1394_BASE,
++#endif
+       __end_of_fixed_addresses
+ };
  
--#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
--#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
--#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
--#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
--#define __HAVE_ARCH_PTEP_SET_WRPROTECT
- #define __HAVE_ARCH_PTE_SAME
--#include <asm-generic/pgtable.h>
- #endif /* !__ASSEMBLY__ */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/fixmap_64.h     2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/fixmap_64.h  2009-03-16 16:33:40.000000000 +0100
+@@ -15,6 +15,7 @@
+ #include <asm/apicdef.h>
+ #include <asm/page.h>
+ #include <asm/vsyscall.h>
++#include <asm/efi.h>
+ #include <asm/acpi.h>
  
- #endif /* _X86_64_PGTABLE_H */
---- a/include/asm-x86/mach-xen/asm/pgtable.h
-+++ b/include/asm-x86/mach-xen/asm/pgtable.h
-@@ -1,5 +1,454 @@
-+#ifndef _ASM_X86_PGTABLE_H
-+#define _ASM_X86_PGTABLE_H
-+
-+#define USER_PTRS_PER_PGD     ((TASK_SIZE-1)/PGDIR_SIZE+1)
-+#define FIRST_USER_ADDRESS    0
-+
-+#define _PAGE_BIT_PRESENT     0
-+#define _PAGE_BIT_RW          1
-+#define _PAGE_BIT_USER                2
-+#define _PAGE_BIT_PWT         3
-+#define _PAGE_BIT_PCD         4
-+#define _PAGE_BIT_ACCESSED    5
-+#define _PAGE_BIT_DIRTY               6
-+#define _PAGE_BIT_FILE                6
-+#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page */
-+#define _PAGE_BIT_PAT         7       /* on 4KB pages */
-+#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
-+#define _PAGE_BIT_IO          9       /* Mapped page is I/O or foreign and
-+                                       * has no associated page struct. */
-+#define _PAGE_BIT_UNUSED2     10      /* available for programmer */
-+#define _PAGE_BIT_UNUSED3     11
-+#define _PAGE_BIT_PAT_LARGE   12      /* On 2MB or 1GB pages */
-+#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
-+
-+/*
-+ * Note: we use _AC(1, L) instead of _AC(1, UL) so that we get a
-+ * sign-extended value on 32-bit with all 1's in the upper word,
-+ * which preserves the upper pte values on 64-bit ptes:
-+ */
-+#define _PAGE_PRESENT (_AC(1, L)<<_PAGE_BIT_PRESENT)
-+#define _PAGE_RW      (_AC(1, L)<<_PAGE_BIT_RW)
-+#define _PAGE_USER    (_AC(1, L)<<_PAGE_BIT_USER)
-+#define _PAGE_PWT     (_AC(1, L)<<_PAGE_BIT_PWT)
-+#define _PAGE_PCD     (_AC(1, L)<<_PAGE_BIT_PCD)
-+#define _PAGE_ACCESSED        (_AC(1, L)<<_PAGE_BIT_ACCESSED)
-+#define _PAGE_DIRTY   (_AC(1, L)<<_PAGE_BIT_DIRTY)
-+#define _PAGE_PSE     (_AC(1, L)<<_PAGE_BIT_PSE)      /* 2MB page */
-+#define _PAGE_GLOBAL  (_AC(1, L)<<_PAGE_BIT_GLOBAL)   /* Global TLB entry */
-+#define _PAGE_IO      (_AC(1, L)<<_PAGE_BIT_IO)
-+#define _PAGE_UNUSED2 (_AC(1, L)<<_PAGE_BIT_UNUSED2)
-+#define _PAGE_UNUSED3 (_AC(1, L)<<_PAGE_BIT_UNUSED3)
-+#define _PAGE_PAT     (_AC(1, L)<<_PAGE_BIT_PAT)
-+#define _PAGE_PAT_LARGE (_AC(1, L)<<_PAGE_BIT_PAT_LARGE)
-+
-+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
-+#define _PAGE_NX      (_AC(1, ULL) << _PAGE_BIT_NX)
-+#else
-+#define _PAGE_NX      0
-+#endif
-+
-+/* If _PAGE_PRESENT is clear, we use these: */
-+#define _PAGE_FILE    _PAGE_DIRTY     /* nonlinear file mapping, saved PTE; unset:swap */
-+#define _PAGE_PROTNONE        _PAGE_PSE       /* if the user mapped it with PROT_NONE;
-+                                         pte_present gives true */
-+
-+#ifndef __ASSEMBLY__
-+#if defined(CONFIG_X86_64) && CONFIG_XEN_COMPAT <= 0x030002
-+extern unsigned int __kernel_page_user;
-+#else
-+#define __kernel_page_user 0
+ /*
+@@ -46,6 +47,10 @@ enum fixed_addresses {
+       FIX_IO_APIC_BASE_0,
+       FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
+ #endif
++#ifdef CONFIG_EFI
++      FIX_EFI_IO_MAP_LAST_PAGE,
++      FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1,
 +#endif
+ #ifdef CONFIG_ACPI
+       FIX_ACPI_BEGIN,
+       FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
+@@ -55,10 +60,22 @@ enum fixed_addresses {
+       FIX_ISAMAP_END,
+       FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
+       __end_of_permanent_fixed_addresses,
+-      /* temporary boot-time mappings, used before ioremap() is functional */
+-#define NR_FIX_BTMAPS 16
+-      FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+-      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
++      /*
++       * 256 temporary boot-time mappings, used by early_ioremap(),
++       * before ioremap() is functional.
++       *
++       * We round it up to the next 512 pages boundary so that we
++       * can have a single pgd entry and a single pte table:
++       */
++#define NR_FIX_BTMAPS         64
++#define FIX_BTMAPS_NESTING    4
++      FIX_BTMAP_END =
++              __end_of_permanent_fixed_addresses + 512 -
++                      (__end_of_permanent_fixed_addresses & 511),
++      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
++#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
++      FIX_OHCI1394_BASE,
 +#endif
+       __end_of_fixed_addresses
+ };
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/highmem.h       2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/highmem.h    2009-03-16 16:33:40.000000000 +0100
+@@ -37,11 +37,6 @@ extern pte_t *pkmap_page_table;
+  * easily, subsequent pte tables have to be allocated in one physical
+  * chunk of RAM.
+  */
+-#ifdef CONFIG_X86_PAE
+-#define LAST_PKMAP 512
+-#else
+-#define LAST_PKMAP 1024
+-#endif
+ /*
+  * Ordering is:
+  *
+@@ -57,13 +52,12 @@ extern pte_t *pkmap_page_table;
+  * VMALLOC_START
+  * high_memory
+  */
+-#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK )
+ #define LAST_PKMAP_MASK (LAST_PKMAP-1)
+ #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+ #define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+-extern void * FASTCALL(kmap_high(struct page *page));
+-extern void FASTCALL(kunmap_high(struct page *page));
++extern void *kmap_high(struct page *page);
++extern void kunmap_high(struct page *page);
+ void *kmap(struct page *page);
+ void kunmap(struct page *page);
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/hypervisor.h    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/hypervisor.h 2009-03-16 16:33:40.000000000 +0100
+@@ -264,6 +264,25 @@ HYPERVISOR_poll(
+       return rc;
+ }
++static inline int __must_check
++HYPERVISOR_poll_no_timeout(
++      evtchn_port_t *ports, unsigned int nr_ports)
++{
++      int rc;
++      struct sched_poll sched_poll = {
++              .nr_ports = nr_ports
++      };
++      set_xen_guest_handle(sched_poll.ports, ports);
 +
-+#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
-+#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
-+
-+#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
-+
-+#define PAGE_NONE     __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-+#define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+
-+#define PAGE_SHARED_EXEC      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-+#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_COPY_EXEC                __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+#define PAGE_COPY             PAGE_COPY_NOEXEC
-+#define PAGE_READONLY         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_READONLY_EXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+
-+#ifdef CONFIG_X86_32
-+#define _PAGE_KERNEL_EXEC \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-+#define _PAGE_KERNEL (_PAGE_KERNEL_EXEC | _PAGE_NX)
-+
-+#ifndef __ASSEMBLY__
-+extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
-+#endif        /* __ASSEMBLY__ */
-+#else
-+#define __PAGE_KERNEL_EXEC                                            \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | __kernel_page_user)
-+#define __PAGE_KERNEL         (__PAGE_KERNEL_EXEC | _PAGE_NX)
++      rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
++#if CONFIG_XEN_COMPAT <= 0x030002
++      if (rc == -ENOSYS)
++              rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
 +#endif
 +
-+#define __PAGE_KERNEL_RO              (__PAGE_KERNEL & ~_PAGE_RW)
-+#define __PAGE_KERNEL_RX              (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
-+#define __PAGE_KERNEL_EXEC_NOCACHE    (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
-+#define __PAGE_KERNEL_NOCACHE         (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
-+#define __PAGE_KERNEL_UC_MINUS                (__PAGE_KERNEL | _PAGE_PCD)
-+#define __PAGE_KERNEL_VSYSCALL                (__PAGE_KERNEL_RX | _PAGE_USER)
-+#define __PAGE_KERNEL_VSYSCALL_NOCACHE        (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
-+#define __PAGE_KERNEL_LARGE           (__PAGE_KERNEL | _PAGE_PSE)
-+#define __PAGE_KERNEL_LARGE_EXEC      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
-+
-+/*
-+ * We don't support GLOBAL page in xenolinux64
-+ */
-+#define MAKE_GLOBAL(x)                        __pgprot((x))
-+
-+#define PAGE_KERNEL                   MAKE_GLOBAL(__PAGE_KERNEL)
-+#define PAGE_KERNEL_RO                        MAKE_GLOBAL(__PAGE_KERNEL_RO)
-+#define PAGE_KERNEL_EXEC              MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
-+#define PAGE_KERNEL_RX                        MAKE_GLOBAL(__PAGE_KERNEL_RX)
-+#define PAGE_KERNEL_NOCACHE           MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
-+#define PAGE_KERNEL_UC_MINUS          MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS)
-+#define PAGE_KERNEL_EXEC_NOCACHE      MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE)
-+#define PAGE_KERNEL_LARGE             MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
-+#define PAGE_KERNEL_LARGE_EXEC                MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC)
-+#define PAGE_KERNEL_VSYSCALL          MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
-+#define PAGE_KERNEL_VSYSCALL_NOCACHE  MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
++      return rc;
++}
 +
-+/*         xwr */
-+#define __P000        PAGE_NONE
-+#define __P001        PAGE_READONLY
-+#define __P010        PAGE_COPY
-+#define __P011        PAGE_COPY
-+#define __P100        PAGE_READONLY_EXEC
-+#define __P101        PAGE_READONLY_EXEC
-+#define __P110        PAGE_COPY_EXEC
-+#define __P111        PAGE_COPY_EXEC
+ #ifdef CONFIG_XEN
+ static inline void
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/irqflags.h      2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/irqflags.h   2009-03-16 16:33:40.000000000 +0100
+@@ -1,5 +1,247 @@
+-#ifdef CONFIG_X86_32
+-# include "irqflags_32.h"
++#ifndef _X86_IRQFLAGS_H_
++#define _X86_IRQFLAGS_H_
 +
-+#define __S000        PAGE_NONE
-+#define __S001        PAGE_READONLY
-+#define __S010        PAGE_SHARED
-+#define __S011        PAGE_SHARED
-+#define __S100        PAGE_READONLY_EXEC
-+#define __S101        PAGE_READONLY_EXEC
-+#define __S110        PAGE_SHARED_EXEC
-+#define __S111        PAGE_SHARED_EXEC
++#include <asm/processor-flags.h>
 +
 +#ifndef __ASSEMBLY__
-+
-+/*
-+ * ZERO_PAGE is a global shared page that is always zero: used
-+ * for zero-mapped memory areas etc..
-+ */
-+extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-+
-+extern spinlock_t pgd_lock;
-+extern struct list_head pgd_list;
-+
 +/*
-+ * The following only work if pte_present() is true.
-+ * Undefined behaviour if not..
++ * The use of 'barrier' in the following reflects their use as local-lock
++ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
++ * critical operations are executed. All critical operations must complete
++ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
++ * includes these barriers, for example.
 + */
-+static inline int pte_dirty(pte_t pte)                { return __pte_val(pte) & _PAGE_DIRTY; }
-+static inline int pte_young(pte_t pte)                { return __pte_val(pte) & _PAGE_ACCESSED; }
-+static inline int pte_write(pte_t pte)                { return __pte_val(pte) & _PAGE_RW; }
-+static inline int pte_file(pte_t pte)         { return __pte_val(pte) & _PAGE_FILE; }
-+static inline int pte_huge(pte_t pte)         { return __pte_val(pte) & _PAGE_PSE; }
-+static inline int pte_global(pte_t pte)       { return 0; }
-+static inline int pte_exec(pte_t pte)         { return !(__pte_val(pte) & _PAGE_NX); }
-+
-+static inline int pmd_large(pmd_t pte) {
-+      return (__pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) ==
-+              (_PAGE_PSE|_PAGE_PRESENT);
-+}
-+
-+static inline pte_t pte_mkclean(pte_t pte)    { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); }
-+static inline pte_t pte_mkold(pte_t pte)      { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); }
-+static inline pte_t pte_wrprotect(pte_t pte)  { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_RW); }
-+static inline pte_t pte_mkexec(pte_t pte)     { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_NX); }
-+static inline pte_t pte_mkdirty(pte_t pte)    { return __pte_ma(__pte_val(pte) | _PAGE_DIRTY); }
-+static inline pte_t pte_mkyoung(pte_t pte)    { return __pte_ma(__pte_val(pte) | _PAGE_ACCESSED); }
-+static inline pte_t pte_mkwrite(pte_t pte)    { return __pte_ma(__pte_val(pte) | _PAGE_RW); }
-+static inline pte_t pte_mkhuge(pte_t pte)     { return __pte_ma(__pte_val(pte) | _PAGE_PSE); }
-+static inline pte_t pte_clrhuge(pte_t pte)    { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_PSE); }
-+static inline pte_t pte_mkglobal(pte_t pte)   { return pte; }
-+static inline pte_t pte_clrglobal(pte_t pte)  { return pte; }
-+
-+extern pteval_t __supported_pte_mask;
-+
-+static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
-+                    pgprot_val(pgprot)) & __supported_pte_mask);
-+}
-+
-+static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      return __pte_ma((((phys_addr_t)page_nr << PAGE_SHIFT) |
-+                       pgprot_val(pgprot)) & __supported_pte_mask);
-+}
-+
-+static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) |
-+                    pgprot_val(pgprot)) & __supported_pte_mask);
-+}
-+
-+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-+{
-+      pteval_t val = pte_val(pte);
-+
-+      val &= _PAGE_CHG_MASK;
-+      val |= pgprot_val(newprot) & __supported_pte_mask;
-+
-+      return __pte(val);
-+}
-+
-+#define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX))
-+
-+#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
-+
-+#define set_pte(ptep, pte)            xen_set_pte(ptep, pte)
-+#define set_pte_at(mm, addr, ptep, pte)       xen_set_pte_at(mm, addr, ptep, pte)
 +
-+#define set_pte_atomic(ptep, pte)                                     \
-+      xen_set_pte_atomic(ptep, pte)
-+
-+#define set_pmd(pmdp, pmd)            xen_set_pmd(pmdp, pmd)
++#define xen_save_fl(void) (current_vcpu_info()->evtchn_upcall_mask)
 +
-+#ifndef __PAGETABLE_PUD_FOLDED
-+#define set_pgd(pgdp, pgd)            xen_set_pgd(pgdp, pgd)
-+#define pgd_clear(pgd)                        xen_pgd_clear(pgd)
-+#endif
++#define xen_restore_fl(f)                                     \
++do {                                                          \
++      vcpu_info_t *_vcpu;                                     \
++      barrier();                                              \
++      _vcpu = current_vcpu_info();                            \
++      if ((_vcpu->evtchn_upcall_mask = (f)) == 0) {           \
++              barrier(); /* unmask then check (avoid races) */\
++              if (unlikely(_vcpu->evtchn_upcall_pending))     \
++                      force_evtchn_callback();                \
++      }                                                       \
++} while (0)
 +
-+#ifndef set_pud
-+# define set_pud(pudp, pud)           xen_set_pud(pudp, pud)
-+#endif
++#define xen_irq_disable()                                     \
++do {                                                          \
++      current_vcpu_info()->evtchn_upcall_mask = 1;            \
++      barrier();                                              \
++} while (0)
 +
-+#ifndef __PAGETABLE_PMD_FOLDED
-+#define pud_clear(pud)                        xen_pud_clear(pud)
-+#endif
++#define xen_irq_enable()                                      \
++do {                                                          \
++      vcpu_info_t *_vcpu;                                     \
++      barrier();                                              \
++      _vcpu = current_vcpu_info();                            \
++      _vcpu->evtchn_upcall_mask = 0;                          \
++      barrier(); /* unmask then check (avoid races) */        \
++      if (unlikely(_vcpu->evtchn_upcall_pending))             \
++              force_evtchn_callback();                        \
++} while (0)
 +
-+#define pte_clear(mm, addr, ptep)     xen_pte_clear(mm, addr, ptep)
-+#define pmd_clear(pmd)                        xen_pmd_clear(pmd)
++void xen_safe_halt(void);
 +
-+#define pte_update(mm, addr, ptep)              do { } while (0)
-+#define pte_update_defer(mm, addr, ptep)        do { } while (0)
++void xen_halt(void);
 +
-+#endif        /* __ASSEMBLY__ */
++#define __raw_local_save_flags() xen_save_fl()
 +
- #ifdef CONFIG_X86_32
- # include "pgtable_32.h"
- #else
- # include "pgtable_64.h"
- #endif
++#define raw_local_irq_restore(flags) xen_restore_fl(flags)
 +
-+#ifndef __ASSEMBLY__
++#define raw_local_irq_disable()       xen_irq_disable()
 +
-+enum {
-+      PG_LEVEL_NONE,
-+      PG_LEVEL_4K,
-+      PG_LEVEL_2M,
-+      PG_LEVEL_1G,
-+};
++#define raw_local_irq_enable() xen_irq_enable()
 +
 +/*
-+ * Helper function that returns the kernel pagetable entry controlling
-+ * the virtual address 'address'. NULL means no pagetable entry present.
-+ * NOTE: the return type is pte_t but if the pmd is PSE then we return it
-+ * as a pte too.
++ * Used in the idle loop; sti takes one instruction cycle
++ * to complete:
 + */
-+extern pte_t *lookup_address(unsigned long address, unsigned int *level);
-+
-+/* local pte updates need not use xchg for locking */
-+static inline pte_t xen_local_ptep_get_and_clear(pte_t *ptep, pte_t res)
-+{
-+      xen_set_pte(ptep, __pte(0));
-+      return res;
-+}
-+
-+static inline void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
-+                                pte_t *ptep , pte_t pte)
-+{
-+      if ((mm != current->mm && mm != &init_mm) ||
-+          HYPERVISOR_update_va_mapping(addr, pte, 0))
-+              xen_set_pte(ptep, pte);
-+}
-+
-+static inline void xen_pte_clear(struct mm_struct *mm, unsigned long addr,
-+                               pte_t *ptep)
++static inline void raw_safe_halt(void)
 +{
-+      if ((mm != current->mm && mm != &init_mm)
-+          || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
-+              __xen_pte_clear(ptep);
++      xen_safe_halt();
 +}
 +
-+#ifndef CONFIG_PARAVIRT
 +/*
-+ * Rules for using pte_update - it must be called after any PTE update which
-+ * has not been done using the set_pte / clear_pte interfaces.  It is used by
-+ * shadow mode hypervisors to resynchronize the shadow page tables.  Kernel PTE
-+ * updates should either be sets, clears, or set_pte_atomic for P->P
-+ * transitions, which means this hook should only be called for user PTEs.
-+ * This hook implies a P->P protection or access change has taken place, which
-+ * requires a subsequent TLB flush.  The notification can optionally be delayed
-+ * until the TLB flush event by using the pte_update_defer form of the
-+ * interface, but care must be taken to assure that the flush happens while
-+ * still holding the same page table lock so that the shadow and primary pages
-+ * do not become out of sync on SMP.
-+ */
-+#define pte_update(mm, addr, ptep)            do { } while (0)
-+#define pte_update_defer(mm, addr, ptep)      do { } while (0)
-+#endif
++ * Used when interrupts are already enabled or to
++ * shutdown the processor:
++ */
++static inline void halt(void)
++{
++      xen_halt();
++}
 +
 +/*
-+ * We only update the dirty/accessed state if we set
-+ * the dirty bit by hand in the kernel, since the hardware
-+ * will do the accessed bit for us, and we don't want to
-+ * race with other CPU's that might be updating the dirty
-+ * bit at the same time.
++ * For spinlocks, etc:
 + */
-+#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-+#define ptep_set_access_flags(vma, address, ptep, entry, dirty)               \
++#define __raw_local_irq_save()                                                \
 +({                                                                    \
-+      int __changed = !pte_same(*(ptep), entry);                      \
-+      if (__changed && (dirty)) {                                     \
-+              if ( likely((vma)->vm_mm == current->mm) ) {            \
-+                      BUG_ON(HYPERVISOR_update_va_mapping(address,    \
-+                              entry,                                  \
-+                              (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
-+                                      UVMF_INVLPG|UVMF_MULTI));       \
-+              } else {                                                \
-+                      xen_l1_entry_update(ptep, entry);               \
-+                      flush_tlb_page(vma, address);                   \
-+              }                                                       \
-+      }                                                               \
-+      __changed;                                                      \
++      unsigned long flags = __raw_local_save_flags();                 \
++                                                                      \
++      raw_local_irq_disable();                                        \
++                                                                      \
++      flags;                                                          \
 +})
+ #else
+-# include "irqflags_64.h"
 +
-+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-+#define ptep_test_and_clear_young(vma, addr, ptep) ({                 \
-+      int __ret = 0;                                                  \
-+      if (pte_young(*(ptep)))                                         \
-+              __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,          \
-+                                         &(ptep)->pte);               \
-+      if (__ret)                                                      \
-+              pte_update((vma)->vm_mm, addr, ptep);                   \
-+      __ret;                                                          \
-+})
++/* Offsets into shared_info_t. */
++#define evtchn_upcall_pending         /* 0 */
++#define evtchn_upcall_mask            1
 +
-+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-+#define ptep_clear_flush_young(vma, address, ptep)                    \
-+({                                                                    \
-+      pte_t __pte = *(ptep);                                          \
-+      int __young = pte_young(__pte);                                 \
-+      __pte = pte_mkold(__pte);                                       \
-+      if (PagePinned(virt_to_page((vma)->vm_mm->pgd)))                \
-+              (void)ptep_set_access_flags(vma, address, ptep, __pte, __young); \
-+      else if (__young)                                               \
-+              (ptep)->pte_low = __pte.pte_low;                        \
-+      __young;                                                        \
-+})
++#define sizeof_vcpu_shift             6
 +
-+#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
-+#define ptep_clear_flush(vma, addr, ptep)                     \
-+({                                                            \
-+      pte_t *__ptep = (ptep);                                 \
-+      pte_t __res = *__ptep;                                  \
-+      if (!pte_none(__res) &&                                 \
-+          ((vma)->vm_mm != current->mm ||                     \
-+           HYPERVISOR_update_va_mapping(addr, __pte(0),       \
-+                      (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
-+                              UVMF_INVLPG|UVMF_MULTI))) {     \
-+              __xen_pte_clear(__ptep);                        \
-+              flush_tlb_page(vma, addr);                      \
-+      }                                                       \
-+      __res;                                                  \
-+})
++#ifdef CONFIG_X86_64
++# define __REG_si %rsi
++# define __CPU_num %gs:pda_cpunumber
++#else
++# define __REG_si %esi
++# define __CPU_num TI_cpu(%ebp)
++#endif
 +
-+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-+{
-+      pte_t pte = *ptep;
-+      if (!pte_none(pte)
-+          && (mm != &init_mm
-+              || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))) {
-+              pte = xen_ptep_get_and_clear(ptep, pte);
-+              pte_update(mm, addr, ptep);
-+      }
-+      return pte;
-+}
++#ifdef CONFIG_SMP
++#define GET_VCPU_INFO         movl __CPU_num,%esi                     ; \
++                              shl $sizeof_vcpu_shift,%esi             ; \
++                              add HYPERVISOR_shared_info,__REG_si
++#else
++#define GET_VCPU_INFO         mov HYPERVISOR_shared_info,__REG_si
++#endif
 +
-+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
-+#define ptep_get_and_clear_full(mm, addr, ptep, full)         \
-+      ((full) ? ({                                            \
-+              pte_t *__ptep = (ptep);                         \
-+              pte_t __res = *__ptep;                          \
-+              if (!PagePinned(virt_to_page((mm)->pgd)))       \
-+                      __xen_pte_clear(__ptep);                \
-+              else if (!pte_none(__res))                      \
-+                      xen_l1_entry_update(__ptep, __pte(0));  \
-+              __res;                                          \
-+       }) :                                                   \
-+       ptep_get_and_clear(mm, addr, ptep))
++#define __DISABLE_INTERRUPTS  movb $1,evtchn_upcall_mask(__REG_si)
++#define __ENABLE_INTERRUPTS   movb $0,evtchn_upcall_mask(__REG_si)
++#define __TEST_PENDING                testb $0xFF,evtchn_upcall_pending(__REG_si)
++#define DISABLE_INTERRUPTS(clb)       GET_VCPU_INFO                           ; \
++                              __DISABLE_INTERRUPTS
++#define ENABLE_INTERRUPTS(clb)        GET_VCPU_INFO                           ; \
++                              __ENABLE_INTERRUPTS
 +
-+pte_t xen_ptep_get_and_clear_full(struct vm_area_struct *, unsigned long, pte_t *, int);
++#ifndef CONFIG_X86_64
++#define INTERRUPT_RETURN              iret
++#define ENABLE_INTERRUPTS_SYSCALL_RET __ENABLE_INTERRUPTS             ; \
++sysexit_scrit:        /**** START OF SYSEXIT CRITICAL REGION ****/            ; \
++      __TEST_PENDING                                                  ; \
++      jnz  14f        /* process more events if necessary... */       ; \
++      movl PT_ESI(%esp), %esi                                         ; \
++      sysexit                                                         ; \
++14:   __DISABLE_INTERRUPTS                                            ; \
++      TRACE_IRQS_OFF                                                  ; \
++sysexit_ecrit:        /**** END OF SYSEXIT CRITICAL REGION ****/              ; \
++      push %esp                                                       ; \
++      call evtchn_do_upcall                                           ; \
++      add  $4,%esp                                                    ; \
++      jmp  ret_from_intr
++#endif
 +
-+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
++
++#endif /* __ASSEMBLY__ */
++
++#ifndef __ASSEMBLY__
++#define raw_local_save_flags(flags) \
++              do { (flags) = __raw_local_save_flags(); } while (0)
++
++#define raw_local_irq_save(flags) \
++              do { (flags) = __raw_local_irq_save(); } while (0)
++
++static inline int raw_irqs_disabled_flags(unsigned long flags)
 +{
-+      pte_t pte = *ptep;
-+      if (pte_write(pte))
-+              set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
++      return (flags != 0);
 +}
 +
-+#define arch_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable) \
-+      xen_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable)
-+
-+#define arbitrary_virt_to_machine(va)                                 \
++#define raw_irqs_disabled()                                           \
 +({                                                                    \
-+      unsigned int __lvl;                                             \
-+      pte_t *__ptep = lookup_address((unsigned long)(va), &__lvl);    \
-+      BUG_ON(!__ptep || __lvl != PG_LEVEL_4K || !pte_present(*__ptep));\
-+      (((maddr_t)pte_mfn(*__ptep) << PAGE_SHIFT)                      \
-+       | ((unsigned long)(va) & (PAGE_SIZE - 1)));                    \
++      unsigned long flags = __raw_local_save_flags();                 \
++                                                                      \
++      raw_irqs_disabled_flags(flags);                                 \
 +})
 +
-+#include <asm-generic/pgtable.h>
++/*
++ * makes the traced hardirq state match with the machine state
++ *
++ * should be a rarely used function, only in places where its
++ * otherwise impossible to know the irq state, like in traps.
++ */
++static inline void trace_hardirqs_fixup_flags(unsigned long flags)
++{
++      if (raw_irqs_disabled_flags(flags))
++              trace_hardirqs_off();
++      else
++              trace_hardirqs_on();
++}
 +
-+#include <xen/features.h>
-+void make_page_readonly(void *va, unsigned int feature);
-+void make_page_writable(void *va, unsigned int feature);
-+void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
-+void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
++#define trace_hardirqs_fixup() \
++      trace_hardirqs_fixup_flags(__raw_local_save_flags())
 +
-+struct vm_area_struct;
++#else
 +
-+int direct_remap_pfn_range(struct vm_area_struct *vma,
-+                           unsigned long address,
-+                           unsigned long mfn,
-+                           unsigned long size,
-+                           pgprot_t prot,
-+                           domid_t  domid);
-+int direct_kernel_remap_pfn_range(unsigned long address,
-+                                unsigned long mfn,
-+                                unsigned long size,
-+                                pgprot_t prot,
-+                                domid_t  domid);
-+int create_lookup_pte_addr(struct mm_struct *mm,
-+                           unsigned long address,
-+                           uint64_t *ptep);
-+int touch_pte_range(struct mm_struct *mm,
-+                    unsigned long address,
-+                    unsigned long size);
++#ifdef CONFIG_X86_64
++/*
++ * Currently paravirt can't handle swapgs nicely when we
++ * don't have a stack we can rely on (such as a user space
++ * stack).  So we either find a way around these or just fault
++ * and emulate if a guest tries to call swapgs directly.
++ *
++ * Either way, this is a good way to document that we don't
++ * have a reliable stack. x86_64 only.
++ */
++#define SWAPGS_UNSAFE_STACK   swapgs
++#define ARCH_TRACE_IRQS_ON            call trace_hardirqs_on_thunk
++#define ARCH_TRACE_IRQS_OFF           call trace_hardirqs_off_thunk
++#define ARCH_LOCKDEP_SYS_EXIT         call lockdep_sys_exit_thunk
++#define ARCH_LOCKDEP_SYS_EXIT_IRQ     \
++      TRACE_IRQS_ON; \
++      ENABLE_INTERRUPTS(CLBR_NONE); \
++      SAVE_REST; \
++      LOCKDEP_SYS_EXIT; \
++      RESTORE_REST; \
++      __DISABLE_INTERRUPTS; \
++      TRACE_IRQS_OFF;
++
++#else
++#define ARCH_TRACE_IRQS_ON                    \
++      pushl %eax;                             \
++      pushl %ecx;                             \
++      pushl %edx;                             \
++      call trace_hardirqs_on;                 \
++      popl %edx;                              \
++      popl %ecx;                              \
++      popl %eax;
++
++#define ARCH_TRACE_IRQS_OFF                   \
++      pushl %eax;                             \
++      pushl %ecx;                             \
++      pushl %edx;                             \
++      call trace_hardirqs_off;                \
++      popl %edx;                              \
++      popl %ecx;                              \
++      popl %eax;
++
++#define ARCH_LOCKDEP_SYS_EXIT                 \
++      pushl %eax;                             \
++      pushl %ecx;                             \
++      pushl %edx;                             \
++      call lockdep_sys_exit;                  \
++      popl %edx;                              \
++      popl %ecx;                              \
++      popl %eax;
 +
-+int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
-+              unsigned long addr, unsigned long end, pgprot_t newprot,
-+              int dirty_accountable);
++#define ARCH_LOCKDEP_SYS_EXIT_IRQ
++#endif
 +
-+#endif        /* __ASSEMBLY__ */
++#ifdef CONFIG_TRACE_IRQFLAGS
++#  define TRACE_IRQS_ON               ARCH_TRACE_IRQS_ON
++#  define TRACE_IRQS_OFF      ARCH_TRACE_IRQS_OFF
++#else
++#  define TRACE_IRQS_ON
++#  define TRACE_IRQS_OFF
++#endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++#  define LOCKDEP_SYS_EXIT    ARCH_LOCKDEP_SYS_EXIT
++#  define LOCKDEP_SYS_EXIT_IRQ        ARCH_LOCKDEP_SYS_EXIT_IRQ
++# else
++#  define LOCKDEP_SYS_EXIT
++#  define LOCKDEP_SYS_EXIT_IRQ
++# endif
 +
-+#endif        /* _ASM_X86_PGTABLE_H */
---- a/include/asm-x86/mach-xen/asm/processor_32.h
-+++ /dev/null
-@@ -1,751 +0,0 @@
++#endif /* __ASSEMBLY__ */
+ #endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/irqflags_32.h   2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,212 +0,0 @@
 -/*
-- * include/asm-i386/processor.h
+- * include/asm-i386/irqflags.h
 - *
-- * Copyright (C) 1994 Linus Torvalds
+- * IRQ flags handling
+- *
+- * This file gets included from lowlevel asm headers too, to provide
+- * wrapped versions of the local_irq_*() APIs, based on the
+- * raw_local_irq_*() functions from the lowlevel headers.
 - */
+-#ifndef _ASM_IRQFLAGS_H
+-#define _ASM_IRQFLAGS_H
 -
--#ifndef __ASM_I386_PROCESSOR_H
--#define __ASM_I386_PROCESSOR_H
+-#ifndef __ASSEMBLY__
+-#define xen_save_fl(void) (current_vcpu_info()->evtchn_upcall_mask)
 -
--#include <asm/vm86.h>
--#include <asm/math_emu.h>
--#include <asm/segment.h>
--#include <asm/page.h>
--#include <asm/types.h>
--#include <asm/sigcontext.h>
--#include <asm/cpufeature.h>
--#include <asm/msr.h>
--#include <asm/system.h>
--#include <linux/cache.h>
--#include <linux/threads.h>
--#include <asm/percpu.h>
--#include <linux/cpumask.h>
--#include <linux/init.h>
--#include <asm/processor-flags.h>
--#include <xen/interface/physdev.h>
+-#define xen_restore_fl(f)                                     \
+-do {                                                          \
+-      vcpu_info_t *_vcpu;                                     \
+-      barrier();                                              \
+-      _vcpu = current_vcpu_info();                            \
+-      if ((_vcpu->evtchn_upcall_mask = (f)) == 0) {           \
+-              barrier(); /* unmask then check (avoid races) */\
+-              if (unlikely(_vcpu->evtchn_upcall_pending))     \
+-                      force_evtchn_callback();                \
+-      }                                                       \
+-} while (0)
 -
--/* flag for disabling the tsc */
--#define tsc_disable 0
+-#define xen_irq_disable()                                     \
+-do {                                                          \
+-      current_vcpu_info()->evtchn_upcall_mask = 1;            \
+-      barrier();                                              \
+-} while (0)
 -
--struct desc_struct {
--      unsigned long a,b;
--};
+-#define xen_irq_enable()                                      \
+-do {                                                          \
+-      vcpu_info_t *_vcpu;                                     \
+-      barrier();                                              \
+-      _vcpu = current_vcpu_info();                            \
+-      _vcpu->evtchn_upcall_mask = 0;                          \
+-      barrier(); /* unmask then check (avoid races) */        \
+-      if (unlikely(_vcpu->evtchn_upcall_pending))             \
+-              force_evtchn_callback();                        \
+-} while (0)
 -
--#define desc_empty(desc) \
--              (!((desc)->a | (desc)->b))
+-void xen_safe_halt(void);
+-
+-void xen_halt(void);
+-
+-/* 
+- * The use of 'barrier' in the following reflects their use as local-lock
+- * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
+- * critical operations are executed. All critical operations must complete
+- * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
+- * includes these barriers, for example.
+- */
+-
+-#define __raw_local_save_flags() xen_save_fl()
+-
+-#define raw_local_irq_restore(flags) xen_restore_fl(flags)
+-
+-#define raw_local_irq_disable()       xen_irq_disable()
+-
+-#define raw_local_irq_enable() xen_irq_enable()
 -
--#define desc_equal(desc1, desc2) \
--              (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
 -/*
-- * Default implementation of macro that returns current
-- * instruction pointer ("program counter").
+- * Used in the idle loop; sti takes one instruction cycle
+- * to complete:
 - */
--#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
+-static inline void raw_safe_halt(void)
+-{
+-      xen_safe_halt();
+-}
 -
 -/*
-- *  CPU type and hardware bug flags. Kept separately for each CPU.
-- *  Members of this structure are referenced in head.S, so think twice
-- *  before touching them. [mj]
+- * Used when interrupts are already enabled or to
+- * shutdown the processor:
+- */
+-static inline void halt(void)
+-{
+-      xen_halt();
+-}
+-
+-/*
+- * For spinlocks, etc:
 - */
+-#define __raw_local_irq_save()                                                \
+-({                                                                    \
+-      unsigned long flags = __raw_local_save_flags();                 \
+-                                                                      \
+-      raw_local_irq_disable();                                        \
+-                                                                      \
+-      flags;                                                          \
+-})
+-
+-#else
+-/* Offsets into shared_info_t. */
+-#define evtchn_upcall_pending         /* 0 */
+-#define evtchn_upcall_mask            1
+-
+-#define sizeof_vcpu_shift             6
 -
--struct cpuinfo_x86 {
--      __u8    x86;            /* CPU family */
--      __u8    x86_vendor;     /* CPU vendor */
--      __u8    x86_model;
--      __u8    x86_mask;
--      char    wp_works_ok;    /* It doesn't on 386's */
--      char    hlt_works_ok;   /* Problems on some 486Dx4's and old 386's */
--      char    hard_math;
--      char    rfu;
--              int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
--      unsigned long   x86_capability[NCAPINTS];
--      char    x86_vendor_id[16];
--      char    x86_model_id[64];
--      int     x86_cache_size;  /* in KB - valid for CPUS which support this
--                                  call  */
--      int     x86_cache_alignment;    /* In bytes */
--      char    fdiv_bug;
--      char    f00f_bug;
--      char    coma_bug;
--      char    pad0;
--      int     x86_power;
--      unsigned long loops_per_jiffy;
--#ifdef CONFIG_SMP
--      cpumask_t llc_shared_map;       /* cpus sharing the last level cache */
--#endif
--      unsigned char x86_max_cores;    /* cpuid returned max cores value */
--      unsigned char apicid;
--      unsigned short x86_clflush_size;
 -#ifdef CONFIG_SMP
--      unsigned char booted_cores;     /* number of cores as seen by OS */
--      __u8 phys_proc_id;              /* Physical processor id. */
--      __u8 cpu_core_id;               /* Core id */
--      __u8 cpu_index;                 /* index into per_cpu list */
+-#define GET_VCPU_INFO         movl TI_cpu(%ebp),%esi                  ; \
+-                              shl  $sizeof_vcpu_shift,%esi            ; \
+-                              addl HYPERVISOR_shared_info,%esi
+-#else
+-#define GET_VCPU_INFO         movl HYPERVISOR_shared_info,%esi
 -#endif
--} __attribute__((__aligned__(SMP_CACHE_BYTES)));
 -
--#define X86_VENDOR_INTEL 0
--#define X86_VENDOR_CYRIX 1
--#define X86_VENDOR_AMD 2
--#define X86_VENDOR_UMC 3
--#define X86_VENDOR_NEXGEN 4
--#define X86_VENDOR_CENTAUR 5
--#define X86_VENDOR_TRANSMETA 7
--#define X86_VENDOR_NSC 8
--#define X86_VENDOR_NUM 9
--#define X86_VENDOR_UNKNOWN 0xff
+-#define __DISABLE_INTERRUPTS  movb $1,evtchn_upcall_mask(%esi)
+-#define __ENABLE_INTERRUPTS   movb $0,evtchn_upcall_mask(%esi)
+-#define __TEST_PENDING                testb $0xFF,evtchn_upcall_pending(%esi)
+-#define DISABLE_INTERRUPTS(clb)       GET_VCPU_INFO                           ; \
+-                              __DISABLE_INTERRUPTS
+-#define ENABLE_INTERRUPTS(clb)        GET_VCPU_INFO                           ; \
+-                              __ENABLE_INTERRUPTS
+-#define ENABLE_INTERRUPTS_SYSEXIT __ENABLE_INTERRUPTS                 ; \
+-sysexit_scrit:        /**** START OF SYSEXIT CRITICAL REGION ****/            ; \
+-      __TEST_PENDING                                                  ; \
+-      jnz  14f        /* process more events if necessary... */       ; \
+-      movl PT_ESI(%esp), %esi                                         ; \
+-      sysexit                                                         ; \
+-14:   __DISABLE_INTERRUPTS                                            ; \
+-      TRACE_IRQS_OFF                                                  ; \
+-sysexit_ecrit:        /**** END OF SYSEXIT CRITICAL REGION ****/              ; \
+-      push %esp                                                       ; \
+-      call evtchn_do_upcall                                           ; \
+-      add  $4,%esp                                                    ; \
+-      jmp  ret_from_intr
+-#define INTERRUPT_RETURN      iret
+-#endif /* __ASSEMBLY__ */
+-
+-#ifndef __ASSEMBLY__
+-#define raw_local_save_flags(flags) \
+-              do { (flags) = __raw_local_save_flags(); } while (0)
+-
+-#define raw_local_irq_save(flags) \
+-              do { (flags) = __raw_local_irq_save(); } while (0)
+-
+-static inline int raw_irqs_disabled_flags(unsigned long flags)
+-{
+-      return (flags != 0);
+-}
+-
+-#define raw_irqs_disabled()                                           \
+-({                                                                    \
+-      unsigned long flags = __raw_local_save_flags();                 \
+-                                                                      \
+-      raw_irqs_disabled_flags(flags);                                 \
+-})
 -
 -/*
-- * capabilities of CPUs
+- * makes the traced hardirq state match with the machine state
+- *
+- * should be a rarely used function, only in places where its
+- * otherwise impossible to know the irq state, like in traps.
+- */
+-static inline void trace_hardirqs_fixup_flags(unsigned long flags)
+-{
+-      if (raw_irqs_disabled_flags(flags))
+-              trace_hardirqs_off();
+-      else
+-              trace_hardirqs_on();
+-}
+-
+-#define trace_hardirqs_fixup() \
+-      trace_hardirqs_fixup_flags(__raw_local_save_flags())
+-#endif /* __ASSEMBLY__ */
+-
+-/*
+- * Do the CPU's IRQ-state tracing from assembly code. We call a
+- * C function, so save all the C-clobbered registers:
 - */
+-#ifdef CONFIG_TRACE_IRQFLAGS
 -
--extern struct cpuinfo_x86 boot_cpu_data;
--extern struct cpuinfo_x86 new_cpu_data;
--#ifndef CONFIG_X86_NO_TSS
--extern struct tss_struct doublefault_tss;
--DECLARE_PER_CPU(struct tss_struct, init_tss);
+-# define TRACE_IRQS_ON                                \
+-      pushl %eax;                             \
+-      pushl %ecx;                             \
+-      pushl %edx;                             \
+-      call trace_hardirqs_on;                 \
+-      popl %edx;                              \
+-      popl %ecx;                              \
+-      popl %eax;
+-
+-# define TRACE_IRQS_OFF                               \
+-      pushl %eax;                             \
+-      pushl %ecx;                             \
+-      pushl %edx;                             \
+-      call trace_hardirqs_off;                \
+-      popl %edx;                              \
+-      popl %ecx;                              \
+-      popl %eax;
+-
+-#else
+-# define TRACE_IRQS_ON
+-# define TRACE_IRQS_OFF
 -#endif
 -
--#ifdef CONFIG_SMP
--DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
--#define cpu_data(cpu)         per_cpu(cpu_info, cpu)
--#define current_cpu_data      cpu_data(smp_processor_id())
+-#ifdef CONFIG_DEBUG_LOCK_ALLOC
+-# define LOCKDEP_SYS_EXIT                     \
+-      pushl %eax;                             \
+-      pushl %ecx;                             \
+-      pushl %edx;                             \
+-      call lockdep_sys_exit;                  \
+-      popl %edx;                              \
+-      popl %ecx;                              \
+-      popl %eax;
 -#else
--#define cpu_data(cpu)         boot_cpu_data
--#define current_cpu_data      boot_cpu_data
+-# define LOCKDEP_SYS_EXIT
 -#endif
 -
+-#endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/irqflags_64.h   2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,178 +0,0 @@
 -/*
-- * the following now lives in the per cpu area:
-- * extern     int cpu_llc_id[NR_CPUS];
+- * include/asm-x86_64/irqflags.h
+- *
+- * IRQ flags handling
+- *
+- * This file gets included from lowlevel asm headers too, to provide
+- * wrapped versions of the local_irq_*() APIs, based on the
+- * raw_local_irq_*() functions from the lowlevel headers.
 - */
--DECLARE_PER_CPU(u8, cpu_llc_id);
--extern char ignore_fpu_irq;
+-#ifndef _ASM_IRQFLAGS_H
+-#define _ASM_IRQFLAGS_H
+-#include <asm/processor-flags.h>
 -
--void __init cpu_detect(struct cpuinfo_x86 *c);
+-#ifndef __ASSEMBLY__
+-/*
+- * Interrupt control:
+- */
 -
--extern void identify_boot_cpu(void);
--extern void identify_secondary_cpu(struct cpuinfo_x86 *);
--extern void print_cpu_info(struct cpuinfo_x86 *);
--extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
--extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
--extern unsigned short num_cache_leaves;
+-/*
+- * The use of 'barrier' in the following reflects their use as local-lock
+- * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
+- * critical operations are executed. All critical operations must complete
+- * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
+- * includes these barriers, for example.
+- */
 -
--#ifdef CONFIG_X86_HT
--extern void detect_ht(struct cpuinfo_x86 *c);
--#else
--static inline void detect_ht(struct cpuinfo_x86 *c) {}
--#endif
+-#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
 -
--static inline void xen_cpuid(unsigned int *eax, unsigned int *ebx,
--                           unsigned int *ecx, unsigned int *edx)
--{
--      /* ecx is often an input as well as an output. */
--      __asm__(XEN_CPUID
--              : "=a" (*eax),
--                "=b" (*ebx),
--                "=c" (*ecx),
--                "=d" (*edx)
--              : "0" (*eax), "2" (*ecx));
--}
+-#define raw_local_save_flags(flags) \
+-              do { (flags) = __raw_local_save_flags(); } while (0)
 -
--#define load_cr3(pgdir) write_cr3(__pa(pgdir))
+-#define raw_local_irq_restore(x)                                      \
+-do {                                                                  \
+-      vcpu_info_t *_vcpu;                                             \
+-      barrier();                                                      \
+-      _vcpu = current_vcpu_info();            \
+-      if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
+-              barrier(); /* unmask then check (avoid races) */        \
+-              if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
+-                      force_evtchn_callback();                        \
+-      }                                                               \
+-} while (0)
+-
+-#ifdef CONFIG_X86_VSMP
 -
 -/*
-- * Save the cr4 feature set we're using (ie
-- * Pentium 4MB enable and PPro Global page
-- * enable), so that any CPU's that boot up
-- * after us can get the correct flags.
+- * Interrupt control for the VSMP architecture:
 - */
--extern unsigned long mmu_cr4_features;
 -
--static inline void set_in_cr4 (unsigned long mask)
+-static inline void raw_local_irq_disable(void)
 -{
--      unsigned cr4;
--      mmu_cr4_features |= mask;
--      cr4 = read_cr4();
--      cr4 |= mask;
--      write_cr4(cr4);
--}
+-      unsigned long flags = __raw_local_save_flags();
 -
--static inline void clear_in_cr4 (unsigned long mask)
--{
--      unsigned cr4;
--      mmu_cr4_features &= ~mask;
--      cr4 = read_cr4();
--      cr4 &= ~mask;
--      write_cr4(cr4);
+-      raw_local_irq_restore((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
 -}
 -
--/* Stop speculative execution */
--static inline void sync_core(void)
+-static inline void raw_local_irq_enable(void)
 -{
--      int tmp;
--      asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
--}
+-      unsigned long flags = __raw_local_save_flags();
 -
--static inline void __monitor(const void *eax, unsigned long ecx,
--              unsigned long edx)
--{
--      /* "monitor %eax,%ecx,%edx;" */
--      asm volatile(
--              ".byte 0x0f,0x01,0xc8;"
--              : :"a" (eax), "c" (ecx), "d"(edx));
+-      raw_local_irq_restore((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
 -}
 -
--static inline void __mwait(unsigned long eax, unsigned long ecx)
+-static inline int raw_irqs_disabled_flags(unsigned long flags)
 -{
--      /* "mwait %eax,%ecx;" */
--      asm volatile(
--              ".byte 0x0f,0x01,0xc9;"
--              : :"a" (eax), "c" (ecx));
+-      return !(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC);
 -}
 -
--extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
+-#else /* CONFIG_X86_VSMP */
 -
--/* from system description table in BIOS.  Mostly for MCA use, but
--others may find it useful. */
--extern unsigned int machine_id;
--extern unsigned int machine_submodel_id;
--extern unsigned int BIOS_revision;
--extern unsigned int mca_pentium_flag;
+-#define raw_local_irq_disable()                                               \
+-do {                                                                  \
+-      current_vcpu_info()->evtchn_upcall_mask = 1;                                    \
+-      barrier();                                                      \
+-} while (0)
 -
--/* Boot loader type from the setup header */
--extern int bootloader_type;
+-#define raw_local_irq_enable()                                                \
+-do {                                                                  \
+-      vcpu_info_t *_vcpu;                                             \
+-      barrier();                                                      \
+-      _vcpu = current_vcpu_info();            \
+-      _vcpu->evtchn_upcall_mask = 0;                                  \
+-      barrier(); /* unmask then check (avoid races) */                \
+-      if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
+-              force_evtchn_callback();                                \
+-} while (0)
+-
+-static inline int raw_irqs_disabled_flags(unsigned long flags)
+-{
+-      return (flags != 0);
+-}
+-
+-#endif
 -
 -/*
-- * User space process size: 3GB (default).
+- * For spinlocks, etc.:
 - */
--#define TASK_SIZE     (PAGE_OFFSET)
 -
--/* This decides where the kernel will search for a free chunk of vm
-- * space during mmap's.
-- */
--#define TASK_UNMAPPED_BASE    (PAGE_ALIGN(TASK_SIZE / 3))
+-#define __raw_local_irq_save()                                                \
+-({                                                                    \
+-      unsigned long flags = __raw_local_save_flags();                 \
+-                                                                      \
+-      raw_local_irq_disable();                                        \
+-                                                                      \
+-      flags;                                                          \
+-})
 -
--#define HAVE_ARCH_PICK_MMAP_LAYOUT
+-#define raw_local_irq_save(flags) \
+-              do { (flags) = __raw_local_irq_save(); } while (0)
 -
--extern void hard_disable_TSC(void);
--extern void disable_TSC(void);
--extern void hard_enable_TSC(void);
+-#define raw_irqs_disabled()                                           \
+-({                                                                    \
+-      unsigned long flags = __raw_local_save_flags();                 \
+-                                                                      \
+-      raw_irqs_disabled_flags(flags);                                 \
+-})
 -
 -/*
-- * Size of io_bitmap.
+- * makes the traced hardirq state match with the machine state
+- *
+- * should be a rarely used function, only in places where its
+- * otherwise impossible to know the irq state, like in traps.
 - */
--#define IO_BITMAP_BITS  65536
--#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
--#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
--#ifndef CONFIG_X86_NO_TSS
--#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
--#endif
--#define INVALID_IO_BITMAP_OFFSET 0x8000
--#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
--
--struct i387_fsave_struct {
--      long    cwd;
--      long    swd;
--      long    twd;
--      long    fip;
--      long    fcs;
--      long    foo;
--      long    fos;
--      long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
--      long    status;         /* software status information */
--};
--
--struct i387_fxsave_struct {
--      unsigned short  cwd;
--      unsigned short  swd;
--      unsigned short  twd;
--      unsigned short  fop;
--      long    fip;
--      long    fcs;
--      long    foo;
--      long    fos;
--      long    mxcsr;
--      long    mxcsr_mask;
--      long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
--      long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
--      long    padding[56];
--} __attribute__ ((aligned (16)));
+-static inline void trace_hardirqs_fixup_flags(unsigned long flags)
+-{
+-      if (raw_irqs_disabled_flags(flags))
+-              trace_hardirqs_off();
+-      else
+-              trace_hardirqs_on();
+-}
 -
--struct i387_soft_struct {
--      long    cwd;
--      long    swd;
--      long    twd;
--      long    fip;
--      long    fcs;
--      long    foo;
--      long    fos;
--      long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
--      unsigned char   ftop, changed, lookahead, no_update, rm, alimit;
--      struct info     *info;
--      unsigned long   entry_eip;
--};
+-#define trace_hardirqs_fixup() \
+-      trace_hardirqs_fixup_flags(__raw_local_save_flags())
+-/*
+- * Used in the idle loop; sti takes one instruction cycle
+- * to complete:
+- */
+-void xen_safe_halt(void);
+-static inline void raw_safe_halt(void)
+-{
+-      xen_safe_halt();
+-}
 -
--union i387_union {
--      struct i387_fsave_struct        fsave;
--      struct i387_fxsave_struct       fxsave;
--      struct i387_soft_struct soft;
--};
+-/*
+- * Used when interrupts are already enabled or to
+- * shutdown the processor:
+- */
+-void xen_halt(void);
+-static inline void halt(void)
+-{
+-      xen_halt();
+-}
 -
--typedef struct {
--      unsigned long seg;
--} mm_segment_t;
+-#else /* __ASSEMBLY__: */
+-# ifdef CONFIG_TRACE_IRQFLAGS
+-#  define TRACE_IRQS_ON               call trace_hardirqs_on_thunk
+-#  define TRACE_IRQS_OFF      call trace_hardirqs_off_thunk
+-# else
+-#  define TRACE_IRQS_ON
+-#  define TRACE_IRQS_OFF
+-# endif
+-# ifdef CONFIG_DEBUG_LOCK_ALLOC
+-#  define LOCKDEP_SYS_EXIT    call lockdep_sys_exit_thunk
+-#  define LOCKDEP_SYS_EXIT_IRQ        \
+-      TRACE_IRQS_ON; \
+-      sti; \
+-      SAVE_REST; \
+-      LOCKDEP_SYS_EXIT; \
+-      RESTORE_REST; \
+-      cli; \
+-      TRACE_IRQS_OFF;
+-# else
+-#  define LOCKDEP_SYS_EXIT
+-#  define LOCKDEP_SYS_EXIT_IRQ
+-# endif
+-#endif
 -
--struct thread_struct;
+-#endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/maddr_32.h      2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/maddr_32.h   2009-03-16 16:33:40.000000000 +0100
+@@ -1,6 +1,7 @@
+ #ifndef _I386_MADDR_H
+ #define _I386_MADDR_H
++#include <asm/bug.h>
+ #include <xen/features.h>
+ #include <xen/interface/xen.h>
+@@ -151,25 +152,9 @@ static inline paddr_t pte_machine_to_phy
+       phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
+       return phys;
+ }
+-#endif
 -
--#ifndef CONFIG_X86_NO_TSS
--/* This is the TSS defined by the hardware. */
--struct i386_hw_tss {
--      unsigned short  back_link,__blh;
--      unsigned long   esp0;
--      unsigned short  ss0,__ss0h;
--      unsigned long   esp1;
--      unsigned short  ss1,__ss1h;     /* ss1 is used to cache MSR_IA32_SYSENTER_CS */
--      unsigned long   esp2;
--      unsigned short  ss2,__ss2h;
--      unsigned long   __cr3;
--      unsigned long   eip;
--      unsigned long   eflags;
--      unsigned long   eax,ecx,edx,ebx;
--      unsigned long   esp;
--      unsigned long   ebp;
--      unsigned long   esi;
--      unsigned long   edi;
--      unsigned short  es, __esh;
--      unsigned short  cs, __csh;
--      unsigned short  ss, __ssh;
--      unsigned short  ds, __dsh;
--      unsigned short  fs, __fsh;
--      unsigned short  gs, __gsh;
--      unsigned short  ldt, __ldth;
--      unsigned short  trace, io_bitmap_base;
--} __attribute__((packed));
+-#ifdef CONFIG_X86_PAE
+-#define __pte_ma(x)   ((pte_t) { (x), (maddr_t)(x) >> 32 } )
+-extern unsigned long long __supported_pte_mask;
+-static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
+-{
+-      pte_t pte;
 -
--struct tss_struct {
--      struct i386_hw_tss x86_tss;
+-      pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
+-                                      (pgprot_val(pgprot) >> 32);
+-      pte.pte_high &= (__supported_pte_mask >> 32);
+-      pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
+-                                                      __supported_pte_mask;
+-      return pte;
+-}
+ #else
+-#define __pte_ma(x)   ((pte_t) { (x) } )
+-#define pfn_pte_ma(pfn, prot) __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
++#define pte_phys_to_machine phys_to_machine
++#define pte_machine_to_phys machine_to_phys
+ #endif
+ #else /* !CONFIG_XEN */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/maddr_64.h      2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/maddr_64.h   2009-03-16 16:33:40.000000000 +0100
+@@ -1,6 +1,7 @@
+ #ifndef _X86_64_MADDR_H
+ #define _X86_64_MADDR_H
++#include <asm/bug.h>
+ #include <xen/features.h>
+ #include <xen/interface/xen.h>
+@@ -16,6 +17,7 @@ typedef unsigned long maddr_t;
+ #ifdef CONFIG_XEN
+ extern unsigned long *phys_to_machine_mapping;
++extern unsigned long  max_mapnr;
+ #undef machine_to_phys_mapping
+ extern unsigned long *machine_to_phys_mapping;
+@@ -25,7 +27,7 @@ static inline unsigned long pfn_to_mfn(u
+ {
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return pfn;
+-      BUG_ON(end_pfn && pfn >= end_pfn);
++      BUG_ON(max_mapnr && pfn >= max_mapnr);
+       return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
+ }
+@@ -33,7 +35,7 @@ static inline int phys_to_machine_mappin
+ {
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return 1;
+-      BUG_ON(end_pfn && pfn >= end_pfn);
++      BUG_ON(max_mapnr && pfn >= max_mapnr);
+       return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+ }
+@@ -45,7 +47,7 @@ static inline unsigned long mfn_to_pfn(u
+               return mfn;
+       if (unlikely((mfn >> machine_to_phys_order) != 0))
+-              return end_pfn;
++              return max_mapnr;
+       /* The array access can fail (e.g., device space beyond end of RAM). */
+       asm (
+@@ -60,7 +62,7 @@ static inline unsigned long mfn_to_pfn(u
+               "       .quad 1b,3b\n"
+               ".previous"
+               : "=r" (pfn)
+-              : "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
++              : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
+       return pfn;
+ }
+@@ -88,16 +90,16 @@ static inline unsigned long mfn_to_pfn(u
+ static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+ {
+       unsigned long pfn = mfn_to_pfn(mfn);
+-      if ((pfn < end_pfn)
++      if ((pfn < max_mapnr)
+           && !xen_feature(XENFEAT_auto_translated_physmap)
+           && (phys_to_machine_mapping[pfn] != mfn))
+-              return end_pfn; /* force !pfn_valid() */
++              return max_mapnr; /* force !pfn_valid() */
+       return pfn;
+ }
+ static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+ {
+-      BUG_ON(end_pfn && pfn >= end_pfn);
++      BUG_ON(max_mapnr && pfn >= max_mapnr);
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+               return;
+@@ -135,9 +137,6 @@ static inline paddr_t pte_machine_to_phy
+       return phys;
+ }
+-#define __pte_ma(x)     ((pte_t) { (x) } )
+-#define pfn_pte_ma(pfn, prot) __pte_ma((((pfn) << PAGE_SHIFT) | pgprot_val(prot)) & __supported_pte_mask)
 -
--      /*
--       * The extra 1 is there because the CPU will access an
--       * additional byte beyond the end of the IO permission
--       * bitmap. The extra byte must be all 1 bits, and must
--       * be within the limit.
--       */
--      unsigned long   io_bitmap[IO_BITMAP_LONGS + 1];
--      /*
--       * Cache the current maximum and the last task that used the bitmap:
--       */
--      unsigned long io_bitmap_max;
--      struct thread_struct *io_bitmap_owner;
--      /*
--       * pads the TSS to be cacheline-aligned (size is 0x100)
--       */
--      unsigned long __cacheline_filler[35];
--      /*
--       * .. and then another 0x100 bytes for emergency kernel stack
--       */
--      unsigned long stack[64];
--} __attribute__((packed));
+ #else /* !CONFIG_XEN */
+ #define pfn_to_mfn(pfn) (pfn)
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/mmu_context_32.h        2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/mmu_context_32.h     2009-03-16 16:33:40.000000000 +0100
+@@ -51,8 +51,6 @@ static inline void __prepare_arch_switch
+               : : "r" (0) );
+ }
+-void leave_mm(unsigned long cpu);
+-
+ static inline void switch_mm(struct mm_struct *prev,
+                            struct mm_struct *next,
+                            struct task_struct *tsk)
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/mmu_context_64.h        2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/mmu_context_64.h     2009-03-16 16:33:40.000000000 +0100
+@@ -62,12 +62,6 @@ extern void mm_pin(struct mm_struct *mm)
+ extern void mm_unpin(struct mm_struct *mm);
+ void mm_pin_all(void);
+-static inline void load_cr3(pgd_t *pgd)
+-{
+-      asm volatile("movq %0,%%cr3" :: "r" (phys_to_machine(__pa(pgd))) :
+-                   "memory");
+-}
+-
+ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
+                            struct task_struct *tsk)
+ {
+@@ -97,7 +91,7 @@ static inline void switch_mm(struct mm_s
+               op++;
+               
+               if (unlikely(next->context.ldt != prev->context.ldt)) {
+-                      /* load_LDT_nolock(&next->context, cpu) */
++                      /* load_LDT_nolock(&next->context) */
+                       op->cmd = MMUEXT_SET_LDT;
+                       op->arg1.linear_addr = (unsigned long)next->context.ldt;
+                       op->arg2.nr_ents     = next->context.size;
+@@ -110,7 +104,7 @@ static inline void switch_mm(struct mm_s
+       else {
+               write_pda(mmu_state, TLBSTATE_OK);
+               if (read_pda(active_mm) != next)
+-                      out_of_line_bug();
++                      BUG();
+               if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
+                       /* We were in lazy tlb mode and leave_mm disabled 
+                        * tlb flush IPI delivery. We must reload CR3
+@@ -118,7 +112,7 @@ static inline void switch_mm(struct mm_s
+                        */
+                         load_cr3(next->pgd);
+                         xen_new_user_pt(__pa(__user_pgd(next->pgd)));         
+-                      load_LDT_nolock(&next->context, cpu);
++                      load_LDT_nolock(&next->context);
+               }
+       }
+ #endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/page.h  2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/page.h       2009-03-16 16:33:40.000000000 +0100
+@@ -1,13 +1,231 @@
++#ifndef _ASM_X86_PAGE_H
++#define _ASM_X86_PAGE_H
++
++#include <linux/const.h>
++
++/* PAGE_SHIFT determines the page size */
++#define PAGE_SHIFT    12
++#define PAGE_SIZE     (_AC(1,UL) << PAGE_SHIFT)
++#define PAGE_MASK     (~(PAGE_SIZE-1))
++
+ #ifdef __KERNEL__
+-# ifdef CONFIG_X86_32
+-#  include "page_32.h"
+-# else
+-#  include "page_64.h"
+-# endif
++
++/*
++ * Need to repeat this here in order to not include pgtable.h (which in turn
++ * depends on definitions made here), but to be able to use the symbolics
++ * below. The preprocessor will warn if the two definitions aren't identical.
++ */
++#define _PAGE_BIT_PRESENT     0
++#define _PAGE_PRESENT         (_AC(1, L)<<_PAGE_BIT_PRESENT)
++#define _PAGE_BIT_IO          9
++#define _PAGE_IO              (_AC(1, L)<<_PAGE_BIT_IO)
++
++#define PHYSICAL_PAGE_MASK    (~(_AT(phys_addr_t, PAGE_SIZE) - 1) & __PHYSICAL_MASK)
++#define PTE_MASK              _AT(pteval_t, PHYSICAL_PAGE_MASK)
++
++#define PMD_PAGE_SIZE         (_AC(1, UL) << PMD_SHIFT)
++#define PMD_PAGE_MASK         (~(PMD_PAGE_SIZE-1))
++
++#define HPAGE_SHIFT           PMD_SHIFT
++#define HPAGE_SIZE            (_AC(1,UL) << HPAGE_SHIFT)
++#define HPAGE_MASK            (~(HPAGE_SIZE - 1))
++#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
++
++/* to align the pointer to the (next) page boundary */
++#define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
++
++#define __PHYSICAL_MASK               _AT(phys_addr_t, (_AC(1,ULL) << __PHYSICAL_MASK_SHIFT) - 1)
++#define __VIRTUAL_MASK                ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
++
++#ifndef __ASSEMBLY__
++#include <linux/types.h>
++#endif
++
++#ifdef CONFIG_X86_64
++#include <asm/page_64.h>
++#define max_pfn_mapped                end_pfn_map
++#else
++#include <asm/page_32.h>
++#define max_pfn_mapped                max_low_pfn
++#endif        /* CONFIG_X86_64 */
++
++#define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
++
++#define VM_DATA_DEFAULT_FLAGS \
++      (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
++       VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++
++
++#ifndef __ASSEMBLY__
++
++extern int page_is_ram(unsigned long pagenr);
++
++struct page;
++
++static inline void clear_user_page(void *page, unsigned long vaddr,
++                              struct page *pg)
++{
++      clear_page(page);
++}
++
++static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
++                              struct page *topage)
++{
++      copy_page(to, from);
++}
++
++#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
++      alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
++#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
++
++typedef struct { pgprotval_t pgprot; } pgprot_t;
++
++#define pgprot_val(x) ((x).pgprot)
++#define __pgprot(x)   ((pgprot_t) { (x) } )
++
++#include <asm/maddr.h>
++
++typedef struct { pgdval_t pgd; } pgd_t;
++
++#define __pgd_ma(x) ((pgd_t) { (x) } )
++static inline pgd_t xen_make_pgd(pgdval_t val)
++{
++      if (val & _PAGE_PRESENT)
++              val = pte_phys_to_machine(val);
++      return (pgd_t) { val };
++}
++
++#define __pgd_val(x) ((x).pgd)
++static inline pgdval_t xen_pgd_val(pgd_t pgd)
++{
++      pgdval_t ret = __pgd_val(pgd);
++#if PAGETABLE_LEVELS == 2 && CONFIG_XEN_COMPAT <= 0x030002
++      if (ret)
++              ret = machine_to_phys(ret) | _PAGE_PRESENT;
++#else
++      if (ret & _PAGE_PRESENT)
++              ret = pte_machine_to_phys(ret);
++#endif
++      return ret;
++}
++
++#if PAGETABLE_LEVELS >= 3
++#if PAGETABLE_LEVELS == 4
++typedef struct { pudval_t pud; } pud_t;
++
++#define __pud_ma(x) ((pud_t) { (x) } )
++static inline pud_t xen_make_pud(pudval_t val)
++{
++      if (val & _PAGE_PRESENT)
++              val = pte_phys_to_machine(val);
++      return (pud_t) { val };
++}
++
++#define __pud_val(x) ((x).pud)
++static inline pudval_t xen_pud_val(pud_t pud)
++{
++      pudval_t ret = __pud_val(pud);
++      if (ret & _PAGE_PRESENT)
++              ret = pte_machine_to_phys(ret);
++      return ret;
++}
++#else /* PAGETABLE_LEVELS == 3 */
++#include <asm-generic/pgtable-nopud.h>
++
++#define __pud_val(x) __pgd_val((x).pgd)
++static inline pudval_t xen_pud_val(pud_t pud)
++{
++      return xen_pgd_val(pud.pgd);
++}
++#endif        /* PAGETABLE_LEVELS == 4 */
++
++typedef struct { pmdval_t pmd; } pmd_t;
++
++#define __pmd_ma(x)   ((pmd_t) { (x) } )
++static inline pmd_t xen_make_pmd(pmdval_t val)
++{
++      if (val & _PAGE_PRESENT)
++              val = pte_phys_to_machine(val);
++      return (pmd_t) { val };
++}
++
++#define __pmd_val(x) ((x).pmd)
++static inline pmdval_t xen_pmd_val(pmd_t pmd)
++{
++      pmdval_t ret = __pmd_val(pmd);
++#if CONFIG_XEN_COMPAT <= 0x030002
++      if (ret)
++              ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
+ #else
+-# ifdef __i386__
+-#  include "page_32.h"
+-# else
+-#  include "page_64.h"
+-# endif
++      if (ret & _PAGE_PRESENT)
++              ret = pte_machine_to_phys(ret);
++#endif
++      return ret;
++}
++#else  /* PAGETABLE_LEVELS == 2 */
++#include <asm-generic/pgtable-nopmd.h>
++
++#define __pmd_ma(x) ((pmd_t) { .pud.pgd = __pgd_ma(x) } )
++#define __pmd_val(x) __pgd_val((x).pud.pgd)
++static inline pmdval_t xen_pmd_val(pmd_t pmd)
++{
++      return xen_pgd_val(pmd.pud.pgd);
++}
++#endif        /* PAGETABLE_LEVELS >= 3 */
++
++#define __pte_ma(x) ((pte_t) { .pte = (x) } )
++static inline pte_t xen_make_pte(pteval_t val)
++{
++      if ((val & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
++              val = pte_phys_to_machine(val);
++      return (pte_t) { .pte = val };
++}
++
++#define __pte_val(x) ((x).pte)
++static inline pteval_t xen_pte_val(pte_t pte)
++{
++      pteval_t ret = __pte_val(pte);
++      if ((pte.pte_low & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
++              ret = pte_machine_to_phys(ret);
++      return ret;
++}
++
++#define pgd_val(x)    xen_pgd_val(x)
++#define __pgd(x)      xen_make_pgd(x)
++
++#ifndef __PAGETABLE_PUD_FOLDED
++#define pud_val(x)    xen_pud_val(x)
++#define __pud(x)      xen_make_pud(x)
++#endif
++
++#ifndef __PAGETABLE_PMD_FOLDED
++#define pmd_val(x)    xen_pmd_val(x)
++#define __pmd(x)      xen_make_pmd(x)
+ #endif
++
++#define pte_val(x)    xen_pte_val(x)
++#define __pte(x)      xen_make_pte(x)
++
++#define __pa(x)               __phys_addr((unsigned long)(x))
++/* __pa_symbol should be used for C visible symbols.
++   This seems to be the official gcc blessed way to do such arithmetic. */
++#define __pa_symbol(x)        __pa(__phys_reloc_hide((unsigned long)(x)))
++
++#define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
++
++#define __boot_va(x)          __va(x)
++#define __boot_pa(x)          __pa(x)
++
++#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
++#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
++#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
++
++#endif        /* __ASSEMBLY__ */
++
++#include <asm-generic/memory_model.h>
++#include <asm-generic/page.h>
++
++#define __HAVE_ARCH_GATE_AREA 1
++
++#endif        /* __KERNEL__ */
++#endif        /* _ASM_X86_PAGE_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/page_64.h       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/page_64.h    2009-03-16 16:33:40.000000000 +0100
+@@ -1,37 +1,9 @@
+ #ifndef _X86_64_PAGE_H
+ #define _X86_64_PAGE_H
+-/* #include <linux/string.h> */
+-#ifndef __ASSEMBLY__
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <asm/bug.h>
 -#endif
--
--#define ARCH_MIN_TASKALIGN    16
--
--struct thread_struct {
--/* cached TLS descriptors. */
--      struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
--      unsigned long   esp0;
--      unsigned long   sysenter_cs;
--      unsigned long   eip;
--      unsigned long   esp;
--      unsigned long   fs;
--      unsigned long   gs;
--/* Hardware debugging registers */
--      unsigned long   debugreg[8];  /* %%db0-7 debug registers */
--/* fault info */
--      unsigned long   cr2, trap_no, error_code;
--/* floating point info */
--      union i387_union        i387;
--/* virtual 86 mode info */
--      struct vm86_struct __user * vm86_info;
--      unsigned long           screen_bitmap;
--      unsigned long           v86flags, v86mask, saved_esp0;
--      unsigned int            saved_fs, saved_gs;
--/* IO permissions */
--      unsigned long   *io_bitmap_ptr;
--      unsigned long   iopl;
--/* max allowed port in the bitmap, in bytes: */
--      unsigned long   io_bitmap_max;
--};
--
--#define INIT_THREAD  {                                                        \
--      .esp0 = sizeof(init_stack) + (long)&init_stack,                 \
--      .vm86_info = NULL,                                              \
--      .sysenter_cs = __KERNEL_CS,                                     \
--      .io_bitmap_ptr = NULL,                                          \
--      .fs = __KERNEL_PERCPU,                                          \
--}
+-#include <linux/const.h>
+-#include <xen/interface/xen.h> 
 -
 -/*
-- * Note that the .io_bitmap member must be extra-big. This is because
-- * the CPU will access an additional byte beyond the end of the IO
-- * permission bitmap. The extra byte must be all 1 bits, and must
-- * be within the limit.
+- * Need to repeat this here in order to not include pgtable.h (which in turn
+- * depends on definitions made here), but to be able to use the symbolic
+- * below. The preprocessor will warn if the two definitions aren't identical.
 - */
--#define INIT_TSS  {                                                   \
--      .x86_tss = {                                                    \
--              .esp0           = sizeof(init_stack) + (long)&init_stack, \
--              .ss0            = __KERNEL_DS,                          \
--              .ss1            = __KERNEL_CS,                          \
--              .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,             \
--       },                                                             \
--      .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
--}
+-#define _PAGE_PRESENT 0x001
+-#define _PAGE_IO      0x200
 -
--#define start_thread(regs, new_eip, new_esp) do {             \
--      __asm__("movl %0,%%gs": :"r" (0));                      \
--      regs->xfs = 0;                                          \
--      set_fs(USER_DS);                                        \
--      regs->xds = __USER_DS;                                  \
--      regs->xes = __USER_DS;                                  \
--      regs->xss = __USER_DS;                                  \
--      regs->xcs = __USER_CS;                                  \
--      regs->eip = new_eip;                                    \
--      regs->esp = new_esp;                                    \
--} while (0)
+-/* PAGE_SHIFT determines the page size */
+-#define PAGE_SHIFT    12
+-#define PAGE_SIZE     (_AC(1,UL) << PAGE_SHIFT)
+-#define PAGE_MASK     (~(PAGE_SIZE-1))
 -
--/* Forward declaration, a strange C thing */
--struct task_struct;
--struct mm_struct;
+-/* See Documentation/x86_64/mm.txt for a description of the memory map. */
+-#define __PHYSICAL_MASK_SHIFT 46
+-#define __PHYSICAL_MASK               ((_AC(1,UL) << __PHYSICAL_MASK_SHIFT) - 1)
+-#define __VIRTUAL_MASK_SHIFT  48
+-#define __VIRTUAL_MASK                ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
 -
--/* Free all resources held by a thread. */
--extern void release_thread(struct task_struct *);
+-#define PHYSICAL_PAGE_MASK    (~(PAGE_SIZE-1) & __PHYSICAL_MASK)
++#define PAGETABLE_LEVELS      4
+-#define THREAD_ORDER 1 
++#define THREAD_ORDER  1
+ #define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)
+ #define CURRENT_MASK (~(THREAD_SIZE-1))
+@@ -51,106 +23,10 @@
+ #define MCE_STACK 5
+ #define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
+-#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+-#define LARGE_PAGE_SIZE (_AC(1,UL) << PMD_SHIFT)
 -
--/* Prepare to copy thread state - unlazy all lazy status */
--extern void prepare_to_copy(struct task_struct *tsk);
+-#define HPAGE_SHIFT PMD_SHIFT
+-#define HPAGE_SIZE    (_AC(1,UL) << HPAGE_SHIFT)
+-#define HPAGE_MASK    (~(HPAGE_SIZE - 1))
+-#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
 -
--/*
-- * create a kernel thread without removing it from tasklists
-- */
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+-#ifdef __KERNEL__
+-#ifndef __ASSEMBLY__
 -
--extern unsigned long thread_saved_pc(struct task_struct *tsk);
--void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack);
+-extern unsigned long end_pfn;
 -
--unsigned long get_wchan(struct task_struct *p);
+-#include <asm/maddr.h>
 -
--#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
--#define KSTK_TOP(info)                                                 \
--({                                                                     \
--       unsigned long *__ptr = (unsigned long *)(info);                 \
--       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
--})
+-void clear_page(void *);
+-void copy_page(void *, void *);
+-
+-#define clear_user_page(page, vaddr, pg)      clear_page(page)
+-#define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
+-
+-#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
+-      alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
+-#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
 -
 -/*
-- * The below -8 is to reserve 8 bytes on top of the ring0 stack.
-- * This is necessary to guarantee that the entire "struct pt_regs"
-- * is accessable even if the CPU haven't stored the SS/ESP registers
-- * on the stack (interrupt gate does not save these registers
-- * when switching to the same priv ring).
-- * Therefore beware: accessing the xss/esp fields of the
-- * "struct pt_regs" is possible, but they may contain the
-- * completely wrong values.
+- * These are used to make use of C type-checking..
 - */
--#define task_pt_regs(task)                                             \
--({                                                                     \
--       struct pt_regs *__regs__;                                       \
--       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
--       __regs__ - 1;                                                   \
--})
+-typedef struct { unsigned long pte; } pte_t;
+-typedef struct { unsigned long pmd; } pmd_t;
+-typedef struct { unsigned long pud; } pud_t;
+-typedef struct { unsigned long pgd; } pgd_t;
+-#define PTE_MASK      PHYSICAL_PAGE_MASK
 -
--#define KSTK_EIP(task) (task_pt_regs(task)->eip)
--#define KSTK_ESP(task) (task_pt_regs(task)->esp)
+-typedef struct { unsigned long pgprot; } pgprot_t;
 -
+-#define __pte_val(x) ((x).pte)
+-#define pte_val(x) ((__pte_val(x) & (_PAGE_PRESENT|_PAGE_IO)) \
+-                  == _PAGE_PRESENT ?                          \
+-                  pte_machine_to_phys(__pte_val(x)) :         \
+-                  __pte_val(x))
 -
--struct microcode_header {
--      unsigned int hdrver;
--      unsigned int rev;
--      unsigned int date;
--      unsigned int sig;
--      unsigned int cksum;
--      unsigned int ldrver;
--      unsigned int pf;
--      unsigned int datasize;
--      unsigned int totalsize;
--      unsigned int reserved[3];
--};
+-#define __pmd_val(x) ((x).pmd)
+-static inline unsigned long pmd_val(pmd_t x)
+-{
+-      unsigned long ret = __pmd_val(x);
+-#if CONFIG_XEN_COMPAT <= 0x030002
+-      if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
+-#else
+-      if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+-#endif
+-      return ret;
+-}
 -
--struct microcode {
--      struct microcode_header hdr;
--      unsigned int bits[0];
--};
+-#define __pud_val(x) ((x).pud)
+-static inline unsigned long pud_val(pud_t x)
+-{
+-      unsigned long ret = __pud_val(x);
+-      if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+-      return ret;
+-}
 -
--typedef struct microcode microcode_t;
--typedef struct microcode_header microcode_header_t;
+-#define __pgd_val(x) ((x).pgd)
+-static inline unsigned long pgd_val(pgd_t x)
+-{
+-      unsigned long ret = __pgd_val(x);
+-      if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+-      return ret;
+-}
 -
--/* microcode format is extended from prescott processors */
--struct extended_signature {
--      unsigned int sig;
--      unsigned int pf;
--      unsigned int cksum;
--};
+-#define pgprot_val(x) ((x).pgprot)
 -
--struct extended_sigtable {
--      unsigned int count;
--      unsigned int cksum;
--      unsigned int reserved[3];
--      struct extended_signature sigs[0];
--};
+-static inline pte_t __pte(unsigned long x)
+-{
+-      if ((x & (_PAGE_PRESENT|_PAGE_IO)) == _PAGE_PRESENT)
+-              x = pte_phys_to_machine(x);
+-      return ((pte_t) { (x) });
+-}
+-
+-static inline pmd_t __pmd(unsigned long x)
+-{
+-      if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
+-      return ((pmd_t) { (x) });
+-}
+-
+-static inline pud_t __pud(unsigned long x)
+-{
+-      if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
+-      return ((pud_t) { (x) });
+-}
 -
--/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
--static inline void rep_nop(void)
+-static inline pgd_t __pgd(unsigned long x)
 -{
--      __asm__ __volatile__("rep;nop": : :"memory");
+-      if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
+-      return ((pgd_t) { (x) });
 -}
 -
--#define cpu_relax()   rep_nop()
+-#define __pgprot(x)   ((pgprot_t) { (x) } )
++#define PUD_PAGE_SIZE         (_AC(1, UL) << PUD_SHIFT)
++#define PUD_PAGE_MASK         (~(PUD_PAGE_SIZE-1))
+-#endif /* !__ASSEMBLY__ */
++#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
+ #define __PHYSICAL_START      CONFIG_PHYSICAL_START
+ #define __KERNEL_ALIGN                0x200000
+@@ -166,52 +42,58 @@ static inline pgd_t __pgd(unsigned long 
+ #define __START_KERNEL                (__START_KERNEL_map + __PHYSICAL_START)
+ #define __START_KERNEL_map    _AC(0xffffffff80000000, UL)
+-#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
+ #if CONFIG_XEN_COMPAT <= 0x030002
+ #undef LOAD_OFFSET
+ #define LOAD_OFFSET           0
+ #endif
+-/* to align the pointer to the (next) page boundary */
+-#define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 -
--#ifndef CONFIG_X86_NO_TSS
--static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread)
--{
--      tss->x86_tss.esp0 = thread->esp0;
--      /* This can only happen when SEP is enabled, no need to test "SEP"arately */
--      if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
--              tss->x86_tss.ss1 = thread->sysenter_cs;
--              wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
--      }
--}
--#else
--#define xen_load_esp0(tss, thread) do { \
--      if (HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0)) \
--              BUG(); \
+-#define KERNEL_TEXT_SIZE  (40*1024*1024)
+-#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL)
++/* See Documentation/x86_64/mm.txt for a description of the memory map. */
++#define __PHYSICAL_MASK_SHIFT 46
++#define __VIRTUAL_MASK_SHIFT  48
+-#define PAGE_OFFSET           __PAGE_OFFSET
++/*
++ * Kernel image size is limited to 128 MB (see level2_kernel_pgt in
++ * arch/x86/kernel/head_64.S), and it is mapped here:
++ */
++#define KERNEL_IMAGE_SIZE     (128*1024*1024)
++#define KERNEL_IMAGE_START    _AC(0xffffffff80000000, UL)
+ #ifndef __ASSEMBLY__
++void clear_page(void *page);
++void copy_page(void *to, void *from);
++
++extern unsigned long end_pfn;
++extern unsigned long end_pfn_map;
++
+ static inline unsigned long __phys_addr(unsigned long x)
+ {
+-      return x - (x >= __START_KERNEL_map ? __START_KERNEL_map : PAGE_OFFSET);
++      return x - (x >= __START_KERNEL_map ? __START_KERNEL_map : __PAGE_OFFSET);
+ }
+-#endif
+-#define __pa(x)               __phys_addr((unsigned long)(x))
+-#define __pa_symbol(x)        __phys_addr((unsigned long)(x))
++#define __phys_reloc_hide(x)  (x)
+-#define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
+-#define __boot_va(x)          __va(x)
+-#define __boot_pa(x)          __pa(x)
+-#ifdef CONFIG_FLATMEM
+-#define pfn_valid(pfn)                ((pfn) < end_pfn)
+-#endif
++/*
++ * These are used to make use of C type-checking..
++ */
++typedef unsigned long pteval_t;
++typedef unsigned long pmdval_t;
++typedef unsigned long pudval_t;
++typedef unsigned long pgdval_t;
++typedef unsigned long pgprotval_t;
++typedef unsigned long phys_addr_t;
+-#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+-#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+-#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+-
+-#define VM_DATA_DEFAULT_FLAGS \
+-      (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+-       VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++typedef struct page *pgtable_t;
++
++typedef union { pteval_t pte; unsigned int pte_low; } pte_t;
+-#define __HAVE_ARCH_GATE_AREA 1       
+ #define vmemmap ((struct page *)VMEMMAP_START)
+-#include <asm-generic/memory_model.h>
+-#include <asm-generic/page.h>
++#endif        /* !__ASSEMBLY__ */
++
++#ifdef CONFIG_FLATMEM
++#define pfn_valid(pfn)          ((pfn) < max_mapnr)
++#endif
+-#endif /* __KERNEL__ */
+ #endif /* _X86_64_PAGE_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pci.h   2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pci.h        2009-03-16 16:33:40.000000000 +0100
+@@ -71,6 +71,7 @@ extern int pci_mmap_page_range(struct pc
+ #ifdef CONFIG_PCI
++extern void early_quirks(void);
+ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+                                       enum pci_dma_burst_strategy *strat,
+                                       unsigned long *strategy_parameter)
+@@ -78,9 +79,10 @@ static inline void pci_dma_burst_advice(
+       *strat = PCI_DMA_BURST_INFINITY;
+       *strategy_parameter = ~0UL;
+ }
++#else
++static inline void early_quirks(void) { }
+ #endif
+-
+ #endif  /* __KERNEL__ */
+ #ifdef CONFIG_X86_32
+@@ -95,6 +97,19 @@ static inline void pci_dma_burst_advice(
+ /* generic pci stuff */
+ #include <asm-generic/pci.h>
++#ifdef CONFIG_NUMA
++/* Returns the node based on pci bus */
++static inline int __pcibus_to_node(struct pci_bus *bus)
++{
++      struct pci_sysdata *sd = bus->sysdata;
++
++      return sd->node;
++}
++static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
++{
++      return node_to_cpumask(__pcibus_to_node(bus));
++}
++#endif
+ #endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pgalloc_32.h    2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pgalloc_32.h 2009-03-16 16:33:40.000000000 +0100
+@@ -3,69 +3,109 @@
+ #include <linux/threads.h>
+ #include <linux/mm.h>         /* for struct page */
++#include <linux/pagemap.h>
++#include <asm/tlb.h>
++#include <asm-generic/tlb.h>
+ #include <asm/io.h>           /* for phys_to_virt and page_to_pseudophys */
+ #define paravirt_alloc_pt(mm, pfn) do { } while (0)
+-#define paravirt_alloc_pd(pfn) do { } while (0)
+-#define paravirt_alloc_pd(pfn) do { } while (0)
++#define paravirt_alloc_pd(mm, pfn) do { } while (0)
+ #define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) do { } while (0)
+ #define paravirt_release_pt(pfn) do { } while (0)
+ #define paravirt_release_pd(pfn) do { } while (0)
+-#define pmd_populate_kernel(mm, pmd, pte)                     \
+-do {                                                          \
+-      paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);         \
+-      set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));           \
+-} while (0)
+-
+-#define pmd_populate(mm, pmd, pte)                                    \
+-do {                                                                  \
+-      unsigned long pfn = page_to_pfn(pte);                           \
+-      paravirt_alloc_pt(mm, pfn);                                     \
+-      if (PagePinned(virt_to_page((mm)->pgd))) {                      \
+-              if (!PageHighMem(pte))                                  \
+-                      BUG_ON(HYPERVISOR_update_va_mapping(            \
+-                        (unsigned long)__va(pfn << PAGE_SHIFT),       \
+-                        pfn_pte(pfn, PAGE_KERNEL_RO), 0));            \
+-              else if (!test_and_set_bit(PG_pinned, &pte->flags))     \
+-                      kmap_flush_unused();                            \
+-              set_pmd(pmd,                                            \
+-                      __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT))); \
+-      } else                                                  \
+-              *(pmd) = __pmd(_PAGE_TABLE + ((paddr_t)pfn << PAGE_SHIFT)); \
+-} while (0)
++static inline void pmd_populate_kernel(struct mm_struct *mm,
++                                     pmd_t *pmd, pte_t *pte)
++{
++      paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);
++      set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
++}
++
++static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
++{
++      unsigned long pfn = page_to_pfn(pte);
++
++      paravirt_alloc_pt(mm, pfn);
++      if (PagePinned(virt_to_page(mm->pgd))) {
++              if (!PageHighMem(pte))
++                      BUG_ON(HYPERVISOR_update_va_mapping(
++                        (unsigned long)__va(pfn << PAGE_SHIFT),
++                        pfn_pte(pfn, PAGE_KERNEL_RO), 0));
++              else if (!test_and_set_bit(PG_pinned, &pte->flags))
++                      kmap_flush_unused();
++              set_pmd(pmd, __pmd(((pmdval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE));
++      } else
++              *pmd = __pmd(((pmdval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE);
++}
++#define pmd_pgtable(pmd) pmd_page(pmd)
+ /*
+  * Allocate and free page tables.
+  */
++extern void pgd_test_and_unpin(pgd_t *);
+ extern pgd_t *pgd_alloc(struct mm_struct *);
+-extern void pgd_free(pgd_t *pgd);
++extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+ extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+-extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
++extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
+-static inline void pte_free_kernel(pte_t *pte)
++static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+ {
+       make_lowmem_page_writable(pte, XENFEAT_writable_page_tables);
+       free_page((unsigned long)pte);
+ }
+-extern void pte_free(struct page *pte);
++extern void __pte_free(pgtable_t);
++static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
++{
++      __pte_free(pte);
++}
++
+-#define __pte_free_tlb(tlb,pte)                                       \
+-do {                                                                  \
+-      paravirt_release_pt(page_to_pfn(pte));                          \
+-      tlb_remove_page((tlb),(pte));                                   \
 -} while (0)
++extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
+ #ifdef CONFIG_X86_PAE
+ /*
+  * In the PAE case we free the pmds as part of the pgd.
+  */
+-#define pmd_alloc_one(mm, addr)               ({ BUG(); ((pmd_t *)2); })
+-#define pmd_free(x)                   do { } while (0)
+-#define __pmd_free_tlb(tlb,x)         do { } while (0)
+-#define pud_populate(mm, pmd, pte)    BUG()
 -#endif
--
--
--static inline unsigned long xen_get_debugreg(int regno)
--{
--      return HYPERVISOR_get_debugreg(regno);
--}
--
--static inline void xen_set_debugreg(int regno, unsigned long value)
--{
--      WARN_ON(HYPERVISOR_set_debugreg(regno, value));
--}
--
--/*
-- * Set IOPL bits in EFLAGS from given mask
-- */
--static inline void xen_set_iopl_mask(unsigned mask)
++extern pmd_t *pmd_alloc_one(struct mm_struct *, unsigned long);
++
++extern void __pmd_free(pgtable_t);
++static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
++{
++      BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
++      __pmd_free(virt_to_page(pmd));
++}
++
++extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd);
++
++static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
++{
++      struct page *page = virt_to_page(pmd);
++      unsigned long pfn = page_to_pfn(page);
++
++      paravirt_alloc_pd(mm, pfn);
++
++      /* Note: almost everything apart from _PAGE_PRESENT is
++         reserved at the pmd (PDPT) level. */
++      if (PagePinned(virt_to_page(mm->pgd))) {
++              BUG_ON(PageHighMem(page));
++              BUG_ON(HYPERVISOR_update_va_mapping(
++                        (unsigned long)__va(pfn << PAGE_SHIFT),
++                        pfn_pte(pfn, PAGE_KERNEL_RO), 0));
++              set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT));
++      } else
++              *pudp = __pud(__pa(pmd) | _PAGE_PRESENT);
++
++      /*
++       * According to Intel App note "TLBs, Paging-Structure Caches,
++       * and Their Invalidation", April 2007, document 317080-001,
++       * section 8.1: in PAE mode we explicitly have to flush the
++       * TLB via cr3 if the top-level pgd is changed...
++       */
++      if (mm == current->active_mm)
++              xen_tlb_flush();
++}
++#endif        /* CONFIG_X86_PAE */
+ #endif /* _I386_PGALLOC_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pgalloc_64.h    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pgalloc_64.h 2009-03-16 16:33:40.000000000 +0100
+@@ -6,30 +6,13 @@
+ #include <linux/mm.h>
+ #include <asm/io.h>           /* for phys_to_virt and page_to_pseudophys */
+-#include <xen/features.h>
+-void make_page_readonly(void *va, unsigned int feature);
+-void make_page_writable(void *va, unsigned int feature);
+-void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
+-void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
++pmd_t *early_get_pmd(unsigned long va);
++void early_make_page_readonly(void *va, unsigned int feature);
+ #define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
+-static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 -{
--      struct physdev_set_iopl set_iopl;
--
--      /* Force the change at ring 0. */
--      set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
--      WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl));
+-      set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)));
 -}
 -
--
--#define paravirt_enabled() 0
--#define __cpuid xen_cpuid
--
--#define load_esp0 xen_load_esp0
--
--/*
-- * These special macros can be used to get or set a debugging register
-- */
--#define get_debugreg(var, register)                           \
--      (var) = xen_get_debugreg(register)
--#define set_debugreg(value, register)                         \
--      xen_set_debugreg(register, value)
--
--#define set_iopl_mask xen_set_iopl_mask
--
--/*
-- * Generic CPUID function
-- * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
-- * resulting in stale register contents being returned.
-- */
--static inline void cpuid(unsigned int op,
--                       unsigned int *eax, unsigned int *ebx,
--                       unsigned int *ecx, unsigned int *edx)
+-static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
 -{
--      *eax = op;
--      *ecx = 0;
--      __cpuid(eax, ebx, ecx, edx);
+-      if (unlikely(PagePinned(virt_to_page((mm)->pgd)))) {
+-              BUG_ON(HYPERVISOR_update_va_mapping(
+-                             (unsigned long)__va(page_to_pfn(pte) << PAGE_SHIFT),
+-                             pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));
+-              set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
+-      } else {
+-              *(pmd) = __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT));
+-      }
 -}
++#define pmd_populate_kernel(mm, pmd, pte) \
++              set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
+ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ {
+@@ -63,53 +46,58 @@ static inline void pgd_populate(struct m
+       }
+ }
+-extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+-extern void pte_free(struct page *pte);
++#define pmd_pgtable(pmd) pmd_page(pmd)
+-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
++static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
+ {
+-      struct page *pg;
 -
--/* Some CPUID calls want 'count' to be placed in ecx */
--static inline void cpuid_count(unsigned int op, int count,
--                             unsigned int *eax, unsigned int *ebx,
--                             unsigned int *ecx, unsigned int *edx)
--{
--      *eax = op;
--      *ecx = count;
--      __cpuid(eax, ebx, ecx, edx);
--}
+-      pg = pte_alloc_one(mm, addr);
+-      return pg ? page_address(pg) : NULL;
++      if (unlikely(PagePinned(virt_to_page((mm)->pgd)))) {
++              BUG_ON(HYPERVISOR_update_va_mapping(
++                             (unsigned long)__va(page_to_pfn(pte) << PAGE_SHIFT),
++                             pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));
++              set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
++      } else {
++              *(pmd) = __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT));
++      }
+ }
+-static inline void pmd_free(pmd_t *pmd)
++extern void __pmd_free(pgtable_t);
++static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+ {
+       BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
+-      pte_free(virt_to_page(pmd));
++      __pmd_free(virt_to_page(pmd));
+ }
++extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr);
++
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+-      struct page *pg;
 -
+-      pg = pte_alloc_one(mm, addr);
+-      return pg ? page_address(pg) : NULL;
++      return (pud_t *)pmd_alloc_one(mm, addr);
+ }
+-static inline void pud_free(pud_t *pud)
++static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+ {
+       BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
+-      pte_free(virt_to_page(pud));
++      __pmd_free(virt_to_page(pud));
+ }
+ static inline void pgd_list_add(pgd_t *pgd)
+ {
+       struct page *page = virt_to_page(pgd);
++      unsigned long flags;
+-      spin_lock(&pgd_lock);
++      spin_lock_irqsave(&pgd_lock, flags);
+       list_add(&page->lru, &pgd_list);
+-      spin_unlock(&pgd_lock);
++      spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+ static inline void pgd_list_del(pgd_t *pgd)
+ {
+       struct page *page = virt_to_page(pgd);
++      unsigned long flags;
+-      spin_lock(&pgd_lock);
++      spin_lock_irqsave(&pgd_lock, flags);
+       list_del(&page->lru);
+-      spin_unlock(&pgd_lock);
++      spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+ extern void pgd_test_and_unpin(pgd_t *);
+@@ -145,7 +133,7 @@ static inline pgd_t *pgd_alloc(struct mm
+       return pgd;
+ }
+-static inline void pgd_free(pgd_t *pgd)
++static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+ {
+       pgd_test_and_unpin(pgd);
+       pgd_list_del(pgd);
+@@ -161,17 +149,30 @@ static inline pte_t *pte_alloc_one_kerne
+       return pte;
+ }
++extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
++
+ /* Should really implement gc for free page table pages. This could be
+    done with a reference count in struct page. */
+-static inline void pte_free_kernel(pte_t *pte)
++static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+ {
+       BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
+       make_page_writable(pte, XENFEAT_writable_page_tables);
+       free_page((unsigned long)pte); 
+ }
+-#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
++extern void __pte_free(pgtable_t);
++static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
++{
++      __pte_free(pte);
++}
++
++#define __pte_free_tlb(tlb,pte)                               \
++do {                                                  \
++      pgtable_page_dtor((pte));                               \
++      tlb_remove_page((tlb), (pte));                  \
++} while (0)
++
+ #define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
+ #define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pgtable.h       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pgtable.h    2009-03-16 16:33:40.000000000 +0100
+@@ -1,5 +1,467 @@
++#ifndef _ASM_X86_PGTABLE_H
++#define _ASM_X86_PGTABLE_H
++
++#define USER_PTRS_PER_PGD     ((TASK_SIZE-1)/PGDIR_SIZE+1)
++#define FIRST_USER_ADDRESS    0
++
++#define _PAGE_BIT_PRESENT     0
++#define _PAGE_BIT_RW          1
++#define _PAGE_BIT_USER                2
++#define _PAGE_BIT_PWT         3
++#define _PAGE_BIT_PCD         4
++#define _PAGE_BIT_ACCESSED    5
++#define _PAGE_BIT_DIRTY               6
++#define _PAGE_BIT_FILE                6
++#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page */
++#define _PAGE_BIT_PAT         7       /* on 4KB pages */
++#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
++#define _PAGE_BIT_IO          9       /* Mapped page is I/O or foreign and
++                                       * has no associated page struct. */
++#define _PAGE_BIT_UNUSED2     10      /* available for programmer */
++#define _PAGE_BIT_UNUSED3     11
++#define _PAGE_BIT_PAT_LARGE   12      /* On 2MB or 1GB pages */
++#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
++
++/*
++ * Note: we use _AC(1, L) instead of _AC(1, UL) so that we get a
++ * sign-extended value on 32-bit with all 1's in the upper word,
++ * which preserves the upper pte values on 64-bit ptes:
++ */
++#define _PAGE_PRESENT (_AC(1, L)<<_PAGE_BIT_PRESENT)
++#define _PAGE_RW      (_AC(1, L)<<_PAGE_BIT_RW)
++#define _PAGE_USER    (_AC(1, L)<<_PAGE_BIT_USER)
++#define _PAGE_PWT     (_AC(1, L)<<_PAGE_BIT_PWT)
++#define _PAGE_PCD     (_AC(1, L)<<_PAGE_BIT_PCD)
++#define _PAGE_ACCESSED        (_AC(1, L)<<_PAGE_BIT_ACCESSED)
++#define _PAGE_DIRTY   (_AC(1, L)<<_PAGE_BIT_DIRTY)
++#define _PAGE_PSE     (_AC(1, L)<<_PAGE_BIT_PSE)      /* 2MB page */
++#define _PAGE_GLOBAL  (_AC(1, L)<<_PAGE_BIT_GLOBAL)   /* Global TLB entry */
++#define _PAGE_IO      (_AC(1, L)<<_PAGE_BIT_IO)
++#define _PAGE_UNUSED2 (_AC(1, L)<<_PAGE_BIT_UNUSED2)
++#define _PAGE_UNUSED3 (_AC(1, L)<<_PAGE_BIT_UNUSED3)
++#define _PAGE_PAT     (_AC(1, L)<<_PAGE_BIT_PAT)
++#define _PAGE_PAT_LARGE (_AC(1, L)<<_PAGE_BIT_PAT_LARGE)
++
++#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
++#define _PAGE_NX      (_AC(1, ULL) << _PAGE_BIT_NX)
++#else
++#define _PAGE_NX      0
++#endif
++
++/* If _PAGE_PRESENT is clear, we use these: */
++#define _PAGE_FILE    _PAGE_DIRTY     /* nonlinear file mapping, saved PTE; unset:swap */
++#define _PAGE_PROTNONE        _PAGE_PSE       /* if the user mapped it with PROT_NONE;
++                                         pte_present gives true */
++
++#ifndef __ASSEMBLY__
++#if defined(CONFIG_X86_64) && CONFIG_XEN_COMPAT <= 0x030002
++extern unsigned int __kernel_page_user;
++#else
++#define __kernel_page_user 0
++#endif
++#endif
++
++#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
++#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
++
++#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
++
++#define PAGE_NONE     __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
++#define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
++
++#define PAGE_SHARED_EXEC      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
++#define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
++#define PAGE_COPY_EXEC                __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
++#define PAGE_COPY             PAGE_COPY_NOEXEC
++#define PAGE_READONLY         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
++#define PAGE_READONLY_EXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
++
++#ifdef CONFIG_X86_32
++#define _PAGE_KERNEL_EXEC \
++      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
++#define _PAGE_KERNEL (_PAGE_KERNEL_EXEC | _PAGE_NX)
++
++#ifndef __ASSEMBLY__
++extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
++#endif        /* __ASSEMBLY__ */
++#else
++#define __PAGE_KERNEL_EXEC                                            \
++      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | __kernel_page_user)
++#define __PAGE_KERNEL         (__PAGE_KERNEL_EXEC | _PAGE_NX)
++#endif
++
++#define __PAGE_KERNEL_RO              (__PAGE_KERNEL & ~_PAGE_RW)
++#define __PAGE_KERNEL_RX              (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
++#define __PAGE_KERNEL_EXEC_NOCACHE    (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
++#define __PAGE_KERNEL_NOCACHE         (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
++#define __PAGE_KERNEL_UC_MINUS                (__PAGE_KERNEL | _PAGE_PCD)
++#define __PAGE_KERNEL_VSYSCALL                (__PAGE_KERNEL_RX | _PAGE_USER)
++#define __PAGE_KERNEL_VSYSCALL_NOCACHE        (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
++#define __PAGE_KERNEL_LARGE           (__PAGE_KERNEL | _PAGE_PSE)
++#define __PAGE_KERNEL_LARGE_EXEC      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
++
++/*
++ * We don't support GLOBAL page in xenolinux64
++ */
++#define MAKE_GLOBAL(x)                        __pgprot((x))
++
++#define PAGE_KERNEL                   MAKE_GLOBAL(__PAGE_KERNEL)
++#define PAGE_KERNEL_RO                        MAKE_GLOBAL(__PAGE_KERNEL_RO)
++#define PAGE_KERNEL_EXEC              MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
++#define PAGE_KERNEL_RX                        MAKE_GLOBAL(__PAGE_KERNEL_RX)
++#define PAGE_KERNEL_NOCACHE           MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
++#define PAGE_KERNEL_UC_MINUS          MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS)
++#define PAGE_KERNEL_EXEC_NOCACHE      MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE)
++#define PAGE_KERNEL_LARGE             MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
++#define PAGE_KERNEL_LARGE_EXEC                MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC)
++#define PAGE_KERNEL_VSYSCALL          MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
++#define PAGE_KERNEL_VSYSCALL_NOCACHE  MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
++
++/*         xwr */
++#define __P000        PAGE_NONE
++#define __P001        PAGE_READONLY
++#define __P010        PAGE_COPY
++#define __P011        PAGE_COPY
++#define __P100        PAGE_READONLY_EXEC
++#define __P101        PAGE_READONLY_EXEC
++#define __P110        PAGE_COPY_EXEC
++#define __P111        PAGE_COPY_EXEC
++
++#define __S000        PAGE_NONE
++#define __S001        PAGE_READONLY
++#define __S010        PAGE_SHARED
++#define __S011        PAGE_SHARED
++#define __S100        PAGE_READONLY_EXEC
++#define __S101        PAGE_READONLY_EXEC
++#define __S110        PAGE_SHARED_EXEC
++#define __S111        PAGE_SHARED_EXEC
++
++#ifndef __ASSEMBLY__
++
++/*
++ * ZERO_PAGE is a global shared page that is always zero: used
++ * for zero-mapped memory areas etc..
++ */
++extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
++#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
++
++extern spinlock_t pgd_lock;
++extern struct list_head pgd_list;
++
++/*
++ * The following only work if pte_present() is true.
++ * Undefined behaviour if not..
++ */
++static inline int pte_dirty(pte_t pte)                { return __pte_val(pte) & _PAGE_DIRTY; }
++static inline int pte_young(pte_t pte)                { return __pte_val(pte) & _PAGE_ACCESSED; }
++static inline int pte_write(pte_t pte)                { return __pte_val(pte) & _PAGE_RW; }
++static inline int pte_file(pte_t pte)         { return __pte_val(pte) & _PAGE_FILE; }
++static inline int pte_huge(pte_t pte)         { return __pte_val(pte) & _PAGE_PSE; }
++static inline int pte_global(pte_t pte)       { return 0; }
++static inline int pte_exec(pte_t pte)         { return !(__pte_val(pte) & _PAGE_NX); }
++
++static inline int pmd_large(pmd_t pte) {
++      return (__pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) ==
++              (_PAGE_PSE|_PAGE_PRESENT);
++}
++
++static inline pte_t pte_mkclean(pte_t pte)    { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); }
++static inline pte_t pte_mkold(pte_t pte)      { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); }
++static inline pte_t pte_wrprotect(pte_t pte)  { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_RW); }
++static inline pte_t pte_mkexec(pte_t pte)     { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_NX); }
++static inline pte_t pte_mkdirty(pte_t pte)    { return __pte_ma(__pte_val(pte) | _PAGE_DIRTY); }
++static inline pte_t pte_mkyoung(pte_t pte)    { return __pte_ma(__pte_val(pte) | _PAGE_ACCESSED); }
++static inline pte_t pte_mkwrite(pte_t pte)    { return __pte_ma(__pte_val(pte) | _PAGE_RW); }
++static inline pte_t pte_mkhuge(pte_t pte)     { return __pte_ma(__pte_val(pte) | _PAGE_PSE); }
++static inline pte_t pte_clrhuge(pte_t pte)    { return __pte_ma(__pte_val(pte) & ~(pteval_t)_PAGE_PSE); }
++static inline pte_t pte_mkglobal(pte_t pte)   { return pte; }
++static inline pte_t pte_clrglobal(pte_t pte)  { return pte; }
++
++extern pteval_t __supported_pte_mask;
++
++static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
++{
++      return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
++                    pgprot_val(pgprot)) & __supported_pte_mask);
++}
++
++static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
++{
++      return __pte_ma((((phys_addr_t)page_nr << PAGE_SHIFT) |
++                       pgprot_val(pgprot)) & __supported_pte_mask);
++}
++
++static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
++{
++      return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) |
++                    pgprot_val(pgprot)) & __supported_pte_mask);
++}
++
++static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
++{
++      pteval_t val = pte_val(pte);
++
++      val &= _PAGE_CHG_MASK;
++      val |= pgprot_val(newprot) & __supported_pte_mask;
++
++      return __pte(val);
++}
++
++#define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX))
++
++#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
++
++#define set_pte(ptep, pte)            xen_set_pte(ptep, pte)
++#define set_pte_at(mm, addr, ptep, pte)       xen_set_pte_at(mm, addr, ptep, pte)
++
++#define set_pte_atomic(ptep, pte)                                     \
++      xen_set_pte_atomic(ptep, pte)
++
++#define set_pmd(pmdp, pmd)            xen_set_pmd(pmdp, pmd)
++
++#ifndef __PAGETABLE_PUD_FOLDED
++#define set_pgd(pgdp, pgd)            xen_set_pgd(pgdp, pgd)
++#define pgd_clear(pgd)                        xen_pgd_clear(pgd)
++#endif
++
++#ifndef set_pud
++# define set_pud(pudp, pud)           xen_set_pud(pudp, pud)
++#endif
++
++#ifndef __PAGETABLE_PMD_FOLDED
++#define pud_clear(pud)                        xen_pud_clear(pud)
++#endif
++
++#define pte_clear(mm, addr, ptep)     xen_pte_clear(mm, addr, ptep)
++#define pmd_clear(pmd)                        xen_pmd_clear(pmd)
++
++#define pte_update(mm, addr, ptep)              do { } while (0)
++#define pte_update_defer(mm, addr, ptep)        do { } while (0)
++
++#endif        /* __ASSEMBLY__ */
++
+ #ifdef CONFIG_X86_32
+ # include "pgtable_32.h"
+ #else
+ # include "pgtable_64.h"
+ #endif
++
++#ifndef __ASSEMBLY__
++
++enum {
++      PG_LEVEL_NONE,
++      PG_LEVEL_4K,
++      PG_LEVEL_2M,
++      PG_LEVEL_1G,
++};
++
++/*
++ * Helper function that returns the kernel pagetable entry controlling
++ * the virtual address 'address'. NULL means no pagetable entry present.
++ * NOTE: the return type is pte_t but if the pmd is PSE then we return it
++ * as a pte too.
++ */
++extern pte_t *lookup_address(unsigned long address, unsigned int *level);
++
++/* local pte updates need not use xchg for locking */
++static inline pte_t xen_local_ptep_get_and_clear(pte_t *ptep, pte_t res)
++{
++      xen_set_pte(ptep, __pte(0));
++      return res;
++}
++
++static inline void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
++                                pte_t *ptep , pte_t pte)
++{
++      if ((mm != current->mm && mm != &init_mm) ||
++          HYPERVISOR_update_va_mapping(addr, pte, 0))
++              xen_set_pte(ptep, pte);
++}
++
++static inline void xen_pte_clear(struct mm_struct *mm, unsigned long addr,
++                               pte_t *ptep)
++{
++      if ((mm != current->mm && mm != &init_mm)
++          || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
++              __xen_pte_clear(ptep);
++}
++
++#ifndef CONFIG_PARAVIRT
++/*
++ * Rules for using pte_update - it must be called after any PTE update which
++ * has not been done using the set_pte / clear_pte interfaces.  It is used by
++ * shadow mode hypervisors to resynchronize the shadow page tables.  Kernel PTE
++ * updates should either be sets, clears, or set_pte_atomic for P->P
++ * transitions, which means this hook should only be called for user PTEs.
++ * This hook implies a P->P protection or access change has taken place, which
++ * requires a subsequent TLB flush.  The notification can optionally be delayed
++ * until the TLB flush event by using the pte_update_defer form of the
++ * interface, but care must be taken to assure that the flush happens while
++ * still holding the same page table lock so that the shadow and primary pages
++ * do not become out of sync on SMP.
++ */
++#define pte_update(mm, addr, ptep)            do { } while (0)
++#define pte_update_defer(mm, addr, ptep)      do { } while (0)
++#endif
++
++/*
++ * We only update the dirty/accessed state if we set
++ * the dirty bit by hand in the kernel, since the hardware
++ * will do the accessed bit for us, and we don't want to
++ * race with other CPU's that might be updating the dirty
++ * bit at the same time.
++ */
++#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
++#define ptep_set_access_flags(vma, address, ptep, entry, dirty)               \
++({                                                                    \
++      int __changed = !pte_same(*(ptep), entry);                      \
++      if (__changed && (dirty)) {                                     \
++              if ( likely((vma)->vm_mm == current->mm) ) {            \
++                      BUG_ON(HYPERVISOR_update_va_mapping(address,    \
++                              entry,                                  \
++                              (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
++                                      UVMF_INVLPG|UVMF_MULTI));       \
++              } else {                                                \
++                      xen_l1_entry_update(ptep, entry);               \
++                      flush_tlb_page(vma, address);                   \
++              }                                                       \
++      }                                                               \
++      __changed;                                                      \
++})
++
++#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
++#define ptep_test_and_clear_young(vma, addr, ptep) ({                 \
++      int __ret = 0;                                                  \
++      if (pte_young(*(ptep)))                                         \
++              __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,          \
++                                         &(ptep)->pte);               \
++      if (__ret)                                                      \
++              pte_update((vma)->vm_mm, addr, ptep);                   \
++      __ret;                                                          \
++})
++
++#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
++#define ptep_clear_flush_young(vma, address, ptep)                    \
++({                                                                    \
++      pte_t __pte = *(ptep);                                          \
++      int __young = pte_young(__pte);                                 \
++      __pte = pte_mkold(__pte);                                       \
++      if (PagePinned(virt_to_page((vma)->vm_mm->pgd)))                \
++              (void)ptep_set_access_flags(vma, address, ptep, __pte, __young); \
++      else if (__young)                                               \
++              (ptep)->pte_low = __pte.pte_low;                        \
++      __young;                                                        \
++})
++
++#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
++#define ptep_clear_flush(vma, addr, ptep)                     \
++({                                                            \
++      pte_t *__ptep = (ptep);                                 \
++      pte_t __res = *__ptep;                                  \
++      if (!pte_none(__res) &&                                 \
++          ((vma)->vm_mm != current->mm ||                     \
++           HYPERVISOR_update_va_mapping(addr, __pte(0),       \
++                      (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
++                              UVMF_INVLPG|UVMF_MULTI))) {     \
++              __xen_pte_clear(__ptep);                        \
++              flush_tlb_page(vma, addr);                      \
++      }                                                       \
++      __res;                                                  \
++})
++
++#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
++static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
++{
++      pte_t pte = *ptep;
++      if (!pte_none(pte)
++          && (mm != &init_mm
++              || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))) {
++              pte = xen_ptep_get_and_clear(ptep, pte);
++              pte_update(mm, addr, ptep);
++      }
++      return pte;
++}
++
++#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
++#define ptep_get_and_clear_full(mm, addr, ptep, full)         \
++      ((full) ? ({                                            \
++              pte_t *__ptep = (ptep);                         \
++              pte_t __res = *__ptep;                          \
++              if (!PagePinned(virt_to_page((mm)->pgd)))       \
++                      __xen_pte_clear(__ptep);                \
++              else if (!pte_none(__res))                      \
++                      xen_l1_entry_update(__ptep, __pte(0));  \
++              __res;                                          \
++       }) :                                                   \
++       ptep_get_and_clear(mm, addr, ptep))
++
++pte_t xen_ptep_get_and_clear_full(struct vm_area_struct *, unsigned long, pte_t *, int);
++
++#define __HAVE_ARCH_PTEP_SET_WRPROTECT
++static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
++{
++      pte_t pte = *ptep;
++      if (pte_write(pte))
++              set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
++}
++
++#define arch_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable) \
++      xen_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable)
++
++#define arbitrary_virt_to_machine(va)                                 \
++({                                                                    \
++      unsigned int __lvl;                                             \
++      pte_t *__ptep = lookup_address((unsigned long)(va), &__lvl);    \
++      BUG_ON(!__ptep || __lvl != PG_LEVEL_4K || !pte_present(*__ptep));\
++      (((maddr_t)pte_mfn(*__ptep) << PAGE_SHIFT)                      \
++       | ((unsigned long)(va) & (PAGE_SIZE - 1)));                    \
++})
++
++#ifdef CONFIG_HIGHPTE
++#include <asm/io.h>
++struct page *kmap_atomic_to_page(void *);
++#define ptep_to_machine(ptep)                                         \
++({                                                                    \
++      pte_t *__ptep = (ptep);                                         \
++      page_to_phys(kmap_atomic_to_page(__ptep))                       \
++              | ((unsigned long)__ptep & (PAGE_SIZE - 1));            \
++})
++#else
++#define ptep_to_machine(ptep) virt_to_machine(ptep)
++#endif
++
++#include <asm-generic/pgtable.h>
++
++#include <xen/features.h>
++void make_page_readonly(void *va, unsigned int feature);
++void make_page_writable(void *va, unsigned int feature);
++void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
++void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
++
++struct vm_area_struct;
++
++int direct_remap_pfn_range(struct vm_area_struct *vma,
++                           unsigned long address,
++                           unsigned long mfn,
++                           unsigned long size,
++                           pgprot_t prot,
++                           domid_t  domid);
++int direct_kernel_remap_pfn_range(unsigned long address,
++                                unsigned long mfn,
++                                unsigned long size,
++                                pgprot_t prot,
++                                domid_t  domid);
++int create_lookup_pte_addr(struct mm_struct *mm,
++                           unsigned long address,
++                           uint64_t *ptep);
++int touch_pte_range(struct mm_struct *mm,
++                    unsigned long address,
++                    unsigned long size);
++
++int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
++              unsigned long addr, unsigned long end, pgprot_t newprot,
++              int dirty_accountable);
++
++#endif        /* __ASSEMBLY__ */
++
++#endif        /* _ASM_X86_PGTABLE_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pgtable-3level.h        2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pgtable-3level.h     2009-03-16 16:33:40.000000000 +0100
+@@ -18,16 +18,18 @@
+       printk("%s:%d: bad pgd %p(%016Lx pfn %08Lx).\n", __FILE__, __LINE__, \
+              &(e), __pgd_val(e), (pgd_val(e) & PTE_MASK) >> PAGE_SHIFT)
+-#define pud_none(pud)                         0
+-#define pud_bad(pud)                          0
+-#define pud_present(pud)                      1
 -/*
-- * CPUID functions returning a single datum
+- * All present pages with !NX bit are kernel-executable:
 - */
--static inline unsigned int cpuid_eax(unsigned int op)
--{
--      unsigned int eax, ebx, ecx, edx;
--
--      cpuid(op, &eax, &ebx, &ecx, &edx);
--      return eax;
--}
--static inline unsigned int cpuid_ebx(unsigned int op)
--{
--      unsigned int eax, ebx, ecx, edx;
--
--      cpuid(op, &eax, &ebx, &ecx, &edx);
--      return ebx;
--}
--static inline unsigned int cpuid_ecx(unsigned int op)
--{
--      unsigned int eax, ebx, ecx, edx;
--
--      cpuid(op, &eax, &ebx, &ecx, &edx);
--      return ecx;
--}
--static inline unsigned int cpuid_edx(unsigned int op)
--{
--      unsigned int eax, ebx, ecx, edx;
--
--      cpuid(op, &eax, &ebx, &ecx, &edx);
--      return edx;
+-static inline int pte_exec_kernel(pte_t pte)
++static inline int pud_none(pud_t pud)
++{
++      return __pud_val(pud) == 0;
++}
++static inline int pud_bad(pud_t pud)
+ {
+-      return !(__pte_val(pte) & _PAGE_NX);
++      return (__pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
++}
++static inline int pud_present(pud_t pud)
++{
++      return __pud_val(pud) & _PAGE_PRESENT;
+ }
+ /* Rules for using set_pte: the pte being assigned *must* be
+@@ -44,14 +46,6 @@ static inline void xen_set_pte(pte_t *pt
+       ptep->pte_low = pte.pte_low;
+ }
+-static inline void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
+-                                pte_t *ptep , pte_t pte)
+-{
+-      if ((mm != current->mm && mm != &init_mm) ||
+-          HYPERVISOR_update_va_mapping(addr, pte, 0))
+-              xen_set_pte(ptep, pte);
 -}
 -
--/* generic versions from gas */
--#define GENERIC_NOP1  ".byte 0x90\n"
--#define GENERIC_NOP2          ".byte 0x89,0xf6\n"
--#define GENERIC_NOP3        ".byte 0x8d,0x76,0x00\n"
--#define GENERIC_NOP4        ".byte 0x8d,0x74,0x26,0x00\n"
--#define GENERIC_NOP5        GENERIC_NOP1 GENERIC_NOP4
--#define GENERIC_NOP6  ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
--#define GENERIC_NOP7  ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
--#define GENERIC_NOP8  GENERIC_NOP1 GENERIC_NOP7
--
--/* Opteron nops */
--#define K8_NOP1 GENERIC_NOP1
--#define K8_NOP2       ".byte 0x66,0x90\n" 
--#define K8_NOP3       ".byte 0x66,0x66,0x90\n" 
--#define K8_NOP4       ".byte 0x66,0x66,0x66,0x90\n" 
--#define K8_NOP5       K8_NOP3 K8_NOP2 
--#define K8_NOP6       K8_NOP3 K8_NOP3
--#define K8_NOP7       K8_NOP4 K8_NOP3
--#define K8_NOP8       K8_NOP4 K8_NOP4
--
--/* K7 nops */
--/* uses eax dependencies (arbitary choice) */
--#define K7_NOP1  GENERIC_NOP1
--#define K7_NOP2       ".byte 0x8b,0xc0\n" 
--#define K7_NOP3       ".byte 0x8d,0x04,0x20\n"
--#define K7_NOP4       ".byte 0x8d,0x44,0x20,0x00\n"
--#define K7_NOP5       K7_NOP4 ASM_NOP1
--#define K7_NOP6       ".byte 0x8d,0x80,0,0,0,0\n"
--#define K7_NOP7        ".byte 0x8D,0x04,0x05,0,0,0,0\n"
--#define K7_NOP8        K7_NOP7 ASM_NOP1
--
--/* P6 nops */
--/* uses eax dependencies (Intel-recommended choice) */
--#define P6_NOP1       GENERIC_NOP1
--#define P6_NOP2       ".byte 0x66,0x90\n"
--#define P6_NOP3       ".byte 0x0f,0x1f,0x00\n"
--#define P6_NOP4       ".byte 0x0f,0x1f,0x40,0\n"
--#define P6_NOP5       ".byte 0x0f,0x1f,0x44,0x00,0\n"
--#define P6_NOP6       ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
--#define P6_NOP7       ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
--#define P6_NOP8       ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
--
--#ifdef CONFIG_MK8
--#define ASM_NOP1 K8_NOP1
--#define ASM_NOP2 K8_NOP2
--#define ASM_NOP3 K8_NOP3
--#define ASM_NOP4 K8_NOP4
--#define ASM_NOP5 K8_NOP5
--#define ASM_NOP6 K8_NOP6
--#define ASM_NOP7 K8_NOP7
--#define ASM_NOP8 K8_NOP8
--#elif defined(CONFIG_MK7)
--#define ASM_NOP1 K7_NOP1
--#define ASM_NOP2 K7_NOP2
--#define ASM_NOP3 K7_NOP3
--#define ASM_NOP4 K7_NOP4
--#define ASM_NOP5 K7_NOP5
--#define ASM_NOP6 K7_NOP6
--#define ASM_NOP7 K7_NOP7
--#define ASM_NOP8 K7_NOP8
--#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
--      defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
--      defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
--#define ASM_NOP1 P6_NOP1
--#define ASM_NOP2 P6_NOP2
--#define ASM_NOP3 P6_NOP3
--#define ASM_NOP4 P6_NOP4
--#define ASM_NOP5 P6_NOP5
--#define ASM_NOP6 P6_NOP6
--#define ASM_NOP7 P6_NOP7
--#define ASM_NOP8 P6_NOP8
--#else
--#define ASM_NOP1 GENERIC_NOP1
--#define ASM_NOP2 GENERIC_NOP2
--#define ASM_NOP3 GENERIC_NOP3
--#define ASM_NOP4 GENERIC_NOP4
--#define ASM_NOP5 GENERIC_NOP5
--#define ASM_NOP6 GENERIC_NOP6
--#define ASM_NOP7 GENERIC_NOP7
--#define ASM_NOP8 GENERIC_NOP8
--#endif
+ static inline void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
+ {
+       set_64bit((unsigned long long *)(ptep),__pte_val(pte));
+@@ -70,14 +64,11 @@ static inline void xen_set_pud(pud_t *pu
+  * entry, so clear the bottom half first and enforce ordering with a compiler
+  * barrier.
+  */
+-static inline void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
++static inline void __xen_pte_clear(pte_t *ptep)
+ {
+-      if ((mm != current->mm && mm != &init_mm)
+-          || HYPERVISOR_update_va_mapping(addr, __pte(0), 0)) {
+-              ptep->pte_low = 0;
+-              smp_wmb();
+-              ptep->pte_high = 0;
+-      }
++      ptep->pte_low = 0;
++      smp_wmb();
++      ptep->pte_high = 0;
+ }
+ static inline void xen_pmd_clear(pmd_t *pmd)
+@@ -85,21 +76,25 @@ static inline void xen_pmd_clear(pmd_t *
+       xen_l2_entry_update(pmd, __pmd(0));
+ }
+-#define set_pte(ptep, pte)                    xen_set_pte(ptep, pte)
+-#define set_pte_at(mm, addr, ptep, pte)               xen_set_pte_at(mm, addr, ptep, pte)
+-#define set_pte_atomic(ptep, pte)             xen_set_pte_atomic(ptep, pte)
+-#define set_pmd(pmdp, pmd)                    xen_set_pmd(pmdp, pmd)
+-#define set_pud(pudp, pud)                    xen_set_pud(pudp, pud)
+-#define pte_clear(mm, addr, ptep)             xen_pte_clear(mm, addr, ptep)
+-#define pmd_clear(pmd)                                xen_pmd_clear(pmd)
++static inline void pud_clear(pud_t *pudp)
++{
++      pgdval_t pgd;
++
++      set_pud(pudp, __pud(0));
+-/*
+- * Pentium-II erratum A13: in PAE mode we explicitly have to flush
+- * the TLB via cr3 if the top-level pgd is changed...
+- * We do not let the generic code free and clear pgd entries due to
+- * this erratum.
+- */
+-static inline void pud_clear (pud_t * pud) { }
++      /*
++       * According to Intel App note "TLBs, Paging-Structure Caches,
++       * and Their Invalidation", April 2007, document 317080-001,
++       * section 8.1: in PAE mode we explicitly have to flush the
++       * TLB via cr3 if the top-level pgd is changed...
++       *
++       * Make sure the pud entry we're updating is within the
++       * current pgd to avoid unnecessary TLB flushes.
++       */
++      pgd = read_cr3();
++      if (__pa(pudp) >= pgd && __pa(pudp) < (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
++              xen_tlb_flush();
++}
+ #define pud_page(pud) \
+ ((struct page *) __va(pud_val(pud) & PAGE_MASK))
+@@ -128,24 +123,6 @@ static inline pte_t xen_ptep_get_and_cle
+ #define xen_ptep_get_and_clear(xp, pte) xen_local_ptep_get_and_clear(xp, pte)
+ #endif
+-#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
+-#define ptep_clear_flush(vma, addr, ptep)                     \
+-({                                                            \
+-      pte_t *__ptep = (ptep);                                 \
+-      pte_t __res = *__ptep;                                  \
+-      if (!pte_none(__res) &&                                 \
+-          ((vma)->vm_mm != current->mm ||                     \
+-           HYPERVISOR_update_va_mapping(addr, __pte(0),       \
+-                      (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
+-                              UVMF_INVLPG|UVMF_MULTI))) {     \
+-              __ptep->pte_low = 0;                            \
+-              smp_wmb();                                      \
+-              __ptep->pte_high = 0;                           \
+-              flush_tlb_page(vma, addr);                      \
+-      }                                                       \
+-      __res;                                                  \
+-})
 -
--#define ASM_NOP_MAX 8
+ #define __HAVE_ARCH_PTE_SAME
+ static inline int pte_same(pte_t a, pte_t b)
+ {
+@@ -168,26 +145,12 @@ static inline int pte_none(pte_t pte)
+                      mfn_to_local_pfn(__pte_mfn(_pte)) :      \
+                      __pte_mfn(_pte))
+-extern unsigned long long __supported_pte_mask;
 -
--/* Prefetch instructions for Pentium III and AMD Athlon */
--/* It's not worth to care about 3dnow! prefetches for the K6
--   because they are microcoded there and very slow.
--   However we don't do prefetches for pre XP Athlons currently
--   That should be fixed. */
--#define ARCH_HAS_PREFETCH
--static inline void prefetch(const void *x)
+-static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 -{
--      alternative_input(ASM_NOP4,
--                        "prefetchnta (%1)",
--                        X86_FEATURE_XMM,
--                        "r" (x));
+-      return __pte((((unsigned long long)page_nr << PAGE_SHIFT) |
+-                    pgprot_val(pgprot)) & __supported_pte_mask);
 -}
 -
--#define ARCH_HAS_PREFETCH
--#define ARCH_HAS_PREFETCHW
--#define ARCH_HAS_SPINLOCK_PREFETCH
--
--/* 3dnow! prefetch to get an exclusive cache line. Useful for 
--   spinlocks to avoid one state transition in the cache coherency protocol. */
--static inline void prefetchw(const void *x)
+-static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
 -{
--      alternative_input(ASM_NOP4,
--                        "prefetchw (%1)",
--                        X86_FEATURE_3DNOW,
--                        "r" (x));
+-      return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) |
+-                    pgprot_val(pgprot)) & __supported_pte_mask);
 -}
--#define spin_lock_prefetch(x) prefetchw(x)
 -
--extern void select_idle_routine(const struct cpuinfo_x86 *c);
--
--#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
+ /*
+  * Bits 0, 6 and 7 are taken in the low part of the pte,
+  * put the 32 bits of offset into the high part.
+  */
+ #define pte_to_pgoff(pte) ((pte).pte_high)
+-#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
++#define pgoff_to_pte(off) ((pte_t) { { .pte_low = _PAGE_FILE, .pte_high = (off) } })
+ #define PTE_FILE_MAX_BITS       32
+ /* Encode and de-code a swap entry */
+@@ -195,8 +158,6 @@ static inline pmd_t pfn_pmd(unsigned lon
+ #define __swp_offset(x)                       ((x).val >> 5)
+ #define __swp_entry(type, offset)     ((swp_entry_t){(type) | (offset) << 5})
+ #define __pte_to_swp_entry(pte)               ((swp_entry_t){ (pte).pte_high })
+-#define __swp_entry_to_pte(x)         ((pte_t){ 0, (x).val })
 -
--extern unsigned long boot_option_idle_override;
--extern void enable_sep_cpu(void);
--extern int sysenter_setup(void);
+-#define __pmd_free_tlb(tlb, x)                do { } while (0)
++#define __swp_entry_to_pte(x)         ((pte_t){ { .pte_high = (x).val } })
+ #endif /* _I386_PGTABLE_3LEVEL_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pgtable_32.h    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pgtable_32.h 2009-03-16 16:33:40.000000000 +0100
+@@ -1,8 +1,6 @@
+ #ifndef _I386_PGTABLE_H
+ #define _I386_PGTABLE_H
+-#include <asm/hypervisor.h>
 -
--/* Defined in head.S */
--extern struct Xgt_desc_struct early_gdt_descr;
+ /*
+  * The Linux memory management assumes a three-level page table setup. On
+  * the i386, we use that, but "fold" the mid level into the top-level page
+@@ -25,20 +23,10 @@
+ struct vm_area_struct;
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+-extern unsigned long empty_zero_page[1024];
+ extern pgd_t *swapper_pg_dir;
+-extern struct kmem_cache *pmd_cache;
+-extern spinlock_t pgd_lock;
+-extern struct page *pgd_list;
+-void check_pgt_cache(void);
+-void pmd_ctor(struct kmem_cache *, void *);
+-void pgtable_cache_init(void);
++static inline void pgtable_cache_init(void) { }
++static inline void check_pgt_cache(void) { }
+ void paging_init(void);
+@@ -58,16 +46,9 @@ void paging_init(void);
+ #define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK    (~(PGDIR_SIZE-1))
+-#define USER_PTRS_PER_PGD     (TASK_SIZE/PGDIR_SIZE)
+-#define FIRST_USER_ADDRESS    0
 -
--extern void cpu_set_gdt(int);
--extern void switch_to_new_gdt(void);
--extern void cpu_init(void);
--extern void init_gdt(int cpu);
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+ #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
+-#define TWOLEVEL_PGDIR_SHIFT  22
+-#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+-#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
 -
--extern int force_mwait;
+ /* Just any arbitrary offset to the start of the vmalloc VM area: the
+  * current 8MB value just means that there will be a 8MB "hole" after the
+  * physical memory until the kernel virtual memory starts.  That means that
+@@ -78,121 +59,19 @@ void paging_init(void);
+ #define VMALLOC_OFFSET        (8*1024*1024)
+ #define VMALLOC_START (((unsigned long) high_memory + \
+                       2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))
+-#ifdef CONFIG_HIGHMEM
+-# define VMALLOC_END  (PKMAP_BASE-2*PAGE_SIZE)
+-#else
+-# define VMALLOC_END  (FIXADDR_START-2*PAGE_SIZE)
+-#endif
 -
--#endif /* __ASM_I386_PROCESSOR_H */
---- a/include/asm-x86/mach-xen/asm/processor_64.h
-+++ /dev/null
-@@ -1,461 +0,0 @@
 -/*
-- * include/asm-x86_64/processor.h
-- *
-- * Copyright (C) 1994 Linus Torvalds
+- * _PAGE_PSE set in the page directory entry just means that
+- * the page directory entry points directly to a 4MB-aligned block of
+- * memory. 
 - */
+-#define _PAGE_BIT_PRESENT     0
+-#define _PAGE_BIT_RW          1
+-#define _PAGE_BIT_USER                2
+-#define _PAGE_BIT_PWT         3
+-#define _PAGE_BIT_PCD         4
+-#define _PAGE_BIT_ACCESSED    5
+-#define _PAGE_BIT_DIRTY               6
+-#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page, Pentium+, if present.. */
+-#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
+-/*#define _PAGE_BIT_UNUSED1   9*/     /* available for programmer */
+-#define _PAGE_BIT_UNUSED2     10
+-#define _PAGE_BIT_UNUSED3     11
+-#define _PAGE_BIT_NX          63
 -
--#ifndef __ASM_X86_64_PROCESSOR_H
--#define __ASM_X86_64_PROCESSOR_H
+-#define _PAGE_PRESENT 0x001
+-#define _PAGE_RW      0x002
+-#define _PAGE_USER    0x004
+-#define _PAGE_PWT     0x008
+-#define _PAGE_PCD     0x010
+-#define _PAGE_ACCESSED        0x020
+-#define _PAGE_DIRTY   0x040
+-#define _PAGE_PSE     0x080   /* 4 MB (or 2MB) page, Pentium+, if present.. */
+-#define _PAGE_GLOBAL  0x100   /* Global TLB entry PPro+ */
+-/*#define _PAGE_UNUSED1       0x200*/ /* available for programmer */
+-#define _PAGE_UNUSED2 0x400
+-#define _PAGE_UNUSED3 0x800
 -
--#include <asm/segment.h>
--#include <asm/page.h>
--#include <asm/types.h>
--#include <asm/sigcontext.h>
--#include <asm/cpufeature.h>
--#include <linux/threads.h>
--#include <asm/msr.h>
--#include <asm/current.h>
--#include <asm/system.h>
--#include <asm/mmsegment.h>
--#include <asm/percpu.h>
--#include <linux/personality.h>
--#include <linux/cpumask.h>
--#include <asm/processor-flags.h>
+-/* If _PAGE_PRESENT is clear, we use these: */
+-#define _PAGE_FILE    0x040   /* nonlinear file mapping, saved PTE; unset:swap */
+-#define _PAGE_PROTNONE        0x080   /* if the user mapped it with PROT_NONE;
+-                                 pte_present gives true */
+ #ifdef CONFIG_X86_PAE
+-#define _PAGE_NX      (1ULL<<_PAGE_BIT_NX)
++#define LAST_PKMAP 512
+ #else
+-#define _PAGE_NX      0
++#define LAST_PKMAP 1024
+ #endif
+-/* Mapped page is I/O or foreign and has no associated page struct. */
+-#define _PAGE_IO      0x200
++#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK)
+-#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
+-#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+-#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
 -
--#define TF_MASK               0x00000100
--#define IF_MASK               0x00000200
--#define IOPL_MASK     0x00003000
--#define NT_MASK               0x00004000
--#define VM_MASK               0x00020000
--#define AC_MASK               0x00040000
--#define VIF_MASK      0x00080000      /* virtual interrupt flag */
--#define VIP_MASK      0x00100000      /* virtual interrupt pending */
--#define ID_MASK               0x00200000
+-#define PAGE_NONE \
+-      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+-#define PAGE_SHARED \
+-      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
 -
--#define desc_empty(desc) \
--               (!((desc)->a | (desc)->b))
+-#define PAGE_SHARED_EXEC \
+-      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
+-#define PAGE_COPY_NOEXEC \
+-      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+-#define PAGE_COPY_EXEC \
+-      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+-#define PAGE_COPY \
+-      PAGE_COPY_NOEXEC
+-#define PAGE_READONLY \
+-      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+-#define PAGE_READONLY_EXEC \
+-      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 -
--#define desc_equal(desc1, desc2) \
--               (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
+-#define _PAGE_KERNEL \
+-      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
+-#define _PAGE_KERNEL_EXEC \
+-      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+-
+-extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
+-#define __PAGE_KERNEL_RO              (__PAGE_KERNEL & ~_PAGE_RW)
+-#define __PAGE_KERNEL_RX              (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
+-#define __PAGE_KERNEL_NOCACHE         (__PAGE_KERNEL | _PAGE_PCD)
+-#define __PAGE_KERNEL_LARGE           (__PAGE_KERNEL | _PAGE_PSE)
+-#define __PAGE_KERNEL_LARGE_EXEC      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
+-
+-#define PAGE_KERNEL           __pgprot(__PAGE_KERNEL)
+-#define PAGE_KERNEL_RO                __pgprot(__PAGE_KERNEL_RO)
+-#define PAGE_KERNEL_EXEC      __pgprot(__PAGE_KERNEL_EXEC)
+-#define PAGE_KERNEL_RX                __pgprot(__PAGE_KERNEL_RX)
+-#define PAGE_KERNEL_NOCACHE   __pgprot(__PAGE_KERNEL_NOCACHE)
+-#define PAGE_KERNEL_LARGE     __pgprot(__PAGE_KERNEL_LARGE)
+-#define PAGE_KERNEL_LARGE_EXEC        __pgprot(__PAGE_KERNEL_LARGE_EXEC)
 -
 -/*
-- * Default implementation of macro that returns current
-- * instruction pointer ("program counter").
+- * The i386 can't do page protection for execute, and considers that
+- * the same are read. Also, write permissions imply read permissions.
+- * This is the closest we can get..
 - */
--#define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; })
+-#define __P000        PAGE_NONE
+-#define __P001        PAGE_READONLY
+-#define __P010        PAGE_COPY
+-#define __P011        PAGE_COPY
+-#define __P100        PAGE_READONLY_EXEC
+-#define __P101        PAGE_READONLY_EXEC
+-#define __P110        PAGE_COPY_EXEC
+-#define __P111        PAGE_COPY_EXEC
 -
+-#define __S000        PAGE_NONE
+-#define __S001        PAGE_READONLY
+-#define __S010        PAGE_SHARED
+-#define __S011        PAGE_SHARED
+-#define __S100        PAGE_READONLY_EXEC
+-#define __S101        PAGE_READONLY_EXEC
+-#define __S110        PAGE_SHARED_EXEC
+-#define __S111        PAGE_SHARED_EXEC
++#ifdef CONFIG_HIGHMEM
++# define VMALLOC_END  (PKMAP_BASE-2*PAGE_SIZE)
++#else
++# define VMALLOC_END  (FIXADDR_START-2*PAGE_SIZE)
++#endif
+ /*
+  * Define this if things work differently on an i386 and an i486:
+@@ -221,28 +100,6 @@ extern unsigned long pg0[];
+ #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 -/*
-- *  CPU type and hardware bug flags. Kept separately for each CPU.
+- * The following only work if pte_present() is true.
+- * Undefined behaviour if not..
 - */
+-static inline int pte_dirty(pte_t pte)                { return (pte).pte_low & _PAGE_DIRTY; }
+-static inline int pte_young(pte_t pte)                { return (pte).pte_low & _PAGE_ACCESSED; }
+-static inline int pte_write(pte_t pte)                { return (pte).pte_low & _PAGE_RW; }
+-static inline int pte_huge(pte_t pte)         { return (pte).pte_low & _PAGE_PSE; }
 -
--struct cpuinfo_x86 {
--      __u8    x86;            /* CPU family */
--      __u8    x86_vendor;     /* CPU vendor */
--      __u8    x86_model;
--      __u8    x86_mask;
--      int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
--      __u32   x86_capability[NCAPINTS];
--      char    x86_vendor_id[16];
--      char    x86_model_id[64];
--      int     x86_cache_size;  /* in KB */
--      int     x86_clflush_size;
--      int     x86_cache_alignment;
--      int     x86_tlbsize;    /* number of 4K pages in DTLB/ITLB combined(in pages)*/
--        __u8    x86_virt_bits, x86_phys_bits;
--      __u8    x86_max_cores;  /* cpuid returned max cores value */
--        __u32   x86_power;    
--      __u32   extended_cpuid_level;   /* Max extended CPUID function supported */
--      unsigned long loops_per_jiffy;
--#ifdef CONFIG_SMP
--      cpumask_t llc_shared_map;       /* cpus sharing the last level cache */
--#endif
--      __u8    apicid;
--#ifdef CONFIG_SMP
--      __u8    booted_cores;   /* number of cores as seen by OS */
--      __u8    phys_proc_id;   /* Physical Processor id. */
--      __u8    cpu_core_id;    /* Core id. */
--      __u8    cpu_index;      /* index into per_cpu list */
--#endif
--} ____cacheline_aligned;
--
--#define X86_VENDOR_INTEL 0
--#define X86_VENDOR_CYRIX 1
--#define X86_VENDOR_AMD 2
--#define X86_VENDOR_UMC 3
--#define X86_VENDOR_NEXGEN 4
--#define X86_VENDOR_CENTAUR 5
--#define X86_VENDOR_TRANSMETA 7
--#define X86_VENDOR_NUM 8
--#define X86_VENDOR_UNKNOWN 0xff
+-/*
+- * The following only works if pte_present() is not true.
+- */
+-static inline int pte_file(pte_t pte)         { return (pte).pte_low & _PAGE_FILE; }
 -
--#ifdef CONFIG_SMP
--DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
--#define cpu_data(cpu)         per_cpu(cpu_info, cpu)
--#define current_cpu_data      cpu_data(smp_processor_id())
--#else
--#define cpu_data(cpu)         boot_cpu_data
--#define current_cpu_data      boot_cpu_data
--#endif
+-static inline pte_t pte_mkclean(pte_t pte)    { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
+-static inline pte_t pte_mkold(pte_t pte)      { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
+-static inline pte_t pte_wrprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_RW; return pte; }
+-static inline pte_t pte_mkdirty(pte_t pte)    { (pte).pte_low |= _PAGE_DIRTY; return pte; }
+-static inline pte_t pte_mkyoung(pte_t pte)    { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
+-static inline pte_t pte_mkwrite(pte_t pte)    { (pte).pte_low |= _PAGE_RW; return pte; }
+-static inline pte_t pte_mkhuge(pte_t pte)     { (pte).pte_low |= _PAGE_PSE; return pte; }
 -
--extern char ignore_irq13;
+ #ifdef CONFIG_X86_PAE
+ # include <asm/pgtable-3level.h>
+ #else
+@@ -250,111 +107,6 @@ static inline pte_t pte_mkhuge(pte_t pte
+ #endif
+ /*
+- * Rules for using pte_update - it must be called after any PTE update which
+- * has not been done using the set_pte / clear_pte interfaces.  It is used by
+- * shadow mode hypervisors to resynchronize the shadow page tables.  Kernel PTE
+- * updates should either be sets, clears, or set_pte_atomic for P->P
+- * transitions, which means this hook should only be called for user PTEs.
+- * This hook implies a P->P protection or access change has taken place, which
+- * requires a subsequent TLB flush.  The notification can optionally be delayed
+- * until the TLB flush event by using the pte_update_defer form of the
+- * interface, but care must be taken to assure that the flush happens while
+- * still holding the same page table lock so that the shadow and primary pages
+- * do not become out of sync on SMP.
+- */
+-#define pte_update(mm, addr, ptep)            do { } while (0)
+-#define pte_update_defer(mm, addr, ptep)      do { } while (0)
 -
--extern void identify_cpu(struct cpuinfo_x86 *);
--extern void print_cpu_info(struct cpuinfo_x86 *);
--extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
--extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
--extern unsigned short num_cache_leaves;
+-/* local pte updates need not use xchg for locking */
+-static inline pte_t xen_local_ptep_get_and_clear(pte_t *ptep, pte_t res)
+-{
+-      xen_set_pte(ptep, __pte(0));
+-      return res;
+-}
 -
 -/*
-- * Save the cr4 feature set we're using (ie
-- * Pentium 4MB enable and PPro Global page
-- * enable), so that any CPU's that boot up
-- * after us can get the correct flags.
+- * We only update the dirty/accessed state if we set
+- * the dirty bit by hand in the kernel, since the hardware
+- * will do the accessed bit for us, and we don't want to
+- * race with other CPU's that might be updating the dirty
+- * bit at the same time.
 - */
--extern unsigned long mmu_cr4_features;
+-#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+-#define ptep_set_access_flags(vma, address, ptep, entry, dirty)               \
+-({                                                                    \
+-      int __changed = !pte_same(*(ptep), entry);                      \
+-      if (__changed && (dirty)) {                                     \
+-              if ( likely((vma)->vm_mm == current->mm) ) {            \
+-                      BUG_ON(HYPERVISOR_update_va_mapping(address,    \
+-                              entry,                                  \
+-                              (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
+-                                      UVMF_INVLPG|UVMF_MULTI));       \
+-              } else {                                                \
+-                      xen_l1_entry_update(ptep, entry);               \
+-                      flush_tlb_page(vma, address);                   \
+-              }                                                       \
+-      }                                                               \
+-      __changed;                                                      \
+-})
 -
--static inline void set_in_cr4 (unsigned long mask)
+-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+-#define ptep_test_and_clear_young(vma, addr, ptep) ({                 \
+-      int __ret = 0;                                                  \
+-      if (pte_young(*(ptep)))                                         \
+-              __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,          \
+-                                              &(ptep)->pte_low);      \
+-      if (__ret)                                                      \
+-              pte_update((vma)->vm_mm, addr, ptep);                   \
+-      __ret;                                                          \
+-})
+-
+-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+-#define ptep_clear_flush_young(vma, address, ptep)                    \
+-({                                                                    \
+-      pte_t __pte = *(ptep);                                          \
+-      int __young = pte_young(__pte);                                 \
+-      __pte = pte_mkold(__pte);                                       \
+-      if (PagePinned(virt_to_page((vma)->vm_mm->pgd)))                \
+-              (void)ptep_set_access_flags(vma, address, ptep, __pte, __young); \
+-      else if (__young)                                               \
+-              (ptep)->pte_low = __pte.pte_low;                        \
+-      __young;                                                        \
+-})
+-
+-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 -{
--      mmu_cr4_features |= mask;
--      __asm__("movq %%cr4,%%rax\n\t"
--              "orq %0,%%rax\n\t"
--              "movq %%rax,%%cr4\n"
--              : : "irg" (mask)
--              :"ax");
+-      pte_t pte = *ptep;
+-      if (!pte_none(pte)
+-          && (mm != &init_mm
+-              || HYPERVISOR_update_va_mapping(addr, __pte(0), 0))) {
+-              pte = xen_ptep_get_and_clear(ptep, pte);
+-              pte_update(mm, addr, ptep);
+-      }
+-      return pte;
 -}
 -
--static inline void clear_in_cr4 (unsigned long mask)
+-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+-#define ptep_get_and_clear_full(mm, addr, ptep, full)                 \
+-      ((full) ? ({                                                    \
+-              pte_t __res = *(ptep);                                  \
+-              if (PagePinned(virt_to_page((mm)->pgd)))                \
+-                      xen_l1_entry_update(ptep, __pte(0));            \
+-              else                                                    \
+-                      *(ptep) = __pte(0);                             \
+-              __res;                                                  \
+-       }) :                                                           \
+-       ptep_get_and_clear(mm, addr, ptep))
+-
+-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 -{
--      mmu_cr4_features &= ~mask;
--      __asm__("movq %%cr4,%%rax\n\t"
--              "andq %0,%%rax\n\t"
--              "movq %%rax,%%cr4\n"
--              : : "irg" (~mask)
--              :"ax");
+-      pte_t pte = *ptep;
+-      if (pte_write(pte))
+-              set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
 -}
 -
--
 -/*
-- * User space process size. 47bits minus one guard page.
-- */
--#define TASK_SIZE64   (0x800000000000UL - 4096)
+  * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
+  *
+  *  dst - pointer to pgd range anwhere on a pgd page
+@@ -383,26 +135,6 @@ static inline void clone_pgd_range(pgd_t
+ #define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
+-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+-{
+-      /*
+-       * Since this might change the present bit (which controls whether
+-       * a pte_t object has undergone p2m translation), we must use
+-       * pte_val() on the input pte and __pte() for the return value.
+-       */
+-      paddr_t pteval = pte_val(pte);
 -
--/* This decides where the kernel will search for a free chunk of vm
-- * space during mmap's.
-- */
--#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
+-      pteval &= _PAGE_CHG_MASK;
+-      pteval |= pgprot_val(newprot);
+-#ifdef CONFIG_X86_PAE
+-      pteval &= __supported_pte_mask;
+-#endif
+-      return __pte(pteval);
+-}
 -
--#define TASK_SIZE             (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
--#define TASK_SIZE_OF(child)   ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
+-#define pmd_large(pmd) \
+-((__pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
 -
--#define TASK_UNMAPPED_BASE    PAGE_ALIGN(TASK_SIZE/3)
+ /*
+  * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
+  *
+@@ -424,6 +156,8 @@ static inline pte_t pte_modify(pte_t pte
+  */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, address)
++static inline int pud_large(pud_t pud) { return 0; }
++
+ /*
+  * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+  *
+@@ -449,26 +183,6 @@ static inline pte_t pte_modify(pte_t pte
+ #define pmd_page_vaddr(pmd) \
+               ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+-/*
+- * Helper function that returns the kernel pagetable entry controlling
+- * the virtual address 'address'. NULL means no pagetable entry present.
+- * NOTE: the return type is pte_t but if the pmd is PSE then we return it
+- * as a pte too.
+- */
+-extern pte_t *lookup_address(unsigned long address);
 -
 -/*
-- * Size of io_bitmap.
+- * Make a given kernel text page executable/non-executable.
+- * Returns the previous executability setting of that page (which
+- * is used to restore the previous state). Used by the SMP bootup code.
+- * NOTE: this is an __init function for security reasons.
 - */
--#define IO_BITMAP_BITS  65536
--#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
--#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
--#ifndef CONFIG_X86_NO_TSS
--#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
+-#ifdef CONFIG_X86_PAE
+- extern int set_kernel_exec(unsigned long vaddr, int enable);
+-#else
+- static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;}
 -#endif
--#define INVALID_IO_BITMAP_OFFSET 0x8000
 -
--struct i387_fxsave_struct {
--      u16     cwd;
--      u16     swd;
--      u16     twd;
--      u16     fop;
--      u64     rip;
--      u64     rdp; 
--      u32     mxcsr;
--      u32     mxcsr_mask;
--      u32     st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
--      u32     xmm_space[64];  /* 16*16 bytes for each XMM-reg = 256 bytes */
--      u32     padding[24];
--} __attribute__ ((aligned (16)));
+ #if defined(CONFIG_HIGHPTE)
+ #define pte_offset_map(dir, address) \
+       ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
+@@ -496,72 +210,22 @@ extern pte_t *lookup_address(unsigned lo
+  */
+ #define update_mmu_cache(vma,address,pte) do { } while (0)
+-#include <xen/features.h>
+ void make_lowmem_page_readonly(void *va, unsigned int feature);
+ void make_lowmem_page_writable(void *va, unsigned int feature);
+-void make_page_readonly(void *va, unsigned int feature);
+-void make_page_writable(void *va, unsigned int feature);
+-void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
+-void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
 -
--union i387_union {
--      struct i387_fxsave_struct       fxsave;
--};
+-#define virt_to_ptep(va)                                              \
+-({                                                                    \
+-      pte_t *__ptep = lookup_address((unsigned long)(va));            \
+-      BUG_ON(!__ptep || !pte_present(*__ptep));                       \
+-      __ptep;                                                         \
+-})
 -
--#ifndef CONFIG_X86_NO_TSS
--struct tss_struct {
--      u32 reserved1;
--      u64 rsp0;       
--      u64 rsp1;
--      u64 rsp2;
--      u64 reserved2;
--      u64 ist[7];
--      u32 reserved3;
--      u32 reserved4;
--      u16 reserved5;
--      u16 io_bitmap_base;
--      /*
--       * The extra 1 is there because the CPU will access an
--       * additional byte beyond the end of the IO permission
--       * bitmap. The extra byte must be all 1 bits, and must
--       * be within the limit. Thus we have:
--       *
--       * 128 bytes, the bitmap itself, for ports 0..0x3ff
--       * 8 bytes, for an extra "long" of ~0UL
--       */
--      unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
--} __attribute__((packed)) ____cacheline_aligned;
+-#define arbitrary_virt_to_machine(va)                                 \
+-      (((maddr_t)pte_mfn(*virt_to_ptep(va)) << PAGE_SHIFT)            \
+-       | ((unsigned long)(va) & (PAGE_SIZE - 1)))
 -
--DECLARE_PER_CPU(struct tss_struct,init_tss);
+-#ifdef CONFIG_HIGHPTE
+-#include <asm/io.h>
+-struct page *kmap_atomic_to_page(void *);
+-#define ptep_to_machine(ptep)                                         \
+-({                                                                    \
+-      pte_t *__ptep = (ptep);                                         \
+-      page_to_phys(kmap_atomic_to_page(__ptep))                       \
+-              | ((unsigned long)__ptep & (PAGE_SIZE - 1));            \
+-})
+-#else
+-#define ptep_to_machine(ptep) virt_to_machine(ptep)
 -#endif
+ #endif /* !__ASSEMBLY__ */
++/*
++ * kern_addr_valid() is (1) for FLATMEM and (0) for
++ * SPARSEMEM and DISCONTIGMEM
++ */
+ #ifdef CONFIG_FLATMEM
+ #define kern_addr_valid(addr) (1)
+-#endif /* CONFIG_FLATMEM */
 -
+-int direct_remap_pfn_range(struct vm_area_struct *vma,
+-                           unsigned long address, 
+-                           unsigned long mfn,
+-                           unsigned long size, 
+-                           pgprot_t prot,
+-                           domid_t  domid);
+-int direct_kernel_remap_pfn_range(unsigned long address, 
+-                                unsigned long mfn,
+-                                unsigned long size, 
+-                                pgprot_t prot,
+-                                domid_t  domid);
+-int create_lookup_pte_addr(struct mm_struct *mm,
+-                           unsigned long address,
+-                           uint64_t *ptep);
+-int touch_pte_range(struct mm_struct *mm,
+-                    unsigned long address,
+-                    unsigned long size);
 -
--extern struct cpuinfo_x86 boot_cpu_data;
--#ifndef CONFIG_X86_NO_TSS
--/* Save the original ist values for checking stack pointers during debugging */
--struct orig_ist {
--      unsigned long ist[7];
--};
--DECLARE_PER_CPU(struct orig_ist, orig_ist);
--#endif
+-int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
+-              unsigned long addr, unsigned long end, pgprot_t newprot,
+-              int dirty_accountable);
 -
--#ifdef CONFIG_X86_VSMP
--#define ARCH_MIN_TASKALIGN    (1 << INTERNODE_CACHE_SHIFT)
--#define ARCH_MIN_MMSTRUCT_ALIGN       (1 << INTERNODE_CACHE_SHIFT)
--#else
--#define ARCH_MIN_TASKALIGN    16
--#define ARCH_MIN_MMSTRUCT_ALIGN       0
--#endif
+-#define arch_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable) \
+-      xen_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable)
++#else
++#define kern_addr_valid(kaddr)        (0)
++#endif
+ #define io_remap_pfn_range(vma,from,pfn,size,prot) \
+ direct_remap_pfn_range(vma,from,pfn,size,prot,DOMID_IO)
+-#include <asm-generic/pgtable.h>
 -
--struct thread_struct {
--      unsigned long   rsp0;
--      unsigned long   rsp;
--      unsigned long   userrsp;        /* Copy from PDA */ 
--      unsigned long   fs;
--      unsigned long   gs;
--      unsigned short  es, ds, fsindex, gsindex;       
--/* Hardware debugging registers */
--      unsigned long   debugreg0;  
--      unsigned long   debugreg1;  
--      unsigned long   debugreg2;  
--      unsigned long   debugreg3;  
--      unsigned long   debugreg6;  
--      unsigned long   debugreg7;  
--/* fault info */
--      unsigned long   cr2, trap_no, error_code;
--/* floating point info */
--      union i387_union        i387  __attribute__((aligned(16)));
--/* IO permissions. the bitmap could be moved into the GDT, that would make
--   switch faster for a limited number of ioperm using tasks. -AK */
--      int             ioperm;
--      unsigned long   *io_bitmap_ptr;
--      unsigned io_bitmap_max;
--/* cached TLS descriptors. */
--      u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
--      unsigned int    iopl;
--} __attribute__((aligned(16)));
+ #endif /* _I386_PGTABLE_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/pgtable_64.h    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/pgtable_64.h 2009-03-16 16:33:40.000000000 +0100
+@@ -13,49 +13,26 @@
+ #include <linux/threads.h>
+ #include <linux/sched.h>
+ #include <asm/pda.h>
+-#ifdef CONFIG_XEN
+-#include <asm/hypervisor.h>
++#ifdef CONFIG_XEN
+ extern pud_t level3_user_pgt[512];
+ extern void xen_init_pt(void);
 -
--#define INIT_THREAD  { \
--      .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
--}
+-extern pte_t *lookup_address(unsigned long address);
 -
--#ifndef CONFIG_X86_NO_TSS
--#define INIT_TSS  { \
--      .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
--}
--#endif
+-#define virt_to_ptep(va)                                              \
+-({                                                                    \
+-      pte_t *__ptep = lookup_address((unsigned long)(va));            \
+-      BUG_ON(!__ptep || !pte_present(*__ptep));                       \
+-      __ptep;                                                         \
+-})
 -
--#define INIT_MMAP \
--{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+-#define arbitrary_virt_to_machine(va)                                 \
+-      (((maddr_t)pte_mfn(*virt_to_ptep(va)) << PAGE_SHIFT)            \
+-       | ((unsigned long)(va) & (PAGE_SIZE - 1)))
 -
--#define start_thread(regs,new_rip,new_rsp) do { \
--      asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));      \
--      load_gs_index(0);                                                       \
--      (regs)->rip = (new_rip);                                                 \
--      (regs)->rsp = (new_rsp);                                                 \
--      write_pda(oldrsp, (new_rsp));                                            \
--      (regs)->cs = __USER_CS;                                                  \
--      (regs)->ss = __USER_DS;                                                  \
--      (regs)->eflags = 0x200;                                                  \
--      set_fs(USER_DS);                                                         \
--} while(0) 
+-#define ptep_to_machine(ptep) virt_to_machine(ptep)
+ #endif
+ extern pud_t level3_kernel_pgt[512];
+ extern pud_t level3_ident_pgt[512];
+ extern pmd_t level2_kernel_pgt[512];
+ extern pgd_t init_level4_pgt[];
+-extern unsigned long __supported_pte_mask;
+ #define swapper_pg_dir init_level4_pgt
+ extern void paging_init(void);
+-extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
+-
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
+-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+ #endif /* !__ASSEMBLY__ */
++#define SHARED_KERNEL_PMD     1
++
+ /*
+  * PGDIR_SHIFT determines what a top-level page table entry can map
+  */
+@@ -98,31 +75,63 @@ extern unsigned long empty_zero_page[PAG
+ #define pgd_none(x)   (!__pgd_val(x))
+ #define pud_none(x)   (!__pud_val(x))
+-static inline void set_pte(pte_t *dst, pte_t val)
++struct mm_struct;
++
++#define __xen_pte_clear(ptep) xen_set_pte(ptep, __pte(0))
++
++static inline void xen_set_pte(pte_t *ptep, pte_t pte)
++{
++      *ptep = pte;
++}
++
++static inline void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
+ {
+-      *dst = val;
++      xen_set_pte(ptep, pte);
+ }
+-#define set_pmd(pmdptr, pmdval) xen_l2_entry_update(pmdptr, (pmdval))
+-#define set_pud(pudptr, pudval) xen_l3_entry_update(pudptr, (pudval))
+-#define set_pgd(pgdptr, pgdval) xen_l4_entry_update(pgdptr, (pgdval))
++#ifdef CONFIG_SMP
++static inline pte_t xen_ptep_get_and_clear(pte_t *xp, pte_t ret)
++{
++      return __pte_ma(xchg(&xp->pte, 0));
++}
++#else
++#define xen_ptep_get_and_clear(xp, pte) xen_local_ptep_get_and_clear(xp, pte)
++#endif
+-static inline void pud_clear (pud_t * pud)
++static inline void xen_set_pmd(pmd_t *pmdp, pmd_t pmd)
+ {
+-      set_pud(pud, __pud(0));
++      xen_l2_entry_update(pmdp, pmd);
++}
++
++static inline void xen_pmd_clear(pmd_t *pmd)
++{
++      xen_set_pmd(pmd, xen_make_pmd(0));
++}
++
++static inline void xen_set_pud(pud_t *pudp, pud_t pud)
++{
++      xen_l3_entry_update(pudp, pud);
++}
++
++static inline void xen_pud_clear(pud_t *pud)
++{
++      xen_set_pud(pud, xen_make_pud(0));
+ }
+ #define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
+-static inline void pgd_clear (pgd_t * pgd)
++static inline void xen_set_pgd(pgd_t *pgdp, pgd_t pgd)
+ {
+-        set_pgd(pgd, __pgd(0));
+-        set_pgd(__user_pgd(pgd), __pgd(0));
++      xen_l4_entry_update(pgdp, pgd);
+ }
+-#define pte_same(a, b)                ((a).pte == (b).pte)
++static inline void xen_pgd_clear(pgd_t * pgd)
++{
++      xen_set_pgd(pgd, xen_make_pgd(0));
++      xen_set_pgd(__user_pgd(pgd), xen_make_pgd(0));
++}
+-#define pte_pgprot(a) (__pgprot((a).pte & ~PHYSICAL_PAGE_MASK))
++#define pte_same(a, b)                ((a).pte == (b).pte)
+ #endif /* !__ASSEMBLY__ */
+@@ -133,8 +142,6 @@ static inline void pgd_clear (pgd_t * pg
+ #define PGDIR_SIZE    (_AC(1,UL) << PGDIR_SHIFT)
+ #define PGDIR_MASK    (~(PGDIR_SIZE-1))
+-#define USER_PTRS_PER_PGD     ((TASK_SIZE-1)/PGDIR_SIZE+1)
+-#define FIRST_USER_ADDRESS    0
+ #define MAXMEM                 _AC(0x3fffffffffff, UL)
+ #define VMALLOC_START    _AC(0xffffc20000000000, UL)
+@@ -144,105 +151,6 @@ static inline void pgd_clear (pgd_t * pg
+ #define MODULES_END      _AC(0xfffffffffff00000, UL)
+ #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
+-#define _PAGE_BIT_PRESENT     0
+-#define _PAGE_BIT_RW          1
+-#define _PAGE_BIT_USER                2
+-#define _PAGE_BIT_PWT         3
+-#define _PAGE_BIT_PCD         4
+-#define _PAGE_BIT_ACCESSED    5
+-#define _PAGE_BIT_DIRTY               6
+-#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page */
+-#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
+-#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
+-
+-#define _PAGE_PRESENT 0x001
+-#define _PAGE_RW      0x002
+-#define _PAGE_USER    0x004
+-#define _PAGE_PWT     0x008
+-#define _PAGE_PCD     0x010
+-#define _PAGE_ACCESSED        0x020
+-#define _PAGE_DIRTY   0x040
+-#define _PAGE_PSE     0x080   /* 2MB page */
+-#define _PAGE_FILE    0x040   /* nonlinear file mapping, saved PTE; unset:swap */
+-#define _PAGE_GLOBAL  0x100   /* Global TLB entry */
 -
--#define get_debugreg(var, register)                           \
--      var = HYPERVISOR_get_debugreg(register)
--#define set_debugreg(value, register) do {                    \
--      if (HYPERVISOR_set_debugreg(register, value))           \
--              BUG();                                          \
--} while (0)
+-#define _PAGE_PROTNONE        0x080   /* If not present */
+-#define _PAGE_NX        (_AC(1,UL)<<_PAGE_BIT_NX)
 -
--struct task_struct;
--struct mm_struct;
+-/* Mapped page is I/O or foreign and has no associated page struct. */
+-#define _PAGE_IO      0x200
 -
--/* Free all resources held by a thread. */
--extern void release_thread(struct task_struct *);
+-#ifndef __ASSEMBLY__
+-#if CONFIG_XEN_COMPAT <= 0x030002
+-extern unsigned int __kernel_page_user;
+-#else
+-#define __kernel_page_user 0
+-#endif
+-#endif
 -
--/* Prepare to copy thread state - unlazy all lazy status */
--extern void prepare_to_copy(struct task_struct *tsk);
+-#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
+-#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
 -
--/*
-- * create a kernel thread without removing it from tasklists
-- */
--extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+-#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_IO)
+-
+-#define PAGE_NONE     __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+-#define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+-#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
+-#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+-#define PAGE_COPY PAGE_COPY_NOEXEC
+-#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+-#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+-#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+-#define __PAGE_KERNEL \
+-      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
+-#define __PAGE_KERNEL_EXEC \
+-      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | __kernel_page_user)
+-#define __PAGE_KERNEL_NOCACHE \
+-      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
+-#define __PAGE_KERNEL_RO \
+-      (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
+-#define __PAGE_KERNEL_VSYSCALL \
+-      (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+-#define __PAGE_KERNEL_VSYSCALL_NOCACHE \
+-      (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
+-#define __PAGE_KERNEL_LARGE \
+-      (__PAGE_KERNEL | _PAGE_PSE)
+-#define __PAGE_KERNEL_LARGE_EXEC \
+-      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
 -
 -/*
-- * Return saved PC of a blocked thread.
-- * What is this good for? it will be always the scheduler or ret_from_fork.
+- * We don't support GLOBAL page in xenolinux64
 - */
--#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8))
--
--extern unsigned long get_wchan(struct task_struct *p);
--#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
--#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
--#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
+-#define MAKE_GLOBAL(x) __pgprot((x))
 -
+-#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
+-#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
+-#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
+-#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+-#define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
+-#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
+-#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
+-#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
 -
--struct microcode_header {
--      unsigned int hdrver;
--      unsigned int rev;
--      unsigned int date;
--      unsigned int sig;
--      unsigned int cksum;
--      unsigned int ldrver;
--      unsigned int pf;
--      unsigned int datasize;
--      unsigned int totalsize;
--      unsigned int reserved[3];
--};
+-/*         xwr */
+-#define __P000        PAGE_NONE
+-#define __P001        PAGE_READONLY
+-#define __P010        PAGE_COPY
+-#define __P011        PAGE_COPY
+-#define __P100        PAGE_READONLY_EXEC
+-#define __P101        PAGE_READONLY_EXEC
+-#define __P110        PAGE_COPY_EXEC
+-#define __P111        PAGE_COPY_EXEC
 -
--struct microcode {
--      struct microcode_header hdr;
--      unsigned int bits[0];
--};
+-#define __S000        PAGE_NONE
+-#define __S001        PAGE_READONLY
+-#define __S010        PAGE_SHARED
+-#define __S011        PAGE_SHARED
+-#define __S100        PAGE_READONLY_EXEC
+-#define __S101        PAGE_READONLY_EXEC
+-#define __S110        PAGE_SHARED_EXEC
+-#define __S111        PAGE_SHARED_EXEC
 -
--typedef struct microcode microcode_t;
--typedef struct microcode_header microcode_header_t;
+ #ifndef __ASSEMBLY__
+ static inline unsigned long pgd_bad(pgd_t pgd)
+@@ -260,119 +168,26 @@ static inline unsigned long pmd_bad(pmd_
+       return __pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
+ }
+-#define set_pte_at(_mm,addr,ptep,pteval) do {                         \
+-      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
+-          HYPERVISOR_update_va_mapping((addr), (pteval), 0))          \
+-              set_pte((ptep), (pteval));                              \
+-} while (0)
 -
--/* microcode format is extended from prescott processors */
--struct extended_signature {
--      unsigned int sig;
--      unsigned int pf;
--      unsigned int cksum;
--};
+ #define pte_none(x)   (!(x).pte)
+ #define pte_present(x)        ((x).pte & (_PAGE_PRESENT | _PAGE_PROTNONE))
+-#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+-#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
++#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))       /* FIXME: is this right? */
+ #define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
+ #define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
+       __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+-#define pte_pfn(_pte) ((_pte).pte & _PAGE_IO ? end_pfn :      \
++#define pte_pfn(_pte) ((_pte).pte & _PAGE_IO ? max_mapnr :    \
+                      (_pte).pte & _PAGE_PRESENT ?             \
+                      mfn_to_local_pfn(__pte_mfn(_pte)) :      \
+                      __pte_mfn(_pte))
+ #define pte_page(x)   pfn_to_page(pte_pfn(x))
+-static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
+-{
+-      unsigned long pte = page_nr << PAGE_SHIFT;
+-      pte |= pgprot_val(pgprot);
+-      pte &= __supported_pte_mask;
+-      return __pte(pte);
+-}
 -
--struct extended_sigtable {
--      unsigned int count;
--      unsigned int cksum;
--      unsigned int reserved[3];
--      struct extended_signature sigs[0];
--};
+-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+-{
+-      pte_t pte = *ptep;
+-      if (!pte_none(pte)) {
+-              if ((mm != &init_mm) ||
+-                  HYPERVISOR_update_va_mapping(addr, __pte(0), 0))
+-                      pte = __pte_ma(xchg(&ptep->pte, 0));
+-      }
+-      return pte;
+-}
 -
+-static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
+-{
+-      if (full) {
+-              pte_t pte = *ptep;
+-              if (PagePinned(virt_to_page(mm->pgd)))
+-                      xen_l1_entry_update(ptep, __pte(0));
+-              else
+-                      *ptep = __pte(0);
+-              return pte;
+-      }
+-      return ptep_get_and_clear(mm, addr, ptep);
+-}
 -
--#if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2)
--#define ASM_NOP1 P6_NOP1
--#define ASM_NOP2 P6_NOP2
--#define ASM_NOP3 P6_NOP3
--#define ASM_NOP4 P6_NOP4
--#define ASM_NOP5 P6_NOP5
--#define ASM_NOP6 P6_NOP6
--#define ASM_NOP7 P6_NOP7
--#define ASM_NOP8 P6_NOP8
--#else
--#define ASM_NOP1 K8_NOP1
--#define ASM_NOP2 K8_NOP2
--#define ASM_NOP3 K8_NOP3
--#define ASM_NOP4 K8_NOP4
--#define ASM_NOP5 K8_NOP5
--#define ASM_NOP6 K8_NOP6
--#define ASM_NOP7 K8_NOP7
--#define ASM_NOP8 K8_NOP8
--#endif
+-#define ptep_clear_flush(vma, addr, ptep)                     \
+-({                                                            \
+-      pte_t *__ptep = (ptep);                                 \
+-      pte_t __res = *__ptep;                                  \
+-      if (!pte_none(__res) &&                                 \
+-          ((vma)->vm_mm != current->mm ||                     \
+-           HYPERVISOR_update_va_mapping(addr, __pte(0),       \
+-                      (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
+-                              UVMF_INVLPG|UVMF_MULTI))) {     \
+-              __ptep->pte = 0;                                \
+-              flush_tlb_page(vma, addr);                      \
+-      }                                                       \
+-      __res;                                                  \
+-})
 -
--/* Opteron nops */
--#define K8_NOP1 ".byte 0x90\n"
--#define K8_NOP2       ".byte 0x66,0x90\n" 
--#define K8_NOP3       ".byte 0x66,0x66,0x90\n" 
--#define K8_NOP4       ".byte 0x66,0x66,0x66,0x90\n" 
--#define K8_NOP5       K8_NOP3 K8_NOP2 
--#define K8_NOP6       K8_NOP3 K8_NOP3
--#define K8_NOP7       K8_NOP4 K8_NOP3
--#define K8_NOP8       K8_NOP4 K8_NOP4
+-/*
+- * The following only work if pte_present() is true.
+- * Undefined behaviour if not..
+- */
+-#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
+-static inline int pte_dirty(pte_t pte)                { return __pte_val(pte) & _PAGE_DIRTY; }
+-static inline int pte_young(pte_t pte)                { return __pte_val(pte) & _PAGE_ACCESSED; }
+-static inline int pte_write(pte_t pte)                { return __pte_val(pte) & _PAGE_RW; }
+-static inline int pte_file(pte_t pte)         { return __pte_val(pte) & _PAGE_FILE; }
+-static inline int pte_huge(pte_t pte)         { return __pte_val(pte) & _PAGE_PSE; }
 -
--/* P6 nops */
--/* uses eax dependencies (Intel-recommended choice) */
--#define P6_NOP1       ".byte 0x90\n"
--#define P6_NOP2       ".byte 0x66,0x90\n"
--#define P6_NOP3       ".byte 0x0f,0x1f,0x00\n"
--#define P6_NOP4       ".byte 0x0f,0x1f,0x40,0\n"
--#define P6_NOP5       ".byte 0x0f,0x1f,0x44,0x00,0\n"
--#define P6_NOP6       ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
--#define P6_NOP7       ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
--#define P6_NOP8       ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
+-static inline pte_t pte_mkclean(pte_t pte)    { __pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+-static inline pte_t pte_mkold(pte_t pte)      { __pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+-static inline pte_t pte_wrprotect(pte_t pte)  { __pte_val(pte) &= ~_PAGE_RW; return pte; }
+-static inline pte_t pte_mkexec(pte_t pte)     { __pte_val(pte) &= ~_PAGE_NX; return pte; }
+-static inline pte_t pte_mkdirty(pte_t pte)    { __pte_val(pte) |= _PAGE_DIRTY; return pte; }
+-static inline pte_t pte_mkyoung(pte_t pte)    { __pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+-static inline pte_t pte_mkwrite(pte_t pte)    { __pte_val(pte) |= _PAGE_RW; return pte; }
+-static inline pte_t pte_mkhuge(pte_t pte)     { __pte_val(pte) |= _PAGE_PSE; return pte; }
+-static inline pte_t pte_clrhuge(pte_t pte)    { __pte_val(pte) &= ~_PAGE_PSE; return pte; }
 -
--#define ASM_NOP_MAX 8
+-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+-{
+-      if (!pte_young(*ptep))
+-              return 0;
+-      return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte);
+-}
 -
--/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
--static inline void rep_nop(void)
+-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 -{
--      __asm__ __volatile__("rep;nop": : :"memory");
+-      pte_t pte = *ptep;
+-      if (pte_write(pte))
+-              set_pte_at(mm, addr, ptep, pte_wrprotect(pte));
 -}
 -
--/* Stop speculative execution */
--static inline void sync_core(void)
--{ 
--      int tmp;
--      asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
--} 
+ /*
+  * Macro to mark a page protection value as "uncacheable".
+  */
+ #define pgprot_noncached(prot)        (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
+-static inline int pmd_large(pmd_t pte) { 
+-      return (__pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE;
+-}     
 -
--#define ARCH_HAS_PREFETCHW 1
--static inline void prefetchw(void *x) 
+ /*
+  * Conversion functions: convert a page and protection to a page entry,
+@@ -388,6 +203,7 @@ static inline int pmd_large(pmd_t pte) {
+ #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+ #define pgd_offset_k(address) (init_level4_pgt + pgd_index(address))
+ #define pgd_present(pgd) (__pgd_val(pgd) & _PAGE_PRESENT)
++static inline int pgd_large(pgd_t pgd) { return 0; }
+ #define mk_kernel_pgd(address) __pgd((address) | _KERNPG_TABLE)
+ /* PUD - Level3 access */
+@@ -398,6 +214,12 @@ static inline int pmd_large(pmd_t pte) {
+ #define pud_offset(pgd, address) ((pud_t *) pgd_page_vaddr(*(pgd)) + pud_index(address))
+ #define pud_present(pud) (__pud_val(pud) & _PAGE_PRESENT)
++static inline int pud_large(pud_t pte)
++{
++      return (__pud_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) ==
++              (_PAGE_PSE|_PAGE_PRESENT);
++}
++
+ /* PMD  - Level 2 access */
+ #define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK))
+ #define pmd_page(pmd)         (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+@@ -413,36 +235,18 @@ static inline int pmd_large(pmd_t pte) {
+ #else
+ #define pmd_present(x)        (__pmd_val(x) & _PAGE_PRESENT)
+ #endif
+-#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
+ #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
+ #define pmd_pfn(x)  ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
+ #define pte_to_pgoff(pte) ((__pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
+-#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
++#define pgoff_to_pte(off) ((pte_t) { .pte = ((off) << PAGE_SHIFT) | _PAGE_FILE })
+ #define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT
+ /* PTE - Level 1 access. */
+ /* page, protection -> pte */
+ #define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
+-#define mk_pte_huge(entry) (__pte_val(entry) |= _PAGE_PRESENT | _PAGE_PSE)
+  
+-/* Change flags of a PTE */
+-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 -{ 
--      alternative_input("prefetcht0 (%1)",
--                        "prefetchw (%1)",
--                        X86_FEATURE_3DNOW,
--                        "r" (x));
--} 
+-      /*
+-       * Since this might change the present bit (which controls whether
+-       * a pte_t object has undergone p2m translation), we must use
+-       * pte_val() on the input pte and __pte() for the return value.
+-       */
+-      unsigned long pteval = pte_val(pte);
 -
--#define ARCH_HAS_SPINLOCK_PREFETCH 1
+-      pteval &= _PAGE_CHG_MASK;
+-      pteval |= pgprot_val(newprot);
+-      pteval &= __supported_pte_mask;
+-      return __pte(pteval);
+-}
 -
--#define spin_lock_prefetch(x)  prefetchw(x)
+ #define pte_index(address) \
+               (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+ #define pte_offset_kernel(dir, address) ((pte_t *) pmd_page_vaddr(*(dir)) + \
+@@ -456,101 +260,21 @@ static inline pte_t pte_modify(pte_t pte
+ #define update_mmu_cache(vma,address,pte) do { } while (0)
+-/*
+- * Rules for using ptep_establish: the pte MUST be a user pte, and
+- * must be a present->present transition.
+- */
+-#define __HAVE_ARCH_PTEP_ESTABLISH
+-#define ptep_establish(vma, address, ptep, pteval)                    \
+-      do {                                                            \
+-              if ( likely((vma)->vm_mm == current->mm) ) {            \
+-                      BUG_ON(HYPERVISOR_update_va_mapping(address,    \
+-                              pteval,                                 \
+-                              (unsigned long)(vma)->vm_mm->cpu_vm_mask.bits| \
+-                                      UVMF_INVLPG|UVMF_MULTI));       \
+-              } else {                                                \
+-                      xen_l1_entry_update(ptep, pteval);              \
+-                      flush_tlb_page(vma, address);                   \
+-              }                                                       \
+-      } while (0)
 -
--#define cpu_relax()   rep_nop()
+-/* We only update the dirty/accessed state if we set
+- * the dirty bit by hand in the kernel, since the hardware
+- * will do the accessed bit for us, and we don't want to
+- * race with other CPU's that might be updating the dirty
+- * bit at the same time. */
+-#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+-#define ptep_set_access_flags(vma, address, ptep, entry, dirty)               \
+-({                                                                    \
+-      int __changed = !pte_same(*(ptep), entry);                      \
+-      if (__changed && (dirty))                                       \
+-              ptep_establish(vma, address, ptep, entry);              \
+-      __changed;                                                      \
+-})
 -
--static inline void __monitor(const void *eax, unsigned long ecx,
--              unsigned long edx)
--{
--      /* "monitor %eax,%ecx,%edx;" */
--      asm volatile(
--              ".byte 0x0f,0x01,0xc8;"
--              : :"a" (eax), "c" (ecx), "d"(edx));
--}
+-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+-#define ptep_clear_flush_young(vma, address, ptep)                    \
+-({                                                                    \
+-      pte_t __pte = *(ptep);                                          \
+-      int __young = pte_young(__pte);                                 \
+-      __pte = pte_mkold(__pte);                                       \
+-      if (PagePinned(virt_to_page((vma)->vm_mm->pgd)))                \
+-              (void)ptep_set_access_flags(vma, address, ptep, __pte, __young); \
+-      else if (__young)                                               \
+-              set_pte(ptep, __pte);                                   \
+-      __young;                                                        \
+-})
 -
--static inline void __mwait(unsigned long eax, unsigned long ecx)
--{
--      /* "mwait %eax,%ecx;" */
--      asm volatile(
--              ".byte 0x0f,0x01,0xc9;"
--              : :"a" (eax), "c" (ecx));
--}
+ /* Encode and de-code a swap entry */
+ #define __swp_type(x)                 (((x).val >> 1) & 0x3f)
+ #define __swp_offset(x)                       ((x).val >> 8)
+ #define __swp_entry(type, offset)     ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+ #define __pte_to_swp_entry(pte)               ((swp_entry_t) { __pte_val(pte) })
+-#define __swp_entry_to_pte(x)         ((pte_t) { (x).val })
 -
--static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
--{
--      /* "mwait %eax,%ecx;" */
--      asm volatile(
--              "sti; .byte 0x0f,0x01,0xc9;"
--              : :"a" (eax), "c" (ecx));
--}
+-extern spinlock_t pgd_lock;
+-extern struct list_head pgd_list;
++#define __swp_entry_to_pte(x)         ((pte_t) { .pte = (x).val })
+ extern int kern_addr_valid(unsigned long addr); 
 -
--extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
+-#define DOMID_LOCAL (0xFFFFU)
 -
--#define stack_current() \
--({                                                            \
--      struct thread_info *ti;                                 \
--      asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));  \
--      ti->task;                                       \
--})
+-struct vm_area_struct;
 -
--#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
+-int direct_remap_pfn_range(struct vm_area_struct *vma,
+-                            unsigned long address,
+-                            unsigned long mfn,
+-                            unsigned long size,
+-                            pgprot_t prot,
+-                            domid_t  domid);
 -
--extern unsigned long boot_option_idle_override;
--/* Boot loader type from the setup header */
--extern int bootloader_type;
+-int direct_kernel_remap_pfn_range(unsigned long address, 
+-                                unsigned long mfn,
+-                                unsigned long size, 
+-                                pgprot_t prot,
+-                                domid_t  domid);
 -
--#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
+-int create_lookup_pte_addr(struct mm_struct *mm,
+-                           unsigned long address,
+-                           uint64_t *ptep);
 -
--#endif /* __ASM_X86_64_PROCESSOR_H */
---- a/include/asm-x86/mach-xen/asm/processor.h
-+++ b/include/asm-x86/mach-xen/asm/processor.h
+-int touch_pte_range(struct mm_struct *mm,
+-                    unsigned long address,
+-                    unsigned long size);
+-
+-int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
+-              unsigned long addr, unsigned long end, pgprot_t newprot,
+-              int dirty_accountable);
+-
+-#define arch_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable) \
+-      xen_change_pte_range(mm, pmd, addr, end, newprot, dirty_accountable)
+-
+-pte_t *lookup_address(unsigned long addr);
++extern void cleanup_highmap(void);
+ #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)               \
+               direct_remap_pfn_range(vma,vaddr,pfn,size,prot,DOMID_IO)
+ #define HAVE_ARCH_UNMAPPED_AREA
++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+ #define pgtable_cache_init()   do { } while (0)
+ #define check_pgt_cache()      do { } while (0)
+@@ -563,13 +287,7 @@ pte_t *lookup_address(unsigned long addr
+ #define       kc_offset_to_vaddr(o) \
+    (((o) & (1UL << (__VIRTUAL_MASK_SHIFT-1))) ? ((o) | (~__VIRTUAL_MASK)) : (o))
+-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+-#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
+-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+ #define __HAVE_ARCH_PTE_SAME
+-#include <asm-generic/pgtable.h>
+ #endif /* !__ASSEMBLY__ */
+ #endif /* _X86_64_PGTABLE_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/processor.h     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/processor.h  2009-03-16 16:33:40.000000000 +0100
 @@ -1,5 +1,793 @@
 +#ifndef __ASM_X86_PROCESSOR_H
 +#define __ASM_X86_PROCESSOR_H
@@ -27077,161 +25540,1226 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +#define KSTK_EIP(task) (task_pt_regs(task)->ip)
 +
  #endif
---- a/include/asm-x86/mach-xen/asm/segment_32.h
-+++ /dev/null
-@@ -1,150 +0,0 @@
--#ifndef _ASM_SEGMENT_H
--#define _ASM_SEGMENT_H
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/processor_32.h  2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,751 +0,0 @@
+-/*
+- * include/asm-i386/processor.h
+- *
+- * Copyright (C) 1994 Linus Torvalds
+- */
+-
+-#ifndef __ASM_I386_PROCESSOR_H
+-#define __ASM_I386_PROCESSOR_H
+-
+-#include <asm/vm86.h>
+-#include <asm/math_emu.h>
+-#include <asm/segment.h>
+-#include <asm/page.h>
+-#include <asm/types.h>
+-#include <asm/sigcontext.h>
+-#include <asm/cpufeature.h>
+-#include <asm/msr.h>
+-#include <asm/system.h>
+-#include <linux/cache.h>
+-#include <linux/threads.h>
+-#include <asm/percpu.h>
+-#include <linux/cpumask.h>
+-#include <linux/init.h>
+-#include <asm/processor-flags.h>
+-#include <xen/interface/physdev.h>
+-
+-/* flag for disabling the tsc */
+-#define tsc_disable 0
+-
+-struct desc_struct {
+-      unsigned long a,b;
+-};
+-
+-#define desc_empty(desc) \
+-              (!((desc)->a | (desc)->b))
+-
+-#define desc_equal(desc1, desc2) \
+-              (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
+-/*
+- * Default implementation of macro that returns current
+- * instruction pointer ("program counter").
+- */
+-#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
+-
+-/*
+- *  CPU type and hardware bug flags. Kept separately for each CPU.
+- *  Members of this structure are referenced in head.S, so think twice
+- *  before touching them. [mj]
+- */
+-
+-struct cpuinfo_x86 {
+-      __u8    x86;            /* CPU family */
+-      __u8    x86_vendor;     /* CPU vendor */
+-      __u8    x86_model;
+-      __u8    x86_mask;
+-      char    wp_works_ok;    /* It doesn't on 386's */
+-      char    hlt_works_ok;   /* Problems on some 486Dx4's and old 386's */
+-      char    hard_math;
+-      char    rfu;
+-              int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
+-      unsigned long   x86_capability[NCAPINTS];
+-      char    x86_vendor_id[16];
+-      char    x86_model_id[64];
+-      int     x86_cache_size;  /* in KB - valid for CPUS which support this
+-                                  call  */
+-      int     x86_cache_alignment;    /* In bytes */
+-      char    fdiv_bug;
+-      char    f00f_bug;
+-      char    coma_bug;
+-      char    pad0;
+-      int     x86_power;
+-      unsigned long loops_per_jiffy;
+-#ifdef CONFIG_SMP
+-      cpumask_t llc_shared_map;       /* cpus sharing the last level cache */
+-#endif
+-      unsigned char x86_max_cores;    /* cpuid returned max cores value */
+-      unsigned char apicid;
+-      unsigned short x86_clflush_size;
+-#ifdef CONFIG_SMP
+-      unsigned char booted_cores;     /* number of cores as seen by OS */
+-      __u8 phys_proc_id;              /* Physical processor id. */
+-      __u8 cpu_core_id;               /* Core id */
+-      __u8 cpu_index;                 /* index into per_cpu list */
+-#endif
+-} __attribute__((__aligned__(SMP_CACHE_BYTES)));
+-
+-#define X86_VENDOR_INTEL 0
+-#define X86_VENDOR_CYRIX 1
+-#define X86_VENDOR_AMD 2
+-#define X86_VENDOR_UMC 3
+-#define X86_VENDOR_NEXGEN 4
+-#define X86_VENDOR_CENTAUR 5
+-#define X86_VENDOR_TRANSMETA 7
+-#define X86_VENDOR_NSC 8
+-#define X86_VENDOR_NUM 9
+-#define X86_VENDOR_UNKNOWN 0xff
+-
+-/*
+- * capabilities of CPUs
+- */
+-
+-extern struct cpuinfo_x86 boot_cpu_data;
+-extern struct cpuinfo_x86 new_cpu_data;
+-#ifndef CONFIG_X86_NO_TSS
+-extern struct tss_struct doublefault_tss;
+-DECLARE_PER_CPU(struct tss_struct, init_tss);
+-#endif
+-
+-#ifdef CONFIG_SMP
+-DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+-#define cpu_data(cpu)         per_cpu(cpu_info, cpu)
+-#define current_cpu_data      cpu_data(smp_processor_id())
+-#else
+-#define cpu_data(cpu)         boot_cpu_data
+-#define current_cpu_data      boot_cpu_data
+-#endif
+-
+-/*
+- * the following now lives in the per cpu area:
+- * extern     int cpu_llc_id[NR_CPUS];
+- */
+-DECLARE_PER_CPU(u8, cpu_llc_id);
+-extern char ignore_fpu_irq;
+-
+-void __init cpu_detect(struct cpuinfo_x86 *c);
+-
+-extern void identify_boot_cpu(void);
+-extern void identify_secondary_cpu(struct cpuinfo_x86 *);
+-extern void print_cpu_info(struct cpuinfo_x86 *);
+-extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
+-extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
+-extern unsigned short num_cache_leaves;
+-
+-#ifdef CONFIG_X86_HT
+-extern void detect_ht(struct cpuinfo_x86 *c);
+-#else
+-static inline void detect_ht(struct cpuinfo_x86 *c) {}
+-#endif
+-
+-static inline void xen_cpuid(unsigned int *eax, unsigned int *ebx,
+-                           unsigned int *ecx, unsigned int *edx)
+-{
+-      /* ecx is often an input as well as an output. */
+-      __asm__(XEN_CPUID
+-              : "=a" (*eax),
+-                "=b" (*ebx),
+-                "=c" (*ecx),
+-                "=d" (*edx)
+-              : "0" (*eax), "2" (*ecx));
+-}
+-
+-#define load_cr3(pgdir) write_cr3(__pa(pgdir))
+-
+-/*
+- * Save the cr4 feature set we're using (ie
+- * Pentium 4MB enable and PPro Global page
+- * enable), so that any CPU's that boot up
+- * after us can get the correct flags.
+- */
+-extern unsigned long mmu_cr4_features;
+-
+-static inline void set_in_cr4 (unsigned long mask)
+-{
+-      unsigned cr4;
+-      mmu_cr4_features |= mask;
+-      cr4 = read_cr4();
+-      cr4 |= mask;
+-      write_cr4(cr4);
+-}
+-
+-static inline void clear_in_cr4 (unsigned long mask)
+-{
+-      unsigned cr4;
+-      mmu_cr4_features &= ~mask;
+-      cr4 = read_cr4();
+-      cr4 &= ~mask;
+-      write_cr4(cr4);
+-}
+-
+-/* Stop speculative execution */
+-static inline void sync_core(void)
+-{
+-      int tmp;
+-      asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
+-}
+-
+-static inline void __monitor(const void *eax, unsigned long ecx,
+-              unsigned long edx)
+-{
+-      /* "monitor %eax,%ecx,%edx;" */
+-      asm volatile(
+-              ".byte 0x0f,0x01,0xc8;"
+-              : :"a" (eax), "c" (ecx), "d"(edx));
+-}
+-
+-static inline void __mwait(unsigned long eax, unsigned long ecx)
+-{
+-      /* "mwait %eax,%ecx;" */
+-      asm volatile(
+-              ".byte 0x0f,0x01,0xc9;"
+-              : :"a" (eax), "c" (ecx));
+-}
+-
+-extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
+-
+-/* from system description table in BIOS.  Mostly for MCA use, but
+-others may find it useful. */
+-extern unsigned int machine_id;
+-extern unsigned int machine_submodel_id;
+-extern unsigned int BIOS_revision;
+-extern unsigned int mca_pentium_flag;
+-
+-/* Boot loader type from the setup header */
+-extern int bootloader_type;
+-
+-/*
+- * User space process size: 3GB (default).
+- */
+-#define TASK_SIZE     (PAGE_OFFSET)
+-
+-/* This decides where the kernel will search for a free chunk of vm
+- * space during mmap's.
+- */
+-#define TASK_UNMAPPED_BASE    (PAGE_ALIGN(TASK_SIZE / 3))
+-
+-#define HAVE_ARCH_PICK_MMAP_LAYOUT
+-
+-extern void hard_disable_TSC(void);
+-extern void disable_TSC(void);
+-extern void hard_enable_TSC(void);
+-
+-/*
+- * Size of io_bitmap.
+- */
+-#define IO_BITMAP_BITS  65536
+-#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
+-#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
+-#ifndef CONFIG_X86_NO_TSS
+-#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
+-#endif
+-#define INVALID_IO_BITMAP_OFFSET 0x8000
+-#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
+-
+-struct i387_fsave_struct {
+-      long    cwd;
+-      long    swd;
+-      long    twd;
+-      long    fip;
+-      long    fcs;
+-      long    foo;
+-      long    fos;
+-      long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
+-      long    status;         /* software status information */
+-};
+-
+-struct i387_fxsave_struct {
+-      unsigned short  cwd;
+-      unsigned short  swd;
+-      unsigned short  twd;
+-      unsigned short  fop;
+-      long    fip;
+-      long    fcs;
+-      long    foo;
+-      long    fos;
+-      long    mxcsr;
+-      long    mxcsr_mask;
+-      long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
+-      long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
+-      long    padding[56];
+-} __attribute__ ((aligned (16)));
+-
+-struct i387_soft_struct {
+-      long    cwd;
+-      long    swd;
+-      long    twd;
+-      long    fip;
+-      long    fcs;
+-      long    foo;
+-      long    fos;
+-      long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
+-      unsigned char   ftop, changed, lookahead, no_update, rm, alimit;
+-      struct info     *info;
+-      unsigned long   entry_eip;
+-};
+-
+-union i387_union {
+-      struct i387_fsave_struct        fsave;
+-      struct i387_fxsave_struct       fxsave;
+-      struct i387_soft_struct soft;
+-};
+-
+-typedef struct {
+-      unsigned long seg;
+-} mm_segment_t;
+-
+-struct thread_struct;
+-
+-#ifndef CONFIG_X86_NO_TSS
+-/* This is the TSS defined by the hardware. */
+-struct i386_hw_tss {
+-      unsigned short  back_link,__blh;
+-      unsigned long   esp0;
+-      unsigned short  ss0,__ss0h;
+-      unsigned long   esp1;
+-      unsigned short  ss1,__ss1h;     /* ss1 is used to cache MSR_IA32_SYSENTER_CS */
+-      unsigned long   esp2;
+-      unsigned short  ss2,__ss2h;
+-      unsigned long   __cr3;
+-      unsigned long   eip;
+-      unsigned long   eflags;
+-      unsigned long   eax,ecx,edx,ebx;
+-      unsigned long   esp;
+-      unsigned long   ebp;
+-      unsigned long   esi;
+-      unsigned long   edi;
+-      unsigned short  es, __esh;
+-      unsigned short  cs, __csh;
+-      unsigned short  ss, __ssh;
+-      unsigned short  ds, __dsh;
+-      unsigned short  fs, __fsh;
+-      unsigned short  gs, __gsh;
+-      unsigned short  ldt, __ldth;
+-      unsigned short  trace, io_bitmap_base;
+-} __attribute__((packed));
+-
+-struct tss_struct {
+-      struct i386_hw_tss x86_tss;
+-
+-      /*
+-       * The extra 1 is there because the CPU will access an
+-       * additional byte beyond the end of the IO permission
+-       * bitmap. The extra byte must be all 1 bits, and must
+-       * be within the limit.
+-       */
+-      unsigned long   io_bitmap[IO_BITMAP_LONGS + 1];
+-      /*
+-       * Cache the current maximum and the last task that used the bitmap:
+-       */
+-      unsigned long io_bitmap_max;
+-      struct thread_struct *io_bitmap_owner;
+-      /*
+-       * pads the TSS to be cacheline-aligned (size is 0x100)
+-       */
+-      unsigned long __cacheline_filler[35];
+-      /*
+-       * .. and then another 0x100 bytes for emergency kernel stack
+-       */
+-      unsigned long stack[64];
+-} __attribute__((packed));
+-#endif
+-
+-#define ARCH_MIN_TASKALIGN    16
+-
+-struct thread_struct {
+-/* cached TLS descriptors. */
+-      struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
+-      unsigned long   esp0;
+-      unsigned long   sysenter_cs;
+-      unsigned long   eip;
+-      unsigned long   esp;
+-      unsigned long   fs;
+-      unsigned long   gs;
+-/* Hardware debugging registers */
+-      unsigned long   debugreg[8];  /* %%db0-7 debug registers */
+-/* fault info */
+-      unsigned long   cr2, trap_no, error_code;
+-/* floating point info */
+-      union i387_union        i387;
+-/* virtual 86 mode info */
+-      struct vm86_struct __user * vm86_info;
+-      unsigned long           screen_bitmap;
+-      unsigned long           v86flags, v86mask, saved_esp0;
+-      unsigned int            saved_fs, saved_gs;
+-/* IO permissions */
+-      unsigned long   *io_bitmap_ptr;
+-      unsigned long   iopl;
+-/* max allowed port in the bitmap, in bytes: */
+-      unsigned long   io_bitmap_max;
+-};
+-
+-#define INIT_THREAD  {                                                        \
+-      .esp0 = sizeof(init_stack) + (long)&init_stack,                 \
+-      .vm86_info = NULL,                                              \
+-      .sysenter_cs = __KERNEL_CS,                                     \
+-      .io_bitmap_ptr = NULL,                                          \
+-      .fs = __KERNEL_PERCPU,                                          \
+-}
+-
+-/*
+- * Note that the .io_bitmap member must be extra-big. This is because
+- * the CPU will access an additional byte beyond the end of the IO
+- * permission bitmap. The extra byte must be all 1 bits, and must
+- * be within the limit.
+- */
+-#define INIT_TSS  {                                                   \
+-      .x86_tss = {                                                    \
+-              .esp0           = sizeof(init_stack) + (long)&init_stack, \
+-              .ss0            = __KERNEL_DS,                          \
+-              .ss1            = __KERNEL_CS,                          \
+-              .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,             \
+-       },                                                             \
+-      .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
+-}
+-
+-#define start_thread(regs, new_eip, new_esp) do {             \
+-      __asm__("movl %0,%%gs": :"r" (0));                      \
+-      regs->xfs = 0;                                          \
+-      set_fs(USER_DS);                                        \
+-      regs->xds = __USER_DS;                                  \
+-      regs->xes = __USER_DS;                                  \
+-      regs->xss = __USER_DS;                                  \
+-      regs->xcs = __USER_CS;                                  \
+-      regs->eip = new_eip;                                    \
+-      regs->esp = new_esp;                                    \
+-} while (0)
+-
+-/* Forward declaration, a strange C thing */
+-struct task_struct;
+-struct mm_struct;
+-
+-/* Free all resources held by a thread. */
+-extern void release_thread(struct task_struct *);
+-
+-/* Prepare to copy thread state - unlazy all lazy status */
+-extern void prepare_to_copy(struct task_struct *tsk);
+-
+-/*
+- * create a kernel thread without removing it from tasklists
+- */
+-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+-
+-extern unsigned long thread_saved_pc(struct task_struct *tsk);
+-void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack);
+-
+-unsigned long get_wchan(struct task_struct *p);
+-
+-#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
+-#define KSTK_TOP(info)                                                 \
+-({                                                                     \
+-       unsigned long *__ptr = (unsigned long *)(info);                 \
+-       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
+-})
+-
+-/*
+- * The below -8 is to reserve 8 bytes on top of the ring0 stack.
+- * This is necessary to guarantee that the entire "struct pt_regs"
+- * is accessable even if the CPU haven't stored the SS/ESP registers
+- * on the stack (interrupt gate does not save these registers
+- * when switching to the same priv ring).
+- * Therefore beware: accessing the xss/esp fields of the
+- * "struct pt_regs" is possible, but they may contain the
+- * completely wrong values.
+- */
+-#define task_pt_regs(task)                                             \
+-({                                                                     \
+-       struct pt_regs *__regs__;                                       \
+-       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
+-       __regs__ - 1;                                                   \
+-})
+-
+-#define KSTK_EIP(task) (task_pt_regs(task)->eip)
+-#define KSTK_ESP(task) (task_pt_regs(task)->esp)
+-
+-
+-struct microcode_header {
+-      unsigned int hdrver;
+-      unsigned int rev;
+-      unsigned int date;
+-      unsigned int sig;
+-      unsigned int cksum;
+-      unsigned int ldrver;
+-      unsigned int pf;
+-      unsigned int datasize;
+-      unsigned int totalsize;
+-      unsigned int reserved[3];
+-};
+-
+-struct microcode {
+-      struct microcode_header hdr;
+-      unsigned int bits[0];
+-};
+-
+-typedef struct microcode microcode_t;
+-typedef struct microcode_header microcode_header_t;
+-
+-/* microcode format is extended from prescott processors */
+-struct extended_signature {
+-      unsigned int sig;
+-      unsigned int pf;
+-      unsigned int cksum;
+-};
+-
+-struct extended_sigtable {
+-      unsigned int count;
+-      unsigned int cksum;
+-      unsigned int reserved[3];
+-      struct extended_signature sigs[0];
+-};
+-
+-/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+-static inline void rep_nop(void)
+-{
+-      __asm__ __volatile__("rep;nop": : :"memory");
+-}
+-
+-#define cpu_relax()   rep_nop()
+-
+-#ifndef CONFIG_X86_NO_TSS
+-static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread)
+-{
+-      tss->x86_tss.esp0 = thread->esp0;
+-      /* This can only happen when SEP is enabled, no need to test "SEP"arately */
+-      if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
+-              tss->x86_tss.ss1 = thread->sysenter_cs;
+-              wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
+-      }
+-}
+-#else
+-#define xen_load_esp0(tss, thread) do { \
+-      if (HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0)) \
+-              BUG(); \
+-} while (0)
+-#endif
+-
+-
+-static inline unsigned long xen_get_debugreg(int regno)
+-{
+-      return HYPERVISOR_get_debugreg(regno);
+-}
+-
+-static inline void xen_set_debugreg(int regno, unsigned long value)
+-{
+-      WARN_ON(HYPERVISOR_set_debugreg(regno, value));
+-}
+-
+-/*
+- * Set IOPL bits in EFLAGS from given mask
+- */
+-static inline void xen_set_iopl_mask(unsigned mask)
+-{
+-      struct physdev_set_iopl set_iopl;
+-
+-      /* Force the change at ring 0. */
+-      set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
+-      WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl));
+-}
+-
+-
+-#define paravirt_enabled() 0
+-#define __cpuid xen_cpuid
+-
+-#define load_esp0 xen_load_esp0
+-
+-/*
+- * These special macros can be used to get or set a debugging register
+- */
+-#define get_debugreg(var, register)                           \
+-      (var) = xen_get_debugreg(register)
+-#define set_debugreg(value, register)                         \
+-      xen_set_debugreg(register, value)
+-
+-#define set_iopl_mask xen_set_iopl_mask
+-
+-/*
+- * Generic CPUID function
+- * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
+- * resulting in stale register contents being returned.
+- */
+-static inline void cpuid(unsigned int op,
+-                       unsigned int *eax, unsigned int *ebx,
+-                       unsigned int *ecx, unsigned int *edx)
+-{
+-      *eax = op;
+-      *ecx = 0;
+-      __cpuid(eax, ebx, ecx, edx);
+-}
+-
+-/* Some CPUID calls want 'count' to be placed in ecx */
+-static inline void cpuid_count(unsigned int op, int count,
+-                             unsigned int *eax, unsigned int *ebx,
+-                             unsigned int *ecx, unsigned int *edx)
+-{
+-      *eax = op;
+-      *ecx = count;
+-      __cpuid(eax, ebx, ecx, edx);
+-}
+-
+-/*
+- * CPUID functions returning a single datum
+- */
+-static inline unsigned int cpuid_eax(unsigned int op)
+-{
+-      unsigned int eax, ebx, ecx, edx;
+-
+-      cpuid(op, &eax, &ebx, &ecx, &edx);
+-      return eax;
+-}
+-static inline unsigned int cpuid_ebx(unsigned int op)
+-{
+-      unsigned int eax, ebx, ecx, edx;
+-
+-      cpuid(op, &eax, &ebx, &ecx, &edx);
+-      return ebx;
+-}
+-static inline unsigned int cpuid_ecx(unsigned int op)
+-{
+-      unsigned int eax, ebx, ecx, edx;
+-
+-      cpuid(op, &eax, &ebx, &ecx, &edx);
+-      return ecx;
+-}
+-static inline unsigned int cpuid_edx(unsigned int op)
+-{
+-      unsigned int eax, ebx, ecx, edx;
+-
+-      cpuid(op, &eax, &ebx, &ecx, &edx);
+-      return edx;
+-}
+-
+-/* generic versions from gas */
+-#define GENERIC_NOP1  ".byte 0x90\n"
+-#define GENERIC_NOP2          ".byte 0x89,0xf6\n"
+-#define GENERIC_NOP3        ".byte 0x8d,0x76,0x00\n"
+-#define GENERIC_NOP4        ".byte 0x8d,0x74,0x26,0x00\n"
+-#define GENERIC_NOP5        GENERIC_NOP1 GENERIC_NOP4
+-#define GENERIC_NOP6  ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
+-#define GENERIC_NOP7  ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
+-#define GENERIC_NOP8  GENERIC_NOP1 GENERIC_NOP7
+-
+-/* Opteron nops */
+-#define K8_NOP1 GENERIC_NOP1
+-#define K8_NOP2       ".byte 0x66,0x90\n" 
+-#define K8_NOP3       ".byte 0x66,0x66,0x90\n" 
+-#define K8_NOP4       ".byte 0x66,0x66,0x66,0x90\n" 
+-#define K8_NOP5       K8_NOP3 K8_NOP2 
+-#define K8_NOP6       K8_NOP3 K8_NOP3
+-#define K8_NOP7       K8_NOP4 K8_NOP3
+-#define K8_NOP8       K8_NOP4 K8_NOP4
+-
+-/* K7 nops */
+-/* uses eax dependencies (arbitary choice) */
+-#define K7_NOP1  GENERIC_NOP1
+-#define K7_NOP2       ".byte 0x8b,0xc0\n" 
+-#define K7_NOP3       ".byte 0x8d,0x04,0x20\n"
+-#define K7_NOP4       ".byte 0x8d,0x44,0x20,0x00\n"
+-#define K7_NOP5       K7_NOP4 ASM_NOP1
+-#define K7_NOP6       ".byte 0x8d,0x80,0,0,0,0\n"
+-#define K7_NOP7        ".byte 0x8D,0x04,0x05,0,0,0,0\n"
+-#define K7_NOP8        K7_NOP7 ASM_NOP1
+-
+-/* P6 nops */
+-/* uses eax dependencies (Intel-recommended choice) */
+-#define P6_NOP1       GENERIC_NOP1
+-#define P6_NOP2       ".byte 0x66,0x90\n"
+-#define P6_NOP3       ".byte 0x0f,0x1f,0x00\n"
+-#define P6_NOP4       ".byte 0x0f,0x1f,0x40,0\n"
+-#define P6_NOP5       ".byte 0x0f,0x1f,0x44,0x00,0\n"
+-#define P6_NOP6       ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
+-#define P6_NOP7       ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
+-#define P6_NOP8       ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
+-
+-#ifdef CONFIG_MK8
+-#define ASM_NOP1 K8_NOP1
+-#define ASM_NOP2 K8_NOP2
+-#define ASM_NOP3 K8_NOP3
+-#define ASM_NOP4 K8_NOP4
+-#define ASM_NOP5 K8_NOP5
+-#define ASM_NOP6 K8_NOP6
+-#define ASM_NOP7 K8_NOP7
+-#define ASM_NOP8 K8_NOP8
+-#elif defined(CONFIG_MK7)
+-#define ASM_NOP1 K7_NOP1
+-#define ASM_NOP2 K7_NOP2
+-#define ASM_NOP3 K7_NOP3
+-#define ASM_NOP4 K7_NOP4
+-#define ASM_NOP5 K7_NOP5
+-#define ASM_NOP6 K7_NOP6
+-#define ASM_NOP7 K7_NOP7
+-#define ASM_NOP8 K7_NOP8
+-#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
+-      defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
+-      defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
+-#define ASM_NOP1 P6_NOP1
+-#define ASM_NOP2 P6_NOP2
+-#define ASM_NOP3 P6_NOP3
+-#define ASM_NOP4 P6_NOP4
+-#define ASM_NOP5 P6_NOP5
+-#define ASM_NOP6 P6_NOP6
+-#define ASM_NOP7 P6_NOP7
+-#define ASM_NOP8 P6_NOP8
+-#else
+-#define ASM_NOP1 GENERIC_NOP1
+-#define ASM_NOP2 GENERIC_NOP2
+-#define ASM_NOP3 GENERIC_NOP3
+-#define ASM_NOP4 GENERIC_NOP4
+-#define ASM_NOP5 GENERIC_NOP5
+-#define ASM_NOP6 GENERIC_NOP6
+-#define ASM_NOP7 GENERIC_NOP7
+-#define ASM_NOP8 GENERIC_NOP8
+-#endif
+-
+-#define ASM_NOP_MAX 8
+-
+-/* Prefetch instructions for Pentium III and AMD Athlon */
+-/* It's not worth to care about 3dnow! prefetches for the K6
+-   because they are microcoded there and very slow.
+-   However we don't do prefetches for pre XP Athlons currently
+-   That should be fixed. */
+-#define ARCH_HAS_PREFETCH
+-static inline void prefetch(const void *x)
+-{
+-      alternative_input(ASM_NOP4,
+-                        "prefetchnta (%1)",
+-                        X86_FEATURE_XMM,
+-                        "r" (x));
+-}
+-
+-#define ARCH_HAS_PREFETCH
+-#define ARCH_HAS_PREFETCHW
+-#define ARCH_HAS_SPINLOCK_PREFETCH
+-
+-/* 3dnow! prefetch to get an exclusive cache line. Useful for 
+-   spinlocks to avoid one state transition in the cache coherency protocol. */
+-static inline void prefetchw(const void *x)
+-{
+-      alternative_input(ASM_NOP4,
+-                        "prefetchw (%1)",
+-                        X86_FEATURE_3DNOW,
+-                        "r" (x));
+-}
+-#define spin_lock_prefetch(x) prefetchw(x)
+-
+-extern void select_idle_routine(const struct cpuinfo_x86 *c);
+-
+-#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
+-
+-extern unsigned long boot_option_idle_override;
+-extern void enable_sep_cpu(void);
+-extern int sysenter_setup(void);
+-
+-/* Defined in head.S */
+-extern struct Xgt_desc_struct early_gdt_descr;
+-
+-extern void cpu_set_gdt(int);
+-extern void switch_to_new_gdt(void);
+-extern void cpu_init(void);
+-extern void init_gdt(int cpu);
+-
+-extern int force_mwait;
+-
+-#endif /* __ASM_I386_PROCESSOR_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/processor_64.h  2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,461 +0,0 @@
+-/*
+- * include/asm-x86_64/processor.h
+- *
+- * Copyright (C) 1994 Linus Torvalds
+- */
+-
+-#ifndef __ASM_X86_64_PROCESSOR_H
+-#define __ASM_X86_64_PROCESSOR_H
+-
+-#include <asm/segment.h>
+-#include <asm/page.h>
+-#include <asm/types.h>
+-#include <asm/sigcontext.h>
+-#include <asm/cpufeature.h>
+-#include <linux/threads.h>
+-#include <asm/msr.h>
+-#include <asm/current.h>
+-#include <asm/system.h>
+-#include <asm/mmsegment.h>
+-#include <asm/percpu.h>
+-#include <linux/personality.h>
+-#include <linux/cpumask.h>
+-#include <asm/processor-flags.h>
+-
+-#define TF_MASK               0x00000100
+-#define IF_MASK               0x00000200
+-#define IOPL_MASK     0x00003000
+-#define NT_MASK               0x00004000
+-#define VM_MASK               0x00020000
+-#define AC_MASK               0x00040000
+-#define VIF_MASK      0x00080000      /* virtual interrupt flag */
+-#define VIP_MASK      0x00100000      /* virtual interrupt pending */
+-#define ID_MASK               0x00200000
+-
+-#define desc_empty(desc) \
+-               (!((desc)->a | (desc)->b))
+-
+-#define desc_equal(desc1, desc2) \
+-               (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
+-
+-/*
+- * Default implementation of macro that returns current
+- * instruction pointer ("program counter").
+- */
+-#define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; })
+-
+-/*
+- *  CPU type and hardware bug flags. Kept separately for each CPU.
+- */
+-
+-struct cpuinfo_x86 {
+-      __u8    x86;            /* CPU family */
+-      __u8    x86_vendor;     /* CPU vendor */
+-      __u8    x86_model;
+-      __u8    x86_mask;
+-      int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
+-      __u32   x86_capability[NCAPINTS];
+-      char    x86_vendor_id[16];
+-      char    x86_model_id[64];
+-      int     x86_cache_size;  /* in KB */
+-      int     x86_clflush_size;
+-      int     x86_cache_alignment;
+-      int     x86_tlbsize;    /* number of 4K pages in DTLB/ITLB combined(in pages)*/
+-        __u8    x86_virt_bits, x86_phys_bits;
+-      __u8    x86_max_cores;  /* cpuid returned max cores value */
+-        __u32   x86_power;    
+-      __u32   extended_cpuid_level;   /* Max extended CPUID function supported */
+-      unsigned long loops_per_jiffy;
+-#ifdef CONFIG_SMP
+-      cpumask_t llc_shared_map;       /* cpus sharing the last level cache */
+-#endif
+-      __u8    apicid;
+-#ifdef CONFIG_SMP
+-      __u8    booted_cores;   /* number of cores as seen by OS */
+-      __u8    phys_proc_id;   /* Physical Processor id. */
+-      __u8    cpu_core_id;    /* Core id. */
+-      __u8    cpu_index;      /* index into per_cpu list */
+-#endif
+-} ____cacheline_aligned;
+-
+-#define X86_VENDOR_INTEL 0
+-#define X86_VENDOR_CYRIX 1
+-#define X86_VENDOR_AMD 2
+-#define X86_VENDOR_UMC 3
+-#define X86_VENDOR_NEXGEN 4
+-#define X86_VENDOR_CENTAUR 5
+-#define X86_VENDOR_TRANSMETA 7
+-#define X86_VENDOR_NUM 8
+-#define X86_VENDOR_UNKNOWN 0xff
+-
+-#ifdef CONFIG_SMP
+-DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+-#define cpu_data(cpu)         per_cpu(cpu_info, cpu)
+-#define current_cpu_data      cpu_data(smp_processor_id())
+-#else
+-#define cpu_data(cpu)         boot_cpu_data
+-#define current_cpu_data      boot_cpu_data
+-#endif
+-
+-extern char ignore_irq13;
+-
+-extern void identify_cpu(struct cpuinfo_x86 *);
+-extern void print_cpu_info(struct cpuinfo_x86 *);
+-extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
+-extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
+-extern unsigned short num_cache_leaves;
+-
+-/*
+- * Save the cr4 feature set we're using (ie
+- * Pentium 4MB enable and PPro Global page
+- * enable), so that any CPU's that boot up
+- * after us can get the correct flags.
+- */
+-extern unsigned long mmu_cr4_features;
+-
+-static inline void set_in_cr4 (unsigned long mask)
+-{
+-      mmu_cr4_features |= mask;
+-      __asm__("movq %%cr4,%%rax\n\t"
+-              "orq %0,%%rax\n\t"
+-              "movq %%rax,%%cr4\n"
+-              : : "irg" (mask)
+-              :"ax");
+-}
+-
+-static inline void clear_in_cr4 (unsigned long mask)
+-{
+-      mmu_cr4_features &= ~mask;
+-      __asm__("movq %%cr4,%%rax\n\t"
+-              "andq %0,%%rax\n\t"
+-              "movq %%rax,%%cr4\n"
+-              : : "irg" (~mask)
+-              :"ax");
+-}
+-
+-
+-/*
+- * User space process size. 47bits minus one guard page.
+- */
+-#define TASK_SIZE64   (0x800000000000UL - 4096)
+-
+-/* This decides where the kernel will search for a free chunk of vm
+- * space during mmap's.
+- */
+-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
+-
+-#define TASK_SIZE             (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
+-#define TASK_SIZE_OF(child)   ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
+-
+-#define TASK_UNMAPPED_BASE    PAGE_ALIGN(TASK_SIZE/3)
+-
+-/*
+- * Size of io_bitmap.
+- */
+-#define IO_BITMAP_BITS  65536
+-#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
+-#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
+-#ifndef CONFIG_X86_NO_TSS
+-#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
+-#endif
+-#define INVALID_IO_BITMAP_OFFSET 0x8000
+-
+-struct i387_fxsave_struct {
+-      u16     cwd;
+-      u16     swd;
+-      u16     twd;
+-      u16     fop;
+-      u64     rip;
+-      u64     rdp; 
+-      u32     mxcsr;
+-      u32     mxcsr_mask;
+-      u32     st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
+-      u32     xmm_space[64];  /* 16*16 bytes for each XMM-reg = 256 bytes */
+-      u32     padding[24];
+-} __attribute__ ((aligned (16)));
+-
+-union i387_union {
+-      struct i387_fxsave_struct       fxsave;
+-};
+-
+-#ifndef CONFIG_X86_NO_TSS
+-struct tss_struct {
+-      u32 reserved1;
+-      u64 rsp0;       
+-      u64 rsp1;
+-      u64 rsp2;
+-      u64 reserved2;
+-      u64 ist[7];
+-      u32 reserved3;
+-      u32 reserved4;
+-      u16 reserved5;
+-      u16 io_bitmap_base;
+-      /*
+-       * The extra 1 is there because the CPU will access an
+-       * additional byte beyond the end of the IO permission
+-       * bitmap. The extra byte must be all 1 bits, and must
+-       * be within the limit. Thus we have:
+-       *
+-       * 128 bytes, the bitmap itself, for ports 0..0x3ff
+-       * 8 bytes, for an extra "long" of ~0UL
+-       */
+-      unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
+-} __attribute__((packed)) ____cacheline_aligned;
+-
+-DECLARE_PER_CPU(struct tss_struct,init_tss);
+-#endif
+-
+-
+-extern struct cpuinfo_x86 boot_cpu_data;
+-#ifndef CONFIG_X86_NO_TSS
+-/* Save the original ist values for checking stack pointers during debugging */
+-struct orig_ist {
+-      unsigned long ist[7];
+-};
+-DECLARE_PER_CPU(struct orig_ist, orig_ist);
+-#endif
+-
+-#ifdef CONFIG_X86_VSMP
+-#define ARCH_MIN_TASKALIGN    (1 << INTERNODE_CACHE_SHIFT)
+-#define ARCH_MIN_MMSTRUCT_ALIGN       (1 << INTERNODE_CACHE_SHIFT)
+-#else
+-#define ARCH_MIN_TASKALIGN    16
+-#define ARCH_MIN_MMSTRUCT_ALIGN       0
+-#endif
+-
+-struct thread_struct {
+-      unsigned long   rsp0;
+-      unsigned long   rsp;
+-      unsigned long   userrsp;        /* Copy from PDA */ 
+-      unsigned long   fs;
+-      unsigned long   gs;
+-      unsigned short  es, ds, fsindex, gsindex;       
+-/* Hardware debugging registers */
+-      unsigned long   debugreg0;  
+-      unsigned long   debugreg1;  
+-      unsigned long   debugreg2;  
+-      unsigned long   debugreg3;  
+-      unsigned long   debugreg6;  
+-      unsigned long   debugreg7;  
+-/* fault info */
+-      unsigned long   cr2, trap_no, error_code;
+-/* floating point info */
+-      union i387_union        i387  __attribute__((aligned(16)));
+-/* IO permissions. the bitmap could be moved into the GDT, that would make
+-   switch faster for a limited number of ioperm using tasks. -AK */
+-      int             ioperm;
+-      unsigned long   *io_bitmap_ptr;
+-      unsigned io_bitmap_max;
+-/* cached TLS descriptors. */
+-      u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
+-      unsigned int    iopl;
+-} __attribute__((aligned(16)));
+-
+-#define INIT_THREAD  { \
+-      .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
+-}
+-
+-#ifndef CONFIG_X86_NO_TSS
+-#define INIT_TSS  { \
+-      .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
+-}
+-#endif
+-
+-#define INIT_MMAP \
+-{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+-
+-#define start_thread(regs,new_rip,new_rsp) do { \
+-      asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));      \
+-      load_gs_index(0);                                                       \
+-      (regs)->rip = (new_rip);                                                 \
+-      (regs)->rsp = (new_rsp);                                                 \
+-      write_pda(oldrsp, (new_rsp));                                            \
+-      (regs)->cs = __USER_CS;                                                  \
+-      (regs)->ss = __USER_DS;                                                  \
+-      (regs)->eflags = 0x200;                                                  \
+-      set_fs(USER_DS);                                                         \
+-} while(0) 
+-
+-#define get_debugreg(var, register)                           \
+-      var = HYPERVISOR_get_debugreg(register)
+-#define set_debugreg(value, register) do {                    \
+-      if (HYPERVISOR_set_debugreg(register, value))           \
+-              BUG();                                          \
+-} while (0)
+-
+-struct task_struct;
+-struct mm_struct;
+-
+-/* Free all resources held by a thread. */
+-extern void release_thread(struct task_struct *);
+-
+-/* Prepare to copy thread state - unlazy all lazy status */
+-extern void prepare_to_copy(struct task_struct *tsk);
 -
 -/*
-- * The layout of the per-CPU GDT under Linux:
-- *
-- *   0 - null
-- *   1 - reserved
-- *   2 - reserved
-- *   3 - reserved
-- *
-- *   4 - unused                       <==== new cacheline
-- *   5 - unused
-- *
-- *  ------- start of TLS (Thread-Local Storage) segments:
-- *
-- *   6 - TLS segment #1                       [ glibc's TLS segment ]
-- *   7 - TLS segment #2                       [ Wine's %fs Win32 segment ]
-- *   8 - TLS segment #3
-- *   9 - reserved
-- *  10 - reserved
-- *  11 - reserved
-- *
-- *  ------- start of kernel segments:
-- *
-- *  12 - kernel code segment          <==== new cacheline
-- *  13 - kernel data segment
-- *  14 - default user CS
-- *  15 - default user DS
-- *  16 - TSS
-- *  17 - LDT
-- *  18 - PNPBIOS support (16->32 gate)
-- *  19 - PNPBIOS support
-- *  20 - PNPBIOS support
-- *  21 - PNPBIOS support
-- *  22 - PNPBIOS support
-- *  23 - APM BIOS support
-- *  24 - APM BIOS support
-- *  25 - APM BIOS support 
-- *
-- *  26 - ESPFIX small SS
-- *  27 - per-cpu                      [ offset to per-cpu data area ]
-- *  28 - unused
-- *  29 - unused
-- *  30 - unused
-- *  31 - TSS for double fault handler
+- * create a kernel thread without removing it from tasklists
 - */
--#define GDT_ENTRY_TLS_ENTRIES 3
--#define GDT_ENTRY_TLS_MIN     6
--#define GDT_ENTRY_TLS_MAX     (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
+-extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 -
--#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
+-/*
+- * Return saved PC of a blocked thread.
+- * What is this good for? it will be always the scheduler or ret_from_fork.
+- */
+-#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8))
 -
--#define GDT_ENTRY_DEFAULT_USER_CS     14
--#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3)
+-extern unsigned long get_wchan(struct task_struct *p);
+-#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
+-#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
+-#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
 -
--#define GDT_ENTRY_DEFAULT_USER_DS     15
--#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS * 8 + 3)
 -
--#define GDT_ENTRY_KERNEL_BASE 12
+-struct microcode_header {
+-      unsigned int hdrver;
+-      unsigned int rev;
+-      unsigned int date;
+-      unsigned int sig;
+-      unsigned int cksum;
+-      unsigned int ldrver;
+-      unsigned int pf;
+-      unsigned int datasize;
+-      unsigned int totalsize;
+-      unsigned int reserved[3];
+-};
 -
--#define GDT_ENTRY_KERNEL_CS           (GDT_ENTRY_KERNEL_BASE + 0)
--#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8)
+-struct microcode {
+-      struct microcode_header hdr;
+-      unsigned int bits[0];
+-};
 -
--#define GDT_ENTRY_KERNEL_DS           (GDT_ENTRY_KERNEL_BASE + 1)
--#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8)
+-typedef struct microcode microcode_t;
+-typedef struct microcode_header microcode_header_t;
 -
--#define GDT_ENTRY_TSS                 (GDT_ENTRY_KERNEL_BASE + 4)
--#define GDT_ENTRY_LDT                 (GDT_ENTRY_KERNEL_BASE + 5)
+-/* microcode format is extended from prescott processors */
+-struct extended_signature {
+-      unsigned int sig;
+-      unsigned int pf;
+-      unsigned int cksum;
+-};
 -
--#define GDT_ENTRY_PNPBIOS_BASE                (GDT_ENTRY_KERNEL_BASE + 6)
--#define GDT_ENTRY_APMBIOS_BASE                (GDT_ENTRY_KERNEL_BASE + 11)
+-struct extended_sigtable {
+-      unsigned int count;
+-      unsigned int cksum;
+-      unsigned int reserved[3];
+-      struct extended_signature sigs[0];
+-};
 -
--#define GDT_ENTRY_ESPFIX_SS           (GDT_ENTRY_KERNEL_BASE + 14)
--#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
 -
--#define GDT_ENTRY_PERCPU                      (GDT_ENTRY_KERNEL_BASE + 15)
--#ifdef CONFIG_SMP
--#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
+-#if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2)
+-#define ASM_NOP1 P6_NOP1
+-#define ASM_NOP2 P6_NOP2
+-#define ASM_NOP3 P6_NOP3
+-#define ASM_NOP4 P6_NOP4
+-#define ASM_NOP5 P6_NOP5
+-#define ASM_NOP6 P6_NOP6
+-#define ASM_NOP7 P6_NOP7
+-#define ASM_NOP8 P6_NOP8
 -#else
--#define __KERNEL_PERCPU 0
+-#define ASM_NOP1 K8_NOP1
+-#define ASM_NOP2 K8_NOP2
+-#define ASM_NOP3 K8_NOP3
+-#define ASM_NOP4 K8_NOP4
+-#define ASM_NOP5 K8_NOP5
+-#define ASM_NOP6 K8_NOP6
+-#define ASM_NOP7 K8_NOP7
+-#define ASM_NOP8 K8_NOP8
 -#endif
 -
--#define GDT_ENTRY_DOUBLEFAULT_TSS     31
+-/* Opteron nops */
+-#define K8_NOP1 ".byte 0x90\n"
+-#define K8_NOP2       ".byte 0x66,0x90\n" 
+-#define K8_NOP3       ".byte 0x66,0x66,0x90\n" 
+-#define K8_NOP4       ".byte 0x66,0x66,0x66,0x90\n" 
+-#define K8_NOP5       K8_NOP3 K8_NOP2 
+-#define K8_NOP6       K8_NOP3 K8_NOP3
+-#define K8_NOP7       K8_NOP4 K8_NOP3
+-#define K8_NOP8       K8_NOP4 K8_NOP4
 -
--/*
-- * The GDT has 32 entries
-- */
--#define GDT_ENTRIES 32
--#define GDT_SIZE (GDT_ENTRIES * 8)
+-/* P6 nops */
+-/* uses eax dependencies (Intel-recommended choice) */
+-#define P6_NOP1       ".byte 0x90\n"
+-#define P6_NOP2       ".byte 0x66,0x90\n"
+-#define P6_NOP3       ".byte 0x0f,0x1f,0x00\n"
+-#define P6_NOP4       ".byte 0x0f,0x1f,0x40,0\n"
+-#define P6_NOP5       ".byte 0x0f,0x1f,0x44,0x00,0\n"
+-#define P6_NOP6       ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
+-#define P6_NOP7       ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
+-#define P6_NOP8       ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
 -
--/* Simple and small GDT entries for booting only */
+-#define ASM_NOP_MAX 8
 -
--#define GDT_ENTRY_BOOT_CS             2
--#define __BOOT_CS     (GDT_ENTRY_BOOT_CS * 8)
+-/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+-static inline void rep_nop(void)
+-{
+-      __asm__ __volatile__("rep;nop": : :"memory");
+-}
 -
--#define GDT_ENTRY_BOOT_DS             (GDT_ENTRY_BOOT_CS + 1)
--#define __BOOT_DS     (GDT_ENTRY_BOOT_DS * 8)
+-/* Stop speculative execution */
+-static inline void sync_core(void)
+-{ 
+-      int tmp;
+-      asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
+-} 
 -
--/* The PnP BIOS entries in the GDT */
--#define GDT_ENTRY_PNPBIOS_CS32                (GDT_ENTRY_PNPBIOS_BASE + 0)
--#define GDT_ENTRY_PNPBIOS_CS16                (GDT_ENTRY_PNPBIOS_BASE + 1)
--#define GDT_ENTRY_PNPBIOS_DS          (GDT_ENTRY_PNPBIOS_BASE + 2)
--#define GDT_ENTRY_PNPBIOS_TS1         (GDT_ENTRY_PNPBIOS_BASE + 3)
--#define GDT_ENTRY_PNPBIOS_TS2         (GDT_ENTRY_PNPBIOS_BASE + 4)
+-#define ARCH_HAS_PREFETCHW 1
+-static inline void prefetchw(void *x) 
+-{ 
+-      alternative_input("prefetcht0 (%1)",
+-                        "prefetchw (%1)",
+-                        X86_FEATURE_3DNOW,
+-                        "r" (x));
+-} 
 -
--/* The PnP BIOS selectors */
--#define PNP_CS32   (GDT_ENTRY_PNPBIOS_CS32 * 8)       /* segment for calling fn */
--#define PNP_CS16   (GDT_ENTRY_PNPBIOS_CS16 * 8)       /* code segment for BIOS */
--#define PNP_DS     (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */
--#define PNP_TS1    (GDT_ENTRY_PNPBIOS_TS1 * 8)        /* transfer data segment */
--#define PNP_TS2    (GDT_ENTRY_PNPBIOS_TS2 * 8)        /* another data segment */
+-#define ARCH_HAS_SPINLOCK_PREFETCH 1
 -
--/*
-- * The interrupt descriptor table has room for 256 idt's,
-- * the global descriptor table is dependent on the number
-- * of tasks we can have..
-- */
--#define IDT_ENTRIES 256
+-#define spin_lock_prefetch(x)  prefetchw(x)
 -
--/* Bottom two bits of selector give the ring privilege level */
--#define SEGMENT_RPL_MASK      0x3
--/* Bit 2 is table indicator (LDT/GDT) */
--#define SEGMENT_TI_MASK               0x4
+-#define cpu_relax()   rep_nop()
 -
--/* User mode is privilege level 3 */
--#define USER_RPL              0x3
--/* LDT segment has TI set, GDT has it cleared */
--#define SEGMENT_LDT           0x4
--#define SEGMENT_GDT           0x0
+-static inline void __monitor(const void *eax, unsigned long ecx,
+-              unsigned long edx)
+-{
+-      /* "monitor %eax,%ecx,%edx;" */
+-      asm volatile(
+-              ".byte 0x0f,0x01,0xc8;"
+-              : :"a" (eax), "c" (ecx), "d"(edx));
+-}
 -
--#define get_kernel_rpl()  (xen_feature(XENFEAT_supervisor_mode_kernel)?0:1)
+-static inline void __mwait(unsigned long eax, unsigned long ecx)
+-{
+-      /* "mwait %eax,%ecx;" */
+-      asm volatile(
+-              ".byte 0x0f,0x01,0xc9;"
+-              : :"a" (eax), "c" (ecx));
+-}
 -
--/*
-- * Matching rules for certain types of segments.
-- */
+-static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
+-{
+-      /* "mwait %eax,%ecx;" */
+-      asm volatile(
+-              "sti; .byte 0x0f,0x01,0xc9;"
+-              : :"a" (eax), "c" (ecx));
+-}
 -
--/* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */
--#define SEGMENT_IS_KERNEL_CODE(x) (((x) & ~3) == GDT_ENTRY_KERNEL_CS * 8 \
--                                   || ((x) & ~3) == (FLAT_KERNEL_CS & ~3))
+-extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
 -
--/* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
--#define SEGMENT_IS_FLAT_CODE(x)  (((x) & ~0x13) == GDT_ENTRY_KERNEL_CS * 8 \
--                                  || ((x) & ~3) == (FLAT_KERNEL_CS & ~3) \
--                                  || ((x) & ~3) == (FLAT_USER_CS & ~3))
+-#define stack_current() \
+-({                                                            \
+-      struct thread_info *ti;                                 \
+-      asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));  \
+-      ti->task;                                       \
+-})
+-
+-#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
+-
+-extern unsigned long boot_option_idle_override;
+-/* Boot loader type from the setup header */
+-extern int bootloader_type;
 -
--/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
--#define SEGMENT_IS_PNP_CODE(x)   (((x) & ~0x0b) == GDT_ENTRY_PNPBIOS_BASE * 8)
+-#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
 -
--#endif
---- a/include/asm-x86/mach-xen/asm/segment.h
-+++ b/include/asm-x86/mach-xen/asm/segment.h
+-#endif /* __ASM_X86_64_PROCESSOR_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/segment.h       2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/segment.h    2009-03-16 16:33:40.000000000 +0100
 @@ -1,5 +1,204 @@
 +#ifndef _ASM_X86_SEGMENT_H_
 +#define _ASM_X86_SEGMENT_H_
@@ -27439,8 +26967,161 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +#endif
 +
  #endif
---- a/include/asm-x86/mach-xen/asm/smp_32.h
-+++ b/include/asm-x86/mach-xen/asm/smp_32.h
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/segment_32.h    2008-12-15 11:27:22.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,150 +0,0 @@
+-#ifndef _ASM_SEGMENT_H
+-#define _ASM_SEGMENT_H
+-
+-/*
+- * The layout of the per-CPU GDT under Linux:
+- *
+- *   0 - null
+- *   1 - reserved
+- *   2 - reserved
+- *   3 - reserved
+- *
+- *   4 - unused                       <==== new cacheline
+- *   5 - unused
+- *
+- *  ------- start of TLS (Thread-Local Storage) segments:
+- *
+- *   6 - TLS segment #1                       [ glibc's TLS segment ]
+- *   7 - TLS segment #2                       [ Wine's %fs Win32 segment ]
+- *   8 - TLS segment #3
+- *   9 - reserved
+- *  10 - reserved
+- *  11 - reserved
+- *
+- *  ------- start of kernel segments:
+- *
+- *  12 - kernel code segment          <==== new cacheline
+- *  13 - kernel data segment
+- *  14 - default user CS
+- *  15 - default user DS
+- *  16 - TSS
+- *  17 - LDT
+- *  18 - PNPBIOS support (16->32 gate)
+- *  19 - PNPBIOS support
+- *  20 - PNPBIOS support
+- *  21 - PNPBIOS support
+- *  22 - PNPBIOS support
+- *  23 - APM BIOS support
+- *  24 - APM BIOS support
+- *  25 - APM BIOS support 
+- *
+- *  26 - ESPFIX small SS
+- *  27 - per-cpu                      [ offset to per-cpu data area ]
+- *  28 - unused
+- *  29 - unused
+- *  30 - unused
+- *  31 - TSS for double fault handler
+- */
+-#define GDT_ENTRY_TLS_ENTRIES 3
+-#define GDT_ENTRY_TLS_MIN     6
+-#define GDT_ENTRY_TLS_MAX     (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
+-
+-#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
+-
+-#define GDT_ENTRY_DEFAULT_USER_CS     14
+-#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3)
+-
+-#define GDT_ENTRY_DEFAULT_USER_DS     15
+-#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS * 8 + 3)
+-
+-#define GDT_ENTRY_KERNEL_BASE 12
+-
+-#define GDT_ENTRY_KERNEL_CS           (GDT_ENTRY_KERNEL_BASE + 0)
+-#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8)
+-
+-#define GDT_ENTRY_KERNEL_DS           (GDT_ENTRY_KERNEL_BASE + 1)
+-#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8)
+-
+-#define GDT_ENTRY_TSS                 (GDT_ENTRY_KERNEL_BASE + 4)
+-#define GDT_ENTRY_LDT                 (GDT_ENTRY_KERNEL_BASE + 5)
+-
+-#define GDT_ENTRY_PNPBIOS_BASE                (GDT_ENTRY_KERNEL_BASE + 6)
+-#define GDT_ENTRY_APMBIOS_BASE                (GDT_ENTRY_KERNEL_BASE + 11)
+-
+-#define GDT_ENTRY_ESPFIX_SS           (GDT_ENTRY_KERNEL_BASE + 14)
+-#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
+-
+-#define GDT_ENTRY_PERCPU                      (GDT_ENTRY_KERNEL_BASE + 15)
+-#ifdef CONFIG_SMP
+-#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
+-#else
+-#define __KERNEL_PERCPU 0
+-#endif
+-
+-#define GDT_ENTRY_DOUBLEFAULT_TSS     31
+-
+-/*
+- * The GDT has 32 entries
+- */
+-#define GDT_ENTRIES 32
+-#define GDT_SIZE (GDT_ENTRIES * 8)
+-
+-/* Simple and small GDT entries for booting only */
+-
+-#define GDT_ENTRY_BOOT_CS             2
+-#define __BOOT_CS     (GDT_ENTRY_BOOT_CS * 8)
+-
+-#define GDT_ENTRY_BOOT_DS             (GDT_ENTRY_BOOT_CS + 1)
+-#define __BOOT_DS     (GDT_ENTRY_BOOT_DS * 8)
+-
+-/* The PnP BIOS entries in the GDT */
+-#define GDT_ENTRY_PNPBIOS_CS32                (GDT_ENTRY_PNPBIOS_BASE + 0)
+-#define GDT_ENTRY_PNPBIOS_CS16                (GDT_ENTRY_PNPBIOS_BASE + 1)
+-#define GDT_ENTRY_PNPBIOS_DS          (GDT_ENTRY_PNPBIOS_BASE + 2)
+-#define GDT_ENTRY_PNPBIOS_TS1         (GDT_ENTRY_PNPBIOS_BASE + 3)
+-#define GDT_ENTRY_PNPBIOS_TS2         (GDT_ENTRY_PNPBIOS_BASE + 4)
+-
+-/* The PnP BIOS selectors */
+-#define PNP_CS32   (GDT_ENTRY_PNPBIOS_CS32 * 8)       /* segment for calling fn */
+-#define PNP_CS16   (GDT_ENTRY_PNPBIOS_CS16 * 8)       /* code segment for BIOS */
+-#define PNP_DS     (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */
+-#define PNP_TS1    (GDT_ENTRY_PNPBIOS_TS1 * 8)        /* transfer data segment */
+-#define PNP_TS2    (GDT_ENTRY_PNPBIOS_TS2 * 8)        /* another data segment */
+-
+-/*
+- * The interrupt descriptor table has room for 256 idt's,
+- * the global descriptor table is dependent on the number
+- * of tasks we can have..
+- */
+-#define IDT_ENTRIES 256
+-
+-/* Bottom two bits of selector give the ring privilege level */
+-#define SEGMENT_RPL_MASK      0x3
+-/* Bit 2 is table indicator (LDT/GDT) */
+-#define SEGMENT_TI_MASK               0x4
+-
+-/* User mode is privilege level 3 */
+-#define USER_RPL              0x3
+-/* LDT segment has TI set, GDT has it cleared */
+-#define SEGMENT_LDT           0x4
+-#define SEGMENT_GDT           0x0
+-
+-#define get_kernel_rpl()  (xen_feature(XENFEAT_supervisor_mode_kernel)?0:1)
+-
+-/*
+- * Matching rules for certain types of segments.
+- */
+-
+-/* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */
+-#define SEGMENT_IS_KERNEL_CODE(x) (((x) & ~3) == GDT_ENTRY_KERNEL_CS * 8 \
+-                                   || ((x) & ~3) == (FLAT_KERNEL_CS & ~3))
+-
+-/* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
+-#define SEGMENT_IS_FLAT_CODE(x)  (((x) & ~0x13) == GDT_ENTRY_KERNEL_CS * 8 \
+-                                  || ((x) & ~3) == (FLAT_KERNEL_CS & ~3) \
+-                                  || ((x) & ~3) == (FLAT_USER_CS & ~3))
+-
+-/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
+-#define SEGMENT_IS_PNP_CODE(x)   (((x) & ~0x0b) == GDT_ENTRY_PNPBIOS_BASE * 8)
+-
+-#endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/smp_32.h        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/smp_32.h     2009-03-16 16:33:40.000000000 +0100
 @@ -1,56 +1,51 @@
  #ifndef __ASM_SMP_H
  #define __ASM_SMP_H
@@ -27638,8 +27319,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -
 +#endif /* !ASSEMBLY */
  #endif
---- a/include/asm-x86/mach-xen/asm/smp_64.h
-+++ b/include/asm-x86/mach-xen/asm/smp_64.h
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/smp_64.h        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/smp_64.h     2009-03-16 16:33:40.000000000 +0100
 @@ -1,139 +1,103 @@
  #ifndef __ASM_SMP_H
  #define __ASM_SMP_H
@@ -27831,8 +27512,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -#endif /* !CONFIG_SMP */
  #endif
  
---- /dev/null
-+++ b/include/asm-x86/mach-xen/asm/spinlock.h
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/spinlock.h   2009-03-16 16:33:40.000000000 +0100
 @@ -0,0 +1,333 @@
 +#ifndef _X86_SPINLOCK_H_
 +#define _X86_SPINLOCK_H_
@@ -27991,184 +27672,582 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +                  : "memory", "cc"); \
 +      } while (0)
 +
-+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
++static inline int __raw_spin_trylock(raw_spinlock_t *lock)
++{
++      int tmp;
++      int new;
++
++      asm("movl %2, %0\n\t"
++          "movl %0, %1\n\t"
++          "roll $16, %0\n\t"
++          "cmpl %0, %1\n\t"
++          "leal 0x00010000(%" REG_PTR_MODE "0), %1\n\t"
++          "jne 1f\n\t"
++          LOCK_PREFIX "cmpxchgl %1, %2\n"
++          "1:\t"
++          "sete %b1\n\t"
++          "movzbl %b1, %0\n\t"
++          : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
++          :
++          : "memory", "cc");
++
++      return tmp;
++}
++
++static inline void __raw_spin_unlock(raw_spinlock_t *lock)
++{
++      unsigned int token, tmp;
++      bool kick;
++
++      asm(UNLOCK_LOCK_PREFIX "incw %2\n\t"
++          "movl %2, %0\n\t"
++          "shldl $16, %0, %3\n\t"
++          "cmpw %w3, %w0\n\t"
++          "setne %1"
++          : "=&r" (token), "=qm" (kick), "+m" (lock->slock), "=&r" (tmp)
++          :
++          : "memory", "cc");
++      if (kick)
++              xen_spin_kick(lock, token);
++}
++#endif
++
++static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
++{
++      int tmp = *(volatile signed int *)(&(lock)->slock);
++
++      return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1 << TICKET_SHIFT) - 1));
++}
++
++static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
++{
++      int tmp = *(volatile signed int *)(&(lock)->slock);
++
++      return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1;
++}
++
++static inline void __raw_spin_lock(raw_spinlock_t *lock)
++{
++      unsigned int token, count;
++      bool free;
++
++      __raw_spin_lock_preamble;
++      if (unlikely(!free))
++              token = xen_spin_adjust(lock, token);
++      do {
++              count = 1 << 10;
++              __raw_spin_lock_body;
++      } while (unlikely(!count) && !xen_spin_wait(lock, token));
++}
++
++static inline void __raw_spin_lock_flags(raw_spinlock_t *lock,
++                                       unsigned long flags)
++{
++      unsigned int token, count;
++      bool free;
++
++      __raw_spin_lock_preamble;
++      if (unlikely(!free))
++              token = xen_spin_adjust(lock, token);
++      do {
++              count = 1 << 10;
++              __raw_spin_lock_body;
++      } while (unlikely(!count) && !xen_spin_wait_flags(lock, &token, flags));
++}
++
++static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
++{
++      while (__raw_spin_is_locked(lock))
++              cpu_relax();
++}
++
++/*
++ * Read-write spinlocks, allowing multiple readers
++ * but only one writer.
++ *
++ * NOTE! it is quite common to have readers in interrupts
++ * but no interrupt writers. For those circumstances we
++ * can "mix" irq-safe locks - any writer needs to get a
++ * irq-safe write-lock, but readers can get non-irqsafe
++ * read-locks.
++ *
++ * On x86, we implement read-write locks as a 32-bit counter
++ * with the high bit (sign) being the "contended" bit.
++ */
++
++/**
++ * read_can_lock - would read_trylock() succeed?
++ * @lock: the rwlock in question.
++ */
++static inline int __raw_read_can_lock(raw_rwlock_t *lock)
 +{
-+      int tmp;
-+      int new;
-+
-+      asm("movl %2, %0\n\t"
-+          "movl %0, %1\n\t"
-+          "roll $16, %0\n\t"
-+          "cmpl %0, %1\n\t"
-+          "leal 0x00010000(%" REG_PTR_MODE "0), %1\n\t"
-+          "jne 1f\n\t"
-+          LOCK_PREFIX "cmpxchgl %1, %2\n"
-+          "1:\t"
-+          "sete %b1\n\t"
-+          "movzbl %b1, %0\n\t"
-+          : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
-+          :
-+          : "memory", "cc");
++      return (int)(lock)->lock > 0;
++}
 +
-+      return tmp;
++/**
++ * write_can_lock - would write_trylock() succeed?
++ * @lock: the rwlock in question.
++ */
++static inline int __raw_write_can_lock(raw_rwlock_t *lock)
++{
++      return (lock)->lock == RW_LOCK_BIAS;
 +}
 +
-+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
++static inline void __raw_read_lock(raw_rwlock_t *rw)
 +{
-+      unsigned int token, tmp;
-+      bool kick;
++      asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
++                   "jns 1f\n"
++                   "call __read_lock_failed\n\t"
++                   "1:\n"
++                   ::LOCK_PTR_REG (rw) : "memory");
++}
 +
-+      asm(UNLOCK_LOCK_PREFIX "incw %2\n\t"
-+          "movl %2, %0\n\t"
-+          "shldl $16, %0, %3\n\t"
-+          "cmpw %w3, %w0\n\t"
-+          "setne %1"
-+          : "=&r" (token), "=qm" (kick), "+m" (lock->slock), "=&r" (tmp)
-+          :
-+          : "memory", "cc");
-+      if (kick)
-+              xen_spin_kick(lock, token);
++static inline void __raw_write_lock(raw_rwlock_t *rw)
++{
++      asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
++                   "jz 1f\n"
++                   "call __write_lock_failed\n\t"
++                   "1:\n"
++                   ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
 +}
-+#endif
 +
-+static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
++static inline int __raw_read_trylock(raw_rwlock_t *lock)
 +{
-+      int tmp = *(volatile signed int *)(&(lock)->slock);
++      atomic_t *count = (atomic_t *)lock;
 +
-+      return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1 << TICKET_SHIFT) - 1));
++      atomic_dec(count);
++      if (atomic_read(count) >= 0)
++              return 1;
++      atomic_inc(count);
++      return 0;
 +}
 +
-+static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
++static inline int __raw_write_trylock(raw_rwlock_t *lock)
 +{
-+      int tmp = *(volatile signed int *)(&(lock)->slock);
++      atomic_t *count = (atomic_t *)lock;
 +
-+      return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1;
++      if (atomic_sub_and_test(RW_LOCK_BIAS, count))
++              return 1;
++      atomic_add(RW_LOCK_BIAS, count);
++      return 0;
 +}
 +
-+static inline void __raw_spin_lock(raw_spinlock_t *lock)
++static inline void __raw_read_unlock(raw_rwlock_t *rw)
 +{
-+      unsigned int token, count;
-+      bool free;
++      asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
++}
 +
-+      __raw_spin_lock_preamble;
-+      if (unlikely(!free))
-+              token = xen_spin_adjust(lock, token);
-+      do {
-+              count = 1 << 10;
-+              __raw_spin_lock_body;
-+      } while (unlikely(!count) && !xen_spin_wait(lock, token));
++static inline void __raw_write_unlock(raw_rwlock_t *rw)
++{
++      asm volatile(LOCK_PREFIX "addl %1, %0"
++                   : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
++}
++
++#define _raw_spin_relax(lock) cpu_relax()
++#define _raw_read_relax(lock) cpu_relax()
++#define _raw_write_relax(lock)        cpu_relax()
++
++#endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/system.h        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/system.h     2009-03-16 16:33:40.000000000 +0100
+@@ -1,5 +1,393 @@
++#ifndef _ASM_X86_SYSTEM_H_
++#define _ASM_X86_SYSTEM_H_
++
++#include <asm/asm.h>
++#include <asm/segment.h>
++#include <asm/cpufeature.h>
++#include <asm/cmpxchg.h>
++#include <asm/nops.h>
++#include <asm/hypervisor.h>
++
++#include <linux/kernel.h>
++#include <linux/irqflags.h>
++
++/* entries in ARCH_DLINFO: */
++#ifdef CONFIG_IA32_EMULATION
++# define AT_VECTOR_SIZE_ARCH 2
++#else
++# define AT_VECTOR_SIZE_ARCH 1
++#endif
++
++#ifdef CONFIG_X86_32
++
++struct task_struct; /* one of the stranger aspects of C forward declarations */
++struct task_struct *__switch_to(struct task_struct *prev,
++                              struct task_struct *next);
++
++/*
++ * Saving eflags is important. It switches not only IOPL between tasks,
++ * it also protects other tasks from NT leaking through sysenter etc.
++ */
++#define switch_to(prev, next, last) do {                              \
++      unsigned long esi, edi;                                         \
++      asm volatile("pushfl\n\t"               /* Save flags */        \
++                   "pushl %%ebp\n\t"                                  \
++                   "movl %%esp,%0\n\t"        /* save ESP */          \
++                   "movl %5,%%esp\n\t"        /* restore ESP */       \
++                   "movl $1f,%1\n\t"          /* save EIP */          \
++                   "pushl %6\n\t"             /* restore EIP */       \
++                   "jmp __switch_to\n"                                \
++                   "1:\t"                                             \
++                   "popl %%ebp\n\t"                                   \
++                   "popfl"                                            \
++                   :"=m" (prev->thread.sp), "=m" (prev->thread.ip),   \
++                    "=a" (last), "=S" (esi), "=D" (edi)               \
++                   :"m" (next->thread.sp), "m" (next->thread.ip),     \
++                    "2" (prev), "d" (next));                          \
++} while (0)
++
++/*
++ * disable hlt during certain critical i/o operations
++ */
++#define HAVE_DISABLE_HLT
++#else
++#define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
++#define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
++
++/* frame pointer must be last for get_wchan */
++#define SAVE_CONTEXT    "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"
++#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t"
++
++#define __EXTRA_CLOBBER  \
++      , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
++        "r12", "r13", "r14", "r15"
++
++/* Save restore flags to clear handle leaking NT */
++#define switch_to(prev, next, last) \
++      asm volatile(SAVE_CONTEXT                                                   \
++           "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */       \
++           "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \
++           "call __switch_to\n\t"                                       \
++           ".globl thread_return\n"                                     \
++           "thread_return:\n\t"                                         \
++           "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"                       \
++           "movq %P[thread_info](%%rsi),%%r8\n\t"                       \
++           LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"        \
++           "movq %%rax,%%rdi\n\t"                                       \
++           "jc   ret_from_fork\n\t"                                     \
++           RESTORE_CONTEXT                                              \
++           : "=a" (last)                                                \
++           : [next] "S" (next), [prev] "D" (prev),                      \
++             [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \
++             [ti_flags] "i" (offsetof(struct thread_info, flags)),      \
++             [tif_fork] "i" (TIF_FORK),                                 \
++             [thread_info] "i" (offsetof(struct task_struct, stack)),   \
++             [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))  \
++           : "memory", "cc" __EXTRA_CLOBBER)
++#endif
++
++#ifdef __KERNEL__
++#define _set_base(addr, base) do { unsigned long __pr; \
++__asm__ __volatile__ ("movw %%dx,%1\n\t" \
++      "rorl $16,%%edx\n\t" \
++      "movb %%dl,%2\n\t" \
++      "movb %%dh,%3" \
++      :"=&d" (__pr) \
++      :"m" (*((addr)+2)), \
++       "m" (*((addr)+4)), \
++       "m" (*((addr)+7)), \
++       "0" (base) \
++      ); } while (0)
++
++#define _set_limit(addr, limit) do { unsigned long __lr; \
++__asm__ __volatile__ ("movw %%dx,%1\n\t" \
++      "rorl $16,%%edx\n\t" \
++      "movb %2,%%dh\n\t" \
++      "andb $0xf0,%%dh\n\t" \
++      "orb %%dh,%%dl\n\t" \
++      "movb %%dl,%2" \
++      :"=&d" (__lr) \
++      :"m" (*(addr)), \
++       "m" (*((addr)+6)), \
++       "0" (limit) \
++      ); } while (0)
++
++#define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base))
++#define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1))
++
++extern void load_gs_index(unsigned);
++
++/*
++ * Load a segment. Fall back on loading the zero
++ * segment if something goes wrong..
++ */
++#define loadsegment(seg, value)                       \
++      asm volatile("\n"                       \
++              "1:\t"                          \
++              "movl %k0,%%" #seg "\n"         \
++              "2:\n"                          \
++              ".section .fixup,\"ax\"\n"      \
++              "3:\t"                          \
++              "movl %k1, %%" #seg "\n\t"      \
++              "jmp 2b\n"                      \
++              ".previous\n"                   \
++              _ASM_EXTABLE(1b,3b)             \
++              : :"r" (value), "r" (0))
++
++
++/*
++ * Save a segment register away
++ */
++#define savesegment(seg, value) \
++      asm volatile("mov %%" #seg ",%0":"=rm" (value))
++
++static inline unsigned long get_limit(unsigned long segment)
++{
++      unsigned long __limit;
++      __asm__("lsll %1,%0"
++              :"=r" (__limit):"r" (segment));
++      return __limit+1;
 +}
 +
-+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock,
-+                                       unsigned long flags)
++static inline void xen_clts(void)
 +{
-+      unsigned int token, count;
-+      bool free;
-+
-+      __raw_spin_lock_preamble;
-+      if (unlikely(!free))
-+              token = xen_spin_adjust(lock, token);
-+      do {
-+              count = 1 << 10;
-+              __raw_spin_lock_body;
-+      } while (unlikely(!count) && !xen_spin_wait_flags(lock, &token, flags));
++      HYPERVISOR_fpu_taskswitch(0);
 +}
 +
-+static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
++static inline void xen_stts(void)
 +{
-+      while (__raw_spin_is_locked(lock))
-+              cpu_relax();
++      HYPERVISOR_fpu_taskswitch(1);
 +}
 +
 +/*
-+ * Read-write spinlocks, allowing multiple readers
-+ * but only one writer.
-+ *
-+ * NOTE! it is quite common to have readers in interrupts
-+ * but no interrupt writers. For those circumstances we
-+ * can "mix" irq-safe locks - any writer needs to get a
-+ * irq-safe write-lock, but readers can get non-irqsafe
-+ * read-locks.
-+ *
-+ * On x86, we implement read-write locks as a 32-bit counter
-+ * with the high bit (sign) being the "contended" bit.
++ * Volatile isn't enough to prevent the compiler from reordering the
++ * read/write functions for the control registers and messing everything up.
++ * A memory clobber would solve the problem, but would prevent reordering of
++ * all loads stores around it, which can hurt performance. Solution is to
++ * use a variable and mimic reads and writes to it to enforce serialization
 + */
++static unsigned long __force_order;
 +
-+/**
-+ * read_can_lock - would read_trylock() succeed?
-+ * @lock: the rwlock in question.
-+ */
-+static inline int __raw_read_can_lock(raw_rwlock_t *lock)
++static inline unsigned long xen_read_cr0(void)
 +{
-+      return (int)(lock)->lock > 0;
++      unsigned long val;
++      asm volatile("mov %%cr0,%0\n\t" :"=r" (val), "=m" (__force_order));
++      return val;
 +}
 +
-+/**
-+ * write_can_lock - would write_trylock() succeed?
-+ * @lock: the rwlock in question.
-+ */
-+static inline int __raw_write_can_lock(raw_rwlock_t *lock)
++static inline void xen_write_cr0(unsigned long val)
 +{
-+      return (lock)->lock == RW_LOCK_BIAS;
++      asm volatile("mov %0,%%cr0": :"r" (val), "m" (__force_order));
 +}
 +
-+static inline void __raw_read_lock(raw_rwlock_t *rw)
++#define xen_read_cr2() (current_vcpu_info()->arch.cr2)
++#define xen_write_cr2(val) ((void)(current_vcpu_info()->arch.cr2 = (val)))
++
++static inline unsigned long xen_read_cr3(void)
 +{
-+      asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
-+                   "jns 1f\n"
-+                   "call __read_lock_failed\n\t"
-+                   "1:\n"
-+                   ::LOCK_PTR_REG (rw) : "memory");
++      unsigned long val;
++      asm volatile("mov %%cr3,%0\n\t" :"=r" (val), "=m" (__force_order));
++#ifdef CONFIG_X86_32
++      return mfn_to_pfn(xen_cr3_to_pfn(val)) << PAGE_SHIFT;
++#else
++      return machine_to_phys(val);
++#endif
 +}
 +
-+static inline void __raw_write_lock(raw_rwlock_t *rw)
++static inline void xen_write_cr3(unsigned long val)
 +{
-+      asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
-+                   "jz 1f\n"
-+                   "call __write_lock_failed\n\t"
-+                   "1:\n"
-+                   ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
++#ifdef CONFIG_X86_32
++      val = xen_pfn_to_cr3(pfn_to_mfn(val >> PAGE_SHIFT));
++#else
++      val = phys_to_machine(val);
++#endif
++      asm volatile("mov %0,%%cr3": :"r" (val), "m" (__force_order));
 +}
 +
-+static inline int __raw_read_trylock(raw_rwlock_t *lock)
++static inline unsigned long xen_read_cr4(void)
 +{
-+      atomic_t *count = (atomic_t *)lock;
++      unsigned long val;
++      asm volatile("mov %%cr4,%0\n\t" :"=r" (val), "=m" (__force_order));
++      return val;
++}
 +
-+      atomic_dec(count);
-+      if (atomic_read(count) >= 0)
-+              return 1;
-+      atomic_inc(count);
++#define xen_read_cr4_safe() xen_read_cr4()
++
++static inline void xen_write_cr4(unsigned long val)
++{
++      asm volatile("mov %0,%%cr4": :"r" (val), "m" (__force_order));
++}
++
++#ifdef CONFIG_X86_64
++static inline unsigned long xen_read_cr8(void)
++{
 +      return 0;
 +}
 +
-+static inline int __raw_write_trylock(raw_rwlock_t *lock)
++static inline void xen_write_cr8(unsigned long val)
 +{
-+      atomic_t *count = (atomic_t *)lock;
++      BUG_ON(val);
++}
++#endif
 +
-+      if (atomic_sub_and_test(RW_LOCK_BIAS, count))
-+              return 1;
-+      atomic_add(RW_LOCK_BIAS, count);
-+      return 0;
++static inline void xen_wbinvd(void)
++{
++      asm volatile("wbinvd": : :"memory");
 +}
++#define read_cr0()    (xen_read_cr0())
++#define write_cr0(x)  (xen_write_cr0(x))
++#define read_cr2()    (xen_read_cr2())
++#define write_cr2(x)  (xen_write_cr2(x))
++#define read_cr3()    (xen_read_cr3())
++#define write_cr3(x)  (xen_write_cr3(x))
++#define read_cr4()    (xen_read_cr4())
++#define read_cr4_safe()       (xen_read_cr4_safe())
++#define write_cr4(x)  (xen_write_cr4(x))
++#define wbinvd()      (xen_wbinvd())
++#ifdef CONFIG_X86_64
++#define read_cr8()    (xen_read_cr8())
++#define write_cr8(x)  (xen_write_cr8(x))
++#endif
 +
-+static inline void __raw_read_unlock(raw_rwlock_t *rw)
++/* Clear the 'TS' bit */
++#define clts()                (xen_clts())
++#define stts()                (xen_stts())
++
++#endif /* __KERNEL__ */
++
++static inline void clflush(volatile void *__p)
 +{
-+      asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
++      asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
 +}
 +
-+static inline void __raw_write_unlock(raw_rwlock_t *rw)
++#define nop() __asm__ __volatile__ ("nop")
++
++void disable_hlt(void);
++void enable_hlt(void);
++
++extern int es7000_plat;
++void cpu_idle_wait(void);
++
++extern unsigned long arch_align_stack(unsigned long sp);
++extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
++
++void default_idle(void);
++
++/*
++ * Force strict CPU ordering.
++ * And yes, this is required on UP too when we're talking
++ * to devices.
++ */
+ #ifdef CONFIG_X86_32
+-# include "system_32.h"
++/*
++ * For now, "wmb()" doesn't actually do anything, as all
++ * Intel CPU's follow what Intel calls a *Processor Order*,
++ * in which all writes are seen in the program order even
++ * outside the CPU.
++ *
++ * I expect future Intel CPU's to have a weaker ordering,
++ * but I'd also expect them to finally get their act together
++ * and add some real memory barriers if so.
++ *
++ * Some non intel clones support out of order store. wmb() ceases to be a
++ * nop for these.
++ */
++#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
++#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
++#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
++#else
++#define mb()  asm volatile("mfence":::"memory")
++#define rmb() asm volatile("lfence":::"memory")
++#define wmb() asm volatile("sfence" ::: "memory")
++#endif
++
++/**
++ * read_barrier_depends - Flush all pending reads that subsequents reads
++ * depend on.
++ *
++ * No data-dependent reads from memory-like regions are ever reordered
++ * over this barrier.  All reads preceding this primitive are guaranteed
++ * to access memory (but not necessarily other CPUs' caches) before any
++ * reads following this primitive that depend on the data return by
++ * any of the preceding reads.  This primitive is much lighter weight than
++ * rmb() on most CPUs, and is never heavier weight than is
++ * rmb().
++ *
++ * These ordering constraints are respected by both the local CPU
++ * and the compiler.
++ *
++ * Ordering is not guaranteed by anything other than these primitives,
++ * not even by data dependencies.  See the documentation for
++ * memory_barrier() for examples and URLs to more information.
++ *
++ * For example, the following code would force ordering (the initial
++ * value of "a" is zero, "b" is one, and "p" is "&a"):
++ *
++ * <programlisting>
++ *    CPU 0                           CPU 1
++ *
++ *    b = 2;
++ *    memory_barrier();
++ *    p = &b;                         q = p;
++ *                                    read_barrier_depends();
++ *                                    d = *q;
++ * </programlisting>
++ *
++ * because the read of "*q" depends on the read of "p" and these
++ * two reads are separated by a read_barrier_depends().  However,
++ * the following code, with the same initial values for "a" and "b":
++ *
++ * <programlisting>
++ *    CPU 0                           CPU 1
++ *
++ *    a = 2;
++ *    memory_barrier();
++ *    b = 3;                          y = b;
++ *                                    read_barrier_depends();
++ *                                    x = a;
++ * </programlisting>
++ *
++ * does not enforce ordering, since there is no data dependency between
++ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
++ * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
++ * in cases like this where there are no data dependencies.
++ **/
++
++#define read_barrier_depends()        do { } while (0)
++
++#ifdef CONFIG_SMP
++#define smp_mb()      mb()
++#ifdef CONFIG_X86_PPRO_FENCE
++# define smp_rmb()    rmb()
+ #else
+-# include "system_64.h"
++# define smp_rmb()    barrier()
++#endif
++#ifdef CONFIG_X86_OOSTORE
++# define smp_wmb()    wmb()
++#else
++# define smp_wmb()    barrier()
++#endif
++#define smp_read_barrier_depends()    read_barrier_depends()
++#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
++#else
++#define smp_mb()      barrier()
++#define smp_rmb()     barrier()
++#define smp_wmb()     barrier()
++#define smp_read_barrier_depends()    do { } while (0)
++#define set_mb(var, value) do { var = value; barrier(); } while (0)
++#endif
++
++/*
++ * Stop RDTSC speculation. This is needed when you need to use RDTSC
++ * (or get_cycles or vread that possibly accesses the TSC) in a defined
++ * code region.
++ *
++ * (Could use an alternative three way for this if there was one.)
++ */
++static inline void rdtsc_barrier(void)
 +{
-+      asm volatile(LOCK_PREFIX "addl %1, %0"
-+                   : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
++      alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
++      alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
 +}
 +
-+#define _raw_spin_relax(lock) cpu_relax()
-+#define _raw_read_relax(lock) cpu_relax()
-+#define _raw_write_relax(lock)        cpu_relax()
-+
-+#endif
---- a/include/asm-x86/mach-xen/asm/system_32.h
-+++ /dev/null
+ #endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/system_32.h     2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
 @@ -1,312 +0,0 @@
 -#ifndef __ASM_SYSTEM_H
 -#define __ASM_SYSTEM_H
@@ -28482,8 +28561,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -void __show_registers(struct pt_regs *, int all);
 -
 -#endif
---- a/include/asm-x86/mach-xen/asm/system_64.h
-+++ b/include/asm-x86/mach-xen/asm/system_64.h
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/system_64.h     2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/system_64.h  2009-03-16 16:33:40.000000000 +0100
 @@ -1,122 +1,9 @@
  #ifndef __ASM_SYSTEM_H
  #define __ASM_SYSTEM_H
@@ -28565,501 +28644,214 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 - */
 -#define clts() (HYPERVISOR_fpu_taskswitch(0))
 -
--static inline unsigned long read_cr0(void)
--{ 
--      unsigned long cr0;
--      asm volatile("movq %%cr0,%0" : "=r" (cr0));
--      return cr0;
--}
--
--static inline void write_cr0(unsigned long val) 
--{ 
--      asm volatile("movq %0,%%cr0" :: "r" (val));
--}
--
--#define read_cr2() current_vcpu_info()->arch.cr2
--
--#define write_cr2(val) ((void)(current_vcpu_info()->arch.cr2 = (val)))
--
--#define read_cr3() ({ \
--      unsigned long __dummy; \
--      asm volatile("movq %%cr3,%0" : "=r" (__dummy)); \
--      machine_to_phys(__dummy); \
--})
--
--static inline void write_cr3(unsigned long val)
--{
--      val = phys_to_machine(val);
--      asm volatile("movq %0,%%cr3" :: "r" (val) : "memory");
--}
--
--static inline unsigned long read_cr4(void)
--{ 
--      unsigned long cr4;
--      asm volatile("movq %%cr4,%0" : "=r" (cr4));
--      return cr4;
--}
--
--static inline void write_cr4(unsigned long val)
--{ 
--      asm volatile("movq %0,%%cr4" :: "r" (val) : "memory");
--}
- static inline unsigned long read_cr8(void)
- {
-@@ -128,52 +15,6 @@ static inline void write_cr8(unsigned lo
-       BUG_ON(val);
- }
--#define stts() (HYPERVISOR_fpu_taskswitch(1))
--
--#define wbinvd() \
--      __asm__ __volatile__ ("wbinvd": : :"memory")
--
--#endif        /* __KERNEL__ */
--
--static inline void clflush(volatile void *__p)
--{
--      asm volatile("clflush %0" : "+m" (*(char __force *)__p));
--}
--
--#define nop() __asm__ __volatile__ ("nop")
--
--#ifdef CONFIG_SMP
--#define smp_mb()      mb()
--#define smp_rmb()     barrier()
--#define smp_wmb()     barrier()
--#define smp_read_barrier_depends()    do {} while(0)
--#else
--#define smp_mb()      barrier()
--#define smp_rmb()     barrier()
--#define smp_wmb()     barrier()
--#define smp_read_barrier_depends()    do {} while(0)
--#endif
--
--    
--/*
-- * Force strict CPU ordering.
-- * And yes, this is required on UP too when we're talking
-- * to devices.
-- */
--#define mb()  asm volatile("mfence":::"memory")
--#define rmb() asm volatile("lfence":::"memory")
--#define wmb() asm volatile("sfence" ::: "memory")
--
--#define read_barrier_depends()        do {} while(0)
--#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
--
--#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
--
- #include <linux/irqflags.h>
--void cpu_idle_wait(void);
--
--extern unsigned long arch_align_stack(unsigned long sp);
--extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
--
- #endif
---- a/include/asm-x86/mach-xen/asm/system.h
-+++ b/include/asm-x86/mach-xen/asm/system.h
-@@ -1,5 +1,393 @@
-+#ifndef _ASM_X86_SYSTEM_H_
-+#define _ASM_X86_SYSTEM_H_
-+
-+#include <asm/asm.h>
-+#include <asm/segment.h>
-+#include <asm/cpufeature.h>
-+#include <asm/cmpxchg.h>
-+#include <asm/nops.h>
-+#include <asm/hypervisor.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/irqflags.h>
-+
-+/* entries in ARCH_DLINFO: */
-+#ifdef CONFIG_IA32_EMULATION
-+# define AT_VECTOR_SIZE_ARCH 2
-+#else
-+# define AT_VECTOR_SIZE_ARCH 1
-+#endif
-+
-+#ifdef CONFIG_X86_32
-+
-+struct task_struct; /* one of the stranger aspects of C forward declarations */
-+struct task_struct *__switch_to(struct task_struct *prev,
-+                              struct task_struct *next);
-+
-+/*
-+ * Saving eflags is important. It switches not only IOPL between tasks,
-+ * it also protects other tasks from NT leaking through sysenter etc.
-+ */
-+#define switch_to(prev, next, last) do {                              \
-+      unsigned long esi, edi;                                         \
-+      asm volatile("pushfl\n\t"               /* Save flags */        \
-+                   "pushl %%ebp\n\t"                                  \
-+                   "movl %%esp,%0\n\t"        /* save ESP */          \
-+                   "movl %5,%%esp\n\t"        /* restore ESP */       \
-+                   "movl $1f,%1\n\t"          /* save EIP */          \
-+                   "pushl %6\n\t"             /* restore EIP */       \
-+                   "jmp __switch_to\n"                                \
-+                   "1:\t"                                             \
-+                   "popl %%ebp\n\t"                                   \
-+                   "popfl"                                            \
-+                   :"=m" (prev->thread.sp), "=m" (prev->thread.ip),   \
-+                    "=a" (last), "=S" (esi), "=D" (edi)               \
-+                   :"m" (next->thread.sp), "m" (next->thread.ip),     \
-+                    "2" (prev), "d" (next));                          \
-+} while (0)
-+
-+/*
-+ * disable hlt during certain critical i/o operations
-+ */
-+#define HAVE_DISABLE_HLT
-+#else
-+#define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
-+#define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
-+
-+/* frame pointer must be last for get_wchan */
-+#define SAVE_CONTEXT    "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"
-+#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t"
-+
-+#define __EXTRA_CLOBBER  \
-+      , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
-+        "r12", "r13", "r14", "r15"
-+
-+/* Save restore flags to clear handle leaking NT */
-+#define switch_to(prev, next, last) \
-+      asm volatile(SAVE_CONTEXT                                                   \
-+           "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */       \
-+           "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \
-+           "call __switch_to\n\t"                                       \
-+           ".globl thread_return\n"                                     \
-+           "thread_return:\n\t"                                         \
-+           "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"                       \
-+           "movq %P[thread_info](%%rsi),%%r8\n\t"                       \
-+           LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"        \
-+           "movq %%rax,%%rdi\n\t"                                       \
-+           "jc   ret_from_fork\n\t"                                     \
-+           RESTORE_CONTEXT                                              \
-+           : "=a" (last)                                                \
-+           : [next] "S" (next), [prev] "D" (prev),                      \
-+             [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \
-+             [ti_flags] "i" (offsetof(struct thread_info, flags)),      \
-+             [tif_fork] "i" (TIF_FORK),                                 \
-+             [thread_info] "i" (offsetof(struct task_struct, stack)),   \
-+             [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))  \
-+           : "memory", "cc" __EXTRA_CLOBBER)
-+#endif
-+
-+#ifdef __KERNEL__
-+#define _set_base(addr, base) do { unsigned long __pr; \
-+__asm__ __volatile__ ("movw %%dx,%1\n\t" \
-+      "rorl $16,%%edx\n\t" \
-+      "movb %%dl,%2\n\t" \
-+      "movb %%dh,%3" \
-+      :"=&d" (__pr) \
-+      :"m" (*((addr)+2)), \
-+       "m" (*((addr)+4)), \
-+       "m" (*((addr)+7)), \
-+       "0" (base) \
-+      ); } while (0)
-+
-+#define _set_limit(addr, limit) do { unsigned long __lr; \
-+__asm__ __volatile__ ("movw %%dx,%1\n\t" \
-+      "rorl $16,%%edx\n\t" \
-+      "movb %2,%%dh\n\t" \
-+      "andb $0xf0,%%dh\n\t" \
-+      "orb %%dh,%%dl\n\t" \
-+      "movb %%dl,%2" \
-+      :"=&d" (__lr) \
-+      :"m" (*(addr)), \
-+       "m" (*((addr)+6)), \
-+       "0" (limit) \
-+      ); } while (0)
-+
-+#define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base))
-+#define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1))
-+
-+extern void load_gs_index(unsigned);
-+
-+/*
-+ * Load a segment. Fall back on loading the zero
-+ * segment if something goes wrong..
-+ */
-+#define loadsegment(seg, value)                       \
-+      asm volatile("\n"                       \
-+              "1:\t"                          \
-+              "movl %k0,%%" #seg "\n"         \
-+              "2:\n"                          \
-+              ".section .fixup,\"ax\"\n"      \
-+              "3:\t"                          \
-+              "movl %k1, %%" #seg "\n\t"      \
-+              "jmp 2b\n"                      \
-+              ".previous\n"                   \
-+              _ASM_EXTABLE(1b,3b)             \
-+              : :"r" (value), "r" (0))
-+
+-static inline unsigned long read_cr0(void)
+-{ 
+-      unsigned long cr0;
+-      asm volatile("movq %%cr0,%0" : "=r" (cr0));
+-      return cr0;
+-}
+-
+-static inline void write_cr0(unsigned long val) 
+-{ 
+-      asm volatile("movq %0,%%cr0" :: "r" (val));
+-}
+-
+-#define read_cr2() current_vcpu_info()->arch.cr2
+-
+-#define write_cr2(val) ((void)(current_vcpu_info()->arch.cr2 = (val)))
+-
+-#define read_cr3() ({ \
+-      unsigned long __dummy; \
+-      asm volatile("movq %%cr3,%0" : "=r" (__dummy)); \
+-      machine_to_phys(__dummy); \
+-})
+-
+-static inline void write_cr3(unsigned long val)
+-{
+-      val = phys_to_machine(val);
+-      asm volatile("movq %0,%%cr3" :: "r" (val) : "memory");
+-}
+-
+-static inline unsigned long read_cr4(void)
+-{ 
+-      unsigned long cr4;
+-      asm volatile("movq %%cr4,%0" : "=r" (cr4));
+-      return cr4;
+-}
+-
+-static inline void write_cr4(unsigned long val)
+-{ 
+-      asm volatile("movq %0,%%cr4" :: "r" (val) : "memory");
+-}
+ static inline unsigned long read_cr8(void)
+ {
+@@ -128,52 +15,6 @@ static inline void write_cr8(unsigned lo
+       BUG_ON(val);
+ }
+-#define stts() (HYPERVISOR_fpu_taskswitch(1))
+-
+-#define wbinvd() \
+-      __asm__ __volatile__ ("wbinvd": : :"memory")
+-
+-#endif        /* __KERNEL__ */
+-
+-static inline void clflush(volatile void *__p)
+-{
+-      asm volatile("clflush %0" : "+m" (*(char __force *)__p));
+-}
+-
+-#define nop() __asm__ __volatile__ ("nop")
+-
+-#ifdef CONFIG_SMP
+-#define smp_mb()      mb()
+-#define smp_rmb()     barrier()
+-#define smp_wmb()     barrier()
+-#define smp_read_barrier_depends()    do {} while(0)
+-#else
+-#define smp_mb()      barrier()
+-#define smp_rmb()     barrier()
+-#define smp_wmb()     barrier()
+-#define smp_read_barrier_depends()    do {} while(0)
+-#endif
+-
+-    
+-/*
+- * Force strict CPU ordering.
+- * And yes, this is required on UP too when we're talking
+- * to devices.
+- */
+-#define mb()  asm volatile("mfence":::"memory")
+-#define rmb() asm volatile("lfence":::"memory")
+-#define wmb() asm volatile("sfence" ::: "memory")
+-
+-#define read_barrier_depends()        do {} while(0)
+-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
+-
+-#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
+-
+ #include <linux/irqflags.h>
+-void cpu_idle_wait(void);
+-
+-extern unsigned long arch_align_stack(unsigned long sp);
+-extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
+-
+ #endif
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/tlbflush.h      2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mach-xen/asm/tlbflush.h   2009-03-16 16:33:40.000000000 +0100
+@@ -1,5 +1,106 @@
++#ifndef _ASM_X86_TLBFLUSH_H
++#define _ASM_X86_TLBFLUSH_H
 +
-+/*
-+ * Save a segment register away
-+ */
-+#define savesegment(seg, value) \
-+      asm volatile("mov %%" #seg ",%0":"=rm" (value))
++#include <linux/mm.h>
++#include <linux/sched.h>
 +
-+static inline unsigned long get_limit(unsigned long segment)
-+{
-+      unsigned long __limit;
-+      __asm__("lsll %1,%0"
-+              :"=r" (__limit):"r" (segment));
-+      return __limit+1;
-+}
++#include <asm/processor.h>
++#include <asm/system.h>
 +
-+static inline void xen_clts(void)
-+{
-+      HYPERVISOR_fpu_taskswitch(0);
-+}
++#define __flush_tlb() xen_tlb_flush()
++#define __flush_tlb_global() xen_tlb_flush()
++#define __flush_tlb_single(addr) xen_invlpg(addr)
++#define __flush_tlb_all() xen_tlb_flush()
++#define __flush_tlb_one(addr) xen_invlpg(addr)
 +
-+static inline void xen_stts(void)
-+{
-+      HYPERVISOR_fpu_taskswitch(1);
-+}
+ #ifdef CONFIG_X86_32
+-# include "tlbflush_32.h"
++# define TLB_FLUSH_ALL        0xffffffff
+ #else
+-# include "tlbflush_64.h"
++# define TLB_FLUSH_ALL        -1ULL
+ #endif
 +
 +/*
-+ * Volatile isn't enough to prevent the compiler from reordering the
-+ * read/write functions for the control registers and messing everything up.
-+ * A memory clobber would solve the problem, but would prevent reordering of
-+ * all loads stores around it, which can hurt performance. Solution is to
-+ * use a variable and mimic reads and writes to it to enforce serialization
++ * TLB flushing:
++ *
++ *  - flush_tlb() flushes the current mm struct TLBs
++ *  - flush_tlb_all() flushes all processes TLBs
++ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
++ *  - flush_tlb_page(vma, vmaddr) flushes one page
++ *  - flush_tlb_range(vma, start, end) flushes a range of pages
++ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
++ *
++ * ..but the i386 has somewhat limited tlb flushing capabilities,
++ * and page-granular flushes are available only on i486 and up.
++ *
++ * x86-64 can only flush individual pages or full VMs. For a range flush
++ * we always do the full VM. Might be worth trying if for a small
++ * range a few INVLPGs in a row are a win.
 + */
-+static unsigned long __force_order;
-+
-+static inline unsigned long xen_read_cr0(void)
-+{
-+      unsigned long val;
-+      asm volatile("mov %%cr0,%0\n\t" :"=r" (val), "=m" (__force_order));
-+      return val;
-+}
-+
-+static inline void xen_write_cr0(unsigned long val)
-+{
-+      asm volatile("mov %0,%%cr0": :"r" (val), "m" (__force_order));
-+}
-+
-+#define xen_read_cr2() (current_vcpu_info()->arch.cr2)
-+#define xen_write_cr2(val) ((void)(current_vcpu_info()->arch.cr2 = (val)))
-+
-+static inline unsigned long xen_read_cr3(void)
-+{
-+      unsigned long val;
-+      asm volatile("mov %%cr3,%0\n\t" :"=r" (val), "=m" (__force_order));
-+#ifdef CONFIG_X86_32
-+      return mfn_to_pfn(xen_cr3_to_pfn(val)) << PAGE_SHIFT;
-+#else
-+      return machine_to_phys(val);
-+#endif
-+}
-+
-+static inline void xen_write_cr3(unsigned long val)
-+{
-+#ifdef CONFIG_X86_32
-+      val = xen_pfn_to_cr3(pfn_to_mfn(val >> PAGE_SHIFT));
-+#else
-+      val = phys_to_machine(val);
-+#endif
-+      asm volatile("mov %0,%%cr3": :"r" (val), "m" (__force_order));
-+}
-+
-+static inline unsigned long xen_read_cr4(void)
-+{
-+      unsigned long val;
-+      asm volatile("mov %%cr4,%0\n\t" :"=r" (val), "=m" (__force_order));
-+      return val;
-+}
-+
-+#define xen_read_cr4_safe() xen_read_cr4()
 +
-+static inline void xen_write_cr4(unsigned long val)
-+{
-+      asm volatile("mov %0,%%cr4": :"r" (val), "m" (__force_order));
-+}
++#ifndef CONFIG_SMP
 +
-+#ifdef CONFIG_X86_64
-+static inline unsigned long xen_read_cr8(void)
-+{
-+      return 0;
-+}
++#define flush_tlb() __flush_tlb()
++#define flush_tlb_all() __flush_tlb_all()
++#define local_flush_tlb() __flush_tlb()
 +
-+static inline void xen_write_cr8(unsigned long val)
++static inline void flush_tlb_mm(struct mm_struct *mm)
 +{
-+      BUG_ON(val);
++      if (mm == current->active_mm)
++              __flush_tlb();
 +}
-+#endif
 +
-+static inline void xen_wbinvd(void)
++static inline void flush_tlb_page(struct vm_area_struct *vma,
++                                unsigned long addr)
 +{
-+      asm volatile("wbinvd": : :"memory");
++      if (vma->vm_mm == current->active_mm)
++              __flush_tlb_one(addr);
 +}
-+#define read_cr0()    (xen_read_cr0())
-+#define write_cr0(x)  (xen_write_cr0(x))
-+#define read_cr2()    (xen_read_cr2())
-+#define write_cr2(x)  (xen_write_cr2(x))
-+#define read_cr3()    (xen_read_cr3())
-+#define write_cr3(x)  (xen_write_cr3(x))
-+#define read_cr4()    (xen_read_cr4())
-+#define read_cr4_safe()       (xen_read_cr4_safe())
-+#define write_cr4(x)  (xen_write_cr4(x))
-+#define wbinvd()      (xen_wbinvd())
-+#ifdef CONFIG_X86_64
-+#define read_cr8()    (xen_read_cr8())
-+#define write_cr8(x)  (xen_write_cr8(x))
-+#endif
-+
-+/* Clear the 'TS' bit */
-+#define clts()                (xen_clts())
-+#define stts()                (xen_stts())
-+
-+#endif /* __KERNEL__ */
 +
-+static inline void clflush(volatile void *__p)
++static inline void flush_tlb_range(struct vm_area_struct *vma,
++                                 unsigned long start, unsigned long end)
 +{
-+      asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
++      if (vma->vm_mm == current->active_mm)
++              __flush_tlb();
 +}
 +
-+#define nop() __asm__ __volatile__ ("nop")
-+
-+void disable_hlt(void);
-+void enable_hlt(void);
-+
-+extern int es7000_plat;
-+void cpu_idle_wait(void);
++#else  /* SMP */
 +
-+extern unsigned long arch_align_stack(unsigned long sp);
-+extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
++#include <asm/smp.h>
 +
-+void default_idle(void);
++#define local_flush_tlb() __flush_tlb()
 +
-+/*
-+ * Force strict CPU ordering.
-+ * And yes, this is required on UP too when we're talking
-+ * to devices.
-+ */
- #ifdef CONFIG_X86_32
--# include "system_32.h"
-+/*
-+ * For now, "wmb()" doesn't actually do anything, as all
-+ * Intel CPU's follow what Intel calls a *Processor Order*,
-+ * in which all writes are seen in the program order even
-+ * outside the CPU.
-+ *
-+ * I expect future Intel CPU's to have a weaker ordering,
-+ * but I'd also expect them to finally get their act together
-+ * and add some real memory barriers if so.
-+ *
-+ * Some non intel clones support out of order store. wmb() ceases to be a
-+ * nop for these.
-+ */
-+#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
-+#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
-+#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
-+#else
-+#define mb()  asm volatile("mfence":::"memory")
-+#define rmb() asm volatile("lfence":::"memory")
-+#define wmb() asm volatile("sfence" ::: "memory")
-+#endif
++#define flush_tlb_all xen_tlb_flush_all
++#define flush_tlb_current_task() xen_tlb_flush_mask(&current->mm->cpu_vm_mask)
++#define flush_tlb_mm(mm) xen_tlb_flush_mask(&(mm)->cpu_vm_mask)
++#define flush_tlb_page(vma, va) xen_invlpg_mask(&(vma)->vm_mm->cpu_vm_mask, va)
 +
-+/**
-+ * read_barrier_depends - Flush all pending reads that subsequents reads
-+ * depend on.
-+ *
-+ * No data-dependent reads from memory-like regions are ever reordered
-+ * over this barrier.  All reads preceding this primitive are guaranteed
-+ * to access memory (but not necessarily other CPUs' caches) before any
-+ * reads following this primitive that depend on the data return by
-+ * any of the preceding reads.  This primitive is much lighter weight than
-+ * rmb() on most CPUs, and is never heavier weight than is
-+ * rmb().
-+ *
-+ * These ordering constraints are respected by both the local CPU
-+ * and the compiler.
-+ *
-+ * Ordering is not guaranteed by anything other than these primitives,
-+ * not even by data dependencies.  See the documentation for
-+ * memory_barrier() for examples and URLs to more information.
-+ *
-+ * For example, the following code would force ordering (the initial
-+ * value of "a" is zero, "b" is one, and "p" is "&a"):
-+ *
-+ * <programlisting>
-+ *    CPU 0                           CPU 1
-+ *
-+ *    b = 2;
-+ *    memory_barrier();
-+ *    p = &b;                         q = p;
-+ *                                    read_barrier_depends();
-+ *                                    d = *q;
-+ * </programlisting>
-+ *
-+ * because the read of "*q" depends on the read of "p" and these
-+ * two reads are separated by a read_barrier_depends().  However,
-+ * the following code, with the same initial values for "a" and "b":
-+ *
-+ * <programlisting>
-+ *    CPU 0                           CPU 1
-+ *
-+ *    a = 2;
-+ *    memory_barrier();
-+ *    b = 3;                          y = b;
-+ *                                    read_barrier_depends();
-+ *                                    x = a;
-+ * </programlisting>
-+ *
-+ * does not enforce ordering, since there is no data dependency between
-+ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
-+ * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
-+ * in cases like this where there are no data dependencies.
-+ **/
++#define flush_tlb()   flush_tlb_current_task()
 +
-+#define read_barrier_depends()        do { } while (0)
++static inline void flush_tlb_range(struct vm_area_struct *vma,
++                                 unsigned long start, unsigned long end)
++{
++      flush_tlb_mm(vma->vm_mm);
++}
 +
-+#ifdef CONFIG_SMP
-+#define smp_mb()      mb()
-+#ifdef CONFIG_X86_PPRO_FENCE
-+# define smp_rmb()    rmb()
- #else
--# include "system_64.h"
-+# define smp_rmb()    barrier()
-+#endif
-+#ifdef CONFIG_X86_OOSTORE
-+# define smp_wmb()    wmb()
-+#else
-+# define smp_wmb()    barrier()
-+#endif
-+#define smp_read_barrier_depends()    read_barrier_depends()
-+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-+#else
-+#define smp_mb()      barrier()
-+#define smp_rmb()     barrier()
-+#define smp_wmb()     barrier()
-+#define smp_read_barrier_depends()    do { } while (0)
-+#define set_mb(var, value) do { var = value; barrier(); } while (0)
++#define TLBSTATE_OK   1
++#define TLBSTATE_LAZY 2
++
++#ifdef CONFIG_X86_32
++struct tlb_state
++{
++      struct mm_struct *active_mm;
++      int state;
++      char __cacheline_padding[L1_CACHE_BYTES-8];
++};
++DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
 +#endif
 +
-+/*
-+ * Stop RDTSC speculation. This is needed when you need to use RDTSC
-+ * (or get_cycles or vread that possibly accesses the TSC) in a defined
-+ * code region.
-+ *
-+ * (Could use an alternative three way for this if there was one.)
-+ */
-+static inline void rdtsc_barrier(void)
++#endif        /* SMP */
++
++static inline void flush_tlb_kernel_range(unsigned long start,
++                                        unsigned long end)
 +{
-+      alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
-+      alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
++      flush_tlb_all();
 +}
 +
- #endif
---- a/include/asm-x86/mach-xen/asm/tlbflush_32.h
-+++ /dev/null
++#endif /* _ASM_X86_TLBFLUSH_H */
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/tlbflush_32.h   2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
 @@ -1,99 +0,0 @@
 -#ifndef _I386_TLBFLUSH_H
 -#define _I386_TLBFLUSH_H
@@ -29160,8 +28952,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -}
 -
 -#endif /* _I386_TLBFLUSH_H */
---- a/include/asm-x86/mach-xen/asm/tlbflush_64.h
-+++ /dev/null
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/asm/tlbflush_64.h   2009-02-16 16:18:36.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
 @@ -1,97 +0,0 @@
 -#ifndef _X8664_TLBFLUSH_H
 -#define _X8664_TLBFLUSH_H
@@ -29260,119 +29052,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 -}
 -
 -#endif /* _X8664_TLBFLUSH_H */
---- a/include/asm-x86/mach-xen/asm/tlbflush.h
-+++ b/include/asm-x86/mach-xen/asm/tlbflush.h
-@@ -1,5 +1,106 @@
-+#ifndef _ASM_X86_TLBFLUSH_H
-+#define _ASM_X86_TLBFLUSH_H
-+
-+#include <linux/mm.h>
-+#include <linux/sched.h>
-+
-+#include <asm/processor.h>
-+#include <asm/system.h>
-+
-+#define __flush_tlb() xen_tlb_flush()
-+#define __flush_tlb_global() xen_tlb_flush()
-+#define __flush_tlb_single(addr) xen_invlpg(addr)
-+#define __flush_tlb_all() xen_tlb_flush()
-+#define __flush_tlb_one(addr) xen_invlpg(addr)
-+
- #ifdef CONFIG_X86_32
--# include "tlbflush_32.h"
-+# define TLB_FLUSH_ALL        0xffffffff
- #else
--# include "tlbflush_64.h"
-+# define TLB_FLUSH_ALL        -1ULL
- #endif
-+
-+/*
-+ * TLB flushing:
-+ *
-+ *  - flush_tlb() flushes the current mm struct TLBs
-+ *  - flush_tlb_all() flushes all processes TLBs
-+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
-+ *  - flush_tlb_page(vma, vmaddr) flushes one page
-+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
-+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
-+ *
-+ * ..but the i386 has somewhat limited tlb flushing capabilities,
-+ * and page-granular flushes are available only on i486 and up.
-+ *
-+ * x86-64 can only flush individual pages or full VMs. For a range flush
-+ * we always do the full VM. Might be worth trying if for a small
-+ * range a few INVLPGs in a row are a win.
-+ */
-+
-+#ifndef CONFIG_SMP
-+
-+#define flush_tlb() __flush_tlb()
-+#define flush_tlb_all() __flush_tlb_all()
-+#define local_flush_tlb() __flush_tlb()
-+
-+static inline void flush_tlb_mm(struct mm_struct *mm)
-+{
-+      if (mm == current->active_mm)
-+              __flush_tlb();
-+}
-+
-+static inline void flush_tlb_page(struct vm_area_struct *vma,
-+                                unsigned long addr)
-+{
-+      if (vma->vm_mm == current->active_mm)
-+              __flush_tlb_one(addr);
-+}
-+
-+static inline void flush_tlb_range(struct vm_area_struct *vma,
-+                                 unsigned long start, unsigned long end)
-+{
-+      if (vma->vm_mm == current->active_mm)
-+              __flush_tlb();
-+}
-+
-+#else  /* SMP */
-+
-+#include <asm/smp.h>
-+
-+#define local_flush_tlb() __flush_tlb()
-+
-+#define flush_tlb_all xen_tlb_flush_all
-+#define flush_tlb_current_task() xen_tlb_flush_mask(&current->mm->cpu_vm_mask)
-+#define flush_tlb_mm(mm) xen_tlb_flush_mask(&(mm)->cpu_vm_mask)
-+#define flush_tlb_page(vma, va) xen_invlpg_mask(&(vma)->vm_mm->cpu_vm_mask, va)
-+
-+#define flush_tlb()   flush_tlb_current_task()
-+
-+static inline void flush_tlb_range(struct vm_area_struct *vma,
-+                                 unsigned long start, unsigned long end)
-+{
-+      flush_tlb_mm(vma->vm_mm);
-+}
-+
-+#define TLBSTATE_OK   1
-+#define TLBSTATE_LAZY 2
-+
-+#ifdef CONFIG_X86_32
-+struct tlb_state
-+{
-+      struct mm_struct *active_mm;
-+      int state;
-+      char __cacheline_padding[L1_CACHE_BYTES-8];
-+};
-+DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
-+#endif
-+
-+#endif        /* SMP */
-+
-+static inline void flush_tlb_kernel_range(unsigned long start,
-+                                        unsigned long end)
-+{
-+      flush_tlb_all();
-+}
-+
-+#endif /* _ASM_X86_TLBFLUSH_H */
---- a/include/asm-x86/mach-xen/irq_vectors.h
-+++ b/include/asm-x86/mach-xen/irq_vectors.h
+--- sle11-2009-05-14.orig/include/asm-x86/mach-xen/irq_vectors.h       2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/include/asm-x86/mach-xen/irq_vectors.h    2009-03-16 16:33:40.000000000 +0100
 @@ -82,7 +82,8 @@
  
  #define RESCHEDULE_VECTOR     0
@@ -29383,8 +29064,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  /*
   * The maximum number of vectors supported by i386 processors
---- a/include/asm-x86/mmu.h
-+++ b/include/asm-x86/mmu.h
+--- sle11-2009-05-14.orig/include/asm-x86/mmu.h        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/mmu.h     2009-03-16 16:33:40.000000000 +0100
 @@ -23,7 +23,7 @@ typedef struct {
        void *vdso;
  } mm_context_t;
@@ -29394,8 +29075,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  void leave_mm(int cpu);
  #else
  static inline void leave_mm(int cpu)
---- a/include/asm-x86/ptrace.h
-+++ b/include/asm-x86/ptrace.h
+--- sle11-2009-05-14.orig/include/asm-x86/ptrace.h     2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/include/asm-x86/ptrace.h  2009-03-16 16:33:40.000000000 +0100
 @@ -249,7 +249,9 @@ extern void user_enable_single_step(stru
  extern void user_disable_single_step(struct task_struct *);
  
@@ -29407,22 +29088,22 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  #define arch_has_block_step() (1)
  #else
  #define arch_has_block_step() (boot_cpu_data.x86 >= 6)
---- a/include/asm-x86/thread_info.h
-+++ b/include/asm-x86/thread_info.h
+--- sle11-2009-05-14.orig/include/asm-x86/thread_info.h        2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/asm-x86/thread_info.h     2009-03-16 16:33:40.000000000 +0100
 @@ -94,6 +94,9 @@ struct thread_info {
- #define TIF_DEBUGCTLMSR               25      /* uses thread_struct.debugctlmsr */
  #define TIF_DS_AREA_MSR               26      /* uses thread_struct.ds_area_msr */
  #define TIF_BTS_TRACE_TS      27      /* record scheduling event timestamps */
+ #define TIF_PERFMON_CTXSW     28      /* perfmon needs ctxsw calls */
 +#ifdef CONFIG_X86_XEN
 +#define TIF_CSTAR             31      /* cstar-based syscall (special handling) */
 +#endif
  
  #define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
- #define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
+ #define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
 @@ -118,6 +121,7 @@ struct thread_info {
- #define _TIF_DEBUGCTLMSR      (1 << TIF_DEBUGCTLMSR)
- #define _TIF_DS_AREA_MSR      (1 << TIF_DS_AREA_MSR)
  #define _TIF_BTS_TRACE_TS     (1 << TIF_BTS_TRACE_TS)
+ #define _TIF_PERFMON_WORK     (1 << TIF_PERFMON_WORK)
+ #define _TIF_PERFMON_CTXSW    (1 << TIF_PERFMON_CTXSW)
 +#define _TIF_CSTAR            (1 << TIF_CSTAR)
  
  /* work to do in syscall_trace_enter() */
@@ -29444,8 +29125,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  #define PREEMPT_ACTIVE                0x10000000
  
---- a/include/asm-x86/time.h
-+++ b/include/asm-x86/time.h
+--- sle11-2009-05-14.orig/include/asm-x86/time.h       2009-05-14 10:56:29.000000000 +0200
++++ sle11-2009-05-14/include/asm-x86/time.h    2009-03-16 16:33:40.000000000 +0100
 @@ -58,4 +58,10 @@ static inline int native_set_wallclock(u
  
  extern unsigned long __init calibrate_cpu(void);
@@ -29457,9 +29138,9 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
 +#endif
 +
  #endif
---- a/include/linux/page-flags.h
-+++ b/include/linux/page-flags.h
-@@ -101,8 +101,8 @@ enum pageflags {
+--- sle11-2009-05-14.orig/include/linux/page-flags.h   2009-02-16 16:17:21.000000000 +0100
++++ sle11-2009-05-14/include/linux/page-flags.h        2009-03-16 16:33:40.000000000 +0100
+@@ -102,8 +102,8 @@ enum pageflags {
        PG_foreign,             /* Page is owned by foreign allocator. */
        PG_pinned,              /* Cannot alias with PG_owner_priv_1 since
                                 * bad_page() checks include this bit.
@@ -29470,8 +29151,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  #endif
        __NR_PAGEFLAGS,
  
---- a/include/linux/pci.h
-+++ b/include/linux/pci.h
+--- sle11-2009-05-14.orig/include/linux/pci.h  2008-12-15 11:27:22.000000000 +0100
++++ sle11-2009-05-14/include/linux/pci.h       2009-03-16 16:33:40.000000000 +0100
 @@ -644,6 +644,9 @@ int pcie_set_readrq(struct pci_dev *dev,
  void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
  int __must_check pci_assign_resource(struct pci_dev *dev, int i);
@@ -29482,8 +29163,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  
  /* ROM control related routines */
  void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
---- a/include/xen/evtchn.h
-+++ b/include/xen/evtchn.h
+--- sle11-2009-05-14.orig/include/xen/evtchn.h 2009-03-04 11:28:34.000000000 +0100
++++ sle11-2009-05-14/include/xen/evtchn.h      2009-03-16 16:33:40.000000000 +0100
 @@ -130,12 +130,37 @@ static inline void clear_evtchn(int port
        synch_clear_bit(port, s->evtchn_pending);
  }
@@ -29522,8 +29203,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
  /*
   * Use these to access the event channel underlying the IRQ handle returned
   * by bind_*_to_irqhandler().
---- a/kernel/sysctl_check.c
-+++ b/kernel/sysctl_check.c
+--- sle11-2009-05-14.orig/kernel/sysctl_check.c        2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/kernel/sysctl_check.c     2009-03-16 16:33:40.000000000 +0100
 @@ -899,7 +899,7 @@ static const struct trans_ctl_table tran
  };
  
@@ -29533,8 +29214,8 @@ Automatically created from "patches.kernel.org/patch-2.6.25" by xen-port-patches
        { CTL_XEN_INDEPENDENT_WALLCLOCK,        "independent_wallclock" },
        { CTL_XEN_PERMITTED_CLOCK_JITTER,       "permitted_clock_jitter" },
        {}
---- a/lib/swiotlb-xen.c
-+++ b/lib/swiotlb-xen.c
+--- sle11-2009-05-14.orig/lib/swiotlb-xen.c    2009-02-16 16:18:36.000000000 +0100
++++ sle11-2009-05-14/lib/swiotlb-xen.c 2009-03-16 16:33:40.000000000 +0100
 @@ -30,7 +30,6 @@
  #include <asm/gnttab_dma.h>