[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH 16/16] xen/grant-table: host_addr fixup in mapping on xenhost_r0
Xenhost type xenhost_r0 does not support standard GNTTABOP_map_grant_ref semantics (map a gref onto a specified host_addr). That's because since the hypervisor is local (same address space as the caller of GNTTABOP_map_grant_ref), there is no external entity that could map an arbitrary page underneath an arbitrary address. To handle this, the GNTTABOP_map_grant_ref hypercall on xenhost_r0 treats the host_addr as an OUT parameter instead of IN and expects the gnttab_map_refs() and similar to fixup any state that caches the value of host_addr from before the hypercall. Accordingly gnttab_map_refs() now adds two parameters, a fixup function and a pointer to cached maps to fixup: int gnttab_map_refs(xenhost_t *xh, struct gnttab_map_grant_ref *map_ops, struct gnttab_map_grant_ref *kmap_ops, - struct page **pages, unsigned int count) + struct page **pages, gnttab_map_fixup_t map_fixup_fn, + void **map_fixup[], unsigned int count) The reason we use a fixup function and not an additional mapping op in the xenhost_t is because, depending on the caller, what we are fixing might be different: blkback, netback for instance cache host_addr in via a struct page *, while __xenbus_map_ring() caches a phys_addr. This patch fixes up xen-blkback and xen-gntdev drivers. TODO: - also rewrite gnttab_batch_map() and __xenbus_map_ring(). - modify xen-netback, scsiback, pciback etc Co-developed-by: Joao Martins <joao.m.martins@xxxxxxxxxx> Signed-off-by: Ankur Arora <ankur.a.arora@xxxxxxxxxx> --- drivers/block/xen-blkback/blkback.c | 14 +++++++++++++- drivers/xen/gntdev.c | 2 +- drivers/xen/grant-table.c | 20 ++++++++++++++------ include/xen/grant_table.h | 11 ++++++++++- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index d366a17a4bd8..50ce40ba35e5 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -806,11 +806,18 @@ static void xen_blkbk_unmap(struct xen_blkif_ring *ring, } } +static void blkbk_map_fixup(uint64_t host_addr, void **fixup) +{ + struct page **pg = (struct page **)fixup; + *pg = virt_to_page(host_addr); +} + static int xen_blkbk_map(struct xen_blkif_ring *ring, struct grant_page *pages[], int num, bool ro) { struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct page **map_fixup[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct page *pages_to_gnt[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct persistent_gnt *persistent_gnt = NULL; phys_addr_t addr = 0; @@ -858,6 +865,9 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, gnttab_set_map_op(&map[segs_to_map++], addr, flags, pages[i]->gref, blkif->domid); + + if (gnttab_map_fixup(dev->xh)) + map_fixup[i] = &pages[i]->page; } map_until = i + 1; if (segs_to_map == BLKIF_MAX_SEGMENTS_PER_REQUEST) @@ -865,7 +875,9 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, } if (segs_to_map) { - ret = gnttab_map_refs(dev->xh, map, NULL, pages_to_gnt, segs_to_map); + ret = gnttab_map_refs(dev->xh, map, NULL, pages_to_gnt, + gnttab_map_fixup(dev->xh) ? blkbk_map_fixup : NULL, + (void ***) map_fixup, segs_to_map); BUG_ON(ret); } diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 40a42abe2dd0..32c6471834ba 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -342,7 +342,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) pr_debug("map %d+%d\n", map->index, map->count); err = gnttab_map_refs(xh, map->map_ops, use_ptemod ? map->kmap_ops : NULL, - map->pages, map->count); + map->pages, NULL, NULL, map->count); if (err) return err; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 959b81ade113..2f3a0a4a2660 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -1084,7 +1084,8 @@ void gnttab_foreach_grant(struct page **pages, int gnttab_map_refs(xenhost_t *xh, struct gnttab_map_grant_ref *map_ops, struct gnttab_map_grant_ref *kmap_ops, - struct page **pages, unsigned int count) + struct page **pages, gnttab_map_fixup_t map_fixup_fn, + void **map_fixup[], unsigned int count) { int i, ret; @@ -1096,12 +1097,19 @@ int gnttab_map_refs(xenhost_t *xh, struct gnttab_map_grant_ref *map_ops, switch (map_ops[i].status) { case GNTST_okay: { - struct xen_page_foreign *foreign; + if (!gnttab_map_fixup(xh)) { + struct xen_page_foreign *foreign; - SetPageForeign(pages[i]); - foreign = xen_page_foreign(pages[i]); - foreign->domid = map_ops[i].dom; - foreign->gref = map_ops[i].ref; + SetPageForeign(pages[i]); + foreign = xen_page_foreign(pages[i]); + foreign->domid = map_ops[i].dom; + foreign->gref = map_ops[i].ref; + } else { + pages[i] = virt_to_page(map_ops[i].host_addr); + + if (map_fixup_fn) + map_fixup_fn(map_ops[i].host_addr, map_fixup[i]); + } break; } diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 827b790199fb..14f7cc70cd01 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -219,9 +219,18 @@ int gnttab_dma_free_pages(xenhost_t *xh, struct gnttab_dma_alloc_args *args); int gnttab_pages_set_private(int nr_pages, struct page **pages); void gnttab_pages_clear_private(int nr_pages, struct page **pages); +static inline bool +gnttab_map_fixup(xenhost_t *xh) +{ + return xh->type == xenhost_r0; +} + +typedef void (*gnttab_map_fixup_t)(uint64_t host_addr, void **map_fixup); + int gnttab_map_refs(xenhost_t *xh, struct gnttab_map_grant_ref *map_ops, struct gnttab_map_grant_ref *kmap_ops, - struct page **pages, unsigned int count); + struct page **pages, gnttab_map_fixup_t map_fixup_fn, + void **map_fixup[], unsigned int count); int gnttab_unmap_refs(xenhost_t *xh, struct gnttab_unmap_grant_ref *unmap_ops, struct gnttab_unmap_grant_ref *kunmap_ops, struct page **pages, unsigned int count); -- 2.20.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |