diff options
Diffstat (limited to 'drivers/xen')
| -rw-r--r-- | drivers/xen/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/xen/Makefile | 7 | ||||
| -rw-r--r-- | drivers/xen/balloon.c | 5 | ||||
| -rw-r--r-- | drivers/xen/privcmd.c | 72 | ||||
| -rw-r--r-- | drivers/xen/swiotlb-xen.c | 25 | ||||
| -rw-r--r-- | drivers/xen/xen-acpi-pad.c | 182 | ||||
| -rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 120 | ||||
| -rw-r--r-- | drivers/xen/xen-selfballoon.c | 2 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 1 | 
9 files changed, 340 insertions, 77 deletions
| diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 126d8ce591ce..cabfa97f4674 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -206,4 +206,7 @@ config XEN_MCE_LOG  	  Allow kernel fetching MCE error from Xen platform and  	  converting it into Linux mcelog format for mcelog tools +config XEN_HAVE_PVMMU +       bool +  endmenu diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 74354708c6c4..fb213cf81a7b 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -1,9 +1,9 @@  ifneq ($(CONFIG_ARM),y) -obj-y	+= manage.o balloon.o +obj-y	+= manage.o  obj-$(CONFIG_HOTPLUG_CPU)		+= cpu_hotplug.o  endif  obj-$(CONFIG_X86)			+= fallback.o -obj-y	+= grant-table.o features.o events.o +obj-y	+= grant-table.o features.o events.o balloon.o  obj-y	+= xenbus/  nostackp := $(call cc-option, -fno-stack-protector) @@ -11,7 +11,8 @@ CFLAGS_features.o			:= $(nostackp)  dom0-$(CONFIG_PCI) += pci.o  dom0-$(CONFIG_USB_SUPPORT) += dbgp.o -dom0-$(CONFIG_ACPI) += acpi.o +dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y) +xen-pad-$(CONFIG_X86) += xen-acpi-pad.o  dom0-$(CONFIG_X86) += pcpu.o  obj-$(CONFIG_XEN_DOM0)			+= $(dom0-y)  obj-$(CONFIG_BLOCK)			+= biomerge.o diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index d6886d90ccfd..a56776dbe095 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -359,6 +359,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)  		set_phys_to_machine(pfn, frame_list[i]); +#ifdef CONFIG_XEN_HAVE_PVMMU  		/* Link back into the page tables if not highmem. */  		if (xen_pv_domain() && !PageHighMem(page)) {  			int ret; @@ -368,6 +369,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)  				0);  			BUG_ON(ret);  		} +#endif  		/* Relinquish the page back to the allocator. */  		ClearPageReserved(page); @@ -416,13 +418,14 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)  		scrub_page(page); +#ifdef CONFIG_XEN_HAVE_PVMMU  		if (xen_pv_domain() && !PageHighMem(page)) {  			ret = HYPERVISOR_update_va_mapping(  				(unsigned long)__va(pfn << PAGE_SHIFT),  				__pte_ma(0), 0);  			BUG_ON(ret);  		} - +#endif  	}  	/* Ensure that ballooned highmem pages don't have kmaps. */ diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 71f5c459b088..0bbbccbb1f12 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -33,11 +33,14 @@  #include <xen/features.h>  #include <xen/page.h>  #include <xen/xen-ops.h> +#include <xen/balloon.h>  #include "privcmd.h"  MODULE_LICENSE("GPL"); +#define PRIV_VMA_LOCKED ((void *)1) +  #ifndef HAVE_ARCH_PRIVCMD_MMAP  static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);  #endif @@ -178,7 +181,7 @@ static int mmap_mfn_range(void *data, void *state)  					msg->va & PAGE_MASK,  					msg->mfn, msg->npages,  					vma->vm_page_prot, -					st->domain); +					st->domain, NULL);  	if (rc < 0)  		return rc; @@ -199,6 +202,10 @@ static long privcmd_ioctl_mmap(void __user *udata)  	if (!xen_initial_domain())  		return -EPERM; +	/* We only support privcmd_ioctl_mmap_batch for auto translated. */ +	if (xen_feature(XENFEAT_auto_translated_physmap)) +		return -ENOSYS; +  	if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))  		return -EFAULT; @@ -246,6 +253,7 @@ struct mmap_batch_state {  	domid_t domain;  	unsigned long va;  	struct vm_area_struct *vma; +	int index;  	/* A tristate:  	 *      0 for no errors  	 *      1 if at least one error has happened (and no @@ -260,14 +268,24 @@ struct mmap_batch_state {  	xen_pfn_t __user *user_mfn;  }; +/* auto translated dom0 note: if domU being created is PV, then mfn is + * mfn(addr on bus). If it's auto xlated, then mfn is pfn (input to HAP). + */  static int mmap_batch_fn(void *data, void *state)  {  	xen_pfn_t *mfnp = data;  	struct mmap_batch_state *st = state; +	struct vm_area_struct *vma = st->vma; +	struct page **pages = vma->vm_private_data; +	struct page *cur_page = NULL;  	int ret; +	if (xen_feature(XENFEAT_auto_translated_physmap)) +		cur_page = pages[st->index++]; +  	ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1, -					 st->vma->vm_page_prot, st->domain); +					 st->vma->vm_page_prot, st->domain, +					 &cur_page);  	/* Store error code for second pass. */  	*(st->err++) = ret; @@ -303,6 +321,32 @@ static int mmap_return_errors_v1(void *data, void *state)  	return __put_user(*mfnp, st->user_mfn++);  } +/* Allocate pfns that are then mapped with gmfns from foreign domid. Update + * the vma with the page info to use later. + * Returns: 0 if success, otherwise -errno + */ +static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs) +{ +	int rc; +	struct page **pages; + +	pages = kcalloc(numpgs, sizeof(pages[0]), GFP_KERNEL); +	if (pages == NULL) +		return -ENOMEM; + +	rc = alloc_xenballooned_pages(numpgs, pages, 0); +	if (rc != 0) { +		pr_warn("%s Could not alloc %d pfns rc:%d\n", __func__, +			numpgs, rc); +		kfree(pages); +		return -ENOMEM; +	} +	BUG_ON(vma->vm_private_data != PRIV_VMA_LOCKED); +	vma->vm_private_data = pages; + +	return 0; +} +  static struct vm_operations_struct privcmd_vm_ops;  static long privcmd_ioctl_mmap_batch(void __user *udata, int version) @@ -370,10 +414,18 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)  		ret = -EINVAL;  		goto out;  	} +	if (xen_feature(XENFEAT_auto_translated_physmap)) { +		ret = alloc_empty_pages(vma, m.num); +		if (ret < 0) { +			up_write(&mm->mmap_sem); +			goto out; +		} +	}  	state.domain        = m.dom;  	state.vma           = vma;  	state.va            = m.addr; +	state.index         = 0;  	state.global_error  = 0;  	state.err           = err_array; @@ -442,6 +494,19 @@ static long privcmd_ioctl(struct file *file,  	return ret;  } +static void privcmd_close(struct vm_area_struct *vma) +{ +	struct page **pages = vma->vm_private_data; +	int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + +	if (!xen_feature(XENFEAT_auto_translated_physmap || !numpgs || !pages)) +		return; + +	xen_unmap_domain_mfn_range(vma, numpgs, pages); +	free_xenballooned_pages(numpgs, pages); +	kfree(pages); +} +  static int privcmd_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  {  	printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n", @@ -452,6 +517,7 @@ static int privcmd_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  }  static struct vm_operations_struct privcmd_vm_ops = { +	.close = privcmd_close,  	.fault = privcmd_fault  }; @@ -469,7 +535,7 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)  static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)  { -	return (xchg(&vma->vm_private_data, (void *)1) == NULL); +	return !cmpxchg(&vma->vm_private_data, NULL, PRIV_VMA_LOCKED);  }  const struct file_operations xen_privcmd_fops = { diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 58db6df866ef..af47e7594460 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -338,9 +338,8 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,  				enum dma_data_direction dir,  				struct dma_attrs *attrs)  { -	phys_addr_t phys = page_to_phys(page) + offset; +	phys_addr_t map, phys = page_to_phys(page) + offset;  	dma_addr_t dev_addr = xen_phys_to_bus(phys); -	void *map;  	BUG_ON(dir == DMA_NONE);  	/* @@ -356,10 +355,10 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,  	 * Oh well, have to allocate and map a bounce buffer.  	 */  	map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, size, dir); -	if (!map) +	if (map == SWIOTLB_MAP_ERROR)  		return DMA_ERROR_CODE; -	dev_addr = xen_virt_to_bus(map); +	dev_addr = xen_phys_to_bus(map);  	/*  	 * Ensure that the address returned is DMA'ble @@ -389,7 +388,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,  	/* NOTE: We use dev_addr here, not paddr! */  	if (is_xen_swiotlb_buffer(dev_addr)) { -		swiotlb_tbl_unmap_single(hwdev, phys_to_virt(paddr), size, dir); +		swiotlb_tbl_unmap_single(hwdev, paddr, size, dir);  		return;  	} @@ -434,8 +433,7 @@ xen_swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,  	/* NOTE: We use dev_addr here, not paddr! */  	if (is_xen_swiotlb_buffer(dev_addr)) { -		swiotlb_tbl_sync_single(hwdev, phys_to_virt(paddr), size, dir, -				       target); +		swiotlb_tbl_sync_single(hwdev, paddr, size, dir, target);  		return;  	} @@ -494,11 +492,12 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,  		if (swiotlb_force ||  		    !dma_capable(hwdev, dev_addr, sg->length) ||  		    range_straddles_page_boundary(paddr, sg->length)) { -			void *map = swiotlb_tbl_map_single(hwdev, -							   start_dma_addr, -							   sg_phys(sg), -							   sg->length, dir); -			if (!map) { +			phys_addr_t map = swiotlb_tbl_map_single(hwdev, +								 start_dma_addr, +								 sg_phys(sg), +								 sg->length, +								 dir); +			if (map == SWIOTLB_MAP_ERROR) {  				/* Don't panic here, we expect map_sg users  				   to do proper error handling. */  				xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir, @@ -506,7 +505,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,  				sgl[0].dma_length = 0;  				return DMA_ERROR_CODE;  			} -			sg->dma_address = xen_virt_to_bus(map); +			sg->dma_address = xen_phys_to_bus(map);  		} else  			sg->dma_address = dev_addr;  		sg->dma_length = sg->length; diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c new file mode 100644 index 000000000000..da39191e7278 --- /dev/null +++ b/drivers/xen/xen-acpi-pad.c @@ -0,0 +1,182 @@ +/* + * xen-acpi-pad.c - Xen pad interface + * + * Copyright (c) 2012, Intel Corporation. + *    Author: Liu, Jinsong <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <acpi/acpi_bus.h> +#include <acpi/acpi_drivers.h> +#include <asm/xen/hypercall.h> +#include <xen/interface/version.h> +#include <xen/xen-ops.h> + +#define ACPI_PROCESSOR_AGGREGATOR_CLASS	"acpi_pad" +#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" +#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 +static DEFINE_MUTEX(xen_cpu_lock); + +static int xen_acpi_pad_idle_cpus(unsigned int idle_nums) +{ +	struct xen_platform_op op; + +	op.cmd = XENPF_core_parking; +	op.u.core_parking.type = XEN_CORE_PARKING_SET; +	op.u.core_parking.idle_nums = idle_nums; + +	return HYPERVISOR_dom0_op(&op); +} + +static int xen_acpi_pad_idle_cpus_num(void) +{ +	struct xen_platform_op op; + +	op.cmd = XENPF_core_parking; +	op.u.core_parking.type = XEN_CORE_PARKING_GET; + +	return HYPERVISOR_dom0_op(&op) +	       ?: op.u.core_parking.idle_nums; +} + +/* + * Query firmware how many CPUs should be idle + * return -1 on failure + */ +static int acpi_pad_pur(acpi_handle handle) +{ +	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; +	union acpi_object *package; +	int num = -1; + +	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) +		return num; + +	if (!buffer.length || !buffer.pointer) +		return num; + +	package = buffer.pointer; + +	if (package->type == ACPI_TYPE_PACKAGE && +		package->package.count == 2 && +		package->package.elements[0].integer.value == 1) /* rev 1 */ +		num = package->package.elements[1].integer.value; + +	kfree(buffer.pointer); +	return num; +} + +/* Notify firmware how many CPUs are idle */ +static void acpi_pad_ost(acpi_handle handle, int stat, +	uint32_t idle_nums) +{ +	union acpi_object params[3] = { +		{.type = ACPI_TYPE_INTEGER,}, +		{.type = ACPI_TYPE_INTEGER,}, +		{.type = ACPI_TYPE_BUFFER,}, +	}; +	struct acpi_object_list arg_list = {3, params}; + +	params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; +	params[1].integer.value =  stat; +	params[2].buffer.length = 4; +	params[2].buffer.pointer = (void *)&idle_nums; +	acpi_evaluate_object(handle, "_OST", &arg_list, NULL); +} + +static void acpi_pad_handle_notify(acpi_handle handle) +{ +	int idle_nums; + +	mutex_lock(&xen_cpu_lock); +	idle_nums = acpi_pad_pur(handle); +	if (idle_nums < 0) { +		mutex_unlock(&xen_cpu_lock); +		return; +	} + +	idle_nums = xen_acpi_pad_idle_cpus(idle_nums) +		    ?: xen_acpi_pad_idle_cpus_num(); +	if (idle_nums >= 0) +		acpi_pad_ost(handle, 0, idle_nums); +	mutex_unlock(&xen_cpu_lock); +} + +static void acpi_pad_notify(acpi_handle handle, u32 event, +	void *data) +{ +	switch (event) { +	case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: +		acpi_pad_handle_notify(handle); +		break; +	default: +		pr_warn("Unsupported event [0x%x]\n", event); +		break; +	} +} + +static int acpi_pad_add(struct acpi_device *device) +{ +	acpi_status status; + +	strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME); +	strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS); + +	status = acpi_install_notify_handler(device->handle, +		ACPI_DEVICE_NOTIFY, acpi_pad_notify, device); +	if (ACPI_FAILURE(status)) +		return -ENODEV; + +	return 0; +} + +static int acpi_pad_remove(struct acpi_device *device, +	int type) +{ +	mutex_lock(&xen_cpu_lock); +	xen_acpi_pad_idle_cpus(0); +	mutex_unlock(&xen_cpu_lock); + +	acpi_remove_notify_handler(device->handle, +		ACPI_DEVICE_NOTIFY, acpi_pad_notify); +	return 0; +} + +static const struct acpi_device_id pad_device_ids[] = { +	{"ACPI000C", 0}, +	{"", 0}, +}; + +static struct acpi_driver acpi_pad_driver = { +	.name = "processor_aggregator", +	.class = ACPI_PROCESSOR_AGGREGATOR_CLASS, +	.ids = pad_device_ids, +	.ops = { +		.add = acpi_pad_add, +		.remove = acpi_pad_remove, +	}, +}; + +static int __init xen_acpi_pad_init(void) +{ +	/* Only DOM0 is responsible for Xen acpi pad */ +	if (!xen_initial_domain()) +		return -ENODEV; + +	/* Only Xen4.2 or later support Xen acpi pad */ +	if (!xen_running_on_version_or_later(4, 2)) +		return -ENODEV; + +	return acpi_bus_register_driver(&acpi_pad_driver); +} +subsys_initcall(xen_acpi_pad_init); diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 961d664e2d2f..cd50d251998e 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -142,7 +142,8 @@ static struct pcistub_device *pcistub_device_find(int domain, int bus,  		if (psdev->dev != NULL  		    && domain == pci_domain_nr(psdev->dev->bus)  		    && bus == psdev->dev->bus->number -		    && PCI_DEVFN(slot, func) == psdev->dev->devfn) { +		    && slot == PCI_SLOT(psdev->dev->devfn) +		    && func == PCI_FUNC(psdev->dev->devfn)) {  			pcistub_device_get(psdev);  			goto out;  		} @@ -191,7 +192,8 @@ struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,  		if (psdev->dev != NULL  		    && domain == pci_domain_nr(psdev->dev->bus)  		    && bus == psdev->dev->bus->number -		    && PCI_DEVFN(slot, func) == psdev->dev->devfn) { +		    && slot == PCI_SLOT(psdev->dev->devfn) +		    && func == PCI_FUNC(psdev->dev->devfn)) {  			found_dev = pcistub_device_get_pci_dev(pdev, psdev);  			break;  		} @@ -360,7 +362,7 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)  	if (!dev_data->pci_saved_state)  		dev_err(&dev->dev, "Could not store PCI conf saved state!\n");  	else { -		dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); +		dev_dbg(&dev->dev, "resetting (FLR, D3, etc) the device\n");  		__pci_reset_function_locked(dev);  		pci_restore_state(dev);  	} @@ -897,42 +899,35 @@ static struct pci_driver xen_pcibk_pci_driver = {  static inline int str_to_slot(const char *buf, int *domain, int *bus,  			      int *slot, int *func)  { -	int err; -	char wc = '*'; +	int parsed = 0; -	err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func); -	switch (err) { +	switch (sscanf(buf, " %x:%x:%x.%x %n", domain, bus, slot, func, +		       &parsed)) {  	case 3:  		*func = -1; -		err = sscanf(buf, " %x:%x:%x.%c", domain, bus, slot, &wc); +		sscanf(buf, " %x:%x:%x.* %n", domain, bus, slot, &parsed);  		break;  	case 2:  		*slot = *func = -1; -		err = sscanf(buf, " %x:%x:*.%c", domain, bus, &wc); -		if (err >= 2) -			++err; +		sscanf(buf, " %x:%x:*.* %n", domain, bus, &parsed);  		break;  	} -	if (err == 4 && wc == '*') +	if (parsed && !buf[parsed])  		return 0; -	else if (err < 0) -		return -EINVAL;  	/* try again without domain */  	*domain = 0; -	wc = '*'; -	err = sscanf(buf, " %x:%x.%x", bus, slot, func); -	switch (err) { +	switch (sscanf(buf, " %x:%x.%x %n", bus, slot, func, &parsed)) {  	case 2:  		*func = -1; -		err = sscanf(buf, " %x:%x.%c", bus, slot, &wc); +		sscanf(buf, " %x:%x.* %n", bus, slot, &parsed);  		break;  	case 1:  		*slot = *func = -1; -		err = sscanf(buf, " %x:*.%c", bus, &wc) + 1; +		sscanf(buf, " %x:*.* %n", bus, &parsed);  		break;  	} -	if (err == 3 && wc == '*') +	if (parsed && !buf[parsed])  		return 0;  	return -EINVAL; @@ -941,13 +936,20 @@ static inline int str_to_slot(const char *buf, int *domain, int *bus,  static inline int str_to_quirk(const char *buf, int *domain, int *bus, int  			       *slot, int *func, int *reg, int *size, int *mask)  { -	int err; +	int parsed = 0; -	err = -	    sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot, -		   func, reg, size, mask); -	if (err == 7) +	sscanf(buf, " %x:%x:%x.%x-%x:%x:%x %n", domain, bus, slot, func, +	       reg, size, mask, &parsed); +	if (parsed && !buf[parsed])  		return 0; + +	/* try again without domain */ +	*domain = 0; +	sscanf(buf, " %x:%x.%x-%x:%x:%x %n", bus, slot, func, reg, size, +	       mask, &parsed); +	if (parsed && !buf[parsed]) +		return 0; +  	return -EINVAL;  } @@ -955,7 +957,7 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)  {  	struct pcistub_device_id *pci_dev_id;  	unsigned long flags; -	int rc = 0; +	int rc = 0, devfn = PCI_DEVFN(slot, func);  	if (slot < 0) {  		for (slot = 0; !rc && slot < 32; ++slot) @@ -969,13 +971,24 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)  		return rc;  	} +	if (( +#if !defined(MODULE) /* pci_domains_supported is not being exported */ \ +    || !defined(CONFIG_PCI_DOMAINS) +	     !pci_domains_supported ? domain : +#endif +	     domain < 0 || domain > 0xffff) +	    || bus < 0 || bus > 0xff +	    || PCI_SLOT(devfn) != slot +	    || PCI_FUNC(devfn) != func) +		return -EINVAL; +  	pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);  	if (!pci_dev_id)  		return -ENOMEM;  	pci_dev_id->domain = domain;  	pci_dev_id->bus = bus; -	pci_dev_id->devfn = PCI_DEVFN(slot, func); +	pci_dev_id->devfn = devfn;  	pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n",  		 domain, bus, slot, func); @@ -1016,14 +1029,18 @@ static int pcistub_device_id_remove(int domain, int bus, int slot, int func)  	return err;  } -static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg, -			   int size, int mask) +static int pcistub_reg_add(int domain, int bus, int slot, int func, +			   unsigned int reg, unsigned int size, +			   unsigned int mask)  {  	int err = 0;  	struct pcistub_device *psdev;  	struct pci_dev *dev;  	struct config_field *field; +	if (reg > 0xfff || (size < 4 && (mask >> (size * 8)))) +		return -EINVAL; +  	psdev = pcistub_device_find(domain, bus, slot, func);  	if (!psdev) {  		err = -ENODEV; @@ -1254,13 +1271,11 @@ static ssize_t permissive_add(struct device_driver *drv, const char *buf,  	int err;  	struct pcistub_device *psdev;  	struct xen_pcibk_dev_data *dev_data; +  	err = str_to_slot(buf, &domain, &bus, &slot, &func);  	if (err)  		goto out; -	if (slot < 0 || func < 0) { -		err = -EINVAL; -		goto out; -	} +  	psdev = pcistub_device_find(domain, bus, slot, func);  	if (!psdev) {  		err = -ENODEV; @@ -1339,8 +1354,6 @@ static int __init pcistub_init(void)  	if (pci_devs_to_hide && *pci_devs_to_hide) {  		do { -			char wc = '*'; -  			parsed = 0;  			err = sscanf(pci_devs_to_hide + pos, @@ -1349,51 +1362,48 @@ static int __init pcistub_init(void)  			switch (err) {  			case 3:  				func = -1; -				err = sscanf(pci_devs_to_hide + pos, -					     " (%x:%x:%x.%c) %n", -					     &domain, &bus, &slot, &wc, -					     &parsed); +				sscanf(pci_devs_to_hide + pos, +				       " (%x:%x:%x.*) %n", +				       &domain, &bus, &slot, &parsed);  				break;  			case 2:  				slot = func = -1; -				err = sscanf(pci_devs_to_hide + pos, -					     " (%x:%x:*.%c) %n", -					     &domain, &bus, &wc, &parsed) + 1; +				sscanf(pci_devs_to_hide + pos, +				       " (%x:%x:*.*) %n", +				       &domain, &bus, &parsed);  				break;  			} -			if (err != 4 || wc != '*') { +			if (!parsed) {  				domain = 0; -				wc = '*';  				err = sscanf(pci_devs_to_hide + pos,  					     " (%x:%x.%x) %n",  					     &bus, &slot, &func, &parsed);  				switch (err) {  				case 2:  					func = -1; -					err = sscanf(pci_devs_to_hide + pos, -						     " (%x:%x.%c) %n", -						     &bus, &slot, &wc, -						     &parsed); +					sscanf(pci_devs_to_hide + pos, +					       " (%x:%x.*) %n", +					       &bus, &slot, &parsed);  					break;  				case 1:  					slot = func = -1; -					err = sscanf(pci_devs_to_hide + pos, -						     " (%x:*.%c) %n", -						     &bus, &wc, &parsed) + 1; +					sscanf(pci_devs_to_hide + pos, +					       " (%x:*.*) %n", +					       &bus, &parsed);  					break;  				} -				if (err != 3 || wc != '*') -					goto parse_error;  			} +			if (parsed <= 0) +				goto parse_error; +  			err = pcistub_device_id_add(domain, bus, slot, func);  			if (err)  				goto out; -			/* if parsed<=0, we've reached the end of the string */  			pos += parsed; -		} while (parsed > 0 && pci_devs_to_hide[pos]); +		} while (pci_devs_to_hide[pos]);  	}  	/* If we're the first PCI Device Driver to register, we're the diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 7d041cb6da26..2552d3e0a70f 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c @@ -222,7 +222,7 @@ static void selfballoon_process(struct work_struct *work)  	if (xen_selfballooning_enabled) {  		cur_pages = totalram_pages;  		tgt_pages = cur_pages; /* default is no change */ -		goal_pages = percpu_counter_read_positive(&vm_committed_as) + +		goal_pages = vm_memory_committed() +  				totalreserve_pages +  				MB2PAGES(selfballoon_reserved_mb);  #ifdef CONFIG_FRONTSWAP diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index acedeabe589c..88e677b0de74 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -48,7 +48,6 @@  #include <xen/xenbus.h>  #include <xen/xen.h>  #include "xenbus_comms.h" -#include <asm/xen/hypervisor.h>  struct xs_stored_msg {  	struct list_head list; |