WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 20 May 2008 08:30:49 -0700
Delivery-date: Tue, 20 May 2008 08:32:41 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1210642684 -32400
# Node ID f6fcc65413aee0da4b6b1df03a876342fd526667
# Parent  5d938fac27a2f7365f1cc0b28a0dcbe1af95b727
# Parent  05b7df5cc607bf5b00725232085c35e5b6d493fe
merge with linux-2.6.18-xen.hg
---
 arch/i386/kernel/acpi/Makefile                  |    1 
 arch/i386/kernel/acpi/processor.c               |   11 
 arch/i386/kernel/acpi/processor_extcntl_xen.c   |  142 ++++
 arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c     |   11 
 arch/x86_64/kernel/acpi/Makefile                |    2 
 buildconfigs/linux-defconfig_xen0_x86_32        |    1 
 buildconfigs/linux-defconfig_xen0_x86_64        |    1 
 buildconfigs/linux-defconfig_xen_x86_32         |    1 
 buildconfigs/linux-defconfig_xen_x86_64         |    1 
 drivers/acpi/Kconfig                            |    6 
 drivers/acpi/Makefile                           |    3 
 drivers/acpi/processor_core.c                   |   70 ++
 drivers/acpi/processor_extcntl.c                |  137 ++++
 drivers/acpi/processor_idle.c                   |   44 +
 drivers/acpi/processor_perflib.c                |    5 
 drivers/pci/Kconfig                             |    1 
 drivers/pci/msi-xen.c                           |  709 ++++++++++++++++++++++++
 drivers/pci/msi.h                               |    5 
 drivers/xen/core/evtchn.c                       |    5 
 drivers/xen/pciback/Makefile                    |    1 
 drivers/xen/pciback/conf_space_capability_msi.c |   60 ++
 drivers/xen/pciback/pci_stub.c                  |   24 
 drivers/xen/pciback/pciback.h                   |   14 
 drivers/xen/pciback/pciback_ops.c               |   38 +
 drivers/xen/pcifront/pci_op.c                   |  116 +++
 drivers/xen/privcmd/privcmd.c                   |    2 
 include/acpi/processor.h                        |   97 +++
 include/asm-i386/io_apic.h                      |    2 
 include/asm-x86_64/io_apic.h                    |    2 
 include/asm-x86_64/msi.h                        |    9 
 include/linux/pci.h                             |    3 
 include/xen/evtchn.h                            |   14 
 include/xen/interface/arch-ia64.h               |   59 -
 include/xen/interface/arch-ia64/hvm/memmap.h    |   88 ++
 include/xen/interface/arch-ia64/sioemu.h        |   53 +
 include/xen/interface/arch-x86/xen-x86_32.h     |    7 
 include/xen/interface/domctl.h                  |   23 
 include/xen/interface/hvm/hvm_op.h              |   16 
 include/xen/interface/hvm/params.h              |    8 
 include/xen/interface/io/protocols.h            |    3 
 include/xen/interface/io/xs_wire.h              |    1 
 include/xen/interface/libelf.h                  |    4 
 include/xen/interface/physdev.h                 |   32 +
 include/xen/interface/platform.h                |   65 ++
 include/xen/interface/sysctl.h                  |   11 
 include/xen/interface/xen.h                     |    2 
 include/xen/interface/xsm/acm.h                 |    8 
 47 files changed, 1829 insertions(+), 89 deletions(-)

diff -r 5d938fac27a2 -r f6fcc65413ae arch/i386/kernel/acpi/Makefile
--- a/arch/i386/kernel/acpi/Makefile    Thu Apr 24 14:08:54 2008 -0600
+++ b/arch/i386/kernel/acpi/Makefile    Tue May 13 10:38:04 2008 +0900
@@ -4,6 +4,7 @@ obj-$(CONFIG_ACPI_SLEEP)        += sleep.o wake
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                          += cstate.o processor.o
+obj-$(CONFIG_XEN)              += processor_extcntl_xen.o
 endif
 
 disabled-obj-$(CONFIG_XEN)     := cstate.o wakeup.o
diff -r 5d938fac27a2 -r f6fcc65413ae arch/i386/kernel/acpi/processor.c
--- a/arch/i386/kernel/acpi/processor.c Thu Apr 24 14:08:54 2008 -0600
+++ b/arch/i386/kernel/acpi/processor.c Tue May 13 10:38:04 2008 +0900
@@ -62,7 +62,18 @@ static void init_intel_pdc(struct acpi_p
 /* Initialize _PDC data based on the CPU vendor */
 void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
 {
+#ifdef CONFIG_XEN
+       /* 
+        * As a work-around, just use cpu0's cpuinfo for all processors.
+        * Further work is required to expose xen hypervisor interface of
+        * getting physical cpuinfo to dom0 kernel and then
+        * arch_acpi_processor_init_pdc can set _PDC parameters according
+        * to Xen's phys information.
+        */
+       unsigned int cpu = 0;
+#else
        unsigned int cpu = pr->id;
+#endif /* CONFIG_XEN */
        struct cpuinfo_x86 *c = cpu_data + cpu;
 
        pr->pdc = NULL;
diff -r 5d938fac27a2 -r f6fcc65413ae 
arch/i386/kernel/acpi/processor_extcntl_xen.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/i386/kernel/acpi/processor_extcntl_xen.c     Tue May 13 10:38:04 
2008 +0900
@@ -0,0 +1,142 @@
+/*
+ * processor_extcntl_xen.c - interface to notify Xen
+ *
+ *  Copyright (C) 2008, Intel corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
+
+#include <acpi/processor.h>
+#include <asm/hypercall.h>
+
+static int xen_processor_pmbits;
+static int __init set_xen_processor_pmbits(char *str)
+{
+       get_option(&str, &xen_processor_pmbits);
+
+       return 1;
+}
+__setup("xen_processor_pmbits=", set_xen_processor_pmbits);
+EXPORT_SYMBOL(xen_processor_pmbits);
+
+static int xen_cx_notifier(struct acpi_processor *pr, int action)
+{
+       int ret, count = 0, i;
+       xen_platform_op_t op = {
+               .cmd                    = XENPF_set_processor_pminfo,
+               .interface_version      = XENPF_INTERFACE_VERSION,
+               .u.set_pminfo.id        = pr->acpi_id,
+               .u.set_pminfo.type      = XEN_PM_CX,
+       };
+       struct xen_processor_cx *data, *buf;
+       struct acpi_processor_cx *cx;
+
+       if (action == PROCESSOR_PM_CHANGE)
+               return -EINVAL;
+
+       /* Convert to Xen defined structure and hypercall */
+       buf = kzalloc(pr->power.count * sizeof(struct xen_processor_cx),
+                       GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       data = buf;
+       for (i = 1; i <= pr->power.count; i++) {
+               cx = &pr->power.states[i];
+               /* Skip invalid cstate entry */
+               if (!cx->valid)
+                       continue;
+
+               data->type = cx->type;
+               data->latency = cx->latency;
+               data->power = cx->power;
+               data->reg.space_id = cx->reg.space_id;
+               data->reg.bit_width = cx->reg.bit_width;
+               data->reg.bit_offset = cx->reg.bit_offset;
+               data->reg.access_size = cx->reg.reserved;
+               data->reg.address = cx->reg.address;
+
+               /* Get dependency relationships */
+               if (cx->csd_count) {
+                       printk("Wow! _CSD is found. Not support for now!\n");
+                       kfree(buf);
+                       return -EINVAL;
+               } else {
+                       data->dpcnt = 0;
+                       set_xen_guest_handle(data->dp, NULL);
+               }
+
+               data++;
+               count++;
+       }
+
+       if (!count) {
+               printk("No available Cx info for cpu %d\n", pr->acpi_id);
+               kfree(buf);
+               return -EINVAL;
+       }
+
+       op.u.set_pminfo.power.count = count;
+       op.u.set_pminfo.power.flags.bm_control = pr->flags.bm_control;
+       op.u.set_pminfo.power.flags.bm_check = pr->flags.bm_check;
+       op.u.set_pminfo.power.flags.has_cst = pr->flags.has_cst;
+       op.u.set_pminfo.power.flags.power_setup_done = 
pr->flags.power_setup_done;
+
+       set_xen_guest_handle(op.u.set_pminfo.power.states, buf);
+       ret = HYPERVISOR_platform_op(&op);
+       kfree(buf);
+       return ret;
+}
+
+static int xen_px_notifier(struct acpi_processor *pr, int action)
+{
+       return -EINVAL;
+}
+
+static int xen_tx_notifier(struct acpi_processor *pr, int action)
+{
+       return -EINVAL;
+}
+static int xen_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+       return -EINVAL;
+}
+
+static struct processor_extcntl_ops xen_extcntl_ops = {
+       .hotplug                = xen_hotplug_notifier,
+};
+
+static int __cpuinit xen_init_processor_extcntl(void)
+{
+       if (xen_processor_pmbits & XEN_PROCESSOR_PM_CX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_IDLE] = xen_cx_notifier;
+       if (xen_processor_pmbits & XEN_PROCESSOR_PM_PX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_PERF] = xen_px_notifier;
+       if (xen_processor_pmbits & XEN_PROCESSOR_PM_TX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_THR] = xen_tx_notifier;
+
+       return processor_register_extcntl(&xen_extcntl_ops);
+}
+core_initcall(xen_init_processor_extcntl);
diff -r 5d938fac27a2 -r f6fcc65413ae arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c       Thu Apr 24 14:08:54 
2008 -0600
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c       Tue May 13 10:38:04 
2008 +0900
@@ -568,6 +568,17 @@ acpi_cpufreq_init (void)
 {
        dprintk("acpi_cpufreq_init\n");
 
+#ifdef CONFIG_XEN
+       /*
+        * This effectively blocks in-kernel cpufreq driver to interfere
+        * external control logic
+        */
+       if (processor_pmperf_external()) {
+               printk("CPUFREQ is controllerd externally...exit then!\n");
+               return -1;
+       }
+#endif /* CONFIG_XEN */
+
        acpi_cpufreq_early_init_acpi();
 
        return cpufreq_register_driver(&acpi_cpufreq_driver);
diff -r 5d938fac27a2 -r f6fcc65413ae arch/x86_64/kernel/acpi/Makefile
--- a/arch/x86_64/kernel/acpi/Makefile  Thu Apr 24 14:08:54 2008 -0600
+++ b/arch/x86_64/kernel/acpi/Makefile  Tue May 13 10:38:04 2008 +0900
@@ -8,4 +8,6 @@ processor-$(CONFIG_XEN) := ../../../i386
 processor-$(CONFIG_XEN)        := ../../../i386/kernel/acpi/processor.o
 endif
 
+obj-$(CONFIG_XEN)      += processor_extcnt_xen.o
+processor_extcnt_xen-$(CONFIG_XEN) := 
../../../i386/kernel/acpi/processor_extcntl_xen.o
 disabled-obj-$(CONFIG_XEN) := wakeup.o
diff -r 5d938fac27a2 -r f6fcc65413ae buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32  Thu Apr 24 14:08:54 2008 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_32  Tue May 13 10:38:04 2008 +0900
@@ -248,6 +248,7 @@ CONFIG_XEN_PCIDEV_FRONTEND=y
 CONFIG_XEN_PCIDEV_FRONTEND=y
 # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 # CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_ISA_DMA_API=y
 # CONFIG_SCx200 is not set
diff -r 5d938fac27a2 -r f6fcc65413ae buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64  Thu Apr 24 14:08:54 2008 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_64  Tue May 13 10:38:04 2008 +0900
@@ -204,6 +204,7 @@ CONFIG_XEN_PCIDEV_FRONTEND=y
 CONFIG_XEN_PCIDEV_FRONTEND=y
 # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 # CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
diff -r 5d938fac27a2 -r f6fcc65413ae buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Thu Apr 24 14:08:54 2008 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Tue May 13 10:38:04 2008 +0900
@@ -254,6 +254,7 @@ CONFIG_XEN_PCIDEV_FRONTEND=y
 CONFIG_XEN_PCIDEV_FRONTEND=y
 # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 # CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_ISA_DMA_API=y
 CONFIG_SCx200=m
diff -r 5d938fac27a2 -r f6fcc65413ae buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Thu Apr 24 14:08:54 2008 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Tue May 13 10:38:04 2008 +0900
@@ -209,6 +209,7 @@ CONFIG_XEN_PCIDEV_FRONTEND=y
 CONFIG_XEN_PCIDEV_FRONTEND=y
 # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 # CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig      Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/acpi/Kconfig      Tue May 13 10:38:04 2008 +0900
@@ -367,6 +367,12 @@ config ACPI_PV_SLEEP
        bool
        depends on X86 && XEN && ACPI_SLEEP
        default y
+
+config PROCESSOR_EXTERNAL_CONTROL
+       bool
+       depends on X86 && XEN
+       select ACPI_PROCESSOR
+       default y
 endif  # ACPI
 
 endmenu
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/acpi/Makefile
--- a/drivers/acpi/Makefile     Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/acpi/Makefile     Tue May 13 10:38:04 2008 +0900
@@ -34,6 +34,9 @@ ifdef CONFIG_CPU_FREQ
 ifdef CONFIG_CPU_FREQ
 processor-objs += processor_perflib.o                  
 endif
+ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+processor-objs += processor_extcntl.o
+endif
 
 obj-y                          += sleep/
 obj-y                          += bus.o glue.o
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/acpi/processor_core.c
--- a/drivers/acpi/processor_core.c     Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/acpi/processor_core.c     Tue May 13 10:38:04 2008 +0900
@@ -474,8 +474,14 @@ static int acpi_processor_get_info(struc
         *  they are physically not present.
         */
        if (cpu_index == -1) {
+#ifdef CONFIG_XEN
+               if (ACPI_FAILURE
+                   (acpi_processor_hotadd_init(pr->handle, &pr->id)) &&
+                   !processor_cntl_external()) {
+#else
                if (ACPI_FAILURE
                    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
+#endif /* CONFIG_XEN */
                        printk(KERN_ERR PREFIX
                                    "Getting cpuindex for acpiid 0x%x\n",
                                    pr->acpi_id);
@@ -517,7 +523,11 @@ static int acpi_processor_get_info(struc
        return 0;
 }
 
+#ifdef CONFIG_XEN
+static void *processor_device_array[NR_ACPI_CPUS];
+#else
 static void *processor_device_array[NR_CPUS];
+#endif /* CONFIG_XEN */
 
 static int acpi_processor_start(struct acpi_device *device)
 {
@@ -529,27 +539,48 @@ static int acpi_processor_start(struct a
        pr = acpi_driver_data(device);
 
        result = acpi_processor_get_info(pr);
+#ifdef CONFIG_XEN
+       if (result || 
+           ((pr->id == -1) && !processor_cntl_external())) {
+#else
        if (result) {
+#endif /* CONFIG_XEN */
                /* Processor is physically not present */
                return 0;
        }
 
+#ifdef CONFIG_XEN
+       BUG_ON(!processor_cntl_external() &&
+              ((pr->id >= NR_CPUS) || (pr->id < 0)));
+#else
        BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
+#endif /* CONFIG_XEN */
 
        /*
         * Buggy BIOS check
         * ACPI id of processors can be reported wrongly by the BIOS.
         * Don't trust it blindly
         */
+#ifdef CONFIG_XEN
+       if (processor_device_array[pr->acpi_id] != NULL &&
+           processor_device_array[pr->acpi_id] != (void *)device) {
+#else
        if (processor_device_array[pr->id] != NULL &&
            processor_device_array[pr->id] != (void *)device) {
+#endif /* CONFIG_XEN */
                printk(KERN_WARNING "BIOS reported wrong ACPI id"
                        "for the processor\n");
                return -ENODEV;
        }
+#ifdef CONFIG_XEN
+       processor_device_array[pr->acpi_id] = (void *)device;
+       if (pr->id != -1)
+               processors[pr->id] = pr;
+#else
        processor_device_array[pr->id] = (void *)device;
 
        processors[pr->id] = pr;
+#endif /* CONFIG_XEN */
 
        result = acpi_processor_add_fs(device);
        if (result)
@@ -563,6 +594,10 @@ static int acpi_processor_start(struct a
        acpi_processor_set_pdc(pr);
 
        acpi_processor_power_init(pr, device);
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+       processor_extcntl_init(pr);
+#endif
 
        if (pr->flags.throttling) {
                printk(KERN_INFO PREFIX "%s [%s] (supports",
@@ -656,7 +691,13 @@ static int acpi_processor_remove(struct 
 
        acpi_processor_remove_fs(device);
 
+#ifdef CONFIG_XEN
+       if (pr->id != -1)
+               processors[pr->id] = NULL;
+#else
        processors[pr->id] = NULL;
+#endif /* CONFIG_XEN */
+
 
        kfree(pr);
 
@@ -709,6 +750,12 @@ int acpi_processor_device_add(acpi_handl
        pr = acpi_driver_data(*device);
        if (!pr)
                return -ENODEV;
+
+#ifdef CONFIG_XEN
+       if (processor_cntl_external())
+               processor_notify_external(pr,
+                       PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD);
+#endif /* CONFIG_XEN */
 
        if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
                kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
@@ -747,6 +794,12 @@ acpi_processor_hotplug_notify(acpi_handl
                        printk(KERN_ERR PREFIX "Driver data is NULL\n");
                        break;
                }
+
+#ifdef CONFIG_XEN
+               if (processor_cntl_external())
+                       processor_notify_external(pr,
+                                       PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD);
+#endif /* CONFIG_XEN */
 
                if (pr->id >= 0 && (pr->id < NR_CPUS)) {
                        kobject_uevent(&device->kobj, KOBJ_OFFLINE);
@@ -777,8 +830,20 @@ acpi_processor_hotplug_notify(acpi_handl
                        return;
                }
 
+#ifdef CONFIG_XEN
+               if ((pr->id >= 0) && (pr->id < NR_CPUS)
+                   && (cpu_present(pr->id)))
+#else
                if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
+#endif /* CONFIG_XEN */
                        kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+
+#ifdef CONFIG_XEN
+               if (processor_cntl_external())
+                       processor_notify_external(pr, PROCESSOR_HOTPLUG,
+                                                       HOTPLUG_TYPE_REMOVE);
+#endif /* CONFIG_XEN */
+
                break;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -843,6 +908,11 @@ static acpi_status acpi_processor_hotadd
 
 static int acpi_processor_handle_eject(struct acpi_processor *pr)
 {
+#ifdef CONFIG_XEN
+       if (pr->id == -1)
+               return (0);
+#endif /* CONFIG_XEN */
+
        if (cpu_online(pr->id)) {
                return (-EINVAL);
        }
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/acpi/processor_extcntl.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/acpi/processor_extcntl.c  Tue May 13 10:38:04 2008 +0900
@@ -0,0 +1,137 @@
+/*
+ * processor_extcntl.c - channel to external control logic
+ *
+ *  Copyright (C) 2008, Intel corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
+
+#include <acpi/processor.h>
+
+static int processor_extcntl_parse_csd(struct acpi_processor *pr);
+/*
+ * External processor control logic may register with its own set of
+ * ops to get ACPI related notification. One example is like VMM.
+ */
+struct processor_extcntl_ops *processor_extcntl_ops;
+
+int processor_notify_external(struct acpi_processor *pr, int event, int type)
+{
+       int ret = -EINVAL;
+
+       if (!processor_cntl_external())
+               return -EINVAL;
+
+       switch (event) {
+       case PROCESSOR_PM_INIT:
+       case PROCESSOR_PM_CHANGE:
+               if ((type >= PM_TYPE_MAX) ||
+                       !processor_extcntl_ops->pm_ops[type])
+                       break;
+
+               ret = processor_extcntl_ops->pm_ops[type](pr, event);
+               break;
+       case PROCESSOR_HOTPLUG:
+               if (processor_extcntl_ops->hotplug)
+                       ret = processor_extcntl_ops->hotplug(pr, type);
+               break;
+       default:
+               printk(KERN_ERR "Unsupport processor events %d.\n", event);
+               break;
+       }
+
+       return ret;
+}
+
+/*
+ * External control logic can decide to grab full or part of physical
+ * processor control bits. Take a VMM for example, physical processors
+ * are owned by VMM and thus existence information like hotplug is
+ * always required to be notified to VMM. Similar is processor idle
+ * state which is also necessarily controlled by VMM. But for other
+ * control bits like performance/throttle states, VMM may choose to
+ * control or not upon its own policy.
+ *
+ * Such ownership is unlikely to be switched in the fly, and thus
+ * not sure unregister interface is required or not. Being same reason,
+ * lock is not forced now.
+ */
+int processor_register_extcntl(struct processor_extcntl_ops *ops)
+{
+       if (!ops)
+               return -EINVAL;
+
+       if (processor_extcntl_ops &&
+               (processor_extcntl_ops != ops))
+               return -EBUSY;
+
+       processor_extcntl_ops = ops;
+       return 0;
+}
+
+int processor_unregister_extcntl(struct processor_extcntl_ops *ops)
+{
+       if (processor_extcntl_ops == ops)
+               processor_extcntl_ops = NULL;
+
+       return 0;
+}
+
+/*
+ * This is called from ACPI processor init, and targeted to hold
+ * some tricky housekeeping jobs to satisfy external control model.
+ * For example, we may put dependency parse stub here for idle
+ * and performance state. Those information may be not available
+ * if splitting from dom0 control logic like cpufreq driver.
+ */
+int processor_extcntl_init(struct acpi_processor *pr)
+{
+       /* parse cstate dependency information */
+       processor_extcntl_parse_csd(pr);
+
+       return 0;
+}
+
+/*
+ * Currently no _CSD is implemented which is why existing ACPI code
+ * doesn't parse _CSD at all. But to keep interface complete with
+ * external control logic, we put a placeholder here for future
+ * compatibility.
+ */
+static int processor_extcntl_parse_csd(struct acpi_processor *pr)
+{
+       int i;
+
+       for (i = 0; i < pr->power.count; i++) {
+               if (!pr->power.states[i].valid)
+                       continue;
+
+               /* No dependency by default */
+               pr->power.states[i].domain_info = NULL;
+               pr->power.states[i].csd_count = 0;
+       }
+
+       return 0;
+}
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/acpi/processor_idle.c
--- a/drivers/acpi/processor_idle.c     Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/acpi/processor_idle.c     Tue May 13 10:38:04 2008 +0900
@@ -714,8 +714,17 @@ static int acpi_processor_get_power_info
                    (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
                        continue;
 
+#ifdef CONFIG_XEN
+               if (!processor_pm_external())
+                       cx.address = (reg->space_id ==
+                                     ACPI_ADR_SPACE_FIXED_HARDWARE) ?
+                                     0 : reg->address;
+               else
+                       cx.address = reg->address;
+#else
                cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
                    0 : reg->address;
+#endif /* CONFIG_XEN */
 
                /* There should be an easy way to extract an integer... */
                obj = (union acpi_object *)&(element->package.elements[1]);
@@ -724,9 +733,17 @@ static int acpi_processor_get_power_info
 
                cx.type = obj->integer.value;
 
+#ifdef CONFIG_XEN
+               /* Following check doesn't apply to external control case */
+               if (!processor_pm_external())
+                       if ((cx.type != ACPI_STATE_C1) &&
+                           (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
+                               continue;
+#else
                if ((cx.type != ACPI_STATE_C1) &&
                    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
                        continue;
+#endif /* CONFIG_XEN */
 
                if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
                        continue;
@@ -742,6 +759,12 @@ static int acpi_processor_get_power_info
                        continue;
 
                cx.power = obj->integer.value;
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+               /* cache control methods to notify external logic */
+               if (processor_pm_external())
+                       memcpy(&cx.reg, reg, sizeof(*reg));
+#endif
 
                current_count++;
                memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
@@ -985,12 +1008,24 @@ int acpi_processor_cst_has_changed(struc
                return -ENODEV;
 
        /* Fall back to the default idle loop */
+#ifdef CONFIG_XEN
+       if (!processor_pm_external())
+               pm_idle = pm_idle_save;
+#else
        pm_idle = pm_idle_save;
+#endif /* CONFIG_XEN */
        synchronize_sched();    /* Relies on interrupts forcing exit from idle. 
*/
 
        pr->flags.power = 0;
        result = acpi_processor_get_power_info(pr);
+#ifdef CONFIG_XEN
+       if (processor_pm_external())
+               processor_notify_external(pr,
+                       PROCESSOR_PM_CHANGE, PM_TYPE_IDLE);
+       else if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+#else
        if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+#endif /* CONFIG_XEN */
                pm_idle = acpi_processor_idle;
 
        return result;
@@ -1122,7 +1157,11 @@ int acpi_processor_power_init(struct acp
                                       pr->power.states[i].type);
                printk(")\n");
 
+#ifdef CONFIG_XEN
+               if (!processor_pm_external() && (pr->id == 0)) {
+#else
                if (pr->id == 0) {
+#endif /* CONFIG_XEN */
                        pm_idle_save = pm_idle;
                        pm_idle = acpi_processor_idle;
                }
@@ -1141,6 +1180,11 @@ int acpi_processor_power_init(struct acp
 
        pr->flags.power_setup_done = 1;
 
+#ifdef CONFIG_XEN
+       if (processor_pm_external())
+               processor_notify_external(pr,
+                       PROCESSOR_PM_INIT, PM_TYPE_IDLE);
+#endif /* CONFIG_XEN */
        return 0;
 }
 
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/acpi/processor_perflib.c
--- a/drivers/acpi/processor_perflib.c  Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/acpi/processor_perflib.c  Tue May 13 10:38:04 2008 +0900
@@ -136,6 +136,11 @@ int acpi_processor_ppc_has_changed(struc
        int ret = acpi_processor_get_platform_limit(pr);
        if (ret < 0)
                return (ret);
+#ifdef CONFIG_XEN
+       else if (processor_pmperf_external())
+               return processor_notify_external(pr,
+                               PROCESSOR_PM_CHANGE, PM_TYPE_PERF);
+#endif /* CONFIG_XEN */
        else
                return cpufreq_update_policy(pr->id);
 }
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/pci/Kconfig
--- a/drivers/pci/Kconfig       Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/pci/Kconfig       Tue May 13 10:38:04 2008 +0900
@@ -5,7 +5,6 @@ config PCI_MSI
        bool "Message Signaled Interrupts (MSI and MSI-X)"
        depends on PCI
        depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64
-       depends on !XEN
        help
           This allows device drivers to enable MSI (Message Signaled
           Interrupts).  Message Signaled Interrupts enable a device to
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/pci/msi-xen.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/pci/msi-xen.c     Tue May 13 10:38:04 2008 +0900
@@ -0,0 +1,709 @@
+/*
+ * File:       msi.c
+ * Purpose:    PCI Message Signaled Interrupt (MSI)
+ *
+ * Copyright (C) 2003-2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@xxxxxxxxx)
+ */
+
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/smp_lock.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+
+#include "pci.h"
+#include "msi.h"
+
+static int pci_msi_enable = 1;
+
+static struct msi_ops *msi_ops;
+
+int msi_register(struct msi_ops *ops)
+{
+       msi_ops = ops;
+       return 0;
+}
+
+static struct list_head msi_dev_head;
+static int msi_dev_head_inited = 0;
+DEFINE_SPINLOCK(msi_dev_lock);
+
+struct msi_dev_list {
+       struct pci_dev *dev;
+       struct list_head list;
+       spinlock_t pirq_list_lock;
+       struct list_head pirq_list_head;
+};
+
+struct msi_pirq_entry {
+       struct list_head list;
+       int pirq;
+       int entry_nr;
+};
+
+static struct msi_dev_list *get_msi_dev_pirq_list(struct pci_dev *dev)
+{
+       struct msi_dev_list *msi_dev_list, *ret = NULL;
+       unsigned long flags;
+
+       if (!msi_dev_head_inited) {
+               INIT_LIST_HEAD(&msi_dev_head);
+               msi_dev_head_inited = 1;
+       }
+
+       spin_lock_irqsave(&msi_dev_lock, flags);
+
+       list_for_each_entry(msi_dev_list, &msi_dev_head, list)
+               if ( msi_dev_list->dev == dev )
+                       ret = msi_dev_list;
+
+       if ( ret ) {
+               spin_unlock_irqrestore(&msi_dev_lock, flags);
+               return ret;
+       }
+
+       /* Has not allocate msi_dev until now. */
+       ret = kmalloc(sizeof(struct msi_dev_list), GFP_ATOMIC);
+
+       /* Failed to allocate msi_dev structure */
+       if ( !ret ) {
+               spin_unlock_irqrestore(&msi_dev_lock, flags);
+               return NULL;
+       }
+
+       list_add_tail(&ret->list, &msi_dev_head);
+       spin_unlock_irqrestore(&msi_dev_lock, flags);
+       spin_lock_init(&ret->pirq_list_lock);
+       INIT_LIST_HEAD(&ret->pirq_list_head);
+       return ret;
+}
+
+static int attach_pirq_entry(int pirq, int entry_nr,
+                             struct msi_dev_list *msi_dev_entry)
+{
+       struct msi_pirq_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+       unsigned long flags;
+
+       if (!entry)
+               return -ENOMEM;
+       entry->pirq = pirq;
+       entry->entry_nr = entry_nr;
+       spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
+       list_add_tail(&entry->list, &msi_dev_entry->pirq_list_head);
+       spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+       return 0;
+}
+
+/*
+ * pciback will provide device's owner
+ */
+int (*get_owner)(struct pci_dev *dev);
+
+int register_msi_get_owner(int (*func)(struct pci_dev *dev))
+{
+       if (get_owner) {
+               printk(KERN_WARNING "register msi_get_owner again\n");
+               return -EEXIST;
+       }
+       get_owner = func;
+       return 0;
+}
+
+int unregister_msi_get_owner(int (*func)(struct pci_dev *dev))
+{
+       if (get_owner == func)
+               get_owner = NULL;
+       return 0;
+}
+
+static int msi_get_dev_owner(struct pci_dev *dev)
+{
+       int owner = DOMID_SELF;
+
+       BUG_ON(!is_initial_xendomain());
+       if (get_owner && (owner = get_owner(dev)) >=0 ) {
+               printk(KERN_INFO "get owner for dev %x get %x \n",
+                                   dev->devfn, owner);
+               return owner;
+       }
+       else
+               return DOMID_SELF;
+}
+
+static int msi_unmap_pirq(struct pci_dev *dev, int pirq)
+{
+       struct physdev_unmap_pirq unmap;
+       int rc;
+       domid_t domid = DOMID_SELF;
+
+       domid = msi_get_dev_owner(dev);
+       unmap.domid = domid;
+       unmap.pirq = pirq;
+
+       if ((rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap)))
+               printk(KERN_WARNING "unmap irq %x failed\n", pirq);
+
+       if (rc < 0)
+               return rc;
+    return 0;
+}
+
+/*
+ * Protected by msi_lock
+ */
+static int msi_map_pirq_to_vector(struct pci_dev *dev, int pirq,
+                                  int entry_nr, int msi)
+{
+       struct physdev_map_pirq map_irq;
+       int rc;
+       domid_t domid = DOMID_SELF;
+
+       domid = msi_get_dev_owner(dev);
+
+       map_irq.domid = domid;
+       map_irq.type = MAP_PIRQ_TYPE_MSI;
+       map_irq.index = -1;
+       map_irq.pirq = pirq;
+    map_irq.msi_info.bus = dev->bus->number;
+    map_irq.msi_info.devfn = dev->devfn;
+       map_irq.msi_info.entry_nr = entry_nr;
+    map_irq.msi_info.msi = msi;
+
+       if ((rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq)))
+               printk(KERN_WARNING "map irq failed\n");
+
+       if (rc < 0)
+               return rc;
+
+       return map_irq.pirq;
+}
+
+static int msi_map_vector(struct pci_dev *dev, int entry_nr, int msi)
+{
+       return msi_map_pirq_to_vector(dev, -1, entry_nr, msi);
+}
+
+static int msi_init(void)
+{
+       static int status = 0;
+
+       if (pci_msi_quirk) {
+               pci_msi_enable = 0;
+               printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n");
+               status = -EINVAL;
+       }
+
+       return status;
+}
+
+void pci_scan_msi_device(struct pci_dev *dev) { }
+
+void disable_msi_mode(struct pci_dev *dev, int pos, int type)
+{
+       u16 control;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       if (type == PCI_CAP_ID_MSI) {
+               /* Set enabled bits to single MSI & enable MSI_enable bit */
+               msi_disable(control);
+               pci_write_config_word(dev, msi_control_reg(pos), control);
+               dev->msi_enabled = 0;
+       } else {
+               msix_disable(control);
+               pci_write_config_word(dev, msi_control_reg(pos), control);
+               dev->msix_enabled = 0;
+       }
+       if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
+               /* PCI Express Endpoint device detected */
+               pci_intx(dev, 1);  /* enable intx */
+       }
+}
+
+static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
+{
+       u16 control;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       if (type == PCI_CAP_ID_MSI) {
+               /* Set enabled bits to single MSI & enable MSI_enable bit */
+               msi_enable(control, 1);
+               pci_write_config_word(dev, msi_control_reg(pos), control);
+               dev->msi_enabled = 1;
+       } else {
+               msix_enable(control);
+               pci_write_config_word(dev, msi_control_reg(pos), control);
+               dev->msix_enabled = 1;
+       }
+       if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
+               /* PCI Express Endpoint device detected */
+               pci_intx(dev, 0);  /* disable intx */
+       }
+}
+
+#ifdef CONFIG_PM
+int pci_save_msi_state(struct pci_dev *dev)
+{
+       int pos;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (pos <= 0 || dev->no_msi)
+               return 0;
+
+       if (!dev->msi_enabled)
+               return 0;
+
+       /* Restore dev->irq to its default pin-assertion vector */
+       msi_unmap_pirq(dev, dev->irq);
+       /* Disable MSI mode */
+       disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
+       /* Set the flags for use of restore */
+       dev->msi_enabled = 1;
+       return 0;
+}
+
+void pci_restore_msi_state(struct pci_dev *dev)
+{
+       int pos, pirq;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (pos <= 0)
+               return;
+
+       if (!dev->msi_enabled)
+               return;
+
+       pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 1);
+       if (pirq < 0)
+               return;
+       enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
+}
+
+int pci_save_msix_state(struct pci_dev *dev)
+{
+       int pos;
+       unsigned long flags;
+       struct msi_dev_list *msi_dev_entry;
+       struct msi_pirq_entry *pirq_entry, *tmp;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (pos <= 0 || dev->no_msi)
+               return 0;
+
+       /* save the capability */
+       if (!dev->msix_enabled)
+               return 0;
+
+       msi_dev_entry = get_msi_dev_pirq_list(dev);
+
+       spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
+       if (!list_empty_careful(&msi_dev_entry->pirq_list_head))
+               list_for_each_entry_safe(pirq_entry, tmp,
+                                        &msi_dev_entry->pirq_list_head, list)
+                       msi_unmap_pirq(dev, pirq_entry->pirq);
+       spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+
+       disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
+       /* Set the flags for use of restore */
+       dev->msix_enabled = 1;
+
+       return 0;
+}
+
+void pci_restore_msix_state(struct pci_dev *dev)
+{
+       int pos;
+       unsigned long flags;
+       struct msi_dev_list *msi_dev_entry;
+       struct msi_pirq_entry *pirq_entry, *tmp;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (pos <= 0)
+               return;
+
+       if (!dev->msix_enabled)
+               return;
+
+       msi_dev_entry = get_msi_dev_pirq_list(dev);
+
+       spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
+       list_for_each_entry_safe(pirq_entry, tmp,
+                                                        
&msi_dev_entry->pirq_list_head, list)
+               msi_map_pirq_to_vector(dev, pirq_entry->pirq, 
pirq_entry->entry_nr, 0);
+       spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+
+       enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
+}
+#endif
+
+/**
+ * msi_capability_init - configure device's MSI capability structure
+ * @dev: pointer to the pci_dev data structure of MSI device function
+ *
+ * Setup the MSI capability structure of device function with a single
+ * MSI vector, regardless of device function is capable of handling
+ * multiple messages. A return of zero indicates the successful setup
+ * of an entry zero with the new MSI vector or non-zero for otherwise.
+ **/
+static int msi_capability_init(struct pci_dev *dev)
+{
+       int pos, pirq;
+       u16 control;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+
+       pirq = msi_map_vector(dev, 0, 1);
+       if (pirq < 0)
+               return -EBUSY;
+
+       dev->irq = pirq;
+       /* Set MSI enabled bits  */
+       enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
+       dev->msi_enabled = 1;
+
+       return 0;
+}
+
+/**
+ * msix_capability_init - configure device's MSI-X capability
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ * @entries: pointer to an array of struct msix_entry entries
+ * @nvec: number of @entries
+ *
+ * Setup the MSI-X capability structure of device function with a
+ * single MSI-X vector. A return of zero indicates the successful setup of
+ * requested MSI-X entries with allocated vectors or non-zero for otherwise.
+ **/
+static int msix_capability_init(struct pci_dev *dev,
+                               struct msix_entry *entries, int nvec)
+{
+       int pirq, i, pos;
+       struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
+       struct msi_pirq_entry *pirq_entry, *tmp;
+       unsigned long flags;
+
+       if (!msi_dev_entry)
+               return -ENOMEM;
+
+       spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
+       if (!list_empty_careful(&msi_dev_entry->pirq_list_head))
+       {
+               printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not 
freed \
+                      before acquire again.\n", dev->bus->number, 
PCI_SLOT(dev->devfn),
+                          PCI_FUNC(dev->devfn));
+               list_for_each_entry_safe(pirq_entry, tmp,
+                                        &msi_dev_entry->pirq_list_head, list) {
+                       msi_unmap_pirq(dev, pirq_entry->pirq);
+                       list_del(&pirq_entry->list);
+                       kfree(pirq_entry);
+               }
+       }
+       spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+
+       /* MSI-X Table Initialization */
+       for (i = 0; i < nvec; i++) {
+               pirq = msi_map_vector(dev, entries[i].entry, 0);
+               if (pirq < 0)
+                       break;
+               attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
+               (entries + i)->vector = pirq;
+       }
+       if (i != nvec) {
+               msi_unmap_pirq(dev, dev->irq);
+               (entries + i)->vector = 0;
+               return -EBUSY;
+       }
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
+       dev->msix_enabled = 1;
+
+       return 0;
+}
+
+/**
+ * pci_enable_msi - configure device's MSI capability structure
+ * @dev: pointer to the pci_dev data structure of MSI device function
+ *
+ * Setup the MSI capability structure of device function with
+ * a single MSI vector upon its software driver call to request for
+ * MSI mode enabled on its hardware device function. A return of zero
+ * indicates the successful setup of an entry zero with the new MSI
+ * vector or non-zero for otherwise.
+ **/
+extern int pci_frontend_enable_msi(struct pci_dev *dev);
+int pci_enable_msi(struct pci_dev* dev)
+{
+       struct pci_bus *bus;
+       int pos, temp, status = -EINVAL;
+
+       if (!pci_msi_enable || !dev)
+               return status;
+
+       if (dev->no_msi)
+               return status;
+
+       for (bus = dev->bus; bus; bus = bus->parent)
+               if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+                       return -EINVAL;
+
+       status = msi_init();
+       if (status < 0)
+               return status;
+
+#ifdef CONFIG_XEN_PCIDEV_FRONTEND
+       if (!is_initial_xendomain())
+       {
+               int ret;
+
+               temp = dev->irq;
+               ret = pci_frontend_enable_msi(dev);
+               if (ret)
+                       return ret;
+
+               dev->irq_old = temp;
+
+               return ret;
+       }
+#endif
+
+       temp = dev->irq;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (!pos)
+               return -EINVAL;
+
+       /* Check whether driver already requested for MSI-X vectors */
+       if (dev->msix_enabled) {
+               printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
+                          "Device already has MSI-X vectors assigned\n",
+                          pci_name(dev));
+               dev->irq = temp;
+               return -EINVAL;
+       }
+
+       status = msi_capability_init(dev);
+       if ( !status )
+               dev->irq_old = temp;
+    else
+               dev->irq = temp;
+
+       return status;
+}
+
+extern void pci_frontend_disable_msi(struct pci_dev* dev);
+void pci_disable_msi(struct pci_dev* dev)
+{
+       int pos;
+       int pirq;
+
+       if (!pci_msi_enable)
+               return;
+       if (!dev)
+               return;
+
+#ifdef CONFIG_XEN_PCIDEV_FRONTEND
+       if (!is_initial_xendomain()) {
+               pci_frontend_disable_msi(dev);
+               dev->irq = dev->irq_old;
+               return;
+       }
+#endif
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (!pos)
+               return;
+
+       pirq = dev->irq;
+       /* Restore dev->irq to its default pin-assertion vector */
+       dev->irq = dev->irq_old;
+       msi_unmap_pirq(dev, pirq);
+
+       /* Disable MSI mode */
+       disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
+}
+
+/**
+ * pci_enable_msix - configure device's MSI-X capability structure
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ * @entries: pointer to an array of MSI-X entries
+ * @nvec: number of MSI-X vectors requested for allocation by device driver
+ *
+ * Setup the MSI-X capability structure of device function with the number
+ * of requested vectors upon its software driver call to request for
+ * MSI-X mode enabled on its hardware device function. A return of zero
+ * indicates the successful configuration of MSI-X capability structure
+ * with new allocated MSI-X vectors. A return of < 0 indicates a failure.
+ * Or a return of > 0 indicates that driver request is exceeding the number
+ * of vectors available. Driver should use the returned value to re-send
+ * its request.
+ **/
+extern int pci_frontend_enable_msix(struct pci_dev *dev,
+               struct msix_entry *entries, int nvec);
+int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
+{
+       struct pci_bus *bus;
+       int status, pos, nr_entries;
+       int i, j, temp;
+       u16 control;
+
+       if (!pci_msi_enable || !dev || !entries)
+               return -EINVAL;
+
+       if (dev->no_msi)
+               return -EINVAL;
+
+       for (bus = dev->bus; bus; bus = bus->parent)
+               if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+                       return -EINVAL;
+
+#ifdef CONFIG_XEN_PCIDEV_FRONTEND
+       if (!is_initial_xendomain()) {
+               int ret;
+
+               ret = pci_frontend_enable_msix(dev, entries, nvec);
+               if (ret) {
+                       printk("get %x from pci_frontend_enable_msix\n", ret);
+                       return ret;
+               }
+
+        return 0;
+       }
+#endif
+
+       status = msi_init();
+       if (status < 0)
+               return status;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (!pos)
+               return -EINVAL;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       nr_entries = multi_msix_capable(control);
+       if (nvec > nr_entries)
+               return -EINVAL;
+
+       /* Check for any invalid entries */
+       for (i = 0; i < nvec; i++) {
+               if (entries[i].entry >= nr_entries)
+                       return -EINVAL;         /* invalid entry */
+               for (j = i + 1; j < nvec; j++) {
+                       if (entries[i].entry == entries[j].entry)
+                               return -EINVAL; /* duplicate entry */
+               }
+       }
+
+       temp = dev->irq;
+       /* Check whether driver already requested for MSI vector */
+       if (dev->msi_enabled) {
+               printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
+                      "Device already has an MSI vector assigned\n",
+                      pci_name(dev));
+               dev->irq = temp;
+               return -EINVAL;
+       }
+
+       status = msix_capability_init(dev, entries, nvec);
+
+       if ( !status )
+               dev->irq_old = temp;
+       else
+               dev->irq = temp;
+
+       return status;
+}
+
+extern void pci_frontend_disable_msix(struct pci_dev* dev);
+void pci_disable_msix(struct pci_dev* dev)
+{
+       int pos;
+       u16 control;
+
+
+       if (!pci_msi_enable)
+               return;
+       if (!dev)
+               return;
+
+#ifdef CONFIG_XEN_PCIDEV_FRONTEND
+       if (!is_initial_xendomain()) {
+               pci_frontend_disable_msix(dev);
+               dev->irq = dev->irq_old;
+               return;
+       }
+#endif
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (!pos)
+               return;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       if (!(control & PCI_MSIX_FLAGS_ENABLE))
+               return;
+
+       msi_remove_pci_irq_vectors(dev);
+
+       /* Disable MSI mode */
+       disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
+}
+
+/**
+ * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
+ * @dev: pointer to the pci_dev data structure of MSI(X) device function
+ *
+ * Being called during hotplug remove, from which the device function
+ * is hot-removed. All previous assigned MSI/MSI-X vectors, if
+ * allocated for this device function, are reclaimed to unused state,
+ * which may be used later on.
+ **/
+void msi_remove_pci_irq_vectors(struct pci_dev* dev)
+{
+       unsigned long flags;
+       struct msi_dev_list *msi_dev_entry;
+       struct msi_pirq_entry *pirq_entry, *tmp;
+
+       if (!pci_msi_enable || !dev)
+               return;
+
+       msi_dev_entry = get_msi_dev_pirq_list(dev);
+
+       spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
+       if (!list_empty_careful(&msi_dev_entry->pirq_list_head))
+       {
+               printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not 
freed \
+                      before acquire again.\n", dev->bus->number, 
PCI_SLOT(dev->devfn),
+                          PCI_FUNC(dev->devfn));
+               list_for_each_entry_safe(pirq_entry, tmp,
+                                        &msi_dev_entry->pirq_list_head, list) {
+                       msi_unmap_pirq(dev, pirq_entry->pirq);
+                       list_del(&pirq_entry->list);
+                       kfree(pirq_entry);
+               }
+       }
+       spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+       dev->irq = dev->irq_old;
+}
+
+void pci_no_msi(void)
+{
+       pci_msi_enable = 0;
+}
+
+EXPORT_SYMBOL(pci_enable_msi);
+EXPORT_SYMBOL(pci_disable_msi);
+EXPORT_SYMBOL(pci_enable_msix);
+EXPORT_SYMBOL(pci_disable_msix);
+#ifdef CONFIG_XEN
+EXPORT_SYMBOL(register_msi_get_owner);
+EXPORT_SYMBOL(unregister_msi_get_owner);
+#endif
+
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/pci/msi.h
--- a/drivers/pci/msi.h Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/pci/msi.h Tue May 13 10:38:04 2008 +0900
@@ -84,6 +84,11 @@ extern void (*interrupt[NR_IRQS])(void);
 extern void (*interrupt[NR_IRQS])(void);
 extern int pci_vector_resources(int last, int nr_released);
 
+#ifdef CONFIG_XEN
+extern int unregister_msi_get_owner(int (*func)(struct pci_dev *dev));
+extern int register_msi_get_owner(int (*func)(struct pci_dev *dev));
+#endif
+
 /*
  * MSI-X Address Register
  */
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/core/evtchn.c Tue May 13 10:38:04 2008 +0900
@@ -200,9 +200,6 @@ static inline void exit_idle(void) {}
        (regs)->IRQ_REG = ~(irq);       \
        do_IRQ((regs));                 \
 } while (0)
-#elif defined (__powerpc__)
-#define do_IRQ(irq, regs)      __do_IRQ(irq, regs)
-static inline void exit_idle(void) {}
 #endif
 
 /* Xen will never allocate port zero for any purpose. */
@@ -246,7 +243,7 @@ asmlinkage void evtchn_do_upcall(struct 
 
 #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
                /* Clear master flag /before/ clearing selector flag. */
-               rmb();
+               wmb();
 #endif
                l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
 
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/pciback/Makefile
--- a/drivers/xen/pciback/Makefile      Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/pciback/Makefile      Tue May 13 10:38:04 2008 +0900
@@ -6,6 +6,7 @@ pciback-y += conf_space.o conf_space_hea
             conf_space_capability_vpd.o \
             conf_space_capability_pm.o \
              conf_space_quirks.o
+pciback-$(CONFIG_PCI_MSI) += conf_space_capability_msi.o
 pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
 pciback-$(CONFIG_XEN_PCIDEV_BACKEND_SLOT) += slot.o
 pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
diff -r 5d938fac27a2 -r f6fcc65413ae 
drivers/xen/pciback/conf_space_capability_msi.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/pciback/conf_space_capability_msi.c   Tue May 13 10:38:04 
2008 +0900
@@ -0,0 +1,60 @@
+/*
+ * PCI Backend -- Configuration overlay for MSI capability
+ */
+#include <linux/pci.h>
+#include "conf_space.h"
+#include "conf_space_capability.h"
+#include <xen/interface/io/pciif.h>
+#include "pciback.h"
+
+int pciback_enable_msi(struct pciback_device *pdev,
+               struct pci_dev *dev, struct xen_pci_op *op)
+{
+       int otherend = pdev->xdev->otherend_id;
+       int irq;
+       int status;
+
+       status = pci_enable_msi(dev);
+
+       if (status) {
+               printk("error enable msi for guest %x status %x\n", otherend, 
status);
+               op->value = 0;
+               return XEN_PCI_ERR_op_failed;
+       }
+
+       op->value = dev->irq;
+       return 0;
+}
+
+int pciback_disable_msi(struct pciback_device *pdev,
+               struct pci_dev *dev, struct xen_pci_op *op)
+{
+       int old_irq = dev->irq;
+
+       pci_disable_msi(dev);
+
+       op->value = dev->irq;
+       return 0;
+}
+
+int pciback_enable_msix(struct pciback_device *pdev,
+               struct pci_dev *dev, struct xen_pci_op *op)
+{
+       int otherend = pdev->xdev->otherend_id, result, i;
+
+       result = pci_enable_msix(dev, op->msix_entries, op->value);
+
+       op->value = result;
+       return result;
+}
+
+int pciback_disable_msix(struct pciback_device *pdev,
+               struct pci_dev *dev, struct xen_pci_op *op)
+{
+
+       pci_disable_msix(dev);
+
+       op->value = dev->irq;
+       return 0;
+}
+
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/pciback/pci_stub.c
--- a/drivers/xen/pciback/pci_stub.c    Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/pciback/pci_stub.c    Tue May 13 10:38:04 2008 +0900
@@ -805,6 +805,23 @@ static ssize_t permissive_show(struct de
 
 DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
 
+#ifdef CONFIG_PCI_MSI
+
+int pciback_get_owner(struct pci_dev *dev)
+{
+       struct pcistub_device *psdev;
+
+       psdev = pcistub_device_find(pci_domain_nr(dev->bus), dev->bus->number,
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+       /* XXX will other domain has pciback support ??? */
+       if (!psdev || !psdev->pdev) {
+               printk(KERN_WARNING "no ownder\n");
+               return -1;
+       }
+       return psdev->pdev->xdev->otherend_id;
+}
+#endif
+
 static void pcistub_exit(void)
 {
        driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
@@ -815,6 +832,9 @@ static void pcistub_exit(void)
        driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
 
        pci_unregister_driver(&pciback_pci_driver);
+#ifdef CONFIG_PCI_MSI
+       unregister_msi_get_owner(pciback_get_owner);
+#endif
 }
 
 static int __init pcistub_init(void)
@@ -872,6 +892,10 @@ static int __init pcistub_init(void)
                err = driver_create_file(&pciback_pci_driver.driver,
                                         &driver_attr_permissive);
 
+#ifdef CONFIG_PCI_MSI
+       if (!err)
+               err = register_msi_get_owner(pciback_get_owner);
+#endif
        if (err)
                pcistub_exit();
 
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/pciback/pciback.h
--- a/drivers/xen/pciback/pciback.h     Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/pciback/pciback.h     Tue May 13 10:38:04 2008 +0900
@@ -93,5 +93,19 @@ int pciback_xenbus_register(void);
 int pciback_xenbus_register(void);
 void pciback_xenbus_unregister(void);
 
+#ifdef CONFIG_PCI_MSI
+int pciback_enable_msi(struct pciback_device *pdev,
+                       struct pci_dev *dev, struct xen_pci_op *op);
+
+int pciback_disable_msi(struct pciback_device *pdev,
+                         struct pci_dev *dev, struct xen_pci_op *op);
+
+
+int pciback_enable_msix(struct pciback_device *pdev,
+                        struct pci_dev *dev, struct xen_pci_op *op);
+
+int pciback_disable_msix(struct pciback_device *pdev,
+                        struct pci_dev *dev, struct xen_pci_op *op);
+#endif
 extern int verbose_request;
 #endif
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/pciback/pciback_ops.c
--- a/drivers/xen/pciback/pciback_ops.c Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/pciback/pciback_ops.c Tue May 13 10:38:04 2008 +0900
@@ -61,15 +61,37 @@ void pciback_do_op(void *data)
 
        if (dev == NULL)
                op->err = XEN_PCI_ERR_dev_not_found;
-       else if (op->cmd == XEN_PCI_OP_conf_read)
-               op->err = pciback_config_read(dev, op->offset, op->size,
-                                             &op->value);
-       else if (op->cmd == XEN_PCI_OP_conf_write)
-               op->err = pciback_config_write(dev, op->offset, op->size,
-                                              op->value);
        else
-               op->err = XEN_PCI_ERR_not_implemented;
-
+       {
+               switch (op->cmd)
+               {
+                       case XEN_PCI_OP_conf_read:
+                               op->err = pciback_config_read(dev,
+                                         op->offset, op->size, &op->value);
+                               break;
+                       case XEN_PCI_OP_conf_write:
+                               op->err = pciback_config_write(dev,
+                                         op->offset, op->size, op->value);
+                               break;
+#ifdef CONFIG_PCI_MSI
+                       case XEN_PCI_OP_enable_msi:
+                               op->err = pciback_enable_msi(pdev, dev, op);
+                               break;
+                       case XEN_PCI_OP_disable_msi:
+                               op->err = pciback_disable_msi(pdev, dev, op);
+                               break;
+                       case XEN_PCI_OP_enable_msix:
+                               op->err = pciback_enable_msix(pdev, dev, op);
+                               break;
+                       case XEN_PCI_OP_disable_msix:
+                               op->err = pciback_disable_msix(pdev, dev, op);
+                               break;
+#endif
+                       default:
+                               op->err = XEN_PCI_ERR_not_implemented;
+                               break;
+               }
+       }
        /* Tell the driver domain that we're done. */ 
        wmb();
        clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/pcifront/pci_op.c
--- a/drivers/xen/pcifront/pci_op.c     Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/pcifront/pci_op.c     Tue May 13 10:38:04 2008 +0900
@@ -277,6 +277,122 @@ struct pci_ops pcifront_bus_ops = {
        .write = pcifront_bus_write,
 };
 
+#ifdef CONFIG_PCI_MSI
+int pci_frontend_enable_msix(struct pci_dev *dev,
+               struct msix_entry *entries,
+               int nvec)
+{
+       int err;
+       int i;
+       struct xen_pci_op op = {
+               .cmd    = XEN_PCI_OP_enable_msix,
+               .domain = pci_domain_nr(dev->bus),
+               .bus = dev->bus->number,
+               .devfn = dev->devfn,
+               .value = nvec,
+       };
+       struct pcifront_sd *sd = dev->bus->sysdata;
+       struct pcifront_device *pdev = pcifront_get_pdev(sd);
+
+       if (nvec > SH_INFO_MAX_VEC) {
+               printk("too much vector for pci frontend%x\n", nvec);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < nvec; i++) {
+               op.msix_entries[i].entry = entries[i].entry;
+               op.msix_entries[i].vector = entries[i].vector;
+       }
+
+       err = do_pci_op(pdev, &op);
+
+       if (!err) {
+               if (!op.value) {
+                       /* we get the result */
+                       for ( i = 0; i < nvec; i++)
+                               entries[i].vector = op.msix_entries[i].vector;
+                       return 0;
+               }
+               else {
+            printk("enable msix get value %x\n", op.value);
+                       return op.value;
+               }
+       }
+       else {
+        printk("enable msix get err %x\n", err);
+               return err;
+       }
+}
+
+void pci_frontend_disable_msix(struct pci_dev* dev)
+{
+       int err;
+       struct xen_pci_op op = {
+               .cmd    = XEN_PCI_OP_disable_msix,
+               .domain = pci_domain_nr(dev->bus),
+               .bus = dev->bus->number,
+               .devfn = dev->devfn,
+       };
+       struct pcifront_sd *sd = dev->bus->sysdata;
+       struct pcifront_device *pdev = pcifront_get_pdev(sd);
+
+       err = do_pci_op(pdev, &op);
+
+       /* What should do for error ? */
+       if (err)
+               printk("pci_disable_msix get err %x\n", err);
+}
+
+int pci_frontend_enable_msi(struct pci_dev *dev)
+{
+       int err;
+       struct xen_pci_op op = {
+               .cmd    = XEN_PCI_OP_enable_msi,
+               .domain = pci_domain_nr(dev->bus),
+               .bus = dev->bus->number,
+               .devfn = dev->devfn,
+       };
+       struct pcifront_sd *sd = dev->bus->sysdata;
+       struct pcifront_device *pdev = pcifront_get_pdev(sd);
+
+       err = do_pci_op(pdev, &op);
+       if (likely(!err)) {
+               dev->irq = op.value;
+       }
+       else {
+               printk("pci frontend enable msi failed for dev %x:%x \n",
+                               op.bus, op.devfn);
+               err = -EINVAL;
+       }
+       return err;
+}
+
+void pci_frontend_disable_msi(struct pci_dev* dev)
+{
+       int err;
+       struct xen_pci_op op = {
+               .cmd    = XEN_PCI_OP_disable_msi,
+               .domain = pci_domain_nr(dev->bus),
+               .bus = dev->bus->number,
+               .devfn = dev->devfn,
+       };
+       struct pcifront_sd *sd = dev->bus->sysdata;
+       struct pcifront_device *pdev = pcifront_get_pdev(sd);
+
+       err = do_pci_op(pdev, &op);
+       if (err == XEN_PCI_ERR_dev_not_found) {
+               /* XXX No response from backend, what shall we do? */
+               printk("get no response from backend for disable MSI\n");
+               return;
+       }
+       if (likely(!err))
+               dev->irq = op.value;
+       else
+               /* how can pciback notify us fail? */
+               printk("get fake response frombackend \n");
+}
+#endif /* CONFIG_PCI_MSI */
+
 /* Claim resources for the PCI frontend as-is, backend won't allow changes */
 static void pcifront_claim_resource(struct pci_dev *dev, void *data)
 {
diff -r 5d938fac27a2 -r f6fcc65413ae drivers/xen/privcmd/privcmd.c
--- a/drivers/xen/privcmd/privcmd.c     Thu Apr 24 14:08:54 2008 -0600
+++ b/drivers/xen/privcmd/privcmd.c     Tue May 13 10:38:04 2008 +0900
@@ -229,11 +229,9 @@ static struct vm_operations_struct privc
 
 static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
 {
-#ifndef __powerpc__ /* PowerPC has a trick to safely do this. */
        /* Unsupported for auto-translate guests. */
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return -ENOSYS;
-#endif
 
        /* DONTCOPY is essential for Xen as copy_page_range is broken. */
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
diff -r 5d938fac27a2 -r f6fcc65413ae include/acpi/processor.h
--- a/include/acpi/processor.h  Thu Apr 24 14:08:54 2008 -0600
+++ b/include/acpi/processor.h  Tue May 13 10:38:04 2008 +0900
@@ -20,6 +20,10 @@
 
 #define ACPI_PSD_REV0_REVISION         0 /* Support for _PSD as in ACPI 3.0 */
 #define ACPI_PSD_REV0_ENTRIES          5
+
+#ifdef CONFIG_XEN
+#define NR_ACPI_CPUS                   256
+#endif /* CONFIG_XEN */
 
 /*
  * Types of coordination defined in ACPI 3.0. Same macros can be used across
@@ -32,6 +36,17 @@
 /* Power Management */
 
 struct acpi_processor_cx;
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+struct acpi_csd_package {
+       acpi_integer num_entries;
+       acpi_integer revision;
+       acpi_integer domain;
+       acpi_integer coord_type;
+       acpi_integer num_processors;
+       acpi_integer index;
+} __attribute__ ((packed));
+#endif
 
 struct acpi_power_register {
        u8 descriptor;
@@ -63,6 +78,12 @@ struct acpi_processor_cx {
        u32 power;
        u32 usage;
        u64 time;
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+       /* Require raw information for external control logic */
+       struct acpi_power_register reg;
+       u32 csd_count;
+       struct acpi_csd_package *domain_info;
+#endif
        struct acpi_processor_cx_policy promotion;
        struct acpi_processor_cx_policy demotion;
 };
@@ -275,4 +296,78 @@ static inline void acpi_thermal_cpufreq_
 }
 #endif
 
-#endif
+#ifdef CONFIG_XEN
+/* 
+ * Following are interfaces geared to external processor PM control
+ * logic like a VMM
+ */
+/* Events notified to external control logic */
+#define PROCESSOR_PM_INIT      1
+#define PROCESSOR_PM_CHANGE    2
+#define PROCESSOR_HOTPLUG      3
+
+/* Objects for the PM envents */
+#define PM_TYPE_IDLE           0
+#define PM_TYPE_PERF           1
+#define PM_TYPE_THR            2
+#define PM_TYPE_MAX            3
+
+/* Processor hotplug events */
+#define HOTPLUG_TYPE_ADD       0
+#define HOTPLUG_TYPE_REMOVE    1
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+struct processor_extcntl_ops {
+       /* Transfer processor PM events to external control logic */
+       int (*pm_ops[PM_TYPE_MAX])(struct acpi_processor *pr, int event);
+       /* Notify physical processor status to external control logic */
+       int (*hotplug)(struct acpi_processor *pr, int event);
+};
+extern struct processor_extcntl_ops *processor_extcntl_ops;
+
+static inline int processor_cntl_external(void)
+{
+       return (processor_extcntl_ops != NULL);
+}
+
+static inline int processor_pm_external(void)
+{
+       return processor_cntl_external() &&
+               (processor_extcntl_ops->pm_ops[PM_TYPE_IDLE] != NULL);
+}
+
+static inline int processor_pmperf_external(void)
+{
+       return processor_cntl_external() &&
+               (processor_extcntl_ops->pm_ops[PM_TYPE_PERF] != NULL);
+}
+
+static inline int processor_pmthr_external(void)
+{
+       return processor_cntl_external() &&
+               (processor_extcntl_ops->pm_ops[PM_TYPE_THR] != NULL);
+}
+
+extern int processor_notify_external(struct acpi_processor *pr,
+                       int event, int type);
+extern int processor_register_extcntl(struct processor_extcntl_ops *ops);
+extern int processor_unregister_extcntl(struct processor_extcntl_ops *ops);
+extern int processor_extcntl_init(struct acpi_processor *pr);
+#else
+static inline int processor_cntl_external(void) {return 0;}
+static inline int processor_pm_external(void) {return 0;}
+static inline int processor_pmperf_external(void) {return 0;}
+static inline int processor_pmthr_external(void) {return 0;}
+static inline int processor_notify_external(struct acpi_processor *pr,
+                       int event, int type)
+{
+       return -EINVAL;
+}
+static inline int processor_extcntl_init(struct acpi_processor *pr)
+{
+       return -EINVAL;
+}
+#endif /* CONFIG_PROCESSOR_EXTERNAL_CONTROL */
+#endif /* CONFIG_XEN */
+
+#endif
diff -r 5d938fac27a2 -r f6fcc65413ae include/asm-i386/io_apic.h
--- a/include/asm-i386/io_apic.h        Thu Apr 24 14:08:54 2008 -0600
+++ b/include/asm-i386/io_apic.h        Tue May 13 10:38:04 2008 +0900
@@ -12,7 +12,7 @@
 
 #ifdef CONFIG_X86_IO_APIC
 
-#ifdef CONFIG_PCI_MSI
+#if defined(CONFIG_PCI_MSI) && !defined(CONFIG_XEN)
 static inline int use_pci_vector(void) {return 1;}
 static inline void disable_edge_ioapic_vector(unsigned int vector) { }
 static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
diff -r 5d938fac27a2 -r f6fcc65413ae include/asm-x86_64/io_apic.h
--- a/include/asm-x86_64/io_apic.h      Thu Apr 24 14:08:54 2008 -0600
+++ b/include/asm-x86_64/io_apic.h      Tue May 13 10:38:04 2008 +0900
@@ -12,7 +12,7 @@
 
 #ifdef CONFIG_X86_IO_APIC
 
-#ifdef CONFIG_PCI_MSI
+#if defined(CONFIG_PCI_MSI) && !defined(CONFIG_XEN)
 static inline int use_pci_vector(void) {return 1;}
 static inline void disable_edge_ioapic_vector(unsigned int vector) { }
 static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
diff -r 5d938fac27a2 -r f6fcc65413ae include/asm-x86_64/msi.h
--- a/include/asm-x86_64/msi.h  Thu Apr 24 14:08:54 2008 -0600
+++ b/include/asm-x86_64/msi.h  Tue May 13 10:38:04 2008 +0900
@@ -7,14 +7,21 @@
 #define ASM_MSI_H
 
 #include <asm/desc.h>
+#ifndef CONFIG_XEN
 #include <asm/mach_apic.h>
+#endif
 #include <asm/smp.h>
 
+#ifndef CONFIG_XEN
 #define LAST_DEVICE_VECTOR     (FIRST_SYSTEM_VECTOR - 1)
+#else
+#define LAST_DYNAMIC_VECTOR 0xdf
+#define LAST_DEVICE_VECTOR     (LAST_DYNAMIC_VECTOR)
+#endif
+
 #define MSI_TARGET_CPU_SHIFT   12
 
 extern struct msi_ops msi_apic_ops;
-
 static inline int msi_arch_init(void)
 {
        msi_register(&msi_apic_ops);
diff -r 5d938fac27a2 -r f6fcc65413ae include/linux/pci.h
--- a/include/linux/pci.h       Thu Apr 24 14:08:54 2008 -0600
+++ b/include/linux/pci.h       Tue May 13 10:38:04 2008 +0900
@@ -152,6 +152,9 @@ struct pci_dev {
         * directly, use the values stored here. They might be different!
         */
        unsigned int    irq;
+#ifdef CONFIG_XEN
+       unsigned int    irq_old;
+#endif
        struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory 
regions + expansion ROMs */
 
        /* These fields are used by common fixups */
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/evtchn.h
--- a/include/xen/evtchn.h      Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/evtchn.h      Tue May 13 10:38:04 2008 +0900
@@ -136,4 +136,18 @@ void notify_remote_via_irq(int irq);
 void notify_remote_via_irq(int irq);
 int irq_to_evtchn_port(int irq);
 
+#define PIRQ_SET_MAPPING 0x0
+#define PIRQ_CLEAR_MAPPING 0x1
+#define PIRQ_GET_MAPPING 0x3
+int pirq_mapstatus(int pirq, int action);
+int set_pirq_hw_action(int pirq, int (*action)(int pirq, int action));
+int clear_pirq_hw_action(int pirq);
+
+#define PIRQ_STARTUP 1
+#define PIRQ_SHUTDOWN 2
+#define PIRQ_ENABLE 3
+#define PIRQ_DISABLE 4
+#define PIRQ_END 5
+#define PIRQ_ACK 6
+
 #endif /* __ASM_EVTCHN_H__ */
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/arch-ia64.h
--- a/include/xen/interface/arch-ia64.h Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/arch-ia64.h Tue May 13 10:38:04 2008 +0900
@@ -68,6 +68,10 @@ typedef unsigned long xen_pfn_t;
 /* WARNING: before changing this, check that shared_info fits on a page */
 #define MAX_VIRT_CPUS 64
 
+/* IO ports location for PV.  */
+#define IO_PORTS_PADDR          0x00000ffffc000000UL
+#define IO_PORTS_SIZE           0x0000000004000000UL
+
 #ifndef __ASSEMBLY__
 
 typedef unsigned long xen_ulong_t;
@@ -79,54 +83,6 @@ typedef unsigned long xen_ulong_t;
 #endif
 
 #define INVALID_MFN       (~0UL)
-
-#define MEM_G   (1UL << 30)
-#define MEM_M   (1UL << 20)
-#define MEM_K   (1UL << 10)
-
-/* Guest physical address of IO ports space.  */
-#define IO_PORTS_PADDR          0x00000ffffc000000UL
-#define IO_PORTS_SIZE           0x0000000004000000UL
-
-#define MMIO_START       (3 * MEM_G)
-#define MMIO_SIZE        (512 * MEM_M)
-
-#define VGA_IO_START     0xA0000UL
-#define VGA_IO_SIZE      0x20000
-
-#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
-#define LEGACY_IO_SIZE   (64*MEM_M)
-
-#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
-#define IO_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
-#define STORE_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE)
-#define BUFFER_IO_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
-#define BUFFER_PIO_PAGE_SIZE  XEN_PAGE_SIZE
-
-#define IO_SAPIC_START   0xfec00000UL
-#define IO_SAPIC_SIZE    0x100000
-
-#define PIB_START 0xfee00000UL
-#define PIB_SIZE 0x200000
-
-#define GFW_START        (4*MEM_G -16*MEM_M)
-#define GFW_SIZE         (16*MEM_M)
-
-/* Nvram belongs to GFW memory space  */
-#define NVRAM_SIZE       (MEM_K * 64)
-#define NVRAM_START      (GFW_START + 10 * MEM_M)
-
-#define NVRAM_VALID_SIG 0x4650494e45584948             // "HIXENIPF"
-struct nvram_save_addr {
-    unsigned long addr;
-    unsigned long signature;
-};
 
 struct pt_fpreg {
     union {
@@ -509,6 +465,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
 /* Internal only: associated with PGC_allocated bit */
 #define _ASSIGN_pgc_allocated           3
 #define ASSIGN_pgc_allocated            (1UL << _ASSIGN_pgc_allocated)
+/* Page is an IO page.  */
+#define _ASSIGN_io                      4
+#define ASSIGN_io                       (1UL << _ASSIGN_io)
 
 /* This structure has the same layout of struct ia64_boot_param, defined in
    <asm/system.h>.  It is redefined here to ease use.  */
@@ -644,6 +603,10 @@ DEFINE_XEN_GUEST_HANDLE(pfarg_load_t);
 #endif /* __ASSEMBLY__ */
 #endif /* XEN */
 
+#ifndef __ASSEMBLY__
+#include "arch-ia64/hvm/memmap.h"
+#endif
+
 #endif /* __HYPERVISOR_IF_IA64_H__ */
 
 /*
diff -r 5d938fac27a2 -r f6fcc65413ae 
include/xen/interface/arch-ia64/hvm/memmap.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/include/xen/interface/arch-ia64/hvm/memmap.h      Tue May 13 10:38:04 
2008 +0900
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * memmap.h
+ *
+ * Copyright (c) 2008 Tristan Gingold <tgingold AT free fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
+#define __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
+
+#define MEM_G  (1UL << 30)
+#define MEM_M  (1UL << 20)
+#define MEM_K  (1UL << 10)
+
+/* Guest physical address of IO ports space.  */
+#define MMIO_START  (3 * MEM_G)
+#define MMIO_SIZE   (512 * MEM_M)
+
+#define VGA_IO_START  0xA0000UL
+#define VGA_IO_SIZE   0x20000
+
+#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
+#define LEGACY_IO_SIZE   (64 * MEM_M)
+
+#define IO_PAGE_START  (LEGACY_IO_START + LEGACY_IO_SIZE)
+#define IO_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define STORE_PAGE_START  (IO_PAGE_START + IO_PAGE_SIZE)
+#define STORE_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define BUFFER_IO_PAGE_START  (STORE_PAGE_START + STORE_PAGE_SIZE)
+#define BUFFER_IO_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define BUFFER_PIO_PAGE_START  (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
+#define BUFFER_PIO_PAGE_SIZE   XEN_PAGE_SIZE
+
+#define IO_SAPIC_START  0xfec00000UL
+#define IO_SAPIC_SIZE   0x100000
+
+#define PIB_START  0xfee00000UL
+#define PIB_SIZE   0x200000
+
+#define GFW_START  (4 * MEM_G - 16 * MEM_M)
+#define GFW_SIZE   (16 * MEM_M)
+
+/* domVTI */
+#define GPFN_FRAME_BUFFER  0x1 /* VGA framebuffer */
+#define GPFN_LOW_MMIO      0x2 /* Low MMIO range */
+#define GPFN_PIB           0x3 /* PIB base */
+#define GPFN_IOSAPIC       0x4 /* IOSAPIC base */
+#define GPFN_LEGACY_IO     0x5 /* Legacy I/O base */
+#define GPFN_HIGH_MMIO     0x6 /* High MMIO range */
+
+/* Nvram belongs to GFW memory space  */
+#define NVRAM_SIZE   (MEM_K * 64)
+#define NVRAM_START  (GFW_START + 10 * MEM_M)
+
+#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
+struct nvram_save_addr {
+    unsigned long addr;
+    unsigned long signature;
+};
+
+#endif /* __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/arch-ia64/sioemu.h
--- a/include/xen/interface/arch-ia64/sioemu.h  Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/arch-ia64/sioemu.h  Tue May 13 10:38:04 2008 +0900
@@ -22,6 +22,9 @@
 #ifndef __XEN_PUBLIC_IA64_SIOEMU_H__
 #define __XEN_PUBLIC_IA64_SIOEMU_H__
 
+/* SIOEMU specific hypercalls.
+   The numbers are the minor part of FW_HYPERCALL_SIOEMU.  */
+
 /* Defines the callback entry point.  r8=ip, r9=data.
    Must be called per-vcpu.  */
 #define SIOEMU_HYPERCALL_SET_CALLBACK 0x01
@@ -35,8 +38,52 @@
 /* Get wallclock time.  */
 #define SIOEMU_HYPERCALL_GET_TIME 0x04
 
-/* Return from callback.  r16=0.
-   Unmask vcpu events.  */
-#define SIOEMU_HYPERPRIVOP_CALLBACK_RETURN 0x01
+/* Flush cache.  */
+#define SIOEMU_HYPERCALL_FLUSH_CACHE 0x07
 
+/* Get freq base.  */
+#define SIOEMU_HYPERCALL_FREQ_BASE 0x08
+
+/* Return from callback.  */
+#define SIOEMU_HYPERCALL_CALLBACK_RETURN 0x09
+
+/* Deliver an interrupt.  */
+#define SIOEMU_HYPERCALL_DELIVER_INT 0x0a
+
+/* SIOEMU callback reason.  */
+
+/* An event (from event channel) has to be delivered.  */
+#define SIOEMU_CB_EVENT       0x00
+
+/* Emulate an IO access.  */
+#define SIOEMU_CB_IO_EMULATE  0x01
+
+/* An IPI is sent to a dead vcpu.  */
+#define SIOEMU_CB_WAKEUP_VCPU 0x02
+
+/* A SAL hypercall is executed.  */
+#define SIOEMU_CB_SAL_ASSIST  0x03
+
+#ifndef __ASSEMBLY__
+struct sioemu_callback_info {
+    /* Saved registers.  */
+    unsigned long ip;
+    unsigned long psr;
+    unsigned long ifs;
+    unsigned long nats;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long r11;
+
+    /* Callback parameters.  */
+    unsigned long cause;
+    unsigned long arg0;
+    unsigned long arg1;
+    unsigned long arg2;
+    unsigned long arg3;
+    unsigned long _pad2[2];
+    unsigned long r2;
+};
+#endif /* __ASSEMBLY__ */
 #endif /* __XEN_PUBLIC_IA64_SIOEMU_H__ */
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/arch-x86/xen-x86_32.h
--- a/include/xen/interface/arch-x86/xen-x86_32.h       Thu Apr 24 14:08:54 
2008 -0600
+++ b/include/xen/interface/arch-x86/xen-x86_32.h       Tue May 13 10:38:04 
2008 +0900
@@ -74,6 +74,7 @@
 #define MACH2PHYS_VIRT_END_PAE         \
     mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE)
 
+/* Non-PAE bounds are obsolete. */
 #define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000
 #define __MACH2PHYS_VIRT_START_NONPAE  0xFC000000
 #define __MACH2PHYS_VIRT_END_NONPAE    0xFC400000
@@ -84,15 +85,9 @@
 #define MACH2PHYS_VIRT_END_NONPAE      \
     mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE)
 
-#ifdef CONFIG_X86_PAE
 #define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE
 #define __MACH2PHYS_VIRT_START  __MACH2PHYS_VIRT_START_PAE
 #define __MACH2PHYS_VIRT_END    __MACH2PHYS_VIRT_END_PAE
-#else
-#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_NONPAE
-#define __MACH2PHYS_VIRT_START  __MACH2PHYS_VIRT_START_NONPAE
-#define __MACH2PHYS_VIRT_END    __MACH2PHYS_VIRT_END_NONPAE
-#endif
 
 #ifndef HYPERVISOR_VIRT_START
 #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/domctl.h
--- a/include/xen/interface/domctl.h    Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/domctl.h    Tue May 13 10:38:04 2008 +0900
@@ -454,7 +454,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_assig
 #define XEN_DOMCTL_unbind_pt_irq     48
 typedef enum pt_irq_type_e {
     PT_IRQ_TYPE_PCI,
-    PT_IRQ_TYPE_ISA
+    PT_IRQ_TYPE_ISA,
+    PT_IRQ_TYPE_MSI,
 } pt_irq_type_t;
 struct xen_domctl_bind_pt_irq {
     uint32_t machine_irq;
@@ -470,6 +471,10 @@ struct xen_domctl_bind_pt_irq {
             uint8_t device;
             uint8_t intx;
         } pci;
+        struct {
+            uint8_t gvec;
+            uint32_t gflags;
+        } msi;
     } u;
 };
 typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t;
@@ -571,6 +576,19 @@ typedef struct xen_domctl_set_target xen
 typedef struct xen_domctl_set_target xen_domctl_set_target_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_target_t);
 
+#if defined(__i386__) || defined(__x86_64__)
+# define XEN_CPUID_INPUT_UNUSED  0xFFFFFFFF
+# define XEN_DOMCTL_set_cpuid 49
+struct xen_domctl_cpuid {
+  unsigned int  input[2];
+  unsigned int  eax;
+  unsigned int  ebx;
+  unsigned int  ecx;
+  unsigned int  edx;
+};
+typedef struct xen_domctl_cpuid xen_domctl_cpuid_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_cpuid_t);
+#endif
 
 struct xen_domctl {
     uint32_t cmd;
@@ -609,6 +627,9 @@ struct xen_domctl {
         struct xen_domctl_ext_vcpucontext   ext_vcpucontext;
         struct xen_domctl_set_opt_feature   set_opt_feature;
         struct xen_domctl_set_target        set_target;
+#if defined(__i386__) || defined(__x86_64__)
+        struct xen_domctl_cpuid             cpuid;
+#endif
         uint8_t                             pad[128];
     } u;
 };
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/hvm/hvm_op.h
--- a/include/xen/interface/hvm/hvm_op.h        Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/hvm/hvm_op.h        Tue May 13 10:38:04 2008 +0900
@@ -73,4 +73,20 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_
 /* Flushes all VCPU TLBs: @arg must be NULL. */
 #define HVMOP_flush_tlbs          5
 
+/* Track dirty VRAM. */
+#define HVMOP_track_dirty_vram    6
+struct xen_hvm_track_dirty_vram {
+    /* Domain to be tracked. */
+    domid_t  domid;
+    /* First pfn to track. */
+    uint64_aligned_t first_pfn;
+    /* Number of pages to track. */
+    uint64_aligned_t nr;
+    /* OUT variable. */
+    /* Dirty bitmap buffer. */
+    XEN_GUEST_HANDLE_64(uint8) dirty_bitmap;
+};
+typedef struct xen_hvm_track_dirty_vram xen_hvm_track_dirty_vram_t;
+DEFINE_XEN_GUEST_HANDLE(xen_hvm_track_dirty_vram_t);
+
 #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/hvm/params.h
--- a/include/xen/interface/hvm/params.h        Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/hvm/params.h        Tue May 13 10:38:04 2008 +0900
@@ -84,6 +84,12 @@
 /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
 #define HVM_PARAM_HPET_ENABLED 11
 
-#define HVM_NR_PARAMS          12
+/* 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
+
+#define HVM_NR_PARAMS          14
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/io/protocols.h
--- a/include/xen/interface/io/protocols.h      Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/io/protocols.h      Tue May 13 10:38:04 2008 +0900
@@ -26,7 +26,6 @@
 #define XEN_IO_PROTO_ABI_X86_32     "x86_32-abi"
 #define XEN_IO_PROTO_ABI_X86_64     "x86_64-abi"
 #define XEN_IO_PROTO_ABI_IA64       "ia64-abi"
-#define XEN_IO_PROTO_ABI_POWERPC64  "powerpc64-abi"
 
 #if defined(__i386__)
 # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
@@ -34,8 +33,6 @@
 # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
 #elif defined(__ia64__)
 # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
-#elif defined(__powerpc64__)
-# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
 #else
 # error arch fixup needed here
 #endif
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/io/xs_wire.h
--- a/include/xen/interface/io/xs_wire.h        Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/io/xs_wire.h        Tue May 13 10:38:04 2008 +0900
@@ -61,6 +61,7 @@ struct xsd_errors
     const char *errstring;
 };
 #define XSD_ERROR(x) { x, #x }
+/* LINTED: static unused */
 static struct xsd_errors xsd_errors[]
 #if defined(__GNUC__)
 __attribute__((unused))
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/libelf.h
--- a/include/xen/interface/libelf.h    Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/libelf.h    Tue May 13 10:38:04 2008 +0900
@@ -23,10 +23,8 @@
 #ifndef __XC_LIBELF__
 #define __XC_LIBELF__ 1
 
-#if defined(__i386__) || defined(__x86_64) || defined(__ia64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
 #define XEN_ELF_LITTLE_ENDIAN
-#elif defined(__powerpc__)
-#define XEN_ELF_BIG_ENDIAN
 #else
 #error define architectural endianness
 #endif
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/physdev.h
--- a/include/xen/interface/physdev.h   Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/physdev.h   Tue May 13 10:38:04 2008 +0900
@@ -121,6 +121,38 @@ struct physdev_irq {
 };
 typedef struct physdev_irq physdev_irq_t;
 DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
+ 
+#define MAP_PIRQ_TYPE_MSI               0x0
+#define MAP_PIRQ_TYPE_GSI               0x1
+#define MAP_PIRQ_TYPE_UNKNOWN           0x2
+
+#define PHYSDEVOP_map_pirq               13
+struct physdev_map_pirq {
+    domid_t domid;
+    /* IN */
+    int type;
+    /* IN */
+    int index;
+    /* IN or OUT */
+    int pirq;
+    /* IN */
+    struct {
+        int bus, devfn, entry_nr;
+               int msi;  /* 0 - MSIX    1 - MSI */
+    } msi_info;
+};
+typedef struct physdev_map_pirq physdev_map_pirq_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
+
+#define PHYSDEVOP_unmap_pirq             14
+struct physdev_unmap_pirq {
+    domid_t domid;
+    /* IN */
+    int pirq;
+};
+
+typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
 
 /*
  * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/platform.h
--- a/include/xen/interface/platform.h  Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/platform.h  Tue May 13 10:38:04 2008 +0900
@@ -199,6 +199,70 @@ typedef struct xenpf_getidletime xenpf_g
 typedef struct xenpf_getidletime xenpf_getidletime_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
 
+#define XENPF_set_processor_pminfo      54
+
+/* ability bits */
+#define XEN_PROCESSOR_PM_CX    1
+#define XEN_PROCESSOR_PM_PX    2
+#define XEN_PROCESSOR_PM_TX    4
+
+/* cmd type */
+#define XEN_PM_CX   0
+#define XEN_PM_PX   1
+#define XEN_PM_TX   2
+
+struct xen_power_register {
+    uint32_t     space_id;
+    uint32_t     bit_width;
+    uint32_t     bit_offset;
+    uint32_t     access_size;
+    uint64_t     address;
+};
+
+struct xen_processor_csd {
+    uint32_t    domain;      /* domain number of one dependent group */
+    uint32_t    coord_type;  /* coordination type */
+    uint32_t    num;         /* number of processors in same domain */
+};
+typedef struct xen_processor_csd xen_processor_csd_t;
+DEFINE_XEN_GUEST_HANDLE(xen_processor_csd_t);
+
+struct xen_processor_cx {
+    struct xen_power_register  reg; /* GAS for Cx trigger register */
+    uint8_t     type;     /* cstate value, c0: 0, c1: 1, ... */
+    uint32_t    latency;  /* worst latency (ms) to enter/exit this cstate */
+    uint32_t    power;    /* average power consumption(mW) */
+    uint32_t    dpcnt;    /* number of dependency entries */
+    XEN_GUEST_HANDLE(xen_processor_csd_t) dp; /* NULL if no dependency */
+};
+typedef struct xen_processor_cx xen_processor_cx_t;
+DEFINE_XEN_GUEST_HANDLE(xen_processor_cx_t);
+
+struct xen_processor_flags {
+    uint32_t bm_control:1;
+    uint32_t bm_check:1;
+    uint32_t has_cst:1;
+    uint32_t power_setup_done:1;
+    uint32_t bm_rld_set:1;
+};
+
+struct xen_processor_power {
+    uint32_t count;  /* number of C state entries in array below */
+    struct xen_processor_flags flags;  /* global flags of this processor */
+    XEN_GUEST_HANDLE(xen_processor_cx_t) states; /* supported c states */
+};
+
+struct xenpf_set_processor_pminfo {
+    /* IN variables */
+    uint32_t id;    /* ACPI CPU ID */
+    uint32_t type;  /* {XEN_PM_CX, ...} */
+    union {
+        struct xen_processor_power          power;/* Cx: _CST/_CSD */
+    };
+};
+typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);
+
 struct xen_platform_op {
     uint32_t cmd;
     uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -213,6 +277,7 @@ struct xen_platform_op {
         struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
         struct xenpf_change_freq       change_freq;
         struct xenpf_getidletime       getidletime;
+        struct xenpf_set_processor_pminfo set_pminfo;
         uint8_t                        pad[128];
     } u;
 };
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/sysctl.h
--- a/include/xen/interface/sysctl.h    Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/sysctl.h    Tue May 13 10:38:04 2008 +0900
@@ -84,8 +84,13 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_
  * Get physical information about the host machine
  */
 #define XEN_SYSCTL_physinfo          3
+ /* (x86) The platform supports HVM guests. */
+#define _XEN_SYSCTL_PHYSCAP_hvm          0
+#define XEN_SYSCTL_PHYSCAP_hvm           (1u<<_XEN_SYSCTL_PHYSCAP_hvm)
+ /* (x86) The platform supports HVM-guest direct access to I/O devices. */
+#define _XEN_SYSCTL_PHYSCAP_hvm_directio 1
+#define XEN_SYSCTL_PHYSCAP_hvm_directio  (1u<<_XEN_SYSCTL_PHYSCAP_hvm_directio)
 struct xen_sysctl_physinfo {
-    /* IN variables. */
     uint32_t threads_per_core;
     uint32_t cores_per_socket;
     uint32_t nr_cpus;
@@ -96,7 +101,6 @@ struct xen_sysctl_physinfo {
     uint64_aligned_t scrub_pages;
     uint32_t hw_cap[8];
 
-    /* IN/OUT variables. */
     /*
      * IN: maximum addressable entry in the caller-provided cpu_to_node array.
      * OUT: largest cpu identifier in the system.
@@ -112,6 +116,9 @@ struct xen_sysctl_physinfo {
      * elements of the array will not be written by the sysctl.
      */
     XEN_GUEST_HANDLE_64(uint32) cpu_to_node;
+
+    /* XEN_SYSCTL_PHYSCAP_??? */
+    uint32_t capabilities;
 };
 typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t);
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/xen.h
--- a/include/xen/interface/xen.h       Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/xen.h       Tue May 13 10:38:04 2008 +0900
@@ -33,8 +33,6 @@
 #include "arch-x86/xen.h"
 #elif defined(__ia64__)
 #include "arch-ia64.h"
-#elif defined(__powerpc__)
-#include "arch-powerpc.h"
 #else
 #error "Unsupported architecture"
 #endif
diff -r 5d938fac27a2 -r f6fcc65413ae include/xen/interface/xsm/acm.h
--- a/include/xen/interface/xsm/acm.h   Thu Apr 24 14:08:54 2008 -0600
+++ b/include/xen/interface/xsm/acm.h   Tue May 13 10:38:04 2008 +0900
@@ -91,7 +91,7 @@
  * whenever the interpretation of the related
  * policy's data structure changes
  */
-#define ACM_POLICY_VERSION 3
+#define ACM_POLICY_VERSION 4
 #define ACM_CHWALL_VERSION 1
 #define ACM_STE_VERSION  1
 
@@ -102,6 +102,7 @@ typedef uint32_t ssidref_t;
 #define ACMHOOK_none          0
 #define ACMHOOK_sharing       1
 #define ACMHOOK_authorization 2
+#define ACMHOOK_conflictset   3
 
 /* -------security policy relevant type definitions-------- */
 
@@ -130,6 +131,10 @@ typedef uint16_t domaintype_t;
 /* high-16 = version, low-16 = check magic */
 #define ACM_MAGIC  0x0001debc
 
+/* size of the SHA1 hash identifying the XML policy from which the
+   binary policy was created */
+#define ACM_SHA1_HASH_SIZE    20
+
 /* each offset in bytes from start of the struct they
  * are part of */
 
@@ -159,6 +164,7 @@ struct acm_policy_buffer {
     uint32_t secondary_policy_code;
     uint32_t secondary_buffer_offset;
     struct acm_policy_version xml_pol_version; /* add in V3 */
+    uint8_t xml_policy_hash[ACM_SHA1_HASH_SIZE]; /* added in V4 */
 };
 
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>