diff options
author | David Vrabel <david.vrabel@citrix.com> | 2014-07-02 06:25:29 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2014-07-14 15:28:30 -0400 |
commit | 438b33c7145ca8a5131a30c36d8f59bce119a19a (patch) | |
tree | 3f7550d8598a3cb764982543ba34efd35f787d0a /drivers/xen/grant-table.c | |
parent | 162e371712768248a38646eefa71af38b6e0f8ce (diff) |
xen/grant-table: remove support for V2 tables
Since 11c7ff17c9b6dbf3a4e4f36be30ad531a6cf0ec9 (xen/grant-table: Force
to use v1 of grants.) the code for V2 grant tables is not used.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen/grant-table.c')
-rw-r--r-- | drivers/xen/grant-table.c | 309 |
1 files changed, 6 insertions, 303 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index eeba7544f0cd..c254ae036f18 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -69,7 +69,6 @@ struct grant_frames xen_auto_xlat_grant_frames; | |||
69 | 69 | ||
70 | static union { | 70 | static union { |
71 | struct grant_entry_v1 *v1; | 71 | struct grant_entry_v1 *v1; |
72 | union grant_entry_v2 *v2; | ||
73 | void *addr; | 72 | void *addr; |
74 | } gnttab_shared; | 73 | } gnttab_shared; |
75 | 74 | ||
@@ -120,36 +119,10 @@ struct gnttab_ops { | |||
120 | * by bit operations. | 119 | * by bit operations. |
121 | */ | 120 | */ |
122 | int (*query_foreign_access)(grant_ref_t ref); | 121 | 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); | ||
134 | /* | ||
135 | * Redirect an available grant entry on domain A to another grant | ||
136 | * reference of domain B, then allow domain C to use grant reference | ||
137 | * of domain B transitively. Ref parameter is an available grant entry | ||
138 | * reference on domain A, domid is id of domain C which accesses grant | ||
139 | * entry transitively, flags is grant type and flag information, | ||
140 | * trans_domid is id of domain B whose grant entry is finally accessed | ||
141 | * transitively, trans_gref is grant entry transitive reference of | ||
142 | * domain B. | ||
143 | */ | ||
144 | void (*update_trans_entry)(grant_ref_t ref, domid_t domid, int flags, | ||
145 | domid_t trans_domid, grant_ref_t trans_gref); | ||
146 | }; | 122 | }; |
147 | 123 | ||
148 | static struct gnttab_ops *gnttab_interface; | 124 | static struct gnttab_ops *gnttab_interface; |
149 | 125 | ||
150 | /*This reflects status of grant entries, so act as a global value*/ | ||
151 | static grant_status_t *grstatus; | ||
152 | |||
153 | static int grant_table_version; | 126 | static int grant_table_version; |
154 | static int grefs_per_grant_frame; | 127 | static int grefs_per_grant_frame; |
155 | 128 | ||
@@ -231,7 +204,7 @@ static void put_free_entry(grant_ref_t ref) | |||
231 | } | 204 | } |
232 | 205 | ||
233 | /* | 206 | /* |
234 | * Following applies to gnttab_update_entry_v1 and gnttab_update_entry_v2. | 207 | * Following applies to gnttab_update_entry_v1. |
235 | * Introducing a valid entry into the grant table: | 208 | * Introducing a valid entry into the grant table: |
236 | * 1. Write ent->domid. | 209 | * 1. Write ent->domid. |
237 | * 2. Write ent->frame: | 210 | * 2. Write ent->frame: |
@@ -250,15 +223,6 @@ static void gnttab_update_entry_v1(grant_ref_t ref, domid_t domid, | |||
250 | gnttab_shared.v1[ref].flags = flags; | 223 | gnttab_shared.v1[ref].flags = flags; |
251 | } | 224 | } |
252 | 225 | ||
253 | static void gnttab_update_entry_v2(grant_ref_t ref, domid_t domid, | ||
254 | unsigned long frame, unsigned flags) | ||
255 | { | ||
256 | gnttab_shared.v2[ref].hdr.domid = domid; | ||
257 | gnttab_shared.v2[ref].full_page.frame = frame; | ||
258 | wmb(); | ||
259 | gnttab_shared.v2[ref].hdr.flags = GTF_permit_access | flags; | ||
260 | } | ||
261 | |||
262 | /* | 226 | /* |
263 | * Public grant-issuing interface functions | 227 | * Public grant-issuing interface functions |
264 | */ | 228 | */ |
@@ -285,132 +249,11 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, | |||
285 | } | 249 | } |
286 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); | 250 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); |
287 | 251 | ||
288 | static void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid, | ||
289 | unsigned long frame, int flags, | ||
290 | unsigned page_off, unsigned length) | ||
291 | { | ||
292 | gnttab_shared.v2[ref].sub_page.frame = frame; | ||
293 | gnttab_shared.v2[ref].sub_page.page_off = page_off; | ||
294 | gnttab_shared.v2[ref].sub_page.length = length; | ||
295 | gnttab_shared.v2[ref].hdr.domid = domid; | ||
296 | wmb(); | ||
297 | gnttab_shared.v2[ref].hdr.flags = | ||
298 | GTF_permit_access | GTF_sub_page | flags; | ||
299 | } | ||
300 | |||
301 | int gnttab_grant_foreign_access_subpage_ref(grant_ref_t ref, domid_t domid, | ||
302 | unsigned long frame, int flags, | ||
303 | unsigned page_off, | ||
304 | unsigned length) | ||
305 | { | ||
306 | if (flags & (GTF_accept_transfer | GTF_reading | | ||
307 | GTF_writing | GTF_transitive)) | ||
308 | return -EPERM; | ||
309 | |||
310 | if (gnttab_interface->update_subpage_entry == NULL) | ||
311 | return -ENOSYS; | ||
312 | |||
313 | gnttab_interface->update_subpage_entry(ref, domid, frame, flags, | ||
314 | page_off, length); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage_ref); | ||
319 | |||
320 | int gnttab_grant_foreign_access_subpage(domid_t domid, unsigned long frame, | ||
321 | int flags, unsigned page_off, | ||
322 | unsigned length) | ||
323 | { | ||
324 | int ref, rc; | ||
325 | |||
326 | ref = get_free_entries(1); | ||
327 | if (unlikely(ref < 0)) | ||
328 | return -ENOSPC; | ||
329 | |||
330 | rc = gnttab_grant_foreign_access_subpage_ref(ref, domid, frame, flags, | ||
331 | page_off, length); | ||
332 | if (rc < 0) { | ||
333 | put_free_entry(ref); | ||
334 | return rc; | ||
335 | } | ||
336 | |||
337 | return ref; | ||
338 | } | ||
339 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage); | ||
340 | |||
341 | bool gnttab_subpage_grants_available(void) | ||
342 | { | ||
343 | return gnttab_interface->update_subpage_entry != NULL; | ||
344 | } | ||
345 | EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available); | ||
346 | |||
347 | static void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid, | ||
348 | int flags, domid_t trans_domid, | ||
349 | grant_ref_t trans_gref) | ||
350 | { | ||
351 | gnttab_shared.v2[ref].transitive.trans_domid = trans_domid; | ||
352 | gnttab_shared.v2[ref].transitive.gref = trans_gref; | ||
353 | gnttab_shared.v2[ref].hdr.domid = domid; | ||
354 | wmb(); | ||
355 | gnttab_shared.v2[ref].hdr.flags = | ||
356 | GTF_permit_access | GTF_transitive | flags; | ||
357 | } | ||
358 | |||
359 | int gnttab_grant_foreign_access_trans_ref(grant_ref_t ref, domid_t domid, | ||
360 | int flags, domid_t trans_domid, | ||
361 | grant_ref_t trans_gref) | ||
362 | { | ||
363 | if (flags & (GTF_accept_transfer | GTF_reading | | ||
364 | GTF_writing | GTF_sub_page)) | ||
365 | return -EPERM; | ||
366 | |||
367 | if (gnttab_interface->update_trans_entry == NULL) | ||
368 | return -ENOSYS; | ||
369 | |||
370 | gnttab_interface->update_trans_entry(ref, domid, flags, trans_domid, | ||
371 | trans_gref); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_trans_ref); | ||
376 | |||
377 | int gnttab_grant_foreign_access_trans(domid_t domid, int flags, | ||
378 | domid_t trans_domid, | ||
379 | grant_ref_t trans_gref) | ||
380 | { | ||
381 | int ref, rc; | ||
382 | |||
383 | ref = get_free_entries(1); | ||
384 | if (unlikely(ref < 0)) | ||
385 | return -ENOSPC; | ||
386 | |||
387 | rc = gnttab_grant_foreign_access_trans_ref(ref, domid, flags, | ||
388 | trans_domid, trans_gref); | ||
389 | if (rc < 0) { | ||
390 | put_free_entry(ref); | ||
391 | return rc; | ||
392 | } | ||
393 | |||
394 | return ref; | ||
395 | } | ||
396 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_trans); | ||
397 | |||
398 | bool gnttab_trans_grants_available(void) | ||
399 | { | ||
400 | return gnttab_interface->update_trans_entry != NULL; | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(gnttab_trans_grants_available); | ||
403 | |||
404 | static int gnttab_query_foreign_access_v1(grant_ref_t ref) | 252 | static int gnttab_query_foreign_access_v1(grant_ref_t ref) |
405 | { | 253 | { |
406 | return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); | 254 | return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing); |
407 | } | 255 | } |
408 | 256 | ||
409 | static int gnttab_query_foreign_access_v2(grant_ref_t ref) | ||
410 | { | ||
411 | return grstatus[ref] & (GTF_reading|GTF_writing); | ||
412 | } | ||
413 | |||
414 | int gnttab_query_foreign_access(grant_ref_t ref) | 257 | int gnttab_query_foreign_access(grant_ref_t ref) |
415 | { | 258 | { |
416 | return gnttab_interface->query_foreign_access(ref); | 259 | return gnttab_interface->query_foreign_access(ref); |
@@ -433,29 +276,6 @@ static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly) | |||
433 | return 1; | 276 | return 1; |
434 | } | 277 | } |
435 | 278 | ||
436 | static int gnttab_end_foreign_access_ref_v2(grant_ref_t ref, int readonly) | ||
437 | { | ||
438 | gnttab_shared.v2[ref].hdr.flags = 0; | ||
439 | mb(); | ||
440 | if (grstatus[ref] & (GTF_reading|GTF_writing)) { | ||
441 | return 0; | ||
442 | } else { | ||
443 | /* The read of grstatus needs to have acquire | ||
444 | semantics. On x86, reads already have | ||
445 | that, and we just need to protect against | ||
446 | compiler reorderings. On other | ||
447 | architectures we may need a full | ||
448 | barrier. */ | ||
449 | #ifdef CONFIG_X86 | ||
450 | barrier(); | ||
451 | #else | ||
452 | mb(); | ||
453 | #endif | ||
454 | } | ||
455 | |||
456 | return 1; | ||
457 | } | ||
458 | |||
459 | static inline int _gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) | 279 | static inline int _gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) |
460 | { | 280 | { |
461 | return gnttab_interface->end_foreign_access_ref(ref, readonly); | 281 | return gnttab_interface->end_foreign_access_ref(ref, readonly); |
@@ -616,37 +436,6 @@ static unsigned long gnttab_end_foreign_transfer_ref_v1(grant_ref_t ref) | |||
616 | return frame; | 436 | return frame; |
617 | } | 437 | } |
618 | 438 | ||
619 | static unsigned long gnttab_end_foreign_transfer_ref_v2(grant_ref_t ref) | ||
620 | { | ||
621 | unsigned long frame; | ||
622 | u16 flags; | ||
623 | u16 *pflags; | ||
624 | |||
625 | pflags = &gnttab_shared.v2[ref].hdr.flags; | ||
626 | |||
627 | /* | ||
628 | * If a transfer is not even yet started, try to reclaim the grant | ||
629 | * reference and return failure (== 0). | ||
630 | */ | ||
631 | while (!((flags = *pflags) & GTF_transfer_committed)) { | ||
632 | if (sync_cmpxchg(pflags, flags, 0) == flags) | ||
633 | return 0; | ||
634 | cpu_relax(); | ||
635 | } | ||
636 | |||
637 | /* If a transfer is in progress then wait until it is completed. */ | ||
638 | while (!(flags & GTF_transfer_completed)) { | ||
639 | flags = *pflags; | ||
640 | cpu_relax(); | ||
641 | } | ||
642 | |||
643 | rmb(); /* Read the frame number /after/ reading completion status. */ | ||
644 | frame = gnttab_shared.v2[ref].full_page.frame; | ||
645 | BUG_ON(frame == 0); | ||
646 | |||
647 | return frame; | ||
648 | } | ||
649 | |||
650 | unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) | 439 | unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) |
651 | { | 440 | { |
652 | return gnttab_interface->end_foreign_transfer_ref(ref); | 441 | return gnttab_interface->end_foreign_transfer_ref(ref); |
@@ -962,12 +751,6 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
962 | } | 751 | } |
963 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); | 752 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); |
964 | 753 | ||
965 | static unsigned nr_status_frames(unsigned nr_grant_frames) | ||
966 | { | ||
967 | BUG_ON(grefs_per_grant_frame == 0); | ||
968 | return (nr_grant_frames * grefs_per_grant_frame + SPP - 1) / SPP; | ||
969 | } | ||
970 | |||
971 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) | 754 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) |
972 | { | 755 | { |
973 | int rc; | 756 | int rc; |
@@ -985,55 +768,6 @@ static void gnttab_unmap_frames_v1(void) | |||
985 | arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); | 768 | arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); |
986 | } | 769 | } |
987 | 770 | ||
988 | static int gnttab_map_frames_v2(xen_pfn_t *frames, unsigned int nr_gframes) | ||
989 | { | ||
990 | uint64_t *sframes; | ||
991 | unsigned int nr_sframes; | ||
992 | struct gnttab_get_status_frames getframes; | ||
993 | int rc; | ||
994 | |||
995 | nr_sframes = nr_status_frames(nr_gframes); | ||
996 | |||
997 | /* No need for kzalloc as it is initialized in following hypercall | ||
998 | * GNTTABOP_get_status_frames. | ||
999 | */ | ||
1000 | sframes = kmalloc(nr_sframes * sizeof(uint64_t), GFP_ATOMIC); | ||
1001 | if (!sframes) | ||
1002 | return -ENOMEM; | ||
1003 | |||
1004 | getframes.dom = DOMID_SELF; | ||
1005 | getframes.nr_frames = nr_sframes; | ||
1006 | set_xen_guest_handle(getframes.frame_list, sframes); | ||
1007 | |||
1008 | rc = HYPERVISOR_grant_table_op(GNTTABOP_get_status_frames, | ||
1009 | &getframes, 1); | ||
1010 | if (rc == -ENOSYS) { | ||
1011 | kfree(sframes); | ||
1012 | return -ENOSYS; | ||
1013 | } | ||
1014 | |||
1015 | BUG_ON(rc || getframes.status); | ||
1016 | |||
1017 | rc = arch_gnttab_map_status(sframes, nr_sframes, | ||
1018 | nr_status_frames(gnttab_max_grant_frames()), | ||
1019 | &grstatus); | ||
1020 | BUG_ON(rc); | ||
1021 | kfree(sframes); | ||
1022 | |||
1023 | rc = arch_gnttab_map_shared(frames, nr_gframes, | ||
1024 | gnttab_max_grant_frames(), | ||
1025 | &gnttab_shared.addr); | ||
1026 | BUG_ON(rc); | ||
1027 | |||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1031 | static void gnttab_unmap_frames_v2(void) | ||
1032 | { | ||
1033 | arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); | ||
1034 | arch_gnttab_unmap(grstatus, nr_status_frames(nr_grant_frames)); | ||
1035 | } | ||
1036 | |||
1037 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | 771 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) |
1038 | { | 772 | { |
1039 | struct gnttab_setup_table setup; | 773 | struct gnttab_setup_table setup; |
@@ -1101,43 +835,13 @@ static struct gnttab_ops gnttab_v1_ops = { | |||
1101 | .query_foreign_access = gnttab_query_foreign_access_v1, | 835 | .query_foreign_access = gnttab_query_foreign_access_v1, |
1102 | }; | 836 | }; |
1103 | 837 | ||
1104 | static struct gnttab_ops gnttab_v2_ops = { | ||
1105 | .map_frames = gnttab_map_frames_v2, | ||
1106 | .unmap_frames = gnttab_unmap_frames_v2, | ||
1107 | .update_entry = gnttab_update_entry_v2, | ||
1108 | .end_foreign_access_ref = gnttab_end_foreign_access_ref_v2, | ||
1109 | .end_foreign_transfer_ref = gnttab_end_foreign_transfer_ref_v2, | ||
1110 | .query_foreign_access = gnttab_query_foreign_access_v2, | ||
1111 | .update_subpage_entry = gnttab_update_subpage_entry_v2, | ||
1112 | .update_trans_entry = gnttab_update_trans_entry_v2, | ||
1113 | }; | ||
1114 | |||
1115 | static void gnttab_request_version(void) | 838 | static void gnttab_request_version(void) |
1116 | { | 839 | { |
1117 | int rc; | 840 | /* Only version 1 is used, which will always be available. */ |
1118 | struct gnttab_set_version gsv; | 841 | grant_table_version = 1; |
842 | grefs_per_grant_frame = PAGE_SIZE / sizeof(struct grant_entry_v1); | ||
843 | gnttab_interface = &gnttab_v1_ops; | ||
1119 | 844 | ||
1120 | gsv.version = 1; | ||
1121 | |||
1122 | rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); | ||
1123 | if (rc == 0 && gsv.version == 2) { | ||
1124 | grant_table_version = 2; | ||
1125 | grefs_per_grant_frame = PAGE_SIZE / sizeof(union grant_entry_v2); | ||
1126 | gnttab_interface = &gnttab_v2_ops; | ||
1127 | } else if (grant_table_version == 2) { | ||
1128 | /* | ||
1129 | * If we've already used version 2 features, | ||
1130 | * but then suddenly discover that they're not | ||
1131 | * available (e.g. migrating to an older | ||
1132 | * version of Xen), almost unbounded badness | ||
1133 | * can happen. | ||
1134 | */ | ||
1135 | panic("we need grant tables version 2, but only version 1 is available"); | ||
1136 | } else { | ||
1137 | grant_table_version = 1; | ||
1138 | grefs_per_grant_frame = PAGE_SIZE / sizeof(struct grant_entry_v1); | ||
1139 | gnttab_interface = &gnttab_v1_ops; | ||
1140 | } | ||
1141 | pr_info("Grant tables using version %d layout\n", grant_table_version); | 845 | pr_info("Grant tables using version %d layout\n", grant_table_version); |
1142 | } | 846 | } |
1143 | 847 | ||
@@ -1225,8 +929,7 @@ int gnttab_init(void) | |||
1225 | } | 929 | } |
1226 | } | 930 | } |
1227 | 931 | ||
1228 | ret = arch_gnttab_init(max_nr_grant_frames, | 932 | ret = arch_gnttab_init(max_nr_grant_frames); |
1229 | nr_status_frames(max_nr_grant_frames)); | ||
1230 | if (ret < 0) | 933 | if (ret < 0) |
1231 | goto ini_nomem; | 934 | goto ini_nomem; |
1232 | 935 | ||