From: Lu Baolu baolu.lu@linux.intel.com
[ Upstream commit 4402e8f39d0bfff5c0a5edb5e1afe27a56545e11 ]
Bit 66 in the page group response descriptor used to be the LPIG (Last Page in Group), but it was marked as Reserved since Specification 4.0. Remove programming on this bit to make it consistent with the latest specification.
Existing hardware all treats bit 66 of the page group response descriptor as "ignored", therefore this change doesn't break any existing hardware.
Signed-off-by: Lu Baolu baolu.lu@linux.intel.com Link: https://lore.kernel.org/r/20250901053943.1708490-1-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel joerg.roedel@amd.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES - VT-d responses no longer program bit 66 (`QI_PGRP_LPIG`), which the Intel spec has marked reserved since 4.0; both the macro removal in `drivers/iommu/intel/iommu.h:455-463` and the descriptor writes in `drivers/iommu/intel/prq.c:149-155` and `drivers/iommu/intel/prq.c:372-395` now guarantee the reserved bit is left zero. That brings the driver back into spec compliance and avoids undefined behaviour on newer hardware that enforces the “reserved must be zero” rule for page-request responses. - Without this change the kernel still reflected `req->lpig` into the response descriptor (`drivers/iommu/intel/prq.c:149-155`, `372-395` before the patch), so a “last-page” response would carry a ‘1’ in a field the spec now forbids. VT-d PRQ handshakes are sensitive: if the IOMMU rejects the response, devices stall waiting for completion, so this is a real bug for any implementation following the latest spec. Existing hardware already ignores the bit, so clearing it cannot regress older systems. - The fix is tightly scoped to the Intel VT-d page-request path, keeps the driver’s outward behaviour (e.g. still reporting `IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE` to device drivers at `drivers/iommu/intel/prq.c:187-194`), and has no dependencies beyond trivial code motion. Backporting simply drops the `QI_PGRP_LPIG()` usage in the equivalent response paths (older stable trees have the same logic in `svm.c`), so the risk of regression is minimal while the upside is support for spec-compliant hardware.
drivers/iommu/intel/iommu.h | 1 - drivers/iommu/intel/prq.c | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 2c261c069001c..21b2c3f85ddc5 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -462,7 +462,6 @@ enum { #define QI_PGRP_PASID(pasid) (((u64)(pasid)) << 32)
/* Page group response descriptor QW1 */ -#define QI_PGRP_LPIG(x) (((u64)(x)) << 2) #define QI_PGRP_IDX(idx) (((u64)(idx)) << 3)
diff --git a/drivers/iommu/intel/prq.c b/drivers/iommu/intel/prq.c index 52570e42a14c0..ff63c228e6e19 100644 --- a/drivers/iommu/intel/prq.c +++ b/drivers/iommu/intel/prq.c @@ -151,8 +151,7 @@ static void handle_bad_prq_event(struct intel_iommu *iommu, QI_PGRP_PASID_P(req->pasid_present) | QI_PGRP_RESP_CODE(result) | QI_PGRP_RESP_TYPE; - desc.qw1 = QI_PGRP_IDX(req->prg_index) | - QI_PGRP_LPIG(req->lpig); + desc.qw1 = QI_PGRP_IDX(req->prg_index);
qi_submit_sync(iommu, &desc, 1, 0); } @@ -379,19 +378,17 @@ void intel_iommu_page_response(struct device *dev, struct iopf_fault *evt, struct iommu_fault_page_request *prm; struct qi_desc desc; bool pasid_present; - bool last_page; u16 sid;
prm = &evt->fault.prm; sid = PCI_DEVID(bus, devfn); pasid_present = prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID; - last_page = prm->flags & IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE;
desc.qw0 = QI_PGRP_PASID(prm->pasid) | QI_PGRP_DID(sid) | QI_PGRP_PASID_P(pasid_present) | QI_PGRP_RESP_CODE(msg->code) | QI_PGRP_RESP_TYPE; - desc.qw1 = QI_PGRP_IDX(prm->grpid) | QI_PGRP_LPIG(last_page); + desc.qw1 = QI_PGRP_IDX(prm->grpid); desc.qw2 = 0; desc.qw3 = 0;