Messages in this thread | | | From | "Liu, Yi L" <> | Subject | RE: [PATCH v4 04/12] iommu/vt-d: Add 256-bit invalidation descriptor support | Date | Wed, 7 Nov 2018 06:07:07 +0000 |
| |
Hi Baolu,
> From: Lu Baolu [mailto:baolu.lu@linux.intel.com] > Sent: Monday, November 5, 2018 1:32 PM
[...]
> --- > drivers/iommu/dmar.c | 83 +++++++++++++++++++---------- > drivers/iommu/intel-svm.c | 76 ++++++++++++++++---------- > drivers/iommu/intel_irq_remapping.c | 6 ++- > include/linux/intel-iommu.h | 9 +++- > 4 files changed, 115 insertions(+), 59 deletions(-) > > diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c > index d9c748b6f9e4..ec10427b98ac 100644 > --- a/drivers/iommu/dmar.c > +++ b/drivers/iommu/dmar.c > @@ -1160,6 +1160,7 @@ static int qi_check_fault(struct intel_iommu *iommu, int > index) > int head, tail; > struct q_inval *qi = iommu->qi; > int wait_index = (index + 1) % QI_LENGTH; > + int shift = qi_shift(iommu); > > if (qi->desc_status[wait_index] == QI_ABORT) > return -EAGAIN; > @@ -1173,13 +1174,15 @@ static int qi_check_fault(struct intel_iommu *iommu, > int index) > */ > if (fault & DMA_FSTS_IQE) { > head = readl(iommu->reg + DMAR_IQH_REG); > - if ((head >> DMAR_IQ_SHIFT) == index) { > + if ((head >> shift) == index) { > + struct qi_desc *desc = qi->desc + head; > + > pr_err("VT-d detected invalid descriptor: " > "low=%llx, high=%llx\n", > - (unsigned long long)qi->desc[index].low, > - (unsigned long long)qi->desc[index].high); > - memcpy(&qi->desc[index], &qi->desc[wait_index], > - sizeof(struct qi_desc)); > + (unsigned long long)desc->qw0, > + (unsigned long long)desc->qw1);
Still missing qw2 and qw3. May make the print differ based on if smts is configed.
> + memcpy(desc, qi->desc + (wait_index << shift),
Would "memcpy(desc, (unsigned long long) (qi->desc + (wait_index << shift)," be more safe?
> + 1 << shift); > writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG); > return -EINVAL; > } > @@ -1191,10 +1194,10 @@ static int qi_check_fault(struct intel_iommu *iommu, > int index) > */ > if (fault & DMA_FSTS_ITE) { > head = readl(iommu->reg + DMAR_IQH_REG); > - head = ((head >> DMAR_IQ_SHIFT) - 1 + QI_LENGTH) % QI_LENGTH; > + head = ((head >> shift) - 1 + QI_LENGTH) % QI_LENGTH; > head |= 1; > tail = readl(iommu->reg + DMAR_IQT_REG); > - tail = ((tail >> DMAR_IQ_SHIFT) - 1 + QI_LENGTH) % QI_LENGTH; > + tail = ((tail >> shift) - 1 + QI_LENGTH) % QI_LENGTH; > > writel(DMA_FSTS_ITE, iommu->reg + DMAR_FSTS_REG); > > @@ -1222,15 +1225,14 @@ int qi_submit_sync(struct qi_desc *desc, struct > intel_iommu *iommu) > { > int rc; > struct q_inval *qi = iommu->qi; > - struct qi_desc *hw, wait_desc; > + int offset, shift, length; > + struct qi_desc wait_desc; > int wait_index, index; > unsigned long flags; > > if (!qi) > return 0; > > - hw = qi->desc; > - > restart: > rc = 0; > > @@ -1243,16 +1245,21 @@ int qi_submit_sync(struct qi_desc *desc, struct > intel_iommu *iommu) > > index = qi->free_head; > wait_index = (index + 1) % QI_LENGTH; > + shift = qi_shift(iommu); > + length = 1 << shift; > > qi->desc_status[index] = qi->desc_status[wait_index] = QI_IN_USE; > > - hw[index] = *desc; > - > - wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) | > + offset = index << shift; > + memcpy(qi->desc + offset, desc, length); > + wait_desc.qw0 = QI_IWD_STATUS_DATA(QI_DONE) | > QI_IWD_STATUS_WRITE | QI_IWD_TYPE; > - wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); > + wait_desc.qw1 = virt_to_phys(&qi->desc_status[wait_index]); > + wait_desc.qw2 = 0; > + wait_desc.qw3 = 0; > > - hw[wait_index] = wait_desc; > + offset = wait_index << shift; > + memcpy(qi->desc + offset, &wait_desc, length);
same question with above one.
Thanks, Yi Liu
| |