Inter-revision diff: patch 3

Comparing rfc (message) to v4 (message)

--- vrfc
+++ v4
@@ -1,170 +1,133 @@
 From: Tianyu Lan <Tianyu.Lan@microsoft.com>
 
-Hyper-V exposes GHCB page via SEV ES GHCB MSR for SNP guest
-to communicate with hypervisor. Map GHCB page for all
-cpus to read/write MSR register and submit hvcall request
-via GHCB. Hyper-V also exposes shared memory boundary via
-cpuid HYPERV_CPUID_ISOLATION_CONFIG and store it in the
-shared_gpa_boundary of ms_hyperv struct. This prepares
-to share memory with host for SNP guest.
+Mark vmbus ring buffer visible with set_memory_decrypted() when
+establish gpadl handle.
 
 Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
 ---
- arch/x86/hyperv/hv_init.c      | 52 +++++++++++++++++++++++++++++++---
- arch/x86/kernel/cpu/mshyperv.c |  2 ++
- include/asm-generic/mshyperv.h | 14 ++++++++-
- 3 files changed, 63 insertions(+), 5 deletions(-)
+ drivers/hv/channel.c   | 38 ++++++++++++++++++++++++++++++++++++--
+ include/linux/hyperv.h | 10 ++++++++++
+ 2 files changed, 46 insertions(+), 2 deletions(-)
 
-diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
-index 0db5137d5b81..90e65fbf4c58 100644
---- a/arch/x86/hyperv/hv_init.c
-+++ b/arch/x86/hyperv/hv_init.c
-@@ -82,6 +82,9 @@ static int hv_cpu_init(unsigned int cpu)
- 	struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
- 	void **input_arg;
- 	struct page *pg;
-+	u64 ghcb_gpa;
-+	void *ghcb_va;
-+	void **ghcb_base;
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index f3761c73b074..01048bb07082 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -17,6 +17,7 @@
+ #include <linux/hyperv.h>
+ #include <linux/uio.h>
+ #include <linux/interrupt.h>
++#include <linux/set_memory.h>
+ #include <asm/page.h>
+ #include <asm/mshyperv.h>
  
- 	/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
- 	pg = alloc_pages(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL, hv_root_partition ? 1 : 0);
-@@ -128,6 +131,17 @@ static int hv_cpu_init(unsigned int cpu)
- 		wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, val);
+@@ -465,7 +466,7 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
+ 	struct list_head *curr;
+ 	u32 next_gpadl_handle;
+ 	unsigned long flags;
+-	int ret = 0;
++	int ret = 0, index;
+ 
+ 	next_gpadl_handle =
+ 		(atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1);
+@@ -474,6 +475,13 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
+ 	if (ret)
+ 		return ret;
+ 
++	ret = set_memory_decrypted((unsigned long)kbuffer,
++				   HVPFN_UP(size));
++	if (ret) {
++		pr_warn("Failed to set host visibility.\n");
++		return ret;
++	}
++
+ 	init_completion(&msginfo->waitevent);
+ 	msginfo->waiting_channel = channel;
+ 
+@@ -539,6 +547,15 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
+ 	/* At this point, we received the gpadl created msg */
+ 	*gpadl_handle = gpadlmsg->gpadl;
+ 
++	if (type == HV_GPADL_BUFFER)
++		index = 0;
++	else
++		index = channel->gpadl_range[1].gpadlhandle ? 2 : 1;
++
++	channel->gpadl_range[index].size = size;
++	channel->gpadl_range[index].buffer = kbuffer;
++	channel->gpadl_range[index].gpadlhandle = *gpadl_handle;
++
+ cleanup:
+ 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
+ 	list_del(&msginfo->msglistentry);
+@@ -549,6 +566,11 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
  	}
  
-+	if (ms_hyperv.ghcb_base) {
-+		rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa);
+ 	kfree(msginfo);
 +
-+		ghcb_va = ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE);
-+		if (!ghcb_va)
-+			return -ENOMEM;
++	if (ret)
++		set_memory_encrypted((unsigned long)kbuffer,
++				     HVPFN_UP(size));
 +
-+		ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base);
-+		*ghcb_base = ghcb_va;
-+	}
-+
- 	return 0;
+ 	return ret;
  }
  
-@@ -223,6 +237,7 @@ static int hv_cpu_die(unsigned int cpu)
+@@ -811,7 +833,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
+ 	struct vmbus_channel_gpadl_teardown *msg;
+ 	struct vmbus_channel_msginfo *info;
  	unsigned long flags;
- 	void **input_arg;
- 	void *pg;
-+	void **ghcb_va = NULL;
+-	int ret;
++	int ret, i;
  
