diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | config-generic | 2 | ||||
-rw-r--r-- | drm-upgrayedd.patch | 4 | ||||
-rw-r--r-- | ipc-shm-fix-information-leak-to-user.patch | 30 | ||||
-rw-r--r-- | ipc-zero-struct-memory-for-compat-fns.patch | 73 | ||||
-rw-r--r-- | kernel.spec | 25 | ||||
-rw-r--r-- | posix-cpu-timers-workaround-to-suppress-problems-with-mt-exec.patch | 60 | ||||
-rw-r--r-- | sources | 3 | ||||
-rw-r--r-- | xen.pvops.patch | 1531 | ||||
-rw-r--r-- | xen.pvops.post.patch | 48 |
10 files changed, 1055 insertions, 723 deletions
@@ -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 - @@ -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) - |