From e9e87eb3f9180b2b0470409b24fb39b8a1941520 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Tue, 11 Nov 2014 11:14:45 +0000 Subject: xen/arm: remove handling of XENFEAT_grant_map_identity The feature has been removed from Xen. Also Linux cannot use it on ARM32 without CONFIG_ARM_LPAE. Signed-off-by: Stefano Stabellini Acked-by: Ian Campbell Reviewed-by: David Vrabel Reviewed-by: Catalin Marinas --- include/xen/interface/features.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h index 14334d0161d5..131a6ccdba25 100644 --- a/include/xen/interface/features.h +++ b/include/xen/interface/features.h @@ -53,9 +53,6 @@ /* operation as Dom0 is supported */ #define XENFEAT_dom0 11 -/* Xen also maps grant references at pfn = mfn */ -#define XENFEAT_grant_map_identity 12 - #define XENFEAT_NR_SUBMAPS 1 #endif /* __XEN_PUBLIC_FEATURES_H__ */ -- cgit v1.2.3 From da095a996090a412c3b6292c7a8680661dca157d Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 21 Nov 2014 11:08:39 +0000 Subject: xen/arm: introduce GNTTABOP_cache_flush Introduce support for new hypercall GNTTABOP_cache_flush. Use it to perform cache flashing on pages used for dma when necessary. If GNTTABOP_cache_flush is supported by the hypervisor, we don't need to bounce dma map operations that involve foreign grants and non-coherent devices. Signed-off-by: Stefano Stabellini Reviewed-by: Catalin Marinas Acked-by: Ian Campbell --- arch/arm/xen/mm.c | 34 ++++++++++++++++++++++++++++++++-- include/xen/interface/grant_table.h | 19 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index 28ebf3ecee4e..351b24a979d4 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -24,12 +25,14 @@ enum dma_cache_op { DMA_UNMAP, DMA_MAP, }; +static bool hypercall_cflush = false; /* functions called by SWIOTLB */ static void dma_cache_maint(dma_addr_t handle, unsigned long offset, size_t size, enum dma_data_direction dir, enum dma_cache_op op) { + struct gnttab_cache_flush cflush; unsigned long pfn; size_t left = size; @@ -39,7 +42,26 @@ static void dma_cache_maint(dma_addr_t handle, unsigned long offset, do { size_t len = left; - /* TODO: cache flush */ + /* buffers in highmem or foreign pages cannot cross page + * boundaries */ + if (len + offset > PAGE_SIZE) + len = PAGE_SIZE - offset; + + cflush.op = 0; + cflush.a.dev_bus_addr = pfn << PAGE_SHIFT; + cflush.offset = offset; + cflush.length = len; + + if (op == DMA_UNMAP && dir != DMA_TO_DEVICE) + cflush.op = GNTTAB_CACHE_INVAL; + if (op == DMA_MAP) { + if (dir == DMA_FROM_DEVICE) + cflush.op = GNTTAB_CACHE_INVAL; + else + cflush.op = GNTTAB_CACHE_CLEAN; + } + if (cflush.op) + HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1); offset = 0; pfn++; @@ -104,7 +126,7 @@ bool xen_arch_need_swiotlb(struct device *dev, unsigned long pfn, unsigned long mfn) { - return ((pfn != mfn) && !is_device_dma_coherent(dev)); + return (!hypercall_cflush && (pfn != mfn) && !is_device_dma_coherent(dev)); } int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, @@ -147,10 +169,18 @@ static struct dma_map_ops xen_swiotlb_dma_ops = { int __init xen_mm_init(void) { + struct gnttab_cache_flush cflush; if (!xen_initial_domain()) return 0; xen_swiotlb_init(1, false); xen_dma_ops = &xen_swiotlb_dma_ops; + + cflush.op = 0; + cflush.a.dev_bus_addr = 0; + cflush.offset = 0; + cflush.length = 0; + if (HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1) != -ENOSYS) + hypercall_cflush = true; return 0; } arch_initcall(xen_mm_init); diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h index e40fae9bf11a..bcce56439d64 100644 --- a/include/xen/interface/grant_table.h +++ b/include/xen/interface/grant_table.h @@ -478,6 +478,25 @@ struct gnttab_get_version { }; DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version); +/* + * Issue one or more cache maintenance operations on a portion of a + * page granted to the calling domain by a foreign domain. + */ +#define GNTTABOP_cache_flush 12 +struct gnttab_cache_flush { + union { + uint64_t dev_bus_addr; + grant_ref_t ref; + } a; + uint16_t offset; /* offset from start of grant */ + uint16_t length; /* size within the grant */ +#define GNTTAB_CACHE_CLEAN (1<<0) +#define GNTTAB_CACHE_INVAL (1<<1) +#define GNTTAB_CACHE_SOURCE_GREF (1<<31) + uint32_t op; +}; +DEFINE_GUEST_HANDLE_STRUCT(gnttab_cache_flush); + /* * Bitfield values for update_pin_status.flags. */ -- cgit v1.2.3 From ac8010221d3fa8697151dfe9a1bb2c504adc68c1 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 3 Dec 2014 16:40:27 -0500 Subject: driver core: Provide an wrapper around the mutex to do lockdep warnings Instead of open-coding it in drivers that want to double check that their functions are indeed holding the device lock. Signed-off-by: Konrad Rzeszutek Wilk Suggested-by: David Vrabel Acked-by: Greg Kroah-Hartman Signed-off-by: David Vrabel --- drivers/xen/xen-pciback/pci_stub.c | 2 +- include/linux/device.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 9cbe1a31c1e5..8b77089eddac 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -278,7 +278,7 @@ void pcistub_put_pci_dev(struct pci_dev *dev) /* Cleanup our device * (so it's ready for the next domain) */ - lockdep_assert_held(&dev->dev.mutex); + device_lock_assert(&dev->dev); __pci_reset_function_locked(dev); pci_restore_state(dev); diff --git a/include/linux/device.h b/include/linux/device.h index ce1f21608b16..41d6a7555c6b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -911,6 +911,11 @@ static inline void device_unlock(struct device *dev) mutex_unlock(&dev->mutex); } +static inline void device_lock_assert(struct device *dev) +{ + lockdep_assert_held(&dev->mutex); +} + void driver_init(void); /* -- cgit v1.2.3 From 98d9b271250bd83337e3ed66d63e7deefcda8712 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 3 Dec 2014 16:40:31 -0500 Subject: PCI: Expose pci_load_saved_state for public consumption. We have the pci_load_and_free_saved_state, and pci_store_saved_state but are missing the functionality to just load the state multiple times in the PCI device without having to free/save the state. This patch makes it possible to use this function. Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Bjorn Helgaas Signed-off-by: David Vrabel --- drivers/pci/pci.c | 5 +++-- include/linux/pci.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 625a4ace10b4..f00a9d63fd7d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1142,8 +1142,8 @@ EXPORT_SYMBOL_GPL(pci_store_saved_state); * @dev: PCI device that we're dealing with * @state: Saved state returned from pci_store_saved_state() */ -static int pci_load_saved_state(struct pci_dev *dev, - struct pci_saved_state *state) +int pci_load_saved_state(struct pci_dev *dev, + struct pci_saved_state *state) { struct pci_cap_saved_data *cap; @@ -1171,6 +1171,7 @@ static int pci_load_saved_state(struct pci_dev *dev, dev->state_saved = true; return 0; } +EXPORT_SYMBOL_GPL(pci_load_saved_state); /** * pci_load_and_free_saved_state - Reload the save state pointed to by state, diff --git a/include/linux/pci.h b/include/linux/pci.h index 4c8ac5fcc224..42ae347d3fc7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1004,6 +1004,8 @@ void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size); int pci_save_state(struct pci_dev *dev); void pci_restore_state(struct pci_dev *dev); struct pci_saved_state *pci_store_saved_state(struct pci_dev *dev); +int pci_load_saved_state(struct pci_dev *dev, + struct pci_saved_state *state); int pci_load_and_free_saved_state(struct pci_dev *dev, struct pci_saved_state **state); struct pci_cap_saved_state *pci_find_saved_cap(struct pci_dev *dev, char cap); -- cgit v1.2.3