From f1479f0a4f53ef4fc12108a59caee61c39bc6843 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 6 Dec 2023 10:17:24 -0800 Subject: xen/xenbus: client: fix kernel-doc comments Correct function kernel-doc notation to prevent warnings from scripts/kernel-doc. xenbus_client.c:134: warning: No description found for return value of 'xenbus_watch_path' xenbus_client.c:177: warning: No description found for return value of 'xenbus_watch_pathfmt' xenbus_client.c:258: warning: missing initial short description on line: * xenbus_switch_state xenbus_client.c:267: warning: No description found for return value of 'xenbus_switch_state' xenbus_client.c:308: warning: missing initial short description on line: * xenbus_dev_error xenbus_client.c:327: warning: missing initial short description on line: * xenbus_dev_fatal xenbus_client.c:350: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Equivalent to xenbus_dev_fatal(dev, err, fmt, args), but helps xenbus_client.c:457: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Allocate an event channel for the given xenbus_device, assigning the newly xenbus_client.c:486: warning: expecting prototype for Free an existing event channel. Returns 0 on success or(). Prototype was for xenbus_free_evtchn() instead xenbus_client.c:502: warning: missing initial short description on line: * xenbus_map_ring_valloc xenbus_client.c:517: warning: No description found for return value of 'xenbus_map_ring_valloc' xenbus_client.c:602: warning: missing initial short description on line: * xenbus_unmap_ring xenbus_client.c:614: warning: No description found for return value of 'xenbus_unmap_ring' xenbus_client.c:715: warning: missing initial short description on line: * xenbus_unmap_ring_vfree xenbus_client.c:727: warning: No description found for return value of 'xenbus_unmap_ring_vfree' xenbus_client.c:919: warning: missing initial short description on line: * xenbus_read_driver_state xenbus_client.c:926: warning: No description found for return value of 'xenbus_read_driver_state' Signed-off-by: Randy Dunlap Cc: Juergen Gross Cc: Stefano Stabellini Cc: Oleksandr Tyshchenko Cc: xen-devel@lists.xenproject.org Reviewed-by: Juergen Gross Link: https://lore.kernel.org/r/20231206181724.27767-1-rdunlap@infradead.org Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_client.c | 59 ++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index d4b251925796..32835b4b9bc5 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -119,11 +119,13 @@ EXPORT_SYMBOL_GPL(xenbus_strstate); * @callback: callback to register * * Register a @watch on the given path, using the given xenbus_watch structure - * for storage, and the given @callback function as the callback. Return 0 on - * success, or -errno on error. On success, the given @path will be saved as - * @watch->node, and remains the caller's to free. On error, @watch->node will + * for storage, and the given @callback function as the callback. On success, + * the given @path will be saved as @watch->node, and remains the + * caller's to free. On error, @watch->node will * be NULL, the device will switch to %XenbusStateClosing, and the error will * be saved in the store. + * + * Returns: %0 on success or -errno on error */ int xenbus_watch_path(struct xenbus_device *dev, const char *path, struct xenbus_watch *watch, @@ -160,12 +162,14 @@ EXPORT_SYMBOL_GPL(xenbus_watch_path); * @pathfmt: format of path to watch * * Register a watch on the given @path, using the given xenbus_watch - * structure for storage, and the given @callback function as the callback. - * Return 0 on success, or -errno on error. On success, the watched path - * (@path/@path2) will be saved as @watch->node, and becomes the caller's to - * kfree(). On error, watch->node will be NULL, so the caller has nothing to + * structure for storage, and the given @callback function as the + * callback. On success, the watched path (@path/@path2) will be saved + * as @watch->node, and becomes the caller's to kfree(). + * On error, watch->node will be NULL, so the caller has nothing to * free, the device will switch to %XenbusStateClosing, and the error will be * saved in the store. + * + * Returns: %0 on success or -errno on error */ int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch, @@ -255,13 +259,15 @@ abort: } /** - * xenbus_switch_state + * xenbus_switch_state - save the new state of a driver * @dev: xenbus device * @state: new state * * Advertise in the store a change of the given driver to the given new_state. - * Return 0 on success, or -errno on error. On error, the device will switch - * to XenbusStateClosing, and the error will be saved in the store. + * On error, the device will switch to XenbusStateClosing, and the error + * will be saved in the store. + * + * Returns: %0 on success or -errno on error */ int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state) { @@ -305,7 +311,7 @@ static void xenbus_va_dev_error(struct xenbus_device *dev, int err, } /** - * xenbus_dev_error + * xenbus_dev_error - place an error message into the store * @dev: xenbus device * @err: error to report * @fmt: error message format @@ -324,7 +330,7 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) EXPORT_SYMBOL_GPL(xenbus_dev_error); /** - * xenbus_dev_fatal + * xenbus_dev_fatal - put an error messages into the store and then shutdown * @dev: xenbus device * @err: error to report * @fmt: error message format @@ -346,7 +352,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...) } EXPORT_SYMBOL_GPL(xenbus_dev_fatal); -/** +/* * Equivalent to xenbus_dev_fatal(dev, err, fmt, args), but helps * avoiding recursion within xenbus_switch_state. */ @@ -453,7 +459,7 @@ void xenbus_teardown_ring(void **vaddr, unsigned int nr_pages, } EXPORT_SYMBOL_GPL(xenbus_teardown_ring); -/** +/* * Allocate an event channel for the given xenbus_device, assigning the newly * created local port to *port. Return 0 on success, or -errno on error. On * error, the device will switch to XenbusStateClosing, and the error will be @@ -479,7 +485,7 @@ int xenbus_alloc_evtchn(struct xenbus_device *dev, evtchn_port_t *port) EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn); -/** +/* * Free an existing event channel. Returns 0 on success or -errno on error. */ int xenbus_free_evtchn(struct xenbus_device *dev, evtchn_port_t port) @@ -499,7 +505,7 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn); /** - * xenbus_map_ring_valloc + * xenbus_map_ring_valloc - allocate & map pages of VA space * @dev: xenbus device * @gnt_refs: grant reference array * @nr_grefs: number of grant references @@ -507,10 +513,11 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn); * * Map @nr_grefs pages of memory into this domain from another * domain's grant table. xenbus_map_ring_valloc allocates @nr_grefs - * pages of virtual address space, maps the pages to that address, and - * sets *vaddr to that address. Returns 0 on success, and -errno on - * error. If an error is returned, device will switch to + * pages of virtual address space, maps the pages to that address, and sets + * *vaddr to that address. If an error is returned, device will switch to * XenbusStateClosing and the error message will be saved in XenStore. + * + * Returns: %0 on success or -errno on error */ int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs, unsigned int nr_grefs, void **vaddr) @@ -599,14 +606,15 @@ static int __xenbus_map_ring(struct xenbus_device *dev, } /** - * xenbus_unmap_ring + * xenbus_unmap_ring - unmap memory from another domain * @dev: xenbus device * @handles: grant handle array * @nr_handles: number of handles in the array * @vaddrs: addresses to unmap * * Unmap memory in this domain that was imported from another domain. - * Returns 0 on success and returns GNTST_* on error + * + * Returns: %0 on success or GNTST_* on error * (see xen/include/interface/grant_table.h). */ static int xenbus_unmap_ring(struct xenbus_device *dev, grant_handle_t *handles, @@ -712,7 +720,7 @@ static int xenbus_map_ring_hvm(struct xenbus_device *dev, } /** - * xenbus_unmap_ring_vfree + * xenbus_unmap_ring_vfree - unmap a page of memory from another domain * @dev: xenbus device * @vaddr: addr to unmap * @@ -720,7 +728,8 @@ static int xenbus_map_ring_hvm(struct xenbus_device *dev, * Unmap a page of memory in this domain that was imported from another domain. * Use xenbus_unmap_ring_vfree if you mapped in your memory with * xenbus_map_ring_valloc (it will free the virtual address space). - * Returns 0 on success and returns GNTST_* on error + * + * Returns: %0 on success or GNTST_* on error * (see xen/include/interface/grant_table.h). */ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr) @@ -916,10 +925,10 @@ static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr) } /** - * xenbus_read_driver_state + * xenbus_read_driver_state - read state from a store path * @path: path for driver * - * Return the state of the driver rooted at the given store path, or + * Returns: the state of the driver rooted at the given store path, or * XenbusStateUnknown if no state can be read. */ enum xenbus_state xenbus_read_driver_state(const char *path) -- cgit From 2d2db7d40254d5fb53b11ebd703cd1ed0c5de7a1 Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Sun, 7 Jan 2024 12:34:26 +0200 Subject: xen/gntdev: Fix the abuse of underlying struct page in DMA-buf import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DO NOT access the underlying struct page of an sg table exported by DMA-buf in dmabuf_imp_to_refs(), this is not allowed. Please see drivers/dma-buf/dma-buf.c:mangle_sg_table() for details. Fortunately, here (for special Xen device) we can avoid using pages and calculate gfns directly from dma addresses provided by the sg table. Suggested-by: Daniel Vetter Signed-off-by: Oleksandr Tyshchenko Acked-by: Christian König Reviewed-by: Stefano Stabellini Acked-by: Daniel Vetter Link: https://lore.kernel.org/r/20240107103426.2038075-1-olekstysh@gmail.com Signed-off-by: Juergen Gross --- drivers/xen/gntdev-dmabuf.c | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c index 4440e626b797..42adc2c1e06b 100644 --- a/drivers/xen/gntdev-dmabuf.c +++ b/drivers/xen/gntdev-dmabuf.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,7 @@ struct gntdev_dmabuf { /* Number of pages this buffer has. */ int nr_pages; - /* Pages of this buffer. */ + /* Pages of this buffer (only for dma-buf export). */ struct page **pages; }; @@ -484,7 +485,7 @@ out: /* DMA buffer import support. */ static int -dmabuf_imp_grant_foreign_access(struct page **pages, u32 *refs, +dmabuf_imp_grant_foreign_access(unsigned long *gfns, u32 *refs, int count, int domid) { grant_ref_t priv_gref_head; @@ -507,7 +508,7 @@ dmabuf_imp_grant_foreign_access(struct page **pages, u32 *refs, } gnttab_grant_foreign_access_ref(cur_ref, domid, - xen_page_to_gfn(pages[i]), 0); + gfns[i], 0); refs[i] = cur_ref; } @@ -529,7 +530,6 @@ static void dmabuf_imp_end_foreign_access(u32 *refs, int count) static void dmabuf_imp_free_storage(struct gntdev_dmabuf *gntdev_dmabuf) { - kfree(gntdev_dmabuf->pages); kfree(gntdev_dmabuf->u.imp.refs); kfree(gntdev_dmabuf); } @@ -549,12 +549,6 @@ static struct gntdev_dmabuf *dmabuf_imp_alloc_storage(int count) if (!gntdev_dmabuf->u.imp.refs) goto fail; - gntdev_dmabuf->pages = kcalloc(count, - sizeof(gntdev_dmabuf->pages[0]), - GFP_KERNEL); - if (!gntdev_dmabuf->pages) - goto fail; - gntdev_dmabuf->nr_pages = count; for (i = 0; i < count; i++) @@ -576,7 +570,8 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev, struct dma_buf *dma_buf; struct dma_buf_attachment *attach; struct sg_table *sgt; - struct sg_page_iter sg_iter; + struct sg_dma_page_iter sg_iter; + unsigned long *gfns; int i; dma_buf = dma_buf_get(fd); @@ -624,26 +619,31 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev, gntdev_dmabuf->u.imp.sgt = sgt; - /* Now convert sgt to array of pages and check for page validity. */ + gfns = kcalloc(count, sizeof(*gfns), GFP_KERNEL); + if (!gfns) { + ret = ERR_PTR(-ENOMEM); + goto fail_unmap; + } + + /* + * Now convert sgt to array of gfns without accessing underlying pages. + * It is not allowed to access the underlying struct page of an sg table + * exported by DMA-buf, but since we deal with special Xen dma device here + * (not a normal physical one) look at the dma addresses in the sg table + * and then calculate gfns directly from them. + */ i = 0; - for_each_sgtable_page(sgt, &sg_iter, 0) { - struct page *page = sg_page_iter_page(&sg_iter); - /* - * Check if page is valid: this can happen if we are given - * a page from VRAM or other resources which are not backed - * by a struct page. - */ - if (!pfn_valid(page_to_pfn(page))) { - ret = ERR_PTR(-EINVAL); - goto fail_unmap; - } + for_each_sgtable_dma_page(sgt, &sg_iter, 0) { + dma_addr_t addr = sg_page_iter_dma_address(&sg_iter); + unsigned long pfn = bfn_to_pfn(XEN_PFN_DOWN(dma_to_phys(dev, addr))); - gntdev_dmabuf->pages[i++] = page; + gfns[i++] = pfn_to_gfn(pfn); } - ret = ERR_PTR(dmabuf_imp_grant_foreign_access(gntdev_dmabuf->pages, + ret = ERR_PTR(dmabuf_imp_grant_foreign_access(gfns, gntdev_dmabuf->u.imp.refs, count, domid)); + kfree(gfns); if (IS_ERR(ret)) goto fail_end_access; -- cgit