From c0c4c54954748d14571ad17c7dea5819f61858b9 Mon Sep 17 00:00:00 2001 From: xiongmengbiao Date: Tue, 9 Jul 2024 14:31:54 +0800 Subject: [PATCH] driver/crypto/ccp: fix vtkm without C-bit when host SME deactivate CSV guests can run without SME enabled. Regardless of the host's SME status, the C-bit must be set for the physical address. Memory will be encrypted with a different key than SME. Signed-off-by: xiongmengbiao --- drivers/crypto/ccp/hygon/vpsp.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccp/hygon/vpsp.c b/drivers/crypto/ccp/hygon/vpsp.c index 10a42df444ce..230d8217abd4 100644 --- a/drivers/crypto/ccp/hygon/vpsp.c +++ b/drivers/crypto/ccp/hygon/vpsp.c @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef pr_fmt #undef pr_fmt @@ -188,13 +189,43 @@ static int kvm_bind_vtkm(uint32_t vm_handle, uint32_t cmd_id, uint32_t vid, uint return ret; } +static unsigned long vpsp_get_me_mask(void) +{ + unsigned int eax, ebx, ecx, edx; + unsigned long me_mask; + +#define AMD_SME_BIT BIT(0) +#define AMD_SEV_BIT BIT(1) + /* + * Check for the SME/SEV feature: + * CPUID Fn8000_001F[EAX] + * - Bit 0 - Secure Memory Encryption support + * - Bit 1 - Secure Encrypted Virtualization support + * CPUID Fn8000_001F[EBX] + * - Bits 5:0 - Pagetable bit position used to indicate encryption + */ + eax = 0x8000001f; + ecx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + /* Check whether SEV or SME is supported */ + if (!(eax & (AMD_SEV_BIT | AMD_SME_BIT))) + return 0; + + me_mask = 1UL << (ebx & 0x3f); + return me_mask; +} + static phys_addr_t gpa_to_hpa(struct kvm_vpsp *vpsp, unsigned long data_gpa) { phys_addr_t hpa = 0; unsigned long pfn = vpsp->gfn_to_pfn(vpsp->kvm, data_gpa >> PAGE_SHIFT); + unsigned long me_mask = sme_get_me_mask(); + + if (me_mask == 0 && vpsp->is_csv_guest) + me_mask = vpsp_get_me_mask(); if (!is_error_pfn(pfn)) - hpa = ((pfn << PAGE_SHIFT) + offset_in_page(data_gpa)) | sme_get_me_mask(); + hpa = ((pfn << PAGE_SHIFT) + offset_in_page(data_gpa)) | me_mask; pr_debug("gpa %lx, hpa %llx\n", data_gpa, hpa); return hpa;