diff options
-rw-r--r-- | drivers/xen/grant-table.c | 72 | ||||
-rw-r--r-- | include/xen/grant_table.h | 13 |
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 | ||
125 | static struct gnttab_ops *gnttab_interface; | 136 | static struct gnttab_ops *gnttab_interface; |
@@ -261,6 +272,66 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, | |||
261 | } | 272 | } |
262 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); | 273 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); |
263 | 274 | ||
275 | void 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 | |||
289 | int 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 | } | ||
306 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage_ref); | ||
307 | |||
308 | int 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 | } | ||
327 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage); | ||
328 | |||
329 | bool gnttab_subpage_grants_available(void) | ||
330 | { | ||
331 | return gnttab_interface->update_subpage_entry != NULL; | ||
332 | } | ||
333 | EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available); | ||
334 | |||
264 | static int gnttab_query_foreign_access_v1(grant_ref_t ref) | 335 | static 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 | ||
818 | static void gnttab_request_version(void) | 890 | static 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 | ||
63 | int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, | 63 | int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, |
64 | int readonly); | 64 | int readonly); |
65 | int 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 | */ | ||
73 | bool 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 | ||
109 | void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, | 118 | void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, |
110 | unsigned long frame, int readonly); | 119 | unsigned long frame, int readonly); |
120 | int 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 | ||
112 | void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, | 125 | void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, |
113 | unsigned long pfn); | 126 | unsigned long pfn); |