Skip to content

Commit d4dccf3

Browse files
Tianyu Lanliuw
authored andcommitted
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 <[email protected]> Signed-off-by: Tianyu Lan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Wei Liu <[email protected]>
1 parent 810a521 commit d4dccf3

File tree

5 files changed

+65
-38
lines changed

5 files changed

+65
-38
lines changed

drivers/hv/channel.c

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/hyperv.h>
1818
#include <linux/uio.h>
1919
#include <linux/interrupt.h>
20+
#include <linux/set_memory.h>
2021
#include <asm/page.h>
2122
#include <asm/mshyperv.h>
2223

@@ -456,7 +457,7 @@ static int create_gpadl_header(enum hv_gpadl_type type, void *kbuffer,
456457
static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
457458
enum hv_gpadl_type type, void *kbuffer,
458459
u32 size, u32 send_offset,
459-
u32 *gpadl_handle)
460+
struct vmbus_gpadl *gpadl)
460461
{
461462
struct vmbus_channel_gpadl_header *gpadlmsg;
462463
struct vmbus_channel_gpadl_body *gpadl_body;
@@ -474,6 +475,15 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
474475
if (ret)
475476
return ret;
476477

478+
ret = set_memory_decrypted((unsigned long)kbuffer,
479+
PFN_UP(size));
480+
if (ret) {
481+
dev_warn(&channel->device_obj->device,
482+
"Failed to set host visibility for new GPADL %d.\n",
483+
ret);
484+
return ret;
485+
}
486+
477487
init_completion(&msginfo->waitevent);
478488
msginfo->waiting_channel = channel;
479489

@@ -537,7 +547,10 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
537547
}
538548

539549
/* At this point, we received the gpadl created msg */
540-
*gpadl_handle = gpadlmsg->gpadl;
550+
gpadl->gpadl_handle = gpadlmsg->gpadl;
551+
gpadl->buffer = kbuffer;
552+
gpadl->size = size;
553+
541554

542555
cleanup:
543556
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
@@ -549,6 +562,11 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
549562
}
550563

551564
kfree(msginfo);
565+
566+
if (ret)
567+
set_memory_encrypted((unsigned long)kbuffer,
568+
PFN_UP(size));
569+
552570
return ret;
553571
}
554572

@@ -561,10 +579,10 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
561579
* @gpadl_handle: some funky thing
562580
*/
563581
int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
564-
u32 size, u32 *gpadl_handle)
582+
u32 size, struct vmbus_gpadl *gpadl)
565583
{
566584
return __vmbus_establish_gpadl(channel, HV_GPADL_BUFFER, kbuffer, size,
567-
0U, gpadl_handle);
585+
0U, gpadl);
568586
}
569587
EXPORT_SYMBOL_GPL(vmbus_establish_gpadl);
570588

@@ -675,7 +693,7 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
675693
goto error_clean_ring;
676694

677695
/* Establish the gpadl for the ring buffer */
678-
newchannel->ringbuffer_gpadlhandle = 0;
696+
newchannel->ringbuffer_gpadlhandle.gpadl_handle = 0;
679697