- 	local_irq_save(flags);
- 	input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
-@@ -236,6 +251,13 @@ static int hv_cpu_die(unsigned int cpu)
- 		*output_arg = NULL;
- 	}
+ 	info = kzalloc(sizeof(*info) +
+ 		       sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
+@@ -859,6 +881,18 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
+ 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
  
-+	if (ms_hyperv.ghcb_base) {
-+		ghcb_va = (void **)this_cpu_ptr(ms_hyperv.ghcb_base);
-+		if (*ghcb_va)
-+			iounmap(*ghcb_va);
-+		*ghcb_va = NULL;
-+	}
+ 	kfree(info);
 +
- 	local_irq_restore(flags);
++	/* Find gpadl buffer virtual address and size. */
++	for (i = 0; i < VMBUS_GPADL_RANGE_COUNT; i++)
++		if (channel->gpadl_range[i].gpadlhandle == gpadl_handle)
++			break;
++
++	if (set_memory_encrypted((unsigned long)channel->gpadl_range[i].buffer,
++			HVPFN_UP(channel->gpadl_range[i].size)))
++		pr_warn("Fail to set mem host visibility.\n");
++
++	channel->gpadl_range[i].gpadlhandle = 0;
++
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 2e859d2f9609..06eccaba10c5 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -809,6 +809,14 @@ struct vmbus_device {
  
- 	free_pages((unsigned long)pg, hv_root_partition ? 1 : 0);
-@@ -372,6 +394,9 @@ void __init hyperv_init(void)
- 	u64 guest_id, required_msrs;
- 	union hv_x64_msr_hypercall_contents hypercall_msr;
- 	int cpuhp, i;
-+	u64 ghcb_gpa;
-+	void *ghcb_va;
-+	void **ghcb_base;
+ #define VMBUS_DEFAULT_MAX_PKT_SIZE 4096
  
- 	if (x86_hyper_type != X86_HYPER_MS_HYPERV)
- 		return;
-@@ -432,9 +457,24 @@ void __init hyperv_init(void)
- 			VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX,
- 			VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
- 			__builtin_return_address(0));
--	if (hv_hypercall_pg == NULL) {
--		wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
--		goto remove_cpuhp_state;
-+	if (hv_hypercall_pg == NULL)
-+		goto clean_guest_os_id;
++struct vmbus_gpadl_range {
++	u32 gpadlhandle;
++	u32 size;
++	void *buffer;
++};
 +
-+	if (hv_isolation_type_snp()) {
-+		ms_hyperv.ghcb_base = alloc_percpu(void *);
-+		if (!ms_hyperv.ghcb_base)
-+			goto clean_guest_os_id;
++#define VMBUS_GPADL_RANGE_COUNT		3
 +
-+		rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa);
-+		ghcb_va = ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE);
-+		if (!ghcb_va) {
-+			free_percpu(ms_hyperv.ghcb_base);
-+			ms_hyperv.ghcb_base = NULL;
-+			goto clean_guest_os_id;
-+		}
-+
-+		ghcb_base = (void **)this_cpu_ptr(ms_hyperv.ghcb_base);
-+		*ghcb_base = ghcb_va;
- 	}
+ struct vmbus_channel {
+ 	struct list_head listentry;
  
- 	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
-@@ -499,7 +539,8 @@ void __init hyperv_init(void)
+@@ -829,6 +837,8 @@ struct vmbus_channel {
+ 	struct completion rescind_event;
  
- 	return;
+ 	u32 ringbuffer_gpadlhandle;
++	/* GPADL_RING and Send/Receive GPADL_BUFFER. */
++	struct vmbus_gpadl_range gpadl_range[VMBUS_GPADL_RANGE_COUNT];
  
--remove_cpuhp_state:
-+clean_guest_os_id:
-+	wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
- 	cpuhp_remove_state(cpuhp);
- free_vp_assist_page:
- 	kfree(hv_vp_assist_page);
-@@ -528,6 +569,9 @@ void hyperv_cleanup(void)
- 	 */
- 	hv_hypercall_pg = NULL;
- 
-+	if (ms_hyperv.ghcb_base)
-+		free_percpu(ms_hyperv.ghcb_base);
-+
- 	/* Reset the hypercall page */
- 	hypercall_msr.as_uint64 = 0;
- 	wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
-diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
-index 347c32eac8fd..d6c363456cbf 100644
---- a/arch/x86/kernel/cpu/mshyperv.c
-+++ b/arch/x86/kernel/cpu/mshyperv.c
-@@ -330,6 +330,8 @@ static void __init ms_hyperv_init_platform(void)
- 	if (ms_hyperv.features_b & HV_ISOLATION) {
- 		ms_hyperv.isolation_config_a = cpuid_eax(HYPERV_CPUID_ISOLATION_CONFIG);
- 		ms_hyperv.isolation_config_b = cpuid_ebx(HYPERV_CPUID_ISOLATION_CONFIG);
-+		ms_hyperv.shared_gpa_boundary =
-+			(u64)1 << ms_hyperv.shared_gpa_boundary_bits;
- 
- 		pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
- 			ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
-diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
-index dff58a3db5d5..ad0e33776668 100644
---- a/include/asm-generic/mshyperv.h
-+++ b/include/asm-generic/mshyperv.h
-@@ -34,7 +34,19 @@ struct ms_hyperv_info {
- 	u32 max_vp_index;
- 	u32 max_lp_index;
- 	u32 isolation_config_a;
--	u32 isolation_config_b;
-+	union
-+	{
-+		u32 isolation_config_b;;
-+		struct {
-+			u32 cvm_type : 4;
-+			u32 Reserved11 : 1;
-+			u32 shared_gpa_boundary_active : 1;
-+			u32 shared_gpa_boundary_bits : 6;
-+			u32 Reserved12 : 20;
-+		};
-+	};
-+	void  __percpu **ghcb_base;
-+	u64 shared_gpa_boundary;
- };
- extern struct ms_hyperv_info ms_hyperv;
- 
+ 	/* Allocated memory for ring buffer */
+ 	struct page *ringbuffer_page;
 -- 
 2.25.1
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help