diff options
| author | Juergen Gross <jgross@suse.com> | 2017-11-02 05:19:19 -0400 |
|---|---|---|
| committer | Boris Ostrovsky <boris.ostrovsky@oracle.com> | 2017-11-06 15:50:17 -0500 |
| commit | 83c69324f43816f8259d1a361062a974f4bdb86d (patch) | |
| tree | 3b5963faa5e846f24ab0531a64b94b9cd05bdc6a | |
| parent | 56c9c700c4399858e50971d98ac44b5842b06a87 (diff) | |
xen: add grant interface version dependent constants to gnttab_ops
Instead of having multiple variables with constants like
grant_table_version or grefs_per_grant_frame add those to struct
gnttab_ops and access them just via the gnttab_interface pointer.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
| -rw-r--r-- | drivers/xen/grant-table.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index db6a1b9efd11..573e7fe9b147 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
| @@ -78,6 +78,14 @@ static union { | |||
| 78 | /*This is a structure of function pointers for grant table*/ | 78 | /*This is a structure of function pointers for grant table*/ |
| 79 | struct gnttab_ops { | 79 | struct gnttab_ops { |
| 80 | /* | 80 | /* |
| 81 | * Version of the grant interface. | ||
| 82 | */ | ||
| 83 | unsigned int version; | ||
| 84 | /* | ||
| 85 | * Grant refs per grant frame. | ||
| 86 | */ | ||
| 87 | unsigned int grefs_per_grant_frame; | ||
| 88 | /* | ||
| 81 | * Mapping a list of frames for storing grant entries. Frames parameter | 89 | * Mapping a list of frames for storing grant entries. Frames parameter |
| 82 | * is used to store grant table address when grant table being setup, | 90 | * is used to store grant table address when grant table being setup, |
| 83 | * nr_gframes is the number of frames to map grant table. Returning | 91 | * nr_gframes is the number of frames to map grant table. Returning |
| @@ -134,9 +142,6 @@ static const struct gnttab_ops *gnttab_interface; | |||
| 134 | /* This reflects status of grant entries, so act as a global value. */ | 142 | /* This reflects status of grant entries, so act as a global value. */ |
| 135 | static grant_status_t *grstatus; | 143 | static grant_status_t *grstatus; |
| 136 | 144 | ||
| 137 | static int grant_table_version; | ||
| 138 | static int grefs_per_grant_frame; | ||
| 139 | |||
| 140 | static struct gnttab_free_callback *gnttab_free_callback_list; | 145 | static struct gnttab_free_callback *gnttab_free_callback_list; |
| 141 | 146 | ||
| 142 | static int gnttab_expand(unsigned int req_entries); | 147 | static int gnttab_expand(unsigned int req_entries); |
| @@ -636,19 +641,26 @@ void gnttab_cancel_free_callback(struct gnttab_free_callback *callback) | |||
| 636 | } | 641 | } |
| 637 | EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback); | 642 | EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback); |
| 638 | 643 | ||
| 644 | static unsigned int gnttab_frames(unsigned int frames, unsigned int align) | ||
| 645 | { | ||
| 646 | return (frames * gnttab_interface->grefs_per_grant_frame + align - 1) / | ||
| 647 | align; | ||
| 648 | } | ||
| 649 | |||
| 639 | static int grow_gnttab_list(unsigned int more_frames) | 650 | static int grow_gnttab_list(unsigned int more_frames) |
| 640 | { | 651 | { |
| 641 | unsigned int new_nr_grant_frames, extra_entries, i; | 652 | unsigned int new_nr_grant_frames, extra_entries, i; |
| 642 | unsigned int nr_glist_frames, new_nr_glist_frames; | 653 | unsigned int nr_glist_frames, new_nr_glist_frames; |
| 654 | unsigned int grefs_per_frame; | ||
| 643 | 655 | ||
| 644 | BUG_ON(grefs_per_grant_frame == 0); | 656 | BUG_ON(gnttab_interface == NULL); |
| 657 | grefs_per_frame = gnttab_interface->grefs_per_grant_frame; | ||
| 645 | 658 | ||
| 646 | new_nr_grant_frames = nr_grant_frames + more_frames; | 659 | new_nr_grant_frames = nr_grant_frames + more_frames; |
| 647 | extra_entries = more_frames * grefs_per_grant_frame; | 660 | extra_entries = more_frames * grefs_per_frame; |
| 648 | 661 | ||
| 649 | nr_glist_frames = (nr_grant_frames * grefs_per_grant_frame + RPP - 1) / RPP; | 662 | nr_glist_frames = gnttab_frames(nr_grant_frames, RPP); |
| 650 | new_nr_glist_frames = | 663 | new_nr_glist_frames = gnttab_frames(new_nr_grant_frames, RPP); |
| 651 | (new_nr_grant_frames * grefs_per_grant_frame + RPP - 1) / RPP; | ||
| 652 | for (i = nr_glist_frames; i < new_nr_glist_frames; i++) { | 664 | for (i = nr_glist_frames; i < new_nr_glist_frames; i++) { |
| 653 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC); | 665 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC); |
| 654 | if (!gnttab_list[i]) | 666 | if (!gnttab_list[i]) |
| @@ -656,12 +668,12 @@ static int grow_gnttab_list(unsigned int more_frames) | |||
| 656 | } | 668 | } |
| 657 | 669 | ||
| 658 | 670 | ||
| 659 | for (i = grefs_per_grant_frame * nr_grant_frames; | 671 | for (i = grefs_per_frame * nr_grant_frames; |
| 660 | i < grefs_per_grant_frame * new_nr_grant_frames - 1; i++) | 672 | i < grefs_per_frame * new_nr_grant_frames - 1; i++) |
| 661 | gnttab_entry(i) = i + 1; | 673 | gnttab_entry(i) = i + 1; |
| 662 | 674 | ||
| 663 | gnttab_entry(i) = gnttab_free_head; | 675 | gnttab_entry(i) = gnttab_free_head; |
| 664 | gnttab_free_head = grefs_per_grant_frame * nr_grant_frames; | 676 | gnttab_free_head = grefs_per_frame * nr_grant_frames; |
| 665 | gnttab_free_count += extra_entries; | 677 | gnttab_free_count += extra_entries; |
| 666 | 678 | ||
| 667 | nr_grant_frames = new_nr_grant_frames; | 679 | nr_grant_frames = new_nr_grant_frames; |
| @@ -1013,8 +1025,8 @@ EXPORT_SYMBOL_GPL(gnttab_unmap_refs_sync); | |||
| 1013 | 1025 | ||
| 1014 | static unsigned int nr_status_frames(unsigned int nr_grant_frames) | 1026 | static unsigned int nr_status_frames(unsigned int nr_grant_frames) |
| 1015 | { | 1027 | { |
| 1016 | BUG_ON(grefs_per_grant_frame == 0); | 1028 | BUG_ON(gnttab_interface == NULL); |
| 1017 | return (nr_grant_frames * grefs_per_grant_frame + SPP - 1) / SPP; | 1029 | return gnttab_frames(nr_grant_frames, SPP); |
| 1018 | } | 1030 | } |
| 1019 | 1031 | ||
| 1020 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) | 1032 | static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes) |
| @@ -1142,6 +1154,9 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | |||
| 1142 | } | 1154 | } |
| 1143 | 1155 | ||
| 1144 | static const struct gnttab_ops gnttab_v1_ops = { | 1156 | static const struct gnttab_ops gnttab_v1_ops = { |
| 1157 | .version = 1, | ||
| 1158 | .grefs_per_grant_frame = XEN_PAGE_SIZE / | ||
| 1159 | sizeof(struct grant_entry_v1), | ||
| 1145 | .map_frames = gnttab_map_frames_v1, | 1160 | .map_frames = gnttab_map_frames_v1, |
| 1146 | .unmap_frames = gnttab_unmap_frames_v1, | 1161 | .unmap_frames = gnttab_unmap_frames_v1, |
| 1147 | .update_entry = gnttab_update_entry_v1, | 1162 | .update_entry = gnttab_update_entry_v1, |
| @@ -1151,6 +1166,9 @@ static const struct gnttab_ops gnttab_v1_ops = { | |||
| 1151 | }; | 1166 | }; |
| 1152 | 1167 | ||
| 1153 | static const struct gnttab_ops gnttab_v2_ops = { | 1168 | static const struct gnttab_ops gnttab_v2_ops = { |
| 1169 | .version = 2, | ||
| 1170 | .grefs_per_grant_frame = XEN_PAGE_SIZE / | ||
| 1171 | sizeof(union grant_entry_v2), | ||
| 1154 | .map_frames = gnttab_map_frames_v2, | 1172 | .map_frames = gnttab_map_frames_v2, |
| 1155 | .unmap_frames = gnttab_unmap_frames_v2, | 1173 | .unmap_frames = gnttab_unmap_frames_v2, |
| 1156 | .update_entry = gnttab_update_entry_v2, | 1174 | .update_entry = gnttab_update_entry_v2, |
| @@ -1167,18 +1185,12 @@ static void gnttab_request_version(void) | |||
| 1167 | gsv.version = 1; | 1185 | gsv.version = 1; |
| 1168 | 1186 | ||
| 1169 | rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); | 1187 | rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); |
| 1170 | if (rc == 0 && gsv.version == 2) { | 1188 | if (rc == 0 && gsv.version == 2) |
| 1171 | grant_table_version = 2; | ||
| 1172 | grefs_per_grant_frame = XEN_PAGE_SIZE / | ||
| 1173 | sizeof(union grant_entry_v2); | ||
| 1174 | gnttab_interface = &gnttab_v2_ops; | 1189 | gnttab_interface = &gnttab_v2_ops; |
| 1175 | } else { | 1190 | else |
| 1176 | grant_table_version = 1; | ||
| 1177 | grefs_per_grant_frame = XEN_PAGE_SIZE / | ||
| 1178 | sizeof(struct grant_entry_v1); | ||
| 1179 | gnttab_interface = &gnttab_v1_ops; | 1191 | gnttab_interface = &gnttab_v1_ops; |
| 1180 | } | 1192 | pr_info("Grant tables using version %d layout\n", |
| 1181 | pr_info("Grant tables using version %d layout\n", grant_table_version); | 1193 | gnttab_interface->version); |
| 1182 | } | 1194 | } |
| 1183 | 1195 | ||
| 1184 | static int gnttab_setup(void) | 1196 | static int gnttab_setup(void) |
| @@ -1218,10 +1230,10 @@ static int gnttab_expand(unsigned int req_entries) | |||
| 1218 | int rc; | 1230 | int rc; |
| 1219 | unsigned int cur, extra; | 1231 | unsigned int cur, extra; |
| 1220 | 1232 | ||
| 1221 | BUG_ON(grefs_per_grant_frame == 0); | 1233 | BUG_ON(gnttab_interface == NULL); |
| 1222 | cur = nr_grant_frames; | 1234 | cur = nr_grant_frames; |
| 1223 | extra = ((req_entries + (grefs_per_grant_frame-1)) / | 1235 | extra = ((req_entries + gnttab_interface->grefs_per_grant_frame - 1) / |
| 1224 | grefs_per_grant_frame); | 1236 | gnttab_interface->grefs_per_grant_frame); |
| 1225 | if (cur + extra > gnttab_max_grant_frames()) { | 1237 | if (cur + extra > gnttab_max_grant_frames()) { |
| 1226 | pr_warn_ratelimited("xen/grant-table: max_grant_frames reached" | 1238 | pr_warn_ratelimited("xen/grant-table: max_grant_frames reached" |
| 1227 | " cur=%u extra=%u limit=%u" | 1239 | " cur=%u extra=%u limit=%u" |
| @@ -1253,16 +1265,16 @@ int gnttab_init(void) | |||
| 1253 | /* Determine the maximum number of frames required for the | 1265 | /* Determine the maximum number of frames required for the |
| 1254 | * grant reference free list on the current hypervisor. | 1266 | * grant reference free list on the current hypervisor. |
| 1255 | */ | 1267 | */ |
| 1256 | BUG_ON(grefs_per_grant_frame == 0); | 1268 | BUG_ON(gnttab_interface == NULL); |
| 1257 | max_nr_glist_frames = (max_nr_grant_frames * | 1269 | max_nr_glist_frames = (max_nr_grant_frames * |
| 1258 | grefs_per_grant_frame / RPP); | 1270 | gnttab_interface->grefs_per_grant_frame / RPP); |
| 1259 | 1271 | ||
| 1260 | gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), | 1272 | gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), |
| 1261 | GFP_KERNEL); | 1273 | GFP_KERNEL); |
| 1262 | if (gnttab_list == NULL) | 1274 | if (gnttab_list == NULL) |
| 1263 | return -ENOMEM; | 1275 | return -ENOMEM; |
| 1264 | 1276 | ||
| 1265 | nr_glist_frames = (nr_grant_frames * grefs_per_grant_frame + RPP - 1) / RPP; | 1277 | nr_glist_frames = gnttab_frames(nr_grant_frames, RPP); |
| 1266 | for (i = 0; i < nr_glist_frames; i++) { | 1278 | for (i = 0; i < nr_glist_frames; i++) { |
| 1267 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); | 1279 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); |
| 1268 | if (gnttab_list[i] == NULL) { | 1280 | if (gnttab_list[i] == NULL) { |
| @@ -1281,7 +1293,8 @@ int gnttab_init(void) | |||
| 1281 | goto ini_nomem; | 1293 | goto ini_nomem; |
| 1282 | } | 1294 | } |
| 1283 | 1295 | ||
| 1284 | nr_init_grefs = nr_grant_frames * grefs_per_grant_frame; | 1296 | nr_init_grefs = nr_grant_frames * |
| 1297 | gnttab_interface->grefs_per_grant_frame; | ||
| 1285 | 1298 | ||
| 1286 | for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) | 1299 | for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) |
| 1287 | gnttab_entry(i) = i + 1; | 1300 | gnttab_entry(i) = i + 1; |
