[kernel] r16168 - in dists/sid/linux-2.6/debian: . config/kernelarch-x86 patches/features/all/xen patches/features/all/xen/pvhvm patches/series
Ian Campbell
ijc-guest at alioth.debian.org
Fri Aug 20 06:29:56 UTC 2010
Author: ijc-guest
Date: Fri Aug 20 06:29:47 2010
New Revision: 16168
Log:
xen: backport pvhvm drivers from upstream.
Regenerate pvops.patch to match
Added:
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0001-xen-Add-support-for-HVM-hypercalls.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0002-x86-early-PV-on-HVM-features-initialization.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0003-x86-xen-event-channels-delivery-on-HVM.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0004-xen-Xen-PCI-platform-device-driver.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0005-xen-Add-suspend-resume-support-for-PV-on-HVM-guests.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0006-xen-Fix-find_unbound_irq-in-presence-of-ioapic-irqs.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0007-x86-Use-xen_vcpuop_clockevent-xen_clocksource-and.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0008-x86-Unplug-emulated-disks-and-nics.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0009-x86-Call-HVMOP_pagetable_dying-on-exit_mmap.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0010-xenfs-enable-for-HVM-domains-too.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0011-support-multiple-.discard.-sections-to-avoid-sectio.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0012-blkfront-do-not-create-a-PV-cdrom-device-if-xen_hvm.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0013-Introduce-CONFIG_XEN_PVHVM-compile-option.patch
dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0014-pvops-do-not-notify-callers-from-register_xenstore_.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/config/kernelarch-x86/config
dists/sid/linux-2.6/debian/patches/features/all/xen/pvops.patch
dists/sid/linux-2.6/debian/patches/series/21
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog Fri Aug 20 06:29:20 2010 (r16167)
+++ dists/sid/linux-2.6/debian/changelog Fri Aug 20 06:29:47 2010 (r16168)
@@ -21,6 +21,9 @@
[ Ritesh Raj Sarraf ]
* Add .gnu_debuglink information into kernel modules (Closes: #555549)
+ [ Ian Campbell ]
+ * xen: backport pvhvm drivers from upstream.
+
-- Ben Hutchings <ben at decadent.org.uk> Thu, 12 Aug 2010 23:20:55 +0100
linux-2.6 (2.6.32-20) unstable; urgency=low
Modified: dists/sid/linux-2.6/debian/config/kernelarch-x86/config
==============================================================================
--- dists/sid/linux-2.6/debian/config/kernelarch-x86/config Fri Aug 20 06:29:20 2010 (r16167)
+++ dists/sid/linux-2.6/debian/config/kernelarch-x86/config Fri Aug 20 06:29:47 2010 (r16168)
@@ -1268,6 +1268,7 @@
CONFIG_XENFS=m
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_SYS_HYPERVISOR=y
+CONFIG_XEN_PLATFORM_PCI=y
##
## file: fs/partitions/Kconfig
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0001-xen-Add-support-for-HVM-hypercalls.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0001-xen-Add-support-for-HVM-hypercalls.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,211 @@
+From f1d25fa1b16536b1dfe8ee41fd152b6960d618a1 Mon Sep 17 00:00:00 2001
+From: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+Date: Fri, 14 May 2010 12:38:24 +0100
+Subject: [PATCH] xen: Add support for HVM hypercalls.
+
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+Signed-off-by: Sheng Yang <sheng at linux.intel.com>
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+(cherry picked from commit 18f19aa62a267f2f759e278018f1032adf4c3774)
+---
+ arch/x86/include/asm/xen/hypercall.h | 6 ++
+ include/xen/hvm.h | 24 +++++++++
+ include/xen/interface/hvm/hvm_op.h | 35 ++++++++++++
+ include/xen/interface/hvm/params.h | 95 ++++++++++++++++++++++++++++++++++
+ 4 files changed, 160 insertions(+), 0 deletions(-)
+ create mode 100644 include/xen/hvm.h
+ create mode 100644 include/xen/interface/hvm/hvm_op.h
+ create mode 100644 include/xen/interface/hvm/params.h
+
+diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
+index 9c371e4..7fda040 100644
+--- a/arch/x86/include/asm/xen/hypercall.h
++++ b/arch/x86/include/asm/xen/hypercall.h
+@@ -417,6 +417,12 @@ HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
+ return _hypercall2(int, nmi_op, op, arg);
+ }
+
++static inline unsigned long __must_check
++HYPERVISOR_hvm_op(int op, void *arg)
++{
++ return _hypercall2(unsigned long, hvm_op, op, arg);
++}
++
+ static inline void
+ MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
+ {
+diff --git a/include/xen/hvm.h b/include/xen/hvm.h
+new file mode 100644
+index 0000000..5dfe8fb
+--- /dev/null
++++ b/include/xen/hvm.h
+@@ -0,0 +1,24 @@
++/* Simple wrappers around HVM functions */
++#ifndef XEN_HVM_H__
++#define XEN_HVM_H__
++
++#include <xen/interface/hvm/params.h>
++
++static inline int hvm_get_parameter(int idx, uint64_t *value)
++{
++ struct xen_hvm_param xhv;
++ int r;
++
++ xhv.domid = DOMID_SELF;
++ xhv.index = idx;
++ r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
++ if (r < 0) {
++ printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n",
++ idx, r);
++ return r;
++ }
++ *value = xhv.value;
++ return r;
++}
++
++#endif /* XEN_HVM_H__ */
+diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h
+new file mode 100644
+index 0000000..73c8c7e
+--- /dev/null
++++ b/include/xen/interface/hvm/hvm_op.h
+@@ -0,0 +1,35 @@
++/*
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++
++#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
++#define __XEN_PUBLIC_HVM_HVM_OP_H__
++
++/* Get/set subcommands: the second argument of the hypercall is a
++ * pointer to a xen_hvm_param struct. */
++#define HVMOP_set_param 0
++#define HVMOP_get_param 1
++struct xen_hvm_param {
++ domid_t domid; /* IN */
++ uint32_t index; /* IN */
++ uint64_t value; /* IN/OUT */
++};
++DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_param);
++
++#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
+diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h
+new file mode 100644
+index 0000000..1888d8c
+--- /dev/null
++++ b/include/xen/interface/hvm/params.h
+@@ -0,0 +1,95 @@
++/*
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++
++#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
++#define __XEN_PUBLIC_HVM_PARAMS_H__
++
++#include "hvm_op.h"
++
++/*
++ * Parameter space for HVMOP_{set,get}_param.
++ */
++
++/*
++ * How should CPU0 event-channel notifications be delivered?
++ * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
++ * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
++ * Domain = val[47:32], Bus = val[31:16],
++ * DevFn = val[15: 8], IntX = val[ 1: 0]
++ * val[63:56] == 2: val[7:0] is a vector number.
++ * If val == 0 then CPU0 event-channel notifications are not delivered.
++ */
++#define HVM_PARAM_CALLBACK_IRQ 0
++
++#define HVM_PARAM_STORE_PFN 1
++#define HVM_PARAM_STORE_EVTCHN 2
++
++#define HVM_PARAM_PAE_ENABLED 4
++
++#define HVM_PARAM_IOREQ_PFN 5
++
++#define HVM_PARAM_BUFIOREQ_PFN 6
++
++/*
++ * Set mode for virtual timers (currently x86 only):
++ * delay_for_missed_ticks (default):
++ * Do not advance a vcpu's time beyond the correct delivery time for
++ * interrupts that have been missed due to preemption. Deliver missed
++ * interrupts when the vcpu is rescheduled and advance the vcpu's virtual
++ * time stepwise for each one.
++ * no_delay_for_missed_ticks:
++ * As above, missed interrupts are delivered, but guest time always tracks
++ * wallclock (i.e., real) time while doing so.
++ * no_missed_ticks_pending:
++ * No missed interrupts are held pending. Instead, to ensure ticks are
++ * delivered at some non-zero rate, if we detect missed ticks then the
++ * internal tick alarm is not disabled if the VCPU is preempted during the
++ * next tick period.
++ * one_missed_tick_pending:
++ * Missed interrupts are collapsed together and delivered as one 'late tick'.
++ * Guest time always tracks wallclock (i.e., real) time.
++ */
++#define HVM_PARAM_TIMER_MODE 10
++#define HVMPTM_delay_for_missed_ticks 0
++#define HVMPTM_no_delay_for_missed_ticks 1
++#define HVMPTM_no_missed_ticks_pending 2
++#define HVMPTM_one_missed_tick_pending 3
++
++/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
++#define HVM_PARAM_HPET_ENABLED 11
++
++/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
++#define HVM_PARAM_IDENT_PT 12
++
++/* Device Model domain, defaults to 0. */
++#define HVM_PARAM_DM_DOMAIN 13
++
++/* ACPI S state: currently support S0 and S3 on x86. */
++#define HVM_PARAM_ACPI_S_STATE 14
++
++/* TSS used on Intel when CR0.PE=0. */
++#define HVM_PARAM_VM86_TSS 15
++
++/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
++#define HVM_PARAM_VPT_ALIGN 16
++
++#define HVM_NR_PARAMS 17
++
++#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0002-x86-early-PV-on-HVM-features-initialization.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0002-x86-early-PV-on-HVM-features-initialization.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,245 @@
+From 79bec05f7773879d51ff89e221713c86c2311c6c Mon Sep 17 00:00:00 2001
+From: Sheng Yang <sheng at linux.intel.com>
+Date: Fri, 14 May 2010 12:39:33 +0100
+Subject: [PATCH] x86: early PV on HVM features initialization.
+
+Initialize basic pv on hvm features in xen_hvm_guest_init.
+
+Don't try to initialize xen-kbdfront and xen-fbfront when running on HVM
+because the backends are not available.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Sheng Yang <sheng at linux.intel.com>
+Signed-off-by: Yaozu (Eddie) Dong <eddie.dong at intel.com>
+(cherry picked from commit bee6ab53e652a414af20392899879b58cd80d033 and
+adjusted to not use the generic hypervisor detection routines which are not in
+this kernel)
+---
+ arch/x86/include/asm/xen/hypervisor.h | 2 +
+ arch/x86/kernel/setup.c | 2 +
+ arch/x86/xen/enlighten.c | 85 +++++++++++++++++++++++++++++++++
+ drivers/input/xen-kbdfront.c | 2 +-
+ drivers/video/xen-fbfront.c | 2 +-
+ drivers/xen/xenbus/xenbus_probe.c | 21 +++++++-
+ 6 files changed, 109 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
+index d5b7e90..5d298fd 100644
+--- a/arch/x86/include/asm/xen/hypervisor.h
++++ b/arch/x86/include/asm/xen/hypervisor.h
+@@ -45,8 +45,10 @@ enum xen_domain_type {
+
+ #ifdef CONFIG_XEN
+ extern enum xen_domain_type xen_domain_type;
++extern void __init xen_hvm_guest_init(void);
+ #else
+ #define xen_domain_type XEN_NATIVE
++#define xen_hvm_guest_init() do { } while (0)
+ #endif
+
+ #define xen_domain() (xen_domain_type != XEN_NATIVE)
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index d7a0888..c852868 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -102,6 +102,7 @@
+
+ #include <asm/paravirt.h>
+ #include <asm/hypervisor.h>
++#include <asm/xen/hypervisor.h>
+
+ #include <asm/percpu.h>
+ #include <asm/topology.h>
+@@ -1034,6 +1035,7 @@ void __init setup_arch(char **cmdline_p)
+ probe_nr_irqs_gsi();
+
+ kvm_guest_init();
++ xen_hvm_guest_init();
+
+ e820_reserve_resources();
+ e820_mark_nosave_regions(max_low_pfn);
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 942ccf1..6bfbd45 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -32,6 +32,7 @@
+ #include <xen/interface/version.h>
+ #include <xen/interface/physdev.h>
+ #include <xen/interface/vcpu.h>
++#include <xen/interface/memory.h>
+ #include <xen/features.h>
+ #include <xen/page.h>
+ #include <xen/hvc-console.h>
+@@ -52,7 +53,9 @@
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
+ #include <asm/reboot.h>
++#include <asm/setup.h>
+ #include <asm/stackprotector.h>
++#include <asm/hypervisor.h>
+
+ #include "xen-ops.h"
+ #include "mmu.h"
+@@ -73,6 +76,8 @@ struct shared_info xen_dummy_shared_info;
+
+ void *xen_initial_gdt;
+
++RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
++
+ /*
+ * Point at some empty memory to start with. We map the real shared_info
+ * page as soon as fixmap is up and running.
+@@ -1197,3 +1202,83 @@ asmlinkage void __init xen_start_kernel(void)
+ x86_64_start_reservations((char *)__pa_symbol(&boot_params));
+ #endif
+ }
++
++static uint32_t xen_cpuid_base(void)
++{
++ uint32_t base, eax, ebx, ecx, edx;
++ char signature[13];
++
++ for (base = 0x40000000; base < 0x40010000; base += 0x100) {
++ cpuid(base, &eax, &ebx, &ecx, &edx);
++ *(uint32_t *)(signature + 0) = ebx;
++ *(uint32_t *)(signature + 4) = ecx;
++ *(uint32_t *)(signature + 8) = edx;
++ signature[12] = 0;
++
++ if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2))
++ return base;
++ }
++
++ return 0;
++}
++
++static int init_hvm_pv_info(int *major, int *minor)
++{
++ uint32_t eax, ebx, ecx, edx, pages, msr, base;
++ u64 pfn;
++
++ base = xen_cpuid_base();
++ cpuid(base + 1, &eax, &ebx, &ecx, &edx);
++
++ *major = eax >> 16;
++ *minor = eax & 0xffff;
++ printk(KERN_INFO "Xen version %d.%d.\n", *major, *minor);
++
++ cpuid(base + 2, &pages, &msr, &ecx, &edx);
++
++ pfn = __pa(hypercall_page);
++ wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
++
++ xen_setup_features();
++
++ pv_info = xen_info;
++ pv_info.kernel_rpl = 0;
++
++ xen_domain_type = XEN_HVM_DOMAIN;
++
++ return 0;
++}
++
++static void __init init_shared_info(void)
++{
++ struct xen_add_to_physmap xatp;
++ struct shared_info *shared_info_page;
++
++ shared_info_page = (struct shared_info *)
++ extend_brk(PAGE_SIZE, PAGE_SIZE);
++ xatp.domid = DOMID_SELF;
++ xatp.idx = 0;
++ xatp.space = XENMAPSPACE_shared_info;
++ xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
++ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
++ BUG();
++
++ HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
++
++ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
++}
++
++void __init xen_hvm_guest_init(void)
++{
++ int r;
++ int major, minor;
++
++ if (xen_pv_domain())
++ return;
++
++ r = init_hvm_pv_info(&major, &minor);
++ if (r < 0)
++ return;
++
++ init_shared_info();
++}
+diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
+index b115726..8ec2201 100644
+--- a/drivers/input/xen-kbdfront.c
++++ b/drivers/input/xen-kbdfront.c
+@@ -335,7 +335,7 @@ static struct xenbus_driver xenkbd_driver = {
+
+ static int __init xenkbd_init(void)
+ {
+- if (!xen_domain())
++ if (!xen_pv_domain())
+ return -ENODEV;
+
+ /* Nothing to do if running in dom0. */
+diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
+index 54cd916..450f958 100644
+--- a/drivers/video/xen-fbfront.c
++++ b/drivers/video/xen-fbfront.c
+@@ -680,7 +680,7 @@ static struct xenbus_driver xenfb_driver = {
+
+ static int __init xenfb_init(void)
+ {
+- if (!xen_domain())
++ if (!xen_pv_domain())
+ return -ENODEV;
+
+ /* Nothing to do if running in dom0. */
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 649fcdf..568d14d 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -53,6 +53,8 @@
+ #include <xen/events.h>
+ #include <xen/page.h>
+
++#include <xen/hvm.h>
++
+ #include "xenbus_comms.h"
+ #include "xenbus_probe.h"
+
+@@ -802,11 +804,24 @@ static int __init xenbus_probe_init(void)
+ if (xen_initial_domain()) {
+ /* dom0 not yet supported */
+ } else {
++ if (xen_hvm_domain()) {
++ uint64_t v = 0;
++ err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
++ if (err)
++ goto out_error;
++ xen_store_evtchn = (int)v;
++ err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
++ if (err)
++ goto out_error;
++ xen_store_mfn = (unsigned long)v;
++ xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
++ } else {
++ 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_evtchn = xen_start_info->store_evtchn;
+- xen_store_mfn = xen_start_info->store_mfn;
+ }
+- xen_store_interface = mfn_to_virt(xen_store_mfn);
+
+ /* Initialize the interface to xenstore. */
+ err = xs_init();
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0003-x86-xen-event-channels-delivery-on-HVM.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0003-x86-xen-event-channels-delivery-on-HVM.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,334 @@
+From 48a0a3d35ae1c2b5851620b46713f536bf6978f8 Mon Sep 17 00:00:00 2001
+From: Sheng Yang <sheng at linux.intel.com>
+Date: Fri, 14 May 2010 12:40:51 +0100
+Subject: [PATCH] x86/xen: event channels delivery on HVM.
+
+Set the callback to receive evtchns from Xen, using the
+callback vector delivery mechanism.
+
+The traditional way for receiving event channel notifications from Xen
+is via the interrupts from the platform PCI device.
+The callback vector is a newer alternative that allow us to receive
+notifications on any vcpu and doesn't need any PCI support: we allocate
+a vector exclusively to receive events, in the vector handler we don't
+need to interact with the vlapic, therefore we avoid a VMEXIT.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Sheng Yang <sheng at linux.intel.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 38e20b07efd541a959de367dc90a17f92ce2e8a6 with
+trivial merge conflicts resolved in arch/x86/include/asm/irq_vectors.h
+arch/x86/xen/enlighten.c)
+---
+ arch/x86/include/asm/irq_vectors.h | 3 ++
+ arch/x86/kernel/entry_32.S | 3 ++
+ arch/x86/kernel/entry_64.S | 3 ++
+ arch/x86/xen/enlighten.c | 28 ++++++++++++++
+ arch/x86/xen/xen-ops.h | 2 +
+ drivers/xen/events.c | 69 ++++++++++++++++++++++++++++++++----
+ include/xen/events.h | 7 ++++
+ include/xen/hvm.h | 6 +++
+ include/xen/interface/features.h | 3 ++
+ 9 files changed, 117 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
+index 6e90a04..893179f 100644
+--- a/arch/x86/include/asm/irq_vectors.h
++++ b/arch/x86/include/asm/irq_vectors.h
+@@ -120,6 +120,9 @@
+ */
+ #define MCE_SELF_VECTOR 0xeb
+
++/* Xen vector callback to receive events in a HVM domain */
++#define XEN_HVM_EVTCHN_CALLBACK 0xe9
++
+ /*
+ * First APIC vector available to drivers: (vectors 0x30-0xee) we
+ * start at 0x31(0x41) to spread out vectors evenly between priority
+diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
+index c097e7d..7764118 100644
+--- a/arch/x86/kernel/entry_32.S
++++ b/arch/x86/kernel/entry_32.S
+@@ -1088,6 +1088,9 @@ ENTRY(xen_failsafe_callback)
+ .previous
+ ENDPROC(xen_failsafe_callback)
+
++BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
++ xen_evtchn_do_upcall)
++
+ #endif /* CONFIG_XEN */
+
+ #ifdef CONFIG_FUNCTION_TRACER
+diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
+index b5c061f..a626344 100644
+--- a/arch/x86/kernel/entry_64.S
++++ b/arch/x86/kernel/entry_64.S
+@@ -1364,6 +1364,9 @@ ENTRY(xen_failsafe_callback)
+ CFI_ENDPROC
+ END(xen_failsafe_callback)
+
++apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
++ xen_hvm_callback_vector xen_evtchn_do_upcall
++
+ #endif /* CONFIG_XEN */
+
+ /*
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 6bfbd45..786fd94 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -11,6 +11,7 @@
+ * Jeremy Fitzhardinge <jeremy at xensource.com>, XenSource Inc, 2007
+ */
+
++#include <linux/cpu.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/smp.h>
+@@ -35,6 +36,7 @@
+ #include <xen/interface/memory.h>
+ #include <xen/features.h>
+ #include <xen/page.h>
++#include <xen/hvm.h>
+ #include <xen/hvc-console.h>
+
+ #include <asm/paravirt.h>
+@@ -77,6 +79,8 @@ struct shared_info xen_dummy_shared_info;
+ void *xen_initial_gdt;
+
+ RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
++__read_mostly int xen_have_vector_callback;
++EXPORT_SYMBOL_GPL(xen_have_vector_callback);
+
+ /*
+ * Point at some empty memory to start with. We map the real shared_info
+@@ -1268,6 +1272,24 @@ static void __init init_shared_info(void)
+ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
+ }
+
++static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
++ unsigned long action, void *hcpu)
++{
++ int cpu = (long)hcpu;
++ switch (action) {
++ case CPU_UP_PREPARE:
++ per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
++ break;
++ default:
++ break;
++ }
++ return NOTIFY_OK;
++}
++
++static struct notifier_block __cpuinitdata xen_hvm_cpu_notifier = {
++ .notifier_call = xen_hvm_cpu_notify,
++};
++
+ void __init xen_hvm_guest_init(void)
+ {
+ int r;
+@@ -1281,4 +1303,10 @@ void __init xen_hvm_guest_init(void)
+ return;
+
+ init_shared_info();
++
++ if (xen_feature(XENFEAT_hvm_callback_vector))
++ xen_have_vector_callback = 1;
++ register_cpu_notifier(&xen_hvm_cpu_notifier);
++ have_vcpu_info_placement = 0;
++ x86_init.irqs.intr_init = xen_init_IRQ;
+ }
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index f9153a3..0d0e0e6 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -38,6 +38,8 @@ void xen_enable_sysenter(void);
+ void xen_enable_syscall(void);
+ void xen_vcpu_restore(void);
+
++void xen_callback_vector(void);
++
+ void __init xen_build_dynamic_phys_to_machine(void);
+
+ void xen_init_irq_ops(void);
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index 30e0467..9b03dcd 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -28,6 +28,7 @@
+ #include <linux/string.h>
+ #include <linux/bootmem.h>
+
++#include <asm/desc.h>
+ #include <asm/ptrace.h>
+ #include <asm/irq.h>
+ #include <asm/idle.h>
+@@ -35,10 +36,13 @@
+ #include <asm/xen/hypercall.h>
+ #include <asm/xen/hypervisor.h>
+
++#include <xen/hvm.h>
+ #include <xen/xen-ops.h>
+ #include <xen/events.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/event_channel.h>
++#include <xen/interface/hvm/hvm_op.h>
++#include <xen/interface/hvm/params.h>
+
+ /*
+ * This lock protects updates to the following mapping and reference-count
+@@ -617,17 +621,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.
+ */
+-void xen_evtchn_do_upcall(struct pt_regs *regs)
++static void __xen_evtchn_do_upcall(struct pt_regs *regs)
+ {
+ int cpu = get_cpu();
+- struct pt_regs *old_regs = set_irq_regs(regs);
+ struct shared_info *s = HYPERVISOR_shared_info;
+ struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
+ unsigned count;
+
+- exit_idle();
+- irq_enter();
+-
+ do {
+ unsigned long pending_words;
+
+@@ -663,10 +663,26 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
+ } while(count != 1);
+
+ out:
++
++ put_cpu();
++}
++
++void xen_evtchn_do_upcall(struct pt_regs *regs)
++{
++ struct pt_regs *old_regs = set_irq_regs(regs);
++
++ exit_idle();
++ irq_enter();
++
++ __xen_evtchn_do_upcall(regs);
++
+ irq_exit();
+ set_irq_regs(old_regs);
++}
+
+- put_cpu();
++void xen_hvm_evtchn_do_upcall(void)
++{
++ __xen_evtchn_do_upcall(get_irq_regs());
+ }
+
+ /* Rebind a new event channel to an existing irq. */
+@@ -929,6 +945,40 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
+ .retrigger = retrigger_dynirq,
+ };
+
++int xen_set_callback_via(uint64_t via)
++{
++ struct xen_hvm_param a;
++ a.domid = DOMID_SELF;
++ a.index = HVM_PARAM_CALLBACK_IRQ;
++ a.value = via;
++ return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
++}
++EXPORT_SYMBOL_GPL(xen_set_callback_via);
++
++/* Vector callbacks are better than PCI interrupts to receive event
++ * channel notifications because we can receive vector callbacks on any
++ * vcpu and we don't need PCI support or APIC interactions. */
++void xen_callback_vector(void)
++{
++ int rc;
++ uint64_t callback_via;
++ if (xen_have_vector_callback) {
++ callback_via = HVM_CALLBACK_VECTOR(XEN_HVM_EVTCHN_CALLBACK);
++ rc = xen_set_callback_via(callback_via);
++ if (rc) {
++ printk(KERN_ERR "Request for Xen HVM callback vector"
++ " failed.\n");
++ xen_have_vector_callback = 0;
++ return;
++ }
++ printk(KERN_INFO "Xen HVM callback vector for event delivery is "
++ "enabled\n");
++ /* 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);
++ }
++}
++
+ void __init xen_init_IRQ(void)
+ {
+ int i;
+@@ -943,5 +993,10 @@ void __init xen_init_IRQ(void)
+ for (i = 0; i < NR_EVENT_CHANNELS; i++)
+ mask_evtchn(i);
+
+- irq_ctx_init(smp_processor_id());
++ if (xen_hvm_domain()) {
++ xen_callback_vector();
++ native_init_IRQ();
++ } else {
++ irq_ctx_init(smp_processor_id());
++ }
+ }
+diff --git a/include/xen/events.h b/include/xen/events.h
+index e68d59a..a15d932 100644
+--- a/include/xen/events.h
++++ b/include/xen/events.h
+@@ -56,4 +56,11 @@ void xen_poll_irq(int irq);
+ /* Determine the IRQ which is bound to an event channel */
+ unsigned irq_from_evtchn(unsigned int evtchn);
+
++/* Xen HVM evtchn vector callback */
++extern void xen_hvm_callback_vector(void);
++extern int xen_have_vector_callback;
++int xen_set_callback_via(uint64_t via);
++void xen_evtchn_do_upcall(struct pt_regs *regs);
++void xen_hvm_evtchn_do_upcall(void);
++
+ #endif /* _XEN_EVENTS_H */
+diff --git a/include/xen/hvm.h b/include/xen/hvm.h
+index 5dfe8fb..b193fa2 100644
+--- a/include/xen/hvm.h
++++ b/include/xen/hvm.h
+@@ -3,6 +3,7 @@
+ #define XEN_HVM_H__
+
+ #include <xen/interface/hvm/params.h>
++#include <asm/xen/hypercall.h>
+
+ static inline int hvm_get_parameter(int idx, uint64_t *value)
+ {
+@@ -21,4 +22,9 @@ static inline int hvm_get_parameter(int idx, uint64_t *value)
+ return r;
+ }
+
++#define HVM_CALLBACK_VIA_TYPE_VECTOR 0x2
++#define HVM_CALLBACK_VIA_TYPE_SHIFT 56
++#define HVM_CALLBACK_VECTOR(x) (((uint64_t)HVM_CALLBACK_VIA_TYPE_VECTOR)<<\
++ HVM_CALLBACK_VIA_TYPE_SHIFT | (x))
++
+ #endif /* XEN_HVM_H__ */
+diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
+index f51b641..8ab08b9 100644
+--- a/include/xen/interface/features.h
++++ b/include/xen/interface/features.h
+@@ -41,6 +41,9 @@
+ /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
+ #define XENFEAT_mmu_pt_update_preserve_ad 5
+
++/* x86: Does this Xen host support the HVM callback vector type? */
++#define XENFEAT_hvm_callback_vector 8
++
+ #define XENFEAT_NR_SUBMAPS 1
+
+ #endif /* __XEN_PUBLIC_FEATURES_H__ */
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0004-xen-Xen-PCI-platform-device-driver.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0004-xen-Xen-PCI-platform-device-driver.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,564 @@
+From 6bbaa5ed0ec08dd8f30d271956dc8f1db8a92fca Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Mon, 17 May 2010 17:08:21 +0100
+Subject: [PATCH] xen: Xen PCI platform device driver.
+
+Add the xen pci platform device driver that is responsible
+for initializing the grant table and xenbus in PV on HVM mode.
+Few changes to xenbus and grant table are necessary to allow the delayed
+initialization in HVM mode.
+Grant table needs few additional modifications to work in HVM mode.
+
+The Xen PCI platform device raises an irq every time an event has been
+delivered to us. However these interrupts are only delivered to vcpu 0.
+The Xen PCI platform interrupt handler calls xen_hvm_evtchn_do_upcall
+that is a little wrapper around __xen_evtchn_do_upcall, the traditional
+Xen upcall handler, the very same used with traditional PV guests.
+
+When running on HVM the event channel upcall is never called while in
+progress because it is a normal Linux irq handler (and we cannot switch
+the irq chip wholesale to the Xen PV ones as we are running QEMU and
+might have passed in PCI devices), therefore we cannot be sure that
+evtchn_upcall_pending is 0 when returning.
+For this reason if evtchn_upcall_pending is set by Xen we need to loop
+again on the event channels set pending otherwise we might loose some
+event channel deliveries.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Sheng Yang <sheng at linux.intel.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 183d03cc4ff39e0f0d952c09aa96d0abfd6e0c3c with
+trivial merge conflict resolved in drivers/xen/Kconfig)
+---
+ drivers/xen/Kconfig | 12 ++-
+ drivers/xen/Makefile | 3 +-
+ drivers/xen/events.c | 8 +-
+ drivers/xen/grant-table.c | 77 +++++++++++++--
+ drivers/xen/manage.c | 1 +
+ drivers/xen/platform-pci.c | 181 +++++++++++++++++++++++++++++++++++
+ drivers/xen/xenbus/xenbus_probe.c | 22 ++++-
+ include/linux/pci_ids.h | 3 +
+ include/xen/grant_table.h | 4 +
+ include/xen/interface/grant_table.h | 1 +
+ 10 files changed, 293 insertions(+), 19 deletions(-)
+ create mode 100644 drivers/xen/platform-pci.c
+
+diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
+index cab100a..f65d2c9 100644
+--- a/drivers/xen/Kconfig
++++ b/drivers/xen/Kconfig
+@@ -60,4 +60,14 @@ config XEN_SYS_HYPERVISOR
+ Create entries under /sys/hypervisor describing the Xen
+ hypervisor environment. When running native or in another
+ virtual environment, /sys/hypervisor will still be present,
+- but will have no xen contents.
+\ No newline at end of file
++ but will have no xen contents.
++
++config XEN_PLATFORM_PCI
++ tristate "xen platform pci device driver"
++ depends on XEN
++ default m
++ help
++ Driver for the Xen PCI Platform device: it is responsible for
++ initializing xenbus and grant_table when running in a Xen HVM
++ domain. As a consequence this driver is required to run any Xen PV
++ frontend on Xen HVM.
+diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
+index 7c28434..e392fb7 100644
+--- a/drivers/xen/Makefile
++++ b/drivers/xen/Makefile
+@@ -9,4 +9,5 @@ obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
+ obj-$(CONFIG_XEN_BALLOON) += balloon.o
+ obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o
+ obj-$(CONFIG_XENFS) += xenfs/
+-obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
+\ No newline at end of file
++obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
++obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index 9b03dcd..9d99c9a 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -660,7 +660,7 @@ static void __xen_evtchn_do_upcall(struct pt_regs *regs)
+
+ count = __get_cpu_var(xed_nesting_count);
+ __get_cpu_var(xed_nesting_count) = 0;
+- } while(count != 1);
++ } while (count != 1 || vcpu_info->evtchn_upcall_pending);
+
+ out:
+
+@@ -684,6 +684,7 @@ void xen_hvm_evtchn_do_upcall(void)
+ {
+ __xen_evtchn_do_upcall(get_irq_regs());
+ }
++EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
+
+ /* Rebind a new event channel to an existing irq. */
+ void rebind_evtchn_irq(int evtchn, int irq)
+@@ -720,7 +721,10 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
+ struct evtchn_bind_vcpu bind_vcpu;
+ int evtchn = evtchn_from_irq(irq);
+
+- if (!VALID_EVTCHN(evtchn))
++ /* events delivered via platform PCI interrupts are always
++ * routed to vcpu 0 */
++ if (!VALID_EVTCHN(evtchn) ||
++ (xen_hvm_domain() && !xen_have_vector_callback))
+ return -1;
+
+ /* Send future instances of this interrupt to other vcpu. */
+diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
+index 7d8f531..6652ce9 100644
+--- a/drivers/xen/grant-table.c
++++ b/drivers/xen/grant-table.c
+@@ -36,10 +36,12 @@
+ #include <linux/mm.h>
+ #include <linux/vmalloc.h>
+ #include <linux/uaccess.h>
++#include <linux/io.h>
+
+ #include <xen/interface/xen.h>
+ #include <xen/page.h>
+ #include <xen/grant_table.h>
++#include <xen/interface/memory.h>
+ #include <asm/xen/hypercall.h>
+
+ #include <asm/pgtable.h>
+@@ -57,6 +59,8 @@ static unsigned int boot_max_nr_grant_frames;
+ static int gnttab_free_count;
+ static grant_ref_t gnttab_free_head;
+ static DEFINE_SPINLOCK(gnttab_list_lock);
++unsigned long xen_hvm_resume_frames;
++EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
+
+ static struct grant_entry *shared;
+
+@@ -431,7 +435,7 @@ static unsigned int __max_nr_grant_frames(void)
+ return query.max_nr_frames;
+ }
+
+-static inline unsigned int max_nr_grant_frames(void)
++unsigned int gnttab_max_grant_frames(void)
+ {
+ unsigned int xen_max = __max_nr_grant_frames();
+
+@@ -439,6 +443,7 @@ static inline unsigned int max_nr_grant_frames(void)
+ return boot_max_nr_grant_frames;
+ return xen_max;
+ }
++EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
+
+ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+ {
+@@ -447,6 +452,30 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+ unsigned int nr_gframes = end_idx + 1;
+ int rc;
+
++ if (xen_hvm_domain()) {
++ struct xen_add_to_physmap xatp;
++ unsigned int i = end_idx;
++ rc = 0;
++ /*
++ * Loop backwards, so that the first hypercall has the largest
++ * index, ensuring that the table will grow only once.
++ */
++ do {
++ xatp.domid = DOMID_SELF;
++ xatp.idx = i;
++ xatp.space = XENMAPSPACE_grant_table;
++ xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i;
++ rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
++ if (rc != 0) {
++ printk(KERN_WARNING
++ "grant table add_to_physmap failed, err=%d\n", rc);
++ break;
++ }
++ } while (i-- > start_idx);
++
++ return rc;
++ }
++
+ frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
+ if (!frames)
+ return -ENOMEM;
+@@ -463,7 +492,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+
+ BUG_ON(rc || setup.status);
+
+- rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(),
++ rc = arch_gnttab_map_shared(frames, nr_gframes, gnttab_max_grant_frames(),
+ &shared);
+ BUG_ON(rc);
+
+@@ -474,9 +503,27 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+
+ int gnttab_resume(void)
+ {
+- if (max_nr_grant_frames() < nr_grant_frames)
++ unsigned int max_nr_gframes;
++
++ max_nr_gframes = gnttab_max_grant_frames();
++ if (max_nr_gframes < nr_grant_frames)
+ return -ENOSYS;
+- return gnttab_map(0, nr_grant_frames - 1);
++
++ if (xen_pv_domain())
++ return gnttab_map(0, nr_grant_frames - 1);
++
++ if (!shared) {
++ shared = ioremap(xen_hvm_resume_frames, PAGE_SIZE * max_nr_gframes);
++ if (shared == NULL) {
++ printk(KERN_WARNING
++ "Failed to ioremap gnttab share frames!");
++ return -ENOMEM;
++ }
++ }
++
++ gnttab_map(0, nr_grant_frames - 1);
++
++ return 0;
+ }
+
+ int gnttab_suspend(void)
+@@ -493,7 +540,7 @@ static int gnttab_expand(unsigned int req_entries)
+ cur = nr_grant_frames;
+ extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
+ GREFS_PER_GRANT_FRAME);
+- if (cur + extra > max_nr_grant_frames())
++ if (cur + extra > gnttab_max_grant_frames())
+ return -ENOSPC;
+
+ rc = gnttab_map(cur, cur + extra - 1);
+@@ -503,15 +550,12 @@ static int gnttab_expand(unsigned int req_entries)
+ return rc;
+ }
+
+-static int __devinit gnttab_init(void)
++int gnttab_init(void)
+ {
+ int i;
+ unsigned int max_nr_glist_frames, nr_glist_frames;
+ unsigned int nr_init_grefs;
+
+- if (!xen_domain())
+- return -ENODEV;
+-
+ nr_grant_frames = 1;
+ boot_max_nr_grant_frames = __max_nr_grant_frames();
+
+@@ -554,5 +598,18 @@ static int __devinit gnttab_init(void)
+ kfree(gnttab_list);
+ return -ENOMEM;
+ }
++EXPORT_SYMBOL_GPL(gnttab_init);
++
++static int __devinit __gnttab_init(void)
++{
++ /* Delay grant-table initialization in the PV on HVM case */
++ if (xen_hvm_domain())
++ return 0;
++
++ if (!xen_pv_domain())
++ return -ENODEV;
++
++ return gnttab_init();
++}
+
+-core_initcall(gnttab_init);
++core_initcall(__gnttab_init);
+diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
+index 5d42d55..95e7b32 100644
+--- a/drivers/xen/manage.c
++++ b/drivers/xen/manage.c
+@@ -269,5 +269,6 @@ static int __init setup_shutdown_event(void)
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
+
+ subsys_initcall(setup_shutdown_event);
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+new file mode 100644
+index 0000000..a0ee5d0
+--- /dev/null
++++ b/drivers/xen/platform-pci.c
+@@ -0,0 +1,181 @@
++/******************************************************************************
++ * platform-pci.c
++ *
++ * Xen platform PCI device driver
++ * Copyright (c) 2005, Intel Corporation.
++ * Copyright (c) 2007, XenSource Inc.
++ * Copyright (c) 2010, Citrix
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ * Place - Suite 330, Boston, MA 02111-1307 USA.
++ *
++ */
++
++
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++
++#include <xen/grant_table.h>
++#include <xen/xenbus.h>
++#include <xen/events.h>
++#include <xen/hvm.h>
++
++#define DRV_NAME "xen-platform-pci"
++
++MODULE_AUTHOR("ssmith at xensource.com and stefano.stabellini at eu.citrix.com");
++MODULE_DESCRIPTION("Xen platform PCI device");
++MODULE_LICENSE("GPL");
++
++static unsigned long platform_mmio;
++static unsigned long platform_mmio_alloc;
++static unsigned long platform_mmiolen;
++
++unsigned long alloc_xen_mmio(unsigned long len)
++{
++ unsigned long addr;
++
++ addr = platform_mmio + platform_mmio_alloc;
++ platform_mmio_alloc += len;
++ BUG_ON(platform_mmio_alloc > platform_mmiolen);
++
++ return addr;
++}
++
++static uint64_t get_callback_via(struct pci_dev *pdev)
++{
++ u8 pin;
++ int irq;
++
++ irq = pdev->irq;
++ if (irq < 16)
++ return irq; /* ISA IRQ */
++
++ pin = pdev->pin;
++
++ /* We don't know the GSI. Specify the PCI INTx line instead. */
++ return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */
++ ((uint64_t)pci_domain_nr(pdev->bus) << 32) |
++ ((uint64_t)pdev->bus->number << 16) |
++ ((uint64_t)(pdev->devfn & 0xff) << 8) |
++ ((uint64_t)(pin - 1) & 3);
++}
++
++static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
++{
++ xen_hvm_evtchn_do_upcall();
++ return IRQ_HANDLED;
++}
++
++static int xen_allocate_irq(struct pci_dev *pdev)
++{
++ return request_irq(pdev->irq, do_hvm_evtchn_intr,
++ IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
++ "xen-platform-pci", pdev);
++}
++
++static int __devinit platform_pci_init(struct pci_dev *pdev,
++ const struct pci_device_id *ent)
++{
++ int i, ret;
++ long ioaddr, iolen;
++ long mmio_addr, mmio_len;
++ uint64_t callback_via;
++ unsigned int max_nr_gframes;
++
++ i = pci_enable_device(pdev);
++ if (i)
++ return i;
++
++ ioaddr = pci_resource_start(pdev, 0);
++ iolen = pci_resource_len(pdev, 0);
++
++ mmio_addr = pci_resource_start(pdev, 1);
++ mmio_len = pci_resource_len(pdev, 1);
++
++ if (mmio_addr == 0 || ioaddr == 0) {
++ dev_err(&pdev->dev, "no resources found\n");
++ ret = -ENOENT;
++ goto pci_out;
++ }
++
++ if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {
++ dev_err(&pdev->dev, "MEM I/O resource 0x%lx @ 0x%lx busy\n",
++ mmio_addr, mmio_len);
++ ret = -EBUSY;
++ goto pci_out;
++ }
++
++ if (request_region(ioaddr, iolen, DRV_NAME) == NULL) {
++ dev_err(&pdev->dev, "I/O resource 0x%lx @ 0x%lx busy\n",
++ iolen, ioaddr);
++ ret = -EBUSY;
++ goto mem_out;
++ }
++
++ platform_mmio = mmio_addr;
++ platform_mmiolen = mmio_len;
++
++ if (!xen_have_vector_callback) {
++ ret = xen_allocate_irq(pdev);
++ if (ret) {
++ dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret);
++ goto out;
++ }
++ callback_via = get_callback_via(pdev);
++ ret = xen_set_callback_via(callback_via);
++ if (ret) {
++ dev_warn(&pdev->dev, "Unable to set the evtchn callback "
++ "err=%d\n", ret);
++ goto out;
++ }
++ }
++
++ max_nr_gframes = gnttab_max_grant_frames();
++ xen_hvm_resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
++ ret = gnttab_init();
++ if (ret)
++ goto out;
++ xenbus_probe(NULL);
++ return 0;
++
++out:
++ release_region(ioaddr, iolen);
++mem_out:
++ release_mem_region(mmio_addr, mmio_len);
++pci_out:
++ pci_disable_device(pdev);
++ return ret;
++}
++
++static struct pci_device_id platform_pci_tbl[] __devinitdata = {
++ {PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++ {0,}
++};
++
++MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
++
++static struct pci_driver platform_driver = {
++ .name = DRV_NAME,
++ .probe = platform_pci_init,
++ .id_table = platform_pci_tbl,
++};
++
++static int __init platform_pci_module_init(void)
++{
++ return pci_register_driver(&platform_driver);
++}
++
++module_init(platform_pci_module_init);
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 568d14d..e8169db 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -778,8 +778,23 @@ void xenbus_probe(struct work_struct *unused)
+ /* Notify others that xenstore is up */
+ blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
+ }
++EXPORT_SYMBOL_GPL(xenbus_probe);
+
+-static int __init xenbus_probe_init(void)
++static int __init xenbus_probe_initcall(void)
++{
++ if (!xen_domain())
++ return -ENODEV;
++
++ if (xen_initial_domain() || xen_hvm_domain())
++ return 0;
++
++ xenbus_probe(NULL);
++ return 0;
++}
++
++device_initcall(xenbus_probe_initcall);
++
++static int __init xenbus_init(void)
+ {
+ int err = 0;
+
+@@ -831,9 +846,6 @@ static int __init xenbus_probe_init(void)
+ goto out_unreg_back;
+ }
+
+- if (!xen_initial_domain())
+- xenbus_probe(NULL);
+-
+ #ifdef CONFIG_XEN_COMPAT_XENFS
+ /*
+ * Create xenfs mountpoint in /proc for compatibility with
+@@ -854,7 +866,7 @@ static int __init xenbus_probe_init(void)
+ return err;
+ }
+
+-postcore_initcall(xenbus_probe_init);
++postcore_initcall(xenbus_init);
+
+ MODULE_LICENSE("GPL");
+
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 67325bf..c398cc3 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -2712,3 +2712,6 @@
+ #define PCI_DEVICE_ID_RME_DIGI32 0x9896
+ #define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
+ #define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
++
++#define PCI_VENDOR_ID_XEN 0x5853
++#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
+diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
+index a40f1cd..9a73170 100644
+--- a/include/xen/grant_table.h
++++ b/include/xen/grant_table.h
+@@ -51,6 +51,7 @@ struct gnttab_free_callback {
+ u16 count;
+ };
+
++int gnttab_init(void);
+ int gnttab_suspend(void);
+ int gnttab_resume(void);
+
+@@ -112,6 +113,9 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
+ void arch_gnttab_unmap_shared(struct grant_entry *shared,
+ unsigned long nr_gframes);
+
++extern unsigned long xen_hvm_resume_frames;
++unsigned int gnttab_max_grant_frames(void);
++
+ #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
+
+ #endif /* __ASM_GNTTAB_H__ */
+diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
+index 39da93c..39e5717 100644
+--- a/include/xen/interface/grant_table.h
++++ b/include/xen/interface/grant_table.h
+@@ -28,6 +28,7 @@
+ #ifndef __XEN_PUBLIC_GRANT_TABLE_H__
+ #define __XEN_PUBLIC_GRANT_TABLE_H__
+
++#include <xen/interface/xen.h>
+
+ /***********************************
+ * GRANT TABLE REPRESENTATION
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0005-xen-Add-suspend-resume-support-for-PV-on-HVM-guests.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0005-xen-Add-suspend-resume-support-for-PV-on-HVM-guests.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,283 @@
+From 4c3557c9741ce066ef6bdbd678d02a4afba9540b Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Fri, 14 May 2010 12:45:07 +0100
+Subject: [PATCH] xen: Add suspend/resume support for PV on HVM guests.
+
+Suspend/resume requires few different things on HVM: the suspend
+hypercall is different; we don't need to save/restore memory related
+settings; except the shared info page and the callback mechanism.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 016b6f5fe8398b0291cece60b749d7c930a2e09c,
+ adusted for lack of hypervisor detection infrastructure)
+---
+ arch/x86/xen/enlighten.c | 25 ++++++++++++++++++-------
+ arch/x86/xen/suspend.c | 6 ++++++
+ arch/x86/xen/xen-ops.h | 1 +
+ drivers/xen/manage.c | 44 ++++++++++++++++++++++++++++++++++++++++----
+ drivers/xen/platform-pci.c | 22 +++++++++++++++++++++-
+ include/xen/xen-ops.h | 3 +++
+ 6 files changed, 89 insertions(+), 12 deletions(-)
+
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 786fd94..7f2cfe7 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -78,7 +78,6 @@ struct shared_info xen_dummy_shared_info;
+
+ void *xen_initial_gdt;
+
+-RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
+ __read_mostly int xen_have_vector_callback;
+ EXPORT_SYMBOL_GPL(xen_have_vector_callback);
+
+@@ -1253,13 +1252,15 @@ static int init_hvm_pv_info(int *major, int *minor)
+ return 0;
+ }
+
+-static void __init init_shared_info(void)
++void xen_hvm_init_shared_info(void)
+ {
++ int cpu;
+ struct xen_add_to_physmap xatp;
+- struct shared_info *shared_info_page;
++ static struct shared_info *shared_info_page = 0;
++
++ if (!shared_info_page)
++ shared_info_page = (struct shared_info *) alloc_bootmem_pages(PAGE_SIZE);
+
+- shared_info_page = (struct shared_info *)
+- extend_brk(PAGE_SIZE, PAGE_SIZE);
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = XENMAPSPACE_shared_info;
+@@ -1269,7 +1270,17 @@ static void __init init_shared_info(void)
+
+ HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
+
+- per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
++ /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
++ * page, we use it in the event channel upcall and in some pvclock
++ * related functions. We don't need the vcpu_info placement
++ * optimizations because we don't use any pv_mmu or pv_irq op on
++ * HVM.
++ * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is
++ * online but xen_hvm_init_shared_info is run at resume time too and
++ * in that case multiple vcpus might be online. */
++ for_each_online_cpu(cpu) {
++ per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
++ }
+ }
+
+ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
+@@ -1302,7 +1313,7 @@ void __init xen_hvm_guest_init(void)
+ if (r < 0)
+ return;
+
+- init_shared_info();
++ xen_hvm_init_shared_info();
+
+ if (xen_feature(XENFEAT_hvm_callback_vector))
+ xen_have_vector_callback = 1;
+diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
+index a9c6611..d07479c 100644
+--- a/arch/x86/xen/suspend.c
++++ b/arch/x86/xen/suspend.c
+@@ -26,6 +26,12 @@ void xen_pre_suspend(void)
+ BUG();
+ }
+
++void xen_hvm_post_suspend(int suspend_cancelled)
++{
++ xen_hvm_init_shared_info();
++ xen_callback_vector();
++}
++
+ void xen_post_suspend(int suspend_cancelled)
+ {
+ xen_build_mfn_list_list();
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index 0d0e0e6..01c9dd3 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -39,6 +39,7 @@ void xen_enable_syscall(void);
+ void xen_vcpu_restore(void);
+
+ void xen_callback_vector(void);
++void xen_hvm_init_shared_info(void);
+
+ void __init xen_build_dynamic_phys_to_machine(void);
+
+diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
+index 95e7b32..aee1f59 100644
+--- a/drivers/xen/manage.c
++++ b/drivers/xen/manage.c
+@@ -16,6 +16,7 @@
+
+ #include <asm/xen/hypercall.h>
+ #include <asm/xen/page.h>
++#include <asm/xen/hypervisor.h>
+
+ enum shutdown_state {
+ SHUTDOWN_INVALID = -1,
+@@ -32,10 +33,30 @@ enum shutdown_state {
+ 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);
++
++ xen_hvm_post_suspend(*cancelled);
++ gnttab_resume();
++
++ if (!*cancelled) {
++ xen_irq_resume();
++ xen_timer_resume();
++ }
++
++ return 0;
++}
++
++static int xen_suspend(void *data)
++{
+ int err;
++ int *cancelled = data;
+
+ BUG_ON(!irqs_disabled());
+
+@@ -111,7 +132,10 @@ static void do_suspend(void)
+ 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));
+
+ dpm_resume_noirq(PMSG_RESUME);
+
+@@ -260,7 +284,19 @@ static int shutdown_event(struct notifier_block *notifier,
+ return NOTIFY_DONE;
+ }
+
+-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;
++
++ if (!xen_pv_domain())
++ return -ENODEV;
++
++ return xen_setup_shutdown_event();
++}
++
++int xen_setup_shutdown_event(void)
+ {
+ static struct notifier_block xenstore_notifier = {
+ .notifier_call = shutdown_event
+@@ -271,4 +307,4 @@ static int __init setup_shutdown_event(void)
+ }
+ EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
+
+-subsys_initcall(setup_shutdown_event);
++subsys_initcall(__setup_shutdown_event);
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index a0ee5d0..bdb44f2 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -31,6 +31,7 @@
+ #include <xen/xenbus.h>
+ #include <xen/events.h>
+ #include <xen/hvm.h>
++#include <xen/xen-ops.h>
+
+ #define DRV_NAME "xen-platform-pci"
+
+@@ -41,6 +42,7 @@ MODULE_LICENSE("GPL");
+ static unsigned long platform_mmio;
+ static unsigned long platform_mmio_alloc;
+ static unsigned long platform_mmiolen;
++static uint64_t callback_via;
+
+ unsigned long alloc_xen_mmio(unsigned long len)
+ {
+@@ -85,13 +87,25 @@ static int xen_allocate_irq(struct pci_dev *pdev)
+ "xen-platform-pci", pdev);
+ }
+
++static int platform_pci_resume(struct pci_dev *pdev)
++{
++ int err;
++ if (xen_have_vector_callback)
++ return 0;
++ err = xen_set_callback_via(callback_via);
++ if (err) {
++ dev_err(&pdev->dev, "platform_pci_resume failure!\n");
++ return err;
++ }
++ return 0;
++}
++
+ static int __devinit platform_pci_init(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+ {
+ int i, ret;
+ long ioaddr, iolen;
+ long mmio_addr, mmio_len;
+- uint64_t callback_via;
+ unsigned int max_nr_gframes;
+
+ i = pci_enable_device(pdev);
+@@ -148,6 +162,9 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
+ if (ret)
+ goto out;
+ xenbus_probe(NULL);
++ ret = xen_setup_shutdown_event();
++ if (ret)
++ goto out;
+ return 0;
+
+ out:
+@@ -171,6 +188,9 @@ static struct pci_driver platform_driver = {
+ .name = DRV_NAME,
+ .probe = platform_pci_init,
+ .id_table = platform_pci_tbl,
++#ifdef CONFIG_PM
++ .resume_early = platform_pci_resume,
++#endif
+ };
+
+ static int __init platform_pci_module_init(void)
+diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
+index 883a21b..46bc81e 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);
+
+ void xen_pre_suspend(void);
+ void xen_post_suspend(int suspend_cancelled);
++void xen_hvm_post_suspend(int suspend_cancelled);
+
+ void xen_mm_pin_all(void);
+ void xen_mm_unpin_all(void);
+@@ -14,4 +15,6 @@ void xen_mm_unpin_all(void);
+ void xen_timer_resume(void);
+ void xen_arch_resume(void);
+
++int xen_setup_shutdown_event(void);
++
+ #endif /* INCLUDE_XEN_OPS_H */
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0006-xen-Fix-find_unbound_irq-in-presence-of-ioapic-irqs.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0006-xen-Fix-find_unbound_irq-in-presence-of-ioapic-irqs.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,55 @@
+From 26f6c2b5b7b31e4a93aca248361ac2b07789ce25 Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Fri, 14 May 2010 12:41:20 +0100
+Subject: [PATCH] xen: Fix find_unbound_irq in presence of ioapic irqs.
+
+Don't break the assumption that the first 16 irqs are ISA irqs;
+make sure that the irq is actually free before using it.
+
+Use dynamic_irq_init_keep_chip_data instead of
+dynamic_irq_init so that chip_data is not NULL (a NULL chip_data breaks
+setup_vector_irq).
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 99ad198c4978036bb9f7ebd11618b225b77046da)
+---
+ drivers/xen/events.c | 13 +++++++++++--
+ 1 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index 9d99c9a..da01209 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -338,9 +338,18 @@ static int find_unbound_irq(void)
+ int irq;
+ struct irq_desc *desc;
+
+- for (irq = 0; irq < nr_irqs; irq++)
++ for (irq = 0; irq < nr_irqs; irq++) {
++ desc = irq_to_desc(irq);
++ /* only 0->15 have init'd desc; handle irq > 16 */
++ if (desc == NULL)
++ break;
++ if (desc->chip == &no_irq_chip)
++ break;
++ if (desc->chip != &xen_dynamic_chip)
++ continue;
+ if (irq_info[irq].type == IRQT_UNBOUND)
+ break;
++ }
+
+ if (irq == nr_irqs)
+ panic("No available IRQ to bind to: increase nr_irqs!\n");
+@@ -349,7 +358,7 @@ static int find_unbound_irq(void)
+ if (WARN_ON(desc == NULL))
+ return -1;
+
+- dynamic_irq_init(irq);
++ dynamic_irq_init_keep_chip_data(irq);
+
+ return irq;
+ }
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0007-x86-Use-xen_vcpuop_clockevent-xen_clocksource-and.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0007-x86-Use-xen_vcpuop_clockevent-xen_clocksource-and.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,227 @@
+From 57a140eb75d2d3f6fded1cb807d22b3aa414d714 Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Fri, 14 May 2010 12:48:19 +0100
+Subject: [PATCH] x86: Use xen_vcpuop_clockevent, xen_clocksource and xen wallclock.
+
+Use xen_vcpuop_clockevent instead of hpet and APIC timers as main
+clockevent device on all vcpus, use the xen wallclock time as wallclock
+instead of rtc and use xen_clocksource as clocksource.
+The pv clock algorithm needs to work correctly for the xen_clocksource
+and xen wallclock to be usable, only modern Xen versions offer a
+reliable pv clock in HVM guests (XENFEAT_hvm_safe_pvclock).
+
+Using the hpet as clocksource means a VMEXIT every time we read/write to
+the hpet mmio addresses, pvclock give us a better rating without
+VMEXITs. Same goes for the xen wallclock and xen_vcpuop_clockevent
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Don Dutile <ddutile at redhat.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 409771d258e9dd71c30f3c9520fd2b796ffc40f0, conflict
+resolution arising from addition of 8a22b9996b001c88f2bfb54c6de6a05fc39e177a to
+2.6.32.18)
+---
+ arch/x86/xen/enlighten.c | 14 +--------
+ arch/x86/xen/suspend.c | 6 ++++
+ arch/x86/xen/time.c | 56 +++++++++++++++++++++++++++++++++++---
+ arch/x86/xen/xen-ops.h | 7 +---
+ include/xen/interface/features.h | 3 ++
+ 5 files changed, 65 insertions(+), 21 deletions(-)
+
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 7f2cfe7..f41ae25 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -931,10 +931,6 @@ static const struct pv_init_ops xen_init_ops __initdata = {
+ .patch = xen_patch,
+ };
+
+-static const struct pv_time_ops xen_time_ops __initdata = {
+- .sched_clock = xen_clocksource_read,
+-};
+-
+ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
+ .cpuid = xen_cpuid,
+
+@@ -1072,7 +1068,6 @@ asmlinkage void __init xen_start_kernel(void)
+ /* Install Xen paravirt ops */
+ pv_info = xen_info;
+ pv_init_ops = xen_init_ops;
+- pv_time_ops = xen_time_ops;
+ pv_cpu_ops = xen_cpu_ops;
+ pv_apic_ops = xen_apic_ops;
+
+@@ -1080,13 +1075,7 @@ asmlinkage void __init xen_start_kernel(void)
+ x86_init.oem.arch_setup = xen_arch_setup;
+ x86_init.oem.banner = xen_banner;
+
+- x86_init.timers.timer_init = xen_time_init;
+- x86_init.timers.setup_percpu_clockev = x86_init_noop;
+- x86_cpuinit.setup_percpu_clockev = x86_init_noop;
+-
+- x86_platform.calibrate_tsc = xen_tsc_khz;
+- x86_platform.get_wallclock = xen_get_wallclock;
+- x86_platform.set_wallclock = xen_set_wallclock;
++ xen_init_time_ops();
+
+ /*
+ * Set up some pagetable state before starting to set any ptes.
+@@ -1320,4 +1309,5 @@ void __init xen_hvm_guest_init(void)
+ register_cpu_notifier(&xen_hvm_cpu_notifier);
+ have_vcpu_info_placement = 0;
+ x86_init.irqs.intr_init = xen_init_IRQ;
++ xen_hvm_init_time_ops();
+ }
+diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
+index d07479c..1d789d5 100644
+--- a/arch/x86/xen/suspend.c
++++ b/arch/x86/xen/suspend.c
+@@ -28,8 +28,14 @@ void xen_pre_suspend(void)
+
+ void xen_hvm_post_suspend(int suspend_cancelled)
+ {
++ int cpu;
+ xen_hvm_init_shared_info();
+ xen_callback_vector();
++ if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
++ for_each_online_cpu(cpu) {
++ xen_setup_runstate_info(cpu);
++ }
++ }
+ }
+
+ void xen_post_suspend(int suspend_cancelled)
+diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
+index 8e04980..7e47d09 100644
+--- a/arch/x86/xen/time.c
++++ b/arch/x86/xen/time.c
+@@ -19,6 +19,7 @@
+ #include <asm/xen/hypercall.h>
+
+ #include <xen/events.h>
++#include <xen/features.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/vcpu.h>
+
+@@ -155,7 +156,7 @@ static void do_stolen_accounting(void)
+ }
+
+ /* Get the TSC speed from Xen */
+-unsigned long xen_tsc_khz(void)
++static unsigned long xen_tsc_khz(void)
+ {
+ struct pvclock_vcpu_time_info *info =
+ &HYPERVISOR_shared_info->vcpu_info[0].time;
+@@ -190,7 +191,7 @@ static void xen_read_wallclock(struct timespec *ts)
+ put_cpu_var(xen_vcpu);
+ }
+
+-unsigned long xen_get_wallclock(void)
++static unsigned long xen_get_wallclock(void)
+ {
+ struct timespec ts;
+
+@@ -198,7 +199,7 @@ unsigned long xen_get_wallclock(void)
+ return ts.tv_sec;
+ }
+
+-int xen_set_wallclock(unsigned long now)
++static int xen_set_wallclock(unsigned long now)
+ {
+ /* do nothing for domU */
+ return -1;
+@@ -433,7 +434,11 @@ void xen_timer_resume(void)
+ }
+ }
+
+-__init void xen_time_init(void)
++static const struct pv_time_ops xen_time_ops __initdata = {
++ .sched_clock = xen_clocksource_read,
++};
++
++static __init void xen_time_init(void)
+ {
+ int cpu = smp_processor_id();
+
+@@ -457,3 +462,46 @@ __init void xen_time_init(void)
+ xen_setup_timer(cpu);
+ xen_setup_cpu_clockevents();
+ }
++
++__init void xen_init_time_ops(void)
++{
++ pv_time_ops = xen_time_ops;
++
++ x86_init.timers.timer_init = xen_time_init;
++ x86_init.timers.setup_percpu_clockev = x86_init_noop;
++ x86_cpuinit.setup_percpu_clockev = x86_init_noop;
++
++ x86_platform.calibrate_tsc = xen_tsc_khz;
++ x86_platform.get_wallclock = xen_get_wallclock;
++ x86_platform.set_wallclock = xen_set_wallclock;
++}
++
++static void xen_hvm_setup_cpu_clockevents(void)
++{
++ int cpu = smp_processor_id();
++ xen_setup_runstate_info(cpu);
++ xen_setup_timer(cpu);
++ xen_setup_cpu_clockevents();
++}
++
++__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)
++ return;
++ if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
++ printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
++ "disable pv timer\n");
++ return;
++ }
++
++ pv_time_ops = xen_time_ops;
++ x86_init.timers.setup_percpu_clockev = xen_time_init;
++ x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents;
++
++ x86_platform.calibrate_tsc = xen_tsc_khz;
++ x86_platform.get_wallclock = xen_get_wallclock;
++ x86_platform.set_wallclock = xen_set_wallclock;
++}
++
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index 01c9dd3..089d189 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -49,11 +49,8 @@ void xen_setup_runstate_info(int cpu);
+ void xen_teardown_timer(int cpu);
+ cycle_t xen_clocksource_read(void);
+ void xen_setup_cpu_clockevents(void);
+-unsigned long xen_tsc_khz(void);
+-void __init xen_time_init(void);
+-unsigned long xen_get_wallclock(void);
+-int xen_set_wallclock(unsigned long time);
+-unsigned long long xen_sched_clock(void);
++void __init xen_init_time_ops(void);
++void __init xen_hvm_init_time_ops(void);
+
+ irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
+
+diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
+index 8ab08b9..70d2563 100644
+--- a/include/xen/interface/features.h
++++ b/include/xen/interface/features.h
+@@ -44,6 +44,9 @@
+ /* x86: Does this Xen host support the HVM callback vector type? */
+ #define XENFEAT_hvm_callback_vector 8
+
++/* x86: pvclock algorithm is safe to use on HVM */
++#define XENFEAT_hvm_safe_pvclock 9
++
+ #define XENFEAT_NR_SUBMAPS 1
+
+ #endif /* __XEN_PUBLIC_FEATURES_H__ */
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0008-x86-Unplug-emulated-disks-and-nics.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0008-x86-Unplug-emulated-disks-and-nics.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,378 @@
+From 67f3b6d66143353ca4536c643cef70941ecaade0 Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Fri, 14 May 2010 12:44:30 +0100
+Subject: [PATCH] x86: Unplug emulated disks and nics.
+
+Add a xen_emul_unplug command line option to the kernel to unplug
+xen emulated disks and nics.
+
+Set the default value of xen_emul_unplug depending on whether or
+not the Xen PV frontends and the Xen platform PCI driver have
+been compiled for this kernel (modules or built-in are both OK).
+
+The user can specify xen_emul_unplug=ignore to enable PV drivers on HVM
+even if the host platform doesn't support unplug.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit c1c5413ad58cb73267d328e6020268aa2e50d8ca)
+---
+ Documentation/kernel-parameters.txt | 11 +++
+ arch/x86/xen/Makefile | 2 +-
+ arch/x86/xen/enlighten.c | 1 +
+ arch/x86/xen/platform-pci-unplug.c | 135 +++++++++++++++++++++++++++++++++++
+ arch/x86/xen/xen-ops.h | 1 +
+ drivers/block/xen-blkfront.c | 17 +++++
+ drivers/xen/platform-pci.c | 6 ++
+ drivers/xen/xenbus/xenbus_probe.c | 4 +
+ include/xen/platform_pci.h | 49 +++++++++++++
+ 9 files changed, 225 insertions(+), 1 deletions(-)
+ create mode 100644 arch/x86/xen/platform-pci-unplug.c
+ create mode 100644 include/xen/platform_pci.h
+
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index 5f6aa11..3e30e60 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -113,6 +113,7 @@ parameter is applicable:
+ More X86-64 boot options can be found in
+ Documentation/x86/x86_64/boot-options.txt .
+ X86 Either 32bit or 64bit x86 (same as X86-32+X86-64)
++ XEN Xen support is enabled
+
+ In addition, the following text indicates that the option:
+
+@@ -2760,6 +2761,16 @@ 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.
+
++ xen_emul_unplug= [HW,X86,XEN]
++ Unplug Xen emulated devices
++ Format: [unplug0,][unplug1]
++ ide-disks -- unplug primary master IDE devices
++ aux-ide-disks -- unplug non-primary-master IDE devices
++ nics -- unplug network devices
++ all -- unplug all emulated devices (NICs and IDE disks)
++ ignore -- continue loading the Xen platform PCI driver even
++ if the version check failed
++
+ xirc2ps_cs= [NET,PCMCIA]
+ Format:
+ <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
+diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
+index 3bb4fc2..9309546 100644
+--- a/arch/x86/xen/Makefile
++++ b/arch/x86/xen/Makefile
+@@ -12,7 +12,7 @@ CFLAGS_mmu.o := $(nostackp)
+
+ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
+ time.o xen-asm.o xen-asm_$(BITS).o \
+- grant-table.o suspend.o
++ grant-table.o suspend.o platform-pci-unplug.o
+
+ obj-$(CONFIG_SMP) += smp.o
+ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index f41ae25..bb2b65f 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -1307,6 +1307,7 @@ void __init xen_hvm_guest_init(void)
+ if (xen_feature(XENFEAT_hvm_callback_vector))
+ xen_have_vector_callback = 1;
+ register_cpu_notifier(&xen_hvm_cpu_notifier);
++ xen_unplug_emulated_devices();
+ have_vcpu_info_placement = 0;
+ x86_init.irqs.intr_init = xen_init_IRQ;
+ xen_hvm_init_time_ops();
+diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
+new file mode 100644
+index 0000000..2f7f3fb
+--- /dev/null
++++ b/arch/x86/xen/platform-pci-unplug.c
+@@ -0,0 +1,135 @@
++/******************************************************************************
++ * platform-pci-unplug.c
++ *
++ * Xen platform PCI device driver
++ * Copyright (c) 2010, Citrix
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
++ * Place - Suite 330, Boston, MA 02111-1307 USA.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/module.h>
++
++#include <xen/platform_pci.h>
++
++#define XEN_PLATFORM_ERR_MAGIC -1
++#define XEN_PLATFORM_ERR_PROTOCOL -2
++#define XEN_PLATFORM_ERR_BLACKLIST -3
++
++/* store the value of xen_emul_unplug after the unplug is done */
++int xen_platform_pci_unplug;
++EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
++static int xen_emul_unplug;
++
++static int __init check_platform_magic(void)
++{
++ short magic;
++ char protocol;
++
++ magic = inw(XEN_IOPORT_MAGIC);
++ if (magic != XEN_IOPORT_MAGIC_VAL) {
++ printk(KERN_ERR "Xen Platform PCI: unrecognised magic value\n");
++ return XEN_PLATFORM_ERR_MAGIC;
++ }
++
++ protocol = inb(XEN_IOPORT_PROTOVER);
++
++ printk(KERN_DEBUG "Xen Platform PCI: I/O protocol version %d\n",
++ protocol);
++
++ switch (protocol) {
++ case 1:
++ outw(XEN_IOPORT_LINUX_PRODNUM, XEN_IOPORT_PRODNUM);
++ outl(XEN_IOPORT_LINUX_DRVVER, XEN_IOPORT_DRVVER);
++ if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
++ printk(KERN_ERR "Xen Platform: blacklisted by host\n");
++ return XEN_PLATFORM_ERR_BLACKLIST;
++ }
++ break;
++ default:
++ printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version");
++ return XEN_PLATFORM_ERR_PROTOCOL;
++ }
++
++ return 0;
++}
++
++void __init xen_unplug_emulated_devices(void)
++{
++ int r;
++
++ /* check the version of the xen platform PCI device */
++ r = check_platform_magic();
++ /* If the version matches enable the Xen platform PCI driver.
++ * Also enable the Xen platform PCI driver if the version is really old
++ * and the user told us to ignore it. */
++ if (r && !(r == XEN_PLATFORM_ERR_MAGIC &&
++ (xen_emul_unplug & XEN_UNPLUG_IGNORE)))
++ return;
++ /* Set the default value of xen_emul_unplug depending on whether or
++ * not the Xen PV frontends and the Xen platform PCI driver have
++ * been compiled for this kernel (modules or built-in are both OK). */
++ if (!xen_emul_unplug) {
++ if (xen_must_unplug_nics()) {
++ printk(KERN_INFO "Netfront and the Xen platform PCI driver have "
++ "been compiled for this kernel: unplug emulated NICs.\n");
++ xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
++ }
++ if (xen_must_unplug_disks()) {
++ printk(KERN_INFO "Blkfront and the Xen platform PCI driver have "
++ "been compiled for this kernel: unplug emulated disks.\n"
++ "You might have to change the root device\n"
++ "from /dev/hd[a-d] to /dev/xvd[a-d]\n"
++ "in your root= kernel command line option\n");
++ xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
++ }
++ }
++ /* Now unplug the emulated devices */
++ if (!(xen_emul_unplug & XEN_UNPLUG_IGNORE))
++ outw(xen_emul_unplug, XEN_IOPORT_UNPLUG);
++ xen_platform_pci_unplug = xen_emul_unplug;
++}
++
++static int __init parse_xen_emul_unplug(char *arg)
++{
++ char *p, *q;
++ int l;
++
++ for (p = arg; p; p = q) {
++ q = strchr(p, ',');
++ if (q) {
++ l = q - p;
++ q++;
++ } else {
++ l = strlen(p);
++ }
++ if (!strncmp(p, "all", l))
++ xen_emul_unplug |= XEN_UNPLUG_ALL;
++ else if (!strncmp(p, "ide-disks", l))
++ xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
++ else if (!strncmp(p, "aux-ide-disks", l))
++ xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS;
++ else if (!strncmp(p, "nics", l))
++ xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
++ else if (!strncmp(p, "ignore", l))
++ xen_emul_unplug |= XEN_UNPLUG_IGNORE;
++ else
++ printk(KERN_WARNING "unrecognised option '%s' "
++ "in parameter 'xen_emul_unplug'\n", p);
++ }
++ return 0;
++}
++early_param("xen_emul_unplug", parse_xen_emul_unplug);
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index 089d189..ed77694 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -40,6 +40,7 @@ void xen_vcpu_restore(void);
+
+ void xen_callback_vector(void);
+ void xen_hvm_init_shared_info(void);
++void __init xen_unplug_emulated_devices(void);
+
+ void __init xen_build_dynamic_phys_to_machine(void);
+
+diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
+index b8578bb..151c560 100644
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -46,6 +46,7 @@
+ #include <xen/grant_table.h>
+ #include <xen/events.h>
+ #include <xen/page.h>
++#include <xen/platform_pci.h>
+
+ #include <xen/interface/grant_table.h>
+ #include <xen/interface/io/blkif.h>
+@@ -736,6 +737,22 @@ static int blkfront_probe(struct xenbus_device *dev,
+ }
+ }
+
++ /* no unplug has been done: do not hook devices != xen vbds */
++ if (xen_hvm_domain() && (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE)) {
++ int major;
++
++ if (!VDEV_IS_EXTENDED(vdevice))
++ major = BLKIF_MAJOR(vdevice);
++ else
++ major = XENVBD_MAJOR;
++
++ if (major != XENVBD_MAJOR) {
++ printk(KERN_INFO
++ "%s: HVM does not support vbd %d as xen block device\n",
++ __FUNCTION__, vdevice);
++ return -ENODEV;
++ }
++ }
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index bdb44f2..c01b5dd 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -27,6 +27,7 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
+
++#include <xen/platform_pci.h>
+ #include <xen/grant_table.h>
+ #include <xen/xenbus.h>
+ #include <xen/events.h>
+@@ -195,6 +196,11 @@ static struct pci_driver platform_driver = {
+
+ static int __init platform_pci_module_init(void)
+ {
++ /* no unplug has been done, IGNORE hasn't been specified: just
++ * return now */
++ if (!xen_platform_pci_unplug)
++ return -ENODEV;
++
+ return pci_register_driver(&platform_driver);
+ }
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index e8169db..840c9ff 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -53,6 +53,7 @@
+ #include <xen/events.h>
+ #include <xen/page.h>
+
++#include <xen/platform_pci.h>
+ #include <xen/hvm.h>
+
+ #include "xenbus_comms.h"
+@@ -974,6 +975,9 @@ static void wait_for_devices(struct xenbus_driver *xendrv)
+ #ifndef MODULE
+ static int __init boot_wait_for_devices(void)
+ {
++ if (xen_hvm_domain() && !xen_platform_pci_unplug)
++ return -ENODEV;
++
+ ready_to_wait_for_devices = 1;
+ wait_for_devices(NULL);
+ return 0;
+diff --git a/include/xen/platform_pci.h b/include/xen/platform_pci.h
+new file mode 100644
+index 0000000..ce9d671
+--- /dev/null
++++ b/include/xen/platform_pci.h
+@@ -0,0 +1,49 @@
++#ifndef _XEN_PLATFORM_PCI_H
++#define _XEN_PLATFORM_PCI_H
++
++#define XEN_IOPORT_MAGIC_VAL 0x49d2
++#define XEN_IOPORT_LINUX_PRODNUM 0x0003
++#define XEN_IOPORT_LINUX_DRVVER 0x0001
++
++#define XEN_IOPORT_BASE 0x10
++
++#define XEN_IOPORT_PLATFLAGS (XEN_IOPORT_BASE + 0) /* 1 byte access (R/W) */
++#define XEN_IOPORT_MAGIC (XEN_IOPORT_BASE + 0) /* 2 byte access (R) */
++#define XEN_IOPORT_UNPLUG (XEN_IOPORT_BASE + 0) /* 2 byte access (W) */
++#define XEN_IOPORT_DRVVER (XEN_IOPORT_BASE + 0) /* 4 byte access (W) */
++
++#define XEN_IOPORT_SYSLOG (XEN_IOPORT_BASE + 2) /* 1 byte access (W) */
++#define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */
++#define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */
++
++#define XEN_UNPLUG_ALL_IDE_DISKS 1
++#define XEN_UNPLUG_ALL_NICS 2
++#define XEN_UNPLUG_AUX_IDE_DISKS 4
++#define XEN_UNPLUG_ALL 7
++#define XEN_UNPLUG_IGNORE 8
++
++static inline int xen_must_unplug_nics(void) {
++#if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
++ defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \
++ (defined(CONFIG_XEN_PLATFORM_PCI) || \
++ defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
++ return 1;
++#else
++ return 0;
++#endif
++}
++
++static inline int xen_must_unplug_disks(void) {
++#if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \
++ defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \
++ (defined(CONFIG_XEN_PLATFORM_PCI) || \
++ defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
++ return 1;
++#else
++ return 0;
++#endif
++}
++
++extern int xen_platform_pci_unplug;
++
++#endif /* _XEN_PLATFORM_PCI_H */
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0009-x86-Call-HVMOP_pagetable_dying-on-exit_mmap.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0009-x86-Call-HVMOP_pagetable_dying-on-exit_mmap.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,112 @@
+From eb5d901cbe6cfb1f9ca7835995af8634fd34bc3a Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Thu, 17 Jun 2010 14:22:52 +0100
+Subject: [PATCH] x86: Call HVMOP_pagetable_dying on exit_mmap.
+
+When a pagetable is about to be destroyed, we notify Xen so that the
+hypervisor can clear the related shadow pagetable.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 5915100106b8f14a38053ad6c03a664d208aeaa2)
+---
+ arch/x86/xen/enlighten.c | 1 +
+ arch/x86/xen/mmu.c | 33 +++++++++++++++++++++++++++++++++
+ arch/x86/xen/mmu.h | 1 +
+ include/xen/interface/hvm/hvm_op.h | 11 +++++++++++
+ 4 files changed, 46 insertions(+), 0 deletions(-)
+
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index bb2b65f..bdb6d66 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -1311,4 +1311,5 @@ void __init xen_hvm_guest_init(void)
+ have_vcpu_info_placement = 0;
+ x86_init.irqs.intr_init = xen_init_IRQ;
+ xen_hvm_init_time_ops();
++ xen_hvm_init_mmu_ops();
+ }
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
+index 350a3de..f3ff12a 100644
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -57,6 +57,7 @@
+
+ #include <xen/page.h>
+ #include <xen/interface/xen.h>
++#include <xen/interface/hvm/hvm_op.h>
+ #include <xen/interface/version.h>
+ #include <xen/hvc-console.h>
+
+@@ -1962,6 +1963,38 @@ void __init xen_init_mmu_ops(void)
+ pv_mmu_ops = xen_mmu_ops;
+ }
+
++static void xen_hvm_exit_mmap(struct mm_struct *mm)
++{
++ struct xen_hvm_pagetable_dying a;
++ int rc;
++
++ a.domid = DOMID_SELF;
++ a.gpa = __pa(mm->pgd);
++ rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
++ WARN_ON_ONCE(rc < 0);
++}
++
++static int is_pagetable_dying_supported(void)
++{
++ struct xen_hvm_pagetable_dying a;
++ int rc = 0;
++
++ a.domid = DOMID_SELF;
++ a.gpa = 0x00;
++ rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
++ if (rc < 0) {
++ printk(KERN_DEBUG "HVMOP_pagetable_dying not supported\n");
++ return 0;
++ }
++ return 1;
++}
++
++void __init xen_hvm_init_mmu_ops(void)
++{
++ if (is_pagetable_dying_supported())
++ pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap;
++}
++
+ #ifdef CONFIG_XEN_DEBUG_FS
+
+ static struct dentry *d_mmu_debug;
+diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
+index 5fe6bc7..fa938c4 100644
+--- a/arch/x86/xen/mmu.h
++++ b/arch/x86/xen/mmu.h
+@@ -60,4 +60,5 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
+ unsigned long xen_read_cr2_direct(void);
+
+ extern void xen_init_mmu_ops(void);
++extern void xen_hvm_init_mmu_ops(void);
+ #endif /* _XEN_MMU_H */
+diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h
+index 73c8c7e..a4827f4 100644
+--- a/include/xen/interface/hvm/hvm_op.h
++++ b/include/xen/interface/hvm/hvm_op.h
+@@ -32,4 +32,15 @@ struct xen_hvm_param {
+ };
+ DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_param);
+
++/* Hint from PV drivers for pagetable destruction. */
++#define HVMOP_pagetable_dying 9
++struct xen_hvm_pagetable_dying {
++ /* Domain with a pagetable about to be destroyed. */
++ domid_t domid;
++ /* guest physical address of the toplevel pagetable dying */
++ aligned_u64 gpa;
++};
++typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t;
++DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t);
++
+ #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0010-xenfs-enable-for-HVM-domains-too.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0010-xenfs-enable-for-HVM-domains-too.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,36 @@
+From bda530187b0fb9dc0ea7dc38537adeb245bebb2b Mon Sep 17 00:00:00 2001
+From: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+Date: Wed, 21 Jul 2010 22:51:39 -0700
+Subject: [PATCH] xenfs: enable for HVM domains too
+
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 43df95c44e71d009b5a73f104ff183f73af9526f)
+---
+ drivers/xen/xenfs/super.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
+index 6559e0c..6c16685 100644
+--- a/drivers/xen/xenfs/super.c
++++ b/drivers/xen/xenfs/super.c
+@@ -63,7 +63,7 @@ static struct file_system_type xenfs_type = {
+
+ static int __init xenfs_init(void)
+ {
+- if (xen_pv_domain())
++ if (xen_domain())
+ return register_filesystem(&xenfs_type);
+
+ printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n");
+@@ -72,7 +72,7 @@ static int __init xenfs_init(void)
+
+ static void __exit xenfs_exit(void)
+ {
+- if (xen_pv_domain())
++ if (xen_domain())
+ unregister_filesystem(&xenfs_type);
+ }
+
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0011-support-multiple-.discard.-sections-to-avoid-sectio.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0011-support-multiple-.discard.-sections-to-avoid-sectio.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,45 @@
+From 52d1c46dfd7f8e562ae5e3fa3ac21468d4ac4d9a Mon Sep 17 00:00:00 2001
+From: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+Date: Thu, 22 Jul 2010 22:58:01 -0700
+Subject: [PATCH] support multiple .discard.* sections to avoid section type conflicts
+
+gcc 4.4.4 will complain if you use a .discard section for both text and
+data ("causes a section type conflict"). Add support for ".discard.*"
+sections, and use .discard.text for a dummy function in the x86
+RESERVE_BRK() macro.
+
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit c7f52cdc2f3e1733d3864e439ac2e92edd99ef31)
+---
+ arch/x86/include/asm/setup.h | 2 +-
+ include/asm-generic/vmlinux.lds.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
+index 18e496c..fee81d0 100644
+--- a/arch/x86/include/asm/setup.h
++++ b/arch/x86/include/asm/setup.h
+@@ -84,7 +84,7 @@ void *extend_brk(size_t size, size_t align);
+ * executable.)
+ */
+ #define RESERVE_BRK(name,sz) \
+- static void __section(.discard) __used \
++ static void __section(.discard.text) __used \
+ __brk_reservation_fn_##name##__(void) { \
+ asm volatile ( \
+ ".pushsection .brk_reservation,\"aw\", at nobits;" \
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index b6e818f..ca060ce 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -639,6 +639,7 @@
+ EXIT_DATA \
+ EXIT_CALL \
+ *(.discard) \
++ *(.discard.*) \
+ }
+
+ /**
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0012-blkfront-do-not-create-a-PV-cdrom-device-if-xen_hvm.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0012-blkfront-do-not-create-a-PV-cdrom-device-if-xen_hvm.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,70 @@
+From ea861bd95ad4f8a2bc15d244f475a3b91e9fb877 Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Thu, 29 Jul 2010 14:53:16 +0100
+Subject: [PATCH] blkfront: do not create a PV cdrom device if xen_hvm_guest
+
+It is not possible to unplug emulated cdrom devices, and PV cdroms don't
+handle media insert, eject and stream, so we are better off disabling PV
+cdroms when running as a Xen HVM guest.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+(cherry picked from commit b98a409b80ac510c95b4f1bafdef28edaeabd3e7)
+---
+ drivers/block/xen-blkfront.c | 39 ++++++++++++++++++++++++++-------------
+ 1 files changed, 26 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
+index 151c560..ac692c5 100644
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -737,21 +737,34 @@ static int blkfront_probe(struct xenbus_device *dev,
+ }
+ }
+
+- /* no unplug has been done: do not hook devices != xen vbds */
+- if (xen_hvm_domain() && (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE)) {
+- int major;
+-
+- if (!VDEV_IS_EXTENDED(vdevice))
+- major = BLKIF_MAJOR(vdevice);
+- else
+- major = XENVBD_MAJOR;
+-
+- if (major != XENVBD_MAJOR) {
+- printk(KERN_INFO
+- "%s: HVM does not support vbd %d as xen block device\n",
+- __FUNCTION__, vdevice);
++ if (xen_hvm_domain()) {
++ char *type;
++ int len;
++ /* no unplug has been done: do not hook devices != xen vbds */
++ if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) {
++ int major;
++
++ if (!VDEV_IS_EXTENDED(vdevice))
++ major = BLKIF_MAJOR(vdevice);
++ else
++ major = XENVBD_MAJOR;
++
++ if (major != XENVBD_MAJOR) {
++ printk(KERN_INFO
++ "%s: HVM does not support vbd %d as xen block device\n",
++ __FUNCTION__, vdevice);
++ return -ENODEV;
++ }
++ }
++ /* do not create a PV cdrom device if we are an HVM guest */
++ type = xenbus_read(XBT_NIL, dev->nodename, "device-type", &len);
++ if (IS_ERR(type))
++ return -ENODEV;
++ if (strncmp(type, "cdrom", 5) == 0) {
++ kfree(type);
+ return -ENODEV;
+ }
++ kfree(type);
+ }
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0013-Introduce-CONFIG_XEN_PVHVM-compile-option.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0013-Introduce-CONFIG_XEN_PVHVM-compile-option.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,147 @@
+From 978759a28b039bc1e9d09e110bf85b1940731fbb Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Thu, 29 Jul 2010 14:37:48 +0100
+Subject: [PATCH] Introduce CONFIG_XEN_PVHVM compile option
+
+This patch introduce a CONFIG_XEN_PVHVM compile time option to
+enable/disable Xen PV on HVM support.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+(cherry picked from commit 5b270b05c41c21b19c88617c3, updated for lack of
+hypervisor detection infrastructure)
+---
+ arch/x86/xen/Kconfig | 5 +++++
+ arch/x86/xen/enlighten.c | 2 ++
+ arch/x86/xen/mmu.c | 2 ++
+ arch/x86/xen/platform-pci-unplug.c | 2 ++
+ arch/x86/xen/time.c | 3 ++-
+ drivers/xen/Kconfig | 2 +-
+ drivers/xen/events.c | 4 ++++
+ 7 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
+index b83e119..68128a1 100644
+--- a/arch/x86/xen/Kconfig
++++ b/arch/x86/xen/Kconfig
+@@ -13,6 +13,11 @@ config XEN
+ kernel to boot in a paravirtualized environment under the
+ Xen hypervisor.
+
++config XEN_PVHVM
++ def_bool y
++ depends on XEN
++ depends on X86_LOCAL_APIC
++
+ config XEN_MAX_DOMAIN_MEMORY
+ int "Maximum allowed size of a domain in gigabytes"
+ default 8 if X86_32
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index bdb6d66..50fbf65 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -1272,6 +1272,7 @@ void xen_hvm_init_shared_info(void)
+ }
+ }
+
++#ifdef CONFIG_XEN_PVHVM
+ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+ {
+@@ -1313,3 +1314,4 @@ void __init xen_hvm_guest_init(void)
+ xen_hvm_init_time_ops();
+ xen_hvm_init_mmu_ops();
+ }
++#endif
+diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
+index f3ff12a..971a405 100644
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -1963,6 +1963,7 @@ void __init xen_init_mmu_ops(void)
+ pv_mmu_ops = xen_mmu_ops;
+ }
+
++#ifdef CONFIG_XEN_PVHVM
+ static void xen_hvm_exit_mmap(struct mm_struct *mm)
+ {
+ struct xen_hvm_pagetable_dying a;
+@@ -1994,6 +1995,7 @@ void __init xen_hvm_init_mmu_ops(void)
+ if (is_pagetable_dying_supported())
+ pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap;
+ }
++#endif
+
+ #ifdef CONFIG_XEN_DEBUG_FS
+
+diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
+index 2f7f3fb..554c002 100644
+--- a/arch/x86/xen/platform-pci-unplug.c
++++ b/arch/x86/xen/platform-pci-unplug.c
+@@ -32,6 +32,7 @@
+ /* store the value of xen_emul_unplug after the unplug is done */
+ int xen_platform_pci_unplug;
+ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
++#ifdef CONFIG_XEN_PVHVM
+ static int xen_emul_unplug;
+
+ static int __init check_platform_magic(void)
+@@ -133,3 +134,4 @@ static int __init parse_xen_emul_unplug(char *arg)
+ return 0;
+ }
+ early_param("xen_emul_unplug", parse_xen_emul_unplug);
++#endif
+diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
+index 7e47d09..094c70a 100644
+--- a/arch/x86/xen/time.c
++++ b/arch/x86/xen/time.c
+@@ -476,6 +476,7 @@ __init void xen_init_time_ops(void)
+ x86_platform.set_wallclock = xen_set_wallclock;
+ }
+
++#ifdef CONFIG_XEN_PVHVM
+ static void xen_hvm_setup_cpu_clockevents(void)
+ {
+ int cpu = smp_processor_id();
+@@ -504,4 +505,4 @@ __init void xen_hvm_init_time_ops(void)
+ x86_platform.get_wallclock = xen_get_wallclock;
+ x86_platform.set_wallclock = xen_set_wallclock;
+ }
+-
++#endif
+diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
+index f65d2c9..96572e2 100644
+--- a/drivers/xen/Kconfig
++++ b/drivers/xen/Kconfig
+@@ -64,7 +64,7 @@ config XEN_SYS_HYPERVISOR
+
+ config XEN_PLATFORM_PCI
+ tristate "xen platform pci device driver"
+- depends on XEN
++ depends on XEN_PVHVM
+ default m
+ help
+ Driver for the Xen PCI Platform device: it is responsible for
+diff --git a/drivers/xen/events.c b/drivers/xen/events.c
+index da01209..5d25cdf 100644
+--- a/drivers/xen/events.c
++++ b/drivers/xen/events.c
+@@ -968,6 +968,7 @@ int xen_set_callback_via(uint64_t via)
+ }
+ EXPORT_SYMBOL_GPL(xen_set_callback_via);
+
++#ifdef CONFIG_XEN_PVHVM
+ /* Vector callbacks are better than PCI interrupts to receive event
+ * channel notifications because we can receive vector callbacks on any
+ * vcpu and we don't need PCI support or APIC interactions. */
+@@ -991,6 +992,9 @@ void xen_callback_vector(void)
+ alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
+ }
+ }
++#else
++void xen_callback_vector(void) {}
++#endif
+
+ void __init xen_init_IRQ(void)
+ {
+--
+1.5.6.5
+
Added: dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0014-pvops-do-not-notify-callers-from-register_xenstore_.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvhvm/0014-pvops-do-not-notify-callers-from-register_xenstore_.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -0,0 +1,40 @@
+From c49e45c5f96592d6ddf3635d6003b26492704dac Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Date: Fri, 16 Jul 2010 17:30:19 +0100
+Subject: [PATCH] pvops: do not notify callers from register_xenstore_notifier
+
+Currently register_xenstore_notifier notifies the caller during the
+registration itself if xenstore is believed to be ready. This behaviour
+causes problems to PV on HVM guests, in which case callers should be
+notified by xenbus_probe only after the platform pci driver is loaded.
+We already make sure xenbus_probe is called at the right time, calling
+it either from device_initcall (PV case) or from the platform pci
+driver initialization (HVM case) so we don't need this additional
+notification.
+
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+(cherry picked from commit 31de189f7d02da163f77d46a86d9e655a2d83124)
+---
+ drivers/xen/xenbus/xenbus_probe.c | 5 +----
+ 1 files changed, 1 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 840c9ff..f52baf3 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -752,10 +752,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);
+
+ return ret;
+ }
+--
+1.5.6.5
+
Modified: dists/sid/linux-2.6/debian/patches/features/all/xen/pvops.patch
==============================================================================
--- dists/sid/linux-2.6/debian/patches/features/all/xen/pvops.patch Fri Aug 20 06:29:20 2010 (r16167)
+++ dists/sid/linux-2.6/debian/patches/features/all/xen/pvops.patch Fri Aug 20 06:29:47 2010 (r16168)
@@ -7,41 +7,13 @@
To regenerate:
$ git checkout -b debian-base v2.6.32.19
+$ git pull git://xenbits.xensource.com/people/ianc/linux-2.6.git debian/squeeze/pvhvm
$ git checkout -b debian-pvops e73f4955a821f850f5b88c32d12a81714523a95f
$ git revert -m 1 bcf16b6b4f34fb40a7aaf637947c7d3bce0be671
$ git diff debian-base..debian-pvops
-diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 5f6aa11..3e30e60 100644
---- a/Documentation/kernel-parameters.txt
-+++ b/Documentation/kernel-parameters.txt
-@@ -113,6 +113,7 @@ parameter is applicable:
- More X86-64 boot options can be found in
- Documentation/x86/x86_64/boot-options.txt .
- X86 Either 32bit or 64bit x86 (same as X86-32+X86-64)
-+ XEN Xen support is enabled
-
- In addition, the following text indicates that the option:
-
-@@ -2760,6 +2761,16 @@ 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.
-
-+ xen_emul_unplug= [HW,X86,XEN]
-+ Unplug Xen emulated devices
-+ Format: [unplug0,][unplug1]
-+ ide-disks -- unplug primary master IDE devices
-+ aux-ide-disks -- unplug non-primary-master IDE devices
-+ nics -- unplug network devices
-+ all -- unplug all emulated devices (NICs and IDE disks)
-+ ignore -- continue loading the Xen platform PCI driver even
-+ if the version check failed
-+
- xirc2ps_cs= [NET,PCMCIA]
- Format:
- <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt
index 29a6ff8..81f9b94 100644
--- a/Documentation/x86/x86_64/boot-options.txt
@@ -431,23 +403,22 @@
extern int force_iommu, no_iommu;
extern int iommu_detected;
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
-index 6e90a04..ba4dc7b 100644
+index 893179f..ba4dc7b 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
-@@ -120,6 +120,12 @@
+@@ -120,8 +120,11 @@
*/
#define MCE_SELF_VECTOR 0xeb
+#ifdef CONFIG_XEN
-+/* Xen vector callback to receive events in a HVM domain */
-+#define XEN_HVM_EVTCHN_CALLBACK 0xe9
+ /* Xen vector callback to receive events in a HVM domain */
+ #define XEN_HVM_EVTCHN_CALLBACK 0xe9
+#endif
+
-+
+
/*
* First APIC vector available to drivers: (vectors 0x30-0xee) we
- * start at 0x31(0x41) to spread out vectors evenly between priority
-@@ -157,6 +163,14 @@ static inline int invalid_vm86_irq(int irq)
+@@ -160,6 +163,14 @@ static inline int invalid_vm86_irq(int irq)
#define CPU_VECTOR_LIMIT ( 8 * NR_CPUS )
#define IO_APIC_VECTOR_LIMIT ( 32 * MAX_IO_APICS )
@@ -462,7 +433,7 @@
#ifdef CONFIG_X86_IO_APIC
# ifdef CONFIG_SPARSE_IRQ
# define NR_IRQS \
-@@ -165,13 +179,13 @@ static inline int invalid_vm86_irq(int irq)
+@@ -168,13 +179,13 @@ static inline int invalid_vm86_irq(int irq)
(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
# else
# if NR_CPUS < MAX_IO_APICS
@@ -727,6 +698,19 @@
#endif /* CONFIG_PARAVIRT */
/*
+diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
+index fee81d0..18e496c 100644
+--- a/arch/x86/include/asm/setup.h
++++ b/arch/x86/include/asm/setup.h
+@@ -84,7 +84,7 @@ void *extend_brk(size_t size, size_t align);
+ * executable.)
+ */
+ #define RESERVE_BRK(name,sz) \
+- static void __section(.discard.text) __used \
++ static void __section(.discard) __used \
+ __brk_reservation_fn_##name##__(void) { \
+ asm volatile ( \
+ ".pushsection .brk_reservation,\"aw\", at nobits;" \
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h
index b9e4e20..8085277 100644
--- a/arch/x86/include/asm/swiotlb.h
@@ -841,7 +825,7 @@
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 7fda040..41c4be0 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -45,6 +45,8 @@
@@ -898,20 +882,7 @@
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)
- return _hypercall2(int, nmi_op, op, arg);
- }
-
-+static inline unsigned long __must_check
-+HYPERVISOR_hvm_op(int op, void *arg)
-+{
-+ return _hypercall2(unsigned long, hvm_op, op, arg);
-+}
-+
- 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)
+@@ -430,6 +463,14 @@ MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
mcl->args[0] = set;
}
@@ -926,7 +897,7 @@
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,
+@@ -438,12 +479,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;
@@ -941,10 +912,10 @@
static inline void
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
-index d5b7e90..396ff4c 100644
+index 5d298fd..396ff4c 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
-@@ -37,31 +37,4 @@
+@@ -37,33 +37,4 @@
extern struct shared_info *HYPERVISOR_shared_info;
extern struct start_info *xen_start_info;
@@ -956,8 +927,10 @@
-
-#ifdef CONFIG_XEN
-extern enum xen_domain_type xen_domain_type;
+-extern void __init xen_hvm_guest_init(void);
-#else
-#define xen_domain_type XEN_NATIVE
+-#define xen_hvm_guest_init() do { } while (0)
-#endif
-
-#define xen_domain() (xen_domain_type != XEN_NATIVE)
@@ -2005,32 +1978,32 @@
static void kdump_nmi_callback(int cpu, struct die_args *args)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
-index c097e7d..21feb03 100644
+index 7764118..21feb03 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
-@@ -1088,6 +1088,8 @@ ENTRY(xen_failsafe_callback)
+@@ -1088,8 +1088,7 @@ ENTRY(xen_failsafe_callback)
.previous
ENDPROC(xen_failsafe_callback)
+-BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
+- xen_evtchn_do_upcall)
+BUILD_INTERRUPT(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK)
-+
+
#endif /* CONFIG_XEN */
- #ifdef CONFIG_FUNCTION_TRACER
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
-index b5c061f..1bf0911 100644
+index a626344..1bf0911 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
-@@ -1364,6 +1364,9 @@ ENTRY(xen_failsafe_callback)
- CFI_ENDPROC
+@@ -1365,7 +1365,7 @@ ENTRY(xen_failsafe_callback)
END(xen_failsafe_callback)
-+apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
+ apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
+- xen_hvm_callback_vector xen_evtchn_do_upcall
+ xen_hvm_callback_vector smp_xen_hvm_callback_vector
-+
+
#endif /* CONFIG_XEN */
- /*
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 19528ef..40e47cd 100644
--- a/arch/x86/kernel/hpet.c
@@ -2931,7 +2904,7 @@
}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
-index d7a0888..594e324 100644
+index c852868..594e324 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -70,6 +70,7 @@
@@ -2950,7 +2923,15 @@
#include <asm/system.h>
#include <asm/vsyscall.h>
-@@ -966,6 +968,9 @@ void __init setup_arch(char **cmdline_p)
+@@ -102,7 +104,6 @@
+
+ #include <asm/paravirt.h>
+ #include <asm/hypervisor.h>
+-#include <asm/xen/hypervisor.h>
+
+ #include <asm/percpu.h>
+ #include <asm/topology.h>
+@@ -967,6 +968,9 @@ void __init setup_arch(char **cmdline_p)
initmem_init(0, max_pfn);
@@ -2960,14 +2941,6 @@
#ifdef CONFIG_ACPI_SLEEP
/*
* Reserve low memory region for sleep support.
-@@ -1034,6 +1039,7 @@ void __init setup_arch(char **cmdline_p)
- probe_nr_irqs_gsi();
-
- kvm_guest_init();
-+ xen_hvm_guest_init();
-
- e820_reserve_resources();
- e820_mark_nosave_regions(max_low_pfn);
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 4449a4a..d11c5ff 100644
--- a/arch/x86/kernel/x86_init.c
@@ -3426,10 +3399,22 @@
+}
+
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
-index b83e119..7675f9b 100644
+index 68128a1..7675f9b 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
-@@ -36,3 +36,40 @@ config XEN_DEBUG_FS
+@@ -13,11 +13,6 @@ config XEN
+ kernel to boot in a paravirtualized environment under the
+ Xen hypervisor.
+
+-config XEN_PVHVM
+- def_bool y
+- depends on XEN
+- depends on X86_LOCAL_APIC
+-
+ config XEN_MAX_DOMAIN_MEMORY
+ int "Maximum allowed size of a domain in gigabytes"
+ default 8 if X86_32
+@@ -41,3 +36,40 @@ config XEN_DEBUG_FS
help
Enable statistics output and various tuning options in debugfs.
Enabling this option may incur a significant performance overhead.
@@ -3471,16 +3456,10 @@
+ Enable support for passing PCI devices through to
+ unprivileged domains. (COMPLETELY UNTESTED)
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
-index 3bb4fc2..13ca65c 100644
+index 9309546..13ca65c 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
-@@ -12,9 +12,12 @@ CFLAGS_mmu.o := $(nostackp)
-
- obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
- time.o xen-asm.o xen-asm_$(BITS).o \
-- grant-table.o suspend.o
-+ grant-table.o suspend.o platform-pci-unplug.o
-
+@@ -17,4 +17,7 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o
@@ -3530,18 +3509,10 @@
+#endif
+}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
-index 942ccf1..56b85d2 100644
+index 50fbf65..56b85d2 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
-@@ -11,6 +11,7 @@
- * Jeremy Fitzhardinge <jeremy at xensource.com>, XenSource Inc, 2007
- */
-
-+#include <linux/cpu.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/smp.h>
-@@ -28,12 +29,15 @@
+@@ -29,6 +29,7 @@
#include <linux/highmem.h>
#include <linux/console.h>
@@ -3549,23 +3520,15 @@
#include <xen/interface/xen.h>
#include <xen/interface/version.h>
#include <xen/interface/physdev.h>
- #include <xen/interface/vcpu.h>
-+#include <xen/interface/memory.h>
- #include <xen/features.h>
- #include <xen/page.h>
-+#include <xen/hvm.h>
- #include <xen/hvc-console.h>
-
- #include <asm/paravirt.h>
-@@ -53,6 +57,7 @@
+@@ -55,7 +56,6 @@
+ #include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/reboot.h>
+-#include <asm/setup.h>
#include <asm/stackprotector.h>
-+#include <asm/hypervisor.h>
+ #include <asm/hypervisor.h>
- #include "xen-ops.h"
- #include "mmu.h"
-@@ -66,6 +71,11 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
+@@ -71,6 +71,11 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
enum xen_domain_type xen_domain_type = XEN_NATIVE;
EXPORT_SYMBOL_GPL(xen_domain_type);
@@ -3577,17 +3540,7 @@
struct start_info *xen_start_info;
EXPORT_SYMBOL_GPL(xen_start_info);
-@@ -73,6 +83,9 @@ struct shared_info xen_dummy_shared_info;
-
- void *xen_initial_gdt;
-
-+__read_mostly int xen_have_vector_callback;
-+EXPORT_SYMBOL_GPL(xen_have_vector_callback);
-+
- /*
- * Point at some empty memory to start with. We map the real shared_info
- * page as soon as fixmap is up and running.
-@@ -94,6 +107,14 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
+@@ -102,6 +107,14 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
*/
static int have_vcpu_info_placement = 1;
@@ -3602,7 +3555,7 @@
static void xen_vcpu_setup(int cpu)
{
struct vcpu_register_vcpu_info info;
-@@ -101,13 +122,17 @@ static void xen_vcpu_setup(int cpu)
+@@ -109,13 +122,17 @@ static void xen_vcpu_setup(int cpu)
struct vcpu_info *vcpup;
BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
@@ -3624,7 +3577,7 @@
info.mfn = arbitrary_virt_to_mfn(vcpup);
info.offset = offset_in_page(vcpup);
-@@ -122,6 +147,7 @@ static void xen_vcpu_setup(int cpu)
+@@ -130,6 +147,7 @@ static void xen_vcpu_setup(int cpu)
if (err) {
printk(KERN_DEBUG "register_vcpu_info failed: err=%d\n", err);
have_vcpu_info_placement = 0;
@@ -3632,7 +3585,7 @@
} else {
/* This cpu is using the registered vcpu info, even if
later ones fail to. */
-@@ -167,13 +193,16 @@ static void __init xen_banner(void)
+@@ -175,13 +193,16 @@ static void __init xen_banner(void)
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
pv_info.name);
@@ -3651,7 +3604,7 @@
static void xen_cpuid(unsigned int *ax, unsigned int *bx,
unsigned int *cx, unsigned int *dx)
-@@ -187,7 +216,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
+@@ -195,7 +216,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
* unsupported kernel subsystems as possible.
*/
switch (*ax) {
@@ -3660,7 +3613,7 @@
maskecx = cpuid_leaf1_ecx_mask;
maskedx = cpuid_leaf1_edx_mask;
break;
-@@ -196,6 +225,10 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
+@@ -204,6 +225,10 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
/* Suppress extended topology stuff */
maskebx = 0;
break;
@@ -3671,7 +3624,7 @@
}
asm(XEN_EMULATE_PREFIX "cpuid"
-@@ -215,13 +248,15 @@ static __init void xen_init_cpuid_mask(void)
+@@ -223,13 +248,15 @@ static __init void xen_init_cpuid_mask(void)
unsigned int ax, bx, cx, dx;
cpuid_leaf1_edx_mask =
@@ -3691,7 +3644,7 @@
(1 << X86_FEATURE_ACPI)); /* disable ACPI */
ax = 1;
-@@ -406,7 +441,7 @@ static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
+@@ -414,7 +441,7 @@ static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
pte = pfn_pte(pfn, PAGE_KERNEL_RO);
@@ -3700,7 +3653,7 @@
BUG();
frames[f] = mfn;
-@@ -517,13 +552,13 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
+@@ -525,13 +552,13 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
return 0;
#ifdef CONFIG_X86_MCE
} else if (addr == (unsigned long)machine_check) {
@@ -3720,7 +3673,7 @@
#endif /* CONFIG_X86_64 */
info->address = addr;
-@@ -679,6 +714,18 @@ static void xen_set_iopl_mask(unsigned mask)
+@@ -687,6 +714,18 @@ static void xen_set_iopl_mask(unsigned mask)
HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
}
@@ -3739,7 +3692,7 @@
static void xen_io_delay(void)
{
}
-@@ -716,7 +763,7 @@ static u32 xen_safe_apic_wait_icr_idle(void)
+@@ -724,7 +763,7 @@ static u32 xen_safe_apic_wait_icr_idle(void)
return 0;
}
@@ -3748,7 +3701,7 @@
{
apic->read = xen_apic_read;
apic->write = xen_apic_write;
-@@ -728,7 +775,6 @@ static void set_xen_basic_apic_ops(void)
+@@ -736,7 +775,6 @@ static void set_xen_basic_apic_ops(void)
#endif
@@ -3756,7 +3709,7 @@
static void xen_clts(void)
{
struct multicall_space mcs;
-@@ -811,6 +857,11 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
+@@ -819,6 +857,11 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
Xen console noise. */
break;
@@ -3768,18 +3721,7 @@
default:
ret = native_write_msr_safe(msr, low, high);
}
-@@ -923,10 +974,6 @@ static const struct pv_init_ops xen_init_ops __initdata = {
- .patch = xen_patch,
- };
-
--static const struct pv_time_ops xen_time_ops __initdata = {
-- .sched_clock = xen_clocksource_read,
--};
--
- static const struct pv_cpu_ops xen_cpu_ops __initdata = {
- .cpuid = xen_cpuid,
-
-@@ -978,6 +1025,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
+@@ -982,6 +1025,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
.load_sp0 = xen_load_sp0,
.set_iopl_mask = xen_set_iopl_mask,
@@ -3787,7 +3729,7 @@
.io_delay = xen_io_delay,
/* Xen takes care of %gs when switching to usermode for us */
-@@ -1020,15 +1068,40 @@ static void xen_machine_halt(void)
+@@ -1024,15 +1068,40 @@ static void xen_machine_halt(void)
xen_reboot(SHUTDOWN_poweroff);
}
@@ -3829,7 +3771,7 @@
.shutdown = xen_machine_halt,
.crash_shutdown = xen_crash_shutdown,
.emergency_restart = xen_emergency_restart,
-@@ -1061,10 +1134,11 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1065,6 +1134,8 @@ asmlinkage void __init xen_start_kernel(void)
xen_domain_type = XEN_PV_DOMAIN;
@@ -3838,26 +3780,7 @@
/* Install Xen paravirt ops */
pv_info = xen_info;
pv_init_ops = xen_init_ops;
-- pv_time_ops = xen_time_ops;
- pv_cpu_ops = xen_cpu_ops;
- pv_apic_ops = xen_apic_ops;
-
-@@ -1072,13 +1146,7 @@ asmlinkage void __init xen_start_kernel(void)
- x86_init.oem.arch_setup = xen_arch_setup;
- x86_init.oem.banner = xen_banner;
-
-- x86_init.timers.timer_init = xen_time_init;
-- x86_init.timers.setup_percpu_clockev = x86_init_noop;
-- x86_cpuinit.setup_percpu_clockev = x86_init_noop;
--
-- x86_platform.calibrate_tsc = xen_tsc_khz;
-- x86_platform.get_wallclock = xen_get_wallclock;
-- x86_platform.set_wallclock = xen_set_wallclock;
-+ xen_init_time_ops();
-
- /*
- * Set up some pagetable state before starting to set any ptes.
-@@ -1116,6 +1184,10 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1113,6 +1184,10 @@ asmlinkage void __init xen_start_kernel(void)
*/
xen_setup_stackprotector();
@@ -3868,7 +3791,7 @@
xen_init_irq_ops();
xen_init_cpuid_mask();
-@@ -1144,6 +1216,8 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1141,6 +1216,8 @@ asmlinkage void __init xen_start_kernel(void)
pgd = (pgd_t *)xen_start_info->pt_base;
@@ -3877,7 +3800,7 @@
/* 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 +1227,7 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1150,6 +1227,7 @@ 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);
@@ -3885,7 +3808,7 @@
init_mm.pgd = pgd;
-@@ -1162,6 +1237,14 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1159,6 +1237,14 @@ asmlinkage void __init xen_start_kernel(void)
if (xen_feature(XENFEAT_supervisor_mode_kernel))
pv_info.kernel_rpl = 0;
@@ -3900,7 +3823,7 @@
/* set the limit of our address space */
xen_reserve_top();
-@@ -1184,6 +1267,16 @@ asmlinkage void __init xen_start_kernel(void)
+@@ -1181,6 +1267,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);
@@ -3917,133 +3840,39 @@
}
xen_raw_console_write("about to get started...\n");
-@@ -1197,3 +1290,124 @@ asmlinkage void __init xen_start_kernel(void)
- x86_64_start_reservations((char *)__pa_symbol(&boot_params));
- #endif
- }
-+
-+static uint32_t xen_cpuid_base(void)
-+{
-+ uint32_t base, eax, ebx, ecx, edx;
-+ char signature[13];
-+
-+ for (base = 0x40000000; base < 0x40010000; base += 0x100) {
-+ cpuid(base, &eax, &ebx, &ecx, &edx);
-+ *(uint32_t *)(signature + 0) = ebx;
-+ *(uint32_t *)(signature + 4) = ecx;
-+ *(uint32_t *)(signature + 8) = edx;
-+ signature[12] = 0;
-+
-+ if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2))
-+ return base;
-+ }
-+
-+ return 0;
-+}
-+
-+static int init_hvm_pv_info(int *major, int *minor)
-+{
-+ uint32_t eax, ebx, ecx, edx, pages, msr, base;
-+ u64 pfn;
-+
-+ base = xen_cpuid_base();
+@@ -1220,6 +1316,9 @@ static int init_hvm_pv_info(int *major, int *minor)
+ u64 pfn;
+
+ base = xen_cpuid_base();
+ if (!base)
+ return -EINVAL;
+
-+ cpuid(base + 1, &eax, &ebx, &ecx, &edx);
-+
-+ *major = eax >> 16;
-+ *minor = eax & 0xffff;
-+ printk(KERN_INFO "Xen version %d.%d.\n", *major, *minor);
-+
-+ cpuid(base + 2, &pages, &msr, &ecx, &edx);
-+
-+ pfn = __pa(hypercall_page);
-+ wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
-+
-+ xen_setup_features();
-+
-+ pv_info = xen_info;
-+ pv_info.kernel_rpl = 0;
-+
-+ xen_domain_type = XEN_HVM_DOMAIN;
-+
-+ return 0;
-+}
-+
-+void xen_hvm_init_shared_info(void)
-+{
-+ int cpu;
-+ struct xen_add_to_physmap xatp;
-+ static struct shared_info *shared_info_page = 0;
-+
-+ if (!shared_info_page)
-+ shared_info_page = (struct shared_info *) alloc_bootmem_pages(PAGE_SIZE);
-+ xatp.domid = DOMID_SELF;
-+ xatp.idx = 0;
-+ xatp.space = XENMAPSPACE_shared_info;
-+ xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
-+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
-+ BUG();
-+
-+ HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
-+
-+ /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
-+ * page, we use it in the event channel upcall and in some pvclock
-+ * related functions. We don't need the vcpu_info placement
-+ * optimizations because we don't use any pv_mmu or pv_irq op on
-+ * HVM.
-+ * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is
-+ * online but xen_hvm_init_shared_info is run at resume time too and
-+ * in that case multiple vcpus might be online. */
-+ for_each_online_cpu(cpu) {
-+ per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
-+ }
-+}
-+
-+static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
-+ unsigned long action, void *hcpu)
-+{
-+ int cpu = (long)hcpu;
-+ switch (action) {
-+ case CPU_UP_PREPARE:
-+ per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
-+ break;
-+ default:
-+ break;
-+ }
-+ return NOTIFY_OK;
-+}
-+
-+static struct notifier_block __cpuinitdata xen_hvm_cpu_notifier = {
-+ .notifier_call = xen_hvm_cpu_notify,
-+};
-+
-+void __init xen_hvm_guest_init(void)
-+{
-+ int r;
-+ int major, minor;
-+
-+ if (xen_pv_domain())
-+ return;
-+
-+ r = init_hvm_pv_info(&major, &minor);
-+ if (r < 0)
-+ return;
-+
-+ xen_hvm_init_shared_info();
-+
-+ if (xen_feature(XENFEAT_hvm_callback_vector))
-+ xen_have_vector_callback = 1;
-+ register_cpu_notifier(&xen_hvm_cpu_notifier);
-+ xen_unplug_emulated_devices();
-+ have_vcpu_info_placement = 0;
-+ x86_init.irqs.intr_init = xen_init_IRQ;
-+ xen_hvm_init_time_ops();
-+ xen_hvm_init_mmu_ops();
-+}
+ cpuid(base + 1, &eax, &ebx, &ecx, &edx);
+
+ *major = eax >> 16;
+@@ -1249,7 +1348,6 @@ void xen_hvm_init_shared_info(void)
+
+ if (!shared_info_page)
+ shared_info_page = (struct shared_info *) alloc_bootmem_pages(PAGE_SIZE);
+-
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = XENMAPSPACE_shared_info;
+@@ -1272,7 +1370,6 @@ void xen_hvm_init_shared_info(void)
+ }
+ }
+
+-#ifdef CONFIG_XEN_PVHVM
+ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+ {
+@@ -1314,4 +1411,3 @@ void __init xen_hvm_guest_init(void)
+ xen_hvm_init_time_ops();
+ xen_hvm_init_mmu_ops();
+ }
+-#endif
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
-index 350a3de..74e284f 100644
+index 971a405..74e284f 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -42,6 +42,7 @@
@@ -4054,7 +3883,7 @@
#include <linux/module.h>
#include <asm/pgtable.h>
-@@ -50,14 +51,19 @@
+@@ -50,7 +51,10 @@
#include <asm/mmu_context.h>
#include <asm/setup.h>
#include <asm/paravirt.h>
@@ -4065,16 +3894,15 @@
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
-
- #include <xen/page.h>
+@@ -59,6 +63,7 @@
#include <xen/interface/xen.h>
-+#include <xen/interface/hvm/hvm_op.h>
+ #include <xen/interface/hvm/hvm_op.h>
#include <xen/interface/version.h>
+#include <xen/interface/memory.h>
#include <xen/hvc-console.h>
#include "multicalls.h"
-@@ -66,6 +72,13 @@
+@@ -67,6 +72,13 @@
#define MMU_UPDATE_HISTO 30
@@ -4088,7 +3916,7 @@
#ifdef CONFIG_XEN_DEBUG_FS
static struct {
-@@ -184,6 +197,26 @@ static inline unsigned p2m_index(unsigned long pfn)
+@@ -185,6 +197,26 @@ static inline unsigned p2m_index(unsigned long pfn)
return pfn % P2M_ENTRIES_PER_PAGE;
}
@@ -4115,7 +3943,7 @@
/* Build the parallel p2m_top_mfn structures */
void xen_build_mfn_list_list(void)
{
-@@ -315,6 +348,7 @@ unsigned long arbitrary_virt_to_mfn(void *vaddr)
+@@ -316,6 +348,7 @@ unsigned long arbitrary_virt_to_mfn(void *vaddr)
return PFN_DOWN(maddr.maddr);
}
@@ -4123,7 +3951,7 @@
xmaddr_t arbitrary_virt_to_machine(void *vaddr)
{
-@@ -376,6 +410,34 @@ static bool xen_page_pinned(void *ptr)
+@@ -377,6 +410,34 @@ static bool xen_page_pinned(void *ptr)
return PagePinned(page);
}
@@ -4158,7 +3986,7 @@
static void xen_extend_mmu_update(const struct mmu_update *update)
{
struct multicall_space mcs;
-@@ -452,6 +514,11 @@ void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
+@@ -453,6 +514,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)
{
@@ -4170,7 +3998,7 @@
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);
-@@ -522,9 +589,34 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
+@@ -523,9 +589,34 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
return val;
}
@@ -4206,7 +4034,7 @@
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
-@@ -534,9 +626,62 @@ pgdval_t xen_pgd_val(pgd_t pgd)
+@@ -535,9 +626,62 @@ pgdval_t xen_pgd_val(pgd_t pgd)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pgd_val);
@@ -4270,7 +4098,7 @@
return native_make_pte(pte);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
-@@ -592,6 +737,11 @@ void xen_set_pud(pud_t *ptr, pud_t val)
+@@ -593,6 +737,11 @@ void xen_set_pud(pud_t *ptr, pud_t val)
void xen_set_pte(pte_t *ptep, pte_t pte)
{
@@ -4282,7 +4110,7 @@
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 +758,11 @@ void xen_set_pte(pte_t *ptep, pte_t pte)
+@@ -609,6 +758,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)
{
@@ -4294,7 +4122,7 @@
set_64bit((u64 *)ptep, native_pte_val(pte));
}
-@@ -934,8 +1089,6 @@ static int xen_pin_page(struct mm_struct *mm, struct page *page,
+@@ -935,8 +1089,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)
{
@@ -4303,7 +4131,7 @@
xen_mc_batch();
if (__xen_pgd_walk(mm, pgd, xen_pin_page, USER_LIMIT)) {
-@@ -1219,7 +1372,7 @@ void xen_exit_mmap(struct mm_struct *mm)
+@@ -1220,7 +1372,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 */
@@ -4312,7 +4140,7 @@
xen_pgd_unpin(mm);
spin_unlock(&mm->page_table_lock);
-@@ -1288,12 +1441,19 @@ static void xen_flush_tlb_single(unsigned long addr)
+@@ -1289,12 +1441,19 @@ static void xen_flush_tlb_single(unsigned long addr)
preempt_enable();
}
@@ -4333,7 +4161,7 @@
} *args;
struct multicall_space mcs;
-@@ -1417,6 +1577,13 @@ static int xen_pgd_alloc(struct mm_struct *mm)
+@@ -1418,6 +1577,13 @@ static int xen_pgd_alloc(struct mm_struct *mm)
return ret;
}
@@ -4347,7 +4175,7 @@
static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
#ifdef CONFIG_X86_64
-@@ -1448,10 +1615,17 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
+@@ -1449,10 +1615,17 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
#ifdef CONFIG_X86_32
static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
{
@@ -4367,7 +4195,7 @@
return pte;
}
-@@ -1517,7 +1691,6 @@ static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned l
+@@ -1518,7 +1691,6 @@ static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned l
if (PagePinned(virt_to_page(mm->pgd))) {
SetPagePinned(page);
@@ -4375,7 +4203,7 @@
if (!PageHighMem(page)) {
make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn)));
if (level == PT_PTE && USE_SPLIT_PTLOCKS)
-@@ -1620,6 +1793,7 @@ static void *m2v(phys_addr_t maddr)
+@@ -1621,6 +1793,7 @@ static void *m2v(phys_addr_t maddr)
return __ka(m2p(maddr));
}
@@ -4383,7 +4211,7 @@
static void set_page_prot(void *addr, pgprot_t prot)
{
unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
-@@ -1675,6 +1849,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+@@ -1676,6 +1849,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
set_page_prot(pmd, PAGE_KERNEL_RO);
}
@@ -4404,7 +4232,7 @@
#ifdef CONFIG_X86_64
static void convert_pfn_mfn(void *v)
{
-@@ -1766,6 +1954,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1767,6 +1954,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
unsigned long max_pfn)
{
pmd_t *kernel_pmd;
@@ -4412,7 +4240,7 @@
max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
xen_start_info->nr_pt_frames * PAGE_SIZE +
-@@ -1777,6 +1966,20 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1778,6 +1966,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);
@@ -4433,7 +4261,7 @@
set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
__pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
-@@ -1799,6 +2002,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1800,6 +2002,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
}
#endif /* CONFIG_X86_64 */
@@ -4442,7 +4270,7 @@
static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
{
pte_t pte;
-@@ -1828,9 +2033,26 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
+@@ -1829,9 +2033,26 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
pte = pfn_pte(phys, prot);
break;
@@ -4470,7 +4298,7 @@
}
__native_set_fixmap(idx, pte);
-@@ -1845,6 +2067,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
+@@ -1846,6 +2067,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
#endif
}
@@ -4500,7 +4328,7 @@
static __init void xen_post_allocator_init(void)
{
pv_mmu_ops.set_pte = xen_set_pte;
-@@ -1960,6 +2205,301 @@ void __init xen_init_mmu_ops(void)
+@@ -1961,9 +2205,271 @@ 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;
@@ -4700,7 +4528,7 @@
+ xen_remap_exchanged_ptes(vstart, order, NULL, in_frame);
+
+ spin_unlock_irqrestore(&xen_reservation_lock, flags);
-+}
+ }
+EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
+
+#define REMAP_BATCH_SIZE 16
@@ -4768,50 +4596,19 @@
+ return err;
+}
+EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
-+
-+static void xen_hvm_exit_mmap(struct mm_struct *mm)
-+{
-+ struct xen_hvm_pagetable_dying a;
-+ int rc;
-+
-+ a.domid = DOMID_SELF;
-+ a.gpa = __pa(mm->pgd);
-+ rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
-+ WARN_ON_ONCE(rc < 0);
-+}
-+
-+static int is_pagetable_dying_supported(void)
-+{
-+ struct xen_hvm_pagetable_dying a;
-+ int rc = 0;
-+
-+ a.domid = DOMID_SELF;
-+ a.gpa = 0x00;
-+ rc = HYPERVISOR_hvm_op(HVMOP_pagetable_dying, &a);
-+ if (rc < 0) {
-+ printk(KERN_DEBUG "HVMOP_pagetable_dying not supported\n");
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+void __init xen_hvm_init_mmu_ops(void)
-+{
-+ if (is_pagetable_dying_supported())
-+ pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap;
+
+-#ifdef CONFIG_XEN_PVHVM
+ static void xen_hvm_exit_mmap(struct mm_struct *mm)
+ {
+ struct xen_hvm_pagetable_dying a;
+@@ -1995,7 +2501,6 @@ void __init xen_hvm_init_mmu_ops(void)
+ if (is_pagetable_dying_supported())
+ pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap;
}
+-#endif
#ifdef CONFIG_XEN_DEBUG_FS
-diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
-index 5fe6bc7..fa938c4 100644
---- a/arch/x86/xen/mmu.h
-+++ b/arch/x86/xen/mmu.h
-@@ -60,4 +60,5 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
- unsigned long xen_read_cr2_direct(void);
-
- extern void xen_init_mmu_ops(void);
-+extern void xen_hvm_init_mmu_ops(void);
- #endif /* _XEN_MMU_H */
+
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
new file mode 100644
index 0000000..4d55524
@@ -5173,146 +4970,22 @@
+}
+EXPORT_SYMBOL(xen_unregister_device_domain_owner);
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
-new file mode 100644
-index 0000000..2f7f3fb
---- /dev/null
+index 554c002..2f7f3fb 100644
+--- a/arch/x86/xen/platform-pci-unplug.c
+++ b/arch/x86/xen/platform-pci-unplug.c
-@@ -0,0 +1,135 @@
-+/******************************************************************************
-+ * platform-pci-unplug.c
-+ *
-+ * Xen platform PCI device driver
-+ * Copyright (c) 2010, Citrix
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ * more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along with
-+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-+ * Place - Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+
-+#include <xen/platform_pci.h>
-+
-+#define XEN_PLATFORM_ERR_MAGIC -1
-+#define XEN_PLATFORM_ERR_PROTOCOL -2
-+#define XEN_PLATFORM_ERR_BLACKLIST -3
-+
-+/* store the value of xen_emul_unplug after the unplug is done */
-+int xen_platform_pci_unplug;
-+EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
-+static int xen_emul_unplug;
-+
-+static int __init check_platform_magic(void)
-+{
-+ short magic;
-+ char protocol;
-+
-+ magic = inw(XEN_IOPORT_MAGIC);
-+ if (magic != XEN_IOPORT_MAGIC_VAL) {
-+ printk(KERN_ERR "Xen Platform PCI: unrecognised magic value\n");
-+ return XEN_PLATFORM_ERR_MAGIC;
-+ }
-+
-+ protocol = inb(XEN_IOPORT_PROTOVER);
-+
-+ printk(KERN_DEBUG "Xen Platform PCI: I/O protocol version %d\n",
-+ protocol);
-+
-+ switch (protocol) {
-+ case 1:
-+ outw(XEN_IOPORT_LINUX_PRODNUM, XEN_IOPORT_PRODNUM);
-+ outl(XEN_IOPORT_LINUX_DRVVER, XEN_IOPORT_DRVVER);
-+ if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
-+ printk(KERN_ERR "Xen Platform: blacklisted by host\n");
-+ return XEN_PLATFORM_ERR_BLACKLIST;
-+ }
-+ break;
-+ default:
-+ printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version");
-+ return XEN_PLATFORM_ERR_PROTOCOL;
-+ }
-+
-+ return 0;
-+}
-+
-+void __init xen_unplug_emulated_devices(void)
-+{
-+ int r;
-+
-+ /* check the version of the xen platform PCI device */
-+ r = check_platform_magic();
-+ /* If the version matches enable the Xen platform PCI driver.
-+ * Also enable the Xen platform PCI driver if the version is really old
-+ * and the user told us to ignore it. */
-+ if (r && !(r == XEN_PLATFORM_ERR_MAGIC &&
-+ (xen_emul_unplug & XEN_UNPLUG_IGNORE)))
-+ return;
-+ /* Set the default value of xen_emul_unplug depending on whether or
-+ * not the Xen PV frontends and the Xen platform PCI driver have
-+ * been compiled for this kernel (modules or built-in are both OK). */
-+ if (!xen_emul_unplug) {
-+ if (xen_must_unplug_nics()) {
-+ printk(KERN_INFO "Netfront and the Xen platform PCI driver have "
-+ "been compiled for this kernel: unplug emulated NICs.\n");
-+ xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
-+ }
-+ if (xen_must_unplug_disks()) {
-+ printk(KERN_INFO "Blkfront and the Xen platform PCI driver have "
-+ "been compiled for this kernel: unplug emulated disks.\n"
-+ "You might have to change the root device\n"
-+ "from /dev/hd[a-d] to /dev/xvd[a-d]\n"
-+ "in your root= kernel command line option\n");
-+ xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
-+ }
-+ }
-+ /* Now unplug the emulated devices */
-+ if (!(xen_emul_unplug & XEN_UNPLUG_IGNORE))
-+ outw(xen_emul_unplug, XEN_IOPORT_UNPLUG);
-+ xen_platform_pci_unplug = xen_emul_unplug;
-+}
-+
-+static int __init parse_xen_emul_unplug(char *arg)
-+{
-+ char *p, *q;
-+ int l;
-+
-+ for (p = arg; p; p = q) {
-+ q = strchr(p, ',');
-+ if (q) {
-+ l = q - p;
-+ q++;
-+ } else {
-+ l = strlen(p);
-+ }
-+ if (!strncmp(p, "all", l))
-+ xen_emul_unplug |= XEN_UNPLUG_ALL;
-+ else if (!strncmp(p, "ide-disks", l))
-+ xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
-+ else if (!strncmp(p, "aux-ide-disks", l))
-+ xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS;
-+ else if (!strncmp(p, "nics", l))
-+ xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
-+ else if (!strncmp(p, "ignore", l))
-+ xen_emul_unplug |= XEN_UNPLUG_IGNORE;
-+ else
-+ printk(KERN_WARNING "unrecognised option '%s' "
-+ "in parameter 'xen_emul_unplug'\n", p);
-+ }
-+ return 0;
-+}
-+early_param("xen_emul_unplug", parse_xen_emul_unplug);
+@@ -32,7 +32,6 @@
+ /* store the value of xen_emul_unplug after the unplug is done */
+ int xen_platform_pci_unplug;
+ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
+-#ifdef CONFIG_XEN_PVHVM
+ static int xen_emul_unplug;
+
+ static int __init check_platform_magic(void)
+@@ -134,4 +133,3 @@ static int __init parse_xen_emul_unplug(char *arg)
+ return 0;
+ }
+ 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..804815c 100644
--- a/arch/x86/xen/setup.c
@@ -5549,65 +5222,13 @@
HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
BUG();
}
-diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
-index a9c6611..1d789d5 100644
---- a/arch/x86/xen/suspend.c
-+++ b/arch/x86/xen/suspend.c
-@@ -26,6 +26,18 @@ void xen_pre_suspend(void)
- BUG();
- }
-
-+void xen_hvm_post_suspend(int suspend_cancelled)
-+{
-+ int cpu;
-+ xen_hvm_init_shared_info();
-+ xen_callback_vector();
-+ if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
-+ for_each_online_cpu(cpu) {
-+ xen_setup_runstate_info(cpu);
-+ }
-+ }
-+}
-+
- void xen_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..68feb40 100644
+index 094c70a..68feb40 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
-@@ -19,6 +19,7 @@
- #include <asm/xen/hypercall.h>
-
- #include <xen/events.h>
-+#include <xen/features.h>
- #include <xen/interface/xen.h>
- #include <xen/interface/vcpu.h>
-
-@@ -155,7 +156,7 @@ static void do_stolen_accounting(void)
- }
-
- /* Get the TSC speed from Xen */
--unsigned long xen_tsc_khz(void)
-+static unsigned long xen_tsc_khz(void)
- {
- struct pvclock_vcpu_time_info *info =
- &HYPERVISOR_shared_info->vcpu_info[0].time;
-@@ -190,7 +191,7 @@ static void xen_read_wallclock(struct timespec *ts)
- put_cpu_var(xen_vcpu);
- }
-
--unsigned long xen_get_wallclock(void)
-+static unsigned long xen_get_wallclock(void)
- {
- struct timespec ts;
-
-@@ -198,10 +199,24 @@ unsigned long xen_get_wallclock(void)
- return ts.tv_sec;
- }
+@@ -201,8 +201,22 @@ static unsigned long xen_get_wallclock(void)
--int xen_set_wallclock(unsigned long now)
-+static int xen_set_wallclock(unsigned long now)
+ static int xen_set_wallclock(unsigned long now)
{
+ struct xen_platform_op op;
+ int rc;
@@ -5629,7 +5250,7 @@
}
static struct clocksource xen_clocksource __read_mostly = {
-@@ -403,6 +418,8 @@ void xen_setup_timer(int cpu)
+@@ -404,6 +418,8 @@ void xen_setup_timer(int cpu)
evt->cpumask = cpumask_of(cpu);
evt->irq = irq;
@@ -5638,65 +5259,41 @@
}
void xen_teardown_timer(int cpu)
-@@ -433,7 +450,7 @@ void xen_timer_resume(void)
+@@ -434,10 +450,6 @@ void xen_timer_resume(void)
}
}
--__init void xen_time_init(void)
-+static __init void xen_time_init(void)
+-static const struct pv_time_ops xen_time_ops __initdata = {
+- .sched_clock = xen_clocksource_read,
+-};
+-
+ static __init void xen_time_init(void)
{
int cpu = smp_processor_id();
-
-@@ -457,3 +474,49 @@ __init void xen_time_init(void)
- xen_setup_timer(cpu);
+@@ -463,6 +475,10 @@ static __init void xen_time_init(void)
xen_setup_cpu_clockevents();
}
-+
+
+static const struct pv_time_ops xen_time_ops __initdata = {
+ .sched_clock = xen_clocksource_read,
+};
+
-+__init void xen_init_time_ops(void)
-+{
-+ pv_time_ops = xen_time_ops;
-+
-+ x86_init.timers.timer_init = xen_time_init;
-+ x86_init.timers.setup_percpu_clockev = x86_init_noop;
-+ x86_cpuinit.setup_percpu_clockev = x86_init_noop;
-+
-+ x86_platform.calibrate_tsc = xen_tsc_khz;
-+ x86_platform.get_wallclock = xen_get_wallclock;
-+ x86_platform.set_wallclock = xen_set_wallclock;
-+}
-+
-+static void xen_hvm_setup_cpu_clockevents(void)
-+{
-+ int cpu = smp_processor_id();
-+ xen_setup_runstate_info(cpu);
-+ xen_setup_timer(cpu);
-+ xen_setup_cpu_clockevents();
-+}
-+
-+__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)
-+ return;
-+ if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
-+ printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
-+ "disable pv timer\n");
-+ return;
-+ }
-+
-+ pv_time_ops = xen_time_ops;
-+ x86_init.timers.setup_percpu_clockev = xen_time_init;
-+ x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents;
-+
-+ x86_platform.calibrate_tsc = xen_tsc_khz;
-+ x86_platform.get_wallclock = xen_get_wallclock;
-+ x86_platform.set_wallclock = xen_set_wallclock;
-+}
+ __init void xen_init_time_ops(void)
+ {
+ pv_time_ops = xen_time_ops;
+@@ -476,7 +492,6 @@ __init void xen_init_time_ops(void)
+ x86_platform.set_wallclock = xen_set_wallclock;
+ }
+
+-#ifdef CONFIG_XEN_PVHVM
+ static void xen_hvm_setup_cpu_clockevents(void)
+ {
+ int cpu = smp_processor_id();
+@@ -505,4 +520,3 @@ __init void xen_hvm_init_time_ops(void)
+ x86_platform.get_wallclock = xen_get_wallclock;
+ x86_platform.set_wallclock = xen_set_wallclock;
+ }
+-#endif
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c
new file mode 100644
index 0000000..1cd7f4d
@@ -5771,7 +5368,7 @@
+ }
+}
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
-index f9153a3..3bcdbed 100644
+index ed77694..3bcdbed 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -30,6 +30,9 @@ void xen_setup_machphys_mapping(void);
@@ -5784,32 +5381,7 @@
char * __init xen_memory_setup(void);
void __init xen_arch_setup(void);
-@@ -38,6 +41,10 @@ void xen_enable_sysenter(void);
- void xen_enable_syscall(void);
- void xen_vcpu_restore(void);
-
-+void xen_callback_vector(void);
-+void xen_hvm_init_shared_info(void);
-+void __init xen_unplug_emulated_devices(void);
-+
- void __init xen_build_dynamic_phys_to_machine(void);
-
- void xen_init_irq_ops(void);
-@@ -46,11 +53,8 @@ void xen_setup_runstate_info(int cpu);
- void xen_teardown_timer(int cpu);
- cycle_t xen_clocksource_read(void);
- void xen_setup_cpu_clockevents(void);
--unsigned long xen_tsc_khz(void);
--void __init xen_time_init(void);
--unsigned long xen_get_wallclock(void);
--int xen_set_wallclock(unsigned long time);
--unsigned long long xen_sched_clock(void);
-+void __init xen_init_time_ops(void);
-+void __init xen_hvm_init_time_ops(void);
-
- irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
-
-@@ -82,6 +86,23 @@ static inline void xen_uninit_lock_cpu(int cpu)
+@@ -83,6 +86,23 @@ static inline void xen_uninit_lock_cpu(int cpu)
}
#endif
@@ -5833,7 +5405,7 @@
/* Declare an asm function, along with symbols needed to make it
inlineable */
#define DECL_ASM(ret, name, ...) \
-@@ -101,4 +122,6 @@ void xen_sysret32(void);
+@@ -102,4 +122,6 @@ void xen_sysret32(void);
void xen_sysret64(void);
void xen_adjust_exception_frame(void);
@@ -6829,10 +6401,10 @@
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..89adac5 100644
+index ac692c5..89adac5 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
-@@ -42,10 +42,12 @@
+@@ -42,6 +42,7 @@
#include <linux/module.h>
#include <linux/scatterlist.h>
@@ -6840,12 +6412,7 @@
#include <xen/xenbus.h>
#include <xen/grant_table.h>
#include <xen/events.h>
- #include <xen/page.h>
-+#include <xen/platform_pci.h>
-
- #include <xen/interface/grant_table.h>
- #include <xen/interface/io/blkif.h>
-@@ -76,6 +78,7 @@ static const struct block_device_operations xlvbd_block_fops;
+@@ -77,6 +78,7 @@ static const struct block_device_operations xlvbd_block_fops;
*/
struct blkfront_info
{
@@ -6853,7 +6420,7 @@
struct xenbus_device *xbdev;
struct gendisk *gd;
int vdevice;
-@@ -92,16 +95,14 @@ struct blkfront_info
+@@ -93,16 +95,14 @@ struct blkfront_info
unsigned long shadow_free;
int feature_barrier;
int is_ready;
@@ -6874,7 +6441,7 @@
#define MAXIMUM_OUTSTANDING_BLOCK_REQS \
(BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE)
#define GRANT_INVALID_REF 0
-@@ -136,6 +137,55 @@ static void add_id_to_freelist(struct blkfront_info *info,
+@@ -137,6 +137,55 @@ static void add_id_to_freelist(struct blkfront_info *info,
info->shadow_free = id;
}
@@ -6930,7 +6497,7 @@
static void blkif_restart_queue_callback(void *arg)
{
struct blkfront_info *info = (struct blkfront_info *)arg;
-@@ -416,9 +466,14 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+@@ -417,9 +466,14 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
if ((minor % nr_parts) == 0)
nr_minors = nr_parts;
@@ -6946,7 +6513,7 @@
offset = minor / nr_parts;
-@@ -449,7 +504,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+@@ -450,7 +504,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
if (xlvbd_init_blk_queue(gd, sector_size)) {
del_gendisk(gd);
@@ -6955,7 +6522,7 @@
}
info->rq = gd->queue;
-@@ -469,10 +524,45 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+@@ -470,10 +524,45 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
return 0;
@@ -7001,7 +6568,7 @@
static void kick_pending_request_queues(struct blkfront_info *info)
{
if (!RING_FULL(&info->ring)) {
-@@ -650,7 +740,7 @@ fail:
+@@ -651,7 +740,7 @@ fail:
/* Common code used when first setting up, and when resuming. */
@@ -7010,7 +6577,7 @@
struct blkfront_info *info)
{
const char *message = NULL;
-@@ -710,7 +800,6 @@ again:
+@@ -711,7 +800,6 @@ again:
return err;
}
@@ -7018,10 +6585,35 @@
/**
* 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,12 +825,29 @@ static int blkfront_probe(struct xenbus_device *dev,
+@@ -737,34 +825,21 @@ static int blkfront_probe(struct xenbus_device *dev,
}
}
+- if (xen_hvm_domain()) {
+- char *type;
+- int len;
+- /* no unplug has been done: do not hook devices != xen vbds */
+- if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) {
+- int major;
+-
+- if (!VDEV_IS_EXTENDED(vdevice))
+- major = BLKIF_MAJOR(vdevice);
+- else
+- major = XENVBD_MAJOR;
+-
+- if (major != XENVBD_MAJOR) {
+- printk(KERN_INFO
+- "%s: HVM does not support vbd %d as xen block device\n",
+- __FUNCTION__, vdevice);
+- return -ENODEV;
+- }
+- }
+- /* do not create a PV cdrom device if we are an HVM guest */
+- type = xenbus_read(XBT_NIL, dev->nodename, "device-type", &len);
+- if (IS_ERR(type))
+- return -ENODEV;
+- if (strncmp(type, "cdrom", 5) == 0) {
+- kfree(type);
+ /* no unplug has been done: do not hook devices != xen vbds */
+ if (xen_hvm_domain() && (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE)) {
+ int major;
@@ -7035,12 +6627,13 @@
+ printk(KERN_INFO
+ "%s: HVM does not support vbd %d as xen block device\n",
+ __FUNCTION__, vdevice);
-+ return -ENODEV;
-+ }
-+ }
+ return -ENODEV;
+ }
+- kfree(type);
+ }
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
- xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
+@@ -772,6 +847,7 @@ static int blkfront_probe(struct xenbus_device *dev,
return -ENOMEM;
}
@@ -7048,7 +6641,7 @@
info->xbdev = dev;
info->vdevice = vdevice;
info->connected = BLKIF_STATE_DISCONNECTED;
-@@ -755,7 +861,7 @@ static int blkfront_probe(struct xenbus_device *dev,
+@@ -785,7 +861,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);
@@ -7057,7 +6650,7 @@
if (err) {
kfree(info);
dev_set_drvdata(&dev->dev, NULL);
-@@ -850,13 +956,50 @@ static int blkfront_resume(struct xenbus_device *dev)
+@@ -880,13 +956,50 @@ static int blkfront_resume(struct xenbus_device *dev)
blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
@@ -7109,7 +6702,7 @@
/*
* Invoked when the backend is finally 'ready' (and has told produced
-@@ -869,10 +1012,29 @@ static void blkfront_connect(struct blkfront_info *info)
+@@ -899,10 +1012,29 @@ static void blkfront_connect(struct blkfront_info *info)
unsigned int binfo;
int err;
@@ -7141,7 +6734,7 @@
dev_dbg(&info->xbdev->dev, "%s:%s.\n",
__func__, info->xbdev->otherend);
-@@ -915,57 +1077,21 @@ static void blkfront_connect(struct blkfront_info *info)
+@@ -945,57 +1077,21 @@ static void blkfront_connect(struct blkfront_info *info)
}
/**
@@ -7203,7 +6796,7 @@
case XenbusStateUnknown:
case XenbusStateClosed:
break;
-@@ -975,35 +1101,56 @@ static void backend_changed(struct xenbus_device *dev,
+@@ -1005,35 +1101,56 @@ static void backend_changed(struct xenbus_device *dev,
break;
case XenbusStateClosing:
@@ -7280,7 +6873,7 @@
return 0;
}
-@@ -1012,30 +1159,68 @@ static int blkfront_is_ready(struct xenbus_device *dev)
+@@ -1042,30 +1159,68 @@ static int blkfront_is_ready(struct xenbus_device *dev)
{
struct blkfront_info *info = dev_get_drvdata(&dev->dev);
@@ -7363,7 +6956,7 @@
return 0;
}
-@@ -1061,7 +1246,7 @@ static struct xenbus_driver blkfront = {
+@@ -1091,7 +1246,7 @@ static struct xenbus_driver blkfront = {
.probe = blkfront_probe,
.remove = blkfront_remove,
.resume = blkfront_resume,
@@ -7786,7 +7379,7 @@
}
EXPORT_SYMBOL(ttm_fbdev_mmap);
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
-index b115726..80a072e 100644
+index 8ec2201..80a072e 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -21,7 +21,10 @@
@@ -7813,7 +7406,7 @@
static int __init xenkbd_init(void)
{
-- if (!xen_domain())
+- if (!xen_pv_domain())
+ if (!xen_domain() || xen_hvm_domain())
return -ENODEV;
@@ -9767,7 +9360,7 @@
info->fbdefio = &metronomefb_defio;
fb_deferred_io_init(info);
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
-index 54cd916..dc72563 100644
+index 450f958..dc72563 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -25,7 +25,10 @@
@@ -9803,13 +9396,13 @@
static int __init xenfb_init(void)
{
-- if (!xen_domain())
+- if (!xen_pv_domain())
+ if (!xen_domain() || xen_hvm_domain())
return -ENODEV;
/* Nothing to do if running in dom0. */
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
-index cab100a..a3e1923 100644
+index 96572e2..a3e1923 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -28,6 +28,110 @@ config XEN_DEV_EVTCHN
@@ -9923,14 +9516,10 @@
config XENFS
tristate "Xen filesystem"
depends on XEN
-@@ -60,4 +164,37 @@ config XEN_SYS_HYPERVISOR
- Create entries under /sys/hypervisor describing the Xen
- hypervisor environment. When running native or in another
+@@ -62,9 +166,32 @@ config XEN_SYS_HYPERVISOR
virtual environment, /sys/hypervisor will still be present,
-- but will have no xen contents.
-\ No newline at end of file
-+ but will have no xen contents.
-+
+ but will have no xen contents.
+
+config XEN_MCE
+ def_bool y
+ depends on XEN_DOM0 && X86_64 && X86_MCE_INTEL
@@ -9954,20 +9543,18 @@
+ depends on XEN_DOM0 && ACPI_PROCESSOR && CPU_FREQ
+ default y
+
-+config XEN_PLATFORM_PCI
-+ tristate "xen platform pci device driver"
+ config XEN_PLATFORM_PCI
+ tristate "xen platform pci device driver"
+- depends on XEN_PVHVM
+ depends on XEN
-+ default m
-+ help
-+ Driver for the Xen PCI Platform device: it is responsible for
-+ initializing xenbus and grant_table when running in a Xen HVM
-+ domain. As a consequence this driver is required to run any Xen PV
-+ frontend on Xen HVM.
+ default m
+ help
+ Driver for the Xen PCI Platform device: it is responsible for
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
-index 7c28434..ef1ea63 100644
+index e392fb7..ef1ea63 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
-@@ -1,12 +1,27 @@
+@@ -1,13 +1,27 @@
-obj-y += grant-table.o features.o events.o manage.o
+obj-y += grant-table.o features.o events.o manage.o biomerge.o pcpu.o
obj-y += xenbus/
@@ -9980,8 +9567,6 @@
-obj-$(CONFIG_XEN_BALLOON) += balloon.o
-obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o
-obj-$(CONFIG_XENFS) += xenfs/
--obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
-\ No newline at end of file
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
+obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
@@ -9993,13 +9578,13 @@
+obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
+obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/
+obj-$(CONFIG_XENFS) += xenfs/
-+obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
+ obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
+obj-$(CONFIG_XEN_MCE) += mce.o
+
+obj-$(CONFIG_XEN_S3) += acpi.o
+obj-$(CONFIG_ACPI_PROCESSOR_XEN) += acpi_processor.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += xen_acpi_memhotplug.o
-+obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
+ obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
+
+xen-evtchn-y := evtchn.o
+xen-gntdev-y := gntdev.o
@@ -15399,7 +14984,7 @@
#include <asm/xen/hypervisor.h>
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
-index 30e0467..b4a00bf 100644
+index 5d25cdf..b4a00bf 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -16,7 +16,7 @@
@@ -15411,7 +14996,7 @@
*
* Jeremy Fitzhardinge <jeremy at xensource.com>, XenSource Inc, 2007
*/
-@@ -27,18 +27,31 @@
+@@ -27,15 +27,22 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bootmem.h>
@@ -15420,7 +15005,7 @@
+#include <linux/pci.h>
+#include <linux/msi.h>
-+#include <asm/desc.h>
+ #include <asm/desc.h>
#include <asm/ptrace.h>
#include <asm/irq.h>
#include <asm/idle.h>
@@ -15431,19 +15016,19 @@
+#include <asm/xen/pci.h>
+#include <xen/xen.h>
-+#include <xen/hvm.h>
+ #include <xen/hvm.h>
#include <xen/xen-ops.h>
#include <xen/events.h>
- #include <xen/interface/xen.h>
- #include <xen/interface/event_channel.h>
-+#include <xen/interface/hvm/hvm_op.h>
-+#include <xen/interface/hvm/params.h>
-+
-+#include "../pci/msi.h"
+@@ -44,6 +51,8 @@
+ #include <xen/interface/hvm/hvm_op.h>
+ #include <xen/interface/hvm/params.h>
++#include "../pci/msi.h"
++
/*
* This lock protects updates to the following mapping and reference-count
-@@ -67,7 +80,7 @@ enum xen_irq_type {
+ * arrays. The lock does not need to be acquired to read the mapping tables.
+@@ -71,7 +80,7 @@ enum xen_irq_type {
* event channel - irq->event channel mapping
* cpu - cpu this event channel is bound to
* index - type-specific information:
@@ -15452,7 +15037,7 @@
* VIRQ - virq number
* IPI - IPI vector
* EVTCHN -
-@@ -83,20 +96,27 @@ struct irq_info
+@@ -87,20 +96,27 @@ struct irq_info
enum ipi_vector ipi;
struct {
unsigned short gsi;
@@ -15486,7 +15071,7 @@
static inline unsigned long *cpu_evtchn_mask(int cpu)
{
return cpu_evtchn_mask_p[cpu].bits;
-@@ -106,6 +126,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu)
+@@ -110,6 +126,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu)
#define VALID_EVTCHN(chn) ((chn) != 0)
static struct irq_chip xen_dynamic_chip;
@@ -15494,7 +15079,7 @@
/* Constructor for packed IRQ information. */
static struct irq_info mk_unbound_info(void)
-@@ -135,7 +156,8 @@ static struct irq_info mk_pirq_info(unsigned short evtchn,
+@@ -139,7 +156,8 @@ static struct irq_info mk_pirq_info(unsigned short evtchn,
unsigned short gsi, unsigned short vector)
{
return (struct irq_info) { .type = IRQT_PIRQ, .evtchn = evtchn,
@@ -15504,7 +15089,7 @@
}
/*
-@@ -218,6 +240,15 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn)
+@@ -222,6 +240,15 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn)
return ret;
}
@@ -15520,7 +15105,7 @@
static inline unsigned long active_evtchns(unsigned int cpu,
struct shared_info *sh,
unsigned int idx)
-@@ -329,27 +360,372 @@ static void unmask_evtchn(int port)
+@@ -333,12 +360,29 @@ static void unmask_evtchn(int port)
put_cpu();
}
@@ -15542,23 +15127,18 @@
+ int start = get_nr_hw_irqs();
+ void *chip_data;
-- for (irq = 0; irq < nr_irqs; irq++)
+- for (irq = 0; irq < nr_irqs; irq++) {
+ if (start == nr_irqs)
+ goto no_irqs;
+
+ /* nr_irqs is a magic value. Must not use it.*/
+ for (irq = nr_irqs-1; irq > start; irq--) {
-+ desc = irq_to_desc(irq);
-+ /* only 0->15 have init'd desc; handle irq > 16 */
-+ if (desc == NULL)
-+ break;
-+ if (desc->chip == &no_irq_chip)
-+ break;
-+ if (desc->chip != &xen_dynamic_chip)
-+ continue;
- if (irq_info[irq].type == IRQT_UNBOUND)
+ desc = irq_to_desc(irq);
+ /* only 0->15 have init'd desc; handle irq > 16 */
+ if (desc == NULL)
+@@ -351,18 +395,337 @@ static int find_unbound_irq(void)
break;
-+ }
+ }
- if (irq == nr_irqs)
- panic("No available IRQ to bind to: increase nr_irqs!\n");
@@ -15569,9 +15149,10 @@
if (WARN_ON(desc == NULL))
return -1;
+- dynamic_irq_init_keep_chip_data(irq);
+ /* save and restore chip_data */
+ chip_data = desc->chip_data;
- dynamic_irq_init(irq);
++ dynamic_irq_init(irq);
+ desc->chip_data = chip_data;
return irq;
@@ -15584,8 +15165,8 @@
+{
+ /* identity map all the hardware irqs */
+ return irq < get_nr_hw_irqs();
- }
-
++}
++
+static void pirq_unmask_notify(int irq)
+{
+ struct irq_info *info = info_for_irq(irq);
@@ -15595,8 +15176,8 @@
+ int rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
+ WARN_ON(rc);
+ }
-+}
-+
+ }
+
+static void pirq_query_unmask(int irq)
+{
+ struct physdev_irq_status_query irq_status;
@@ -15896,7 +15477,7 @@
int bind_evtchn_to_irq(unsigned int evtchn)
{
int irq;
-@@ -409,8 +785,23 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
+@@ -422,8 +785,23 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
return irq;
}
@@ -15908,20 +15489,20 @@
+
+ bind_interdomain.remote_dom = remote_domain;
+ bind_interdomain.remote_port = remote_port;
-+
+
+-static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
+
+ 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;
-@@ -504,6 +895,29 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
+@@ -517,6 +895,29 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
}
EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler);
@@ -15951,26 +15532,7 @@
int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
-@@ -617,17 +1031,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.
- */
--void xen_evtchn_do_upcall(struct pt_regs *regs)
-+static void __xen_evtchn_do_upcall(struct pt_regs *regs)
- {
- int cpu = get_cpu();
-- struct pt_regs *old_regs = set_irq_regs(regs);
- struct shared_info *s = HYPERVISOR_shared_info;
- struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
- unsigned count;
-
-- exit_idle();
-- irq_enter();
--
- do {
- unsigned long pending_words;
-
-@@ -650,9 +1060,13 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
+@@ -659,9 +1060,13 @@ static 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];
@@ -15986,54 +15548,17 @@
}
}
-@@ -660,14 +1074,32 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
-
- count = __get_cpu_var(xed_nesting_count);
- __get_cpu_var(xed_nesting_count) = 0;
-- } while(count != 1);
-+ } while (count != 1 || vcpu_info->evtchn_upcall_pending);
-
- out:
-+
-+ put_cpu();
-+}
-+
-+void xen_evtchn_do_upcall(struct pt_regs *regs)
-+{
-+ struct pt_regs *old_regs = set_irq_regs(regs);
-+
-+ exit_idle();
-+ irq_enter();
-+
-+ __xen_evtchn_do_upcall(regs);
-+
- irq_exit();
- set_irq_regs(old_regs);
-+}
+@@ -691,7 +1096,8 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
-- put_cpu();
-+void xen_hvm_evtchn_do_upcall(void)
-+{
+ void xen_hvm_evtchn_do_upcall(void)
+ {
+- __xen_evtchn_do_upcall(get_irq_regs());
+ struct pt_regs *regs = get_irq_regs();
+ __xen_evtchn_do_upcall(regs);
}
-+EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
+ EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall);
- /* Rebind a new event channel to an existing irq. */
- void rebind_evtchn_irq(int evtchn, int irq)
-@@ -704,7 +1136,10 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
- struct evtchn_bind_vcpu bind_vcpu;
- int evtchn = evtchn_from_irq(irq);
-
-- if (!VALID_EVTCHN(evtchn))
-+ /* events delivered via platform PCI interrupts are always
-+ * routed to vcpu 0 */
-+ if (!VALID_EVTCHN(evtchn) ||
-+ (xen_hvm_domain() && !xen_have_vector_callback))
- return -1;
-
- /* Send future instances of this interrupt to other vcpu. */
-@@ -856,7 +1291,7 @@ void xen_clear_irq_pending(int irq)
+@@ -885,7 +1291,7 @@ void xen_clear_irq_pending(int irq)
if (VALID_EVTCHN(evtchn))
clear_evtchn(evtchn);
}
@@ -16042,7 +15567,7 @@
void xen_set_irq_pending(int irq)
{
int evtchn = evtchn_from_irq(irq);
-@@ -876,9 +1311,9 @@ bool xen_test_irq_pending(int irq)
+@@ -905,9 +1311,9 @@ bool xen_test_irq_pending(int irq)
return ret;
}
@@ -16054,7 +15579,7 @@
{
evtchn_port_t evtchn = evtchn_from_irq(irq);
-@@ -886,13 +1321,33 @@ void xen_poll_irq(int irq)
+@@ -915,13 +1321,33 @@ void xen_poll_irq(int irq)
struct sched_poll poll;
poll.nr_ports = 1;
@@ -16089,7 +15614,7 @@
void xen_irq_resume(void)
{
-@@ -929,13 +1384,85 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
+@@ -958,6 +1384,26 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
.retrigger = retrigger_dynirq,
};
@@ -16113,16 +15638,14 @@
+ .retrigger = retrigger_dynirq,
+};
+
-+int xen_set_callback_via(uint64_t via)
-+{
-+ struct xen_hvm_param a;
-+ a.domid = DOMID_SELF;
-+ a.index = HVM_PARAM_CALLBACK_IRQ;
-+ a.value = via;
-+ return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
-+}
-+EXPORT_SYMBOL_GPL(xen_set_callback_via);
-+
+ int xen_set_callback_via(uint64_t via)
+ {
+ struct xen_hvm_param a;
+@@ -968,7 +1414,21 @@ int xen_set_callback_via(uint64_t via)
+ }
+ EXPORT_SYMBOL_GPL(xen_set_callback_via);
+
+-#ifdef CONFIG_XEN_PVHVM
+void smp_xen_hvm_callback_vector(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
@@ -16138,31 +15661,26 @@
+ set_irq_regs(old_regs);
+}
+
-+/* Vector callbacks are better than PCI interrupts to receive event
-+ * channel notifications because we can receive vector callbacks on any
-+ * vcpu and we don't need PCI support or APIC interactions. */
-+void xen_callback_vector(void)
-+{
-+ int rc;
-+ uint64_t callback_via;
-+ if (xen_have_vector_callback) {
-+ callback_via = HVM_CALLBACK_VECTOR(XEN_HVM_EVTCHN_CALLBACK);
-+ rc = xen_set_callback_via(callback_via);
-+ if (rc) {
-+ printk(KERN_ERR "Request for Xen HVM callback vector"
-+ " failed.\n");
-+ xen_have_vector_callback = 0;
-+ return;
-+ }
-+ printk(KERN_INFO "Xen HVM callback vector for event delivery is "
-+ "enabled\n");
+ /* Vector callbacks are better than PCI interrupts to receive event
+ * channel notifications because we can receive vector callbacks on any
+ * vcpu and we don't need PCI support or APIC interactions. */
+@@ -987,14 +1447,9 @@ void xen_callback_vector(void)
+ }
+ printk(KERN_INFO "Xen HVM callback vector for event delivery is "
+ "enabled\n");
+- /* 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);
+ alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
-+ }
-+}
-+
+ }
+ }
+-#else
+-void xen_callback_vector(void) {}
+-#endif
+
void __init xen_init_IRQ(void)
{
- int i;
+@@ -1002,7 +1457,12 @@ void __init xen_init_IRQ(void)
cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
GFP_KERNEL);
@@ -16176,18 +15694,12 @@
init_evtchn_cpu_bindings();
-@@ -943,5 +1470,11 @@ void __init xen_init_IRQ(void)
- for (i = 0; i < NR_EVENT_CHANNELS; i++)
- mask_evtchn(i);
-
-- irq_ctx_init(smp_processor_id());
-+ if (xen_hvm_domain()) {
-+ xen_callback_vector();
-+ native_init_IRQ();
-+ } else {
-+ irq_ctx_init(smp_processor_id());
+@@ -1015,5 +1475,6 @@ void __init xen_init_IRQ(void)
+ native_init_IRQ();
+ } else {
+ irq_ctx_init(smp_processor_id());
+ xen_setup_pirqs();
-+ }
+ }
}
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index 79bedba..b82666a 100644
@@ -17064,90 +16576,18 @@
+
+/* ------------------------------------------------------------------ */
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
-index 7d8f531..5a8ad45 100644
+index 6652ce9..5a8ad45 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
-@@ -36,10 +36,13 @@
- #include <linux/mm.h>
- #include <linux/vmalloc.h>
+@@ -38,6 +38,7 @@
#include <linux/uaccess.h>
-+#include <linux/io.h>
+ #include <linux/io.h>
+#include <xen/xen.h>
#include <xen/interface/xen.h>
#include <xen/page.h>
#include <xen/grant_table.h>
-+#include <xen/interface/memory.h>
- #include <asm/xen/hypercall.h>
-
- #include <asm/pgtable.h>
-@@ -57,6 +60,8 @@ static unsigned int boot_max_nr_grant_frames;
- static int gnttab_free_count;
- static grant_ref_t gnttab_free_head;
- static DEFINE_SPINLOCK(gnttab_list_lock);
-+unsigned long xen_hvm_resume_frames;
-+EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
-
- static struct grant_entry *shared;
-
-@@ -431,7 +436,7 @@ static unsigned int __max_nr_grant_frames(void)
- return query.max_nr_frames;
- }
-
--static inline unsigned int max_nr_grant_frames(void)
-+unsigned int gnttab_max_grant_frames(void)
- {
- unsigned int xen_max = __max_nr_grant_frames();
-
-@@ -439,6 +444,7 @@ static inline unsigned int max_nr_grant_frames(void)
- return boot_max_nr_grant_frames;
- return xen_max;
- }
-+EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
-
- static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
- {
-@@ -447,6 +453,30 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
- unsigned int nr_gframes = end_idx + 1;
- int rc;
-
-+ if (xen_hvm_domain()) {
-+ struct xen_add_to_physmap xatp;
-+ unsigned int i = end_idx;
-+ rc = 0;
-+ /*
-+ * Loop backwards, so that the first hypercall has the largest
-+ * index, ensuring that the table will grow only once.
-+ */
-+ do {
-+ xatp.domid = DOMID_SELF;
-+ xatp.idx = i;
-+ xatp.space = XENMAPSPACE_grant_table;
-+ xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i;
-+ rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
-+ if (rc != 0) {
-+ printk(KERN_WARNING
-+ "grant table add_to_physmap failed, err=%d\n", rc);
-+ break;
-+ }
-+ } while (i-- > start_idx);
-+
-+ return rc;
-+ }
-+
- frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
- if (!frames)
- return -ENOMEM;
-@@ -463,7 +493,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
-
- BUG_ON(rc || setup.status);
-
-- rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(),
-+ rc = arch_gnttab_map_shared(frames, nr_gframes, gnttab_max_grant_frames(),
- &shared);
- BUG_ON(rc);
-
-@@ -472,11 +502,134 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+@@ -501,6 +502,111 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
return 0;
}
@@ -17258,80 +16698,9 @@
+
int gnttab_resume(void)
{
-- if (max_nr_grant_frames() < nr_grant_frames)
-+ unsigned int max_nr_gframes;
-+
-+ max_nr_gframes = gnttab_max_grant_frames();
-+ if (max_nr_gframes < nr_grant_frames)
- return -ENOSYS;
-- return gnttab_map(0, nr_grant_frames - 1);
-+
-+ if (xen_pv_domain())
-+ return gnttab_map(0, nr_grant_frames - 1);
-+
-+ if (!shared) {
-+ shared = ioremap(xen_hvm_resume_frames, PAGE_SIZE * max_nr_gframes);
-+ if (shared == NULL) {
-+ printk(KERN_WARNING
-+ "Failed to ioremap gnttab share frames!");
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ gnttab_map(0, nr_grant_frames - 1);
-+
-+ return 0;
- }
-
- int gnttab_suspend(void)
-@@ -493,7 +646,7 @@ static int gnttab_expand(unsigned int req_entries)
- cur = nr_grant_frames;
- extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
- GREFS_PER_GRANT_FRAME);
-- if (cur + extra > max_nr_grant_frames())
-+ if (cur + extra > gnttab_max_grant_frames())
- return -ENOSPC;
-
- rc = gnttab_map(cur, cur + extra - 1);
-@@ -503,15 +656,12 @@ static int gnttab_expand(unsigned int req_entries)
- return rc;
- }
-
--static int __devinit gnttab_init(void)
-+int gnttab_init(void)
- {
- int i;
- unsigned int max_nr_glist_frames, nr_glist_frames;
- unsigned int nr_init_grefs;
-
-- if (!xen_domain())
-- return -ENODEV;
--
- nr_grant_frames = 1;
- boot_max_nr_grant_frames = __max_nr_grant_frames();
-
-@@ -554,5 +704,18 @@ static int __devinit gnttab_init(void)
- kfree(gnttab_list);
- return -ENOMEM;
- }
-+EXPORT_SYMBOL_GPL(gnttab_init);
-+
-+static int __devinit __gnttab_init(void)
-+{
-+ /* Delay grant-table initialization in the PV on HVM case */
-+ if (xen_hvm_domain())
-+ return 0;
-+
-+ if (!xen_pv_domain())
-+ return -ENODEV;
-+
-+ return gnttab_init();
-+}
-
--core_initcall(gnttab_init);
-+core_initcall(__gnttab_init);
+ unsigned int max_nr_gframes;
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
-index 5d42d55..0b50906 100644
+index aee1f59..0b50906 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -8,6 +8,7 @@
@@ -17342,79 +16711,14 @@
#include <xen/xenbus.h>
#include <xen/grant_table.h>
#include <xen/events.h>
-@@ -32,10 +33,30 @@ enum shutdown_state {
- static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
+@@ -16,7 +17,6 @@
- #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);
-+
-+ xen_hvm_post_suspend(*cancelled);
-+ gnttab_resume();
-+
-+ if (!*cancelled) {
-+ xen_irq_resume();
-+ xen_timer_resume();
-+ }
-+
-+ return 0;
-+}
-+
-+static int xen_suspend(void *data)
-+{
- int err;
-+ int *cancelled = data;
-
- BUG_ON(!irqs_disabled());
-
-@@ -111,7 +132,10 @@ static void do_suspend(void)
- 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));
-
- dpm_resume_noirq(PMSG_RESUME);
-
-@@ -260,7 +284,19 @@ static int shutdown_event(struct notifier_block *notifier,
- return NOTIFY_DONE;
- }
-
--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;
-+
-+ if (!xen_pv_domain())
-+ return -ENODEV;
-+
-+ return xen_setup_shutdown_event();
-+}
-+
-+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)
-
- return 0;
- }
-+EXPORT_SYMBOL_GPL(xen_setup_shutdown_event);
+ #include <asm/xen/hypercall.h>
+ #include <asm/xen/page.h>
+-#include <asm/xen/hypervisor.h>
--subsys_initcall(setup_shutdown_event);
-+subsys_initcall(__setup_shutdown_event);
+ enum shutdown_state {
+ SHUTDOWN_INVALID = -1,
diff --git a/drivers/xen/mce.c b/drivers/xen/mce.c
new file mode 100644
index 0000000..da566a5
@@ -26573,219 +25877,6 @@
+}
+
+subsys_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
---- /dev/null
-+++ b/drivers/xen/platform-pci.c
-@@ -0,0 +1,207 @@
-+/******************************************************************************
-+ * platform-pci.c
-+ *
-+ * Xen platform PCI device driver
-+ * Copyright (c) 2005, Intel Corporation.
-+ * Copyright (c) 2007, XenSource Inc.
-+ * Copyright (c) 2010, Citrix
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ * more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along with
-+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-+ * Place - Suite 330, Boston, MA 02111-1307 USA.
-+ *
-+ */
-+
-+
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+
-+#include <xen/platform_pci.h>
-+#include <xen/grant_table.h>
-+#include <xen/xenbus.h>
-+#include <xen/events.h>
-+#include <xen/hvm.h>
-+#include <xen/xen-ops.h>
-+
-+#define DRV_NAME "xen-platform-pci"
-+
-+MODULE_AUTHOR("ssmith at xensource.com and stefano.stabellini at eu.citrix.com");
-+MODULE_DESCRIPTION("Xen platform PCI device");
-+MODULE_LICENSE("GPL");
-+
-+static unsigned long platform_mmio;
-+static unsigned long platform_mmio_alloc;
-+static unsigned long platform_mmiolen;
-+static uint64_t callback_via;
-+
-+unsigned long alloc_xen_mmio(unsigned long len)
-+{
-+ unsigned long addr;
-+
-+ addr = platform_mmio + platform_mmio_alloc;
-+ platform_mmio_alloc += len;
-+ BUG_ON(platform_mmio_alloc > platform_mmiolen);
-+
-+ return addr;
-+}
-+
-+static uint64_t get_callback_via(struct pci_dev *pdev)
-+{
-+ u8 pin;
-+ int irq;
-+
-+ irq = pdev->irq;
-+ if (irq < 16)
-+ return irq; /* ISA IRQ */
-+
-+ pin = pdev->pin;
-+
-+ /* We don't know the GSI. Specify the PCI INTx line instead. */
-+ return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */
-+ ((uint64_t)pci_domain_nr(pdev->bus) << 32) |
-+ ((uint64_t)pdev->bus->number << 16) |
-+ ((uint64_t)(pdev->devfn & 0xff) << 8) |
-+ ((uint64_t)(pin - 1) & 3);
-+}
-+
-+static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
-+{
-+ xen_hvm_evtchn_do_upcall();
-+ return IRQ_HANDLED;
-+}
-+
-+static int xen_allocate_irq(struct pci_dev *pdev)
-+{
-+ return request_irq(pdev->irq, do_hvm_evtchn_intr,
-+ IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
-+ "xen-platform-pci", pdev);
-+}
-+
-+static int platform_pci_resume(struct pci_dev *pdev)
-+{
-+ int err;
-+ if (xen_have_vector_callback)
-+ return 0;
-+ err = xen_set_callback_via(callback_via);
-+ if (err) {
-+ dev_err(&pdev->dev, "platform_pci_resume failure!\n");
-+ return err;
-+ }
-+ return 0;
-+}
-+
-+static int __devinit platform_pci_init(struct pci_dev *pdev,
-+ const struct pci_device_id *ent)
-+{
-+ int i, ret;
-+ long ioaddr, iolen;
-+ long mmio_addr, mmio_len;
-+ unsigned int max_nr_gframes;
-+
-+ i = pci_enable_device(pdev);
-+ if (i)
-+ return i;
-+
-+ ioaddr = pci_resource_start(pdev, 0);
-+ iolen = pci_resource_len(pdev, 0);
-+
-+ mmio_addr = pci_resource_start(pdev, 1);
-+ mmio_len = pci_resource_len(pdev, 1);
-+
-+ if (mmio_addr == 0 || ioaddr == 0) {
-+ dev_err(&pdev->dev, "no resources found\n");
-+ ret = -ENOENT;
-+ goto pci_out;
-+ }
-+
-+ if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {
-+ dev_err(&pdev->dev, "MEM I/O resource 0x%lx @ 0x%lx busy\n",
-+ mmio_addr, mmio_len);
-+ ret = -EBUSY;
-+ goto pci_out;
-+ }
-+
-+ if (request_region(ioaddr, iolen, DRV_NAME) == NULL) {
-+ dev_err(&pdev->dev, "I/O resource 0x%lx @ 0x%lx busy\n",
-+ iolen, ioaddr);
-+ ret = -EBUSY;
-+ goto mem_out;
-+ }
-+
-+ platform_mmio = mmio_addr;
-+ platform_mmiolen = mmio_len;
-+
-+ if (!xen_have_vector_callback) {
-+ ret = xen_allocate_irq(pdev);
-+ if (ret) {
-+ dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret);
-+ goto out;
-+ }
-+ callback_via = get_callback_via(pdev);
-+ ret = xen_set_callback_via(callback_via);
-+ if (ret) {
-+ dev_warn(&pdev->dev, "Unable to set the evtchn callback "
-+ "err=%d\n", ret);
-+ goto out;
-+ }
-+ }
-+
-+ max_nr_gframes = gnttab_max_grant_frames();
-+ xen_hvm_resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
-+ ret = gnttab_init();
-+ if (ret)
-+ goto out;
-+ xenbus_probe(NULL);
-+ ret = xen_setup_shutdown_event();
-+ if (ret)
-+ goto out;
-+ return 0;
-+
-+out:
-+ release_region(ioaddr, iolen);
-+mem_out:
-+ release_mem_region(mmio_addr, mmio_len);
-+pci_out:
-+ pci_disable_device(pdev);
-+ return ret;
-+}
-+
-+static struct pci_device_id platform_pci_tbl[] __devinitdata = {
-+ {PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+ {0,}
-+};
-+
-+MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
-+
-+static struct pci_driver platform_driver = {
-+ .name = DRV_NAME,
-+ .probe = platform_pci_init,
-+ .id_table = platform_pci_tbl,
-+#ifdef CONFIG_PM
-+ .resume_early = platform_pci_resume,
-+#endif
-+};
-+
-+static int __init platform_pci_module_init(void)
-+{
-+ /* no unplug has been done, IGNORE hasn't been specified: just
-+ * return now */
-+ if (!xen_platform_pci_unplug)
-+ return -ENODEV;
-+
-+ return pci_register_driver(&platform_driver);
-+}
-+
-+module_init(platform_pci_module_init);
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index 88a60e0..ae5cb05 100644
--- a/drivers/xen/sys-hypervisor.c
@@ -27167,10 +26258,10 @@
* @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 f52baf3..3a83ba2 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
-@@ -49,31 +49,29 @@
+@@ -49,6 +49,8 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/xen/hypervisor.h>
@@ -27179,12 +26270,7 @@
#include <xen/xenbus.h>
#include <xen/events.h>
#include <xen/page.h>
-
-+#include <xen/platform_pci.h>
-+#include <xen/hvm.h>
-+
- #include "xenbus_comms.h"
- #include "xenbus_probe.h"
+@@ -61,22 +63,15 @@
int xen_store_evtchn;
@@ -27210,7 +26296,7 @@
/* If something in array of ids matches this device, return it. */
static const struct xenbus_device_id *
match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
-@@ -94,34 +92,7 @@ int xenbus_match(struct device *_dev, struct device_driver *_drv)
+@@ -97,34 +92,7 @@ int xenbus_match(struct device *_dev, struct device_driver *_drv)
return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
}
@@ -27246,7 +26332,7 @@
static void free_otherend_details(struct xenbus_device *dev)
-@@ -141,7 +112,28 @@ static void free_otherend_watch(struct xenbus_device *dev)
+@@ -144,7 +112,28 @@ static void free_otherend_watch(struct xenbus_device *dev)
}
@@ -27276,7 +26362,7 @@
char *id_node, char *path_node)
{
int err = xenbus_gather(XBT_NIL, xendev->nodename,
-@@ -166,39 +158,11 @@ int read_otherend_details(struct xenbus_device *xendev,
+@@ -169,39 +158,11 @@ int read_otherend_details(struct xenbus_device *xendev,
return 0;
}
@@ -27320,7 +26406,7 @@
{
struct xenbus_device *dev =
container_of(watch, struct xenbus_device, otherend_watch);
-@@ -226,11 +190,7 @@ static void otherend_changed(struct xenbus_watch *watch,
+@@ -229,11 +190,7 @@ static void otherend_changed(struct xenbus_watch *watch,
* work that can fail e.g., when the rootfs is gone.
*/
if (system_state > SYSTEM_RUNNING) {
@@ -27333,7 +26419,7 @@
xenbus_frontend_closed(dev);
return;
}
-@@ -238,25 +198,7 @@ static void otherend_changed(struct xenbus_watch *watch,
+@@ -241,25 +198,7 @@ static void otherend_changed(struct xenbus_watch *watch,
if (drv->otherend_changed)
drv->otherend_changed(dev, state);
}
@@ -27360,7 +26446,7 @@
int xenbus_dev_probe(struct device *_dev)
{
-@@ -300,8 +242,9 @@ int xenbus_dev_probe(struct device *_dev)
+@@ -303,8 +242,9 @@ int xenbus_dev_probe(struct device *_dev)
fail:
xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
xenbus_switch_state(dev, XenbusStateClosed);
@@ -27371,7 +26457,7 @@
int xenbus_dev_remove(struct device *_dev)
{
-@@ -319,8 +262,9 @@ int xenbus_dev_remove(struct device *_dev)
+@@ -322,8 +262,9 @@ int xenbus_dev_remove(struct device *_dev)
xenbus_switch_state(dev, XenbusStateClosed);
return 0;
}
@@ -27382,7 +26468,7 @@
{
struct xenbus_device *dev = to_xenbus_device(_dev);
unsigned long timeout = 5*HZ;
-@@ -341,6 +285,7 @@ static void xenbus_dev_shutdown(struct device *_dev)
+@@ -344,6 +285,7 @@ static void xenbus_dev_shutdown(struct device *_dev)
out:
put_device(&dev->dev);
}
@@ -27390,7 +26476,7 @@
int xenbus_register_driver_common(struct xenbus_driver *drv,
struct xen_bus_type *bus,
-@@ -354,25 +299,7 @@ int xenbus_register_driver_common(struct xenbus_driver *drv,
+@@ -357,25 +299,7 @@ int xenbus_register_driver_common(struct xenbus_driver *drv,
return driver_register(&drv->driver);
}
@@ -27417,7 +26503,7 @@
void xenbus_unregister_driver(struct xenbus_driver *drv)
{
-@@ -543,24 +470,7 @@ fail:
+@@ -546,24 +470,7 @@ fail:
kfree(xendev);
return err;
}
@@ -27443,7 +26529,7 @@
static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
{
-@@ -574,10 +484,11 @@ static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
+@@ -577,10 +484,11 @@ static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
return PTR_ERR(dir);
for (i = 0; i < dir_n; i++) {
@@ -27456,7 +26542,7 @@
kfree(dir);
return err;
}
-@@ -597,9 +508,11 @@ int xenbus_probe_devices(struct xen_bus_type *bus)
+@@ -600,9 +508,11 @@ int xenbus_probe_devices(struct xen_bus_type *bus)
if (err)
break;
}
@@ -27468,7 +26554,7 @@
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)
+@@ -665,32 +575,17 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
}
EXPORT_SYMBOL_GPL(xenbus_dev_changed);
@@ -27504,7 +26590,7 @@
if (drv->suspend)
err = drv->suspend(xdev, state);
if (err)
-@@ -695,21 +593,19 @@ static int xenbus_dev_suspend(struct device *dev, pm_message_t state)
+@@ -698,21 +593,19 @@ static int xenbus_dev_suspend(struct device *dev, pm_message_t state)
"xenbus: suspend %s failed: %i\n", dev_name(dev), err);
return 0;
}
@@ -27530,7 +26616,7 @@
err = talk_to_otherend(xdev);
if (err) {
printk(KERN_WARNING
-@@ -740,6 +636,7 @@ static int xenbus_dev_resume(struct device *dev)
+@@ -743,6 +636,7 @@ static int xenbus_dev_resume(struct device *dev)
return 0;
}
@@ -27538,19 +26624,7 @@
/* 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);
-
- return ret;
- }
-@@ -768,57 +662,93 @@ void xenbus_probe(struct work_struct *unused)
+@@ -768,11 +662,6 @@ void xenbus_probe(struct work_struct *unused)
{
BUG_ON((xenstored_ready <= 0));
@@ -27562,24 +26636,8 @@
/* Notify others that xenstore is up */
blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
}
-+EXPORT_SYMBOL_GPL(xenbus_probe);
-+
-+static int __init xenbus_probe_initcall(void)
-+{
-+ if (!xen_domain())
-+ return -ENODEV;
-+
-+ if (xen_initial_domain() || xen_hvm_domain())
-+ return 0;
-+
-+ xenbus_probe(NULL);
-+ return 0;
-+}
-+
-+device_initcall(xenbus_probe_initcall);
-
--static int __init xenbus_probe_init(void)
-+static int __init xenbus_init(void)
+@@ -795,28 +684,45 @@ device_initcall(xenbus_probe_initcall);
+ static int __init xenbus_init(void)
{
int err = 0;
+ unsigned long page = 0;
@@ -27631,30 +26689,19 @@
+
+ xen_store_interface = mfn_to_virt(xen_store_mfn);
} else {
- xenstored_ready = 1;
-- xen_store_evtchn = xen_start_info->store_evtchn;
-- xen_store_mfn = xen_start_info->store_mfn;
-+ if (xen_hvm_domain()) {
-+ uint64_t v = 0;
-+ err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
-+ if (err)
-+ goto out_error;
-+ xen_store_evtchn = (int)v;
-+ err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
-+ if (err)
-+ goto out_error;
-+ xen_store_mfn = (unsigned long)v;
-+ xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
-+ } else {
-+ 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;
+ if (xen_hvm_domain()) {
+ uint64_t v = 0;
+ err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
+@@ -833,7 +739,6 @@ static int __init xenbus_init(void)
+ 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);
/* Initialize the interface to xenstore. */
- err = xs_init();
+@@ -841,7 +746,7 @@ static int __init xenbus_init(void)
if (err) {
printk(KERN_WARNING
"XENBUS: Error initializing xenstore comms: %i\n", err);
@@ -27662,13 +26709,8 @@
+ goto out_error;
}
-- if (!xen_initial_domain())
-- xenbus_probe(NULL);
--
#ifdef CONFIG_XEN_COMPAT_XENFS
- /*
- * Create xenfs mountpoint in /proc for compatibility with
-@@ -829,128 +759,13 @@ static int __init xenbus_probe_init(void)
+@@ -854,131 +759,13 @@ static int __init xenbus_init(void)
return 0;
@@ -27685,8 +26727,7 @@
return err;
}
--postcore_initcall(xenbus_probe_init);
-+postcore_initcall(xenbus_init);
+ postcore_initcall(xenbus_init);
MODULE_LICENSE("GPL");
-
@@ -27794,6 +26835,9 @@
-#ifndef MODULE
-static int __init boot_wait_for_devices(void)
-{
+- if (xen_hvm_domain() && !xen_platform_pci_unplug)
+- return -ENODEV;
+-
- ready_to_wait_for_devices = 1;
- wait_for_devices(NULL);
- return 0;
@@ -29012,7 +28056,7 @@
+ .mmap = privcmd_mmap,
+};
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
-index 6559e0c..229c831 100644
+index 6c16685..229c831 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -12,6 +12,10 @@
@@ -29114,11 +28158,11 @@
}
static int xenfs_get_sb(struct file_system_type *fs_type,
-@@ -63,11 +137,25 @@ static struct file_system_type xenfs_type = {
+@@ -63,16 +137,30 @@ static struct file_system_type xenfs_type = {
static int __init xenfs_init(void)
{
-- if (xen_pv_domain())
+- if (xen_domain())
- return register_filesystem(&xenfs_type);
+ int err;
+ if (!xen_pv_domain()) {
@@ -29144,6 +28188,12 @@
}
static void __exit xenfs_exit(void)
+ {
+- if (xen_domain())
++ if (xen_pv_domain())
+ unregister_filesystem(&xenfs_type);
+ }
+
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index 6c4269b..64b3be4 100644
--- a/drivers/xen/xenfs/xenbus.c
@@ -29334,6 +28384,18 @@
#ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index ca060ce..b6e818f 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -639,7 +639,6 @@
+ EXIT_DATA \
+ EXIT_CALL \
+ *(.discard) \
+- *(.discard.*) \
+ }
+
+ /**
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 7ad3faa..cf9ddce 100644
--- a/include/drm/drmP.h
@@ -29609,17 +28671,6 @@
#endif
#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 67325bf..c398cc3 100644
---- a/include/linux/pci_ids.h
-+++ b/include/linux/pci_ids.h
-@@ -2712,3 +2712,6 @@
- #define PCI_DEVICE_ID_RME_DIGI32 0x9896
- #define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
- #define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
-+
-+#define PCI_VENDOR_ID_XEN 0x5853
-+#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 73b1f1c..113585a 100644
--- a/include/linux/swiotlb.h
@@ -30034,7 +29085,7 @@
+
+#endif /* __XEN_BLKIF_H__ */
diff --git a/include/xen/events.h b/include/xen/events.h
-index e68d59a..7e17e2a 100644
+index a15d932..7e17e2a 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -12,6 +12,8 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
@@ -30059,7 +29110,7 @@
/*
* Common unbind function for all event sources. Takes IRQ to unbind from.
-@@ -53,7 +61,42 @@ bool xen_test_irq_pending(int irq);
+@@ -53,9 +61,37 @@ bool xen_test_irq_pending(int irq);
irq will be disabled so it won't deliver an interrupt. */
void xen_poll_irq(int irq);
@@ -30094,14 +29145,9 @@
+
+/* Determine whether to ignore this IRQ if passed to a guest. */
+int xen_ignore_irq(int irq);
-+/* Xen HVM evtchn vector callback */
-+extern void xen_hvm_callback_vector(void);
-+extern int xen_have_vector_callback;
-+int xen_set_callback_via(uint64_t via);
-+void xen_evtchn_do_upcall(struct pt_regs *regs);
-+void xen_hvm_evtchn_do_upcall(void);
-+
- #endif /* _XEN_EVENTS_H */
+ /* Xen HVM evtchn vector callback */
+ extern void xen_hvm_callback_vector(void);
+ extern int xen_have_vector_callback;
diff --git a/include/xen/gntdev.h b/include/xen/gntdev.h
new file mode 100644
index 0000000..8bd1467
@@ -30228,7 +29274,7 @@
+
+#endif /* __LINUX_PUBLIC_GNTDEV_H__ */
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
-index a40f1cd..871b553 100644
+index 9a73170..871b553 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -37,10 +37,16 @@
@@ -30249,17 +29295,16 @@
/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
#define NR_GRANT_FRAMES 4
-@@ -51,6 +57,9 @@ struct gnttab_free_callback {
+@@ -51,6 +57,8 @@ struct gnttab_free_callback {
u16 count;
};
+void gnttab_reset_grant_page(struct page *page);
+
-+int gnttab_init(void);
+ int gnttab_init(void);
int gnttab_suspend(void);
int gnttab_resume(void);
-
-@@ -80,6 +89,8 @@ unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
+@@ -81,6 +89,8 @@ unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
int gnttab_query_foreign_access(grant_ref_t ref);
@@ -30268,7 +29313,7 @@
/*
* operations on reserved batches of grant references
*/
-@@ -106,12 +117,46 @@ void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
+@@ -107,6 +117,37 @@ void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
unsigned long pfn);
@@ -30306,81 +29351,11 @@
int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
unsigned long max_nr_gframes,
struct grant_entry **__shared);
- void arch_gnttab_unmap_shared(struct grant_entry *shared,
- unsigned long nr_gframes);
-
-+extern unsigned long xen_hvm_resume_frames;
-+unsigned int gnttab_max_grant_frames(void);
-+
- #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
-
- #endif /* __ASM_GNTTAB_H__ */
-diff --git a/include/xen/hvm.h b/include/xen/hvm.h
-new file mode 100644
-index 0000000..b193fa2
---- /dev/null
-+++ b/include/xen/hvm.h
-@@ -0,0 +1,30 @@
-+/* Simple wrappers around HVM functions */
-+#ifndef XEN_HVM_H__
-+#define XEN_HVM_H__
-+
-+#include <xen/interface/hvm/params.h>
-+#include <asm/xen/hypercall.h>
-+
-+static inline int hvm_get_parameter(int idx, uint64_t *value)
-+{
-+ struct xen_hvm_param xhv;
-+ int r;
-+
-+ xhv.domid = DOMID_SELF;
-+ xhv.index = idx;
-+ r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
-+ if (r < 0) {
-+ printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n",
-+ idx, r);
-+ return r;
-+ }
-+ *value = xhv.value;
-+ return r;
-+}
-+
-+#define HVM_CALLBACK_VIA_TYPE_VECTOR 0x2
-+#define HVM_CALLBACK_VIA_TYPE_SHIFT 56
-+#define HVM_CALLBACK_VECTOR(x) (((uint64_t)HVM_CALLBACK_VIA_TYPE_VECTOR)<<\
-+ HVM_CALLBACK_VIA_TYPE_SHIFT | (x))
-+
-+#endif /* XEN_HVM_H__ */
-diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
-index f51b641..70d2563 100644
---- a/include/xen/interface/features.h
-+++ b/include/xen/interface/features.h
-@@ -41,6 +41,12 @@
- /* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
- #define XENFEAT_mmu_pt_update_preserve_ad 5
-
-+/* x86: Does this Xen host support the HVM callback vector type? */
-+#define XENFEAT_hvm_callback_vector 8
-+
-+/* x86: pvclock algorithm is safe to use on HVM */
-+#define XENFEAT_hvm_safe_pvclock 9
-+
- #define XENFEAT_NR_SUBMAPS 1
-
- #endif /* __XEN_PUBLIC_FEATURES_H__ */
diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
-index 39da93c..c704fe5 100644
+index 39e5717..c704fe5 100644
--- a/include/xen/interface/grant_table.h
+++ b/include/xen/interface/grant_table.h
-@@ -28,6 +28,7 @@
- #ifndef __XEN_PUBLIC_GRANT_TABLE_H__
- #define __XEN_PUBLIC_GRANT_TABLE_H__
-
-+#include <xen/interface/xen.h>
-
- /***********************************
- * GRANT TABLE REPRESENTATION
-@@ -321,6 +322,28 @@ struct gnttab_query_size {
+@@ -322,6 +322,28 @@ struct gnttab_query_size {
DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);
/*
@@ -30409,159 +29384,6 @@
* Bitfield values for update_pin_status.flags.
*/
/* Map the grant entry for access by I/O devices. */
-diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h
-new file mode 100644
-index 0000000..a4827f4
---- /dev/null
-+++ b/include/xen/interface/hvm/hvm_op.h
-@@ -0,0 +1,46 @@
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to
-+ * deal in the Software without restriction, including without limitation the
-+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-+ * sell copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ */
-+
-+#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
-+#define __XEN_PUBLIC_HVM_HVM_OP_H__
-+
-+/* Get/set subcommands: the second argument of the hypercall is a
-+ * pointer to a xen_hvm_param struct. */
-+#define HVMOP_set_param 0
-+#define HVMOP_get_param 1
-+struct xen_hvm_param {
-+ domid_t domid; /* IN */
-+ uint32_t index; /* IN */
-+ uint64_t value; /* IN/OUT */
-+};
-+DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_param);
-+
-+/* Hint from PV drivers for pagetable destruction. */
-+#define HVMOP_pagetable_dying 9
-+struct xen_hvm_pagetable_dying {
-+ /* Domain with a pagetable about to be destroyed. */
-+ domid_t domid;
-+ /* guest physical address of the toplevel pagetable dying */
-+ aligned_u64 gpa;
-+};
-+typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t;
-+DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t);
-+
-+#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
-diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h
-new file mode 100644
-index 0000000..1888d8c
---- /dev/null
-+++ b/include/xen/interface/hvm/params.h
-@@ -0,0 +1,95 @@
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to
-+ * deal in the Software without restriction, including without limitation the
-+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-+ * sell copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ */
-+
-+#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
-+#define __XEN_PUBLIC_HVM_PARAMS_H__
-+
-+#include "hvm_op.h"
-+
-+/*
-+ * Parameter space for HVMOP_{set,get}_param.
-+ */
-+
-+/*
-+ * How should CPU0 event-channel notifications be delivered?
-+ * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
-+ * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
-+ * Domain = val[47:32], Bus = val[31:16],
-+ * DevFn = val[15: 8], IntX = val[ 1: 0]
-+ * val[63:56] == 2: val[7:0] is a vector number.
-+ * If val == 0 then CPU0 event-channel notifications are not delivered.
-+ */
-+#define HVM_PARAM_CALLBACK_IRQ 0
-+
-+#define HVM_PARAM_STORE_PFN 1
-+#define HVM_PARAM_STORE_EVTCHN 2
-+
-+#define HVM_PARAM_PAE_ENABLED 4
-+
-+#define HVM_PARAM_IOREQ_PFN 5
-+
-+#define HVM_PARAM_BUFIOREQ_PFN 6
-+
-+/*
-+ * Set mode for virtual timers (currently x86 only):
-+ * delay_for_missed_ticks (default):
-+ * Do not advance a vcpu's time beyond the correct delivery time for
-+ * interrupts that have been missed due to preemption. Deliver missed
-+ * interrupts when the vcpu is rescheduled and advance the vcpu's virtual
-+ * time stepwise for each one.
-+ * no_delay_for_missed_ticks:
-+ * As above, missed interrupts are delivered, but guest time always tracks
-+ * wallclock (i.e., real) time while doing so.
-+ * no_missed_ticks_pending:
-+ * No missed interrupts are held pending. Instead, to ensure ticks are
-+ * delivered at some non-zero rate, if we detect missed ticks then the
-+ * internal tick alarm is not disabled if the VCPU is preempted during the
-+ * next tick period.
-+ * one_missed_tick_pending:
-+ * Missed interrupts are collapsed together and delivered as one 'late tick'.
-+ * Guest time always tracks wallclock (i.e., real) time.
-+ */
-+#define HVM_PARAM_TIMER_MODE 10
-+#define HVMPTM_delay_for_missed_ticks 0
-+#define HVMPTM_no_delay_for_missed_ticks 1
-+#define HVMPTM_no_missed_ticks_pending 2
-+#define HVMPTM_one_missed_tick_pending 3
-+
-+/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
-+#define HVM_PARAM_HPET_ENABLED 11
-+
-+/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
-+#define HVM_PARAM_IDENT_PT 12
-+
-+/* Device Model domain, defaults to 0. */
-+#define HVM_PARAM_DM_DOMAIN 13
-+
-+/* ACPI S state: currently support S0 and S3 on x86. */
-+#define HVM_PARAM_ACPI_S_STATE 14
-+
-+/* TSS used on Intel when CR0.PE=0. */
-+#define HVM_PARAM_VM86_TSS 15
-+
-+/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
-+#define HVM_PARAM_VPT_ALIGN 16
-+
-+#define HVM_NR_PARAMS 17
-+
-+#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h
index 518481c..8309344 100644
--- a/include/xen/interface/io/netif.h
@@ -31895,61 +30717,6 @@
+
+extern void unregister_xen_pcpu_notifier(struct notifier_block *nb);
+#endif
-diff --git a/include/xen/platform_pci.h b/include/xen/platform_pci.h
-new file mode 100644
-index 0000000..ce9d671
---- /dev/null
-+++ b/include/xen/platform_pci.h
-@@ -0,0 +1,49 @@
-+#ifndef _XEN_PLATFORM_PCI_H
-+#define _XEN_PLATFORM_PCI_H
-+
-+#define XEN_IOPORT_MAGIC_VAL 0x49d2
-+#define XEN_IOPORT_LINUX_PRODNUM 0x0003
-+#define XEN_IOPORT_LINUX_DRVVER 0x0001
-+
-+#define XEN_IOPORT_BASE 0x10
-+
-+#define XEN_IOPORT_PLATFLAGS (XEN_IOPORT_BASE + 0) /* 1 byte access (R/W) */
-+#define XEN_IOPORT_MAGIC (XEN_IOPORT_BASE + 0) /* 2 byte access (R) */
-+#define XEN_IOPORT_UNPLUG (XEN_IOPORT_BASE + 0) /* 2 byte access (W) */
-+#define XEN_IOPORT_DRVVER (XEN_IOPORT_BASE + 0) /* 4 byte access (W) */
-+
-+#define XEN_IOPORT_SYSLOG (XEN_IOPORT_BASE + 2) /* 1 byte access (W) */
-+#define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */
-+#define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */
-+
-+#define XEN_UNPLUG_ALL_IDE_DISKS 1
-+#define XEN_UNPLUG_ALL_NICS 2
-+#define XEN_UNPLUG_AUX_IDE_DISKS 4
-+#define XEN_UNPLUG_ALL 7
-+#define XEN_UNPLUG_IGNORE 8
-+
-+static inline int xen_must_unplug_nics(void) {
-+#if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
-+ defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \
-+ (defined(CONFIG_XEN_PLATFORM_PCI) || \
-+ defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
-+ return 1;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static inline int xen_must_unplug_disks(void) {
-+#if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \
-+ defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \
-+ (defined(CONFIG_XEN_PLATFORM_PCI) || \
-+ defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
-+ return 1;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+extern int xen_platform_pci_unplug;
-+
-+#endif /* _XEN_PLATFORM_PCI_H */
diff --git a/include/xen/privcmd.h b/include/xen/privcmd.h
new file mode 100644
index 0000000..b42cdfd
@@ -32037,18 +30804,10 @@
+
+#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
-index 883a21b..7058f8a 100644
+index 46bc81e..7058f8a 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);
-
- void xen_pre_suspend(void);
- void xen_post_suspend(int suspend_cancelled);
-+void xen_hvm_post_suspend(int suspend_cancelled);
-
- void xen_mm_pin_all(void);
- void xen_mm_unpin_all(void);
-@@ -14,4 +15,16 @@ void xen_mm_unpin_all(void);
+@@ -15,6 +15,16 @@ void xen_mm_unpin_all(void);
void xen_timer_resume(void);
void xen_arch_resume(void);
@@ -32062,8 +30821,8 @@
+ unsigned int address_bits);
+
+void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
-+int xen_setup_shutdown_event(void);
-+
+ int xen_setup_shutdown_event(void);
+
#endif /* INCLUDE_XEN_OPS_H */
diff --git a/include/xen/xen.h b/include/xen/xen.h
new file mode 100644
Modified: dists/sid/linux-2.6/debian/patches/series/21
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/21 Fri Aug 20 06:29:20 2010 (r16167)
+++ dists/sid/linux-2.6/debian/patches/series/21 Fri Aug 20 06:29:47 2010 (r16168)
@@ -9,3 +9,18 @@
+ bugfix/x86/drm-i915-Use-RSEN-instead-of-HTPLG-for-tfp410-monito.patch
+ bugfix/x86/i915-fix-ironlake-edp-panel-setup-v4.patch
+ bugfix/all/stable/2.6.32.20-rc1.patch
+
++ features/all/xen/pvhvm/0001-xen-Add-support-for-HVM-hypercalls.patch
++ features/all/xen/pvhvm/0002-x86-early-PV-on-HVM-features-initialization.patch
++ features/all/xen/pvhvm/0003-x86-xen-event-channels-delivery-on-HVM.patch
++ features/all/xen/pvhvm/0004-xen-Xen-PCI-platform-device-driver.patch
++ features/all/xen/pvhvm/0005-xen-Add-suspend-resume-support-for-PV-on-HVM-guests.patch
++ features/all/xen/pvhvm/0006-xen-Fix-find_unbound_irq-in-presence-of-ioapic-irqs.patch
++ features/all/xen/pvhvm/0007-x86-Use-xen_vcpuop_clockevent-xen_clocksource-and.patch
++ features/all/xen/pvhvm/0008-x86-Unplug-emulated-disks-and-nics.patch
++ features/all/xen/pvhvm/0009-x86-Call-HVMOP_pagetable_dying-on-exit_mmap.patch
++ features/all/xen/pvhvm/0010-xenfs-enable-for-HVM-domains-too.patch
++ features/all/xen/pvhvm/0011-support-multiple-.discard.-sections-to-avoid-sectio.patch
++ features/all/xen/pvhvm/0012-blkfront-do-not-create-a-PV-cdrom-device-if-xen_hvm.patch
++ features/all/xen/pvhvm/0013-Introduce-CONFIG_XEN_PVHVM-compile-option.patch
++ features/all/xen/pvhvm/0014-pvops-do-not-notify-callers-from-register_xenstore_.patch
More information about the Kernel-svn-changes
mailing list