ia64/linux-2.6.18-xen.hg

changeset 542:f6fcc65413ae

merge with linux-2.6.18-xen.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Tue May 13 10:38:04 2008 +0900 (2008-05-13)
parents 5d938fac27a2 05b7df5cc607
children e5933404dada
files
line diff
     1.1 --- a/arch/i386/kernel/acpi/Makefile	Thu Apr 24 14:08:54 2008 -0600
     1.2 +++ b/arch/i386/kernel/acpi/Makefile	Tue May 13 10:38:04 2008 +0900
     1.3 @@ -4,6 +4,7 @@ obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wake
     1.4  
     1.5  ifneq ($(CONFIG_ACPI_PROCESSOR),)
     1.6  obj-y				+= cstate.o processor.o
     1.7 +obj-$(CONFIG_XEN)		+= processor_extcntl_xen.o
     1.8  endif
     1.9  
    1.10  disabled-obj-$(CONFIG_XEN)	:= cstate.o wakeup.o
     2.1 --- a/arch/i386/kernel/acpi/processor.c	Thu Apr 24 14:08:54 2008 -0600
     2.2 +++ b/arch/i386/kernel/acpi/processor.c	Tue May 13 10:38:04 2008 +0900
     2.3 @@ -62,7 +62,18 @@ static void init_intel_pdc(struct acpi_p
     2.4  /* Initialize _PDC data based on the CPU vendor */
     2.5  void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
     2.6  {
     2.7 +#ifdef CONFIG_XEN
     2.8 +	/* 
     2.9 +	 * As a work-around, just use cpu0's cpuinfo for all processors.
    2.10 +	 * Further work is required to expose xen hypervisor interface of
    2.11 +	 * getting physical cpuinfo to dom0 kernel and then
    2.12 +	 * arch_acpi_processor_init_pdc can set _PDC parameters according
    2.13 +	 * to Xen's phys information.
    2.14 +	 */
    2.15 +	unsigned int cpu = 0;
    2.16 +#else
    2.17  	unsigned int cpu = pr->id;
    2.18 +#endif /* CONFIG_XEN */
    2.19  	struct cpuinfo_x86 *c = cpu_data + cpu;
    2.20  
    2.21  	pr->pdc = NULL;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/arch/i386/kernel/acpi/processor_extcntl_xen.c	Tue May 13 10:38:04 2008 +0900
     3.3 @@ -0,0 +1,142 @@
     3.4 +/*
     3.5 + * processor_extcntl_xen.c - interface to notify Xen
     3.6 + *
     3.7 + *  Copyright (C) 2008, Intel corporation
     3.8 + *
     3.9 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    3.10 + *
    3.11 + *  This program is free software; you can redistribute it and/or modify
    3.12 + *  it under the terms of the GNU General Public License as published by
    3.13 + *  the Free Software Foundation; either version 2 of the License, or (at
    3.14 + *  your option) any later version.
    3.15 + *
    3.16 + *  This program is distributed in the hope that it will be useful, but
    3.17 + *  WITHOUT ANY WARRANTY; without even the implied warranty of
    3.18 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.19 + *  General Public License for more details.
    3.20 + *
    3.21 + *  You should have received a copy of the GNU General Public License along
    3.22 + *  with this program; if not, write to the Free Software Foundation, Inc.,
    3.23 + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
    3.24 + *
    3.25 + */
    3.26 +
    3.27 +#include <linux/kernel.h>
    3.28 +#include <linux/init.h>
    3.29 +#include <linux/types.h>
    3.30 +#include <linux/acpi.h>
    3.31 +#include <linux/pm.h>
    3.32 +#include <linux/cpu.h>
    3.33 +
    3.34 +#include <acpi/processor.h>
    3.35 +#include <asm/hypercall.h>
    3.36 +
    3.37 +static int xen_processor_pmbits;
    3.38 +static int __init set_xen_processor_pmbits(char *str)
    3.39 +{
    3.40 +	get_option(&str, &xen_processor_pmbits);
    3.41 +
    3.42 +	return 1;
    3.43 +}
    3.44 +__setup("xen_processor_pmbits=", set_xen_processor_pmbits);
    3.45 +EXPORT_SYMBOL(xen_processor_pmbits);
    3.46 +
    3.47 +static int xen_cx_notifier(struct acpi_processor *pr, int action)
    3.48 +{
    3.49 +	int ret, count = 0, i;
    3.50 +	xen_platform_op_t op = {
    3.51 +		.cmd			= XENPF_set_processor_pminfo,
    3.52 +		.interface_version	= XENPF_INTERFACE_VERSION,
    3.53 +		.u.set_pminfo.id	= pr->acpi_id,
    3.54 +		.u.set_pminfo.type	= XEN_PM_CX,
    3.55 +	};
    3.56 +	struct xen_processor_cx *data, *buf;
    3.57 +	struct acpi_processor_cx *cx;
    3.58 +
    3.59 +	if (action == PROCESSOR_PM_CHANGE)
    3.60 +		return -EINVAL;
    3.61 +
    3.62 +	/* Convert to Xen defined structure and hypercall */
    3.63 +	buf = kzalloc(pr->power.count * sizeof(struct xen_processor_cx),
    3.64 +			GFP_KERNEL);
    3.65 +	if (!buf)
    3.66 +		return -ENOMEM;
    3.67 +
    3.68 +	data = buf;
    3.69 +	for (i = 1; i <= pr->power.count; i++) {
    3.70 +		cx = &pr->power.states[i];
    3.71 +		/* Skip invalid cstate entry */
    3.72 +		if (!cx->valid)
    3.73 +			continue;
    3.74 +
    3.75 +		data->type = cx->type;
    3.76 +		data->latency = cx->latency;
    3.77 +		data->power = cx->power;
    3.78 +		data->reg.space_id = cx->reg.space_id;
    3.79 +		data->reg.bit_width = cx->reg.bit_width;
    3.80 +		data->reg.bit_offset = cx->reg.bit_offset;
    3.81 +		data->reg.access_size = cx->reg.reserved;
    3.82 +		data->reg.address = cx->reg.address;
    3.83 +
    3.84 +		/* Get dependency relationships */
    3.85 +		if (cx->csd_count) {
    3.86 +			printk("Wow! _CSD is found. Not support for now!\n");
    3.87 +			kfree(buf);
    3.88 +			return -EINVAL;
    3.89 +		} else {
    3.90 +			data->dpcnt = 0;
    3.91 +			set_xen_guest_handle(data->dp, NULL);
    3.92 +		}
    3.93 +
    3.94 +		data++;
    3.95 +		count++;
    3.96 +	}
    3.97 +
    3.98 +	if (!count) {
    3.99 +		printk("No available Cx info for cpu %d\n", pr->acpi_id);
   3.100 +		kfree(buf);
   3.101 +		return -EINVAL;
   3.102 +	}
   3.103 +
   3.104 +	op.u.set_pminfo.power.count = count;
   3.105 +	op.u.set_pminfo.power.flags.bm_control = pr->flags.bm_control;
   3.106 +	op.u.set_pminfo.power.flags.bm_check = pr->flags.bm_check;
   3.107 +	op.u.set_pminfo.power.flags.has_cst = pr->flags.has_cst;
   3.108 +	op.u.set_pminfo.power.flags.power_setup_done = pr->flags.power_setup_done;
   3.109 +
   3.110 +	set_xen_guest_handle(op.u.set_pminfo.power.states, buf);
   3.111 +	ret = HYPERVISOR_platform_op(&op);
   3.112 +	kfree(buf);
   3.113 +	return ret;
   3.114 +}
   3.115 +
   3.116 +static int xen_px_notifier(struct acpi_processor *pr, int action)
   3.117 +{
   3.118 +	return -EINVAL;
   3.119 +}
   3.120 +
   3.121 +static int xen_tx_notifier(struct acpi_processor *pr, int action)
   3.122 +{
   3.123 +	return -EINVAL;
   3.124 +}
   3.125 +static int xen_hotplug_notifier(struct acpi_processor *pr, int event)
   3.126 +{
   3.127 +	return -EINVAL;
   3.128 +}
   3.129 +
   3.130 +static struct processor_extcntl_ops xen_extcntl_ops = {
   3.131 +	.hotplug		= xen_hotplug_notifier,
   3.132 +};
   3.133 +
   3.134 +static int __cpuinit xen_init_processor_extcntl(void)
   3.135 +{
   3.136 +	if (xen_processor_pmbits & XEN_PROCESSOR_PM_CX)
   3.137 +		xen_extcntl_ops.pm_ops[PM_TYPE_IDLE] = xen_cx_notifier;
   3.138 +	if (xen_processor_pmbits & XEN_PROCESSOR_PM_PX)
   3.139 +		xen_extcntl_ops.pm_ops[PM_TYPE_PERF] = xen_px_notifier;
   3.140 +	if (xen_processor_pmbits & XEN_PROCESSOR_PM_TX)
   3.141 +		xen_extcntl_ops.pm_ops[PM_TYPE_THR] = xen_tx_notifier;
   3.142 +
   3.143 +	return processor_register_extcntl(&xen_extcntl_ops);
   3.144 +}
   3.145 +core_initcall(xen_init_processor_extcntl);
     4.1 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	Thu Apr 24 14:08:54 2008 -0600
     4.2 +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	Tue May 13 10:38:04 2008 +0900
     4.3 @@ -568,6 +568,17 @@ acpi_cpufreq_init (void)
     4.4  {
     4.5  	dprintk("acpi_cpufreq_init\n");
     4.6  
     4.7 +#ifdef CONFIG_XEN
     4.8 +	/*
     4.9 +	 * This effectively blocks in-kernel cpufreq driver to interfere
    4.10 +	 * external control logic
    4.11 +	 */
    4.12 +	if (processor_pmperf_external()) {
    4.13 +		printk("CPUFREQ is controllerd externally...exit then!\n");
    4.14 +		return -1;
    4.15 +	}
    4.16 +#endif /* CONFIG_XEN */
    4.17 +
    4.18  	acpi_cpufreq_early_init_acpi();
    4.19  
    4.20  	return cpufreq_register_driver(&acpi_cpufreq_driver);
     5.1 --- a/arch/x86_64/kernel/acpi/Makefile	Thu Apr 24 14:08:54 2008 -0600
     5.2 +++ b/arch/x86_64/kernel/acpi/Makefile	Tue May 13 10:38:04 2008 +0900
     5.3 @@ -8,4 +8,6 @@ processor-y		:= ../../../i386/kernel/acp
     5.4  processor-$(CONFIG_XEN)	:= ../../../i386/kernel/acpi/processor.o
     5.5  endif
     5.6  
     5.7 +obj-$(CONFIG_XEN)	+= processor_extcnt_xen.o
     5.8 +processor_extcnt_xen-$(CONFIG_XEN) := ../../../i386/kernel/acpi/processor_extcntl_xen.o
     5.9  disabled-obj-$(CONFIG_XEN) := wakeup.o
     6.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Thu Apr 24 14:08:54 2008 -0600
     6.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Tue May 13 10:38:04 2008 +0900
     6.3 @@ -248,6 +248,7 @@ CONFIG_PCI_MMCONFIG=y
     6.4  CONFIG_XEN_PCIDEV_FRONTEND=y
     6.5  # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
     6.6  # CONFIG_PCIEPORTBUS is not set
     6.7 +# CONFIG_PCI_MSI is not set
     6.8  # CONFIG_PCI_DEBUG is not set
     6.9  CONFIG_ISA_DMA_API=y
    6.10  # CONFIG_SCx200 is not set
     7.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64	Thu Apr 24 14:08:54 2008 -0600
     7.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64	Tue May 13 10:38:04 2008 +0900
     7.3 @@ -204,6 +204,7 @@ CONFIG_PCI_MMCONFIG=y
     7.4  CONFIG_XEN_PCIDEV_FRONTEND=y
     7.5  # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
     7.6  # CONFIG_PCIEPORTBUS is not set
     7.7 +# CONFIG_PCI_MSI is not set
     7.8  # CONFIG_PCI_DEBUG is not set
     7.9  
    7.10  #
     8.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Thu Apr 24 14:08:54 2008 -0600
     8.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Tue May 13 10:38:04 2008 +0900
     8.3 @@ -254,6 +254,7 @@ CONFIG_PCI_MMCONFIG=y
     8.4  CONFIG_XEN_PCIDEV_FRONTEND=y
     8.5  # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
     8.6  # CONFIG_PCIEPORTBUS is not set
     8.7 +# CONFIG_PCI_MSI is not set
     8.8  # CONFIG_PCI_DEBUG is not set
     8.9  CONFIG_ISA_DMA_API=y
    8.10  CONFIG_SCx200=m
     9.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Thu Apr 24 14:08:54 2008 -0600
     9.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Tue May 13 10:38:04 2008 +0900
     9.3 @@ -209,6 +209,7 @@ CONFIG_PCI_DIRECT=y
     9.4  CONFIG_XEN_PCIDEV_FRONTEND=y
     9.5  # CONFIG_XEN_PCIDEV_FE_DEBUG is not set
     9.6  # CONFIG_PCIEPORTBUS is not set
     9.7 +# CONFIG_PCI_MSI is not set
     9.8  # CONFIG_PCI_DEBUG is not set
     9.9  
    9.10  #
    10.1 --- a/drivers/acpi/Kconfig	Thu Apr 24 14:08:54 2008 -0600
    10.2 +++ b/drivers/acpi/Kconfig	Tue May 13 10:38:04 2008 +0900
    10.3 @@ -367,6 +367,12 @@ config ACPI_PV_SLEEP
    10.4  	bool
    10.5  	depends on X86 && XEN && ACPI_SLEEP
    10.6  	default y
    10.7 +
    10.8 +config PROCESSOR_EXTERNAL_CONTROL
    10.9 +	bool
   10.10 +	depends on X86 && XEN
   10.11 +	select ACPI_PROCESSOR
   10.12 +	default y
   10.13  endif	# ACPI
   10.14  
   10.15  endmenu
    11.1 --- a/drivers/acpi/Makefile	Thu Apr 24 14:08:54 2008 -0600
    11.2 +++ b/drivers/acpi/Makefile	Tue May 13 10:38:04 2008 +0900
    11.3 @@ -34,6 +34,9 @@ processor-objs	+= processor_core.o proce
    11.4  ifdef CONFIG_CPU_FREQ
    11.5  processor-objs	+= processor_perflib.o			
    11.6  endif
    11.7 +ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
    11.8 +processor-objs	+= processor_extcntl.o
    11.9 +endif
   11.10  
   11.11  obj-y				+= sleep/
   11.12  obj-y				+= bus.o glue.o
    12.1 --- a/drivers/acpi/processor_core.c	Thu Apr 24 14:08:54 2008 -0600
    12.2 +++ b/drivers/acpi/processor_core.c	Tue May 13 10:38:04 2008 +0900
    12.3 @@ -474,8 +474,14 @@ static int acpi_processor_get_info(struc
    12.4  	 *  they are physically not present.
    12.5  	 */
    12.6  	if (cpu_index == -1) {
    12.7 +#ifdef CONFIG_XEN
    12.8 +		if (ACPI_FAILURE
    12.9 +		    (acpi_processor_hotadd_init(pr->handle, &pr->id)) &&
   12.10 +		    !processor_cntl_external()) {
   12.11 +#else
   12.12  		if (ACPI_FAILURE
   12.13  		    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
   12.14 +#endif /* CONFIG_XEN */
   12.15  			printk(KERN_ERR PREFIX
   12.16  				    "Getting cpuindex for acpiid 0x%x\n",
   12.17  				    pr->acpi_id);
   12.18 @@ -517,7 +523,11 @@ static int acpi_processor_get_info(struc
   12.19  	return 0;
   12.20  }
   12.21  
   12.22 +#ifdef CONFIG_XEN
   12.23 +static void *processor_device_array[NR_ACPI_CPUS];
   12.24 +#else
   12.25  static void *processor_device_array[NR_CPUS];
   12.26 +#endif /* CONFIG_XEN */
   12.27  
   12.28  static int acpi_processor_start(struct acpi_device *device)
   12.29  {
   12.30 @@ -529,27 +539,48 @@ static int acpi_processor_start(struct a
   12.31  	pr = acpi_driver_data(device);
   12.32  
   12.33  	result = acpi_processor_get_info(pr);
   12.34 +#ifdef CONFIG_XEN
   12.35 +	if (result || 
   12.36 +	    ((pr->id == -1) && !processor_cntl_external())) {
   12.37 +#else
   12.38  	if (result) {
   12.39 +#endif /* CONFIG_XEN */
   12.40  		/* Processor is physically not present */
   12.41  		return 0;
   12.42  	}
   12.43  
   12.44 +#ifdef CONFIG_XEN
   12.45 +	BUG_ON(!processor_cntl_external() &&
   12.46 +	       ((pr->id >= NR_CPUS) || (pr->id < 0)));
   12.47 +#else
   12.48  	BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
   12.49 +#endif /* CONFIG_XEN */
   12.50  
   12.51  	/*
   12.52  	 * Buggy BIOS check
   12.53  	 * ACPI id of processors can be reported wrongly by the BIOS.
   12.54  	 * Don't trust it blindly
   12.55  	 */
   12.56 +#ifdef CONFIG_XEN
   12.57 +	if (processor_device_array[pr->acpi_id] != NULL &&
   12.58 +	    processor_device_array[pr->acpi_id] != (void *)device) {
   12.59 +#else
   12.60  	if (processor_device_array[pr->id] != NULL &&
   12.61  	    processor_device_array[pr->id] != (void *)device) {
   12.62 +#endif /* CONFIG_XEN */
   12.63  		printk(KERN_WARNING "BIOS reported wrong ACPI id"
   12.64  			"for the processor\n");
   12.65  		return -ENODEV;
   12.66  	}
   12.67 +#ifdef CONFIG_XEN
   12.68 +	processor_device_array[pr->acpi_id] = (void *)device;
   12.69 +	if (pr->id != -1)
   12.70 +		processors[pr->id] = pr;
   12.71 +#else
   12.72  	processor_device_array[pr->id] = (void *)device;
   12.73  
   12.74  	processors[pr->id] = pr;
   12.75 +#endif /* CONFIG_XEN */
   12.76  
   12.77  	result = acpi_processor_add_fs(device);
   12.78  	if (result)
   12.79 @@ -564,6 +595,10 @@ static int acpi_processor_start(struct a
   12.80  
   12.81  	acpi_processor_power_init(pr, device);
   12.82  
   12.83 +#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
   12.84 +	processor_extcntl_init(pr);
   12.85 +#endif
   12.86 +
   12.87  	if (pr->flags.throttling) {
   12.88  		printk(KERN_INFO PREFIX "%s [%s] (supports",
   12.89  		       acpi_device_name(device), acpi_device_bid(device));
   12.90 @@ -656,7 +691,13 @@ static int acpi_processor_remove(struct 
   12.91  
   12.92  	acpi_processor_remove_fs(device);
   12.93  
   12.94 +#ifdef CONFIG_XEN
   12.95 +	if (pr->id != -1)
   12.96 +		processors[pr->id] = NULL;
   12.97 +#else
   12.98  	processors[pr->id] = NULL;
   12.99 +#endif /* CONFIG_XEN */
  12.100 +
  12.101  
  12.102  	kfree(pr);
  12.103  
  12.104 @@ -710,6 +751,12 @@ int acpi_processor_device_add(acpi_handl
  12.105  	if (!pr)
  12.106  		return -ENODEV;
  12.107  
  12.108 +#ifdef CONFIG_XEN
  12.109 +	if (processor_cntl_external())
  12.110 +		processor_notify_external(pr,
  12.111 +			PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD);
  12.112 +#endif /* CONFIG_XEN */
  12.113 +
  12.114  	if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
  12.115  		kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
  12.116  	}
  12.117 @@ -748,6 +795,12 @@ acpi_processor_hotplug_notify(acpi_handl
  12.118  			break;
  12.119  		}
  12.120  
  12.121 +#ifdef CONFIG_XEN
  12.122 +		if (processor_cntl_external())
  12.123 +			processor_notify_external(pr,
  12.124 +					PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD);
  12.125 +#endif /* CONFIG_XEN */
  12.126 +
  12.127  		if (pr->id >= 0 && (pr->id < NR_CPUS)) {
  12.128  			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
  12.129  			break;
  12.130 @@ -777,8 +830,20 @@ acpi_processor_hotplug_notify(acpi_handl
  12.131  			return;
  12.132  		}
  12.133  
  12.134 +#ifdef CONFIG_XEN
  12.135 +		if ((pr->id >= 0) && (pr->id < NR_CPUS)
  12.136 +		    && (cpu_present(pr->id)))
  12.137 +#else
  12.138  		if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
  12.139 +#endif /* CONFIG_XEN */
  12.140  			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
  12.141 +
  12.142 +#ifdef CONFIG_XEN
  12.143 +		if (processor_cntl_external())
  12.144 +			processor_notify_external(pr, PROCESSOR_HOTPLUG,
  12.145 +							HOTPLUG_TYPE_REMOVE);
  12.146 +#endif /* CONFIG_XEN */
  12.147 +
  12.148  		break;
  12.149  	default:
  12.150  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  12.151 @@ -843,6 +908,11 @@ static acpi_status acpi_processor_hotadd
  12.152  
  12.153  static int acpi_processor_handle_eject(struct acpi_processor *pr)
  12.154  {
  12.155 +#ifdef CONFIG_XEN
  12.156 +	if (pr->id == -1)
  12.157 +		return (0);
  12.158 +#endif /* CONFIG_XEN */
  12.159 +
  12.160  	if (cpu_online(pr->id)) {
  12.161  		return (-EINVAL);
  12.162  	}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/drivers/acpi/processor_extcntl.c	Tue May 13 10:38:04 2008 +0900
    13.3 @@ -0,0 +1,137 @@
    13.4 +/*
    13.5 + * processor_extcntl.c - channel to external control logic
    13.6 + *
    13.7 + *  Copyright (C) 2008, Intel corporation
    13.8 + *
    13.9 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   13.10 + *
   13.11 + *  This program is free software; you can redistribute it and/or modify
   13.12 + *  it under the terms of the GNU General Public License as published by
   13.13 + *  the Free Software Foundation; either version 2 of the License, or (at
   13.14 + *  your option) any later version.
   13.15 + *
   13.16 + *  This program is distributed in the hope that it will be useful, but
   13.17 + *  WITHOUT ANY WARRANTY; without even the implied warranty of
   13.18 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.19 + *  General Public License for more details.
   13.20 + *
   13.21 + *  You should have received a copy of the GNU General Public License along
   13.22 + *  with this program; if not, write to the Free Software Foundation, Inc.,
   13.23 + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
   13.24 + *
   13.25 + */
   13.26 +
   13.27 +#include <linux/kernel.h>
   13.28 +#include <linux/init.h>
   13.29 +#include <linux/types.h>
   13.30 +#include <linux/acpi.h>
   13.31 +#include <linux/pm.h>
   13.32 +#include <linux/cpu.h>
   13.33 +
   13.34 +#include <acpi/processor.h>
   13.35 +
   13.36 +static int processor_extcntl_parse_csd(struct acpi_processor *pr);
   13.37 +/*
   13.38 + * External processor control logic may register with its own set of
   13.39 + * ops to get ACPI related notification. One example is like VMM.
   13.40 + */
   13.41 +struct processor_extcntl_ops *processor_extcntl_ops;
   13.42 +
   13.43 +int processor_notify_external(struct acpi_processor *pr, int event, int type)
   13.44 +{
   13.45 +	int ret = -EINVAL;
   13.46 +
   13.47 +	if (!processor_cntl_external())
   13.48 +		return -EINVAL;
   13.49 +
   13.50 +	switch (event) {
   13.51 +	case PROCESSOR_PM_INIT:
   13.52 +	case PROCESSOR_PM_CHANGE:
   13.53 +		if ((type >= PM_TYPE_MAX) ||
   13.54 +			!processor_extcntl_ops->pm_ops[type])
   13.55 +			break;
   13.56 +
   13.57 +		ret = processor_extcntl_ops->pm_ops[type](pr, event);
   13.58 +		break;
   13.59 +	case PROCESSOR_HOTPLUG:
   13.60 +		if (processor_extcntl_ops->hotplug)
   13.61 +			ret = processor_extcntl_ops->hotplug(pr, type);
   13.62 +		break;
   13.63 +	default:
   13.64 +		printk(KERN_ERR "Unsupport processor events %d.\n", event);
   13.65 +		break;
   13.66 +	}
   13.67 +
   13.68 +	return ret;
   13.69 +}
   13.70 +
   13.71 +/*
   13.72 + * External control logic can decide to grab full or part of physical
   13.73 + * processor control bits. Take a VMM for example, physical processors
   13.74 + * are owned by VMM and thus existence information like hotplug is
   13.75 + * always required to be notified to VMM. Similar is processor idle
   13.76 + * state which is also necessarily controlled by VMM. But for other
   13.77 + * control bits like performance/throttle states, VMM may choose to
   13.78 + * control or not upon its own policy.
   13.79 + *
   13.80 + * Such ownership is unlikely to be switched in the fly, and thus
   13.81 + * not sure unregister interface is required or not. Being same reason,
   13.82 + * lock is not forced now.
   13.83 + */
   13.84 +int processor_register_extcntl(struct processor_extcntl_ops *ops)
   13.85 +{
   13.86 +	if (!ops)
   13.87 +		return -EINVAL;
   13.88 +
   13.89 +	if (processor_extcntl_ops &&
   13.90 +		(processor_extcntl_ops != ops))
   13.91 +		return -EBUSY;
   13.92 +
   13.93 +	processor_extcntl_ops = ops;
   13.94 +	return 0;
   13.95 +}
   13.96 +
   13.97 +int processor_unregister_extcntl(struct processor_extcntl_ops *ops)
   13.98 +{
   13.99 +	if (processor_extcntl_ops == ops)
  13.100 +		processor_extcntl_ops = NULL;
  13.101 +
  13.102 +	return 0;
  13.103 +}
  13.104 +
  13.105 +/*
  13.106 + * This is called from ACPI processor init, and targeted to hold
  13.107 + * some tricky housekeeping jobs to satisfy external control model.
  13.108 + * For example, we may put dependency parse stub here for idle
  13.109 + * and performance state. Those information may be not available
  13.110 + * if splitting from dom0 control logic like cpufreq driver.
  13.111 + */
  13.112 +int processor_extcntl_init(struct acpi_processor *pr)
  13.113 +{
  13.114 +	/* parse cstate dependency information */
  13.115 +	processor_extcntl_parse_csd(pr);
  13.116 +
  13.117 +	return 0;
  13.118 +}
  13.119 +
  13.120 +/*
  13.121 + * Currently no _CSD is implemented which is why existing ACPI code
  13.122 + * doesn't parse _CSD at all. But to keep interface complete with
  13.123 + * external control logic, we put a placeholder here for future
  13.124 + * compatibility.
  13.125 + */
  13.126 +static int processor_extcntl_parse_csd(struct acpi_processor *pr)
  13.127 +{
  13.128 +	int i;
  13.129 +
  13.130 +	for (i = 0; i < pr->power.count; i++) {
  13.131 +		if (!pr->power.states[i].valid)
  13.132 +			continue;
  13.133 +
  13.134 +		/* No dependency by default */
  13.135 +		pr->power.states[i].domain_info = NULL;
  13.136 +		pr->power.states[i].csd_count = 0;
  13.137 +	}
  13.138 +
  13.139 +	return 0;
  13.140 +}
    14.1 --- a/drivers/acpi/processor_idle.c	Thu Apr 24 14:08:54 2008 -0600
    14.2 +++ b/drivers/acpi/processor_idle.c	Tue May 13 10:38:04 2008 +0900
    14.3 @@ -714,8 +714,17 @@ static int acpi_processor_get_power_info
    14.4  		    (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
    14.5  			continue;
    14.6  
    14.7 +#ifdef CONFIG_XEN
    14.8 +		if (!processor_pm_external())
    14.9 +			cx.address = (reg->space_id ==
   14.10 +				      ACPI_ADR_SPACE_FIXED_HARDWARE) ?
   14.11 +		    		      0 : reg->address;
   14.12 +		else
   14.13 +			cx.address = reg->address;
   14.14 +#else
   14.15  		cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
   14.16  		    0 : reg->address;
   14.17 +#endif /* CONFIG_XEN */
   14.18  
   14.19  		/* There should be an easy way to extract an integer... */
   14.20  		obj = (union acpi_object *)&(element->package.elements[1]);
   14.21 @@ -724,9 +733,17 @@ static int acpi_processor_get_power_info
   14.22  
   14.23  		cx.type = obj->integer.value;
   14.24  
   14.25 +#ifdef CONFIG_XEN
   14.26 +		/* Following check doesn't apply to external control case */
   14.27 +		if (!processor_pm_external())
   14.28 +			if ((cx.type != ACPI_STATE_C1) &&
   14.29 +			    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
   14.30 +				continue;
   14.31 +#else
   14.32  		if ((cx.type != ACPI_STATE_C1) &&
   14.33  		    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
   14.34  			continue;
   14.35 +#endif /* CONFIG_XEN */
   14.36  
   14.37  		if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
   14.38  			continue;
   14.39 @@ -743,6 +760,12 @@ static int acpi_processor_get_power_info
   14.40  
   14.41  		cx.power = obj->integer.value;
   14.42  
   14.43 +#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
   14.44 +		/* cache control methods to notify external logic */
   14.45 +		if (processor_pm_external())
   14.46 +			memcpy(&cx.reg, reg, sizeof(*reg));
   14.47 +#endif
   14.48 +
   14.49  		current_count++;
   14.50  		memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
   14.51  
   14.52 @@ -985,12 +1008,24 @@ int acpi_processor_cst_has_changed(struc
   14.53  		return -ENODEV;
   14.54  
   14.55  	/* Fall back to the default idle loop */
   14.56 +#ifdef CONFIG_XEN
   14.57 +	if (!processor_pm_external())
   14.58 +		pm_idle = pm_idle_save;
   14.59 +#else
   14.60  	pm_idle = pm_idle_save;
   14.61 +#endif /* CONFIG_XEN */
   14.62  	synchronize_sched();	/* Relies on interrupts forcing exit from idle. */
   14.63  
   14.64  	pr->flags.power = 0;
   14.65  	result = acpi_processor_get_power_info(pr);
   14.66 +#ifdef CONFIG_XEN
   14.67 +	if (processor_pm_external())
   14.68 +		processor_notify_external(pr,
   14.69 +			PROCESSOR_PM_CHANGE, PM_TYPE_IDLE);
   14.70 +	else if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
   14.71 +#else
   14.72  	if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
   14.73 +#endif /* CONFIG_XEN */
   14.74  		pm_idle = acpi_processor_idle;
   14.75  
   14.76  	return result;
   14.77 @@ -1122,7 +1157,11 @@ int acpi_processor_power_init(struct acp
   14.78  				       pr->power.states[i].type);
   14.79  		printk(")\n");
   14.80  
   14.81 +#ifdef CONFIG_XEN
   14.82 +		if (!processor_pm_external() && (pr->id == 0)) {
   14.83 +#else
   14.84  		if (pr->id == 0) {
   14.85 +#endif /* CONFIG_XEN */
   14.86  			pm_idle_save = pm_idle;
   14.87  			pm_idle = acpi_processor_idle;
   14.88  		}
   14.89 @@ -1141,6 +1180,11 @@ int acpi_processor_power_init(struct acp
   14.90  
   14.91  	pr->flags.power_setup_done = 1;
   14.92  
   14.93 +#ifdef CONFIG_XEN
   14.94 +	if (processor_pm_external())
   14.95 +		processor_notify_external(pr,
   14.96 +			PROCESSOR_PM_INIT, PM_TYPE_IDLE);
   14.97 +#endif /* CONFIG_XEN */
   14.98  	return 0;
   14.99  }
  14.100  
    15.1 --- a/drivers/acpi/processor_perflib.c	Thu Apr 24 14:08:54 2008 -0600
    15.2 +++ b/drivers/acpi/processor_perflib.c	Tue May 13 10:38:04 2008 +0900
    15.3 @@ -136,6 +136,11 @@ int acpi_processor_ppc_has_changed(struc
    15.4  	int ret = acpi_processor_get_platform_limit(pr);
    15.5  	if (ret < 0)
    15.6  		return (ret);
    15.7 +#ifdef CONFIG_XEN
    15.8 +	else if (processor_pmperf_external())
    15.9 +		return processor_notify_external(pr,
   15.10 +				PROCESSOR_PM_CHANGE, PM_TYPE_PERF);
   15.11 +#endif /* CONFIG_XEN */
   15.12  	else
   15.13  		return cpufreq_update_policy(pr->id);
   15.14  }
    16.1 --- a/drivers/pci/Kconfig	Thu Apr 24 14:08:54 2008 -0600
    16.2 +++ b/drivers/pci/Kconfig	Tue May 13 10:38:04 2008 +0900
    16.3 @@ -5,7 +5,6 @@ config PCI_MSI
    16.4  	bool "Message Signaled Interrupts (MSI and MSI-X)"
    16.5  	depends on PCI
    16.6  	depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64
    16.7 -	depends on !XEN
    16.8  	help
    16.9  	   This allows device drivers to enable MSI (Message Signaled
   16.10  	   Interrupts).  Message Signaled Interrupts enable a device to
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/drivers/pci/msi-xen.c	Tue May 13 10:38:04 2008 +0900
    17.3 @@ -0,0 +1,709 @@
    17.4 +/*
    17.5 + * File:	msi.c
    17.6 + * Purpose:	PCI Message Signaled Interrupt (MSI)
    17.7 + *
    17.8 + * Copyright (C) 2003-2004 Intel
    17.9 + * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
   17.10 + */
   17.11 +
   17.12 +#include <linux/mm.h>
   17.13 +#include <linux/irq.h>
   17.14 +#include <linux/interrupt.h>
   17.15 +#include <linux/init.h>
   17.16 +#include <linux/ioport.h>
   17.17 +#include <linux/smp_lock.h>
   17.18 +#include <linux/pci.h>
   17.19 +#include <linux/proc_fs.h>
   17.20 +
   17.21 +#include <asm/errno.h>
   17.22 +#include <asm/io.h>
   17.23 +#include <asm/smp.h>
   17.24 +
   17.25 +#include "pci.h"
   17.26 +#include "msi.h"
   17.27 +
   17.28 +static int pci_msi_enable = 1;
   17.29 +
   17.30 +static struct msi_ops *msi_ops;
   17.31 +
   17.32 +int msi_register(struct msi_ops *ops)
   17.33 +{
   17.34 +	msi_ops = ops;
   17.35 +	return 0;
   17.36 +}
   17.37 +
   17.38 +static struct list_head msi_dev_head;
   17.39 +static int msi_dev_head_inited = 0;
   17.40 +DEFINE_SPINLOCK(msi_dev_lock);
   17.41 +
   17.42 +struct msi_dev_list {
   17.43 +	struct pci_dev *dev;
   17.44 +	struct list_head list;
   17.45 +	spinlock_t pirq_list_lock;
   17.46 +	struct list_head pirq_list_head;
   17.47 +};
   17.48 +
   17.49 +struct msi_pirq_entry {
   17.50 +	struct list_head list;
   17.51 +	int pirq;
   17.52 +	int entry_nr;
   17.53 +};
   17.54 +
   17.55 +static struct msi_dev_list *get_msi_dev_pirq_list(struct pci_dev *dev)
   17.56 +{
   17.57 +	struct msi_dev_list *msi_dev_list, *ret = NULL;
   17.58 +	unsigned long flags;
   17.59 +
   17.60 +	if (!msi_dev_head_inited) {
   17.61 +		INIT_LIST_HEAD(&msi_dev_head);
   17.62 +		msi_dev_head_inited = 1;
   17.63 +	}
   17.64 +
   17.65 +	spin_lock_irqsave(&msi_dev_lock, flags);
   17.66 +
   17.67 +	list_for_each_entry(msi_dev_list, &msi_dev_head, list)
   17.68 +		if ( msi_dev_list->dev == dev )
   17.69 +			ret = msi_dev_list;
   17.70 +
   17.71 +	if ( ret ) {
   17.72 +		spin_unlock_irqrestore(&msi_dev_lock, flags);
   17.73 +		return ret;
   17.74 +	}
   17.75 +
   17.76 +	/* Has not allocate msi_dev until now. */
   17.77 +	ret = kmalloc(sizeof(struct msi_dev_list), GFP_ATOMIC);
   17.78 +
   17.79 +	/* Failed to allocate msi_dev structure */
   17.80 +	if ( !ret ) {
   17.81 +		spin_unlock_irqrestore(&msi_dev_lock, flags);
   17.82 +		return NULL;
   17.83 +	}
   17.84 +
   17.85 +	list_add_tail(&ret->list, &msi_dev_head);
   17.86 +	spin_unlock_irqrestore(&msi_dev_lock, flags);
   17.87 +	spin_lock_init(&ret->pirq_list_lock);
   17.88 +	INIT_LIST_HEAD(&ret->pirq_list_head);
   17.89 +	return ret;
   17.90 +}
   17.91 +
   17.92 +static int attach_pirq_entry(int pirq, int entry_nr,
   17.93 +                             struct msi_dev_list *msi_dev_entry)
   17.94 +{
   17.95 +	struct msi_pirq_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
   17.96 +	unsigned long flags;
   17.97 +
   17.98 +	if (!entry)
   17.99 +		return -ENOMEM;
  17.100 +	entry->pirq = pirq;
  17.101 +	entry->entry_nr = entry_nr;
  17.102 +	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
  17.103 +	list_add_tail(&entry->list, &msi_dev_entry->pirq_list_head);
  17.104 +	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
  17.105 +	return 0;
  17.106 +}
  17.107 +
  17.108 +/*
  17.109 + * pciback will provide device's owner
  17.110 + */
  17.111 +int (*get_owner)(struct pci_dev *dev);
  17.112 +
  17.113 +int register_msi_get_owner(int (*func)(struct pci_dev *dev))
  17.114 +{
  17.115 +	if (get_owner) {
  17.116 +		printk(KERN_WARNING "register msi_get_owner again\n");
  17.117 +		return -EEXIST;
  17.118 +	}
  17.119 +	get_owner = func;
  17.120 +	return 0;
  17.121 +}
  17.122 +
  17.123 +int unregister_msi_get_owner(int (*func)(struct pci_dev *dev))
  17.124 +{
  17.125 +	if (get_owner == func)
  17.126 +		get_owner = NULL;
  17.127 +	return 0;
  17.128 +}
  17.129 +
  17.130 +static int msi_get_dev_owner(struct pci_dev *dev)
  17.131 +{
  17.132 +	int owner = DOMID_SELF;
  17.133 +
  17.134 +	BUG_ON(!is_initial_xendomain());
  17.135 +	if (get_owner && (owner = get_owner(dev)) >=0 ) {
  17.136 +		printk(KERN_INFO "get owner for dev %x get %x \n",
  17.137 +				    dev->devfn, owner);
  17.138 +		return owner;
  17.139 +	}
  17.140 +	else
  17.141 +		return DOMID_SELF;
  17.142 +}
  17.143 +
  17.144 +static int msi_unmap_pirq(struct pci_dev *dev, int pirq)
  17.145 +{
  17.146 +	struct physdev_unmap_pirq unmap;
  17.147 +	int rc;
  17.148 +	domid_t domid = DOMID_SELF;
  17.149 +
  17.150 +	domid = msi_get_dev_owner(dev);
  17.151 +	unmap.domid = domid;
  17.152 +	unmap.pirq = pirq;
  17.153 +
  17.154 +	if ((rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap)))
  17.155 +		printk(KERN_WARNING "unmap irq %x failed\n", pirq);
  17.156 +
  17.157 +	if (rc < 0)
  17.158 +		return rc;
  17.159 +    return 0;
  17.160 +}
  17.161 +
  17.162 +/*
  17.163 + * Protected by msi_lock
  17.164 + */
  17.165 +static int msi_map_pirq_to_vector(struct pci_dev *dev, int pirq,
  17.166 +                                  int entry_nr, int msi)
  17.167 +{
  17.168 +	struct physdev_map_pirq map_irq;
  17.169 +	int rc;
  17.170 +	domid_t domid = DOMID_SELF;
  17.171 +
  17.172 +	domid = msi_get_dev_owner(dev);
  17.173 +
  17.174 +	map_irq.domid = domid;
  17.175 +	map_irq.type = MAP_PIRQ_TYPE_MSI;
  17.176 +	map_irq.index = -1;
  17.177 +	map_irq.pirq = pirq;
  17.178 +    map_irq.msi_info.bus = dev->bus->number;
  17.179 +    map_irq.msi_info.devfn = dev->devfn;
  17.180 +	map_irq.msi_info.entry_nr = entry_nr;
  17.181 +    map_irq.msi_info.msi = msi;
  17.182 +
  17.183 +	if ((rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq)))
  17.184 +		printk(KERN_WARNING "map irq failed\n");
  17.185 +
  17.186 +	if (rc < 0)
  17.187 +		return rc;
  17.188 +
  17.189 +	return map_irq.pirq;
  17.190 +}
  17.191 +
  17.192 +static int msi_map_vector(struct pci_dev *dev, int entry_nr, int msi)
  17.193 +{
  17.194 +	return msi_map_pirq_to_vector(dev, -1, entry_nr, msi);
  17.195 +}
  17.196 +
  17.197 +static int msi_init(void)
  17.198 +{
  17.199 +	static int status = 0;
  17.200 +
  17.201 +	if (pci_msi_quirk) {
  17.202 +		pci_msi_enable = 0;
  17.203 +		printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n");
  17.204 +		status = -EINVAL;
  17.205 +	}
  17.206 +
  17.207 +	return status;
  17.208 +}
  17.209 +
  17.210 +void pci_scan_msi_device(struct pci_dev *dev) { }
  17.211 +
  17.212 +void disable_msi_mode(struct pci_dev *dev, int pos, int type)
  17.213 +{
  17.214 +	u16 control;
  17.215 +
  17.216 +	pci_read_config_word(dev, msi_control_reg(pos), &control);
  17.217 +	if (type == PCI_CAP_ID_MSI) {
  17.218 +		/* Set enabled bits to single MSI & enable MSI_enable bit */
  17.219 +		msi_disable(control);
  17.220 +		pci_write_config_word(dev, msi_control_reg(pos), control);
  17.221 +		dev->msi_enabled = 0;
  17.222 +	} else {
  17.223 +		msix_disable(control);
  17.224 +		pci_write_config_word(dev, msi_control_reg(pos), control);
  17.225 +		dev->msix_enabled = 0;
  17.226 +	}
  17.227 +    	if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
  17.228 +		/* PCI Express Endpoint device detected */
  17.229 +		pci_intx(dev, 1);  /* enable intx */
  17.230 +	}
  17.231 +}
  17.232 +
  17.233 +static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
  17.234 +{
  17.235 +	u16 control;
  17.236 +
  17.237 +	pci_read_config_word(dev, msi_control_reg(pos), &control);
  17.238 +	if (type == PCI_CAP_ID_MSI) {
  17.239 +		/* Set enabled bits to single MSI & enable MSI_enable bit */
  17.240 +		msi_enable(control, 1);
  17.241 +		pci_write_config_word(dev, msi_control_reg(pos), control);
  17.242 +		dev->msi_enabled = 1;
  17.243 +	} else {
  17.244 +		msix_enable(control);
  17.245 +		pci_write_config_word(dev, msi_control_reg(pos), control);
  17.246 +		dev->msix_enabled = 1;
  17.247 +	}
  17.248 +    	if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
  17.249 +		/* PCI Express Endpoint device detected */
  17.250 +		pci_intx(dev, 0);  /* disable intx */
  17.251 +	}
  17.252 +}
  17.253 +
  17.254 +#ifdef CONFIG_PM
  17.255 +int pci_save_msi_state(struct pci_dev *dev)
  17.256 +{
  17.257 +	int pos;
  17.258 +
  17.259 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
  17.260 +	if (pos <= 0 || dev->no_msi)
  17.261 +		return 0;
  17.262 +
  17.263 +	if (!dev->msi_enabled)
  17.264 +		return 0;
  17.265 +
  17.266 +	/* Restore dev->irq to its default pin-assertion vector */
  17.267 +	msi_unmap_pirq(dev, dev->irq);
  17.268 +	/* Disable MSI mode */
  17.269 +	disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
  17.270 +	/* Set the flags for use of restore */
  17.271 +	dev->msi_enabled = 1;
  17.272 +	return 0;
  17.273 +}
  17.274 +
  17.275 +void pci_restore_msi_state(struct pci_dev *dev)
  17.276 +{
  17.277 +	int pos, pirq;
  17.278 +
  17.279 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
  17.280 +	if (pos <= 0)
  17.281 +		return;
  17.282 +
  17.283 +	if (!dev->msi_enabled)
  17.284 +		return;
  17.285 +
  17.286 +	pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 1);
  17.287 +	if (pirq < 0)
  17.288 +		return;
  17.289 +	enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
  17.290 +}
  17.291 +
  17.292 +int pci_save_msix_state(struct pci_dev *dev)
  17.293 +{
  17.294 +	int pos;
  17.295 +	unsigned long flags;
  17.296 +	struct msi_dev_list *msi_dev_entry;
  17.297 +	struct msi_pirq_entry *pirq_entry, *tmp;
  17.298 +
  17.299 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
  17.300 +	if (pos <= 0 || dev->no_msi)
  17.301 +		return 0;
  17.302 +
  17.303 +	/* save the capability */
  17.304 +	if (!dev->msix_enabled)
  17.305 +		return 0;
  17.306 +
  17.307 +	msi_dev_entry = get_msi_dev_pirq_list(dev);
  17.308 +
  17.309 +	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
  17.310 +	if (!list_empty_careful(&msi_dev_entry->pirq_list_head))
  17.311 +		list_for_each_entry_safe(pirq_entry, tmp,
  17.312 +		                         &msi_dev_entry->pirq_list_head, list)
  17.313 +			msi_unmap_pirq(dev, pirq_entry->pirq);
  17.314 +	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
  17.315 +
  17.316 +	disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
  17.317 +	/* Set the flags for use of restore */
  17.318 +	dev->msix_enabled = 1;
  17.319 +
  17.320 +	return 0;
  17.321 +}
  17.322 +
  17.323 +void pci_restore_msix_state(struct pci_dev *dev)
  17.324 +{
  17.325 +	int pos;
  17.326 +	unsigned long flags;
  17.327 +	struct msi_dev_list *msi_dev_entry;
  17.328 +	struct msi_pirq_entry *pirq_entry, *tmp;
  17.329 +
  17.330 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
  17.331 +	if (pos <= 0)
  17.332 +		return;
  17.333 +
  17.334 +	if (!dev->msix_enabled)
  17.335 +		return;
  17.336 +
  17.337 +	msi_dev_entry = get_msi_dev_pirq_list(dev);
  17.338 +
  17.339 +	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
  17.340 +	list_for_each_entry_safe(pirq_entry, tmp,
  17.341 +							 &msi_dev_entry->pirq_list_head, list)
  17.342 +		msi_map_pirq_to_vector(dev, pirq_entry->pirq, pirq_entry->entry_nr, 0);
  17.343 +	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
  17.344 +
  17.345 +	enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
  17.346 +}
  17.347 +#endif
  17.348 +
  17.349 +/**
  17.350 + * msi_capability_init - configure device's MSI capability structure
  17.351 + * @dev: pointer to the pci_dev data structure of MSI device function
  17.352 + *
  17.353 + * Setup the MSI capability structure of device function with a single
  17.354 + * MSI vector, regardless of device function is capable of handling
  17.355 + * multiple messages. A return of zero indicates the successful setup
  17.356 + * of an entry zero with the new MSI vector or non-zero for otherwise.
  17.357 + **/
  17.358 +static int msi_capability_init(struct pci_dev *dev)
  17.359 +{
  17.360 +	int pos, pirq;
  17.361 +	u16 control;
  17.362 +
  17.363 +   	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
  17.364 +	pci_read_config_word(dev, msi_control_reg(pos), &control);
  17.365 +
  17.366 +	pirq = msi_map_vector(dev, 0, 1);
  17.367 +	if (pirq < 0)
  17.368 +		return -EBUSY;
  17.369 +
  17.370 +	dev->irq = pirq;
  17.371 +	/* Set MSI enabled bits	 */
  17.372 +	enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
  17.373 +	dev->msi_enabled = 1;
  17.374 +
  17.375 +	return 0;
  17.376 +}
  17.377 +
  17.378 +/**
  17.379 + * msix_capability_init - configure device's MSI-X capability
  17.380 + * @dev: pointer to the pci_dev data structure of MSI-X device function
  17.381 + * @entries: pointer to an array of struct msix_entry entries
  17.382 + * @nvec: number of @entries
  17.383 + *
  17.384 + * Setup the MSI-X capability structure of device function with a
  17.385 + * single MSI-X vector. A return of zero indicates the successful setup of
  17.386 + * requested MSI-X entries with allocated vectors or non-zero for otherwise.
  17.387 + **/
  17.388 +static int msix_capability_init(struct pci_dev *dev,
  17.389 +				struct msix_entry *entries, int nvec)
  17.390 +{
  17.391 +	int pirq, i, pos;
  17.392 +	struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
  17.393 +	struct msi_pirq_entry *pirq_entry, *tmp;
  17.394 +	unsigned long flags;
  17.395 +
  17.396 +	if (!msi_dev_entry)
  17.397 +		return -ENOMEM;
  17.398 +
  17.399 +	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
  17.400 +	if (!list_empty_careful(&msi_dev_entry->pirq_list_head))
  17.401 +	{
  17.402 +		printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not freed \
  17.403 +		       before acquire again.\n", dev->bus->number, PCI_SLOT(dev->devfn),
  17.404 +			   PCI_FUNC(dev->devfn));
  17.405 +		list_for_each_entry_safe(pirq_entry, tmp,
  17.406 +		                         &msi_dev_entry->pirq_list_head, list) {
  17.407 +			msi_unmap_pirq(dev, pirq_entry->pirq);
  17.408 +			list_del(&pirq_entry->list);
  17.409 +			kfree(pirq_entry);
  17.410 +		}
  17.411 +	}
  17.412 +	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
  17.413 +
  17.414 +	/* MSI-X Table Initialization */
  17.415 +	for (i = 0; i < nvec; i++) {
  17.416 +		pirq = msi_map_vector(dev, entries[i].entry, 0);
  17.417 +		if (pirq < 0)
  17.418 +			break;
  17.419 +		attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
  17.420 +		(entries + i)->vector = pirq;
  17.421 +	}
  17.422 +	if (i != nvec) {
  17.423 +		msi_unmap_pirq(dev, dev->irq);
  17.424 +		(entries + i)->vector = 0;
  17.425 +		return -EBUSY;
  17.426 +	}
  17.427 +
  17.428 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
  17.429 +	enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
  17.430 +	dev->msix_enabled = 1;
  17.431 +
  17.432 +	return 0;
  17.433 +}
  17.434 +
  17.435 +/**
  17.436 + * pci_enable_msi - configure device's MSI capability structure
  17.437 + * @dev: pointer to the pci_dev data structure of MSI device function
  17.438 + *
  17.439 + * Setup the MSI capability structure of device function with
  17.440 + * a single MSI vector upon its software driver call to request for
  17.441 + * MSI mode enabled on its hardware device function. A return of zero
  17.442 + * indicates the successful setup of an entry zero with the new MSI
  17.443 + * vector or non-zero for otherwise.
  17.444 + **/
  17.445 +extern int pci_frontend_enable_msi(struct pci_dev *dev);
  17.446 +int pci_enable_msi(struct pci_dev* dev)
  17.447 +{
  17.448 +	struct pci_bus *bus;
  17.449 +	int pos, temp, status = -EINVAL;
  17.450 +
  17.451 +	if (!pci_msi_enable || !dev)
  17.452 + 		return status;
  17.453 +
  17.454 +	if (dev->no_msi)
  17.455 +		return status;
  17.456 +
  17.457 +	for (bus = dev->bus; bus; bus = bus->parent)
  17.458 +		if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
  17.459 +			return -EINVAL;
  17.460 +
  17.461 +	status = msi_init();
  17.462 +	if (status < 0)
  17.463 +		return status;
  17.464 +
  17.465 +#ifdef CONFIG_XEN_PCIDEV_FRONTEND
  17.466 +	if (!is_initial_xendomain())
  17.467 +	{
  17.468 +		int ret;
  17.469 +
  17.470 +		temp = dev->irq;
  17.471 +		ret = pci_frontend_enable_msi(dev);
  17.472 +		if (ret)
  17.473 +			return ret;
  17.474 +
  17.475 +		dev->irq_old = temp;
  17.476 +
  17.477 +		return ret;
  17.478 +	}
  17.479 +#endif
  17.480 +
  17.481 +	temp = dev->irq;
  17.482 +
  17.483 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
  17.484 +	if (!pos)
  17.485 +		return -EINVAL;
  17.486 +
  17.487 +	/* Check whether driver already requested for MSI-X vectors */
  17.488 +	if (dev->msix_enabled) {
  17.489 +		printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
  17.490 +			   "Device already has MSI-X vectors assigned\n",
  17.491 +			   pci_name(dev));
  17.492 +		dev->irq = temp;
  17.493 +		return -EINVAL;
  17.494 +	}
  17.495 +
  17.496 +	status = msi_capability_init(dev);
  17.497 +	if ( !status )
  17.498 +		dev->irq_old = temp;
  17.499 +    else
  17.500 +		dev->irq = temp;
  17.501 +
  17.502 +	return status;
  17.503 +}
  17.504 +
  17.505 +extern void pci_frontend_disable_msi(struct pci_dev* dev);
  17.506 +void pci_disable_msi(struct pci_dev* dev)
  17.507 +{
  17.508 +	int pos;
  17.509 +	int pirq;
  17.510 +
  17.511 +	if (!pci_msi_enable)
  17.512 +		return;
  17.513 +	if (!dev)
  17.514 +		return;
  17.515 +
  17.516 +#ifdef CONFIG_XEN_PCIDEV_FRONTEND
  17.517 +	if (!is_initial_xendomain()) {
  17.518 +		pci_frontend_disable_msi(dev);
  17.519 +		dev->irq = dev->irq_old;
  17.520 +		return;
  17.521 +	}
  17.522 +#endif
  17.523 +
  17.524 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
  17.525 +	if (!pos)
  17.526 +		return;
  17.527 +
  17.528 +	pirq = dev->irq;
  17.529 +	/* Restore dev->irq to its default pin-assertion vector */
  17.530 +	dev->irq = dev->irq_old;
  17.531 +	msi_unmap_pirq(dev, pirq);
  17.532 +
  17.533 +	/* Disable MSI mode */
  17.534 +	disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
  17.535 +}
  17.536 +
  17.537 +/**
  17.538 + * pci_enable_msix - configure device's MSI-X capability structure
  17.539 + * @dev: pointer to the pci_dev data structure of MSI-X device function
  17.540 + * @entries: pointer to an array of MSI-X entries
  17.541 + * @nvec: number of MSI-X vectors requested for allocation by device driver
  17.542 + *
  17.543 + * Setup the MSI-X capability structure of device function with the number
  17.544 + * of requested vectors upon its software driver call to request for
  17.545 + * MSI-X mode enabled on its hardware device function. A return of zero
  17.546 + * indicates the successful configuration of MSI-X capability structure
  17.547 + * with new allocated MSI-X vectors. A return of < 0 indicates a failure.
  17.548 + * Or a return of > 0 indicates that driver request is exceeding the number
  17.549 + * of vectors available. Driver should use the returned value to re-send
  17.550 + * its request.
  17.551 + **/
  17.552 +extern int pci_frontend_enable_msix(struct pci_dev *dev,
  17.553 +		struct msix_entry *entries, int nvec);
  17.554 +int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
  17.555 +{
  17.556 +	struct pci_bus *bus;
  17.557 +	int status, pos, nr_entries;
  17.558 +	int i, j, temp;
  17.559 +	u16 control;
  17.560 +
  17.561 +	if (!pci_msi_enable || !dev || !entries)
  17.562 + 		return -EINVAL;
  17.563 +
  17.564 +	if (dev->no_msi)
  17.565 +		return -EINVAL;
  17.566 +
  17.567 +	for (bus = dev->bus; bus; bus = bus->parent)
  17.568 +		if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
  17.569 +			return -EINVAL;
  17.570 +
  17.571 +#ifdef CONFIG_XEN_PCIDEV_FRONTEND
  17.572 +	if (!is_initial_xendomain()) {
  17.573 +		int ret;
  17.574 +
  17.575 +		ret = pci_frontend_enable_msix(dev, entries, nvec);
  17.576 +		if (ret) {
  17.577 +			printk("get %x from pci_frontend_enable_msix\n", ret);
  17.578 +			return ret;
  17.579 +		}
  17.580 +
  17.581 +        return 0;
  17.582 +	}
  17.583 +#endif
  17.584 +
  17.585 +	status = msi_init();
  17.586 +	if (status < 0)
  17.587 +		return status;
  17.588 +
  17.589 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
  17.590 +	if (!pos)
  17.591 + 		return -EINVAL;
  17.592 +
  17.593 +	pci_read_config_word(dev, msi_control_reg(pos), &control);
  17.594 +	nr_entries = multi_msix_capable(control);
  17.595 +	if (nvec > nr_entries)
  17.596 +		return -EINVAL;
  17.597 +
  17.598 +	/* Check for any invalid entries */
  17.599 +	for (i = 0; i < nvec; i++) {
  17.600 +		if (entries[i].entry >= nr_entries)
  17.601 +			return -EINVAL;		/* invalid entry */
  17.602 +		for (j = i + 1; j < nvec; j++) {
  17.603 +			if (entries[i].entry == entries[j].entry)
  17.604 +				return -EINVAL;	/* duplicate entry */
  17.605 +		}
  17.606 +	}
  17.607 +
  17.608 +	temp = dev->irq;
  17.609 +	/* Check whether driver already requested for MSI vector */
  17.610 +	if (dev->msi_enabled) {
  17.611 +		printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
  17.612 +		       "Device already has an MSI vector assigned\n",
  17.613 +		       pci_name(dev));
  17.614 +		dev->irq = temp;
  17.615 +		return -EINVAL;
  17.616 +	}
  17.617 +
  17.618 +	status = msix_capability_init(dev, entries, nvec);
  17.619 +
  17.620 +	if ( !status )
  17.621 +		dev->irq_old = temp;
  17.622 +	else
  17.623 +		dev->irq = temp;
  17.624 +
  17.625 +	return status;
  17.626 +}
  17.627 +
  17.628 +extern void pci_frontend_disable_msix(struct pci_dev* dev);
  17.629 +void pci_disable_msix(struct pci_dev* dev)
  17.630 +{
  17.631 +	int pos;
  17.632 +	u16 control;
  17.633 +
  17.634 +
  17.635 +	if (!pci_msi_enable)
  17.636 +		return;
  17.637 +	if (!dev)
  17.638 +		return;
  17.639 +
  17.640 +#ifdef CONFIG_XEN_PCIDEV_FRONTEND
  17.641 +	if (!is_initial_xendomain()) {
  17.642 +		pci_frontend_disable_msix(dev);
  17.643 +		dev->irq = dev->irq_old;
  17.644 +		return;
  17.645 +	}
  17.646 +#endif
  17.647 +
  17.648 +	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
  17.649 +	if (!pos)
  17.650 +		return;
  17.651 +
  17.652 +	pci_read_config_word(dev, msi_control_reg(pos), &control);
  17.653 +	if (!(control & PCI_MSIX_FLAGS_ENABLE))
  17.654 +		return;
  17.655 +
  17.656 +	msi_remove_pci_irq_vectors(dev);
  17.657 +
  17.658 +	/* Disable MSI mode */
  17.659 +	disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
  17.660 +}
  17.661 +
  17.662 +/**
  17.663 + * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
  17.664 + * @dev: pointer to the pci_dev data structure of MSI(X) device function
  17.665 + *
  17.666 + * Being called during hotplug remove, from which the device function
  17.667 + * is hot-removed. All previous assigned MSI/MSI-X vectors, if
  17.668 + * allocated for this device function, are reclaimed to unused state,
  17.669 + * which may be used later on.
  17.670 + **/
  17.671 +void msi_remove_pci_irq_vectors(struct pci_dev* dev)
  17.672 +{
  17.673 +	unsigned long flags;
  17.674 +	struct msi_dev_list *msi_dev_entry;
  17.675 +	struct msi_pirq_entry *pirq_entry, *tmp;
  17.676 +
  17.677 +	if (!pci_msi_enable || !dev)
  17.678 + 		return;
  17.679 +
  17.680 +	msi_dev_entry = get_msi_dev_pirq_list(dev);
  17.681 +
  17.682 +	spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
  17.683 +	if (!list_empty_careful(&msi_dev_entry->pirq_list_head))
  17.684 +	{
  17.685 +		printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not freed \
  17.686 +		       before acquire again.\n", dev->bus->number, PCI_SLOT(dev->devfn),
  17.687 +			   PCI_FUNC(dev->devfn));
  17.688 +		list_for_each_entry_safe(pirq_entry, tmp,
  17.689 +		                         &msi_dev_entry->pirq_list_head, list) {
  17.690 +			msi_unmap_pirq(dev, pirq_entry->pirq);
  17.691 +			list_del(&pirq_entry->list);
  17.692 +			kfree(pirq_entry);
  17.693 +		}
  17.694 +	}
  17.695 +	spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
  17.696 +	dev->irq = dev->irq_old;
  17.697 +}
  17.698 +
  17.699 +void pci_no_msi(void)
  17.700 +{
  17.701 +	pci_msi_enable = 0;
  17.702 +}
  17.703 +
  17.704 +EXPORT_SYMBOL(pci_enable_msi);
  17.705 +EXPORT_SYMBOL(pci_disable_msi);
  17.706 +EXPORT_SYMBOL(pci_enable_msix);
  17.707 +EXPORT_SYMBOL(pci_disable_msix);
  17.708 +#ifdef CONFIG_XEN
  17.709 +EXPORT_SYMBOL(register_msi_get_owner);
  17.710 +EXPORT_SYMBOL(unregister_msi_get_owner);
  17.711 +#endif
  17.712 +
    18.1 --- a/drivers/pci/msi.h	Thu Apr 24 14:08:54 2008 -0600
    18.2 +++ b/drivers/pci/msi.h	Tue May 13 10:38:04 2008 +0900
    18.3 @@ -84,6 +84,11 @@ extern int vector_irq[NR_VECTORS];
    18.4  extern void (*interrupt[NR_IRQS])(void);
    18.5  extern int pci_vector_resources(int last, int nr_released);
    18.6  
    18.7 +#ifdef CONFIG_XEN
    18.8 +extern int unregister_msi_get_owner(int (*func)(struct pci_dev *dev));
    18.9 +extern int register_msi_get_owner(int (*func)(struct pci_dev *dev));
   18.10 +#endif
   18.11 +
   18.12  /*
   18.13   * MSI-X Address Register
   18.14   */
    19.1 --- a/drivers/xen/core/evtchn.c	Thu Apr 24 14:08:54 2008 -0600
    19.2 +++ b/drivers/xen/core/evtchn.c	Tue May 13 10:38:04 2008 +0900
    19.3 @@ -200,9 +200,6 @@ static inline void exit_idle(void) {}
    19.4  	(regs)->IRQ_REG = ~(irq);	\
    19.5  	do_IRQ((regs));			\
    19.6  } while (0)
    19.7 -#elif defined (__powerpc__)
    19.8 -#define do_IRQ(irq, regs)	__do_IRQ(irq, regs)
    19.9 -static inline void exit_idle(void) {}
   19.10  #endif
   19.11  
   19.12  /* Xen will never allocate port zero for any purpose. */
   19.13 @@ -246,7 +243,7 @@ asmlinkage void evtchn_do_upcall(struct 
   19.14  
   19.15  #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
   19.16  		/* Clear master flag /before/ clearing selector flag. */
   19.17 -		rmb();
   19.18 +		wmb();
   19.19  #endif
   19.20  		l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
   19.21  
    20.1 --- a/drivers/xen/pciback/Makefile	Thu Apr 24 14:08:54 2008 -0600
    20.2 +++ b/drivers/xen/pciback/Makefile	Tue May 13 10:38:04 2008 +0900
    20.3 @@ -6,6 +6,7 @@ pciback-y += conf_space.o conf_space_hea
    20.4  	     conf_space_capability_vpd.o \
    20.5  	     conf_space_capability_pm.o \
    20.6               conf_space_quirks.o
    20.7 +pciback-$(CONFIG_PCI_MSI) += conf_space_capability_msi.o
    20.8  pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
    20.9  pciback-$(CONFIG_XEN_PCIDEV_BACKEND_SLOT) += slot.o
   20.10  pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/drivers/xen/pciback/conf_space_capability_msi.c	Tue May 13 10:38:04 2008 +0900
    21.3 @@ -0,0 +1,60 @@
    21.4 +/*
    21.5 + * PCI Backend -- Configuration overlay for MSI capability
    21.6 + */
    21.7 +#include <linux/pci.h>
    21.8 +#include "conf_space.h"
    21.9 +#include "conf_space_capability.h"
   21.10 +#include <xen/interface/io/pciif.h>
   21.11 +#include "pciback.h"
   21.12 +
   21.13 +int pciback_enable_msi(struct pciback_device *pdev,
   21.14 +		struct pci_dev *dev, struct xen_pci_op *op)
   21.15 +{
   21.16 +	int otherend = pdev->xdev->otherend_id;
   21.17 +	int irq;
   21.18 +	int status;
   21.19 +
   21.20 +	status = pci_enable_msi(dev);
   21.21 +
   21.22 +	if (status) {
   21.23 +		printk("error enable msi for guest %x status %x\n", otherend, status);
   21.24 +		op->value = 0;
   21.25 +		return XEN_PCI_ERR_op_failed;
   21.26 +	}
   21.27 +
   21.28 +	op->value = dev->irq;
   21.29 +	return 0;
   21.30 +}
   21.31 +
   21.32 +int pciback_disable_msi(struct pciback_device *pdev,
   21.33 +		struct pci_dev *dev, struct xen_pci_op *op)
   21.34 +{
   21.35 +	int old_irq = dev->irq;
   21.36 +
   21.37 +	pci_disable_msi(dev);
   21.38 +
   21.39 +	op->value = dev->irq;
   21.40 +	return 0;
   21.41 +}
   21.42 +
   21.43 +int pciback_enable_msix(struct pciback_device *pdev,
   21.44 +		struct pci_dev *dev, struct xen_pci_op *op)
   21.45 +{
   21.46 +	int otherend = pdev->xdev->otherend_id, result, i;
   21.47 +
   21.48 +	result = pci_enable_msix(dev, op->msix_entries, op->value);
   21.49 +
   21.50 +	op->value = result;
   21.51 +	return result;
   21.52 +}
   21.53 +
   21.54 +int pciback_disable_msix(struct pciback_device *pdev,
   21.55 +		struct pci_dev *dev, struct xen_pci_op *op)
   21.56 +{
   21.57 +
   21.58 +	pci_disable_msix(dev);
   21.59 +
   21.60 +	op->value = dev->irq;
   21.61 +	return 0;
   21.62 +}
   21.63 +
    22.1 --- a/drivers/xen/pciback/pci_stub.c	Thu Apr 24 14:08:54 2008 -0600
    22.2 +++ b/drivers/xen/pciback/pci_stub.c	Tue May 13 10:38:04 2008 +0900
    22.3 @@ -805,6 +805,23 @@ static ssize_t permissive_show(struct de
    22.4  
    22.5  DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
    22.6  
    22.7 +#ifdef CONFIG_PCI_MSI
    22.8 +
    22.9 +int pciback_get_owner(struct pci_dev *dev)
   22.10 +{
   22.11 +	struct pcistub_device *psdev;
   22.12 +
   22.13 +	psdev = pcistub_device_find(pci_domain_nr(dev->bus), dev->bus->number,
   22.14 +			PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
   22.15 +	/* XXX will other domain has pciback support ??? */
   22.16 +	if (!psdev || !psdev->pdev) {
   22.17 +		printk(KERN_WARNING "no ownder\n");
   22.18 +		return -1;
   22.19 +	}
   22.20 +	return psdev->pdev->xdev->otherend_id;
   22.21 +}
   22.22 +#endif
   22.23 +
   22.24  static void pcistub_exit(void)
   22.25  {
   22.26  	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
   22.27 @@ -815,6 +832,9 @@ static void pcistub_exit(void)
   22.28  	driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
   22.29  
   22.30  	pci_unregister_driver(&pciback_pci_driver);
   22.31 +#ifdef CONFIG_PCI_MSI
   22.32 +	unregister_msi_get_owner(pciback_get_owner);
   22.33 +#endif
   22.34  }
   22.35  
   22.36  static int __init pcistub_init(void)
   22.37 @@ -872,6 +892,10 @@ static int __init pcistub_init(void)
   22.38  		err = driver_create_file(&pciback_pci_driver.driver,
   22.39  					 &driver_attr_permissive);
   22.40  
   22.41 +#ifdef CONFIG_PCI_MSI
   22.42 +	if (!err)
   22.43 +		err = register_msi_get_owner(pciback_get_owner);
   22.44 +#endif
   22.45  	if (err)
   22.46  		pcistub_exit();
   22.47  
    23.1 --- a/drivers/xen/pciback/pciback.h	Thu Apr 24 14:08:54 2008 -0600
    23.2 +++ b/drivers/xen/pciback/pciback.h	Tue May 13 10:38:04 2008 +0900
    23.3 @@ -93,5 +93,19 @@ void pciback_do_op(void *data);
    23.4  int pciback_xenbus_register(void);
    23.5  void pciback_xenbus_unregister(void);
    23.6  
    23.7 +#ifdef CONFIG_PCI_MSI
    23.8 +int pciback_enable_msi(struct pciback_device *pdev,
    23.9 +                       struct pci_dev *dev, struct xen_pci_op *op);
   23.10 +
   23.11 +int pciback_disable_msi(struct pciback_device *pdev,
   23.12 +                         struct pci_dev *dev, struct xen_pci_op *op);
   23.13 +
   23.14 +
   23.15 +int pciback_enable_msix(struct pciback_device *pdev,
   23.16 +                        struct pci_dev *dev, struct xen_pci_op *op);
   23.17 +
   23.18 +int pciback_disable_msix(struct pciback_device *pdev,
   23.19 +                        struct pci_dev *dev, struct xen_pci_op *op);
   23.20 +#endif
   23.21  extern int verbose_request;
   23.22  #endif
    24.1 --- a/drivers/xen/pciback/pciback_ops.c	Thu Apr 24 14:08:54 2008 -0600
    24.2 +++ b/drivers/xen/pciback/pciback_ops.c	Tue May 13 10:38:04 2008 +0900
    24.3 @@ -61,15 +61,37 @@ void pciback_do_op(void *data)
    24.4  
    24.5  	if (dev == NULL)
    24.6  		op->err = XEN_PCI_ERR_dev_not_found;
    24.7 -	else if (op->cmd == XEN_PCI_OP_conf_read)
    24.8 -		op->err = pciback_config_read(dev, op->offset, op->size,
    24.9 -					      &op->value);
   24.10 -	else if (op->cmd == XEN_PCI_OP_conf_write)
   24.11 -		op->err = pciback_config_write(dev, op->offset, op->size,
   24.12 -					       op->value);
   24.13  	else
   24.14 -		op->err = XEN_PCI_ERR_not_implemented;
   24.15 -
   24.16 +	{
   24.17 +		switch (op->cmd)
   24.18 +		{
   24.19 +			case XEN_PCI_OP_conf_read:
   24.20 +				op->err = pciback_config_read(dev,
   24.21 +					  op->offset, op->size, &op->value);
   24.22 +				break;
   24.23 +			case XEN_PCI_OP_conf_write:
   24.24 +				op->err = pciback_config_write(dev,
   24.25 +					  op->offset, op->size,	op->value);
   24.26 +				break;
   24.27 +#ifdef CONFIG_PCI_MSI
   24.28 +			case XEN_PCI_OP_enable_msi:
   24.29 +				op->err = pciback_enable_msi(pdev, dev, op);
   24.30 +				break;
   24.31 +			case XEN_PCI_OP_disable_msi:
   24.32 +				op->err = pciback_disable_msi(pdev, dev, op);
   24.33 +				break;
   24.34 +			case XEN_PCI_OP_enable_msix:
   24.35 +				op->err = pciback_enable_msix(pdev, dev, op);
   24.36 +				break;
   24.37 +			case XEN_PCI_OP_disable_msix:
   24.38 +				op->err = pciback_disable_msix(pdev, dev, op);
   24.39 +				break;
   24.40 +#endif
   24.41 +			default:
   24.42 +				op->err = XEN_PCI_ERR_not_implemented;
   24.43 +				break;
   24.44 +		}
   24.45 +	}
   24.46  	/* Tell the driver domain that we're done. */ 
   24.47  	wmb();
   24.48  	clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
    25.1 --- a/drivers/xen/pcifront/pci_op.c	Thu Apr 24 14:08:54 2008 -0600
    25.2 +++ b/drivers/xen/pcifront/pci_op.c	Tue May 13 10:38:04 2008 +0900
    25.3 @@ -277,6 +277,122 @@ struct pci_ops pcifront_bus_ops = {
    25.4  	.write = pcifront_bus_write,
    25.5  };
    25.6  
    25.7 +#ifdef CONFIG_PCI_MSI
    25.8 +int pci_frontend_enable_msix(struct pci_dev *dev,
    25.9 +		struct msix_entry *entries,
   25.10 +		int nvec)
   25.11 +{
   25.12 +	int err;
   25.13 +	int i;
   25.14 +	struct xen_pci_op op = {
   25.15 +		.cmd    = XEN_PCI_OP_enable_msix,
   25.16 +		.domain = pci_domain_nr(dev->bus),
   25.17 +		.bus = dev->bus->number,
   25.18 +		.devfn = dev->devfn,
   25.19 +		.value = nvec,
   25.20 +	};
   25.21 +	struct pcifront_sd *sd = dev->bus->sysdata;
   25.22 +	struct pcifront_device *pdev = pcifront_get_pdev(sd);
   25.23 +
   25.24 +	if (nvec > SH_INFO_MAX_VEC) {
   25.25 +		printk("too much vector for pci frontend%x\n", nvec);
   25.26 +		return -EINVAL;
   25.27 +	}
   25.28 +
   25.29 +	for (i = 0; i < nvec; i++) {
   25.30 +		op.msix_entries[i].entry = entries[i].entry;
   25.31 +		op.msix_entries[i].vector = entries[i].vector;
   25.32 +	}
   25.33 +
   25.34 +	err = do_pci_op(pdev, &op);
   25.35 +
   25.36 +	if (!err) {
   25.37 +		if (!op.value) {
   25.38 +			/* we get the result */
   25.39 +			for ( i = 0; i < nvec; i++)
   25.40 +				entries[i].vector = op.msix_entries[i].vector;
   25.41 +			return 0;
   25.42 +		}
   25.43 +		else {
   25.44 +            printk("enable msix get value %x\n", op.value);
   25.45 +			return op.value;
   25.46 +		}
   25.47 +	}
   25.48 +	else {
   25.49 +        printk("enable msix get err %x\n", err);
   25.50 +		return err;
   25.51 +	}
   25.52 +}
   25.53 +
   25.54 +void pci_frontend_disable_msix(struct pci_dev* dev)
   25.55 +{
   25.56 +	int err;
   25.57 +	struct xen_pci_op op = {
   25.58 +		.cmd    = XEN_PCI_OP_disable_msix,
   25.59 +		.domain = pci_domain_nr(dev->bus),
   25.60 +		.bus = dev->bus->number,
   25.61 +		.devfn = dev->devfn,
   25.62 +	};
   25.63 +	struct pcifront_sd *sd = dev->bus->sysdata;
   25.64 +	struct pcifront_device *pdev = pcifront_get_pdev(sd);
   25.65 +
   25.66 +	err = do_pci_op(pdev, &op);
   25.67 +
   25.68 +	/* What should do for error ? */
   25.69 +	if (err)
   25.70 +		printk("pci_disable_msix get err %x\n", err);
   25.71 +}
   25.72 +
   25.73 +int pci_frontend_enable_msi(struct pci_dev *dev)
   25.74 +{
   25.75 +	int err;
   25.76 +	struct xen_pci_op op = {
   25.77 +		.cmd    = XEN_PCI_OP_enable_msi,
   25.78 +		.domain = pci_domain_nr(dev->bus),
   25.79 +		.bus = dev->bus->number,
   25.80 +		.devfn = dev->devfn,
   25.81 +	};
   25.82 +	struct pcifront_sd *sd = dev->bus->sysdata;
   25.83 +	struct pcifront_device *pdev = pcifront_get_pdev(sd);
   25.84 +
   25.85 +	err = do_pci_op(pdev, &op);
   25.86 +	if (likely(!err)) {
   25.87 +		dev->irq = op.value;
   25.88 +	}
   25.89 +	else {
   25.90 +		printk("pci frontend enable msi failed for dev %x:%x \n",
   25.91 +				op.bus, op.devfn);
   25.92 +		err = -EINVAL;
   25.93 +	}
   25.94 +	return err;
   25.95 +}
   25.96 +
   25.97 +void pci_frontend_disable_msi(struct pci_dev* dev)
   25.98 +{
   25.99 +	int err;
  25.100 +	struct xen_pci_op op = {
  25.101 +		.cmd    = XEN_PCI_OP_disable_msi,
  25.102 +		.domain = pci_domain_nr(dev->bus),
  25.103 +		.bus = dev->bus->number,
  25.104 +		.devfn = dev->devfn,
  25.105 +	};
  25.106 +	struct pcifront_sd *sd = dev->bus->sysdata;
  25.107 +	struct pcifront_device *pdev = pcifront_get_pdev(sd);
  25.108 +
  25.109 +	err = do_pci_op(pdev, &op);
  25.110 +	if (err == XEN_PCI_ERR_dev_not_found) {
  25.111 +		/* XXX No response from backend, what shall we do? */
  25.112 +		printk("get no response from backend for disable MSI\n");
  25.113 +		return;
  25.114 +	}
  25.115 +	if (likely(!err))
  25.116 +		dev->irq = op.value;
  25.117 +	else
  25.118 +		/* how can pciback notify us fail? */
  25.119 +		printk("get fake response frombackend \n");
  25.120 +}
  25.121 +#endif /* CONFIG_PCI_MSI */
  25.122 +
  25.123  /* Claim resources for the PCI frontend as-is, backend won't allow changes */
  25.124  static void pcifront_claim_resource(struct pci_dev *dev, void *data)
  25.125  {
    26.1 --- a/drivers/xen/privcmd/privcmd.c	Thu Apr 24 14:08:54 2008 -0600
    26.2 +++ b/drivers/xen/privcmd/privcmd.c	Tue May 13 10:38:04 2008 +0900
    26.3 @@ -229,11 +229,9 @@ static struct vm_operations_struct privc
    26.4  
    26.5  static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
    26.6  {
    26.7 -#ifndef __powerpc__ /* PowerPC has a trick to safely do this. */
    26.8  	/* Unsupported for auto-translate guests. */
    26.9  	if (xen_feature(XENFEAT_auto_translated_physmap))
   26.10  		return -ENOSYS;
   26.11 -#endif
   26.12  
   26.13  	/* DONTCOPY is essential for Xen as copy_page_range is broken. */
   26.14  	vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
    27.1 --- a/include/acpi/processor.h	Thu Apr 24 14:08:54 2008 -0600
    27.2 +++ b/include/acpi/processor.h	Tue May 13 10:38:04 2008 +0900
    27.3 @@ -21,6 +21,10 @@
    27.4  #define ACPI_PSD_REV0_REVISION		0 /* Support for _PSD as in ACPI 3.0 */
    27.5  #define ACPI_PSD_REV0_ENTRIES		5
    27.6  
    27.7 +#ifdef CONFIG_XEN
    27.8 +#define NR_ACPI_CPUS			256
    27.9 +#endif /* CONFIG_XEN */
   27.10 +
   27.11  /*
   27.12   * Types of coordination defined in ACPI 3.0. Same macros can be used across
   27.13   * P, C and T states
   27.14 @@ -33,6 +37,17 @@
   27.15  
   27.16  struct acpi_processor_cx;
   27.17  
   27.18 +#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
   27.19 +struct acpi_csd_package {
   27.20 +	acpi_integer num_entries;
   27.21 +	acpi_integer revision;
   27.22 +	acpi_integer domain;
   27.23 +	acpi_integer coord_type;
   27.24 +	acpi_integer num_processors;
   27.25 +	acpi_integer index;
   27.26 +} __attribute__ ((packed));
   27.27 +#endif
   27.28 +
   27.29  struct acpi_power_register {
   27.30  	u8 descriptor;
   27.31  	u16 length;
   27.32 @@ -63,6 +78,12 @@ struct acpi_processor_cx {
   27.33  	u32 power;
   27.34  	u32 usage;
   27.35  	u64 time;
   27.36 +#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
   27.37 +	/* Require raw information for external control logic */
   27.38 +	struct acpi_power_register reg;
   27.39 +	u32 csd_count;
   27.40 +	struct acpi_csd_package *domain_info;
   27.41 +#endif
   27.42  	struct acpi_processor_cx_policy promotion;
   27.43  	struct acpi_processor_cx_policy demotion;
   27.44  };
   27.45 @@ -275,4 +296,78 @@ static inline void acpi_thermal_cpufreq_
   27.46  }
   27.47  #endif
   27.48  
   27.49 +#ifdef CONFIG_XEN
   27.50 +/* 
   27.51 + * Following are interfaces geared to external processor PM control
   27.52 + * logic like a VMM
   27.53 + */
   27.54 +/* Events notified to external control logic */
   27.55 +#define PROCESSOR_PM_INIT	1
   27.56 +#define PROCESSOR_PM_CHANGE	2
   27.57 +#define PROCESSOR_HOTPLUG	3
   27.58 +
   27.59 +/* Objects for the PM envents */
   27.60 +#define PM_TYPE_IDLE		0
   27.61 +#define PM_TYPE_PERF		1
   27.62 +#define PM_TYPE_THR		2
   27.63 +#define PM_TYPE_MAX		3
   27.64 +
   27.65 +/* Processor hotplug events */
   27.66 +#define HOTPLUG_TYPE_ADD	0
   27.67 +#define HOTPLUG_TYPE_REMOVE	1
   27.68 +
   27.69 +#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
   27.70 +struct processor_extcntl_ops {
   27.71 +	/* Transfer processor PM events to external control logic */
   27.72 +	int (*pm_ops[PM_TYPE_MAX])(struct acpi_processor *pr, int event);
   27.73 +	/* Notify physical processor status to external control logic */
   27.74 +	int (*hotplug)(struct acpi_processor *pr, int event);
   27.75 +};
   27.76 +extern struct processor_extcntl_ops *processor_extcntl_ops;
   27.77 +
   27.78 +static inline int processor_cntl_external(void)
   27.79 +{
   27.80 +	return (processor_extcntl_ops != NULL);
   27.81 +}
   27.82 +
   27.83 +static inline int processor_pm_external(void)
   27.84 +{
   27.85 +	return processor_cntl_external() &&
   27.86 +		(processor_extcntl_ops->pm_ops[PM_TYPE_IDLE] != NULL);
   27.87 +}
   27.88 +
   27.89 +static inline int processor_pmperf_external(void)
   27.90 +{
   27.91 +	return processor_cntl_external() &&
   27.92 +		(processor_extcntl_ops->pm_ops[PM_TYPE_PERF] != NULL);
   27.93 +}
   27.94 +
   27.95 +static inline int processor_pmthr_external(void)
   27.96 +{
   27.97 +	return processor_cntl_external() &&
   27.98 +		(processor_extcntl_ops->pm_ops[PM_TYPE_THR] != NULL);
   27.99 +}
  27.100 +
  27.101 +extern int processor_notify_external(struct acpi_processor *pr,
  27.102 +			int event, int type);
  27.103 +extern int processor_register_extcntl(struct processor_extcntl_ops *ops);
  27.104 +extern int processor_unregister_extcntl(struct processor_extcntl_ops *ops);
  27.105 +extern int processor_extcntl_init(struct acpi_processor *pr);
  27.106 +#else
  27.107 +static inline int processor_cntl_external(void) {return 0;}
  27.108 +static inline int processor_pm_external(void) {return 0;}
  27.109 +static inline int processor_pmperf_external(void) {return 0;}
  27.110 +static inline int processor_pmthr_external(void) {return 0;}
  27.111 +static inline int processor_notify_external(struct acpi_processor *pr,
  27.112 +			int event, int type)
  27.113 +{
  27.114 +	return -EINVAL;
  27.115 +}
  27.116 +static inline int processor_extcntl_init(struct acpi_processor *pr)
  27.117 +{
  27.118 +	return -EINVAL;
  27.119 +}
  27.120 +#endif /* CONFIG_PROCESSOR_EXTERNAL_CONTROL */
  27.121 +#endif /* CONFIG_XEN */
  27.122 +
  27.123  #endif
    28.1 --- a/include/asm-i386/io_apic.h	Thu Apr 24 14:08:54 2008 -0600
    28.2 +++ b/include/asm-i386/io_apic.h	Tue May 13 10:38:04 2008 +0900
    28.3 @@ -12,7 +12,7 @@
    28.4  
    28.5  #ifdef CONFIG_X86_IO_APIC
    28.6  
    28.7 -#ifdef CONFIG_PCI_MSI
    28.8 +#if defined(CONFIG_PCI_MSI) && !defined(CONFIG_XEN)
    28.9  static inline int use_pci_vector(void)	{return 1;}
   28.10  static inline void disable_edge_ioapic_vector(unsigned int vector) { }
   28.11  static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
    29.1 --- a/include/asm-x86_64/io_apic.h	Thu Apr 24 14:08:54 2008 -0600
    29.2 +++ b/include/asm-x86_64/io_apic.h	Tue May 13 10:38:04 2008 +0900
    29.3 @@ -12,7 +12,7 @@
    29.4  
    29.5  #ifdef CONFIG_X86_IO_APIC
    29.6  
    29.7 -#ifdef CONFIG_PCI_MSI
    29.8 +#if defined(CONFIG_PCI_MSI) && !defined(CONFIG_XEN)
    29.9  static inline int use_pci_vector(void)	{return 1;}
   29.10  static inline void disable_edge_ioapic_vector(unsigned int vector) { }
   29.11  static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
    30.1 --- a/include/asm-x86_64/msi.h	Thu Apr 24 14:08:54 2008 -0600
    30.2 +++ b/include/asm-x86_64/msi.h	Tue May 13 10:38:04 2008 +0900
    30.3 @@ -7,14 +7,21 @@
    30.4  #define ASM_MSI_H
    30.5  
    30.6  #include <asm/desc.h>
    30.7 +#ifndef CONFIG_XEN
    30.8  #include <asm/mach_apic.h>
    30.9 +#endif
   30.10  #include <asm/smp.h>
   30.11  
   30.12 +#ifndef CONFIG_XEN
   30.13  #define LAST_DEVICE_VECTOR	(FIRST_SYSTEM_VECTOR - 1)
   30.14 +#else
   30.15 +#define LAST_DYNAMIC_VECTOR 0xdf
   30.16 +#define LAST_DEVICE_VECTOR	(LAST_DYNAMIC_VECTOR)
   30.17 +#endif
   30.18 +
   30.19  #define MSI_TARGET_CPU_SHIFT	12
   30.20  
   30.21  extern struct msi_ops msi_apic_ops;
   30.22 -
   30.23  static inline int msi_arch_init(void)
   30.24  {
   30.25  	msi_register(&msi_apic_ops);
    31.1 --- a/include/linux/pci.h	Thu Apr 24 14:08:54 2008 -0600
    31.2 +++ b/include/linux/pci.h	Tue May 13 10:38:04 2008 +0900
    31.3 @@ -152,6 +152,9 @@ struct pci_dev {
    31.4  	 * directly, use the values stored here. They might be different!
    31.5  	 */
    31.6  	unsigned int	irq;
    31.7 +#ifdef CONFIG_XEN
    31.8 +	unsigned int    irq_old;
    31.9 +#endif
   31.10  	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
   31.11  
   31.12  	/* These fields are used by common fixups */
    32.1 --- a/include/xen/evtchn.h	Thu Apr 24 14:08:54 2008 -0600
    32.2 +++ b/include/xen/evtchn.h	Tue May 13 10:38:04 2008 +0900
    32.3 @@ -136,4 +136,18 @@ static inline void notify_remote_via_evt
    32.4  void notify_remote_via_irq(int irq);
    32.5  int irq_to_evtchn_port(int irq);
    32.6  
    32.7 +#define PIRQ_SET_MAPPING 0x0
    32.8 +#define PIRQ_CLEAR_MAPPING 0x1
    32.9 +#define PIRQ_GET_MAPPING 0x3
   32.10 +int pirq_mapstatus(int pirq, int action);
   32.11 +int set_pirq_hw_action(int pirq, int (*action)(int pirq, int action));
   32.12 +int clear_pirq_hw_action(int pirq);
   32.13 +
   32.14 +#define PIRQ_STARTUP 1
   32.15 +#define PIRQ_SHUTDOWN 2
   32.16 +#define PIRQ_ENABLE 3
   32.17 +#define PIRQ_DISABLE 4
   32.18 +#define PIRQ_END 5
   32.19 +#define PIRQ_ACK 6
   32.20 +
   32.21  #endif /* __ASM_EVTCHN_H__ */
    33.1 --- a/include/xen/interface/arch-ia64.h	Thu Apr 24 14:08:54 2008 -0600
    33.2 +++ b/include/xen/interface/arch-ia64.h	Tue May 13 10:38:04 2008 +0900
    33.3 @@ -68,6 +68,10 @@ typedef unsigned long xen_pfn_t;
    33.4  /* WARNING: before changing this, check that shared_info fits on a page */
    33.5  #define MAX_VIRT_CPUS 64
    33.6  
    33.7 +/* IO ports location for PV.  */
    33.8 +#define IO_PORTS_PADDR          0x00000ffffc000000UL
    33.9 +#define IO_PORTS_SIZE           0x0000000004000000UL
   33.10 +
   33.11  #ifndef __ASSEMBLY__
   33.12  
   33.13  typedef unsigned long xen_ulong_t;
   33.14 @@ -80,54 +84,6 @@ typedef unsigned long xen_ulong_t;
   33.15  
   33.16  #define INVALID_MFN       (~0UL)
   33.17  
   33.18 -#define MEM_G   (1UL << 30)
   33.19 -#define MEM_M   (1UL << 20)
   33.20 -#define MEM_K   (1UL << 10)
   33.21 -
   33.22 -/* Guest physical address of IO ports space.  */
   33.23 -#define IO_PORTS_PADDR          0x00000ffffc000000UL
   33.24 -#define IO_PORTS_SIZE           0x0000000004000000UL
   33.25 -
   33.26 -#define MMIO_START       (3 * MEM_G)
   33.27 -#define MMIO_SIZE        (512 * MEM_M)
   33.28 -
   33.29 -#define VGA_IO_START     0xA0000UL
   33.30 -#define VGA_IO_SIZE      0x20000
   33.31 -
   33.32 -#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
   33.33 -#define LEGACY_IO_SIZE   (64*MEM_M)
   33.34 -
   33.35 -#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
   33.36 -#define IO_PAGE_SIZE  XEN_PAGE_SIZE
   33.37 -
   33.38 -#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
   33.39 -#define STORE_PAGE_SIZE  XEN_PAGE_SIZE
   33.40 -
   33.41 -#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE)
   33.42 -#define BUFFER_IO_PAGE_SIZE  XEN_PAGE_SIZE
   33.43 -
   33.44 -#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
   33.45 -#define BUFFER_PIO_PAGE_SIZE  XEN_PAGE_SIZE
   33.46 -
   33.47 -#define IO_SAPIC_START   0xfec00000UL
   33.48 -#define IO_SAPIC_SIZE    0x100000
   33.49 -
   33.50 -#define PIB_START 0xfee00000UL
   33.51 -#define PIB_SIZE 0x200000
   33.52 -
   33.53 -#define GFW_START        (4*MEM_G -16*MEM_M)
   33.54 -#define GFW_SIZE         (16*MEM_M)
   33.55 -
   33.56 -/* Nvram belongs to GFW memory space  */
   33.57 -#define NVRAM_SIZE       (MEM_K * 64)
   33.58 -#define NVRAM_START      (GFW_START + 10 * MEM_M)
   33.59 -
   33.60 -#define NVRAM_VALID_SIG 0x4650494e45584948 		// "HIXENIPF"
   33.61 -struct nvram_save_addr {
   33.62 -    unsigned long addr;
   33.63 -    unsigned long signature;
   33.64 -};
   33.65 -
   33.66  struct pt_fpreg {
   33.67      union {
   33.68          unsigned long bits[2];
   33.69 @@ -509,6 +465,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
   33.70  /* Internal only: associated with PGC_allocated bit */
   33.71  #define _ASSIGN_pgc_allocated           3
   33.72  #define ASSIGN_pgc_allocated            (1UL << _ASSIGN_pgc_allocated)
   33.73 +/* Page is an IO page.  */
   33.74 +#define _ASSIGN_io                      4
   33.75 +#define ASSIGN_io                       (1UL << _ASSIGN_io)
   33.76  
   33.77  /* This structure has the same layout of struct ia64_boot_param, defined in
   33.78     <asm/system.h>.  It is redefined here to ease use.  */
   33.79 @@ -644,6 +603,10 @@ DEFINE_XEN_GUEST_HANDLE(pfarg_load_t);
   33.80  #endif /* __ASSEMBLY__ */
   33.81  #endif /* XEN */
   33.82  
   33.83 +#ifndef __ASSEMBLY__
   33.84 +#include "arch-ia64/hvm/memmap.h"
   33.85 +#endif
   33.86 +
   33.87  #endif /* __HYPERVISOR_IF_IA64_H__ */
   33.88  
   33.89  /*
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/include/xen/interface/arch-ia64/hvm/memmap.h	Tue May 13 10:38:04 2008 +0900
    34.3 @@ -0,0 +1,88 @@
    34.4 +/******************************************************************************
    34.5 + * memmap.h
    34.6 + *
    34.7 + * Copyright (c) 2008 Tristan Gingold <tgingold AT free fr>
    34.8 + *
    34.9 + * This program is free software; you can redistribute it and/or modify
   34.10 + * it under the terms of the GNU General Public License as published by
   34.11 + * the Free Software Foundation; either version 2 of the License, or
   34.12 + * (at your option) any later version.
   34.13 + *
   34.14 + * This program is distributed in the hope that it will be useful,
   34.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.17 + * GNU General Public License for more details.
   34.18 + *
   34.19 + * You should have received a copy of the GNU General Public License
   34.20 + * along with this program; if not, write to the Free Software
   34.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   34.22 + *
   34.23 + */
   34.24 +
   34.25 +#ifndef __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
   34.26 +#define __XEN_PUBLIC_HVM_MEMMAP_IA64_H__
   34.27 +
   34.28 +#define MEM_G  (1UL << 30)
   34.29 +#define MEM_M  (1UL << 20)
   34.30 +#define MEM_K  (1UL << 10)
   34.31 +
   34.32 +/* Guest physical address of IO ports space.  */
   34.33 +#define MMIO_START  (3 * MEM_G)
   34.34 +#define MMIO_SIZE   (512 * MEM_M)
   34.35 +
   34.36 +#define VGA_IO_START  0xA0000UL
   34.37 +#define VGA_IO_SIZE   0x20000
   34.38 +
   34.39 +#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
   34.40 +#define LEGACY_IO_SIZE   (64 * MEM_M)
   34.41 +
   34.42 +#define IO_PAGE_START  (LEGACY_IO_START + LEGACY_IO_SIZE)
   34.43 +#define IO_PAGE_SIZE   XEN_PAGE_SIZE
   34.44 +
   34.45 +#define STORE_PAGE_START  (IO_PAGE_START + IO_PAGE_SIZE)
   34.46 +#define STORE_PAGE_SIZE   XEN_PAGE_SIZE
   34.47 +
   34.48 +#define BUFFER_IO_PAGE_START  (STORE_PAGE_START + STORE_PAGE_SIZE)
   34.49 +#define BUFFER_IO_PAGE_SIZE   XEN_PAGE_SIZE
   34.50 +
   34.51 +#define BUFFER_PIO_PAGE_START  (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)
   34.52 +#define BUFFER_PIO_PAGE_SIZE   XEN_PAGE_SIZE
   34.53 +
   34.54 +#define IO_SAPIC_START  0xfec00000UL
   34.55 +#define IO_SAPIC_SIZE   0x100000
   34.56 +
   34.57 +#define PIB_START  0xfee00000UL
   34.58 +#define PIB_SIZE   0x200000
   34.59 +
   34.60 +#define GFW_START  (4 * MEM_G - 16 * MEM_M)
   34.61 +#define GFW_SIZE   (16 * MEM_M)
   34.62 +
   34.63 +/* domVTI */
   34.64 +#define GPFN_FRAME_BUFFER  0x1 /* VGA framebuffer */
   34.65 +#define GPFN_LOW_MMIO      0x2 /* Low MMIO range */
   34.66 +#define GPFN_PIB           0x3 /* PIB base */
   34.67 +#define GPFN_IOSAPIC       0x4 /* IOSAPIC base */
   34.68 +#define GPFN_LEGACY_IO     0x5 /* Legacy I/O base */
   34.69 +#define GPFN_HIGH_MMIO     0x6 /* High MMIO range */
   34.70 +
   34.71 +/* Nvram belongs to GFW memory space  */
   34.72 +#define NVRAM_SIZE   (MEM_K * 64)
   34.73 +#define NVRAM_START  (GFW_START + 10 * MEM_M)
   34.74 +
   34.75 +#define NVRAM_VALID_SIG  0x4650494e45584948 /* "HIXENIPF" */
   34.76 +struct nvram_save_addr {
   34.77 +    unsigned long addr;
   34.78 +    unsigned long signature;
   34.79 +};
   34.80 +
   34.81 +#endif /* __XEN_PUBLIC_HVM_MEMMAP_IA64_H__ */
   34.82 +
   34.83 +/*
   34.84 + * Local variables:
   34.85 + * mode: C
   34.86 + * c-set-style: "BSD"
   34.87 + * c-basic-offset: 4
   34.88 + * tab-width: 4
   34.89 + * indent-tabs-mode: nil
   34.90 + * End:
   34.91 + */
    35.1 --- a/include/xen/interface/arch-ia64/sioemu.h	Thu Apr 24 14:08:54 2008 -0600
    35.2 +++ b/include/xen/interface/arch-ia64/sioemu.h	Tue May 13 10:38:04 2008 +0900
    35.3 @@ -22,6 +22,9 @@
    35.4  #ifndef __XEN_PUBLIC_IA64_SIOEMU_H__
    35.5  #define __XEN_PUBLIC_IA64_SIOEMU_H__
    35.6  
    35.7 +/* SIOEMU specific hypercalls.
    35.8 +   The numbers are the minor part of FW_HYPERCALL_SIOEMU.  */
    35.9 +
   35.10  /* Defines the callback entry point.  r8=ip, r9=data.
   35.11     Must be called per-vcpu.  */
   35.12  #define SIOEMU_HYPERCALL_SET_CALLBACK 0x01
   35.13 @@ -35,8 +38,52 @@
   35.14  /* Get wallclock time.  */
   35.15  #define SIOEMU_HYPERCALL_GET_TIME 0x04
   35.16  
   35.17 -/* Return from callback.  r16=0.
   35.18 -   Unmask vcpu events.  */
   35.19 -#define SIOEMU_HYPERPRIVOP_CALLBACK_RETURN 0x01
   35.20 +/* Flush cache.  */
   35.21 +#define SIOEMU_HYPERCALL_FLUSH_CACHE 0x07
   35.22  
   35.23 +/* Get freq base.  */
   35.24 +#define SIOEMU_HYPERCALL_FREQ_BASE 0x08
   35.25 +
   35.26 +/* Return from callback.  */
   35.27 +#define SIOEMU_HYPERCALL_CALLBACK_RETURN 0x09
   35.28 +
   35.29 +/* Deliver an interrupt.  */
   35.30 +#define SIOEMU_HYPERCALL_DELIVER_INT 0x0a
   35.31 +
   35.32 +/* SIOEMU callback reason.  */
   35.33 +
   35.34 +/* An event (from event channel) has to be delivered.  */
   35.35 +#define SIOEMU_CB_EVENT       0x00
   35.36 +
   35.37 +/* Emulate an IO access.  */
   35.38 +#define SIOEMU_CB_IO_EMULATE  0x01
   35.39 +
   35.40 +/* An IPI is sent to a dead vcpu.  */
   35.41 +#define SIOEMU_CB_WAKEUP_VCPU 0x02
   35.42 +
   35.43 +/* A SAL hypercall is executed.  */
   35.44 +#define SIOEMU_CB_SAL_ASSIST  0x03
   35.45 +
   35.46 +#ifndef __ASSEMBLY__
   35.47 +struct sioemu_callback_info {
   35.48 +    /* Saved registers.  */
   35.49 +    unsigned long ip;
   35.50 +    unsigned long psr;
   35.51 +    unsigned long ifs;
   35.52 +    unsigned long nats;
   35.53 +    unsigned long r8;
   35.54 +    unsigned long r9;
   35.55 +    unsigned long r10;
   35.56 +    unsigned long r11;
   35.57 +
   35.58 +    /* Callback parameters.  */
   35.59 +    unsigned long cause;
   35.60 +    unsigned long arg0;
   35.61 +    unsigned long arg1;
   35.62 +    unsigned long arg2;
   35.63 +    unsigned long arg3;
   35.64 +    unsigned long _pad2[2];
   35.65 +    unsigned long r2;
   35.66 +};
   35.67 +#endif /* __ASSEMBLY__ */
   35.68  #endif /* __XEN_PUBLIC_IA64_SIOEMU_H__ */
    36.1 --- a/include/xen/interface/arch-x86/xen-x86_32.h	Thu Apr 24 14:08:54 2008 -0600
    36.2 +++ b/include/xen/interface/arch-x86/xen-x86_32.h	Tue May 13 10:38:04 2008 +0900
    36.3 @@ -74,6 +74,7 @@
    36.4  #define MACH2PHYS_VIRT_END_PAE         \
    36.5      mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE)
    36.6  
    36.7 +/* Non-PAE bounds are obsolete. */
    36.8  #define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000
    36.9  #define __MACH2PHYS_VIRT_START_NONPAE  0xFC000000
   36.10  #define __MACH2PHYS_VIRT_END_NONPAE    0xFC400000
   36.11 @@ -84,15 +85,9 @@
   36.12  #define MACH2PHYS_VIRT_END_NONPAE      \
   36.13      mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE)
   36.14  
   36.15 -#ifdef CONFIG_X86_PAE
   36.16  #define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE
   36.17  #define __MACH2PHYS_VIRT_START  __MACH2PHYS_VIRT_START_PAE
   36.18  #define __MACH2PHYS_VIRT_END    __MACH2PHYS_VIRT_END_PAE
   36.19 -#else
   36.20 -#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_NONPAE
   36.21 -#define __MACH2PHYS_VIRT_START  __MACH2PHYS_VIRT_START_NONPAE
   36.22 -#define __MACH2PHYS_VIRT_END    __MACH2PHYS_VIRT_END_NONPAE
   36.23 -#endif
   36.24  
   36.25  #ifndef HYPERVISOR_VIRT_START
   36.26  #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
    37.1 --- a/include/xen/interface/domctl.h	Thu Apr 24 14:08:54 2008 -0600
    37.2 +++ b/include/xen/interface/domctl.h	Tue May 13 10:38:04 2008 +0900
    37.3 @@ -454,7 +454,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_assig
    37.4  #define XEN_DOMCTL_unbind_pt_irq     48
    37.5  typedef enum pt_irq_type_e {
    37.6      PT_IRQ_TYPE_PCI,
    37.7 -    PT_IRQ_TYPE_ISA
    37.8 +    PT_IRQ_TYPE_ISA,
    37.9 +    PT_IRQ_TYPE_MSI,
   37.10  } pt_irq_type_t;
   37.11  struct xen_domctl_bind_pt_irq {
   37.12      uint32_t machine_irq;
   37.13 @@ -470,6 +471,10 @@ struct xen_domctl_bind_pt_irq {
   37.14              uint8_t device;
   37.15              uint8_t intx;
   37.16          } pci;
   37.17 +        struct {
   37.18 +            uint8_t gvec;
   37.19 +            uint32_t gflags;
   37.20 +        } msi;
   37.21      } u;
   37.22  };
   37.23  typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t;
   37.24 @@ -571,6 +576,19 @@ struct xen_domctl_set_target {
   37.25  typedef struct xen_domctl_set_target xen_domctl_set_target_t;
   37.26  DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_target_t);
   37.27  
   37.28 +#if defined(__i386__) || defined(__x86_64__)
   37.29 +# define XEN_CPUID_INPUT_UNUSED  0xFFFFFFFF
   37.30 +# define XEN_DOMCTL_set_cpuid 49
   37.31 +struct xen_domctl_cpuid {
   37.32 +  unsigned int  input[2];
   37.33 +  unsigned int  eax;
   37.34 +  unsigned int  ebx;
   37.35 +  unsigned int  ecx;
   37.36 +  unsigned int  edx;
   37.37 +};
   37.38 +typedef struct xen_domctl_cpuid xen_domctl_cpuid_t;
   37.39 +DEFINE_XEN_GUEST_HANDLE(xen_domctl_cpuid_t);
   37.40 +#endif
   37.41  
   37.42  struct xen_domctl {
   37.43      uint32_t cmd;
   37.44 @@ -609,6 +627,9 @@ struct xen_domctl {
   37.45          struct xen_domctl_ext_vcpucontext   ext_vcpucontext;
   37.46          struct xen_domctl_set_opt_feature   set_opt_feature;
   37.47          struct xen_domctl_set_target        set_target;
   37.48 +#if defined(__i386__) || defined(__x86_64__)
   37.49 +        struct xen_domctl_cpuid             cpuid;
   37.50 +#endif
   37.51          uint8_t                             pad[128];
   37.52      } u;
   37.53  };
    38.1 --- a/include/xen/interface/hvm/hvm_op.h	Thu Apr 24 14:08:54 2008 -0600
    38.2 +++ b/include/xen/interface/hvm/hvm_op.h	Tue May 13 10:38:04 2008 +0900
    38.3 @@ -73,4 +73,20 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_
    38.4  /* Flushes all VCPU TLBs: @arg must be NULL. */
    38.5  #define HVMOP_flush_tlbs          5
    38.6  
    38.7 +/* Track dirty VRAM. */
    38.8 +#define HVMOP_track_dirty_vram    6
    38.9 +struct xen_hvm_track_dirty_vram {
   38.10 +    /* Domain to be tracked. */
   38.11 +    domid_t  domid;
   38.12 +    /* First pfn to track. */
   38.13 +    uint64_aligned_t first_pfn;
   38.14 +    /* Number of pages to track. */
   38.15 +    uint64_aligned_t nr;
   38.16 +    /* OUT variable. */
   38.17 +    /* Dirty bitmap buffer. */
   38.18 +    XEN_GUEST_HANDLE_64(uint8) dirty_bitmap;
   38.19 +};
   38.20 +typedef struct xen_hvm_track_dirty_vram xen_hvm_track_dirty_vram_t;
   38.21 +DEFINE_XEN_GUEST_HANDLE(xen_hvm_track_dirty_vram_t);
   38.22 +
   38.23  #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
    39.1 --- a/include/xen/interface/hvm/params.h	Thu Apr 24 14:08:54 2008 -0600
    39.2 +++ b/include/xen/interface/hvm/params.h	Tue May 13 10:38:04 2008 +0900
    39.3 @@ -84,6 +84,12 @@
    39.4  /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
    39.5  #define HVM_PARAM_HPET_ENABLED 11
    39.6  
    39.7 -#define HVM_NR_PARAMS          12
    39.8 +/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
    39.9 +#define HVM_PARAM_IDENT_PT     12
   39.10 +
   39.11 +/* Device Model domain, defaults to 0. */
   39.12 +#define HVM_PARAM_DM_DOMAIN    13
   39.13 +
   39.14 +#define HVM_NR_PARAMS          14
   39.15  
   39.16  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
    40.1 --- a/include/xen/interface/io/protocols.h	Thu Apr 24 14:08:54 2008 -0600
    40.2 +++ b/include/xen/interface/io/protocols.h	Tue May 13 10:38:04 2008 +0900
    40.3 @@ -26,7 +26,6 @@
    40.4  #define XEN_IO_PROTO_ABI_X86_32     "x86_32-abi"
    40.5  #define XEN_IO_PROTO_ABI_X86_64     "x86_64-abi"
    40.6  #define XEN_IO_PROTO_ABI_IA64       "ia64-abi"
    40.7 -#define XEN_IO_PROTO_ABI_POWERPC64  "powerpc64-abi"
    40.8  
    40.9  #if defined(__i386__)
   40.10  # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
   40.11 @@ -34,8 +33,6 @@
   40.12  # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
   40.13  #elif defined(__ia64__)
   40.14  # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
   40.15 -#elif defined(__powerpc64__)
   40.16 -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
   40.17  #else
   40.18  # error arch fixup needed here
   40.19  #endif
    41.1 --- a/include/xen/interface/io/xs_wire.h	Thu Apr 24 14:08:54 2008 -0600
    41.2 +++ b/include/xen/interface/io/xs_wire.h	Tue May 13 10:38:04 2008 +0900
    41.3 @@ -61,6 +61,7 @@ struct xsd_errors
    41.4      const char *errstring;
    41.5  };
    41.6  #define XSD_ERROR(x) { x, #x }
    41.7 +/* LINTED: static unused */
    41.8  static struct xsd_errors xsd_errors[]
    41.9  #if defined(__GNUC__)
   41.10  __attribute__((unused))
    42.1 --- a/include/xen/interface/libelf.h	Thu Apr 24 14:08:54 2008 -0600
    42.2 +++ b/include/xen/interface/libelf.h	Tue May 13 10:38:04 2008 +0900
    42.3 @@ -23,10 +23,8 @@
    42.4  #ifndef __XC_LIBELF__
    42.5  #define __XC_LIBELF__ 1
    42.6  
    42.7 -#if defined(__i386__) || defined(__x86_64) || defined(__ia64__)
    42.8 +#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
    42.9  #define XEN_ELF_LITTLE_ENDIAN
   42.10 -#elif defined(__powerpc__)
   42.11 -#define XEN_ELF_BIG_ENDIAN
   42.12  #else
   42.13  #error define architectural endianness
   42.14  #endif
    43.1 --- a/include/xen/interface/physdev.h	Thu Apr 24 14:08:54 2008 -0600
    43.2 +++ b/include/xen/interface/physdev.h	Tue May 13 10:38:04 2008 +0900
    43.3 @@ -121,6 +121,38 @@ struct physdev_irq {
    43.4  };
    43.5  typedef struct physdev_irq physdev_irq_t;
    43.6  DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
    43.7 + 
    43.8 +#define MAP_PIRQ_TYPE_MSI               0x0
    43.9 +#define MAP_PIRQ_TYPE_GSI               0x1
   43.10 +#define MAP_PIRQ_TYPE_UNKNOWN           0x2
   43.11 +
   43.12 +#define PHYSDEVOP_map_pirq               13
   43.13 +struct physdev_map_pirq {
   43.14 +    domid_t domid;
   43.15 +    /* IN */
   43.16 +    int type;
   43.17 +    /* IN */
   43.18 +    int index;
   43.19 +    /* IN or OUT */
   43.20 +    int pirq;
   43.21 +    /* IN */
   43.22 +    struct {
   43.23 +        int bus, devfn, entry_nr;
   43.24 +		int msi;  /* 0 - MSIX    1 - MSI */
   43.25 +    } msi_info;
   43.26 +};
   43.27 +typedef struct physdev_map_pirq physdev_map_pirq_t;
   43.28 +DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
   43.29 +
   43.30 +#define PHYSDEVOP_unmap_pirq             14
   43.31 +struct physdev_unmap_pirq {
   43.32 +    domid_t domid;
   43.33 +    /* IN */
   43.34 +    int pirq;
   43.35 +};
   43.36 +
   43.37 +typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
   43.38 +DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
   43.39  
   43.40  /*
   43.41   * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
    44.1 --- a/include/xen/interface/platform.h	Thu Apr 24 14:08:54 2008 -0600
    44.2 +++ b/include/xen/interface/platform.h	Tue May 13 10:38:04 2008 +0900
    44.3 @@ -199,6 +199,70 @@ struct xenpf_getidletime {
    44.4  typedef struct xenpf_getidletime xenpf_getidletime_t;
    44.5  DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
    44.6  
    44.7 +#define XENPF_set_processor_pminfo      54
    44.8 +
    44.9 +/* ability bits */
   44.10 +#define XEN_PROCESSOR_PM_CX	1
   44.11 +#define XEN_PROCESSOR_PM_PX	2
   44.12 +#define XEN_PROCESSOR_PM_TX	4
   44.13 +
   44.14 +/* cmd type */
   44.15 +#define XEN_PM_CX   0
   44.16 +#define XEN_PM_PX   1
   44.17 +#define XEN_PM_TX   2
   44.18 +
   44.19 +struct xen_power_register {
   44.20 +    uint32_t     space_id;
   44.21 +    uint32_t     bit_width;
   44.22 +    uint32_t     bit_offset;
   44.23 +    uint32_t     access_size;
   44.24 +    uint64_t     address;
   44.25 +};
   44.26 +
   44.27 +struct xen_processor_csd {
   44.28 +    uint32_t    domain;      /* domain number of one dependent group */
   44.29 +    uint32_t    coord_type;  /* coordination type */
   44.30 +    uint32_t    num;         /* number of processors in same domain */
   44.31 +};
   44.32 +typedef struct xen_processor_csd xen_processor_csd_t;
   44.33 +DEFINE_XEN_GUEST_HANDLE(xen_processor_csd_t);
   44.34 +
   44.35 +struct xen_processor_cx {
   44.36 +    struct xen_power_register  reg; /* GAS for Cx trigger register */
   44.37 +    uint8_t     type;     /* cstate value, c0: 0, c1: 1, ... */
   44.38 +    uint32_t    latency;  /* worst latency (ms) to enter/exit this cstate */
   44.39 +    uint32_t    power;    /* average power consumption(mW) */
   44.40 +    uint32_t    dpcnt;    /* number of dependency entries */
   44.41 +    XEN_GUEST_HANDLE(xen_processor_csd_t) dp; /* NULL if no dependency */
   44.42 +};
   44.43 +typedef struct xen_processor_cx xen_processor_cx_t;
   44.44 +DEFINE_XEN_GUEST_HANDLE(xen_processor_cx_t);
   44.45 +
   44.46 +struct xen_processor_flags {
   44.47 +    uint32_t bm_control:1;
   44.48 +    uint32_t bm_check:1;
   44.49 +    uint32_t has_cst:1;
   44.50 +    uint32_t power_setup_done:1;
   44.51 +    uint32_t bm_rld_set:1;
   44.52 +};
   44.53 +
   44.54 +struct xen_processor_power {
   44.55 +    uint32_t count;  /* number of C state entries in array below */
   44.56 +    struct xen_processor_flags flags;  /* global flags of this processor */
   44.57 +    XEN_GUEST_HANDLE(xen_processor_cx_t) states; /* supported c states */
   44.58 +};
   44.59 +
   44.60 +struct xenpf_set_processor_pminfo {
   44.61 +    /* IN variables */
   44.62 +    uint32_t id;    /* ACPI CPU ID */
   44.63 +    uint32_t type;  /* {XEN_PM_CX, ...} */
   44.64 +    union {
   44.65 +        struct xen_processor_power          power;/* Cx: _CST/_CSD */
   44.66 +    };
   44.67 +};
   44.68 +typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
   44.69 +DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);
   44.70 +
   44.71  struct xen_platform_op {
   44.72      uint32_t cmd;
   44.73      uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
   44.74 @@ -213,6 +277,7 @@ struct xen_platform_op {
   44.75          struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
   44.76          struct xenpf_change_freq       change_freq;
   44.77          struct xenpf_getidletime       getidletime;
   44.78 +        struct xenpf_set_processor_pminfo set_pminfo;
   44.79          uint8_t                        pad[128];
   44.80      } u;
   44.81  };
    45.1 --- a/include/xen/interface/sysctl.h	Thu Apr 24 14:08:54 2008 -0600
    45.2 +++ b/include/xen/interface/sysctl.h	Tue May 13 10:38:04 2008 +0900
    45.3 @@ -84,8 +84,13 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_
    45.4   * Get physical information about the host machine
    45.5   */
    45.6  #define XEN_SYSCTL_physinfo          3
    45.7 + /* (x86) The platform supports HVM guests. */
    45.8 +#define _XEN_SYSCTL_PHYSCAP_hvm          0
    45.9 +#define XEN_SYSCTL_PHYSCAP_hvm           (1u<<_XEN_SYSCTL_PHYSCAP_hvm)
   45.10 + /* (x86) The platform supports HVM-guest direct access to I/O devices. */
   45.11 +#define _XEN_SYSCTL_PHYSCAP_hvm_directio 1
   45.12 +#define XEN_SYSCTL_PHYSCAP_hvm_directio  (1u<<_XEN_SYSCTL_PHYSCAP_hvm_directio)
   45.13  struct xen_sysctl_physinfo {
   45.14 -    /* IN variables. */
   45.15      uint32_t threads_per_core;
   45.16      uint32_t cores_per_socket;
   45.17      uint32_t nr_cpus;
   45.18 @@ -96,7 +101,6 @@ struct xen_sysctl_physinfo {
   45.19      uint64_aligned_t scrub_pages;
   45.20      uint32_t hw_cap[8];
   45.21  
   45.22 -    /* IN/OUT variables. */
   45.23      /*
   45.24       * IN: maximum addressable entry in the caller-provided cpu_to_node array.
   45.25       * OUT: largest cpu identifier in the system.
   45.26 @@ -112,6 +116,9 @@ struct xen_sysctl_physinfo {
   45.27       * elements of the array will not be written by the sysctl.
   45.28       */
   45.29      XEN_GUEST_HANDLE_64(uint32) cpu_to_node;
   45.30 +
   45.31 +    /* XEN_SYSCTL_PHYSCAP_??? */
   45.32 +    uint32_t capabilities;
   45.33  };
   45.34  typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t;
   45.35  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t);
    46.1 --- a/include/xen/interface/xen.h	Thu Apr 24 14:08:54 2008 -0600
    46.2 +++ b/include/xen/interface/xen.h	Tue May 13 10:38:04 2008 +0900
    46.3 @@ -33,8 +33,6 @@
    46.4  #include "arch-x86/xen.h"
    46.5  #elif defined(__ia64__)
    46.6  #include "arch-ia64.h"
    46.7 -#elif defined(__powerpc__)
    46.8 -#include "arch-powerpc.h"
    46.9  #else
   46.10  #error "Unsupported architecture"
   46.11  #endif
    47.1 --- a/include/xen/interface/xsm/acm.h	Thu Apr 24 14:08:54 2008 -0600
    47.2 +++ b/include/xen/interface/xsm/acm.h	Tue May 13 10:38:04 2008 +0900
    47.3 @@ -91,7 +91,7 @@
    47.4   * whenever the interpretation of the related
    47.5   * policy's data structure changes
    47.6   */
    47.7 -#define ACM_POLICY_VERSION 3
    47.8 +#define ACM_POLICY_VERSION 4
    47.9  #define ACM_CHWALL_VERSION 1
   47.10  #define ACM_STE_VERSION  1
   47.11  
   47.12 @@ -102,6 +102,7 @@ typedef uint32_t ssidref_t;
   47.13  #define ACMHOOK_none          0
   47.14  #define ACMHOOK_sharing       1
   47.15  #define ACMHOOK_authorization 2
   47.16 +#define ACMHOOK_conflictset   3
   47.17  
   47.18  /* -------security policy relevant type definitions-------- */
   47.19  
   47.20 @@ -130,6 +131,10 @@ typedef uint16_t domaintype_t;
   47.21  /* high-16 = version, low-16 = check magic */
   47.22  #define ACM_MAGIC  0x0001debc
   47.23  
   47.24 +/* size of the SHA1 hash identifying the XML policy from which the
   47.25 +   binary policy was created */
   47.26 +#define ACM_SHA1_HASH_SIZE    20
   47.27 +
   47.28  /* each offset in bytes from start of the struct they
   47.29   * are part of */
   47.30  
   47.31 @@ -159,6 +164,7 @@ struct acm_policy_buffer {
   47.32      uint32_t secondary_policy_code;
   47.33      uint32_t secondary_buffer_offset;
   47.34      struct acm_policy_version xml_pol_version; /* add in V3 */
   47.35 +    uint8_t xml_policy_hash[ACM_SHA1_HASH_SIZE]; /* added in V4 */
   47.36  };
   47.37  
   47.38