[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.