| @@ -152,6 +152,10 @@ static unsigned int xen_blkif_max_ring_order; · 151 unmodified lines |
| 152 | 152 | module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444); |
| 153 | 153 | MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring"); |
| 154 | 154 | |
| 155 | +static bool __read_mostly xen_blkif_trusted = true; |
| 156 | +module_param_named(trusted, xen_blkif_trusted, bool, 0644); |
| 157 | +MODULE_PARM_DESC(trusted, "Is the backend trusted"); |
| 158 | + |
| 155 | 159 | #define BLK_RING_SIZE(info) \ |
| 156 | 160 | __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages) |
| 157 | 161 | |
| @@ -210,6 +214,7 @@ struct blkfront_info · 52 unmodified lines |
| 210 | 214 | unsigned int feature_discard:1; |
| 211 | 215 | unsigned int feature_secdiscard:1; |
| 212 | 216 | unsigned int feature_persistent:1; |
| 217 | + unsigned int bounce:1; |
| 213 | 218 | unsigned int discard_granularity; |
| 214 | 219 | unsigned int discard_alignment; |
| 215 | 220 | /* Number of 4KB segments handled */ |
| @@ -310,8 +315,8 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) · 94 unmodified lines |
| 310 | 315 | if (!gnt_list_entry) |
| 311 | 316 | goto out_of_memory; |
| 312 | 317 | |
| 313 | | − if (info->feature_persistent) { |
| 314 | | − granted_page = alloc_page(GFP_NOIO); |
| 318 | + if (info->bounce) { |
| 319 | + granted_page = alloc_page(GFP_NOIO | __GFP_ZERO); |
| 315 | 320 | if (!granted_page) { |
| 316 | 321 | kfree(gnt_list_entry); |
| 317 | 322 | goto out_of_memory; |
| @@ -330,7 +335,7 @@ out_of_memory: · 12 unmodified lines |
| 330 | 335 | list_for_each_entry_safe(gnt_list_entry, n, |
| 331 | 336 | &rinfo->grants, node) { |
| 332 | 337 | list_del(&gnt_list_entry->node); |
| 333 | | − if (info->feature_persistent) |
| 338 | + if (info->bounce) |
| 334 | 339 | __free_page(gnt_list_entry->page); |
| 335 | 340 | kfree(gnt_list_entry); |
| 336 | 341 | i--; |
| @@ -376,7 +381,7 @@ static struct grant *get_grant(grant_ref_t *gref_head, · 39 unmodified lines |
| 376 | 381 | /* Assign a gref to this page */ |
| 377 | 382 | gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); |
| 378 | 383 | BUG_ON(gnt_list_entry->gref == -ENOSPC); |
| 379 | | − if (info->feature_persistent) |
| 384 | + if (info->bounce) |
| 380 | 385 | grant_foreign_access(gnt_list_entry, info); |
| 381 | 386 | else { |
| 382 | 387 | /* Grant access to the GFN passed by the caller */ |
| @@ -400,7 +405,7 @@ static struct grant *get_indirect_grant(grant_ref_t *gref_head, · 17 unmodified lines |
| 400 | 405 | /* Assign a gref to this page */ |
| 401 | 406 | gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); |
| 402 | 407 | BUG_ON(gnt_list_entry->gref == -ENOSPC); |
| 403 | | − if (!info->feature_persistent) { |
| 408 | + if (!info->bounce) { |
| 404 | 409 | struct page *indirect_page; |
| 405 | 410 | |
| 406 | 411 | /* Fetch a pre-allocated page to use for indirect grefs */ |
| @@ -703,7 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri · 296 unmodified lines |
| 703 | 708 | .grant_idx = 0, |
| 704 | 709 | .segments = NULL, |
| 705 | 710 | .rinfo = rinfo, |
| 706 | | − .need_copy = rq_data_dir(req) && info->feature_persistent, |
| 711 | + .need_copy = rq_data_dir(req) && info->bounce, |
| 707 | 712 | }; |
| 708 | 713 | |
| 709 | 714 | /* |
| @@ -981,11 +986,12 @@ static void xlvbd_flush(struct blkfront_info *info) · 271 unmodified lines |
| 981 | 986 | { |
| 982 | 987 | blk_queue_write_cache(info->rq, info->feature_flush ? true : false, |
| 983 | 988 | info->feature_fua ? true : false); |
| 984 | | − pr_info("blkfront: %s: %s %s %s %s %s\n", |
| 989 | + pr_info("blkfront: %s: %s %s %s %s %s %s %s\n", |
| 985 | 990 | info->gd->disk_name, flush_info(info), |
| 986 | 991 | "persistent grants:", info->feature_persistent ? |
| 987 | 992 | "enabled;" : "disabled;", "indirect descriptors:", |
| 988 | | − info->max_indirect_segments ? "enabled;" : "disabled;"); |
| 993 | + info->max_indirect_segments ? "enabled;" : "disabled;", |
| 994 | + "bounce buffer:", info->bounce ? "enabled" : "disabled;"); |
| 989 | 995 | } |
| 990 | 996 | |
| 991 | 997 | static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) |
| @@ -1207,7 +1213,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) · 215 unmodified lines |
| 1207 | 1213 | if (!list_empty(&rinfo->indirect_pages)) { |
| 1208 | 1214 | struct page *indirect_page, *n; |
| 1209 | 1215 | |
| 1210 | | − BUG_ON(info->feature_persistent); |
| 1216 | + BUG_ON(info->bounce); |
| 1211 | 1217 | list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { |
| 1212 | 1218 | list_del(&indirect_page->lru); |
| 1213 | 1219 | __free_page(indirect_page); |
| @@ -1224,7 +1230,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) · 10 unmodified lines |
| 1224 | 1230 | NULL); |
| 1225 | 1231 | rinfo->persistent_gnts_c--; |
| 1226 | 1232 | } |
| 1227 | | − if (info->feature_persistent) |
| 1233 | + if (info->bounce) |
| 1228 | 1234 | __free_page(persistent_gnt->page); |
| 1229 | 1235 | kfree(persistent_gnt); |
| 1230 | 1236 | } |
| @@ -1245,7 +1251,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) · 14 unmodified lines |
| 1245 | 1251 | for (j = 0; j < segs; j++) { |
| 1246 | 1252 | persistent_gnt = rinfo->shadow[i].grants_used[j]; |
| 1247 | 1253 | gnttab_end_foreign_access(persistent_gnt->gref, NULL); |
| 1248 | | − if (info->feature_persistent) |
| 1254 | + if (info->bounce) |
| 1249 | 1255 | __free_page(persistent_gnt->page); |
| 1250 | 1256 | kfree(persistent_gnt); |
| 1251 | 1257 | } |
| @@ -1428,7 +1434,7 @@ static int blkif_completion(unsigned long *id, · 176 unmodified lines |
| 1428 | 1434 | data.s = s; |
| 1429 | 1435 | num_sg = s->num_sg; |
| 1430 | 1436 | |
| 1431 | | − if (bret->operation == BLKIF_OP_READ && info->feature_persistent) { |
| 1437 | + if (bret->operation == BLKIF_OP_READ && info->bounce) { |
| 1432 | 1438 | for_each_sg(s->sg, sg, num_sg, i) { |
| 1433 | 1439 | BUG_ON(sg->offset + sg->length > PAGE_SIZE); |
| 1434 | 1440 | |
| @@ -1487,7 +1493,7 @@ static int blkif_completion(unsigned long *id, · 52 unmodified lines |
| 1487 | 1493 | * Add the used indirect page back to the list of |
| 1488 | 1494 | * available pages for indirect grefs. |
| 1489 | 1495 | */ |
| 1490 | | − if (!info->feature_persistent) { |
| 1496 | + if (!info->bounce) { |
| 1491 | 1497 | indirect_page = s->indirect_grants[i]->page; |
| 1492 | 1498 | list_add(&indirect_page->lru, &rinfo->indirect_pages); |
| 1493 | 1499 | } |
| @@ -1764,6 +1770,10 @@ static int talk_to_blkback(struct xenbus_device *dev, · 270 unmodified lines |
| 1764 | 1770 | if (!info) |
| 1765 | 1771 | return -ENODEV; |
| 1766 | 1772 | |
| 1773 | + /* Check if backend is trusted. */ |
| 1774 | + info->bounce = !xen_blkif_trusted || |
| 1775 | + !xenbus_read_unsigned(dev->nodename, "trusted", 1); |
| 1776 | + |
| 1767 | 1777 | max_page_order = xenbus_read_unsigned(info->xbdev->otherend, |
| 1768 | 1778 | "max-ring-page-order", 0); |
| 1769 | 1779 | ring_page_order = min(xen_blkif_max_ring_order, max_page_order); |
| @@ -2173,17 +2183,18 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) · 403 unmodified lines |
| 2173 | 2183 | if (err) |
| 2174 | 2184 | goto out_of_memory; |
| 2175 | 2185 | |
| 2176 | | − if (!info->feature_persistent && info->max_indirect_segments) { |
| 2186 | + if (!info->bounce && info->max_indirect_segments) { |
| 2177 | 2187 | /* |
| 2178 | | − * We are using indirect descriptors but not persistent |
| 2179 | | − * grants, we need to allocate a set of pages that can be |
| 2188 | + * We are using indirect descriptors but don't have a bounce |
| 2189 | + * buffer, we need to allocate a set of pages that can be |
| 2180 | 2190 | * used for mapping indirect grefs |
| 2181 | 2191 | */ |
| 2182 | 2192 | int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info); |
| 2183 | 2193 | |
| 2184 | 2194 | BUG_ON(!list_empty(&rinfo->indirect_pages)); |
| 2185 | 2195 | for (i = 0; i < num; i++) { |
| 2186 | | − struct page *indirect_page = alloc_page(GFP_KERNEL); |
| 2196 | + struct page *indirect_page = alloc_page(GFP_KERNEL | |
| 2197 | + __GFP_ZERO); |
| 2187 | 2198 | if (!indirect_page) |
| 2188 | 2199 | goto out_of_memory; |
| 2189 | 2200 | list_add(&indirect_page->lru, &rinfo->indirect_pages); |
| @@ -2276,6 +2287,8 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) · 86 unmodified lines |
| 2276 | 2287 | info->feature_persistent = |
| 2277 | 2288 | !!xenbus_read_unsigned(info->xbdev->otherend, |
| 2278 | 2289 | "feature-persistent", 0); |
| 2290 | + if (info->feature_persistent) |
| 2291 | + info->bounce = true; |
| 2279 | 2292 | |
| 2280 | 2293 | indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, |
| 2281 | 2294 | "feature-max-indirect-segments", 0); |
| @@ -2547,6 +2560,13 @@ static void blkfront_delay_work(struct work_struct *work) · 265 unmodified lines |
| 2547 | 2560 | struct blkfront_info *info; |
| 2548 | 2561 | bool need_schedule_work = false; |
| 2549 | 2562 | |
| 2563 | + /* |
| 2564 | + * Note that when using bounce buffers but not persistent grants |
| 2565 | + * there's no need to run blkfront_delay_work because grants are |
| 2566 | + * revoked in blkif_completion or else an error is reported and the |
| 2567 | + * connection is closed. |
| 2568 | + */ |
| 2569 | + |
| 2550 | 2570 | mutex_lock(&blkfront_mutex); |
| 2551 | 2571 | |
| 2552 | 2572 | list_for_each_entry(info, &info_list, info_list) { |