diff options
author | Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | 2014-03-05 19:54:18 -0500 |
---|---|---|
committer | Joerg Roedel <joro@8bytes.org> | 2014-03-24 11:45:59 -0400 |
commit | a919a018cccf999aa56d7f9adeae0525b01b7434 (patch) | |
tree | 2dc30421a1fff7a9bb26d0209aff36ba39a4998d | |
parent | e8d2d82d4a73f37b3270e4fd19ba83e48b589656 (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.c | 4 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 16 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu_types.h | 11 |
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; | |||
150 | bool amd_iommu_np_cache __read_mostly; | 150 | bool amd_iommu_np_cache __read_mostly; |
151 | bool amd_iommu_iotlb_sup __read_mostly = true; | 151 | bool amd_iommu_iotlb_sup __read_mostly = true; |
152 | 152 | ||
153 | u32 amd_iommu_max_pasids __read_mostly = ~0; | 153 | u32 amd_iommu_max_pasid __read_mostly = ~0; |
154 | 154 | ||
155 | bool amd_iommu_v2_present __read_mostly; | 155 | bool amd_iommu_v2_present __read_mostly; |
156 | bool amd_iommu_pc_present __read_mostly; | 156 | bool 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 | */ |
697 | extern u32 amd_iommu_unmap_flush; | 702 | extern 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 */ |
700 | extern u32 amd_iommu_max_pasids; | 705 | extern u32 amd_iommu_max_pasid; |
701 | 706 | ||
702 | extern bool amd_iommu_v2_present; | 707 | extern bool amd_iommu_v2_present; |
703 | 708 | ||