[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |