diff options
author | Jennifer Herbert <jennifer.herbert@citrix.com> | 2014-12-24 09:17:06 -0500 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2015-01-28 09:03:12 -0500 |
commit | 8da7633f168b5428e2cfb7342408b2c44088f5df (patch) | |
tree | 33e17f065d1aa9bf8a57ac03b737154bac0d3468 /drivers/xen/grant-table.c | |
parent | ff4b156f166b3931894d2a8b5cdba6cdf4da0618 (diff) |
xen: mark grant mapped pages as foreign
Use the "foreign" page flag to mark pages that have a grant map. Use
page->private to store information of the grant (the granting domain
and the grant reference).
Signed-off-by: Jennifer Herbert <jennifer.herbert@citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'drivers/xen/grant-table.c')
-rw-r--r-- | drivers/xen/grant-table.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index b4f93c490f83..89dcca448bb6 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -679,12 +679,27 @@ EXPORT_SYMBOL_GPL(gnttab_free_auto_xlat_frames); | |||
679 | */ | 679 | */ |
680 | int gnttab_alloc_pages(int nr_pages, struct page **pages) | 680 | int gnttab_alloc_pages(int nr_pages, struct page **pages) |
681 | { | 681 | { |
682 | int i; | ||
682 | int ret; | 683 | int ret; |
683 | 684 | ||
684 | ret = alloc_xenballooned_pages(nr_pages, pages, false); | 685 | ret = alloc_xenballooned_pages(nr_pages, pages, false); |
685 | if (ret < 0) | 686 | if (ret < 0) |
686 | return ret; | 687 | return ret; |
687 | 688 | ||
689 | for (i = 0; i < nr_pages; i++) { | ||
690 | #if BITS_PER_LONG < 64 | ||
691 | struct xen_page_foreign *foreign; | ||
692 | |||
693 | foreign = kzalloc(sizeof(*foreign), GFP_KERNEL); | ||
694 | if (!foreign) { | ||
695 | gnttab_free_pages(nr_pages, pages); | ||
696 | return -ENOMEM; | ||
697 | } | ||
698 | set_page_private(pages[i], (unsigned long)foreign); | ||
699 | #endif | ||
700 | SetPagePrivate(pages[i]); | ||
701 | } | ||
702 | |||
688 | return 0; | 703 | return 0; |
689 | } | 704 | } |
690 | EXPORT_SYMBOL(gnttab_alloc_pages); | 705 | EXPORT_SYMBOL(gnttab_alloc_pages); |
@@ -696,6 +711,16 @@ EXPORT_SYMBOL(gnttab_alloc_pages); | |||
696 | */ | 711 | */ |
697 | void gnttab_free_pages(int nr_pages, struct page **pages) | 712 | void gnttab_free_pages(int nr_pages, struct page **pages) |
698 | { | 713 | { |
714 | int i; | ||
715 | |||
716 | for (i = 0; i < nr_pages; i++) { | ||
717 | if (PagePrivate(pages[i])) { | ||
718 | #if BITS_PER_LONG < 64 | ||
719 | kfree((void *)page_private(pages[i])); | ||
720 | #endif | ||
721 | ClearPagePrivate(pages[i]); | ||
722 | } | ||
723 | } | ||
699 | free_xenballooned_pages(nr_pages, pages); | 724 | free_xenballooned_pages(nr_pages, pages); |
700 | } | 725 | } |
701 | EXPORT_SYMBOL(gnttab_free_pages); | 726 | EXPORT_SYMBOL(gnttab_free_pages); |
@@ -756,12 +781,22 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
756 | if (ret) | 781 | if (ret) |
757 | return ret; | 782 | return ret; |
758 | 783 | ||
759 | /* Retry eagain maps */ | 784 | for (i = 0; i < count; i++) { |
760 | for (i = 0; i < count; i++) | 785 | /* Retry eagain maps */ |
761 | if (map_ops[i].status == GNTST_eagain) | 786 | if (map_ops[i].status == GNTST_eagain) |
762 | gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i, | 787 | gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i, |
763 | &map_ops[i].status, __func__); | 788 | &map_ops[i].status, __func__); |
764 | 789 | ||
790 | if (map_ops[i].status == GNTST_okay) { | ||
791 | struct xen_page_foreign *foreign; | ||
792 | |||
793 | SetPageForeign(pages[i]); | ||
794 | foreign = xen_page_foreign(pages[i]); | ||
795 | foreign->domid = map_ops[i].dom; | ||
796 | foreign->gref = map_ops[i].ref; | ||
797 | } | ||
798 | } | ||
799 | |||
765 | return set_foreign_p2m_mapping(map_ops, kmap_ops, pages, count); | 800 | return set_foreign_p2m_mapping(map_ops, kmap_ops, pages, count); |
766 | } | 801 | } |
767 | EXPORT_SYMBOL_GPL(gnttab_map_refs); | 802 | EXPORT_SYMBOL_GPL(gnttab_map_refs); |
@@ -770,12 +805,16 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
770 | struct gnttab_unmap_grant_ref *kunmap_ops, | 805 | struct gnttab_unmap_grant_ref *kunmap_ops, |
771 | struct page **pages, unsigned int count) | 806 | struct page **pages, unsigned int count) |
772 | { | 807 | { |
808 | unsigned int i; | ||
773 | int ret; | 809 | int ret; |
774 | 810 | ||
775 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); | 811 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); |
776 | if (ret) | 812 | if (ret) |
777 | return ret; | 813 | return ret; |
778 | 814 | ||
815 | for (i = 0; i < count; i++) | ||
816 | ClearPageForeign(pages[i]); | ||
817 | |||
779 | return clear_foreign_p2m_mapping(unmap_ops, kunmap_ops, pages, count); | 818 | return clear_foreign_p2m_mapping(unmap_ops, kunmap_ops, pages, count); |
780 | } | 819 | } |
781 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); | 820 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); |