Hyper-V provides two modes for running a TDX/SNP VM:

1) In TD Partitioning mode (TDX) or vTOM mode (SNP) with a paravisor;
2) In "fully enlightened" mode with the normal TDX shared bit or SNP C-bit
   control over page encryption, and no paravisor.

In the first mode (i.e. paravisor mode), the native TDX/SNP CPUID
capability is hidden from the VM, but cc_platform_has(CC_ATTR_MEM_ENCRYPT)
and cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) are true; as a result,
mem_encrypt_init() incorrectly prints the below message when an Intel TDX
VM with a paravisor runs on Hyper-V:
"Memory Encryption Features active: AMD SEV".

Introduce x86_platform.print_mem_enc_feature_info and allow hv_vtom_init()
to override the function pointer so that the correct message is printed.

BTW, when a VBS (Virtualization-based Security) VM running on Hyper-V
(the physical CPU can be an AMD CPU or an Intel CPU), the VM's memory is
not encrypted, but mem_encrypt_init() also prints the same incorrect
message. The introduction of x86_platform.print_mem_enc_feature_info can
also fix the issue.

Signed-off-by: Dexuan Cui <[email protected]>
---

Some open questions:

1. Should we refactor the existing print_memory_encrypt_feature_info()
into a TDX-specific function and an SEV-specific function?  The
function pointer in x86_platform_ops would be initialized to a no-op
function, and then early_tdx_init(), sme_enable() and hv_vtom_init()
would fill it in accordingly.

2. Should we rename "print_mem_enc_feature_info()" to
"print_coco_feature_info()"?  CC_ATTR_GUEST_STATE_ENCRYPT (and
CC_ATTR_GUEST_SEV_SNP?) may not look like *memory* encryption to me?

 arch/x86/hyperv/ivm.c              | 11 +++++++++++
 arch/x86/include/asm/mem_encrypt.h |  1 +
 arch/x86/include/asm/x86_init.h    |  2 ++
 arch/x86/kernel/x86_init.c         |  1 +
 arch/x86/mm/mem_encrypt.c          |  4 ++--
 5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index e68051eba25a..fdc2fab0415e 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -450,6 +450,16 @@ static bool hv_is_private_mmio(u64 addr)
        return false;
 }
 
+static void hv_print_mem_enc_feature_info(void)
+{
+       enum hv_isolation_type type = hv_get_isolation_type();
+
+       if (type == HV_ISOLATION_TYPE_SNP)
+               pr_info("Memory Encryption Features active: AMD SEV\n");
+       else if (type == HV_ISOLATION_TYPE_TDX)
+               pr_info("Memory Encryption Features active: Intel TDX\n");
+}
+
 void __init hv_vtom_init(void)
 {
        enum hv_isolation_type type = hv_get_isolation_type();
@@ -479,6 +489,7 @@ void __init hv_vtom_init(void)
        cc_set_mask(ms_hyperv.shared_gpa_boundary);
        physical_mask &= ms_hyperv.shared_gpa_boundary - 1;
 
+       x86_platform.print_mem_enc_feature_info = hv_print_mem_enc_feature_info;
        x86_platform.hyper.is_private_mmio = hv_is_private_mmio;
        x86_platform.guest.enc_cache_flush_required = 
hv_vtom_cache_flush_required;
        x86_platform.guest.enc_tlb_flush_required = hv_vtom_tlb_flush_required;
diff --git a/arch/x86/include/asm/mem_encrypt.h 
b/arch/x86/include/asm/mem_encrypt.h
index 7f97a8a97e24..6e8050a9138e 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -19,6 +19,7 @@
 
 #ifdef CONFIG_X86_MEM_ENCRYPT
 void __init mem_encrypt_init(void);
+void print_mem_encrypt_feature_info(void);
 #else
 static inline void mem_encrypt_init(void) { }
 #endif
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 14b0562c1d8b..7798174d4b8d 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -291,6 +291,7 @@ struct x86_hyper_runtime {
  *                             semantics.
  * @realmode_reserve:          reserve memory for realmode trampoline
  * @realmode_init:             initialize realmode trampoline
+ * @print_mem_enc_feature_info:        print the supported memory encryption 
features
  * @hyper:                     x86 hypervisor specific runtime callbacks
  */
 struct x86_platform_ops {
@@ -309,6 +310,7 @@ struct x86_platform_ops {
        void (*set_legacy_features)(void);
        void (*realmode_reserve)(void);
        void (*realmode_init)(void);
+       void (*print_mem_enc_feature_info)(void);
        struct x86_hyper_runtime hyper;
        struct x86_guest guest;
 };
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 6117662ae4e6..ccb53db1b51e 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -149,6 +149,7 @@ struct x86_platform_ops x86_platform __ro_after_init = {
        .restore_sched_clock_state      = tsc_restore_sched_clock_state,
        .realmode_reserve               = reserve_real_mode,
        .realmode_init                  = init_real_mode,
+       .print_mem_enc_feature_info     = print_mem_encrypt_feature_info,
        .hyper.pin_vcpu                 = x86_op_int_noop,
        .hyper.is_private_mmio          = is_private_mmio_noop,
 
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 9f27e14e185f..8d37048bc1df 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -39,7 +39,7 @@ bool force_dma_unencrypted(struct device *dev)
        return false;
 }
 
-static void print_mem_encrypt_feature_info(void)
+void print_mem_encrypt_feature_info(void)
 {
        pr_info("Memory Encryption Features active:");
 
@@ -84,5 +84,5 @@ void __init mem_encrypt_init(void)
        /* Call into SWIOTLB to update the SWIOTLB DMA buffers */
        swiotlb_update_mem_attributes();
 
-       print_mem_encrypt_feature_info();
+       x86_platform.print_mem_enc_feature_info();
 }
-- 
2.25.1


Reply via email to