mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-21 23:16:50 +08:00
Merge tag 'iommu-fixes-v7.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux
Pull iommu fixes from Joerg Roedel:
"Intel VT-d:
- Abort all pending requests on dev_tlb_inv timeout to avoid
hardlockup
- Limit IOPF handling to PRI-capable device to avoid SVA attach
failure
AMD-Vi:
- Make sure identity domain is not used when SNP is active
Core fixes:
- Handle mapping IOVA 0x0 correctly
- Fix crash in SVA code
- Kernel-doc fix in IO-PGTable code"
* tag 'iommu-fixes-v7.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux:
iommu/amd: Block identity domain when SNP enabled
iommu/sva: Fix crash in iommu_sva_unbind_device()
iommu/io-pgtable: fix all kernel-doc warnings in io-pgtable.h
iommu: Fix mapping check for 0x0 to avoid re-mapping it
iommu/vt-d: Only handle IOPF for SVA when PRI is supported
iommu/vt-d: Fix intel iommu iotlb sync hardlockup and retry
This commit is contained in:
@@ -2909,8 +2909,21 @@ static struct iommu_domain blocked_domain = {
|
||||
|
||||
static struct protection_domain identity_domain;
|
||||
|
||||
static int amd_iommu_identity_attach(struct iommu_domain *dom, struct device *dev,
|
||||
struct iommu_domain *old)
|
||||
{
|
||||
/*
|
||||
* Don't allow attaching a device to the identity domain if SNP is
|
||||
* enabled.
|
||||
*/
|
||||
if (amd_iommu_snp_en)
|
||||
return -EINVAL;
|
||||
|
||||
return amd_iommu_attach_device(dom, dev, old);
|
||||
}
|
||||
|
||||
static const struct iommu_domain_ops identity_domain_ops = {
|
||||
.attach_dev = amd_iommu_attach_device,
|
||||
.attach_dev = amd_iommu_identity_attach,
|
||||
};
|
||||
|
||||
void amd_iommu_init_identity_domain(void)
|
||||
|
||||
@@ -1314,7 +1314,6 @@ static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
|
||||
if (fault & DMA_FSTS_ITE) {
|
||||
head = readl(iommu->reg + DMAR_IQH_REG);
|
||||
head = ((head >> shift) - 1 + QI_LENGTH) % QI_LENGTH;
|
||||
head |= 1;
|
||||
tail = readl(iommu->reg + DMAR_IQT_REG);
|
||||
tail = ((tail >> shift) - 1 + QI_LENGTH) % QI_LENGTH;
|
||||
|
||||
@@ -1331,7 +1330,7 @@ static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
|
||||
do {
|
||||
if (qi->desc_status[head] == QI_IN_USE)
|
||||
qi->desc_status[head] = QI_ABORT;
|
||||
head = (head - 2 + QI_LENGTH) % QI_LENGTH;
|
||||
head = (head - 1 + QI_LENGTH) % QI_LENGTH;
|
||||
} while (head != tail);
|
||||
|
||||
/*
|
||||
|
||||
@@ -164,9 +164,12 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
|
||||
if (IS_ERR(dev_pasid))
|
||||
return PTR_ERR(dev_pasid);
|
||||
|
||||
ret = iopf_for_domain_replace(domain, old, dev);
|
||||
if (ret)
|
||||
goto out_remove_dev_pasid;
|
||||
/* SVA with non-IOMMU/PRI IOPF handling is allowed. */
|
||||
if (info->pri_supported) {
|
||||
ret = iopf_for_domain_replace(domain, old, dev);
|
||||
if (ret)
|
||||
goto out_remove_dev_pasid;
|
||||
}
|
||||
|
||||
/* Setup the pasid table: */
|
||||
sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0;
|
||||
@@ -181,7 +184,8 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
|
||||
|
||||
return 0;
|
||||
out_unwind_iopf:
|
||||
iopf_for_domain_replace(old, domain, dev);
|
||||
if (info->pri_supported)
|
||||
iopf_for_domain_replace(old, domain, dev);
|
||||
out_remove_dev_pasid:
|
||||
domain_remove_dev_pasid(domain, dev, pasid);
|
||||
return ret;
|
||||
|
||||
@@ -182,13 +182,13 @@ void iommu_sva_unbind_device(struct iommu_sva *handle)
|
||||
iommu_detach_device_pasid(domain, dev, iommu_mm->pasid);
|
||||
if (--domain->users == 0) {
|
||||
list_del(&domain->next);
|
||||
iommu_domain_free(domain);
|
||||
}
|
||||
if (list_empty(&iommu_mm->sva_domains)) {
|
||||
list_del(&iommu_mm->mm_list_elm);
|
||||
if (list_empty(&iommu_sva_mms))
|
||||
iommu_sva_present = false;
|
||||
}
|
||||
|
||||
if (list_empty(&iommu_mm->sva_domains)) {
|
||||
list_del(&iommu_mm->mm_list_elm);
|
||||
if (list_empty(&iommu_sva_mms))
|
||||
iommu_sva_present = false;
|
||||
iommu_domain_free(domain);
|
||||
}
|
||||
|
||||
mutex_unlock(&iommu_sva_lock);
|
||||
|
||||
@@ -1213,7 +1213,11 @@ static int iommu_create_device_direct_mappings(struct iommu_domain *domain,
|
||||
if (addr == end)
|
||||
goto map_end;
|
||||
|
||||
phys_addr = iommu_iova_to_phys(domain, addr);
|
||||
/*
|
||||
* Return address by iommu_iova_to_phys for 0 is
|
||||
* ambiguous. Offset to address 1 if addr is 0.
|
||||
*/
|
||||
phys_addr = iommu_iova_to_phys(domain, addr ? addr : 1);
|
||||
if (!phys_addr) {
|
||||
map_size += pg_size;
|
||||
continue;
|
||||
|
||||
@@ -53,7 +53,7 @@ struct iommu_flush_ops {
|
||||
* tables.
|
||||
* @ias: Input address (iova) size, in bits.
|
||||
* @oas: Output address (paddr) size, in bits.
|
||||
* @coherent_walk A flag to indicate whether or not page table walks made
|
||||
* @coherent_walk: A flag to indicate whether or not page table walks made
|
||||
* by the IOMMU are coherent with the CPU caches.
|
||||
* @tlb: TLB management callbacks for this set of tables.
|
||||
* @iommu_dev: The device representing the DMA configuration for the
|
||||
@@ -136,6 +136,7 @@ struct io_pgtable_cfg {
|
||||
void (*free)(void *cookie, void *pages, size_t size);
|
||||
|
||||
/* Low-level data specific to the table format */
|
||||
/* private: */
|
||||
union {
|
||||
struct {
|
||||
u64 ttbr;
|
||||
@@ -203,6 +204,9 @@ struct arm_lpae_io_pgtable_walk_data {
|
||||
* @unmap_pages: Unmap a range of virtually contiguous pages of the same size.
|
||||
* @iova_to_phys: Translate iova to physical address.
|
||||
* @pgtable_walk: (optional) Perform a page table walk for a given iova.
|
||||
* @read_and_clear_dirty: Record dirty info per IOVA. If an IOVA is dirty,
|
||||
* clear its dirty state from the PTE unless the
|
||||
* IOMMU_DIRTY_NO_CLEAR flag is passed in.
|
||||
*
|
||||
* These functions map directly onto the iommu_ops member functions with
|
||||
* the same names.
|
||||
@@ -231,7 +235,9 @@ struct io_pgtable_ops {
|
||||
* the configuration actually provided by the allocator (e.g. the
|
||||
* pgsize_bitmap may be restricted).
|
||||
* @cookie: An opaque token provided by the IOMMU driver and passed back to
|
||||
* the callback routines in cfg->tlb.
|
||||
* the callback routines.
|
||||
*
|
||||
* Returns: Pointer to the &struct io_pgtable_ops for this set of page tables.
|
||||
*/
|
||||
struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
|
||||
struct io_pgtable_cfg *cfg,
|
||||
|
||||
Reference in New Issue
Block a user