Merge tag 'x86-apic-2023-04-24' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-block.git] / arch / x86 / coco / core.c
index 684f0a910475cf6622bb32535ba47cd9d59f80be..73f83233d25df8481b322456039b49b0f108699f 100644 (file)
@@ -29,6 +29,22 @@ static bool intel_cc_platform_has(enum cc_attr attr)
        }
 }
 
+/*
+ * Handle the SEV-SNP vTOM case where sme_me_mask is zero, and
+ * the other levels of SME/SEV functionality, including C-bit
+ * based SEV-SNP, are not enabled.
+ */
+static __maybe_unused bool amd_cc_platform_vtom(enum cc_attr attr)
+{
+       switch (attr) {
+       case CC_ATTR_GUEST_MEM_ENCRYPT:
+       case CC_ATTR_MEM_ENCRYPT:
+               return true;
+       default:
+               return false;
+       }
+}
+
 /*
  * SME and SEV are very similar but they are not the same, so there are
  * times that the kernel will need to distinguish between SME and SEV. The
@@ -41,9 +57,14 @@ static bool intel_cc_platform_has(enum cc_attr attr)
  * up under SME the trampoline area cannot be encrypted, whereas under SEV
  * the trampoline area must be encrypted.
  */
+
 static bool amd_cc_platform_has(enum cc_attr attr)
 {
 #ifdef CONFIG_AMD_MEM_ENCRYPT
+
+       if (sev_status & MSR_AMD64_SNP_VTOM)
+               return amd_cc_platform_vtom(attr);
+
        switch (attr) {
        case CC_ATTR_MEM_ENCRYPT:
                return sme_me_mask;
@@ -76,11 +97,6 @@ static bool amd_cc_platform_has(enum cc_attr attr)
 #endif
 }
 
-static bool hyperv_cc_platform_has(enum cc_attr attr)
-{
-       return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
-}
-
 bool cc_platform_has(enum cc_attr attr)
 {
        switch (cc_vendor) {
@@ -88,8 +104,6 @@ bool cc_platform_has(enum cc_attr attr)
                return amd_cc_platform_has(attr);
        case CC_VENDOR_INTEL:
                return intel_cc_platform_has(attr);
-       case CC_VENDOR_HYPERV:
-               return hyperv_cc_platform_has(attr);
        default:
                return false;
        }
@@ -103,11 +117,14 @@ u64 cc_mkenc(u64 val)
         * encryption status of the page.
         *
         * - for AMD, bit *set* means the page is encrypted
-        * - for Intel *clear* means encrypted.
+        * - for AMD with vTOM and for Intel, *clear* means encrypted
         */
        switch (cc_vendor) {
        case CC_VENDOR_AMD:
-               return val | cc_mask;
+               if (sev_status & MSR_AMD64_SNP_VTOM)
+                       return val & ~cc_mask;
+               else
+                       return val | cc_mask;
        case CC_VENDOR_INTEL:
                return val & ~cc_mask;
        default:
@@ -120,7 +137,10 @@ u64 cc_mkdec(u64 val)
        /* See comment in cc_mkenc() */
        switch (cc_vendor) {
        case CC_VENDOR_AMD:
-               return val & ~cc_mask;
+               if (sev_status & MSR_AMD64_SNP_VTOM)
+                       return val | cc_mask;
+               else
+                       return val & ~cc_mask;
        case CC_VENDOR_INTEL:
                return val | cc_mask;
        default: