summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Marineau <marineam@gentoo.org>2008-02-16 01:09:22 +0000
committerMichael Marineau <marineam@gentoo.org>2008-02-16 01:09:22 +0000
commit8980e5200f5cc42d8dc769a7ef12080822104b92 (patch)
treebdbb38d650ac91351e006f2d64cd4e3c30a4320c
parentTesting 2.6.22 release (diff)
downloadxen-8980e5200f5cc42d8dc769a7ef12080822104b92.tar.gz
xen-8980e5200f5cc42d8dc769a7ef12080822104b92.tar.bz2
xen-8980e5200f5cc42d8dc769a7ef12080822104b92.zip
Bump the 2.6.18 patches to xen 3.2.0
svn path=/patches/; revision=65
-rw-r--r--trunk/2.6.18/00000_README20
-rw-r--r--trunk/2.6.18/10001_xen-3.2.0.patch (renamed from trunk/2.6.18/10001_xen-3.1.2.patch)46939
-rw-r--r--trunk/2.6.18/10002_i386-fix-xen_l1_entry_update-for-highptes.patch24
-rw-r--r--trunk/2.6.18/30038_don-t-leak-nt-bit-into-next-task-xen.patch32
-rw-r--r--trunk/2.6.18/50001_make-install.patch52
-rw-r--r--trunk/2.6.18/50002_always-enable-xen-genapic.patch12
6 files changed, 40021 insertions, 7058 deletions
diff --git a/trunk/2.6.18/00000_README b/trunk/2.6.18/00000_README
index ca16f8b..3eae5d1 100644
--- a/trunk/2.6.18/00000_README
+++ b/trunk/2.6.18/00000_README
@@ -19,12 +19,8 @@ Numbering
Patches
-------
-10001_xen-3.1.2.patch
- Upstream 3.1.2 patch
-
-10002_i386-fix-xen_l1_entry_update-for-highptes.patch
- Fix for kernels compiled with CONFIG_HIGHPTE.
- Pulled from linux-2.6.18-xen.hg, changeset e79729740288.
+10001_xen-3.2.0.patch
+ Upstream 3.2.0 patch
30001_nfnetlink_log-null-deref.patch
[SECURITY] Fix remotely exploitable NULL pointer dereference in
@@ -184,10 +180,6 @@ Patches
prevent incorrect permissions upon remount.
See CVE-2007-4849
-30038_don-t-leak-nt-bit-into-next-task-xen.patch
- [SECURITY] Don't leak NT bit into next task (Xen).
- See CVE-2006-5755
-
30039_hugetlb-prio_tree-unit-fix.patch
[SECURITY] Fix misconversion of hugetlb_vmtruncate_list to prio_tree
which could be used to trigger a BUG_ON() call in exit_mmap.
@@ -208,13 +200,5 @@ Patches
Update fix for CVE-2007-3848 with the patch accepted upstream
(formerly 30013_reset-pdeathsig-on-suid.patch)
-50001_make-install.patch
- Handle make install in a semi-sane way that plays nice with
- split domU/dom0 kernels.
-
-50002_always-enable-xen-genapic.patch
- Compile fix for non-SMP (UP) kernels. Since UP support is broken in
- upstream Xen I'm not sure if I trust it or not. :-P
-
50009_gentooify-tls-warning.patch
Change tls warning instructions to apply directly to Gentoo.
diff --git a/trunk/2.6.18/10001_xen-3.1.2.patch b/trunk/2.6.18/10001_xen-3.2.0.patch
index 099033d..d3d6c2b 100644
--- a/trunk/2.6.18/10001_xen-3.1.2.patch
+++ b/trunk/2.6.18/10001_xen-3.2.0.patch
@@ -1,6 +1,6 @@
-diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/i386/Kconfig
---- pristine-linux-2.6.18/arch/i386/Kconfig 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/Kconfig 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/Kconfig linux-2.6.18-xen-3.2.0/arch/i386/Kconfig
+--- linux-2.6.18.8/arch/i386/Kconfig 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/Kconfig 2008-02-15 16:21:49.000000000 -0800
@@ -16,6 +16,7 @@ config X86_32
config GENERIC_TIME
@@ -9,12 +9,13 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
default y
config LOCKDEP_SUPPORT
-@@ -103,6 +104,15 @@ config X86_PC
+@@ -103,6 +104,16 @@ config X86_PC
help
Choose this option if your computer is a standard PC or compatible.
+config X86_XEN
+ bool "Xen-compatible"
++ select XEN
+ select X86_UP_APIC if !SMP && XEN_PRIVILEGED_GUEST
+ select X86_UP_IOAPIC if !SMP && XEN_PRIVILEGED_GUEST
+ select SWIOTLB
@@ -25,7 +26,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
config X86_ELAN
bool "AMD Elan"
help
-@@ -213,6 +223,7 @@ source "arch/i386/Kconfig.cpu"
+@@ -213,6 +224,7 @@ source "arch/i386/Kconfig.cpu"
config HPET_TIMER
bool "HPET Timer Support"
@@ -33,7 +34,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
help
This enables the use of the HPET for the kernel's internal timer.
HPET is the next generation timer replacing legacy 8254s.
-@@ -263,7 +274,7 @@ source "kernel/Kconfig.preempt"
+@@ -263,7 +275,7 @@ source "kernel/Kconfig.preempt"
config X86_UP_APIC
bool "Local APIC support on uniprocessors"
@@ -42,7 +43,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
help
A local APIC (Advanced Programmable Interrupt Controller) is an
integrated interrupt controller in the CPU. If you have a single-CPU
-@@ -288,12 +299,12 @@ config X86_UP_IOAPIC
+@@ -288,12 +300,12 @@ config X86_UP_IOAPIC
config X86_LOCAL_APIC
bool
@@ -57,7 +58,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
default y
config X86_VISWS_APIC
-@@ -303,7 +314,7 @@ config X86_VISWS_APIC
+@@ -303,7 +315,7 @@ config X86_VISWS_APIC
config X86_MCE
bool "Machine Check Exception"
@@ -66,7 +67,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
---help---
Machine Check Exception support allows the processor to notify the
kernel if it detects a problem (e.g. overheating, component failure).
-@@ -402,6 +413,7 @@ config X86_REBOOTFIXUPS
+@@ -402,6 +414,7 @@ config X86_REBOOTFIXUPS
config MICROCODE
tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
@@ -74,14 +75,6 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
---help---
If you say Y here and also to "/dev file system support" in the
'File systems' section, you will be able to update the microcode on
-@@ -419,6 +431,7 @@ config MICROCODE
-
- config X86_MSR
- tristate "/dev/cpu/*/msr - Model-specific register support"
-+ depends on !X86_XEN
- help
- This device gives privileged processes access to the x86
- Model-Specific Registers (MSRs). It is a character device with
@@ -434,6 +447,10 @@ config X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
@@ -145,16 +138,15 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
default y
help
Map the VDSO to the predictable old-style address too.
-@@ -810,18 +831,20 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
+@@ -810,18 +831,18 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
depends on HIGHMEM
menu "Power management options (ACPI, APM)"
- depends on !X86_VOYAGER
+ depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)
-+if !X86_XEN
- source kernel/power/Kconfig
-+endif
+-source kernel/power/Kconfig
++source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
@@ -169,7 +161,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
---help---
APM is a BIOS specification for saving power using several different
techniques. This is mostly useful for battery powered laptops with
-@@ -1006,6 +1029,7 @@ choice
+@@ -1006,6 +1027,7 @@ choice
config PCI_GOBIOS
bool "BIOS"
@@ -177,7 +169,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
config PCI_GOMMCONFIG
bool "MMConfig"
-@@ -1013,6 +1037,13 @@ config PCI_GOMMCONFIG
+@@ -1013,6 +1035,13 @@ config PCI_GOMMCONFIG
config PCI_GODIRECT
bool "Direct"
@@ -191,7 +183,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
config PCI_GOANY
bool "Any"
-@@ -1020,7 +1051,7 @@ endchoice
+@@ -1020,7 +1049,7 @@ endchoice
config PCI_BIOS
bool
@@ -200,7 +192,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
default y
config PCI_DIRECT
-@@ -1033,6 +1064,18 @@ config PCI_MMCONFIG
+@@ -1033,6 +1062,18 @@ config PCI_MMCONFIG
depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
default y
@@ -219,7 +211,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
-@@ -1043,7 +1086,7 @@ config ISA_DMA_API
+@@ -1043,7 +1084,7 @@ config ISA_DMA_API
config ISA
bool "ISA support"
@@ -228,7 +220,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
-@@ -1070,7 +1113,7 @@ config EISA
+@@ -1070,7 +1111,7 @@ config EISA
source "drivers/eisa/Kconfig"
config MCA
@@ -237,7 +229,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
default y if X86_VOYAGER
help
MicroChannel Architecture is found in some IBM PS/2 machines and
-@@ -1146,6 +1189,8 @@ source "security/Kconfig"
+@@ -1146,6 +1187,8 @@ source "security/Kconfig"
source "crypto/Kconfig"
@@ -246,7 +238,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
source "lib/Kconfig"
#
-@@ -1171,7 +1216,7 @@ config X86_SMP
+@@ -1171,7 +1214,7 @@ config X86_SMP
config X86_HT
bool
@@ -255,7 +247,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
default y
config X86_BIOS_REBOOT
-@@ -1184,6 +1229,16 @@ config X86_TRAMPOLINE
+@@ -1184,6 +1227,16 @@ config X86_TRAMPOLINE
depends on X86_SMP || (X86_VOYAGER && SMP)
default y
@@ -272,10 +264,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig tmp-linux-2.6-xen.patch/arch/
config KTIME_SCALAR
bool
default y
-diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig.cpu tmp-linux-2.6-xen.patch/arch/i386/Kconfig.cpu
---- pristine-linux-2.6.18/arch/i386/Kconfig.cpu 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/Kconfig.cpu 2007-11-14 15:35:27.000000000 -0800
-@@ -251,7 +251,7 @@ config X86_PPRO_FENCE
+diff -rpuN linux-2.6.18.8/arch/i386/Kconfig.cpu linux-2.6.18-xen-3.2.0/arch/i386/Kconfig.cpu
+--- linux-2.6.18.8/arch/i386/Kconfig.cpu 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/Kconfig.cpu 2008-02-15 16:21:49.000000000 -0800
+@@ -252,7 +252,7 @@ config X86_PPRO_FENCE
config X86_F00F_BUG
bool
@@ -284,16 +276,16 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig.cpu tmp-linux-2.6-xen.patch/a
default y
config X86_WP_WORKS_OK
-@@ -311,5 +311,5 @@ config X86_OOSTORE
+@@ -312,5 +312,5 @@ config X86_OOSTORE
config X86_TSC
bool
- depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ
+ depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ && !X86_XEN
default y
-diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig.debug tmp-linux-2.6-xen.patch/arch/i386/Kconfig.debug
---- pristine-linux-2.6.18/arch/i386/Kconfig.debug 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/Kconfig.debug 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/Kconfig.debug linux-2.6.18-xen-3.2.0/arch/i386/Kconfig.debug
+--- linux-2.6.18.8/arch/i386/Kconfig.debug 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/Kconfig.debug 2008-02-15 16:21:49.000000000 -0800
@@ -79,6 +79,7 @@ config X86_MPPARSE
config DOUBLEFAULT
default y
@@ -302,22 +294,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Kconfig.debug tmp-linux-2.6-xen.patch
help
This option allows trapping of rare doublefault exceptions that
would otherwise cause a system to silently reboot. Disabling this
-diff -Nurp pristine-linux-2.6.18/arch/i386/Makefile tmp-linux-2.6-xen.patch/arch/i386/Makefile
---- pristine-linux-2.6.18/arch/i386/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -48,6 +48,11 @@ CFLAGS += $(shell if [ $(call cc-vers
-
- CFLAGS += $(cflags-y)
-
-+cppflags-$(CONFIG_XEN) += \
-+ -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
-+
-+CPPFLAGS += $(cppflags-y)
-+
- # Default subarch .c files
- mcore-y := mach-default
-
-@@ -71,6 +76,10 @@ mcore-$(CONFIG_X86_BIGSMP) := mach-defau
+diff -rpuN linux-2.6.18.8/arch/i386/Makefile linux-2.6.18-xen-3.2.0/arch/i386/Makefile
+--- linux-2.6.18.8/arch/i386/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -71,6 +71,10 @@ mcore-$(CONFIG_X86_BIGSMP) := mach-defau
mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit
mcore-$(CONFIG_X86_SUMMIT) := mach-default
@@ -328,125 +308,93 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/Makefile tmp-linux-2.6-xen.patch/arch
# generic subarchitecture
mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic
mcore-$(CONFIG_X86_GENERICARCH) := mach-default
-@@ -105,6 +114,19 @@ boot := arch/i386/boot
- PHONY += zImage bzImage compressed zlilo bzlilo \
+@@ -102,9 +106,20 @@ AFLAGS += $(mflags-y)
+
+ boot := arch/i386/boot
+
+-PHONY += zImage bzImage compressed zlilo bzlilo \
++PHONY += zImage bzImage vmlinuz compressed zlilo bzlilo \
zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
+ifdef CONFIG_XEN
-+CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
-+head-y := arch/i386/kernel/head-xen.o arch/i386/kernel/init_task-xen.o
-+boot := arch/i386/boot-xen
-+.PHONY: vmlinuz
++CPPFLAGS := -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION) \
++ -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
+all: vmlinuz
+
-+vmlinuz: vmlinux
-+ $(Q)$(MAKE) $(build)=$(boot) $@
++# KBUILD_IMAGE specifies the target image being built
++KBUILD_IMAGE := $(boot)/vmlinuz
+
-+install:
-+ $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@
++vmlinuz: vmlinux
++ $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
+else
all: bzImage
# KBUILD_IMAGE specify target image being built
-@@ -127,6 +149,7 @@ fdimage fdimage144 fdimage288 isoimage:
+@@ -124,6 +139,7 @@ zdisk bzdisk: vmlinux
- install:
- $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+ fdimage fdimage144 fdimage288 isoimage: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
+endif
- archclean:
- $(Q)$(MAKE) $(clean)=arch/i386/boot
-@@ -145,3 +168,4 @@ endef
- CLEAN_FILES += arch/$(ARCH)/boot/fdimage \
- arch/$(ARCH)/boot/image.iso \
- arch/$(ARCH)/boot/mtools.conf
-+CLEAN_FILES += vmlinuz vmlinux-stripped
-diff -Nurp pristine-linux-2.6.18/arch/i386/boot-xen/Makefile tmp-linux-2.6-xen.patch/arch/i386/boot-xen/Makefile
---- pristine-linux-2.6.18/arch/i386/boot-xen/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/boot-xen/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,21 @@
-+
-+OBJCOPYFLAGS := -g --strip-unneeded
-+
-+vmlinuz: vmlinux-stripped FORCE
+ install:
+ $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+diff -rpuN linux-2.6.18.8/arch/i386/boot/Makefile linux-2.6.18-xen-3.2.0/arch/i386/boot/Makefile
+--- linux-2.6.18.8/arch/i386/boot/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/boot/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -26,7 +26,7 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
+ #RAMDISK := -DRAMDISK=512
+
+ targets := vmlinux.bin bootsect bootsect.o \
+- setup setup.o zImage bzImage
++ setup setup.o zImage bzImage vmlinuz vmlinux-stripped
+ subdir- := compressed
+
+ hostprogs-y := tools/build
+@@ -133,5 +133,13 @@ zlilo: $(BOOTIMAGE)
+ cp System.map $(INSTALL_PATH)/
+ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+
++$(obj)/vmlinuz: $(obj)/vmlinux-stripped FORCE
+ $(call if_changed,gzip)
++ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
-+vmlinux-stripped: vmlinux FORCE
++$(obj)/vmlinux-stripped: OBJCOPYFLAGS := -g --strip-unneeded
++$(obj)/vmlinux-stripped: vmlinux FORCE
+ $(call if_changed,objcopy)
+
-+INSTALL_ROOT := $(patsubst %/boot,%,$(INSTALL_PATH))
-+
-+XINSTALL_NAME ?= $(KERNELRELEASE)
-+install:
-+ mkdir -p $(INSTALL_ROOT)/boot
-+ ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
-+ rm -f $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+ install -m0644 vmlinuz $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+ install -m0644 vmlinux $(INSTALL_ROOT)/boot/vmlinux-syms-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+ install -m0664 .config $(INSTALL_ROOT)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+ install -m0664 System.map $(INSTALL_ROOT)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+ ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/Makefile tmp-linux-2.6-xen.patch/arch/i386/kernel/Makefile
---- pristine-linux-2.6.18/arch/i386/kernel/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -44,6 +44,12 @@ EXTRA_AFLAGS := -traditional
+ install:
+ sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/Makefile linux-2.6.18-xen-3.2.0/arch/i386/kernel/Makefile
+--- linux-2.6.18.8/arch/i386/kernel/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -43,6 +43,7 @@ obj-$(CONFIG_K8_NB) += k8.o
+ EXTRA_AFLAGS := -traditional
obj-$(CONFIG_SCx200) += scx200.o
++obj-$(CONFIG_XEN) += fixup.o
-+ifdef CONFIG_XEN
-+vsyscall_note := vsyscall-note-xen.o
-+else
-+vsyscall_note := vsyscall-note.o
-+endif
-+
# vsyscall.o contains the vsyscall DSO images as __initdata.
# We must build both images before we can assemble it.
- # Note: kbuild does not track this dependency due to usage of .incbin
-@@ -65,7 +71,7 @@ SYSCFLAGS_vsyscall-int80.so = $(vsyscall
-
- $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
- $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
-- $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE
-+ $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
- $(call if_changed,syscall)
-
- # We also create a special relocatable object that should mirror the symbol
-@@ -77,8 +83,20 @@ $(obj)/built-in.o: ld_flags += -R $(obj)
-
- SYSCFLAGS_vsyscall-syms.o = -r
- $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
-- $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
-+ $(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE
+@@ -80,5 +81,8 @@ $(obj)/vsyscall-syms.o: $(src)/vsyscall.
+ $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
$(call if_changed,syscall)
++early_printk-y += ../../x86_64/kernel/early_printk.o
k8-y += ../../x86_64/kernel/k8.o
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y += fixup.o
-+microcode-$(subst m,y,$(CONFIG_MICROCODE)) := microcode-xen.o
-+n-obj-xen := i8259.o timers/ reboot.o smpboot.o trampoline.o
-+
-+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
-+obj-y := $(call cherrypickxen, $(obj-y))
-+extra-y := $(call cherrypickxen, $(extra-y))
-+%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/acpi/Makefile tmp-linux-2.6-xen.patch/arch/i386/kernel/acpi/Makefile
---- pristine-linux-2.6.18/arch/i386/kernel/acpi/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/acpi/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -6,3 +6,7 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),)
++disabled-obj-$(CONFIG_XEN) := i8259.o reboot.o smpboot.o trampoline.o
++%/head.o %/head.s: $(if $(CONFIG_XEN),EXTRA_AFLAGS,dummy) :=
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/acpi/Makefile linux-2.6.18-xen-3.2.0/arch/i386/kernel/acpi/Makefile
+--- linux-2.6.18.8/arch/i386/kernel/acpi/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/acpi/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -6,3 +6,4 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),)
obj-y += cstate.o processor.o
endif
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+obj-y := $(call cherrypickxen, $(obj-y), $(src))
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/acpi/boot-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/acpi/boot-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/acpi/boot-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/acpi/boot-xen.c 2007-11-14 15:35:27.000000000 -0800
++disabled-obj-$(CONFIG_XEN) := cstate.o wakeup.o
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/acpi/boot-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/acpi/boot-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/acpi/boot-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/acpi/boot-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,1168 @@
+/*
+ * boot.c - Architecture-Specific Low-Level ACPI Boot Support
@@ -1616,9 +1564,147 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/acpi/boot-xen.c tmp-linux-2.6-
+
+ return 0;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/apic-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/apic-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/apic-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/apic-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/acpi/sleep-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/acpi/sleep-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/acpi/sleep-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/acpi/sleep-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,134 @@
++/*
++ * 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_video_flags;
++extern char wakeup_start, wakeup_end;
++
++extern unsigned long FASTCALL(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)
++ return 1;
++ 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) {
++ printk(KERN_ERR
++ "ACPI: Wakeup code way too big, S3 disabled.\n");
++ return;
++ }
++
++ acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
++ 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_video_flags = 1;
++ if (strncmp(str, "s3_mode", 7) == 0)
++ acpi_video_flags |= 2;
++ str = strchr(str, ',');
++ if (str != NULL)
++ str += strspn(str, ", \t");
++ }
++ return 1;
++}
++
++__setup("acpi_sleep=", acpi_sleep_setup);
++
++static __init int reset_videomode_after_s3(struct dmi_system_id *d)
++{
++ acpi_video_flags |= 2;
++ return 0;
++}
++
++static __initdata struct dmi_system_id acpisleep_dmi_table[] = {
++ { /* Reset video mode after returning from ACPI S3 sleep */
++ .callback = reset_videomode_after_s3,
++ .ident = "Toshiba Satellite 4030cdt",
++ .matches = {
++ DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
++ },
++ },
++ {}
++};
++
++static int __init acpisleep_dmi_init(void)
++{
++ dmi_check_system(acpisleep_dmi_table);
++ return 0;
++}
++
++core_initcall(acpisleep_dmi_init);
++
++#else /* CONFIG_ACPI_PV_SLEEP */
++#include <asm/hypervisor.h>
++#include <xen/interface/platform.h>
++int acpi_notify_hypervisor_state(u8 sleep_state,
++ u32 pm1a_cnt, u32 pm1b_cnt)
++{
++ struct xen_platform_op op = {
++ .cmd = XENPF_enter_acpi_sleep,
++ .interface_version = XENPF_INTERFACE_VERSION,
++ .u = {
++ .enter_acpi_sleep = {
++ .pm1a_cnt_val = (u16)pm1a_cnt,
++ .pm1b_cnt_val = (u16)pm1b_cnt,
++ .sleep_state = sleep_state,
++ },
++ },
++ };
++
++ return HYPERVISOR_platform_op(&op);
++}
++#endif /* CONFIG_ACPI_PV_SLEEP */
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/apic-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/apic-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/apic-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/apic-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,155 @@
+/*
+ * Local APIC handling, local APIC timers
@@ -1775,9 +1861,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/apic-xen.c tmp-linux-2.6-xen.p
+
+ return 0;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/asm-offsets.c tmp-linux-2.6-xen.patch/arch/i386/kernel/asm-offsets.c
---- pristine-linux-2.6.18/arch/i386/kernel/asm-offsets.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/asm-offsets.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/asm-offsets.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/asm-offsets.c
+--- linux-2.6.18.8/arch/i386/kernel/asm-offsets.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/asm-offsets.c 2008-02-15 16:21:49.000000000 -0800
@@ -66,9 +66,14 @@ void foo(void)
OFFSET(pbe_orig_address, pbe, orig_address);
OFFSET(pbe_next, pbe, next);
@@ -1794,21 +1880,17 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/asm-offsets.c tmp-linux-2.6-xe
DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
DEFINE(VDSO_PRELINK, VDSO_PRELINK);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/Makefile tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/Makefile
---- pristine-linux-2.6.18/arch/i386/kernel/cpu/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -17,3 +17,8 @@ obj-$(CONFIG_X86_MCE) += mcheck/
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/cpu/Makefile linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/Makefile
+--- linux-2.6.18.8/arch/i386/kernel/cpu/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -17,3 +17,4 @@ obj-$(CONFIG_X86_MCE) += mcheck/
obj-$(CONFIG_MTRR) += mtrr/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+obj-y := $(call cherrypickxen, $(obj-y), $(src))
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/common-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/common-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/cpu/common-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/common-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/cpu/common-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/common-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/cpu/common-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/common-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,743 @@
+#include <linux/init.h>
+#include <linux/string.h>
@@ -2402,7 +2484,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/common-xen.c tmp-linux-2.6
+#endif
+}
+
-+void __cpuinit cpu_gdt_init(struct Xgt_desc_struct *gdt_descr)
++static void __cpuinit cpu_gdt_init(const struct Xgt_desc_struct *gdt_descr)
+{
+ unsigned long frames[16];
+ unsigned long va;
@@ -2415,7 +2497,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/common-xen.c tmp-linux-2.6
+ make_lowmem_page_readonly(
+ (void *)va, XENFEAT_writable_descriptor_tables);
+ }
-+ if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
++ if (HYPERVISOR_set_gdt(frames, (gdt_descr->size + 1) / 8))
+ BUG();
+}
+
@@ -2553,24 +2635,530 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/common-xen.c tmp-linux-2.6
+ per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
+}
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/mtrr/Makefile tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/mtrr/Makefile
---- pristine-linux-2.6.18/arch/i386/kernel/cpu/mtrr/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/mtrr/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -3,3 +3,10 @@ obj-y += amd.o
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/cpu/cpufreq/powernow-k8.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+--- linux-2.6.18.8/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2008-02-15 16:21:49.000000000 -0800
+@@ -46,7 +46,7 @@
+
+ #define PFX "powernow-k8: "
+ #define BFX PFX "BIOS error: "
+-#define VERSION "version 2.00.00"
++#define VERSION "version 2.20.00"
+ #include "powernow-k8.h"
+
+ /* serialize freq changes */
+@@ -66,36 +66,15 @@ static u32 find_freq_from_fid(u32 fid)
+ return 800 + (fid * 100);
+ }
+
+-
+ /* Return a frequency in KHz, given an input fid */
+ static u32 find_khz_freq_from_fid(u32 fid)
+ {
+ return 1000 * find_freq_from_fid(fid);
+ }
+
+-/* Return a frequency in MHz, given an input fid and did */
+-static u32 find_freq_from_fiddid(u32 fid, u32 did)
+-{
+- return 100 * (fid + 0x10) >> did;
+-}
+-
+-static u32 find_khz_freq_from_fiddid(u32 fid, u32 did)
+-{
+- return 1000 * find_freq_from_fiddid(fid, did);
+-}
+-
+-static u32 find_fid_from_pstate(u32 pstate)
+-{
+- u32 hi, lo;
+- rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
+- return lo & HW_PSTATE_FID_MASK;
+-}
+-
+-static u32 find_did_from_pstate(u32 pstate)
++static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate)
+ {
+- u32 hi, lo;
+- rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
+- return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
++ return data[pstate].frequency;
+ }
+
+ /* Return the vco fid for an input fid
+@@ -139,9 +118,7 @@ static int query_current_values_with_pen
+ if (cpu_family == CPU_HW_PSTATE) {
+ rdmsr(MSR_PSTATE_STATUS, lo, hi);
+ i = lo & HW_PSTATE_MASK;
+- rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi);
+- data->currfid = lo & HW_PSTATE_FID_MASK;
+- data->currdid = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
++ data->currpstate = i;
+ return 0;
+ }
+ do {
+@@ -292,7 +269,7 @@ static int decrease_vid_code_by_step(str
+ static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
+ {
+ wrmsr(MSR_PSTATE_CTRL, pstate, 0);
+- data->currfid = find_fid_from_pstate(pstate);
++ data->currpstate = pstate;
+ return 0;
+ }
+
+@@ -738,6 +715,7 @@ static int find_psb_table(struct powerno
+
+ data->numps = psb->numps;
+ dprintk("numpstates: 0x%x\n", data->numps);
++ data->starting_core_affinity = cpumask_of_cpu(0);
+ return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
+ }
+ /*
+@@ -758,15 +736,43 @@ static int find_psb_table(struct powerno
+ #ifdef CONFIG_X86_POWERNOW_K8_ACPI
+ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
+ {
+- if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
++ if (!data->acpi_data->state_count || (cpu_family == CPU_HW_PSTATE))
+ return;
+
+- data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
+- data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
+- data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
+- data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
+- data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
+- data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
++ data->irt = (data->acpi_data->states[index].control >> IRT_SHIFT) & IRT_MASK;
++ data->rvo = (data->acpi_data->states[index].control >> RVO_SHIFT) & RVO_MASK;
++ data->exttype = (data->acpi_data->states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
++ data->plllock = (data->acpi_data->states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
++ data->vidmvs = 1 << ((data->acpi_data->states[index].control >> MVS_SHIFT) & MVS_MASK);
++ data->vstable = (data->acpi_data->states[index].control >> VST_SHIFT) & VST_MASK;
++}
++
++static struct acpi_processor_performance *acpi_perf_data[NR_CPUS];
++static int preregister_valid = 0;
++
++static int powernow_k8_cpu_preinit_acpi()
++{
++ int i;
++ struct acpi_processor_performance *data;
++ for_each_possible_cpu(i) {
++ data = kzalloc(sizeof(struct acpi_processor_performance),
++ GFP_KERNEL);
++ if (!data) {
++ int j;
++ for_each_possible_cpu(j) {
++ kfree(acpi_perf_data[j]);
++ acpi_perf_data[j] = NULL;
++ }
++ return -ENODEV;
++ }
++ acpi_perf_data[i] = data;
++ }
++
++ if (acpi_processor_preregister_performance(acpi_perf_data))
++ return -ENODEV;
++ else
++ preregister_valid = 1;
++ return 0;
+ }
+
+ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
+@@ -774,28 +780,29 @@ static int powernow_k8_cpu_init_acpi(str
+ struct cpufreq_frequency_table *powernow_table;
+ int ret_val;
+
+- if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
++ data->acpi_data = acpi_perf_data[data->cpu];
++ if (acpi_processor_register_performance(data->acpi_data, data->cpu)) {
+ dprintk("register performance failed: bad ACPI data\n");
+ return -EIO;
+ }
+
+ /* verify the data contained in the ACPI structures */
+- if (data->acpi_data.state_count <= 1) {
++ if (data->acpi_data->state_count <= 1) {
+ dprintk("No ACPI P-States\n");
+ goto err_out;
+ }
+
+- if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+- (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
++ if ((data->acpi_data->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
++ (data->acpi_data->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+ dprintk("Invalid control/status registers (%x - %x)\n",
+- data->acpi_data.control_register.space_id,
+- data->acpi_data.status_register.space_id);
++ data->acpi_data->control_register.space_id,
++ data->acpi_data->status_register.space_id);
+ goto err_out;
+ }
+
+ /* fill in data->powernow_table */
+ powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
+- * (data->acpi_data.state_count + 1)), GFP_KERNEL);
++ * (data->acpi_data->state_count + 1)), GFP_KERNEL);
+ if (!powernow_table) {
+ dprintk("powernow_table memory alloc failure\n");
+ goto err_out;
+@@ -808,28 +815,43 @@ static int powernow_k8_cpu_init_acpi(str
+ if (ret_val)
+ goto err_out_mem;
+
+- powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END;
+- powernow_table[data->acpi_data.state_count].index = 0;
++ powernow_table[data->acpi_data->state_count].frequency = CPUFREQ_TABLE_END;
++ powernow_table[data->acpi_data->state_count].index = 0;
+ data->powernow_table = powernow_table;
+
+ /* fill in data */
+- data->numps = data->acpi_data.state_count;
++ data->numps = data->acpi_data->state_count;
+ print_basics(data);
+ powernow_k8_acpi_pst_values(data, 0);
+
+ /* notify BIOS that we exist */
+ acpi_processor_notify_smm(THIS_MODULE);
+
++ /* determine affinity, from ACPI if available */
++ if (preregister_valid) {
++ if ((data->acpi_data->shared_type == CPUFREQ_SHARED_TYPE_ALL) ||
++ (data->acpi_data->shared_type == CPUFREQ_SHARED_TYPE_ANY))
++ data->starting_core_affinity = data->acpi_data->shared_cpu_map;
++ else
++ data->starting_core_affinity = cpumask_of_cpu(data->cpu);
++ } else {
++ /* best guess from family if not */
++ if (cpu_family == CPU_HW_PSTATE)
++ data->starting_core_affinity = cpumask_of_cpu(data->cpu);
++ else
++ data->starting_core_affinity = cpu_core_map[data->cpu];
++ }
++
+ return 0;
+
+ err_out_mem:
+ kfree(powernow_table);
+
+ err_out:
+- acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
++ acpi_processor_unregister_performance(data->acpi_data, data->cpu);
+
+- /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
+- data->acpi_data.state_count = 0;
++ /* data->acpi_data->state_count informs us at ->exit() whether ACPI was used */
++ data->acpi_data->state_count = 0;
+
+ return -ENODEV;
+ }
+@@ -837,41 +859,23 @@ err_out:
+ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
+ {
+ int i;
++ u32 hi = 0, lo = 0;
++ rdmsr(MSR_PSTATE_CUR_LIMIT, hi, lo);
++ data->max_hw_pstate = (hi & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
+
+- for (i = 0; i < data->acpi_data.state_count; i++) {
++ for (i = 0; i < data->acpi_data->state_count; i++) {
+ u32 index;
+- u32 hi = 0, lo = 0;
+- u32 fid;
+- u32 did;
+
+- index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
+- if (index > MAX_HW_PSTATE) {
++ index = data->acpi_data->states[i].control & HW_PSTATE_MASK;
++ if (index > data->max_hw_pstate) {
+ printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index);
+ printk(KERN_ERR PFX "Please report to BIOS manufacturer\n");
+- }
+- rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
+- if (!(hi & HW_PSTATE_VALID_MASK)) {
+- dprintk("invalid pstate %d, ignoring\n", index);
+- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ continue;
+ }
+
+- fid = lo & HW_PSTATE_FID_MASK;
+- did = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
+-
+- dprintk(" %d : fid 0x%x, did 0x%x\n", index, fid, did);
++ powernow_table[i].index = index;
++ powernow_table[i].frequency = data->acpi_data->states[i].core_frequency * 1000;
+
+- powernow_table[i].index = index | (fid << HW_FID_INDEX_SHIFT) | (did << HW_DID_INDEX_SHIFT);
+-
+- powernow_table[i].frequency = find_khz_freq_from_fiddid(fid, did);
+-
+- if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
+- printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
+- powernow_table[i].frequency,
+- (unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
+- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+- continue;
+- }
+ }
+ return 0;
+ }
+@@ -880,16 +884,16 @@ static int fill_powernow_table_fidvid(st
+ {
+ int i;
+ int cntlofreq = 0;
+- for (i = 0; i < data->acpi_data.state_count; i++) {
++ for (i = 0; i < data->acpi_data->state_count; i++) {
+ u32 fid;
+ u32 vid;
+
+ if (data->exttype) {
+- fid = data->acpi_data.states[i].status & EXT_FID_MASK;
+- vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK;
++ fid = data->acpi_data->states[i].status & EXT_FID_MASK;
++ vid = (data->acpi_data->states[i].status >> VID_SHIFT) & EXT_VID_MASK;
+ } else {
+- fid = data->acpi_data.states[i].control & FID_MASK;
+- vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
++ fid = data->acpi_data->states[i].control & FID_MASK;
++ vid = (data->acpi_data->states[i].control >> VID_SHIFT) & VID_MASK;
+ }
+
+ dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
+@@ -930,10 +934,10 @@ static int fill_powernow_table_fidvid(st
+ cntlofreq = i;
+ }
+
+- if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
++ if (powernow_table[i].frequency != (data->acpi_data->states[i].core_frequency * 1000)) {
+ printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
+ powernow_table[i].frequency,
+- (unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
++ (unsigned int) (data->acpi_data->states[i].core_frequency * 1000));
+ powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ continue;
+ }
+@@ -943,14 +947,15 @@ static int fill_powernow_table_fidvid(st
+
+ static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
+ {
+- if (data->acpi_data.state_count)
+- acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
++ if (data->acpi_data->state_count)
++ acpi_processor_unregister_performance(data->acpi_data, data->cpu);
+ }
+
+ #else
+ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
+ static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
+ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
++static int powernow_k8_cpu_preinit_acpi() { return -ENODEV; }
+ #endif /* CONFIG_X86_POWERNOW_K8_ACPI */
+
+ /* Take a frequency, and issue the fid/vid transition command */
+@@ -1012,22 +1017,18 @@ static int transition_frequency_fidvid(s
+ /* Take a frequency, and issue the hardware pstate transition command */
+ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index)
+ {
+- u32 fid = 0;
+- u32 did = 0;
+ u32 pstate = 0;
+ int res, i;
+ struct cpufreq_freqs freqs;
+
+ dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
+
+- /* get fid did for hardware pstate transition */
++ /* get MSR index for hardware pstate transition */
+ pstate = index & HW_PSTATE_MASK;
+- if (pstate > MAX_HW_PSTATE)
++ if (pstate > data->max_hw_pstate)
+ return 0;
+- fid = (index & HW_FID_INDEX_MASK) >> HW_FID_INDEX_SHIFT;
+- did = (index & HW_DID_INDEX_MASK) >> HW_DID_INDEX_SHIFT;
+- freqs.old = find_khz_freq_from_fiddid(data->currfid, data->currdid);
+- freqs.new = find_khz_freq_from_fiddid(fid, did);
++ freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
++ freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
+
+ for_each_cpu_mask(i, *(data->available_cores)) {
+ freqs.cpu = i;
+@@ -1035,9 +1036,7 @@ static int transition_frequency_pstate(s
+ }
+
+ res = transition_pstate(data, pstate);
+- data->currfid = find_fid_from_pstate(pstate);
+- data->currdid = find_did_from_pstate(pstate);
+- freqs.new = find_khz_freq_from_fiddid(data->currfid, data->currdid);
++ freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
+
+ for_each_cpu_mask(i, *(data->available_cores)) {
+ freqs.cpu = i;
+@@ -1082,10 +1081,7 @@ static int powernowk8_target(struct cpuf
+ if (query_current_values_with_pending_wait(data))
+ goto err_out;
+
+- if (cpu_family == CPU_HW_PSTATE)
+- dprintk("targ: curr fid 0x%x, did 0x%x\n",
+- data->currfid, data->currvid);
+- else {
++ if (cpu_family != CPU_HW_PSTATE) {
+ dprintk("targ: curr fid 0x%x, vid 0x%x\n",
+ data->currfid, data->currvid);
+
+@@ -1116,7 +1112,7 @@ static int powernowk8_target(struct cpuf
+ mutex_unlock(&fidvid_mutex);
+
+ if (cpu_family == CPU_HW_PSTATE)
+- pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
++ pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate);
+ else
+ pol->cur = find_khz_freq_from_fid(data->currfid);
+ ret = 0;
+@@ -1164,7 +1160,7 @@ static int __cpuinit powernowk8_cpu_init
+ * an UP version, and is deprecated by AMD.
+ */
+ if (num_online_cpus() != 1) {
+- printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
++ printk(KERN_ERR PFX "Your BIOS does not provide _PSS objects. PowerNow! does not work on SMP systems without _PSS objects. Complain to your BIOS vendor.\n");
+ kfree(data);
+ return -ENODEV;
+ }
+@@ -1204,10 +1200,7 @@ static int __cpuinit powernowk8_cpu_init
+ set_cpus_allowed(current, oldmask);
+
+ pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
+- if (cpu_family == CPU_HW_PSTATE)
+- pol->cpus = cpumask_of_cpu(pol->cpu);
+- else
+- pol->cpus = cpu_core_map[pol->cpu];
++ pol->cpus = data->starting_core_affinity;
+ data->available_cores = &(pol->cpus);
+
+ /* Take a crude guess here.
+@@ -1216,7 +1209,7 @@ static int __cpuinit powernowk8_cpu_init
+ + (3 * (1 << data->irt) * 10)) * 1000;
+
+ if (cpu_family == CPU_HW_PSTATE)
+- pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
++ pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
+ else
+ pol->cur = find_khz_freq_from_fid(data->currfid);
+ dprintk("policy current frequency %d kHz\n", pol->cur);
+@@ -1233,8 +1226,7 @@ static int __cpuinit powernowk8_cpu_init
+ cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
+
+ if (cpu_family == CPU_HW_PSTATE)
+- dprintk("cpu_init done, current fid 0x%x, did 0x%x\n",
+- data->currfid, data->currdid);
++ dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate);
+ else
+ dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
+ data->currfid, data->currvid);
+@@ -1289,7 +1281,10 @@ static unsigned int powernowk8_get (unsi
+ if (query_current_values_with_pending_wait(data))
+ goto out;
+
+- khz = find_khz_freq_from_fid(data->currfid);
++ if (cpu_family == CPU_HW_PSTATE)
++ khz = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
++ else
++ khz = find_khz_freq_from_fid(data->currfid);
+
+ out:
+ set_cpus_allowed(current, oldmask);
+@@ -1323,6 +1318,7 @@ static int __cpuinit powernowk8_init(voi
+ }
+
+ if (supported_cpus == num_online_cpus()) {
++ powernow_k8_cpu_preinit_acpi();
+ printk(KERN_INFO PFX "Found %d %s "
+ "processors (" VERSION ")\n", supported_cpus,
+ boot_cpu_data.x86_model_id);
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/cpu/cpufreq/powernow-k8.h linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+--- linux-2.6.18.8/arch/i386/kernel/cpu/cpufreq/powernow-k8.h 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/cpufreq/powernow-k8.h 2008-02-15 16:21:49.000000000 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * (c) 2003-2006 Advanced Micro Devices, Inc.
++#* (c) 2003-2006 Advanced Micro Devices, Inc.
+ * Your use of this code is subject to the terms and conditions of the
+ * GNU general public license version 2. See "COPYING" or
+ * http://www.gnu.org/licenses/gpl.html
+@@ -10,6 +10,7 @@ struct powernow_k8_data {
+
+ u32 numps; /* number of p-states */
+ u32 batps; /* number of p-states supported on battery */
++ u32 max_hw_pstate; /* maximum legal hardware pstate */
+
+ /* these values are constant when the PSB is used to determine
+ * vid/fid pairings, but are modified during the ->target() call
+@@ -21,8 +22,8 @@ struct powernow_k8_data {
+ u32 plllock; /* pll lock time, units 1 us */
+ u32 exttype; /* extended interface = 1 */
+
+- /* keep track of the current fid / vid or did */
+- u32 currvid, currfid, currdid;
++ /* keep track of the current fid / vid or pstate */
++ u32 currvid, currfid, currpstate;
+
+ /* the powernow_table includes all frequency and vid/fid pairings:
+ * fid are the lower 8 bits of the index, vid are the upper 8 bits.
+@@ -32,12 +33,13 @@ struct powernow_k8_data {
+ #ifdef CONFIG_X86_POWERNOW_K8_ACPI
+ /* the acpi table needs to be kept. it's only available if ACPI was
+ * used to determine valid frequency/vid/fid states */
+- struct acpi_processor_performance acpi_data;
++ struct acpi_processor_performance *acpi_data;
+ #endif
+ /* we need to keep track of associated cores, but let cpufreq
+ * handle hotplug events - so just point at cpufreq pol->cpus
+ * structure */
+ cpumask_t *available_cores;
++ cpumask_t starting_core_affinity;
+ };
+
+
+@@ -87,23 +89,14 @@ struct powernow_k8_data {
+
+ /* Hardware Pstate _PSS and MSR definitions */
+ #define USE_HW_PSTATE 0x00000080
+-#define HW_PSTATE_FID_MASK 0x0000003f
+-#define HW_PSTATE_DID_MASK 0x000001c0
+-#define HW_PSTATE_DID_SHIFT 6
+-#define HW_PSTATE_MASK 0x00000007
+-#define HW_PSTATE_VALID_MASK 0x80000000
+-#define HW_FID_INDEX_SHIFT 8
+-#define HW_FID_INDEX_MASK 0x0000ff00
+-#define HW_DID_INDEX_SHIFT 16
+-#define HW_DID_INDEX_MASK 0x00ff0000
+-#define HW_WATTS_MASK 0xff
+-#define HW_PWR_DVR_MASK 0x300
+-#define HW_PWR_DVR_SHIFT 8
+-#define HW_PWR_MAX_MULT 3
+-#define MAX_HW_PSTATE 8 /* hw pstate supports up to 8 */
++#define HW_PSTATE_MASK 0x00000007
++#define HW_PSTATE_VALID_MASK 0x80000000
++#define HW_PSTATE_MAX_MASK 0x000000f0
++#define HW_PSTATE_MAX_SHIFT 4
+ #define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */
+ #define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */
+ #define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */
++#define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */
+
+ /* define the two driver architectures */
+ #define CPU_OPTERON 0
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/cpu/mtrr/Makefile linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/mtrr/Makefile
+--- linux-2.6.18.8/arch/i386/kernel/cpu/mtrr/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/mtrr/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -3,3 +3,4 @@ obj-y += amd.o
obj-y += cyrix.o
obj-y += centaur.o
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+n-obj-xen := generic.o state.o amd.o cyrix.o centaur.o
-+
-+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/mtrr/main-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/mtrr/main-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/cpu/mtrr/main-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/cpu/mtrr/main-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,197 @@
++obj-$(CONFIG_XEN) := main.o if.o
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/cpu/mtrr/main-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/mtrr/main-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/cpu/mtrr/main-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/cpu/mtrr/main-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,198 @@
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
@@ -2591,7 +3179,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/mtrr/main-xen.c tmp-linux-
+
+ op.cmd = XENPF_read_memtype;
+ op.u.read_memtype.reg = reg;
-+ (void)HYPERVISOR_platform_op(&op);
++ if (unlikely(HYPERVISOR_platform_op(&op)))
++ memset(&op.u.read_memtype, 0, sizeof(op.u.read_memtype));
+
+ *size = op.u.read_memtype.nr_mfns;
+ *base = op.u.read_memtype.mfn;
@@ -2768,9 +3357,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/cpu/mtrr/main-xen.c tmp-linux-
+}
+
+subsys_initcall(mtrr_init);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/crash.c tmp-linux-2.6-xen.patch/arch/i386/kernel/crash.c
---- pristine-linux-2.6.18/arch/i386/kernel/crash.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/crash.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/crash.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/crash.c
+--- linux-2.6.18.8/arch/i386/kernel/crash.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/crash.c 2008-02-15 16:21:49.000000000 -0800
@@ -90,6 +90,7 @@ static void crash_save_self(struct pt_re
crash_save_this_cpu(regs, cpu);
}
@@ -2800,16 +3389,16 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/crash.c tmp-linux-2.6-xen.patc
+#endif /* CONFIG_XEN */
crash_save_self(regs);
}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/early_printk-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/early_printk-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/early_printk-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/early_printk-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/early_printk-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/early_printk-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/early_printk-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/early_printk-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,2 @@
+
+#include "../../x86_64/kernel/early_printk-xen.c"
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/entry-xen.S tmp-linux-2.6-xen.patch/arch/i386/kernel/entry-xen.S
---- pristine-linux-2.6.18/arch/i386/kernel/entry-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/entry-xen.S 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,1216 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/entry-xen.S linux-2.6.18-xen-3.2.0/arch/i386/kernel/entry-xen.S
+--- linux-2.6.18.8/arch/i386/kernel/entry-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/entry-xen.S 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,1238 @@
+/*
+ * linux/arch/i386/entry.S
+ *
@@ -3193,6 +3782,29 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/entry-xen.S tmp-linux-2.6-xen.
+#endif /* !CONFIG_XEN */
+ CFI_ENDPROC
+
++ # pv sysenter call handler stub
++ENTRY(sysenter_entry_pv)
++ RING0_INT_FRAME
++ movl $__USER_DS,16(%esp)
++ movl %ebp,12(%esp)
++ movl $__USER_CS,4(%esp)
++ addl $4,%esp
++ /* +5*4 is SS:ESP,EFLAGS,CS:EIP. +8 is esp0 setting. */
++ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
++/*
++ * Load the potential sixth argument from user stack.
++ * Careful about security.
++ */
++ cmpl $__PAGE_OFFSET-3,%ebp
++ jae syscall_fault
++1: movl (%ebp),%ebp
++.section __ex_table,"a"
++ .align 4
++ .long 1b,syscall_fault
++.previous
++ /* fall through */
++ CFI_ENDPROC
++ENDPROC(sysenter_entry_pv)
+
+ # system call handler stub
+ENTRY(system_call)
@@ -4022,13 +4634,12 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/entry-xen.S tmp-linux-2.6-xen.
+ CFI_ENDPROC
+
+.section .rodata,"a"
-+.align 4
+#include "syscall_table.S"
+
+syscall_table_size=(.-sys_call_table)
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/entry.S tmp-linux-2.6-xen.patch/arch/i386/kernel/entry.S
---- pristine-linux-2.6.18/arch/i386/kernel/entry.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/entry.S 2007-11-16 16:18:13.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/entry.S linux-2.6.18-xen-3.2.0/arch/i386/kernel/entry.S
+--- linux-2.6.18.8/arch/i386/kernel/entry.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/entry.S 2008-02-15 16:21:49.000000000 -0800
@@ -269,7 +269,7 @@ ENTRY(sysenter_entry)
CFI_STARTPROC simple
CFI_DEF_CFA esp, 0
@@ -4056,9 +4667,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/entry.S tmp-linux-2.6-xen.patc
pushfl; \
pushl $__KERNEL_CS; \
pushl $sysenter_past_esp
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/fixup.c tmp-linux-2.6-xen.patch/arch/i386/kernel/fixup.c
---- pristine-linux-2.6.18/arch/i386/kernel/fixup.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/fixup.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/fixup.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/fixup.c
+--- linux-2.6.18.8/arch/i386/kernel/fixup.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/fixup.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * fixup.c
@@ -4108,8 +4719,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/fixup.c tmp-linux-2.6-xen.patc
+ if (current->tgid == 1)
+ return;
+
-+ HYPERVISOR_vm_assist(
-+ VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
++ VOID(HYPERVISOR_vm_assist(VMASST_CMD_disable,
++ VMASST_TYPE_4gb_segments_notify));
+
+ if (test_and_set_bit(0, &printed))
+ return;
@@ -4143,14 +4754,14 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/fixup.c tmp-linux-2.6-xen.patc
+
+static int __init fixup_init(void)
+{
-+ HYPERVISOR_vm_assist(
-+ VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
++ WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
++ VMASST_TYPE_4gb_segments_notify));
+ return 0;
+}
+__initcall(fixup_init);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/head-xen.S tmp-linux-2.6-xen.patch/arch/i386/kernel/head-xen.S
---- pristine-linux-2.6.18/arch/i386/kernel/head-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/head-xen.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/head-xen.S linux-2.6.18-xen-3.2.0/arch/i386/kernel/head-xen.S
+--- linux-2.6.18.8/arch/i386/kernel/head-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/head-xen.S 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,207 @@
+
+
@@ -4359,9 +4970,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/head-xen.S tmp-linux-2.6-xen.p
+#endif
+ ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
+ ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1)
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/init_task-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/init_task-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/init_task-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/init_task-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/init_task-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/init_task-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/init_task-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/init_task-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,51 @@
+#include <linux/mm.h>
+#include <linux/module.h>
@@ -4414,10 +5025,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/init_task-xen.c tmp-linux-2.6-
+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
+#endif
+
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/io_apic-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/io_apic-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,2777 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/io_apic-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/io_apic-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/io_apic-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/io_apic-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,2770 @@
+/*
+ * Intel IO-APIC support for multi-Pentium hosts.
+ *
@@ -4495,7 +5106,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c tmp-linux-2.6-xe
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ apic_op.value = value;
-+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
++ WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op));
+}
+
+#define io_apic_read(a,r) xen_io_apic_read(a,r)
@@ -5958,8 +6569,6 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c tmp-linux-2.6-xe
+ return;
+}
+
-+#if 0
-+
+static void print_APIC_bitfield (int base)
+{
+ unsigned int v;
@@ -6100,11 +6709,6 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c tmp-linux-2.6-xe
+ v = inb(0x4d1) << 8 | inb(0x4d0);
+ printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
+}
-+
-+#endif /* 0 */
-+
-+#else
-+void __init print_IO_APIC(void) { }
+#endif /* !CONFIG_XEN */
+
+static void __init enable_IO_APIC(void)
@@ -6933,7 +7537,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c tmp-linux-2.6-xe
+ struct xen_platform_op op = { .cmd = XENPF_platform_quirk };
+ op.u.platform_quirk.quirk_id = sis_apic_bug ?
+ QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
-+ HYPERVISOR_platform_op(&op);
++ VOID(HYPERVISOR_platform_op(&op));
+ }
+ return 0;
+}
@@ -7195,10 +7799,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/io_apic-xen.c tmp-linux-2.6-xe
+}
+
+#endif /* CONFIG_ACPI */
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/ioport-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/ioport-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/ioport-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/ioport-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,122 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/ioport-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/ioport-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/ioport-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/ioport-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,123 @@
+/*
+ * linux/arch/i386/kernel/ioport.c
+ *
@@ -7284,7 +7888,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/ioport-xen.c tmp-linux-2.6-xen
+
+ set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
+ set_iobitmap.nr_ports = IO_BITMAP_BITS;
-+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
++ WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
++ &set_iobitmap));
+ }
+
+ set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
@@ -7321,9 +7926,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/ioport-xen.c tmp-linux-2.6-xen
+ set_iopl_mask(t->iopl);
+ return 0;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/irq-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/irq-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/irq-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/irq-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/irq-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/irq-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/irq-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/irq-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,324 @@
+/*
+ * linux/arch/i386/kernel/irq.c
@@ -7649,9 +8254,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/irq-xen.c tmp-linux-2.6-xen.pa
+}
+#endif
+
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/ldt-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/ldt-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/ldt-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/ldt-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/ldt-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/ldt-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/ldt-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/ldt-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,270 @@
+/*
+ * linux/kernel/ldt.c
@@ -7923,9 +8528,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/ldt-xen.c tmp-linux-2.6-xen.pa
+ }
+ return ret;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/machine_kexec.c tmp-linux-2.6-xen.patch/arch/i386/kernel/machine_kexec.c
---- pristine-linux-2.6.18/arch/i386/kernel/machine_kexec.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/machine_kexec.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/machine_kexec.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/machine_kexec.c
+--- linux-2.6.18.8/arch/i386/kernel/machine_kexec.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/machine_kexec.c 2008-02-15 16:21:49.000000000 -0800
@@ -19,123 +19,52 @@
#include <asm/desc.h>
#include <asm/system.h>
@@ -8156,9 +8761,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/machine_kexec.c tmp-linux-2.6-
+ image->start, cpu_has_pae);
}
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/microcode-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/microcode-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/microcode-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/microcode-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/microcode-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/microcode-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/microcode-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/microcode-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,144 @@
+/*
+ * Intel CPU Microcode Update Driver for Linux
@@ -8304,9 +8909,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/microcode-xen.c tmp-linux-2.6-
+module_init(microcode_init)
+module_exit(microcode_exit)
+MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/mpparse-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/mpparse-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/mpparse-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/mpparse-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/mpparse-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/mpparse-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/mpparse-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/mpparse-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,1185 @@
+/*
+ * Intel Multiprocessor Specification 1.1 and 1.4
@@ -9493,10 +10098,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/mpparse-xen.c tmp-linux-2.6-xe
+
+#endif /* CONFIG_X86_IO_APIC */
+#endif /* CONFIG_ACPI */
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/pci-dma-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/pci-dma-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,369 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/pci-dma-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/pci-dma-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/pci-dma-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/pci-dma-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,382 @@
+/*
+ * Dynamic DMA mapping support.
+ *
@@ -9514,9 +10119,11 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+#include <linux/version.h>
+#include <asm/io.h>
+#include <xen/balloon.h>
++#include <xen/gnttab.h>
+#include <asm/swiotlb.h>
+#include <asm/tlbflush.h>
+#include <asm-i386/mach-xen/asm/swiotlb.h>
++#include <asm-i386/mach-xen/asm/gnttab_dma.h>
+#include <asm/bug.h>
+
+#ifdef __x86_64__
@@ -9588,10 +10195,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+ rc = swiotlb_map_sg(hwdev, sg, nents, direction);
+ } else {
+ for (i = 0; i < nents; i++ ) {
++ BUG_ON(!sg[i].page);
+ sg[i].dma_address =
-+ page_to_bus(sg[i].page) + sg[i].offset;
++ gnttab_dma_map_page(sg[i].page) + sg[i].offset;
+ sg[i].dma_length = sg[i].length;
-+ BUG_ON(!sg[i].page);
+ IOMMU_BUG_ON(address_needs_mapping(
+ hwdev, sg[i].dma_address));
+ IOMMU_BUG_ON(range_straddles_page_boundary(
@@ -9610,9 +10217,15 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
++ int i;
++
+ BUG_ON(direction == DMA_NONE);
+ if (swiotlb)
+ swiotlb_unmap_sg(hwdev, sg, nents, direction);
++ else {
++ for (i = 0; i < nents; i++ )
++ gnttab_dma_unmap_page(sg[i].dma_address);
++ }
+}
+EXPORT_SYMBOL(dma_unmap_sg);
+
@@ -9629,7 +10242,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+ dma_addr = swiotlb_map_page(
+ dev, page, offset, size, direction);
+ } else {
-+ dma_addr = page_to_bus(page) + offset;
++ dma_addr = gnttab_dma_map_page(page) + offset;
+ IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
+ }
+
@@ -9644,6 +10257,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+ BUG_ON(direction == DMA_NONE);
+ if (swiotlb)
+ swiotlb_unmap_page(dev, dma_address, size, direction);
++ else
++ gnttab_dma_unmap_page(dma_address);
+}
+EXPORT_SYMBOL(dma_unmap_page);
+#endif /* CONFIG_HIGHMEM */
@@ -9828,7 +10443,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+ if (swiotlb) {
+ dma = swiotlb_map_single(dev, ptr, size, direction);
+ } else {
-+ dma = virt_to_bus(ptr);
++ dma = gnttab_dma_map_page(virt_to_page(ptr)) +
++ offset_in_page(ptr);
+ IOMMU_BUG_ON(range_straddles_page_boundary(__pa(ptr), size));
+ IOMMU_BUG_ON(address_needs_mapping(dev, dma));
+ }
@@ -9846,6 +10462,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+ BUG();
+ if (swiotlb)
+ swiotlb_unmap_single(dev, dma_addr, size, direction);
++ else
++ gnttab_dma_unmap_page(dma_addr);
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
@@ -9866,10 +10484,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/pci-dma-xen.c tmp-linux-2.6-xe
+ swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
+}
+EXPORT_SYMBOL(dma_sync_single_for_device);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/process-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/process-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/process-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/process-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,853 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/process-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/process-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/process-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/process-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,856 @@
+/*
+ * linux/arch/i386/kernel/process.c
+ *
@@ -10010,7 +10628,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/process-xen.c tmp-linux-2.6-xe
+ local_irq_disable();
+ cpu_clear(smp_processor_id(), cpu_initialized);
+ preempt_enable_no_resched();
-+ HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
++ VOID(HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL));
+ cpu_bringup();
+}
+#else
@@ -10181,7 +10799,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/process-xen.c tmp-linux-2.6-xe
+ struct thread_struct *t = &tsk->thread;
+ struct physdev_set_iobitmap set_iobitmap;
+ memset(&set_iobitmap, 0, sizeof(set_iobitmap));
-+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
++ WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
++ &set_iobitmap));
+ kfree(t->io_bitmap_ptr);
+ t->io_bitmap_ptr = NULL;
+ clear_thread_flag(TIF_IO_BITMAP);
@@ -10488,7 +11107,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/process-xen.c tmp-linux-2.6-xe
+ mcl++;
+ }
+
-+ (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
++ BUG_ON(mcl > _mcl + ARRAY_SIZE(_mcl));
++ if (unlikely(HYPERVISOR_multicall_check(_mcl, mcl - _mcl, NULL)))
++ BUG();
+
+ /*
+ * Restore %fs and %gs if needed.
@@ -10723,9 +11344,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/process-xen.c tmp-linux-2.6-xe
+ sp -= get_random_int() % 8192;
+ return sp & ~0xf;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/quirks-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/quirks-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/quirks-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/quirks-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/quirks-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/quirks-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/quirks-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/quirks-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,47 @@
+/*
+ * This file contains work-arounds for x86 and x86_64 platform bugs.
@@ -10763,7 +11384,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/quirks-xen.c tmp-linux-2.6-xen
+ printk(KERN_INFO "Disabling irq balancing and affinity\n");
+ op.cmd = XENPF_platform_quirk;
+ op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING;
-+ (void)HYPERVISOR_platform_op(&op);
++ WARN_ON(HYPERVISOR_platform_op(&op));
+ }
+
+ /* put back the original value for config space*/
@@ -10774,9 +11395,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/quirks-xen.c tmp-linux-2.6-xen
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance);
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/relocate_kernel.S tmp-linux-2.6-xen.patch/arch/i386/kernel/relocate_kernel.S
---- pristine-linux-2.6.18/arch/i386/kernel/relocate_kernel.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/relocate_kernel.S 2007-11-16 16:18:11.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/relocate_kernel.S linux-2.6.18-xen-3.2.0/arch/i386/kernel/relocate_kernel.S
+--- linux-2.6.18.8/arch/i386/kernel/relocate_kernel.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/relocate_kernel.S 2008-02-15 16:21:49.000000000 -0800
@@ -7,16 +7,138 @@
*/
@@ -11009,10 +11630,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/relocate_kernel.S tmp-linux-2.
+idt_48:
+ .word 0 /* limit */
+ .long 0 /* base */
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/setup-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/setup-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,1898 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/setup-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/setup-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/setup-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/setup-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,1919 @@
+/*
+ * linux/arch/i386/kernel/setup.c
+ *
@@ -11081,6 +11702,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+#include <xen/interface/physdev.h>
+#include <xen/interface/memory.h>
+#include <xen/features.h>
++#include <xen/firmware.h>
+#include <xen/xencons.h>
+#include <setup_arch.h>
+#include <bios_ebda.h>
@@ -11170,6 +11792,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+};
+struct edid_info edid_info;
+EXPORT_SYMBOL_GPL(edid_info);
++#ifndef CONFIG_XEN
++#define copy_edid() (edid_info = EDID_INFO)
++#endif
+struct ist_info ist_info;
+#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
+ defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
@@ -11755,6 +12380,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+#ifdef CONFIG_EDD_MODULE
+EXPORT_SYMBOL(edd);
+#endif
++#ifndef CONFIG_XEN
+/**
+ * copy_edd() - Copy the BIOS EDD information
+ * from boot_params into a safe place.
@@ -11767,6 +12393,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ edd.mbr_signature_nr = EDD_MBR_SIG_NR;
+ edd.edd_info_nr = EDD_NR;
+}
++#endif
+#else
+static inline void copy_edd(void)
+{
@@ -12037,6 +12664,35 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ return 0;
+}
+
++/*
++ * This function checks if any part of the range <start,end> is mapped
++ * with type.
++ */
++int
++e820_any_mapped(u64 start, u64 end, unsigned type)
++{
++ int i;
++
++#ifndef CONFIG_XEN
++ for (i = 0; i < e820.nr_map; i++) {
++ const struct e820entry *ei = &e820.map[i];
++#else
++ if (!is_initial_xendomain())
++ return 0;
++ for (i = 0; i < machine_e820.nr_map; ++i) {
++ const struct e820entry *ei = &machine_e820.map[i];
++#endif
++
++ if (type && ei->type != type)
++ continue;
++ if (ei->addr >= end || ei->addr + ei->size <= start)
++ continue;
++ return 1;
++ }
++ return 0;
++}
++EXPORT_SYMBOL_GPL(e820_any_mapped);
++
+ /*
+ * This function checks if the entire range <start,end> is mapped with type.
+ *
@@ -12285,14 +12941,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned int max_dma, low;
+
-+ /*
-+ * XEN: Our notion of "DMA memory" is fake when running over Xen.
-+ * We simply put all RAM in the DMA zone so that those drivers which
-+ * needlessly specify GFP_DMA do not get starved of RAM unnecessarily.
-+ * Those drivers that *do* require lowmem are screwed anyway when
-+ * running over Xen!
-+ */
-+ max_dma = max_low_pfn;
++ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = max_low_pfn;
+
+ if (low < max_dma)
@@ -12608,9 +13257,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ /* Register a call for panic conditions. */
+ atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
+
-+ HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
-+ HYPERVISOR_vm_assist(VMASST_CMD_enable,
-+ VMASST_TYPE_writable_pagetables);
++ WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
++ VMASST_TYPE_4gb_segments));
++ WARN_ON(HYPERVISOR_vm_assist(VMASST_CMD_enable,
++ VMASST_TYPE_writable_pagetables));
+
+ memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
+ early_cpu_init();
@@ -12636,7 +13286,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ ROOT_DEV = MKDEV(UNNAMED_MAJOR,0);
+ drive_info = DRIVE_INFO;
+ screen_info = SCREEN_INFO;
-+ edid_info = EDID_INFO;
++ copy_edid();
+ apm_info.bios = APM_BIOS_INFO;
+ ist_info = IST_INFO;
+ saved_videomode = VIDEO_MODE;
@@ -12649,23 +13299,12 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ bootloader_type = LOADER_TYPE;
+
+ if (is_initial_xendomain()) {
-+ /* This is drawn from a dump from vgacon:startup in
-+ * standard Linux. */
-+ screen_info.orig_video_mode = 3;
-+ screen_info.orig_video_isVGA = 1;
-+ screen_info.orig_video_lines = 25;
-+ screen_info.orig_video_cols = 80;
-+ screen_info.orig_video_ega_bx = 3;
-+ screen_info.orig_video_points = 16;
-+ screen_info.orig_y = screen_info.orig_video_lines - 1;
-+ if (xen_start_info->console.dom0.info_size >=
-+ sizeof(struct dom0_vga_console_info)) {
-+ const struct dom0_vga_console_info *info =
-+ (struct dom0_vga_console_info *)(
-+ (char *)xen_start_info +
-+ xen_start_info->console.dom0.info_off);
-+ dom0_init_screen_info(info);
-+ }
++ const struct dom0_vga_console_info *info =
++ (void *)((char *)xen_start_info +
++ xen_start_info->console.dom0.info_off);
++
++ dom0_init_screen_info(info,
++ xen_start_info->console.dom0.info_size);
+ xen_start_info->console.domU.mfn = 0;
+ xen_start_info->console.domU.evtchn = 0;
+ } else
@@ -12806,6 +13445,11 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ virt_to_mfn(pfn_to_mfn_frame_list_list);
+ }
+
++ /* Mark all ISA DMA channels in-use - using them wouldn't work. */
++ for (i = 0; i < MAX_DMA_CHANNELS; ++i)
++ if (i != 4 && request_dma(i, "xen") != 0)
++ BUG();
++
+ /*
+ * NOTE: at this point the bootmem allocator is fully available.
+ */
@@ -12820,7 +13464,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ efi_map_memmap();
+
+ set_iopl.iopl = 1;
-+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
++ WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl));
+
+#ifdef CONFIG_ACPI
+ if (!is_initial_xendomain()) {
@@ -12872,8 +13516,6 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+#endif
+ }
+ tsc_init();
-+
-+ xencons_early_setup();
+}
+
+static int
@@ -12911,10 +13553,42 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/setup-xen.c tmp-linux-2.6-xen.
+ * c-basic-offset:8
+ * End:
+ */
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/smp-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/smp-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,624 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/setup.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/setup.c
+--- linux-2.6.18.8/arch/i386/kernel/setup.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/setup.c 2008-02-15 16:21:49.000000000 -0800
+@@ -956,6 +956,28 @@ efi_memory_present_wrapper(unsigned long
+ return 0;
+ }
+
++/*
++ * This function checks if any part of the range <start,end> is mapped
++ * with type.
++ */
++int
++e820_any_mapped(u64 start, u64 end, unsigned type)
++{
++ int i;
++
++ for (i = 0; i < e820.nr_map; i++) {
++ const struct e820entry *ei = &e820.map[i];
++
++ if (type && ei->type != type)
++ continue;
++ if (ei->addr >= end || ei->addr + ei->size <= start)
++ continue;
++ return 1;
++ }
++ return 0;
++}
++EXPORT_SYMBOL_GPL(e820_any_mapped);
++
+ /*
+ * This function checks if the entire range <start,end> is mapped with type.
+ *
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/smp-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/smp-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/smp-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/smp-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,605 @@
+/*
+ * Intel SMP support routines.
+ *
@@ -13358,21 +14032,6 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c tmp-linux-2.6-xen.pa
+ on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
+}
+
-+#else
-+
-+irqreturn_t smp_invalidate_interrupt(int irq, void *dev_id,
-+ struct pt_regs *regs)
-+{ return 0; }
-+void flush_tlb_current_task(void)
-+{ xen_tlb_flush_mask(&current->mm->cpu_vm_mask); }
-+void flush_tlb_mm(struct mm_struct * mm)
-+{ xen_tlb_flush_mask(&mm->cpu_vm_mask); }
-+void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
-+{ xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
-+EXPORT_SYMBOL(flush_tlb_page);
-+void flush_tlb_all(void)
-+{ xen_tlb_flush_all(); }
-+
+#endif /* XEN */
+
+/*
@@ -13457,11 +14116,11 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c tmp-linux-2.6-xen.pa
+
+ /* Wait for response */
+ while (atomic_read(&data.started) != cpus)
-+ barrier();
++ cpu_relax();
+
+ if (wait)
+ while (atomic_read(&data.finished) != cpus)
-+ barrier();
++ cpu_relax();
+ spin_unlock(&call_lock);
+
+ return 0;
@@ -13475,9 +14134,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c tmp-linux-2.6-xen.pa
+ */
+ cpu_clear(smp_processor_id(), cpu_online_map);
+ local_irq_disable();
-+#if 0
-+ disable_local_APIC();
-+#endif
++ disable_all_local_evtchn();
+ if (cpu_data[smp_processor_id()].hlt_works_ok)
+ for(;;) halt();
+ for (;;);
@@ -13492,9 +14149,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c tmp-linux-2.6-xen.pa
+ smp_call_function(stop_this_cpu, NULL, 1, 0);
+
+ local_irq_disable();
-+#if 0
-+ disable_local_APIC();
-+#endif
++ disable_all_local_evtchn();
+ local_irq_enable();
+}
+
@@ -13539,747 +14194,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/smp-xen.c tmp-linux-2.6-xen.pa
+ return IRQ_HANDLED;
+}
+
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/swiotlb.c tmp-linux-2.6-xen.patch/arch/i386/kernel/swiotlb.c
---- pristine-linux-2.6.18/arch/i386/kernel/swiotlb.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/swiotlb.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,734 @@
-+/*
-+ * Dynamic DMA mapping support.
-+ *
-+ * This implementation is a fallback for platforms that do not support
-+ * I/O TLBs (aka DMA address translation hardware).
-+ * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
-+ * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
-+ * Copyright (C) 2000, 2003 Hewlett-Packard Co
-+ * David Mosberger-Tang <davidm@hpl.hp.com>
-+ * Copyright (C) 2005 Keir Fraser <keir@xensource.com>
-+ */
-+
-+#include <linux/cache.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ctype.h>
-+#include <linux/init.h>
-+#include <linux/bootmem.h>
-+#include <linux/highmem.h>
-+#include <asm/io.h>
-+#include <asm/pci.h>
-+#include <asm/dma.h>
-+#include <asm/uaccess.h>
-+#include <xen/interface/memory.h>
-+
-+int swiotlb;
-+EXPORT_SYMBOL(swiotlb);
-+
-+#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
-+
-+#define SG_ENT_PHYS_ADDRESS(sg) (page_to_bus((sg)->page) + (sg)->offset)
-+
-+/*
-+ * Maximum allowable number of contiguous slabs to map,
-+ * must be a power of 2. What is the appropriate value ?
-+ * The complexity of {map,unmap}_single is linearly dependent on this value.
-+ */
-+#define IO_TLB_SEGSIZE 128
-+
-+/*
-+ * log of the size of each IO TLB slab. The number of slabs is command line
-+ * controllable.
-+ */
-+#define IO_TLB_SHIFT 11
-+
-+int swiotlb_force;
-+
-+static char *iotlb_virt_start;
-+static unsigned long iotlb_nslabs;
-+
-+/*
-+ * Used to do a quick range check in swiotlb_unmap_single and
-+ * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
-+ * API.
-+ */
-+static unsigned long iotlb_pfn_start, iotlb_pfn_end;
-+
-+/* Does the given dma address reside within the swiotlb aperture? */
-+static inline int in_swiotlb_aperture(dma_addr_t dev_addr)
-+{
-+ unsigned long pfn = mfn_to_local_pfn(dev_addr >> PAGE_SHIFT);
-+ return (pfn_valid(pfn)
-+ && (pfn >= iotlb_pfn_start)
-+ && (pfn < iotlb_pfn_end));
-+}
-+
-+/*
-+ * When the IOMMU overflows we return a fallback buffer. This sets the size.
-+ */
-+static unsigned long io_tlb_overflow = 32*1024;
-+
-+void *io_tlb_overflow_buffer;
-+
-+/*
-+ * This is a free list describing the number of free entries available from
-+ * each index
-+ */
-+static unsigned int *io_tlb_list;
-+static unsigned int io_tlb_index;
-+
-+/*
-+ * We need to save away the original address corresponding to a mapped entry
-+ * for the sync operations.
-+ */
-+static struct phys_addr {
-+ struct page *page;
-+ unsigned int offset;
-+} *io_tlb_orig_addr;
-+
-+/*
-+ * Protect the above data structures in the map and unmap calls
-+ */
-+static DEFINE_SPINLOCK(io_tlb_lock);
-+
-+static unsigned int dma_bits;
-+static unsigned int __initdata max_dma_bits = 32;
-+static int __init
-+setup_dma_bits(char *str)
-+{
-+ max_dma_bits = simple_strtoul(str, NULL, 0);
-+ return 0;
-+}
-+__setup("dma_bits=", setup_dma_bits);
-+
-+static int __init
-+setup_io_tlb_npages(char *str)
-+{
-+ /* Unlike ia64, the size is aperture in megabytes, not 'slabs'! */
-+ if (isdigit(*str)) {
-+ iotlb_nslabs = simple_strtoul(str, &str, 0) <<
-+ (20 - IO_TLB_SHIFT);
-+ iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
-+ /* Round up to power of two (xen_create_contiguous_region). */
-+ while (iotlb_nslabs & (iotlb_nslabs-1))
-+ iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
-+ }
-+ if (*str == ',')
-+ ++str;
-+ /*
-+ * NB. 'force' enables the swiotlb, but doesn't force its use for
-+ * every DMA like it does on native Linux. 'off' forcibly disables
-+ * use of the swiotlb.
-+ */
-+ if (!strcmp(str, "force"))
-+ swiotlb_force = 1;
-+ else if (!strcmp(str, "off"))
-+ swiotlb_force = -1;
-+ return 1;
-+}
-+__setup("swiotlb=", setup_io_tlb_npages);
-+/* make io_tlb_overflow tunable too? */
-+
-+/*
-+ * Statically reserve bounce buffer space and initialize bounce buffer data
-+ * structures for the software IO TLB used to implement the PCI DMA API.
-+ */
-+void
-+swiotlb_init_with_default_size (size_t default_size)
-+{
-+ unsigned long i, bytes;
-+ int rc;
-+
-+ if (!iotlb_nslabs) {
-+ iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
-+ iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
-+ /* Round up to power of two (xen_create_contiguous_region). */
-+ while (iotlb_nslabs & (iotlb_nslabs-1))
-+ iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
-+ }
-+
-+ bytes = iotlb_nslabs * (1UL << IO_TLB_SHIFT);
-+
-+ /*
-+ * Get IO TLB memory from the low pages
-+ */
-+ iotlb_virt_start = alloc_bootmem_low_pages(bytes);
-+ if (!iotlb_virt_start)
-+ panic("Cannot allocate SWIOTLB buffer!\n");
-+
-+ dma_bits = get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT) + PAGE_SHIFT;
-+ for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
-+ do {
-+ rc = xen_create_contiguous_region(
-+ (unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
-+ get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
-+ dma_bits);
-+ } while (rc && dma_bits++ < max_dma_bits);
-+ if (rc) {
-+ if (i == 0)
-+ panic("No suitable physical memory available for SWIOTLB buffer!\n"
-+ "Use dom0_mem Xen boot parameter to reserve\n"
-+ "some DMA memory (e.g., dom0_mem=-128M).\n");
-+ iotlb_nslabs = i;
-+ i <<= IO_TLB_SHIFT;
-+ free_bootmem(__pa(iotlb_virt_start + i), bytes - i);
-+ bytes = i;
-+ for (dma_bits = 0; i > 0; i -= IO_TLB_SEGSIZE << IO_TLB_SHIFT) {
-+ unsigned int bits = fls64(virt_to_bus(iotlb_virt_start + i - 1));
-+
-+ if (bits > dma_bits)
-+ dma_bits = bits;
-+ }
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * Allocate and initialize the free list array. This array is used
-+ * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE.
-+ */
-+ io_tlb_list = alloc_bootmem(iotlb_nslabs * sizeof(int));
-+ for (i = 0; i < iotlb_nslabs; i++)
-+ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
-+ io_tlb_index = 0;
-+ io_tlb_orig_addr = alloc_bootmem(
-+ iotlb_nslabs * sizeof(*io_tlb_orig_addr));
-+
-+ /*
-+ * Get the overflow emergency buffer
-+ */
-+ io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
-+ if (!io_tlb_overflow_buffer)
-+ panic("Cannot allocate SWIOTLB overflow buffer!\n");
-+
-+ do {
-+ rc = xen_create_contiguous_region(
-+ (unsigned long)io_tlb_overflow_buffer,
-+ get_order(io_tlb_overflow),
-+ dma_bits);
-+ } while (rc && dma_bits++ < max_dma_bits);
-+ if (rc)
-+ panic("No suitable physical memory available for SWIOTLB overflow buffer!\n");
-+
-+ iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
-+ iotlb_pfn_end = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
-+
-+ printk(KERN_INFO "Software IO TLB enabled: \n"
-+ " Aperture: %lu megabytes\n"
-+ " Kernel range: %p - %p\n"
-+ " Address size: %u bits\n",
-+ bytes >> 20,
-+ iotlb_virt_start, iotlb_virt_start + bytes,
-+ dma_bits);
-+}
-+
-+void
-+swiotlb_init(void)
-+{
-+ long ram_end;
-+ size_t defsz = 64 * (1 << 20); /* 64MB default size */
-+
-+ if (swiotlb_force == 1) {
-+ swiotlb = 1;
-+ } else if ((swiotlb_force != -1) &&
-+ is_running_on_xen() &&
-+ is_initial_xendomain()) {
-+ /* Domain 0 always has a swiotlb. */
-+ ram_end = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
-+ if (ram_end <= 0x7ffff)
-+ defsz = 2 * (1 << 20); /* 2MB on <2GB on systems. */
-+ swiotlb = 1;
-+ }
-+
-+ if (swiotlb)
-+ swiotlb_init_with_default_size(defsz);
-+ else
-+ printk(KERN_INFO "Software IO TLB disabled\n");
-+}
-+
-+/*
-+ * We use __copy_to_user_inatomic to transfer to the host buffer because the
-+ * buffer may be mapped read-only (e.g, in blkback driver) but lower-level
-+ * drivers map the buffer for DMA_BIDIRECTIONAL access. This causes an
-+ * unnecessary copy from the aperture to the host buffer, and a page fault.
-+ */
-+static void
-+__sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir)
-+{
-+ if (PageHighMem(buffer.page)) {
-+ size_t len, bytes;
-+ char *dev, *host, *kmp;
-+ len = size;
-+ while (len != 0) {
-+ unsigned long flags;
-+
-+ if (((bytes = len) + buffer.offset) > PAGE_SIZE)
-+ bytes = PAGE_SIZE - buffer.offset;
-+ local_irq_save(flags); /* protects KM_BOUNCE_READ */
-+ kmp = kmap_atomic(buffer.page, KM_BOUNCE_READ);
-+ dev = dma_addr + size - len;
-+ host = kmp + buffer.offset;
-+ if (dir == DMA_FROM_DEVICE) {
-+ if (__copy_to_user_inatomic(host, dev, bytes))
-+ /* inaccessible */;
-+ } else
-+ memcpy(dev, host, bytes);
-+ kunmap_atomic(kmp, KM_BOUNCE_READ);
-+ local_irq_restore(flags);
-+ len -= bytes;
-+ buffer.page++;
-+ buffer.offset = 0;
-+ }
-+ } else {
-+ char *host = (char *)phys_to_virt(
-+ page_to_pseudophys(buffer.page)) + buffer.offset;
-+ if (dir == DMA_FROM_DEVICE) {
-+ if (__copy_to_user_inatomic(host, dma_addr, size))
-+ /* inaccessible */;
-+ } else if (dir == DMA_TO_DEVICE)
-+ memcpy(dma_addr, host, size);
-+ }
-+}
-+
-+/*
-+ * Allocates bounce buffer and returns its kernel virtual address.
-+ */
-+static void *
-+map_single(struct device *hwdev, struct phys_addr buffer, size_t size, int dir)
-+{
-+ unsigned long flags;
-+ char *dma_addr;
-+ unsigned int nslots, stride, index, wrap;
-+ struct phys_addr slot_buf;
-+ int i;
-+
-+ /*
-+ * For mappings greater than a page, we limit the stride (and
-+ * hence alignment) to a page size.
-+ */
-+ nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-+ if (size > PAGE_SIZE)
-+ stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
-+ else
-+ stride = 1;
-+
-+ BUG_ON(!nslots);
-+
-+ /*
-+ * Find suitable number of IO TLB entries size that will fit this
-+ * request and allocate a buffer from that IO TLB pool.
-+ */
-+ spin_lock_irqsave(&io_tlb_lock, flags);
-+ {
-+ wrap = index = ALIGN(io_tlb_index, stride);
-+
-+ if (index >= iotlb_nslabs)
-+ wrap = index = 0;
-+
-+ do {
-+ /*
-+ * If we find a slot that indicates we have 'nslots'
-+ * number of contiguous buffers, we allocate the
-+ * buffers from that slot and mark the entries as '0'
-+ * indicating unavailable.
-+ */
-+ if (io_tlb_list[index] >= nslots) {
-+ int count = 0;
-+
-+ for (i = index; i < (int)(index + nslots); i++)
-+ io_tlb_list[i] = 0;
-+ for (i = index - 1;
-+ (OFFSET(i, IO_TLB_SEGSIZE) !=
-+ IO_TLB_SEGSIZE -1) && io_tlb_list[i];
-+ i--)
-+ io_tlb_list[i] = ++count;
-+ dma_addr = iotlb_virt_start +
-+ (index << IO_TLB_SHIFT);
-+
-+ /*
-+ * Update the indices to avoid searching in
-+ * the next round.
-+ */
-+ io_tlb_index =
-+ ((index + nslots) < iotlb_nslabs
-+ ? (index + nslots) : 0);
-+
-+ goto found;
-+ }
-+ index += stride;
-+ if (index >= iotlb_nslabs)
-+ index = 0;
-+ } while (index != wrap);
-+
-+ spin_unlock_irqrestore(&io_tlb_lock, flags);
-+ return NULL;
-+ }
-+ found:
-+ spin_unlock_irqrestore(&io_tlb_lock, flags);
-+
-+ /*
-+ * Save away the mapping from the original address to the DMA address.
-+ * This is needed when we sync the memory. Then we sync the buffer if
-+ * needed.
-+ */
-+ slot_buf = buffer;
-+ for (i = 0; i < nslots; i++) {
-+ slot_buf.page += slot_buf.offset >> PAGE_SHIFT;
-+ slot_buf.offset &= PAGE_SIZE - 1;
-+ io_tlb_orig_addr[index+i] = slot_buf;
-+ slot_buf.offset += 1 << IO_TLB_SHIFT;
-+ }
-+ if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL))
-+ __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE);
-+
-+ return dma_addr;
-+}
-+
-+static struct phys_addr dma_addr_to_phys_addr(char *dma_addr)
-+{
-+ int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
-+ struct phys_addr buffer = io_tlb_orig_addr[index];
-+ buffer.offset += (long)dma_addr & ((1 << IO_TLB_SHIFT) - 1);
-+ buffer.page += buffer.offset >> PAGE_SHIFT;
-+ buffer.offset &= PAGE_SIZE - 1;
-+ return buffer;
-+}
-+
-+/*
-+ * dma_addr is the kernel virtual address of the bounce buffer to unmap.
-+ */
-+static void
-+unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
-+{
-+ unsigned long flags;
-+ int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-+ int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
-+ struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
-+
-+ /*
-+ * First, sync the memory before unmapping the entry
-+ */
-+ if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))
-+ __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE);
-+
-+ /*
-+ * Return the buffer to the free list by setting the corresponding
-+ * entries to indicate the number of contigous entries available.
-+ * While returning the entries to the free list, we merge the entries
-+ * with slots below and above the pool being returned.
-+ */
-+ spin_lock_irqsave(&io_tlb_lock, flags);
-+ {
-+ count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
-+ io_tlb_list[index + nslots] : 0);
-+ /*
-+ * Step 1: return the slots to the free list, merging the
-+ * slots with superceeding slots
-+ */
-+ for (i = index + nslots - 1; i >= index; i--)
-+ io_tlb_list[i] = ++count;
-+ /*
-+ * Step 2: merge the returned slots with the preceding slots,
-+ * if available (non zero)
-+ */
-+ for (i = index - 1;
-+ (OFFSET(i, IO_TLB_SEGSIZE) !=
-+ IO_TLB_SEGSIZE -1) && io_tlb_list[i];
-+ i--)
-+ io_tlb_list[i] = ++count;
-+ }
-+ spin_unlock_irqrestore(&io_tlb_lock, flags);
-+}
-+
-+static void
-+sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
-+{
-+ struct phys_addr buffer = dma_addr_to_phys_addr(dma_addr);
-+ BUG_ON((dir != DMA_FROM_DEVICE) && (dir != DMA_TO_DEVICE));
-+ __sync_single(buffer, dma_addr, size, dir);
-+}
-+
-+static void
-+swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
-+{
-+ /*
-+ * Ran out of IOMMU space for this operation. This is very bad.
-+ * Unfortunately the drivers cannot handle this operation properly.
-+ * unless they check for pci_dma_mapping_error (most don't)
-+ * When the mapping is small enough return a static buffer to limit
-+ * the damage, or panic when the transfer is too big.
-+ */
-+ printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
-+ "device %s\n", (unsigned long)size, dev ? dev->bus_id : "?");
-+
-+ if (size > io_tlb_overflow && do_panic) {
-+ if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-+ panic("PCI-DMA: Memory would be corrupted\n");
-+ if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-+ panic("PCI-DMA: Random memory would be DMAed\n");
-+ }
-+}
-+
-+/*
-+ * Map a single buffer of the indicated size for DMA in streaming mode. The
-+ * PCI address to use is returned.
-+ *
-+ * Once the device is given the dma address, the device owns this memory until
-+ * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
-+ */
-+dma_addr_t
-+swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
-+{
-+ dma_addr_t dev_addr = virt_to_bus(ptr);
-+ void *map;
-+ struct phys_addr buffer;
-+
-+ BUG_ON(dir == DMA_NONE);
-+
-+ /*
-+ * If the pointer passed in happens to be in the device's DMA window,
-+ * we can safely return the device addr and not worry about bounce
-+ * buffering it.
-+ */
-+ if (!range_straddles_page_boundary(__pa(ptr), size) &&
-+ !address_needs_mapping(hwdev, dev_addr))
-+ return dev_addr;
-+
-+ /*
-+ * Oh well, have to allocate and map a bounce buffer.
-+ */
-+ buffer.page = virt_to_page(ptr);
-+ buffer.offset = (unsigned long)ptr & ~PAGE_MASK;
-+ map = map_single(hwdev, buffer, size, dir);
-+ if (!map) {
-+ swiotlb_full(hwdev, size, dir, 1);
-+ map = io_tlb_overflow_buffer;
-+ }
-+
-+ dev_addr = virt_to_bus(map);
-+ return dev_addr;
-+}
-+
-+/*
-+ * Unmap a single streaming mode DMA translation. The dma_addr and size must
-+ * match what was provided for in a previous swiotlb_map_single call. All
-+ * other usages are undefined.
-+ *
-+ * After this call, reads by the cpu to the buffer are guaranteed to see
-+ * whatever the device wrote there.
-+ */
-+void
-+swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
-+ int dir)
-+{
-+ BUG_ON(dir == DMA_NONE);
-+ if (in_swiotlb_aperture(dev_addr))
-+ unmap_single(hwdev, bus_to_virt(dev_addr), size, dir);
-+}
-+
-+/*
-+ * Make physical memory consistent for a single streaming mode DMA translation
-+ * after a transfer.
-+ *
-+ * If you perform a swiotlb_map_single() but wish to interrogate the buffer
-+ * using the cpu, yet do not wish to teardown the PCI dma mapping, you must
-+ * call this function before doing so. At the next point you give the PCI dma
-+ * address back to the card, you must first perform a
-+ * swiotlb_dma_sync_for_device, and then the device again owns the buffer
-+ */
-+void
-+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
-+ size_t size, int dir)
-+{
-+ BUG_ON(dir == DMA_NONE);
-+ if (in_swiotlb_aperture(dev_addr))
-+ sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
-+}
-+
-+void
-+swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
-+ size_t size, int dir)
-+{
-+ BUG_ON(dir == DMA_NONE);
-+ if (in_swiotlb_aperture(dev_addr))
-+ sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
-+}
-+
-+/*
-+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
-+ * This is the scatter-gather version of the above swiotlb_map_single
-+ * interface. Here the scatter gather list elements are each tagged with the
-+ * appropriate dma address and length. They are obtained via
-+ * sg_dma_{address,length}(SG).
-+ *
-+ * NOTE: An implementation may be able to use a smaller number of
-+ * DMA address/length pairs than there are SG table elements.
-+ * (for example via virtual mapping capabilities)
-+ * The routine returns the number of addr/length pairs actually
-+ * used, at most nents.
-+ *
-+ * Device ownership issues as mentioned above for swiotlb_map_single are the
-+ * same here.
-+ */
-+int
-+swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
-+ int dir)
-+{
-+ struct phys_addr buffer;
-+ dma_addr_t dev_addr;
-+ char *map;
-+ int i;
-+
-+ BUG_ON(dir == DMA_NONE);
-+
-+ for (i = 0; i < nelems; i++, sg++) {
-+ dev_addr = SG_ENT_PHYS_ADDRESS(sg);
-+ if (range_straddles_page_boundary(page_to_pseudophys(sg->page)
-+ + sg->offset, sg->length)
-+ || address_needs_mapping(hwdev, dev_addr)) {
-+ buffer.page = sg->page;
-+ buffer.offset = sg->offset;
-+ map = map_single(hwdev, buffer, sg->length, dir);
-+ if (!map) {
-+ /* Don't panic here, we expect map_sg users
-+ to do proper error handling. */
-+ swiotlb_full(hwdev, sg->length, dir, 0);
-+ swiotlb_unmap_sg(hwdev, sg - i, i, dir);
-+ sg[0].dma_length = 0;
-+ return 0;
-+ }
-+ sg->dma_address = (dma_addr_t)virt_to_bus(map);
-+ } else
-+ sg->dma_address = dev_addr;
-+ sg->dma_length = sg->length;
-+ }
-+ return nelems;
-+}
-+
-+/*
-+ * Unmap a set of streaming mode DMA translations. Again, cpu read rules
-+ * concerning calls here are the same as for swiotlb_unmap_single() above.
-+ */
-+void
-+swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
-+ int dir)
-+{
-+ int i;
-+
-+ BUG_ON(dir == DMA_NONE);
-+
-+ for (i = 0; i < nelems; i++, sg++)
-+ if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-+ unmap_single(hwdev,
-+ (void *)bus_to_virt(sg->dma_address),
-+ sg->dma_length, dir);
-+}
-+
-+/*
-+ * Make physical memory consistent for a set of streaming mode DMA translations
-+ * after a transfer.
-+ *
-+ * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
-+ * and usage.
-+ */
-+void
-+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
-+ int nelems, int dir)
-+{
-+ int i;
-+
-+ BUG_ON(dir == DMA_NONE);
-+
-+ for (i = 0; i < nelems; i++, sg++)
-+ if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-+ sync_single(hwdev,
-+ (void *)bus_to_virt(sg->dma_address),
-+ sg->dma_length, dir);
-+}
-+
-+void
-+swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
-+ int nelems, int dir)
-+{
-+ int i;
-+
-+ BUG_ON(dir == DMA_NONE);
-+
-+ for (i = 0; i < nelems; i++, sg++)
-+ if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-+ sync_single(hwdev,
-+ (void *)bus_to_virt(sg->dma_address),
-+ sg->dma_length, dir);
-+}
-+
-+#ifdef CONFIG_HIGHMEM
-+
-+dma_addr_t
-+swiotlb_map_page(struct device *hwdev, struct page *page,
-+ unsigned long offset, size_t size,
-+ enum dma_data_direction direction)
-+{
-+ struct phys_addr buffer;
-+ dma_addr_t dev_addr;
-+ char *map;
-+
-+ dev_addr = page_to_bus(page) + offset;
-+ if (address_needs_mapping(hwdev, dev_addr)) {
-+ buffer.page = page;
-+ buffer.offset = offset;
-+ map = map_single(hwdev, buffer, size, direction);
-+ if (!map) {
-+ swiotlb_full(hwdev, size, direction, 1);
-+ map = io_tlb_overflow_buffer;
-+ }
-+ dev_addr = (dma_addr_t)virt_to_bus(map);
-+ }
-+
-+ return dev_addr;
-+}
-+
-+void
-+swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
-+ size_t size, enum dma_data_direction direction)
-+{
-+ BUG_ON(direction == DMA_NONE);
-+ if (in_swiotlb_aperture(dma_address))
-+ unmap_single(hwdev, bus_to_virt(dma_address), size, direction);
-+}
-+
-+#endif
-+
-+int
-+swiotlb_dma_mapping_error(dma_addr_t dma_addr)
-+{
-+ return (dma_addr == virt_to_bus(io_tlb_overflow_buffer));
-+}
-+
-+/*
-+ * Return whether the given PCI device DMA address mask can be supported
-+ * properly. For example, if your device can only drive the low 24-bits
-+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
-+ * this function.
-+ */
-+int
-+swiotlb_dma_supported (struct device *hwdev, u64 mask)
-+{
-+ return (mask >= ((1UL << dma_bits) - 1));
-+}
-+
-+EXPORT_SYMBOL(swiotlb_init);
-+EXPORT_SYMBOL(swiotlb_map_single);
-+EXPORT_SYMBOL(swiotlb_unmap_single);
-+EXPORT_SYMBOL(swiotlb_map_sg);
-+EXPORT_SYMBOL(swiotlb_unmap_sg);
-+EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
-+EXPORT_SYMBOL(swiotlb_sync_single_for_device);
-+EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
-+EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
-+EXPORT_SYMBOL(swiotlb_dma_mapping_error);
-+EXPORT_SYMBOL(swiotlb_dma_supported);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/sysenter.c tmp-linux-2.6-xen.patch/arch/i386/kernel/sysenter.c
---- pristine-linux-2.6.18/arch/i386/kernel/sysenter.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/sysenter.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/sysenter.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/sysenter.c
+--- linux-2.6.18.8/arch/i386/kernel/sysenter.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/sysenter.c 2008-02-15 16:21:49.000000000 -0800
@@ -23,6 +23,10 @@
#include <asm/pgtable.h>
#include <asm/unistd.h>
@@ -14295,41 +14212,52 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/sysenter.c tmp-linux-2.6-xen.p
void enable_sep_cpu(void)
{
-+#ifndef CONFIG_X86_NO_TSS
++#ifndef CONFIG_XEN
int cpu = get_cpu();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
-@@ -58,6 +63,7 @@ void enable_sep_cpu(void)
+@@ -57,7 +62,36 @@ void enable_sep_cpu(void)
+ wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
- put_cpu();
+- put_cpu();
++#else
++ extern asmlinkage void sysenter_entry_pv(void);
++ static struct callback_register sysenter = {
++ .type = CALLBACKTYPE_sysenter,
++ .address = { __KERNEL_CS, (unsigned long)sysenter_entry_pv },
++ };
++
++ if (!boot_cpu_has(X86_FEATURE_SEP))
++ return;
++
++ get_cpu();
++
++ if (xen_feature(XENFEAT_supervisor_mode_kernel))
++ sysenter.address.eip = (unsigned long)sysenter_entry;
++
++ 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
++ put_cpu();
}
/*
-@@ -72,6 +78,18 @@ int __init sysenter_setup(void)
- {
- syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
-
-+#ifdef CONFIG_XEN
-+ if (boot_cpu_has(X86_FEATURE_SEP)) {
-+ static struct callback_register __initdata sysenter = {
-+ .type = CALLBACKTYPE_sysenter,
-+ .address = { __KERNEL_CS, (unsigned long)sysenter_entry },
-+ };
-+
-+ if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0)
-+ clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
-+ }
-+#endif
-+
- #ifdef CONFIG_COMPAT_VDSO
- __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
- printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/time-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/time-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/time-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,1159 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/time-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/time-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/time-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/time-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,1194 @@
+/*
+ * linux/arch/i386/kernel/time.c
+ *
@@ -14382,6 +14310,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+#include <linux/percpu.h>
+#include <linux/kernel_stat.h>
+#include <linux/posix-timers.h>
++#include <linux/cpufreq.h>
+
+#include <asm/io.h>
+#include <asm/smp.h>
@@ -14633,7 +14562,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ * Reads a consistent set of time-base values from Xen, into a shadow data
+ * area.
+ */
-+static void get_time_values_from_xen(int cpu)
++static void get_time_values_from_xen(unsigned int cpu)
+{
+ struct vcpu_time_info *src;
+ struct shadow_time_info *dst;
@@ -14654,7 +14583,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
+}
+
-+static inline int time_values_up_to_date(int cpu)
++static inline int time_values_up_to_date(unsigned int cpu)
+{
+ struct vcpu_time_info *src;
+ struct shadow_time_info *dst;
@@ -14805,7 +14734,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ op.u.settime.secs = sec;
+ op.u.settime.nsecs = nsec;
+ op.u.settime.system_time = shadow->system_timestamp;
-+ HYPERVISOR_platform_op(&op);
++ WARN_ON(HYPERVISOR_platform_op(&op));
+ update_wallclock();
+ } else if (independent_wallclock) {
+ nsec -= shadow->system_timestamp;
@@ -14850,7 +14779,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ op.u.settime.secs = sec;
+ op.u.settime.nsecs = nsec;
+ op.u.settime.system_time = processed_system_time;
-+ HYPERVISOR_platform_op(&op);
++ WARN_ON(HYPERVISOR_platform_op(&op));
+
+ update_wallclock();
+
@@ -14886,7 +14815,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ */
+unsigned long long monotonic_clock(void)
+{
-+ int cpu = get_cpu();
++ unsigned int cpu = get_cpu();
+ struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
+ u64 time;
+ u32 local_time_version;
@@ -14952,7 +14881,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+{
+ s64 delta, delta_cpu, stolen, blocked;
+ u64 sched_time;
-+ int i, cpu = smp_processor_id();
++ unsigned int i, cpu = smp_processor_id();
+ struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
+ struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
+
@@ -14993,7 +14922,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ if ((unlikely(delta < -(s64)permitted_clock_jitter) ||
+ unlikely(delta_cpu < -(s64)permitted_clock_jitter))
+ && printk_ratelimit()) {
-+ printk("Timer ISR/%d: Time went backwards: "
++ printk("Timer ISR/%u: Time went backwards: "
+ "delta=%lld delta_cpu=%lld shadow=%lld "
+ "off=%lld processed=%lld cpu_processed=%lld\n",
+ cpu, delta, delta_cpu, shadow->system_timestamp,
@@ -15076,7 +15005,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ return IRQ_HANDLED;
+}
+
-+static void init_missing_ticks_accounting(int cpu)
++static void init_missing_ticks_accounting(unsigned int cpu)
+{
+ struct vcpu_register_runstate_memory_area area;
+ struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
@@ -15164,44 +15093,15 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ mod_timer(&sync_xen_wallclock_timer, jiffies + 1);
+}
+
-+static long clock_cmos_diff, sleep_start;
-+
-+static int timer_suspend(struct sys_device *dev, pm_message_t state)
-+{
-+ /*
-+ * Estimate time zone so that set_time can update the clock
-+ */
-+ clock_cmos_diff = -get_cmos_time();
-+ clock_cmos_diff += get_seconds();
-+ sleep_start = get_cmos_time();
-+ return 0;
-+}
-+
+static int timer_resume(struct sys_device *dev)
+{
-+ unsigned long flags;
-+ unsigned long sec;
-+ unsigned long sleep_length;
-+
-+#ifdef CONFIG_HPET_TIMER
-+ if (is_hpet_enabled())
-+ hpet_reenable();
-+#endif
-+ sec = get_cmos_time() + clock_cmos_diff;
-+ sleep_length = (get_cmos_time() - sleep_start) * HZ;
-+ write_seqlock_irqsave(&xtime_lock, flags);
-+ xtime.tv_sec = sec;
-+ xtime.tv_nsec = 0;
-+ jiffies_64 += sleep_length;
-+ wall_jiffies += sleep_length;
-+ write_sequnlock_irqrestore(&xtime_lock, flags);
-+ touch_softlockup_watchdog();
++ extern void time_resume(void);
++ time_resume();
+ return 0;
+}
+
+static struct sysdev_class timer_sysclass = {
+ .resume = timer_resume,
-+ .suspend = timer_suspend,
+ set_kset_name("timer"),
+};
+
@@ -15274,8 +15174,16 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ }
+#endif
+
-+ HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0,
-+ &xen_set_periodic_tick);
++ switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0,
++ &xen_set_periodic_tick)) {
++ case 0:
++#if CONFIG_XEN_COMPAT <= 0x030004
++ case -ENOSYS:
++#endif
++ break;
++ default:
++ BUG();
++ }
+
+ get_time_values_from_xen(0);
+
@@ -15386,7 +15294,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+void halt(void)
+{
+ if (irqs_disabled())
-+ HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
++ VOID(HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL));
+}
+EXPORT_SYMBOL(halt);
+
@@ -15398,8 +15306,16 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ init_cpu_khz();
+
+ for_each_online_cpu(cpu) {
-+ HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
-+ &xen_set_periodic_tick);
++ switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
++ &xen_set_periodic_tick)) {
++ case 0:
++#if CONFIG_XEN_COMPAT <= 0x030004
++ case -ENOSYS:
++#endif
++ break;
++ default:
++ BUG();
++ }
+ get_time_values_from_xen(cpu);
+ per_cpu(processed_system_time, cpu) =
+ per_cpu(shadow_time, 0).system_timestamp;
@@ -15414,14 +15330,22 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+#ifdef CONFIG_SMP
+static char timer_name[NR_CPUS][15];
+
-+int local_setup_timer(unsigned int cpu)
++int __cpuinit local_setup_timer(unsigned int cpu)
+{
+ int seq, irq;
+
+ BUG_ON(cpu == 0);
+
-+ HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
-+ &xen_set_periodic_tick);
++ switch (HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
++ &xen_set_periodic_tick)) {
++ case 0:
++#if CONFIG_XEN_COMPAT <= 0x030004
++ case -ENOSYS:
++#endif
++ break;
++ default:
++ BUG();
++ }
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
@@ -15431,7 +15355,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ init_missing_ticks_accounting(cpu);
+ } while (read_seqretry(&xtime_lock, seq));
+
-+ sprintf(timer_name[cpu], "timer%d", cpu);
++ sprintf(timer_name[cpu], "timer%u", cpu);
+ irq = bind_virq_to_irqhandler(VIRQ_TIMER,
+ cpu,
+ timer_interrupt,
@@ -15445,13 +15369,52 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ return 0;
+}
+
-+void local_teardown_timer(unsigned int cpu)
++void __cpuexit local_teardown_timer(unsigned int cpu)
+{
+ BUG_ON(cpu == 0);
+ unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
+}
+#endif
+
++#ifdef CONFIG_CPU_FREQ
++static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
++ void *data)
++{
++ struct cpufreq_freqs *freq = data;
++ struct xen_platform_op op;
++
++ if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
++ return 0;
++
++ if (val == CPUFREQ_PRECHANGE)
++ return 0;
++
++ op.cmd = XENPF_change_freq;
++ op.u.change_freq.flags = 0;
++ op.u.change_freq.cpu = freq->cpu;
++ op.u.change_freq.freq = (u64)freq->new * 1000;
++ WARN_ON(HYPERVISOR_platform_op(&op));
++
++ return 0;
++}
++
++static struct notifier_block time_cpufreq_notifier_block = {
++ .notifier_call = time_cpufreq_notifier
++};
++
++static int __init cpufreq_time_setup(void)
++{
++ if (!cpufreq_register_notifier(&time_cpufreq_notifier_block,
++ CPUFREQ_TRANSITION_NOTIFIER)) {
++ printk(KERN_ERR "failed to set up cpufreq notifier\n");
++ return -ENODEV;
++ }
++ return 0;
++}
++
++core_initcall(cpufreq_time_setup);
++#endif
++
+/*
+ * /proc/sys/xen: This really belongs in another file. It can stay here for
+ * now however.
@@ -15489,10 +15452,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/time-xen.c tmp-linux-2.6-xen.p
+ return 0;
+}
+__initcall(xen_sysctl_init);
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/traps-xen.c tmp-linux-2.6-xen.patch/arch/i386/kernel/traps-xen.c
---- pristine-linux-2.6.18/arch/i386/kernel/traps-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/traps-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,1186 @@
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/traps-xen.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/traps-xen.c
+--- linux-2.6.18.8/arch/i386/kernel/traps-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/traps-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,1190 @@
+/*
+ * linux/arch/i386/traps.c
+ *
@@ -16616,7 +16579,11 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/traps-xen.c tmp-linux-2.6-xen.
+
+void __init trap_init(void)
+{
-+ HYPERVISOR_set_trap_table(trap_table);
++ int ret;
++
++ ret = HYPERVISOR_set_trap_table(trap_table);
++ if (ret)
++ printk("HYPERVISOR_set_trap_table failed: error %d\n", ret);
+
+ if (cpu_has_fxsr) {
+ /*
@@ -16648,7 +16615,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/traps-xen.c tmp-linux-2.6-xen.
+
+void smp_trap_init(trap_info_t *trap_ctxt)
+{
-+ trap_info_t *t = trap_table;
++ const trap_info_t *t = trap_table;
+
+ for (t = trap_table; t->address; t++) {
+ trap_ctxt[t->vector].flags = t->flags;
@@ -16679,9 +16646,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/traps-xen.c tmp-linux-2.6-xen.
+}
+__setup("call_trace=", call_trace_setup);
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/traps.c tmp-linux-2.6-xen.patch/arch/i386/kernel/traps.c
---- pristine-linux-2.6.18/arch/i386/kernel/traps.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/traps.c 2007-11-16 16:18:12.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/traps.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/traps.c
+--- linux-2.6.18.8/arch/i386/kernel/traps.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/traps.c 2008-02-15 16:21:49.000000000 -0800
@@ -642,18 +642,11 @@ static void mem_parity_error(unsigned ch
static void io_check_error(unsigned char reason, struct pt_regs * regs)
@@ -16702,9 +16669,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/traps.c tmp-linux-2.6-xen.patc
}
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/vm86.c tmp-linux-2.6-xen.patch/arch/i386/kernel/vm86.c
---- pristine-linux-2.6.18/arch/i386/kernel/vm86.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/vm86.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/vm86.c linux-2.6.18-xen-3.2.0/arch/i386/kernel/vm86.c
+--- linux-2.6.18.8/arch/i386/kernel/vm86.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/vm86.c 2008-02-15 16:21:49.000000000 -0800
@@ -97,7 +97,9 @@
struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs));
struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
@@ -16759,9 +16726,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/vm86.c tmp-linux-2.6-xen.patch
tsk->thread.screen_bitmap = info->screen_bitmap;
if (info->flags & VM86_SCREEN_BITMAP)
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/vmlinux.lds.S tmp-linux-2.6-xen.patch/arch/i386/kernel/vmlinux.lds.S
---- pristine-linux-2.6.18/arch/i386/kernel/vmlinux.lds.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/vmlinux.lds.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/vmlinux.lds.S linux-2.6.18-xen-3.2.0/arch/i386/kernel/vmlinux.lds.S
+--- linux-2.6.18.8/arch/i386/kernel/vmlinux.lds.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/vmlinux.lds.S 2008-02-15 16:21:49.000000000 -0800
@@ -13,6 +13,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386"
OUTPUT_ARCH(i386)
ENTRY(phys_startup_32)
@@ -16804,9 +16771,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/vmlinux.lds.S tmp-linux-2.6-xe
+
+ NOTES
}
-diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/vsyscall-note-xen.S tmp-linux-2.6-xen.patch/arch/i386/kernel/vsyscall-note-xen.S
---- pristine-linux-2.6.18/arch/i386/kernel/vsyscall-note-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/kernel/vsyscall-note-xen.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/kernel/vsyscall-note-xen.S linux-2.6.18-xen-3.2.0/arch/i386/kernel/vsyscall-note-xen.S
+--- linux-2.6.18.8/arch/i386/kernel/vsyscall-note-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/kernel/vsyscall-note-xen.S 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,32 @@
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
@@ -16840,18 +16807,51 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/kernel/vsyscall-note-xen.S tmp-linux-
+NOTE_KERNELCAP_BEGIN(1, 1)
+NOTE_KERNELCAP(0, "nosegneg")
+NOTE_KERNELCAP_END
-diff -Nurp pristine-linux-2.6.18/arch/i386/mach-xen/Makefile tmp-linux-2.6-xen.patch/arch/i386/mach-xen/Makefile
---- pristine-linux-2.6.18/arch/i386/mach-xen/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mach-xen/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/lib/Makefile linux-2.6.18-xen-3.2.0/arch/i386/lib/Makefile
+--- linux-2.6.18.8/arch/i386/lib/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/lib/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -7,3 +7,4 @@ lib-y = checksum.o delay.o usercopy.o ge
+ bitops.o
+
+ lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
++lib-$(CONFIG_XEN_SCRUB_PAGES) += scrub.o
+diff -rpuN linux-2.6.18.8/arch/i386/lib/scrub.c linux-2.6.18-xen-3.2.0/arch/i386/lib/scrub.c
+--- linux-2.6.18.8/arch/i386/lib/scrub.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/lib/scrub.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,21 @@
++#include <asm/cpufeature.h>
++#include <asm/page.h>
++#include <asm/processor.h>
++
++void scrub_pages(void *v, unsigned int count)
++{
++ if (likely(cpu_has_xmm2)) {
++ unsigned long n = count * (PAGE_SIZE / sizeof(long) / 4);
++
++ for (; n--; v += sizeof(long) * 4)
++ asm("movnti %1,(%0)\n\t"
++ "movnti %1,%c2(%0)\n\t"
++ "movnti %1,2*%c2(%0)\n\t"
++ "movnti %1,3*%c2(%0)\n\t"
++ : : "r" (v), "r" (0L), "i" (sizeof(long))
++ : "memory");
++ asm volatile("sfence" : : : "memory");
++ } else
++ for (; count--; v += PAGE_SIZE)
++ clear_page(v);
++}
+diff -rpuN linux-2.6.18.8/arch/i386/mach-xen/Makefile linux-2.6.18-xen-3.2.0/arch/i386/mach-xen/Makefile
+--- linux-2.6.18.8/arch/i386/mach-xen/Makefile 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mach-xen/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,5 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := setup.o
-diff -Nurp pristine-linux-2.6.18/arch/i386/mach-xen/setup.c tmp-linux-2.6-xen.patch/arch/i386/mach-xen/setup.c
---- pristine-linux-2.6.18/arch/i386/mach-xen/setup.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mach-xen/setup.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/mach-xen/setup.c linux-2.6.18-xen-3.2.0/arch/i386/mach-xen/setup.c
+--- linux-2.6.18.8/arch/i386/mach-xen/setup.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mach-xen/setup.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,147 @@
+/*
+ * Machine specific setup for generic
@@ -17000,25 +17000,18 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mach-xen/setup.c tmp-linux-2.6-xen.pa
+ while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
+ machine_to_phys_order++;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/Makefile tmp-linux-2.6-xen.patch/arch/i386/mm/Makefile
---- pristine-linux-2.6.18/arch/i386/mm/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -8,3 +8,11 @@ obj-$(CONFIG_NUMA) += discontig.o
+diff -rpuN linux-2.6.18.8/arch/i386/mm/Makefile linux-2.6.18-xen-3.2.0/arch/i386/mm/Makefile
+--- linux-2.6.18.8/arch/i386/mm/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -8,3 +8,4 @@ obj-$(CONFIG_NUMA) += discontig.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y += hypervisor.o
-+
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patch/arch/i386/mm/fault-xen.c
---- pristine-linux-2.6.18/arch/i386/mm/fault-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/fault-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,782 @@
++obj-$(CONFIG_XEN) += hypervisor.o
+diff -rpuN linux-2.6.18.8/arch/i386/mm/fault-xen.c linux-2.6.18-xen-3.2.0/arch/i386/mm/fault-xen.c
+--- linux-2.6.18.8/arch/i386/mm/fault-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/fault-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,779 @@
+/*
+ * linux/arch/i386/mm/fault.c
+ *
@@ -17282,7 +17275,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patc
+ 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] & 1) {
++ 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);
@@ -17295,7 +17288,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patc
+ if (mfn_to_pfn(mfn) >= highstart_pfn)
+ return;
+#endif
-+ if (p[0] & 1) {
++ if (p[0] & _PAGE_PRESENT) {
+ page = mfn_to_pfn(mfn) << PAGE_SHIFT;
+ p = (unsigned long *) __va(page);
+ address &= 0x001fffff;
@@ -17367,7 +17360,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patc
+ if ((error_code & 0x02) && !pte_write(*pte))
+ return 0;
+#ifdef CONFIG_X86_PAE
-+ if ((error_code & 0x10) && (pte_val(*pte) & _PAGE_NX))
++ if ((error_code & 0x10) && (__pte_val(*pte) & _PAGE_NX))
+ return 0;
+#endif
+
@@ -17403,11 +17396,11 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patc
+ if (!pmd_present(*pmd_k))
+ return NULL;
+ if (!pmd_present(*pmd))
-+#ifndef CONFIG_XEN
++#if CONFIG_XEN_COMPAT > 0x030002
+ set_pmd(pmd, *pmd_k);
+#else
+ /*
-+ * When running on Xen we must launder *pmd_k through
++ * 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)));
@@ -17777,10 +17770,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patc
+ struct page *page;
+
+ spin_lock_irqsave(&pgd_lock, flags);
-+ /*
-+ * XEN: vmalloc_sync_one() failure path logic assumes
-+ * pgd_list is non-empty.
-+ */
++ /* XEN: failure path assumes non-empty pgd_list. */
+ if (unlikely(!pgd_list)) {
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ return;
@@ -17801,9 +17791,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/fault-xen.c tmp-linux-2.6-xen.patc
+ }
+}
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/highmem-xen.c tmp-linux-2.6-xen.patch/arch/i386/mm/highmem-xen.c
---- pristine-linux-2.6.18/arch/i386/mm/highmem-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/highmem-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/mm/highmem-xen.c linux-2.6.18-xen-3.2.0/arch/i386/mm/highmem-xen.c
+--- linux-2.6.18.8/arch/i386/mm/highmem-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/highmem-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,136 @@
+#include <linux/highmem.h>
+#include <linux/module.h>
@@ -17941,10 +17931,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/highmem-xen.c tmp-linux-2.6-xen.pa
+EXPORT_SYMBOL(kmap_atomic_pte);
+EXPORT_SYMBOL(kunmap_atomic);
+EXPORT_SYMBOL(kmap_atomic_to_page);
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.patch/arch/i386/mm/hypervisor.c
---- pristine-linux-2.6.18/arch/i386/mm/hypervisor.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/hypervisor.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,543 @@
+diff -rpuN linux-2.6.18.8/arch/i386/mm/hypervisor.c linux-2.6.18-xen-3.2.0/arch/i386/mm/hypervisor.c
+--- linux-2.6.18.8/arch/i386/mm/hypervisor.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/hypervisor.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,602 @@
+/******************************************************************************
+ * mm/hypervisor.c
+ *
@@ -17994,10 +17984,16 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+void xen_l1_entry_update(pte_t *ptr, pte_t val)
+{
+ mmu_update_t u;
++#ifdef CONFIG_HIGHPTE
++ u.ptr = ((unsigned long)ptr >= (unsigned long)high_memory) ?
++ arbitrary_virt_to_machine(ptr) : virt_to_machine(ptr);
++#else
+ u.ptr = virt_to_machine(ptr);
++#endif
+ u.val = __pte_val(val);
+ BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
+}
++EXPORT_SYMBOL_GPL(xen_l1_entry_update);
+
+void xen_l2_entry_update(pmd_t *ptr, pmd_t val)
+{
@@ -18122,12 +18118,12 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
+}
+
-+void xen_set_ldt(unsigned long ptr, unsigned long len)
++void xen_set_ldt(const void *ptr, unsigned int ents)
+{
+ struct mmuext_op op;
+ op.cmd = MMUEXT_SET_LDT;
-+ op.arg1.linear_addr = ptr;
-+ op.arg2.nr_ents = len;
++ op.arg1.linear_addr = (unsigned long)ptr;
++ op.arg2.nr_ents = ents;
+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
+}
+
@@ -18190,9 +18186,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ unsigned long vstart, unsigned int order, unsigned int address_bits)
+{
+ unsigned long *in_frames = discontig_frames, out_frame;
-+ unsigned long frame, i, flags;
-+ long rc;
-+ int success;
++ unsigned long frame, flags;
++ unsigned int i;
++ int rc, success;
+ struct xen_memory_exchange exchange = {
+ .in = {
+ .nr_extents = 1UL << order,
@@ -18221,12 +18217,12 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ set_xen_guest_handle(exchange.in.extent_start, in_frames);
+ set_xen_guest_handle(exchange.out.extent_start, &out_frame);
+
-+ scrub_pages(vstart, 1 << order);
++ scrub_pages((void *)vstart, 1 << order);
+
+ balloon_lock(flags);
+
+ /* 1. Zap current PTEs, remembering MFNs. */
-+ for (i = 0; i < (1UL<<order); i++) {
++ for (i = 0; i < (1U<<order); i++) {
+ in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
+ MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
+ __pte_ma(0), 0);
@@ -18252,7 +18248,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ &exchange.out) == 1);
+ if (!success) {
+ /* Couldn't get special memory: fall back to normal. */
-+ for (i = 0; i < (1UL<<order); i++)
++ for (i = 0; i < (1U<<order); i++)
+ in_frames[i] = (__pa(vstart)>>PAGE_SHIFT) + i;
+ if (HYPERVISOR_memory_op(XENMEM_populate_physmap,
+ &exchange.in) != (1UL<<order))
@@ -18262,7 +18258,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+#endif
+
+ /* 3. Map the new extent in place of old pages. */
-+ for (i = 0; i < (1UL<<order); i++) {
++ for (i = 0; i < (1U<<order); i++) {
+ frame = success ? (out_frame + i) : in_frames[i];
+ MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
+ pfn_pte_ma(frame, PAGE_KERNEL), 0);
@@ -18288,9 +18284,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
+{
+ unsigned long *out_frames = discontig_frames, in_frame;
-+ unsigned long frame, i, flags;
-+ long rc;
-+ int success;
++ unsigned long frame, flags;
++ unsigned int i;
++ int rc, success;
+ struct xen_memory_exchange exchange = {
+ .in = {
+ .nr_extents = 1,
@@ -18314,7 +18310,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ set_xen_guest_handle(exchange.in.extent_start, &in_frame);
+ set_xen_guest_handle(exchange.out.extent_start, out_frames);
+
-+ scrub_pages(vstart, 1 << order);
++ scrub_pages((void *)vstart, 1 << order);
+
+ balloon_lock(flags);
+
@@ -18324,7 +18320,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ in_frame = pfn_to_mfn(__pa(vstart) >> PAGE_SHIFT);
+
+ /* 2. Zap current PTEs. */
-+ for (i = 0; i < (1UL<<order); i++) {
++ for (i = 0; i < (1U<<order); i++) {
+ MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
+ __pte_ma(0), 0);
+ set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
@@ -18353,7 +18349,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+#endif
+
+ /* 4. Map new pages in place of old pages. */
-+ for (i = 0; i < (1UL<<order); i++) {
++ for (i = 0; i < (1U<<order); i++) {
+ frame = success ? out_frames[i] : (in_frame + i);
+ MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
+ pfn_pte_ma(frame, PAGE_KERNEL), 0);
@@ -18375,18 +18371,17 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+{
+ unsigned long flags, frame;
+ unsigned long *in_frames = discontig_frames, *out_frames = limited_frames;
-+ void *v;
+ struct page *page;
-+ int i, nr_mcl, rc, success;
++ unsigned int i, n, nr_mcl;
++ int rc, success;
++ DECLARE_BITMAP(limit_map, 1 << MAX_CONTIG_ORDER);
+
+ struct xen_memory_exchange exchange = {
+ .in = {
-+ .nr_extents = 1UL << order,
+ .extent_order = 0,
+ .domid = DOMID_SELF
+ },
+ .out = {
-+ .nr_extents = 1UL << order,
+ .extent_order = 0,
+ .address_bits = address_bits,
+ .domid = DOMID_SELF
@@ -18399,79 +18394,98 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ if (unlikely(order > MAX_CONTIG_ORDER))
+ return -ENOMEM;
+
++ bitmap_zero(limit_map, 1U << order);
+ set_xen_guest_handle(exchange.in.extent_start, in_frames);
+ set_xen_guest_handle(exchange.out.extent_start, out_frames);
+
+ /* 0. Scrub the pages. */
-+ for ( i = 0 ; i < 1UL<<order ; i++ ) {
++ for (i = 0, n = 0; i < 1U<<order ; i++) {
+ page = &pages[i];
++ if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - PAGE_SHIFT)))
++ continue;
++ __set_bit(i, limit_map);
+
-+ if (!PageHighMem(page)) {
-+ v = page_address(page);
-+ scrub_pages(v, 1);
-+ } else {
-+ v = kmap(page);
-+ scrub_pages(v, 1);
++ if (!PageHighMem(page))
++ scrub_pages(page_address(page), 1);
++#ifdef CONFIG_XEN_SCRUB_PAGES
++ else {
++ scrub_pages(kmap(page), 1);
+ kunmap(page);
++ ++n;
+ }
++#endif
+ }
++ if (bitmap_empty(limit_map, 1U << order))
++ return 0;
+
-+ kmap_flush_unused();
++ if (n)
++ kmap_flush_unused();
+
+ balloon_lock(flags);
+
+ /* 1. Zap current PTEs (if any), remembering MFNs. */
-+ for (i = 0, nr_mcl = 0; i < (1UL<<order); i++) {
++ for (i = 0, n = 0, nr_mcl = 0; i < (1U<<order); i++) {
++ if(!test_bit(i, limit_map))
++ continue;
+ page = &pages[i];
+
-+ out_frames[i] = page_to_pfn(page);
-+ in_frames[i] = pfn_to_mfn(out_frames[i]);
++ out_frames[n] = page_to_pfn(page);
++ in_frames[n] = pfn_to_mfn(out_frames[n]);
+
+ if (!PageHighMem(page))
+ MULTI_update_va_mapping(cr_mcl + nr_mcl++,
+ (unsigned long)page_address(page),
+ __pte_ma(0), 0);
+
-+ set_phys_to_machine(out_frames[i], INVALID_P2M_ENTRY);
++ set_phys_to_machine(out_frames[n], INVALID_P2M_ENTRY);
++ ++n;
+ }
-+ if (HYPERVISOR_multicall_check(cr_mcl, nr_mcl, NULL))
++ if (nr_mcl && HYPERVISOR_multicall_check(cr_mcl, nr_mcl, NULL))
+ BUG();
+
+ /* 2. Get new memory below the required limit. */
++ exchange.in.nr_extents = n;
++ exchange.out.nr_extents = n;
+ rc = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
-+ success = (exchange.nr_exchanged == (1UL << order));
++ success = (exchange.nr_exchanged == n);
+ BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
+ BUG_ON(success && (rc != 0));
+#if CONFIG_XEN_COMPAT <= 0x030002
+ if (unlikely(rc == -ENOSYS)) {
+ /* Compatibility when XENMEM_exchange is unsupported. */
+ if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+ &exchange.in) != (1UL << order))
++ &exchange.in) != n)
+ BUG();
-+ success = (HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+ &exchange.out) != (1UL <<order));
++ if (HYPERVISOR_memory_op(XENMEM_populate_physmap,
++ &exchange.out) != n)
++ BUG();
++ success = 1;
+ }
+#endif
+
+ /* 3. Map the new pages in place of old pages. */
-+ for (i = 0, nr_mcl = 0; i < (1UL<<order); i++) {
++ for (i = 0, n = 0, nr_mcl = 0; i < (1U<<order); i++) {
++ if(!test_bit(i, limit_map))
++ continue;
+ page = &pages[i];
-+ unsigned long pfn = page_to_pfn(page);
+
-+ frame = success ? out_frames[i] : in_frames[i];
++ frame = success ? out_frames[n] : in_frames[n];
+
+ if (!PageHighMem(page))
+ MULTI_update_va_mapping(cr_mcl + nr_mcl++,
+ (unsigned long)page_address(page),
+ pfn_pte_ma(frame, PAGE_KERNEL), 0);
+
-+ set_phys_to_machine(pfn, frame);
++ set_phys_to_machine(page_to_pfn(page), frame);
++ ++n;
++ }
++ if (nr_mcl) {
++ cr_mcl[nr_mcl - 1].args[MULTI_UVMFLAGS_INDEX] = order
++ ? UVMF_TLB_FLUSH|UVMF_ALL
++ : UVMF_INVLPG|UVMF_ALL;
++ if (HYPERVISOR_multicall_check(cr_mcl, nr_mcl, NULL))
++ BUG();
+ }
-+ cr_mcl[nr_mcl - 1].args[MULTI_UVMFLAGS_INDEX] = order
-+ ? UVMF_TLB_FLUSH|UVMF_ALL
-+ : UVMF_INVLPG|UVMF_ALL;
-+ if (HYPERVISOR_multicall_check(cr_mcl, nr_mcl, NULL))
-+ BUG();
+
+ balloon_unlock(flags);
+
@@ -18488,9 +18502,44 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/hypervisor.c tmp-linux-2.6-xen.pat
+ mach_lp, (u64)entry_a | ((u64)entry_b<<32));
+}
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/init-xen.c tmp-linux-2.6-xen.patch/arch/i386/mm/init-xen.c
---- pristine-linux-2.6.18/arch/i386/mm/init-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/init-xen.c 2007-11-14 15:35:27.000000000 -0800
++
++#define MAX_BATCHED_FULL_PTES 32
++
++int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd,
++ unsigned long addr, unsigned long end, pgprot_t newprot)
++{
++ int rc = 0, i = 0;
++ mmu_update_t u[MAX_BATCHED_FULL_PTES];
++ pte_t *pte;
++ spinlock_t *ptl;
++
++ if (!xen_feature(XENFEAT_mmu_pt_update_preserve_ad))
++ return 0;
++
++ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
++ do {
++ if (pte_present(*pte)) {
++ u[i].ptr = (__pmd_val(*pmd) & PHYSICAL_PAGE_MASK)
++ | ((unsigned long)pte & ~PAGE_MASK)
++ | MMU_PT_UPDATE_PRESERVE_AD;
++ u[i].val = __pte_val(pte_modify(*pte, newprot));
++ if (++i == MAX_BATCHED_FULL_PTES) {
++ if ((rc = HYPERVISOR_mmu_update(
++ &u[0], i, NULL, DOMID_SELF)) != 0)
++ break;
++ i = 0;
++ }
++ }
++ } while (pte++, addr += PAGE_SIZE, addr != end);
++ if (i)
++ rc = HYPERVISOR_mmu_update( &u[0], i, NULL, DOMID_SELF);
++ pte_unmap_unlock(pte - 1, ptl);
++ BUG_ON(rc && rc != -ENOSYS);
++ return !rc;
++}
+diff -rpuN linux-2.6.18.8/arch/i386/mm/init-xen.c linux-2.6.18-xen-3.2.0/arch/i386/mm/init-xen.c
+--- linux-2.6.18.8/arch/i386/mm/init-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/init-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,850 @@
+/*
+ * linux/arch/i386/mm/init.c
@@ -19342,9 +19391,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/init-xen.c tmp-linux-2.6-xen.patch
+}
+#endif
+
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/ioremap-xen.c tmp-linux-2.6-xen.patch/arch/i386/mm/ioremap-xen.c
---- pristine-linux-2.6.18/arch/i386/mm/ioremap-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/ioremap-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/mm/ioremap-xen.c linux-2.6.18-xen-3.2.0/arch/i386/mm/ioremap-xen.c
+--- linux-2.6.18.8/arch/i386/mm/ioremap-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/ioremap-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,443 @@
+/*
+ * arch/i386/mm/ioremap.c
@@ -19789,9 +19838,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/ioremap-xen.c tmp-linux-2.6-xen.pa
+ --nrpages;
+ }
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pageattr.c tmp-linux-2.6-xen.patch/arch/i386/mm/pageattr.c
---- pristine-linux-2.6.18/arch/i386/mm/pageattr.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/pageattr.c 2007-11-16 16:18:12.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/mm/pageattr.c linux-2.6.18-xen-3.2.0/arch/i386/mm/pageattr.c
+--- linux-2.6.18.8/arch/i386/mm/pageattr.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/pageattr.c 2008-02-15 16:21:49.000000000 -0800
@@ -84,7 +84,7 @@ static void set_pmd_pte(pte_t *kpte, uns
unsigned long flags;
@@ -19801,10 +19850,10 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pageattr.c tmp-linux-2.6-xen.patch
return;
spin_lock_irqsave(&pgd_lock, flags);
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.patch/arch/i386/mm/pgtable-xen.c
---- pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/pgtable-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,727 @@
+diff -rpuN linux-2.6.18.8/arch/i386/mm/pgtable-xen.c linux-2.6.18-xen-3.2.0/arch/i386/mm/pgtable-xen.c
+--- linux-2.6.18.8/arch/i386/mm/pgtable-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/pgtable-xen.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,725 @@
+/*
+ * linux/arch/i386/mm/pgtable.c
+ */
@@ -19881,87 +19930,6 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+}
+
+/*
-+ * Associate a virtual page frame with a given physical page frame
-+ * and protection flags for that frame.
-+ */
-+static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
-+{
-+ pgd_t *pgd;
-+ pud_t *pud;
-+ pmd_t *pmd;
-+ pte_t *pte;
-+
-+ pgd = swapper_pg_dir + pgd_index(vaddr);
-+ if (pgd_none(*pgd)) {
-+ BUG();
-+ return;
-+ }
-+ pud = pud_offset(pgd, vaddr);
-+ if (pud_none(*pud)) {
-+ BUG();
-+ return;
-+ }
-+ pmd = pmd_offset(pud, vaddr);
-+ if (pmd_none(*pmd)) {
-+ BUG();
-+ return;
-+ }
-+ pte = pte_offset_kernel(pmd, vaddr);
-+ if (pgprot_val(flags))
-+ /* <pfn,flags> stored as-is, to permit clearing entries */
-+ set_pte(pte, pfn_pte(pfn, flags));
-+ else
-+ pte_clear(&init_mm, vaddr, pte);
-+
-+ /*
-+ * It's enough to flush this one mapping.
-+ * (PGE mappings get flushed as well)
-+ */
-+ __flush_tlb_one(vaddr);
-+}
-+
-+/*
-+ * Associate a virtual page frame with a given physical page frame
-+ * and protection flags for that frame.
-+ */
-+static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn,
-+ pgprot_t flags)
-+{
-+ pgd_t *pgd;
-+ pud_t *pud;
-+ pmd_t *pmd;
-+ pte_t *pte;
-+
-+ pgd = swapper_pg_dir + pgd_index(vaddr);
-+ if (pgd_none(*pgd)) {
-+ BUG();
-+ return;
-+ }
-+ pud = pud_offset(pgd, vaddr);
-+ if (pud_none(*pud)) {
-+ BUG();
-+ return;
-+ }
-+ pmd = pmd_offset(pud, vaddr);
-+ if (pmd_none(*pmd)) {
-+ BUG();
-+ return;
-+ }
-+ pte = pte_offset_kernel(pmd, vaddr);
-+ if (pgprot_val(flags))
-+ /* <pfn,flags> stored as-is, to permit clearing entries */
-+ set_pte(pte, pfn_pte_ma(pfn, flags));
-+ else
-+ pte_clear(&init_mm, vaddr, pte);
-+
-+ /*
-+ * It's enough to flush this one mapping.
-+ * (PGE mappings get flushed as well)
-+ */
-+ __flush_tlb_one(vaddr);
-+}
-+
-+/*
+ * Associate a large virtual page frame with a given physical page frame
+ * and protection flags for that frame. pfn is for the base of the page,
+ * vaddr is what the page gets mapped to - both must be properly aligned.
@@ -20011,6 +19979,7 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
+{
+ unsigned long address = __fix_to_virt(idx);
++ pte_t pte;
+
+ if (idx >= __end_of_fixed_addresses) {
+ BUG();
@@ -20018,16 +19987,16 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+ }
+ switch (idx) {
+ case FIX_WP_TEST:
-+#ifdef CONFIG_X86_F00F_BUG
-+ case FIX_F00F_IDT:
-+#endif
+ case FIX_VDSO:
-+ set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
++ pte = pfn_pte(phys >> PAGE_SHIFT, flags);
+ break;
+ default:
-+ set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags);
++ pte = pfn_pte_ma(phys >> PAGE_SHIFT, flags);
+ break;
+ }
++ if (HYPERVISOR_update_va_mapping(address, pte,
++ UVMF_INVLPG|UVMF_ALL))
++ BUG();
+ nr_fixmaps++;
+}
+
@@ -20381,10 +20350,71 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+ }
+}
+
-+static inline void pgd_walk_set_prot(struct page *page, pgprot_t flags)
++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 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);
-+ int rc;
+
+ if (PageHighMem(page)) {
+ if (pgprot_val(flags) & _PAGE_RW)
@@ -20392,12 +20422,18 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+ else
+ set_bit(PG_pinned, &page->flags);
+ } else {
-+ rc = HYPERVISOR_update_va_mapping(
-+ (unsigned long)__va(pfn << PAGE_SHIFT),
-+ pfn_pte(pfn, flags), 0);
-+ if (rc)
-+ BUG();
++ 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)
@@ -20405,37 +20441,48 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+ pgd_t *pgd = pgd_base;
+ pud_t *pud;
+ pmd_t *pmd;
-+ int g, u, m, rc;
++ int g, u, m;
++ unsigned int cpu, seq;
+
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ return;
+
-+ for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
++ 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 */
-+ pgd_walk_set_prot(virt_to_page(pud),flags);
++ 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 */
-+ pgd_walk_set_prot(virt_to_page(pmd),flags);
++ 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;
-+ pgd_walk_set_prot(pmd_page(*pmd),flags);
++ seq = pgd_walk_set_prot(pmd_page(*pmd),flags,cpu,seq);
+ }
+ }
+ }
+
-+ rc = HYPERVISOR_update_va_mapping(
-+ (unsigned long)pgd_base,
-+ pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
-+ UVMF_TLB_FLUSH);
-+ if (rc)
++ 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)
@@ -20463,18 +20510,18 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+{
+ if (xen_feature(XENFEAT_writable_page_tables))
+ return;
-+ spin_lock(&mm->page_table_lock);
++ pin_lock(mm);
+ __pgd_pin(mm->pgd);
-+ spin_unlock(&mm->page_table_lock);
++ pin_unlock(mm);
+}
+
+void mm_unpin(struct mm_struct *mm)
+{
+ if (xen_feature(XENFEAT_writable_page_tables))
+ return;
-+ spin_lock(&mm->page_table_lock);
++ pin_lock(mm);
+ __pgd_unpin(mm->pgd);
-+ spin_unlock(&mm->page_table_lock);
++ pin_unlock(mm);
+}
+
+void mm_pin_all(void)
@@ -20532,9 +20579,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable-xen.c tmp-linux-2.6-xen.pa
+ !mm->context.has_foreign_mappings)
+ mm_unpin(mm);
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable.c tmp-linux-2.6-xen.patch/arch/i386/mm/pgtable.c
---- pristine-linux-2.6.18/arch/i386/mm/pgtable.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/mm/pgtable.c 2007-11-16 16:18:13.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/mm/pgtable.c linux-2.6.18-xen-3.2.0/arch/i386/mm/pgtable.c
+--- linux-2.6.18.8/arch/i386/mm/pgtable.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/mm/pgtable.c 2008-02-15 16:21:49.000000000 -0800
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
@@ -20640,9 +20687,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/mm/pgtable.c tmp-linux-2.6-xen.patch/
/* in the non-PAE case, free_pgtables() clears user pgd entries */
kmem_cache_free(pgd_cache, pgd);
}
-diff -Nurp pristine-linux-2.6.18/arch/i386/oprofile/Makefile tmp-linux-2.6-xen.patch/arch/i386/oprofile/Makefile
---- pristine-linux-2.6.18/arch/i386/oprofile/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/oprofile/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/oprofile/Makefile linux-2.6.18-xen-3.2.0/arch/i386/oprofile/Makefile
+--- linux-2.6.18.8/arch/i386/oprofile/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/oprofile/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -6,7 +6,14 @@ DRIVER_OBJS = $(addprefix ../../../drive
oprofilefs.o oprofile_stats.o \
timer_int.o )
@@ -20658,9 +20705,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/oprofile/Makefile tmp-linux-2.6-xen.p
op_model_ppro.o op_model_p4.o
oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/oprofile/xenoprof.c tmp-linux-2.6-xen.patch/arch/i386/oprofile/xenoprof.c
---- pristine-linux-2.6.18/arch/i386/oprofile/xenoprof.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/oprofile/xenoprof.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/oprofile/xenoprof.c linux-2.6.18-xen-3.2.0/arch/i386/oprofile/xenoprof.c
+--- linux-2.6.18.8/arch/i386/oprofile/xenoprof.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/oprofile/xenoprof.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,179 @@
+/**
+ * @file xenoprof.c
@@ -20716,8 +20763,8 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/oprofile/xenoprof.c tmp-linux-2.6-xen
+ counter.kernel = (uint32_t)counter_config[i].kernel;
+ counter.user = (uint32_t)counter_config[i].user;
+ counter.unit_mask = (uint64_t)counter_config[i].unit_mask;
-+ HYPERVISOR_xenoprof_op(XENOPROF_counter,
-+ &counter);
++ WARN_ON(HYPERVISOR_xenoprof_op(XENOPROF_counter,
++ &counter));
+ }
+}
+
@@ -20841,9 +20888,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/oprofile/xenoprof.c tmp-linux-2.6-xen
+{
+ xenoprofile_exit();
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/pci/Makefile tmp-linux-2.6-xen.patch/arch/i386/pci/Makefile
---- pristine-linux-2.6.18/arch/i386/pci/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/pci/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/pci/Makefile linux-2.6.18-xen-3.2.0/arch/i386/pci/Makefile
+--- linux-2.6.18.8/arch/i386/pci/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/pci/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -4,6 +4,10 @@ obj-$(CONFIG_PCI_BIOS) += pcbios.o
obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
obj-$(CONFIG_PCI_DIRECT) += direct.o
@@ -20855,18 +20902,9 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/pci/Makefile tmp-linux-2.6-xen.patch/
pci-y := fixup.o
pci-$(CONFIG_ACPI) += acpi.o
pci-y += legacy.o irq.o
-@@ -12,3 +16,8 @@ pci-$(CONFIG_X86_VISWS) := visws.o fixu
- pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o
-
- obj-y += $(pci-y) common.o
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/i386/pci/irq-xen.c tmp-linux-2.6-xen.patch/arch/i386/pci/irq-xen.c
---- pristine-linux-2.6.18/arch/i386/pci/irq-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/pci/irq-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/pci/irq-xen.c linux-2.6.18-xen-3.2.0/arch/i386/pci/irq-xen.c
+--- linux-2.6.18.8/arch/i386/pci/irq-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/pci/irq-xen.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,1205 @@
+/*
+ * Low-Level PCI Support for PC -- Routing of Interrupts
@@ -22073,9 +22111,25 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/pci/irq-xen.c tmp-linux-2.6-xen.patch
+
+ return count;
+}
-diff -Nurp pristine-linux-2.6.18/arch/i386/pci/pcifront.c tmp-linux-2.6-xen.patch/arch/i386/pci/pcifront.c
---- pristine-linux-2.6.18/arch/i386/pci/pcifront.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/i386/pci/pcifront.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/pci/irq.c linux-2.6.18-xen-3.2.0/arch/i386/pci/irq.c
+--- linux-2.6.18.8/arch/i386/pci/irq.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/pci/irq.c 2008-02-15 16:21:49.000000000 -0800
+@@ -543,6 +543,12 @@ static __init int intel_router_probe(str
+ case PCI_DEVICE_ID_INTEL_ICH8_2:
+ case PCI_DEVICE_ID_INTEL_ICH8_3:
+ case PCI_DEVICE_ID_INTEL_ICH8_4:
++ case PCI_DEVICE_ID_INTEL_ICH9_0:
++ case PCI_DEVICE_ID_INTEL_ICH9_1:
++ case PCI_DEVICE_ID_INTEL_ICH9_2:
++ case PCI_DEVICE_ID_INTEL_ICH9_3:
++ case PCI_DEVICE_ID_INTEL_ICH9_4:
++ case PCI_DEVICE_ID_INTEL_ICH9_5:
+ r->name = "PIIX/ICH";
+ r->get = pirq_piix_get;
+ r->set = pirq_piix_set;
+diff -rpuN linux-2.6.18.8/arch/i386/pci/pcifront.c linux-2.6.18-xen-3.2.0/arch/i386/pci/pcifront.c
+--- linux-2.6.18.8/arch/i386/pci/pcifront.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/pci/pcifront.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,55 @@
+/*
+ * PCI Frontend Stub - puts some "dummy" functions in to the Linux x86 PCI core
@@ -22132,36 +22186,47 @@ diff -Nurp pristine-linux-2.6.18/arch/i386/pci/pcifront.c tmp-linux-2.6-xen.patc
+}
+
+arch_initcall(pcifront_x86_stub_init);
-diff -Nurp pristine-linux-2.6.18/arch/i386/power/Makefile tmp-linux-2.6-xen.patch/arch/i386/power/Makefile
---- pristine-linux-2.6.18/arch/i386/power/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/i386/power/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/i386/power/Makefile linux-2.6.18-xen-3.2.0/arch/i386/power/Makefile
+--- linux-2.6.18.8/arch/i386/power/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/power/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -1,2 +1,4 @@
-obj-$(CONFIG_PM) += cpu.o
-+obj-$(CONFIG_PM_LEGACY) += cpu.o
++obj-$(subst m,y,$(CONFIG_APM)) += cpu.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += cpu.o
+obj-$(CONFIG_ACPI_SLEEP) += cpu.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
-diff -Nurp pristine-linux-2.6.18/arch/ia64/Kconfig tmp-linux-2.6-xen.patch/arch/ia64/Kconfig
---- pristine-linux-2.6.18/arch/ia64/Kconfig 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/Kconfig 2007-11-14 15:35:27.000000000 -0800
-@@ -58,6 +58,34 @@ config GENERIC_IOMAP
+diff -rpuN linux-2.6.18.8/arch/i386/power/cpu.c linux-2.6.18-xen-3.2.0/arch/i386/power/cpu.c
+--- linux-2.6.18.8/arch/i386/power/cpu.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/i386/power/cpu.c 2008-02-15 16:21:49.000000000 -0800
+@@ -62,11 +62,12 @@ static void do_fpu_end(void)
+
+ static void fix_processor_context(void)
+ {
++#ifndef CONFIG_X86_NO_TSS
+ int cpu = smp_processor_id();
+ struct tss_struct * t = &per_cpu(init_tss, cpu);
+
+ set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
+-
++#endif
+ load_TR_desc(); /* This does ltr */
+ load_LDT(&current->active_mm->context); /* This does lldt */
+
+diff -rpuN linux-2.6.18.8/arch/ia64/Kconfig linux-2.6.18-xen-3.2.0/arch/ia64/Kconfig
+--- linux-2.6.18.8/arch/ia64/Kconfig 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/Kconfig 2008-02-15 16:21:49.000000000 -0800
+@@ -58,6 +58,28 @@ config GENERIC_IOMAP
bool
default y
+config XEN
+ bool "Xen hypervisor support"
+ default y
++ select XEN_XENCOMM
+ help
+ Enable Xen hypervisor support. Resulting kernel runs
+ both as a guest OS on Xen and natively on hardware.
+
-+config XEN_IA64_VDSO_PARAVIRT
-+ bool
-+ depends on XEN && !ITANIUM
-+ default y
-+ help
-+ vDSO paravirtualization
-+
+config XEN_IA64_EXPOSE_P2M
+ bool "Xen/IA64 exposure p2m table"
+ depends on XEN
@@ -22179,7 +22244,48 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/Kconfig tmp-linux-2.6-xen.patch/arch/
config SCHED_NO_NO_OMIT_FRAME_POINTER
bool
default y
-@@ -465,6 +493,21 @@ config PCI_DOMAINS
+@@ -133,6 +155,10 @@ config IA64_SGI_SN2
+ config IA64_HP_SIM
+ bool "Ski-simulator"
+
++config IA64_XEN
++ bool "Xen guest"
++ depends on XEN
++
+ endchoice
+
+ choice
+@@ -431,6 +457,29 @@ config SGI_SN
+
+ source "drivers/sn/Kconfig"
+
++config KEXEC
++ bool "kexec system call (EXPERIMENTAL)"
++ depends on EXPERIMENTAL && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
++ help
++ kexec is a system call that implements the ability to shutdown your
++ current kernel, and to start another kernel. It is like a reboot
++ but it is indepedent of the system firmware. And like a reboot
++ you can start any kernel with it, not just Linux.
++
++ The name comes from the similiarity to the exec system call.
++
++ It is an ongoing process to be certain the hardware in a machine
++ is properly shutdown, so do not be surprised if this code does not
++ initially work for you. It may help to enable device hotplugging
++ support. As of this writing the exact hardware interface is
++ strongly in flux, so no good recommendation can be made.
++
++config CRASH_DUMP
++ bool "kernel crash dumps (EXPERIMENTAL)"
++ depends on EXPERIMENTAL && IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
++ help
++ Generate crash dump after being started by kexec.
++
+ source "drivers/firmware/Kconfig"
+
+ source "fs/Kconfig.binfmt"
+@@ -465,6 +514,21 @@ config PCI_DOMAINS
bool
default PCI
@@ -22201,7 +22307,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/Kconfig tmp-linux-2.6-xen.patch/arch/
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
-@@ -528,3 +571,13 @@ source "arch/ia64/Kconfig.debug"
+@@ -528,3 +592,16 @@ source "arch/ia64/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
@@ -22212,12 +22318,15 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/Kconfig tmp-linux-2.6-xen.patch/arch/
+if XEN
+config XEN_SMPBOOT
+ default n
++
++config XEN_DEVMEM
++ default n
+endif
+
+source "drivers/xen/Kconfig"
-diff -Nurp pristine-linux-2.6.18/arch/ia64/Makefile tmp-linux-2.6-xen.patch/arch/ia64/Makefile
---- pristine-linux-2.6.18/arch/ia64/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/Makefile linux-2.6.18-xen-3.2.0/arch/ia64/Makefile
+--- linux-2.6.18.8/arch/ia64/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -45,6 +45,12 @@ ifeq ($(call cc-version),0304)
endif
@@ -22231,23 +22340,17 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/Makefile tmp-linux-2.6-xen.patch/arch
head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
libs-y += arch/ia64/lib/
-@@ -55,9 +61,15 @@ core-$(CONFIG_IA64_GENERIC) += arch/ia6
+@@ -54,7 +60,9 @@ core-$(CONFIG_IA64_DIG) += arch/ia64/di
+ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/
core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/
core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
++core-$(CONFIG_IA64_XEN) += arch/ia64/dig/
core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/
+core-$(CONFIG_XEN) += arch/ia64/xen/
drivers-$(CONFIG_PCI) += arch/ia64/pci/
-+ifneq ($(CONFIG_XEN),y)
drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
-+endif
-+ifneq ($(CONFIG_IA64_GENERIC),y)
-+drivers-$(CONFIG_XEN) += arch/ia64/hp/sim/
-+endif
- drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
- drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
- drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/
-@@ -87,8 +99,8 @@ CLEAN_FILES += vmlinux.gz bootloader
+@@ -87,8 +95,8 @@ CLEAN_FILES += vmlinux.gz bootloader
boot: lib/lib.a vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
@@ -22258,41 +22361,446 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/Makefile tmp-linux-2.6-xen.patch/arch
define archhelp
echo '* compressed - Build compressed kernel image'
-diff -Nurp pristine-linux-2.6.18/arch/ia64/dig/setup.c tmp-linux-2.6-xen.patch/arch/ia64/dig/setup.c
---- pristine-linux-2.6.18/arch/ia64/dig/setup.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/dig/setup.c 2007-11-14 15:35:27.000000000 -0800
-@@ -24,6 +24,8 @@
- #include <asm/machvec.h>
- #include <asm/system.h>
+diff -rpuN linux-2.6.18.8/arch/ia64/hp/common/sba_iommu.c linux-2.6.18-xen-3.2.0/arch/ia64/hp/common/sba_iommu.c
+--- linux-2.6.18.8/arch/ia64/hp/common/sba_iommu.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/hp/common/sba_iommu.c 2008-02-15 16:21:49.000000000 -0800
+@@ -42,6 +42,11 @@
+ #include <asm/system.h> /* wmb() */
+
+ #include <asm/acpi-ext.h>
++#include <asm/maddr.h> /* range_straddles_page_boundary() */
++#ifdef CONFIG_XEN
++#include <xen/gnttab.h>
++#include <asm/gnttab_dma.h>
++#endif
-+#include <xen/xencons.h>
-+
- void __init
- dig_setup (char **cmdline_p)
+ #define PFX "IOC: "
+
+@@ -198,6 +203,9 @@ struct ioc {
+ void __iomem *ioc_hpa; /* I/O MMU base address */
+ char *res_map; /* resource map, bit == pdir entry */
+ u64 *pdir_base; /* physical base address */
++#ifdef CONFIG_XEN
++ u64 *xen_virt_cache;
++#endif
+ unsigned long ibase; /* pdir IOV Space base */
+ unsigned long imask; /* pdir IOV Space mask */
+
+@@ -762,14 +770,21 @@ sba_free_range(struct ioc *ioc, dma_addr
+ * on the vba.
+ */
+
+-#if 1
+-#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) \
+- | 0x8000000000000000ULL)
++#ifndef CONFIG_XEN
++#define sba_io_pdir_entry(ioc, pdir_ptr, vba) *pdir_ptr = \
++ ((virt_to_bus((void *)vba) & ~0xFFFULL) | 0x8000000000000000ULL)
+ #else
+ void SBA_INLINE
+-sba_io_pdir_entry(u64 *pdir_ptr, unsigned long vba)
++sba_io_pdir_entry(struct ioc *ioc, u64 *pdir_ptr, unsigned long vba)
{
-@@ -67,4 +69,19 @@ dig_setup (char **cmdline_p)
- screen_info.orig_video_mode = 3; /* XXX fake */
- screen_info.orig_video_isVGA = 1; /* XXX fake */
- screen_info.orig_video_ega_bx = 3; /* XXX fake */
+- *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x80000000000000FFULL);
++ *pdir_ptr = ((virt_to_bus((void *)vba) & ~0xFFFULL) |
++ 0x80000000000000FFULL);
+#ifdef CONFIG_XEN
-+ if (!is_running_on_xen() || !is_initial_xendomain())
++ if (is_running_on_xen()) {
++ int pide = ((u64)pdir_ptr - (u64)ioc->pdir_base) >> 3;
++ ioc->xen_virt_cache[pide] = vba;
++ }
++#endif
+ }
+ #endif
+
+@@ -784,6 +799,12 @@ mark_clean (void *addr, size_t size)
+ {
+ unsigned long pg_addr, end;
+
++#ifdef CONFIG_XEN
++ /* XXX: Bad things happen starting domUs when this is enabled. */
++ if (is_running_on_xen())
+ return;
++#endif
+
-+ if (xen_start_info->console.dom0.info_size >=
-+ sizeof(struct dom0_vga_console_info)) {
-+ const struct dom0_vga_console_info *info =
-+ (struct dom0_vga_console_info *)(
-+ (char *)xen_start_info +
-+ xen_start_info->console.dom0.info_off);
-+ dom0_init_screen_info(info);
+ pg_addr = PAGE_ALIGN((unsigned long) addr);
+ end = (unsigned long) addr + size;
+ while (pg_addr + PAGE_SIZE <= end) {
+@@ -850,6 +871,10 @@ sba_mark_invalid(struct ioc *ioc, dma_ad
+ */
+ ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
+ #endif
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ ioc->xen_virt_cache[off] = 0UL;
++#endif
+ } else {
+ u32 t = get_iovp_order(byte_cnt) + iovp_shift;
+
+@@ -865,6 +890,10 @@ sba_mark_invalid(struct ioc *ioc, dma_ad
+ #else
+ ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
+ #endif
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ ioc->xen_virt_cache[off] = 0UL;
++#endif
+ off++;
+ byte_cnt -= iovp_size;
+ } while (byte_cnt > 0);
+@@ -894,15 +923,29 @@ sba_map_single(struct device *dev, void
+ unsigned long flags;
+ #endif
+ #ifdef ALLOW_IOV_BYPASS
+- unsigned long pci_addr = virt_to_phys(addr);
++ unsigned long pci_addr;
++#endif
++
++#ifdef CONFIG_XEN
++ if (is_running_on_xen()) {
++ void* tmp_addr = addr;
++ size_t tmp_size = size;
++ do {
++ gnttab_dma_use_page(virt_to_page(tmp_addr));
++ tmp_addr += PAGE_SIZE;
++ tmp_size -= min(tmp_size, PAGE_SIZE);
++ } while (tmp_size);
+ }
-+ xen_start_info->console.domU.mfn = 0;
-+ xen_start_info->console.domU.evtchn = 0;
+ #endif
+
+ #ifdef ALLOW_IOV_BYPASS
++ pci_addr = virt_to_bus(addr);
+ ASSERT(to_pci_dev(dev)->dma_mask);
+ /*
+ ** Check if the PCI device can DMA to ptr... if so, just return ptr
+ */
+- if (likely((pci_addr & ~to_pci_dev(dev)->dma_mask) == 0)) {
++ if (likely((pci_addr & ~to_pci_dev(dev)->dma_mask) == 0 &&
++ !range_straddles_page_boundary(__pa(addr), size))) {
+ /*
+ ** Device is bit capable of DMA'ing to the buffer...
+ ** just return the PCI address of ptr
+@@ -944,7 +987,7 @@ sba_map_single(struct device *dev, void
+
+ while (size > 0) {
+ ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
+- sba_io_pdir_entry(pdir_start, (unsigned long) addr);
++ sba_io_pdir_entry(ioc, pdir_start, (unsigned long) addr);
+
+ DBG_RUN(" pdir 0x%p %lx\n", pdir_start, *pdir_start);
+
+@@ -973,13 +1016,29 @@ sba_mark_clean(struct ioc *ioc, dma_addr
+ void *addr;
+
+ if (size <= iovp_size) {
+- addr = phys_to_virt(ioc->pdir_base[off] &
+- ~0xE000000000000FFFULL);
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ addr = (void *)ioc->xen_virt_cache[off];
++ else
++ addr = bus_to_virt(ioc->pdir_base[off] &
++ ~0xE000000000000FFFULL);
++#else
++ addr = bus_to_virt(ioc->pdir_base[off] &
++ ~0xE000000000000FFFULL);
++#endif
+ mark_clean(addr, size);
+ } else {
+ do {
+- addr = phys_to_virt(ioc->pdir_base[off] &
+- ~0xE000000000000FFFULL);
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ addr = (void *)ioc->xen_virt_cache[off];
++ else
++ addr = bus_to_virt(ioc->pdir_base[off] &
++ ~0xE000000000000FFFULL);
++#else
++ addr = bus_to_virt(ioc->pdir_base[off] &
++ ~0xE000000000000FFFULL);
++#endif
+ mark_clean(addr, min(size, iovp_size));
+ off++;
+ size -= iovp_size;
+@@ -988,6 +1047,34 @@ sba_mark_clean(struct ioc *ioc, dma_addr
+ }
+ #endif
+
++#ifdef CONFIG_XEN
++static void
++sba_gnttab_dma_unmap_page(struct ioc *ioc, dma_addr_t iova, size_t size)
++{
++ u32 iovp = (u32) SBA_IOVP(ioc,iova);
++ int off = PDIR_INDEX(iovp);
++ struct page *page;
++
++ if (size <= iovp_size) {
++ BUG_ON(!ioc->xen_virt_cache[off]);
++ page = virt_to_page(ioc->xen_virt_cache[off]);
++ __gnttab_dma_unmap_page(page);
++ } else {
++ struct page *last_page = (struct page *)~0UL;
++ do {
++ BUG_ON(!ioc->xen_virt_cache[off]);
++ page = virt_to_page(ioc->xen_virt_cache[off]);
++ if (page != last_page) {
++ __gnttab_dma_unmap_page(page);
++ last_page = page;
++ }
++ off++;
++ size -= iovp_size;
++ } while (size > 0);
++ }
++}
++#endif
++
+ /**
+ * sba_unmap_single - unmap one IOVA and free resources
+ * @dev: instance of PCI owned by the driver that's asking.
+@@ -1018,7 +1105,16 @@ void sba_unmap_single(struct device *dev
+
+ #ifdef ENABLE_MARK_CLEAN
+ if (dir == DMA_FROM_DEVICE) {
+- mark_clean(phys_to_virt(iova), size);
++ mark_clean(bus_to_virt(iova), size);
++ }
++#endif
++#ifdef CONFIG_XEN
++ if (is_running_on_xen()) {
++ do {
++ gnttab_dma_unmap_page(iova);
++ iova += PAGE_SIZE;
++ size -= min(size,PAGE_SIZE);
++ } while (size);
+ }
+ #endif
+ return;
+@@ -1037,6 +1133,10 @@ void sba_unmap_single(struct device *dev
+ if (dir == DMA_FROM_DEVICE)
+ sba_mark_clean(ioc, iova, size);
+ #endif
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ sba_gnttab_dma_unmap_page(ioc, iova, size);
++#endif
+
+ #if DELAYED_RESOURCE_CNT > 0
+ spin_lock_irqsave(&ioc->saved_lock, flags);
+@@ -1102,9 +1202,14 @@ sba_alloc_coherent (struct device *dev,
+ return NULL;
+
+ memset(addr, 0, size);
+- *dma_handle = virt_to_phys(addr);
+
+ #ifdef ALLOW_IOV_BYPASS
++#ifdef CONFIG_XEN
++ if (xen_create_contiguous_region((unsigned long)addr, get_order(size),
++ fls64(dev->coherent_dma_mask)))
++ goto iommu_map;
+#endif
++ *dma_handle = virt_to_bus(addr);
+ ASSERT(dev->coherent_dma_mask);
+ /*
+ ** Check if the PCI device can DMA to ptr... if so, just return ptr
+@@ -1115,6 +1220,9 @@ sba_alloc_coherent (struct device *dev,
+
+ return addr;
+ }
++#ifdef CONFIG_XEN
++iommu_map:
++#endif
+ #endif
+
+ /*
+@@ -1138,6 +1246,13 @@ sba_alloc_coherent (struct device *dev,
+ */
+ void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+ {
++#if defined(ALLOW_IOV_BYPASS) && defined(CONFIG_XEN)
++ struct ioc *ioc = GET_IOC(dev);
++
++ if (likely((dma_handle & ioc->imask) != ioc->ibase))
++ xen_destroy_contiguous_region((unsigned long)vaddr,
++ get_order(size));
++#endif
+ sba_unmap_single(dev, dma_handle, size, 0);
+ free_pages((unsigned long) vaddr, get_order(size));
}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/asm-offsets.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/asm-offsets.c
---- pristine-linux-2.6.18/arch/ia64/kernel/asm-offsets.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/asm-offsets.c 2007-11-14 15:35:27.000000000 -0800
+@@ -1219,7 +1334,7 @@ sba_fill_pdir(
+ dma_offset=0; /* only want offset on first chunk */
+ cnt = ROUNDUP(cnt, iovp_size);
+ do {
+- sba_io_pdir_entry(pdirp, vaddr);
++ sba_io_pdir_entry(ioc, pdirp, vaddr);
+ vaddr += iovp_size;
+ cnt -= iovp_size;
+ pdirp++;
+@@ -1406,7 +1521,11 @@ int sba_map_sg(struct device *dev, struc
+ if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) {
+ for (sg = sglist ; filled < nents ; filled++, sg++){
+ sg->dma_length = sg->length;
+- sg->dma_address = virt_to_phys(sba_sg_address(sg));
++#ifdef CONFIG_XEN
++ sg->dma_address = gnttab_dma_map_page(sg->page) + sg->offset;
++#else
++ sg->dma_address = virt_to_bus(sba_sg_address(sg));
++#endif
+ }
+ return filled;
+ }
+@@ -1430,6 +1549,15 @@ int sba_map_sg(struct device *dev, struc
+
+ prefetch(ioc->res_hint);
+
++#ifdef CONFIG_XEN
++ if (is_running_on_xen()) {
++ int i;
++
++ for (i = 0; i < nents; i++)
++ gnttab_dma_use_page(sglist[i].page);
++ }
++#endif
++
+ /*
+ ** First coalesce the chunks and allocate I/O pdir space
+ **
+@@ -1562,11 +1690,25 @@ ioc_iova_init(struct ioc *ioc)
+
+ memset(ioc->pdir_base, 0, ioc->pdir_size);
+
++#ifdef CONFIG_XEN
++ /* The page table needs to be pinned in Xen memory */
++ if (xen_create_contiguous_region((unsigned long)ioc->pdir_base,
++ get_order(ioc->pdir_size), 0))
++ panic(PFX "Couldn't contiguously map I/O Page Table\n");
++
++ ioc->xen_virt_cache = (void *) __get_free_pages(
++ GFP_KERNEL, get_order(ioc->pdir_size));
++ if (!ioc->xen_virt_cache)
++ panic(PFX "Couldn't allocate Xen virtual address cache\n");
++
++ memset(ioc->xen_virt_cache, 0, ioc->pdir_size);
++#endif
++
+ DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __FUNCTION__,
+ iovp_size >> 10, ioc->pdir_base, ioc->pdir_size);
+
+ ASSERT(ALIGN((unsigned long) ioc->pdir_base, 4*1024) == (unsigned long) ioc->pdir_base);
+- WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
++ WRITE_REG(virt_to_bus(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+ /*
+ ** If an AGP device is present, only use half of the IOV space
+@@ -1603,7 +1745,7 @@ ioc_iova_init(struct ioc *ioc)
+ for ( ; (u64) poison_addr < addr + iovp_size; poison_addr += poison_size)
+ memcpy(poison_addr, spill_poison, poison_size);
+
+- prefetch_spill_page = virt_to_phys(addr);
++ prefetch_spill_page = virt_to_bus(addr);
+
+ DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __FUNCTION__, prefetch_spill_page);
+ }
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/Makefile linux-2.6.18-xen-3.2.0/arch/ia64/kernel/Makefile
+--- linux-2.6.18.8/arch/ia64/kernel/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/Makefile 2008-02-15 16:21:49.000000000 -0800
+@@ -28,6 +28,8 @@ obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
+ obj-$(CONFIG_CPU_FREQ) += cpufreq/
+ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
+ obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
++obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
++obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+ obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
+ obj-$(CONFIG_AUDIT) += audit.o
+ mca_recovery-y += mca_drv.o mca_drv_asm.o
+@@ -61,3 +63,61 @@ $(obj)/gate-syms.o: $(obj)/gate.lds $(ob
+ # We must build gate.so before we can assemble it.
+ # Note: kbuild does not track this dependency due to usage of .incbin
+ $(obj)/gate-data.o: $(obj)/gate.so
++
++#
++# gate page paravirtualization for xen
++#
++obj-$(CONFIG_XEN) += xengate-data.o
++
++ifeq ($(CONFIG_XEN), y)
++# The gate DSO image is built using a special linker script.
++targets += xengate.so xengate-syms.o
++endif
++
++extra-$(CONFIG_XEN) += xengate.so xengate.lds xengate.o
++
++AFLAGS_xengate.o += -D__XEN_IA64_VDSO_PARAVIRT
++$(obj)/xengate.o: $(src)/gate.S FORCE
++ $(call if_changed_dep,as_o_S)
++
++CPPFLAGS_xengate.lds := -P -C -U$(ARCH) -D__XEN_IA64_VDSO_PARAVIRT
++$(obj)/xengate.lds: $(src)/gate.lds.S
++ $(call if_changed_dep,cpp_lds_S)
++
++GATECFLAGS_xengate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
++ $(call ld-option, -Wl$(comma)--hash-style=sysv)
++$(obj)/xengate.so: $(obj)/xengate.lds $(obj)/xengate.o FORCE
++ $(call if_changed,gate)
++
++ifeq ($(CONFIG_XEN), y)
++$(obj)/built-in.o: $(obj)/xengate-syms.o
++$(obj)/built-in.o: ld_flags += -R $(obj)/xengate-syms.o
++$(obj)/mca_recovery.o: $(obj)/gate-syms.o $(obj)/xengate-syms.o
++endif
++
++GATECFLAGS_xengate-syms.o = -r
++$(obj)/xengate-syms.o: $(obj)/xengate.lds $(obj)/xengate.o FORCE
++ $(call if_changed,gate)
++$(obj)/xengate-data.o: $(obj)/xengate.so
++
++#
++# .tmp_gate.o to calculate padding size for __kernel_syscall_via_epc
++#
++extra-$(CONFIG_XEN) += gate-skip.s .tmp_gate.o
++
++ifeq ($(CONFIG_XEN), y)
++AFLAGS_gate.o += -D__KERNEL_SYSCALL_VIA_EPC_PADDING
++$(obj)/gate.o: $(obj)/gate-skip.s FORCE
++endif
++
++$(obj)/.tmp_gate.o: $(src)/gate.S FORCE
++ $(call if_changed_dep,as_o_S)
++
++quiet_cmd_gate_size = GATE_SIZE $@
++ cmd_gate_size = $(NM) --extern-only --print-size $(obj)/xengate.o | \
++ $(AWK) '/__kernel_syscall_via_epc/{printf "\t.skip 0x"$$2" - "}' > $@; \
++ $(NM) --extern-only --print-size $(obj)/.tmp_gate.o | \
++ $(AWK) '/__kernel_syscall_via_epc/{printf "0x"$$2"\n"}' >> $@
++
++$(obj)/gate-skip.s: $(obj)/xengate.o $(obj)/.tmp_gate.o FORCE
++ $(call if_changed,gate_size)
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/acpi.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/acpi.c
+--- linux-2.6.18.8/arch/ia64/kernel/acpi.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/acpi.c 2008-02-15 16:21:49.000000000 -0800
+@@ -109,6 +109,10 @@ const char *acpi_get_sysname(void)
+ return "hpzx1";
+ } else if (!strcmp(hdr->oem_id, "SGI")) {
+ return "sn2";
++#ifdef CONFIG_XEN
++ } else if (is_running_on_xen() && !strcmp(hdr->oem_id, "XEN")) {
++ return "xen";
++#endif
+ }
+
+ return "dig";
+@@ -123,6 +127,8 @@ const char *acpi_get_sysname(void)
+ return "sn2";
+ # elif defined (CONFIG_IA64_DIG)
+ return "dig";
++# elif defined (CONFIG_IA64_XEN)
++ return "xen";
+ # else
+ # error Unknown platform. Fix acpi.c.
+ # endif
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/asm-offsets.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/asm-offsets.c
+--- linux-2.6.18.8/arch/ia64/kernel/asm-offsets.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/asm-offsets.c 2008-02-15 16:21:49.000000000 -0800
@@ -268,4 +268,29 @@ void foo(void)
DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64);
DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32);
@@ -22323,9 +22831,536 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/asm-offsets.c tmp-linux-2.6-xe
+ DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat);
+#endif /* CONFIG_XEN */
}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/entry.S tmp-linux-2.6-xen.patch/arch/ia64/kernel/entry.S
---- pristine-linux-2.6.18/arch/ia64/kernel/entry.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/entry.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/crash.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/crash.c
+--- linux-2.6.18.8/arch/ia64/kernel/crash.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/crash.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,222 @@
++/*
++ * arch/ia64/kernel/crash.c
++ *
++ * Architecture specific (ia64) functions for kexec based crash dumps.
++ *
++ * Created by: Khalid Aziz <khalid.aziz@hp.com>
++ * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
++ * Copyright (C) 2005 Intel Corp Zou Nan hai <nanhai.zou@intel.com>
++ *
++ */
++#include <linux/smp.h>
++#include <linux/delay.h>
++#include <linux/crash_dump.h>
++#include <linux/bootmem.h>
++#include <linux/kexec.h>
++#include <linux/elfcore.h>
++#include <linux/sysctl.h>
++#include <linux/init.h>
++
++#include <asm/kdebug.h>
++#include <asm/mca.h>
++
++int kdump_status[NR_CPUS];
++atomic_t kdump_cpu_freezed;
++atomic_t kdump_in_progress;
++int kdump_on_init = 1;
++
++static inline Elf64_Word
++*append_elf_note(Elf64_Word *buf, char *name, unsigned type, void *data,
++ size_t data_len)
++{
++ struct elf_note *note = (struct elf_note *)buf;
++ note->n_namesz = strlen(name) + 1;
++ note->n_descsz = data_len;
++ note->n_type = type;
++ buf += (sizeof(*note) + 3)/4;
++ memcpy(buf, name, note->n_namesz);
++ buf += (note->n_namesz + 3)/4;
++ memcpy(buf, data, data_len);
++ buf += (data_len + 3)/4;
++ return buf;
++}
++
++static void
++final_note(void *buf)
++{
++ memset(buf, 0, sizeof(struct elf_note));
++}
++
++extern void ia64_dump_cpu_regs(void *);
++
++static DEFINE_PER_CPU(struct elf_prstatus, elf_prstatus);
++
++void
++crash_save_this_cpu()
++{
++ void *buf;
++ unsigned long cfm, sof, sol;
++
++ int cpu = smp_processor_id();
++ struct elf_prstatus *prstatus = &per_cpu(elf_prstatus, cpu);
++
++ elf_greg_t *dst = (elf_greg_t *)&(prstatus->pr_reg);
++ memset(prstatus, 0, sizeof(*prstatus));
++ prstatus->pr_pid = current->pid;
++
++ ia64_dump_cpu_regs(dst);
++ cfm = dst[43];
++ sol = (cfm >> 7) & 0x7f;
++ sof = cfm & 0x7f;
++ dst[46] = (unsigned long)ia64_rse_skip_regs((unsigned long *)dst[46],
++ sof - sol);
++
++ buf = (u64 *) per_cpu_ptr(crash_notes, cpu);
++ if (!buf)
++ return;
++ buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus,
++ sizeof(*prstatus));
++ final_note(buf);
++}
++
++static int
++kdump_wait_cpu_freeze(void)
++{
++ int cpu_num = num_online_cpus() - 1;
++ int timeout = 1000;
++ while(timeout-- > 0) {
++ if (atomic_read(&kdump_cpu_freezed) == cpu_num)
++ return 0;
++ udelay(1000);
++ }
++ return 1;
++}
++
++void
++machine_crash_shutdown(struct pt_regs *pt)
++{
++ /* This function is only called after the system
++ * has paniced or is otherwise in a critical state.
++ * The minimum amount of code to allow a kexec'd kernel
++ * to run successfully needs to happen here.
++ *
++ * In practice this means shooting down the other cpus in
++ * an SMP system.
++ */
++ kexec_disable_iosapic();
++#ifdef CONFIG_SMP
++ kdump_smp_send_stop();
++ if (kdump_wait_cpu_freeze() && kdump_on_init) {
++ //not all cpu response to IPI, send INIT to freeze them
++ kdump_smp_send_init();
++ }
++#endif
++}
++
++static void
++machine_kdump_on_init(void)
++{
++ local_irq_disable();
++ kexec_disable_iosapic();
++ machine_kexec(ia64_kimage);
++}
++
++void
++kdump_cpu_freeze(struct unw_frame_info *info, void *arg)
++{
++ int cpuid;
++ local_irq_disable();
++ cpuid = smp_processor_id();
++ crash_save_this_cpu();
++ current->thread.ksp = (__u64)info->sw - 16;
++ atomic_inc(&kdump_cpu_freezed);
++ kdump_status[cpuid] = 1;
++ mb();
++ if (cpuid == 0) {
++ for (;;)
++ cpu_relax();
++ } else
++ ia64_jump_to_sal(&sal_boot_rendez_state[cpuid]);
++}
++
++static int
++kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
++{
++ struct die_args *args = data;
++
++ if (!kdump_on_init)
++ return NOTIFY_DONE;
++
++ if (val != DIE_INIT_MONARCH_ENTER &&
++ val != DIE_INIT_SLAVE_ENTER &&
++ val != DIE_MCA_RENDZVOUS_LEAVE &&
++ val != DIE_MCA_MONARCH_LEAVE)
++ return NOTIFY_DONE;
++
++ /* There really ought to be a check here to see if this
++ * is a machine check rendevous. The kexec code that
++ * was merged around 2.6.20-rc1 includes such a check.
++ * But the check relies on infastructure that is not
++ * available in 2.6.16. */
++
++ switch (val) {
++ case DIE_INIT_MONARCH_ENTER:
++ machine_kdump_on_init();
++ break;
++ case DIE_INIT_SLAVE_ENTER:
++ unw_init_running(kdump_cpu_freeze, NULL);
++ break;
++ case DIE_MCA_RENDZVOUS_LEAVE:
++ if (atomic_read(&kdump_in_progress))
++ unw_init_running(kdump_cpu_freeze, NULL);
++ break;
++ case DIE_MCA_MONARCH_LEAVE:
++ /* die_register->signr indicate if MCA is recoverable */
++ if (!args->signr)
++ machine_kdump_on_init();
++ break;
++ }
++ return NOTIFY_DONE;
++}
++
++#ifdef CONFIG_SYSCTL
++static ctl_table kdump_on_init_table[] = {
++ {
++ .ctl_name = CTL_UNNUMBERED,
++ .procname = "kdump_on_init",
++ .data = &kdump_on_init,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec,
++ },
++ { .ctl_name = 0 }
++};
++
++static ctl_table sys_table[] = {
++ {
++ .ctl_name = CTL_KERN,
++ .procname = "kernel",
++ .mode = 0555,
++ .child = kdump_on_init_table,
++ },
++ { .ctl_name = 0 }
++};
++#endif
++
++static int
++machine_crash_setup(void)
++{
++ static struct notifier_block kdump_init_notifier_nb = {
++ .notifier_call = kdump_init_notifier,
++ };
++ int ret;
++ if((ret = register_die_notifier(&kdump_init_notifier_nb)) != 0)
++ return ret;
++#ifdef CONFIG_SYSCTL
++ register_sysctl_table(sys_table, 0);
++#endif
++ return 0;
++}
++
++__initcall(machine_crash_setup);
++
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/crash_dump.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/crash_dump.c
+--- linux-2.6.18.8/arch/ia64/kernel/crash_dump.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/crash_dump.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,48 @@
++/*
++ * kernel/crash_dump.c - Memory preserving reboot related code.
++ *
++ * Created by: Simon Horman <horms@verge.net.au>
++ * Original code moved from kernel/crash.c
++ * Original code comment copied from the i386 version of this file
++ */
++
++#include <linux/errno.h>
++#include <linux/types.h>
++
++#include <linux/uaccess.h>
++
++/**
++ * copy_oldmem_page - copy one page from "oldmem"
++ * @pfn: page frame number to be copied
++ * @buf: target memory address for the copy; this can be in kernel address
++ * space or user address space (see @userbuf)
++ * @csize: number of bytes to copy
++ * @offset: offset in bytes into the page (based on pfn) to begin the copy
++ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
++ * otherwise @buf is in kernel address space, use memcpy().
++ *
++ * Copy a page from "oldmem". For this page, there is no pte mapped
++ * in the current kernel. We stitch up a pte, similar to kmap_atomic.
++ *
++ * Calling copy_to_user() in atomic context is not desirable. Hence first
++ * copying the data to a pre-allocated kernel page and then copying to user
++ * space in non-atomic context.
++ */
++ssize_t
++copy_oldmem_page(unsigned long pfn, char *buf,
++ size_t csize, unsigned long offset, int userbuf)
++{
++ void *vaddr;
++
++ if (!csize)
++ return 0;
++ vaddr = __va(pfn<<PAGE_SHIFT);
++ if (userbuf) {
++ if (copy_to_user(buf, (vaddr + offset), csize)) {
++ return -EFAULT;
++ }
++ } else
++ memcpy(buf, (vaddr + offset), csize);
++ return csize;
++}
++
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/efi.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/efi.c
+--- linux-2.6.18.8/arch/ia64/kernel/efi.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/efi.c 2008-02-15 16:21:49.000000000 -0800
+@@ -26,6 +26,7 @@
+ #include <linux/types.h>
+ #include <linux/time.h>
+ #include <linux/efi.h>
++#include <linux/kexec.h>
+
+ #include <asm/io.h>
+ #include <asm/kregs.h>
+@@ -34,6 +35,11 @@
+ #include <asm/processor.h>
+ #include <asm/mca.h>
+
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++#include <xen/interface/memory.h>
++#include <asm/hypercall.h>
++#endif
++
+ #define EFI_DEBUG 0
+
+ extern efi_status_t efi_call_phys (void *, ...);
+@@ -41,7 +47,7 @@ extern efi_status_t efi_call_phys (void
+ struct efi efi;
+ EXPORT_SYMBOL(efi);
+ static efi_runtime_services_t *runtime;
+-static unsigned long mem_limit = ~0UL, max_addr = ~0UL;
++static unsigned long mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
+
+ #define efi_call_virt(f, args...) (*(f))(args)
+
+@@ -421,6 +427,8 @@ efi_init (void)
+ mem_limit = memparse(cp + 4, &cp);
+ } else if (memcmp(cp, "max_addr=", 9) == 0) {
+ max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
++ } else if (memcmp(cp, "min_addr=", 9) == 0) {
++ min_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
+ } else {
+ while (*cp != ' ' && *cp)
+ ++cp;
+@@ -428,6 +436,8 @@ efi_init (void)
+ ++cp;
+ }
+ }
++ if (min_addr != 0UL)
++ printk(KERN_INFO "Ignoring memory below %luMB\n", min_addr >> 20);
+ if (max_addr != ~0UL)
+ printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20);
+
+@@ -894,7 +904,8 @@ find_memmap_space (void)
+ as = max(contig_low, md->phys_addr);
+ ae = min(contig_high, efi_md_end(md));
+
+- /* keep within max_addr= command line arg */
++ /* keep within max_addr= and min_addr= command line arg */
++ as = max(as, min_addr);
+ ae = min(ae, max_addr);
+ if (ae <= as)
+ continue;
+@@ -1004,7 +1015,8 @@ efi_memmap_init(unsigned long *s, unsign
+ } else
+ ae = efi_md_end(md);
+
+- /* keep within max_addr= command line arg */
++ /* keep within max_addr= and min_addr= command line arg */
++ as = max(as, min_addr);
+ ae = min(ae, max_addr);
+ if (ae <= as)
+ continue;
+@@ -1033,21 +1045,22 @@ efi_memmap_init(unsigned long *s, unsign
+ *e = (u64)++k;
+ }
+
+-void
+-efi_initialize_iomem_resources(struct resource *code_resource,
+- struct resource *data_resource)
++#define EFI_INITIALISE_PHYS 0x1
++#define EFI_INITIALISE_MACH 0x2
++#define EFI_INITIALISE_ALL (EFI_INITIALISE_PHYS|EFI_INITIALISE_MACH)
++
++static void
++efi_initialize_resources(void *efi_map_start, void *efi_map_end,
++ u64 efi_desc_size, struct resource *root_resource,
++ struct resource *code_resource,
++ struct resource *data_resource, unsigned flag)
+ {
+ struct resource *res;
+- void *efi_map_start, *efi_map_end, *p;
++ void *p;
+ efi_memory_desc_t *md;
+- u64 efi_desc_size;
+ char *name;
+ unsigned long flags;
+
+- efi_map_start = __va(ia64_boot_param->efi_memmap);
+- efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+- efi_desc_size = ia64_boot_param->efi_memdesc_size;
+-
+ res = NULL;
+
+ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+@@ -1106,7 +1119,7 @@ efi_initialize_iomem_resources(struct re
+ res->end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
+ res->flags = flags;
+
+- if (insert_resource(&iomem_resource, res) < 0)
++ if (insert_resource(root_resource, res) < 0)
+ kfree(res);
+ else {
+ /*
+@@ -1114,8 +1127,135 @@ efi_initialize_iomem_resources(struct re
+ * kernel data so we try it repeatedly and
+ * let the resource manager test it.
+ */
+- insert_resource(res, code_resource);
+- insert_resource(res, data_resource);
++ if (flag & EFI_INITIALISE_PHYS) {
++ insert_resource(res, code_resource);
++ insert_resource(res, data_resource);
++ }
++#ifdef CONFIG_KEXEC
++ if (flag & EFI_INITIALISE_MACH) {
++ insert_resource(res, &efi_memmap_res);
++ insert_resource(res, &boot_param_res);
++ if (crashk_res.end > crashk_res.start)
++ insert_resource(res, &crashk_res);
++#ifdef CONFIG_XEN
++ if (is_initial_xendomain())
++ xen_machine_kexec_register_resources(
++ res);
++#endif
++ }
++#endif
+ }
+ }
+ }
++
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++static int
++efi_initialize_iomem_machine_resources(void)
++{
++ unsigned long size;
++ xen_memory_map_t memmap;
++ xen_ia64_memmap_info_t *memmap_info = NULL;
++ void *efi_map_start, *efi_map_end;
++ u64 efi_desc_size;
++ int ret;
++
++ /* It would be nice if it wasn't neccessary to loop like this */
++ for (size = 1024; 1; size += 1024) {
++ memmap_info = kmalloc(size, GFP_KERNEL);
++ if (memmap_info == NULL)
++ return -ENOMEM;
++
++ memmap.nr_entries = size;
++ set_xen_guest_handle(memmap.buffer, memmap_info);
++ ret = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap);
++ if (!ret)
++ break;
++
++ kfree(memmap_info);
++ }
++
++ efi_map_start = &memmap_info->memdesc;
++ efi_map_end = efi_map_start + memmap_info->efi_memmap_size;
++ efi_desc_size = memmap_info->efi_memdesc_size;
++ efi_initialize_resources(efi_map_start, efi_map_end, efi_desc_size,
++ &iomem_machine_resource, NULL, NULL,
++ EFI_INITIALISE_MACH);
++
++ kfree(memmap_info);
++}
++#endif
++
++void
++efi_initialize_iomem_resources(struct resource *code_resource,
++ struct resource *data_resource)
++{
++ void *efi_map_start, *efi_map_end;
++ u64 efi_desc_size;
++
++ efi_map_start = __va(ia64_boot_param->efi_memmap);
++ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
++ efi_desc_size = ia64_boot_param->efi_memdesc_size;
++
++#ifdef CONFIG_PROC_IOMEM_MACHINE
++ if (is_initial_xendomain()) {
++ efi_initialize_resources(efi_map_start, efi_map_end,
++ efi_desc_size, &iomem_resource,
++ code_resource, data_resource,
++ EFI_INITIALISE_PHYS);
++ efi_initialize_iomem_machine_resources();
++ }
++ else
++#endif
++ efi_initialize_resources(efi_map_start, efi_map_end,
++ efi_desc_size, &iomem_resource,
++ code_resource, data_resource,
++ EFI_INITIALISE_ALL);
++}
++
++
++
++#ifdef CONFIG_KEXEC
++/* find a block of memory aligned to 64M exclude reserved regions
++ rsvd_regions are sorted
++ */
++unsigned long
++kdump_find_rsvd_region (unsigned long size,
++ struct rsvd_region *r, int n)
++{
++ int i;
++ u64 start, end;
++ u64 alignment = 1UL << _PAGE_SIZE_64M;
++ void *efi_map_start, *efi_map_end, *p;
++ efi_memory_desc_t *md;
++ u64 efi_desc_size;
++
++ efi_map_start = __va(ia64_boot_param->efi_memmap);
++ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
++ efi_desc_size = ia64_boot_param->efi_memdesc_size;
++
++ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
++ md = p;
++ if (!efi_wb(md))
++ continue;
++ start = ALIGN(md->phys_addr, alignment);
++ end = efi_md_end(md);
++ for (i = 0; i < n; i++) {
++ if (__pa(r[i].start) >= start && __pa(r[i].end) < end) {
++ if (__pa(r[i].start) > start + size)
++ return start;
++ start = ALIGN(__pa(r[i].end), alignment);
++ if (i < n-1 && __pa(r[i+1].start) < start + size)
++ continue;
++ else
++ break;
++ }
++ }
++ if (end > start + size)
++ return start;
++ }
++
++ printk(KERN_WARNING "Cannot reserve 0x%lx byte of memory for crashdump\n",
++ size);
++ return ~0UL;
++}
++#endif
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/entry.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/entry.S
+--- linux-2.6.18.8/arch/ia64/kernel/entry.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/entry.S 2008-02-15 16:21:49.000000000 -0800
@@ -180,7 +180,7 @@ END(sys_clone)
* called. The code starting at .map relies on this. The rest of the code
* doesn't care about the interrupt masking status.
@@ -22463,9 +23498,18 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/entry.S tmp-linux-2.6-xen.patc
;;
mov ar.unat=r9
br.many b7
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/fsys.S tmp-linux-2.6-xen.patch/arch/ia64/kernel/fsys.S
---- pristine-linux-2.6.18/arch/ia64/kernel/fsys.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/fsys.S 2007-11-14 15:35:27.000000000 -0800
+@@ -1575,7 +1581,7 @@ sys_call_table:
+ data8 sys_mq_timedreceive // 1265
+ data8 sys_mq_notify
+ data8 sys_mq_getsetattr
+- data8 sys_ni_syscall // reserved for kexec_load
++ data8 sys_kexec_load
+ data8 sys_ni_syscall // reserved for vserver
+ data8 sys_waitid // 1270
+ data8 sys_add_key
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/fsys.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/fsys.S
+--- linux-2.6.18.8/arch/ia64/kernel/fsys.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/fsys.S 2008-02-15 16:21:49.000000000 -0800
@@ -516,11 +516,34 @@ ENTRY(fsys_fallback_syscall)
adds r17=-1024,r15
movl r14=sys_call_table
@@ -22527,189 +23571,298 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/fsys.S tmp-linux-2.6-xen.patch
cmp.eq p8,p0=r3,r0 // A
(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/gate.S tmp-linux-2.6-xen.patch/arch/ia64/kernel/gate.S
---- pristine-linux-2.6.18/arch/ia64/kernel/gate.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/gate.S 2007-11-14 15:35:27.000000000 -0800
-@@ -13,6 +13,9 @@
- #include <asm/sigcontext.h>
- #include <asm/system.h>
- #include <asm/unistd.h>
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+# include <asm/privop.h>
-+#endif
-
- /*
- * We can't easily refer to symbols inside the kernel. To avoid full runtime relocation,
-@@ -32,6 +35,40 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/gate.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/gate.S
+--- linux-2.6.18.8/arch/ia64/kernel/gate.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/gate.S 2008-02-15 16:21:49.000000000 -0800
+@@ -32,102 +32,6 @@
[1:](pr)brl.cond.sptk 0; \
.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+ // The page in which hyperprivop lives must be pinned by ITR.
-+ // However vDSO area isn't pinned. So issuing hyperprivop
-+ // from vDSO page causes trouble that Kevin pointed out.
-+ // After clearing vpsr.ic, the vcpu is pre-empted and the itlb
-+ // is flushed. Then vcpu get cpu again, tlb miss fault occures.
-+ // However it results in nested dtlb fault because vpsr.ic is off.
-+ // To avoid such a situation, we jump into the kernel text area
-+ // which is pinned, and then issue hyperprivop and return back
-+ // to vDSO page.
-+ // This is Dan Magenheimer's idea.
-+
-+ // Currently is_running_on_xen() is defined as running_on_xen.
-+ // If is_running_on_xen() is a real function, we must update
-+ // according to it.
-+ .section ".data.patch.running_on_xen", "a"
-+ .previous
-+#define LOAD_RUNNING_ON_XEN(reg) \
-+[1:] movl reg=0; \
-+ .xdata4 ".data.patch.running_on_xen", 1b-.
-+
-+ .section ".data.patch.brl_xen_ssm_i_0", "a"
-+ .previous
-+#define BRL_COND_XEN_SSM_I_0(pr) \
-+[1:](pr)brl.cond.sptk 0; \
-+ .xdata4 ".data.patch.brl_xen_ssm_i_0", 1b-.
+-GLOBAL_ENTRY(__kernel_syscall_via_break)
+- .prologue
+- .altrp b6
+- .body
+- /*
+- * Note: for (fast) syscall restart to work, the break instruction must be
+- * the first one in the bundle addressed by syscall_via_break.
+- */
+-{ .mib
+- break 0x100000
+- nop.i 0
+- br.ret.sptk.many b6
+-}
+-END(__kernel_syscall_via_break)
+-
+-/*
+- * On entry:
+- * r11 = saved ar.pfs
+- * r15 = system call #
+- * b0 = saved return address
+- * b6 = return address
+- * On exit:
+- * r11 = saved ar.pfs
+- * r15 = system call #
+- * b0 = saved return address
+- * all other "scratch" registers: undefined
+- * all "preserved" registers: same as on entry
+- */
+-
+-GLOBAL_ENTRY(__kernel_syscall_via_epc)
+- .prologue
+- .altrp b6
+- .body
+-{
+- /*
+- * Note: the kernel cannot assume that the first two instructions in this
+- * bundle get executed. The remaining code must be safe even if
+- * they do not get executed.
+- */
+- adds r17=-1024,r15 // A
+- mov r10=0 // A default to successful syscall execution
+- epc // B causes split-issue
+-}
+- ;;
+- rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
+- LOAD_FSYSCALL_TABLE(r14) // X
+- ;;
+- mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
+- shladd r18=r17,3,r14 // A
+- mov r19=NR_syscalls-1 // A
+- ;;
+- lfetch [r18] // M0|1
+- mov r29=psr // M2 (12 cyc)
+- // If r17 is a NaT, p6 will be zero
+- cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+- ;;
+- mov r21=ar.fpsr // M2 (12 cyc)
+- tnat.nz p10,p9=r15 // I0
+- mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
+- ;;
+- srlz.d // M0 (forces split-issue) ensure PSR.BE==0
+-(p6) ld8 r18=[r18] // M0|1
+- nop.i 0
+- ;;
+- nop.m 0
+-(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
+- nop.i 0
+- ;;
+-(p8) ssm psr.i
+-(p6) mov b7=r18 // I0
+-(p8) br.dptk.many b7 // B
+-
+- mov r27=ar.rsc // M2 (12 cyc)
+-/*
+- * brl.cond doesn't work as intended because the linker would convert this branch
+- * into a branch to a PLT. Perhaps there will be a way to avoid this with some
+- * future version of the linker. In the meantime, we just use an indirect branch
+- * instead.
+- */
+-#ifdef CONFIG_ITANIUM
+-(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
+- ;;
+-(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
+- ;;
+-(p6) mov b7=r14
+-(p6) br.sptk.many b7
+-#else
+- BRL_COND_FSYS_BUBBLE_DOWN(p6)
+-#endif
+- ssm psr.i
+- mov r10=-1
+-(p10) mov r8=EINVAL
+-(p9) mov r8=ENOSYS
+- FSYS_RETURN
+-END(__kernel_syscall_via_epc)
+-
+ # define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
+ # define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET)
+ # define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET)
+@@ -373,3 +277,154 @@ restore_rbs:
+ // invala not necessary as that will happen when returning to user-mode
+ br.cond.sptk back_from_restore_rbs
+ END(__kernel_sigtramp)
++
++GLOBAL_ENTRY(__kernel_syscall_via_break)
++ .prologue
++ .altrp b6
++ .body
++ /*
++ * Note: for (fast) syscall restart to work, the break instruction must be
++ * the first one in the bundle addressed by syscall_via_break.
++ */
++{ .mib
++ break 0x100000
++ nop.i 0
++ br.ret.sptk.many b6
++}
++END(__kernel_syscall_via_break)
+
-+ .section ".data.patch.brl_xen_ssm_i_1", "a"
-+ .previous
-+#define BRL_COND_XEN_SSM_I_1(pr) \
-+[1:](pr)brl.cond.sptk 0; \
-+ .xdata4 ".data.patch.brl_xen_ssm_i_1", 1b-.
-+#endif
++/*
++ * On entry:
++ * r11 = saved ar.pfs
++ * r15 = system call #
++ * b0 = saved return address
++ * b6 = return address
++ * On exit:
++ * r11 = saved ar.pfs
++ * r15 = system call #
++ * b0 = saved return address
++ * all other "scratch" registers: undefined
++ * all "preserved" registers: same as on entry
++ */
+
- GLOBAL_ENTRY(__kernel_syscall_via_break)
- .prologue
- .altrp b6
-@@ -76,7 +113,42 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
- epc // B causes split-issue
- }
- ;;
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
++GLOBAL_ENTRY(__kernel_syscall_via_epc)
++ .prologue
++ .altrp b6
++ .body
++{
++ /*
++ * Note: the kernel cannot assume that the first two instructions in this
++ * bundle get executed. The remaining code must be safe even if
++ * they do not get executed.
++ */
++ adds r17=-1024,r15 // A
++ mov r10=0 // A default to successful syscall execution
++ epc // B causes split-issue
++}
++ ;;
++#ifdef __XEN_IA64_VDSO_PARAVIRT
+ // r20 = 1
+ // r22 = &vcpu->vcpu_info->evtchn_upcall_mask
-+ // r23 = &vpsr.ic
+ // r24 = &vcpu->vcpu_info->evtchn_upcall_pending
+ // r25 = tmp
-+ // r28 = &running_on_xen
-+ // r30 = running_on_xen
+ // r31 = tmp
+ // p11 = tmp
-+ // p12 = running_on_xen
-+ // p13 = !running_on_xen
+ // p14 = tmp
-+ // p15 = tmp
-+#define isXen p12
-+#define isRaw p13
-+ LOAD_RUNNING_ON_XEN(r28)
++ mov r20=1
+ movl r22=XSI_PSR_I_ADDR
+ ;;
+ ld8 r22=[r22]
+ ;;
-+ movl r23=XSI_PSR_IC
++ st1 [r22]=r20
++ rum psr.be
+ adds r24=-1,r22
-+ mov r20=1
-+ ;;
-+ ld4 r30=[r28]
-+ ;;
-+ cmp.ne isXen,isRaw=r0,r30
++#else
++ rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
++#endif
++ LOAD_FSYSCALL_TABLE(r14) // X
+ ;;
-+(isRaw) rsm psr.be | psr.i
-+(isXen) st1 [r22]=r20
-+(isXen) rum psr.be
++ mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
++ shladd r18=r17,3,r14 // A
++ mov r19=NR_syscalls-1 // A
++#ifdef __XEN_IA64_VDSO_PARAVIRT
++ XEN_HYPER_GET_PSR
+ ;;
++ lfetch [r18] // M0|1
++ mov r29=r8
+#else
- rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
++ ;;
++ lfetch [r18] // M0|1
++ mov r29=psr // M2 (12 cyc)
+#endif
- LOAD_FSYSCALL_TABLE(r14) // X
- ;;
- mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
-@@ -84,7 +156,14 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
- mov r19=NR_syscalls-1 // A
- ;;
- lfetch [r18] // M0|1
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+(isRaw) mov r29=psr
-+(isXen) XEN_HYPER_GET_PSR
++ // If r17 is a NaT, p6 will be zero
++ cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+ ;;
-+(isXen) mov r29=r8
++ mov r21=ar.fpsr // M2 (12 cyc)
++ tnat.nz p10,p9=r15 // I0
++ mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
++ ;;
++ srlz.d // M0 (forces split-issue) ensure PSR.BE==0
++(p6) ld8 r18=[r18] // M0|1
++ nop.i 0
++ ;;
++ nop.m 0
++(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
++#ifdef __XEN_IA64_VDSO_PARAVIRT
++
++#define XEN_SET_PSR_I(pred) \
++(pred) ld1 r31=[r22]; \
++ ;; ; \
++(pred) st1 [r22]=r0; \
++(pred) cmp.ne.unc p14,p0=r0,r31; \
++ ;; ; \
++(p14) ld1 r25=[r24]; \
++ ;; ; \
++(p14) cmp.ne.unc p11,p0=r0,r25; \
++ ;; ; \
++(p11) XEN_HYPER_SSM_I;
++
++ ;;
++ XEN_SET_PSR_I(p8)
+#else
- mov r29=psr // M2 (12 cyc)
++ nop.i 0
++ ;;
++(p8) ssm psr.i
+#endif
- // If r17 is a NaT, p6 will be zero
- cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
- ;;
-@@ -98,9 +177,21 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
- ;;
- nop.m 0
- (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
++(p6) mov b7=r18 // I0
++(p8) br.dptk.many b7 // B
++
++ mov r27=ar.rsc // M2 (12 cyc)
++/*
++ * brl.cond doesn't work as intended because the linker would convert this branch
++ * into a branch to a PLT. Perhaps there will be a way to avoid this with some
++ * future version of the linker. In the meantime, we just use an indirect branch
++ * instead.
++ */
++#ifdef CONFIG_ITANIUM
++(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
+ ;;
-+ // p14 = running_on_xen && p8
-+ // p15 = !running_on_xen && p8
-+(p8) cmp.ne.unc p14,p15=r0,r30
++(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
+ ;;
-+(p15) ssm psr.i
-+ BRL_COND_XEN_SSM_I_0(p14)
-+ .global .vdso_ssm_i_0_ret
-+.vdso_ssm_i_0_ret:
++(p6) mov b7=r14
++(p6) br.sptk.many b7
+#else
- nop.i 0
- ;;
- (p8) ssm psr.i
++ BRL_COND_FSYS_BUBBLE_DOWN(p6)
+#endif
- (p6) mov b7=r18 // I0
- (p8) br.dptk.many b7 // B
-
-@@ -121,9 +212,21 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
- #else
- BRL_COND_FSYS_BUBBLE_DOWN(p6)
- #endif
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+(isRaw) ssm psr.i
-+ BRL_COND_XEN_SSM_I_1(isXen)
-+ .global .vdso_ssm_i_1_ret
-+.vdso_ssm_i_1_ret:
++#ifdef __XEN_IA64_VDSO_PARAVIRT
++ XEN_SET_PSR_I(p0)
+#else
- ssm psr.i
-+#endif
- mov r10=-1
- (p10) mov r8=EINVAL
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+ dv_serialize_data // shut up gas warning.
-+ // we know xen_hyper_ssm_i_0 or xen_hyper_ssm_i_1
-+ // doesn't change p9 and p10
-+#endif
- (p9) mov r8=ENOSYS
- FSYS_RETURN
- END(__kernel_syscall_via_epc)
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/gate.lds.S tmp-linux-2.6-xen.patch/arch/ia64/kernel/gate.lds.S
---- pristine-linux-2.6.18/arch/ia64/kernel/gate.lds.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/gate.lds.S 2007-11-14 15:35:27.000000000 -0800
-@@ -43,6 +43,20 @@ SECTIONS
- __start_gate_brl_fsys_bubble_down_patchlist = .;
- *(.data.patch.brl_fsys_bubble_down)
- __end_gate_brl_fsys_bubble_down_patchlist = .;
-+
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+ __start_gate_running_on_xen_patchlist = .;
-+ *(.data.patch.running_on_xen)
-+ __end_gate_running_on_xen_patchlist = .;
-+
-+ __start_gate_brl_xen_ssm_i_0_patchlist = .;
-+ *(.data.patch.brl_xen_ssm_i_0)
-+ __end_gate_brl_xen_ssm_i_0_patchlist = .;
-+
-+ __start_gate_brl_xen_ssm_i_1_patchlist = .;
-+ *(.data.patch.brl_xen_ssm_i_1)
-+ __end_gate_brl_xen_ssm_i_1_patchlist = .;
-+#endif
- } :readable
- .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
- .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/head.S tmp-linux-2.6-xen.patch/arch/ia64/kernel/head.S
---- pristine-linux-2.6.18/arch/ia64/kernel/head.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/head.S 2007-11-14 15:35:27.000000000 -0800
++ ssm psr.i
++#endif
++ mov r10=-1
++(p10) mov r8=EINVAL
++(p9) mov r8=ENOSYS
++ FSYS_RETURN
++#ifdef __KERNEL_SYSCALL_VIA_EPC_PADDING
++ /*
++ * All values/sizes of __kernel_xxx symbol in gate.so and xengate.so
++ * must be same to each other.
++ * Adjust symbol size in gate.so to be same to the one in xengate.so.
++ */
++.include "arch/ia64/kernel/gate-skip.s"
++#endif
++END(__kernel_syscall_via_epc)
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/gate.lds.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/gate.lds.S
+--- linux-2.6.18.8/arch/ia64/kernel/gate.lds.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/gate.lds.S 2008-02-15 16:21:49.000000000 -0800
+@@ -28,6 +28,24 @@ SECTIONS
+ . = GATE_ADDR + 0x500;
+
+ .data.patch : {
++#ifdef __XEN_IA64_VDSO_PARAVIRT
++#define __start_gate_mckinley_e9_patchlist \
++ __start_gate_mckinley_e9_patchlist_xen
++#define __end_gate_mckinley_e9_patchlist \
++ __end_gate_mckinley_e9_patchlist_xen
++#define __start_gate_vtop_patchlist \
++ __start_gate_vtop_patchlist_xen
++#define __end_gate_vtop_patchlist \
++ __end_gate_vtop_patchlist_xen
++#define __start_gate_fsyscall_patchlist \
++ __start_gate_fsyscall_patchlist_xen
++#define __end_gate_fsyscall_patchlist \
++ __end_gate_fsyscall_patchlist_xen
++#define __start_gate_brl_fsys_bubble_down_patchlist \
++ __start_gate_brl_fsys_bubble_down_patchlist_xen
++#define __end_gate_brl_fsys_bubble_down_patchlist \
++ __end_gate_brl_fsys_bubble_down_patchlist_xen
++#endif
+ __start_gate_mckinley_e9_patchlist = .;
+ *(.data.patch.mckinley_e9)
+ __end_gate_mckinley_e9_patchlist = .;
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/head.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/head.S
+--- linux-2.6.18.8/arch/ia64/kernel/head.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/head.S 2008-02-15 16:21:49.000000000 -0800
@@ -367,6 +367,12 @@ start_ap:
;;
(isBP) st8 [r2]=r28 // save the address of the boot param area passed by the bootloader
@@ -22723,9 +23876,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/head.S tmp-linux-2.6-xen.patch
#ifdef CONFIG_SMP
(isAP) br.call.sptk.many rp=start_secondary
.ret0:
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/iosapic.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/iosapic.c
---- pristine-linux-2.6.18/arch/ia64/kernel/iosapic.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/iosapic.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/iosapic.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/iosapic.c
+--- linux-2.6.18.8/arch/ia64/kernel/iosapic.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/iosapic.c 2008-02-15 16:21:49.000000000 -0800
@@ -159,6 +159,75 @@ static unsigned char pcat_compat __devin
static int iosapic_kmalloc_ok;
static LIST_HEAD(free_rte_list);
@@ -22802,7 +23955,35 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/iosapic.c tmp-linux-2.6-xen.pa
/*
* Find an IOSAPIC associated with a GSI
*/
-@@ -653,6 +722,9 @@ register_intr (unsigned int gsi, int vec
+@@ -288,6 +357,27 @@ nop (unsigned int irq)
+ /* do nothing... */
+ }
+
++
++#ifdef CONFIG_KEXEC
++void
++kexec_disable_iosapic(void)
++{
++ struct iosapic_intr_info *info;
++ struct iosapic_rte_info *rte;
++ u8 vec = 0;
++ for (info = iosapic_intr_info; info <
++ iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) {
++ list_for_each_entry(rte, &info->rtes,
++ rte_list) {
++ iosapic_write(rte->addr,
++ IOSAPIC_RTE_LOW(rte->rte_index),
++ IOSAPIC_MASK|vec);
++ iosapic_eoi(rte->addr, vec);
++ }
++ }
++}
++#endif
++
+ static void
+ mask_irq (unsigned int irq)
+ {
+@@ -653,6 +743,9 @@ register_intr (unsigned int gsi, int vec
iosapic_intr_info[vector].dmode = delivery;
iosapic_intr_info[vector].trigger = trigger;
@@ -22812,7 +23993,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/iosapic.c tmp-linux-2.6-xen.pa
if (trigger == IOSAPIC_EDGE)
irq_type = &irq_type_iosapic_edge;
else
-@@ -1015,6 +1087,9 @@ iosapic_system_init (int system_pcat_com
+@@ -1015,6 +1108,9 @@ iosapic_system_init (int system_pcat_com
}
pcat_compat = system_pcat_compat;
@@ -22822,9 +24003,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/iosapic.c tmp-linux-2.6-xen.pa
if (pcat_compat) {
/*
* Disable the compatibility mode interrupts (8259 style),
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/irq_ia64.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/irq_ia64.c
---- pristine-linux-2.6.18/arch/ia64/kernel/irq_ia64.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/irq_ia64.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/irq_ia64.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/irq_ia64.c
+--- linux-2.6.18.8/arch/ia64/kernel/irq_ia64.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/irq_ia64.c 2008-02-15 16:21:49.000000000 -0800
@@ -30,6 +30,9 @@
#include <linux/smp_lock.h>
#include <linux/threads.h>
@@ -22863,7 +24044,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/irq_ia64.c tmp-linux-2.6-xen.p
pos = vector - IA64_FIRST_DEVICE_VECTOR;
if (!test_and_clear_bit(pos, ia64_vector_mask))
printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
-@@ -240,12 +257,277 @@ static struct irqaction ipi_irqaction =
+@@ -240,12 +257,340 @@ static struct irqaction ipi_irqaction =
};
#endif
@@ -23124,72 +24305,46 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/irq_ia64.c tmp-linux-2.6-xen.p
+#endif /* CONFIG_SMP */
+}
+
-+#endif /* CONFIG_XEN */
++void
++xen_irq_init(void)
++{
++ struct callback_register event = {
++ .type = CALLBACKTYPE_event,
++ .address = (unsigned long)&xen_event_callback,
++ };
+
- void
- register_percpu_irq (ia64_vector vec, struct irqaction *action)
- {
- irq_desc_t *desc;
- unsigned int irq;
-
-+#ifdef CONFIG_XEN
-+ if (is_running_on_xen())
-+ return xen_register_percpu_irq(smp_processor_id(),
-+ vec, action, 1);
++ xen_init_IRQ();
++ BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
++ late_time_init = xen_bind_early_percpu_irq;
++#ifdef CONFIG_SMP
++ register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
+#endif
++}
+
- for (irq = 0; irq < NR_IRQS; ++irq)
- if (irq_to_vector(irq) == vec) {
- desc = irq_desc + irq;
-@@ -259,6 +541,21 @@ register_percpu_irq (ia64_vector vec, st
- void __init
- init_IRQ (void)
- {
-+#ifdef CONFIG_XEN
-+ /* Maybe put into platform_irq_init later */
-+ if (is_running_on_xen()) {
-+ struct callback_register event = {
-+ .type = CALLBACKTYPE_event,
-+ .address = (unsigned long)&xen_event_callback,
-+ };
-+ xen_init_IRQ();
-+ BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
-+ late_time_init = xen_bind_early_percpu_irq;
-+#ifdef CONFIG_SMP
-+ register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
-+#endif /* CONFIG_SMP */
-+ }
-+#endif /* CONFIG_XEN */
- register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
- #ifdef CONFIG_SMP
- register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
-@@ -276,6 +573,54 @@ ia64_send_ipi (int cpu, int vector, int
- unsigned long ipi_data;
- unsigned long phys_cpu_id;
-
-+#ifdef CONFIG_XEN
-+ if (is_running_on_xen()) {
-+ int irq = -1;
++void
++xen_platform_send_ipi(int cpu, int vector, int delivery_mode, int redirect)
++{
++ int irq = -1;
+
+#ifdef CONFIG_SMP
-+ /* TODO: we need to call vcpu_up here */
-+ if (unlikely(vector == ap_wakeup_vector)) {
-+ extern void xen_send_ipi (int cpu, int vec);
-+
-+ /* XXX
-+ * This should be in __cpu_up(cpu) in ia64 smpboot.c
-+ * like x86. But don't want to modify it,
-+ * keep it untouched.
-+ */
-+ xen_smp_intr_init_early(cpu);
++ /* TODO: we need to call vcpu_up here */
++ if (unlikely(vector == ap_wakeup_vector)) {
++ extern void xen_send_ipi (int cpu, int vec);
++
++ /* XXX
++ * This should be in __cpu_up(cpu) in ia64 smpboot.c
++ * like x86. But don't want to modify it,
++ * keep it untouched.
++ */
++ xen_smp_intr_init_early(cpu);
+
-+ xen_send_ipi (cpu, vector);
-+ //vcpu_prepare_and_up(cpu);
-+ return;
-+ }
++ xen_send_ipi (cpu, vector);
++ //vcpu_prepare_and_up(cpu);
++ return;
++ }
+#endif
+
-+ switch(vector) {
++ switch (vector) {
+ case IA64_IPI_VECTOR:
+ irq = per_cpu(ipi_to_irq, cpu)[IPI_VECTOR];
+ break;
@@ -23207,20 +24362,265 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/irq_ia64.c tmp-linux-2.6-xen.p
+ vector);
+ irq = 0;
+ break;
-+ }
++ }
+
-+ BUG_ON(irq < 0);
-+ notify_remote_via_irq(irq);
-+ return;
-+ }
++ BUG_ON(irq < 0);
++ notify_remote_via_irq(irq);
++ return;
++}
+#endif /* CONFIG_XEN */
+
+ void
+ register_percpu_irq (ia64_vector vec, struct irqaction *action)
+ {
+ irq_desc_t *desc;
+ unsigned int irq;
+
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ return xen_register_percpu_irq(smp_processor_id(),
++ vec, action, 1);
++#endif
++
+ for (irq = 0; irq < NR_IRQS; ++irq)
+ if (irq_to_vector(irq) == vec) {
+ desc = irq_desc + irq;
+@@ -267,6 +612,10 @@ init_IRQ (void)
+ pfm_init_percpu();
+ #endif
+ platform_irq_init();
++#ifdef CONFIG_XEN
++ if (is_running_on_xen() && !ia64_platform_is("xen"))
++ xen_irq_init();
++#endif
+ }
+
+ void
+@@ -276,6 +625,13 @@ ia64_send_ipi (int cpu, int vector, int
+ unsigned long ipi_data;
+ unsigned long phys_cpu_id;
+
++#ifdef CONFIG_XEN
++ if (is_running_on_xen()) {
++ xen_platform_send_ipi(cpu, vector, delivery_mode, redirect);
++ return;
++ }
++#endif
++
#ifdef CONFIG_SMP
phys_cpu_id = cpu_physical_id(cpu);
#else
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/pal.S tmp-linux-2.6-xen.patch/arch/ia64/kernel/pal.S
---- pristine-linux-2.6.18/arch/ia64/kernel/pal.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/pal.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/machine_kexec.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/machine_kexec.c
+--- linux-2.6.18.8/arch/ia64/kernel/machine_kexec.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/machine_kexec.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,145 @@
++/*
++ * arch/ia64/kernel/machine_kexec.c
++ *
++ * Handle transition of Linux booting another kernel
++ * Copyright (C) 2005 Hewlett-Packard Development Comapny, L.P.
++ * Copyright (C) 2005 Khalid Aziz <khalid.aziz@hp.com>
++ * Copyright (C) 2006 Intel Corp, Zou Nan hai <nanhai.zou@intel.com>
++ *
++ * This source code is licensed under the GNU General Public License,
++ * Version 2. See the file COPYING for more details.
++ */
++
++#include <linux/mm.h>
++#include <linux/kexec.h>
++#include <linux/cpu.h>
++#include <linux/irq.h>
++#include <asm/mmu_context.h>
++#include <asm/setup.h>
++#include <asm/delay.h>
++#include <asm/meminit.h>
++#ifdef CONFIG_XEN
++#include <xen/interface/kexec.h>
++#include <asm/kexec.h>
++#endif
++
++typedef void (*relocate_new_kernel_t)(unsigned long, unsigned long,
++ struct ia64_boot_param *, unsigned long);
++
++struct kimage *ia64_kimage;
++
++struct resource efi_memmap_res = {
++ .name = "EFI Memory Map",
++ .start = 0,
++ .end = 0,
++ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++struct resource boot_param_res = {
++ .name = "Boot parameter",
++ .start = 0,
++ .end = 0,
++ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
++};
++
++
++/*
++ * Do what every setup is needed on image and the
++ * reboot code buffer to allow us to avoid allocations
++ * later.
++ */
++int machine_kexec_prepare(struct kimage *image)
++{
++ void *control_code_buffer;
++ const unsigned long *func;
++
++ func = (unsigned long *)&relocate_new_kernel;
++ /* Pre-load control code buffer to minimize work in kexec path */
++ control_code_buffer = page_address(image->control_code_page);
++ memcpy((void *)control_code_buffer, (const void *)func[0],
++ relocate_new_kernel_size);
++ flush_icache_range((unsigned long)control_code_buffer,
++ (unsigned long)control_code_buffer + relocate_new_kernel_size);
++ ia64_kimage = image;
++
++ return 0;
++}
++
++void machine_kexec_cleanup(struct kimage *image)
++{
++}
++
++#ifndef CONFIG_XEN
++void machine_shutdown(void)
++{
++ int cpu;
++
++ for_each_online_cpu(cpu) {
++ if (cpu != smp_processor_id())
++ cpu_down(cpu);
++ }
++ kexec_disable_iosapic();
++}
++
++/*
++ * Do not allocate memory (or fail in any way) in machine_kexec().
++ * We are past the point of no return, committed to rebooting now.
++ */
++extern void *efi_get_pal_addr(void);
++static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
++{
++ struct kimage *image = arg;
++ relocate_new_kernel_t rnk;
++ void *pal_addr = efi_get_pal_addr();
++ unsigned long code_addr = (unsigned long)page_address(image->control_code_page);
++ unsigned long vector;
++ int ii;
++
++ if (image->type == KEXEC_TYPE_CRASH) {
++ crash_save_this_cpu();
++ current->thread.ksp = (__u64)info->sw - 16;
++ }
++
++ /* Interrupts aren't acceptable while we reboot */
++ local_irq_disable();
++
++ /* Mask CMC and Performance Monitor interrupts */
++ ia64_setreg(_IA64_REG_CR_PMV, 1 << 16);
++ ia64_setreg(_IA64_REG_CR_CMCV, 1 << 16);
++
++ /* Mask ITV and Local Redirect Registers */
++ ia64_set_itv(1 << 16);
++ ia64_set_lrr0(1 << 16);
++ ia64_set_lrr1(1 << 16);
++
++ /* terminate possible nested in-service interrupts */
++ for (ii = 0; ii < 16; ii++)
++ ia64_eoi();
++
++ /* unmask TPR and clear any pending interrupts */
++ ia64_setreg(_IA64_REG_CR_TPR, 0);
++ ia64_srlz_d();
++ vector = ia64_get_ivr();
++ while (vector != IA64_SPURIOUS_INT_VECTOR) {
++ ia64_eoi();
++ vector = ia64_get_ivr();
++ }
++ platform_kernel_launch_event();
++ rnk = (relocate_new_kernel_t)&code_addr;
++ (*rnk)(image->head, image->start, ia64_boot_param,
++ GRANULEROUNDDOWN((unsigned long) pal_addr));
++ BUG();
++}
++
++void machine_kexec(struct kimage *image)
++{
++ unw_init_running(ia64_machine_kexec, image);
++ for(;;);
++}
++#else /* CONFIG_XEN */
++void machine_kexec_setup_load_arg(xen_kexec_image_t *xki,struct kimage *image)
++{
++ xki->reboot_code_buffer =
++ kexec_page_to_pfn(image->control_code_page) << PAGE_SHIFT;
++}
++#endif /* CONFIG_XEN */
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/mca.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/mca.c
+--- linux-2.6.18.8/arch/ia64/kernel/mca.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/mca.c 2008-02-15 16:21:49.000000000 -0800
+@@ -79,6 +79,7 @@
+ #include <asm/system.h>
+ #include <asm/sal.h>
+ #include <asm/mca.h>
++#include <asm/kexec.h>
+
+ #include <asm/irq.h>
+ #include <asm/hw_irq.h>
+@@ -160,11 +161,33 @@ typedef struct ia64_state_log_s
+
+ static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
+
++#ifdef CONFIG_XEN
++DEFINE_SPINLOCK(ia64_mca_xencomm_lock);
++LIST_HEAD(ia64_mca_xencomm_list);
++
++#define IA64_MCA_XENCOMM_ALLOCATE(rec, desc) \
++ if (is_running_on_xen()) { \
++ ia64_mca_xencomm_t *entry; \
++ entry = alloc_bootmem(sizeof(ia64_mca_xencomm_t)); \
++ entry->record = rec; \
++ entry->handle = desc; \
++ list_add(&entry->list, &ia64_mca_xencomm_list); \
++ }
++#define IA64_LOG_ALLOCATE(it, size) \
++ {ia64_err_rec_t *rec; \
++ ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = rec = \
++ (ia64_err_rec_t *)alloc_bootmem(size); \
++ IA64_MCA_XENCOMM_ALLOCATE(rec, xencomm_map(rec, size)); \
++ ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = rec = \
++ (ia64_err_rec_t *)alloc_bootmem(size); \
++ IA64_MCA_XENCOMM_ALLOCATE(rec, xencomm_map(rec, size));}
++#else
+ #define IA64_LOG_ALLOCATE(it, size) \
+ {ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \
+ (ia64_err_rec_t *)alloc_bootmem(size); \
+ ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \
+ (ia64_err_rec_t *)alloc_bootmem(size);}
++#endif
+ #define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock)
+ #define IA64_LOG_LOCK(it) spin_lock_irqsave(&ia64_state_log[it].isl_lock, s)
+ #define IA64_LOG_UNLOCK(it) spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s)
+@@ -1066,7 +1089,12 @@ ia64_mca_handler(struct pt_regs *regs, s
+ rh->severity = sal_log_severity_corrected;
+ ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
+ sos->os_status = IA64_MCA_CORRECTED;
+- }
++ } else {
++#ifdef CONFIG_KEXEC
++ atomic_set(&kdump_in_progress, 1);
++ monarch_cpu = -1;
++#endif
++ }
+ if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
+ == NOTIFY_STOP)
+ ia64_mca_spin(__FUNCTION__);
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/pal.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/pal.S
+--- linux-2.6.18.8/arch/ia64/kernel/pal.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/pal.S 2008-02-15 16:21:49.000000000 -0800
@@ -16,6 +16,7 @@
#include <asm/processor.h>
@@ -23247,97 +24647,55 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/pal.S tmp-linux-2.6-xen.patch/
/*
* Make a PAL call using the stacked registers calling convention.
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/patch.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/patch.c
---- pristine-linux-2.6.18/arch/ia64/kernel/patch.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/patch.c 2007-11-14 15:35:27.000000000 -0800
-@@ -184,6 +184,69 @@ patch_brl_fsys_bubble_down (unsigned lon
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/patch.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/patch.c
+--- linux-2.6.18.8/arch/ia64/kernel/patch.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/patch.c 2008-02-15 16:21:49.000000000 -0800
+@@ -184,9 +184,37 @@ patch_brl_fsys_bubble_down (unsigned lon
ia64_srlz_i();
}
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+extern char __start_gate_running_on_xen_patchlist[];
-+extern char __end_gate_running_on_xen_patchlist[];
-+
-+void
-+patch_running_on_xen(unsigned long start, unsigned long end)
++#ifdef CONFIG_XEN
++void __init
++ia64_patch_gate_xen (void)
+{
-+ extern int running_on_xen;
-+ s32 *offp = (s32 *)start;
-+ u64 ip;
-+
-+ while (offp < (s32 *)end) {
-+ ip = (u64)ia64_imva((char *)offp + *offp);
-+ ia64_patch_imm64(ip, (u64)&running_on_xen);
-+ ia64_fc((void *)ip);
-+ ++offp;
-+ }
-+ ia64_sync_i();
-+ ia64_srlz_i();
-+}
++ extern char __start_gate_mckinley_e9_patchlist_xen[], __end_gate_mckinley_e9_patchlist_xen[];
++ extern char __start_gate_vtop_patchlist_xen[], __end_gate_vtop_patchlist_xen[];
++ extern char __start_gate_fsyscall_patchlist_xen[], __end_gate_fsyscall_patchlist_xen[];
++ extern char __start_gate_brl_fsys_bubble_down_patchlist_xen[], __end_gate_brl_fsys_bubble_down_patchlist_xen[];
++# define START(name) ((unsigned long) __start_gate_##name##_patchlist_xen)
++# define END(name) ((unsigned long)__end_gate_##name##_patchlist_xen)
+
-+static void
-+patch_brl_symaddr(unsigned long start, unsigned long end,
-+ unsigned long symaddr)
-+{
-+ s32 *offp = (s32 *)start;
-+ u64 ip;
++ patch_fsyscall_table(START(fsyscall), END(fsyscall));
++ patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
++ ia64_patch_vtop(START(vtop), END(vtop));
++ ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
+
-+ while (offp < (s32 *)end) {
-+ ip = (u64)offp + *offp;
-+ ia64_patch_imm60((u64)ia64_imva((void *)ip),
-+ (u64)(symaddr - (ip & -16)) / 16);
-+ ia64_fc((void *)ip);
-+ ++offp;
-+ }
-+ ia64_sync_i();
-+ ia64_srlz_i();
-+}
-+
-+#define EXTERN_PATCHLIST(name) \
-+ extern char __start_gate_brl_##name##_patchlist[]; \
-+ extern char __end_gate_brl_##name##_patchlist[]; \
-+ extern char name[]
-+
-+#define PATCH_BRL_SYMADDR(name) \
-+ patch_brl_symaddr((unsigned long)__start_gate_brl_##name##_patchlist, \
-+ (unsigned long)__end_gate_brl_##name##_patchlist, \
-+ (unsigned long)name)
-+
-+static void
-+patch_brl_in_vdso(void)
-+{
-+ EXTERN_PATCHLIST(xen_ssm_i_0);
-+ EXTERN_PATCHLIST(xen_ssm_i_1);
-+
-+ PATCH_BRL_SYMADDR(xen_ssm_i_0);
-+ PATCH_BRL_SYMADDR(xen_ssm_i_1);
++# undef START
++# undef END
+}
+#else
-+#define patch_running_on_xen(start, end) do { } while (0)
-+#define patch_brl_in_vdso() do { } while (0)
++#define ia64_patch_gate_xen() do { } while (0)
+#endif
+
void __init
ia64_patch_gate (void)
{
-@@ -192,6 +255,10 @@ ia64_patch_gate (void)
++ if (is_running_on_xen()) {
++ ia64_patch_gate_xen();
++ return;
++ }
++
+ # define START(name) ((unsigned long) __start_gate_##name##_patchlist)
+ # define END(name) ((unsigned long)__end_gate_##name##_patchlist)
- patch_fsyscall_table(START(fsyscall), END(fsyscall));
- patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
-+#ifdef CONFIG_XEN
-+ patch_running_on_xen(START(running_on_xen), END(running_on_xen));
-+ patch_brl_in_vdso();
-+#endif
- ia64_patch_vtop(START(vtop), END(vtop));
- ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
- }
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/perfmon.c
---- pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/perfmon.c 2007-11-14 15:35:27.000000000 -0800
-@@ -52,6 +52,28 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/perfmon.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/perfmon.c
+--- linux-2.6.18.8/arch/ia64/kernel/perfmon.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/perfmon.c 2008-02-15 16:21:49.000000000 -0800
+@@ -52,6 +52,31 @@
#include <asm/delay.h>
#ifdef CONFIG_PERFMON
++#include <asm/hypervisor.h>
+#ifdef CONFIG_XEN
+//#include <xen/xenoprof.h>
+#include <xen/interface/xenoprof.h>
@@ -23357,13 +24715,15 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
+#define init_xenoprof_primary(is_primary) do { } while (0)
+#define is_xenoprof_primary() (0)
+#define XEN_NOT_SUPPORTED_YET do { } while (0)
-+#define HYPERVISOR_perfmon_op(cmd, arg, count) do { } while (0)
++#define HYPERVISOR_perfmon_op(cmd, arg, count) (0)
++#define HYPERVISOR_xenoprof_op(op, arg) ({(void)arg;0;})
++struct xenoprof_init { /* dummy */ };
+#endif
+
/*
* perfmon context state
*/
-@@ -1514,6 +1536,7 @@ pfm_read(struct file *filp, char __user
+@@ -1514,6 +1539,7 @@ pfm_read(struct file *filp, char __user
ssize_t ret;
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
@@ -23371,7 +24731,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
if (PFM_IS_FILE(filp) == 0) {
printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
return -EINVAL;
-@@ -2112,6 +2135,15 @@ doit:
+@@ -2112,6 +2138,15 @@ doit:
*/
if (free_possible) pfm_context_free(ctx);
@@ -23387,7 +24747,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
return 0;
}
-@@ -2735,6 +2767,23 @@ pfm_context_create(pfm_context_t *ctx, v
+@@ -2735,6 +2770,23 @@ pfm_context_create(pfm_context_t *ctx, v
*/
pfm_reset_pmu_state(ctx);
@@ -23411,7 +24771,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
return 0;
buffer_error:
-@@ -2871,6 +2920,12 @@ pfm_write_pmcs(pfm_context_t *ctx, void
+@@ -2871,6 +2923,12 @@ pfm_write_pmcs(pfm_context_t *ctx, void
pfm_reg_check_t wr_func;
#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
@@ -23424,7 +24784,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
state = ctx->ctx_state;
is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
is_system = ctx->ctx_fl_system;
-@@ -3111,6 +3166,12 @@ pfm_write_pmds(pfm_context_t *ctx, void
+@@ -3111,6 +3169,12 @@ pfm_write_pmds(pfm_context_t *ctx, void
int ret = -EINVAL;
pfm_reg_check_t wr_func;
@@ -23437,7 +24797,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
state = ctx->ctx_state;
is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
-@@ -3308,6 +3369,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *
+@@ -3308,6 +3372,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *
int is_loaded, is_system, is_counting, expert_mode;
int ret = -EINVAL;
pfm_reg_check_t rd_func;
@@ -23445,7 +24805,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
/*
* access is possible when loaded only for
-@@ -3559,6 +3621,7 @@ pfm_restart(pfm_context_t *ctx, void *ar
+@@ -3559,6 +3624,7 @@ pfm_restart(pfm_context_t *ctx, void *ar
pfm_ovfl_ctrl_t rst_ctrl;
int state, is_system;
int ret = 0;
@@ -23453,7 +24813,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
state = ctx->ctx_state;
fmt = ctx->ctx_buf_fmt;
-@@ -3708,6 +3771,7 @@ static int
+@@ -3708,6 +3774,7 @@ static int
pfm_debug(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
{
unsigned int m = *(unsigned int *)arg;
@@ -23461,7 +24821,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
pfm_sysctl.debug = m == 0 ? 0 : 1;
-@@ -3978,6 +4042,8 @@ pfm_get_features(pfm_context_t *ctx, voi
+@@ -3978,6 +4045,8 @@ pfm_get_features(pfm_context_t *ctx, voi
{
pfarg_features_t *req = (pfarg_features_t *)arg;
@@ -23470,7 +24830,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
req->ft_version = PFM_VERSION;
return 0;
}
-@@ -3989,6 +4055,12 @@ pfm_stop(pfm_context_t *ctx, void *arg,
+@@ -3989,6 +4058,12 @@ pfm_stop(pfm_context_t *ctx, void *arg,
struct task_struct *task = PFM_CTX_TASK(ctx);
int state, is_system;
@@ -23483,7 +24843,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
state = ctx->ctx_state;
is_system = ctx->ctx_fl_system;
-@@ -4077,6 +4149,11 @@ pfm_start(pfm_context_t *ctx, void *arg,
+@@ -4077,6 +4152,11 @@ pfm_start(pfm_context_t *ctx, void *arg,
struct pt_regs *tregs;
int state, is_system;
@@ -23495,7 +24855,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
state = ctx->ctx_state;
is_system = ctx->ctx_fl_system;
-@@ -4159,6 +4236,7 @@ pfm_get_pmc_reset(pfm_context_t *ctx, vo
+@@ -4159,6 +4239,7 @@ pfm_get_pmc_reset(pfm_context_t *ctx, vo
unsigned int cnum;
int i;
int ret = -EINVAL;
@@ -23503,7 +24863,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
for (i = 0; i < count; i++, req++) {
-@@ -4217,6 +4295,11 @@ pfm_context_load(pfm_context_t *ctx, voi
+@@ -4217,6 +4298,11 @@ pfm_context_load(pfm_context_t *ctx, voi
int ret = 0;
int state, is_system, set_dbregs = 0;
@@ -23515,7 +24875,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
state = ctx->ctx_state;
is_system = ctx->ctx_fl_system;
/*
-@@ -4465,6 +4548,12 @@ pfm_context_unload(pfm_context_t *ctx, v
+@@ -4465,6 +4551,12 @@ pfm_context_unload(pfm_context_t *ctx, v
int prev_state, is_system;
int ret;
@@ -23528,10 +24888,463 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/perfmon.c tmp-linux-2.6-xen.pa
DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
prev_state = ctx->ctx_state;
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/setup.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/setup.c
---- pristine-linux-2.6.18/arch/ia64/kernel/setup.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/setup.c 2007-11-14 15:35:27.000000000 -0800
-@@ -60,6 +60,12 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/relocate_kernel.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/relocate_kernel.S
+--- linux-2.6.18.8/arch/ia64/kernel/relocate_kernel.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/relocate_kernel.S 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,380 @@
++/*
++ * arch/ia64/kernel/relocate_kernel.S
++ *
++ * Relocate kexec'able kernel and start it
++ *
++ * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
++ * Copyright (C) 2005 Khalid Aziz <khalid.aziz@hp.com>
++ * Copyright (C) 2005 Intel Corp, Zou Nan hai <nanhai.zou@intel.com>
++ *
++ * This source code is licensed under the GNU General Public License,
++ * Version 2. See the file COPYING for more details.
++ */
++#include <asm/asmmacro.h>
++#include <asm/kregs.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/mca_asm.h>
++
++ /* Must be relocatable PIC code callable as a C function
++ */
++GLOBAL_ENTRY(relocate_new_kernel)
++ .prologue
++#ifdef CONFIG_XEN
++ alloc r31=ar.pfs,8,0,0,0
++#else
++ alloc r31=ar.pfs,4,0,0,0
++#endif
++ .body
++.reloc_entry:
++{
++ rsm psr.i| psr.ic
++ mov r2=ip
++}
++ ;;
++{
++ flushrs // must be first insn in group
++ srlz.i
++}
++ ;;
++#ifdef CONFIG_XEN
++ dep r2=0,r2,60,4 //to physical address
++#else
++ dep r2=0,r2,61,3 //to physical address
++#endif
++ ;;
++ //first switch to physical mode
++ add r3=1f-.reloc_entry, r2
++ movl r16 = IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_IC
++ mov ar.rsc=0 // put RSE in enforced lazy mode
++ ;;
++ add sp=(memory_stack_end - 16 - .reloc_entry),r2
++ add r8=(register_stack - .reloc_entry),r2
++ ;;
++ mov r18=ar.rnat
++ mov ar.bspstore=r8
++ ;;
++ mov cr.ipsr=r16
++ mov cr.iip=r3
++ mov cr.ifs=r0
++ srlz.i
++ ;;
++ mov ar.rnat=r18
++ rfi
++ ;;
++1:
++ //physical mode code begin
++ mov b6=in1
++#ifdef CONFIG_XEN
++ dep r28=0,in2,60,4 //to physical address
++#else
++ dep r28=0,in2,61,3 //to physical address
++#endif
++
++ // purge all TC entries
++#define O(member) IA64_CPUINFO_##member##_OFFSET
++#ifdef CONFIG_XEN
++ mov r2=in4 // load phys addr of cpu_info into r2
++#else
++ GET_THIS_PADDR(r2, cpu_info) // load phys addr of cpu_info into r2
++#endif
++ ;;
++ addl r17=O(PTCE_STRIDE),r2
++ addl r2=O(PTCE_BASE),r2
++ ;;
++ ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base
++ ld4 r19=[r2],4 // r19=ptce_count[0]
++ ld4 r21=[r17],4 // r21=ptce_stride[0]
++ ;;
++ ld4 r20=[r2] // r20=ptce_count[1]
++ ld4 r22=[r17] // r22=ptce_stride[1]
++ mov r24=r0
++ ;;
++ adds r20=-1,r20
++ ;;
++#undef O
++2:
++ cmp.ltu p6,p7=r24,r19
++(p7) br.cond.dpnt.few 4f
++ mov ar.lc=r20
++3:
++ ptc.e r18
++ ;;
++ add r18=r22,r18
++ br.cloop.sptk.few 3b
++ ;;
++ add r18=r21,r18
++ add r24=1,r24
++ ;;
++ br.sptk.few 2b
++4:
++ srlz.i
++ ;;
++ //purge TR entry for kernel text and data
++#ifdef CONFIG_XEN
++ mov r16=in5
++#else
++ movl r16=KERNEL_START
++#endif
++ mov r18=KERNEL_TR_PAGE_SHIFT<<2
++ ;;
++ ptr.i r16, r18
++ ptr.d r16, r18
++ ;;
++ srlz.i
++ ;;
++
++ // purge TR entry for percpu data
++ movl r16=PERCPU_ADDR
++ mov r18=PERCPU_PAGE_SHIFT<<2
++ ;;
++ ptr.d r16,r18
++ ;;
++ srlz.d
++ ;;
++
++ // purge TR entry for pal code
++ mov r16=in3
++ mov r18=IA64_GRANULE_SHIFT<<2
++ ;;
++ ptr.i r16,r18
++ ;;
++ srlz.i
++ ;;
++
++ // purge TR entry for stack
++ mov r16=IA64_KR(CURRENT_STACK)
++ ;;
++ shl r16=r16,IA64_GRANULE_SHIFT
++#ifdef CONFIG_XEN
++ mov r19=in6
++#else
++ movl r19=PAGE_OFFSET
++#endif
++ ;;
++ add r16=r19,r16
++ mov r18=IA64_GRANULE_SHIFT<<2
++ ;;
++ ptr.d r16,r18
++ ;;
++ srlz.i
++ ;;
++
++#ifdef XEN
++ /* XXX: Is this neccessary ??? */
++ // purge TR entry for VHPT
++ mov r16=in7
++ ;;
++ dep r16=0,r16,0,IA64_GRANULE_SHIFT
++ mov r18=IA64_GRANULE_SHIFT<<2
++ ;;
++ ptr.d r16,r18
++ ;;
++ srlz.i
++ ;;
++#endif
++
++ //copy segments
++ movl r16=PAGE_MASK
++ mov r30=in0 // in0 is page_list
++ br.sptk.few .dest_page
++ ;;
++.loop:
++ ld8 r30=[in0], 8;;
++.dest_page:
++ tbit.z p0, p6=r30, 0;; // 0x1 dest page
++(p6) and r17=r30, r16
++(p6) br.cond.sptk.few .loop;;
++
++ tbit.z p0, p6=r30, 1;; // 0x2 indirect page
++(p6) and in0=r30, r16
++(p6) br.cond.sptk.few .loop;;
++
++ tbit.z p0, p6=r30, 2;; // 0x4 end flag
++(p6) br.cond.sptk.few .end_loop;;
++
++ tbit.z p6, p0=r30, 3;; // 0x8 source page
++(p6) br.cond.sptk.few .loop
++
++ and r18=r30, r16
++
++ // simple copy page, may optimize later
++ movl r14=PAGE_SIZE/8 - 1;;
++ mov ar.lc=r14;;
++1:
++ ld8 r14=[r18], 8;;
++ st8 [r17]=r14;;
++ fc.i r17
++ add r17=8, r17
++ br.ctop.sptk.few 1b
++ br.sptk.few .loop
++ ;;
++
++.end_loop:
++ sync.i // for fc.i
++ ;;
++ srlz.i
++ ;;
++ srlz.d
++ ;;
++ br.call.sptk.many b0=b6;;
++
++.align 32
++memory_stack:
++#ifdef CONFIG_XEN
++ .fill 4096, 1, 0
++#else
++ .fill 8192, 1, 0
++#endif
++memory_stack_end:
++register_stack:
++#ifdef CONFIG_XEN
++ .fill 4096, 1, 0
++#else
++ .fill 8192, 1, 0
++#endif
++register_stack_end:
++relocate_new_kernel_end:
++END(relocate_new_kernel)
++
++.global relocate_new_kernel_size
++relocate_new_kernel_size:
++ data8 relocate_new_kernel_end - relocate_new_kernel
++
++GLOBAL_ENTRY(ia64_dump_cpu_regs)
++ .prologue
++ alloc loc0=ar.pfs,1,2,0,0
++ .body
++ mov ar.rsc=0 // put RSE in enforced lazy mode
++ add loc1=4*8, in0 // save r4 and r5 first
++ ;;
++{
++ flushrs // flush dirty regs to backing store
++ srlz.i
++}
++ st8 [loc1]=r4, 8
++ ;;
++ st8 [loc1]=r5, 8
++ ;;
++ add loc1=32*8, in0
++ mov r4=ar.rnat
++ ;;
++ st8 [in0]=r0, 8 // r0
++ st8 [loc1]=r4, 8 // rnat
++ mov r5=pr
++ ;;
++ st8 [in0]=r1, 8 // r1
++ st8 [loc1]=r5, 8 // pr
++ mov r4=b0
++ ;;
++ st8 [in0]=r2, 8 // r2
++ st8 [loc1]=r4, 8 // b0
++ mov r5=b1;
++ ;;
++ st8 [in0]=r3, 24 // r3
++ st8 [loc1]=r5, 8 // b1
++ mov r4=b2
++ ;;
++ st8 [in0]=r6, 8 // r6
++ st8 [loc1]=r4, 8 // b2
++ mov r5=b3
++ ;;
++ st8 [in0]=r7, 8 // r7
++ st8 [loc1]=r5, 8 // b3
++ mov r4=b4
++ ;;
++ st8 [in0]=r8, 8 // r8
++ st8 [loc1]=r4, 8 // b4
++ mov r5=b5
++ ;;
++ st8 [in0]=r9, 8 // r9
++ st8 [loc1]=r5, 8 // b5
++ mov r4=b6
++ ;;
++ st8 [in0]=r10, 8 // r10
++ st8 [loc1]=r5, 8 // b6
++ mov r5=b7
++ ;;
++ st8 [in0]=r11, 8 // r11
++ st8 [loc1]=r5, 8 // b7
++ mov r4=b0
++ ;;
++ st8 [in0]=r12, 8 // r12
++ st8 [loc1]=r4, 8 // ip
++ mov r5=loc0
++ ;;
++ st8 [in0]=r13, 8 // r13
++ extr.u r5=r5, 0, 38 // ar.pfs.pfm
++ mov r4=r0 // user mask
++ ;;
++ st8 [in0]=r14, 8 // r14
++ st8 [loc1]=r5, 8 // cfm
++ ;;
++ st8 [in0]=r15, 8 // r15
++ st8 [loc1]=r4, 8 // user mask
++ mov r5=ar.rsc
++ ;;
++ st8 [in0]=r16, 8 // r16
++ st8 [loc1]=r5, 8 // ar.rsc
++ mov r4=ar.bsp
++ ;;
++ st8 [in0]=r17, 8 // r17
++ st8 [loc1]=r4, 8 // ar.bsp
++ mov r5=ar.bspstore
++ ;;
++ st8 [in0]=r18, 8 // r18
++ st8 [loc1]=r5, 8 // ar.bspstore
++ mov r4=ar.rnat
++ ;;
++ st8 [in0]=r19, 8 // r19
++ st8 [loc1]=r4, 8 // ar.rnat
++ mov r5=ar.ccv
++ ;;
++ st8 [in0]=r20, 8 // r20
++ st8 [loc1]=r5, 8 // ar.ccv
++ mov r4=ar.unat
++ ;;
++ st8 [in0]=r21, 8 // r21
++ st8 [loc1]=r4, 8 // ar.unat
++ mov r5 = ar.fpsr
++ ;;
++ st8 [in0]=r22, 8 // r22
++ st8 [loc1]=r5, 8 // ar.fpsr
++ mov r4 = ar.unat
++ ;;
++ st8 [in0]=r23, 8 // r23
++ st8 [loc1]=r4, 8 // unat
++ mov r5 = ar.fpsr
++ ;;
++ st8 [in0]=r24, 8 // r24
++ st8 [loc1]=r5, 8 // fpsr
++ mov r4 = ar.pfs
++ ;;
++ st8 [in0]=r25, 8 // r25
++ st8 [loc1]=r4, 8 // ar.pfs
++ mov r5 = ar.lc
++ ;;
++ st8 [in0]=r26, 8 // r26
++ st8 [loc1]=r5, 8 // ar.lc
++ mov r4 = ar.ec
++ ;;
++ st8 [in0]=r27, 8 // r27
++ st8 [loc1]=r4, 8 // ar.ec
++ mov r5 = ar.csd
++ ;;
++ st8 [in0]=r28, 8 // r28
++ st8 [loc1]=r5, 8 // ar.csd
++ mov r4 = ar.ssd
++ ;;
++ st8 [in0]=r29, 8 // r29
++ st8 [loc1]=r4, 8 // ar.ssd
++ ;;
++ st8 [in0]=r30, 8 // r30
++ ;;
++ st8 [in0]=r31, 8 // r31
++ mov ar.pfs=loc0
++ ;;
++ br.ret.sptk.many rp
++END(ia64_dump_cpu_regs)
++
++
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/salinfo.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/salinfo.c
+--- linux-2.6.18.8/arch/ia64/kernel/salinfo.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/salinfo.c 2008-02-15 16:21:49.000000000 -0800
+@@ -375,6 +375,25 @@ salinfo_log_open(struct inode *inode, st
+ data->open = 0;
+ return -ENOMEM;
+ }
++#ifdef CONFIG_XEN
++ if (is_running_on_xen()) {
++ ia64_mca_xencomm_t *entry;
++ unsigned long flags;
++
++ entry = vmalloc(sizeof(ia64_mca_xencomm_t));
++ if (!entry) {
++ data->open = 0;
++ vfree(data->log_buffer);
++ return -ENOMEM;
++ }
++ entry->record = data->log_buffer;
++ entry->handle = xencomm_map(data->log_buffer,
++ ia64_sal_get_state_info_size(data->type));
++ spin_lock_irqsave(&ia64_mca_xencomm_lock, flags);
++ list_add(&entry->list, &ia64_mca_xencomm_list);
++ spin_unlock_irqrestore(&ia64_mca_xencomm_lock, flags);
++ }
++#endif
+
+ return 0;
+ }
+@@ -386,6 +405,30 @@ salinfo_log_release(struct inode *inode,
+ struct salinfo_data *data = entry->data;
+
+ if (data->state == STATE_NO_DATA) {
++#ifdef CONFIG_XEN
++ if (is_running_on_xen()) {
++ struct list_head *pos, *n;
++ ia64_mca_xencomm_t *found_entry = NULL;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ia64_mca_xencomm_lock, flags);
++ list_for_each_safe(pos, n, &ia64_mca_xencomm_list) {
++ ia64_mca_xencomm_t *entry;
++
++ entry = list_entry(pos, ia64_mca_xencomm_t, list);
++ if (entry->record == data->log_buffer) {
++ list_del(&entry->list);
++ found_entry = entry;
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&ia64_mca_xencomm_lock, flags);
++ if (found_entry) {
++ xencomm_free(found_entry->handle);
++ vfree(found_entry);
++ }
++ }
++#endif
+ vfree(data->log_buffer);
+ vfree(data->oemdata);
+ data->log_buffer = NULL;
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/setup.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/setup.c
+--- linux-2.6.18.8/arch/ia64/kernel/setup.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/setup.c 2008-02-15 16:21:49.000000000 -0800
+@@ -43,6 +43,8 @@
+ #include <linux/initrd.h>
+ #include <linux/pm.h>
+ #include <linux/cpufreq.h>
++#include <linux/kexec.h>
++#include <linux/crash_dump.h>
+
+ #include <asm/ia32.h>
+ #include <asm/machvec.h>
+@@ -60,6 +62,12 @@
#include <asm/system.h>
#include <asm/unistd.h>
#include <asm/system.h>
@@ -23544,7 +25357,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/setup.c tmp-linux-2.6-xen.patc
#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
# error "struct cpuinfo_ia64 too big!"
-@@ -70,6 +76,34 @@ unsigned long __per_cpu_offset[NR_CPUS];
+@@ -70,6 +78,34 @@ unsigned long __per_cpu_offset[NR_CPUS];
EXPORT_SYMBOL(__per_cpu_offset);
#endif
@@ -23579,7 +25392,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/setup.c tmp-linux-2.6-xen.patc
extern void ia64_setup_printk_clock(void);
DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
-@@ -242,6 +276,14 @@ reserve_memory (void)
+@@ -242,6 +278,14 @@ reserve_memory (void)
rsvd_region[n].end = (unsigned long) ia64_imva(_end);
n++;
@@ -23594,59 +25407,148 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/setup.c tmp-linux-2.6-xen.patc
#ifdef CONFIG_BLK_DEV_INITRD
if (ia64_boot_param->initrd_start) {
rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
-@@ -402,6 +444,19 @@ setup_arch (char **cmdline_p)
+@@ -253,6 +297,56 @@ reserve_memory (void)
+ efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
+ n++;
+
++#ifdef CONFIG_KEXEC
++ /* crashkernel=size@offset specifies the size to reserve for a crash
++ * kernel. If offset is 0, then it is determined automatically.
++ * By reserving this memory we guarantee that linux never set's it
++ * up as a DMA target.Useful for holding code to do something
++ * appropriate after a kernel panic.
++ */
++ {
++ char *from = strstr(saved_command_line, "crashkernel=");
++ unsigned long base, size;
++#ifdef CONFIG_XEN
++ if (is_initial_xendomain() && from)
++ printk("Ignoring crashkernel command line, "
++ "parameter will be supplied by xen\n");
++ else {
++#endif
++ if (from) {
++ size = memparse(from + 12, &from);
++ if (*from == '@')
++ base = memparse(from+1, &from);
++ else
++ base = 0;
++ if (size) {
++ if (!base) {
++ sort_regions(rsvd_region, n);
++ base = kdump_find_rsvd_region(size,
++ rsvd_region, n);
++ }
++ if (base != ~0UL) {
++ rsvd_region[n].start =
++ (unsigned long)__va(base);
++ rsvd_region[n].end =
++ (unsigned long)__va(base + size);
++ n++;
++ crashk_res.start = base;
++ crashk_res.end = base + size - 1;
++ }
++ }
++ }
++#ifdef CONFIG_XEN
++ }
++#endif
++ efi_memmap_res.start = ia64_boot_param->efi_memmap;
++ efi_memmap_res.end = efi_memmap_res.start +
++ ia64_boot_param->efi_memmap_size;
++ boot_param_res.start = kexec_virt_to_phys(ia64_boot_param);
++ boot_param_res.end = boot_param_res.start +
++ sizeof(*ia64_boot_param);
++ }
++#endif
+ /* end of memory marker */
+ rsvd_region[n].start = ~0UL;
+ rsvd_region[n].end = ~0UL;
+@@ -264,6 +358,7 @@ reserve_memory (void)
+ sort_regions(rsvd_region, num_rsvd_regions);
+ }
+
++
+ /**
+ * find_initrd - get initrd parameters from the boot parameter structure
+ *
+@@ -397,11 +492,49 @@ static __init int setup_nomca(char *s)
+ }
+ early_param("nomca", setup_nomca);
+
++#ifdef CONFIG_PROC_VMCORE
++/* elfcorehdr= specifies the location of elf core header
++ * stored by the crashed kernel.
++ */
++static int __init parse_elfcorehdr(char *arg)
++{
++ if (!arg)
++ return -EINVAL;
++
++ elfcorehdr_addr = memparse(arg, &arg);
++ return 0;
++}
++early_param("elfcorehdr", parse_elfcorehdr);
++#endif /* CONFIG_PROC_VMCORE */
++
+ void __init
+ setup_arch (char **cmdline_p)
{
++#ifdef CONFIG_XEN
++ shared_info_t *s = NULL;
++ if (is_running_on_xen()) {
++ s = HYPERVISOR_shared_info;
++ xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
++ }
++#endif
++
unw_init();
+#ifdef CONFIG_XEN
+ if (is_running_on_xen()) {
+ /* Must be done before any hypercall. */
-+ xencomm_init();
++ xencomm_initialize();
+
+ setup_xen_features();
+ /* Register a call for panic conditions. */
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &xen_panic_block);
+ pm_power_off = xen_pm_power_off;
++
++ xen_ia64_enable_opt_feature();
+ }
+#endif
+
ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
*cmdline_p = __va(ia64_boot_param->command_line);
-@@ -478,14 +533,79 @@ setup_arch (char **cmdline_p)
- conswitchp = &vga_con;
- # endif
- }
+@@ -462,6 +595,57 @@ setup_arch (char **cmdline_p)
+ acpi_boot_init();
+ #endif
+
+#ifdef CONFIG_XEN
+ if (is_running_on_xen()) {
-+ shared_info_t *s = HYPERVISOR_shared_info;
-+
-+ xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
-+
+ printk("Running on Xen! start_info_pfn=0x%lx nr_pages=%ld "
+ "flags=0x%x\n", s->arch.start_info_pfn,
+ xen_start_info->nr_pages, xen_start_info->flags);
+
-+ if (!is_initial_xendomain()) {
-+#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
-+ conswitchp = NULL;
-+#endif
-+ }
-+
+ /*
+ * If a console= is NOT specified, we assume using the
-+ * xencons console is desired. By default, this is ttyS0
-+ * for dom0 and tty0 for domU.
++ * xencons console is desired. By default, this is xvc0
++ * for both dom0 and domU.
+ */
+ if (!strstr(*cmdline_p, "console=")) {
-+ char *p, *q, name[5];
++ char *p, *q, name[5] = "xvc";
+ int offset = 0;
+
-+ if (is_initial_xendomain())
-+ strncpy(name, "ttyS", 4);
-+ else
++#if defined(CONFIG_VGA_CONSOLE)
++ /*
++ * conswitchp might be set intelligently from the
++ * PCDP code. If set to VGA console, use it.
++ */
++ if (is_initial_xendomain() && conswitchp == &vga_con)
+ strncpy(name, "tty", 3);
++#endif
+
+ p = strstr(*cmdline_p, "xencons=");
+
@@ -23673,47 +25575,114 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/setup.c tmp-linux-2.6-xen.patc
+ add_preferred_console(name, offset, NULL);
+ }
+ }
-+ xencons_early_setup();
+#endif
++
+ #ifdef CONFIG_VT
+ if (!conswitchp) {
+ # if defined(CONFIG_DUMMY_CONSOLE)
+@@ -481,11 +665,28 @@ setup_arch (char **cmdline_p)
#endif
-+
/* enable IA-64 Machine Check Abort Handling unless disabled */
+#ifdef CONFIG_XEN
-+ if (is_running_on_xen() && !is_initial_xendomain())
++ if (is_running_on_xen() && !is_initial_xendomain()) {
+ nomca = 1;
++#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
++ conswitchp = NULL;
++#endif
++ }
+#endif
if (!nomca)
ia64_mca_init();
platform_setup(cmdline_p);
++#ifdef CONFIG_XEN
++ if (is_running_on_xen() && !ia64_platform_is("xen")) {
++ extern ia64_mv_setup_t xen_setup;
++ xen_setup(cmdline_p);
++ }
++#endif
paging_init();
+#ifdef CONFIG_XEN
-+ contiguous_bitmap_init(max_pfn);
++ xen_contiguous_bitmap_init(max_pfn);
+#endif
}
/*
-@@ -870,6 +990,15 @@ cpu_init (void)
+@@ -870,6 +1071,13 @@ cpu_init (void)
/* size of physical stacked register partition plus 8 bytes: */
__get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
platform_cpu_init();
-+
+#ifdef CONFIG_XEN
-+ /* Need to be moved into platform_cpu_init later */
-+ if (is_running_on_xen()) {
-+ extern void xen_smp_intr_init(void);
-+ xen_smp_intr_init();
++ if (is_running_on_xen() && !ia64_platform_is("xen")) {
++ extern ia64_mv_cpu_init_t xen_cpu_init;
++ xen_cpu_init();
+ }
+#endif
+
pm_idle = default_idle;
}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/smp.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/smp.c
---- pristine-linux-2.6.18/arch/ia64/kernel/smp.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/smp.c 2007-11-16 16:18:13.000000000 -0800
-@@ -328,10 +328,14 @@ int
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/smp.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/smp.c
+--- linux-2.6.18.8/arch/ia64/kernel/smp.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/smp.c 2008-02-15 16:21:49.000000000 -0800
+@@ -30,6 +30,7 @@
+ #include <linux/delay.h>
+ #include <linux/efi.h>
+ #include <linux/bitops.h>
++#include <linux/kexec.h>
+
+ #include <asm/atomic.h>
+ #include <asm/current.h>
+@@ -66,6 +67,7 @@ static volatile struct call_data_struct
+
+ #define IPI_CALL_FUNC 0
+ #define IPI_CPU_STOP 1
++#define IPI_KDUMP_CPU_STOP 3
+
+ /* This needs to be cacheline aligned because it is written to by *other* CPUs. */
+ static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
+@@ -155,7 +157,11 @@ handle_IPI (int irq, void *dev_id, struc
+ case IPI_CPU_STOP:
+ stop_this_cpu();
+ break;
+-
++#ifdef CONFIG_KEXEC
++ case IPI_KDUMP_CPU_STOP:
++ unw_init_running(kdump_cpu_freeze, NULL);
++ break;
++#endif
+ default:
+ printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
+ break;
+@@ -213,6 +219,26 @@ send_IPI_self (int op)
+ send_IPI_single(smp_processor_id(), op);
+ }
+
++#ifdef CONFIG_KEXEC
++void
++kdump_smp_send_stop()
++{
++ send_IPI_allbutself(IPI_KDUMP_CPU_STOP);
++}
++
++void
++kdump_smp_send_init()
++{
++ unsigned int cpu, self_cpu;
++ self_cpu = smp_processor_id();
++ for_each_online_cpu(cpu) {
++ if (cpu != self_cpu) {
++ if(kdump_status[cpu] == 0)
++ platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
++ }
++ }
++}
++#endif
+ /*
+ * Called with preeemption disabled.
+ */
+@@ -328,10 +354,14 @@ int
smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait)
{
struct call_data_struct data;
@@ -23730,7 +25699,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/smp.c tmp-linux-2.6-xen.patch/
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
-@@ -343,8 +347,6 @@ smp_call_function (void (*func) (void *i
+@@ -343,8 +373,6 @@ smp_call_function (void (*func) (void *i
if (wait)
atomic_set(&data.finished, 0);
@@ -23739,13 +25708,14 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/smp.c tmp-linux-2.6-xen.patch/
call_data = &data;
mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */
send_IPI_allbutself(IPI_CALL_FUNC);
-diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch/arch/ia64/kernel/time.c
---- pristine-linux-2.6.18/arch/ia64/kernel/time.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/kernel/time.c 2007-11-14 15:35:27.000000000 -0800
-@@ -29,6 +29,13 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/time.c linux-2.6.18-xen-3.2.0/arch/ia64/kernel/time.c
+--- linux-2.6.18.8/arch/ia64/kernel/time.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/time.c 2008-02-15 16:21:49.000000000 -0800
+@@ -29,6 +29,14 @@
#include <asm/sections.h>
#include <asm/system.h>
++#include <asm/hypervisor.h>
+#ifdef CONFIG_XEN
+#include <linux/kernel_stat.h>
+#include <linux/posix-timers.h>
@@ -23756,7 +25726,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch
extern unsigned long wall_jiffies;
volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */
-@@ -40,16 +47,109 @@ EXPORT_SYMBOL(last_cli_ip);
+@@ -40,16 +48,109 @@ EXPORT_SYMBOL(last_cli_ip);
#endif
@@ -23866,7 +25836,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch
if (unlikely(cpu_is_offline(smp_processor_id()))) {
return IRQ_HANDLED;
-@@ -65,6 +165,13 @@ timer_interrupt (int irq, void *dev_id,
+@@ -65,6 +166,13 @@ timer_interrupt (int irq, void *dev_id,
profile_tick(CPU_PROFILING, regs);
@@ -23880,7 +25850,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch
while (1) {
update_process_times(user_mode(regs));
-@@ -88,6 +195,8 @@ timer_interrupt (int irq, void *dev_id,
+@@ -88,6 +196,8 @@ timer_interrupt (int irq, void *dev_id,
break;
}
@@ -23889,7 +25859,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch
do {
/*
* If we're too close to the next clock tick for
-@@ -142,6 +251,85 @@ static int __init nojitter_setup(char *s
+@@ -142,6 +252,85 @@ static int __init nojitter_setup(char *s
__setup("nojitter", nojitter_setup);
@@ -23975,7 +25945,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch
void __devinit
ia64_init_itm (void)
-@@ -225,6 +413,12 @@ ia64_init_itm (void)
+@@ -225,6 +414,12 @@ ia64_init_itm (void)
register_time_interpolator(&itc_interpolator);
}
@@ -23988,22 +25958,116 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/kernel/time.c tmp-linux-2.6-xen.patch
/* Setup the CPU local timer tick */
ia64_cpu_local_tick();
}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/mm/ioremap.c tmp-linux-2.6-xen.patch/arch/ia64/mm/ioremap.c
---- pristine-linux-2.6.18/arch/ia64/mm/ioremap.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/mm/ioremap.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/vmlinux.lds.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/vmlinux.lds.S
+--- linux-2.6.18.8/arch/ia64/kernel/vmlinux.lds.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/vmlinux.lds.S 2008-02-15 16:21:49.000000000 -0800
+@@ -183,6 +183,12 @@ SECTIONS
+ __start_gate_section = .;
+ *(.data.gate)
+ __stop_gate_section = .;
++#if defined(CONFIG_XEN)
++ . = ALIGN(PAGE_SIZE);
++ __start_xen_gate_section = .;
++ *(.data.gate.xen)
++ __stop_xen_gate_section = .;
++#endif
+ }
+ . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */
+
+diff -rpuN linux-2.6.18.8/arch/ia64/kernel/xengate-data.S linux-2.6.18-xen-3.2.0/arch/ia64/kernel/xengate-data.S
+--- linux-2.6.18.8/arch/ia64/kernel/xengate-data.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/kernel/xengate-data.S 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,3 @@
++ .section .data.gate.xen, "aw"
++
++ .incbin "arch/ia64/kernel/xengate.so"
+diff -rpuN linux-2.6.18.8/arch/ia64/mm/contig.c linux-2.6.18-xen-3.2.0/arch/ia64/mm/contig.c
+--- linux-2.6.18.8/arch/ia64/mm/contig.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/mm/contig.c 2008-02-15 16:21:49.000000000 -0800
+@@ -18,6 +18,9 @@
+ #include <linux/efi.h>
+ #include <linux/mm.h>
+ #include <linux/swap.h>
++#ifdef CONFIG_XEN
++#include <linux/kexec.h>
++#endif
+
+ #include <asm/meminit.h>
+ #include <asm/pgalloc.h>
+@@ -172,8 +175,17 @@ find_memory (void)
+ /* Free all available memory, then mark bootmem-map as being in use. */
+ efi_memmap_walk(filter_rsvd_memory, free_bootmem);
+ reserve_bootmem(bootmap_start, bootmap_size);
++#if defined(CONFIG_XEN) && defined(CONFIG_KEXEC)
++ xen_machine_kexec_setup_resources();
++#endif
+
+ find_initrd();
++
++#ifdef CONFIG_CRASH_DUMP
++ /* If we are doing a crash dump, we still need to know the real mem
++ * size before original memory map is * reset. */
++ saved_max_pfn = max_pfn;
++#endif
+ }
+
+ #ifdef CONFIG_SMP
+diff -rpuN linux-2.6.18.8/arch/ia64/mm/init.c linux-2.6.18-xen-3.2.0/arch/ia64/mm/init.c
+--- linux-2.6.18.8/arch/ia64/mm/init.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/mm/init.c 2008-02-15 16:21:49.000000000 -0800
+@@ -303,16 +303,34 @@ static void __init
+ setup_gate (void)
+ {
+ struct page *page;
++ void *gate_page_addr = __start_gate_section;
++
++#ifdef CONFIG_XEN
++ unsigned long unused_gate;
++ extern char __start_xen_gate_section[];
++ if (is_running_on_xen()) {
++ gate_page_addr = __start_xen_gate_section;
++ unused_gate = (unsigned long)ia64_imva(__start_gate_section);
++ } else
++ unused_gate =
++ (unsigned long)ia64_imva(__start_xen_gate_section);
++#ifndef HAVE_BUGGY_SEGREL
++ ClearPageReserved(virt_to_page(unused_gate));
++ init_page_count(virt_to_page(unused_gate));
++ free_page(unused_gate);
++ ++totalram_pages;
++#endif
++#endif
+
+ /*
+ * Map the gate page twice: once read-only to export the ELF
+ * headers etc. and once execute-only page to enable
+ * privilege-promotion via "epc":
+ */
+- page = virt_to_page(ia64_imva(__start_gate_section));
++ page = virt_to_page(ia64_imva(gate_page_addr));
+ put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
+ #ifdef HAVE_BUGGY_SEGREL
+- page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
++ page = virt_to_page(ia64_imva(gate_page_addr + PAGE_SIZE));
+ put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
+ #else
+ put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
+diff -rpuN linux-2.6.18.8/arch/ia64/mm/ioremap.c linux-2.6.18-xen-3.2.0/arch/ia64/mm/ioremap.c
+--- linux-2.6.18.8/arch/ia64/mm/ioremap.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/mm/ioremap.c 2008-02-15 16:21:49.000000000 -0800
@@ -16,6 +16,9 @@
static inline void __iomem *
__ioremap (unsigned long offset, unsigned long size)
{
+ offset = HYPERVISOR_ioremap(offset, size);
+ if (IS_ERR_VALUE(offset))
-+ return (void __iomem*)offset;
++ return NULL;
return (void __iomem *) (__IA64_UNCACHED_OFFSET | offset);
}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/Makefile tmp-linux-2.6-xen.patch/arch/ia64/oprofile/Makefile
---- pristine-linux-2.6.18/arch/ia64/oprofile/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/oprofile/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/oprofile/Makefile linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/Makefile
+--- linux-2.6.18.8/arch/ia64/oprofile/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -8,3 +8,7 @@ DRIVER_OBJS := $(addprefix ../../../driv
oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
@@ -24012,18 +26076,19 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/Makefile tmp-linux-2.6-xen.p
+oprofile-$(CONFIG_PERFMON) += xenoprof.o \
+ ../../../drivers/xen/xenoprof/xenoprofile.o
+endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/init.c tmp-linux-2.6-xen.patch/arch/ia64/oprofile/init.c
---- pristine-linux-2.6.18/arch/ia64/oprofile/init.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/oprofile/init.c 2007-11-14 15:35:27.000000000 -0800
-@@ -11,6 +11,7 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/oprofile/init.c linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/init.c
+--- linux-2.6.18.8/arch/ia64/oprofile/init.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/init.c 2008-02-15 16:21:49.000000000 -0800
+@@ -11,6 +11,8 @@
#include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/errno.h>
++#include <asm/hypervisor.h>
+#include "oprofile_perfmon.h"
extern int perfmon_init(struct oprofile_operations * ops);
extern void perfmon_exit(void);
-@@ -20,6 +21,13 @@ int __init oprofile_arch_init(struct opr
+@@ -20,6 +22,13 @@ int __init oprofile_arch_init(struct opr
{
int ret = -ENODEV;
@@ -24037,7 +26102,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/init.c tmp-linux-2.6-xen.pat
#ifdef CONFIG_PERFMON
/* perfmon_init() can fail, but we have no way to report it */
ret = perfmon_init(ops);
-@@ -32,6 +40,12 @@ int __init oprofile_arch_init(struct opr
+@@ -32,6 +41,12 @@ int __init oprofile_arch_init(struct opr
void oprofile_arch_exit(void)
{
@@ -24050,18 +26115,20 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/init.c tmp-linux-2.6-xen.pat
#ifdef CONFIG_PERFMON
perfmon_exit();
#endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/oprofile_perfmon.h tmp-linux-2.6-xen.patch/arch/ia64/oprofile/oprofile_perfmon.h
---- pristine-linux-2.6.18/arch/ia64/oprofile/oprofile_perfmon.h 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/oprofile/oprofile_perfmon.h 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,28 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/oprofile/oprofile_perfmon.h linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/oprofile_perfmon.h
+--- linux-2.6.18.8/arch/ia64/oprofile/oprofile_perfmon.h 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/oprofile_perfmon.h 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,30 @@
+#ifndef OPROFILE_PERFMON_H
+#define OPROFILE_PERFMON_H
+
+#ifdef CONFIG_PERFMON
++#ifdef CONFIG_XEN
+int __perfmon_init(void);
+void __perfmon_exit(void);
+int perfmon_start(void);
+void perfmon_stop(void);
++#endif
+#else
+#define __perfmon_init() (-ENOSYS)
+#define __perfmon_exit() do {} while (0)
@@ -24077,14 +26144,14 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/oprofile_perfmon.h tmp-linux
+#define STATIC_IF_NO_XEN static
+#define xen_perfmon_init() (-ENOSYS)
+#define xen_perfmon_exit() do {} while (0)
-+#define xenoprofile_init() (-ENOSYS)
++#define xenoprofile_init(ops) (-ENOSYS)
+#define xenoprofile_exit() do {} while (0)
+#endif /* CONFIG_XEN */
+
+#endif /* OPROFILE_PERFMON_H */
-diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/perfmon.c tmp-linux-2.6-xen.patch/arch/ia64/oprofile/perfmon.c
---- pristine-linux-2.6.18/arch/ia64/oprofile/perfmon.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/oprofile/perfmon.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/oprofile/perfmon.c linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/perfmon.c
+--- linux-2.6.18.8/arch/ia64/oprofile/perfmon.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/perfmon.c 2008-02-15 16:21:49.000000000 -0800
@@ -13,6 +13,7 @@
#include <asm/perfmon.h>
#include <asm/ptrace.h>
@@ -24160,9 +26227,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/perfmon.c tmp-linux-2.6-xen.
- pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
+ __perfmon_exit();
}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c tmp-linux-2.6-xen.patch/arch/ia64/oprofile/xenoprof.c
---- pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/oprofile/xenoprof.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/oprofile/xenoprof.c linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/xenoprof.c
+--- linux-2.6.18.8/arch/ia64/oprofile/xenoprof.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/oprofile/xenoprof.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,142 @@
+/******************************************************************************
+ * xenoprof ia64 specific part
@@ -24217,9 +26284,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c tmp-linux-2.6-xen
+}
+
+/* XXX move them to an appropriate header file. */
-+struct resource* xen_ia64_allocate_resource(unsigned long size);
-+void xen_ia64_release_resource(struct resource* res);
-+void xen_ia64_unmap_resource(struct resource* res);
++struct resource* xen_ia64_allocate_resource(unsigned long size);
++void xen_ia64_release_resource(struct resource *res);
++void xen_ia64_unmap_resource(struct resource *res);
+
+struct resource*
+xenoprof_ia64_allocate_resource(int32_t max_samples)
@@ -24239,7 +26306,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c tmp-linux-2.6-xen
+ return xen_ia64_allocate_resource(bufsize);
+}
+
-+void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf)
++void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer *sbuf)
+{
+ if (sbuf->buffer) {
+ xen_ia64_unmap_resource(sbuf->arch.res);
@@ -24248,11 +26315,11 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c tmp-linux-2.6-xen
+ }
+}
+
-+int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer,
-+ struct xenoprof_shared_buffer* sbuf)
++int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer *get_buffer,
++ struct xenoprof_shared_buffer *sbuf)
+{
+ int ret;
-+ struct resource* res;
++ struct resource *res;
+
+ sbuf->buffer = NULL;
+ sbuf->arch.res = NULL;
@@ -24278,11 +26345,11 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c tmp-linux-2.6-xen
+ return ret;
+}
+
-+int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain,
-+ struct xenoprof_shared_buffer* sbuf)
++int xenoprof_arch_set_passive(struct xenoprof_passive *pdomain,
++ struct xenoprof_shared_buffer *sbuf)
+{
+ int ret;
-+ struct resource* res;
++ struct resource *res;
+
+ sbuf->buffer = NULL;
+ sbuf->arch.res = NULL;
@@ -24306,10 +26373,26 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/oprofile/xenoprof.c tmp-linux-2.6-xen
+
+ return ret;
+}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/pci/pci.c tmp-linux-2.6-xen.patch/arch/ia64/pci/pci.c
---- pristine-linux-2.6.18/arch/ia64/pci/pci.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/ia64/pci/pci.c 2007-11-14 15:35:27.000000000 -0800
-@@ -165,6 +165,11 @@ new_space (u64 phys_base, int sparse)
+diff -rpuN linux-2.6.18.8/arch/ia64/pci/pci.c linux-2.6.18-xen-3.2.0/arch/ia64/pci/pci.c
+--- linux-2.6.18.8/arch/ia64/pci/pci.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/pci/pci.c 2008-02-15 16:21:49.000000000 -0800
+@@ -30,6 +30,15 @@
+ #include <asm/irq.h>
+ #include <asm/hw_irq.h>
+
++#ifdef CONFIG_XEN
++struct ioremap_issue_list {
++ struct list_head listp;
++ unsigned long start;
++ unsigned long end;
++};
++typedef struct ioremap_issue_list ioremap_issue_list_t;
++#endif /* CONFIG_XEN */
++
+ /*
+ * Low-level SAL-based PCI configuration access functions. Note that SAL
+ * calls are already serialized (via sal_lock), so we don't need another
+@@ -165,6 +174,11 @@ new_space (u64 phys_base, int sparse)
io_space[i].mmio_base = mmio_base;
io_space[i].sparse = sparse;
@@ -24321,37 +26404,196 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/pci/pci.c tmp-linux-2.6-xen.patch/arc
return i;
}
-@@ -607,6 +612,14 @@ pci_mmap_page_range (struct pci_dev *dev
- else
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+@@ -332,6 +346,169 @@ pcibios_setup_root_windows(struct pci_bu
+ }
+ }
-+ if (is_initial_xendomain()) {
-+ unsigned long addr = vma->vm_pgoff << PAGE_SHIFT;
-+ size_t size = vma->vm_end - vma->vm_start;
-+ unsigned long offset = HYPERVISOR_ioremap(addr, size);
-+ if (IS_ERR_VALUE(offset))
-+ return offset;
++#ifdef CONFIG_XEN
++static void __devinit
++__cleanup_issue_list(struct list_head *top)
++{
++ ioremap_issue_list_t *ptr, *tmp_ptr;
++
++ list_for_each_entry_safe(ptr, tmp_ptr, top, listp) {
++ list_del(&(ptr->listp));
++ kfree(ptr);
++ }
++}
++
++static int __devinit
++__add_issue_list(unsigned long start, unsigned long end, struct list_head *top)
++{
++ ioremap_issue_list_t *ptr, *new;
++
++ if (start > end) {
++ printk(KERN_ERR "%s: Internal error (start addr > end addr)\n",
++ __FUNCTION__);
++ return 0;
++ }
++
++ /*
++ * Head of the resource structure list contains
++ * dummy val.(start=0, end=~0), so skip it
++ */
++ if ((start == 0) && (end == ~0))
++ return 0;
++
++ start &= PAGE_MASK;
++ end |= ~PAGE_MASK;
++
++ /* We can merge specified address range into existing entry */
++ list_for_each_entry(ptr, top, listp) {
++ if ((ptr->start > end + 1) || (ptr->end + 1 < start))
++ continue;
++ ptr->start = min(start, ptr->start);
++ ptr->end = max(end, ptr->end);
++ return 0;
++ }
++
++ /* We could not merge, so create new entry */
++ new = kmalloc(sizeof(ioremap_issue_list_t), GFP_KERNEL);
++ if (new == NULL) {
++ printk(KERN_ERR "%s: Could not allocate memory. "
++ "HYPERVISOR_ioremap will not be issued\n",
++ __FUNCTION__);
++ return -ENOMEM;
+ }
+
- if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
- vma->vm_end - vma->vm_start, vma->vm_page_prot))
- return -EAGAIN;
-@@ -664,6 +677,14 @@ pci_mmap_legacy_page_range(struct pci_bu
- vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT;
- vma->vm_page_prot = prot;
++ new->start = start;
++ new->end = end;
++
++ /* Insert the new entry to the list by ascending order */
++ if (list_empty(top)) {
++ list_add_tail(&(new->listp), top);
++ return 0;
++ }
++ list_for_each_entry(ptr, top, listp) {
++ if (new->start > ptr->start)
++ continue;
++ list_add(&(new->listp), ((struct list_head *)ptr)->prev);
++ return 0;
++ }
++ list_add_tail(&(new->listp), top);
++
++ return 0;
++}
++
++static int __devinit
++__make_issue_list(struct resource *ptr, struct list_head *top)
++{
++ int ret;
++
++ if (ptr->child) {
++ ret = __make_issue_list(ptr->child, top);
++ if (ret)
++ return ret;
++ }
++ if (ptr->sibling) {
++ ret = __make_issue_list(ptr->sibling, top);
++ if (ret)
++ return ret;
++ }
++
++ if (ptr->flags & IORESOURCE_MEM) {
++ ret = __add_issue_list(ptr->start, ptr->end, top);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static void __devinit
++__compress_issue_list(struct list_head *top)
++{
++ ioremap_issue_list_t *ptr, *tmp_ptr, *next;
++ int compressed;
++
++ /*
++ * Merge adjacent entries, if overlapped
++ * (entries are sorted by ascending order)
++ */
++ list_for_each_entry_safe(ptr, tmp_ptr, top, listp) {
++ if (list_is_last((struct list_head *)ptr, top))
++ continue;
++
++ next = (ioremap_issue_list_t *)
++ (((struct list_head *)ptr)->next);
++ if (next->start <= (ptr->end) + 1) {
++ next->start = min(ptr->start, next->start);
++ next->end = max(ptr->end, next->end);
++
++ list_del(&(ptr->listp));
++ kfree(ptr);
++ }
++ }
++}
++
++static int __devinit
++__issue_ioremap(struct list_head *top)
++{
++ ioremap_issue_list_t *ptr, *tmp_ptr;
++ unsigned int offset;
++
++ list_for_each_entry_safe(ptr, tmp_ptr, top, listp) {
++ offset = HYPERVISOR_ioremap(ptr->start,
++ ptr->end - ptr->start + 1);
++ if (offset == ~0) {
++ printk(KERN_ERR "%s: HYPERVISOR_ioremap() failed. "
++ "Address Range: 0x%016lx-0x%016lx\n",
++ __FUNCTION__, ptr->start, ptr->end);
++ }
++
++ list_del(&(ptr->listp));
++ kfree(ptr);
++ }
++
++ return 0;
++}
++
++static int __devinit
++do_ioremap_on_resource_list(struct resource *top)
++{
++ LIST_HEAD(ioremap_issue_list_top);
++ int ret;
++
++ ret = __make_issue_list(top, &ioremap_issue_list_top);
++ if (ret) {
++ __cleanup_issue_list(&ioremap_issue_list_top);
++ return ret;
++ }
++
++ __compress_issue_list(&ioremap_issue_list_top);
++
++ (void)__issue_ioremap(&ioremap_issue_list_top);
++
++ return 0;
++}
++#endif /* CONFIG_XEN */
++
+ struct pci_bus * __devinit
+ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
+ {
+@@ -375,6 +552,18 @@ pci_acpi_scan_root(struct acpi_device *d
+ if (pbus)
+ pcibios_setup_root_windows(pbus, controller);
++#ifdef CONFIG_XEN
+ if (is_initial_xendomain()) {
-+ unsigned long addr = vma->vm_pgoff << PAGE_SHIFT;
-+ size_t size = vma->vm_end - vma->vm_start;
-+ unsigned long offset = HYPERVISOR_ioremap(addr, size);
-+ if (IS_ERR_VALUE(offset))
-+ return offset;
++ if (do_ioremap_on_resource_list(&iomem_resource) != 0) {
++ printk(KERN_ERR
++ "%s: Counld not issue HYPERVISOR_ioremap "
++ "due to lack of memory or hypercall failure\n",
++ __FUNCTION__);
++ goto out3;
++ }
+ }
++#endif /* CONFIG_XEN */
+
- if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
- size, vma->vm_page_prot))
- return -EAGAIN;
-@@ -818,3 +839,31 @@ int pci_vector_resources(int last, int n
+ return pbus;
+
+ out3:
+@@ -818,3 +1007,31 @@ int pci_vector_resources(int last, int n
return count;
}
@@ -24383,36 +26625,112 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/pci/pci.c tmp-linux-2.6-xen.patch/arc
+}
+EXPORT_SYMBOL(xen_pcibios_setup_root_windows);
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/Makefile tmp-linux-2.6-xen.patch/arch/ia64/xen/Makefile
---- pristine-linux-2.6.18/arch/ia64/xen/Makefile 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/sn/kernel/setup.c linux-2.6.18-xen-3.2.0/arch/ia64/sn/kernel/setup.c
+--- linux-2.6.18.8/arch/ia64/sn/kernel/setup.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/sn/kernel/setup.c 2008-02-15 16:21:49.000000000 -0800
+@@ -763,5 +763,13 @@ int sn_prom_feature_available(int id)
+ return 0;
+ return test_bit(id, sn_prom_features);
+ }
++
++void
++sn_kernel_launch_event(void)
++{
++ /* ignore status until we understand possible failure, if any*/
++ if (ia64_sn_kernel_launch_event())
++ printk(KERN_ERR "KEXEC is not supported in this PROM, Please update the PROM.\n");
++}
+ EXPORT_SYMBOL(sn_prom_feature_available);
+
+diff -rpuN linux-2.6.18.8/arch/ia64/sn/pci/pcibr/pcibr_provider.c linux-2.6.18-xen-3.2.0/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+--- linux-2.6.18.8/arch/ia64/sn/pci/pcibr/pcibr_provider.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/sn/pci/pcibr/pcibr_provider.c 2008-02-15 16:21:49.000000000 -0800
+@@ -15,6 +15,7 @@
+ #include <asm/sn/pcibus_provider_defs.h>
+ #include <asm/sn/pcidev.h>
+ #include <asm/sn/sn_sal.h>
++#include <asm/sn/pic.h>
+ #include <asm/sn/sn2/sn_hwperf.h>
+ #include "xtalk/xwidgetdev.h"
+ #include "xtalk/hubdev.h"
+@@ -129,9 +130,9 @@ pcibr_bus_fixup(struct pcibus_bussoft *p
+ }
+
+ memcpy(soft, prom_bussoft, sizeof(struct pcibus_info));
+- soft->pbi_buscommon.bs_base =
+- (((u64) soft->pbi_buscommon.
+- bs_base << 4) >> 4) | __IA64_UNCACHED_OFFSET;
++ soft->pbi_buscommon.bs_base = (unsigned long)
++ ioremap(REGION_OFFSET(soft->pbi_buscommon.bs_base),
++ sizeof(struct pic));
+
+ spin_lock_init(&soft->pbi_lock);
+
+diff -rpuN linux-2.6.18.8/arch/ia64/sn/pci/tioca_provider.c linux-2.6.18-xen-3.2.0/arch/ia64/sn/pci/tioca_provider.c
+--- linux-2.6.18.8/arch/ia64/sn/pci/tioca_provider.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/sn/pci/tioca_provider.c 2008-02-15 16:21:49.000000000 -0800
+@@ -611,7 +611,9 @@ tioca_bus_fixup(struct pcibus_bussoft *p
+ return NULL;
+
+ memcpy(tioca_common, prom_bussoft, sizeof(struct tioca_common));
+- tioca_common->ca_common.bs_base |= __IA64_UNCACHED_OFFSET;
++ tioca_common->ca_common.bs_base = (unsigned long)
++ ioremap(REGION_OFFSET(tioca_common->ca_common.bs_base),
++ sizeof(struct tioca_common));
+
+ /* init kernel-private area */
+
+diff -rpuN linux-2.6.18.8/arch/ia64/sn/pci/tioce_provider.c linux-2.6.18-xen-3.2.0/arch/ia64/sn/pci/tioce_provider.c
+--- linux-2.6.18.8/arch/ia64/sn/pci/tioce_provider.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/sn/pci/tioce_provider.c 2008-02-15 16:21:49.000000000 -0800
+@@ -1006,7 +1006,9 @@ tioce_bus_fixup(struct pcibus_bussoft *p
+ return NULL;
+
+ memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common));
+- tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET;
++ tioce_common->ce_pcibus.bs_base = (unsigned long)
++ ioremap(REGION_OFFSET(tioce_common->ce_pcibus.bs_base),
++ sizeof(struct tioce_common));
+
+ tioce_kern = tioce_kern_init(tioce_common);
+ if (tioce_kern == NULL) {
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/Makefile linux-2.6.18-xen-3.2.0/arch/ia64/xen/Makefile
+--- linux-2.6.18.8/arch/ia64/xen/Makefile 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/Makefile 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,9 @@
+#
+# Makefile for Xen components
+#
+
+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \
-+ hypervisor.o pci-dma-xen.o util.o xencomm.o xcom_hcall.o \
-+ xcom_mini.o xcom_privcmd.o mem.o
++ hypervisor.o util.o xencomm.o xcom_hcall.o \
++ xcom_privcmd.o xen_dma.o
+
-+pci-dma-xen-y := ../../i386/kernel/pci-dma-xen.o
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypercall.S tmp-linux-2.6-xen.patch/arch/ia64/xen/hypercall.S
---- pristine-linux-2.6.18/arch/ia64/xen/hypercall.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/hypercall.S 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,170 @@
++obj-$(CONFIG_IA64_GENERIC) += machvec.o
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/hypercall.S linux-2.6.18-xen-3.2.0/arch/ia64/xen/hypercall.S
+--- linux-2.6.18.8/arch/ia64/xen/hypercall.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/hypercall.S 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,141 @@
+/*
+ * Support routines for Xen hypercalls
+ *
+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
+ */
+
-+#include <asm/processor.h>
+#include <asm/asmmacro.h>
++#include <asm/intrinsics.h>
++
++#ifdef __INTEL_COMPILER
++# undef ASM_SUPPORTED
++#else
++# define ASM_SUPPORTED
++#endif
+
++#ifndef ASM_SUPPORTED
+GLOBAL_ENTRY(xen_get_psr)
+ XEN_HYPER_GET_PSR
+ br.ret.sptk.many rp
-+ ;;
++ ;;
+END(xen_get_psr)
+
+GLOBAL_ENTRY(xen_get_ivr)
@@ -24515,65 +26833,29 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypercall.S tmp-linux-2.6-xen.pat
+ XEN_HYPER_SET_EFLAG
+ br.ret.sptk.many rp
+END(xen_set_eflag)
-+#endif
++#endif /* CONFIG_IA32_SUPPORT */
++#endif /* ASM_SUPPORTED */
+
+GLOBAL_ENTRY(xen_send_ipi)
-+ mov r14=r32
-+ mov r15=r33
-+ mov r2=0x400
-+ break 0x1000
-+ ;;
-+ br.ret.sptk.many rp
-+ ;;
++ mov r14=r32
++ mov r15=r33
++ mov r2=0x400
++ break 0x1000
++ ;;
++ br.ret.sptk.many rp
++ ;;
+END(xen_send_ipi)
+
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+// Those are vdso specialized.
-+// In fsys mode, call, ret can't be used.
-+
-+ // see xen_ssm_i() in privop.h
-+ // r22 = &vcpu->vcpu_info->evtchn_upcall_mask
-+ // r23 = &vpsr.ic
-+ // r24 = &vcpu->vcpu_info->evtchn_upcall_pending
-+ // r25 = tmp
-+ // r31 = tmp
-+ // p11 = tmp
-+ // p14 = tmp
-+#define XEN_SET_PSR_I \
-+ ld1 r31=[r22]; \
-+ ld1 r25=[r24]; \
-+ ;; \
-+ st1 [r22]=r0; \
-+ cmp.ne.unc p14,p0=r0,r31; \
-+ ;; \
-+(p14) cmp.ne.unc p11,p0=r0,r25; \
-+ ;; \
-+(p11) st1 [r22]=r20; \
-+(p11) XEN_HYPER_SSM_I;
-+
-+GLOBAL_ENTRY(xen_ssm_i_0)
-+ XEN_SET_PSR_I
-+ brl.cond.sptk .vdso_ssm_i_0_ret
-+ ;;
-+END(xen_ssm_i_0)
-+
-+GLOBAL_ENTRY(xen_ssm_i_1)
-+ XEN_SET_PSR_I
-+ brl.cond.sptk .vdso_ssm_i_1_ret
-+ ;;
-+END(xen_ssm_i_1)
-+
+GLOBAL_ENTRY(__hypercall)
+ mov r2=r37
+ break 0x1000
+ br.ret.sptk.many b0
+ ;;
+END(__hypercall)
-+#endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.patch/arch/ia64/xen/hypervisor.c
---- pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/hypervisor.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,1234 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/hypervisor.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/hypervisor.c
+--- linux-2.6.18.8/arch/ia64/xen/hypervisor.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/hypervisor.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,1511 @@
+/******************************************************************************
+ * include/asm-ia64/shadow.h
+ *
@@ -24596,7 +26878,6 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ *
+ */
+
-+//#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
@@ -24608,15 +26889,16 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+#include <asm/hypervisor.h>
+#include <asm/hypercall.h>
+#include <xen/interface/memory.h>
++#include <xen/xencons.h>
+#include <xen/balloon.h>
+
-+shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)XSI_BASE;
++shared_info_t *HYPERVISOR_shared_info __read_mostly =
++ (shared_info_t *)XSI_BASE;
+EXPORT_SYMBOL(HYPERVISOR_shared_info);
+
+start_info_t *xen_start_info;
+EXPORT_SYMBOL(xen_start_info);
+
-+int running_on_xen;
+EXPORT_SYMBOL(running_on_xen);
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
@@ -24628,15 +26910,44 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+EXPORT_SYMBOL(__hypercall);
+
-+//XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
-+// move those to lib/contiguous_bitmap?
-+//XXX discontigmem/sparsemem
++void __init
++xen_setup(char **cmdline_p)
++{
++ struct dom0_vga_console_info *info;
++ extern void dig_setup(char **cmdline_p);
++
++ if (ia64_platform_is("xen"))
++ dig_setup(cmdline_p);
++
++ if (!is_running_on_xen() || !is_initial_xendomain())
++ return;
++
++ info = (void *)((char *)xen_start_info +
++ xen_start_info->console.dom0.info_off);
++ dom0_init_screen_info(info, xen_start_info->console.dom0.info_size);
++
++ xen_start_info->console.domU.mfn = 0;
++ xen_start_info->console.domU.evtchn = 0;
++}
++
++void __cpuinit
++xen_cpu_init(void)
++{
++ extern void xen_smp_intr_init(void);
++ xen_smp_intr_init();
++}
++
++/*
++ *XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
++ * move those to lib/contiguous_bitmap?
++ *XXX discontigmem/sparsemem
++ */
+
+/*
+ * Bitmap is indexed by page number. If bit is set, the page is part of a
+ * xen_create_contiguous_region() area of memory.
+ */
-+unsigned long *contiguous_bitmap;
++unsigned long *contiguous_bitmap __read_mostly;
+
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+/* Following logic is stolen from create_mem_map_table() for virtual memmap */
@@ -24653,16 +26964,16 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ pte_t *pte;
+
+ bitmap_start = (unsigned long)contiguous_bitmap +
-+ ((__pa(start) >> PAGE_SHIFT) >> 3);
++ ((__pa(start) >> PAGE_SHIFT) >> 3);
+ bitmap_end = (unsigned long)contiguous_bitmap +
-+ (((__pa(end) >> PAGE_SHIFT) + 2 * BITS_PER_LONG) >> 3);
++ (((__pa(end) >> PAGE_SHIFT) + 2 * BITS_PER_LONG) >> 3);
+
+ start_page = bitmap_start & PAGE_MASK;
+ end_page = PAGE_ALIGN(bitmap_end);
+ node = paddr_to_nid(__pa(start));
+
+ bitmap = alloc_bootmem_pages_node(NODE_DATA(node),
-+ end_page - start_page);
++ end_page - start_page);
+ BUG_ON(!bitmap);
+ memset(bitmap, 0, end_page - start_page);
+
@@ -24670,26 +26981,26 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ pgd = pgd_offset_k(address);
+ if (pgd_none(*pgd))
+ pgd_populate(&init_mm, pgd,
-+ alloc_bootmem_pages_node(NODE_DATA(node),
-+ PAGE_SIZE));
++ alloc_bootmem_pages_node(NODE_DATA(node),
++ PAGE_SIZE));
+ pud = pud_offset(pgd, address);
+
+ if (pud_none(*pud))
+ pud_populate(&init_mm, pud,
-+ alloc_bootmem_pages_node(NODE_DATA(node),
-+ PAGE_SIZE));
++ alloc_bootmem_pages_node(NODE_DATA(node),
++ PAGE_SIZE));
+ pmd = pmd_offset(pud, address);
+
+ if (pmd_none(*pmd))
+ pmd_populate_kernel(&init_mm, pmd,
-+ alloc_bootmem_pages_node
-+ (NODE_DATA(node), PAGE_SIZE));
++ alloc_bootmem_pages_node
++ (NODE_DATA(node), PAGE_SIZE));
+ pte = pte_offset_kernel(pmd, address);
+
+ if (pte_none(*pte))
+ set_pte(pte,
-+ pfn_pte(__pa(bitmap + (address - start_page))
-+ >> PAGE_SHIFT, PAGE_KERNEL));
++ pfn_pte(__pa(bitmap + (address - start_page))
++ >> PAGE_SHIFT, PAGE_KERNEL));
+ }
+ return 0;
+}
@@ -24704,7 +27015,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+}
+
+void
-+contiguous_bitmap_init(unsigned long end_pfn)
++xen_contiguous_bitmap_init(unsigned long end_pfn)
+{
+ unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
+#ifndef CONFIG_VIRTUAL_MEM_MAP
@@ -24774,9 +27085,11 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ }
+}
+
-+// __xen_create_contiguous_region(), __xen_destroy_contiguous_region()
-+// are based on i386 xen_create_contiguous_region(),
-+// xen_destroy_contiguous_region()
++/*
++ * __xen_create_contiguous_region(), __xen_destroy_contiguous_region()
++ * are based on i386 xen_create_contiguous_region(),
++ * xen_destroy_contiguous_region()
++ */
+
+/* Protected by balloon_lock. */
+#define MAX_CONTIG_ORDER 7
@@ -24822,9 +27135,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ balloon_lock(flags);
+
+ /* Get a new contiguous memory extent. */
-+ for (i = 0; i < num_gpfn; i++) {
++ for (i = 0; i < num_gpfn; i++)
+ in_frames[i] = start_gpfn + i;
-+ }
+ out_frame = start_gpfn;
+ error = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
+ success = (exchange.nr_exchanged == num_gpfn);
@@ -24906,7 +27218,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ .domid = DOMID_SELF
+ },
+ .nr_exchanged = 0
-+ };
++ };
+
+
+ if (!test_bit(start_gpfn, contiguous_bitmap))
@@ -24924,17 +27236,16 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+ contiguous_bitmap_clear(start_gpfn, num_gpfn);
+
-+ /* Do the exchange for non-contiguous MFNs. */
++ /* Do the exchange for non-contiguous MFNs. */
+ in_frame = start_gpfn;
-+ for (i = 0; i < num_gpfn; i++) {
++ for (i = 0; i < num_gpfn; i++)
+ out_frames[i] = start_gpfn + i;
-+ }
+ error = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
+ success = (exchange.nr_exchanged == 1);
+ BUG_ON(!success && ((exchange.nr_exchanged != 0) || (error == 0)));
+ BUG_ON(success && (error != 0));
+ if (unlikely(error == -ENOSYS)) {
-+ /* Compatibility when XENMEM_exchange is unsupported. */
++ /* Compatibility when XENMEM_exchange is unsupported. */
+ error = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ &exchange.in);
+ BUG_ON(error != 1);
@@ -24946,15 +27257,27 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ balloon_unlock(flags);
+}
+
++int
++xen_limit_pages_to_max_mfn(struct page *pages, unsigned int order,
++ unsigned int address_bits)
++{
++ return xen_create_contiguous_region((unsigned long)page_address(pages),
++ order, address_bits);
++}
+
-+///////////////////////////////////////////////////////////////////////////
-+// grant table hack
-+// cmd: GNTTABOP_xxx
-+
++/****************************************************************************
++ * grant table hack
++ * cmd: GNTTABOP_xxx
++ */
+#include <linux/mm.h>
+#include <xen/interface/xen.h>
+#include <xen/gnttab.h>
+
++void *arch_gnttab_alloc_shared(unsigned long *frames)
++{
++ return __va(frames[0] << PAGE_SHIFT);
++}
++
+static void
+gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
+{
@@ -24964,16 +27287,19 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+ if (flags & GNTMAP_host_map) {
+ if (flags & GNTMAP_application_map) {
-+ xprintd("GNTMAP_application_map is not supported yet: flags 0x%x\n", flags);
++ xprintd("GNTMAP_application_map is not supported yet:"
++ " flags 0x%x\n", flags);
+ BUG();
+ }
+ if (flags & GNTMAP_contains_pte) {
-+ xprintd("GNTMAP_contains_pte is not supported yet flags 0x%x\n", flags);
++ xprintd("GNTMAP_contains_pte is not supported yet"
++ " flags 0x%x\n", flags);
+ BUG();
+ }
+ } else if (flags & GNTMAP_device_map) {
-+ xprintd("GNTMAP_device_map is not supported yet 0x%x\n", flags);
-+ BUG();//XXX not yet. actually this flag is not used.
++ xprintd("GNTMAP_device_map is not supported yet 0x%x\n",
++ flags);
++ BUG(); /* XXX not yet. actually this flag is not used. */
+ } else {
+ BUG();
+ }
@@ -24989,19 +27315,21 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ (struct gnttab_map_grant_ref*)uop + i);
+ }
+ }
-+ return xencomm_mini_hypercall_grant_table_op(cmd, uop, count);
++ return xencomm_hypercall_grant_table_op(cmd, uop, count);
+}
+EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
+
-+///////////////////////////////////////////////////////////////////////////
-+// foreign mapping
++/**************************************************************************
++ * foreign mapping
++ */
+#include <linux/efi.h>
-+#include <asm/meminit.h> // for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}()
++#include <asm/meminit.h> /* for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}() */
+
+static unsigned long privcmd_resource_min = 0;
-+// Xen/ia64 currently can handle pseudo physical address bits up to
-+// (PAGE_SHIFT * 3)
-+static unsigned long privcmd_resource_max = GRANULEROUNDDOWN((1UL << (PAGE_SHIFT * 3)) - 1);
++/* Xen/ia64 currently can handle pseudo physical address bits up to
++ * (PAGE_SHIFT * 3) */
++static unsigned long privcmd_resource_max =
++ GRANULEROUNDDOWN((1UL << (PAGE_SHIFT * 3)) - 1);
+static unsigned long privcmd_resource_align = IA64_GRANULE_SIZE;
+
+static unsigned long
@@ -25036,18 +27364,18 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
-+ // at first check the used highest address
++ /* at first check the used highest address */
+ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
-+ // nothing
++ /* nothing */;
+ }
+ md = p - efi_desc_size;
+ privcmd_resource_min = GRANULEROUNDUP(md_end_addr(md));
+ if (xen_ia64_privcmd_check_size(privcmd_resource_min,
-+ privcmd_resource_max)) {
++ privcmd_resource_max))
+ goto out;
-+ }
+
-+ // the used highest address is too large. try to find the largest gap.
++ /* the used highest address is too large.
++ * try to find the largest gap. */
+ tmp_min = privcmd_resource_max;
+ tmp_max = 0;
+ gap_size = 0;
@@ -25061,23 +27389,21 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+ md = p;
+ end = md_end_addr(md);
-+ if (end > privcmd_resource_max) {
++ if (end > privcmd_resource_max)
+ break;
-+ }
+ if (end < prev_end) {
-+ // work around.
-+ // Xen may pass incompletely sorted memory
-+ // descriptors like
-+ // [x, x + length]
-+ // [x, x]
-+ // this order should be reversed.
++ /* work around.
++ * Xen may pass incompletely sorted memory
++ * descriptors like
++ * [x, x + length]
++ * [x, x]
++ * this order should be reversed. */
+ continue;
+ }
+ next = p + efi_desc_size;
+ next_start = next->phys_addr;
-+ if (next_start > privcmd_resource_max) {
++ if (next_start > privcmd_resource_max)
+ next_start = privcmd_resource_max;
-+ }
+ if (end < next_start && gap_size < (next_start - end)) {
+ tmp_min = end;
+ tmp_max = next_start;
@@ -25096,19 +27422,21 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ privcmd_resource_max = tmp_max;
+ if (!xen_ia64_privcmd_check_size(privcmd_resource_min,
+ privcmd_resource_max)) {
-+ // Any large enough gap isn't found.
-+ // go ahead anyway with the warning hoping that large region
-+ // won't be requested.
-+ printk(KERN_WARNING "xen privcmd: large enough region for privcmd mmap is not found.\n");
++ /* Any large enough gap isn't found.
++ * go ahead anyway with the warning hoping that large region
++ * won't be requested. */
++ printk(KERN_WARNING "xen privcmd: "
++ "large enough region for privcmd mmap is not found.\n");
+ }
+
+out:
-+ printk(KERN_INFO "xen privcmd uses pseudo physical addr range [0x%lx, 0x%lx] (%ldMB)\n",
++ printk(KERN_INFO "xen privcmd uses pseudo physical addr range "
++ "[0x%lx, 0x%lx] (%ldMB)\n",
+ privcmd_resource_min, privcmd_resource_max,
+ (privcmd_resource_max - privcmd_resource_min) >> 20);
+ BUG_ON(privcmd_resource_min >= privcmd_resource_max);
+
-+ // XXX this should be somewhere appropriate
++ /* XXX this should be somewhere appropriate */
+ (void)p2m_expose_init();
+
+ return 0;
@@ -25123,8 +27451,12 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+struct xen_ia64_privcmd_range {
+ atomic_t ref_count;
-+ unsigned long pgoff; // in PAGE_SIZE
-+ struct resource* res;
++ unsigned long pgoff; /* in PAGE_SIZE */
++ struct resource *res;
++
++ /* for foreign domain p2m mapping */
++ void *private;
++ void (*callback)(struct xen_ia64_privcmd_range *range, void *arg);
+
+ unsigned long num_entries;
+ struct xen_ia64_privcmd_entry entries[0];
@@ -25132,30 +27464,30 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+struct xen_ia64_privcmd_vma {
+ int is_privcmd_mmapped;
-+ struct xen_ia64_privcmd_range* range;
++ struct xen_ia64_privcmd_range *range;
+
+ unsigned long num_entries;
-+ struct xen_ia64_privcmd_entry* entries;
++ struct xen_ia64_privcmd_entry *entries;
+};
+
+static void
-+xen_ia64_privcmd_init_entry(struct xen_ia64_privcmd_entry* entry)
++xen_ia64_privcmd_init_entry(struct xen_ia64_privcmd_entry *entry)
+{
+ atomic_set(&entry->map_count, 0);
+ entry->gpfn = INVALID_GPFN;
+}
+
+static int
-+xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
++xen_ia64_privcmd_entry_mmap(struct vm_area_struct *vma,
+ unsigned long addr,
-+ struct xen_ia64_privcmd_range* privcmd_range,
++ struct xen_ia64_privcmd_range *privcmd_range,
+ int i,
+ unsigned long gmfn,
+ pgprot_t prot,
+ domid_t domid)
+{
+ int error = 0;
-+ struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
++ struct xen_ia64_privcmd_entry *entry = &privcmd_range->entries[i];
+ unsigned long gpfn;
+ unsigned long flags;
+
@@ -25171,21 +27503,18 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ gpfn = (privcmd_range->res->start >> PAGE_SHIFT) + i;
+
+ flags = ASSIGN_writable;
-+ if (pgprot_val(prot) == PROT_READ) {
++ if (pgprot_val(prot) == PROT_READ)
+ flags = ASSIGN_readonly;
-+ }
+ error = HYPERVISOR_add_physmap_with_gmfn(gpfn, gmfn, flags, domid);
-+ if (error != 0) {
++ if (error != 0)
+ goto out;
-+ }
+
+ prot = vma->vm_page_prot;
+ error = remap_pfn_range(vma, addr, gpfn, 1 << PAGE_SHIFT, prot);
+ if (error != 0) {
+ error = HYPERVISOR_zap_physmap(gpfn, 0);
-+ if (error) {
-+ BUG();//XXX
-+ }
++ if (error)
++ BUG(); /* XXX */
+ } else {
+ atomic_inc(&entry->map_count);
+ entry->gpfn = gpfn;
@@ -25196,47 +27525,44 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+}
+
+static void
-+xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_range* privcmd_range,
++xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_range *privcmd_range,
+ int i)
+{
-+ struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
++ struct xen_ia64_privcmd_entry *entry = &privcmd_range->entries[i];
+ unsigned long gpfn = entry->gpfn;
-+ //gpfn = (privcmd_range->res->start >> PAGE_SHIFT) +
-+ // (vma->vm_pgoff - privcmd_range->pgoff);
++ /* gpfn = (privcmd_range->res->start >> PAGE_SHIFT) +
++ (vma->vm_pgoff - privcmd_range->pgoff); */
+ int error;
+
+ error = HYPERVISOR_zap_physmap(gpfn, 0);
-+ if (error) {
-+ BUG();//XXX
-+ }
++ if (error)
++ BUG(); /* XXX */
+ entry->gpfn = INVALID_GPFN;
+}
+
+static void
-+xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_range* privcmd_range,
++xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_range *privcmd_range,
+ int i)
+{
-+ struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
-+ if (entry->gpfn != INVALID_GPFN) {
++ struct xen_ia64_privcmd_entry *entry = &privcmd_range->entries[i];
++ if (entry->gpfn != INVALID_GPFN)
+ atomic_inc(&entry->map_count);
-+ } else {
++ else
+ BUG_ON(atomic_read(&entry->map_count) != 0);
-+ }
+}
+
+static void
-+xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_range* privcmd_range,
++xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_range *privcmd_range,
+ int i)
+{
-+ struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
++ struct xen_ia64_privcmd_entry *entry = &privcmd_range->entries[i];
+ if (entry->gpfn != INVALID_GPFN &&
-+ atomic_dec_and_test(&entry->map_count)) {
++ atomic_dec_and_test(&entry->map_count))
+ xen_ia64_privcmd_entry_munmap(privcmd_range, i);
-+ }
+}
+
-+static void xen_ia64_privcmd_vma_open(struct vm_area_struct* vma);
-+static void xen_ia64_privcmd_vma_close(struct vm_area_struct* vma);
++static void xen_ia64_privcmd_vma_open(struct vm_area_struct *vma);
++static void xen_ia64_privcmd_vma_close(struct vm_area_struct *vma);
+
+struct vm_operations_struct xen_ia64_privcmd_vm_ops = {
+ .open = &xen_ia64_privcmd_vma_open,
@@ -25244,12 +27570,13 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+};
+
+static void
-+__xen_ia64_privcmd_vma_open(struct vm_area_struct* vma,
-+ struct xen_ia64_privcmd_vma* privcmd_vma,
-+ struct xen_ia64_privcmd_range* privcmd_range)
++__xen_ia64_privcmd_vma_open(struct vm_area_struct *vma,
++ struct xen_ia64_privcmd_vma *privcmd_vma,
++ struct xen_ia64_privcmd_range *privcmd_range)
+{
+ unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
-+ unsigned long num_entries = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
++ unsigned long num_entries =
++ (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ unsigned long i;
+
+ BUG_ON(entry_offset < 0);
@@ -25259,41 +27586,43 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ privcmd_vma->num_entries = num_entries;
+ privcmd_vma->entries = &privcmd_range->entries[entry_offset];
+ vma->vm_private_data = privcmd_vma;
-+ for (i = 0; i < privcmd_vma->num_entries; i++) {
++ for (i = 0; i < privcmd_vma->num_entries; i++)
+ xen_ia64_privcmd_entry_open(privcmd_range, entry_offset + i);
-+ }
+
+ vma->vm_private_data = privcmd_vma;
+ vma->vm_ops = &xen_ia64_privcmd_vm_ops;
+}
+
+static void
-+xen_ia64_privcmd_vma_open(struct vm_area_struct* vma)
++xen_ia64_privcmd_vma_open(struct vm_area_struct *vma)
+{
-+ struct xen_ia64_privcmd_vma* old_privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+ struct xen_ia64_privcmd_vma* privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+ struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
++ struct xen_ia64_privcmd_vma *old_privcmd_vma =
++ (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
++ struct xen_ia64_privcmd_vma *privcmd_vma =
++ (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
++ struct xen_ia64_privcmd_range *privcmd_range = privcmd_vma->range;
+
+ atomic_inc(&privcmd_range->ref_count);
-+ // vm_op->open() can't fail.
++ /* vm_op->open() can't fail. */
+ privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL | __GFP_NOFAIL);
-+ // copy original value if necessary
++ /* copy original value if necessary */
+ privcmd_vma->is_privcmd_mmapped = old_privcmd_vma->is_privcmd_mmapped;
+
+ __xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
+}
+
+static void
-+xen_ia64_privcmd_vma_close(struct vm_area_struct* vma)
++xen_ia64_privcmd_vma_close(struct vm_area_struct *vma)
+{
-+ struct xen_ia64_privcmd_vma* privcmd_vma =
++ struct xen_ia64_privcmd_vma *privcmd_vma =
+ (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+ struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
++ struct xen_ia64_privcmd_range *privcmd_range = privcmd_vma->range;
+ unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+ unsigned long i;
+
+ for (i = 0; i < privcmd_vma->num_entries; i++) {
+ xen_ia64_privcmd_entry_close(privcmd_range, entry_offset + i);
++ cond_resched();
+ }
+ vma->vm_private_data = NULL;
+ kfree(privcmd_vma);
@@ -25301,12 +27630,15 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ if (atomic_dec_and_test(&privcmd_range->ref_count)) {
+#if 1
+ for (i = 0; i < privcmd_range->num_entries; i++) {
-+ struct xen_ia64_privcmd_entry* entry =
++ struct xen_ia64_privcmd_entry *entry =
+ &privcmd_range->entries[i];
+ BUG_ON(atomic_read(&entry->map_count) != 0);
+ BUG_ON(entry->gpfn != INVALID_GPFN);
+ }
+#endif
++ if (privcmd_range->callback)
++ (*privcmd_range->callback)(privcmd_range,
++ privcmd_range->private);
+ release_resource(privcmd_range->res);
+ kfree(privcmd_range->res);
+ vfree(privcmd_range);
@@ -25316,7 +27648,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+int
+privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
+{
-+ struct xen_ia64_privcmd_vma* privcmd_vma =
++ struct xen_ia64_privcmd_vma *privcmd_vma =
+ (struct xen_ia64_privcmd_vma *)vma->vm_private_data;
+ return (xchg(&privcmd_vma->is_privcmd_mmapped, 1) == 0);
+}
@@ -25327,9 +27659,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ int error;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long num_entries = size >> PAGE_SHIFT;
-+ struct xen_ia64_privcmd_range* privcmd_range = NULL;
-+ struct xen_ia64_privcmd_vma* privcmd_vma = NULL;
-+ struct resource* res = NULL;
++ struct xen_ia64_privcmd_range *privcmd_range = NULL;
++ struct xen_ia64_privcmd_vma *privcmd_vma = NULL;
++ struct resource *res = NULL;
+ unsigned long i;
+ BUG_ON(!is_running_on_xen());
+
@@ -25339,26 +27671,22 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ privcmd_range =
+ vmalloc(sizeof(*privcmd_range) +
+ sizeof(privcmd_range->entries[0]) * num_entries);
-+ if (privcmd_range == NULL) {
++ if (privcmd_range == NULL)
+ goto out_enomem0;
-+ }
+ privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL);
-+ if (privcmd_vma == NULL) {
++ if (privcmd_vma == NULL)
+ goto out_enomem1;
-+ }
+ privcmd_vma->is_privcmd_mmapped = 0;
+
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
-+ if (res == NULL) {
++ if (res == NULL)
+ goto out_enomem1;
-+ }
+ res->name = "Xen privcmd mmap";
+ error = allocate_resource(&iomem_resource, res, size,
+ privcmd_resource_min, privcmd_resource_max,
+ privcmd_resource_align, NULL, NULL);
-+ if (error) {
++ if (error)
+ goto out_enomem1;
-+ }
+ privcmd_range->res = res;
+
+ /* DONTCOPY is essential for Xen as copy_page_range is broken. */
@@ -25367,9 +27695,10 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ atomic_set(&privcmd_range->ref_count, 1);
+ privcmd_range->pgoff = vma->vm_pgoff;
+ privcmd_range->num_entries = num_entries;
-+ for (i = 0; i < privcmd_range->num_entries; i++) {
++ privcmd_range->private = NULL;
++ privcmd_range->callback = NULL;
++ for (i = 0; i < privcmd_range->num_entries; i++)
+ xen_ia64_privcmd_init_entry(&privcmd_range->entries[i]);
-+ }
+
+ __xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
+ return 0;
@@ -25384,15 +27713,15 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+int
+direct_remap_pfn_range(struct vm_area_struct *vma,
-+ unsigned long address, // process virtual address
-+ unsigned long gmfn, // gmfn, gmfn + 1, ... gmfn + size/PAGE_SIZE
++ unsigned long address, /* process virtual address */
++ unsigned long gmfn, /* gmfn, gmfn + 1, ... gmfn + size/PAGE_SIZE */
+ unsigned long size,
+ pgprot_t prot,
-+ domid_t domid) // target domain
++ domid_t domid) /* target domain */
+{
-+ struct xen_ia64_privcmd_vma* privcmd_vma =
++ struct xen_ia64_privcmd_vma *privcmd_vma =
+ (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+ struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
++ struct xen_ia64_privcmd_range *privcmd_range = privcmd_vma->range;
+ unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+
+ unsigned long i;
@@ -25401,28 +27730,27 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ BUG_ON(!is_running_on_xen());
+
+#if 0
-+ if (prot != vm->vm_page_prot) {
++ if (prot != vm->vm_page_prot)
+ return -EINVAL;
-+ }
+#endif
+
+ i = (address - vma->vm_start) >> PAGE_SHIFT;
+ for (offset = 0; offset < size; offset += PAGE_SIZE) {
+ error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & PAGE_MASK, privcmd_range, entry_offset + i, gmfn, prot, domid);
-+ if (error != 0) {
++ if (error != 0)
+ break;
-+ }
+
+ i++;
+ gmfn++;
-+ }
++ }
+
+ return error;
+}
+
+
-+///////////////////////////////////////////////////////////////////////////
-+// expose p2m table
++/**************************************************************************
++ * expose p2m table
++ */
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+#include <linux/cpu.h>
+#include <asm/uaccess.h>
@@ -25440,12 +27768,13 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+};
+static unsigned long p2m_assign_start_pfn __read_mostly;
+static unsigned long p2m_assign_end_pfn __read_mostly;
-+static unsigned long p2m_expose_size; // this is referenced only when resume.
-+ // so __read_mostly doesn't make sense.
-+volatile const pte_t* p2m_pte __read_mostly;
++static unsigned long p2m_expose_size; /* this is referenced only when resume.
++ * so __read_mostly doesn't make sense.
++ */
++volatile const pte_t *p2m_pte __read_mostly;
+
-+#define GRNULE_PFN PTRS_PER_PTE
-+static unsigned long p2m_granule_pfn __read_mostly = GRNULE_PFN;
++#define GRANULE_PFN PTRS_PER_PTE
++static unsigned long p2m_granule_pfn __read_mostly = GRANULE_PFN;
+
+#define ROUNDDOWN(x, y) ((x) & ~((y) - 1))
+#define ROUNDUP(x, y) (((x) + (y) - 1) & ~((y) - 1))
@@ -25455,13 +27784,13 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+static int xen_ia64_p2m_expose __read_mostly = 1;
+module_param(xen_ia64_p2m_expose, int, 0);
+MODULE_PARM_DESC(xen_ia64_p2m_expose,
-+ "enable/disable xen/ia64 p2m exposure optimization\n");
++ "enable/disable xen/ia64 p2m exposure optimization\n");
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+static int xen_ia64_p2m_expose_use_dtr __read_mostly = 1;
+module_param(xen_ia64_p2m_expose_use_dtr, int, 0);
+MODULE_PARM_DESC(xen_ia64_p2m_expose_use_dtr,
-+ "use/unuse dtr to map exposed p2m table\n");
++ "use/unuse dtr to map exposed p2m table\n");
+
+static const int p2m_page_shifts[] = {
+ _PAGE_SIZE_4K,
@@ -25483,21 +27812,21 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+};
+static struct p2m_itr_arg p2m_itr_arg __read_mostly;
+
-+// This should be in asm-ia64/kregs.h
++/* This should be in asm-ia64/kregs.h */
+#define IA64_TR_P2M_TABLE 3
+
+static void
-+p2m_itr(void* info)
++p2m_itr(void *info)
+{
-+ struct p2m_itr_arg* arg = (struct p2m_itr_arg*)info;
++ struct p2m_itr_arg *arg = (struct p2m_itr_arg*)info;
+ ia64_itr(0x2, IA64_TR_P2M_TABLE,
-+ arg->vaddr, arg->pteval, arg->log_page_size);
++ arg->vaddr, arg->pteval, arg->log_page_size);
+ ia64_srlz_d();
+}
+
+static int
+p2m_expose_dtr_call(struct notifier_block *self,
-+ unsigned long event, void* ptr)
++ unsigned long event, void *ptr)
+{
+ unsigned int cpu = (unsigned int)(long)ptr;
+ if (event != CPU_ONLINE)
@@ -25521,6 +27850,12 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+};
+#endif
+
++static inline unsigned long
++p2m_table_size(unsigned long num_pfn)
++{
++ return ((num_pfn + PTRS_PER_PTE - 1) / PTRS_PER_PTE) << PAGE_SHIFT;
++}
++
+static int
+p2m_expose_init(void)
+{
@@ -25530,7 +27865,6 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ int error = 0;
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+ int i;
-+ unsigned long page_size;
+ unsigned long log_page_size = 0;
+#endif
+
@@ -25559,8 +27893,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+ if (xen_ia64_p2m_expose_use_dtr) {
++ unsigned long page_size = 0;
+ unsigned long granule_pfn = 0;
-+ p2m_size = p2m_max_low_pfn - p2m_min_low_pfn;
++ p2m_size = p2m_table_size(p2m_max_low_pfn - p2m_min_low_pfn);
+ for (i = 0;
+ i < sizeof(p2m_page_shifts)/sizeof(p2m_page_shifts[0]);
+ i++) {
@@ -25570,15 +27905,16 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ continue;
+
+ granule_pfn = max(page_size >> PAGE_SHIFT,
-+ p2m_granule_pfn);
++ p2m_granule_pfn);
+ p2m_convert_min_pfn = ROUNDDOWN(p2m_min_low_pfn,
-+ granule_pfn);
++ granule_pfn);
+ p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn,
-+ granule_pfn);
++ granule_pfn);
+ num_pfn = p2m_convert_max_pfn - p2m_convert_min_pfn;
+ p2m_expose_size = num_pfn << PAGE_SHIFT;
-+ p2m_size = num_pfn / PTRS_PER_PTE;
-+ p2m_size = ROUNDUP(p2m_size, granule_pfn << PAGE_SHIFT);
++ p2m_size = p2m_table_size(num_pfn);
++ p2m_size = ROUNDUP(p2m_size,
++ granule_pfn << PAGE_SHIFT);
+ if (p2m_size == page_size)
+ break;
+ }
@@ -25593,24 +27929,25 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ {
+ BUG_ON(p2m_granule_pfn & (p2m_granule_pfn - 1));
+ p2m_convert_min_pfn = ROUNDDOWN(p2m_min_low_pfn,
-+ p2m_granule_pfn);
-+ p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn, p2m_granule_pfn);
++ p2m_granule_pfn);
++ p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn,
++ p2m_granule_pfn);
+ num_pfn = p2m_convert_max_pfn - p2m_convert_min_pfn;
+ p2m_expose_size = num_pfn << PAGE_SHIFT;
-+ p2m_size = num_pfn / PTRS_PER_PTE;
++ p2m_size = p2m_table_size(num_pfn);
+ p2m_size = ROUNDUP(p2m_size, p2m_granule_pfn << PAGE_SHIFT);
+ align = max(privcmd_resource_align,
-+ p2m_granule_pfn << PAGE_SHIFT);
++ p2m_granule_pfn << PAGE_SHIFT);
+ }
+
-+ // use privcmd region
++ /* use privcmd region */
+ error = allocate_resource(&iomem_resource, &p2m_resource, p2m_size,
-+ privcmd_resource_min, privcmd_resource_max,
-+ align, NULL, NULL);
++ privcmd_resource_min, privcmd_resource_max,
++ align, NULL, NULL);
+ if (error) {
+ printk(KERN_ERR P2M_PREFIX
+ "can't allocate region for p2m exposure "
-+ "[0x%016lx, 0x%016lx) 0x%016lx\n",
++ "[0x%016lx, 0x%016lx] 0x%016lx\n",
+ p2m_convert_min_pfn, p2m_convert_max_pfn, p2m_size);
+ goto out;
+ }
@@ -25619,8 +27956,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ p2m_assign_end_pfn = p2m_resource.end >> PAGE_SHIFT;
+
+ error = HYPERVISOR_expose_p2m(p2m_convert_min_pfn,
-+ p2m_assign_start_pfn,
-+ p2m_expose_size, p2m_granule_pfn);
++ p2m_assign_start_pfn,
++ p2m_expose_size, p2m_granule_pfn);
+ if (error) {
+ printk(KERN_ERR P2M_PREFIX "failed expose p2m hypercall %d\n",
+ error);
@@ -25635,9 +27972,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+ if (xen_ia64_p2m_expose_use_dtr) {
+ p2m_itr_arg.vaddr = (unsigned long)__va(p2m_assign_start_pfn
-+ << PAGE_SHIFT);
++ << PAGE_SHIFT);
+ p2m_itr_arg.pteval = pte_val(pfn_pte(p2m_assign_start_pfn,
-+ PAGE_KERNEL));
++ PAGE_KERNEL));
+ p2m_itr_arg.log_page_size = log_page_size;
+ smp_mb();
+ smp_call_function(&p2m_itr, &p2m_itr_arg, 1, 1);
@@ -25648,10 +27985,10 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ p2m_initialized = 1;
+ printk(P2M_PREFIX "assign p2m table of [0x%016lx, 0x%016lx)\n",
+ p2m_convert_min_pfn << PAGE_SHIFT,
-+ p2m_convert_max_pfn << PAGE_SHIFT);
++ (p2m_convert_max_pfn << PAGE_SHIFT) + PAGE_SIZE);
+ printk(P2M_PREFIX "to [0x%016lx, 0x%016lx) (%ld KBytes)\n",
+ p2m_assign_start_pfn << PAGE_SHIFT,
-+ p2m_assign_end_pfn << PAGE_SHIFT,
++ (p2m_assign_end_pfn << PAGE_SHIFT) + PAGE_SIZE,
+ p2m_size / 1024);
+out:
+ unlock_cpu_hotplug();
@@ -25685,8 +28022,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ * interrupts are masked when resume.
+ */
+ error = HYPERVISOR_expose_p2m(p2m_convert_min_pfn,
-+ p2m_assign_start_pfn,
-+ p2m_expose_size, p2m_granule_pfn);
++ p2m_assign_start_pfn,
++ p2m_expose_size, p2m_granule_pfn);
+ if (error) {
+ printk(KERN_ERR P2M_PREFIX "failed expose p2m hypercall %d\n",
+ error);
@@ -25713,11 +28050,11 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ }
+}
+
-+//XXX inlinize?
++/* XXX inlinize? */
+unsigned long
+p2m_phystomach(unsigned long gpfn)
+{
-+ volatile const pte_t* pte;
++ volatile const pte_t *pte;
+ unsigned long mfn;
+ unsigned long pteval;
+
@@ -25729,8 +28066,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+
+ mfn = INVALID_MFN;
+ if (likely(__get_user(pteval, (unsigned long __user *)pte) == 0 &&
-+ pte_present(__pte(pteval)) &&
-+ pte_pfn(__pte(pteval)) != (INVALID_MFN >> PAGE_SHIFT)))
++ pte_present(__pte(pteval)) &&
++ pte_pfn(__pte(pteval)) != (INVALID_MFN >> PAGE_SHIFT)))
+ mfn = (pteval & _PFN_MASK) >> PAGE_SHIFT;
+
+ return mfn;
@@ -25743,26 +28080,230 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+EXPORT_SYMBOL_GPL(p2m_convert_max_pfn);
+EXPORT_SYMBOL_GPL(p2m_pte);
+EXPORT_SYMBOL_GPL(p2m_phystomach);
-+#endif
+
-+///////////////////////////////////////////////////////////////////////////
-+// for xenoprof
++/**************************************************************************
++ * foreign domain p2m mapping
++ */
++#include <asm/xen/xencomm.h>
++#include <xen/public/privcmd.h>
++
++struct foreign_p2m_private {
++ unsigned long gpfn;
++ domid_t domid;
++};
++
++static void
++xen_foreign_p2m_unexpose(struct xen_ia64_privcmd_range *privcmd_range,
++ void *arg)
++{
++ struct foreign_p2m_private *private = (struct foreign_p2m_private*)arg;
++ int ret;
++
++ privcmd_range->private = NULL;
++ privcmd_range->callback = NULL;
++
++ ret = HYPERVISOR_unexpose_foreign_p2m(private->gpfn, private->domid);
++ if (ret)
++ printk(KERN_WARNING
++ "unexpose_foreign_p2m hypercall failed.\n");
++ kfree(private);
++}
++
++int
++xen_foreign_p2m_expose(privcmd_hypercall_t *hypercall)
++{
++ /*
++ * hypercall->
++ * arg0: cmd = IA64_DOM0VP_expose_foreign_p2m
++ * arg1: va
++ * arg2: domid
++ * arg3: __user* memmap_info
++ * arg4: flags
++ */
++
++ int ret = 0;
++ struct mm_struct *mm = current->mm;
++
++ unsigned long vaddr = hypercall->arg[1];
++ domid_t domid = hypercall->arg[2];
++ struct xen_ia64_memmap_info __user *u_memmap_info =
++ (struct xen_ia64_memmap_info __user *)hypercall->arg[3];
++
++ struct xen_ia64_memmap_info memmap_info;
++ size_t memmap_size;
++ struct xen_ia64_memmap_info *k_memmap_info = NULL;
++ unsigned long max_gpfn;
++ unsigned long p2m_size;
++ struct resource *res;
++ unsigned long gpfn;
++
++ struct vm_area_struct *vma;
++ void *p;
++ unsigned long prev_src_gpfn_end;
++
++ struct xen_ia64_privcmd_vma *privcmd_vma;
++ struct xen_ia64_privcmd_range *privcmd_range;
++ struct foreign_p2m_private *private = NULL;
+
++ BUG_ON(hypercall->arg[0] != IA64_DOM0VP_expose_foreign_p2m);
++
++ private = kmalloc(sizeof(*private), GFP_KERNEL);
++ if (private == NULL)
++ goto kfree_out;
++
++ if (copy_from_user(&memmap_info, u_memmap_info, sizeof(memmap_info)))
++ return -EFAULT;
++ /* memmap_info integrity check */
++ if (memmap_info.efi_memdesc_size < sizeof(efi_memory_desc_t) ||
++ memmap_info.efi_memmap_size < memmap_info.efi_memdesc_size ||
++ (memmap_info.efi_memmap_size % memmap_info.efi_memdesc_size)
++ != 0) {
++ ret = -EINVAL;
++ goto kfree_out;
++ }
++
++ memmap_size = sizeof(*k_memmap_info) + memmap_info.efi_memmap_size;
++ k_memmap_info = kmalloc(memmap_size, GFP_KERNEL);
++ if (k_memmap_info == NULL)
++ return -ENOMEM;
++ if (copy_from_user(k_memmap_info, u_memmap_info, memmap_size)) {
++ ret = -EFAULT;
++ goto kfree_out;
++ }
++ /* k_memmap_info integrity check is done by the expose foreng p2m
++ hypercall */
++
++ max_gpfn = HYPERVISOR_memory_op(XENMEM_maximum_gpfn, &domid);
++ if (max_gpfn < 0) {
++ ret = max_gpfn;
++ goto kfree_out;
++ }
++ p2m_size = p2m_table_size(max_gpfn + 1);
++
++ down_write(&mm->mmap_sem);
++
++ vma = find_vma(mm, vaddr);
++ if (vma == NULL || vma->vm_ops != &xen_ia64_privcmd_vm_ops ||
++ vaddr != vma->vm_start ||
++ (vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_EXEC) ||
++ !privcmd_enforce_singleshot_mapping(vma))
++ goto mmap_out;
++
++ privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
++ res = privcmd_vma->range->res;
++ if (p2m_size > (res->end - res->start + 1) ||
++ p2m_size > vma->vm_end - vma->vm_start) {
++ ret = -EINVAL;
++ goto mmap_out;
++ }
++
++ gpfn = res->start >> PAGE_SHIFT;
++ /*
++ * arg0: dest_gpfn
++ * arg1: domid
++ * arg2: XEN_GUEST_HANDLE(char) buffer: memmap_info
++ * arg3: flags
++ * The hypercall checks its intergirty/simplfies it and
++ * copy it back for us.
++ */
++ ret = xencomm_arch_expose_foreign_p2m(gpfn, domid,
++ xencomm_map_no_alloc(k_memmap_info, memmap_size),
++ hypercall->arg[4]);
++ if (ret)
++ goto mmap_out;
++
++ privcmd_range = (struct xen_ia64_privcmd_range*)privcmd_vma->range;
++ prev_src_gpfn_end = 0;
++ for (p = k_memmap_info->memdesc;
++ p < (void*)&k_memmap_info->memdesc[0] +
++ k_memmap_info->efi_memmap_size;
++ p += k_memmap_info->efi_memdesc_size) {
++ efi_memory_desc_t* md = p;
++ unsigned long src_gpfn = md->phys_addr >> PAGE_SHIFT;
++ unsigned long src_gpfn_end =
++ (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >>
++ PAGE_SHIFT;
++ unsigned long num_src_gpfn;
++ unsigned long gpfn_offset;
++ unsigned long size;
++ unsigned int i;
++
++ if (src_gpfn <= prev_src_gpfn_end)
++ src_gpfn = prev_src_gpfn_end + 1;
++ if (src_gpfn_end <= prev_src_gpfn_end)
++ continue;
++
++ src_gpfn &= ~(PTRS_PER_PTE - 1);
++ src_gpfn_end = (src_gpfn_end + PTRS_PER_PTE - 1) &
++ ~(PTRS_PER_PTE - 1);
++ num_src_gpfn = src_gpfn_end - src_gpfn;
++ gpfn_offset = src_gpfn / PTRS_PER_PTE;
++ size = p2m_table_size(num_src_gpfn);
++
++ prev_src_gpfn_end = src_gpfn_end;
++ ret = remap_pfn_range(vma,
++ vaddr + (gpfn_offset << PAGE_SHIFT),
++ gpfn + gpfn_offset, size,
++ vma->vm_page_prot);
++ if (ret) {
++ for (i = 0; i < gpfn + gpfn_offset; i++) {
++ struct xen_ia64_privcmd_entry *entry =
++ &privcmd_range->entries[i];
++ BUG_ON(atomic_read(&entry->map_count) != 1 &&
++ atomic_read(&entry->map_count) != 0);
++ atomic_set(&entry->map_count, 0);
++ entry->gpfn = INVALID_GPFN;
++ }
++ (void)HYPERVISOR_unexpose_foreign_p2m(gpfn, domid);
++ goto mmap_out;
++ }
++
++ for (i = gpfn_offset;
++ i < gpfn_offset + (size >> PAGE_SHIFT);
++ i++) {
++ struct xen_ia64_privcmd_entry *entry =
++ &privcmd_range->entries[i];
++ BUG_ON(atomic_read(&entry->map_count) != 0);
++ BUG_ON(entry->gpfn != INVALID_GPFN);
++ atomic_inc(&entry->map_count);
++ entry->gpfn = gpfn + i;
++ }
++ }
++
++ private->gpfn = gpfn;
++ private->domid = domid;
++
++ privcmd_range->callback = &xen_foreign_p2m_unexpose;
++ privcmd_range->private = private;
++
++mmap_out:
++ up_write(&mm->mmap_sem);
++kfree_out:
++ kfree(k_memmap_info);
++ if (ret != 0)
++ kfree(private);
++ return ret;
++}
++#endif
++
++/**************************************************************************
++ * for xenoprof
++ */
+struct resource*
+xen_ia64_allocate_resource(unsigned long size)
+{
-+ struct resource* res;
++ struct resource *res;
+ int error;
+
-+ res = kmalloc(sizeof(*res), GFP_KERNEL);
++ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (res == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ res->name = "Xen";
+ res->flags = IORESOURCE_MEM;
+ error = allocate_resource(&iomem_resource, res, PAGE_ALIGN(size),
-+ privcmd_resource_min, privcmd_resource_max,
-+ IA64_GRANULE_SIZE, NULL, NULL);
++ privcmd_resource_min, privcmd_resource_max,
++ IA64_GRANULE_SIZE, NULL, NULL);
+ if (error) {
+ kfree(res);
+ return ERR_PTR(error);
@@ -25772,7 +28313,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+EXPORT_SYMBOL_GPL(xen_ia64_allocate_resource);
+
+void
-+xen_ia64_release_resource(struct resource* res)
++xen_ia64_release_resource(struct resource *res)
+{
+ release_resource(res);
+ kfree(res);
@@ -25780,7 +28321,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+EXPORT_SYMBOL_GPL(xen_ia64_release_resource);
+
+void
-+xen_ia64_unmap_resource(struct resource* res)
++xen_ia64_unmap_resource(struct resource *res)
+{
+ unsigned long gpfn = res->start >> PAGE_SHIFT;
+ unsigned long nr_pages = (res->end - res->start) >> PAGE_SHIFT;
@@ -25797,8 +28338,25 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+}
+EXPORT_SYMBOL_GPL(xen_ia64_unmap_resource);
+
-+///////////////////////////////////////////////////////////////////////////
-+// suspend/resume
++/**************************************************************************
++ * opt feature
++ */
++void
++xen_ia64_enable_opt_feature(void)
++{
++ /* Enable region 7 identity map optimizations in Xen */
++ struct xen_ia64_opt_feature optf;
++
++ optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7;
++ optf.on = XEN_IA64_OPTF_ON;
++ optf.pgprot = pgprot_val(PAGE_KERNEL);
++ optf.key = 0; /* No key on linux. */
++ HYPERVISOR_opt_feature(&optf);
++}
++
++/**************************************************************************
++ * suspend/resume
++ */
+void
+xen_post_suspend(int suspend_cancelled)
+{
@@ -25806,91 +28364,931 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/hypervisor.c tmp-linux-2.6-xen.pa
+ return;
+
+ p2m_expose_resume();
++ xen_ia64_enable_opt_feature();
+ /* add more if necessary */
+}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/mem.c tmp-linux-2.6-xen.patch/arch/ia64/xen/mem.c
---- pristine-linux-2.6.18/arch/ia64/xen/mem.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/mem.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,75 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/machvec.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/machvec.c
+--- linux-2.6.18.8/arch/ia64/xen/machvec.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/machvec.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,4 @@
++#define MACHVEC_PLATFORM_NAME xen
++#define MACHVEC_PLATFORM_HEADER <asm/machvec_xen.h>
++#include <asm/machvec_init.h>
++
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/swiotlb.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/swiotlb.c
+--- linux-2.6.18.8/arch/ia64/xen/swiotlb.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/swiotlb.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,906 @@
+/*
-+ * Originally from linux/drivers/char/mem.c
++ * Dynamic DMA mapping support.
+ *
-+ * Copyright (C) 1991, 1992 Linus Torvalds
++ * This implementation is for IA-64 and EM64T platforms that do not support
++ * I/O TLBs (aka DMA address translation hardware).
++ * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
++ * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
++ * Copyright (C) 2000, 2003 Hewlett-Packard Co
++ * David Mosberger-Tang <davidm@hpl.hp.com>
+ *
-+ * Added devfs support.
-+ * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
-+ * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
++ * 03/05/07 davidm Switch from PCI-DMA to generic device DMA API.
++ * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid
++ * unnecessary i-cache flushing.
++ * 04/07/.. ak Better overflow handling. Assorted fixes.
++ * 05/09/10 linville Add support for syncing ranges, support syncing for
++ * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup.
+ */
++
++#include <linux/cache.h>
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/ctype.h>
++
++#include <asm/io.h>
++#include <asm/dma.h>
++#include <asm/scatterlist.h>
++
++#include <linux/init.h>
++#include <linux/bootmem.h>
++
++#ifdef CONFIG_XEN
++#include <xen/gnttab.h>
++#include <asm/gnttab_dma.h>
+/*
-+ * taken from
-+ * linux/drivers/char/mem.c and linux-2.6-xen-sparse/drivers/xen/char/mem.c.
-+ * adjusted for IA64 and made transparent.
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ * VA Linux Systems Japan K.K.
++ * What DMA mask should Xen use to remap the bounce buffer pool? Most
++ * reports seem to indicate 30 bits is sufficient, except maybe for old
++ * sound cards that we probably don't care about anyway. If we need to,
++ * we could put in some smarts to try to lower, but hopefully it's not
++ * necessary.
+ */
++#define DMA_BITS (30)
++#endif
+
-+#include <linux/mm.h>
-+#include <linux/efi.h>
++#define OFFSET(val,align) ((unsigned long) \
++ ( (val) & ( (align) - 1)))
++
++#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
++#define SG_ENT_PHYS_ADDRESS(SG) virt_to_bus(SG_ENT_VIRT_ADDRESS(SG))
+
+/*
-+ * Architectures vary in how they handle caching for addresses
-+ * outside of main memory.
-+ *
++ * Maximum allowable number of contiguous slabs to map,
++ * must be a power of 2. What is the appropriate value ?
++ * The complexity of {map,unmap}_single is linearly dependent on this value.
++ */
++#define IO_TLB_SEGSIZE 128
++
++/*
++ * log of the size of each IO TLB slab. The number of slabs is command line
++ * controllable.
++ */
++#define IO_TLB_SHIFT 11
++
++#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
++
++/*
++ * Minimum IO TLB size to bother booting with. Systems with mainly
++ * 64bit capable cards will only lightly use the swiotlb. If we can't
++ * allocate a contiguous 1MB, we're probably in trouble anyway.
++ */
++#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
++
++/*
++ * Enumeration for sync targets
++ */
++enum dma_sync_target {
++ SYNC_FOR_CPU = 0,
++ SYNC_FOR_DEVICE = 1,
++};
++
++int swiotlb_force;
++
++/*
++ * Used to do a quick range check in swiotlb_unmap_single and
++ * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
++ * API.
++ */
++static char *io_tlb_start, *io_tlb_end;
++
++/*
++ * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and
++ * io_tlb_end. This is command line adjustable via setup_io_tlb_npages.
++ */
++static unsigned long io_tlb_nslabs;
++
++/*
++ * When the IOMMU overflows we return a fallback buffer. This sets the size.
++ */
++static unsigned long io_tlb_overflow = 32*1024;
++
++void *io_tlb_overflow_buffer;
++
++/*
++ * This is a free list describing the number of free entries available from
++ * each index
++ */
++static unsigned int *io_tlb_list;
++static unsigned int io_tlb_index;
++
++/*
++ * We need to save away the original address corresponding to a mapped entry
++ * for the sync operations.
++ */
++static unsigned char **io_tlb_orig_addr;
++
++/*
++ * Protect the above data structures in the map and unmap calls
++ */
++static DEFINE_SPINLOCK(io_tlb_lock);
++
++static int __init
++setup_io_tlb_npages(char *str)
++{
++ if (isdigit(*str)) {
++ io_tlb_nslabs = simple_strtoul(str, &str, 0);
++ /* avoid tail segment of size < IO_TLB_SEGSIZE */
++ io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
++ }
++ if (*str == ',')
++ ++str;
++ if (!strcmp(str, "force"))
++ swiotlb_force = 1;
++ return 1;
++}
++__setup("swiotlb=", setup_io_tlb_npages);
++/* make io_tlb_overflow tunable too? */
++
++/*
++ * Statically reserve bounce buffer space and initialize bounce buffer data
++ * structures for the software IO TLB used to implement the DMA API.
+ */
-+static inline int uncached_access(struct file *file, unsigned long addr)
++void
++swiotlb_init_with_default_size (size_t default_size)
+{
++ unsigned long i;
++
++ if (!io_tlb_nslabs) {
++ io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
++ io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
++ }
++
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ io_tlb_nslabs = roundup_pow_of_two(io_tlb_nslabs);
++#endif
++ /*
++ * Get IO TLB memory from the low pages
++ */
++ io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
++ if (!io_tlb_start)
++ panic("Cannot allocate SWIOTLB buffer");
++ io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
++
++#ifdef CONFIG_XEN
++ for (i = 0 ; i < io_tlb_nslabs ; i += IO_TLB_SEGSIZE) {
++ if (xen_create_contiguous_region(
++ (unsigned long)io_tlb_start +
++ (i << IO_TLB_SHIFT),
++ get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
++ DMA_BITS))
++ panic("Failed to setup Xen contiguous region");
++ }
++#endif
++
+ /*
-+ * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
++ * Allocate and initialize the free list array. This array is used
++ * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
++ * between io_tlb_start and io_tlb_end.
++ */
++ io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int));
++ for (i = 0; i < io_tlb_nslabs; i++)
++ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
++ io_tlb_index = 0;
++ io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
++
++ /*
++ * Get the overflow emergency buffer
+ */
-+ return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
++ io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
++#ifdef CONFIG_XEN
++ if (xen_create_contiguous_region((unsigned long)io_tlb_overflow_buffer,
++ get_order(io_tlb_overflow), DMA_BITS))
++ panic("Failed to setup Xen contiguous region for overflow");
++#endif
++ printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n",
++ virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
+}
+
-+int xen_mmap_mem(struct file * file, struct vm_area_struct * vma)
++void
++swiotlb_init (void)
+{
-+ unsigned long addr = vma->vm_pgoff << PAGE_SHIFT;
-+ size_t size = vma->vm_end - vma->vm_start;
++ swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */
++}
++
++/*
++ * Systems with larger DMA zones (those that don't support ISA) can
++ * initialize the swiotlb later using the slab allocator if needed.
++ * This should be just like above, but with some error catching.
++ */
++int
++swiotlb_late_init_with_default_size (size_t default_size)
++{
++ unsigned long i, req_nslabs = io_tlb_nslabs;
++ unsigned int order;
+
++ if (!io_tlb_nslabs) {
++ io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
++ io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
++ }
+
-+#if 0
++#ifdef CONFIG_XEN
++ if (is_running_on_xen())
++ io_tlb_nslabs = roundup_pow_of_two(io_tlb_nslabs);
++#endif
+ /*
-+ *XXX FIXME: linux-2.6.16.29, linux-2.6.17
-+ * valid_mmap_phys_addr_range() in linux/arch/ia64/kernel/efi.c
-+ * fails checks.
-+ * linux-2.6.18.1's returns always 1.
-+ * Its comments says
-+ *
-+ * MMIO regions are often missing from the EFI memory map.
-+ * We must allow mmap of them for programs like X, so we
-+ * currently can't do any useful validation.
-+ */
-+ if (!valid_mmap_phys_addr_range(addr, &size))
-+ return -EINVAL;
-+ if (size < vma->vm_end - vma->vm_start)
-+ return -EINVAL;
++ * Get IO TLB memory from the low pages
++ */
++ order = get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
++ io_tlb_nslabs = SLABS_PER_PAGE << order;
++
++ while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
++ io_tlb_start = (char *)__get_free_pages(GFP_DMA | __GFP_NOWARN,
++ order);
++ if (io_tlb_start)
++ break;
++ order--;
++ }
++
++ if (!io_tlb_start)
++ goto cleanup1;
++
++ if (order != get_order(io_tlb_nslabs * (1 << IO_TLB_SHIFT))) {
++ printk(KERN_WARNING "Warning: only able to allocate %ld MB "
++ "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
++ io_tlb_nslabs = SLABS_PER_PAGE << order;
++ }
++ io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
++ memset(io_tlb_start, 0, io_tlb_nslabs * (1 << IO_TLB_SHIFT));
++
++#ifdef CONFIG_XEN
++ for (i = 0 ; i < io_tlb_nslabs ; i += IO_TLB_SEGSIZE) {
++ if (xen_create_contiguous_region(
++ (unsigned long)io_tlb_start +
++ (i << IO_TLB_SHIFT),
++ get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
++ DMA_BITS))
++ panic("Failed to setup Xen contiguous region");
++ }
+#endif
++ /*
++ * Allocate and initialize the free list array. This array is used
++ * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
++ * between io_tlb_start and io_tlb_end.
++ */
++ io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL,
++ get_order(io_tlb_nslabs * sizeof(int)));
++ if (!io_tlb_list)
++ goto cleanup2;
+
-+ if (is_running_on_xen()) {
-+ unsigned long offset = HYPERVISOR_ioremap(addr, size);
-+ if (IS_ERR_VALUE(offset))
-+ return offset;
++ for (i = 0; i < io_tlb_nslabs; i++)
++ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
++ io_tlb_index = 0;
++
++ io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL,
++ get_order(io_tlb_nslabs * sizeof(char *)));
++ if (!io_tlb_orig_addr)
++ goto cleanup3;
++
++ memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *));
++
++ /*
++ * Get the overflow emergency buffer
++ */
++ io_tlb_overflow_buffer = (void *)__get_free_pages(GFP_DMA,
++ get_order(io_tlb_overflow));
++ if (!io_tlb_overflow_buffer)
++ goto cleanup4;
++
++#ifdef CONFIG_XEN
++ if (xen_create_contiguous_region((unsigned long)io_tlb_overflow_buffer,
++ get_order(io_tlb_overflow), DMA_BITS))
++ panic("Failed to setup Xen contiguous region for overflow");
++#endif
++ printk(KERN_INFO "Placing %ldMB software IO TLB between 0x%lx - "
++ "0x%lx\n", (io_tlb_nslabs * (1 << IO_TLB_SHIFT)) >> 20,
++ virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
++
++ return 0;
++
++cleanup4:
++ free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs *
++ sizeof(char *)));
++ io_tlb_orig_addr = NULL;
++cleanup3:
++ free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
++ sizeof(int)));
++ io_tlb_list = NULL;
++ io_tlb_end = NULL;
++cleanup2:
++ free_pages((unsigned long)io_tlb_start, order);
++ io_tlb_start = NULL;
++cleanup1:
++ io_tlb_nslabs = req_nslabs;
++ return -ENOMEM;
++}
++
++static inline int
++address_needs_mapping(struct device *hwdev, dma_addr_t addr)
++{
++ dma_addr_t mask = 0xffffffff;
++ /* If the device has a mask, use it, otherwise default to 32 bits */
++ if (hwdev && hwdev->dma_mask)
++ mask = *hwdev->dma_mask;
++ return (addr & ~mask) != 0;
++}
++
++/*
++ * Allocates bounce buffer and returns its kernel virtual address.
++ */
++static void *
++map_single(struct device *hwdev, char *buffer, size_t size, int dir)
++{
++ unsigned long flags;
++ char *dma_addr;
++ unsigned int nslots, stride, index, wrap;
++ char *slot_buf;
++ int i;
++
++ /*
++ * For mappings greater than a page, we limit the stride (and
++ * hence alignment) to a page size.
++ */
++ nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
++ if (size > PAGE_SIZE)
++ stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
++ else
++ stride = 1;
++
++ BUG_ON(!nslots);
++
++ /*
++ * Find suitable number of IO TLB entries size that will fit this
++ * request and allocate a buffer from that IO TLB pool.
++ */
++ spin_lock_irqsave(&io_tlb_lock, flags);
++ {
++ wrap = index = ALIGN(io_tlb_index, stride);
++
++ if (index >= io_tlb_nslabs)
++ wrap = index = 0;
++
++ do {
++ /*
++ * If we find a slot that indicates we have 'nslots'
++ * number of contiguous buffers, we allocate the
++ * buffers from that slot and mark the entries as '0'
++ * indicating unavailable.
++ */
++ if (io_tlb_list[index] >= nslots) {
++ int count = 0;
++
++ for (i = index; i < (int) (index + nslots); i++)
++ io_tlb_list[i] = 0;
++ for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--)
++ io_tlb_list[i] = ++count;
++ dma_addr = io_tlb_start + (index << IO_TLB_SHIFT);
++
++ /*
++ * Update the indices to avoid searching in
++ * the next round.
++ */
++ io_tlb_index = ((index + nslots) < io_tlb_nslabs
++ ? (index + nslots) : 0);
++
++ goto found;
++ }
++ index += stride;
++ if (index >= io_tlb_nslabs)
++ index = 0;
++ } while (index != wrap);
++
++ spin_unlock_irqrestore(&io_tlb_lock, flags);
++ return NULL;
+ }
++ found:
++ spin_unlock_irqrestore(&io_tlb_lock, flags);
+
-+ if (uncached_access(file, vma->vm_pgoff << PAGE_SHIFT))
-+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++ /*
++ * Save away the mapping from the original address to the DMA address.
++ * This is needed when we sync the memory. Then we sync the buffer if
++ * needed.
++ */
++ slot_buf = buffer;
++ for (i = 0; i < nslots; i++) {
++ io_tlb_orig_addr[index + i] = slot_buf;
++ slot_buf += 1 << IO_TLB_SHIFT;
++ }
++ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
++ memcpy(dma_addr, buffer, size);
+
-+ /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
-+ if (remap_pfn_range(vma,
-+ vma->vm_start,
-+ vma->vm_pgoff,
-+ size,
-+ vma->vm_page_prot))
-+ return -EAGAIN;
-+ return 0;
-+}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/util.c tmp-linux-2.6-xen.patch/arch/ia64/xen/util.c
---- pristine-linux-2.6.18/arch/ia64/xen/util.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/util.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,105 @@
++ return dma_addr;
++}
++
++/*
++ * dma_addr is the kernel virtual address of the bounce buffer to unmap.
++ */
++static void
++unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
++{
++ unsigned long flags;
++ int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
++ int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
++ char *buffer = io_tlb_orig_addr[index];
++
++ /*
++ * First, sync the memory before unmapping the entry
++ */
++ if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
++ /*
++ * bounce... copy the data back into the original buffer * and
++ * delete the bounce buffer.
++ */
++ memcpy(buffer, dma_addr, size);
++
++ /*
++ * Return the buffer to the free list by setting the corresponding
++ * entries to indicate the number of contigous entries available.
++ * While returning the entries to the free list, we merge the entries
++ * with slots below and above the pool being returned.
++ */
++ spin_lock_irqsave(&io_tlb_lock, flags);
++ {
++ count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
++ io_tlb_list[index + nslots] : 0);
++ /*
++ * Step 1: return the slots to the free list, merging the
++ * slots with superceeding slots
++ */
++ for (i = index + nslots - 1; i >= index; i--)
++ io_tlb_list[i] = ++count;
++ /*
++ * Step 2: merge the returned slots with the preceding slots,
++ * if available (non zero)
++ */
++ for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE -1) && io_tlb_list[i]; i--)
++ io_tlb_list[i] = ++count;
++ }
++ spin_unlock_irqrestore(&io_tlb_lock, flags);
++}
++
++static void
++sync_single(struct device *hwdev, char *dma_addr, size_t size,
++ int dir, int target)
++{
++ int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
++ char *buffer = io_tlb_orig_addr[index];
++
++ switch (target) {
++ case SYNC_FOR_CPU:
++ if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
++ memcpy(buffer, dma_addr, size);
++ else
++ BUG_ON(dir != DMA_TO_DEVICE);
++ break;
++ case SYNC_FOR_DEVICE:
++ if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
++ memcpy(dma_addr, buffer, size);
++ else
++ BUG_ON(dir != DMA_FROM_DEVICE);
++ break;
++ default:
++ BUG();
++ }
++}
++
++void *
++swiotlb_alloc_coherent(struct device *hwdev, size_t size,
++ dma_addr_t *dma_handle, gfp_t flags)
++{
++ unsigned long dev_addr;
++ void *ret;
++ int order = get_order(size);
++
++ /*
++ * XXX fix me: the DMA API should pass us an explicit DMA mask
++ * instead, or use ZONE_DMA32 (ia64 overloads ZONE_DMA to be a ~32
++ * bit range instead of a 16MB one).
++ */
++ flags |= GFP_DMA;
++
++ ret = (void *)__get_free_pages(flags, order);
++#ifdef CONFIG_XEN
++ if (ret && is_running_on_xen()) {
++ if (xen_create_contiguous_region((unsigned long)ret, order,
++ fls64(hwdev->coherent_dma_mask))) {
++ free_pages((unsigned long)ret, order);
++ ret = NULL;
++ } else {
++ /*
++ * Short circuit the rest, xen_create_contiguous_region
++ * should fail if it didn't give us an address within
++ * the mask requested.
++ */
++ memset(ret, 0, size);
++ *dma_handle = virt_to_bus(ret);
++ return ret;
++ }
++ }
++#endif
++ if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) {
++ /*
++ * The allocated memory isn't reachable by the device.
++ * Fall back on swiotlb_map_single().
++ */
++ free_pages((unsigned long) ret, order);
++ ret = NULL;
++ }
++ if (!ret) {
++ /*
++ * We are either out of memory or the device can't DMA
++ * to GFP_DMA memory; fall back on
++ * swiotlb_map_single(), which will grab memory from
++ * the lowest available address range.
++ */
++ dma_addr_t handle;
++ handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE);
++ if (swiotlb_dma_mapping_error(handle))
++ return NULL;
++
++ ret = bus_to_virt(handle);
++ }
++
++ memset(ret, 0, size);
++ dev_addr = virt_to_bus(ret);
++
++ /* Confirm address can be DMA'd by device */
++ if (address_needs_mapping(hwdev, dev_addr)) {
++ printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016lx\n",
++ (unsigned long long)*hwdev->dma_mask, dev_addr);
++ panic("swiotlb_alloc_coherent: allocated memory is out of "
++ "range for device");
++ }
++ *dma_handle = dev_addr;
++ return ret;
++}
++
++void
++swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
++ dma_addr_t dma_handle)
++{
++ if (!(vaddr >= (void *)io_tlb_start
++ && vaddr < (void *)io_tlb_end)) {
++#ifdef CONFIG_XEN
++ xen_destroy_contiguous_region((unsigned long)vaddr,
++ get_order(size));
++#endif
++ free_pages((unsigned long) vaddr, get_order(size));
++ } else
++ /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
++ swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE);
++}
++
++static void
++swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
++{
++ /*
++ * Ran out of IOMMU space for this operation. This is very bad.
++ * Unfortunately the drivers cannot handle this operation properly.
++ * unless they check for dma_mapping_error (most don't)
++ * When the mapping is small enough return a static buffer to limit
++ * the damage, or panic when the transfer is too big.
++ */
++ printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at "
++ "device %s\n", size, dev ? dev->bus_id : "?");
++
++ if (size > io_tlb_overflow && do_panic) {
++ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
++ panic("DMA: Memory would be corrupted\n");
++ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
++ panic("DMA: Random memory would be DMAed\n");
++ }
++}
++
++/*
++ * Map a single buffer of the indicated size for DMA in streaming mode. The
++ * physical address to use is returned.
++ *
++ * Once the device is given the dma address, the device owns this memory until
++ * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
++ */
++dma_addr_t
++swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
++{
++ unsigned long dev_addr = gnttab_dma_map_virt(ptr);
++ void *map;
++
++ BUG_ON(dir == DMA_NONE);
++ /*
++ * If the pointer passed in happens to be in the device's DMA window,
++ * we can safely return the device addr and not worry about bounce
++ * buffering it.
++ */
++ if (!range_straddles_page_boundary(__pa(ptr), size) &&
++ !address_needs_mapping(hwdev, dev_addr) && !swiotlb_force)
++ return dev_addr;
++
++ __gnttab_dma_unmap_page(virt_to_page(ptr));
++ /*
++ * Oh well, have to allocate and map a bounce buffer.
++ */
++ map = map_single(hwdev, ptr, size, dir);
++ if (!map) {
++ swiotlb_full(hwdev, size, dir, 1);
++ map = io_tlb_overflow_buffer;
++ }
++
++ dev_addr = virt_to_bus(map);
++
++ /*
++ * Ensure that the address returned is DMA'ble
++ */
++ if (address_needs_mapping(hwdev, dev_addr))
++ panic("map_single: bounce buffer is not DMA'ble");
++
++ return dev_addr;
++}
++
++/*
++ * Since DMA is i-cache coherent, any (complete) pages that were written via
++ * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
++ * flush them when they get mapped into an executable vm-area.
++ */
++static void
++mark_clean(void *addr, size_t size)
++{
++ unsigned long pg_addr, end;
++
++#ifdef CONFIG_XEN
++ /* XXX: Bad things happen when starting domUs if this is enabled. */
++ if (is_running_on_xen())
++ return;
++#endif
++
++ pg_addr = PAGE_ALIGN((unsigned long) addr);
++ end = (unsigned long) addr + size;
++ while (pg_addr + PAGE_SIZE <= end) {
++ struct page *page = virt_to_page(pg_addr);
++ set_bit(PG_arch_1, &page->flags);
++ pg_addr += PAGE_SIZE;
++ }
++}
++
++/*
++ * Unmap a single streaming mode DMA translation. The dma_addr and size must
++ * match what was provided for in a previous swiotlb_map_single call. All
++ * other usages are undefined.
++ *
++ * After this call, reads by the cpu to the buffer are guaranteed to see
++ * whatever the device wrote there.
++ */
++void
++swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
++ int dir)
++{
++ char *dma_addr = bus_to_virt(dev_addr);
++
++ BUG_ON(dir == DMA_NONE);
++ if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
++ unmap_single(hwdev, dma_addr, size, dir);
++ else {
++ __gnttab_dma_unmap_page(virt_to_page(dma_addr));
++ if (dir == DMA_FROM_DEVICE)
++ mark_clean(dma_addr, size);
++ }
++}
++
++/*
++ * Make physical memory consistent for a single streaming mode DMA translation
++ * after a transfer.
++ *
++ * If you perform a swiotlb_map_single() but wish to interrogate the buffer
++ * using the cpu, yet do not wish to teardown the dma mapping, you must
++ * call this function before doing so. At the next point you give the dma
++ * address back to the card, you must first perform a
++ * swiotlb_dma_sync_for_device, and then the device again owns the buffer
++ */
++static inline void
++swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
++ size_t size, int dir, int target)
++{
++ char *dma_addr = bus_to_virt(dev_addr);
++
++ BUG_ON(dir == DMA_NONE);
++ if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
++ sync_single(hwdev, dma_addr, size, dir, target);
++ else if (dir == DMA_FROM_DEVICE)
++ mark_clean(dma_addr, size);
++}
++
++void
++swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
++ size_t size, int dir)
++{
++ swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
++}
++
++void
++swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
++ size_t size, int dir)
++{
++ swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
++}
++
++/*
++ * Same as above, but for a sub-range of the mapping.
++ */
++static inline void
++swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr,
++ unsigned long offset, size_t size,
++ int dir, int target)
++{
++ char *dma_addr = bus_to_virt(dev_addr) + offset;
++
++ BUG_ON(dir == DMA_NONE);
++ if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
++ sync_single(hwdev, dma_addr, size, dir, target);
++ else if (dir == DMA_FROM_DEVICE)
++ mark_clean(dma_addr, size);
++}
++
++void
++swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
++ unsigned long offset, size_t size, int dir)
++{
++ swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,
++ SYNC_FOR_CPU);
++}
++
++void
++swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
++ unsigned long offset, size_t size, int dir)
++{
++ swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,
++ SYNC_FOR_DEVICE);
++}
++
++/*
++ * Map a set of buffers described by scatterlist in streaming mode for DMA.
++ * This is the scatter-gather version of the above swiotlb_map_single
++ * interface. Here the scatter gather list elements are each tagged with the
++ * appropriate dma address and length. They are obtained via
++ * sg_dma_{address,length}(SG).
++ *
++ * NOTE: An implementation may be able to use a smaller number of
++ * DMA address/length pairs than there are SG table elements.
++ * (for example via virtual mapping capabilities)
++ * The routine returns the number of addr/length pairs actually
++ * used, at most nents.
++ *
++ * Device ownership issues as mentioned above for swiotlb_map_single are the
++ * same here.
++ */
++int
++swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
++ int dir)
++{
++ void *addr;
++ unsigned long dev_addr;
++ int i;
++
++ BUG_ON(dir == DMA_NONE);
++
++ for (i = 0; i < nelems; i++, sg++) {
++ addr = SG_ENT_VIRT_ADDRESS(sg);
++ dev_addr = gnttab_dma_map_virt(addr);
++ if (swiotlb_force ||
++ range_straddles_page_boundary(page_to_pseudophys(sg->page)
++ + sg->offset, sg->length) ||
++ address_needs_mapping(hwdev, dev_addr)) {
++ void *map;
++ __gnttab_dma_unmap_page(sg->page);
++ map = map_single(hwdev, addr, sg->length, dir);
++ sg->dma_address = virt_to_bus(map);
++ if (!map) {
++ /* Don't panic here, we expect map_sg users
++ to do proper error handling. */
++ swiotlb_full(hwdev, sg->length, dir, 0);
++ swiotlb_unmap_sg(hwdev, sg - i, i, dir);
++ sg[0].dma_length = 0;
++ return 0;
++ }
++ } else
++ sg->dma_address = dev_addr;
++ sg->dma_length = sg->length;
++ }
++ return nelems;
++}
++
++/*
++ * Unmap a set of streaming mode DMA translations. Again, cpu read rules
++ * concerning calls here are the same as for swiotlb_unmap_single() above.
++ */
++void
++swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
++ int dir)
++{
++ int i;
++
++ BUG_ON(dir == DMA_NONE);
++
++ for (i = 0; i < nelems; i++, sg++)
++ if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
++ unmap_single(hwdev, (void *) bus_to_virt(sg->dma_address), sg->dma_length, dir);
++ else {
++ __gnttab_dma_unmap_page(sg->page);
++ if (dir == DMA_FROM_DEVICE)
++ mark_clean(SG_ENT_VIRT_ADDRESS(sg),
++ sg->dma_length);
++ }
++}
++
++/*
++ * Make physical memory consistent for a set of streaming mode DMA translations
++ * after a transfer.
++ *
++ * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
++ * and usage.
++ */
++static inline void
++swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,
++ int nelems, int dir, int target)
++{
++ int i;
++
++ BUG_ON(dir == DMA_NONE);
++
++ for (i = 0; i < nelems; i++, sg++)
++ if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
++ sync_single(hwdev, (void *) sg->dma_address,
++ sg->dma_length, dir, target);
++}
++
++void
++swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
++ int nelems, int dir)
++{
++ swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
++}
++
++void
++swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
++ int nelems, int dir)
++{
++ swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
++}
++
++int
++swiotlb_dma_mapping_error(dma_addr_t dma_addr)
++{
++ return (dma_addr == virt_to_bus(io_tlb_overflow_buffer));
++}
++
++/*
++ * Return whether the given device DMA address mask can be supported
++ * properly. For example, if your device can only drive the low 24-bits
++ * during bus mastering, then you would pass 0x00ffffff as the mask to
++ * this function.
++ */
++int
++swiotlb_dma_supported (struct device *hwdev, u64 mask)
++{
++#ifdef CONFIG_XEN
++ return (virt_to_bus(io_tlb_end - 1)) <= mask;
++#else
++ return (virt_to_bus(io_tlb_end) - 1) <= mask;
++#endif
++}
++
++EXPORT_SYMBOL(swiotlb_init);
++EXPORT_SYMBOL(swiotlb_map_single);
++EXPORT_SYMBOL(swiotlb_unmap_single);
++EXPORT_SYMBOL(swiotlb_map_sg);
++EXPORT_SYMBOL(swiotlb_unmap_sg);
++EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
++EXPORT_SYMBOL(swiotlb_sync_single_for_device);
++EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu);
++EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);
++EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
++EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
++EXPORT_SYMBOL(swiotlb_dma_mapping_error);
++EXPORT_SYMBOL(swiotlb_alloc_coherent);
++EXPORT_SYMBOL(swiotlb_free_coherent);
++EXPORT_SYMBOL(swiotlb_dma_supported);
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/util.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/util.c
+--- linux-2.6.18.8/arch/ia64/xen/util.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/util.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,102 @@
+/******************************************************************************
+ * arch/ia64/xen/util.c
+ * This file is the ia64 counterpart of drivers/xen/util.c
@@ -25928,25 +29326,23 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/util.c tmp-linux-2.6-xen.patch/ar
+ int order;
+ unsigned long virt;
+ unsigned long nr_pages;
-+ struct vm_struct* area;
-+
++ struct vm_struct *area;
++
+ order = get_order(size);
+ virt = __get_free_pages(GFP_KERNEL, order);
-+ if (virt == 0) {
++ if (virt == 0)
+ goto err0;
-+ }
+ nr_pages = 1 << order;
+ scrub_pages(virt, nr_pages);
-+
++
+ area = kmalloc(sizeof(*area), GFP_KERNEL);
-+ if (area == NULL) {
++ if (area == NULL)
+ goto err1;
-+ }
-+
-+ area->flags = VM_IOREMAP;//XXX
++
++ area->flags = VM_IOREMAP; /* XXX */
+ area->addr = (void*)virt;
+ area->size = size;
-+ area->pages = NULL; //XXX
++ area->pages = NULL; /* XXX */
+ area->nr_pages = nr_pages;
+ area->phys_addr = 0; /* xenbus_map_ring_valloc uses this field! */
+
@@ -25956,7 +29352,6 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/util.c tmp-linux-2.6-xen.patch/ar
+ free_pages(virt, order);
+err0:
+ return NULL;
-+
+}
+EXPORT_SYMBOL_GPL(alloc_vm_area);
+
@@ -25966,8 +29361,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/util.c tmp-linux-2.6-xen.patch/ar
+ unsigned long i;
+ unsigned long phys_addr = __pa(area->addr);
+
-+ // This area is used for foreign page mappping.
-+ // So underlying machine page may not be assigned.
++ /* This area is used for foreign page mappping.
++ * So underlying machine page may not be assigned. */
+ for (i = 0; i < (1 << order); i++) {
+ unsigned long ret;
+ unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i;
@@ -25996,10 +29391,10 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/util.c tmp-linux-2.6-xen.patch/ar
+ * tab-width: 8
+ * End:
+ */
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.patch/arch/ia64/xen/xcom_hcall.c
---- pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xcom_hcall.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,383 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xcom_hcall.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/xcom_hcall.c
+--- linux-2.6.18.8/arch/ia64/xen/xcom_hcall.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xcom_hcall.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,663 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
@@ -26016,6 +29411,11 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Tristan Gingold <tristan.gingold@bull.net>
++ *
++ * Copyright (c) 2007
++ * Isaku Yamahata <yamahata at valinux co jp>
++ * VA Linux Systems Japan K.K.
++ * consolidate mini and inline version.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
@@ -26032,11 +29432,12 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+#include <xen/interface/physdev.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/callback.h>
-+#include <xen/interface/acm_ops.h>
++#include <xen/interface/xsm/acm_ops.h>
+#include <xen/interface/hvm/params.h>
+#include <xen/interface/xenoprof.h>
+#include <xen/interface/vcpu.h>
-+#include <asm/hypercall.h>
++#include <xen/interface/kexec.h>
++#include <asm/hypervisor.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+#include <asm/xen/xencomm.h>
@@ -26044,8 +29445,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+
+/* Xencomm notes:
+ * This file defines hypercalls to be used by xencomm. The hypercalls simply
-+ * create inlines descriptors for pointers and then call the raw arch hypercall
-+ * xencomm_arch_hypercall_XXX
++ * create inlines or mini descriptors for pointers and then call the raw arch
++ * hypercall xencomm_arch_hypercall_XXX
+ *
+ * If the arch wants to directly use these hypercalls, simply define macros
+ * in asm/hypercall.h, eg:
@@ -26054,106 +29455,206 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+ * The arch may also define HYPERVISOR_xxx as a function and do more operations
+ * before/after doing the hypercall.
+ *
-+ * Note: because only inline descriptors are created these functions must only
-+ * be called with in kernel memory parameters.
++ * Note: because only inline or mini descriptors are created these functions
++ * must only be called with in kernel memory parameters.
+ */
+
+int
+xencomm_hypercall_console_io(int cmd, int count, char *str)
+{
+ return xencomm_arch_hypercall_console_io
-+ (cmd, count, xencomm_create_inline(str));
++ (cmd, count, xencomm_map_no_alloc(str, count));
+}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_console_io);
+
+int
+xencomm_hypercall_event_channel_op(int cmd, void *op)
+{
-+ return xencomm_arch_hypercall_event_channel_op
-+ (cmd, xencomm_create_inline(op));
++ struct xencomm_handle *desc;
++ desc = xencomm_map_no_alloc(op, sizeof(evtchn_op_t));
++ if (desc == NULL)
++ return -EINVAL;
++
++ return xencomm_arch_hypercall_event_channel_op(cmd, desc);
+}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_event_channel_op);
+
+int
+xencomm_hypercall_xen_version(int cmd, void *arg)
+{
++ struct xencomm_handle *desc;
++ unsigned int argsize;
++
+ switch (cmd) {
+ case XENVER_version:
++ /* do not actually pass an argument */
++ return xencomm_arch_hypercall_xen_version(cmd, 0);
+ case XENVER_extraversion:
++ argsize = sizeof(xen_extraversion_t);
++ break;
+ case XENVER_compile_info:
++ argsize = sizeof(xen_compile_info_t);
++ break;
+ case XENVER_capabilities:
++ argsize = sizeof(xen_capabilities_info_t);
++ break;
+ case XENVER_changeset:
++ argsize = sizeof(xen_changeset_info_t);
++ break;
+ case XENVER_platform_parameters:
++ argsize = sizeof(xen_platform_parameters_t);
++ break;
+ case XENVER_pagesize:
++ argsize = (arg == NULL) ? 0 : sizeof(void *);
++ break;
+ case XENVER_get_features:
++ argsize = (arg == NULL) ? 0 : sizeof(xen_feature_info_t);
+ break;
++
+ default:
-+ printk("%s: unknown version cmd %d\n", __func__, cmd);
++ printk("%s: unknown version op %d\n", __func__, cmd);
+ return -ENOSYS;
+ }
+
-+ return xencomm_arch_hypercall_xen_version
-+ (cmd, xencomm_create_inline(arg));
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
++
++ return xencomm_arch_hypercall_xen_version(cmd, desc);
+}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_xen_version);
+
+int
+xencomm_hypercall_physdev_op(int cmd, void *op)
+{
++ unsigned int argsize;
++
++ switch (cmd) {
++ case PHYSDEVOP_apic_read:
++ case PHYSDEVOP_apic_write:
++ argsize = sizeof(physdev_apic_t);
++ break;
++ case PHYSDEVOP_alloc_irq_vector:
++ case PHYSDEVOP_free_irq_vector:
++ argsize = sizeof(physdev_irq_t);
++ break;
++ case PHYSDEVOP_irq_status_query:
++ argsize = sizeof(physdev_irq_status_query_t);
++ break;
++
++ default:
++ printk("%s: unknown physdev op %d\n", __func__, cmd);
++ return -ENOSYS;
++ }
++
+ return xencomm_arch_hypercall_physdev_op
-+ (cmd, xencomm_create_inline(op));
++ (cmd, xencomm_map_no_alloc(op, argsize));
+}
+
-+static void *
-+xencommize_grant_table_op(unsigned int cmd, void *op, unsigned int count)
++static int
++xencommize_grant_table_op(struct xencomm_mini **xc_area,
++ unsigned int cmd, void *op, unsigned int count,
++ struct xencomm_handle **desc)
+{
++ struct xencomm_handle *desc1;
++ unsigned int argsize;
++
+ switch (cmd) {
+ case GNTTABOP_map_grant_ref:
++ argsize = sizeof(struct gnttab_map_grant_ref);
++ break;
+ case GNTTABOP_unmap_grant_ref:
++ argsize = sizeof(struct gnttab_unmap_grant_ref);
++ break;
++ case GNTTABOP_unmap_and_replace:
++ argsize = sizeof(struct gnttab_unmap_and_replace);
+ break;
+ case GNTTABOP_setup_table:
+ {
+ struct gnttab_setup_table *setup = op;
-+ struct xencomm_handle *frame_list;
+
-+ frame_list = xencomm_create_inline
-+ (xen_guest_handle(setup->frame_list));
++ argsize = sizeof(*setup);
+
-+ set_xen_guest_handle(setup->frame_list, (void *)frame_list);
++ if (count != 1)
++ return -EINVAL;
++ desc1 = __xencomm_map_no_alloc
++ (xen_guest_handle(setup->frame_list),
++ setup->nr_frames *
++ sizeof(*xen_guest_handle(setup->frame_list)),
++ *xc_area);
++ if (desc1 == NULL)
++ return -EINVAL;
++ (*xc_area)++;
++ set_xen_guest_handle(setup->frame_list, (void *)desc1);
+ break;
+ }
+ case GNTTABOP_dump_table:
++ argsize = sizeof(struct gnttab_dump_table);
++ break;
+ case GNTTABOP_transfer:
++ argsize = sizeof(struct gnttab_transfer);
++ break;
+ case GNTTABOP_copy:
++ argsize = sizeof(struct gnttab_copy);
++ break;
++ case GNTTABOP_query_size:
++ argsize = sizeof(struct gnttab_query_size);
+ break;
+ default:
-+ printk("%s: unknown grant table op %d\n", __func__, cmd);
++ printk("%s: unknown hypercall grant table op %d\n",
++ __func__, cmd);
+ BUG();
+ }
+
-+ return xencomm_create_inline(op);
++ *desc = __xencomm_map_no_alloc(op, count * argsize, *xc_area);
++ if (*desc == NULL)
++ return -EINVAL;
++ (*xc_area)++;
++
++ return 0;
+}
+
+int
-+xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, unsigned int count)
++xencomm_hypercall_grant_table_op(unsigned int cmd, void *op,
++ unsigned int count)
+{
-+ void *desc = xencommize_grant_table_op (cmd, op, count);
++ int rc;
++ struct xencomm_handle *desc;
++ XENCOMM_MINI_ALIGNED(xc_area, 2);
++
++ rc = xencommize_grant_table_op(&xc_area, cmd, op, count, &desc);
++ if (rc)
++ return rc;
+
+ return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
+}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_grant_table_op);
+
+int
+xencomm_hypercall_sched_op(int cmd, void *arg)
+{
++ struct xencomm_handle *desc;
++ unsigned int argsize;
++
+ switch (cmd) {
+ case SCHEDOP_yield:
+ case SCHEDOP_block:
++ argsize = 0;
++ break;
+ case SCHEDOP_shutdown:
++ argsize = sizeof(sched_shutdown_t);
++ break;
+ case SCHEDOP_remote_shutdown:
++ argsize = sizeof(sched_remote_shutdown_t);
+ break;
+ case SCHEDOP_poll:
+ {
+ sched_poll_t *poll = arg;
+ struct xencomm_handle *ports;
+
-+ ports = xencomm_create_inline(xen_guest_handle(poll->ports));
++ argsize = sizeof(sched_poll_t);
++ ports = xencomm_map_no_alloc(xen_guest_handle(poll->ports),
++ sizeof(*xen_guest_handle(poll->ports)));
+
+ set_xen_guest_handle(poll->ports, (void *)ports);
+ break;
@@ -26163,14 +29664,22 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+ return -ENOSYS;
+ }
+
-+ return xencomm_arch_hypercall_sched_op(cmd, xencomm_create_inline(arg));
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
++
++ return xencomm_arch_hypercall_sched_op(cmd, desc);
+}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op);
+
+int
+xencomm_hypercall_multicall(void *call_list, int nr_calls)
+{
++ int rc;
+ int i;
+ multicall_entry_t *mce;
++ struct xencomm_handle *desc;
++ XENCOMM_MINI_ALIGNED(xc_area, nr_calls * 2);
+
+ for (i = 0; i < nr_calls; i++) {
+ mce = (multicall_entry_t *)call_list + i;
@@ -26181,9 +29690,13 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+ /* No-op on ia64. */
+ break;
+ case __HYPERVISOR_grant_table_op:
-+ mce->args[1] = (unsigned long)xencommize_grant_table_op
-+ (mce->args[0], (void *)mce->args[1],
-+ mce->args[2]);
++ rc = xencommize_grant_table_op
++ (&xc_area,
++ mce->args[0], (void *)mce->args[1],
++ mce->args[2], &desc);
++ if (rc)
++ return rc;
++ mce->args[1] = (unsigned long)desc;
+ break;
+ case __HYPERVISOR_memory_op:
+ default:
@@ -26193,17 +29706,26 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+ }
+ }
+
-+ return xencomm_arch_hypercall_multicall
-+ (xencomm_create_inline(call_list), nr_calls);
++ desc = xencomm_map_no_alloc(call_list,
++ nr_calls * sizeof(multicall_entry_t));
++ if (desc == NULL)
++ return -EINVAL;
++
++ return xencomm_arch_hypercall_multicall(desc, nr_calls);
+}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_multicall);
+
+int
+xencomm_hypercall_callback_op(int cmd, void *arg)
+{
++ unsigned int argsize;
+ switch (cmd)
+ {
+ case CALLBACKOP_register:
++ argsize = sizeof(struct callback_register);
++ break;
+ case CALLBACKOP_unregister:
++ argsize = sizeof(struct callback_unregister);
+ break;
+ default:
+ printk("%s: unknown callback op %d\n", __func__, cmd);
@@ -26211,16 +29733,24 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+ }
+
+ return xencomm_arch_hypercall_callback_op
-+ (cmd, xencomm_create_inline(arg));
++ (cmd, xencomm_map_no_alloc(arg, argsize));
+}
+
-+static void
-+xencommize_memory_reservation (xen_memory_reservation_t *mop)
++static int
++xencommize_memory_reservation(struct xencomm_mini *xc_area,
++ xen_memory_reservation_t *mop)
+{
+ struct xencomm_handle *desc;
+
-+ desc = xencomm_create_inline(xen_guest_handle(mop->extent_start));
++ desc = __xencomm_map_no_alloc(xen_guest_handle(mop->extent_start),
++ mop->nr_extents *
++ sizeof(*xen_guest_handle(mop->extent_start)),
++ xc_area);
++ if (desc == NULL)
++ return -EINVAL;
++
+ set_xen_guest_handle(mop->extent_start, (void *)desc);
++ return 0;
+}
+
+int
@@ -26228,426 +29758,110 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_hcall.c tmp-linux-2.6-xen.pa
+{
+ XEN_GUEST_HANDLE(xen_pfn_t) extent_start_va[2];
+ xen_memory_reservation_t *xmr = NULL, *xme_in = NULL, *xme_out = NULL;
++ xen_memory_map_t *memmap = NULL;
++ XEN_GUEST_HANDLE(void) buffer;
+ int rc;
++ struct xencomm_handle *desc;
++ unsigned int argsize;
++ XENCOMM_MINI_ALIGNED(xc_area, 2);
+
+ switch (cmd) {
+ case XENMEM_increase_reservation:
+ case XENMEM_decrease_reservation:
+ case XENMEM_populate_physmap:
+ xmr = (xen_memory_reservation_t *)arg;
-+ xen_guest_handle(extent_start_va[0]) =
-+ xen_guest_handle(xmr->extent_start);
-+ xencommize_memory_reservation((xen_memory_reservation_t *)arg);
-+ break;
-+
-+ case XENMEM_maximum_ram_page:
-+ break;
-+
-+ case XENMEM_exchange:
-+ xme_in = &((xen_memory_exchange_t *)arg)->in;
-+ xme_out = &((xen_memory_exchange_t *)arg)->out;
-+ xen_guest_handle(extent_start_va[0]) =
-+ xen_guest_handle(xme_in->extent_start);
-+ xen_guest_handle(extent_start_va[1]) =
-+ xen_guest_handle(xme_out->extent_start);
-+ xencommize_memory_reservation
-+ (&((xen_memory_exchange_t *)arg)->in);
-+ xencommize_memory_reservation
-+ (&((xen_memory_exchange_t *)arg)->out);
-+ break;
++ set_xen_guest_handle(extent_start_va[0],
++ xen_guest_handle(xmr->extent_start));
+
-+ default:
-+ printk("%s: unknown memory op %d\n", __func__, cmd);
-+ return -ENOSYS;
-+ }
-+
-+ rc = xencomm_arch_hypercall_memory_op(cmd, xencomm_create_inline(arg));
-+
-+ switch (cmd) {
-+ case XENMEM_increase_reservation:
-+ case XENMEM_decrease_reservation:
-+ case XENMEM_populate_physmap:
-+ xen_guest_handle(xmr->extent_start) =
-+ xen_guest_handle(extent_start_va[0]);
++ argsize = sizeof(*xmr);
++ rc = xencommize_memory_reservation(xc_area, xmr);
++ if (rc)
++ return rc;
++ xc_area++;
+ break;
+
-+ case XENMEM_exchange:
-+ xen_guest_handle(xme_in->extent_start) =
-+ xen_guest_handle(extent_start_va[0]);
-+ xen_guest_handle(xme_out->extent_start) =
-+ xen_guest_handle(extent_start_va[1]);
++ case XENMEM_maximum_gpfn:
++ argsize = 0;
+ break;
-+ }
-+
-+ return rc;
-+}
+
-+unsigned long
-+xencomm_hypercall_hvm_op(int cmd, void *arg)
-+{
-+ switch (cmd) {
-+ case HVMOP_set_param:
-+ case HVMOP_get_param:
++ case XENMEM_maximum_ram_page:
++ argsize = 0;
+ break;
-+ default:
-+ printk("%s: unknown hvm op %d\n", __func__, cmd);
-+ return -ENOSYS;
-+ }
-+
-+ return xencomm_arch_hypercall_hvm_op(cmd, xencomm_create_inline(arg));
-+}
-+
-+int
-+xencomm_hypercall_suspend(unsigned long srec)
-+{
-+ struct sched_shutdown arg;
+
-+ arg.reason = SHUTDOWN_suspend;
-+
-+ return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg));
-+}
-+
-+int
-+xencomm_hypercall_xenoprof_op(int op, void *arg)
-+{
-+ switch (op) {
-+ case XENOPROF_init:
-+ case XENOPROF_set_active:
-+ case XENOPROF_set_passive:
-+ case XENOPROF_counter:
-+ case XENOPROF_get_buffer:
-+ break;
++ case XENMEM_exchange:
++ xme_in = &((xen_memory_exchange_t *)arg)->in;
++ xme_out = &((xen_memory_exchange_t *)arg)->out;
++ set_xen_guest_handle(extent_start_va[0],
++ xen_guest_handle(xme_in->extent_start));
++ set_xen_guest_handle(extent_start_va[1],
++ xen_guest_handle(xme_out->extent_start));
+
-+ case XENOPROF_reset_active_list:
-+ case XENOPROF_reset_passive_list:
-+ case XENOPROF_reserve_counters:
-+ case XENOPROF_setup_events:
-+ case XENOPROF_enable_virq:
-+ case XENOPROF_start:
-+ case XENOPROF_stop:
-+ case XENOPROF_disable_virq:
-+ case XENOPROF_release_counters:
-+ case XENOPROF_shutdown:
-+ return xencomm_arch_hypercall_xenoprof_op(op, arg);
++ argsize = sizeof(xen_memory_exchange_t);
++ rc = xencommize_memory_reservation(xc_area, xme_in);
++ if (rc)
++ return rc;
++ xc_area++;
++ rc = xencommize_memory_reservation(xc_area, xme_out);
++ if (rc)
++ return rc;
++ xc_area++;
+ break;
+
-+ default:
-+ printk("%s: op %d isn't supported\n", __func__, op);
-+ return -ENOSYS;
-+ }
-+ return xencomm_arch_hypercall_xenoprof_op(op,
-+ xencomm_create_inline(arg));
-+}
-+
-+int
-+xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count)
-+{
-+ switch (cmd) {
-+ case PFM_GET_FEATURES:
-+ case PFM_CREATE_CONTEXT:
-+ case PFM_WRITE_PMCS:
-+ case PFM_WRITE_PMDS:
-+ case PFM_LOAD_CONTEXT:
++ case XENMEM_add_to_physmap:
++ argsize = sizeof(xen_add_to_physmap_t);
+ break;
+
-+ case PFM_DESTROY_CONTEXT:
-+ case PFM_UNLOAD_CONTEXT:
-+ case PFM_START:
-+ case PFM_STOP:
-+ return xencomm_arch_hypercall_perfmon_op(cmd, arg, count);
-+
-+ default:
-+ printk("%s:%d cmd %ld isn't supported\n",
-+ __func__,__LINE__, cmd);
-+ BUG();
-+ }
-+
-+ return xencomm_arch_hypercall_perfmon_op(cmd,
-+ xencomm_create_inline(arg),
-+ count);
-+}
-+
-+long
-+xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg)
-+{
-+ switch (cmd) {
-+ case VCPUOP_register_runstate_memory_area:
-+ xencommize_memory_reservation((xen_memory_reservation_t *)arg);
++ case XENMEM_machine_memory_map:
++ argsize = sizeof(*memmap);
++ memmap = (xen_memory_map_t *)arg;
++ set_xen_guest_handle(buffer, xen_guest_handle(memmap->buffer));
++ desc = xencomm_map_no_alloc(xen_guest_handle(memmap->buffer),
++ memmap->nr_entries);
++ if (desc == NULL)
++ return -EINVAL;
++ set_xen_guest_handle(memmap->buffer, (void *)desc);
+ break;
+
+ default:
-+ printk("%s: unknown vcpu op %d\n", __func__, cmd);
++ printk("%s: unknown memory op %d\n", __func__, cmd);
+ return -ENOSYS;
+ }
+
-+ return xencomm_arch_hypercall_vcpu_op(cmd, cpu,
-+ xencomm_create_inline(arg));
-+}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_mini.c tmp-linux-2.6-xen.patch/arch/ia64/xen/xcom_mini.c
---- pristine-linux-2.6.18/arch/ia64/xen/xcom_mini.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xcom_mini.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,456 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-+ *
-+ * Tristan Gingold <tristan.gingold@bull.net>
-+ */
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/platform.h>
-+#include <xen/interface/memory.h>
-+#include <xen/interface/xencomm.h>
-+#include <xen/interface/version.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/interface/hvm/params.h>
-+#include <xen/interface/xenoprof.h>
-+#ifdef CONFIG_VMX_GUEST
-+#include <asm/hypervisor.h>
-+#else
-+#include <asm/hypercall.h>
-+#endif
-+#include <asm/xen/xencomm.h>
-+#include <asm/perfmon.h>
-+
-+int
-+xencomm_mini_hypercall_event_channel_op(int cmd, void *op)
-+{
-+ struct xencomm_mini xc_area[2];
-+ int nbr_area = 2;
-+ struct xencomm_handle *desc;
-+ int rc;
-+
-+ rc = xencomm_create_mini(xc_area, &nbr_area,
-+ op, sizeof(evtchn_op_t), &desc);
-+ if (rc)
-+ return rc;
-+
-+ return xencomm_arch_hypercall_event_channel_op(cmd, desc);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_event_channel_op);
-+
-+static int
-+xencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area,
-+ unsigned int cmd, void *op, unsigned int count,
-+ struct xencomm_handle **desc)
-+{
-+ struct xencomm_handle *desc1;
-+ unsigned int argsize;
-+ int rc;
-+
-+ switch (cmd) {
-+ case GNTTABOP_map_grant_ref:
-+ argsize = sizeof(struct gnttab_map_grant_ref);
-+ break;
-+ case GNTTABOP_unmap_grant_ref:
-+ argsize = sizeof(struct gnttab_unmap_grant_ref);
-+ break;
-+ case GNTTABOP_setup_table:
-+ {
-+ struct gnttab_setup_table *setup = op;
-+
-+ argsize = sizeof(*setup);
-+
-+ if (count != 1)
-+ return -EINVAL;
-+ rc = xencomm_create_mini
-+ (xc_area, nbr_area,
-+ xen_guest_handle(setup->frame_list),
-+ setup->nr_frames
-+ * sizeof(*xen_guest_handle(setup->frame_list)),
-+ &desc1);
-+ if (rc)
-+ return rc;
-+ set_xen_guest_handle(setup->frame_list, (void *)desc1);
-+ break;
-+ }
-+ case GNTTABOP_dump_table:
-+ argsize = sizeof(struct gnttab_dump_table);
-+ break;
-+ case GNTTABOP_transfer:
-+ argsize = sizeof(struct gnttab_transfer);
-+ break;
-+ case GNTTABOP_copy:
-+ argsize = sizeof(struct gnttab_copy);
-+ break;
-+ case GNTTABOP_query_size:
-+ argsize = sizeof(struct gnttab_query_size);
-+ break;
-+ default:
-+ printk("%s: unknown mini grant table op %d\n", __func__, cmd);
-+ BUG();
-+ }
-+
-+ rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc);
-+ if (rc)
-+ return rc;
-+
-+ return 0;
-+}
-+
-+int
-+xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
-+ unsigned int count)
-+{
-+ int rc;
-+ struct xencomm_handle *desc;
-+ int nbr_area = 2;
-+ struct xencomm_mini xc_area[2];
-+
-+ rc = xencommize_mini_grant_table_op(xc_area, &nbr_area,
-+ cmd, op, count, &desc);
-+ if (rc)
-+ return rc;
-+
-+ return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_grant_table_op);
-+
-+int
-+xencomm_mini_hypercall_multicall(void *call_list, int nr_calls)
-+{
-+ int i;
-+ multicall_entry_t *mce;
-+ int nbr_area = 2 + nr_calls * 3;
-+ struct xencomm_mini xc_area[nbr_area];
-+ struct xencomm_handle *desc;
-+ int rc;
-+
-+ for (i = 0; i < nr_calls; i++) {
-+ mce = (multicall_entry_t *)call_list + i;
-+
-+ switch (mce->op) {
-+ case __HYPERVISOR_update_va_mapping:
-+ case __HYPERVISOR_mmu_update:
-+ /* No-op on ia64. */
-+ break;
-+ case __HYPERVISOR_grant_table_op:
-+ rc = xencommize_mini_grant_table_op
-+ (xc_area, &nbr_area,
-+ mce->args[0], (void *)mce->args[1],
-+ mce->args[2], &desc);
-+ if (rc)
-+ return rc;
-+ mce->args[1] = (unsigned long)desc;
-+ break;
-+ case __HYPERVISOR_memory_op:
-+ default:
-+ printk("%s: unhandled multicall op entry op %lu\n",
-+ __func__, mce->op);
-+ return -ENOSYS;
-+ }
-+ }
-+
-+ rc = xencomm_create_mini(xc_area, &nbr_area, call_list,
-+ nr_calls * sizeof(multicall_entry_t), &desc);
-+ if (rc)
-+ return rc;
-+
-+ return xencomm_arch_hypercall_multicall(desc, nr_calls);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_multicall);
-+
-+static int
-+xencommize_mini_memory_reservation(struct xencomm_mini *area, int *nbr_area,
-+ xen_memory_reservation_t *mop)
-+{
-+ struct xencomm_handle *desc;
-+ int rc;
-+
-+ rc = xencomm_create_mini
-+ (area, nbr_area,
-+ xen_guest_handle(mop->extent_start),
-+ mop->nr_extents
-+ * sizeof(*xen_guest_handle(mop->extent_start)),
-+ &desc);
-+ if (rc)
-+ return rc;
-+
-+ set_xen_guest_handle(mop->extent_start, (void *)desc);
-+
-+ return 0;
-+}
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
+
-+int
-+xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg)
-+{
-+ int nbr_area = 4;
-+ struct xencomm_mini xc_area[4];
-+ struct xencomm_handle *desc;
-+ int rc;
-+ unsigned int argsize;
++ rc = xencomm_arch_hypercall_memory_op(cmd, desc);
+
+ switch (cmd) {
+ case XENMEM_increase_reservation:
+ case XENMEM_decrease_reservation:
+ case XENMEM_populate_physmap:
-+ argsize = sizeof(xen_memory_reservation_t);
-+ rc = xencommize_mini_memory_reservation
-+ (xc_area, &nbr_area, (xen_memory_reservation_t *)arg);
-+ if (rc)
-+ return rc;
-+ break;
-+
-+ case XENMEM_maximum_ram_page:
-+ argsize = 0;
++ set_xen_guest_handle(xmr->extent_start,
++ xen_guest_handle(extent_start_va[0]));
+ break;
+
+ case XENMEM_exchange:
-+ argsize = sizeof(xen_memory_exchange_t);
-+ rc = xencommize_mini_memory_reservation
-+ (xc_area, &nbr_area,
-+ &((xen_memory_exchange_t *)arg)->in);
-+ if (rc)
-+ return rc;
-+ rc = xencommize_mini_memory_reservation
-+ (xc_area, &nbr_area,
-+ &((xen_memory_exchange_t *)arg)->out);
-+ if (rc)
-+ return rc;
++ set_xen_guest_handle(xme_in->extent_start,
++ xen_guest_handle(extent_start_va[0]));
++ set_xen_guest_handle(xme_out->extent_start,
++ xen_guest_handle(extent_start_va[1]));
+ break;
+
-+ case XENMEM_add_to_physmap:
-+ argsize = sizeof (xen_add_to_physmap_t);
++ case XENMEM_machine_memory_map:
++ set_xen_guest_handle(memmap->buffer, xen_guest_handle(buffer));
+ break;
-+
-+ default:
-+ printk("%s: unknown mini memory op %d\n", __func__, cmd);
-+ return -ENOSYS;
+ }
+
-+ rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+ if (rc)
-+ return rc;
-+
-+ return xencomm_arch_hypercall_memory_op(cmd, desc);
++ return rc;
+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_memory_op);
++EXPORT_SYMBOL_GPL(xencomm_hypercall_memory_op);
+
+unsigned long
-+xencomm_mini_hypercall_hvm_op(int cmd, void *arg)
++xencomm_hypercall_hvm_op(int cmd, void *arg)
+{
+ struct xencomm_handle *desc;
-+ int nbr_area = 2;
-+ struct xencomm_mini xc_area[2];
+ unsigned int argsize;
-+ int rc;
+
+ switch (cmd) {
+ case HVMOP_get_param:
@@ -26659,70 +29873,32 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_mini.c tmp-linux-2.6-xen.pat
+ return -EINVAL;
+ }
+
-+ rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+ if (rc)
-+ return rc;
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
+
+ return xencomm_arch_hypercall_hvm_op(cmd, desc);
+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_hvm_op);
++EXPORT_SYMBOL_GPL(xencomm_hypercall_hvm_op);
+
++#ifndef CONFIG_VMX_GUEST
+int
-+xencomm_mini_hypercall_xen_version(int cmd, void *arg)
++xencomm_hypercall_suspend(unsigned long srec)
+{
-+ struct xencomm_handle *desc;
-+ int nbr_area = 2;
-+ struct xencomm_mini xc_area[2];
-+ unsigned int argsize;
-+ int rc;
-+
-+ switch (cmd) {
-+ case XENVER_version:
-+ /* do not actually pass an argument */
-+ return xencomm_arch_hypercall_xen_version(cmd, 0);
-+ case XENVER_extraversion:
-+ argsize = sizeof(xen_extraversion_t);
-+ break;
-+ case XENVER_compile_info:
-+ argsize = sizeof(xen_compile_info_t);
-+ break;
-+ case XENVER_capabilities:
-+ argsize = sizeof(xen_capabilities_info_t);
-+ break;
-+ case XENVER_changeset:
-+ argsize = sizeof(xen_changeset_info_t);
-+ break;
-+ case XENVER_platform_parameters:
-+ argsize = sizeof(xen_platform_parameters_t);
-+ break;
-+ case XENVER_pagesize:
-+ argsize = (arg == NULL) ? 0 : sizeof(void *);
-+ break;
-+ case XENVER_get_features:
-+ argsize = (arg == NULL) ? 0 : sizeof(xen_feature_info_t);
-+ break;
-+
-+ default:
-+ printk("%s: unknown version op %d\n", __func__, cmd);
-+ return -ENOSYS;
-+ }
++ struct sched_shutdown arg;
+
-+ rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+ if (rc)
-+ return rc;
++ arg.reason = SHUTDOWN_suspend;
+
-+ return xencomm_arch_hypercall_xen_version(cmd, desc);
++ return xencomm_arch_hypercall_suspend(
++ xencomm_map_no_alloc(&arg, sizeof(arg)));
+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_xen_version);
++#endif
+
+int
-+xencomm_mini_hypercall_xenoprof_op(int op, void *arg)
++xencomm_hypercall_xenoprof_op(int op, void *arg)
+{
+ unsigned int argsize;
-+ struct xencomm_mini xc_area[2];
-+ int nbr_area = 2;
+ struct xencomm_handle *desc;
-+ int rc;
+
+ switch (op) {
+ case XENOPROF_init:
@@ -26757,22 +29933,21 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_mini.c tmp-linux-2.6-xen.pat
+ printk("%s: op %d isn't supported\n", __func__, op);
+ return -ENOSYS;
+ }
-+ rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+ if (rc)
-+ return rc;
++
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
++
+ return xencomm_arch_hypercall_xenoprof_op(op, desc);
+}
-+EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_xenoprof_op);
++EXPORT_SYMBOL_GPL(xencomm_hypercall_xenoprof_op);
+
+int
-+xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg,
++xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg,
+ unsigned long count)
+{
+ unsigned int argsize;
-+ struct xencomm_mini xc_area[2];
-+ int nbr_area = 2;
+ struct xencomm_handle *desc;
-+ int rc;
+
+ switch (cmd) {
+ case PFM_GET_FEATURES:
@@ -26801,52 +29976,92 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_mini.c tmp-linux-2.6-xen.pat
+ BUG();
+ }
+
-+ rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+ if (rc)
-+ return rc;
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
++
+ return xencomm_arch_hypercall_perfmon_op(cmd, desc, count);
+}
-+EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_perfmon_op);
++EXPORT_SYMBOL_GPL(xencomm_hypercall_perfmon_op);
++
++long
++xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg)
++{
++ unsigned int argsize;
++ switch (cmd) {
++ case VCPUOP_register_runstate_memory_area: {
++ vcpu_register_runstate_memory_area_t *area =
++ (vcpu_register_runstate_memory_area_t *)arg;
++ argsize = sizeof(*arg);
++ set_xen_guest_handle(area->addr.h,
++ (void *)xencomm_map_no_alloc(area->addr.v,
++ sizeof(area->addr.v)));
++ break;
++ }
++
++ default:
++ printk("%s: unknown vcpu op %d\n", __func__, cmd);
++ return -ENOSYS;
++ }
++
++ return xencomm_arch_hypercall_vcpu_op(cmd, cpu,
++ xencomm_map_no_alloc(arg, argsize));
++}
++
++long
++xencomm_hypercall_opt_feature(void *arg)
++{
++ return xencomm_arch_hypercall_opt_feature(
++ xencomm_map_no_alloc(arg,
++ sizeof(struct xen_ia64_opt_feature)));
++}
+
+int
-+xencomm_mini_hypercall_sched_op(int cmd, void *arg)
++xencomm_hypercall_fpswa_revision(unsigned int *revision)
+{
-+ int rc, nbr_area = 2;
-+ struct xencomm_mini xc_area[2];
+ struct xencomm_handle *desc;
++
++ desc = xencomm_map_no_alloc(revision, sizeof(*revision));
++ if (desc == NULL)
++ return -EINVAL;
++
++ return xencomm_arch_hypercall_fpswa_revision(desc);
++}
++EXPORT_SYMBOL_GPL(xencomm_hypercall_fpswa_revision);
++
++int
++xencomm_hypercall_kexec_op(int cmd, void *arg)
++{
+ unsigned int argsize;
++ struct xencomm_handle *desc;
+
+ switch (cmd) {
-+ case SCHEDOP_yield:
-+ case SCHEDOP_block:
-+ argsize = 0;
-+ break;
-+ case SCHEDOP_shutdown:
-+ argsize = sizeof(sched_shutdown_t);
++ case KEXEC_CMD_kexec_get_range:
++ argsize = sizeof(xen_kexec_range_t);
+ break;
-+ case SCHEDOP_poll:
-+ argsize = sizeof(sched_poll_t);
++ case KEXEC_CMD_kexec_load:
++ case KEXEC_CMD_kexec_unload:
++ argsize = sizeof(xen_kexec_load_t);
+ break;
-+ case SCHEDOP_remote_shutdown:
-+ argsize = sizeof(sched_remote_shutdown_t);
++ case KEXEC_CMD_kexec:
++ argsize = sizeof(xen_kexec_exec_t);
+ break;
-+
+ default:
-+ printk("%s: unknown sched op %d\n", __func__, cmd);
-+ return -ENOSYS;
++ printk("%s:%d cmd %d isn't supported\n",
++ __func__, __LINE__, cmd);
++ BUG();
+ }
+
-+ rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+ if (rc)
-+ return rc;
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc == NULL)
++ return -EINVAL;
+
-+ return xencomm_arch_hypercall_sched_op(cmd, desc);
++ return xencomm_arch_hypercall_kexec_op(cmd, desc);
+}
-+EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_sched_op);
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.patch/arch/ia64/xen/xcom_privcmd.c
---- pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xcom_privcmd.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,663 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xcom_privcmd.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/xcom_privcmd.c
+--- linux-2.6.18.8/arch/ia64/xen/xcom_privcmd.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xcom_privcmd.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,823 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
@@ -26878,8 +30093,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+#include <xen/interface/memory.h>
+#include <xen/interface/version.h>
+#include <xen/interface/event_channel.h>
-+#include <xen/interface/acm_ops.h>
++#include <xen/interface/xsm/acm_ops.h>
+#include <xen/interface/hvm/params.h>
++#include <xen/interface/arch-ia64/debug_op.h>
+#include <xen/public/privcmd.h>
+#include <asm/hypercall.h>
+#include <asm/page.h>
@@ -26903,7 +30119,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (kern_op.interface_version != XENPF_INTERFACE_VERSION)
+ return -EACCES;
+
-+ op_desc = xencomm_create_inline(&kern_op);
++ op_desc = xencomm_map_no_alloc(&kern_op, sizeof(kern_op));
+
+ switch (kern_op.cmd) {
+ default:
@@ -26922,17 +30138,10 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (copy_to_user(user_op, &kern_op, sizeof(struct xen_platform_op)))
+ ret = -EFAULT;
+
-+ if (desc)
-+ xencomm_free(desc);
++ xencomm_free(desc);
+ return ret;
+}
+
-+/*
-+ * Temporarily disable the NUMA PHYSINFO code until the rest of the
-+ * changes are upstream.
-+ */
-+#undef IA64_NUMA_PHYSINFO
-+
+static int
+xencomm_privcmd_sysctl(privcmd_hypercall_t *hypercall)
+{
@@ -26951,21 +30160,20 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (kern_op.interface_version != XEN_SYSCTL_INTERFACE_VERSION)
+ return -EACCES;
+
-+ op_desc = xencomm_create_inline(&kern_op);
++ op_desc = xencomm_map_no_alloc(&kern_op, sizeof(kern_op));
+
+ switch (kern_op.cmd) {
+ case XEN_SYSCTL_readconsole:
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.readconsole.buffer),
-+ kern_op.u.readconsole.count,
-+ &desc, GFP_KERNEL);
++ kern_op.u.readconsole.count);
++ if (xen_guest_handle(kern_op.u.readconsole.buffer) != NULL &&
++ kern_op.u.readconsole.count > 0 && desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.readconsole.buffer,
+ (void *)desc);
+ break;
+ case XEN_SYSCTL_tbuf_op:
-+#ifndef IA64_NUMA_PHYSINFO
-+ case XEN_SYSCTL_physinfo:
-+#endif
+ case XEN_SYSCTL_sched_id:
+ break;
+ case XEN_SYSCTL_perfc_op:
@@ -26976,8 +30184,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ .interface_version = XEN_SYSCTL_INTERFACE_VERSION,
+ .u.perfc_op = {
+ .cmd = XEN_SYSCTL_PERFCOP_query,
-+ // .desc.p = NULL,
-+ // .val.p = NULL,
++ /* .desc.p = NULL, */
++ /* .val.p = NULL, */
+ },
+ };
+
@@ -26988,60 +30196,66 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ }
+
+ /* query the buffer size for xencomm */
-+ tmp_desc = xencomm_create_inline(&tmp_op);
++ tmp_desc = xencomm_map_no_alloc(&tmp_op, sizeof(tmp_op));
+ ret = xencomm_arch_hypercall_sysctl(tmp_desc);
+ if (ret)
+ return ret;
+
-+ ret = xencomm_create(xen_guest_handle(kern_op.u.perfc_op.desc),
-+ tmp_op.u.perfc_op.nr_counters *
-+ sizeof(xen_sysctl_perfc_desc_t),
-+ &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ desc = xencomm_map(xen_guest_handle(kern_op.u.perfc_op.desc),
++ tmp_op.u.perfc_op.nr_counters *
++ sizeof(xen_sysctl_perfc_desc_t));
++ if (xen_guest_handle(kern_op.u.perfc_op.desc) != NULL &&
++ tmp_op.u.perfc_op.nr_counters > 0 && desc == NULL)
++ return -ENOMEM;
+
+ set_xen_guest_handle(kern_op.u.perfc_op.desc, (void *)desc);
+
-+ ret = xencomm_create(xen_guest_handle(kern_op.u.perfc_op.val),
-+ tmp_op.u.perfc_op.nr_vals *
-+ sizeof(xen_sysctl_perfc_val_t),
-+ &desc1, GFP_KERNEL);
-+ if (ret)
++ desc1 = xencomm_map(xen_guest_handle(kern_op.u.perfc_op.val),
++ tmp_op.u.perfc_op.nr_vals *
++ sizeof(xen_sysctl_perfc_val_t));
++ if (xen_guest_handle(kern_op.u.perfc_op.val) != NULL &&
++ tmp_op.u.perfc_op.nr_vals > 0 && desc1 == NULL) {
+ xencomm_free(desc);
++ return -ENOMEM;
++ }
+
+ set_xen_guest_handle(kern_op.u.perfc_op.val, (void *)desc1);
+ break;
+ }
+ case XEN_SYSCTL_getdomaininfolist:
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
+ kern_op.u.getdomaininfolist.max_domains *
-+ sizeof(xen_domctl_getdomaininfo_t),
-+ &desc, GFP_KERNEL);
++ sizeof(xen_domctl_getdomaininfo_t));
++ if (xen_guest_handle(kern_op.u.getdomaininfolist.buffer) !=
++ NULL && kern_op.u.getdomaininfolist.max_domains > 0 &&
++ desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer,
+ (void *)desc);
+ break;
-+#ifdef IA64_NUMA_PHYSINFO
-+ case XEN_SYSCTL_physinfo:
-+ ret = xencomm_create(
-+ xen_guest_handle(kern_op.u.physinfo.memory_chunks),
-+ PUBLIC_MAXCHUNKS * sizeof(node_data_t),
-+ &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
-+ set_xen_guest_handle(kern_op.u.physinfo.memory_chunks,
-+ (void *)desc);
++ case XEN_SYSCTL_debug_keys:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.debug_keys.keys),
++ kern_op.u.debug_keys.nr_keys);
++ if (xen_guest_handle(kern_op.u.debug_keys.keys) != NULL &&
++ kern_op.u.debug_keys.nr_keys > 0 && desc == NULL)
++ return -ENOMEM;
++ set_xen_guest_handle(kern_op.u.debug_keys.keys,
++ (void *)desc);
++ break;
+
-+ ret = xencomm_create(
++ case XEN_SYSCTL_physinfo:
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.physinfo.cpu_to_node),
-+ PUBLIC_MAX_NUMNODES * sizeof(u64),
-+ &desc1, GFP_KERNEL);
-+ if (ret)
-+ xencomm_free(desc);
++ kern_op.u.physinfo.max_cpu_id * sizeof(uint32_t));
++ if (xen_guest_handle(kern_op.u.physinfo.cpu_to_node) != NULL &&
++ kern_op.u.physinfo.max_cpu_id > 0 && desc == NULL)
++ return -ENOMEM;
++
+ set_xen_guest_handle(kern_op.u.physinfo.cpu_to_node,
-+ (void *)desc1);
++ (void *)desc);
+ break;
-+#endif
+ default:
+ printk("%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
+ return -ENOSYS;
@@ -27058,10 +30272,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t)))
+ ret = -EFAULT;
+
-+ if (desc)
-+ xencomm_free(desc);
-+ if (desc1)
-+ xencomm_free(desc1);
++ xencomm_free(desc);
++ xencomm_free(desc1);
+ return ret;
+}
+
@@ -27082,23 +30294,26 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (kern_op.interface_version != XEN_DOMCTL_INTERFACE_VERSION)
+ return -EACCES;
+
-+ op_desc = xencomm_create_inline(&kern_op);
++ op_desc = xencomm_map_no_alloc(&kern_op, sizeof(kern_op));
+
+ switch (kern_op.cmd) {
+ case XEN_DOMCTL_createdomain:
+ case XEN_DOMCTL_destroydomain:
+ case XEN_DOMCTL_pausedomain:
+ case XEN_DOMCTL_unpausedomain:
++ case XEN_DOMCTL_resumedomain:
+ case XEN_DOMCTL_getdomaininfo:
+ break;
+ case XEN_DOMCTL_getmemlist:
+ {
+ unsigned long nr_pages = kern_op.u.getmemlist.max_pfns;
+
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.getmemlist.buffer),
-+ nr_pages * sizeof(unsigned long),
-+ &desc, GFP_KERNEL);
++ nr_pages * sizeof(unsigned long));
++ if (xen_guest_handle(kern_op.u.getmemlist.buffer) != NULL &&
++ nr_pages > 0 && desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.getmemlist.buffer,
+ (void *)desc);
+ break;
@@ -27106,18 +30321,23 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ case XEN_DOMCTL_getpageframeinfo:
+ break;
+ case XEN_DOMCTL_getpageframeinfo2:
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.getpageframeinfo2.array),
-+ kern_op.u.getpageframeinfo2.num,
-+ &desc, GFP_KERNEL);
++ kern_op.u.getpageframeinfo2.num);
++ if (xen_guest_handle(kern_op.u.getpageframeinfo2.array) !=
++ NULL && kern_op.u.getpageframeinfo2.num > 0 &&
++ desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.getpageframeinfo2.array,
+ (void *)desc);
+ break;
+ case XEN_DOMCTL_shadow_op:
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
-+ ROUND_DIV(kern_op.u.shadow_op.pages, 8),
-+ &desc, GFP_KERNEL);
++ ROUND_DIV(kern_op.u.shadow_op.pages, 8));
++ if (xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap) != NULL
++ && kern_op.u.shadow_op.pages > 0 && desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
+ (void *)desc);
+ break;
@@ -27125,23 +30345,39 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ break;
+ case XEN_DOMCTL_setvcpucontext:
+ case XEN_DOMCTL_getvcpucontext:
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.vcpucontext.ctxt),
-+ sizeof(vcpu_guest_context_t),
-+ &desc, GFP_KERNEL);
++ sizeof(vcpu_guest_context_t));
++ if (xen_guest_handle(kern_op.u.vcpucontext.ctxt) != NULL &&
++ desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.vcpucontext.ctxt, (void *)desc);
+ break;
+ case XEN_DOMCTL_getvcpuinfo:
+ break;
+ case XEN_DOMCTL_setvcpuaffinity:
+ case XEN_DOMCTL_getvcpuaffinity:
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap),
-+ ROUND_DIV(kern_op.u.vcpuaffinity.cpumap.nr_cpus, 8),
-+ &desc, GFP_KERNEL);
++ ROUND_DIV(kern_op.u.vcpuaffinity.cpumap.nr_cpus, 8));
++ if (xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap) !=
++ NULL && kern_op.u.vcpuaffinity.cpumap.nr_cpus > 0 &&
++ desc == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap,
+ (void *)desc);
+ break;
++ case XEN_DOMCTL_gethvmcontext:
++ case XEN_DOMCTL_sethvmcontext:
++ if (kern_op.u.hvmcontext.size > 0)
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.hvmcontext.buffer),
++ kern_op.u.hvmcontext.size);
++ if (xen_guest_handle(kern_op.u.hvmcontext.buffer) != NULL &&
++ kern_op.u.hvmcontext.size > 0 && desc == NULL)
++ return -ENOMEM;
++ set_xen_guest_handle(kern_op.u.hvmcontext.buffer, (void*)desc);
++ break;
+ case XEN_DOMCTL_max_vcpus:
+ case XEN_DOMCTL_scheduler_op:
+ case XEN_DOMCTL_setdomainhandle:
@@ -27153,7 +30389,10 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ case XEN_DOMCTL_arch_setup:
+ case XEN_DOMCTL_settimeoffset:
+ case XEN_DOMCTL_sendtrigger:
++ case XEN_DOMCTL_set_opt_feature:
+ break;
++ case XEN_DOMCTL_pin_mem_cacheattr:
++ return -ENOSYS;
+ default:
+ printk("%s: unknown domctl cmd %d\n", __func__, kern_op.cmd);
+ return -ENOSYS;
@@ -27170,13 +30409,12 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t)))
+ ret = -EFAULT;
+
-+ if (desc)
-+ xencomm_free(desc);
++ xencomm_free(desc);
+ return ret;
+}
+
+static int
-+xencomm_privcmd_acm_op(privcmd_hypercall_t *hypercall)
++xencomm_privcmd_xsm_op(privcmd_hypercall_t *hypercall)
+{
+ void __user *arg = (void __user *)hypercall->arg[0];
+ xen_acmctl_t kern_arg;
@@ -27191,17 +30429,18 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+
+ switch (kern_arg.cmd) {
+ case ACMOP_getssid: {
-+ op_desc = xencomm_create_inline(&kern_arg);
++ op_desc = xencomm_map_no_alloc(&kern_arg, sizeof(kern_arg));
+
-+ ret = xencomm_create(
++ desc = xencomm_map(
+ xen_guest_handle(kern_arg.u.getssid.ssidbuf),
-+ kern_arg.u.getssid.ssidbuf_size, &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ kern_arg.u.getssid.ssidbuf_size);
++ if (xen_guest_handle(kern_arg.u.getssid.ssidbuf) != NULL &&
++ kern_arg.u.getssid.ssidbuf_size > 0 && desc == NULL)
++ return -ENOMEM;
+
+ set_xen_guest_handle(kern_arg.u.getssid.ssidbuf, (void *)desc);
+
-+ ret = xencomm_arch_hypercall_acm_op(op_desc);
++ ret = xencomm_arch_hypercall_xsm_op(op_desc);
+
+ xencomm_free(desc);
+
@@ -27218,6 +30457,102 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+}
+
+static int
++xencomm_privcmd_memory_reservation_op(privcmd_hypercall_t *hypercall)
++{
++ const unsigned long cmd = hypercall->arg[0];
++ int ret = 0;
++ xen_memory_reservation_t kern_op;
++ xen_memory_reservation_t __user *user_op;
++ struct xencomm_handle *desc = NULL;
++ struct xencomm_handle *desc_op;
++
++ user_op = (xen_memory_reservation_t __user *)hypercall->arg[1];
++ if (copy_from_user(&kern_op, user_op,
++ sizeof(xen_memory_reservation_t)))
++ return -EFAULT;
++ desc_op = xencomm_map_no_alloc(&kern_op, sizeof(kern_op));
++
++ if (!xen_guest_handle(kern_op.extent_start)) {
++ ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
++ if (ret < 0)
++ return ret;
++ } else {
++ xen_ulong_t nr_done = 0;
++ xen_ulong_t nr_extents = kern_op.nr_extents;
++ void *addr = xen_guest_handle(kern_op.extent_start);
++
++ /*
++ * Work around.
++ * Xencomm has single page size limit caused
++ * by xencomm_alloc()/xencomm_free() so that
++ * we have to repeat the hypercall.
++ * This limitation can be removed.
++ */
++#define MEMORYOP_XENCOMM_LIMIT \
++ (((((PAGE_SIZE - sizeof(struct xencomm_desc)) / \
++ sizeof(uint64_t)) - 2) * PAGE_SIZE) / \
++ sizeof(*xen_guest_handle(kern_op.extent_start)))
++
++ /*
++ * Work around.
++ * Even if the above limitation is removed,
++ * the hypercall with large number of extents
++ * may cause the soft lockup warning.
++ * In order to avoid the warning, we limit
++ * the number of extents and repeat the hypercall.
++ * The following value is determined by experimentation.
++ * If the following limit causes soft lockup warning,
++ * we should decrease this value.
++ *
++ * Another way would be that start with small value and
++ * increase adoptively measuring hypercall time.
++ * It might be over-kill.
++ */
++#define MEMORYOP_MAX_EXTENTS (MEMORYOP_XENCOMM_LIMIT / 4)
++
++ while (nr_extents > 0) {
++ xen_ulong_t nr_tmp = nr_extents;
++ if (nr_tmp > MEMORYOP_MAX_EXTENTS)
++ nr_tmp = MEMORYOP_MAX_EXTENTS;
++
++ kern_op.nr_extents = nr_tmp;
++ desc = xencomm_map
++ (addr + nr_done * sizeof(*xen_guest_handle(kern_op.extent_start)),
++ nr_tmp * sizeof(*xen_guest_handle(kern_op.extent_start)));
++ if (addr != NULL && nr_tmp > 0 && desc == NULL)
++ return nr_done > 0 ? nr_done : -ENOMEM;
++
++ set_xen_guest_handle(kern_op.extent_start,
++ (void *)desc);
++
++ ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
++ xencomm_free(desc);
++ if (ret < 0)
++ return nr_done > 0 ? nr_done : ret;
++
++ nr_done += ret;
++ nr_extents -= ret;
++ if (ret < nr_tmp)
++ break;
++
++ /*
++ * prevent softlock up message.
++ * give cpu to soft lockup kernel thread.
++ */
++ if (nr_extents > 0)
++ schedule();
++ }
++ ret = nr_done;
++ set_xen_guest_handle(kern_op.extent_start, addr);
++ }
++
++ if (copy_to_user(user_op, &kern_op, sizeof(xen_memory_reservation_t)))
++ return -EFAULT;
++
++ return ret;
++}
++
++static int
+xencomm_privcmd_memory_op(privcmd_hypercall_t *hypercall)
+{
+ const unsigned long cmd = hypercall->arg[0];
@@ -27227,45 +30562,19 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ case XENMEM_increase_reservation:
+ case XENMEM_decrease_reservation:
+ case XENMEM_populate_physmap:
++ return xencomm_privcmd_memory_reservation_op(hypercall);
++ case XENMEM_maximum_gpfn:
+ {
-+ xen_memory_reservation_t kern_op;
-+ xen_memory_reservation_t __user *user_op;
-+ struct xencomm_handle *desc = NULL;
-+ struct xencomm_handle *desc_op;
++ domid_t kern_domid;
++ domid_t __user *user_domid;
++ struct xencomm_handle *desc;
+
-+ user_op = (xen_memory_reservation_t __user *)hypercall->arg[1];
-+ if (copy_from_user(&kern_op, user_op,
-+ sizeof(xen_memory_reservation_t)))
++ user_domid = (domid_t __user *)hypercall->arg[1];
++ if (copy_from_user(&kern_domid, user_domid, sizeof(domid_t)))
+ return -EFAULT;
-+ desc_op = xencomm_create_inline(&kern_op);
-+
-+ if (xen_guest_handle(kern_op.extent_start)) {
-+ void * addr;
-+
-+ addr = xen_guest_handle(kern_op.extent_start);
-+ ret = xencomm_create
-+ (addr,
-+ kern_op.nr_extents *
-+ sizeof(*xen_guest_handle
-+ (kern_op.extent_start)),
-+ &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
-+ set_xen_guest_handle(kern_op.extent_start,
-+ (void *)desc);
-+ }
-+
-+ ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
++ desc = xencomm_map_no_alloc(&kern_domid, sizeof(kern_domid));
+
-+ if (desc)
-+ xencomm_free(desc);
-+
-+ if (ret != 0)
-+ return ret;
-+
-+ if (copy_to_user(user_op, &kern_op,
-+ sizeof(xen_memory_reservation_t)))
-+ return -EFAULT;
++ ret = xencomm_arch_hypercall_memory_op(cmd, desc);
+
+ return ret;
+ }
@@ -27283,41 +30592,41 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ if (copy_from_user(&kern_op, user_op,
+ sizeof(xen_translate_gpfn_list_t)))
+ return -EFAULT;
-+ desc_op = xencomm_create_inline(&kern_op);
++ desc_op = xencomm_map_no_alloc(&kern_op, sizeof(kern_op));
+
+ if (kern_op.nr_gpfns) {
+ /* gpfn_list. */
+ addr = xen_guest_handle(kern_op.gpfn_list);
+
-+ ret = xencomm_create(addr, kern_op.nr_gpfns *
++ desc_gpfn = xencomm_map(addr, kern_op.nr_gpfns *
+ sizeof(*xen_guest_handle
-+ (kern_op.gpfn_list)),
-+ &desc_gpfn, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ (kern_op.gpfn_list)));
++ if (addr != NULL && kern_op.nr_gpfns > 0 &&
++ desc_gpfn == NULL)
++ return -ENOMEM;
+ set_xen_guest_handle(kern_op.gpfn_list,
+ (void *)desc_gpfn);
+
+ /* mfn_list. */
+ addr = xen_guest_handle(kern_op.mfn_list);
+
-+ ret = xencomm_create(addr, kern_op.nr_gpfns *
++ desc_mfn = xencomm_map(addr, kern_op.nr_gpfns *
+ sizeof(*xen_guest_handle
-+ (kern_op.mfn_list)),
-+ &desc_mfn, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ (kern_op.mfn_list)));
++ if (addr != NULL && kern_op.nr_gpfns > 0 &&
++ desc_mfn == NULL) {
++ xencomm_free(desc_gpfn);
++ return -ENOMEM;
++ }
++
+ set_xen_guest_handle(kern_op.mfn_list,
+ (void *)desc_mfn);
+ }
+
+ ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
+
-+ if (desc_gpfn)
-+ xencomm_free(desc_gpfn);
-+
-+ if (desc_mfn)
-+ xencomm_free(desc_mfn);
++ xencomm_free(desc_gpfn);
++ xencomm_free(desc_mfn);
+
+ if (ret != 0)
+ return ret;
@@ -27371,9 +30680,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return -ENOSYS;
+ }
+
-+ rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL);
-+ if (rc)
-+ return rc;
++ desc = xencomm_map(arg, argsize);
++ if (arg != NULL && argsize > 0 && desc == NULL)
++ return -ENOMEM;
+
+ rc = xencomm_arch_hypercall_xen_version(cmd, desc);
+
@@ -27404,10 +30713,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return -EINVAL;
+ }
+
-+ ret = xencomm_create((void *)hypercall->arg[1], argsize,
-+ &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ desc = xencomm_map((void *)hypercall->arg[1], argsize);
++ if ((void *)hypercall->arg[1] != NULL && argsize > 0 && desc == NULL)
++ return -ENOMEM;
+
+ ret = xencomm_arch_hypercall_event_channel_op(cmd, desc);
+
@@ -27443,10 +30751,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return -EINVAL;
+ }
+
-+ ret = xencomm_create((void *)hypercall->arg[1], argsize,
-+ &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ desc = xencomm_map((void *)hypercall->arg[1], argsize);
++ if ((void *)hypercall->arg[1] != NULL && argsize > 0 && desc == NULL)
++ return -ENOMEM;
+
+ ret = xencomm_arch_hypercall_hvm_op(cmd, desc);
+
@@ -27471,10 +30778,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return -EINVAL;
+ }
+
-+ ret = xencomm_create((void *)hypercall->arg[1], argsize,
-+ &desc, GFP_KERNEL);
-+ if (ret)
-+ return ret;
++ desc = xencomm_map((void *)hypercall->arg[1], argsize);
++ if ((void *)hypercall->arg[1] != NULL && argsize > 0 && desc == NULL)
++ return -ENOMEM;
+
+ ret = xencomm_arch_hypercall_sched_op(cmd, desc);
+
@@ -27482,6 +30788,71 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return ret;
+}
+
++static int
++xencomm_privcmd_ia64_dom0vp_op(privcmd_hypercall_t *hypercall)
++{
++ int cmd = hypercall->arg[0];
++ int ret;
++
++ switch (cmd) {
++ case IA64_DOM0VP_fpswa_revision: {
++ unsigned int revision;
++ unsigned int __user *revision_user =
++ (unsigned int* __user)hypercall->arg[1];
++ struct xencomm_handle *desc;
++ desc = xencomm_map(&revision, sizeof(revision));
++ if (desc == NULL)
++ return -ENOMEM;
++
++ ret = xencomm_arch_hypercall_fpswa_revision(desc);
++ xencomm_free(desc);
++ if (ret)
++ break;
++ if (copy_to_user(revision_user, &revision, sizeof(revision)))
++ ret = -EFAULT;
++ break;
++ }
++#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
++ case IA64_DOM0VP_expose_foreign_p2m:
++ ret = xen_foreign_p2m_expose(hypercall);
++ break;
++#endif
++ default:
++ printk("%s: unknown IA64 DOM0VP op %d\n", __func__, cmd);
++ ret = -EINVAL;
++ break;
++ }
++ return ret;
++}
++
++static int
++xencomm_privcmd_ia64_debug_op(privcmd_hypercall_t *hypercall)
++{
++ int cmd = hypercall->arg[0];
++ unsigned long domain = hypercall->arg[1];
++ struct xencomm_handle *desc;
++ int ret;
++
++ switch (cmd) {
++ case XEN_IA64_DEBUG_OP_SET_FLAGS:
++ case XEN_IA64_DEBUG_OP_GET_FLAGS:
++ break;
++ default:
++ printk("%s: unknown IA64 DEBUGOP %d\n", __func__, cmd);
++ return -EINVAL;
++ }
++
++ desc = xencomm_map((void *)hypercall->arg[2],
++ sizeof(xen_ia64_debug_op_t));
++ if (desc == NULL)
++ return -ENOMEM;
++
++ ret = xencomm_arch_hypercall_ia64_debug_op(cmd, domain, desc);
++
++ xencomm_free(desc);
++ return ret;
++}
++
+int
+privcmd_hypercall(privcmd_hypercall_t *hypercall)
+{
@@ -27492,8 +30863,8 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return xencomm_privcmd_domctl(hypercall);
+ case __HYPERVISOR_sysctl:
+ return xencomm_privcmd_sysctl(hypercall);
-+ case __HYPERVISOR_acm_op:
-+ return xencomm_privcmd_acm_op(hypercall);
++ case __HYPERVISOR_xsm_op:
++ return xencomm_privcmd_xsm_op(hypercall);
+ case __HYPERVISOR_xen_version:
+ return xencomm_privcmd_xen_version(hypercall);
+ case __HYPERVISOR_memory_op:
@@ -27504,16 +30875,179 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xcom_privcmd.c tmp-linux-2.6-xen.
+ return xencomm_privcmd_hvm_op(hypercall);
+ case __HYPERVISOR_sched_op:
+ return xencomm_privcmd_sched_op(hypercall);
++ case __HYPERVISOR_ia64_dom0vp_op:
++ return xencomm_privcmd_ia64_dom0vp_op(hypercall);
++ case __HYPERVISOR_ia64_debug_op:
++ return xencomm_privcmd_ia64_debug_op(hypercall);
+ default:
+ printk("%s: unknown hcall (%ld)\n", __func__, hypercall->op);
+ return -ENOSYS;
+ }
+}
+
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xencomm.c tmp-linux-2.6-xen.patch/arch/ia64/xen/xencomm.c
---- pristine-linux-2.6.18/arch/ia64/xen/xencomm.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xencomm.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,263 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xen_dma.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/xen_dma.c
+--- linux-2.6.18.8/arch/ia64/xen/xen_dma.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xen_dma.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,155 @@
++/*
++ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
++ * Alex Williamson <alex.williamson@hp.com>
++ *
++ * Basic DMA mapping services for Xen guests.
++ * Based on arch/i386/kernel/pci-dma-xen.c.
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ */
++
++#include <linux/bitops.h>
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <asm/scatterlist.h>
++#include <xen/gnttab.h>
++#include <asm/gnttab_dma.h>
++
++#define IOMMU_BUG_ON(test) \
++do { \
++ if (unlikely(test)) { \
++ printk(KERN_ALERT "Fatal DMA error!\n"); \
++ BUG(); \
++ } \
++} while (0)
++
++
++/*
++ * This should be broken out of swiotlb and put in a common place
++ * when merged with upstream Linux.
++ */
++static inline int
++address_needs_mapping(struct device *dev, dma_addr_t addr)
++{
++ dma_addr_t mask = 0xffffffff;
++
++ /* If the device has a mask, use it, otherwise default to 32 bits */
++ if (dev && dev->dma_mask)
++ mask = *dev->dma_mask;
++ return (addr & ~mask) != 0;
++}
++
++int
++xen_map_sg(struct device *dev, struct scatterlist *sg, int nents,
++ int direction)
++{
++ int i;
++
++ for (i = 0 ; i < nents ; i++) {
++ sg[i].dma_address = gnttab_dma_map_page(sg[i].page) + sg[i].offset;
++ sg[i].dma_length = sg[i].length;
++
++ IOMMU_BUG_ON(address_needs_mapping(dev, sg[i].dma_address));
++ IOMMU_BUG_ON(range_straddles_page_boundary(
++ page_to_pseudophys(sg[i].page) + sg[i].offset,
++ sg[i].length));
++ }
++
++ return nents;
++}
++EXPORT_SYMBOL(xen_map_sg);
++
++void
++xen_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
++ int direction)
++{
++ int i;
++ for (i = 0; i < nents; i++)
++ __gnttab_dma_unmap_page(sg[i].page);
++}
++EXPORT_SYMBOL(xen_unmap_sg);
++
++int
++xen_dma_mapping_error(dma_addr_t dma_addr)
++{
++ return 0;
++}
++EXPORT_SYMBOL(xen_dma_mapping_error);
++
++int
++xen_dma_supported(struct device *dev, u64 mask)
++{
++ return 1;
++}
++EXPORT_SYMBOL(xen_dma_supported);
++
++void *
++xen_alloc_coherent(struct device *dev, size_t size,
++ dma_addr_t *dma_handle, gfp_t gfp)
++{
++ unsigned long vaddr;
++ unsigned int order = get_order(size);
++
++ vaddr = __get_free_pages(gfp, order);
++
++ if (!vaddr)
++ return NULL;
++
++ if (xen_create_contiguous_region(vaddr, order,
++ fls64(dev->coherent_dma_mask))) {
++ free_pages(vaddr, order);
++ return NULL;
++ }
++
++ memset((void *)vaddr, 0, size);
++ *dma_handle = virt_to_bus((void *)vaddr);
++
++ return (void *)vaddr;
++}
++EXPORT_SYMBOL(xen_alloc_coherent);
++
++void
++xen_free_coherent(struct device *dev, size_t size,
++ void *vaddr, dma_addr_t dma_handle)
++{
++ unsigned int order = get_order(size);
++
++ xen_destroy_contiguous_region((unsigned long)vaddr, order);
++ free_pages((unsigned long)vaddr, order);
++}
++EXPORT_SYMBOL(xen_free_coherent);
++
++dma_addr_t
++xen_map_single(struct device *dev, void *ptr, size_t size,
++ int direction)
++{
++ dma_addr_t dma_addr = gnttab_dma_map_virt(ptr);
++
++ IOMMU_BUG_ON(range_straddles_page_boundary(__pa(ptr), size));
++ IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
++
++ return dma_addr;
++}
++EXPORT_SYMBOL(xen_map_single);
++
++void
++xen_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
++ int direction)
++{
++ gnttab_dma_unmap_page(dma_addr);
++}
++EXPORT_SYMBOL(xen_unmap_single);
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xencomm.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/xencomm.c
+--- linux-2.6.18.8/arch/ia64/xen/xencomm.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xencomm.c 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
+ *
@@ -27543,19 +31077,17 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xencomm.c tmp-linux-2.6-xen.patch
+
+#include <asm/xen/xencomm.h>
+
-+static int xencomm_debug = 0;
-+
+static unsigned long kernel_start_pa;
+
+void
-+xencomm_init (void)
++xencomm_initialize (void)
+{
+ kernel_start_pa = KERNEL_START - ia64_tpa(KERNEL_START);
+}
+
+/* Translate virtual address to physical address. */
+unsigned long
-+xencomm_vaddr_to_paddr(unsigned long vaddr)
++xencomm_vtop(unsigned long vaddr)
+{
+#ifndef CONFIG_VMX_GUEST
+ struct page *page;
@@ -27625,161 +31157,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xencomm.c tmp-linux-2.6-xen.patch
+ return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
+#endif
+}
-+
-+static int
-+xencomm_init_desc(struct xencomm_desc *desc, void *buffer, unsigned long bytes)
-+{
-+ unsigned long recorded = 0;
-+ int i = 0;
-+
-+ BUG_ON((buffer == NULL) && (bytes > 0));
-+
-+ /* record the physical pages used */
-+ if (buffer == NULL)
-+ desc->nr_addrs = 0;
-+
-+ while ((recorded < bytes) && (i < desc->nr_addrs)) {
-+ unsigned long vaddr = (unsigned long)buffer + recorded;
-+ unsigned long paddr;
-+ int offset;
-+ int chunksz;
-+
-+ offset = vaddr % PAGE_SIZE; /* handle partial pages */
-+ chunksz = min(PAGE_SIZE - offset, bytes - recorded);
-+
-+ paddr = xencomm_vaddr_to_paddr(vaddr);
-+ if (paddr == ~0UL) {
-+ printk("%s: couldn't translate vaddr %lx\n",
-+ __func__, vaddr);
-+ return -EINVAL;
-+ }
-+
-+ desc->address[i++] = paddr;
-+ recorded += chunksz;
-+ }
-+
-+ if (recorded < bytes) {
-+ printk("%s: could only translate %ld of %ld bytes\n",
-+ __func__, recorded, bytes);
-+ return -ENOSPC;
-+ }
-+
-+ /* mark remaining addresses invalid (just for safety) */
-+ while (i < desc->nr_addrs)
-+ desc->address[i++] = XENCOMM_INVALID;
-+
-+ desc->magic = XENCOMM_MAGIC;
-+
-+ return 0;
-+}
-+
-+static struct xencomm_desc *
-+xencomm_alloc(gfp_t gfp_mask)
-+{
-+ struct xencomm_desc *desc;
-+
-+ desc = (struct xencomm_desc *)__get_free_page(gfp_mask);
-+ if (desc == NULL)
-+ panic("%s: page allocation failed\n", __func__);
-+
-+ desc->nr_addrs = (PAGE_SIZE - sizeof(struct xencomm_desc)) /
-+ sizeof(*desc->address);
-+
-+ return desc;
-+}
-+
-+void
-+xencomm_free(struct xencomm_handle *desc)
-+{
-+ if (desc)
-+ free_page((unsigned long)__va(desc));
-+}
-+
-+int
-+xencomm_create(void *buffer, unsigned long bytes,
-+ struct xencomm_handle **ret, gfp_t gfp_mask)
-+{
-+ struct xencomm_desc *desc;
-+ struct xencomm_handle *handle;
-+ int rc;
-+
-+ if (xencomm_debug)
-+ printk("%s: %p[%ld]\n", __func__, buffer, bytes);
-+
-+ if (buffer == NULL || bytes == 0) {
-+ *ret = (struct xencomm_handle *)NULL;
-+ return 0;
-+ }
-+
-+ desc = xencomm_alloc(gfp_mask);
-+ if (!desc) {
-+ printk("%s failure\n", "xencomm_alloc");
-+ return -ENOMEM;
-+ }
-+ handle = (struct xencomm_handle *)__pa(desc);
-+
-+ rc = xencomm_init_desc(desc, buffer, bytes);
-+ if (rc) {
-+ printk("%s failure: %d\n", "xencomm_init_desc", rc);
-+ xencomm_free(handle);
-+ return rc;
-+ }
-+
-+ *ret = handle;
-+ return 0;
-+}
-+
-+/* "mini" routines, for stack-based communications: */
-+
-+static void *
-+xencomm_alloc_mini(struct xencomm_mini *area, int *nbr_area)
-+{
-+ unsigned long base;
-+ unsigned int pageoffset;
-+
-+ while (*nbr_area >= 0) {
-+ /* Allocate an area. */
-+ (*nbr_area)--;
-+
-+ base = (unsigned long)(area + *nbr_area);
-+ pageoffset = base % PAGE_SIZE;
-+
-+ /* If the area does not cross a page, use it. */
-+ if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini))
-+ return &area[*nbr_area];
-+ }
-+ /* No more area. */
-+ return NULL;
-+}
-+
-+int
-+xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
-+ void *buffer, unsigned long bytes,
-+ struct xencomm_handle **ret)
-+{
-+ struct xencomm_desc *desc;
-+ int rc;
-+ unsigned long res;
-+
-+ desc = xencomm_alloc_mini(area, nbr_area);
-+ if (!desc)
-+ return -ENOMEM;
-+ desc->nr_addrs = XENCOMM_MINI_ADDRS;
-+
-+ rc = xencomm_init_desc(desc, buffer, bytes);
-+ if (rc)
-+ return rc;
-+
-+ res = xencomm_vaddr_to_paddr((unsigned long)desc);
-+ if (res == ~0UL)
-+ return -EINVAL;
-+
-+ *ret = (struct xencomm_handle*)res;
-+ return 0;
-+}
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenentry.S tmp-linux-2.6-xen.patch/arch/ia64/xen/xenentry.S
---- pristine-linux-2.6.18/arch/ia64/xen/xenentry.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xenentry.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xenentry.S linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenentry.S
+--- linux-2.6.18.8/arch/ia64/xen/xenentry.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenentry.S 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,931 @@
+/*
+ * ia64/xen/entry.S
@@ -28712,12 +32092,12 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenentry.S tmp-linux-2.6-xen.patc
+#else
+END(ia64_leave_kernel)
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenhpski.c tmp-linux-2.6-xen.patch/arch/ia64/xen/xenhpski.c
---- pristine-linux-2.6.18/arch/ia64/xen/xenhpski.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xenhpski.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xenhpski.c linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenhpski.c
+--- linux-2.6.18.8/arch/ia64/xen/xenhpski.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenhpski.c 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,19 @@
-+
-+extern unsigned long xen_get_cpuid(int);
++#include <linux/kernel.h>
++#include <asm/hypervisor.h>
+
+int
+running_on_sim(void)
@@ -28735,9 +32115,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenhpski.c tmp-linux-2.6-xen.patc
+ return 1;
+}
+
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenivt.S tmp-linux-2.6-xen.patch/arch/ia64/xen/xenivt.S
---- pristine-linux-2.6.18/arch/ia64/xen/xenivt.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xenivt.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xenivt.S linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenivt.S
+--- linux-2.6.18.8/arch/ia64/xen/xenivt.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenivt.S 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,2177 @@
+/*
+ * arch/ia64/xen/ivt.S
@@ -29952,7 +33332,7 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenivt.S tmp-linux-2.6-xen.patch/
+ alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
+#ifdef CONFIG_XEN
+ ;;
-+ br.call.sptk.many rp=xen_get_ivr
++ XEN_HYPER_GET_IVR
+ ;;
+ mov out0=r8 // pass cr.ivr as first arg
+#else
@@ -30916,9 +34296,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenivt.S tmp-linux-2.6-xen.patch/
+
+
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenminstate.h tmp-linux-2.6-xen.patch/arch/ia64/xen/xenminstate.h
---- pristine-linux-2.6.18/arch/ia64/xen/xenminstate.h 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xenminstate.h 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xenminstate.h linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenminstate.h
+--- linux-2.6.18.8/arch/ia64/xen/xenminstate.h 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenminstate.h 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,358 @@
+#include <asm/cache.h>
+
@@ -31278,9 +34658,9 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenminstate.h tmp-linux-2.6-xen.p
+#else
+#define SAVE_MIN DO_SAVE_MIN( , mov r30=r0, )
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenpal.S tmp-linux-2.6-xen.patch/arch/ia64/xen/xenpal.S
---- pristine-linux-2.6.18/arch/ia64/xen/xenpal.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xenpal.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xenpal.S linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenpal.S
+--- linux-2.6.18.8/arch/ia64/xen/xenpal.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xenpal.S 2008-02-15 16:21:49.000000000 -0800
@@ -0,0 +1,85 @@
+/*
+ * ia64/xen/xenpal.S
@@ -31367,10 +34747,10 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xenpal.S tmp-linux-2.6-xen.patch/
+ srlz.d // seralize restoration of psr.l
+ br.ret.sptk.many b0
+END(xen_pal_call_static)
-diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xensetup.S tmp-linux-2.6-xen.patch/arch/ia64/xen/xensetup.S
---- pristine-linux-2.6.18/arch/ia64/xen/xensetup.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/ia64/xen/xensetup.S 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,52 @@
+diff -rpuN linux-2.6.18.8/arch/ia64/xen/xensetup.S linux-2.6.18-xen-3.2.0/arch/ia64/xen/xensetup.S
+--- linux-2.6.18.8/arch/ia64/xen/xensetup.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/ia64/xen/xensetup.S 2008-02-15 16:21:49.000000000 -0800
+@@ -0,0 +1,59 @@
+/*
+ * Support routines for Xen
+ *
@@ -31380,6 +34760,13 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xensetup.S tmp-linux-2.6-xen.patc
+#include <asm/processor.h>
+#include <asm/asmmacro.h>
+
++ .section .data.read_mostly
++ .align 8
++ .global running_on_xen
++running_on_xen:
++ data4 0
++ .previous
++
+#define isBP p3 // are we the Bootstrap Processor?
+
+ .text
@@ -31423,36 +34810,4483 @@ diff -Nurp pristine-linux-2.6.18/arch/ia64/xen/xensetup.S tmp-linux-2.6-xen.patc
+ ;;
+ br.ret.sptk.many b0
+END(xencomm_arch_hypercall_suspend)
-diff -Nurp pristine-linux-2.6.18/arch/um/kernel/physmem.c tmp-linux-2.6-xen.patch/arch/um/kernel/physmem.c
---- pristine-linux-2.6.18/arch/um/kernel/physmem.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/um/kernel/physmem.c 2007-11-14 15:35:27.000000000 -0800
-@@ -226,7 +226,7 @@ EXPORT_SYMBOL(physmem_forget_descriptor)
- EXPORT_SYMBOL(physmem_remove_mapping);
- EXPORT_SYMBOL(physmem_subst_mapping);
-
--void arch_free_page(struct page *page, int order)
-+int arch_free_page(struct page *page, int order)
- {
- void *virt;
- int i;
-@@ -235,6 +235,8 @@ void arch_free_page(struct page *page, i
- virt = __va(page_to_phys(page + i));
- physmem_remove_mapping(virt);
+diff -rpuN linux-2.6.18.8/arch/powerpc/Kconfig linux-2.6.18-xen-3.2.0/arch/powerpc/Kconfig
+--- linux-2.6.18.8/arch/powerpc/Kconfig 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/Kconfig 2008-02-15 16:21:51.000000000 -0800
+@@ -439,6 +439,17 @@ config UDBG_RTAS_CONSOLE
+ bool
+ default n
+
++config PPC_XEN
++ bool "Enable Xen compatible kernel"
++ depends on PPC_MULTIPLATFORM && PPC64 && PPC_MAPLE && PPC_PSERIES && SMP
++ select XEN
++ select XEN_PRIVILEGED_GUEST
++ select XEN_UNPRIVILEGED_GUEST
++ select XEN_XENCOMM
++
++ help
++ This option will compile a kernel compatible with Xen hypervisor
++
+ config XICS
+ depends on PPC_PSERIES
+ bool
+@@ -1080,6 +1091,8 @@ source "arch/powerpc/Kconfig.debug"
+
+ source "security/Kconfig"
+
++source "drivers/xen/Kconfig"
++
+ config KEYS_COMPAT
+ bool
+ depends on COMPAT && KEYS
+diff -rpuN linux-2.6.18.8/arch/powerpc/Kconfig.debug linux-2.6.18-xen-3.2.0/arch/powerpc/Kconfig.debug
+--- linux-2.6.18.8/arch/powerpc/Kconfig.debug 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/Kconfig.debug 2008-02-15 16:21:51.000000000 -0800
+@@ -160,6 +160,20 @@ config PPC_EARLY_DEBUG_ISERIES
+ Select this to enable early debugging for legacy iSeries. You need
+ to hit "Ctrl-x Ctrl-x" to see the messages on the console.
+
++config PPC_EARLY_DEBUG_XEN_DOM0
++ bool "Xen Dom0 Console"
++ depends on PPC_XEN
++ help
++ Select this to enable early debugging for Xen Dom0. Setting
++ this will result in a kernel that may not work as a DomU.
++
++config PPC_EARLY_DEBUG_XEN_DOMU
++ bool "Xen DomU Console"
++ depends on PPC_XEN && XEN_UNPRIVILEGED_GUEST
++ help
++ Select this to enable early debugging for Xen DomU. Setting
++ this will result in a kernel that may not work as a Dom0.
++
+ endchoice
+
+ endmenu
+diff -rpuN linux-2.6.18.8/arch/powerpc/Makefile linux-2.6.18-xen-3.2.0/arch/powerpc/Makefile
+--- linux-2.6.18.8/arch/powerpc/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/Makefile 2008-02-15 16:21:51.000000000 -0800
+@@ -65,6 +65,7 @@ CPPFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARC
+ AFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH)
+ CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none -mcall-aixdesc
+ CFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH) -ffixed-r2 -mmultiple
++CFLAGS-$(CONFIG_PPC_XEN) += -Iinclude/asm-$(ARCH)/xen
+ CPPFLAGS += $(CPPFLAGS-y)
+ AFLAGS += $(AFLAGS-y)
+ CFLAGS += -msoft-float -pipe $(CFLAGS-y)
+diff -rpuN linux-2.6.18.8/arch/powerpc/boot/Makefile linux-2.6.18-xen-3.2.0/arch/powerpc/boot/Makefile
+--- linux-2.6.18.8/arch/powerpc/boot/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/boot/Makefile 2008-02-15 16:21:51.000000000 -0800
+@@ -36,8 +36,11 @@ zliblinuxheader := zlib.h zconf.h zutil.
+ $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
+ #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
+
++xen_guest-y = xen_guest.S
++
+ src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
+ src-boot += $(zlib)
++src-boot += $(xen_guest-$(CONFIG_XEN))
+ src-boot := $(addprefix $(obj)/, $(src-boot))
+ obj-boot := $(addsuffix .o, $(basename $(src-boot)))
+
+diff -rpuN linux-2.6.18.8/arch/powerpc/boot/xen_guest.S linux-2.6.18-xen-3.2.0/arch/powerpc/boot/xen_guest.S
+--- linux-2.6.18.8/arch/powerpc/boot/xen_guest.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/boot/xen_guest.S 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,7 @@
++ .section __xen_guest
++ .ascii "GUEST_OS=linux"
++ .ascii ",GUEST_VER=xen-3.0"
++ .ascii ",XEN_VER=xen-3.0"
++ .ascii ",VIRT_BASE=0x0"
++ .ascii ",LOADER=generic"
++ .byte 0
+diff -rpuN linux-2.6.18.8/arch/powerpc/configs/xen_maple_defconfig linux-2.6.18-xen-3.2.0/arch/powerpc/configs/xen_maple_defconfig
+--- linux-2.6.18.8/arch/powerpc/configs/xen_maple_defconfig 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/configs/xen_maple_defconfig 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,1342 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.17
++# Mon Jan 15 23:48:47 2007
++#
++CONFIG_PPC64=y
++CONFIG_64BIT=y
++CONFIG_PPC_MERGE=y
++CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_IRQ_PER_CPU=y
++CONFIG_RWSEM_XCHGADD_ALGORITHM=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_FIND_NEXT_BIT=y
++CONFIG_PPC=y
++CONFIG_EARLY_PRINTK=y
++CONFIG_COMPAT=y
++CONFIG_SYSVIPC_COMPAT=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
++CONFIG_PPC_OF=y
++CONFIG_PPC_UDBG_16550=y
++CONFIG_GENERIC_TBSYNC=y
++# CONFIG_DEFAULT_UIMAGE is not set
++
++#
++# Processor support
++#
++CONFIG_POWER4_ONLY=y
++CONFIG_POWER4=y
++CONFIG_PPC_FPU=y
++CONFIG_ALTIVEC=y
++CONFIG_PPC_STD_MMU=y
++CONFIG_VIRT_CPU_ACCOUNTING=y
++CONFIG_SMP=y
++CONFIG_NR_CPUS=32
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++
++#
++# General setup
++#
++CONFIG_LOCALVERSION="-Xen"
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++# CONFIG_CPUSETS is not set
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++# CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_RT_MUTEXES=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_SLAB=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_SLOB is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++CONFIG_MODVERSIONS=y
++CONFIG_MODULE_SRCVERSION_ALL=y
++CONFIG_KMOD=y
++CONFIG_STOP_MACHINE=y
++
++#
++# Block layer
++#
++# CONFIG_BLK_DEV_IO_TRACE is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++# CONFIG_DEFAULT_AS is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_CFQ is not set
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++
++#
++# Platform support
++#
++CONFIG_PPC_MULTIPLATFORM=y
++# CONFIG_PPC_ISERIES is not set
++# CONFIG_EMBEDDED6xx is not set
++# CONFIG_APUS is not set
++CONFIG_PPC_PSERIES=y
++# CONFIG_PPC_PMAC is not set
++CONFIG_PPC_MAPLE=y
++# CONFIG_PPC_CELL is not set
++# CONFIG_PPC_CELL_NATIVE is not set
++# CONFIG_PPC_IBM_CELL_BLADE is not set
++# CONFIG_UDBG_RTAS_CONSOLE is not set
++CONFIG_PPC_XEN=y
++CONFIG_XICS=y
++CONFIG_U3_DART=y
++CONFIG_MPIC=y
++CONFIG_PPC_RTAS=y
++CONFIG_RTAS_ERROR_LOGGING=y
++CONFIG_RTAS_PROC=y
++CONFIG_RTAS_FLASH=y
++# CONFIG_MMIO_NVRAM is not set
++CONFIG_MPIC_BROKEN_U3=y
++CONFIG_IBMVIO=y
++# CONFIG_IBMEBUS is not set
++# CONFIG_PPC_MPC106 is not set
++CONFIG_PPC_970_NAP=y
++# CONFIG_CPU_FREQ is not set
++# CONFIG_WANT_EARLY_SERIAL is not set
++
++#
++# Kernel options
++#
++CONFIG_HZ_100=y
++# CONFIG_HZ_250 is not set
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=100
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_PREEMPT_BKL is not set
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_MISC is not set
++CONFIG_FORCE_MAX_ZONEORDER=13
++CONFIG_IOMMU_VMERGE=y
++# CONFIG_HOTPLUG_CPU is not set
++CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++CONFIG_IRQ_ALL_CPUS=y
++# CONFIG_PPC_SPLPAR is not set
++CONFIG_EEH=y
++CONFIG_SCANLOG=y
++CONFIG_LPARCFG=y
++CONFIG_NUMA=y
++CONFIG_NODES_SHIFT=4
++CONFIG_ARCH_SELECT_MEMORY_MODEL=y
++CONFIG_ARCH_SPARSEMEM_ENABLE=y
++CONFIG_ARCH_SPARSEMEM_DEFAULT=y
++CONFIG_SELECT_MEMORY_MODEL=y
++# CONFIG_FLATMEM_MANUAL is not set
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_NEED_MULTIPLE_NODES=y
++CONFIG_HAVE_MEMORY_PRESENT=y
++# CONFIG_SPARSEMEM_STATIC is not set
++CONFIG_SPARSEMEM_EXTREME=y
++CONFIG_MEMORY_HOTPLUG=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_MIGRATION=y
++CONFIG_RESOURCES_64BIT=y
++CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
++CONFIG_ARCH_MEMORY_PROBE=y
++# CONFIG_PPC_64K_PAGES is not set
++# CONFIG_SCHED_SMT is not set
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_CMDLINE_BOOL is not set
++# CONFIG_PM is not set
++CONFIG_SECCOMP=y
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_PPC_I8259=y
++# CONFIG_PPC_INDIRECT_PCI is not set
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++# CONFIG_PCIEPORTBUS is not set
++# CONFIG_PCI_DEBUG is not set
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
++
++#
++# PCI Hotplug Support
++#
++# CONFIG_HOTPLUG_PCI is not set
++CONFIG_KERNEL_START=0xc000000000000000
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++# CONFIG_NETDEBUG is not set
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_FWMARK=y
++CONFIG_IP_ROUTE_MULTIPATH=y
++# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_NET_IPIP=y
++# CONFIG_NET_IPGRE is not set
++CONFIG_IP_MROUTE=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++
++#
++# IP: Virtual Server Configuration
++#
++# CONFIG_IP_VS is not set
++CONFIG_IPV6=y
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++CONFIG_IPV6_ROUTE_INFO=y
++CONFIG_INET6_AH=y
++CONFIG_INET6_ESP=y
++CONFIG_INET6_IPCOMP=y
++CONFIG_INET6_XFRM_TUNNEL=y
++CONFIG_INET6_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_IPV6_TUNNEL=y
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_BRIDGE_NETFILTER=y
++
++#
++# Core Netfilter Configuration
++#
++CONFIG_NETFILTER_NETLINK=y
++CONFIG_NETFILTER_NETLINK_QUEUE=y
++CONFIG_NETFILTER_NETLINK_LOG=y
++CONFIG_NETFILTER_XTABLES=y
++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
++CONFIG_NETFILTER_XT_TARGET_MARK=y
++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
++CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
++CONFIG_NETFILTER_XT_MATCH_COMMENT=y
++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
++CONFIG_NETFILTER_XT_MATCH_DCCP=y
++CONFIG_NETFILTER_XT_MATCH_ESP=y
++CONFIG_NETFILTER_XT_MATCH_HELPER=y
++CONFIG_NETFILTER_XT_MATCH_LENGTH=y
++CONFIG_NETFILTER_XT_MATCH_LIMIT=y
++CONFIG_NETFILTER_XT_MATCH_MAC=y
++CONFIG_NETFILTER_XT_MATCH_MARK=y
++CONFIG_NETFILTER_XT_MATCH_POLICY=y
++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y
++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
++CONFIG_NETFILTER_XT_MATCH_QUOTA=y
++CONFIG_NETFILTER_XT_MATCH_REALM=y
++CONFIG_NETFILTER_XT_MATCH_SCTP=y
++CONFIG_NETFILTER_XT_MATCH_STATE=y
++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
++CONFIG_NETFILTER_XT_MATCH_STRING=y
++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=y
++CONFIG_IP_NF_CT_ACCT=y
++CONFIG_IP_NF_CONNTRACK_MARK=y
++CONFIG_IP_NF_CONNTRACK_EVENTS=y
++CONFIG_IP_NF_CONNTRACK_NETLINK=y
++CONFIG_IP_NF_CT_PROTO_SCTP=y
++CONFIG_IP_NF_FTP=y
++CONFIG_IP_NF_IRC=y
++# CONFIG_IP_NF_NETBIOS_NS is not set
++CONFIG_IP_NF_TFTP=y
++CONFIG_IP_NF_AMANDA=y
++CONFIG_IP_NF_PPTP=y
++# CONFIG_IP_NF_H323 is not set
++# CONFIG_IP_NF_SIP is not set
++# CONFIG_IP_NF_QUEUE is not set
++CONFIG_IP_NF_IPTABLES=y
++CONFIG_IP_NF_MATCH_IPRANGE=y
++CONFIG_IP_NF_MATCH_TOS=y
++CONFIG_IP_NF_MATCH_RECENT=y
++CONFIG_IP_NF_MATCH_ECN=y
++CONFIG_IP_NF_MATCH_DSCP=y
++CONFIG_IP_NF_MATCH_AH=y
++CONFIG_IP_NF_MATCH_TTL=y
++CONFIG_IP_NF_MATCH_OWNER=y
++CONFIG_IP_NF_MATCH_ADDRTYPE=y
++CONFIG_IP_NF_MATCH_HASHLIMIT=y
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++CONFIG_IP_NF_TARGET_LOG=y
++CONFIG_IP_NF_TARGET_ULOG=y
++CONFIG_IP_NF_TARGET_TCPMSS=y
++CONFIG_IP_NF_NAT=y
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++CONFIG_IP_NF_TARGET_NETMAP=y
++CONFIG_IP_NF_TARGET_SAME=y
++CONFIG_IP_NF_NAT_SNMP_BASIC=y
++CONFIG_IP_NF_NAT_IRC=y
++CONFIG_IP_NF_NAT_FTP=y
++CONFIG_IP_NF_NAT_TFTP=y
++CONFIG_IP_NF_NAT_AMANDA=y
++CONFIG_IP_NF_NAT_PPTP=y
++CONFIG_IP_NF_MANGLE=y
++CONFIG_IP_NF_TARGET_TOS=y
++CONFIG_IP_NF_TARGET_ECN=y
++CONFIG_IP_NF_TARGET_DSCP=y
++CONFIG_IP_NF_TARGET_TTL=y
++CONFIG_IP_NF_TARGET_CLUSTERIP=y
++CONFIG_IP_NF_RAW=y
++CONFIG_IP_NF_ARPTABLES=y
++CONFIG_IP_NF_ARPFILTER=y
++CONFIG_IP_NF_ARP_MANGLE=y
++
++#
++# IPv6: Netfilter Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP6_NF_QUEUE is not set
++CONFIG_IP6_NF_IPTABLES=y
++CONFIG_IP6_NF_MATCH_RT=y
++CONFIG_IP6_NF_MATCH_OPTS=y
++CONFIG_IP6_NF_MATCH_FRAG=y
++CONFIG_IP6_NF_MATCH_HL=y
++CONFIG_IP6_NF_MATCH_OWNER=y
++CONFIG_IP6_NF_MATCH_IPV6HEADER=y
++CONFIG_IP6_NF_MATCH_AH=y
++CONFIG_IP6_NF_MATCH_EUI64=y
++CONFIG_IP6_NF_FILTER=y
++CONFIG_IP6_NF_TARGET_LOG=y
++CONFIG_IP6_NF_TARGET_REJECT=y
++CONFIG_IP6_NF_MANGLE=y
++CONFIG_IP6_NF_TARGET_HL=y
++CONFIG_IP6_NF_RAW=y
++
++#
++# Bridge: Netfilter Configuration
++#
++CONFIG_BRIDGE_NF_EBTABLES=y
++CONFIG_BRIDGE_EBT_BROUTE=y
++CONFIG_BRIDGE_EBT_T_FILTER=y
++CONFIG_BRIDGE_EBT_T_NAT=y
++CONFIG_BRIDGE_EBT_802_3=y
++CONFIG_BRIDGE_EBT_AMONG=y
++CONFIG_BRIDGE_EBT_ARP=y
++CONFIG_BRIDGE_EBT_IP=y
++CONFIG_BRIDGE_EBT_LIMIT=y
++CONFIG_BRIDGE_EBT_MARK=y
++CONFIG_BRIDGE_EBT_PKTTYPE=y
++CONFIG_BRIDGE_EBT_STP=y
++CONFIG_BRIDGE_EBT_VLAN=y
++CONFIG_BRIDGE_EBT_ARPREPLY=y
++CONFIG_BRIDGE_EBT_DNAT=y
++CONFIG_BRIDGE_EBT_MARK_T=y
++CONFIG_BRIDGE_EBT_REDIRECT=y
++CONFIG_BRIDGE_EBT_SNAT=y
++CONFIG_BRIDGE_EBT_LOG=y
++CONFIG_BRIDGE_EBT_ULOG=y
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
++
++#
++# TIPC Configuration (EXPERIMENTAL)
++#
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++CONFIG_BRIDGE=y
++CONFIG_VLAN_8021Q=y
++# CONFIG_DECNET is not set
++CONFIG_LLC=y
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_NET_DIVERT is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
++CONFIG_NET_CLS_ROUTE=y
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_IEEE80211 is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_FD is not set
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=10240
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++CONFIG_IDE=y
++CONFIG_BLK_DEV_IDE=y
++
++#
++# Please see Documentation/ide.txt for help/info on IDE drives
++#
++# CONFIG_BLK_DEV_IDE_SATA is not set
++CONFIG_BLK_DEV_IDEDISK=y
++# CONFIG_IDEDISK_MULTI_MODE is not set
++CONFIG_BLK_DEV_IDECD=y
++# CONFIG_BLK_DEV_IDETAPE is not set
++# CONFIG_BLK_DEV_IDEFLOPPY is not set
++# CONFIG_BLK_DEV_IDESCSI is not set
++CONFIG_IDE_TASK_IOCTL=y
++
++#
++# IDE chipset support/bugfixes
++#
++CONFIG_IDE_GENERIC=y
++CONFIG_BLK_DEV_IDEPCI=y
++CONFIG_IDEPCI_SHARE_IRQ=y
++# CONFIG_BLK_DEV_OFFBOARD is not set
++CONFIG_BLK_DEV_GENERIC=y
++# CONFIG_BLK_DEV_OPTI621 is not set
++# CONFIG_BLK_DEV_SL82C105 is not set
++CONFIG_BLK_DEV_IDEDMA_PCI=y
++# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
++CONFIG_IDEDMA_PCI_AUTO=y
++# CONFIG_IDEDMA_ONLYDISK is not set
++# CONFIG_BLK_DEV_AEC62XX is not set
++# CONFIG_BLK_DEV_ALI15X3 is not set
++CONFIG_BLK_DEV_AMD74XX=y
++# CONFIG_BLK_DEV_CMD64X is not set
++# CONFIG_BLK_DEV_TRIFLEX is not set
++# CONFIG_BLK_DEV_CY82C693 is not set
++# CONFIG_BLK_DEV_CS5520 is not set
++# CONFIG_BLK_DEV_CS5530 is not set
++# CONFIG_BLK_DEV_HPT34X is not set
++# CONFIG_BLK_DEV_HPT366 is not set
++# CONFIG_BLK_DEV_SC1200 is not set
++# CONFIG_BLK_DEV_PIIX is not set
++# CONFIG_BLK_DEV_IT821X is not set
++# CONFIG_BLK_DEV_NS87415 is not set
++# CONFIG_BLK_DEV_PDC202XX_OLD is not set
++# CONFIG_BLK_DEV_PDC202XX_NEW is not set
++# CONFIG_BLK_DEV_SVWKS is not set
++# CONFIG_BLK_DEV_SIIMAGE is not set
++# CONFIG_BLK_DEV_SLC90E66 is not set
++# CONFIG_BLK_DEV_TRM290 is not set
++# CONFIG_BLK_DEV_VIA82CXXX is not set
++# CONFIG_IDE_ARM is not set
++CONFIG_BLK_DEV_IDEDMA=y
++# CONFIG_IDEDMA_IVB is not set
++CONFIG_IDEDMA_AUTO=y
++# CONFIG_BLK_DEV_HD is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++# CONFIG_SCSI_PROC_FS is not set
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++CONFIG_BLK_DEV_SR=y
++# CONFIG_BLK_DEV_SR_VENDOR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++
++#
++# SCSI Transport Attributes
++#
++CONFIG_SCSI_SPI_ATTRS=y
++CONFIG_SCSI_FC_ATTRS=y
++CONFIG_SCSI_ISCSI_ATTRS=y
++CONFIG_SCSI_SAS_ATTRS=y
++
++#
++# SCSI low-level drivers
++#
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_BUSLOGIC is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_EATA is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_GDTH is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_IBMVSCSI is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++CONFIG_SCSI_IPR=y
++# CONFIG_SCSI_IPR_TRACE is not set
++# CONFIG_SCSI_IPR_DUMP is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_DEBUG is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Fusion MPT device support
++#
++# CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
++# CONFIG_FUSION_SAS is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_IEEE1394 is not set
++
++#
++# I2O device support
++#
++# CONFIG_I2O is not set
++
++#
++# Macintosh device drivers
++#
++# CONFIG_WINDFARM is not set
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# ARCnet devices
++#
++# CONFIG_ARCNET is not set
++
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++# CONFIG_HAPPYMEAL is not set
++# CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
++# CONFIG_NET_VENDOR_3COM is not set
++
++#
++# Tulip family network device support
++#
++# CONFIG_NET_TULIP is not set
++# CONFIG_HP100 is not set
++CONFIG_IBMVETH=y
++CONFIG_NET_PCI=y
++# CONFIG_PCNET32 is not set
++CONFIG_AMD8111_ETH=y
++# CONFIG_AMD8111E_NAPI is not set
++# CONFIG_ADAPTEC_STARFIRE is not set
++# CONFIG_B44 is not set
++# CONFIG_FORCEDETH is not set
++# CONFIG_DGRS is not set
++# CONFIG_EEPRO100 is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++# CONFIG_8139TOO is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_VIA_RHINE is not set
++
++#
++# Ethernet (1000 Mbit)
++#
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++CONFIG_E1000=y
++# CONFIG_E1000_NAPI is not set
++# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++CONFIG_SKY2=y
++CONFIG_SK98LIN=y
++# CONFIG_VIA_VELOCITY is not set
++CONFIG_TIGON3=y
++CONFIG_BNX2=y
++# CONFIG_MV643XX_ETH is not set
++
++#
++# Ethernet (10000 Mbit)
++#
++# CONFIG_CHELSIO_T1 is not set
++# CONFIG_IXGB is not set
++# CONFIG_S2IO is not set
++# CONFIG_MYRI10GE is not set
++
++#
++# Token Ring devices
++#
++# CONFIG_TR is not set
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Telephony Support
++#
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_TSDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_ICOM is not set
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++CONFIG_HVC_DRIVER=y
++CONFIG_HVC_CONSOLE=y
++# CONFIG_HVC_RTAS is not set
++# CONFIG_HVCS is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++CONFIG_HW_RANDOM=y
++CONFIG_GEN_RTC=y
++# CONFIG_GEN_RTC_X is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_AGP is not set
++# CONFIG_DRM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++# CONFIG_TELCLOCK is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=y
++CONFIG_I2C_CHARDEV=y
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++CONFIG_I2C_AMD8111=y
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++# CONFIG_I2C_NFORCE2 is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++# CONFIG_I2C_PCA_ISA is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++
++#
++# Dallas's 1-wire bus
++#
++
++#
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++CONFIG_VIDEO_V4L2=y
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++CONFIG_FIRMWARE_EDID=y
++# CONFIG_FB is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# LED devices
++#
++# CONFIG_NEW_LEDS is not set
++
++#
++# LED drivers
++#
++
++#
++# LED Triggers
++#
++
++#
++# InfiniBand support
++#
++CONFIG_INFINIBAND=y
++CONFIG_INFINIBAND_USER_MAD=y
++CONFIG_INFINIBAND_USER_ACCESS=y
++CONFIG_INFINIBAND_ADDR_TRANS=y
++CONFIG_INFINIBAND_MTHCA=y
++CONFIG_INFINIBAND_MTHCA_DEBUG=y
++CONFIG_INFINIBAND_IPOIB=y
++CONFIG_INFINIBAND_IPOIB_DEBUG=y
++CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
++CONFIG_INFINIBAND_SRP=y
++# CONFIG_INFINIBAND_ISER is not set
++
++#
++# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
++#
++
++#
++# Real Time Clock
++#
++# CONFIG_RTC_CLASS is not set
++
++#
++# DMA Engine support
++#
++# CONFIG_DMA_ENGINE is not set
++
++#
++# DMA Clients
++#
++
++#
++# DMA Devices
++#
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++CONFIG_EXT2_FS_XIP=y
++CONFIG_FS_XIP=y
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_REISERFS_FS=y
++# CONFIG_REISERFS_CHECK is not set
++CONFIG_REISERFS_PROC_INFO=y
++CONFIG_REISERFS_FS_XATTR=y
++CONFIG_REISERFS_FS_POSIX_ACL=y
++CONFIG_REISERFS_FS_SECURITY=y
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++CONFIG_AUTOFS_FS=y
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++CONFIG_ISO9660_FS=y
++# CONFIG_JOLIET is not set
++# CONFIG_ZISOFS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_KCORE=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++# CONFIG_CONFIGFS_FS is not set
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_CRAMFS=y
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
++# CONFIG_NFS_DIRECTIO is not set
++# CONFIG_NFSD is not set
++CONFIG_ROOT_NFS=y
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_ACL_SUPPORT=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++CONFIG_RPCSEC_GSS_KRB5=y
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_CIFS_DEBUG2 is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf-8"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++# CONFIG_NLS_ISO8859_1 is not set
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++
++#
++# Library routines
++#
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=y
++CONFIG_TEXTSEARCH_BM=y
++CONFIG_TEXTSEARCH_FSM=y
++CONFIG_PLIST=y
++
++#
++# Instrumentation Support
++#
++# CONFIG_PROFILING is not set
++# CONFIG_KPROBES is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_LOG_BUF_SHIFT=17
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++CONFIG_DEBUG_SLAB=y
++CONFIG_DEBUG_MUTEXES=y
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++CONFIG_DEBUG_SPINLOCK_SLEEP=y
++# CONFIG_DEBUG_KOBJECT is not set
++CONFIG_DEBUG_INFO=y
++CONFIG_DEBUG_FS=y
++# CONFIG_DEBUG_VM is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_DEBUG_STACKOVERFLOW=y
++CONFIG_DEBUG_STACK_USAGE=y
++CONFIG_DEBUGGER=y
++CONFIG_XMON=y
++CONFIG_XMON_DEFAULT=y
++# CONFIG_IRQSTACKS is not set
++CONFIG_BOOTX_TEXT=y
++# CONFIG_PPC_EARLY_DEBUG is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++CONFIG_XEN=y
++CONFIG_XEN_INTERFACE_VERSION=0x00030202
++
++#
++# XEN
++#
++CONFIG_XEN_PRIVILEGED_GUEST=y
++CONFIG_XEN_UNPRIVILEGED_GUEST=y
++CONFIG_XEN_PRIVCMD=y
++CONFIG_XEN_BACKEND=y
++# CONFIG_XEN_PCIDEV_BACKEND is not set
++CONFIG_XEN_BLKDEV_BACKEND=y
++CONFIG_XEN_XENBUS_DEV=y
++CONFIG_XEN_NETDEV_BACKEND=y
++# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
++CONFIG_XEN_NETDEV_LOOPBACK=y
++# CONFIG_XEN_TPMDEV_BACKEND is not set
++CONFIG_XEN_BLKDEV_FRONTEND=y
++CONFIG_XEN_NETDEV_FRONTEND=y
++CONFIG_XEN_SCRUB_PAGES=y
++CONFIG_XEN_DISABLE_SERIAL=y
++CONFIG_XEN_SYSFS=y
++# CONFIG_XEN_COMPAT_030002_AND_LATER is not set
++CONFIG_XEN_COMPAT_LATEST_ONLY=y
++# CONFIG_XEN_COMPAT_030002 is not set
++CONFIG_HAVE_ARCH_ALLOC_SKB=y
++CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
++CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
++CONFIG_NO_IDLE_HZ=y
++CONFIG_XEN_DEVMEM=y
++CONFIG_XEN_SKBUFF=y
++CONFIG_XEN_REBOOT=y
++CONFIG_XEN_XENCOMM=y
++
++#
++# Cryptographic options
++#
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Hardware crypto devices
++#
+diff -rpuN linux-2.6.18.8/arch/powerpc/kernel/cpu_setup_power4.S linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/cpu_setup_power4.S
+--- linux-2.6.18.8/arch/powerpc/kernel/cpu_setup_power4.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/cpu_setup_power4.S 2008-02-15 16:21:53.000000000 -0800
+@@ -73,6 +73,13 @@ _GLOBAL(__970_cpu_preinit)
+ blr
+
+ _GLOBAL(__setup_cpu_ppc970)
++ /*
++ * Do nothing if not running in HV mode
++ */
++ mfmsr r0
++ rldicl. r0,r0,4,63
++ beqlr
++
+ mfspr r0,SPRN_HID0
+ li r11,5 /* clear DOZE and SLEEP */
+ rldimi r0,r11,52,8 /* set NAP and DPM */
+diff -rpuN linux-2.6.18.8/arch/powerpc/kernel/prom_init.c linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/prom_init.c
+--- linux-2.6.18.8/arch/powerpc/kernel/prom_init.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/prom_init.c 2008-02-15 16:21:53.000000000 -0800
+@@ -188,6 +188,7 @@ static unsigned long __initdata prom_tce
+ #define PLATFORM_LPAR 0x0001
+ #define PLATFORM_POWERMAC 0x0400
+ #define PLATFORM_GENERIC 0x0500
++#define PLATFORM_GENERIC_XEN (PLATFORM_GENERIC | PLATFORM_LPAR)
+
+ static int __initdata of_platform;
+
+@@ -1529,6 +1530,14 @@ static int __init prom_find_machine_type
+ phandle rtas;
+ int x;
+ #endif
++#ifdef CONFIG_PPC_XEN
++ phandle xen;
++
++ xen = call_prom("finddevice", 1, 1, ADDR("/xen"));
++ if (PHANDLE_VALID(xen)) {
++ return PLATFORM_GENERIC_XEN;
++ }
++#endif
+
+ /* Look for a PowerMac */
+ len = prom_getprop(_prom->root, "compatible",
+@@ -2262,6 +2271,31 @@ unsigned long __init prom_init(unsigned
+ if (RELOC(of_platform) == PLATFORM_PSERIES)
+ prom_initialize_tce_table();
+ #endif
++#ifdef CONFIG_PPC_XEN
++ if (RELOC(of_platform) & PLATFORM_LPAR) {
++ phandle xen;
++
++ prom_debug("XXX:checking for Xen OF package\n");
++
++ xen = call_prom("finddevice", 1, 1, ADDR("/xen"));
++ if (PHANDLE_VALID(xen)) {
++ u64 res[2];
++ int l;
++ ulong base;
++
++ l = prom_getprop(xen, "reserved", res, sizeof (res));
++ if (l != sizeof(res)) {
++ prom_panic("Xen reserved prop not exist\n");
++ }
++
++ base = alloc_down(res[1], PAGE_SIZE, 0);
++ if (base != res[0]) {
++ prom_panic("XSI != alloc_down()\n");
++ }
++ reserve_mem(res[0], res[1]);
++ }
++ }
++#endif
+
+ /*
+ * On non-powermacs, try to instantiate RTAS and puts all CPUs
+diff -rpuN linux-2.6.18.8/arch/powerpc/kernel/setup-common.c linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/setup-common.c
+--- linux-2.6.18.8/arch/powerpc/kernel/setup-common.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/setup-common.c 2008-02-15 16:21:53.000000000 -0800
+@@ -387,6 +387,12 @@ void __init smp_setup_cpu_maps(void)
+ }
}
+
++ if (machine_is(xen)) {
++ /* something more inteligent perhaps? */
++ for (cpu = 0; cpu < NR_CPUS; cpu++)
++ cpu_set(cpu, cpu_possible_map);
++ }
+
-+ return 0;
+ #ifdef CONFIG_PPC64
+ /*
+ * On pSeries LPAR, we need to know how many cpus
+diff -rpuN linux-2.6.18.8/arch/powerpc/kernel/udbg.c linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/udbg.c
+--- linux-2.6.18.8/arch/powerpc/kernel/udbg.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/kernel/udbg.c 2008-02-15 16:21:53.000000000 -0800
+@@ -45,6 +45,9 @@ void __init udbg_early_init(void)
+ #elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES)
+ /* For iSeries - hit Ctrl-x Ctrl-x to see the output */
+ udbg_init_iseries();
++#elif defined(CONFIG_PPC_EARLY_DEBUG_XEN_DOM0) || \
++ defined(CONFIG_PPC_EARLY_DEBUG_XEN_DOMU)
++ udbg_init_xen();
+ #endif
}
- int is_remapped(void *virt)
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arch/x86_64/Kconfig
---- pristine-linux-2.6.18/arch/x86_64/Kconfig 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/Kconfig 2007-11-14 15:35:27.000000000 -0800
-@@ -135,6 +135,22 @@ config GENERIC_CPU
+diff -rpuN linux-2.6.18.8/arch/powerpc/mm/slb_low.S linux-2.6.18-xen-3.2.0/arch/powerpc/mm/slb_low.S
+--- linux-2.6.18.8/arch/powerpc/mm/slb_low.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/mm/slb_low.S 2008-02-15 16:21:53.000000000 -0800
+@@ -51,6 +51,23 @@ _GLOBAL(slb_allocate_realmode)
+ */
+ bne cr7,1f
+
++#ifdef CONFIG_PPC_XEN
++_GLOBAL(slb_miss_kernel_load_xen_nop)
++ b 3f
++ /* Need to check if it is in the part of our XEN Foreign Map */
++ rldicl r9,r3,30,63 /* get Xen region */
++ cmpldi cr7,r9,1 /* cmp this bit set to 1 */
++ bne cr7,3f
++ /* Xen Linear mapping encoding bits, the "li" instruction below
++ * could be patched below (like the other pages of the linear map)
++ * if we ever wish to map anything other that 4K pages in
++ * this region, right now it is fine as zero.
++ */
++_GLOBAL(slb_miss_kernel_load_xen_linear)
++ li r11,0
++ b slb_finish_load
++3:
++#endif
+ /* Linear mapping encoding bits, the "li" instruction below will
+ * be patched by the kernel at boot
+ */
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/Makefile linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/Makefile
+--- linux-2.6.18.8/arch/powerpc/platforms/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/Makefile 2008-02-15 16:21:53.000000000 -0800
+@@ -12,6 +12,8 @@ obj-$(CONFIG_PPC_85xx) += 85xx/
+ obj-$(CONFIG_PPC_86xx) += 86xx/
+ obj-$(CONFIG_PPC_PSERIES) += pseries/
+ obj-$(CONFIG_PPC_ISERIES) += iseries/
++# must occur before xen hosting platforms
++obj-$(CONFIG_PPC_XEN) += xen/
+ obj-$(CONFIG_PPC_MAPLE) += maple/
+ obj-$(CONFIG_PPC_CELL) += cell/
+ obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/pseries/iommu.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/pseries/iommu.c
+--- linux-2.6.18.8/arch/powerpc/platforms/pseries/iommu.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/pseries/iommu.c 2008-02-15 16:21:53.000000000 -0800
+@@ -531,6 +531,17 @@ static void iommu_dev_setup_pSeriesLP(st
+ * already allocated.
+ */
+ dn = pci_device_to_OF_node(dev);
++ if (dn == NULL) {
++#ifdef CONFIG_PPC_XEN
++ /* this becomes possible for Xen Dom0 */
++ DBG("%s, dev %p (%s) has no OF devtree entree\n", __func__,
++ dev, pci_name(dev));
++ return;
++#else
++ panic("%s, dev %p (%s) has no OF devtree entree\n", __func__,
++ dev, pci_name(dev));
++#endif
++ }
+
+ for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
+ pdn = pdn->parent) {
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/Makefile linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/Makefile
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/Makefile 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/Makefile 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,20 @@
++obj-y += gnttab.o
++obj-y += hcall.o
++obj-y += reboot.o
++obj-y += setup.o
++obj-y += smp.o
++obj-y += time.o
++obj-y += udbg_xen.o
++obj-y += xen_guest.o
++obj-y += xencomm.o
++
++# we need the latest __XEN_INTERFACE_VERSION__ (see xen-compat.h)
++CFLAGS_hcall.o += -D__XEN_TOOLS__
++
++ifndef CONFIG_XEN_BALLOON
++obj-y += balloon.o
++endif
++
++ifndef CONFIG_XEN_UTIL
++obj-y += util.o
++endif
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/balloon.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/balloon.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/balloon.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/balloon.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,82 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <asm/hypervisor.h>
++#include "setup.h"
++
++/*
++ * FIXME: Port balloon driver, if ever
++ */
++
++struct page **alloc_empty_pages_and_pagevec(int nr_pages)
++{
++ struct page *page, **pagevec;
++ int i;
++
++ pagevec = kmalloc(sizeof(*pagevec) * nr_pages, GFP_KERNEL);
++ if (pagevec == NULL)
++ return NULL;
++
++ for (i = 0; i < nr_pages; i++) {
++ page = alloc_foreign_page();
++ BUG_ON(page == NULL);
++ pagevec[i] = page;
++ /* There is no real page backing us yet so it cannot
++ * be scrubbed */
++ }
++
++ return pagevec;
++}
++
++void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
++{
++ int i;
++
++ if (pagevec == NULL)
++ return;
++
++ for (i = 0; i < nr_pages; i++) {
++ free_foreign_page(pagevec[i]);
++ }
++
++ kfree(pagevec);
++}
++
++void balloon_dealloc_empty_page_range(
++ struct page *page, unsigned long nr_pages)
++{
++ __free_pages(page, get_order(nr_pages * PAGE_SIZE));
++}
++
++void balloon_update_driver_allowance(long delta)
++{
++}
++
++void balloon_release_driver_page(struct page *page)
++{
++ BUG();
++}
++
++EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
++EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec);
++EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec);
++EXPORT_SYMBOL_GPL(balloon_release_driver_page);
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/gnttab.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/gnttab.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/gnttab.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/gnttab.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,468 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/config.h>
++#include <linux/vmalloc.h>
++#include <linux/memory_hotplug.h>
++#include <xen/gnttab.h>
++#include <asm/hypervisor.h>
++#include <xen/interface/grant_table.h>
++#include <asm/pgtable.h>
++#include <asm/sections.h>
++#include <asm/io.h>
++#include <asm/machdep.h>
++#include <asm/prom.h>
++#include <asm/cacheflush.h>
++#include "setup.h"
++#include "../pseries/plpar_wrappers.h"
++
++#undef DEBUG
++
++#ifdef DEBUG
++#define DBG(fmt...) printk(KERN_EMERG fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++#define NR_GRANT_FRAMES 4
++
++struct address_space xen_foreign_dummy_mapping;
++
++static ulong foreign_map_pfn;
++static ulong foreign_map_pgs;
++static unsigned long *foreign_map_bitmap;
++
++
++/* hijack _mapcount */
++static inline int gnt_mapcount(struct page *page)
++{
++ return atomic_read(&(page)->_mapcount) + 1;
++}
++
++static inline int gnt_map(struct page *page)
++{
++ /* return true is transition from -1 to 0 */
++ return atomic_inc_and_test(&page->_mapcount);
++}
++
++static inline int gnt_unmap(struct page *page)
++{
++ int val;
++
++ val = atomic_dec_return(&page->_mapcount);
++ if (val < -1) {
++ atomic_inc(&page->_mapcount);
++ printk(KERN_EMERG "%s: %d\n", __func__, val);
++ }
++
++ return (val == -1);
++}
++
++
++static long map_to_linear(ulong paddr)
++{
++ unsigned long vaddr;
++ int psize;
++ unsigned long mode;
++ int slot;
++ uint shift;
++ unsigned long tmp_mode;
++
++ psize = MMU_PAGE_4K;
++ shift = mmu_psize_defs[psize].shift;
++ mode = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
++ vaddr = (ulong)__va(paddr);
++
++ {
++ unsigned long vpn, hash, hpteg;
++ unsigned long vsid = get_kernel_vsid(vaddr);
++ unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff);
++
++ vpn = va >> shift;
++ tmp_mode = mode;
++
++ /* Make non-kernel text non-executable */
++ if (!in_kernel_text(vaddr))
++ tmp_mode = mode | HPTE_R_N;
++
++ hash = hpt_hash(va, shift);
++ hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
++
++ BUG_ON(!ppc_md.hpte_insert);
++ slot = ppc_md.hpte_insert(hpteg, va, paddr,
++ tmp_mode, HPTE_V_BOLTED, psize);
++ if (slot < 0)
++ printk(KERN_EMERG
++ "%s: no more bolted entries "
++ "HTAB[0x%lx]: 0x%lx\n",
++ __func__, hpteg, paddr);
++ }
++ return slot;
++}
++
++static unsigned long get_hpte_vsid(ulong slot)
++{
++ unsigned long dword0;
++ unsigned long lpar_rc;
++ unsigned long dummy_word1;
++ unsigned long flags;
++
++ /* Read 1 pte at a time */
++ /* Do not need RPN to logical page translation */
++ /* No cross CEC PFT access */
++ flags = 0;
++
++ lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
++
++ BUG_ON(lpar_rc != H_SUCCESS);
++
++ return dword0;
++}
++
++static long find_hpte_slot(unsigned long va, int psize)
++{
++ unsigned long hash;
++ unsigned long i, j;
++ long slot;
++ unsigned long want_v, hpte_v;
++
++ hash = hpt_hash(va, mmu_psize_defs[psize].shift);
++ want_v = hpte_encode_v(va, psize);
++
++ for (j = 0; j < 2; j++) {
++ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
++ for (i = 0; i < HPTES_PER_GROUP; i++) {
++ hpte_v = get_hpte_vsid(slot);
++
++ if (HPTE_V_COMPARE(hpte_v, want_v)
++ && (hpte_v & HPTE_V_VALID)
++ && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
++ /* HPTE matches */
++ if (j)
++ slot = -slot;
++ return slot;
++ }
++ ++slot;
++ }
++ hash = ~hash;
++ }
++
++ return -1;
++}
++
++static long find_map_slot(ulong ea)
++{
++ int psize = MMU_PAGE_4K;
++ ulong vsid;
++ ulong va;
++
++ vsid = get_kernel_vsid(ea);
++ va = (vsid << 28) | (ea & 0x0fffffff);
++
++ return find_hpte_slot(va, psize);
++}
++
++
++static void gnttab_pre_unmap_grant_ref(
++ struct gnttab_unmap_grant_ref *unmap, int count)
++{
++ long slot;
++ int i;
++ ulong ea;
++ unsigned long dummy1, dummy2;
++ ulong flags;
++
++ /* paranoia */
++ local_irq_save(flags);
++
++ for (i = 0 ; i < count; i++) {
++ struct page *page;
++
++ ea = (ulong)__va(unmap[i].host_addr);
++ page = virt_to_page(ea);
++
++ if (!gnt_unmap(page)) {
++ DBG("%s[0x%x]: skip: 0x%lx, mapcount 0x%x\n",
++ __func__, i, ea, gnt_mapcount(page));
++ continue;
++ }
++ slot = find_map_slot(ea);
++ if (slot < 0) {
++ printk(KERN_EMERG "%s: PTE not found: 0x%lx\n",
++ __func__, ea);
++ continue;
++ }
++
++ DBG("%s[0x%x]: 0x%lx: mapcount: 0x%x\n",
++ __func__, i, ea, gnt_mapcount(page));
++ plpar_pte_remove(0, slot, 0, &dummy1, &dummy2);
++ }
++ local_irq_restore(flags);
++}
++
++static void gnttab_post_map_grant_ref(
++ struct gnttab_map_grant_ref *map, int count)
++{
++ int i;
++ long slot;
++ ulong flags;
++
++ /* paranoia */
++ local_irq_save(flags);
++
++ for (i = 0 ; i < count; i++) {
++ ulong pa = map[i].host_addr;
++ struct page *page;
++
++ if (map[i].status != GNTST_okay) {
++ printk(KERN_EMERG "%s: status, skip\n", __func__);
++ continue;
++ }
++
++ BUG_ON(pa < (foreign_map_pfn << PAGE_SHIFT));
++ BUG_ON(pa >= (foreign_map_pfn << PAGE_SHIFT) +
++ (foreign_map_pgs << PAGE_SHIFT));
++
++ page = virt_to_page(__va(pa));
++
++ if (gnt_map(page)) {
++#ifdef DEBUG
++ /* we need to get smarted than this */
++ slot = find_map_slot((ulong)__va(pa));
++ if (slot >= 0) {
++ DBG("%s: redundant 0x%lx\n", __func__, pa);
++ continue;
++ }
++#endif
++ slot = map_to_linear(pa);
++ DBG("%s[0x%x]: 0x%lx, mapcount:0x%x\n",
++ __func__, i, pa, gnt_mapcount(page));
++
++ } else {
++ DBG("%s[0x%x] skip 0x%lx, mapcount:0x%x\n",
++ __func__, i, pa, gnt_mapcount(page));
++ }
++ }
++ local_irq_restore(flags);
++}
++
++int HYPERVISOR_grant_table_op(unsigned int cmd, void *op, unsigned int count)
++{
++ void *desc;
++ void *frame_list = NULL;
++ int argsize;
++ int ret = -ENOMEM;
++
++ switch (cmd) {
++ case GNTTABOP_map_grant_ref:
++ argsize = sizeof(struct gnttab_map_grant_ref);
++ break;
++ case GNTTABOP_unmap_grant_ref:
++ gnttab_pre_unmap_grant_ref(op, count);
++ argsize = sizeof(struct gnttab_unmap_grant_ref);
++ break;
++ case GNTTABOP_setup_table: {
++ struct gnttab_setup_table setup;
++
++ memcpy(&setup, op, sizeof(setup));
++ argsize = sizeof(setup);
++
++ frame_list = xencomm_map(
++ xen_guest_handle(setup.frame_list),
++ (sizeof(*xen_guest_handle(setup.frame_list))
++ * setup.nr_frames));
++
++ if (frame_list == NULL)
++ return -ENOMEM;
++
++ set_xen_guest_handle(setup.frame_list, frame_list);
++ memcpy(op, &setup, sizeof(setup));
++ }
++ break;
++ case GNTTABOP_dump_table:
++ argsize = sizeof(struct gnttab_dump_table);
++ break;
++ case GNTTABOP_transfer:
++ BUG();
++ argsize = sizeof(struct gnttab_transfer);
++ break;
++ case GNTTABOP_copy:
++ argsize = sizeof(struct gnttab_transfer);
++ break;
++ case GNTTABOP_query_size:
++ argsize = sizeof(struct gnttab_query_size);
++ break;
++ default:
++ printk(KERN_EMERG "%s: unknown grant table op %d\n",
++ __func__, cmd);
++ return -ENOSYS;
++ }
++
++ desc = xencomm_map_no_alloc(op, argsize);
++ if (desc) {
++ ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_grant_table_op),
++ cmd, desc, count);
++ if (!ret && cmd == GNTTABOP_map_grant_ref)
++ gnttab_post_map_grant_ref(op, count);
++ xencomm_free(desc);
++ }
++ xencomm_free(frame_list);
++
++ return ret;
++}
++EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
++
++static ulong find_grant_maps(void)
++{
++ struct device_node *xen;
++ u64 *gm;
++ u64 _gm[2];
++ u64 expect;
++
++ /* This value is currently hardcoded into the SLB logic that
++ * it written in assempler, See
++ * slb_miss_kernel_load_xen_linear for more information.
++ * Anything else and we can not run. */
++ expect = 34 - PAGE_SHIFT;
++
++ xen = of_find_node_by_path("/xen");
++
++ /*
++ * The foreign is 2x2 Cells.
++ * The first entry is log2 of the base page frame.
++ * The second is the number of pages
++ */
++ gm = (u64 *)get_property(xen, "foreign-map", NULL);
++ if (gm == NULL) {
++ if (!is_initial_xendomain()) {
++ printk("OF: /xen/foreign-map not present\n");
++ _gm[0] = expect;
++ _gm[1] = 2048;
++ gm = _gm;
++ } else
++ panic("OF: /xen/foreign-map must be present\n");
++ }
++
++ if (gm[0] != expect)
++ panic("foreign-map is 0x%lx, expect 0x%lx\n",
++ gm[0], expect);
++
++ foreign_map_pfn = 1UL << gm[0];
++ return gm[1];
++}
++
++static void setup_foreign_segment(void)
++{
++ extern int *slb_miss_kernel_load_xen_nop;
++ ulong iaddr = (ulong)slb_miss_kernel_load_xen_nop;
++
++ /* By default Linux will branch around this logic we replace
++ * the branch with a NOP to turn the logic on */
++ *slb_miss_kernel_load_xen_nop = 0x60000000;
++ flush_icache_range(iaddr, iaddr + 4);
++}
++
++struct page *alloc_foreign_page(void)
++{
++ ulong bit;
++ do {
++ bit = find_first_zero_bit(foreign_map_bitmap,
++ foreign_map_pgs);
++ if (bit >= foreign_map_pgs)
++ return NULL;
++ } while (test_and_set_bit(bit, foreign_map_bitmap) == 1);
++
++ return pfn_to_page(foreign_map_pfn + bit);
++}
++
++void free_foreign_page(struct page *page)
++{
++ ulong bit = page_to_pfn(page) - foreign_map_pfn;
++
++ BUG_ON(bit >= foreign_map_pgs);
++ BUG_ON(!test_bit(bit, foreign_map_bitmap));
++
++ clear_bit(bit, foreign_map_bitmap);
++}
++
++static void setup_grant_area(void)
++{
++ ulong pgs;
++ int err;
++ struct zone *zone;
++ struct pglist_data *pgdata;
++ int nid;
++
++ pgs = find_grant_maps();
++ setup_foreign_segment();
++
++ printk("%s: Xen VIO will use a foreign address space of 0x%lx pages\n",
++ __func__, pgs);
++
++ /* add pages to the zone */
++ nid = 0;
++ pgdata = NODE_DATA(nid);
++ zone = pgdata->node_zones;
++
++ err = __add_pages(zone, foreign_map_pfn, pgs);
++
++ if (err < 0) {
++ printk(KERN_EMERG "%s: add_pages(0x%lx, 0x%lx) = %d\n",
++ __func__, foreign_map_pfn, pgs, err);
++ BUG();
++ }
++
++ /* create a bitmap to manage these pages */
++ foreign_map_bitmap = kmalloc(BITS_TO_LONGS(pgs) * sizeof(long),
++ GFP_KERNEL);
++ if (foreign_map_bitmap == NULL) {
++ printk(KERN_EMERG
++ "%s: could not allocate foreign_map_bitmap to "
++ "manage 0x%lx foreign pages\n", __func__, pgs);
++ BUG();
++ }
++ /* I'm paranoid so make sure we assign the top bits so we
++ * don't give them away */
++ bitmap_fill(&foreign_map_bitmap[BITS_TO_LONGS(pgs) - 1],
++ BITS_PER_LONG);
++ /* now clear all the real bits */
++ bitmap_zero(foreign_map_bitmap, pgs);
++
++ foreign_map_pgs = pgs;
++}
++
++void *arch_gnttab_alloc_shared(unsigned long *frames)
++{
++ void *shared;
++ ulong pa = frames[0] << PAGE_SHIFT;
++ static int resume;
++
++ shared = ioremap(pa, PAGE_SIZE * NR_GRANT_FRAMES);
++ BUG_ON(shared == NULL);
++ printk("%s: grant table at %p\n", __func__, shared);
++
++ /* no need to do the rest of this if we are resuming */
++ if (!resume)
++ setup_grant_area();
++
++ resume = 1;
++
++ return shared;
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/hcall.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/hcall.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/hcall.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/hcall.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,891 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006, 2007
++ *
++ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/gfp.h>
++#include <linux/module.h>
++#include <xen/interface/xen.h>
++#include <xen/interface/domctl.h>
++#include <xen/interface/sysctl.h>
++#include <xen/interface/platform.h>
++#include <xen/interface/memory.h>
++#include <xen/interface/xencomm.h>
++#include <xen/interface/version.h>
++#include <xen/interface/sched.h>
++#include <xen/interface/event_channel.h>
++#include <xen/interface/physdev.h>
++#include <xen/interface/vcpu.h>
++#include <xen/interface/xsm/acm_ops.h>
++#include <xen/interface/kexec.h>
++#include <xen/public/privcmd.h>
++#include <asm/hypercall.h>
++#include <asm/page.h>
++#include <asm/uaccess.h>
++#include <asm/hvcall.h>
++#include "setup.h"
++
++/* Xencomm notes:
++ *
++ * For kernel memory, we assume that virtually contiguous pages are also
++ * physically contiguous. This allows us to avoid creating descriptors for
++ * kernel hypercalls, such as console and event channel operations.
++ *
++ * In general, we need a xencomm descriptor to cover the top-level data
++ * structure (e.g. the domctl op), plus another for every embedded pointer to
++ * another data structure (i.e. for every GUEST_HANDLE).
++ */
++
++int HYPERVISOR_console_io(int cmd, int count, char *str)
++{
++ struct xencomm_handle *desc;
++ int rc;
++
++ desc = xencomm_map_no_alloc(str, count);
++ if (desc == NULL)
++ return -EINVAL;
++
++ rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_console_io),
++ cmd, count, desc);
++
++ xencomm_free(desc);
++
++ return rc;
++}
++EXPORT_SYMBOL(HYPERVISOR_console_io);
++
++int HYPERVISOR_event_channel_op(int cmd, void *op)
++{
++ int rc;
++
++ struct xencomm_handle *desc =
++ xencomm_map_no_alloc(op, sizeof(evtchn_op_t));
++ if (desc == NULL)
++ return -EINVAL;
++
++ rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_event_channel_op),
++ cmd, desc);
++
++ xencomm_free(desc);
++
++ return rc;
++
++}
++EXPORT_SYMBOL(HYPERVISOR_event_channel_op);
++
++int HYPERVISOR_xen_version(int cmd, void *arg)
++{
++ struct xencomm_handle *desc;
++ const unsigned long hcall = __HYPERVISOR_xen_version;
++ int argsize;
++ int rc;
++
++ switch (cmd) {
++ case XENVER_version:
++ /* do not actually pass an argument */
++ return plpar_hcall_norets(XEN_MARK(hcall), cmd, 0);
++ case XENVER_extraversion:
++ argsize = sizeof(xen_extraversion_t);
++ break;
++ case XENVER_compile_info:
++ argsize = sizeof(xen_compile_info_t);
++ break;
++ case XENVER_capabilities:
++ argsize = sizeof(xen_capabilities_info_t);
++ break;
++ case XENVER_changeset:
++ argsize = sizeof(xen_changeset_info_t);
++ break;
++ case XENVER_platform_parameters:
++ argsize = sizeof(xen_platform_parameters_t);
++ break;
++ case XENVER_pagesize:
++ if (arg == NULL)
++ argsize = 0;
++ else
++ argsize = sizeof(void *);
++ break;
++ case XENVER_get_features:
++ argsize = sizeof(xen_feature_info_t);
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown version cmd %d\n", __func__, cmd);
++ return -ENOSYS;
++ }
++
++ /* desc could be NULL in the case of XENVER_pagesize with NULL arg */
++ desc = xencomm_map(arg, argsize);
++
++ rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, desc);
++
++ xencomm_free(desc);
++
++ return rc;
++}
++EXPORT_SYMBOL(HYPERVISOR_xen_version);
++
++
++int HYPERVISOR_physdev_op(int cmd, void *op)
++{
++ struct xencomm_handle *desc =
++ xencomm_map_no_alloc(op, sizeof(physdev_op_t));
++ int rc;
++
++ if (desc == NULL)
++ return -EINVAL;
++
++ rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_physdev_op),
++ cmd, desc);
++
++ xencomm_free(desc);
++
++ return rc;
++}
++EXPORT_SYMBOL(HYPERVISOR_physdev_op);
++
++int HYPERVISOR_sched_op(int cmd, void *arg)
++{
++ int argsize = 0;
++ int rc = -EINVAL;
++ struct xencomm_handle *desc;
++ struct xencomm_handle *ports = NULL;
++
++ switch (cmd) {
++ case SCHEDOP_yield:
++ case SCHEDOP_block:
++ return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
++ cmd, 0);
++ break;
++
++ case SCHEDOP_poll: {
++ struct sched_poll sched_poll;
++
++ argsize = sizeof(struct sched_poll);
++
++ memcpy(&sched_poll, arg, sizeof(sched_poll));
++
++ ports = xencomm_map(
++ xen_guest_handle(sched_poll.ports),
++ (sizeof(evtchn_port_t) * sched_poll.nr_ports));
++
++ if (ports == NULL)
++ return -ENOMEM;
++
++ set_xen_guest_handle(sched_poll.ports, (evtchn_port_t *)ports);
++ memcpy(arg, &sched_poll, sizeof(sched_poll));
++
++ }
++ break;
++ case SCHEDOP_shutdown:
++ argsize = sizeof(struct sched_shutdown);
++ break;
++ case SCHEDOP_remote_shutdown:
++ argsize = sizeof(struct sched_remote_shutdown);
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown sched op %d\n", __func__, cmd);
++ return -ENOSYS;
++ }
++
++ desc = xencomm_map_no_alloc(arg, argsize);
++ if (desc) {
++ rc = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
++ cmd, desc);
++ xencomm_free(desc);
++ }
++
++ xencomm_free(ports);
++
++ return rc;
++}
++EXPORT_SYMBOL(HYPERVISOR_sched_op);
++
++int HYPERVISOR_suspend(unsigned long srec)
++{
++ int cmd = SCHEDOP_shutdown;
++ struct sched_shutdown sched_shutdown = {
++ .reason = SHUTDOWN_suspend,
++ };
++ struct xencomm_handle *desc;
++
++ desc = xencomm_map_no_alloc(&sched_shutdown, sizeof(struct sched_shutdown));
++
++ return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_sched_op),
++ cmd, desc, srec);
++}
++EXPORT_SYMBOL(HYPERVISOR_suspend);
++
++int HYPERVISOR_kexec_op(unsigned long op, void *args)
++{
++ unsigned long argsize;
++ struct xencomm_handle *desc;
++
++ switch (op) {
++ case KEXEC_CMD_kexec_get_range:
++ argsize = sizeof(struct xen_kexec_range);
++ break;
++ case KEXEC_CMD_kexec_load:
++ argsize = sizeof(struct xen_kexec_load);
++ break;
++ case KEXEC_CMD_kexec_unload:
++ argsize = sizeof(struct xen_kexec_load);
++ break;
++ case KEXEC_CMD_kexec:
++ argsize = sizeof(struct xen_kexec_exec);
++ break;
++ default:
++ return -ENOSYS;
++ }
++ desc = xencomm_map_no_alloc(args, argsize);
++
++ return plpar_hcall_norets(XEN_MARK(__HYPERVISOR_kexec_op),
++ op, desc);
++}
++EXPORT_SYMBOL(HYPERVISOR_kexec_op);
++
++int HYPERVISOR_poll(
++ evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
++{
++ struct sched_poll sched_poll = {
++ .nr_ports = nr_ports,
++ .timeout = jiffies_to_ns(timeout)
++ };
++ set_xen_guest_handle(sched_poll.ports, ports);
++
++ return HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
++}
++EXPORT_SYMBOL(HYPERVISOR_poll);
++
++typedef ulong (mf_t)(ulong arg0, ...);
++
++static mf_t *multicall_funcs[] = {
++ [__HYPERVISOR_grant_table_op] = (mf_t *)HYPERVISOR_grant_table_op,
++};
++
++int HYPERVISOR_multicall(void *call_list, int nr_calls)
++{
++ /* we blow out the multicall because the xencomm stuff is jsut
++ * too tricky */
++ multicall_entry_t *mcl = (multicall_entry_t *)call_list;
++ multicall_entry_t *c;
++ int i;
++ mf_t *mf;
++ int res;
++ ulong flags;
++
++ /* let make sure all the calls are supported */
++ for (i = 0; i < nr_calls; i++) {
++ mf = multicall_funcs[mcl[i].op];
++ BUG_ON(mf == NULL);
++ }
++ /* disable interrupts until we are done all calls */
++ local_irq_save(flags);
++ for (i = 0; i < nr_calls; i++) {
++ /* lookup supported multicalls */
++ c = &mcl[i];
++ mf = multicall_funcs[c->op];
++ res = mf(c->args[0], c->args[1], c->args[2],
++ c->args[3], c->args[4], c->args[5]);
++ c->result = res;
++ }
++ local_irq_restore(flags);
++ return 0;
++}
++EXPORT_SYMBOL(HYPERVISOR_multicall);
++
++
++/* privcmd operations: */
++
++static int xenppc_privcmd_domctl(privcmd_hypercall_t *hypercall)
++{
++ xen_domctl_t kern_op;
++ xen_domctl_t __user *user_op = (xen_domctl_t __user *)hypercall->arg[0];
++ struct xencomm_handle *op_desc;
++ struct xencomm_handle *desc = NULL;
++ int ret = 0;
++
++ if (copy_from_user(&kern_op, user_op, sizeof(xen_domctl_t)))
++ return -EFAULT;
++
++ if (kern_op.interface_version != XEN_DOMCTL_INTERFACE_VERSION) {
++ printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
++ kern_op.interface_version, XEN_DOMCTL_INTERFACE_VERSION);
++ return -EACCES;
++ }
++
++ op_desc = xencomm_map(&kern_op, sizeof(xen_domctl_t));
++ if (op_desc == NULL)
++ return -ENOMEM;
++
++ switch (kern_op.cmd) {
++ case XEN_DOMCTL_createdomain:
++ case XEN_DOMCTL_destroydomain:
++ case XEN_DOMCTL_pausedomain:
++ case XEN_DOMCTL_unpausedomain:
++ case XEN_DOMCTL_getdomaininfo:
++ break;
++ case XEN_DOMCTL_getmemlist:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.getmemlist.buffer),
++ kern_op.u.getmemlist.max_pfns * sizeof(unsigned long));
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.getmemlist.buffer,
++ (void *)desc);
++ break;
++ case XEN_DOMCTL_getpageframeinfo:
++ break;
++ case XEN_DOMCTL_getpageframeinfo2:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.getpageframeinfo2.array),
++ kern_op.u.getpageframeinfo2.num);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.getpageframeinfo2.array,
++ (void *)desc);
++ break;
++ case XEN_DOMCTL_shadow_op:
++
++ if (xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap))
++ {
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
++ kern_op.u.shadow_op.pages * sizeof(unsigned long));
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
++ (void *)desc);
++ }
++ break;
++ case XEN_DOMCTL_max_mem:
++ break;
++ case XEN_DOMCTL_setvcpucontext:
++ case XEN_DOMCTL_getvcpucontext:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.vcpucontext.ctxt),
++ sizeof(vcpu_guest_context_t));
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.vcpucontext.ctxt,
++ (void *)desc);
++ break;
++ case XEN_DOMCTL_getvcpuinfo:
++ break;
++ case XEN_DOMCTL_setvcpuaffinity:
++ case XEN_DOMCTL_getvcpuaffinity:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap),
++ (kern_op.u.vcpuaffinity.cpumap.nr_cpus + 7) / 8);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap,
++ (void *)desc);
++ break;
++ case XEN_DOMCTL_max_vcpus:
++ case XEN_DOMCTL_scheduler_op:
++ case XEN_DOMCTL_setdomainhandle:
++ case XEN_DOMCTL_setdebugging:
++ case XEN_DOMCTL_irq_permission:
++ case XEN_DOMCTL_iomem_permission:
++ case XEN_DOMCTL_ioport_permission:
++ case XEN_DOMCTL_hypercall_init:
++ case XEN_DOMCTL_arch_setup:
++ case XEN_DOMCTL_settimeoffset:
++ case XEN_DOMCTL_real_mode_area:
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown domctl cmd %d\n", __func__, kern_op.cmd);
++ return -ENOSYS;
++ }
++
++ if (ret)
++ goto out; /* error mapping the nested pointer */
++
++ ret = plpar_hcall_norets(XEN_MARK(hypercall->op),op_desc);
++
++ if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t)))
++ ret = -EFAULT;
++
++out:
++ xencomm_free(desc);
++ xencomm_free(op_desc);
++ return ret;
++}
++
++static int xenppc_privcmd_sysctl(privcmd_hypercall_t *hypercall)
++{
++ xen_sysctl_t kern_op;
++ xen_sysctl_t __user *user_op = (xen_sysctl_t __user *)hypercall->arg[0];
++ struct xencomm_handle *op_desc;
++ struct xencomm_handle *desc = NULL;
++ int ret = 0;
++
++ if (copy_from_user(&kern_op, user_op, sizeof(xen_sysctl_t)))
++ return -EFAULT;
++
++ if (kern_op.interface_version != XEN_SYSCTL_INTERFACE_VERSION) {
++ printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
++ kern_op.interface_version, XEN_SYSCTL_INTERFACE_VERSION);
++ return -EACCES;
++ }
++
++ op_desc = xencomm_map(&kern_op, sizeof(xen_sysctl_t));
++
++ if (op_desc == NULL)
++ return -ENOMEM;
++
++ switch (kern_op.cmd) {
++ case XEN_SYSCTL_readconsole:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.readconsole.buffer),
++ kern_op.u.readconsole.count);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.readconsole.buffer,
++ (void *)desc);
++ break;
++ case XEN_SYSCTL_tbuf_op:
++ case XEN_SYSCTL_physinfo:
++ case XEN_SYSCTL_sched_id:
++ break;
++ case XEN_SYSCTL_perfc_op:
++ /* XXX this requires *two* embedded xencomm mappings (desc and val),
++ * and I don't feel like it right now. */
++ printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
++ return -ENOSYS;
++ case XEN_SYSCTL_getdomaininfolist:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
++ kern_op.u.getdomaininfolist.max_domains *
++ sizeof(xen_domctl_getdomaininfo_t));
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer,
++ (void *)desc);
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
++ return -ENOSYS;
++ }
++
++ if (ret)
++ goto out; /* error mapping the nested pointer */
++
++ ret = plpar_hcall_norets(XEN_MARK(hypercall->op), op_desc);
++
++ if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t)))
++ ret = -EFAULT;
++
++out:
++ xencomm_free(desc);
++ xencomm_free(op_desc);
++ return ret;
++}
++
++static int xenppc_privcmd_platform_op(privcmd_hypercall_t *hypercall)
++{
++ xen_platform_op_t kern_op;
++ xen_platform_op_t __user *user_op =
++ (xen_platform_op_t __user *)hypercall->arg[0];
++ struct xencomm_handle *op_desc;
++ struct xencomm_handle *desc = NULL;
++ int ret = 0;
++
++ if (copy_from_user(&kern_op, user_op, sizeof(xen_platform_op_t)))
++ return -EFAULT;
++
++ if (kern_op.interface_version != XENPF_INTERFACE_VERSION) {
++ printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
++ kern_op.interface_version, XENPF_INTERFACE_VERSION);
++ return -EACCES;
++ }
++
++ op_desc = xencomm_map(&kern_op, sizeof(xen_platform_op_t));
++
++ if (op_desc == NULL)
++ return -ENOMEM;
++
++ switch (kern_op.cmd) {
++ case XENPF_settime:
++ case XENPF_add_memtype:
++ case XENPF_del_memtype:
++ case XENPF_read_memtype:
++ case XENPF_microcode_update:
++ case XENPF_platform_quirk:
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown platform_op cmd %d\n", __func__,
++ kern_op.cmd);
++ return -ENOSYS;
++ }
++
++ if (ret)
++ goto out; /* error mapping the nested pointer */
++
++ ret = plpar_hcall_norets(XEN_MARK(hypercall->op), op_desc);
++
++ if (copy_to_user(user_op, &kern_op, sizeof(xen_platform_op_t)))
++ ret = -EFAULT;
++
++out:
++ xencomm_free(desc);
++ xencomm_free(op_desc);
++ return ret;
++}
++
++int HYPERVISOR_memory_op(unsigned int cmd, void *arg)
++{
++ int ret;
++ struct xencomm_handle *op_desc;
++ xen_memory_reservation_t *mop;
++
++
++ mop = (xen_memory_reservation_t *)arg;
++
++ op_desc = xencomm_map(mop, sizeof(xen_memory_reservation_t));
++
++ if (op_desc == NULL)
++ return -ENOMEM;
++
++ switch (cmd) {
++ case XENMEM_increase_reservation:
++ case XENMEM_decrease_reservation:
++ case XENMEM_populate_physmap: {
++ struct xencomm_handle *desc = NULL;
++
++ if (xen_guest_handle(mop->extent_start)) {
++ desc = xencomm_map(
++ xen_guest_handle(mop->extent_start),
++ mop->nr_extents *
++ sizeof(*xen_guest_handle(mop->extent_start)));
++
++ if (desc == NULL) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ set_xen_guest_handle(mop->extent_start,
++ (void *)desc);
++ }
++
++ ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_memory_op),
++ cmd, op_desc);
++
++ xencomm_free(desc);
++ }
++ break;
++
++ case XENMEM_maximum_ram_page:
++ /* arg is NULL so we can call thru here */
++ ret = plpar_hcall_norets(XEN_MARK(__HYPERVISOR_memory_op),
++ cmd, NULL);
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown memory op %d\n", __func__, cmd);
++ ret = -ENOSYS;
++ }
++
++out:
++ xencomm_free(op_desc);
++ return ret;
++}
++EXPORT_SYMBOL(HYPERVISOR_memory_op);
++
++static int xenppc_privcmd_memory_op(privcmd_hypercall_t *hypercall)
++{
++ xen_memory_reservation_t kern_op;
++ xen_memory_reservation_t __user *user_op;
++ const unsigned long cmd = hypercall->arg[0];
++ int ret = 0;
++
++ user_op = (xen_memory_reservation_t __user *)hypercall->arg[1];
++ if (copy_from_user(&kern_op, user_op,
++ sizeof(xen_memory_reservation_t)))
++ return -EFAULT;
++
++ ret = HYPERVISOR_memory_op(cmd, &kern_op);
++ if (ret >= 0) {
++ if (copy_to_user(user_op, &kern_op,
++ sizeof(xen_memory_reservation_t)))
++ return -EFAULT;
++ }
++ return ret;
++}
++
++static int xenppc_privcmd_version(privcmd_hypercall_t *hypercall)
++{
++ return HYPERVISOR_xen_version(hypercall->arg[0],
++ (void *)hypercall->arg[1]);
++}
++
++static int xenppc_privcmd_event_channel_op(privcmd_hypercall_t *hypercall)
++{
++ struct xencomm_handle *desc;
++ unsigned int argsize;
++ int ret;
++
++ switch (hypercall->arg[0]) {
++ case EVTCHNOP_alloc_unbound:
++ argsize = sizeof(evtchn_alloc_unbound_t);
++ break;
++
++ case EVTCHNOP_status:
++ argsize = sizeof(evtchn_status_t);
++ break;
++
++ default:
++ printk(KERN_ERR "%s: unknown EVTCHNOP (%ld)\n",
++ __func__, hypercall->arg[0]);
++ return -EINVAL;
++ }
++
++ desc = xencomm_map((void *)hypercall->arg[1], argsize);
++
++ if (desc == NULL)
++ return -ENOMEM;
++
++ ret = plpar_hcall_norets(XEN_MARK(hypercall->op), hypercall->arg[0],
++ desc);
++
++ xencomm_free(desc);
++ return ret;
++}
++
++static int xenppc_acmcmd_op(privcmd_hypercall_t *hypercall)
++{
++ xen_acmctl_t kern_op;
++ xen_acmctl_t __user *user_op = (xen_acmctl_t __user *)hypercall->arg[0];
++ void *op_desc;
++ void *desc = NULL, *desc2 = NULL, *desc3 = NULL, *desc4 = NULL;
++ int ret = 0;
++
++ if (copy_from_user(&kern_op, user_op, sizeof(xen_acmctl_t)))
++ return -EFAULT;
++
++ if (kern_op.interface_version != ACM_INTERFACE_VERSION) {
++ printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
++ kern_op.interface_version, ACM_INTERFACE_VERSION);
++ return -EACCES;
++ }
++
++ op_desc = xencomm_map(&kern_op, sizeof(xen_acmctl_t));
++ if (op_desc == NULL)
++ return -ENOMEM;
++
++ switch (kern_op.cmd) {
++ case ACMOP_setpolicy:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.setpolicy.pushcache),
++ kern_op.u.setpolicy.pushcache_size);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.setpolicy.pushcache,
++ desc);
++ break;
++ case ACMOP_getpolicy:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.getpolicy.pullcache),
++ kern_op.u.getpolicy.pullcache_size);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.getpolicy.pullcache,
++ desc);
++ break;
++ case ACMOP_dumpstats:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.dumpstats.pullcache),
++ kern_op.u.dumpstats.pullcache_size);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.dumpstats.pullcache,
++ desc);
++ break;
++ case ACMOP_getssid:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.getssid.ssidbuf),
++ kern_op.u.getssid.ssidbuf_size);
++
++ if (desc == NULL)
++ ret = -ENOMEM;
++
++ set_xen_guest_handle(kern_op.u.getssid.ssidbuf,
++ desc);
++ break;
++ case ACMOP_getdecision:
++ break;
++ case ACMOP_chgpolicy:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.change_policy.policy_pushcache),
++ kern_op.u.change_policy.policy_pushcache_size);
++ desc2 = xencomm_map(
++ xen_guest_handle(kern_op.u.change_policy.del_array),
++ kern_op.u.change_policy.delarray_size);
++ desc3 = xencomm_map(
++ xen_guest_handle(kern_op.u.change_policy.chg_array),
++ kern_op.u.change_policy.chgarray_size);
++ desc4 = xencomm_map(
++ xen_guest_handle(kern_op.u.change_policy.err_array),
++ kern_op.u.change_policy.errarray_size);
++
++ if (desc == NULL || desc2 == NULL ||
++ desc3 == NULL || desc4 == NULL) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ set_xen_guest_handle(kern_op.u.change_policy.policy_pushcache,
++ desc);
++ set_xen_guest_handle(kern_op.u.change_policy.del_array,
++ desc2);
++ set_xen_guest_handle(kern_op.u.change_policy.chg_array,
++ desc3);
++ set_xen_guest_handle(kern_op.u.change_policy.err_array,
++ desc4);
++ break;
++ case ACMOP_relabeldoms:
++ desc = xencomm_map(
++ xen_guest_handle(kern_op.u.relabel_doms.relabel_map),
++ kern_op.u.relabel_doms.relabel_map_size);
++ desc2 = xencomm_map(
++ xen_guest_handle(kern_op.u.relabel_doms.err_array),
++ kern_op.u.relabel_doms.errarray_size);
++
++ if (desc == NULL || desc2 == NULL) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ set_xen_guest_handle(kern_op.u.relabel_doms.relabel_map,
++ desc);
++ set_xen_guest_handle(kern_op.u.relabel_doms.err_array,
++ desc2);
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown/unsupported acmctl cmd %d\n",
++ __func__, kern_op.cmd);
++ return -ENOSYS;
++ }
++
++ if (ret)
++ goto out; /* error mapping the nested pointer */
++
++ ret = plpar_hcall_norets(XEN_MARK(hypercall->op),op_desc);
++
++ if (copy_to_user(user_op, &kern_op, sizeof(xen_acmctl_t)))
++ ret = -EFAULT;
++
++out:
++ xencomm_free(desc);
++ xencomm_free(desc2);
++ xencomm_free(desc3);
++ xencomm_free(desc4);
++ xencomm_free(op_desc);
++ return ret;
++}
++
++
++/* The PowerPC hypervisor runs in a separate address space from Linux
++ * kernel/userspace, i.e. real mode. We must therefore translate userspace
++ * pointers to something the hypervisor can make sense of. */
++int privcmd_hypercall(privcmd_hypercall_t *hypercall)
++{
++ switch (hypercall->op) {
++ case __HYPERVISOR_domctl:
++ return xenppc_privcmd_domctl(hypercall);
++ case __HYPERVISOR_sysctl:
++ return xenppc_privcmd_sysctl(hypercall);
++ case __HYPERVISOR_platform_op:
++ return xenppc_privcmd_platform_op(hypercall);
++ case __HYPERVISOR_memory_op:
++ return xenppc_privcmd_memory_op(hypercall);
++ case __HYPERVISOR_xen_version:
++ return xenppc_privcmd_version(hypercall);
++ case __HYPERVISOR_event_channel_op:
++ return xenppc_privcmd_event_channel_op(hypercall);
++ case __HYPERVISOR_acm_op:
++ return xenppc_acmcmd_op(hypercall);
++ default:
++ printk(KERN_ERR "%s: unknown hcall (%ld)\n", __func__, hypercall->op);
++ /* maybe we'll get lucky and the hcall needs no translation. */
++ return plpar_hcall_norets(XEN_MARK(hypercall->op),
++ hypercall->arg[0],
++ hypercall->arg[1],
++ hypercall->arg[2],
++ hypercall->arg[3],
++ hypercall->arg[4]);
++ }
++}
++
++int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
++{
++ int argsize;
++ const unsigned long hcall = __HYPERVISOR_vcpu_op;
++ struct xencomm_handle *desc;
++ int rc;
++
++ switch (cmd) {
++ case VCPUOP_initialise:
++ argsize = sizeof(vcpu_guest_context_t);
++ break;
++ case VCPUOP_up:
++ case VCPUOP_down:
++ case VCPUOP_is_up:
++ return plpar_hcall_norets(XEN_MARK(hcall), cmd, vcpuid, 0);
++
++ case VCPUOP_get_runstate_info:
++ argsize = sizeof (vcpu_runstate_info_t);
++ break;
++ default:
++ printk(KERN_ERR "%s: unknown version cmd %d\n", __func__, cmd);
++ return -ENOSYS;
++ }
++
++ desc = xencomm_map_no_alloc(extra_args, argsize);
++
++ if (desc == NULL)
++ return -EINVAL;
++
++ rc = plpar_hcall_norets(XEN_MARK(hcall), cmd, vcpuid, desc);
++
++ xencomm_free(desc);
++
++ return rc;
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/reboot.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/reboot.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/reboot.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/reboot.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,53 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/module.h>
++#include <xen/interface/xen.h>
++#include <xen/interface/io/console.h>
++#include <xen/xencons.h>
++#include <asm/hypervisor.h>
++#include <asm/machdep.h>
++
++static void domain_machine_restart(char * __unused)
++{
++ /* We really want to get pending console data out before we die. */
++ xencons_force_flush();
++ HYPERVISOR_shutdown(SHUTDOWN_reboot);
++}
++
++static void domain_machine_power_off(void)
++{
++ /* We really want to get pending console data out before we die. */
++ xencons_force_flush();
++ HYPERVISOR_shutdown(SHUTDOWN_poweroff);
++}
++
++void xen_reboot_init(struct machdep_calls *md)
++{
++ if (md != NULL) {
++ ppc_md.restart = md->restart;
++ ppc_md.power_off = md->power_off;
++ ppc_md.halt = md->halt;
++ } else {
++ ppc_md.restart = domain_machine_restart;
++ ppc_md.power_off = domain_machine_power_off;
++ ppc_md.halt = domain_machine_power_off;
++ }
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/setup.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/setup.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/setup.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/setup.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,336 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#define DEBUG
++#define CONFIG_SHARE_MPIC
++
++#include <linux/module.h>
++#include <linux/rwsem.h>
++#include <linux/delay.h>
++#include <linux/console.h>
++#include <xen/interface/xen.h>
++#include <xen/interface/sched.h>
++#include <xen/evtchn.h>
++#include <xen/features.h>
++#include <xen/xencons.h>
++#include <asm/udbg.h>
++#include <asm/pgtable.h>
++#include <asm/prom.h>
++#include <asm/iommu.h>
++#include <asm/mmu.h>
++#include <asm/abs_addr.h>
++#include <asm/machdep.h>
++#include <asm/hypervisor.h>
++#include <asm/time.h>
++#include <asm/pmc.h>
++#include "setup.h"
++
++#ifdef DEBUG
++#define DBG(fmt...) udbg_printf(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++/* Apperently on other arches this could be used before its defined,
++ * this should not be the case in PPC */
++shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)NULL;
++EXPORT_SYMBOL(HYPERVISOR_shared_info);
++
++/* Raw start-of-day parameters from the hypervisor. */
++static start_info_t xsi;
++start_info_t *xen_start_info;
++EXPORT_SYMBOL(xen_start_info);
++
++extern struct machdep_calls mach_maple_md;
++extern void maple_pci_init(void);
++
++static unsigned long foreign_mfn_flag;
++
++/* Must be called with &vma->vm_mm->mmap_sem locked for write */
++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 rc;
++
++ /* Set the MFN flag to tell Xen that this is not a PFN. */
++ printk("%s: mapping mfn 0x%lx (size 0x%lx) -> 0x%lx\n", __func__,
++ mfn, size, mfn | foreign_mfn_flag);
++ mfn = mfn | foreign_mfn_flag;
++
++ WARN_ON(!rwsem_is_locked(&vma->vm_mm->mmap_sem));
++ rc = remap_pfn_range(vma, address, mfn, size, prot);
++
++ return rc;
++}
++
++static void __init xen_fw_feature_init(void)
++{
++ DBG(" -> %s\n", __func__);
++
++ powerpc_firmware_features = 0;
++
++ powerpc_firmware_features |= FW_FEATURE_LPAR;
++ powerpc_firmware_features |= FW_FEATURE_TCE | FW_FEATURE_DABR;
++
++ printk(KERN_INFO "firmware_features = 0x%lx\n",
++ powerpc_firmware_features);
++
++ DBG(" <- %s\n", __func__);
++}
++
++/* if these were global then I could get them from the pseries/setup.c */
++static int pseries_set_dabr(unsigned long dabr)
++{
++ return plpar_hcall_norets(H_SET_DABR, dabr);
++}
++
++static int pseries_set_xdabr(unsigned long dabr)
++{
++ /* We want to catch accesses from kernel and userspace */
++ return plpar_hcall_norets(H_SET_XDABR, dabr,
++ H_DABRX_KERNEL | H_DABRX_USER);
++}
++
++/*
++ * Early initialization.
++ */
++static void __init xenppc_init_early(void)
++{
++ struct device_node *xen;
++
++ DBG(" -> %s\n", __func__);
++
++ xen = of_find_node_by_path("/xen");
++
++ xen_start_info = &xsi;
++
++ /* fill out start_info_t from devtree */
++ if ((char *)get_property(xen, "privileged", NULL))
++ xen_start_info->flags |= SIF_PRIVILEGED;
++ if ((char *)get_property(xen, "initdomain", NULL))
++ xen_start_info->flags |= SIF_INITDOMAIN;
++ xen_start_info->shared_info = *((u64 *)get_property(xen,
++ "shared-info", NULL));
++
++ /* only look for store and console for guest domains */
++ if (xen_start_info->flags == 0) {
++ struct device_node *console = of_find_node_by_path("/xen/console");
++ struct device_node *store = of_find_node_by_path("/xen/store");
++
++ xen_start_info->store_mfn = (*((u64 *)get_property(store,
++ "reg", NULL))) >> PAGE_SHIFT;
++ xen_start_info->store_evtchn = *((u32 *)get_property(store,
++ "interrupts", NULL));
++ xen_start_info->console.domU.mfn = (*((u64 *)get_property(console,
++ "reg", NULL))) >> PAGE_SHIFT;
++ xen_start_info->console.domU.evtchn = *((u32 *)get_property(console,
++ "interrupts", NULL));
++ }
++
++ HYPERVISOR_shared_info = __va(xen_start_info->shared_info);
++
++ udbg_init_xen();
++
++ DBG("xen_start_info at %p\n", xen_start_info);
++ DBG(" magic %s\n", xen_start_info->magic);
++ DBG(" flags %x\n", xen_start_info->flags);
++ DBG(" shared_info %lx, %p\n",
++ xen_start_info->shared_info, HYPERVISOR_shared_info);
++ DBG(" store_mfn %llx\n", xen_start_info->store_mfn);
++ DBG(" store_evtchn %x\n", xen_start_info->store_evtchn);
++ DBG(" console_mfn %llx\n", xen_start_info->console.domU.mfn);
++ DBG(" console_evtchn %x\n", xen_start_info->console.domU.evtchn);
++
++ xen_setup_time(&mach_maple_md);
++
++ add_preferred_console("xvc", 0, NULL);
++
++ if (get_property(xen, "power-control", NULL))
++ xen_reboot_init(&mach_maple_md);
++ else
++ xen_reboot_init(NULL);
++
++ if (is_initial_xendomain()) {
++ u64 *mfnflag = (u64 *)get_property(xen, "mfn-flag", NULL);
++ if (mfnflag) {
++ foreign_mfn_flag = (1UL << mfnflag[0]);
++ printk("OF: using 0x%lx as foreign mfn flag\n", foreign_mfn_flag);
++ } else
++ printk("OF: /xen/mfn-base must be present it build guests\n");
++ }
++
++ /* get the domain features */
++ setup_xen_features();
++
++ DBG("Hello World I'm Maple Xen-LPAR!\n");
++
++ if (firmware_has_feature(FW_FEATURE_DABR))
++ ppc_md.set_dabr = pseries_set_dabr;
++ else if (firmware_has_feature(FW_FEATURE_XDABR))
++ ppc_md.set_dabr = pseries_set_xdabr;
++
++ iommu_init_early_pSeries();
++
++ DBG(" <- %s\n", __func__);
++}
++
++/*
++ * this interface is limiting
++ */
++static int running_on_xen;
++int is_running_on_xen(void)
++{
++ return running_on_xen;
++}
++EXPORT_SYMBOL(is_running_on_xen);
++
++static void xenppc_power_save(void)
++{
++ /* SCHEDOP_yield could immediately return. Instead, we
++ * want to idle in the Xen idle domain, so use
++ * SCHEDOP_block with a one-shot timer. */
++ /* XXX do tickless stuff here. See
++ * linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c */
++ u64 now_ns = tb_to_ns(get_tb());
++ u64 offset_ns = jiffies_to_ns(1);
++ int rc;
++
++ rc = HYPERVISOR_set_timer_op(now_ns + offset_ns);
++ BUG_ON(rc != 0);
++
++ HYPERVISOR_sched_op(SCHEDOP_block, NULL);
++}
++
++void __init xenppc_setup_arch(void)
++{
++ /* init to some ~sane value until calibrate_delay() runs */
++ loops_per_jiffy = 50000000;
++
++ /* Lookup PCI hosts */
++ if (is_initial_xendomain())
++ maple_pci_init();
++
++#ifdef CONFIG_DUMMY_CONSOLE
++ conswitchp = &dummy_con;
++#endif
++#ifdef CONFIG_SMP
++ /* let them fly */
++ xen_setup_smp();
++#endif
++
++ printk(KERN_INFO "Using Xen idle loop\n");
++}
++
++static int __init xen_probe_flat_dt(unsigned long node,
++ const char *uname, int depth,
++ void *data)
++{
++ if (depth != 1)
++ return 0;
++ if (strcmp(uname, "xen") != 0)
++ return 0;
++
++ running_on_xen = 1;
++
++ return 1;
++}
++
++/*
++ * Called very early, MMU is off, device-tree isn't unflattened
++ */
++/* forward ref */
++struct machdep_calls __initdata xen_md;
++static int __init xenppc_probe(void)
++{
++ of_scan_flat_dt(xen_probe_flat_dt, NULL);
++
++ if (!running_on_xen)
++ return 0;
++
++ xen_fw_feature_init();
++
++ hpte_init_lpar();
++
++ return 1;
++}
++
++static void __init xenppc_progress(char *s, unsigned short hex)
++{
++ printk("*** %04x : %s\n", hex, s ? s : "");
++}
++
++unsigned int xenppc_get_irq(struct pt_regs *regs)
++{
++ evtchn_do_upcall(regs);
++ /* evtchn_do_upcall() handles all pending event channels directly, so there
++ * is nothing for do_IRQ() to do.
++ * XXX This means we aren't using IRQ stacks. */
++ return NO_IRQ;
++}
++
++static void xenppc_enable_pmcs(void)
++{
++ unsigned long set, reset;
++
++ power4_enable_pmcs();
++
++ set = 1UL << 63;
++ reset = 0;
++ plpar_hcall_norets(H_PERFMON, set, reset);
++}
++
++#ifdef CONFIG_KEXEC
++void xen_machine_kexec(struct kimage *image)
++{
++ panic("%s(%p): called\n", __func__, image);
++}
++
++int xen_machine_kexec_prepare(struct kimage *image)
++{
++ panic("%s(%p): called\n", __func__, image);
++}
++
++void xen_machine_crash_shutdown(struct pt_regs *regs)
++{
++ panic("%s(%p): called\n", __func__, regs);
++}
++#endif
++
++define_machine(xen) {
++ .name = "Xen-Maple",
++ .probe = xenppc_probe,
++ .setup_arch = xenppc_setup_arch,
++ .init_early = xenppc_init_early,
++ .init_IRQ = xen_init_IRQ,
++ .get_irq = xenppc_get_irq,
++ .calibrate_decr = generic_calibrate_decr,
++ .progress = xenppc_progress,
++ .power_save = xenppc_power_save,
++ .enable_pmcs = xenppc_enable_pmcs,
++#ifdef CONFIG_KEXEC
++ .machine_kexec = xen_machine_kexec,
++ .machine_kexec_prepare = xen_machine_kexec_prepare,
++ .machine_crash_shutdown = xen_machine_crash_shutdown,
++#endif
++};
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/setup.h linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/setup.h
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/setup.h 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/setup.h 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,47 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <asm/machdep.h>
++#include <asm/time.h>
++
++extern void evtchn_init_IRQ(void);
++extern void xen_init_IRQ(void);
++extern void xen_reboot_init(struct machdep_calls *);
++extern void xen_maple_init_IRQ(void);
++extern unsigned int xen_get_irq(struct pt_regs *regs);
++
++static inline u64 tb_to_ns(u64 tb)
++{
++ if (likely(tb_ticks_per_sec)) {
++ return tb * (1000000000UL / tb_ticks_per_sec);
++ }
++ return 0;
++}
++
++static inline u64 jiffies_to_ns(unsigned long j)
++{
++ return j * (1000000000UL / HZ);
++}
++
++extern struct page *alloc_foreign_page(void);
++extern void free_foreign_page(struct page *page);
++
++extern void __init xen_setup_time(struct machdep_calls *host_md);
++extern void xen_setup_smp(void);
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/smp.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/smp.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/smp.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/smp.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,444 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/kernel.h>
++#include <linux/config.h>
++#include <linux/bootmem.h>
++#include <linux/irq.h>
++#include <linux/smp.h>
++#include <xen/interface/xen.h>
++#include <xen/interface/vcpu.h>
++#include <xen/evtchn.h>
++#include <asm/prom.h>
++#include <asm/udbg.h>
++#include <asm/hypervisor.h>
++#include "setup.h"
++
++#undef DEBUG
++
++#ifdef DEBUG
++#define DBG(fmt...) printk(KERN_EMERG fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++static inline void *xen_of_alloc(ulong size)
++{
++ if (mem_init_done)
++ return kmalloc(size, GFP_KERNEL);
++ return alloc_bootmem(size);
++}
++static inline void xen_of_free(void *ptr)
++{
++ /* if this happens with the boot allocator then we are screwed */
++ BUG_ON(!mem_init_done);
++ kfree(ptr);
++}
++
++static struct property *dup_prop(struct property *op)
++{
++ struct property *np;
++ void *p;
++ ulong sz;
++
++
++ /* allocate everything in one go in case it fails */
++ sz = sizeof (*np); /* prop node */
++ sz += strlen(op->name) + 1; /* prop name */
++ sz += op->length; /* prop value */
++
++ p = xen_of_alloc(sz);
++ if (!p)
++ return NULL;
++ memset(p, 0, sz);
++
++ /* prop node first */
++ np = p;
++ p += sizeof (*np);
++
++ /* value next becuase we want it aligned */
++ np->value = p;
++ p += op->length;
++
++ /* name */
++ np->name = p;
++
++ /* copy it all */
++ strcpy(np->name, op->name);
++ np->length = op->length;
++ memcpy(np->value, op->value, np->length);
++
++ return np;
++}
++
++static int dup_properties(struct device_node *dst, struct device_node *src)
++{
++ struct property *op;
++ struct property *np;
++ struct property *lp;
++ int rc = 0;
++
++ DBG("%s: duping to new cpu node: %s\n", __func__, dst->full_name);
++
++ np = lp = NULL;
++ for (op = src->properties; op != 0; op = op->next) {
++ lp = np;
++ np = dup_prop(op);
++ if (!np)
++ break;
++
++ prom_add_property(dst, np);
++ }
++
++ if (!np) {
++ DBG("%s: FAILED duping: %s\n", __func__, dst->full_name);
++ /* we could not allocate enuff so free what we have
++ * allocated */
++ rc = -ENOMEM;
++ for (op = dst->properties; lp && op != lp; op = op->next)
++ xen_of_free(op);
++ }
++
++ return rc;
++}
++
++/* returns added device node so it can be added to procfs in the case
++ * of hotpluging */
++static struct device_node *xen_add_vcpu_node(struct device_node *boot_cpu,
++ uint cpu)
++{
++ struct device_node *new_cpu;
++ struct property *pp;
++ void *p;
++ int sz;
++ int type_sz;
++ int name_sz;
++
++ DBG("%s: boot cpu: %s\n", __func__, boot_cpu->full_name);
++
++ /* allocate in one shot in case we fail */
++ name_sz = strlen(boot_cpu->name) + 1;
++ type_sz = strlen(boot_cpu->type) + 1;
++
++ sz = sizeof (*new_cpu); /* the node */
++ sz += strlen(boot_cpu->full_name) + 3; /* full_name */
++ sz += name_sz; /* name */
++ sz += type_sz; /* type */
++
++ p = xen_of_alloc(sz);
++ if (!p)
++ return NULL;
++ memset(p, 0, sz);
++
++ /* the node */
++ new_cpu = p;
++ p += sizeof (*new_cpu);
++
++ /* name */
++ new_cpu->name = p;
++ strcpy(new_cpu->name, boot_cpu->name);
++ p += name_sz;
++
++ /* type */
++ new_cpu->type = p;
++ strcpy(new_cpu->type, boot_cpu->type);
++ p += type_sz;
++
++ /* full_name */
++ new_cpu->full_name = p;
++
++ /* assemble new full_name */
++ pp = of_find_property(boot_cpu, "name", NULL);
++ if (!pp)
++ panic("%s: no name prop\n", __func__);
++
++ DBG("%s: name is: %s = %s\n", __func__, pp->name, pp->value);
++ sprintf(new_cpu->full_name, "/cpus/%s@%u", pp->value, cpu);
++
++ if (dup_properties(new_cpu, boot_cpu)) {
++ xen_of_free(new_cpu);
++ return NULL;
++ }
++
++ /* fixup reg property */
++ DBG("%s: updating reg: %d\n", __func__, cpu);
++ pp = of_find_property(new_cpu, "reg", NULL);
++ if (!pp)
++ panic("%s: no reg prop\n", __func__);
++ *(int *)pp->value = cpu;
++
++ if (mem_init_done)
++ OF_MARK_DYNAMIC(new_cpu);
++
++ kref_init(&new_cpu->kref);
++
++ /* insert the node */
++ new_cpu->parent = of_get_parent(boot_cpu);
++ of_attach_node(new_cpu);
++ of_node_put(new_cpu->parent);
++
++ return new_cpu;
++}
++
++static void cpu_initialize_context(unsigned int vcpu, ulong entry)
++{
++ vcpu_guest_context_t ctxt;
++
++ memset(&ctxt.user_regs, 0x55, sizeof(ctxt.user_regs));
++
++ ctxt.user_regs.pc = entry;
++ ctxt.user_regs.msr = 0;
++ ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */
++ ctxt.user_regs.gprs[3] = vcpu;
++
++ /* XXX verify this *** */
++ /* There is a buggy kernel that does not zero the "local_paca", so
++ * we must make sure this register is 0 */
++ ctxt.user_regs.gprs[13] = 0;
++
++ DBG("%s: initializing vcpu: %d\n", __func__, vcpu);
++
++ if (HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt))
++ panic("%s: VCPUOP_initialise failed, vcpu: %d\n",
++ __func__, vcpu);
++
++}
++
++static int xen_start_vcpu(uint vcpu, ulong entry)
++{
++ DBG("%s: starting vcpu: %d\n", __func__, vcpu);
++
++ cpu_initialize_context(vcpu, entry);
++
++ DBG("%s: Spinning up vcpu: %d\n", __func__, vcpu);
++ return HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL);
++}
++
++extern void __secondary_hold(void);
++extern unsigned long __secondary_hold_spinloop;
++extern unsigned long __secondary_hold_acknowledge;
++
++static void xen_boot_secondary_vcpus(void)
++{
++ int vcpu;
++ int rc;
++ const unsigned long mark = (unsigned long)-1;
++ unsigned long *spinloop = &__secondary_hold_spinloop;
++ unsigned long *acknowledge = &__secondary_hold_acknowledge;
++#ifdef CONFIG_PPC64
++ /* __secondary_hold is actually a descriptor, not the text address */
++ unsigned long secondary_hold = __pa(*(unsigned long *)__secondary_hold);
++#else
++ unsigned long secondary_hold = __pa(__secondary_hold);
++#endif
++ struct device_node *boot_cpu;
++
++ DBG("%s: finding CPU node\n", __func__);
++ boot_cpu = of_find_node_by_type(NULL, "cpu");
++ if (!boot_cpu)
++ panic("%s: Cannot find Booting CPU node\n", __func__);
++
++ /* Set the common spinloop variable, so all of the secondary cpus
++ * will block when they are awakened from their OF spinloop.
++ * This must occur for both SMP and non SMP kernels, since OF will
++ * be trashed when we move the kernel.
++ */
++ *spinloop = 0;
++
++ DBG("%s: Searching for all vcpu numbers > 0\n", __func__);
++ /* try and start as many as we can */
++ for (vcpu = 1; vcpu < NR_CPUS; vcpu++) {
++ int i;
++
++ rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, vcpu, NULL);
++ if (rc < 0)
++ continue;
++
++ DBG("%s: Found vcpu: %d\n", __func__, vcpu);
++ /* Init the acknowledge var which will be reset by
++ * the secondary cpu when it awakens from its OF
++ * spinloop.
++ */
++ *acknowledge = mark;
++
++ DBG("%s: Starting vcpu: %d at pc: 0x%lx\n", __func__,
++ vcpu, secondary_hold);
++ rc = xen_start_vcpu(vcpu, secondary_hold);
++ if (rc)
++ panic("%s: xen_start_vpcu() failed\n", __func__);
++
++
++ DBG("%s: Waiting for ACK on vcpu: %d\n", __func__, vcpu);
++ for (i = 0; (i < 100000000) && (*acknowledge == mark); i++)
++ mb();
++
++ if (*acknowledge == vcpu)
++ DBG("%s: Recieved for ACK on vcpu: %d\n",
++ __func__, vcpu);
++
++ xen_add_vcpu_node(boot_cpu, vcpu);
++
++ cpu_set(vcpu, cpu_present_map);
++ set_hard_smp_processor_id(vcpu, vcpu);
++ }
++ of_node_put(boot_cpu);
++ DBG("%s: end...\n", __func__);
++}
++
++static int __init smp_xen_probe(void)
++{
++ return cpus_weight(cpu_present_map);
++}
++
++static irqreturn_t xen_ppc_msg_reschedule(int irq, void *dev_id,
++ struct pt_regs *regs)
++{
++ smp_message_recv(PPC_MSG_RESCHEDULE, regs);
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t xen_ppc_msg_call_function(int irq, void *dev_id,
++ struct pt_regs *regs)
++{
++ smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t xen_ppc_msg_debugger_break(int irq, void *dev_id,
++ struct pt_regs *regs)
++{
++ smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
++ return IRQ_HANDLED;
++}
++
++struct message {
++ irqreturn_t (*f)(int, void *, struct pt_regs *);
++ int num;
++ char *name;
++};
++static struct message ipi_msgs[] = {
++ {
++ .num = PPC_MSG_RESCHEDULE,
++ .f = xen_ppc_msg_reschedule,
++ .name = "IPI-resched"
++ },
++ {
++ .num = PPC_MSG_CALL_FUNCTION,
++ .f = xen_ppc_msg_call_function,
++ .name = "IPI-function"
++ },
++ {
++ .num = PPC_MSG_DEBUGGER_BREAK,
++ .f = xen_ppc_msg_debugger_break,
++ .name = "IPI-debug"
++ }
++};
++
++DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
++
++static void __devinit smp_xen_setup_cpu(int cpu)
++{
++ int irq;
++ int i;
++ const int nr_ipis = ARRAY_SIZE(__get_cpu_var(ipi_to_irq));
++
++ /* big scary include web could mess with our values, so we
++ * make sure they are sane */
++ BUG_ON(ARRAY_SIZE(ipi_msgs) > nr_ipis);
++
++ for (i = 0; i < ARRAY_SIZE(ipi_msgs); i++) {
++ BUG_ON(ipi_msgs[i].num >= nr_ipis);
++
++ irq = bind_ipi_to_irqhandler(ipi_msgs[i].num,
++ cpu,
++ ipi_msgs[i].f,
++ SA_INTERRUPT,
++ ipi_msgs[i].name,
++ NULL);
++ BUG_ON(irq < 0);
++ per_cpu(ipi_to_irq, cpu)[ipi_msgs[i].num] = irq;
++ DBG("%s: cpu: %d vector :%d irq: %d\n",
++ __func__, cpu, ipi_msgs[i].num, irq);
++ }
++}
++
++static inline void send_IPI_one(unsigned int cpu, int vector)
++{
++ int irq;
++
++ irq = per_cpu(ipi_to_irq, cpu)[vector];
++ BUG_ON(irq < 0);
++
++ DBG("%s: cpu: %d vector :%d irq: %d!\n",
++ __func__, cpu, vector, irq);
++ DBG("%s: per_cpu[%p]: %d %d %d %d\n",
++ __func__, per_cpu(ipi_to_irq, cpu),
++ per_cpu(ipi_to_irq, cpu)[0],
++ per_cpu(ipi_to_irq, cpu)[1],
++ per_cpu(ipi_to_irq, cpu)[2],
++ per_cpu(ipi_to_irq, cpu)[3]);
++
++ notify_remote_via_irq(irq);
++}
++
++static void smp_xen_message_pass(int target, int msg)
++{
++ int cpu;
++
++ switch (msg) {
++ case PPC_MSG_RESCHEDULE:
++ case PPC_MSG_CALL_FUNCTION:
++ case PPC_MSG_DEBUGGER_BREAK:
++ break;
++ default:
++ panic("SMP %d: smp_message_pass: unknown msg %d\n",
++ smp_processor_id(), msg);
++ return;
++ }
++ switch (target) {
++ case MSG_ALL:
++ case MSG_ALL_BUT_SELF:
++ for_each_online_cpu(cpu) {
++ if (target == MSG_ALL_BUT_SELF &&
++ cpu == smp_processor_id())
++ continue;
++ send_IPI_one(cpu, msg);
++ }
++ break;
++ default:
++ send_IPI_one(target, msg);
++ break;
++ }
++}
++
++static struct smp_ops_t xen_smp_ops = {
++ .probe = smp_xen_probe,
++ .message_pass = smp_xen_message_pass,
++ .kick_cpu = smp_generic_kick_cpu,
++ .setup_cpu = smp_xen_setup_cpu,
++};
++
++void xen_setup_smp(void)
++{
++ smp_ops = &xen_smp_ops;
++
++ xen_boot_secondary_vcpus();
++ smp_release_cpus();
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/time.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/time.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/time.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/time.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,114 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/module.h>
++#include <linux/time.h>
++#include <linux/rtc.h>
++#include <asm/hypervisor.h>
++#include <asm/machdep.h>
++#include <asm/time.h>
++#include <asm/udbg.h>
++
++#ifdef DEBUG
++#define DBG(fmt...) printk(fmt)
++#else
++#define DBG(fmt...)
++#endif
++
++void time_resume(void)
++{
++ snapshot_timebase();
++}
++
++static inline ulong time_from_shared(void)
++{
++ ulong t;
++
++ DBG("tb_freq: %ld\n", ppc_tb_freq);
++
++ t = mftb() - HYPERVISOR_shared_info->arch.boot_timebase;
++ t /= ppc_tb_freq;
++ t += HYPERVISOR_shared_info->wc_sec;
++
++ return t;
++}
++
++static void (*host_md_get_rtc_time)(struct rtc_time *tm);
++static void xen_get_rtc_time(struct rtc_time *tm)
++{
++ if (is_initial_xendomain()) {
++ host_md_get_rtc_time(tm);
++ return;
++ } else {
++ ulong t;
++
++ t = time_from_shared();
++ to_tm(t, tm);
++ }
++}
++
++static int (*host_md_set_rtc_time)(struct rtc_time *tm);
++static int xen_set_rtc_time(struct rtc_time *tm)
++{
++ ulong sec;
++
++ if (is_initial_xendomain()) {
++ host_md_set_rtc_time(tm);
++ return 0;
++ }
++
++ sec = mktime(tm->tm_year, tm->tm_mon, tm->tm_mday,
++ tm->tm_hour, tm->tm_min, tm->tm_sec);
++
++ HYPERVISOR_shared_info->wc_sec = sec;
++ HYPERVISOR_shared_info->arch.boot_timebase = mftb();
++
++ return 0;
++}
++
++static unsigned long (*host_md_get_boot_time)(void);
++static unsigned long __init xen_get_boot_time(void)
++{
++ ulong t;
++
++ if (is_initial_xendomain()) {
++ t = host_md_get_boot_time();
++
++ HYPERVISOR_shared_info->wc_sec = t;
++ HYPERVISOR_shared_info->arch.boot_timebase = mftb();
++ DBG("%s: time: %ld\n", __func__, t);
++ } else {
++ t = time_from_shared();
++ DBG("%s: %ld\n", __func__, t);
++ }
++ return t;
++}
++
++void __init xen_setup_time(struct machdep_calls *host_md)
++{
++ ppc_md.get_boot_time = xen_get_boot_time;
++ host_md_get_boot_time = host_md->get_boot_time;
++
++ ppc_md.set_rtc_time = xen_set_rtc_time;
++ host_md_set_rtc_time = host_md->set_rtc_time;
++
++ ppc_md.get_rtc_time = xen_get_rtc_time;
++ host_md_get_rtc_time = host_md->get_rtc_time;
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/udbg_xen.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/udbg_xen.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/udbg_xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/udbg_xen.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,164 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/module.h>
++#include <xen/interface/xen.h>
++#include <xen/interface/io/console.h>
++#include <xen/evtchn.h>
++#include <asm/udbg.h>
++#include <asm/hypervisor.h>
++#include "setup.h"
++
++static void udbg_xen_wait(void)
++{
++ evtchn_port_t port = 0;
++
++ if (xen_start_info) {
++ port = xen_start_info->console.domU.evtchn;
++ clear_evtchn(port);
++ }
++ HYPERVISOR_poll(&port, 1, 10);
++}
++
++static int udbg_getc_xen(void)
++{
++ int ch;
++ for (;;) {
++ ch = udbg_getc_poll();
++ if (ch == -1) {
++ udbg_xen_wait();
++ } else {
++ return ch;
++ }
++ }
++}
++
++static void udbg_putc_dom0_xen(char c)
++{
++ unsigned long rc;
++
++ if (c == '\n')
++ udbg_putc_dom0_xen('\r');
++
++ do {
++ rc = HYPERVISOR_console_io(CONSOLEIO_write, 1, &c);
++ } while (rc < 0);
++}
++
++/* Buffered chars getc */
++static long inbuflen;
++static char inbuf[128]; /* Xen serial ring buffer */
++
++static int udbg_getc_poll_dom0_xen(void)
++{
++ /* The interface is tricky because it may return many chars.
++ * We save them statically for future calls to udbg_getc().
++ */
++ char ch, *buf = (char *)inbuf;
++ int i;
++
++ if (inbuflen == 0) {
++ /* get some more chars. */
++ inbuflen = HYPERVISOR_console_io(CONSOLEIO_read,
++ sizeof(inbuf), buf);
++ }
++
++ if (inbuflen == 0)
++ return -1;
++
++ ch = buf[0];
++ for (i = 1; i < inbuflen; i++) /* shuffle them down. */
++ buf[i-1] = buf[i];
++ inbuflen--;
++
++ return ch;
++}
++
++static struct xencons_interface *intf;
++
++static void udbg_putc_domu_xen(char c)
++{
++ XENCONS_RING_IDX cons, prod;
++
++ if (c == '\n')
++ udbg_putc_domu_xen('\r');
++
++ cons = intf->out_cons;
++ prod = intf->out_prod;
++ mb();
++
++ if ((prod - cons) < sizeof(intf->out))
++ intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = c;
++
++ wmb();
++ intf->out_prod = prod;
++
++ if (xen_start_info)
++ notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
++}
++
++static int udbg_getc_poll_domu_xen(void)
++{
++ XENCONS_RING_IDX cons, prod;
++ int c;
++
++ mb();
++ cons = intf->in_cons;
++ prod = intf->in_prod;
++ BUG_ON((prod - cons) > sizeof(intf->in));
++
++ if (cons == prod)
++ return -1;
++
++ c = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
++ wmb();
++ intf->in_cons = cons;
++
++ if (xen_start_info)
++ notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
++
++ return c;
++}
++
++void udbg_init_xen(void)
++{
++ ulong __console_mfn = 0;
++
++ if (xen_start_info) {
++ /* we can find out where everything is */
++ if (!(xen_start_info->flags & SIF_INITDOMAIN))
++ __console_mfn = xen_start_info->console.domU.mfn;
++ } else {
++ /* VERY early printf */
++#ifdef CONFIG_PPC_EARLY_DEBUG_XEN_DOMU
++ __console_mfn = 0x3ffdUL;
++#endif
++ }
++
++ udbg_getc = udbg_getc_xen;
++ if (__console_mfn == 0) {
++ udbg_putc = udbg_putc_dom0_xen;
++ udbg_getc_poll = udbg_getc_poll_dom0_xen;
++ } else {
++ udbg_putc = udbg_putc_domu_xen;
++ udbg_getc_poll = udbg_getc_poll_domu_xen;
++ intf = (struct xencons_interface *)mfn_to_virt(__console_mfn);
++ }
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/util.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/util.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/util.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/util.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,70 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++#include <linux/config.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <asm/uaccess.h>
++#include <xen/driver_util.h>
++#include "setup.h"
++
++struct vm_struct *alloc_vm_area(unsigned long size)
++{
++ struct vm_struct *area;
++ struct page *page;
++
++ page = alloc_foreign_page();
++ if (page == NULL) {
++ BUG();
++ return NULL;
++ }
++
++ area = kmalloc(sizeof(*area), GFP_KERNEL);
++ if (area != NULL) {
++ area->flags = VM_MAP;//XXX
++ area->addr = pfn_to_kaddr(page_to_pfn(page));
++ area->size = size;
++ area->pages = NULL; //XXX
++ area->nr_pages = size >> PAGE_SHIFT;
++ area->phys_addr = 0;
++ }
++ return area;
++}
++EXPORT_SYMBOL_GPL(alloc_vm_area);
++
++void free_vm_area(struct vm_struct *area)
++{
++ free_foreign_page(virt_to_page(area->addr));
++ kfree(area);
++}
++EXPORT_SYMBOL_GPL(free_vm_area);
++
++void lock_vm_area(struct vm_struct *area)
++{
++ preempt_disable();
++}
++
++void unlock_vm_area(struct vm_struct *area)
++{
++ preempt_enable();
++}
++EXPORT_SYMBOL_GPL(unlock_vm_area);
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/xen_guest.S linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/xen_guest.S
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/xen_guest.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/xen_guest.S 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,27 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
++ */
++
++ .section __xen_guest
++ .ascii "GUEST_OS=linux"
++ .ascii ",GUEST_VER=xen-3.0"
++ .ascii ",XEN_VER=xen-3.0"
++ .ascii ",VIRT_BASE=0xC000000000000000"
++ .ascii ",LOADER=generic"
++ .byte 0
+diff -rpuN linux-2.6.18.8/arch/powerpc/platforms/xen/xencomm.c linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/xencomm.c
+--- linux-2.6.18.8/arch/powerpc/platforms/xen/xencomm.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/platforms/xen/xencomm.c 2008-02-15 16:21:53.000000000 -0800
+@@ -0,0 +1,54 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * Copyright (C) IBM Corp. 2006
++ *
++ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <asm/page.h>
++#include <asm/current.h>
++#include <xen/interface/arch-powerpc.h>
++#include <xen/xencomm.h>
++
++/* translate virtual address to physical address */
++unsigned long xencomm_vtop(unsigned long vaddr)
++{
++ struct page *page;
++ struct vm_area_struct *vma;
++
++ /* NULL is NULL */
++ if (vaddr == 0)
++ return 0;
++
++ if (is_kernel_addr(vaddr))
++ return __pa(vaddr);
++
++ /* XXX double-check (lack of) locking */
++ vma = find_extend_vma(current->mm, vaddr);
++ BUG_ON(!vma);
++ if (!vma)
++ return ~0UL;
++
++ page = follow_page(vma, vaddr, 0);
++ BUG_ON(!page);
++ if (!page)
++ return ~0UL;
++
++ return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
++}
+diff -rpuN linux-2.6.18.8/arch/powerpc/sysdev/mpic.c linux-2.6.18-xen-3.2.0/arch/powerpc/sysdev/mpic.c
+--- linux-2.6.18.8/arch/powerpc/sysdev/mpic.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/sysdev/mpic.c 2008-02-15 16:21:53.000000000 -0800
+@@ -765,6 +765,9 @@ static int mpic_host_map(struct irq_host
+ else if (hw >= MPIC_VEC_IPI_0) {
+ WARN_ON(!(mpic->flags & MPIC_PRIMARY));
+
++ if (mpic->flags & MPIC_SKIP_IPI_INIT)
++ return 0;
++
+ DBG("mpic: mapping as IPI\n");
+ set_irq_chip_data(virq, mpic);
+ set_irq_chip_and_handler(virq, &mpic->hc_ipi,
+@@ -1019,6 +1022,9 @@ void __init mpic_init(struct mpic *mpic)
+ (MPIC_VEC_TIMER_0 + i));
+ }
+
++ if (mpic->flags & MPIC_SKIP_IPI_INIT)
++ goto ipi_bailout;
++
+ /* Initialize IPIs to our reserved vectors and mark them disabled for now */
+ mpic_test_broken_ipi(mpic);
+ for (i = 0; i < 4; i++) {
+@@ -1028,6 +1034,7 @@ void __init mpic_init(struct mpic *mpic)
+ (MPIC_VEC_IPI_0 + i));
+ }
+
++ipi_bailout:
+ /* Initialize interrupt sources */
+ if (mpic->irq_count == 0)
+ mpic->irq_count = mpic->num_sources;
+diff -rpuN linux-2.6.18.8/arch/powerpc/xmon/xmon.c linux-2.6.18-xen-3.2.0/arch/powerpc/xmon/xmon.c
+--- linux-2.6.18.8/arch/powerpc/xmon/xmon.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/powerpc/xmon/xmon.c 2008-02-15 16:21:53.000000000 -0800
+@@ -752,6 +752,9 @@ cmds(struct pt_regs *excp)
+ cmd = inchar();
+ }
+ switch (cmd) {
++ case 'A':
++ asm volatile(".long 0x200;nop");
++ break;
+ case 'm':
+ cmd = inchar();
+ switch (cmd) {
+diff -rpuN linux-2.6.18.8/arch/x86_64/Kconfig linux-2.6.18-xen-3.2.0/arch/x86_64/Kconfig
+--- linux-2.6.18.8/arch/x86_64/Kconfig 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/Kconfig 2008-02-15 16:21:55.000000000 -0800
+@@ -135,6 +135,23 @@ config GENERIC_CPU
endchoice
+config X86_64_XEN
+ bool "Enable Xen compatible kernel"
++ select XEN
+ select SWIOTLB
+ help
+ This option will compile a kernel compatible with Xen hypervisor
@@ -31470,7 +39304,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
#
# Define implied options from the CPU selection here
#
-@@ -155,6 +171,7 @@ config X86_INTERNODE_CACHE_BYTES
+@@ -155,6 +172,7 @@ config X86_INTERNODE_CACHE_BYTES
config X86_TSC
bool
@@ -31478,7 +39312,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default y
config X86_GOOD_APIC
-@@ -197,7 +214,7 @@ config X86_CPUID
+@@ -197,7 +215,7 @@ config X86_CPUID
config X86_HT
bool
@@ -31487,18 +39321,18 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default y
config MATH_EMULATION
-@@ -211,14 +228,22 @@ config EISA
+@@ -211,14 +229,22 @@ config EISA
config X86_IO_APIC
bool
+ depends !XEN_UNPRIVILEGED_GUEST
- default y
-
++ default y
++
+config X86_XEN_GENAPIC
+ bool
-+ depends X86_64_XEN
-+ default XEN_PRIVILEGED_GUEST || SMP
-+
++ depends on X86_64_XEN
+ default y
+
config X86_LOCAL_APIC
bool
+ depends !XEN_UNPRIVILEGED_GUEST
@@ -31510,7 +39344,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
---help---
On Intel P6 family processors (Pentium Pro, Pentium II and later)
the Memory Type Range Registers (MTRRs) may be used to control
-@@ -259,7 +284,7 @@ config SMP
+@@ -259,7 +285,7 @@ config SMP
config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
@@ -31519,7 +39353,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default n
help
SMT scheduler support improves the CPU scheduler's decision making
-@@ -269,7 +294,7 @@ config SCHED_SMT
+@@ -269,7 +295,7 @@ config SCHED_SMT
config SCHED_MC
bool "Multi-core scheduler support"
@@ -31528,7 +39362,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default y
help
Multi-core scheduler support improves the CPU scheduler's decision
-@@ -280,7 +305,7 @@ source "kernel/Kconfig.preempt"
+@@ -280,7 +306,7 @@ source "kernel/Kconfig.preempt"
config NUMA
bool "Non Uniform Memory Access (NUMA) Support"
@@ -31537,7 +39371,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
help
Enable NUMA (Non Uniform Memory Access) support. The kernel
will try to allocate memory used by a CPU on the local memory
-@@ -341,7 +366,7 @@ config ARCH_DISCONTIGMEM_DEFAULT
+@@ -341,7 +367,7 @@ config ARCH_DISCONTIGMEM_DEFAULT
config ARCH_SPARSEMEM_ENABLE
def_bool y
@@ -31546,7 +39380,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
config ARCH_MEMORY_PROBE
def_bool y
-@@ -365,6 +390,7 @@ config NR_CPUS
+@@ -365,6 +391,7 @@ config NR_CPUS
int "Maximum number of CPUs (2-256)"
range 2 255
depends on SMP
@@ -31554,7 +39388,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default "8"
help
This allows you to specify the maximum number of CPUs which this
-@@ -387,6 +413,7 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
+@@ -387,6 +414,7 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
config HPET_TIMER
bool
@@ -31562,7 +39396,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default y
help
Use the IA-PC HPET (High Precision Event Timer) to manage
-@@ -407,7 +434,7 @@ config IOMMU
+@@ -407,7 +435,7 @@ config IOMMU
default y
select SWIOTLB
select AGP
@@ -31571,7 +39405,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
help
Support for full DMA access of devices with 32bit memory access only
on systems with more than 3GB. This is usually needed for USB,
-@@ -423,7 +450,7 @@ config CALGARY_IOMMU
+@@ -423,7 +451,7 @@ config CALGARY_IOMMU
bool "IBM Calgary IOMMU support"
default y
select SWIOTLB
@@ -31580,7 +39414,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
help
Support for hardware IOMMUs in IBM's xSeries x366 and x460
systems. Needed to run systems with more than 3GB of memory
-@@ -444,6 +471,7 @@ config SWIOTLB
+@@ -444,6 +472,7 @@ config SWIOTLB
config X86_MCE
bool "Machine check support" if EMBEDDED
@@ -31588,7 +39422,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
default y
help
Include a machine check error handler to report hardware errors.
-@@ -469,7 +497,7 @@ config X86_MCE_AMD
+@@ -469,7 +498,7 @@ config X86_MCE_AMD
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
@@ -31597,19 +39431,18 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
-@@ -564,8 +592,11 @@ config GENERIC_PENDING_IRQ
+@@ -564,8 +593,9 @@ config GENERIC_PENDING_IRQ
default y
menu "Power management options"
+ depends on !XEN_UNPRIVILEGED_GUEST
-+if !X86_64_XEN
- source kernel/power/Kconfig
-+endif
+-source kernel/power/Kconfig
++source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
-@@ -588,6 +619,21 @@ config PCI_MMCONFIG
+@@ -588,6 +618,21 @@ config PCI_MMCONFIG
bool "Support mmconfig PCI config space access"
depends on PCI && ACPI
@@ -31631,66 +39464,100 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/Kconfig tmp-linux-2.6-xen.patch/arc
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
-@@ -658,4 +704,6 @@ source "security/Kconfig"
+@@ -658,4 +703,6 @@ source "security/Kconfig"
source "crypto/Kconfig"
+source "drivers/xen/Kconfig"
+
source "lib/Kconfig"
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/Makefile tmp-linux-2.6-xen.patch/arch/x86_64/Makefile
---- pristine-linux-2.6.18/arch/x86_64/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -32,6 +32,10 @@ cflags-$(CONFIG_MK8) += $(call cc-option
- cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
- cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
+diff -rpuN linux-2.6.18.8/arch/x86_64/Makefile linux-2.6.18-xen-3.2.0/arch/x86_64/Makefile
+--- linux-2.6.18.8/arch/x86_64/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/Makefile 2008-02-15 16:21:55.000000000 -0800
+@@ -71,9 +71,22 @@ drivers-$(CONFIG_OPROFILE) += arch/x86_
-+cppflags-$(CONFIG_XEN) += \
-+ -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
-+CPPFLAGS += $(cppflags-y)
-+
- cflags-y += -m64
- cflags-y += -mno-red-zone
- cflags-y += -mcmodel=kernel
-@@ -74,6 +78,21 @@ boot := arch/x86_64/boot
- PHONY += bzImage bzlilo install archmrproper \
+ boot := arch/x86_64/boot
+
+-PHONY += bzImage bzlilo install archmrproper \
++PHONY += bzImage bzlilo vmlinuz install archmrproper \
fdimage fdimage144 fdimage288 isoimage archclean
+ifdef CONFIG_XEN
-+CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
-+head-y := arch/x86_64/kernel/head-xen.o arch/x86_64/kernel/head64-xen.o arch/x86_64/kernel/init_task.o
-+LDFLAGS_vmlinux := -e _start
-+boot := arch/i386/boot-xen
-+.PHONY: vmlinuz
++CPPFLAGS := -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION) \
++ -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
++LDFLAGS_vmlinux := -e startup_64
+#Default target when executing "make"
+all: vmlinuz
+
-+vmlinuz: vmlinux
-+ $(Q)$(MAKE) $(build)=$(boot) $@
++BOOTIMAGE := $(boot)/vmlinuz
++KBUILD_IMAGE := $(BOOTIMAGE)
+
-+install:
-+ $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@
++vmlinuz: vmlinux
++ $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
+else
#Default target when executing "make"
all: bzImage
-@@ -94,6 +113,7 @@ fdimage fdimage144 fdimage288 isoimage:
+@@ -91,6 +104,7 @@ bzdisk: vmlinux
+
+ fdimage fdimage144 fdimage288 isoimage: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
++endif
install:
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
-+endif
+diff -rpuN linux-2.6.18.8/arch/x86_64/boot/Makefile linux-2.6.18-xen-3.2.0/arch/x86_64/boot/Makefile
+--- linux-2.6.18.8/arch/x86_64/boot/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/boot/Makefile 2008-02-15 16:21:55.000000000 -0800
+@@ -26,7 +26,7 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
+ #RAMDISK := -DRAMDISK=512
- archclean:
- $(Q)$(MAKE) $(clean)=$(boot)
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/Makefile tmp-linux-2.6-xen.patch/arch/x86_64/ia32/Makefile
---- pristine-linux-2.6.18/arch/x86_64/ia32/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/ia32/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -27,9 +27,25 @@ quiet_cmd_syscall = SYSCALL $@
+ targets := vmlinux.bin bootsect bootsect.o \
+- setup setup.o bzImage mtools.conf
++ setup setup.o bzImage mtools.conf vmlinuz vmlinux-stripped
+
+ EXTRA_CFLAGS := -m32
+
+@@ -131,5 +131,13 @@ zlilo: $(BOOTIMAGE)
+ cp System.map $(INSTALL_PATH)/
+ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+
++$(obj)/vmlinuz: $(obj)/vmlinux-stripped FORCE
++ $(call if_changed,gzip)
++ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
++
++$(obj)/vmlinux-stripped: OBJCOPYFLAGS := -g --strip-unneeded
++$(obj)/vmlinux-stripped: vmlinux FORCE
++ $(call if_changed,objcopy)
++
+ install:
+ sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/Makefile linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/Makefile
+--- linux-2.6.18.8/arch/x86_64/ia32/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/Makefile 2008-02-15 16:21:55.000000000 -0800
+@@ -14,11 +14,14 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o
+ audit-class-$(CONFIG_AUDIT) := audit.o
+ obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y)
+
++syscall32-types-y := sysenter syscall
++syscall32-types-$(subst 1,$(CONFIG_XEN),$(shell expr $(CONFIG_XEN_COMPAT)0 '<' 0x0302000)) += int80
++
+ $(obj)/syscall32_syscall.o: \
+- $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
++ $(foreach F,$(syscall32-types-y),$(obj)/vsyscall-$F.so)
+
+ # Teach kbuild about targets
+-targets := $(foreach F,sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
++targets := $(foreach F,$(syscall32-types-y),vsyscall-$F.o vsyscall-$F.so)
+
+ # The DSO images are built using a special linker script
+ quiet_cmd_syscall = SYSCALL $@
+@@ -27,9 +30,10 @@ quiet_cmd_syscall = SYSCALL $@
-Wl,-soname=linux-gate.so.1 -o $@ \
-Wl,-T,$(filter-out FORCE,$^)
-+$(obj)/vsyscall-int80.so \
- $(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
+-$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
++$(foreach F,$(syscall32-types-y),$(obj)/vsyscall-$F.so): \
$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
$(call if_changed,syscall)
@@ -31698,25 +39565,81 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/Makefile tmp-linux-2.6-xen.pat
-AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
+AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel
+AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel
-+
-+ifdef CONFIG_XEN
+AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel
-+CFLAGS_syscall32-xen.o += -DUSE_INT80
-+AFLAGS_syscall32_syscall-xen.o += -DUSE_INT80
-+
-+$(obj)/syscall32_syscall-xen.o: \
-+ $(foreach F,int80 sysenter syscall,$(obj)/vsyscall-$F.so)
-+
-+targets := $(foreach F,int80 sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
-+
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-xen.patch/arch/x86_64/ia32/ia32entry-xen.S
---- pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/ia32/ia32entry-xen.S 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,755 @@
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/ia32_signal.c linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/ia32_signal.c
+--- linux-2.6.18.8/arch/x86_64/ia32/ia32_signal.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/ia32_signal.c 2008-02-15 16:21:55.000000000 -0800
+@@ -113,25 +113,19 @@ int copy_siginfo_from_user32(siginfo_t *
+ }
+
+ asmlinkage long
+-sys32_sigsuspend(int history0, int history1, old_sigset_t mask,
+- struct pt_regs *regs)
++sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
+ {
+- sigset_t saveset;
+-
+ mask &= _BLOCKABLE;
+ spin_lock_irq(&current->sighand->siglock);
+- saveset = current->blocked;
++ current->saved_sigmask = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+- regs->rax = -EINTR;
+- while (1) {
+- current->state = TASK_INTERRUPTIBLE;
+- schedule();
+- if (do_signal(regs, &saveset))
+- return -EINTR;
+- }
++ current->state = TASK_INTERRUPTIBLE;
++ schedule();
++ set_thread_flag(TIF_RESTORE_SIGMASK);
++ return -ERESTARTNOHAND;
+ }
+
+ asmlinkage long
+@@ -508,11 +502,11 @@ int ia32_setup_frame(int sig, struct k_s
+ current->comm, current->pid, frame, regs->rip, frame->pretcode);
+ #endif
+
+- return 1;
++ return 0;
+
+ give_sigsegv:
+ force_sigsegv(sig, current);
+- return 0;
++ return -EFAULT;
+ }
+
+ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+@@ -595,7 +589,7 @@ int ia32_setup_rt_frame(int sig, struct
+ regs->ss = __USER32_DS;
+
+ set_fs(USER_DS);
+- regs->eflags &= ~TF_MASK;
++ regs->eflags &= ~TF_MASK;
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+@@ -604,9 +598,9 @@ int ia32_setup_rt_frame(int sig, struct
+ current->comm, current->pid, frame, regs->rip, frame->pretcode);
+ #endif
+
+- return 1;
++ return 0;
+
+ give_sigsegv:
+ force_sigsegv(sig, current);
+- return 0;
++ return -EFAULT;
+ }
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/ia32entry-xen.S linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/ia32entry-xen.S
+--- linux-2.6.18.8/arch/x86_64/ia32/ia32entry-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/ia32entry-xen.S 2008-02-15 16:21:55.000000000 -0800
+@@ -0,0 +1,668 @@
+/*
+ * Compatibility mode system call entry point for x86-64.
+ *
@@ -31735,8 +39658,6 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+#include <asm/irqflags.h>
+#include <linux/linkage.h>
+
-+#define __XEN_X86_64 1
-+
+#define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8)
+
+ .macro IA32_ARG_FIXUP noebp=0
@@ -31771,20 +39692,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ movl \offset+72(%rsp),%eax
+ .endm
+
-+#if defined (__XEN_X86_64)
+#include "../kernel/xen_entry.S"
-+
-+#define __swapgs
-+#define __cli
-+#define __sti
-+#else
-+/*
-+ * Use the native instructions
-+ */
-+#define __swapgs swapgs
-+#define __cli cli
-+#define __sti sti
-+#endif
+
+ .macro CFI_STARTPROC32 simple
+ CFI_STARTPROC \simple
@@ -31811,7 +39719,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ * %ebp user stack
+ * 0(%ebp) Arg6
+ *
-+ * Interrupts off.
++ * Interrupts on.
+ *
+ * This is purely a fast path. For anything complicated we use the int 0x80
+ * path below. Set up a complete hardware stack frame to share code
@@ -31819,38 +39727,26 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ */
+ENTRY(ia32_sysenter_target)
+ CFI_STARTPROC32 simple
-+ CFI_DEF_CFA rsp,0
-+ CFI_REGISTER rsp,rbp
-+ __swapgs
-+ movq %gs:pda_kernelstack, %rsp
-+ addq $(PDA_STACKOFFSET),%rsp
-+ /*
-+ * No need to follow this irqs on/off section: the syscall
-+ * disabled irqs, here we enable it straight after entry:
-+ */
-+ XEN_UNBLOCK_EVENTS(%r11)
-+ __sti
++ CFI_DEF_CFA rsp,SS+8-RIP+16
++ /*CFI_REL_OFFSET ss,SS-RIP+16*/
++ CFI_REL_OFFSET rsp,RSP-RIP+16
++ /*CFI_REL_OFFSET rflags,EFLAGS-RIP+16*/
++ /*CFI_REL_OFFSET cs,CS-RIP+16*/
++ CFI_REL_OFFSET rip,RIP-RIP+16
++ CFI_REL_OFFSET r11,8
++ CFI_REL_OFFSET rcx,0
++ movq 8(%rsp),%r11
++ CFI_RESTORE r11
++ popq %rcx
++ CFI_ADJUST_CFA_OFFSET -8
++ CFI_RESTORE rcx
+ movl %ebp,%ebp /* zero extension */
-+ pushq $__USER32_DS
-+ CFI_ADJUST_CFA_OFFSET 8
-+ /*CFI_REL_OFFSET ss,0*/
-+ pushq %rbp
-+ CFI_ADJUST_CFA_OFFSET 8
-+ CFI_REL_OFFSET rsp,0
-+ pushfq
-+ CFI_ADJUST_CFA_OFFSET 8
-+ /*CFI_REL_OFFSET rflags,0*/
-+ movl $VSYSCALL32_SYSEXIT, %r10d
-+ CFI_REGISTER rip,r10
-+ pushq $__USER32_CS
-+ CFI_ADJUST_CFA_OFFSET 8
-+ /*CFI_REL_OFFSET cs,0*/
-+ movl %eax, %eax
-+ pushq %r10
-+ CFI_ADJUST_CFA_OFFSET 8
-+ CFI_REL_OFFSET rip,0
-+ pushq %rax
-+ CFI_ADJUST_CFA_OFFSET 8
++ movl %eax,%eax
++ movl $__USER32_DS,40(%rsp)
++ movq %rbp,32(%rsp)
++ movl $__USER32_CS,16(%rsp)
++ movl $VSYSCALL32_SYSEXIT,8(%rsp)
++ movq %rax,(%rsp)
+ cld
+ SAVE_ARGS 0,0,0
+ /* no need to do an access_ok check here because rbp has been
@@ -31862,7 +39758,6 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ GET_THREAD_INFO(%r10)
+ orl $TS_COMPAT,threadinfo_status(%r10)
+ testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-+ CFI_REMEMBER_STATE
+ jnz sysenter_tracesys
+sysenter_do_call:
+ cmpl $(IA32_NR_syscalls-1),%eax
@@ -31870,33 +39765,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ IA32_ARG_FIXUP 1
+ call *ia32_sys_call_table(,%rax,8)
+ movq %rax,RAX-ARGOFFSET(%rsp)
-+ GET_THREAD_INFO(%r10)
-+ XEN_BLOCK_EVENTS(%r11)
-+ __cli
-+ TRACE_IRQS_OFF
-+ testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
-+ jnz int_ret_from_sys_call
-+ andl $~TS_COMPAT,threadinfo_status(%r10)
-+ /* clear IF, that popfq doesn't enable interrupts early */
-+ andl $~0x200,EFLAGS-R11(%rsp)
-+ RESTORE_ARGS 1,24,1,1,1,1
-+ popfq
-+ CFI_ADJUST_CFA_OFFSET -8
-+ /*CFI_RESTORE rflags*/
-+ popq %rcx /* User %esp */
-+ CFI_ADJUST_CFA_OFFSET -8
-+ CFI_REGISTER rsp,rcx
-+ movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */
-+ CFI_REGISTER rip,rdx
-+ TRACE_IRQS_ON
-+ __swapgs
-+ XEN_UNBLOCK_EVENTS(%r11)
-+ __sti /* sti only takes effect after the next instruction */
-+ /* sysexit */
-+ .byte 0xf, 0x35 /* TBD */
++ jmp int_ret_from_sys_call
+
+sysenter_tracesys:
-+ CFI_RESTORE_STATE
+ SAVE_REST
+ CLEAR_RREGS
+ movq $-ENOSYS,RAX(%rsp) /* really needed? */
@@ -31929,7 +39800,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ * %esp user stack
+ * 0(%esp) Arg6
+ *
-+ * Interrupts off.
++ * Interrupts on.
+ *
+ * This is purely a fast path. For anything complicated we use the int 0x80
+ * path below. Set up a complete hardware stack frame to share code
@@ -31937,32 +39808,20 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ */
+ENTRY(ia32_cstar_target)
+ CFI_STARTPROC32 simple
-+ CFI_DEF_CFA rsp,PDA_STACKOFFSET
-+ CFI_REGISTER rip,rcx
-+ /*CFI_REGISTER rflags,r11*/
-+ __swapgs
-+ movl %esp,%r8d
-+ CFI_REGISTER rsp,r8
-+ movq %gs:pda_kernelstack,%rsp
-+ /*
-+ * No need to follow this irqs on/off section: the syscall
-+ * disabled irqs and here we enable it straight after entry:
-+ */
-+ XEN_UNBLOCK_EVENTS(%r11)
-+ __sti
-+ SAVE_ARGS 8,1,1
++ CFI_DEF_CFA rsp,SS+8-RIP+16
++ /*CFI_REL_OFFSET ss,SS-RIP+16*/
++ CFI_REL_OFFSET rsp,RSP-RIP+16
++ /*CFI_REL_OFFSET rflags,EFLAGS-RIP+16*/
++ /*CFI_REL_OFFSET cs,CS-RIP+16*/
++ CFI_REL_OFFSET rip,RIP-RIP+16
+ movl %eax,%eax /* zero extension */
++ movl RSP-RIP+16(%rsp),%r8d
++ SAVE_ARGS -8,1,1
+ movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
-+ movq %rcx,RIP-ARGOFFSET(%rsp)
-+ CFI_REL_OFFSET rip,RIP-ARGOFFSET
+ movq %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */
+ movl %ebp,%ecx
-+ movq $__USER32_CS,CS-ARGOFFSET(%rsp)
-+ movq $__USER32_DS,SS-ARGOFFSET(%rsp)
-+ movq %r11,EFLAGS-ARGOFFSET(%rsp)
-+ /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
-+ movq %r8,RSP-ARGOFFSET(%rsp)
-+ CFI_REL_OFFSET rsp,RSP-ARGOFFSET
++ movl $__USER32_CS,CS-ARGOFFSET(%rsp)
++ movl $__USER32_DS,SS-ARGOFFSET(%rsp)
+ /* no need to do an access_ok check here because r8 has been
+ 32bit zero extended */
+ /* hardware stack frame is complete now */
@@ -31973,7 +39832,6 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ GET_THREAD_INFO(%r10)
+ orl $TS_COMPAT,threadinfo_status(%r10)
+ testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-+ CFI_REMEMBER_STATE
+ jnz cstar_tracesys
+cstar_do_call:
+ cmpl $IA32_NR_syscalls-1,%eax
@@ -31981,26 +39839,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ IA32_ARG_FIXUP 1
+ call *ia32_sys_call_table(,%rax,8)
+ movq %rax,RAX-ARGOFFSET(%rsp)
-+ GET_THREAD_INFO(%r10)
-+ XEN_BLOCK_EVENTS(%r11)
-+ __cli
-+ TRACE_IRQS_OFF
-+ testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
-+ jnz int_ret_from_sys_call
-+ andl $~TS_COMPAT,threadinfo_status(%r10)
-+ RESTORE_ARGS 1,-ARG_SKIP,1,1,1
-+ movl RIP-ARGOFFSET(%rsp),%ecx
-+ CFI_REGISTER rip,rcx
-+ movl EFLAGS-ARGOFFSET(%rsp),%r11d
-+ /*CFI_REGISTER rflags,r11*/
-+ TRACE_IRQS_ON
-+ movl RSP-ARGOFFSET(%rsp),%esp
-+ CFI_RESTORE rsp
-+ __swapgs
-+ sysretl /* TBD */
++ jmp int_ret_from_sys_call
+
+cstar_tracesys:
-+ CFI_RESTORE_STATE
+ SAVE_REST
+ CLEAR_RREGS
+ movq $-ENOSYS,RAX(%rsp) /* really needed? */
@@ -32041,32 +39882,27 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ * Arguments are zero extended. For system calls that want sign extension and
+ * take long arguments a wrapper is needed. Most calls can just be called
+ * directly.
-+ * Assumes it is only called from user space and entered with interrupts off.
++ * Assumes it is only called from user space and entered with interrupts on.
+ */
+
+ENTRY(ia32_syscall)
+ CFI_STARTPROC simple
-+ CFI_DEF_CFA rsp,SS+8-RIP
-+ /*CFI_REL_OFFSET ss,SS-RIP*/
-+ CFI_REL_OFFSET rsp,RSP-RIP
-+ /*CFI_REL_OFFSET rflags,EFLAGS-RIP*/
-+ /*CFI_REL_OFFSET cs,CS-RIP*/
-+ CFI_REL_OFFSET rip,RIP-RIP
-+ __swapgs
-+ /*
-+ * No need to follow this irqs on/off section: the syscall
-+ * disabled irqs and here we enable it straight after entry:
-+ */
-+ XEN_UNBLOCK_EVENTS(%r11)
-+ __sti
-+ movq (%rsp),%rcx
++ CFI_DEF_CFA rsp,SS+8-RIP+16
++ /*CFI_REL_OFFSET ss,SS-RIP+16*/
++ CFI_REL_OFFSET rsp,RSP-RIP+16
++ /*CFI_REL_OFFSET rflags,EFLAGS-RIP+16*/
++ /*CFI_REL_OFFSET cs,CS-RIP+16*/
++ CFI_REL_OFFSET rip,RIP-RIP+16
++ CFI_REL_OFFSET r11,8
++ CFI_REL_OFFSET rcx,0
+ movq 8(%rsp),%r11
-+ addq $0x10,%rsp /* skip rcx and r11 */
++ CFI_RESTORE r11
++ popq %rcx
++ CFI_ADJUST_CFA_OFFSET -8
++ CFI_RESTORE rcx
+ movl %eax,%eax
-+ pushq %rax
-+ CFI_ADJUST_CFA_OFFSET 8
++ movq %rax,(%rsp)
+ cld
-+/* 1: jmp 1b */
+ /* note the registers are not zero extended to the sf.
+ this could be a problem. */
+ SAVE_ARGS 0,0,1
@@ -32461,8 +40297,8 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ .quad sys_readlinkat /* 305 */
+ .quad sys_fchmodat
+ .quad sys_faccessat
-+ .quad quiet_ni_syscall /* pselect6 for now */
-+ .quad quiet_ni_syscall /* ppoll for now */
++ .quad compat_sys_pselect6
++ .quad compat_sys_ppoll
+ .quad sys_unshare /* 310 */
+ .quad compat_sys_set_robust_list
+ .quad compat_sys_get_robust_list
@@ -32472,10 +40308,24 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/ia32entry-xen.S tmp-linux-2.6-
+ .quad compat_sys_vmsplice
+ .quad compat_sys_move_pages
+ia32_syscall_end:
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32-xen.c tmp-linux-2.6-xen.patch/arch/x86_64/ia32/syscall32-xen.c
---- pristine-linux-2.6.18/arch/x86_64/ia32/syscall32-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/ia32/syscall32-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,128 @@
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/ia32entry.S linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/ia32entry.S
+--- linux-2.6.18.8/arch/x86_64/ia32/ia32entry.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/ia32entry.S 2008-02-15 16:21:55.000000000 -0800
+@@ -703,8 +703,8 @@ ia32_sys_call_table:
+ .quad sys_readlinkat /* 305 */
+ .quad sys_fchmodat
+ .quad sys_faccessat
+- .quad quiet_ni_syscall /* pselect6 for now */
+- .quad quiet_ni_syscall /* ppoll for now */
++ .quad compat_sys_pselect6
++ .quad compat_sys_ppoll
+ .quad sys_unshare /* 310 */
+ .quad compat_sys_set_robust_list
+ .quad compat_sys_get_robust_list
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/syscall32-xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/syscall32-xen.c
+--- linux-2.6.18.8/arch/x86_64/ia32/syscall32-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/syscall32-xen.c 2008-02-15 16:21:55.000000000 -0800
+@@ -0,0 +1,137 @@
+/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
+
+/* vsyscall handling for 32bit processes. Map a stub page into it
@@ -32491,17 +40341,18 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32-xen.c tmp-linux-2.6-
+#include <asm/proto.h>
+#include <asm/tlbflush.h>
+#include <asm/ia32_unistd.h>
++#include <xen/interface/callback.h>
+
-+#ifdef USE_INT80
-+extern unsigned char syscall32_int80[], syscall32_int80_end[];
-+#endif
+extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
+extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
+extern int sysctl_vsyscall32;
+
+char *syscall32_page;
-+#ifndef USE_INT80
+static int use_sysenter = -1;
++
++#if CONFIG_XEN_COMPAT < 0x030200
++extern unsigned char syscall32_int80[], syscall32_int80_end[];
++static int use_int80 = 1;
+#endif
+
+static struct page *
@@ -32564,13 +40415,12 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32-xen.c tmp-linux-2.6-
+ if (!syscall32_page)
+ panic("Cannot allocate syscall32 page");
+
-+#ifdef USE_INT80
-+ /*
-+ * At this point we use int 0x80.
-+ */
-+ memcpy(syscall32_page, syscall32_int80,
-+ syscall32_int80_end - syscall32_int80);
-+#else
++#if CONFIG_XEN_COMPAT < 0x030200
++ if (use_int80) {
++ memcpy(syscall32_page, syscall32_int80,
++ syscall32_int80_end - syscall32_int80);
++ } else
++#endif
+ if (use_sysenter > 0) {
+ memcpy(syscall32_page, syscall32_sysenter,
+ syscall32_sysenter_end - syscall32_sysenter);
@@ -32578,7 +40428,6 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32-xen.c tmp-linux-2.6-
+ memcpy(syscall32_page, syscall32_syscall,
+ syscall32_syscall_end - syscall32_syscall);
+ }
-+#endif
+ return 0;
+}
+
@@ -32591,28 +40440,38 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32-xen.c tmp-linux-2.6-
+/* May not be __init: called during resume */
+void syscall32_cpu_init(void)
+{
-+#ifndef USE_INT80
-+ if (use_sysenter < 0)
-+ use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
++ 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
++ };
+
+ /* Load these always in case some future AMD CPU supports
+ SYSENTER from compat mode too. */
-+ checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
-+ checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
-+ checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
-+
-+ wrmsrl(MSR_CSTAR, ia32_cstar_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);
+}
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32_syscall-xen.S tmp-linux-2.6-xen.patch/arch/x86_64/ia32/syscall32_syscall-xen.S
---- pristine-linux-2.6.18/arch/x86_64/ia32/syscall32_syscall-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/ia32/syscall32_syscall-xen.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/syscall32_syscall-xen.S linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/syscall32_syscall-xen.S
+--- linux-2.6.18.8/arch/x86_64/ia32/syscall32_syscall-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/syscall32_syscall-xen.S 2008-02-15 16:21:55.000000000 -0800
@@ -0,0 +1,28 @@
+/* 32bit VDSOs mapped into user space. */
+
+ .section ".init.data","aw"
+
-+#ifdef USE_INT80
++#if CONFIG_XEN_COMPAT < 0x030200
+
+ .globl syscall32_int80
+ .globl syscall32_int80_end
@@ -32636,9 +40495,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/syscall32_syscall-xen.S tmp-li
+syscall32_sysenter:
+ .incbin "arch/x86_64/ia32/vsyscall-sysenter.so"
+syscall32_sysenter_end:
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/vsyscall-int80.S tmp-linux-2.6-xen.patch/arch/x86_64/ia32/vsyscall-int80.S
---- pristine-linux-2.6.18/arch/x86_64/ia32/vsyscall-int80.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/ia32/vsyscall-int80.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/vsyscall-int80.S linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/vsyscall-int80.S
+--- linux-2.6.18.8/arch/x86_64/ia32/vsyscall-int80.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/vsyscall-int80.S 2008-02-15 16:21:55.000000000 -0800
@@ -0,0 +1,58 @@
+/*
+ * Code for the vsyscall page. This version uses the old int $0x80 method.
@@ -32698,9 +40557,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/vsyscall-int80.S tmp-linux-2.6
+ */
+#define SYSCALL_ENTER_KERNEL int $0x80
+#include "vsyscall-sigreturn.S"
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/vsyscall-sigreturn.S tmp-linux-2.6-xen.patch/arch/x86_64/ia32/vsyscall-sigreturn.S
---- pristine-linux-2.6.18/arch/x86_64/ia32/vsyscall-sigreturn.S 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/ia32/vsyscall-sigreturn.S 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/ia32/vsyscall-sigreturn.S linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/vsyscall-sigreturn.S
+--- linux-2.6.18.8/arch/x86_64/ia32/vsyscall-sigreturn.S 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/ia32/vsyscall-sigreturn.S 2008-02-15 16:21:55.000000000 -0800
@@ -139,5 +139,5 @@ __kernel_rt_sigreturn:
.align 4
.LENDFDE3:
@@ -32708,9 +40567,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/ia32/vsyscall-sigreturn.S tmp-linux
-#include "../../i386/kernel/vsyscall-note.S"
+#include <vsyscall-note.S>
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/Makefile tmp-linux-2.6-xen.patch/arch/x86_64/kernel/Makefile
---- pristine-linux-2.6.18/arch/x86_64/kernel/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/Makefile 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/Makefile linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/Makefile
+--- linux-2.6.18.8/arch/x86_64/kernel/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/Makefile 2008-02-15 16:21:55.000000000 -0800
@@ -21,11 +21,13 @@ obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
@@ -32726,36 +40585,200 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/Makefile tmp-linux-2.6-xen.p
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-@@ -55,3 +57,18 @@ i8237-y += ../../i386/kernel/i8237.o
+@@ -55,3 +57,8 @@ i8237-y += ../../i386/kernel/i8237.o
msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
alternative-y += ../../i386/kernel/alternative.o
-+ifdef CONFIG_XEN
-+time-y += ../../i386/kernel/time-xen.o
-+pci-dma-y += ../../i386/kernel/pci-dma-xen.o
-+microcode-$(subst m,y,$(CONFIG_MICROCODE)) := ../../i386/kernel/microcode-xen.o
-+quirks-y := ../../i386/kernel/quirks-xen.o
-+
-+n-obj-xen := i8259.o reboot.o i8237.o smpboot.o trampoline.o
-+
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
-+obj-y := $(call cherrypickxen, $(obj-y))
-+extra-y := $(call cherrypickxen, $(extra-y))
-+%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
-+endif
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/acpi/Makefile tmp-linux-2.6-xen.patch/arch/x86_64/kernel/acpi/Makefile
---- pristine-linux-2.6.18/arch/x86_64/kernel/acpi/Makefile 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/acpi/Makefile 2007-11-14 15:35:27.000000000 -0800
-@@ -7,3 +7,4 @@ obj-y += processor.o
++time-$(CONFIG_XEN) += ../../i386/kernel/time.o
++pci-dma-$(CONFIG_XEN) += ../../i386/kernel/pci-dma.o
++
++disabled-obj-$(CONFIG_XEN) := i8259.o reboot.o smpboot.o trampoline.o
++%/head.o %/head.s: $(if $(CONFIG_XEN),EXTRA_AFLAGS,dummy) :=
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/acpi/Makefile linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/acpi/Makefile
+--- linux-2.6.18.8/arch/x86_64/kernel/acpi/Makefile 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/acpi/Makefile 2008-02-15 16:21:55.000000000 -0800
+@@ -5,5 +5,7 @@ obj-$(CONFIG_ACPI_SLEEP) += sleep.o wake
+ ifneq ($(CONFIG_ACPI_PROCESSOR),)
+ obj-y += processor.o
processor-y := ../../../i386/kernel/acpi/processor.o ../../../i386/kernel/acpi/cstate.o
++processor-$(CONFIG_XEN) := ../../../i386/kernel/acpi/processor.o
endif
-+boot-$(CONFIG_XEN) := ../../../i386/kernel/acpi/boot-xen.o
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/apic-xen.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/apic-xen.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/apic-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/apic-xen.c 2007-11-14 15:35:27.000000000 -0800
++disabled-obj-$(CONFIG_XEN) := wakeup.o
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/acpi/sleep-xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/acpi/sleep-xen.c
+--- linux-2.6.18.8/arch/x86_64/kernel/acpi/sleep-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/acpi/sleep-xen.c 2008-02-15 16:21:55.000000000 -0800
+@@ -0,0 +1,167 @@
++/*
++ * acpi.c - Architecture-Specific Low-Level ACPI Support
++ *
++ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
++ * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
++ * Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
++ * Copyright (C) 2002 Andi Kleen, SuSE Labs (x86-64 port)
++ * Copyright (C) 2003 Pavel Machek, SuSE Labs
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/stddef.h>
++#include <linux/slab.h>
++#include <linux/pci.h>
++#include <linux/bootmem.h>
++#include <linux/acpi.h>
++#include <linux/cpumask.h>
++
++#include <asm/mpspec.h>
++#include <asm/io.h>
++#include <asm/apic.h>
++#include <asm/apicdef.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/pgalloc.h>
++#include <asm/io_apic.h>
++#include <asm/proto.h>
++#include <asm/tlbflush.h>
++
++/* --------------------------------------------------------------------------
++ Low-Level Sleep Support
++ -------------------------------------------------------------------------- */
++
++#ifdef CONFIG_ACPI_SLEEP
++
++#ifndef CONFIG_ACPI_PV_SLEEP
++/* address in low memory of the wakeup routine. */
++unsigned long acpi_wakeup_address = 0;
++unsigned long acpi_video_flags;
++extern char wakeup_start, wakeup_end;
++
++extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
++
++static pgd_t low_ptr;
++
++static void init_low_mapping(void)
++{
++ pgd_t *slot0 = pgd_offset(current->mm, 0UL);
++ low_ptr = *slot0;
++ set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET));
++ WARN_ON(num_online_cpus() != 1);
++ local_flush_tlb();
++}
++#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
++ init_low_mapping();
++
++ memcpy((void *)acpi_wakeup_address, &wakeup_start,
++ &wakeup_end - &wakeup_start);
++ acpi_copy_wakeup_routine(acpi_wakeup_address);
++#endif
++ return 0;
++}
++
++/*
++ * acpi_restore_state
++ */
++void acpi_restore_state_mem(void)
++{
++#ifndef CONFIG_ACPI_PV_SLEEP
++ set_pgd(pgd_offset(current->mm, 0UL), low_ptr);
++ local_flush_tlb();
++#endif
++}
++
++/**
++ * acpi_reserve_bootmem - do _very_ early ACPI initialisation
++ *
++ * We allocate a page in low memory for the wakeup
++ * routine for when we come back from a sleep state. The
++ * runtime allocator allows specification of <16M pages, but not
++ * <1M pages.
++ */
++void __init acpi_reserve_bootmem(void)
++{
++#ifndef CONFIG_ACPI_PV_SLEEP
++ acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
++ if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
++ printk(KERN_CRIT
++ "ACPI: Wakeup code way too big, will crash on attempt to suspend\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_video_flags = 1;
++ if (strncmp(str, "s3_mode", 7) == 0)
++ acpi_video_flags |= 2;
++ str = strchr(str, ',');
++ if (str != NULL)
++ str += strspn(str, ", \t");
++ }
++
++ return 1;
++}
++
++__setup("acpi_sleep=", acpi_sleep_setup);
++
++#else /* CONFIG_ACPI_PV_SLEEP */
++#include <asm/hypervisor.h>
++#include <xen/interface/platform.h>
++int acpi_notify_hypervisor_state(u8 sleep_state,
++ u32 pm1a_cnt, u32 pm1b_cnt)
++{
++ struct xen_platform_op op = {
++ .cmd = XENPF_enter_acpi_sleep,
++ .interface_version = XENPF_INTERFACE_VERSION,
++ .u = {
++ .enter_acpi_sleep = {
++ .pm1a_cnt_val = (u16)pm1a_cnt,
++ .pm1b_cnt_val = (u16)pm1b_cnt,
++ .sleep_state = sleep_state,
++ },
++ },
++ };
++
++ return HYPERVISOR_platform_op(&op);
++}
++#endif /* CONFIG_ACPI_PV_SLEEP */
++
++#endif /*CONFIG_ACPI_SLEEP */
++
++void acpi_pci_link_exit(void)
++{
++}
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/apic-xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/apic-xen.c
+--- linux-2.6.18.8/arch/x86_64/kernel/apic-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/apic-xen.c 2008-02-15 16:21:55.000000000 -0800
@@ -0,0 +1,197 @@
+/*
+ * Local APIC handling, local APIC timers
@@ -32954,9 +40977,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/apic-xen.c tmp-linux-2.6-xen
+
+ return 1;
+}
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/asm-offsets.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/asm-offsets.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/asm-offsets.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/asm-offsets.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/asm-offsets.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/asm-offsets.c
+--- linux-2.6.18.8/arch/x86_64/kernel/asm-offsets.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/asm-offsets.c 2008-02-15 16:21:55.000000000 -0800
@@ -67,8 +67,10 @@ int main(void)
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
@@ -32968,9 +40991,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/asm-offsets.c tmp-linux-2.6-
BLANK();
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
return 0;
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/crash.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/crash.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/crash.c 2006-09-19 20:42:06.000000000 -0700
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/crash.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/crash.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/crash.c
+--- linux-2.6.18.8/arch/x86_64/kernel/crash.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/crash.c 2008-02-15 16:21:55.000000000 -0800
@@ -92,6 +92,7 @@ static void crash_save_self(struct pt_re
crash_save_this_cpu(regs, cpu);
}
@@ -33004,10 +41027,10 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/crash.c tmp-linux-2.6-xen.pa
+#endif /* CONFIG_XEN */
crash_save_self(regs);
}
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/e820-xen.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/e820-xen.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/e820-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/e820-xen.c 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,774 @@
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/e820-xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/e820-xen.c
+--- linux-2.6.18.8/arch/x86_64/kernel/e820-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/e820-xen.c 2008-02-15 16:21:55.000000000 -0800
+@@ -0,0 +1,783 @@
+/*
+ * Handle the memory map.
+ * The functions here do the job until bootmem takes over.
@@ -33107,17 +41130,26 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/e820-xen.c tmp-linux-2.6-xen
+ return 0;
+}
+
-+#ifndef CONFIG_XEN
+/*
+ * This function checks if any part of the range <start,end> is mapped
+ * with type.
+ */
-+int __meminit
-+e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
++int e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
+{
+ int i;
++
++#ifndef CONFIG_XEN
+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *ei = &e820.map[i];
++#else
++ extern struct e820map machine_e820;
++
++ if (!is_initial_xendomain())
++ return 0;
++ for (i = 0; i < machine_e820.nr_map; i++) {
++ const struct e820entry *ei = &machine_e820.map[i];
++#endif
++
+ if (type && ei->type != type)
+ continue;
+ if (ei->addr >= end || ei->addr + ei->size <= start)
@@ -33126,7 +41158,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/e820-xen.c tmp-linux-2.6-xen
+ }
+ return 0;
+}
-+#endif
++EXPORT_SYMBOL_GPL(e820_any_mapped);
+
+/*
+ * This function checks if the entire range <start,end> is mapped with type.
@@ -33782,9 +41814,29 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/e820-xen.c tmp-linux-2.6-xen
+ printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
+ pci_mem_start, gapstart, gapsize);
+}
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/early_printk-xen.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/early_printk-xen.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/early_printk-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/early_printk-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/e820.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/e820.c
+--- linux-2.6.18.8/arch/x86_64/kernel/e820.c 2007-02-23 15:52:30.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/e820.c 2008-02-15 16:21:55.000000000 -0800
+@@ -93,7 +93,7 @@ static inline int bad_addr(unsigned long
+ * This function checks if any part of the range <start,end> is mapped
+ * with type.
+ */
+-int __meminit
++int
+ e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
+ {
+ int i;
+@@ -107,6 +107,7 @@ e820_any_mapped(unsigned long start, uns
+ }
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(e820_any_mapped);
+
+ /*
+ * This function checks if the entire range <start,end> is mapped with type.
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/early_printk-xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/early_printk-xen.c
+--- linux-2.6.18.8/arch/x86_64/kernel/early_printk-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/early_printk-xen.c 2008-02-15 16:21:55.000000000 -0800
@@ -0,0 +1,302 @@
+#include <linux/console.h>
+#include <linux/kernel.h>
@@ -34088,10 +42140,10 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/early_printk-xen.c tmp-linux
+}
+
+__setup("earlyprintk=", setup_early_printk);
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S tmp-linux-2.6-xen.patch/arch/x86_64/kernel/entry-xen.S
---- pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/entry-xen.S 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,1325 @@
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/entry-xen.S linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/entry-xen.S
+--- linux-2.6.18.8/arch/x86_64/kernel/entry-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/entry-xen.S 2008-02-15 16:21:55.000000000 -0800
+@@ -0,0 +1,1322 @@
+/*
+ * linux/arch/x86_64/entry.S
+ *
@@ -34144,8 +42196,6 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S tmp-linux-2.6-xe
+#include <xen/interface/arch-x86_64.h>
+#include <xen/interface/features.h>
+
-+#include "irq_vectors.h"
-+
+#include "xen_entry.S"
+
+ .code64
@@ -34274,6 +42324,10 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S tmp-linux-2.6-xe
+/* rdi: prev */
+ENTRY(ret_from_fork)
+ CFI_DEFAULT_STACK
++ push kernel_eflags(%rip)
++ CFI_ADJUST_CFA_OFFSET 4
++ popf # reset kernel eflags
++ CFI_ADJUST_CFA_OFFSET -4
+ call schedule_tail
+ GET_THREAD_INFO(%rcx)
+ testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
@@ -34327,7 +42381,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S tmp-linux-2.6-xe
+ * r11 eflags for syscall/sysret, temporary for C
+ * r12-r15,rbp,rbx saved by C code, not touched.
+ *
-+ * Interrupts are off on entry.
++ * Interrupts are enabled on entry.
+ * Only called from user space.
+ *
+ * XXX if we had a free scratch register we could save the RSP into the stack frame
@@ -34342,11 +42396,6 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S tmp-linux-2.6-xe
+ _frame (RIP-0x10)
+ SAVE_ARGS -8,0
+ movq %rax,ORIG_RAX-ARGOFFSET(%rsp)
-+ /*
-+ * No need to follow this irqs off/on section - it's straight
-+ * and short:
-+ */
-+ XEN_UNBLOCK_EVENTS(%r11)
+ GET_THREAD_INFO(%rcx)
+ testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
+ CFI_REMEMBER_STATE
@@ -35417,9 +43466,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/entry-xen.S tmp-linux-2.6-xe
+ CFI_ENDPROC
+ENDPROC(arch_unwind_init_running)
+#endif
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/genapic-xen.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/genapic-xen.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/genapic-xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/genapic-xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/genapic-xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/genapic-xen.c
+--- linux-2.6.18.8/arch/x86_64/kernel/genapic-xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/genapic-xen.c 2008-02-15 16:21:55.000000000 -0800
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
@@ -35564,9 +43613,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/genapic-xen.c tmp-linux-2.6-
+ xen_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
+#endif
+}
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/genapic_xen.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/genapic_xen.c
---- pristine-linux-2.6.18/arch/x86_64/kernel/genapic_xen.c 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/genapic_xen.c 2007-11-14 15:35:27.000000000 -0800
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/genapic_xen.c linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/genapic_xen.c
+--- linux-2.6.18.8/arch/x86_64/kernel/genapic_xen.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/genapic_xen.c 2008-02-15 16:21:55.000000000 -0800
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
@@ -35729,10 +43778,10 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/genapic_xen.c tmp-linux-2.6-
+ .cpu_mask_to_apicid = xen_cpu_mask_to_apicid,
+ .phys_pkg_id = phys_pkg_id,
+};
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen.patch/arch/x86_64/kernel/head-xen.S
---- pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S 1969-12-31 16:00:00.000000000 -0800
-+++ tmp-linux-2.6-xen.patch/arch/x86_64/kernel/head-xen.S 2007-11-14 15:35:27.000000000 -0800
-@@ -0,0 +1,203 @@
+diff -rpuN linux-2.6.18.8/arch/x86_64/kernel/head-xen.S linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/head-xen.S
+--- linux-2.6.18.8/arch/x86_64/kernel/head-xen.S 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18-xen-3.2.0/arch/x86_64/kernel/head-xen.S 2008-02-15 16:21:55.000000000 -0800
+@@ -0,0 +1,214 @@
+/*
+ * linux/arch/x86_64/kernel/head.S -- start in 32bit and switch to 64bit
+ *
@@ -35762,11 +43811,8 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen
+
+ .section .bootstrap.text, "ax", @progbits
+ .code64
-+#define VIRT_ENTRY_OFFSET 0x0
-+.org VIRT_ENTRY_OFFSET
+ .globl startup_64
+startup_64:
-+ENTRY(_start)
+ movq $(init_thread_union+THREAD_SIZE-8),%rsp
+
+ /* rsi is pointer to startup info structure.
@@ -35775,6 +43821,13 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen
+ pushq $0 # fake return address
+ jmp x86_64_start_kernel
+
++#ifdef CONFIG_ACPI_SLEEP
++.org 0xf00
++ .globl pGDT32
++pGDT32:
++ .word gdt_end-cpu_gdt_table-1
++ .long cpu_gdt_table-__START_KERNEL_map
++#endif
+ENTRY(stext)
+ENTRY(_stext)
+
@@ -35788,15 +43841,14 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen
+NEXT_PAGE(init_level4_pgt)
+ /* This gets initialized in x86_64_start_kernel */
+ .fill 512,8,0
-+
++NEXT_PAGE(init_level4_user_pgt)
+ /*
+ * We update two pgd entries to make kernel and user pgd consistent
+ * at pgd_populate(). It can be used for kernel modules. So we place
+ * this page here for those cases to avoid memory corruption.
-+ * We also use this page to establish the initiali mapping for
++ * We also use this page to establish the initial mapping for the
+ * vsyscall area.
+ */
-+NEXT_PAGE(init_level4_user_pgt)
+ .fill 512,8,0
+
+NEXT_PAGE(level3_kernel_pgt)
@@ -35836,6 +43888,14 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen
+#undef NEXT_PAGE
+
+ .data
++/* Just dummy symbol to allow compilation. Not used in sleep path */
++#ifdef CONFIG_ACPI_SLEEP
++ .align PAGE_SIZE
++ENTRY(wakeup_level4_pgt)
++ .fill 512,8,0
++#endif
++
++ .data
+
+ .align 16
+ .globl cpu_gdt_descr
@@ -35910,7 +43970,7 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen
+ .ascii ",ELF_PADDR_OFFSET=0x"
+ utoh __START_KERNEL_map
+ .ascii ",VIRT_ENTRY=0x"
-+ utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
++ utoh (__START_KERNEL_map + __PHYSICAL_START)
+ .ascii ",HYPERCALL_PAGE=0x"
+ utoh (phys_hypercall_page >> PAGE_SHIFT)
+ .ascii ",FEATURES=writable_page_tables"
@@ -35936,9 +43996,9 @@ diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head-xen.S tmp-linux-2.6-xen
+ ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
+ ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
+ ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1)
-diff -Nurp pristine-linux-2.6.18/arch/x86_64/kernel/head64-xen.c tmp-linux-2.6-xen.patch/arch/x86_64/kernel/head64-xen.c
---- pristine-linux-2.6.1