680698
err = __vmbus_establish_gpadl(newchannel, HV_GPADL_RING,
681699
page_address(newchannel->ringbuffer_page),
@@ -701,7 +719,8 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
701719
open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
702720
open_msg->openid = newchannel->offermsg.child_relid;
703721
open_msg->child_relid = newchannel->offermsg.child_relid;
704-
open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
722+
open_msg->ringbuffer_gpadlhandle
723+
= newchannel->ringbuffer_gpadlhandle.gpadl_handle;
705724
/*
706725
* The unit of ->downstream_ringbuffer_pageoffset is HV_HYP_PAGE and
707726
* the unit of ->ringbuffer_send_offset (i.e. send_pages) is PAGE, so
@@ -759,8 +778,7 @@ static int __vmbus_open(struct vmbus_channel *newchannel,
759778
error_free_info:
760779
kfree(open_info);
761780
error_free_gpadl:
762-
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
763-
newchannel->ringbuffer_gpadlhandle = 0;
781+
vmbus_teardown_gpadl(newchannel, &newchannel->ringbuffer_gpadlhandle);
764782
error_clean_ring:
765783
hv_ringbuffer_cleanup(&newchannel->outbound);
766784
hv_ringbuffer_cleanup(&newchannel->inbound);
@@ -806,7 +824,7 @@ EXPORT_SYMBOL_GPL(vmbus_open);
806824
/*
807825
* vmbus_teardown_gpadl -Teardown the specified GPADL handle
808826
*/
809-
int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
827+
int vmbus_teardown_gpadl(struct vmbus_channel *channel, struct vmbus_gpadl *gpadl)
810828
{
811829
struct vmbus_channel_gpadl_teardown *msg;
812830
struct vmbus_channel_msginfo *info;
@@ -825,7 +843,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
825843

826844
msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN;
827845
msg->child_relid = channel->offermsg.child_relid;
828-
msg->gpadl = gpadl_handle;
846+
msg->gpadl = gpadl->gpadl_handle;
829847

830848
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
831849
list_add_tail(&info->msglistentry,
@@ -845,6 +863,8 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
845863

846864
wait_for_completion(&info->waitevent);
847865

866+
gpadl->gpadl_handle = 0;
867+
848868
post_msg_err:
849869
/*
850870
* If the channel has been rescinded;
@@ -859,6 +879,12 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
859879
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
860880

861881
kfree(info);
882+
883+
ret = set_memory_encrypted((unsigned long)gpadl->buffer,
884+
PFN_UP(gpadl->size));
885+
if (ret)
886+
pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret);
887+
862888
return ret;
863889
}
864890
EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
@@ -933,18 +959,15 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
933959
}
934960

935961
/* Tear down the gpadl for the channel's ring buffer */
936-
else if (channel->ringbuffer_gpadlhandle) {
937-
ret = vmbus_teardown_gpadl(channel,
938-
channel->ringbuffer_gpadlhandle);
962+
else if (channel->ringbuffer_gpadlhandle.gpadl_handle) {
963+
ret = vmbus_teardown_gpadl(channel, &channel->ringbuffer_gpadlhandle);
939964
if (ret) {
940965
pr_err("Close failed: teardown gpadl return %d\n", ret);
941966
/*
942967
* If we failed to teardown gpadl,
943968
* it is perhaps better to leak memory.
944969
*/
945970
}
946-
947-
channel->ringbuffer_gpadlhandle = 0;
948971
}
949972

950973
if (!ret)

drivers/net/hyperv/hyperv_net.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,14 +1075,15 @@ struct netvsc_device {
10751075
/* Receive buffer allocated by us but manages by NetVSP */
10761076
void *recv_buf;
10771077
u32 recv_buf_size; /* allocated bytes */
1078-
u32 recv_buf_gpadl_handle;
1078+
struct vmbus_gpadl recv_buf_gpadl_handle;
10791079
u32 recv_section_cnt;
10801080
u32 recv_section_size;
10811081
u32 recv_completion_cnt;
10821082

10831083
/* Send buffer allocated by us */
10841084
void *send_buf;
1085-
u32 send_buf_gpadl_handle;
1085+
u32 send_buf_size;
1086+
struct vmbus_gpadl send_buf_gpadl_handle;
10861087
u32 send_section_cnt;
10871088
u32 send_section_size;
10881089
unsigned long *send_section_map;

drivers/net/hyperv/netvsc.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,9 @@ static void netvsc_teardown_recv_gpadl(struct hv_device *device,
278278
{
279279
int ret;
280280

281-
if (net_device->recv_buf_gpadl_handle) {
281+
if (net_device->recv_buf_gpadl_handle.gpadl_handle) {
282282
ret = vmbus_teardown_gpadl(device->channel,
283-
net_device->recv_buf_gpadl_handle);
283+
&net_device->recv_buf_gpadl_handle);
284284

285285
/* If we failed here, we might as well return and have a leak
286286
* rather than continue and a bugchk
@@ -290,7 +290,6 @@ static void netvsc_teardown_recv_gpadl(struct hv_device *device,
290290
"unable to teardown receive buffer's gpadl\n");
291291
return;
292292
}
293-
net_device->recv_buf_gpadl_handle = 0;
294293
}
295294
}
296295

@@ -300,9 +299,9 @@ static void netvsc_teardown_send_gpadl(struct hv_device *device,
300299
{
301300
int ret;
302301

303-
if (net_device->send_buf_gpadl_handle) {
302+
if (net_device->send_buf_gpadl_handle.gpadl_handle) {
304303
ret = vmbus_teardown_gpadl(device->channel,
305-
net_device->send_buf_gpadl_handle);
304+
&net_device->send_buf_gpadl_handle);
306305

307306
/* If we failed here, we might as well return and have a leak
308307
* rather than continue and a bugchk
@@ -312,7 +311,6 @@ static void netvsc_teardown_send_gpadl(struct hv_device *device,
312311
"unable to teardown send buffer's gpadl\n");
313312
return;
314313
}
315-
net_device->send_buf_gpadl_handle = 0;
316314
}
317315
}
318316

@@ -380,7 +378,7 @@ static int netvsc_init_buf(struct hv_device *device,
380378
memset(init_packet, 0, sizeof(struct nvsp_message));
381379
init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_RECV_BUF;
382380
init_packet->msg.v1_msg.send_recv_buf.
383-
gpadl_handle = net_device->recv_buf_gpadl_handle;
381+
gpadl_handle = net_device->recv_buf_gpadl_handle.gpadl_handle;
384382
init_packet->msg.v1_msg.
385383
send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
386384

@@ -463,6 +461,7 @@ static int netvsc_init_buf(struct hv_device *device,
463461
ret = -ENOMEM;
464462
goto cleanup;
465463
}
464+
net_device->send_buf_size = buf_size;
466465

467466
/* Establish the gpadl handle for this buffer on this
468467
* channel. Note: This call uses the vmbus connection rather
@@ -482,7 +481,7 @@ static int netvsc_init_buf(struct hv_device *device,
482481
memset(init_packet, 0, sizeof(struct nvsp_message));
483482
init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF;
484483
init_packet->msg.v1_msg.send_send_buf.gpadl_handle =
485-
net_device->send_buf_gpadl_handle;
484+
net_device->send_buf_gpadl_handle.gpadl_handle;
486485
init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID;
487486

488487
trace_nvsp_send(ndev, init_packet);

drivers/uio/uio_hv_generic.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ struct hv_uio_private_data {
5858
atomic_t refcnt;
5959

6060
void *recv_buf;
61-
u32 recv_gpadl;
61+
struct vmbus_gpadl recv_gpadl;
6262
char recv_name[32]; /* "recv_4294967295" */
6363

6464
void *send_buf;
65-
u32 send_gpadl;
65+
struct vmbus_gpadl send_gpadl;
6666
char send_name[32];
6767
};
6868

@@ -179,15 +179,13 @@ hv_uio_new_channel(struct vmbus_channel *new_sc)
179179
static void
180180
hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata)
181181
{
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);
185184
vfree(pdata->send_buf);
186185
}
187186

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);
191189
vfree(pdata->recv_buf);
192190
}
193191
}
@@ -303,7 +301,7 @@ hv_uio_probe(struct hv_device *dev,
303301

304302
/* put Global Physical Address Label in name */
305303
snprintf(pdata->recv_name, sizeof(pdata->recv_name),
306-
"recv:%u", pdata->recv_gpadl);
304+
"recv:%u", pdata->recv_gpadl.gpadl_handle);
307305
pdata->info.mem[RECV_BUF_MAP].name = pdata->recv_name;
308306
pdata->info.mem[RECV_BUF_MAP].addr
309307
= (uintptr_t)pdata->recv_buf;
@@ -324,7 +322,7 @@ hv_uio_probe(struct hv_device *dev,
324322
}
325323

326324
snprintf(pdata->send_name, sizeof(pdata->send_name),
327-
"send:%u", pdata->send_gpadl);
325+
"send:%u", pdata->send_gpadl.gpadl_handle);
328326
pdata->info.mem[SEND_BUF_MAP].name = pdata->send_name;
329327
pdata->info.mem[SEND_BUF_MAP].addr
330328
= (uintptr_t)pdata->send_buf;

include/linux/hyperv.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,12 @@ struct vmbus_device {
803803

804804
#define VMBUS_DEFAULT_MAX_PKT_SIZE 4096
805805

806+
struct vmbus_gpadl {
807+
u32 gpadl_handle;
808+
u32 size;
809+
void *buffer;
810+
};
811+
806812
struct vmbus_channel {
807813
struct list_head listentry;
808814

@@ -822,7 +828,7 @@ struct vmbus_channel {
822828
bool rescind_ref; /* got rescind msg, got channel reference */
823829
struct completion rescind_event;
824830

825-
u32 ringbuffer_gpadlhandle;
831+
struct vmbus_gpadl ringbuffer_gpadlhandle;
826832

827833
/* Allocated memory for ring buffer */
828834
struct page *ringbuffer_page;
@@ -1192,10 +1198,10 @@ extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
11921198
extern int vmbus_establish_gpadl(struct vmbus_channel *channel,
11931199
void *kbuffer,
11941200
u32 size,
1195-
u32 *gpadl_handle);
1201+
struct vmbus_gpadl *gpadl);
11961202

11971203
extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
1198-
u32 gpadl_handle);
1204+
struct vmbus_gpadl *gpadl);
11991205

12001206
void vmbus_reset_channel_cb(struct vmbus_channel *channel);
12011207

0 commit comments

Comments
 (0)