aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/grant-table.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-01-06 10:40:36 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2014-01-06 10:44:20 -0500
commitefaf30a3357872cf0fc7d555b1f9968ec71535d3 (patch)
tree3ce0f48234ccf2b173b88ae8682b7ac5eb6b7722 /drivers/xen/grant-table.c
parent456847533b9ad18baa6685946a2f1e1fa9c05c34 (diff)
xen/grant: Implement an grant frame array struct (v3).
The 'xen_hvm_resume_frames' used to be an 'unsigned long' and contain the virtual address of the grants. That was OK for most architectures (PVHVM, ARM) were the grants are contiguous in memory. That however is not the case for PVH - in which case we will have to do a lookup for each virtual address for the PFN. Instead of doing that, lets make it a structure which will contain the array of PFNs, the virtual address and the count of said PFNs. Also provide a generic functions: gnttab_setup_auto_xlat_frames and gnttab_free_auto_xlat_frames to populate said structure with appropriate values for PVHVM and ARM. To round it off, change the name from 'xen_hvm_resume_frames' to a more descriptive one - 'xen_auto_xlat_grant_frames'. For PVH, in patch "xen/pvh: Piggyback on PVHVM for grant driver" we will populate the 'xen_auto_xlat_grant_frames' by ourselves. v2 moves the xen_remap in the gnttab_setup_auto_xlat_frames and also introduces xen_unmap for gnttab_free_auto_xlat_frames. Suggested-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> [v3: Based on top of 'asm/xen/page.h: remove redundant semicolon'] Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'drivers/xen/grant-table.c')
-rw-r--r--drivers/xen/grant-table.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index e69c7780c208..44b75ccfbbff 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -65,8 +65,7 @@ static unsigned int nr_grant_frames;
65static int gnttab_free_count; 65static int gnttab_free_count;
66static grant_ref_t gnttab_free_head; 66static grant_ref_t gnttab_free_head;
67static DEFINE_SPINLOCK(gnttab_list_lock); 67static DEFINE_SPINLOCK(gnttab_list_lock);
68unsigned long xen_hvm_resume_frames; 68struct grant_frames xen_auto_xlat_grant_frames;
69EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
70 69
71static union { 70static union {
72 struct grant_entry_v1 *v1; 71 struct grant_entry_v1 *v1;
@@ -838,6 +837,51 @@ unsigned int gnttab_max_grant_frames(void)
838} 837}
839EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 838EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
840 839
840int gnttab_setup_auto_xlat_frames(unsigned long addr)
841{
842 xen_pfn_t *pfn;
843 unsigned int max_nr_gframes = __max_nr_grant_frames();
844 unsigned int i;
845 void *vaddr;
846
847 if (xen_auto_xlat_grant_frames.count)
848 return -EINVAL;
849
850 vaddr = xen_remap(addr, PAGE_SIZE * max_nr_gframes);
851 if (vaddr == NULL) {
852 pr_warn("Failed to ioremap gnttab share frames (addr=0x%08lx)!\n",
853 addr);
854 return -ENOMEM;
855 }
856 pfn = kcalloc(max_nr_gframes, sizeof(pfn[0]), GFP_KERNEL);
857 if (!pfn) {
858 xen_unmap(vaddr);
859 return -ENOMEM;
860 }
861 for (i = 0; i < max_nr_gframes; i++)
862 pfn[i] = PFN_DOWN(addr) + i;
863
864 xen_auto_xlat_grant_frames.vaddr = vaddr;
865 xen_auto_xlat_grant_frames.pfn = pfn;
866 xen_auto_xlat_grant_frames.count = max_nr_gframes;
867
868 return 0;
869}
870EXPORT_SYMBOL_GPL(gnttab_setup_auto_xlat_frames);
871
872void gnttab_free_auto_xlat_frames(void)
873{
874 if (!xen_auto_xlat_grant_frames.count)
875 return;
876 kfree(xen_auto_xlat_grant_frames.pfn);
877 xen_unmap(xen_auto_xlat_grant_frames.vaddr);
878
879 xen_auto_xlat_grant_frames.pfn = NULL;
880 xen_auto_xlat_grant_frames.count = 0;
881 xen_auto_xlat_grant_frames.vaddr = NULL;
882}
883EXPORT_SYMBOL_GPL(gnttab_free_auto_xlat_frames);
884
841/* Handling of paged out grant targets (GNTST_eagain) */ 885/* Handling of paged out grant targets (GNTST_eagain) */
842#define MAX_DELAY 256 886#define MAX_DELAY 256
843static inline void 887static inline void
@@ -1068,6 +1112,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
1068 struct xen_add_to_physmap xatp; 1112 struct xen_add_to_physmap xatp;
1069 unsigned int i = end_idx; 1113 unsigned int i = end_idx;
1070 rc = 0; 1114 rc = 0;
1115 BUG_ON(xen_auto_xlat_grant_frames.count < nr_gframes);
1071 /* 1116 /*
1072 * Loop backwards, so that the first hypercall has the largest 1117 * Loop backwards, so that the first hypercall has the largest
1073 * index, ensuring that the table will grow only once. 1118 * index, ensuring that the table will grow only once.
@@ -1076,7 +1121,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
1076 xatp.domid = DOMID_SELF; 1121 xatp.domid = DOMID_SELF;
1077 xatp.idx = i; 1122 xatp.idx = i;
1078 xatp.space = XENMAPSPACE_grant_table; 1123 xatp.space = XENMAPSPACE_grant_table;
1079 xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i; 1124 xatp.gpfn = xen_auto_xlat_grant_frames.pfn[i];
1080 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); 1125 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
1081 if (rc != 0) { 1126 if (rc != 0) {
1082 pr_warn("grant table add_to_physmap failed, err=%d\n", 1127 pr_warn("grant table add_to_physmap failed, err=%d\n",
@@ -1174,11 +1219,10 @@ static int gnttab_setup(void)
1174 return -ENOSYS; 1219 return -ENOSYS;
1175 1220
1176 if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) { 1221 if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) {
1177 gnttab_shared.addr = xen_remap(xen_hvm_resume_frames, 1222 gnttab_shared.addr = xen_auto_xlat_grant_frames.vaddr;
1178 PAGE_SIZE * max_nr_gframes);
1179 if (gnttab_shared.addr == NULL) { 1223 if (gnttab_shared.addr == NULL) {
1180 pr_warn("Failed to ioremap gnttab share frames (addr=0x%08lx)!\n", 1224 pr_warn("gnttab share frames (addr=0x%08lx) is not mapped!\n",
1181 xen_hvm_resume_frames); 1225 (unsigned long)xen_auto_xlat_grant_frames.vaddr);
1182 return -ENOMEM; 1226 return -ENOMEM;
1183 } 1227 }
1184 } 1228 }