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.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 006726688baf..b2b0a375b348 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -38,6 +38,7 @@
38#include <linux/vmalloc.h> 38#include <linux/vmalloc.h>
39#include <linux/uaccess.h> 39#include <linux/uaccess.h>
40#include <linux/io.h> 40#include <linux/io.h>
41#include <linux/delay.h>
41#include <linux/hardirq.h> 42#include <linux/hardirq.h>
42 43
43#include <xen/xen.h> 44#include <xen/xen.h>
@@ -47,6 +48,7 @@
47#include <xen/interface/memory.h> 48#include <xen/interface/memory.h>
48#include <xen/hvc-console.h> 49#include <xen/hvc-console.h>
49#include <asm/xen/hypercall.h> 50#include <asm/xen/hypercall.h>
51#include <asm/xen/interface.h>
50 52
51#include <asm/pgtable.h> 53#include <asm/pgtable.h>
52#include <asm/sync_bitops.h> 54#include <asm/sync_bitops.h>
@@ -285,10 +287,9 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
285} 287}
286EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); 288EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
287 289
288void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid, 290static void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid,
289 unsigned long frame, int flags, 291 unsigned long frame, int flags,
290 unsigned page_off, 292 unsigned page_off, unsigned length)
291 unsigned length)
292{ 293{
293 gnttab_shared.v2[ref].sub_page.frame = frame; 294 gnttab_shared.v2[ref].sub_page.frame = frame;
294 gnttab_shared.v2[ref].sub_page.page_off = page_off; 295 gnttab_shared.v2[ref].sub_page.page_off = page_off;
@@ -345,9 +346,9 @@ bool gnttab_subpage_grants_available(void)
345} 346}
346EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available); 347EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available);
347 348
348void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid, 349static void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid,
349 int flags, domid_t trans_domid, 350 int flags, domid_t trans_domid,
350 grant_ref_t trans_gref) 351 grant_ref_t trans_gref)
351{ 352{
352 gnttab_shared.v2[ref].transitive.trans_domid = trans_domid; 353 gnttab_shared.v2[ref].transitive.trans_domid = trans_domid;
353 gnttab_shared.v2[ref].transitive.gref = trans_gref; 354 gnttab_shared.v2[ref].transitive.gref = trans_gref;
@@ -823,6 +824,52 @@ unsigned int gnttab_max_grant_frames(void)
823} 824}
824EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 825EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
825 826
827/* Handling of paged out grant targets (GNTST_eagain) */
828#define MAX_DELAY 256
829static inline void
830gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status,
831 const char *func)
832{
833 unsigned delay = 1;
834
835 do {
836 BUG_ON(HYPERVISOR_grant_table_op(cmd, gop, 1));
837 if (*status == GNTST_eagain)
838 msleep(delay++);
839 } while ((*status == GNTST_eagain) && (delay < MAX_DELAY));
840
841 if (delay >= MAX_DELAY) {
842 printk(KERN_ERR "%s: %s eagain grant\n", func, current->comm);
843 *status = GNTST_bad_page;
844 }
845}
846
847void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count)
848{
849 struct gnttab_map_grant_ref *op;
850
851 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, batch, count))
852 BUG();
853 for (op = batch; op < batch + count; op++)
854 if (op->status == GNTST_eagain)
855 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, op,
856 &op->status, __func__);
857}
858EXPORT_SYMBOL_GPL(gnttab_batch_map);
859
860void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
861{
862 struct gnttab_copy *op;
863
864 if (HYPERVISOR_grant_table_op(GNTTABOP_copy, batch, count))
865 BUG();
866 for (op = batch; op < batch + count; op++)
867 if (op->status == GNTST_eagain)
868 gnttab_retry_eagain_gop(GNTTABOP_copy, op,
869 &op->status, __func__);
870}
871EXPORT_SYMBOL_GPL(gnttab_batch_copy);
872
826int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, 873int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
827 struct gnttab_map_grant_ref *kmap_ops, 874 struct gnttab_map_grant_ref *kmap_ops,
828 struct page **pages, unsigned int count) 875 struct page **pages, unsigned int count)
@@ -836,6 +883,12 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
836 if (ret) 883 if (ret)
837 return ret; 884 return ret;
838 885
886 /* Retry eagain maps */
887 for (i = 0; i < count; i++)
888 if (map_ops[i].status == GNTST_eagain)
889 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i,
890 &map_ops[i].status, __func__);
891
839 if (xen_feature(XENFEAT_auto_translated_physmap)) 892 if (xen_feature(XENFEAT_auto_translated_physmap))
840 return ret; 893 return ret;
841 894