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

Drivers: hv: Allocate encrypted buffers when requested

Confidential VMBus is built around using buffers not shared with
the host.

Support allocating encrypted buffers when requested.

Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>

authored by

Roman Kisel and committed by
Wei Liu
0a4534bd e096fe2b

+34 -23
+29 -20
drivers/hv/channel.c
··· 444 444 return ret; 445 445 } 446 446 447 - /* 448 - * Set the "decrypted" flag to true for the set_memory_decrypted() 449 - * success case. In the failure case, the encryption state of the 450 - * memory is unknown. Leave "decrypted" as true to ensure the 451 - * memory will be leaked instead of going back on the free list. 452 - */ 453 - gpadl->decrypted = true; 454 - ret = set_memory_decrypted((unsigned long)kbuffer, 455 - PFN_UP(size)); 456 - if (ret) { 457 - dev_warn(&channel->device_obj->device, 458 - "Failed to set host visibility for new GPADL %d.\n", 459 - ret); 460 - return ret; 447 + gpadl->decrypted = !((channel->co_external_memory && type == HV_GPADL_BUFFER) || 448 + (channel->co_ring_buffer && type == HV_GPADL_RING)); 449 + if (gpadl->decrypted) { 450 + /* 451 + * The "decrypted" flag being true assumes that set_memory_decrypted() succeeds. 452 + * But if it fails, the encryption state of the memory is unknown. In that case, 453 + * leave "decrypted" as true to ensure the memory is leaked instead of going back 454 + * on the free list. 455 + */ 456 + ret = set_memory_decrypted((unsigned long)kbuffer, 457 + PFN_UP(size)); 458 + if (ret) { 459 + dev_warn(&channel->device_obj->device, 460 + "Failed to set host visibility for new GPADL %d.\n", 461 + ret); 462 + return ret; 463 + } 461 464 } 462 465 463 466 init_completion(&msginfo->waitevent); ··· 548 545 * left as true so the memory is leaked instead of being 549 546 * put back on the free list. 550 547 */ 551 - if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size))) 552 - gpadl->decrypted = false; 548 + if (gpadl->decrypted) { 549 + if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size))) 550 + gpadl->decrypted = false; 551 + } 553 552 } 554 553 555 554 return ret; ··· 682 677 goto error_clean_ring; 683 678 684 679 err = hv_ringbuffer_init(&newchannel->outbound, 685 - page, send_pages, 0); 680 + page, send_pages, 0, newchannel->co_ring_buffer); 686 681 if (err) 687 682 goto error_free_gpadl; 688 683 689 684 err = hv_ringbuffer_init(&newchannel->inbound, &page[send_pages], 690 - recv_pages, newchannel->max_pkt_size); 685 + recv_pages, newchannel->max_pkt_size, 686 + newchannel->co_ring_buffer); 691 687 if (err) 692 688 goto error_free_gpadl; 693 689 ··· 869 863 870 864 kfree(info); 871 865 872 - ret = set_memory_encrypted((unsigned long)gpadl->buffer, 873 - PFN_UP(gpadl->size)); 866 + if (gpadl->decrypted) 867 + ret = set_memory_encrypted((unsigned long)gpadl->buffer, 868 + PFN_UP(gpadl->size)); 869 + else 870 + ret = 0; 874 871 if (ret) 875 872 pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret); 876 873
+2 -1
drivers/hv/hyperv_vmbus.h
··· 201 201 void hv_ringbuffer_pre_init(struct vmbus_channel *channel); 202 202 203 203 int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, 204 - struct page *pages, u32 pagecnt, u32 max_pkt_size); 204 + struct page *pages, u32 pagecnt, u32 max_pkt_size, 205 + bool confidential); 205 206 206 207 void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); 207 208
+3 -2
drivers/hv/ring_buffer.c
··· 184 184 185 185 /* Initialize the ring buffer. */ 186 186 int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, 187 - struct page *pages, u32 page_cnt, u32 max_pkt_size) 187 + struct page *pages, u32 page_cnt, u32 max_pkt_size, 188 + bool confidential) 188 189 { 189 190 struct page **pages_wraparound; 190 191 int i; ··· 209 208 210 209 ring_info->ring_buffer = (struct hv_ring_buffer *) 211 210 vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP, 212 - pgprot_decrypted(PAGE_KERNEL)); 211 + confidential ? PAGE_KERNEL : pgprot_decrypted(PAGE_KERNEL)); 213 212 214 213 kfree(pages_wraparound); 215 214 if (!ring_info->ring_buffer)