iommu/amd: Fix logic to determine and checking max PASID
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Thu, 6 Mar 2014 00:54:18 +0000 (18:54 -0600)
committerJoerg Roedel <joro@8bytes.org>
Mon, 24 Mar 2014 15:45:59 +0000 (16:45 +0100)
In reality, the spec can only support 16-bit PASID since
INVALIDATE_IOTLB_PAGES and COMPLETE_PPR_REQUEST commands only allow 16-bit
PASID. So, we updated the PASID_MASK accordingly and invoke BUG_ON
if the hardware is reporting PASmax more than 16-bit.

Besides, max PASID is defined as ((2^(PASmax+1)) - 1). The current does not
determine this correctly.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Tested-by: Jay Cornwall <Jay.Cornwall@amd.com>
Signed-off-by: Joerg Roedel <joro@8bytes.org>
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_types.h

index 1dd9f818fc84403f868620c71c1b81f6d0e06222..c949520bd196ec47cf6e572e68cdd67c11b9f84f 100644 (file)
@@ -963,7 +963,7 @@ static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid,
 
        address &= ~(0xfffULL);
 
-       cmd->data[0]  = pasid & PASID_MASK;
+       cmd->data[0]  = pasid;
        cmd->data[1]  = domid;
        cmd->data[2]  = lower_32_bits(address);
        cmd->data[3]  = upper_32_bits(address);
@@ -1001,7 +1001,7 @@ static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid,
 
        cmd->data[0]  = devid;
        if (gn) {
-               cmd->data[1]  = pasid & PASID_MASK;
+               cmd->data[1]  = pasid;
                cmd->data[2]  = CMD_INV_IOMMU_PAGES_GN_MASK;
        }
        cmd->data[3]  = tag & 0x1ff;
index 28b4bea7c1094d79a483ee5256c21a91d3829396..b76c58dbe30ce5ac38c8422b66b5ed2ea4f0fb1e 100644 (file)
@@ -150,7 +150,7 @@ int amd_iommus_present;
 bool amd_iommu_np_cache __read_mostly;
 bool amd_iommu_iotlb_sup __read_mostly = true;
 
-u32 amd_iommu_max_pasids __read_mostly = ~0;
+u32 amd_iommu_max_pasid __read_mostly = ~0;
 
 bool amd_iommu_v2_present __read_mostly;
 bool amd_iommu_pc_present __read_mostly;
@@ -1231,14 +1231,16 @@ static int iommu_init_pci(struct amd_iommu *iommu)
 
        if (iommu_feature(iommu, FEATURE_GT)) {
                int glxval;
-               u32 pasids;
-               u64 shift;
+               u32 max_pasid;
+               u64 pasmax;
 
-               shift   = iommu->features & FEATURE_PASID_MASK;
-               shift >>= FEATURE_PASID_SHIFT;
-               pasids  = (1 << shift);
+               pasmax = iommu->features & FEATURE_PASID_MASK;
+               pasmax >>= FEATURE_PASID_SHIFT;
+               max_pasid  = (1 << (pasmax + 1)) - 1;
 
-               amd_iommu_max_pasids = min(amd_iommu_max_pasids, pasids);
+               amd_iommu_max_pasid = min(amd_iommu_max_pasid, max_pasid);
+
+               BUG_ON(amd_iommu_max_pasid & ~PASID_MASK);
 
                glxval   = iommu->features & FEATURE_GLXVAL_MASK;
                glxval >>= FEATURE_GLXVAL_SHIFT;
index e400fbe411dead310bada51fb74d1475eab55bd0..55ba46bdb01bfcabc0c04834e3955d7ce191013b 100644 (file)
 #define FEATURE_GLXVAL_SHIFT   14
 #define FEATURE_GLXVAL_MASK    (0x03ULL << FEATURE_GLXVAL_SHIFT)
 
-#define PASID_MASK             0x000fffff
+/* Note:
+ * The current driver only support 16-bit PASID.
+ * Currently, hardware only implement upto 16-bit PASID
+ * even though the spec says it could have upto 20 bits.
+ */
+#define PASID_MASK             0x0000ffff
 
 /* MMIO status bits */
 #define MMIO_STATUS_EVT_INT_MASK       (1 << 1)
@@ -696,8 +701,8 @@ extern unsigned long *amd_iommu_pd_alloc_bitmap;
  */
 extern u32 amd_iommu_unmap_flush;
 
-/* Smallest number of PASIDs supported by any IOMMU in the system */
-extern u32 amd_iommu_max_pasids;
+/* Smallest max PASID supported by any IOMMU in the system */
+extern u32 amd_iommu_max_pasid;
 
 extern bool amd_iommu_v2_present;