Merge tag 'x86_seves_for_v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / arch / x86 / mm / mem_encrypt_identity.c
index 6c5eb6f3f14f40f9002e2afde0ebbccee1237e75..a19374d2610132ee94d78ee5f675d7004236aaa0 100644 (file)
@@ -503,14 +503,10 @@ void __init sme_enable(struct boot_params *bp)
 
 #define AMD_SME_BIT    BIT(0)
 #define AMD_SEV_BIT    BIT(1)
-       /*
-        * Set the feature mask (SME or SEV) based on whether we are
-        * running under a hypervisor.
-        */
-       eax = 1;
-       ecx = 0;
-       native_cpuid(&eax, &ebx, &ecx, &edx);
-       feature_mask = (ecx & BIT(31)) ? AMD_SEV_BIT : AMD_SME_BIT;
+
+       /* Check the SEV MSR whether SEV or SME is enabled */
+       sev_status   = __rdmsr(MSR_AMD64_SEV);
+       feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
 
        /*
         * Check for the SME/SEV feature:
@@ -530,19 +526,26 @@ void __init sme_enable(struct boot_params *bp)
 
        /* Check if memory encryption is enabled */
        if (feature_mask == AMD_SME_BIT) {
+               /*
+                * No SME if Hypervisor bit is set. This check is here to
+                * prevent a guest from trying to enable SME. For running as a
+                * KVM guest the MSR_K8_SYSCFG will be sufficient, but there
+                * might be other hypervisors which emulate that MSR as non-zero
+                * or even pass it through to the guest.
+                * A malicious hypervisor can still trick a guest into this
+                * path, but there is no way to protect against that.
+                */
+               eax = 1;
+               ecx = 0;
+               native_cpuid(&eax, &ebx, &ecx, &edx);
+               if (ecx & BIT(31))
+                       return;
+
                /* For SME, check the SYSCFG MSR */
                msr = __rdmsr(MSR_K8_SYSCFG);
                if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT))
                        return;
        } else {
-               /* For SEV, check the SEV MSR */
-               msr = __rdmsr(MSR_AMD64_SEV);
-               if (!(msr & MSR_AMD64_SEV_ENABLED))
-                       return;
-
-               /* Save SEV_STATUS to avoid reading MSR again */
-               sev_status = msr;
-
                /* SEV state cannot be controlled by a command line option */
                sme_me_mask = me_mask;
                sev_enabled = true;