Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Drivers: hv: vmbus: Mark vmbus ring buffer visible to host in Isolation VM

Mark vmbus ring buffer visible with set_memory_decrypted() when
establish gpadl handle.

Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
Link: https://lore.kernel.org/r/20211025122116.264793-5-ltykernel@gmail.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>

authored by

Tianyu Lan and committed by
Wei Liu
d4dccf35 810a5212

+65 -38
+38 -15
drivers/hv/channel.c
··· 17 17 #include <linux/hyperv.h> 18 18 #include <linux/uio.h> 19 19 #include <linux/interrupt.h> 20 + #include <linux/set_memory.h> 20 21 #include <asm/page.h> 21 22 #include <asm/mshyperv.h> 22 23 ··· 457 456 static int __vmbus_establish_gpadl(struct vmbus_channel *channel, 458 457 enum hv_gpadl_type type, void *kbuffer, 459 458 u32 size, u32 send_offset, 460 - u32 *gpadl_handle) 459 + struct vmbus_gpadl *gpadl) 461 460 { 462 461 struct vmbus_channel_gpadl_header *gpadlmsg; 463 462 struct vmbus_channel_gpadl_body *gpadl_body; ··· 474 473 ret = create_gpadl_header(type, kbuffer, size, send_offset, &msginfo); 475 474 if (ret) 476 475 return ret; 476 + 477 + ret = set_memory_decrypted((unsigned long)kbuffer, 478 + PFN_UP(size)); 479 + if (ret) { 480 + dev_warn(&channel->device_obj->device, 481 + "Failed to set host visibility for new GPADL %d.\n", 482 + ret); 483 + return ret; 484 + } 477 485 478 486 init_completion(&msginfo->waitevent); 479 487 msginfo->waiting_channel = channel; ··· 547 537 } 548 538 549 539 /* At this point, we received the gpadl created msg */ 550 - *gpadl_handle = gpadlmsg->gpadl; 540 + gpadl->gpadl_handle = gpadlmsg->gpadl; 541 + gpadl->buffer = kbuffer; 542 + gpadl->size = size; 543 + 551 544 552 545 cleanup: 553 546 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); ··· 562 549 } 563 550 564 551 kfree(msginfo); 552 + 553 + if (ret) 554 + set_memory_encrypted((unsigned long)kbuffer, 555 + PFN_UP(size)); 556 + 565 557 return ret; 566 558 } 567 559 ··· 579 561 * @gpadl_handle: some funky thing 580 562 */ 581 563 int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, 582 - u32 size, u32 *gpadl_handle) 564 + u32 size, struct vmbus_gpadl *gpadl) 583 565 { 584 566 return __vmbus_establish_gpadl(channel, HV_GPADL_BUFFER, kbuffer, size, 585 - 0U, gpadl_handle); 567 + 0U, gpadl); 586 568 } 587 569 EXPORT_SYMBOL_GPL(vmbus_establish_gpadl); 588 570 ··· 693 675 goto error_clean_ring; 694 676 695 677 /* Establish the gpadl for the ring buffer */ 696 - newchannel->ringbuffer_gpadlhandle = 0; 678 + newchannel->ringbuffer_gpadlhandle.gpadl_handle = 0; 697 679 698 680 err = __vmbus_establish_gpadl(newchannel, HV_GPADL_RING, 699 681 page_address(newchannel->ringbuffer_page), ··· 719 701 open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL; 720 702 open_msg->openid = newchannel->offermsg.child_relid; 721 703 open_msg->child_relid = newchannel->offermsg.child_relid; 722 - open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; 704 + open_msg->ringbuffer_gpadlhandle 705 + = newchannel->ringbuffer_gpadlhandle.gpadl_handle; 723 706 /* 724 707 * The unit of ->downstream_ringbuffer_pageoffset is HV_HYP_PAGE and 725 708 * the unit of ->ringbuffer_send_offset (i.e. send_pages) is PAGE, so ··· 778 759 error_free_info: 779 760 kfree(open_info); 780 761 error_free_gpadl: 781 - vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle); 782 - newchannel->ringbuffer_gpadlhandle = 0; 762 + vmbus_teardown_gpadl(newchannel, &newchannel->ringbuffer_gpadlhandle); 783 763 error_clean_ring: 784 764 hv_ringbuffer_cleanup(&newchannel->outbound); 785 765 hv_ringbuffer_cleanup(&newchannel->inbound); ··· 824 806 /* 825 807 * vmbus_teardown_gpadl -Teardown the specified GPADL handle 826 808 */ 827 - int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) 809 + int vmbus_teardown_gpadl(struct vmbus_channel *channel, struct vmbus_gpadl *gpadl) 828 810 { 829 811 struct vmbus_channel_gpadl_teardown *msg; 830 812 struct vmbus_channel_msginfo *info; ··· 843 825 844 826 msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN; 845 827 msg->child_relid = channel->offermsg.child_relid; 846 - msg->gpadl = gpadl_handle; 828 + msg->gpadl = gpadl->gpadl_handle; 847 829 848 830 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 849 831 list_add_tail(&info->msglistentry, ··· 863 845 864 846 wait_for_completion(&info->waitevent); 865 847 848 + gpadl->gpadl_handle = 0; 849 + 866 850 post_msg_err: 867 851 /* 868 852 * If the channel has been rescinded; ··· 879 859 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); 880 860 881 861 kfree(info); 862 + 863 + ret = set_memory_encrypted((unsigned long)gpadl->buffer, 864 + PFN_UP(gpadl->size)); 865 + if (ret) 866 + pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret); 867 + 882 868 return ret; 883 869 } 884 870 EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl); ··· 959 933 } 960 934 961 935 /* Tear down the gpadl for the channel's ring buffer */ 962 - else if (channel->ringbuffer_gpadlhandle) { 963 - ret = vmbus_teardown_gpadl(channel, 964 - channel->ringbuffer_gpadlhandle); 936 + else if (channel->ringbuffer_gpadlhandle.gpadl_handle) { 937 + ret = vmbus_teardown_gpadl(channel, &channel->ringbuffer_gpadlhandle); 965 938 if (ret) { 966 939 pr_err("Close failed: teardown gpadl return %d\n", ret); 967 940 /* ··· 968 943 * it is perhaps better to leak memory. 969 944 */ 970 945 } 971 - 972 - channel->ringbuffer_gpadlhandle = 0; 973 946 } 974 947 975 948 if (!ret)
+3 -2
drivers/net/hyperv/hyperv_net.h
··· 1075 1075 /* Receive buffer allocated by us but manages by NetVSP */ 1076 1076 void *recv_buf; 1077 1077 u32 recv_buf_size; /* allocated bytes */ 1078 - u32 recv_buf_gpadl_handle; 1078 + struct vmbus_gpadl recv_buf_gpadl_handle; 1079 1079 u32 recv_section_cnt; 1080 1080 u32 recv_section_size; 1081 1081 u32 recv_completion_cnt; 1082 1082 1083 1083 /* Send buffer allocated by us */ 1084 1084 void *send_buf; 1085 - u32 send_buf_gpadl_handle; 1085 + u32 send_buf_size; 1086 + struct vmbus_gpadl send_buf_gpadl_handle; 1086 1087 u32 send_section_cnt; 1087 1088 u32 send_section_size; 1088 1089 unsigned long *send_section_map;
+7 -8
drivers/net/hyperv/netvsc.c
··· 278 278 { 279 279 int ret; 280 280 281 - if (net_device->recv_buf_gpadl_handle) { 281 + if (net_device->recv_buf_gpadl_handle.gpadl_handle) { 282 282 ret = vmbus_teardown_gpadl(device->channel, 283 - net_device->recv_buf_gpadl_handle); 283 + &net_device->recv_buf_gpadl_handle); 284 284 285 285 /* If we failed here, we might as well return and have a leak 286 286 * rather than continue and a bugchk ··· 290 290 "unable to teardown receive buffer's gpadl\n"); 291 291 return; 292 292 } 293 - net_device->recv_buf_gpadl_handle = 0; 294 293 } 295 294 } 296 295 ··· 299 300 { 300 301 int ret; 301 302 302 - if (net_device->send_buf_gpadl_handle) { 303 + if (net_device->send_buf_gpadl_handle.gpadl_handle) { 303 304 ret = vmbus_teardown_gpadl(device->channel, 304 - net_device->send_buf_gpadl_handle); 305 + &net_device->send_buf_gpadl_handle); 305 306 306 307 /* If we failed here, we might as well return and have a leak 307 308 * rather than continue and a bugchk ··· 311 312 "unable to teardown send buffer's gpadl\n"); 312 313 return; 313 314 } 314 - net_device->send_buf_gpadl_handle = 0; 315 315 } 316 316 } 317 317 ··· 378 380 memset(init_packet, 0, sizeof(struct nvsp_message)); 379 381 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_RECV_BUF; 380 382 init_packet->msg.v1_msg.send_recv_buf. 381 - gpadl_handle = net_device->recv_buf_gpadl_handle; 383 + gpadl_handle = net_device->recv_buf_gpadl_handle.gpadl_handle; 382 384 init_packet->msg.v1_msg. 383 385 send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; 384 386 ··· 461 463 ret = -ENOMEM; 462 464 goto cleanup; 463 465 } 466 + net_device->send_buf_size = buf_size; 464 467 465 468 /* Establish the gpadl handle for this buffer on this 466 469 * channel. Note: This call uses the vmbus connection rather ··· 481 482 memset(init_packet, 0, sizeof(struct nvsp_message)); 482 483 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; 483 484 init_packet->msg.v1_msg.send_send_buf.gpadl_handle = 484 - net_device->send_buf_gpadl_handle; 485 + net_device->send_buf_gpadl_handle.gpadl_handle; 485 486 init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID; 486 487 487 488 trace_nvsp_send(ndev, init_packet);
+8 -10
drivers/uio/uio_hv_generic.c
··· 58 58 atomic_t refcnt; 59 59 60 60 void *recv_buf; 61 - u32 recv_gpadl; 61 + struct vmbus_gpadl recv_gpadl; 62 62 char recv_name[32]; /* "recv_4294967295" */ 63 63 64 64 void *send_buf; 65 - u32 send_gpadl; 65 + struct vmbus_gpadl send_gpadl; 66 66 char send_name[32]; 67 67 }; 68 68 ··· 179 179 static void 180 180 hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata) 181 181 { 182 - if (pdata->send_gpadl) { 183 - vmbus_teardown_gpadl(dev->channel, pdata->send_gpadl); 184 - pdata->send_gpadl = 0; 182 + if (pdata->send_gpadl.gpadl_handle) { 183 + vmbus_teardown_gpadl(dev->channel, &pdata->send_gpadl); 185 184 vfree(pdata->send_buf); 186 185 } 187 186 188 - if (pdata->recv_gpadl) { 189 - vmbus_teardown_gpadl(dev->channel, pdata->recv_gpadl); 190 - pdata->recv_gpadl = 0; 187 + if (pdata->recv_gpadl.gpadl_handle) { 188 + vmbus_teardown_gpadl(dev->channel, &pdata->recv_gpadl); 191 189 vfree(pdata->recv_buf); 192 190 } 193 191 } ··· 301 303 302 304 /* put Global Physical Address Label in name */ 303 305 snprintf(pdata->recv_name, sizeof(pdata->recv_name), 304 - "recv:%u", pdata->recv_gpadl); 306 + "recv:%u", pdata->recv_gpadl.gpadl_handle); 305 307 pdata->info.mem[RECV_BUF_MAP].name = pdata->recv_name; 306 308 pdata->info.mem[RECV_BUF_MAP].addr 307 309 = (uintptr_t)pdata->recv_buf; ··· 322 324 } 323 325 324 326 snprintf(pdata->send_name, sizeof(pdata->send_name), 325 - "send:%u", pdata->send_gpadl); 327 + "send:%u", pdata->send_gpadl.gpadl_handle); 326 328 pdata->info.mem[SEND_BUF_MAP].name = pdata->send_name; 327 329 pdata->info.mem[SEND_BUF_MAP].addr 328 330 = (uintptr_t)pdata->send_buf;
+9 -3
include/linux/hyperv.h
··· 803 803 804 804 #define VMBUS_DEFAULT_MAX_PKT_SIZE 4096 805 805 806 + struct vmbus_gpadl { 807 + u32 gpadl_handle; 808 + u32 size; 809 + void *buffer; 810 + }; 811 + 806 812 struct vmbus_channel { 807 813 struct list_head listentry; 808 814 ··· 828 822 bool rescind_ref; /* got rescind msg, got channel reference */ 829 823 struct completion rescind_event; 830 824 831 - u32 ringbuffer_gpadlhandle; 825 + struct vmbus_gpadl ringbuffer_gpadlhandle; 832 826 833 827 /* Allocated memory for ring buffer */ 834 828 struct page *ringbuffer_page; ··· 1198 1192 extern int vmbus_establish_gpadl(struct vmbus_channel *channel, 1199 1193 void *kbuffer, 1200 1194 u32 size, 1201 - u32 *gpadl_handle); 1195 + struct vmbus_gpadl *gpadl); 1202 1196 1203 1197 extern int vmbus_teardown_gpadl(struct vmbus_channel *channel, 1204 - u32 gpadl_handle); 1198 + struct vmbus_gpadl *gpadl); 1205 1199 1206 1200 void vmbus_reset_channel_cb(struct vmbus_channel *channel); 1207 1201