--- v2
+++ v4
@@ -1,71 +1,133 @@
From: Tianyu Lan <Tianyu.Lan@microsoft.com>
-Hyper-V and other platforms(e.g Intel and AMD) want to override
-the __set_memory_enc_dec(). Add x86_set_memory_enc static
-call here and platforms can hook their implementation.
+Mark vmbus ring buffer visible with set_memory_decrypted() when
+establish gpadl handle.
Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
- arch/x86/include/asm/set_memory.h | 4 ++++
- arch/x86/mm/pat/set_memory.c | 9 +++++++++
- 2 files changed, 13 insertions(+)
+ drivers/hv/channel.c | 38 ++++++++++++++++++++++++++++++++++++--
+ include/linux/hyperv.h | 10 ++++++++++
+ 2 files changed, 46 insertions(+), 2 deletions(-)
-diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
-index 43fa081a1adb..490f2cfc00fa 100644
---- a/arch/x86/include/asm/set_memory.h
-+++ b/arch/x86/include/asm/set_memory.h
-@@ -4,6 +4,7 @@
+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>
- #include <asm/page.h>
- #include <asm-generic/set_memory.h>
-+#include <linux/static_call.h>
+@@ -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;
- /*
- * The set_memory_* API can be used to change various attributes of a virtual
-@@ -84,6 +85,9 @@ int set_direct_map_invalid_noflush(struct page *page);
- int set_direct_map_default_noflush(struct page *page);
- bool kernel_page_present(struct page *page);
+ 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;
-+int dummy_set_memory_enc(unsigned long addr, int numpages, bool enc);
-+DECLARE_STATIC_CALL(x86_set_memory_enc, dummy_set_memory_enc);
++ ret = set_memory_decrypted((unsigned long)kbuffer,
++ HVPFN_UP(size));
++ if (ret) {
++ pr_warn("Failed to set host visibility.\n");
++ return ret;
++ }
+
- extern int kernel_set_to_readonly;
+ init_completion(&msginfo->waitevent);
+ msginfo->waiting_channel = channel;
- #ifdef CONFIG_X86_64
-diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
-index ad8a5c586a35..68e9ab522cea 100644
---- a/arch/x86/mm/pat/set_memory.c
-+++ b/arch/x86/mm/pat/set_memory.c
-@@ -18,6 +18,7 @@
- #include <linux/libnvdimm.h>
- #include <linux/vmstat.h>
- #include <linux/kernel.h>
-+#include <linux/static_call.h>
+@@ -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;
- #include <asm/e820/api.h>
- #include <asm/processor.h>
-@@ -66,6 +67,9 @@ static const int cpa_warn_level = CPA_PROTECT;
- */
- static DEFINE_SPINLOCK(cpa_lock);
++ 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,
+ }
-+static int default_set_memory_enc(unsigned long addr, int numpages, bool enc);
-+DEFINE_STATIC_CALL(x86_set_memory_enc, default_set_memory_enc);
+ kfree(msginfo);
+
- #define CPA_FLUSHTLB 1
- #define CPA_ARRAY 2
- #define CPA_PAGES_ARRAY 4
-@@ -1981,6 +1985,11 @@ int set_memory_global(unsigned long addr, int numpages)
++ if (ret)
++ set_memory_encrypted((unsigned long)kbuffer,
++ HVPFN_UP(size));
++
+ return ret;
}
- static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
-+{
-+ return static_call(x86_set_memory_enc)(addr, numpages, enc);
-+}
+@@ -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;
+- int ret;
++ int ret, i;
+
+ 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);
+
+ kfree(info);
+
-+static int default_set_memory_enc(unsigned long addr, int numpages, bool enc)
- {
- struct cpa_data cpa;
- int ret;
++ /* 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 {
+
+ #define VMBUS_DEFAULT_MAX_PKT_SIZE 4096
+
++struct vmbus_gpadl_range {
++ u32 gpadlhandle;
++ u32 size;
++ void *buffer;
++};
++
++#define VMBUS_GPADL_RANGE_COUNT 3
++
+ struct vmbus_channel {
+ struct list_head listentry;
+
+@@ -829,6 +837,8 @@ struct vmbus_channel {
+ struct completion rescind_event;
+
+ u32 ringbuffer_gpadlhandle;
++ /* GPADL_RING and Send/Receive GPADL_BUFFER. */
++ struct vmbus_gpadl_range gpadl_range[VMBUS_GPADL_RANGE_COUNT];
+
+ /* Allocated memory for ring buffer */
+ struct page *ringbuffer_page;
--
2.25.1