aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/xen/grant-table.c72
-rw-r--r--include/xen/grant_table.h13
2 files changed, 85 insertions, 0 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 1589ea1a2445..c8312c7056f1 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -120,6 +120,17 @@ struct gnttab_ops {
120 * by bit operations. 120 * by bit operations.
121 */ 121 */
122 int (*query_foreign_access)(grant_ref_t ref); 122 int (*query_foreign_access)(grant_ref_t ref);
123 /*
124 * Grant a domain to access a range of bytes within the page referred by
125 * an available grant entry. Ref parameter is reference of a grant entry
126 * which will be sub-page accessed, domid is id of grantee domain, frame
127 * is frame address of subpage grant, flags is grant type and flag
128 * information, page_off is offset of the range of bytes, and length is
129 * length of bytes to be accessed.
130 */
131 void (*update_subpage_entry)(grant_ref_t ref, domid_t domid,
132 unsigned long frame, int flags,
133 unsigned page_off, unsigned length);
123}; 134};
124 135
125static struct gnttab_ops *gnttab_interface; 136static struct gnttab_ops *gnttab_interface;
@@ -261,6 +272,66 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
261} 272}
262EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); 273EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
263 274
275void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid,
276 unsigned long frame, int flags,
277 unsigned page_off,
278 unsigned length)
279{
280 gnttab_shared.v2[ref].sub_page.frame = frame;
281 gnttab_shared.v2[ref].sub_page.page_off = page_off;
282 gnttab_shared.v2[ref].sub_page.length = length;
283 gnttab_shared.v2[ref].hdr.domid = domid;
284 wmb();
285 gnttab_shared.v2[ref].hdr.flags =
286 GTF_permit_access | GTF_sub_page | flags;
287}
288
289int gnttab_grant_foreign_access_subpage_ref(grant_ref_t ref, domid_t domid,
290 unsigned long frame, int flags,
291 unsigned page_off,
292 unsigned length)
293{
294 if (flags & (GTF_accept_transfer | GTF_reading |
295 GTF_writing | GTF_transitive))
296 return -EPERM;
297
298 if (gnttab_interface->update_subpage_entry == NULL)
299 return -ENOSYS;
300
301 gnttab_interface->update_subpage_entry(ref, domid, frame, flags,
302 page_off, length);
303
304 return 0;
305}
306EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage_ref);
307
308int gnttab_grant_foreign_access_subpage(domid_t domid, unsigned long frame,
309 int flags, unsigned page_off,
310 unsigned length)
311{
312 int ref, rc;
313
314 ref = get_free_entries(1);
315 if (unlikely(ref < 0))
316 return -ENOSPC;
317
318 rc = gnttab_grant_foreign_access_subpage_ref(ref, domid, frame, flags,
319 page_off, length);
320 if (rc < 0) {
321 put_free_entry(ref);
322 return rc;
323 }
324
325 return ref;
326}
327EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage);
328
329bool gnttab_subpage_grants_available(void)
330{
331 return gnttab_interface->update_subpage_entry != NULL;
332}
333EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available);
334
264static int gnttab_query_foreign_access_v1(grant_ref_t ref) 335static int gnttab_query_foreign_access_v1(grant_ref_t ref)
265{ 336{
266 return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); 337 return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing);
@@ -813,6 +884,7 @@ static struct gnttab_ops gnttab_v2_ops = {
813 .end_foreign_access_ref = gnttab_end_foreign_access_ref_v2, 884 .end_foreign_access_ref = gnttab_end_foreign_access_ref_v2,
814 .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v2, 885 .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v2,
815 .query_foreign_access = gnttab_query_foreign_access_v2, 886 .query_foreign_access = gnttab_query_foreign_access_v2,
887 .update_subpage_entry = gnttab_update_subpage_entry_v2,
816}; 888};
817 889
818static void gnttab_request_version(void) 890static void gnttab_request_version(void)
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index fea4954174f0..2b492b9637b3 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -62,6 +62,15 @@ int gnttab_resume(void);
62 62
63int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, 63int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
64 int readonly); 64 int readonly);
65int gnttab_grant_foreign_access_subpage(domid_t domid, unsigned long frame,
66 int flags, unsigned page_off,
67 unsigned length);
68
69/*
70 * Are sub-page grants available on this version of Xen? Returns true if they
71 * are, and false if they're not.
72 */
73bool gnttab_subpage_grants_available(void);
65 74
66/* 75/*
67 * End access through the given grant reference, iff the grant entry is no 76 * End access through the given grant reference, iff the grant entry is no
@@ -108,6 +117,10 @@ void gnttab_cancel_free_callback(struct gnttab_free_callback *callback);
108 117
109void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, 118void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
110 unsigned long frame, int readonly); 119 unsigned long frame, int readonly);
120int gnttab_grant_foreign_access_subpage_ref(grant_ref_t ref, domid_t domid,
121 unsigned long frame, int flags,
122 unsigned page_off,
123 unsigned length);
111 124
112void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, 125void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
113 unsigned long pfn); 126 unsigned long pfn);