[RFC PATCH V2 08/18] x86/hyperv: decrypt vmbus pages for sev-snp enlightened guest

From: Tianyu Lan
Date: Fri Nov 18 2022 - 22:48:02 EST


From: Tianyu Lan <tiala@xxxxxxxxxxxxx>

Vmbus int, synic and post message pages are shared with hypervisor
and so decrypt these pages in the sev-snp guest.

Signed-off-by: Tianyu Lan <tiala@xxxxxxxxxxxxx>
---
drivers/hv/connection.c | 13 +++++++++++++
drivers/hv/hv.c | 32 +++++++++++++++++++++++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 9dc27e5d367a..43141225ea15 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -215,6 +215,15 @@ int vmbus_connect(void)
(void *)((unsigned long)vmbus_connection.int_page +
(HV_HYP_PAGE_SIZE >> 1));

+ if (hv_isolation_type_snp() || hv_isolation_type_en_snp()) {
+ ret = set_memory_decrypted((unsigned long)
+ vmbus_connection.int_page, 1);
+ if (ret)
+ goto cleanup;
+
+ memset(vmbus_connection.int_page, 0, PAGE_SIZE);
+ }
+
/*
* Setup the monitor notification facility. The 1st page for
* parent->child and the 2nd page for child->parent
@@ -372,6 +381,10 @@ void vmbus_disconnect(void)
destroy_workqueue(vmbus_connection.work_queue);

if (vmbus_connection.int_page) {
+ if (hv_isolation_type_en_snp())
+ set_memory_encrypted((unsigned long)
+ vmbus_connection.int_page, 1);
+
hv_free_hyperv_page((unsigned long)vmbus_connection.int_page);
vmbus_connection.int_page = NULL;
}
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 4d6480d57546..f9111eb32739 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <clocksource/hyperv_timer.h>
#include <asm/mshyperv.h>
+#include <linux/set_memory.h>
#include "hyperv_vmbus.h"

/* The one and only */
@@ -117,7 +118,7 @@ int hv_post_message(union hv_connection_id connection_id,

int hv_synic_alloc(void)
{
- int cpu;
+ int cpu, ret;
struct hv_per_cpu_context *hv_cpu;

/*
@@ -168,6 +169,29 @@ int hv_synic_alloc(void)
pr_err("Unable to allocate post msg page\n");
goto err;
}
+
+ if (hv_isolation_type_en_snp()) {
+ ret = set_memory_decrypted((unsigned long)
+ hv_cpu->synic_message_page, 1);
+ ret |= set_memory_decrypted((unsigned long)
+ hv_cpu->synic_event_page, 1);
+ ret |= set_memory_decrypted((unsigned long)
+ hv_cpu->post_msg_page, 1);
+
+ if (ret) {
+ set_memory_encrypted((unsigned long)
+ hv_cpu->synic_message_page, 1);
+ set_memory_encrypted((unsigned long)
+ hv_cpu->synic_event_page, 1);
+ set_memory_encrypted((unsigned long)
+ hv_cpu->post_msg_page, 1);
+ goto err;
+ }
+
+ memset(hv_cpu->synic_message_page, 0, PAGE_SIZE);
+ memset(hv_cpu->synic_event_page, 0, PAGE_SIZE);
+ memset(hv_cpu->post_msg_page, 0, PAGE_SIZE);
+ }
}

return 0;
@@ -188,6 +212,12 @@ void hv_synic_free(void)
struct hv_per_cpu_context *hv_cpu
= per_cpu_ptr(hv_context.cpu_context, cpu);

+ if (hv_isolation_type_en_snp()) {
+ set_memory_encrypted((unsigned long)hv_cpu->synic_message_page, 1);
+ set_memory_encrypted((unsigned long)hv_cpu->synic_event_page, 1);
+ set_memory_encrypted((unsigned long)hv_cpu->post_msg_page, 1);
+ }
+
free_page((unsigned long)hv_cpu->synic_event_page);
free_page((unsigned long)hv_cpu->synic_message_page);
free_page((unsigned long)hv_cpu->post_msg_page);
--
2.25.1