]> Git Repo - linux.git/commitdiff
iommu/amd: Re-purpose Exclusion range registers to support SNP CWWB
authorSuravee Suthikulpanit <[email protected]>
Wed, 23 Sep 2020 12:13:47 +0000 (12:13 +0000)
committerJoerg Roedel <[email protected]>
Thu, 24 Sep 2020 10:46:54 +0000 (12:46 +0200)
When the IOMMU SNP support bit is set in the IOMMU Extended Features
register, hardware re-purposes the following registers:

1. IOMMU Exclusion Base register (MMIO offset 0020h) to
   Completion Wait Write-Back (CWWB) Base register

2. IOMMU Exclusion Range Limit (MMIO offset 0028h) to
   Completion Wait Write-Back (CWWB) Range Limit register

and requires the IOMMU CWWB semaphore base and range to be programmed
in the register offset 0020h and 0028h accordingly.

Signed-off-by: Suravee Suthikulpanit <[email protected]>
Cc: Brijesh Singh <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Joerg Roedel <[email protected]>
drivers/iommu/amd/amd_iommu_types.h
drivers/iommu/amd/init.c

index 1e7966c73707667c1c1383e5f530cd6d97996a36..f696ac7c5f8931251dd0c052ddff26278d250c7e 100644 (file)
@@ -93,6 +93,7 @@
 #define FEATURE_PC             (1ULL<<9)
 #define FEATURE_GAM_VAPIC      (1ULL<<21)
 #define FEATURE_EPHSUP         (1ULL<<50)
+#define FEATURE_SNP            (1ULL<<63)
 
 #define FEATURE_PASID_SHIFT    32
 #define FEATURE_PASID_MASK     (0x1fULL << FEATURE_PASID_SHIFT)
index 35f220704bef377fdaca9dc475b5fc9062bdfcea..662b01eaf0f23d88ffc7e03e3cb0bdb55de9c187 100644 (file)
@@ -359,6 +359,29 @@ static void iommu_set_exclusion_range(struct amd_iommu *iommu)
                        &entry, sizeof(entry));
 }
 
+static void iommu_set_cwwb_range(struct amd_iommu *iommu)
+{
+       u64 start = iommu_virt_to_phys((void *)iommu->cmd_sem);
+       u64 entry = start & PM_ADDR_MASK;
+
+       if (!iommu_feature(iommu, FEATURE_SNP))
+               return;
+
+       /* Note:
+        * Re-purpose Exclusion base/limit registers for Completion wait
+        * write-back base/limit.
+        */
+       memcpy_toio(iommu->mmio_base + MMIO_EXCL_BASE_OFFSET,
+                   &entry, sizeof(entry));
+
+       /* Note:
+        * Default to 4 Kbytes, which can be specified by setting base
+        * address equal to the limit address.
+        */
+       memcpy_toio(iommu->mmio_base + MMIO_EXCL_LIMIT_OFFSET,
+                   &entry, sizeof(entry));
+}
+
 /* Programs the physical address of the device table into the IOMMU hardware */
 static void iommu_set_device_table(struct amd_iommu *iommu)
 {
@@ -1884,6 +1907,9 @@ static int __init amd_iommu_init_pci(void)
                ret = iommu_init_pci(iommu);
                if (ret)
                        break;
+
+               /* Need to setup range after PCI init */
+               iommu_set_cwwb_range(iommu);
        }
 
        /*
This page took 0.068204 seconds and 4 git commands to generate.