mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Change the xenbus_map_ring_valloc() interface and implementation so
that it is buildable as a module. Signed-off-by: Jan Beulich <jbeulich@novell.com>
This commit is contained in:
1 parent
ba770381ca
commit
c0b2433fa9
4 files changed
+21
-36
No files matched your search
@@ -29,6 +29,7 @@ struct pciback_device {
|
||||
|
||||
int evtchn_irq;
|
||||
|
||||
struct vm_struct *sh_area;
|
||||
struct xen_pci_sharedinfo *sh_info;
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
|
||||
|
||||
spin_lock_init(&pdev->dev_lock);
|
||||
|
||||
pdev->sh_area = NULL;
|
||||
pdev->sh_info = NULL;
|
||||
pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
|
||||
pdev->be_watching = 0;
|
||||
@@ -48,7 +49,7 @@ static void free_pdev(struct pciback_device *pdev)
|
||||
unbind_from_irqhandler(pdev->evtchn_irq, pdev);
|
||||
|
||||
if (pdev->sh_info)
|
||||
xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info);
|
||||
xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_area);
|
||||
|
||||
pciback_release_devices(pdev);
|
||||
|
||||
@@ -63,15 +64,19 @@ static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref,
|
||||
{
|
||||
int err = 0;
|
||||
int evtchn;
|
||||
struct vm_struct *area;
|
||||
|
||||
dev_dbg(&pdev->xdev->dev,
|
||||
"Attaching to frontend resources - gnt_ref=%d evtchn=%d\n",
|
||||
gnt_ref, remote_evtchn);
|
||||
|
||||
err =
|
||||
xenbus_map_ring_valloc(pdev->xdev, gnt_ref,
|
||||
(void **)&pdev->sh_info);
|
||||
if (err)
|
||||
area = xenbus_map_ring_valloc(pdev->xdev, gnt_ref);
|
||||
if (IS_ERR(area)) {
|
||||
err = PTR_ERR(area);
|
||||
goto out;
|
||||
}
|
||||
pdev->sh_area = area;
|
||||
pdev->sh_info = area->addr;
|
||||
|
||||
err = xenbus_bind_evtchn(pdev->xdev, remote_evtchn, &evtchn);
|
||||
if (err)
|
||||
|
||||
@@ -30,21 +30,20 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <xen/gnttab.h>
|
||||
#include <xen/xenbus.h>
|
||||
#include <xen/driver_util.h>
|
||||
|
||||
/* Based on Rusty Russell's skeleton driver's map_page */
|
||||
int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
|
||||
struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref)
|
||||
{
|
||||
struct gnttab_map_grant_ref op;
|
||||
struct vm_struct *area;
|
||||
|
||||
*vaddr = NULL;
|
||||
|
||||
area = alloc_vm_area(PAGE_SIZE);
|
||||
if (!area)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
|
||||
gnt_ref, dev->otherend_id);
|
||||
@@ -58,14 +57,14 @@ int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
|
||||
xenbus_dev_fatal(dev, op.status,
|
||||
"mapping in shared page %d from domain %d",
|
||||
gnt_ref, dev->otherend_id);
|
||||
return op.status;
|
||||
BUG_ON(!IS_ERR(ERR_PTR(op.status)));
|
||||
return ERR_PTR(op.status);
|
||||
}
|
||||
|
||||
/* Stuff the handle in an unused field */
|
||||
area->phys_addr = (unsigned long)op.handle;
|
||||
|
||||
*vaddr = area->addr;
|
||||
return 0;
|
||||
return area;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
|
||||
|
||||
@@ -92,30 +91,10 @@ EXPORT_SYMBOL_GPL(xenbus_map_ring);
|
||||
|
||||
|
||||
/* Based on Rusty Russell's skeleton driver's unmap_page */
|
||||
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
|
||||
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *area)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
struct gnttab_unmap_grant_ref op;
|
||||
|
||||
/* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
|
||||
* method so that we don't have to muck with vmalloc internals here.
|
||||
* We could force the user to hang on to their struct vm_struct from
|
||||
* xenbus_map_ring_valloc, but these 6 lines considerably simplify
|
||||
* this API.
|
||||
*/
|
||||
read_lock(&vmlist_lock);
|
||||
for (area = vmlist; area != NULL; area = area->next) {
|
||||
if (area->addr == vaddr)
|
||||
break;
|
||||
}
|
||||
read_unlock(&vmlist_lock);
|
||||
|
||||
if (!area) {
|
||||
xenbus_dev_error(dev, -ENOENT,
|
||||
"can't find mapped virtual address %p", vaddr);
|
||||
return GNTST_bad_virt_addr;
|
||||
}
|
||||
|
||||
gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
|
||||
(grant_handle_t)area->phys_addr);
|
||||
|
||||
|
||||
@@ -228,8 +228,8 @@ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
|
||||
* or -ENOMEM on error. If an error is returned, device will switch to
|
||||
* XenbusStateClosing and the error message will be saved in XenStore.
|
||||
*/
|
||||
int xenbus_map_ring_valloc(struct xenbus_device *dev,
|
||||
int gnt_ref, void **vaddr);
|
||||
struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev,
|
||||
int gnt_ref);
|
||||
int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
|
||||
grant_handle_t *handle, void *vaddr);
|
||||
|
||||
@@ -241,7 +241,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
|
||||
* Returns 0 on success and returns GNTST_* on error
|
||||
* (see xen/include/interface/grant_table.h).
|
||||
*/
|
||||
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr);
|
||||
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *);
|
||||
int xenbus_unmap_ring(struct xenbus_device *dev,
|
||||
grant_handle_t handle, void *vaddr);
|
||||
|
||||
|
||||