xen/grant: Introduce helpers to split a page into grant
[firefly-linux-kernel-4.4.55.git] / include / xen / grant_table.h
index 4478f4b4aae2ff06473f2aff0e0100684f11c2bf..05b5b08c2afc90fd767976c334e56213170bd8e1 100644 (file)
 #include <asm/xen/hypervisor.h>
 
 #include <xen/features.h>
+#include <xen/page.h>
 #include <linux/mm_types.h>
 #include <linux/page-flags.h>
+#include <linux/kernel.h>
 
 #define GNTTAB_RESERVED_XENSTORE 1
 
@@ -224,4 +226,44 @@ static inline struct xen_page_foreign *xen_page_foreign(struct page *page)
 #endif
 }
 
+/* Split Linux page in chunk of the size of the grant and call fn
+ *
+ * Parameters of fn:
+ *     gfn: guest frame number
+ *     offset: offset in the grant
+ *     len: length of the data in the grant.
+ *     data: internal information
+ */
+typedef void (*xen_grant_fn_t)(unsigned long gfn, unsigned int offset,
+                              unsigned int len, void *data);
+
+void gnttab_foreach_grant_in_range(struct page *page,
+                                  unsigned int offset,
+                                  unsigned int len,
+                                  xen_grant_fn_t fn,
+                                  void *data);
+
+/* Helper to get to call fn only on the first "grant chunk" */
+static inline void gnttab_for_one_grant(struct page *page, unsigned int offset,
+                                       unsigned len, xen_grant_fn_t fn,
+                                       void *data)
+{
+       /* The first request is limited to the size of one grant */
+       len = min_t(unsigned int, XEN_PAGE_SIZE - (offset & ~XEN_PAGE_MASK),
+                   len);
+
+       gnttab_foreach_grant_in_range(page, offset, len, fn, data);
+}
+
+/* Get the number of grant in a specified region
+ *
+ * start: Offset from the beginning of the first page
+ * len: total length of data (can cross multiple page)
+ */
+static inline unsigned int gnttab_count_grant(unsigned int start,
+                                             unsigned int len)
+{
+       return XEN_PFN_UP(xen_offset_in_page(start) + len);
+}
+
 #endif /* __ASM_GNTTAB_H__ */