aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2014-03-05 19:54:18 -0500
committerJoerg Roedel <joro@8bytes.org>2014-03-24 11:45:59 -0400
commita919a018cccf999aa56d7f9adeae0525b01b7434 (patch)
tree2dc30421a1fff7a9bb26d0209aff36ba39a4998d
parente8d2d82d4a73f37b3270e4fd19ba83e48b589656 (diff)
iommu/amd: Fix logic to determine and checking max PASID
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>
-rw-r--r--drivers/iommu/amd_iommu.c4
-rw-r--r--drivers/iommu/amd_iommu_init.c16
-rw-r--r--drivers/iommu/amd_iommu_types.h11
3 files changed, 19 insertions, 12 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 1dd9f818fc84..c949520bd196 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -963,7 +963,7 @@ static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid,
963 963
964 address &= ~(0xfffULL); 964 address &= ~(0xfffULL);
965 965
966 cmd->data[0] = pasid & PASID_MASK; 966 cmd->data[0] = pasid;
967 cmd->data[1] = domid; 967 cmd->data[1] = domid;
968 cmd->data[2] = lower_32_bits(address); 968 cmd->data[2] = lower_32_bits(address);
969 cmd->data[3] = upper_32_bits(address); 969 cmd->data[3] = upper_32_bits(address);
@@ -1001,7 +1001,7 @@ static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid,
1001 1001
1002 cmd->data[0] = devid; 1002 cmd->data[0] = devid;
1003 if (gn) { 1003 if (gn) {
1004 cmd->data[1] = pasid & PASID_MASK; 1004 cmd->data[1] = pasid;
1005 cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK; 1005 cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK;
1006 } 1006 }
1007 cmd->data[3] = tag & 0x1ff; 1007 cmd->data[3] = tag & 0x1ff;
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 28b4bea7c109..b76c58dbe30c 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -150,7 +150,7 @@ int amd_iommus_present;
150bool amd_iommu_np_cache __read_mostly; 150bool amd_iommu_np_cache __read_mostly;
151bool amd_iommu_iotlb_sup __read_mostly = true; 151bool amd_iommu_iotlb_sup __read_mostly = true;
152 152
153u32 amd_iommu_max_pasids __read_mostly = ~0; 153u32 amd_iommu_max_pasid __read_mostly = ~0;
154 154
155bool amd_iommu_v2_present __read_mostly; 155bool amd_iommu_v2_present __read_mostly;
156bool amd_iommu_pc_present __read_mostly; 156bool amd_iommu_pc_present __read_mostly;
@@ -1231,14 +1231,16 @@ static int iommu_init_pci(struct amd_iommu *iommu)
1231 1231
1232 if (iommu_feature(iommu, FEATURE_GT)) { 1232 if (iommu_feature(iommu, FEATURE_GT)) {
1233 int glxval; 1233 int glxval;
1234 u32 pasids; 1234 u32 max_pasid;
1235 u64 shift; 1235 u64 pasmax;
1236 1236
1237 shift = iommu->features & FEATURE_PASID_MASK; 1237 pasmax = iommu->features & FEATURE_PASID_MASK;
1238 shift >>= FEATURE_PASID_SHIFT; 1238 pasmax >>= FEATURE_PASID_SHIFT;
1239 pasids = (1 << shift); 1239 max_pasid = (1 << (pasmax + 1)) - 1;
1240 1240
1241 amd_iommu_max_pasids = min(amd_iommu_max_pasids, pasids); 1241 amd_iommu_max_pasid = min(amd_iommu_max_pasid, max_pasid);
1242
1243 BUG_ON(amd_iommu_max_pasid & ~PASID_MASK);
1242 1244
1243 glxval = iommu->features & FEATURE_GLXVAL_MASK; 1245 glxval = iommu->features & FEATURE_GLXVAL_MASK;
1244 glxval >>= FEATURE_GLXVAL_SHIFT; 1246 glxval >>= FEATURE_GLXVAL_SHIFT;
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index e400fbe411de..55ba46bdb01b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,7 +98,12 @@
98#define FEATURE_GLXVAL_SHIFT 14 98#define FEATURE_GLXVAL_SHIFT 14
99#define FEATURE_GLXVAL_MASK (0x03ULL << FEATURE_GLXVAL_SHIFT) 99#define FEATURE_GLXVAL_MASK (0x03ULL << FEATURE_GLXVAL_SHIFT)
100 100
101#define PASID_MASK 0x000fffff 101/* Note:
102 * The current driver only support 16-bit PASID.
103 * Currently, hardware only implement upto 16-bit PASID
104 * even though the spec says it could have upto 20 bits.
105 */
106#define PASID_MASK 0x0000ffff
102 107
103/* MMIO status bits */ 108/* MMIO status bits */
104#define MMIO_STATUS_EVT_INT_MASK (1 << 1) 109#define MMIO_STATUS_EVT_INT_MASK (1 << 1)
@@ -696,8 +701,8 @@ extern unsigned long *amd_iommu_pd_alloc_bitmap;
696 */ 701 */
697extern u32 amd_iommu_unmap_flush; 702extern u32 amd_iommu_unmap_flush;
698 703
699/* Smallest number of PASIDs supported by any IOMMU in the system */ 704/* Smallest max PASID supported by any IOMMU in the system */
700extern u32 amd_iommu_max_pasids; 705extern u32 amd_iommu_max_pasid;
701 706
702extern bool amd_iommu_v2_present; 707extern bool amd_iommu_v2_present;
703 708