aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJennifer Herbert <jennifer.herbert@citrix.com>2014-12-24 09:17:06 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2015-01-28 09:03:12 -0500
commit8da7633f168b5428e2cfb7342408b2c44088f5df (patch)
tree33e17f065d1aa9bf8a57ac03b737154bac0d3468
parentff4b156f166b3931894d2a8b5cdba6cdf4da0618 (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>
-rw-r--r--arch/x86/xen/p2m.c7
-rw-r--r--drivers/xen/grant-table.c43
-rw-r--r--include/xen/grant_table.h20
3 files changed, 61 insertions, 9 deletions
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index a8691cb08420..f18fd1d411f6 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -681,12 +681,8 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
681 } 681 }
682 pfn = page_to_pfn(pages[i]); 682 pfn = page_to_pfn(pages[i]);
683 683
684 WARN_ON(PagePrivate(pages[i]));
685 WARN(pfn_to_mfn(pfn) != INVALID_P2M_ENTRY, "page must be ballooned"); 684 WARN(pfn_to_mfn(pfn) != INVALID_P2M_ENTRY, "page must be ballooned");
686 685
687 SetPagePrivate(pages[i]);
688 set_page_private(pages[i], mfn);
689
690 if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) { 686 if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) {
691 ret = -ENOMEM; 687 ret = -ENOMEM;
692 goto out; 688 goto out;
@@ -716,9 +712,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
716 goto out; 712 goto out;
717 } 713 }
718 714
719 set_page_private(pages[i], INVALID_P2M_ENTRY);
720 WARN_ON(!PagePrivate(pages[i]));
721 ClearPagePrivate(pages[i]);
722 set_phys_to_machine(pfn, INVALID_P2M_ENTRY); 715 set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
723 } 716 }
724 if (kunmap_ops) 717 if (kunmap_ops)
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 */
680int gnttab_alloc_pages(int nr_pages, struct page **pages) 680int 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}
690EXPORT_SYMBOL(gnttab_alloc_pages); 705EXPORT_SYMBOL(gnttab_alloc_pages);
@@ -696,6 +711,16 @@ EXPORT_SYMBOL(gnttab_alloc_pages);
696 */ 711 */
697void gnttab_free_pages(int nr_pages, struct page **pages) 712void 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}
701EXPORT_SYMBOL(gnttab_free_pages); 726EXPORT_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}
767EXPORT_SYMBOL_GPL(gnttab_map_refs); 802EXPORT_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}
781EXPORT_SYMBOL_GPL(gnttab_unmap_refs); 820EXPORT_SYMBOL_GPL(gnttab_unmap_refs);
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 949803e20872..d3bef563e8da 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -45,6 +45,8 @@
45#include <asm/xen/hypervisor.h> 45#include <asm/xen/hypervisor.h>
46 46
47#include <xen/features.h> 47#include <xen/features.h>
48#include <linux/mm_types.h>
49#include <linux/page-flags.h>
48 50
49#define GNTTAB_RESERVED_XENSTORE 1 51#define GNTTAB_RESERVED_XENSTORE 1
50 52
@@ -185,4 +187,22 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
185void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count); 187void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count);
186void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count); 188void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count);
187 189
190
191struct xen_page_foreign {
192 domid_t domid;
193 grant_ref_t gref;
194};
195
196static inline struct xen_page_foreign *xen_page_foreign(struct page *page)
197{
198 if (!PageForeign(page))
199 return NULL;
200#if BITS_PER_LONG < 64
201 return (struct xen_page_foreign *)page->private;
202#else
203 BUILD_BUG_ON(sizeof(struct xen_page_foreign) > BITS_PER_LONG);
204 return (struct xen_page_foreign *)&page->private;
205#endif
206}
207
188#endif /* __ASM_GNTTAB_H__ */ 208#endif /* __ASM_GNTTAB_H__ */