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>
This commit is contained in:
parent
e8d2d82d4a
commit
a919a018cc
|
@ -963,7 +963,7 @@ static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid,
|
||||||
|
|
||||||
address &= ~(0xfffULL);
|
address &= ~(0xfffULL);
|
||||||
|
|
||||||
cmd->data[0] = pasid & PASID_MASK;
|
cmd->data[0] = pasid;
|
||||||
cmd->data[1] = domid;
|
cmd->data[1] = domid;
|
||||||
cmd->data[2] = lower_32_bits(address);
|
cmd->data[2] = lower_32_bits(address);
|
||||||
cmd->data[3] = upper_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;
|
cmd->data[0] = devid;
|
||||||
if (gn) {
|
if (gn) {
|
||||||
cmd->data[1] = pasid & PASID_MASK;
|
cmd->data[1] = pasid;
|
||||||
cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK;
|
cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK;
|
||||||
}
|
}
|
||||||
cmd->data[3] = tag & 0x1ff;
|
cmd->data[3] = tag & 0x1ff;
|
||||||
|
|
|
@ -150,7 +150,7 @@ int amd_iommus_present;
|
||||||
bool amd_iommu_np_cache __read_mostly;
|
bool amd_iommu_np_cache __read_mostly;
|
||||||
bool amd_iommu_iotlb_sup __read_mostly = true;
|
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_v2_present __read_mostly;
|
||||||
bool amd_iommu_pc_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)) {
|
if (iommu_feature(iommu, FEATURE_GT)) {
|
||||||
int glxval;
|
int glxval;
|
||||||
u32 pasids;
|
u32 max_pasid;
|
||||||
u64 shift;
|
u64 pasmax;
|
||||||
|
|
||||||
shift = iommu->features & FEATURE_PASID_MASK;
|
pasmax = iommu->features & FEATURE_PASID_MASK;
|
||||||
shift >>= FEATURE_PASID_SHIFT;
|
pasmax >>= FEATURE_PASID_SHIFT;
|
||||||
pasids = (1 << 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 = iommu->features & FEATURE_GLXVAL_MASK;
|
||||||
glxval >>= FEATURE_GLXVAL_SHIFT;
|
glxval >>= FEATURE_GLXVAL_SHIFT;
|
||||||
|
|
|
@ -98,7 +98,12 @@
|
||||||
#define FEATURE_GLXVAL_SHIFT 14
|
#define FEATURE_GLXVAL_SHIFT 14
|
||||||
#define FEATURE_GLXVAL_MASK (0x03ULL << FEATURE_GLXVAL_SHIFT)
|
#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 */
|
/* MMIO status bits */
|
||||||
#define MMIO_STATUS_EVT_INT_MASK (1 << 1)
|
#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;
|
extern u32 amd_iommu_unmap_flush;
|
||||||
|
|
||||||
/* Smallest number of PASIDs supported by any IOMMU in the system */
|
/* Smallest max PASID supported by any IOMMU in the system */
|
||||||
extern u32 amd_iommu_max_pasids;
|
extern u32 amd_iommu_max_pasid;
|
||||||
|
|
||||||
extern bool amd_iommu_v2_present;
|
extern bool amd_iommu_v2_present;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue