Add Hyper-V specific code so that a TDX guest can run on Hyper-V:
No need to use hv_vp_assist_page.
Don't use the unsafe Hyper-V TSC page.
Don't try to use HV_REGISTER_CRASH_CTL.
Share SynIC Event/Message pages and VMBus Monitor pages with the host.
Use pgprot_decrypted(PAGE_KERNEL_NOENC))in hv_ringbuffer_init().
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Changes in v2:
Used a new function hv_set_memory_enc_dec_needed() in
__set_memory_enc_pgtable().
Added the missing set_memory_encrypted() in hv_synic_free().
---
arch/x86/hyperv/hv_init.c | 19 ++++++++---
arch/x86/hyperv/ivm.c | 5 +++
arch/x86/kernel/cpu/mshyperv.c | 17 +++++++++-
arch/x86/mm/pat/set_memory.c | 2 +-
drivers/hv/connection.c | 4 ++-
drivers/hv/hv.c | 60 +++++++++++++++++++++++++++++++++-
drivers/hv/hv_common.c | 6 ++++
drivers/hv/ring_buffer.c | 2 +-
include/asm-generic/mshyperv.h | 2 ++
9 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index c0ba53ad8b8e..8d7b63346194 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -77,7 +77,7 @@ static int hyperv_init_ghcb(void)
static int hv_cpu_init(unsigned int cpu)
{
union hv_vp_assist_msr_contents msr = { 0 };
- struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
+ struct hv_vp_assist_page **hvp;
int ret;
ret = hv_common_cpu_init(cpu);
@@ -87,6 +87,7 @@ static int hv_cpu_init(unsigned int cpu)
if (!hv_vp_assist_page)
return 0;
+ hvp = &hv_vp_assist_page[cpu];
if (hv_root_partition) {
/*
* For root partition we get the hypervisor provided VP assist
@@ -396,11 +397,21 @@ void __init hyperv_init(void)
if (hv_common_init())
return;
- hv_vp_assist_page = kcalloc(num_possible_cpus(),
- sizeof(*hv_vp_assist_page), GFP_KERNEL);
+ /*
+ * The VP assist page is useless to a TDX guest: the only use we
+ * would have for it is lazy EOI, which can not be used with TDX.
+ */
+ if (hv_isolation_type_tdx())
+ hv_vp_assist_page = NULL;
+ else
+ hv_vp_assist_page = kcalloc(num_possible_cpus(),
+ sizeof(*hv_vp_assist_page),
+ GFP_KERNEL);
if (!hv_vp_assist_page) {
ms_hyperv.hints &= ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED;
- goto common_free;
+
+ if (!hv_isolation_type_tdx())
+ goto common_free;
}
if (hv_isolation_type_snp()) {
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 07e4253b5809..4398042f10d5 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -258,6 +258,11 @@ bool hv_is_isolation_supported(void)
return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
}
+bool hv_set_memory_enc_dec_needed(void)
+{
+ return hv_is_isolation_supported() && !hv_isolation_type_tdx();
+}
+
DEFINE_STATIC_KEY_FALSE(isolation_type_snp);
/*
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 941372449ff2..24569da3c1f8 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -345,8 +345,23 @@ static void __init ms_hyperv_init_platform(void)
}
if (IS_ENABLED(CONFIG_INTEL_TDX_GUEST) &&
- hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX)
+ hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) {
static_branch_enable(&isolation_type_tdx);
+
+ /*
+ * The GPAs of SynIC Event/Message pages and VMBus
+ * Moniter pages need to be added by this offset.
+ */
+ ms_hyperv.shared_gpa_boundary = cc_mkdec(0);
+
+ /* Don't use the unsafe Hyper-V TSC page */
+ ms_hyperv.features &=
+ ~HV_MSR_REFERENCE_TSC_AVAILABLE;
+
+ /* HV_REGISTER_CRASH_CTL is unsupported */
+ ms_hyperv.misc_features &=
+ ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
+ }
}
if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 2e5a045731de..5892196f8ade 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2120,7 +2120,7 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
{
- if (hv_is_isolation_supported())
+ if (hv_set_memory_enc_dec_needed())
return hv_set_mem_host_visibility(addr, numpages, !enc);
if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 9dc27e5d367a..1ecc3c29e3f7 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -250,12 +250,14 @@ int vmbus_connect(void)
* Isolation VM with AMD SNP needs to access monitor page via
* address space above shared gpa boundary.
*/
- if (hv_isolation_type_snp()) {
+ if (hv_isolation_type_snp() || hv_isolation_type_tdx()) {
vmbus_connection.monitor_pages_pa[0] +=
ms_hyperv.shared_gpa_boundary;
vmbus_connection.monitor_pages_pa[1] +=
ms_hyperv.shared_gpa_boundary;
+ }
+ if (hv_isolation_type_snp()) {
vmbus_connection.monitor_pages[0]
= memremap(vmbus_connection.monitor_pages_pa[0],
HV_HYP_PAGE_SIZE,
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 4d6480d57546..78aca415985c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -18,6 +18,7 @@
#include <linux/clockchips.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/set_memory.h>
#include <clocksource/hyperv_timer.h>
#include <asm/mshyperv.h>
#include "hyperv_vmbus.h"
@@ -119,6 +120,7 @@ int hv_synic_alloc(void)
{
int cpu;
struct hv_per_cpu_context *hv_cpu;
+ int ret = -ENOMEM;
/*
* First, zero all per-cpu memory areas so hv_synic_free() can
@@ -168,6 +170,30 @@ int hv_synic_alloc(void)
pr_err("Unable to allocate post msg page\n");
goto err;
}
+
+
+ if (hv_isolation_type_tdx()) {
+ ret = set_memory_decrypted(
+ (unsigned long)hv_cpu->synic_message_page, 1);
+ if (ret) {
+ pr_err("Failed to decrypt SYNIC msg page\n");
+ goto err;
+ }
+
+ ret = set_memory_decrypted(
+ (unsigned long)hv_cpu->synic_event_page, 1);
+ if (ret) {
+ pr_err("Failed to decrypt SYNIC event page\n");
+ goto err;
+ }
+
+ ret = set_memory_decrypted(
+ (unsigned long)hv_cpu->post_msg_page, 1);
+ if (ret) {
+ pr_err("Failed to decrypt post msg page\n");
+ goto err;
+ }
+ }
}
return 0;
@@ -176,18 +202,42 @@ int hv_synic_alloc(void)
* Any memory allocations that succeeded will be freed when
* the caller cleans up by calling hv_synic_free()
*/
- return -ENOMEM;
+ return ret;
}
void hv_synic_free(void)
{
int cpu;
+ int ret;
for_each_present_cpu(cpu) {
struct hv_per_cpu_context *hv_cpu
= per_cpu_ptr(hv_context.cpu_context, cpu);
+ if (hv_isolation_type_tdx()) {
+ ret = set_memory_encrypted(
+ (unsigned long)hv_cpu->synic_message_page, 1);
+ if (ret) {
+ pr_err("Failed to encrypt SYNIC msg page\n");
+ continue;
+ }
+
+ ret = set_memory_encrypted(
+ (unsigned long)hv_cpu->synic_event_page, 1);
+ if (ret) {
+ pr_err("Failed to encrypt SYNIC event page\n");
+ continue;
+ }
+
+ ret = set_memory_encrypted(
+ (unsigned long)hv_cpu->post_msg_page, 1);
+ if (ret) {
+ pr_err("Failed to encrypt post msg page\n");
+ continue;
+ }
+ }
+
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);
@@ -225,6 +275,10 @@ void hv_synic_enable_regs(unsigned int cpu)
} else {
simp.base_simp_gpa = virt_to_phys(hv_cpu->synic_message_page)
>> HV_HYP_PAGE_SHIFT;
+
+ if (hv_isolation_type_tdx())
+ simp.base_simp_gpa |= ms_hyperv.shared_gpa_boundary
+ >> HV_HYP_PAGE_SHIFT;
}
hv_set_register(HV_REGISTER_SIMP, simp.as_uint64);
@@ -243,6 +297,10 @@ void hv_synic_enable_regs(unsigned int cpu)
} else {
siefp.base_siefp_gpa = virt_to_phys(hv_cpu->synic_event_page)
>> HV_HYP_PAGE_SHIFT;
+
+ if (hv_isolation_type_tdx())
+ siefp.base_siefp_gpa |= ms_hyperv.shared_gpa_boundary
+ >> HV_HYP_PAGE_SHIFT;
}
hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index a9a03ab04b97..192dcf295dfc 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -262,6 +262,12 @@ bool __weak hv_is_isolation_supported(void)
}
EXPORT_SYMBOL_GPL(hv_is_isolation_supported);
+bool __weak hv_set_memory_enc_dec_needed(void)
+{
+ return false;
+}
+EXPORT_SYMBOL_GPL(hv_set_memory_enc_dec_needed);
+
bool __weak hv_isolation_type_snp(void)
{
return false;
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index c6692fd5ab15..a51da82316ce 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -233,7 +233,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
ring_info->ring_buffer = (struct hv_ring_buffer *)
vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP,
- PAGE_KERNEL);
+ pgprot_decrypted(PAGE_KERNEL_NOENC));
kfree(pages_wraparound);
if (!ring_info->ring_buffer)
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index bfb9eb9d7215..b7b1b18c9854 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -262,6 +262,7 @@ bool hv_is_hyperv_initialized(void);
bool hv_is_hibernation_supported(void);
enum hv_isolation_type hv_get_isolation_type(void);
bool hv_is_isolation_supported(void);
+bool hv_set_memory_enc_dec_needed(void);
bool hv_isolation_type_snp(void);
u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);
void hyperv_cleanup(void);
@@ -274,6 +275,7 @@ static inline bool hv_is_hyperv_initialized(void) { return false; }
static inline bool hv_is_hibernation_supported(void) { return false; }
static inline void hyperv_cleanup(void) {}
static inline bool hv_is_isolation_supported(void) { return false; }
+static inline bool hv_set_memory_enc_dec_needed(void) { return false; }
static inline enum hv_isolation_type hv_get_isolation_type(void)
{
return HV_ISOLATION_TYPE_NONE;
--
2.25.1
From: Dexuan Cui <decui@microsoft.com> Sent: Tuesday, December 6, 2022 4:33 PM > > Add Hyper-V specific code so that a TDX guest can run on Hyper-V: > No need to use hv_vp_assist_page. > Don't use the unsafe Hyper-V TSC page. > Don't try to use HV_REGISTER_CRASH_CTL. > Share SynIC Event/Message pages and VMBus Monitor pages with the host. > Use pgprot_decrypted(PAGE_KERNEL_NOENC))in hv_ringbuffer_init(). > > Signed-off-by: Dexuan Cui <decui@microsoft.com> > > Changes in v2: > Used a new function hv_set_memory_enc_dec_needed() in > __set_memory_enc_pgtable(). > Added the missing set_memory_encrypted() in hv_synic_free(). > > --- > > arch/x86/hyperv/hv_init.c | 19 ++++++++--- > arch/x86/hyperv/ivm.c | 5 +++ > arch/x86/kernel/cpu/mshyperv.c | 17 +++++++++- > arch/x86/mm/pat/set_memory.c | 2 +- > drivers/hv/connection.c | 4 ++- > drivers/hv/hv.c | 60 +++++++++++++++++++++++++++++++++- > drivers/hv/hv_common.c | 6 ++++ > drivers/hv/ring_buffer.c | 2 +- > include/asm-generic/mshyperv.h | 2 ++ > 9 files changed, 108 insertions(+), 9 deletions(-) > > diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c > index c0ba53ad8b8e..8d7b63346194 100644 > --- a/arch/x86/hyperv/hv_init.c > +++ b/arch/x86/hyperv/hv_init.c > @@ -77,7 +77,7 @@ static int hyperv_init_ghcb(void) > static int hv_cpu_init(unsigned int cpu) > { > union hv_vp_assist_msr_contents msr = { 0 }; > - struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu]; > + struct hv_vp_assist_page **hvp; > int ret; > > ret = hv_common_cpu_init(cpu); > @@ -87,6 +87,7 @@ static int hv_cpu_init(unsigned int cpu) > if (!hv_vp_assist_page) > return 0; > > + hvp = &hv_vp_assist_page[cpu]; > if (hv_root_partition) { > /* > * For root partition we get the hypervisor provided VP assist > @@ -396,11 +397,21 @@ void __init hyperv_init(void) > if (hv_common_init()) > return; > > - hv_vp_assist_page = kcalloc(num_possible_cpus(), > - sizeof(*hv_vp_assist_page), GFP_KERNEL); > + /* > + * The VP assist page is useless to a TDX guest: the only use we > + * would have for it is lazy EOI, which can not be used with TDX. > + */ > + if (hv_isolation_type_tdx()) > + hv_vp_assist_page = NULL; > + else > + hv_vp_assist_page = kcalloc(num_possible_cpus(), > + sizeof(*hv_vp_assist_page), > + GFP_KERNEL); > if (!hv_vp_assist_page) { > ms_hyperv.hints &= > ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; > - goto common_free; > + > + if (!hv_isolation_type_tdx()) > + goto common_free; > } > > if (hv_isolation_type_snp()) { > diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c > index 07e4253b5809..4398042f10d5 100644 > --- a/arch/x86/hyperv/ivm.c > +++ b/arch/x86/hyperv/ivm.c > @@ -258,6 +258,11 @@ bool hv_is_isolation_supported(void) > return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE; > } > > +bool hv_set_memory_enc_dec_needed(void) > +{ > + return hv_is_isolation_supported() && !hv_isolation_type_tdx(); > +} > + > DEFINE_STATIC_KEY_FALSE(isolation_type_snp); > > /* > diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c > index 941372449ff2..24569da3c1f8 100644 > --- a/arch/x86/kernel/cpu/mshyperv.c > +++ b/arch/x86/kernel/cpu/mshyperv.c > @@ -345,8 +345,23 @@ static void __init ms_hyperv_init_platform(void) > } > > if (IS_ENABLED(CONFIG_INTEL_TDX_GUEST) && > - hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) > + hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) { > static_branch_enable(&isolation_type_tdx); > + > + /* > + * The GPAs of SynIC Event/Message pages and VMBus > + * Moniter pages need to be added by this offset. > + */ > + ms_hyperv.shared_gpa_boundary = cc_mkdec(0); > + > + /* Don't use the unsafe Hyper-V TSC page */ > + ms_hyperv.features &= > + ~HV_MSR_REFERENCE_TSC_AVAILABLE; > + > + /* HV_REGISTER_CRASH_CTL is unsupported */ > + ms_hyperv.misc_features &= > + ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE; > + } > } > > if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) { > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c > index 2e5a045731de..5892196f8ade 100644 > --- a/arch/x86/mm/pat/set_memory.c > +++ b/arch/x86/mm/pat/set_memory.c > @@ -2120,7 +2120,7 @@ static int __set_memory_enc_pgtable(unsigned long addr, > int numpages, bool enc) > > static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc) > { > - if (hv_is_isolation_supported()) > + if (hv_set_memory_enc_dec_needed()) > return hv_set_mem_host_visibility(addr, numpages, !enc); > > if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) > diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c > index 9dc27e5d367a..1ecc3c29e3f7 100644 > --- a/drivers/hv/connection.c > +++ b/drivers/hv/connection.c > @@ -250,12 +250,14 @@ int vmbus_connect(void) > * Isolation VM with AMD SNP needs to access monitor page via > * address space above shared gpa boundary. > */ > - if (hv_isolation_type_snp()) { > + if (hv_isolation_type_snp() || hv_isolation_type_tdx()) { > vmbus_connection.monitor_pages_pa[0] += > ms_hyperv.shared_gpa_boundary; > vmbus_connection.monitor_pages_pa[1] += > ms_hyperv.shared_gpa_boundary; > + } > > + if (hv_isolation_type_snp()) { > vmbus_connection.monitor_pages[0] > = > memremap(vmbus_connection.monitor_pages_pa[0], > HV_HYP_PAGE_SIZE, > diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c > index 4d6480d57546..78aca415985c 100644 > --- a/drivers/hv/hv.c > +++ b/drivers/hv/hv.c > @@ -18,6 +18,7 @@ > #include <linux/clockchips.h> > #include <linux/delay.h> > #include <linux/interrupt.h> > +#include <linux/set_memory.h> > #include <clocksource/hyperv_timer.h> > #include <asm/mshyperv.h> > #include "hyperv_vmbus.h" > @@ -119,6 +120,7 @@ int hv_synic_alloc(void) > { > int cpu; > struct hv_per_cpu_context *hv_cpu; > + int ret = -ENOMEM; > > /* > * First, zero all per-cpu memory areas so hv_synic_free() can > @@ -168,6 +170,30 @@ int hv_synic_alloc(void) > pr_err("Unable to allocate post msg page\n"); > goto err; > } > + > + > + if (hv_isolation_type_tdx()) { > + ret = set_memory_decrypted( > + (unsigned long)hv_cpu->synic_message_page, 1); > + if (ret) { > + pr_err("Failed to decrypt SYNIC msg page\n"); > + goto err; > + } > + > + ret = set_memory_decrypted( > + (unsigned long)hv_cpu->synic_event_page, 1); > + if (ret) { > + pr_err("Failed to decrypt SYNIC event page\n"); > + goto err; > + } > + > + ret = set_memory_decrypted( > + (unsigned long)hv_cpu->post_msg_page, 1); > + if (ret) { > + pr_err("Failed to decrypt post msg page\n"); > + goto err; > + } > + } > } > > return 0; > @@ -176,18 +202,42 @@ int hv_synic_alloc(void) > * Any memory allocations that succeeded will be freed when > * the caller cleans up by calling hv_synic_free() > */ > - return -ENOMEM; > + return ret; > } > > > void hv_synic_free(void) > { > int cpu; > + int ret; > > for_each_present_cpu(cpu) { > struct hv_per_cpu_context *hv_cpu > = per_cpu_ptr(hv_context.cpu_context, cpu); > > + if (hv_isolation_type_tdx()) { > + ret = set_memory_encrypted( > + (unsigned long)hv_cpu->synic_message_page, 1); > + if (ret) { > + pr_err("Failed to encrypt SYNIC msg page\n"); > + continue; > + } > + > + ret = set_memory_encrypted( > + (unsigned long)hv_cpu->synic_event_page, 1); > + if (ret) { > + pr_err("Failed to encrypt SYNIC event page\n"); > + continue; > + } > + > + ret = set_memory_encrypted( > + (unsigned long)hv_cpu->post_msg_page, 1); > + if (ret) { > + pr_err("Failed to encrypt post msg page\n"); > + continue; > + } > + } > + > 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); > @@ -225,6 +275,10 @@ void hv_synic_enable_regs(unsigned int cpu) > } else { > simp.base_simp_gpa = virt_to_phys(hv_cpu->synic_message_page) > >> HV_HYP_PAGE_SHIFT; > + > + if (hv_isolation_type_tdx()) > + simp.base_simp_gpa |= ms_hyperv.shared_gpa_boundary > + >> HV_HYP_PAGE_SHIFT; Since we're using cc_mkdec() in hv_do_hypercall() to set the SHARED bit, perhaps the same could be done here to simplify the code and avoid the explicit call to hv_isolation_type_tdx(): simp.base_simp_gpa = cc_mkdec(virt_to_phys(hv_cpu->synic_message)) >> HV_HYP_PAGE_SHIFT; cc_mkdec() does nothing in a normal VM, and vTOM VMs are already special-cased. > } > > hv_set_register(HV_REGISTER_SIMP, simp.as_uint64); > @@ -243,6 +297,10 @@ void hv_synic_enable_regs(unsigned int cpu) > } else { > siefp.base_siefp_gpa = virt_to_phys(hv_cpu->synic_event_page) > >> HV_HYP_PAGE_SHIFT; > + > + if (hv_isolation_type_tdx()) > + siefp.base_siefp_gpa |= ms_hyperv.shared_gpa_boundary > + >> HV_HYP_PAGE_SHIFT; Same here. > } > > hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64); > diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c > index a9a03ab04b97..192dcf295dfc 100644 > --- a/drivers/hv/hv_common.c > +++ b/drivers/hv/hv_common.c > @@ -262,6 +262,12 @@ bool __weak hv_is_isolation_supported(void) > } > EXPORT_SYMBOL_GPL(hv_is_isolation_supported); > > +bool __weak hv_set_memory_enc_dec_needed(void) > +{ > + return false; > +} > +EXPORT_SYMBOL_GPL(hv_set_memory_enc_dec_needed); > + > bool __weak hv_isolation_type_snp(void) > { > return false; > diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c > index c6692fd5ab15..a51da82316ce 100644 > --- a/drivers/hv/ring_buffer.c > +++ b/drivers/hv/ring_buffer.c > @@ -233,7 +233,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, > > ring_info->ring_buffer = (struct hv_ring_buffer *) > vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP, > - PAGE_KERNEL); > + pgprot_decrypted(PAGE_KERNEL_NOENC)); > > kfree(pages_wraparound); > if (!ring_info->ring_buffer) > diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h > index bfb9eb9d7215..b7b1b18c9854 100644 > --- a/include/asm-generic/mshyperv.h > +++ b/include/asm-generic/mshyperv.h > @@ -262,6 +262,7 @@ bool hv_is_hyperv_initialized(void); > bool hv_is_hibernation_supported(void); > enum hv_isolation_type hv_get_isolation_type(void); > bool hv_is_isolation_supported(void); > +bool hv_set_memory_enc_dec_needed(void); > bool hv_isolation_type_snp(void); > u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size); > void hyperv_cleanup(void); > @@ -274,6 +275,7 @@ static inline bool hv_is_hyperv_initialized(void) { return false; } > static inline bool hv_is_hibernation_supported(void) { return false; } > static inline void hyperv_cleanup(void) {} > static inline bool hv_is_isolation_supported(void) { return false; } > +static inline bool hv_set_memory_enc_dec_needed(void) { return false; } > static inline enum hv_isolation_type hv_get_isolation_type(void) > { > return HV_ISOLATION_TYPE_NONE; > -- > 2.25.1
> From: Michael Kelley (LINUX) <mikelley@microsoft.com> > Sent: Monday, December 12, 2022 9:02 AM > > [...] > > @@ -225,6 +275,10 @@ void hv_synic_enable_regs(unsigned int cpu) > > } else { > > simp.base_simp_gpa = virt_to_phys(hv_cpu->synic_message_page) > > >> HV_HYP_PAGE_SHIFT; > > + > > + if (hv_isolation_type_tdx()) > > + simp.base_simp_gpa |= ms_hyperv.shared_gpa_boundary > > + >> HV_HYP_PAGE_SHIFT; > > Since we're using cc_mkdec() in hv_do_hypercall() to set the SHARED bit, > perhaps the same could be done here to simplify the code and avoid the > explicit call to hv_isolation_type_tdx(): Good idea! Will do. > simp.base_simp_gpa = > cc_mkdec(virt_to_phys(hv_cpu->synic_message)) > >> HV_HYP_PAGE_SHIFT; > > cc_mkdec() does nothing in a normal VM, and vTOM VMs are already > special-cased. This should work for C-bit SNP as well (clearing cc_mask from the GPA doesn't really change the GPA since the GPA doesn't have the bit in the first place). > > hv_set_register(HV_REGISTER_SIMP, simp.as_uint64); > > @@ -243,6 +297,10 @@ void hv_synic_enable_regs(unsigned int cpu) > > } else { > > siefp.base_siefp_gpa = virt_to_phys(hv_cpu->synic_event_page) > > >> HV_HYP_PAGE_SHIFT; > > + > > + if (hv_isolation_type_tdx()) > > + siefp.base_siefp_gpa |= ms_hyperv.shared_gpa_boundary > > + >> HV_HYP_PAGE_SHIFT; > > Same here. Will do.
© 2016 - 2025 Red Hat, Inc.