Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/vt-d: Use INVALID response code instead of FAILURE

The VT-d IOMMU response RESPONSE_FAILURE for a page request in below
cases:

- When it gets a Page_Request with no PASID;
- When it gets a Page_Request with PASID that is not in use for this
device.

This is allowed by the spec, but IOMMU driver doesn't support such cases
today. When the device receives RESPONSE_FAILURE, it sends the device
state machine to HALT state. Now if we try to unload the driver, it hangs
since the device doesn't send any outbound transactions to host when the
driver is trying to clear things up. The only possible responses would be
for invalidation requests.

Let's use RESPONSE_INVALID instead for now, so that the device state
machine doesn't enter HALT state.

Suggested-by: Ashok Raj <ashok.raj@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20210126080730.2232859-3-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>

authored by

Lu Baolu and committed by
Joerg Roedel
3aa7c62c 28a77185

+1 -4
+1 -4
drivers/iommu/intel/svm.c
··· 911 911 u64 address; 912 912 913 913 handled = 1; 914 - 915 914 req = &iommu->prq[head / sizeof(*req)]; 916 - 917 - result = QI_RESP_FAILURE; 915 + result = QI_RESP_INVALID; 918 916 address = (u64)req->addr << VTD_PAGE_SHIFT; 919 917 if (!req->pasid_present) { 920 918 pr_err("%s: Page request without PASID: %08llx %08llx\n", ··· 950 952 rcu_read_unlock(); 951 953 } 952 954 953 - result = QI_RESP_INVALID; 954 955 /* Since we're using init_mm.pgd directly, we should never take 955 956 * any faults on kernel addresses. */ 956 957 if (!svm->mm)