aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/grant-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/grant-table.c')
-rw-r--r--drivers/xen/grant-table.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 6c4531816496..fd725cde6ad1 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -447,6 +447,79 @@ unsigned int gnttab_max_grant_frames(void)
447} 447}
448EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 448EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
449 449
450int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
451 struct page **pages, unsigned int count)
452{
453 int i, ret;
454 pte_t *pte;
455 unsigned long mfn;
456
457 ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count);
458 if (ret)
459 return ret;
460
461 if (xen_feature(XENFEAT_auto_translated_physmap))
462 return ret;
463
464 for (i = 0; i < count; i++) {
465 /* Do not add to override if the map failed. */
466 if (map_ops[i].status)
467 continue;
468
469 if (map_ops[i].flags & GNTMAP_contains_pte) {
470 pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
471 (map_ops[i].host_addr & ~PAGE_MASK));
472 mfn = pte_mfn(*pte);
473 } else {
474 /* If you really wanted to do this:
475 * mfn = PFN_DOWN(map_ops[i].dev_bus_addr);
476 *
477 * The reason we do not implement it is b/c on the
478 * unmap path (gnttab_unmap_refs) we have no means of
479 * checking whether the page is !GNTMAP_contains_pte.
480 *
481 * That is without some extra data-structure to carry
482 * the struct page, bool clear_pte, and list_head next
483 * tuples and deal with allocation/delallocation, etc.
484 *
485 * The users of this API set the GNTMAP_contains_pte
486 * flag so lets just return not supported until it
487 * becomes neccessary to implement.
488 */
489 return -EOPNOTSUPP;
490 }
491 ret = m2p_add_override(mfn, pages[i],
492 map_ops[i].flags & GNTMAP_contains_pte);
493 if (ret)
494 return ret;
495 }
496
497 return ret;
498}
499EXPORT_SYMBOL_GPL(gnttab_map_refs);
500
501int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
502 struct page **pages, unsigned int count)
503{
504 int i, ret;
505
506 ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count);
507 if (ret)
508 return ret;
509
510 if (xen_feature(XENFEAT_auto_translated_physmap))
511 return ret;
512
513 for (i = 0; i < count; i++) {
514 ret = m2p_remove_override(pages[i], true /* clear the PTE */);
515 if (ret)
516 return ret;
517 }
518
519 return ret;
520}
521EXPORT_SYMBOL_GPL(gnttab_unmap_refs);
522
450static int gnttab_map(unsigned int start_idx, unsigned int end_idx) 523static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
451{ 524{
452 struct gnttab_setup_table setup; 525 struct gnttab_setup_table setup;