summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Young <m.a.young@durham.ac.uk>2011-03-24 12:49:16 +0000
committerMichael Young <m.a.young@durham.ac.uk>2011-03-24 12:49:16 +0000
commitaf3666d76ee2cd5d748b905f5111e1dadc80001a (patch)
treee731888f14123f0a4bed2e763916fa7b0ebf85c7
parent993c86d8e951ca7dc4d7c6bd96c772d5c480745b (diff)
downloaddom0-kernel-af3666d76ee2cd5d748b905f5111e1dadc80001a.tar.gz
dom0-kernel-af3666d76ee2cd5d748b905f5111e1dadc80001a.tar.xz
dom0-kernel-af3666d76ee2cd5d748b905f5111e1dadc80001a.zip
Update to 2.3.32.34 and latest xen/next-2.6.32
-rw-r--r--.gitignore2
-rw-r--r--config-generic2
-rw-r--r--drm-upgrayedd.patch4
-rw-r--r--ipc-shm-fix-information-leak-to-user.patch30
-rw-r--r--ipc-zero-struct-memory-for-compat-fns.patch73
-rw-r--r--kernel.spec25
-rw-r--r--posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch60
-rw-r--r--sources3
-rw-r--r--xen.pvops.patch1531
-rw-r--r--xen.pvops.post.patch48
10 files changed, 1055 insertions, 723 deletions
diff --git a/.gitignore b/.gitignore
index 5575079..51eba58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@ patch-*.bz2
clog
*.rpm
kernel-2.6.*/
-/patch-2.6.32.26.bz2
+/patch-2.6.32.34.bz2
diff --git a/config-generic b/config-generic
index 87a4b60..6aae44c 100644
--- a/config-generic
+++ b/config-generic
@@ -4075,3 +4075,5 @@ CONFIG_XEN_BLKDEV_TAP=m
CONFIG_XEN_PLATFORM_PCI=m
CONFIG_NET_SCH_PLUG=m
CONFIG_XEN_WDT=m
+# added for 2.6.32.34
+CONFIG_IRQ_TIME_ACCOUNTING=n
diff --git a/drm-upgrayedd.patch b/drm-upgrayedd.patch
index 2530bec..4774109 100644
--- a/drm-upgrayedd.patch
+++ b/drm-upgrayedd.patch
@@ -214,8 +214,8 @@ index 5cae0b3..d91fb8c 100644
int type;
char *name;
@@ -149,6 +158,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
- { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
- { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+ { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
+ { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
+ { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
};
diff --git a/ipc-shm-fix-information-leak-to-user.patch b/ipc-shm-fix-information-leak-to-user.patch
deleted file mode 100644
index b23ad43..0000000
--- a/ipc-shm-fix-information-leak-to-user.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Vasiliy Kulikov <segooon@gmail.com>
-Date: Sat, 30 Oct 2010 14:22:49 +0000 (+0400)
-Subject: ipc: shm: fix information leak to userland
-X-Git-Tag: v2.6.37-rc1~24
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3af54c9bd9e6f14f896aac1bb0e8405ae0bc7a44
-
-ipc: shm: fix information leak to userland
-
-The shmid_ds structure is copied to userland with shm_unused{,2,3}
-fields unitialized. It leads to leaking of contents of kernel stack
-memory.
-
-Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
-Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
-Cc: stable@kernel.org
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
-
-diff --git a/ipc/shm.c b/ipc/shm.c
-index fd658a1..7d3bb22 100644
---- a/ipc/shm.c
-+++ b/ipc/shm.c
-@@ -479,6 +479,7 @@ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_
- {
- struct shmid_ds out;
-
-+ memset(&out, 0, sizeof(out));
- ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
- out.shm_segsz = in->shm_segsz;
- out.shm_atime = in->shm_atime;
diff --git a/ipc-zero-struct-memory-for-compat-fns.patch b/ipc-zero-struct-memory-for-compat-fns.patch
deleted file mode 100644
index b682c7d..0000000
--- a/ipc-zero-struct-memory-for-compat-fns.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: Dan Rosenberg <drosenberg@vsecurity.com>
-Date: Wed, 27 Oct 2010 22:34:17 +0000 (-0700)
-Subject: ipc: initialize structure memory to zero for compat functions
-X-Git-Tag: v2.6.37-rc1~85^2~50
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=03145beb455cf5c20a761e8451e30b8a74ba58d9
-
-ipc: initialize structure memory to zero for compat functions
-
-This takes care of leaking uninitialized kernel stack memory to
-userspace from non-zeroed fields in structs in compat ipc functions.
-
-Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
-Cc: Manfred Spraul <manfred@colorfullife.com>
-Cc: Arnd Bergmann <arnd@arndb.de>
-Cc: <stable@kernel.org>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
-
-diff --git a/ipc/compat.c b/ipc/compat.c
-index 9dc2c7d..845a287 100644
---- a/ipc/compat.c
-+++ b/ipc/compat.c
-@@ -241,6 +241,8 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
- struct semid64_ds __user *up64;
- int version = compat_ipc_parse_version(&third);
-
-+ memset(&s64, 0, sizeof(s64));
-+
- if (!uptr)
- return -EINVAL;
- if (get_user(pad, (u32 __user *) uptr))
-@@ -421,6 +423,8 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
- int version = compat_ipc_parse_version(&second);
- void __user *p;
-
-+ memset(&m64, 0, sizeof(m64));
-+
- switch (second & (~IPC_64)) {
- case IPC_INFO:
- case IPC_RMID:
-@@ -594,6 +598,8 @@ long compat_sys_shmctl(int first, int second, void __user *uptr)
- int err, err2;
- int version = compat_ipc_parse_version(&second);
-
-+ memset(&s64, 0, sizeof(s64));
-+
- switch (second & (~IPC_64)) {
- case IPC_RMID:
- case SHM_LOCK:
-diff --git a/ipc/compat_mq.c b/ipc/compat_mq.c
-index d8d1e9f..380ea4f 100644
---- a/ipc/compat_mq.c
-+++ b/ipc/compat_mq.c
-@@ -53,6 +53,9 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name,
- void __user *p = NULL;
- if (u_attr && oflag & O_CREAT) {
- struct mq_attr attr;
-+
-+ memset(&attr, 0, sizeof(attr));
-+
- p = compat_alloc_user_space(sizeof(attr));
- if (get_compat_mq_attr(&attr, u_attr) ||
- copy_to_user(p, &attr, sizeof(attr)))
-@@ -127,6 +130,8 @@ asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
- struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p));
- long ret;
-
-+ memset(&mqstat, 0, sizeof(mqstat));
-+
- if (u_mqstat) {
- if (get_compat_mq_attr(&mqstat, u_mqstat) ||
- copy_to_user(p, &mqstat, sizeof(mqstat)))
diff --git a/kernel.spec b/kernel.spec
index e69a6cc..d05a879 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -60,7 +60,7 @@ Summary: The Linux kernel
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
-%define stable_update 26
+%define stable_update 34
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
@@ -837,14 +837,9 @@ Patch14200: net-do-not-check-capable-if-kernel.patch
# rhbz#596475
Patch14226: add-support-for-ricoh-e822-sdhci.patch
-Patch14300: ipc-zero-struct-memory-for-compat-fns.patch
-Patch14301: ipc-shm-fix-information-leak-to-user.patch
-
Patch14302: inet_diag-make-sure-we-run-the-same-bytecode-we-audited.patch
Patch14307: netlink-make-nlmsg_find_attr-take-a-const-ptr.patch
-Patch14303: posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
-
Patch14305: tty-make-tiocgicount-a-handler.patch
Patch14306: tty-icount-changeover-for-other-main-devices.patch
@@ -1554,19 +1549,10 @@ ApplyPatch net-do-not-check-capable-if-kernel.patch
# rhbz#596475
ApplyPatch add-support-for-ricoh-e822-sdhci.patch
-# rhbz#648658 (CVE-2010-4073)
-ApplyPatch ipc-zero-struct-memory-for-compat-fns.patch
-
-# rhbz#648656 (CVE-2010-4072)
-ApplyPatch ipc-shm-fix-information-leak-to-user.patch
-
# rhbz#651264 (CVE-2010-3880)
ApplyPatch inet_diag-make-sure-we-run-the-same-bytecode-we-audited.patch
ApplyPatch netlink-make-nlmsg_find_attr-take-a-const-ptr.patch
-# rhbz#656264
-ApplyPatch posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
-
# CVE-2010-4077, CVE-2010-4075 (rhbz#648660, #648663)
ApplyPatch tty-make-tiocgicount-a-handler.patch
ApplyPatch tty-icount-changeover-for-other-main-devices.patch
@@ -2227,6 +2213,15 @@ fi
%kernel_variant_files -k vmlinux %{with_kdump} kdump
%changelog
+* Thu Mar 24 2011 Michael Young <m.a.young@durham.ac.uk>
+- update to 2.6.32.34
+ rebase drm-upgrayedd.patch
+ remove merged ipc-zero-struct-memory-for-compat-fns.patch
+ ipc-shm-fix-information-leak-to-user.patch
+ posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
+ set CONFIG_IRQ_TIME_ACCOUNTING=n
+- update to latest xen/xen-next.2.6.32
+
* Sat Dec 04 2010 Michael Young <m.a.young@durham.ac.uk>
- add patch "fix ethtool_get_drvinfo NULL pointer dereference"
to xen.pvops.post.patch (post F12 EOL)
diff --git a/posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch b/posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
deleted file mode 100644
index 92c2849..0000000
--- a/posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 9bdade1bc13e547130d2629291758a579722e5d1 Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Fri, 5 Nov 2010 16:53:42 +0100
-Subject: posix-cpu-timers: workaround to suppress the problems with mt exec
-
-posix-cpu-timers.c correctly assumes that the dying process does
-posix_cpu_timers_exit_group() and removes all !CPUCLOCK_PERTHREAD
-timers from signal->cpu_timers list.
-
-But, it also assumes that timer->it.cpu.task is always the group
-leader, and thus the dead ->task means the dead thread group.
-
-This is obviously not true after de_thread() changes the leader.
-After that almost every posix_cpu_timer_ method has problems.
-
-It is not simple to fix this bug correctly. First of all, I think
-that timer->it.cpu should use struct pid instead of task_struct.
-Also, the locking should be reworked completely. In particular,
-tasklist_lock should not be used at all. This all needs a lot of
-nontrivial and hard-to-test changes.
-
-Change __exit_signal() to do posix_cpu_timers_exit_group() when
-the old leader dies during exec. This is not the fix, just the
-temporary hack to hide the problem for 2.6.37 and stable. IOW,
-this is obviously wrong but this is what we currently have anyway:
-cpu timers do not work after mt exec.
-
-In theory this change adds another race. The exiting leader can
-detach the timers which were attached to the new leader. However,
-the window between de_thread() and release_task() is small, we
-can pretend that sys_timer_create() was called before de_thread().
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- kernel/exit.c | 8 ++++++++
- 1 files changed, 8 insertions(+), 0 deletions(-)
-
-diff --git a/kernel/exit.c b/kernel/exit.c
-index 45102e9..02b7104 100644
---- a/kernel/exit.c
-+++ b/kernel/exit.c
-@@ -92,6 +92,14 @@ static void __exit_signal(struct task_struct *tsk)
- posix_cpu_timers_exit_group(tsk);
- else {
- /*
-+ * This can only happen if the caller is de_thread().
-+ * FIXME: this is the temporary hack, we should teach
-+ * posix-cpu-timers to handle this case correctly.
-+ */
-+ if (unlikely(has_group_leader_pid(tsk)))
-+ posix_cpu_timers_exit_group(tsk);
-+
-+ /*
- * If there is any task waiting for the group exit
- * then notify it:
- */
---
-1.7.3.2
-
diff --git a/sources b/sources
index bca6be4..f5c45f9 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,3 @@
260551284ac224c3a43c4adac7df4879 linux-2.6.32.tar.bz2
-98071c23205c84912386e10b86c561c8 patch-2.6.32.26.bz2
+f84f7b7a1529c95809e2eef3c4759dbd patch-2.6.32.34.bz2
+
diff --git a/xen.pvops.patch b/xen.pvops.patch
index c692097..d0a4429 100644
--- a/xen.pvops.patch
+++ b/xen.pvops.patch
@@ -1,5 +1,5 @@
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 5f6aa11..9ec8558 100644
+index c840e7d..9238f05 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -113,6 +113,7 @@ parameter is applicable:
@@ -10,7 +10,7 @@ index 5f6aa11..9ec8558 100644
In addition, the following text indicates that the option:
-@@ -2760,6 +2761,18 @@ and is between 256 and 4096 characters. It is defined in the file
+@@ -2765,6 +2766,18 @@ and is between 256 and 4096 characters. It is defined in the file
xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
xd_geo= See header of drivers/block/xd.c.
@@ -112,6 +112,32 @@ index 285aae8..53292ab 100644
dma_ops = &swiotlb_dma_ops;
#else
panic("Unable to find Intel IOMMU");
+diff --git a/arch/ia64/xen/suspend.c b/arch/ia64/xen/suspend.c
+index fd66b04..419c862 100644
+--- a/arch/ia64/xen/suspend.c
++++ b/arch/ia64/xen/suspend.c
+@@ -37,19 +37,14 @@ xen_mm_unpin_all(void)
+ /* nothing */
+ }
+
+-void xen_pre_device_suspend(void)
+-{
+- /* nothing */
+-}
+-
+ void
+-xen_pre_suspend()
++xen_arch_pre_suspend()
+ {
+ /* nothing */
+ }
+
+ void
+-xen_post_suspend(int suspend_cancelled)
++xen_arch_post_suspend(int suspend_cancelled)
+ {
+ if (suspend_cancelled)
+ return;
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index e281dae..80a973b 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
@@ -139,10 +165,10 @@ index 53bcf3d..b152de3 100644
paging_init();
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
-index 04f638d..df2c9e9 100644
+index 00d3b65..dc5eede 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
-@@ -550,7 +550,7 @@ void __init setup_arch(char **cmdline_p)
+@@ -559,7 +559,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_SWIOTLB
if (ppc_swiotlb_enable)
@@ -152,10 +178,10 @@ index 04f638d..df2c9e9 100644
paging_init();
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index cb5a57c..a3b7475 100644
+index 73ae02a..0266f87 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
-@@ -1885,6 +1885,10 @@ config PCI_OLPC
+@@ -1896,6 +1896,10 @@ config PCI_OLPC
def_bool y
depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY)
@@ -752,7 +778,7 @@ index d1f4a76..a81b0ed 100644
#define __pgprot(x) ((pgprot_t) { (x) } )
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
-index 13b1885..0aac25a 100644
+index 78bb4d7..2232bd2 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -551,6 +551,9 @@ static inline void native_set_iopl_mask(unsigned mask)
@@ -773,17 +799,6 @@ index 13b1885..0aac25a 100644
#endif /* CONFIG_PARAVIRT */
/*
-diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
-index 53235fd..daaacab 100644
---- a/arch/x86/include/asm/pvclock.h
-+++ b/arch/x86/include/asm/pvclock.h
-@@ -10,5 +10,6 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
- void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
- struct pvclock_vcpu_time_info *vcpu,
- struct timespec *ts);
-+void pvclock_resume(void);
-
- #endif /* _ASM_X86_PVCLOCK_H */
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 18e496c..154a5f1 100644
--- a/arch/x86/include/asm/setup.h
@@ -914,7 +929,7 @@ index 2c756fd..d8e7145 100644
extern struct x86_init_ops x86_init;
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
-index 9c371e4..41c4be0 100644
+index 9c371e4..8bd4e63 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -45,6 +45,8 @@
@@ -950,6 +965,15 @@ index 9c371e4..41c4be0 100644
static inline int
HYPERVISOR_set_trap_table(struct trap_info *table)
{
+@@ -270,7 +289,7 @@ HYPERVISOR_fpu_taskswitch(int set)
+ static inline int
+ HYPERVISOR_sched_op(int cmd, void *arg)
+ {
+- return _hypercall2(int, sched_op_new, cmd, arg);
++ return _hypercall2(int, sched_op, cmd, arg);
+ }
+
+ static inline long
@@ -282,6 +301,20 @@ HYPERVISOR_set_timer_op(u64 timeout)
}
@@ -971,7 +995,28 @@ index 9c371e4..41c4be0 100644
HYPERVISOR_set_debugreg(int reg, unsigned long value)
{
return _hypercall2(int, set_debugreg, reg, value);
-@@ -417,6 +450,12 @@ HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
+@@ -405,10 +438,17 @@ HYPERVISOR_set_segment_base(int reg, unsigned long value)
+ #endif
+
+ static inline int
+-HYPERVISOR_suspend(unsigned long srec)
++HYPERVISOR_suspend(unsigned long start_info_mfn)
+ {
+- return _hypercall3(int, sched_op, SCHEDOP_shutdown,
+- SHUTDOWN_suspend, srec);
++ struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
++
++ /*
++ * For a PV guest the tools require that the start_info mfn be
++ * present in rdx/edx when the hypercall is made. Per the
++ * hypercall calling convention this is the third hypercall
++ * argument, which is start_info_mfn here.
++ */
++ return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn);
+ }
+
+ static inline int
+@@ -417,6 +457,12 @@ HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
return _hypercall2(int, nmi_op, op, arg);
}
@@ -984,7 +1029,7 @@ index 9c371e4..41c4be0 100644
static inline void
MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
{
-@@ -424,6 +463,14 @@ MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
+@@ -424,6 +470,14 @@ MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
mcl->args[0] = set;
}
@@ -999,7 +1044,7 @@ index 9c371e4..41c4be0 100644
static inline void
MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
pte_t new_val, unsigned long flags)
-@@ -432,12 +479,11 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
+@@ -432,12 +486,11 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
mcl->args[0] = va;
if (sizeof(new_val) == sizeof(long)) {
mcl->args[1] = new_val.pte;
@@ -1134,7 +1179,7 @@ index 0000000..75df312
+#endif
+
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
-index 018a0a4..8760cc6 100644
+index 018a0a4..05c5cf5 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -5,6 +5,7 @@
@@ -1145,7 +1190,15 @@ index 018a0a4..8760cc6 100644
#include <asm/uaccess.h>
#include <asm/page.h>
-@@ -35,16 +36,25 @@ typedef struct xpaddr {
+@@ -28,23 +29,32 @@ typedef struct xpaddr {
+
+ /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+ #define INVALID_P2M_ENTRY (~0UL)
+-#define FOREIGN_FRAME_BIT (1UL<<31)
++#define FOREIGN_FRAME_BIT (1UL << (sizeof(unsigned long) * 8 - 1))
+ #define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
+
+ /* Maximum amount of memory we can handle in a domain in pages */
#define MAX_DOMAIN_PAGES \
((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))
@@ -1352,7 +1405,7 @@ index d1911ab..cfe00bc 100644
obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
-index 23c2da8..a2a5125 100644
+index 8ba08c7..90be997 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -42,6 +42,10 @@
@@ -1366,7 +1419,7 @@ index 23c2da8..a2a5125 100644
static int __initdata acpi_force = 0;
u32 acpi_rsdt_forced;
int acpi_disabled;
-@@ -149,6 +153,10 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled)
+@@ -150,6 +154,10 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled)
{
unsigned int ver = 0;
@@ -1377,7 +1430,7 @@ index 23c2da8..a2a5125 100644
if (!enabled) {
++disabled_cpus;
return;
-@@ -461,9 +469,13 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
+@@ -467,9 +475,13 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
*/
int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
{
@@ -1392,7 +1445,7 @@ index 23c2da8..a2a5125 100644
#ifdef CONFIG_PCI
/*
* Make sure all (legacy) PCI IRQs are set as level-triggered.
-@@ -740,6 +752,10 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
+@@ -746,6 +758,10 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
static void __init acpi_register_lapic_address(unsigned long address)
{
@@ -1403,7 +1456,7 @@ index 23c2da8..a2a5125 100644
mp_lapic_addr = address;
set_fixmap_nocache(FIX_APIC_BASE, address);
-@@ -860,6 +876,9 @@ int __init acpi_probe_gsi(void)
+@@ -866,6 +882,9 @@ int __init acpi_probe_gsi(void)
max_gsi = gsi;
}
@@ -1671,7 +1724,7 @@ index 082089e..8d34362 100644
} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
force_iommu ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
-index d850eeb..2e2cef4 100644
+index 8928d97..4848d5d 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -63,7 +63,12 @@
@@ -1760,7 +1813,7 @@ index d850eeb..2e2cef4 100644
}
#if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
-@@ -3859,7 +3895,14 @@ void __init probe_nr_irqs_gsi(void)
+@@ -3860,7 +3896,14 @@ void __init probe_nr_irqs_gsi(void)
printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}
@@ -1775,7 +1828,7 @@ index d850eeb..2e2cef4 100644
int __init arch_probe_nr_irqs(void)
{
int nr;
-@@ -3877,6 +3920,8 @@ int __init arch_probe_nr_irqs(void)
+@@ -3878,6 +3921,8 @@ int __init arch_probe_nr_irqs(void)
if (nr < nr_irqs)
nr_irqs = nr;
@@ -1909,7 +1962,7 @@ index 55da0c5..42f30cd 100644
+ .num_var_ranges = generic_num_var_ranges,
};
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
-index 84e83de..c8cb9ed 100644
+index 419e328..f5d9309 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -110,21 +110,6 @@ static int have_wrcomb(void)
@@ -2111,7 +2164,7 @@ index ff95824..ebd4c51 100644
static void kdump_nmi_callback(int cpu, struct die_args *args)
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
-index d17d482..4d0aded 100644
+index a89739a..5476113 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -750,6 +750,36 @@ static int __init find_overlapped_early(u64 start, u64 end)
@@ -2166,7 +2219,7 @@ index c097e7d..7764118 100644
#ifdef CONFIG_FUNCTION_TRACER
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
-index b5c061f..a626344 100644
+index 34a56a9..cba6d5a 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1364,6 +1364,9 @@ ENTRY(xen_failsafe_callback)
@@ -2180,20 +2233,21 @@ index b5c061f..a626344 100644
/*
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
-index 0b06cd7..f59b07a 100644
+index 0b06cd7..9c5f23e 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
-@@ -79,6 +79,8 @@ void __init x86_64_start_kernel(char * real_mode_data)
- /* Cleanup the over mapped high alias */
- cleanup_highmap();
+@@ -76,8 +76,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
+ /* Make NULL pointers segfault */
+ zap_identity_mappings();
+- /* Cleanup the over mapped high alias */
+- cleanup_highmap();
+ max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
-+
+
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) {
#ifdef CONFIG_EARLY_PRINTK
- set_intr_gate(i, &early_idt_handlers[i]);
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
-index c771e1a..8b970b8 100644
+index 69cab24..e791bb2 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -98,7 +98,7 @@ static int __init hpet_setup(char *str)
@@ -3069,22 +3123,6 @@ index 5fd5b07..11d8667 100644
}
int sys_fork(struct pt_regs *regs)
-diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
-index dfdfe46..b12fe8d 100644
---- a/arch/x86/kernel/pvclock.c
-+++ b/arch/x86/kernel/pvclock.c
-@@ -111,6 +111,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
-
- static atomic64_t last_value = ATOMIC64_INIT(0);
-
-+void pvclock_resume(void)
-+{
-+ atomic64_set(&last_value, 0);
-+}
-+
- cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
- {
- struct pvclock_shadow_time shadow;
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 200fcde..ff8cc40 100644
--- a/arch/x86/kernel/reboot.c
@@ -3108,7 +3146,7 @@ index 200fcde..ff8cc40 100644
}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
-index d7a0888..a85a61c 100644
+index 5449a26..719cfb0 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -70,6 +70,7 @@
@@ -3127,7 +3165,17 @@ index d7a0888..a85a61c 100644
#include <asm/system.h>
#include <asm/vsyscall.h>
-@@ -908,7 +910,6 @@ void __init setup_arch(char **cmdline_p)
+@@ -294,6 +296,9 @@ static void __init init_gbpages(void)
+ static inline void init_gbpages(void)
+ {
+ }
++static void __init cleanup_highmap(void)
++{
++}
+ #endif
+
+ static void __init reserve_brk(void)
+@@ -909,7 +914,6 @@ void __init setup_arch(char **cmdline_p)
max_low_pfn = max_pfn;
high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
@@ -3135,7 +3183,16 @@ index d7a0888..a85a61c 100644
#endif
#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
-@@ -966,6 +967,9 @@ void __init setup_arch(char **cmdline_p)
+@@ -921,6 +925,8 @@ void __init setup_arch(char **cmdline_p)
+
+ reserve_brk();
+
++ cleanup_highmap();
++
+ init_gbpages();
+
+ /* max_pfn_mapped is updated here */
+@@ -967,6 +973,9 @@ void __init setup_arch(char **cmdline_p)
initmem_init(0, max_pfn);
@@ -3145,7 +3202,7 @@ index d7a0888..a85a61c 100644
#ifdef CONFIG_ACPI_SLEEP
/*
* Reserve low memory region for sleep support.
-@@ -1034,6 +1038,7 @@ void __init setup_arch(char **cmdline_p)
+@@ -1037,6 +1046,7 @@ void __init setup_arch(char **cmdline_p)
probe_nr_irqs_gsi();
kvm_guest_init();
@@ -3205,7 +3262,7 @@ index 06630d2..ad895ae 100644
obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
-index 1739358..e003b83 100644
+index 8ac0d76..7e7dbd1 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -228,7 +228,16 @@ void vmalloc_sync_all(void)
@@ -3262,6 +3319,36 @@ index 71da1bc..892b8eb 100644
/*
* XXX: batch / limit 'nr', to avoid large irq off latency
* needs some instrumenting to determine the common sizes used by
+diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
+index 73ffd55..6bce215 100644
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -287,25 +287,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
+ load_cr3(swapper_pg_dir);
+ #endif
+
+-#ifdef CONFIG_X86_64
+- if (!after_bootmem && !start) {
+- pud_t *pud;
+- pmd_t *pmd;
+-
+- mmu_cr4_features = read_cr4();
+-
+- /*
+- * _brk_end cannot change anymore, but it and _end may be
+- * located on different 2M pages. cleanup_highmap(), however,
+- * can only consider _end when it runs, so destroy any
+- * mappings beyond _brk_end here.
+- */
+- pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
+- pmd = pmd_offset(pud, _brk_end - 1);
+- while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
+- pmd_clear(pmd);
+- }
+-#endif
+ __flush_tlb_all();
+
+ if (!after_bootmem && e820_table_end > e820_table_start)
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 30938c1..10c3719 100644
--- a/arch/x86/mm/init_32.c
@@ -3329,6 +3416,42 @@ index 30938c1..10c3719 100644
work_with_active_regions(nid, add_highpages_work_fn, &data);
}
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index 7d095ad..1584023 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -49,6 +49,7 @@
+ #include <asm/numa.h>
+ #include <asm/cacheflush.h>
+ #include <asm/init.h>
++#include <asm/setup.h>
+ #include <linux/bootmem.h>
+
+ static unsigned long dma_reserve __initdata;
+@@ -257,18 +258,18 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
+ * to the compile time generated pmds. This results in invalid pmds up
+ * to the point where we hit the physaddr 0 mapping.
+ *
+- * We limit the mappings to the region from _text to _end. _end is
+- * rounded up to the 2MB boundary. This catches the invalid pmds as
++ * We limit the mappings to the region from _text to _brk_end. _brk_end
++ * is rounded up to the 2MB boundary. This catches the invalid pmds as
+ * well, as they are located before _text:
+ */
+ void __init cleanup_highmap(void)
+ {
+ unsigned long vaddr = __START_KERNEL_map;
+- unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1;
++ unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped << PAGE_SHIFT);
++ unsigned long end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1;
+ pmd_t *pmd = level2_kernel_pgt;
+- pmd_t *last_pmd = pmd + PTRS_PER_PMD;
+
+- for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) {
++ for (; vaddr + PMD_SIZE - 1 < vaddr_end; pmd++, vaddr += PMD_SIZE) {
+ if (pmd_none(*pmd))
+ continue;
+ if (vaddr < (unsigned long) _text || vaddr > end)
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 2feb9bd..2601df2 100644
--- a/arch/x86/mm/ioremap.c
@@ -3359,7 +3482,7 @@ index e78cd0e..fb91994 100644
#ifdef CONFIG_STRICT_DEVMEM
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
-index c9ba9de..1fcc191 100644
+index e0e6fad..a0db43b 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -4,6 +4,9 @@
@@ -3422,7 +3545,7 @@ index c9ba9de..1fcc191 100644
}
static void pgd_dtor(pgd_t *pgd)
-@@ -271,7 +298,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+@@ -270,7 +297,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
*/
spin_lock_irqsave(&pgd_lock, flags);
@@ -3431,7 +3554,7 @@ index c9ba9de..1fcc191 100644
pgd_prepopulate_pmd(mm, pgd, pmds);
spin_unlock_irqrestore(&pgd_lock, flags);
-@@ -288,6 +315,12 @@ out:
+@@ -287,6 +314,12 @@ out:
void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
@@ -3908,7 +4031,7 @@ index 0000000..21a3089
+#endif
+}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
-index 7f8d2b2..fbb35cd 100644
+index 0087b00..7a48c0b 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -11,6 +11,7 @@
@@ -4095,13 +4218,13 @@ index 7f8d2b2..fbb35cd 100644
- set_in_cr4(X86_CR4_OSXSAVE);
-
- cr4 = read_cr4();
+-
+- if ((cr4 & X86_CR4_OSXSAVE) == 0)
+- cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32));
+ xsave_mask =
+ (1 << (X86_FEATURE_XSAVE % 32)) |
+ (1 << (X86_FEATURE_OSXSAVE % 32));
-- if ((cr4 & X86_CR4_OSXSAVE) == 0)
-- cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32));
--
- clear_in_cr4(X86_CR4_OSXSAVE);
- }
+ /* Xen will set CR4.OSXSAVE if supported and not disabled by force */
@@ -4215,18 +4338,7 @@ index 7f8d2b2..fbb35cd 100644
.io_delay = xen_io_delay,
/* Xen takes care of %gs when switching to usermode for us */
-@@ -997,10 +1030,6 @@ static void xen_reboot(int reason)
- {
- struct sched_shutdown r = { .reason = reason };
-
--#ifdef CONFIG_SMP
-- stop_other_cpus();
--#endif
--
- if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
- BUG();
- }
-@@ -1020,15 +1049,40 @@ static void xen_machine_halt(void)
+@@ -1016,15 +1049,40 @@ static void xen_machine_halt(void)
xen_reboot(SHUTDOWN_poweroff);
}
@@ -4268,7 +4380,7 @@ index 7f8d2b2..fbb35cd 100644
.shutdown = xen_machine_halt,
.crash_shutdown = xen_crash_shutdown,
.emergency_restart = xen_emergency_restart,
-@@ -1061,10 +1115,11 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1057,10 +1115,11 @@ asmlinkage void __init xen_start_kernel(void)
xen_domain_type = XEN_PV_DOMAIN;
@@ -4281,7 +4393,7 @@ index 7f8d2b2..fbb35cd 100644
pv_cpu_ops = xen_cpu_ops;
pv_apic_ops = xen_apic_ops;
-@@ -1072,13 +1127,7 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1068,13 +1127,7 @@ asmlinkage void __init xen_start_kernel(void)
x86_init.oem.arch_setup = xen_arch_setup;
x86_init.oem.banner = xen_banner;
@@ -4296,7 +4408,7 @@ index 7f8d2b2..fbb35cd 100644
/*
* Set up some pagetable state before starting to set any ptes.
-@@ -1116,6 +1165,10 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1112,6 +1165,10 @@ asmlinkage void __init xen_start_kernel(void)
*/
xen_setup_stackprotector();
@@ -4307,8 +4419,19 @@ index 7f8d2b2..fbb35cd 100644
xen_init_irq_ops();
xen_init_cpuid_mask();
-@@ -1144,6 +1197,8 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1138,8 +1195,19 @@ asmlinkage void __init xen_start_kernel(void)
+
+ xen_smp_init();
++#ifdef CONFIG_ACPI_NUMA
++ /*
++ * The pages we from Xen are not related to machine pages, so
++ * any NUMA information the kernel tries to get from ACPI will
++ * be meaningless. Prevent it from trying.
++ */
++ acpi_numa = -1;
++#endif
++
pgd = (pgd_t *)xen_start_info->pt_base;
+ __supported_pte_mask |= _PAGE_IOMAP;
@@ -4316,7 +4439,7 @@ index 7f8d2b2..fbb35cd 100644
/* Don't do the full vcpu_info placement stuff until we have a
possible map and a non-dummy shared_info. */
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
-@@ -1153,6 +1208,10 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1149,6 +1217,10 @@ asmlinkage void __init xen_start_kernel(void)
xen_raw_console_write("mapping kernel into physical memory\n");
pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
@@ -4327,7 +4450,7 @@ index 7f8d2b2..fbb35cd 100644
init_mm.pgd = pgd;
-@@ -1162,6 +1221,14 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1158,6 +1230,14 @@ asmlinkage void __init xen_start_kernel(void)
if (xen_feature(XENFEAT_supervisor_mode_kernel))
pv_info.kernel_rpl = 0;
@@ -4342,7 +4465,7 @@ index 7f8d2b2..fbb35cd 100644
/* set the limit of our address space */
xen_reserve_top();
-@@ -1184,6 +1251,16 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1180,6 +1260,16 @@ asmlinkage void __init xen_start_kernel(void)
add_preferred_console("xenboot", 0, NULL);
add_preferred_console("tty", 0, NULL);
add_preferred_console("hvc", 0, NULL);
@@ -4359,7 +4482,7 @@ index 7f8d2b2..fbb35cd 100644
}
xen_raw_console_write("about to get started...\n");
-@@ -1197,3 +1274,126 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1193,3 +1283,128 @@ asmlinkage void __init xen_start_kernel(void)
x86_64_start_reservations((char *)__pa_symbol(&boot_params));
#endif
}
@@ -4405,8 +4528,7 @@ index 7f8d2b2..fbb35cd 100644
+
+ xen_setup_features();
+
-+ pv_info = xen_info;
-+ pv_info.kernel_rpl = 0;
++ pv_info.name = "Xen HVM";
+
+ xen_domain_type = XEN_HVM_DOMAIN;
+
@@ -4451,6 +4573,8 @@ index 7f8d2b2..fbb35cd 100644
+ switch (action) {
+ case CPU_UP_PREPARE:
+ per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
++ if (xen_have_vector_callback)
++ xen_init_lock_cpu(cpu);
+ break;
+ default:
+ break;
@@ -4478,6 +4602,7 @@ index 7f8d2b2..fbb35cd 100644
+
+ if (xen_feature(XENFEAT_hvm_callback_vector))
+ xen_have_vector_callback = 1;
++ xen_hvm_smp_init();
+ register_cpu_notifier(&xen_hvm_cpu_notifier);
+ xen_unplug_emulated_devices();
+ have_vcpu_info_placement = 0;
@@ -4487,7 +4612,7 @@ index 7f8d2b2..fbb35cd 100644
+}
+#endif
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
-index 350a3de..0fa0445 100644
+index 350a3de..fa36ab8 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -42,6 +42,7 @@
@@ -4623,9 +4748,8 @@ index 350a3de..0fa0445 100644
{
- return pfn % P2M_ENTRIES_PER_PAGE;
+ return pfn % P2M_PER_PAGE;
- }
-
--/* Build the parallel p2m_top_mfn structures */
++}
++
+static void p2m_top_init(unsigned long ***top)
+{
+ unsigned i;
@@ -4672,8 +4796,9 @@ index 350a3de..0fa0445 100644
+
+ for (i = 0; i < P2M_MID_PER_PAGE; i++)
+ p2m[i] = INVALID_P2M_ENTRY;
-+}
-+
+ }
+
+-/* Build the parallel p2m_top_mfn structures */
+static int lookup_pte_fn(
+ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
+{
@@ -4715,11 +4840,11 @@ index 350a3de..0fa0445 100644
+ if (p2m_top_mfn == NULL) {
+ p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_mid_mfn_init(p2m_mid_missing_mfn);
-+
-+ p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
-+ p2m_top_mfn_p_init(p2m_top_mfn_p);
- p2m_top_mfn[topidx] = virt_to_mfn(p2m_top[topidx]);
++ p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
++ p2m_top_mfn_p_init(p2m_top_mfn_p);
++
+ p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_top_mfn_init(p2m_top_mfn);
+ } else {
@@ -4780,7 +4905,7 @@ index 350a3de..0fa0445 100644
}
/* Set up p2m_top to point to the domain-builder provided p2m pages */
-@@ -215,98 +383,176 @@ void __init xen_build_dynamic_phys_to_machine(void)
+@@ -215,98 +383,188 @@ void __init xen_build_dynamic_phys_to_machine(void)
{
unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list;
unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages);
@@ -4791,11 +4916,11 @@ index 350a3de..0fa0445 100644
+
+ p2m_missing = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_init(p2m_missing);
-+
-+ p2m_mid_missing = extend_brk(PAGE_SIZE, PAGE_SIZE);
-+ p2m_mid_init(p2m_mid_missing);
- for (pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES_PER_PAGE) {
++ p2m_mid_missing = extend_brk(PAGE_SIZE, PAGE_SIZE);
++ p2m_mid_init(p2m_mid_missing);
++
+ p2m_top = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_top_init(p2m_top);
+
@@ -4813,11 +4938,23 @@ index 350a3de..0fa0445 100644
+ if (p2m_top[topidx] == p2m_mid_missing) {
+ unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE);
+ p2m_mid_init(mid);
-+
-+ p2m_top[topidx] = mid;
-+ }
- xen_build_mfn_list_list();
++ p2m_top[topidx] = mid;
++ }
++
++ /*
++ * As long as the mfn_list has enough entries to completely
++ * fill a p2m page, pointing into the array is ok. But if
++ * not the entries beyond the last pfn will be undefined.
++ */
++ if (unlikely(pfn + P2M_PER_PAGE > max_pfn)) {
++ unsigned long p2midx;
++
++ p2midx = max_pfn % P2M_PER_PAGE;
++ for ( ; p2midx < P2M_PER_PAGE; p2midx++)
++ mfn_list[pfn + p2midx] = INVALID_P2M_ENTRY;
++ }
+ p2m_top[topidx][mididx] = &mfn_list[pfn];
+ }
}
@@ -4911,7 +5048,9 @@ index 350a3de..0fa0445 100644
+ mid_mfn = alloc_p2m_page();
+ if (!mid_mfn)
+ return false;
-+
+
+- p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
+- BUG_ON(p == NULL);
+ p2m_mid_mfn_init(mid_mfn);
+
+ missing_mfn = virt_to_mfn(p2m_mid_missing_mfn);
@@ -4921,15 +5060,11 @@ index 350a3de..0fa0445 100644
+ else
+ p2m_top_mfn_p[topidx] = mid_mfn;
+ }
-
-- p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
-- BUG_ON(p == NULL);
++
+ if (p2m_top[topidx][mididx] == p2m_missing) {
+ /* p2m leaf page is missing */
+ unsigned long *p2m;
-
-- if (!install_p2mtop_page(pfn, p))
-- free_page((unsigned long)p);
++
+ p2m = alloc_p2m_page();
+ if (!p2m)
+ return false;
@@ -4941,7 +5076,9 @@ index 350a3de..0fa0445 100644
+ else
+ mid_mfn[mididx] = virt_to_mfn(p2m);
+ }
-+
+
+- if (!install_p2mtop_page(pfn, p))
+- free_page((unsigned long)p);
+ return true;
}
@@ -4999,7 +5136,7 @@ index 350a3de..0fa0445 100644
}
unsigned long arbitrary_virt_to_mfn(void *vaddr)
-@@ -315,6 +561,7 @@ unsigned long arbitrary_virt_to_mfn(void *vaddr)
+@@ -315,6 +573,7 @@ unsigned long arbitrary_virt_to_mfn(void *vaddr)
return PFN_DOWN(maddr.maddr);
}
@@ -5007,7 +5144,7 @@ index 350a3de..0fa0445 100644
xmaddr_t arbitrary_virt_to_machine(void *vaddr)
{
-@@ -345,7 +592,8 @@ void make_lowmem_page_readonly(void *vaddr)
+@@ -345,7 +604,8 @@ void make_lowmem_page_readonly(void *vaddr)
unsigned int level;
pte = lookup_address(address, &level);
@@ -5017,7 +5154,7 @@ index 350a3de..0fa0445 100644
ptev = pte_wrprotect(*pte);
-@@ -360,7 +608,8 @@ void make_lowmem_page_readwrite(void *vaddr)
+@@ -360,7 +620,8 @@ void make_lowmem_page_readwrite(void *vaddr)
unsigned int level;
pte = lookup_address(address, &level);
@@ -5027,15 +5164,10 @@ index 350a3de..0fa0445 100644
ptev = pte_mkwrite(*pte);
-@@ -376,6 +625,34 @@ static bool xen_page_pinned(void *ptr)
+@@ -376,6 +637,24 @@ static bool xen_page_pinned(void *ptr)
return PagePinned(page);
}
-+static bool xen_iomap_pte(pte_t pte)
-+{
-+ return pte_flags(pte) & _PAGE_IOMAP;
-+}
-+
+void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid)
+{
+ struct multicall_space mcs;
@@ -5054,27 +5186,10 @@ index 350a3de..0fa0445 100644
+}
+EXPORT_SYMBOL_GPL(xen_set_domain_pte);
+
-+static void xen_set_iomap_pte(pte_t *ptep, pte_t pteval)
-+{
-+ xen_set_domain_pte(ptep, pteval, DOMID_IO);
-+}
-+
static void xen_extend_mmu_update(const struct mmu_update *update)
{
struct multicall_space mcs;
-@@ -452,6 +729,11 @@ void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
- void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pteval)
- {
-+ if (xen_iomap_pte(pteval)) {
-+ xen_set_iomap_pte(ptep, pteval);
-+ goto out;
-+ }
-+
- ADD_STATS(set_pte_at, 1);
- // ADD_STATS(set_pte_at_pinned, xen_page_pinned(ptep));
- ADD_STATS(set_pte_at_current, mm == current->mm);
-@@ -516,7 +798,34 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
+@@ -516,7 +795,34 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
if (val & _PAGE_PRESENT) {
unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
pteval_t flags = val & PTE_FLAGS_MASK;
@@ -5110,7 +5225,7 @@ index 350a3de..0fa0445 100644
}
return val;
-@@ -524,7 +833,18 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
+@@ -524,7 +830,18 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
pteval_t xen_pte_val(pte_t pte)
{
@@ -5130,7 +5245,7 @@ index 350a3de..0fa0445 100644
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
-@@ -534,9 +854,62 @@ pgdval_t xen_pgd_val(pgd_t pgd)
+@@ -534,9 +851,62 @@ pgdval_t xen_pgd_val(pgd_t pgd)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pgd_val);
@@ -5194,31 +5309,7 @@ index 350a3de..0fa0445 100644
return native_make_pte(pte);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
-@@ -592,6 +965,11 @@ void xen_set_pud(pud_t *ptr, pud_t val)
-
- void xen_set_pte(pte_t *ptep, pte_t pte)
- {
-+ if (xen_iomap_pte(pte)) {
-+ xen_set_iomap_pte(ptep, pte);
-+ return;
-+ }
-+
- ADD_STATS(pte_update, 1);
- // ADD_STATS(pte_update_pinned, xen_page_pinned(ptep));
- ADD_STATS(pte_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);
-@@ -608,6 +986,11 @@ void xen_set_pte(pte_t *ptep, pte_t pte)
- #ifdef CONFIG_X86_PAE
- void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
- {
-+ if (xen_iomap_pte(pte)) {
-+ xen_set_iomap_pte(ptep, pte);
-+ return;
-+ }
-+
- set_64bit((u64 *)ptep, native_pte_val(pte));
- }
-
-@@ -934,8 +1317,6 @@ static int xen_pin_page(struct mm_struct *mm, struct page *page,
+@@ -934,8 +1304,6 @@ static int xen_pin_page(struct mm_struct *mm, struct page *page,
read-only, and can be pinned. */
static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd)
{
@@ -5227,7 +5318,7 @@ index 350a3de..0fa0445 100644
xen_mc_batch();
if (__xen_pgd_walk(mm, pgd, xen_pin_page, USER_LIMIT)) {
-@@ -1219,7 +1600,7 @@ void xen_exit_mmap(struct mm_struct *mm)
+@@ -1219,7 +1587,7 @@ void xen_exit_mmap(struct mm_struct *mm)
spin_lock(&mm->page_table_lock);
/* pgd may not be pinned in the error exit path of execve */
@@ -5236,7 +5327,7 @@ index 350a3de..0fa0445 100644
xen_pgd_unpin(mm);
spin_unlock(&mm->page_table_lock);
-@@ -1288,12 +1669,19 @@ static void xen_flush_tlb_single(unsigned long addr)
+@@ -1288,12 +1656,19 @@ static void xen_flush_tlb_single(unsigned long addr)
preempt_enable();
}
@@ -5257,7 +5348,7 @@ index 350a3de..0fa0445 100644
} *args;
struct multicall_space mcs;
-@@ -1417,6 +1805,13 @@ static int xen_pgd_alloc(struct mm_struct *mm)
+@@ -1417,6 +1792,13 @@ static int xen_pgd_alloc(struct mm_struct *mm)
return ret;
}
@@ -5271,7 +5362,7 @@ index 350a3de..0fa0445 100644
static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
#ifdef CONFIG_X86_64
-@@ -1445,13 +1840,29 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
+@@ -1445,13 +1827,29 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
}
#endif
@@ -5304,7 +5395,7 @@ index 350a3de..0fa0445 100644
return pte;
}
-@@ -1464,7 +1875,6 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
+@@ -1464,7 +1862,6 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
xen_set_pte(ptep, pte);
}
@@ -5312,7 +5403,7 @@ index 350a3de..0fa0445 100644
static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
{
-@@ -1517,7 +1927,6 @@ static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned l
+@@ -1517,7 +1914,6 @@ static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned l
if (PagePinned(virt_to_page(mm->pgd))) {
SetPagePinned(page);
@@ -5320,7 +5411,7 @@ index 350a3de..0fa0445 100644
if (!PageHighMem(page)) {
make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn)));
if (level == PT_PTE && USE_SPLIT_PTLOCKS)
-@@ -1620,6 +2029,7 @@ static void *m2v(phys_addr_t maddr)
+@@ -1620,6 +2016,7 @@ static void *m2v(phys_addr_t maddr)
return __ka(m2p(maddr));
}
@@ -5328,7 +5419,7 @@ index 350a3de..0fa0445 100644
static void set_page_prot(void *addr, pgprot_t prot)
{
unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
-@@ -1635,6 +2045,9 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+@@ -1635,6 +2032,9 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
unsigned ident_pte;
unsigned long pfn;
@@ -5338,7 +5429,7 @@ index 350a3de..0fa0445 100644
ident_pte = 0;
pfn = 0;
for (pmdidx = 0; pmdidx < PTRS_PER_PMD && pfn < max_pfn; pmdidx++) {
-@@ -1645,7 +2058,7 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+@@ -1645,7 +2045,7 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
pte_page = m2v(pmd[pmdidx].pmd);
else {
/* Check for free pte pages */
@@ -5347,7 +5438,17 @@ index 350a3de..0fa0445 100644
break;
pte_page = &level1_ident_pgt[ident_pte];
-@@ -1675,6 +2088,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+@@ -1658,9 +2058,6 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+ for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
+ pte_t pte;
+
+- if (pfn > max_pfn_mapped)
+- max_pfn_mapped = pfn;
+-
+ if (!pte_none(pte_page[pteidx]))
+ continue;
+
+@@ -1675,6 +2072,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
set_page_prot(pmd, PAGE_KERNEL_RO);
}
@@ -5368,7 +5469,20 @@ index 350a3de..0fa0445 100644
#ifdef CONFIG_X86_64
static void convert_pfn_mfn(void *v)
{
-@@ -1760,12 +2187,15 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1704,6 +2115,12 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+ pud_t *l3;
+ pmd_t *l2;
+
++ /* max_pfn_mapped is the last pfn mapped in the initial memory
++ * mappings. Considering that on Xen after the kernel mappings we
++ * have the mappings of some pages that don't exist in pfn space, we
++ * set max_pfn_mapped to the last real pfn mapped. */
++ max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list));
++
+ /* Zap identity mapping */
+ init_level4_pgt[0] = __pgd(0);
+
+@@ -1760,16 +2177,17 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
return pgd;
}
#else /* !CONFIG_X86_64 */
@@ -5380,12 +5494,17 @@ index 350a3de..0fa0445 100644
{
pmd_t *kernel_pmd;
+ int i;
-+
+
+- max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
+- xen_start_info->nr_pt_frames * PAGE_SIZE +
+- 512*1024);
+ level2_kernel_pgt = extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
++
++ max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list));
- max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
- xen_start_info->nr_pt_frames * PAGE_SIZE +
-@@ -1777,6 +2207,20 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+ kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
+ memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
+@@ -1777,6 +2195,20 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
xen_map_identity_early(level2_kernel_pgt, max_pfn);
memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
@@ -5406,7 +5525,7 @@ index 350a3de..0fa0445 100644
set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
__pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
-@@ -1799,6 +2243,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1799,6 +2231,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
}
#endif /* CONFIG_X86_64 */
@@ -5415,7 +5534,7 @@ index 350a3de..0fa0445 100644
static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
{
pte_t pte;
-@@ -1828,9 +2274,26 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
+@@ -1828,9 +2262,26 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
pte = pfn_pte(phys, prot);
break;
@@ -5443,7 +5562,7 @@ index 350a3de..0fa0445 100644
}
__native_set_fixmap(idx, pte);
-@@ -1845,6 +2308,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
+@@ -1845,6 +2296,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
#endif
}
@@ -5473,7 +5592,7 @@ index 350a3de..0fa0445 100644
static __init void xen_post_allocator_init(void)
{
pv_mmu_ops.set_pte = xen_set_pte;
-@@ -1907,11 +2393,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
+@@ -1907,11 +2381,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
.kmap_atomic_pte = xen_kmap_atomic_pte,
#endif
@@ -5485,7 +5604,7 @@ index 350a3de..0fa0445 100644
.set_pte_at = xen_set_pte_at,
.set_pmd = xen_set_pmd_hyper,
-@@ -1960,8 +2442,305 @@ void __init xen_init_mmu_ops(void)
+@@ -1960,8 +2430,305 @@ void __init xen_init_mmu_ops(void)
x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start;
x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
pv_mmu_ops = xen_mmu_ops;
@@ -5519,8 +5638,8 @@ index 350a3de..0fa0445 100644
+ out_frames[i] = virt_to_pfn(vaddr);
+ }
+ xen_mc_issue(0);
- }
-
++}
++
+/*
+ * Update the pfn-to-mfn mappings for a virtual address range, either to
+ * point to an array of mfns, or contiguously from a single starting
@@ -5562,8 +5681,8 @@ index 350a3de..0fa0445 100644
+ }
+
+ xen_mc_issue(0);
-+}
-+
+ }
+
+/*
+ * Perform the hypercall to exchange a region of our pfns to point to
+ * memory with the required contiguous alignment. Takes the pfns as
@@ -6319,7 +6438,7 @@ index 0000000..0f45638
+early_param("xen_emul_unplug", parse_xen_emul_unplug);
+#endif
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
-index ad0047f..1a1934a 100644
+index ad0047f..c011a7d 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -10,6 +10,7 @@
@@ -6340,7 +6459,7 @@ index ad0047f..1a1934a 100644
#include <xen/features.h>
#include "xen-ops.h"
-@@ -32,25 +35,178 @@ extern void xen_sysenter_target(void);
+@@ -32,25 +35,192 @@ extern void xen_sysenter_target(void);
extern void xen_syscall_target(void);
extern void xen_syscall32_target(void);
@@ -6487,19 +6606,34 @@ index ad0047f..1a1934a 100644
+ BUG_ON(rc);
e820.nr_map = 0;
+-
+- e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
+ xen_extra_mem_start = mem_end;
+ for (i = 0; i < memmap.nr_entries; i++) {
-+ unsigned long long end = map[i].addr + map[i].size;
++ unsigned long long end;
++
++ /* Guard against non-page aligned E820 entries. */
++ if (map[i].type == E820_RAM)
++ map[i].size -= (map[i].size + map[i].addr) % PAGE_SIZE;
+
++ end = map[i].addr + map[i].size;
+ if (map[i].type == E820_RAM && end > mem_end) {
+ /* RAM off the end - may be partially included */
+ u64 delta = min(map[i].size, end - mem_end);
-
-- e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
++
+ map[i].size -= delta;
+ end -= delta;
+
+ extra_pages += PFN_DOWN(delta);
++ /*
++ * Set RAM below 4GB that is not for us to be unusable.
++ * This prevents "System RAM" address space from being
++ * used as potential resource for I/O address (happens
++ * when 'allocate_resource' is called).
++ */
++ if (delta &&
++ (xen_initial_domain() && end < 0x100000000ULL))
++ e820_add_region(end, delta, E820_UNUSABLE);
+ }
+
+ if (map[i].size > 0 && end > xen_extra_mem_start)
@@ -6523,7 +6657,7 @@ index ad0047f..1a1934a 100644
*/
e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS,
E820_RESERVED);
-@@ -67,21 +223,30 @@ char * __init xen_memory_setup(void)
+@@ -67,21 +237,30 @@ char * __init xen_memory_setup(void)
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
@@ -6568,7 +6702,7 @@ index ad0047f..1a1934a 100644
}
/*
-@@ -156,6 +321,8 @@ void __init xen_arch_setup(void)
+@@ -156,6 +335,8 @@ void __init xen_arch_setup(void)
struct physdev_set_iopl set_iopl;
int rc;
@@ -6577,7 +6711,7 @@ index ad0047f..1a1934a 100644
HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
-@@ -182,13 +349,21 @@ void __init xen_arch_setup(void)
+@@ -182,13 +363,21 @@ void __init xen_arch_setup(void)
}
#endif
@@ -6603,7 +6737,7 @@ index ad0047f..1a1934a 100644
fiddle_vdso();
}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
-index ca5f56e..3e06a9e 100644
+index ca5f56e..5da69a7 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -178,11 +178,18 @@ static void __init xen_smp_prepare_boot_cpu(void)
@@ -6643,16 +6777,69 @@ index ca5f56e..3e06a9e 100644
HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
BUG();
}
+@@ -479,3 +490,41 @@ void __init xen_smp_init(void)
+ xen_fill_possible_map();
+ xen_init_spinlocks();
+ }
++
++static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
++{
++ native_smp_prepare_cpus(max_cpus);
++ WARN_ON(xen_smp_intr_init(0));
++
++ if (!xen_have_vector_callback)
++ return;
++ xen_init_lock_cpu(0);
++ xen_init_spinlocks();
++}
++
++static int __cpuinit xen_hvm_cpu_up(unsigned int cpu)
++{
++ int rc;
++ rc = native_cpu_up(cpu);
++ WARN_ON (xen_smp_intr_init(cpu));
++ return rc;
++}
++
++static void xen_hvm_cpu_die(unsigned int cpu)
++{
++ unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
++ unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
++ unbind_from_irqhandler(per_cpu(debug_irq, cpu), NULL);
++ unbind_from_irqhandler(per_cpu(callfuncsingle_irq, cpu), NULL);
++ native_cpu_die(cpu);
++}
++
++void __init xen_hvm_smp_init(void)
++{
++ smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus;
++ smp_ops.smp_send_reschedule = xen_smp_send_reschedule;
++ smp_ops.cpu_up = xen_hvm_cpu_up;
++ smp_ops.cpu_die = xen_hvm_cpu_die;
++ smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi;
++ smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi;
++}
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
-index a9c6611..1d789d5 100644
+index a9c6611..6c43a90f 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
-@@ -26,6 +26,18 @@ void xen_pre_suspend(void)
+@@ -12,7 +12,7 @@
+ #include "xen-ops.h"
+ #include "mmu.h"
+
+-void xen_pre_suspend(void)
++void xen_arch_pre_suspend(void)
+ {
+ xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
+ xen_start_info->console.domU.mfn =
+@@ -26,7 +26,21 @@ void xen_pre_suspend(void)
BUG();
}
-+void xen_hvm_post_suspend(int suspend_cancelled)
+-void xen_post_suspend(int suspend_cancelled)
++void xen_arch_hvm_post_suspend(int suspend_cancelled)
+{
++#ifdef CONFIG_XEN_PVHVM
+ int cpu;
+ xen_hvm_init_shared_info();
+ xen_callback_vector();
@@ -6661,13 +6848,15 @@ index a9c6611..1d789d5 100644
+ xen_setup_runstate_info(cpu);
+ }
+ }
++#endif
+}
+
- void xen_post_suspend(int suspend_cancelled)
++void xen_arch_post_suspend(int suspend_cancelled)
{
xen_build_mfn_list_list();
+
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
-index 8e04980..ab35140 100644
+index 3e81716..bd3e3c4 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -19,6 +19,7 @@
@@ -6732,16 +6921,7 @@ index 8e04980..ab35140 100644
}
void xen_teardown_timer(int cpu)
-@@ -424,6 +441,8 @@ void xen_timer_resume(void)
- {
- int cpu;
-
-+ pvclock_resume();
-+
- if (xen_clockevent != &xen_vcpuop_clockevent)
- return;
-
-@@ -433,7 +452,7 @@ void xen_timer_resume(void)
+@@ -435,7 +452,7 @@ void xen_timer_resume(void)
}
}
@@ -6750,7 +6930,7 @@ index 8e04980..ab35140 100644
{
int cpu = smp_processor_id();
-@@ -457,3 +476,51 @@ __init void xen_time_init(void)
+@@ -459,3 +476,52 @@ __init void xen_time_init(void)
xen_setup_timer(cpu);
xen_setup_cpu_clockevents();
}
@@ -6784,8 +6964,9 @@ index 8e04980..ab35140 100644
+__init void xen_hvm_init_time_ops(void)
+{
+ /* vector callback is needed otherwise we cannot receive interrupts
-+ * on cpu > 0 */
-+ if (!xen_have_vector_callback && num_present_cpus() > 1)
++ * on cpu > 0 and at this point we don't know how many cpus are
++ * available */
++ if (!xen_have_vector_callback)
+ return;
+ if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
+ printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
@@ -6876,7 +7057,7 @@ index 0000000..1cd7f4d
+ }
+}
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
-index f9153a3..ebbee21 100644
+index f9153a3..e860de7 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -30,6 +30,10 @@ void xen_setup_machphys_mapping(void);
@@ -6915,7 +7096,20 @@ index f9153a3..ebbee21 100644
irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
-@@ -82,6 +87,23 @@ static inline void xen_uninit_lock_cpu(int cpu)
+@@ -60,10 +65,12 @@ void xen_setup_vcpu_info_placement(void);
+
+ #ifdef CONFIG_SMP
+ void xen_smp_init(void);
++void __init xen_hvm_smp_init(void);
+
+ extern cpumask_var_t xen_cpu_initialized_map;
+ #else
+ static inline void xen_smp_init(void) {}
++static inline void xen_hvm_smp_init(void) {}
+ #endif
+
+ #ifdef CONFIG_PARAVIRT_SPINLOCKS
+@@ -82,6 +89,23 @@ static inline void xen_uninit_lock_cpu(int cpu)
}
#endif
@@ -6939,7 +7133,7 @@ index f9153a3..ebbee21 100644
/* Declare an asm function, along with symbols needed to make it
inlineable */
#define DECL_ASM(ret, name, ...) \
-@@ -101,4 +123,6 @@ void xen_sysret32(void);
+@@ -101,4 +125,6 @@ void xen_sysret32(void);
void xen_sysret64(void);
void xen_adjust_exception_frame(void);
@@ -7970,7 +8164,7 @@ index 1d886e0..f4a2b10 100644
This driver implements the front-end of the Xen virtual
block device driver. It communicates with a back-end driver
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
-index b8578bb..44059e6 100644
+index b8578bb..70f3b1b 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -42,10 +42,12 @@
@@ -7986,6 +8180,15 @@ index b8578bb..44059e6 100644
#include <xen/interface/grant_table.h>
#include <xen/interface/io/blkif.h>
+@@ -67,7 +69,7 @@ struct blk_shadow {
+
+ static const struct block_device_operations xlvbd_block_fops;
+
+-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
++#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
+
+ /*
+ * We have one of these per vbd, whether ide, scsi or 'other'. They
@@ -76,6 +78,7 @@ static const struct block_device_operations xlvbd_block_fops;
*/
struct blkfront_info
@@ -8202,7 +8405,7 @@ index b8578bb..44059e6 100644
unsigned int offset;
int minor;
int nr_parts;
-@@ -406,21 +526,33 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+@@ -406,21 +526,32 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
}
if (!VDEV_IS_EXTENDED(info->vdevice)) {
@@ -8216,11 +8419,10 @@ index b8578bb..44059e6 100644
minor = BLKIF_MINOR_EXT(info->vdevice);
nr_parts = PARTS_PER_EXT_DISK;
+ offset = minor / nr_parts;
-+ if (xen_hvm_domain() && minor >= EMULATED_HD_DISK_MINOR_OFFSET) {
++ if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4)
+ printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with "
-+ "emulated IDE and SCSI disks; ignoring", info->vdevice);
-+ return -ENODEV;
-+ }
++ "emulated IDE disks,\n\t choose an xvd device name"
++ "from xvde on\n", info->vdevice);
}
+ err = -ENODEV;
@@ -8241,7 +8443,7 @@ index b8578bb..44059e6 100644
if (nr_minors > 1) {
if (offset < 26)
-@@ -447,16 +579,15 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+@@ -447,16 +578,15 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
gd->driverfs_dev = &(info->xbdev->dev);
set_capacity(gd, capacity);
@@ -8261,7 +8463,7 @@ index b8578bb..44059e6 100644
if (vdisk_info & VDISK_READONLY)
set_disk_ro(gd, 1);
-@@ -469,10 +600,45 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+@@ -469,10 +599,45 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
return 0;
@@ -8307,7 +8509,7 @@ index b8578bb..44059e6 100644
static void kick_pending_request_queues(struct blkfront_info *info)
{
if (!RING_FULL(&info->ring)) {
-@@ -487,16 +653,16 @@ static void blkif_restart_queue(struct work_struct *work)
+@@ -487,16 +652,16 @@ static void blkif_restart_queue(struct work_struct *work)
{
struct blkfront_info *info = container_of(work, struct blkfront_info, work);
@@ -8327,7 +8529,7 @@ index b8578bb..44059e6 100644
info->connected = suspend ?
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
/* No more blkif_request(). */
-@@ -504,7 +670,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
+@@ -504,7 +669,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
blk_stop_queue(info->rq);
/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
@@ -8336,7 +8538,7 @@ index b8578bb..44059e6 100644
/* Flush gnttab callback work. Must be done with no locks held. */
flush_scheduled_work();
-@@ -529,21 +695,20 @@ static void blkif_completion(struct blk_shadow *s)
+@@ -529,21 +694,20 @@ static void blkif_completion(struct blk_shadow *s)
gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL);
}
@@ -8364,7 +8566,7 @@ index b8578bb..44059e6 100644
again:
rp = info->ring.sring->rsp_prod;
-@@ -567,7 +732,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
+@@ -567,7 +731,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
info->gd->disk_name);
error = -EOPNOTSUPP;
@@ -8373,7 +8575,7 @@ index b8578bb..44059e6 100644
xlvbd_barrier(info);
}
/* fall through */
-@@ -596,7 +761,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
+@@ -596,7 +760,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
kick_pending_request_queues(info);
@@ -8392,7 +8594,7 @@ index b8578bb..44059e6 100644
return IRQ_HANDLED;
}
-@@ -650,7 +825,7 @@ fail:
+@@ -650,7 +824,7 @@ fail:
/* Common code used when first setting up, and when resuming. */
@@ -8401,7 +8603,7 @@ index b8578bb..44059e6 100644
struct blkfront_info *info)
{
const char *message = NULL;
-@@ -710,7 +885,6 @@ again:
+@@ -710,7 +884,6 @@ again:
return err;
}
@@ -8409,7 +8611,7 @@ index b8578bb..44059e6 100644
/**
* Entry point to this code when a new device is created. Allocate the basic
* structures and the ring buffer for communication with the backend, and
-@@ -736,16 +910,48 @@ static int blkfront_probe(struct xenbus_device *dev,
+@@ -736,16 +909,48 @@ static int blkfront_probe(struct xenbus_device *dev,
}
}
@@ -8458,7 +8660,7 @@ index b8578bb..44059e6 100644
for (i = 0; i < BLK_RING_SIZE; i++)
info->shadow[i].req.id = i+1;
-@@ -755,7 +961,7 @@ static int blkfront_probe(struct xenbus_device *dev,
+@@ -755,7 +960,7 @@ static int blkfront_probe(struct xenbus_device *dev,
info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
dev_set_drvdata(&dev->dev, info);
@@ -8467,7 +8669,7 @@ index b8578bb..44059e6 100644
if (err) {
kfree(info);
dev_set_drvdata(&dev->dev, NULL);
-@@ -819,7 +1025,7 @@ static int blkif_recover(struct blkfront_info *info)
+@@ -819,7 +1024,7 @@ static int blkif_recover(struct blkfront_info *info)
xenbus_switch_state(info->xbdev, XenbusStateConnected);
@@ -8476,7 +8678,7 @@ index b8578bb..44059e6 100644
/* Now safe for us to use the shared ring */
info->connected = BLKIF_STATE_CONNECTED;
-@@ -830,7 +1036,7 @@ static int blkif_recover(struct blkfront_info *info)
+@@ -830,7 +1035,7 @@ static int blkif_recover(struct blkfront_info *info)
/* Kick any other new requests queued since we resumed */
kick_pending_request_queues(info);
@@ -8485,7 +8687,7 @@ index b8578bb..44059e6 100644
return 0;
}
-@@ -850,13 +1056,50 @@ static int blkfront_resume(struct xenbus_device *dev)
+@@ -850,13 +1055,50 @@ static int blkfront_resume(struct xenbus_device *dev)
blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
@@ -8537,7 +8739,7 @@ index b8578bb..44059e6 100644
/*
* Invoked when the backend is finally 'ready' (and has told produced
-@@ -868,11 +1111,31 @@ static void blkfront_connect(struct blkfront_info *info)
+@@ -868,11 +1110,31 @@ static void blkfront_connect(struct blkfront_info *info)
unsigned long sector_size;
unsigned int binfo;
int err;
@@ -8572,7 +8774,7 @@ index b8578bb..44059e6 100644
dev_dbg(&info->xbdev->dev, "%s:%s.\n",
__func__, info->xbdev->otherend);
-@@ -889,10 +1152,26 @@ static void blkfront_connect(struct blkfront_info *info)
+@@ -889,10 +1151,26 @@ static void blkfront_connect(struct blkfront_info *info)
}
err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
@@ -8601,7 +8803,7 @@ index b8578bb..44059e6 100644
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
if (err) {
-@@ -904,10 +1183,10 @@ static void blkfront_connect(struct blkfront_info *info)
+@@ -904,10 +1182,10 @@ static void blkfront_connect(struct blkfront_info *info)
xenbus_switch_state(info->xbdev, XenbusStateConnected);
/* Kick pending requests. */
@@ -8614,7 +8816,7 @@ index b8578bb..44059e6 100644
add_disk(info->gd);
-@@ -915,57 +1194,21 @@ static void blkfront_connect(struct blkfront_info *info)
+@@ -915,57 +1193,21 @@ static void blkfront_connect(struct blkfront_info *info)
}
/**
@@ -8676,7 +8878,7 @@ index b8578bb..44059e6 100644
case XenbusStateUnknown:
case XenbusStateClosed:
break;
-@@ -975,35 +1218,56 @@ static void backend_changed(struct xenbus_device *dev,
+@@ -975,35 +1217,56 @@ static void backend_changed(struct xenbus_device *dev,
break;
case XenbusStateClosing:
@@ -8753,7 +8955,7 @@ index b8578bb..44059e6 100644
return 0;
}
-@@ -1012,30 +1276,68 @@ static int blkfront_is_ready(struct xenbus_device *dev)
+@@ -1012,30 +1275,68 @@ static int blkfront_is_ready(struct xenbus_device *dev)
{
struct blkfront_info *info = dev_get_drvdata(&dev->dev);
@@ -8836,7 +9038,7 @@ index b8578bb..44059e6 100644
return 0;
}
-@@ -1061,7 +1363,7 @@ static struct xenbus_driver blkfront = {
+@@ -1061,7 +1362,7 @@ static struct xenbus_driver blkfront = {
.probe = blkfront_probe,
.remove = blkfront_remove,
.resume = blkfront_resume,
@@ -9182,7 +9384,7 @@ index b8e0219..7a62c3c 100644
}
readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
-index a6ee32b..a7c6529 100644
+index a6ee32b..5620de5 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -25,6 +25,8 @@
@@ -9218,7 +9420,7 @@ index a6ee32b..a7c6529 100644
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
-@@ -120,28 +123,63 @@ static int read_console(uint32_t vtermno, char *buf, int len)
+@@ -120,28 +123,65 @@ static int read_console(uint32_t vtermno, char *buf, int len)
return recv;
}
@@ -9228,12 +9430,11 @@ index a6ee32b..a7c6529 100644
+static struct hv_ops domU_hvc_ops = {
+ .get_chars = domU_read_console,
+ .put_chars = domU_write_console,
- .notifier_add = notifier_add_irq,
- .notifier_del = notifier_del_irq,
- .notifier_hangup = notifier_hangup_irq,
- };
-
--static int __init xen_init(void)
++ .notifier_add = notifier_add_irq,
++ .notifier_del = notifier_del_irq,
++ .notifier_hangup = notifier_hangup_irq,
++};
++
+static int dom0_read_console(uint32_t vtermno, char *buf, int len)
+{
+ return HYPERVISOR_console_io(CONSOLEIO_read, len, buf);
@@ -9255,11 +9456,12 @@ index a6ee32b..a7c6529 100644
+static struct hv_ops dom0_hvc_ops = {
+ .get_chars = dom0_read_console,
+ .put_chars = dom0_write_console,
-+ .notifier_add = notifier_add_irq,
-+ .notifier_del = notifier_del_irq,
-+ .notifier_hangup = notifier_hangup_irq,
-+};
-+
+ .notifier_add = notifier_add_irq,
+ .notifier_del = notifier_del_irq,
+ .notifier_hangup = notifier_hangup_irq,
+ };
+
+-static int __init xen_init(void)
+static int __init xen_hvc_init(void)
{
struct hvc_struct *hp;
@@ -9285,13 +9487,15 @@ index a6ee32b..a7c6529 100644
+
if (xencons_irq < 0)
xencons_irq = 0; /* NO_IRQ */
++ else
++ set_irq_noprobe(xencons_irq);
- hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
+ hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256);
if (IS_ERR(hp))
return PTR_ERR(hp);
-@@ -158,7 +196,7 @@ void xen_console_resume(void)
+@@ -158,7 +198,7 @@ void xen_console_resume(void)
rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
}
@@ -9300,7 +9504,7 @@ index a6ee32b..a7c6529 100644
{
if (hvc)
hvc_remove(hvc);
-@@ -166,29 +204,24 @@ static void __exit xen_fini(void)
+@@ -166,29 +206,24 @@ static void __exit xen_fini(void)
static int xen_cons_init(void)
{
@@ -9340,7 +9544,7 @@ index a6ee32b..a7c6529 100644
#ifdef CONFIG_EARLY_PRINTK
static void xenboot_write_console(struct console *console, const char *string,
unsigned len)
-@@ -196,19 +229,22 @@ static void xenboot_write_console(struct console *console, const char *string,
+@@ -196,19 +231,22 @@ static void xenboot_write_console(struct console *console, const char *string,
unsigned int linelen, off = 0;
const char *pos;
@@ -9368,7 +9572,7 @@ index a6ee32b..a7c6529 100644
}
struct console xenboot_console = {
-@@ -220,7 +256,7 @@ struct console xenboot_console = {
+@@ -220,7 +258,7 @@ struct console xenboot_console = {
void xen_raw_console_write(const char *str)
{
@@ -9730,7 +9934,7 @@ index a4e9dcb..62ab09e 100644
{
int err;
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
-index b115726..80a072e 100644
+index b115726..46e3ad0 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -21,7 +21,10 @@
@@ -9744,7 +9948,76 @@ index b115726..80a072e 100644
#include <xen/events.h>
#include <xen/page.h>
#include <xen/interface/io/fbif.h>
-@@ -272,6 +275,8 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
+@@ -105,7 +108,7 @@ static irqreturn_t input_handler(int rq, void *dev_id)
+ static int __devinit xenkbd_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+ {
+- int ret, i;
++ int ret, i, abs;
+ struct xenkbd_info *info;
+ struct input_dev *kbd, *ptr;
+
+@@ -123,6 +126,11 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev,
+ if (!info->page)
+ goto error_nomem;
+
++ if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-abs-pointer", "%d", &abs) < 0)
++ abs = 0;
++ if (abs)
++ xenbus_printf(XBT_NIL, dev->nodename, "request-abs-pointer", "1");
++
+ /* keyboard */
+ kbd = input_allocate_device();
+ if (!kbd)
+@@ -132,11 +140,12 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev,
+ kbd->id.bustype = BUS_PCI;
+ kbd->id.vendor = 0x5853;
+ kbd->id.product = 0xffff;
+- kbd->evbit[0] = BIT(EV_KEY);
++
++ __set_bit(EV_KEY, kbd->evbit);
+ for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
+- set_bit(i, kbd->keybit);
++ __set_bit(i, kbd->keybit);
+ for (i = KEY_OK; i < KEY_MAX; i++)
+- set_bit(i, kbd->keybit);
++ __set_bit(i, kbd->keybit);
+
+ ret = input_register_device(kbd);
+ if (ret) {
+@@ -155,12 +164,20 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev,
+ ptr->id.bustype = BUS_PCI;
+ ptr->id.vendor = 0x5853;
+ ptr->id.product = 0xfffe;
+- ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
++
++ if (abs) {
++ __set_bit(EV_ABS, ptr->evbit);
++ input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
++ input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
++ } else {
++ input_set_capability(ptr, EV_REL, REL_X);
++ input_set_capability(ptr, EV_REL, REL_Y);
++ }
++ input_set_capability(ptr, EV_REL, REL_WHEEL);
++
++ __set_bit(EV_KEY, ptr->evbit);
+ for (i = BTN_LEFT; i <= BTN_TASK; i++)
+- set_bit(i, ptr->keybit);
+- ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
+- input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
+- input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
++ __set_bit(i, ptr->keybit);
+
+ ret = input_register_device(ptr);
+ if (ret) {
+@@ -267,28 +284,19 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
+ enum xenbus_state backend_state)
+ {
+ struct xenkbd_info *info = dev_get_drvdata(&dev->dev);
+- int ret, val;
++ int val;
+
switch (backend_state) {
case XenbusStateInitialising:
case XenbusStateInitialised:
@@ -9753,7 +10026,24 @@ index b115726..80a072e 100644
case XenbusStateUnknown:
case XenbusStateClosed:
break;
-@@ -335,7 +340,7 @@ static struct xenbus_driver xenkbd_driver = {
+
+ case XenbusStateInitWait:
+ InitWait:
+- ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+- "feature-abs-pointer", "%d", &val);
+- if (ret < 0)
+- val = 0;
+- if (val) {
+- ret = xenbus_printf(XBT_NIL, info->xbdev->nodename,
+- "request-abs-pointer", "1");
+- if (ret)
+- printk(KERN_WARNING
+- "xenkbd: can't request abs-pointer");
+- }
+ xenbus_switch_state(dev, XenbusStateConnected);
+ break;
+
+@@ -335,7 +343,7 @@ static struct xenbus_driver xenkbd_driver = {
static int __init xenkbd_init(void)
{
@@ -10588,7 +10878,7 @@ index cef28a7..1940183 100644
EXPORT_SYMBOL_GPL(pci_bus_add_device);
EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
-index 5753036..8e6e6d1 100644
+index 91d0390..24f6f28 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -673,10 +673,13 @@ void __init detect_intel_iommu(void)
@@ -10607,6 +10897,32 @@ index 5753036..8e6e6d1 100644
}
early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
dmar_tbl = NULL;
+diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
+index 58d25a1..1ebd547 100644
+--- a/drivers/pci/hotplug/acpiphp_glue.c
++++ b/drivers/pci/hotplug/acpiphp_glue.c
+@@ -213,6 +213,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
+
+ pdev = pci_get_slot(pbus, PCI_DEVFN(device, function));
+ if (pdev) {
++ pdev->current_state = PCI_D0;
+ slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
+ pci_dev_put(pdev);
+ }
+@@ -1017,6 +1018,13 @@ static int __ref enable_device(struct acpiphp_slot *slot)
+ list_for_each_entry(func, &slot->funcs, sibling)
+ acpiphp_configure_ioapics(func->handle);
+ pci_enable_bridges(bus);
++
++ list_for_each_entry(dev, &bus->devices, bus_list) {
++ /* Assume that newly added devices are powered on already. */
++ if (!dev->is_added)
++ dev->current_state = PCI_D0;
++ }
++
+ pci_bus_add_devices(bus);
+
+ list_for_each (l, &slot->funcs) {
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index ba83495..1506d4a 100644
--- a/drivers/pci/intel-iommu.c
@@ -13300,7 +13616,7 @@ index 0000000..e83b615
+subsys_initcall(xen_acpi_processor_extcntl_init);
+MODULE_LICENSE("GPL");
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
-index 4204336..ce198b4 100644
+index 4204336..a065fda 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -43,22 +43,26 @@
@@ -13464,7 +13780,7 @@ index 4204336..ce198b4 100644
+ set_phys_to_machine(pfn, mfn);
+
+ /* Link back into the page tables if not highmem. */
-+ if (pfn < max_low_pfn) {
++ if (!xen_hvm_domain() && pfn < max_low_pfn) {
+ int ret;
+ ret = HYPERVISOR_update_va_mapping(
+ (unsigned long)__va(pfn << PAGE_SHIFT),
@@ -13544,7 +13860,7 @@ index 4204336..ce198b4 100644
+ set_phys_to_machine(lpfn, INVALID_P2M_ENTRY);
+ page = pfn_to_page(lpfn);
+
-+ if (!PageHighMem(page)) {
++ if (!xen_hvm_domain() && !PageHighMem(page)) {
+ ret = HYPERVISOR_update_va_mapping(
+ (unsigned long)__va(lpfn << PAGE_SHIFT),
+ __pte_ma(0), 0);
@@ -13584,15 +13900,16 @@ index 4204336..ce198b4 100644
}
static int balloon_init_watcher(struct notifier_block *notifier,
-@@ -399,15 +450,18 @@ static struct notifier_block xenstore_notifier;
+@@ -399,15 +450,22 @@ static struct notifier_block xenstore_notifier;
static int __init balloon_init(void)
{
- unsigned long pfn;
-+ unsigned long pfn, extra_pfn_end;
++ unsigned long pfn, nr_pages, extra_pfn_end;
struct page *page;
- if (!xen_pv_domain())
+- if (!xen_pv_domain())
++ if (!xen_domain())
return -ENODEV;
- pr_info("xen_balloon: Initialising balloon driver.\n");
@@ -13602,16 +13919,30 @@ index 4204336..ce198b4 100644
+ balloon_npages = 1 << balloon_order;
- balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn);
-+ balloon_stats.current_pages = (min(xen_start_info->nr_pages, max_pfn)) >> balloon_order;
++ if (xen_pv_domain())
++ nr_pages = xen_start_info->nr_pages;
++ else
++ nr_pages = max_pfn;
++ balloon_stats.current_pages = (min(nr_pages, max_pfn)) >> balloon_order;
balloon_stats.target_pages = balloon_stats.current_pages;
balloon_stats.balloon_low = 0;
balloon_stats.balloon_high = 0;
-@@ -420,10 +474,15 @@ static int __init balloon_init(void)
+@@ -419,11 +477,24 @@ static int __init balloon_init(void)
+
register_balloon(&balloon_sysdev);
- /* Initialise the balloon with excess memory space. */
+- /* Initialise the balloon with excess memory space. */
- for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
-+ extra_pfn_end = min(e820_end_of_ram_pfn(),
++ /*
++ * Initialise the balloon with excess memory space. We need
++ * to make sure we don't add memory which doesn't exist or
++ * logically exist. The E820 map can be trimmed to be smaller
++ * than the amount of physical memory due to the mem= command
++ * line parameter. And if this is a 32-bit non-HIGHMEM kernel
++ * on a system with memory which requires highmem to access,
++ * don't try to use it.
++ */
++ extra_pfn_end = min(min(max_pfn, e820_end_of_ram_pfn()),
+ (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size));
+ for (pfn = PFN_UP(xen_extra_mem_start);
+ pfn < extra_pfn_end;
@@ -13625,7 +13956,7 @@ index 4204336..ce198b4 100644
}
target_watch.callback = watch_target;
-@@ -444,6 +503,121 @@ static void balloon_exit(void)
+@@ -444,6 +515,121 @@ static void balloon_exit(void)
module_exit(balloon_exit);
@@ -13747,7 +14078,7 @@ index 4204336..ce198b4 100644
#define BALLOON_SHOW(name, format, args...) \
static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, \
-@@ -477,7 +651,7 @@ static ssize_t store_target_kb(struct sys_device *dev,
+@@ -477,7 +663,7 @@ static ssize_t store_target_kb(struct sys_device *dev,
target_bytes = simple_strtoull(buf, &endchar, 0) * 1024;
@@ -13756,7 +14087,7 @@ index 4204336..ce198b4 100644
return count;
}
-@@ -491,7 +665,7 @@ static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr
+@@ -491,7 +677,7 @@ static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr
{
return sprintf(buf, "%llu\n",
(unsigned long long)balloon_stats.target_pages
@@ -13765,7 +14096,7 @@ index 4204336..ce198b4 100644
}
static ssize_t store_target(struct sys_device *dev,
-@@ -507,7 +681,7 @@ static ssize_t store_target(struct sys_device *dev,
+@@ -507,7 +693,7 @@ static ssize_t store_target(struct sys_device *dev,
target_bytes = memparse(buf, &endchar);
@@ -18110,7 +18441,7 @@ index bdfd584..6625ffe 100644
#include <asm/xen/hypervisor.h>
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
-index ac91a4e..634fcaf 100644
+index 1417015..cf46c7b 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -16,7 +16,7 @@
@@ -18256,19 +18587,18 @@ index ac91a4e..634fcaf 100644
/* By default all event channels notify CPU#0. */
for_each_irq_desc(i, desc) {
-@@ -255,7 +290,10 @@ static void init_evtchn_cpu_bindings(void)
+@@ -255,7 +290,9 @@ static void init_evtchn_cpu_bindings(void)
}
#endif
-- memset(cpu_evtchn_mask(0), ~0, sizeof(cpu_evtchn_mask(0)));
+- memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s));
+ for_each_possible_cpu(i)
+ memset(cpu_evtchn_mask(i),
+ (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s));
-+
}
static inline void clear_evtchn(int port)
-@@ -300,6 +338,14 @@ static void mask_evtchn(int port)
+@@ -300,6 +337,14 @@ static void mask_evtchn(int port)
sync_set_bit(port, &s->evtchn_mask[0]);
}
@@ -18283,7 +18613,7 @@ index ac91a4e..634fcaf 100644
static void unmask_evtchn(int port)
{
struct shared_info *s = HYPERVISOR_shared_info;
-@@ -330,26 +376,370 @@ static void unmask_evtchn(int port)
+@@ -330,26 +375,370 @@ static void unmask_evtchn(int port)
put_cpu();
}
@@ -18335,7 +18665,8 @@ index ac91a4e..634fcaf 100644
+ if (irq == start)
+ goto no_irqs;
- desc = irq_to_desc_alloc_node(irq, 0);
+- desc = irq_to_desc_alloc_node(irq, 0);
++ desc = irq_to_desc_alloc_node(irq, -1);
if (WARN_ON(desc == NULL))
return -1;
@@ -18562,7 +18893,7 @@ index ac91a4e..634fcaf 100644
+ desc = irq_to_desc(irq);
+ if (!desc)
+ goto out;
-
++
+ if (xen_initial_domain()) {
+ unmap_irq.pirq = info->u.pirq.gsi;
+ unmap_irq.domid = info->u.pirq.domid;
@@ -18637,7 +18968,7 @@ index ac91a4e..634fcaf 100644
+ set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
+ handle_fasteoi_irq,
+ (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi");
-+
+
+out:
+ spin_unlock(&irq_mapping_update_lock);
return irq;
@@ -18658,7 +18989,7 @@ index ac91a4e..634fcaf 100644
int bind_evtchn_to_irq(unsigned int evtchn)
{
-@@ -363,7 +753,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
+@@ -363,7 +752,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
irq = find_unbound_irq();
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
@@ -18667,7 +18998,7 @@ index ac91a4e..634fcaf 100644
evtchn_to_irq[evtchn] = irq;
irq_info[irq] = mk_evtchn_info(evtchn);
-@@ -410,8 +800,23 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
+@@ -410,8 +799,23 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
return irq;
}
@@ -18682,17 +19013,17 @@ index ac91a4e..634fcaf 100644
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
-+
+
+-static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+ return err ? : bind_evtchn_to_irq(bind_interdomain.local_port);
+}
+
-
--static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
++
+int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
int evtchn, irq;
-@@ -421,6 +826,11 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+@@ -421,6 +825,11 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
irq = per_cpu(virq_to_irq, cpu)[virq];
if (irq == -1) {
@@ -18704,7 +19035,7 @@ index ac91a4e..634fcaf 100644
bind_virq.virq = virq;
bind_virq.vcpu = cpu;
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
-@@ -428,11 +838,6 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+@@ -428,11 +837,6 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
BUG();
evtchn = bind_virq.port;
@@ -18716,7 +19047,7 @@ index ac91a4e..634fcaf 100644
evtchn_to_irq[evtchn] = irq;
irq_info[irq] = mk_virq_info(evtchn, virq);
-@@ -505,6 +910,29 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
+@@ -505,6 +909,29 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
}
EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler);
@@ -18746,7 +19077,7 @@ index ac91a4e..634fcaf 100644
int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
-@@ -564,41 +992,75 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
+@@ -564,41 +991,75 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
{
struct shared_info *sh = HYPERVISOR_shared_info;
int cpu = smp_processor_id();
@@ -18845,7 +19176,7 @@ index ac91a4e..634fcaf 100644
}
}
-@@ -618,17 +1080,13 @@ static DEFINE_PER_CPU(unsigned, xed_nesting_count);
+@@ -618,17 +1079,13 @@ static DEFINE_PER_CPU(unsigned, xed_nesting_count);
* a bitset of words which contain pending event bits. The second
* level is a bitset of pending events themselves.
*/
@@ -18864,17 +19195,17 @@ index ac91a4e..634fcaf 100644
do {
unsigned long pending_words;
-@@ -651,9 +1109,16 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
+@@ -651,9 +1108,16 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
int bit_idx = __ffs(pending_bits);
int port = (word_idx * BITS_PER_LONG) + bit_idx;
int irq = evtchn_to_irq[port];
+ struct irq_desc *desc;
-+
-+ mask_evtchn(port);
-+ clear_evtchn(port);
- if (irq != -1)
- handle_irq(irq, regs);
++ mask_evtchn(port);
++ clear_evtchn(port);
++
+ if (irq != -1) {
+ desc = irq_to_desc(irq);
+ if (desc)
@@ -18883,7 +19214,7 @@ index ac91a4e..634fcaf 100644
}
}
-@@ -661,14 +1126,32 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
+@@ -661,14 +1125,32 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
count = __get_cpu_var(xed_nesting_count);
__get_cpu_var(xed_nesting_count) = 0;
@@ -18918,7 +19249,7 @@ index ac91a4e..634fcaf 100644
/* Rebind a new event channel to an existing irq. */
void rebind_evtchn_irq(int evtchn, int irq)
-@@ -705,7 +1188,10 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
+@@ -705,7 +1187,10 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
struct evtchn_bind_vcpu bind_vcpu;
int evtchn = evtchn_from_irq(irq);
@@ -18930,7 +19261,7 @@ index ac91a4e..634fcaf 100644
return -1;
/* Send future instances of this interrupt to other vcpu. */
-@@ -746,33 +1232,17 @@ int resend_irq_on_evtchn(unsigned int irq)
+@@ -746,33 +1231,18 @@ int resend_irq_on_evtchn(unsigned int irq)
return 1;
}
@@ -18953,12 +19284,14 @@ index ac91a4e..634fcaf 100644
static void ack_dynirq(unsigned int irq)
{
int evtchn = evtchn_from_irq(irq);
++ struct irq_desc *desc = irq_to_desc(irq);
- move_native_irq(irq);
+ move_masked_irq(irq);
- if (VALID_EVTCHN(evtchn))
+- if (VALID_EVTCHN(evtchn))
- clear_evtchn(evtchn);
++ if (VALID_EVTCHN(evtchn) && !(desc->status & IRQ_DISABLED))
+ unmask_evtchn(evtchn);
}
@@ -19049,7 +19382,7 @@ index ac91a4e..634fcaf 100644
init_evtchn_cpu_bindings();
-@@ -916,37 +1400,134 @@ void xen_irq_resume(void)
+@@ -916,37 +1400,136 @@ void xen_irq_resume(void)
restore_cpu_virqs(cpu);
restore_cpu_ipis(cpu);
}
@@ -19161,7 +19494,9 @@ index ac91a4e..634fcaf 100644
+ }
+ printk(KERN_INFO "Xen HVM callback vector for event delivery is "
+ "enabled\n");
-+ alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
++ /* in the restore case the vector has already been allocated */
++ if (!test_bit(XEN_HVM_EVTCHN_CALLBACK, used_vectors))
++ alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
+ }
+}
+#else
@@ -19193,7 +19528,7 @@ index ac91a4e..634fcaf 100644
init_evtchn_cpu_bindings();
-@@ -954,5 +1535,11 @@ void __init xen_init_IRQ(void)
+@@ -954,5 +1537,11 @@ void __init xen_init_IRQ(void)
for (i = 0; i < NR_EVENT_CHANNELS; i++)
mask_evtchn(i);
@@ -20341,7 +20676,7 @@ index 7d8f531..09bb742 100644
-core_initcall(gnttab_init);
+core_initcall(__gnttab_init);
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
-index 5d42d55..0b50906 100644
+index 5d42d55..9efdfb9 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -8,6 +8,7 @@
@@ -20352,79 +20687,246 @@ index 5d42d55..0b50906 100644
#include <xen/xenbus.h>
#include <xen/grant_table.h>
#include <xen/events.h>
-@@ -32,10 +33,30 @@ enum shutdown_state {
+@@ -31,37 +32,62 @@ enum shutdown_state {
+ /* Ignore multiple shutdown requests. */
static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
- #ifdef CONFIG_PM_SLEEP
--static int xen_suspend(void *data)
-+static int xen_hvm_suspend(void *data)
- {
-+ struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
- int *cancelled = data;
-+
-+ BUG_ON(!irqs_disabled());
-+
-+ *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
+-#ifdef CONFIG_PM_SLEEP
++struct suspend_info {
++ int cancelled;
++ unsigned long arg; /* extra hypercall argument */
++ void (*pre)(void);
++ void (*post)(int cancelled);
++};
+
-+ xen_hvm_post_suspend(*cancelled);
++static void xen_hvm_post_suspend(int cancelled)
++{
++ xen_arch_hvm_post_suspend(cancelled);
+ gnttab_resume();
++}
+
-+ if (!*cancelled) {
-+ xen_irq_resume();
-+ xen_timer_resume();
-+ }
-+
-+ return 0;
++static void xen_pre_suspend(void)
++{
++ xen_mm_pin_all();
++ gnttab_suspend();
++ xen_arch_pre_suspend();
+}
+
-+static int xen_suspend(void *data)
++static void xen_post_suspend(int cancelled)
+{
++ xen_arch_post_suspend(cancelled);
++ gnttab_resume();
++ xen_mm_unpin_all();
++}
++
++#ifdef CONFIG_HIBERNATION
+ static int xen_suspend(void *data)
+ {
+- int *cancelled = data;
++ struct suspend_info *si = data;
int err;
-+ int *cancelled = data;
BUG_ON(!irqs_disabled());
-@@ -111,7 +132,10 @@ static void do_suspend(void)
+- err = sysdev_suspend(PMSG_SUSPEND);
++ err = sysdev_suspend(PMSG_FREEZE);
+ if (err) {
+ printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
+ err);
+ return err;
+ }
+
+- xen_mm_pin_all();
+- gnttab_suspend();
+- xen_pre_suspend();
++ if (si->pre)
++ si->pre();
+
+ /*
+ * This hypercall returns 1 if suspend was cancelled
+ * or the domain was merely checkpointed, and 0 if it
+ * is resuming in a new domain.
+ */
+- *cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
++ si->cancelled = HYPERVISOR_suspend(si->arg);
+
+- xen_post_suspend(*cancelled);
+- gnttab_resume();
+- xen_mm_unpin_all();
++ if (si->post)
++ si->post(si->cancelled);
+
+- if (!*cancelled) {
++ if (!si->cancelled) {
+ xen_irq_resume();
+ xen_console_resume();
+ xen_timer_resume();
+@@ -75,7 +101,7 @@ static int xen_suspend(void *data)
+ static void do_suspend(void)
+ {
+ int err;
+- int cancelled = 1;
++ struct suspend_info si;
+
+ shutting_down = SHUTDOWN_SUSPEND;
+
+@@ -96,7 +122,7 @@ static void do_suspend(void)
+ }
+ #endif
+
+- err = dpm_suspend_start(PMSG_SUSPEND);
++ err = dpm_suspend_start(PMSG_FREEZE);
+ if (err) {
+ printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err);
+ goto out_thaw;
+@@ -105,29 +131,41 @@ static void do_suspend(void)
+ printk(KERN_DEBUG "suspending xenstore...\n");
+ xs_suspend();
+
+- err = dpm_suspend_noirq(PMSG_SUSPEND);
++ err = dpm_suspend_noirq(PMSG_FREEZE);
+ if (err) {
+ printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
goto out_resume;
}
- err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
-+ if (xen_hvm_domain())
-+ err = stop_machine(xen_hvm_suspend, &cancelled, cpumask_of(0));
-+ else
-+ err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
++ si.cancelled = 1;
++
++ if (xen_hvm_domain()) {
++ si.arg = 0UL;
++ si.pre = NULL;
++ si.post = &xen_hvm_post_suspend;
++ } else {
++ si.arg = virt_to_mfn(xen_start_info);
++ si.pre = &xen_pre_suspend;
++ si.post = &xen_post_suspend;
++ }
++
++ err = stop_machine(xen_suspend, &si, cpumask_of(0));
- dpm_resume_noirq(PMSG_RESUME);
+- dpm_resume_noirq(PMSG_RESUME);
++ dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
-@@ -260,7 +284,19 @@ static int shutdown_event(struct notifier_block *notifier,
- return NOTIFY_DONE;
- }
+ if (err) {
+ printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
+- cancelled = 1;
++ si.cancelled = 1;
+ }
--static int __init setup_shutdown_event(void)
-+static int __init __setup_shutdown_event(void)
-+{
-+ /* Delay initialization in the PV on HVM case */
-+ if (xen_hvm_domain())
-+ return 0;
+ out_resume:
+- if (!cancelled) {
++ if (!si.cancelled) {
+ xen_arch_resume();
+ xs_resume();
+ } else
+ xs_suspend_cancel();
+
+- dpm_resume_end(PMSG_RESUME);
++ dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
+
+ /* Make sure timer events get retriggered on all CPUs */
+ clock_was_set();
+@@ -143,7 +181,24 @@ out_destroy_sm:
+ out:
+ shutting_down = SHUTDOWN_INVALID;
+ }
+-#endif /* CONFIG_PM_SLEEP */
++#endif /* CONFIG_HIBERNATION */
+
-+ if (!xen_pv_domain())
-+ return -ENODEV;
++struct shutdown_handler {
++ const char *command;
++ void (*cb)(void);
++};
+
-+ return xen_setup_shutdown_event();
++static void do_poweroff(void)
++{
++ shutting_down = SHUTDOWN_POWEROFF;
++ orderly_poweroff(false);
+}
+
++static void do_reboot(void)
++{
++ shutting_down = SHUTDOWN_POWEROFF; /* ? */
++ ctrl_alt_del();
++}
+
+ static void shutdown_handler(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
+@@ -151,6 +206,16 @@ static void shutdown_handler(struct xenbus_watch *watch,
+ char *str;
+ struct xenbus_transaction xbt;
+ int err;
++ static struct shutdown_handler handlers[] = {
++ { "poweroff", do_poweroff },
++ { "halt", do_poweroff },
++ { "reboot", do_reboot },
++#ifdef CONFIG_HIBERNATION
++ { "suspend", do_suspend },
++#endif
++ {NULL, NULL},
++ };
++ static struct shutdown_handler *handler;
+
+ if (shutting_down != SHUTDOWN_INVALID)
+ return;
+@@ -167,7 +232,14 @@ static void shutdown_handler(struct xenbus_watch *watch,
+ return;
+ }
+
+- xenbus_write(xbt, "control", "shutdown", "");
++ for (handler = &handlers[0]; handler->command; handler++) {
++ if (strcmp(str, handler->command) == 0)
++ break;
++ }
++
++ /* Only acknowledge commands which we are prepared to handle. */
++ if (handler->cb)
++ xenbus_write(xbt, "control", "shutdown", "");
+
+ err = xenbus_transaction_end(xbt, 0);
+ if (err == -EAGAIN) {
+@@ -175,17 +247,8 @@ static void shutdown_handler(struct xenbus_watch *watch,
+ goto again;
+ }
+
+- if (strcmp(str, "poweroff") == 0 ||
+- strcmp(str, "halt") == 0) {
+- shutting_down = SHUTDOWN_POWEROFF;
+- orderly_poweroff(false);
+- } else if (strcmp(str, "reboot") == 0) {
+- shutting_down = SHUTDOWN_POWEROFF; /* ? */
+- ctrl_alt_del();
+-#ifdef CONFIG_PM_SLEEP
+- } else if (strcmp(str, "suspend") == 0) {
+- do_suspend();
+-#endif
++ if (handler->cb) {
++ handler->cb();
+ } else {
+ printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
+ shutting_down = SHUTDOWN_INVALID;
+@@ -260,14 +323,18 @@ static int shutdown_event(struct notifier_block *notifier,
+ return NOTIFY_DONE;
+ }
+
+-static int __init setup_shutdown_event(void)
+int xen_setup_shutdown_event(void)
{
static struct notifier_block xenstore_notifier = {
.notifier_call = shutdown_event
-@@ -269,5 +305,6 @@ static int __init setup_shutdown_event(void)
+ };
++
++ if (!xen_domain())
++ return -ENODEV;
+ register_xenstore_notifier(&xenstore_notifier);
return 0;
}
+EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
-subsys_initcall(setup_shutdown_event);
-+subsys_initcall(__setup_shutdown_event);
++subsys_initcall(xen_setup_shutdown_event);
diff --git a/drivers/xen/mce.c b/drivers/xen/mce.c
new file mode 100644
index 0000000..da566a5
@@ -20658,10 +21160,10 @@ index 0000000..e346e81
+xen-netback-y := netback.o xenbus.o interface.o
diff --git a/drivers/xen/netback/common.h b/drivers/xen/netback/common.h
new file mode 100644
-index 0000000..feacf5f
+index 0000000..2f3ccb3
--- /dev/null
+++ b/drivers/xen/netback/common.h
-@@ -0,0 +1,329 @@
+@@ -0,0 +1,327 @@
+/******************************************************************************
+ * arch/xen/drivers/netif/backend/common.h
+ *
@@ -20764,11 +21266,9 @@ index 0000000..feacf5f
+ unsigned long remaining_credit;
+ struct timer_list credit_timeout;
+
-+ /* Enforce draining of the transmit queue. */
-+ struct timer_list tx_queue_timeout;
-+
+ /* Statistics */
+ int nr_copied_skbs;
++ int rx_gso_checksum_fixup;
+
+ /* Miscellaneous private stuff. */
+ struct list_head list; /* scheduling list */
@@ -20993,10 +21493,10 @@ index 0000000..feacf5f
+#endif /* __NETIF__BACKEND__COMMON_H__ */
diff --git a/drivers/xen/netback/interface.c b/drivers/xen/netback/interface.c
new file mode 100644
-index 0000000..2e8508a
+index 0000000..d3af68e
--- /dev/null
+++ b/drivers/xen/netback/interface.c
-@@ -0,0 +1,475 @@
+@@ -0,0 +1,471 @@
+/******************************************************************************
+ * arch/xen/drivers/netif/backend/interface.c
+ *
@@ -21040,15 +21540,7 @@ index 0000000..2e8508a
+ * Module parameter 'queue_length':
+ *
+ * Enables queuing in the network stack when a client has run out of receive
-+ * descriptors. Although this feature can improve receive bandwidth by avoiding
-+ * packet loss, it can also result in packets sitting in the 'tx_queue' for
-+ * unbounded time. This is bad if those packets hold onto foreign resources.
-+ * For example, consider a packet that holds onto resources belonging to the
-+ * guest for which it is queued (e.g., packet received on vif1.0, destined for
-+ * vif1.1 which is not activated in the guest): in this situation the guest
-+ * will never be destroyed, unless vif1.1 is taken down. To avoid this, we
-+ * run a timer (tx_queue_timeout) to drain the queue when the interface is
-+ * blocked.
++ * descriptors.
+ */
+static unsigned long netbk_queue_length = 32;
+module_param_named(queue_length, netbk_queue_length, ulong, 0644);
@@ -21196,7 +21688,14 @@ index 0000000..2e8508a
+ char name[ETH_GSTRING_LEN];
+ u16 offset;
+} netbk_stats[] = {
-+ { "copied_skbs", offsetof(struct xen_netif, nr_copied_skbs) },
++ {
++ "copied_skbs",
++ offsetof(struct xen_netif, nr_copied_skbs)
++ },
++ {
++ "rx_gso_checksum_fixup",
++ offsetof(struct xen_netif, rx_gso_checksum_fixup)
++ },
+};
+
+static int netbk_get_sset_count(struct net_device *dev, int string_set)
@@ -21294,8 +21793,6 @@ index 0000000..2e8508a
+ /* Initialize 'expires' now: it's used to track the credit window. */
+ netif->credit_timeout.expires = jiffies;
+
-+ init_timer(&netif->tx_queue_timeout);
-+
+ dev->netdev_ops = &netback_ops;
+ netif_set_features(netif);
+ SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
@@ -21457,7 +21954,6 @@ index 0000000..2e8508a
+ wait_event(netif->waiting_to_free, atomic_read(&netif->refcnt) == 0);
+
+ del_timer_sync(&netif->credit_timeout);
-+ del_timer_sync(&netif->tx_queue_timeout);
+
+ if (netif->irq)
+ unbind_from_irqhandler(netif->irq, netif);
@@ -21474,10 +21970,10 @@ index 0000000..2e8508a
+}
diff --git a/drivers/xen/netback/netback.c b/drivers/xen/netback/netback.c
new file mode 100644
-index 0000000..c448675
+index 0000000..92bc31c
--- /dev/null
+++ b/drivers/xen/netback/netback.c
-@@ -0,0 +1,1902 @@
+@@ -0,0 +1,1923 @@
+/******************************************************************************
+ * drivers/xen/netback/netback.c
+ *
@@ -21516,9 +22012,11 @@ index 0000000..c448675
+
+#include "common.h"
+
-+#include <linux/tcp.h>
-+#include <linux/udp.h>
+#include <linux/kthread.h>
++#include <linux/if_vlan.h>
++#include <linux/udp.h>
++
++#include <net/tcp.h>
+
+#include <xen/balloon.h>
+#include <xen/events.h>
@@ -21605,10 +22103,12 @@ index 0000000..c448675
+/*
+ * This is the amount of packet we copy rather than map, so that the
+ * guest can't fiddle with the contents of the headers while we do
-+ * packet processing on them (netfilter, routing, etc). 72 is enough
-+ * to cover TCP+IP headers including options.
++ * packet processing on them (netfilter, routing, etc).
+ */
-+#define PKT_PROT_LEN 72
++#define PKT_PROT_LEN (ETH_HLEN + \
++ VLAN_HLEN + \
++ sizeof(struct iphdr) + MAX_IPOPTLEN + \
++ sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE)
+
+static inline pending_ring_idx_t pending_index(unsigned i)
+{
@@ -21751,13 +22251,6 @@ index 0000000..c448675
+ ((netif->rx.rsp_prod_pvt + NET_RX_RING_SIZE - peek) < needed);
+}
+
-+static void tx_queue_callback(unsigned long data)
-+{
-+ struct xen_netif *netif = (struct xen_netif *)data;
-+ if (netif_schedulable(netif))
-+ netif_wake_queue(netif->dev);
-+}
-+
+/* Figure out how many ring slots we're going to need to send @skb to
+ the guest. */
+static unsigned count_skb_slots(struct sk_buff *skb, struct xen_netif *netif)
@@ -21840,19 +22333,8 @@ index 0000000..c448675
+ netif->rx.sring->req_event = netif->rx_req_cons_peek +
+ netbk_max_required_rx_slots(netif);
+ mb(); /* request notification /then/ check & stop the queue */
-+ if (netbk_queue_full(netif)) {
++ if (netbk_queue_full(netif))
+ netif_stop_queue(dev);
-+ /*
-+ * Schedule 500ms timeout to restart the queue, thus
-+ * ensuring that an inactive queue will be drained.
-+ * Packets will be immediately be dropped until more
-+ * receive buffers become available (see
-+ * netbk_queue_full() check above).
-+ */
-+ netif->tx_queue_timeout.data = (unsigned long)netif;
-+ netif->tx_queue_timeout.function = tx_queue_callback;
-+ mod_timer(&netif->tx_queue_timeout, jiffies + HZ/2);
-+ }
+ }
+ skb_queue_tail(&netbk->rx_queue, skb);
+
@@ -22411,11 +22893,20 @@ index 0000000..c448675
+ gop++;
+ }
+
-+ if (netbk_copy_skb_mode != NETBK_DELAYED_COPY_SKB ||
-+ list_empty(&netbk->pending_inuse_head))
-+ break;
++ } while (dp != netbk->dealloc_prod);
++
++ netbk->dealloc_cons = dc;
++
++ ret = HYPERVISOR_grant_table_op(
++ GNTTABOP_unmap_grant_ref, netbk->tx_unmap_ops,
++ gop - netbk->tx_unmap_ops);
++ BUG_ON(ret);
+
-+ /* Copy any entries that have been pending for too long. */
++ /*
++ * Copy any entries that have been pending for too long
++ */
++ if (netbk_copy_skb_mode == NETBK_DELAYED_COPY_SKB &&
++ !list_empty(&netbk->pending_inuse_head)) {
+ list_for_each_entry_safe(inuse, n,
+ &netbk->pending_inuse_head, list) {
+ struct pending_tx_info *pending_tx_info;
@@ -22441,14 +22932,7 @@ index 0000000..c448675
+
+ break;
+ }
-+ } while (dp != netbk->dealloc_prod);
-+
-+ netbk->dealloc_cons = dc;
-+
-+ ret = HYPERVISOR_grant_table_op(
-+ GNTTABOP_unmap_grant_ref, netbk->tx_unmap_ops,
-+ gop - netbk->tx_unmap_ops);
-+ BUG_ON(ret);
++ }
+
+ list_for_each_entry_safe(inuse, n, &list, list) {
+ struct pending_tx_info *pending_tx_info;
@@ -22725,11 +23209,28 @@ index 0000000..c448675
+ return 0;
+}
+
-+static int skb_checksum_setup(struct sk_buff *skb)
++static int checksum_setup(struct xen_netif *netif, struct sk_buff *skb)
+{
+ struct iphdr *iph;
+ unsigned char *th;
+ int err = -EPROTO;
++ int recalculate_partial_csum = 0;
++
++ /*
++ * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy
++ * peers can fail to set NETRXF_csum_blank when sending a GSO
++ * frame. In this case force the SKB to CHECKSUM_PARTIAL and
++ * recalculate the partial checksum.
++ */
++ if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) {
++ netif->rx_gso_checksum_fixup++;
++ skb->ip_summed = CHECKSUM_PARTIAL;
++ recalculate_partial_csum = 1;
++ }
++
++ /* A non-CHECKSUM_PARTIAL SKB does not require setup. */
++ if (skb->ip_summed != CHECKSUM_PARTIAL)
++ return 0;
+
+ if (skb->protocol != htons(ETH_P_IP))
+ goto out;
@@ -22743,9 +23244,23 @@ index 0000000..c448675
+ switch (iph->protocol) {
+ case IPPROTO_TCP:
+ skb->csum_offset = offsetof(struct tcphdr, check);
++
++ if (recalculate_partial_csum) {
++ struct tcphdr *tcph = (struct tcphdr *)th;
++ tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
++ skb->len - iph->ihl*4,
++ IPPROTO_TCP, 0);
++ }
+ break;
+ case IPPROTO_UDP:
+ skb->csum_offset = offsetof(struct udphdr, check);
++
++ if (recalculate_partial_csum) {
++ struct udphdr *udph = (struct udphdr *)th;
++ udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
++ skb->len - iph->ihl*4,
++ IPPROTO_UDP, 0);
++ }
+ break;
+ default:
+ if (net_ratelimit())
@@ -22999,15 +23514,10 @@ index 0000000..c448675
+ skb->dev = netif->dev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
-+ netif->stats.rx_bytes += skb->len;
-+ netif->stats.rx_packets++;
-+
-+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
-+ if (skb_checksum_setup(skb)) {
-+ DPRINTK("Can't setup checksum in net_tx_action\n");
-+ kfree_skb(skb);
-+ continue;
-+ }
++ if (checksum_setup(netif, skb)) {
++ DPRINTK("Can't setup checksum in net_tx_action\n");
++ kfree_skb(skb);
++ continue;
+ }
+
+ if (unlikely(netbk_copy_skb_mode == NETBK_ALWAYS_COPY_SKB) &&
@@ -23017,6 +23527,9 @@ index 0000000..c448675
+ continue;
+ }
+
++ netif->stats.rx_bytes += skb->len;
++ netif->stats.rx_packets++;
++
+ netif_rx_ni(skb);
+ netif->dev->last_rx = jiffies;
+ }
@@ -23210,6 +23723,10 @@ index 0000000..c448675
+ if (netbk->dealloc_cons != netbk->dealloc_prod)
+ return 1;
+
++ if (netbk_copy_skb_mode == NETBK_DELAYED_COPY_SKB &&
++ !list_empty(&netbk->pending_inuse_head))
++ return 1;
++
+ if (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
+ !list_empty(&netbk->net_schedule_list))
+ return 1;
@@ -29640,10 +30157,10 @@ index 0000000..6d1a770
+arch_initcall(xen_pcpu_init);
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
new file mode 100644
-index 0000000..c01b5dd
+index 0000000..8adaa3b
--- /dev/null
+++ b/drivers/xen/platform-pci.c
-@@ -0,0 +1,207 @@
+@@ -0,0 +1,204 @@
+/******************************************************************************
+ * platform-pci.c
+ *
@@ -29809,9 +30326,6 @@ index 0000000..c01b5dd
+ if (ret)
+ goto out;
+ xenbus_probe(NULL);
-+ ret = xen_setup_shutdown_event();
-+ if (ret)
-+ goto out;
+ return 0;
+
+out:
@@ -30232,7 +30746,7 @@ index 92a1ef8..89f2e42 100644
* @dev: xenbus device
* @ring_mfn: mfn of ring to grant
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
-index 649fcdf..3a83ba2 100644
+index 649fcdf..be4c7c3 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -49,31 +49,29 @@
@@ -30533,7 +31047,7 @@ index 649fcdf..3a83ba2 100644
static unsigned int char_count(const char *str, char c)
{
-@@ -662,32 +575,17 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
+@@ -662,54 +575,37 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
}
EXPORT_SYMBOL_GPL(xenbus_dev_changed);
@@ -30552,7 +31066,7 @@ index 649fcdf..3a83ba2 100644
-};
-
-static int xenbus_dev_suspend(struct device *dev, pm_message_t state)
-+int xenbus_dev_suspend(struct device *dev, pm_message_t state)
++int xenbus_dev_suspend(struct device *dev)
{
int err = 0;
struct xenbus_driver *drv;
@@ -30567,9 +31081,10 @@ index 649fcdf..3a83ba2 100644
drv = to_xenbus_driver(dev->driver);
- xdev = container_of(dev, struct xenbus_device, dev);
if (drv->suspend)
- err = drv->suspend(xdev, state);
+- err = drv->suspend(xdev, state);
++ err = drv->suspend(xdev);
if (err)
-@@ -695,21 +593,19 @@ static int xenbus_dev_suspend(struct device *dev, pm_message_t state)
+ printk(KERN_WARNING
"xenbus: suspend %s failed: %i\n", dev_name(dev), err);
return 0;
}
@@ -30595,35 +31110,34 @@ index 649fcdf..3a83ba2 100644
err = talk_to_otherend(xdev);
if (err) {
printk(KERN_WARNING
-@@ -740,6 +636,7 @@ static int xenbus_dev_resume(struct device *dev)
+@@ -740,6 +636,15 @@ static int xenbus_dev_resume(struct device *dev)
return 0;
}
+EXPORT_SYMBOL_GPL(xenbus_dev_resume);
++
++int xenbus_dev_cancel(struct device *dev)
++{
++ /* Do nothing */
++ DPRINTK("cancel");
++ return 0;
++}
++EXPORT_SYMBOL_GPL(xenbus_dev_cancel);
/* A flag to determine if xenstored is 'ready' (i.e. has started) */
int xenstored_ready = 0;
-@@ -749,10 +646,7 @@ int register_xenstore_notifier(struct notifier_block *nb)
- {
- int ret = 0;
-
-- if (xenstored_ready > 0)
-- ret = nb->notifier_call(nb, 0, NULL);
-- else
-- blocking_notifier_chain_register(&xenstore_chain, nb);
-+ blocking_notifier_chain_register(&xenstore_chain, nb);
+@@ -766,59 +671,96 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
- return ret;
- }
-@@ -768,57 +662,93 @@ void xenbus_probe(struct work_struct *unused)
+ void xenbus_probe(struct work_struct *unused)
{
- BUG_ON((xenstored_ready <= 0));
-
+- BUG_ON((xenstored_ready <= 0));
+-
- /* Enumerate devices in xenstore and watch for changes. */
- xenbus_probe_devices(&xenbus_frontend);
- register_xenbus_watch(&fe_watch);
- xenbus_backend_probe_and_watch();
--
++ xenstored_ready = 1;
+
/* Notify others that xenstore is up */
blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
}
@@ -30714,6 +31228,7 @@ index 649fcdf..3a83ba2 100644
+ xen_store_evtchn = xen_start_info->store_evtchn;
+ xen_store_mfn = xen_start_info->store_mfn;
+ xen_store_interface = mfn_to_virt(xen_store_mfn);
++ xenstored_ready = 1;
+ }
}
- xen_store_interface = mfn_to_virt(xen_store_mfn);
@@ -30733,7 +31248,7 @@ index 649fcdf..3a83ba2 100644
#ifdef CONFIG_XEN_COMPAT_XENFS
/*
* Create xenfs mountpoint in /proc for compatibility with
-@@ -829,128 +759,13 @@ static int __init xenbus_probe_init(void)
+@@ -829,128 +771,13 @@ static int __init xenbus_probe_init(void)
return 0;
@@ -30867,7 +31382,7 @@ index 649fcdf..3a83ba2 100644
-late_initcall(boot_wait_for_devices);
-#endif
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h
-index 6c5e318..0e5fc4c 100644
+index 6c5e318..4019187 100644
--- a/drivers/xen/xenbus/xenbus_probe.h
+++ b/drivers/xen/xenbus/xenbus_probe.h
@@ -36,26 +36,13 @@
@@ -30899,14 +31414,15 @@ index 6c5e318..0e5fc4c 100644
struct bus_type bus;
};
-@@ -73,4 +60,16 @@ extern int xenbus_probe_devices(struct xen_bus_type *bus);
+@@ -73,4 +60,17 @@ extern int xenbus_probe_devices(struct xen_bus_type *bus);
extern void xenbus_dev_changed(const char *node, struct xen_bus_type *bus);
+extern void xenbus_dev_shutdown(struct device *_dev);
+
-+extern int xenbus_dev_suspend(struct device *dev, pm_message_t state);
++extern int xenbus_dev_suspend(struct device *dev);
+extern int xenbus_dev_resume(struct device *dev);
++extern int xenbus_dev_cancel(struct device *dev);
+
+extern void xenbus_otherend_changed(struct xenbus_watch *watch,
+ const char **vec, unsigned int len,
@@ -31217,10 +31733,10 @@ index 0000000..9b9dd36
+subsys_initcall(xenbus_probe_backend_init);
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
new file mode 100644
-index 0000000..5413248
+index 0000000..f91b310
--- /dev/null
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
-@@ -0,0 +1,292 @@
+@@ -0,0 +1,298 @@
+#define DPRINTK(fmt, args...) \
+ pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \
+ __func__, __LINE__, ##args)
@@ -31305,6 +31821,13 @@ index 0000000..5413248
+ __ATTR_NULL
+};
+
++static const struct dev_pm_ops xenbus_pm_ops = {
++ .suspend = xenbus_dev_suspend,
++ .resume = xenbus_dev_resume,
++ .freeze = xenbus_dev_suspend,
++ .thaw = xenbus_dev_cancel,
++ .restore = xenbus_dev_resume,
++};
+
+static struct xen_bus_type xenbus_frontend = {
+ .root = "device",
@@ -31313,16 +31836,15 @@ index 0000000..5413248
+ .probe = xenbus_probe_frontend,
+ .otherend_changed = backend_changed,
+ .bus = {
-+ .name = "xen",
-+ .match = xenbus_match,
-+ .uevent = xenbus_uevent_frontend,
-+ .probe = xenbus_dev_probe,
-+ .remove = xenbus_dev_remove,
-+ .shutdown = xenbus_dev_shutdown,
-+ .dev_attrs= xenbus_frontend_dev_attrs,
-+
-+ .suspend = xenbus_dev_suspend,
-+ .resume = xenbus_dev_resume,
++ .name = "xen",
++ .match = xenbus_match,
++ .uevent = xenbus_uevent_frontend,
++ .probe = xenbus_dev_probe,
++ .remove = xenbus_dev_remove,
++ .shutdown = xenbus_dev_shutdown,
++ .dev_attrs = xenbus_frontend_dev_attrs,
++
++ .pm = &xenbus_pm_ops,
+ },
+};
+
@@ -32476,7 +32998,7 @@ index 26373cf..9fb4270 100644
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 7ad3faa..cf9ddce 100644
+index 66713c6..29c4ec1 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1388,7 +1388,7 @@ extern int drm_vma_info(struct seq_file *m, void *data);
@@ -32628,7 +33150,7 @@ index 11e5be6..4c98621 100644
/*
* set_policy() op must add a reference to any non-NULL @new mempolicy
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index ec12f8c..3f4991c 100644
+index c27a182..04a08e7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -28,6 +28,7 @@
@@ -32751,10 +33273,10 @@ index e07d194..ca28e46 100644
#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
-index 07ed684..49cd5c9 100644
+index fe2f4ee..b72b9e6 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
-@@ -2715,3 +2715,6 @@
+@@ -2717,3 +2717,6 @@
#define PCI_DEVICE_ID_RME_DIGI32 0x9896
#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
@@ -35039,9 +35561,27 @@ index 0000000..f31fdab
+
+#endif /* __XEN_PUBLIC_ARCH_X86_MCA_H__ */
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
-index 2befa3e..9ffaee0 100644
+index 2befa3e..391e0b7 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
+@@ -30,7 +30,7 @@
+ #define __HYPERVISOR_stack_switch 3
+ #define __HYPERVISOR_set_callbacks 4
+ #define __HYPERVISOR_fpu_taskswitch 5
+-#define __HYPERVISOR_sched_op 6
++#define __HYPERVISOR_sched_op_compat 6
+ #define __HYPERVISOR_dom0_op 7
+ #define __HYPERVISOR_set_debugreg 8
+ #define __HYPERVISOR_get_debugreg 9
+@@ -52,7 +52,7 @@
+ #define __HYPERVISOR_mmuext_op 26
+ #define __HYPERVISOR_acm_op 27
+ #define __HYPERVISOR_nmi_op 28
+-#define __HYPERVISOR_sched_op_new 29
++#define __HYPERVISOR_sched_op 29
+ #define __HYPERVISOR_callback_op 30
+ #define __HYPERVISOR_xenoprof_op 31
+ #define __HYPERVISOR_event_channel_op 32
@@ -79,6 +79,7 @@
#define VIRQ_CONSOLE 2 /* (DOM0) Bytes received on emergency console. */
#define VIRQ_DOM_EXC 3 /* (DOM0) Exceptional event for some domain. */
@@ -35315,14 +35855,18 @@ index 0000000..b42cdfd
+
+#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
-index 883a21b..7058f8a 100644
+index 883a21b..4349e89 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
-@@ -7,6 +7,7 @@ DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
+@@ -5,8 +5,9 @@
+
+ DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
- void xen_pre_suspend(void);
- void xen_post_suspend(int suspend_cancelled);
-+void xen_hvm_post_suspend(int suspend_cancelled);
+-void xen_pre_suspend(void);
+-void xen_post_suspend(int suspend_cancelled);
++void xen_arch_pre_suspend(void);
++void xen_arch_post_suspend(int suspend_cancelled);
++void xen_arch_hvm_post_suspend(int suspend_cancelled);
void xen_mm_pin_all(void);
void xen_mm_unpin_all(void);
@@ -35384,12 +35928,15 @@ index 0000000..77604ed
+
+#endif /* _XEN_XEN_H */
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
-index b9763ba..542ca7c 100644
+index b9763ba..23e7f25 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
-@@ -93,7 +93,7 @@ struct xenbus_driver {
+@@ -91,9 +91,9 @@ struct xenbus_driver {
+ void (*otherend_changed)(struct xenbus_device *dev,
+ enum xenbus_state backend_state);
int (*remove)(struct xenbus_device *dev);
- int (*suspend)(struct xenbus_device *dev, pm_message_t state);
+- int (*suspend)(struct xenbus_device *dev, pm_message_t state);
++ int (*suspend)(struct xenbus_device *dev);
int (*resume)(struct xenbus_device *dev);
- int (*uevent)(struct xenbus_device *, char **, int, char *, int);
+ int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *);
@@ -36499,7 +37046,7 @@ index 0000000..bee577f
+}
+EXPORT_SYMBOL(xen_swiotlb_dma_supported);
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
-index ac25cd2..f6bbcd1 100644
+index ac25cd2..9ed5e19 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -1,118 +1,11 @@
@@ -37114,15 +37661,6 @@ index ac25cd2..f6bbcd1 100644
if (!map) {
swiotlb_full(dev, size, dir, 1);
map = io_tlb_overflow_buffer;
-@@ -632,7 +123,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
- * Ensure that the address returned is DMA'ble
- */
- if (!dma_capable(dev, dev_addr, size))
-- panic("map_single: bounce buffer is not DMA'ble");
-+ panic("DMA: swiotlb_map_single: bounce buffer is not DMA'ble");
-
- return dev_addr;
- }
@@ -697,7 +188,7 @@ swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
BUG_ON(dir == DMA_NONE);
@@ -37372,7 +37910,7 @@ index 680dcbb..4f701c2 100644
if (nr || force_flush)
flush_tlb_kernel_range(*start, *end);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
-index 450862e..ff35ce3 100644
+index abbe8fa..e661dd7 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -179,14 +179,24 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
@@ -37405,8 +37943,15 @@ index 450862e..ff35ce3 100644
int rc;
rc = ops->get_sset_count(dev, ETH_SS_TEST);
-@@ -206,9 +216,9 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
- if (ops->get_stats_count)
+@@ -201,14 +211,14 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
+ } else {
+ /* code path for obsolete hooks */
+
+- if (ops->self_test_count)
++ if (ops && ops->self_test_count)
+ info.testinfo_len = ops->self_test_count(dev);
+- if (ops->get_stats_count)
++ if (ops && ops->get_stats_count)
info.n_stats = ops->get_stats_count(dev);
}
- if (ops->get_regs_len)
diff --git a/xen.pvops.post.patch b/xen.pvops.post.patch
index 4108b5a..495a81a 100644
--- a/xen.pvops.post.patch
+++ b/xen.pvops.post.patch
@@ -66,51 +66,3 @@ index 2202b62..f371fe8 100644
} mm_context_t;
#ifdef CONFIG_SMP
-Date: Fri, 03 Dec 2010 21:48:34 +0100
-From: Paolo Bonzini <pbonzini@redhat.com>
-Subject: [PATCH xen/stable-2.6.32.x] fix ethtool_get_drvinfo NULL pointer dereference
-
-Fixes the following crash on "ethtool -i":
-
-BUG: unable to handle kernel NULL pointer dereference at 0000000000000148
-IP: [<ffffffff813bcfe2>] ethtool_get_drvinfo+0x106/0x1a5
-PGD d8040067 PUD d8041067 PMD 0
-Oops: 0000 [#1] SMP
-last sysfs file: /sys/devices/pci0000:00/0000:00:1c.0/0000:09:00.0/irq
-...
-Call Trace:
-[<ffffffff813bd298>] dev_ethtool+0x93/0x1153
-[<ffffffff810dd957>] ? __alloc_pages_nodemask+0x122/0x62d
-[<ffffffff810dd957>] ? __alloc_pages_nodemask+0x122/0x62d
-[<ffffffff811ee21e>] ? avc_has_perm+0x5c/0x6e
-[<ffffffff811158ad>] ? try_get_mem_cgroup_from_mm+0x39/0x49
-...
-RIP [<ffffffff813bcfe2>] ethtool_get_drvinfo+0x106/0x1a5
-
-The backport of 01414802 was incomplete. This is the patch we are
-using in RHEL6.
-
-Reported-by: M A Young <m.a.young@durham.ac.uk>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-Cc: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
----
- ethtool.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/net/core/ethtool.c b/net/core/ethtool.c
-index ff35ce3..8ca3a26 100644
---- a/net/core/ethtool.c
-+++ b/net/core/ethtool.c
-@@ -211,9 +211,9 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
- } else {
- /* code path for obsolete hooks */
-
-- if (ops->self_test_count)
-+ if (ops && ops->self_test_count)
- info.testinfo_len = ops->self_test_count(dev);
-- if (ops->get_stats_count)
-+ if (ops && ops->get_stats_count)
- info.n_stats = ops->get_stats_count(dev);
- }
- if (ops && ops->get_regs_len)
-