Re: [PATCH v4 04/12] iommu/vt-d: Add 256-bit invalidation descriptor support

From: Lu Baolu
Date: Thu Nov 08 2018 - 00:27:40 EST


Hi,

On 11/8/18 11:49 AM, Liu, Yi L wrote:
Hi,

From: Lu Baolu [mailto:baolu.lu@xxxxxxxxxxxxxxx]
Sent: Thursday, November 8, 2018 10:17 AM
Subject: Re: [PATCH v4 04/12] iommu/vt-d: Add 256-bit invalidation descriptor
support

Hi Yi,

On 11/7/18 2:07 PM, Liu, Yi L wrote:
Hi Baolu,

From: Lu Baolu [mailto:baolu.lu@xxxxxxxxxxxxxxx]
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.

qw2 and qw3 are reserved from software point of view. We don't need to print it for
information.

But for Scalable mode, it should be valid?

No. It's reserved for software.




+ memcpy(desc, qi->desc + (wait_index << shift),

Would "memcpy(desc, (unsigned long long) (qi->desc + (wait_index <<
shift)," be more safe?

Can that be compiled? memcpy() requires a "const void *" for the second parameter.
By the way, why it's safer with this casting?

This is just an example. My point is the possibility that "qi->desc + (wait_index << shift)"
would be treated as "qi->desc plus (wait_index << shift)*sizeof(*qi->desc)". Is it possible
for kernel build?

qi->desc is of type of "void *".

Best regards,
Lu Baolu