/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
to match. That way, we can use 'unsigned long' for PFNs with impunity. */ #define DOMAIN_MAX_PFN(gaw) ((unsignedlong) min_t(uint64_t, \
__DOMAIN_MAX_PFN(gaw), (unsignedlong)-1)) #define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
/* * set to 1 to panic kernel if can't successfully enable VT-d * (used when kernel is launched w/ TXT)
*/ staticint force_on = 0; staticint intel_iommu_tboot_noforce; staticint no_platform_optin;
/* * Take a root_entry and return the Lower Context Table Pointer (LCTP) * if marked present.
*/ static phys_addr_t root_entry_lctp(struct root_entry *re)
{ if (!(re->lo & 1)) return 0;
return re->lo & VTD_PAGE_MASK;
}
/* * Take a root_entry and return the Upper Context Table Pointer (UCTP) * if marked present.
*/ static phys_addr_t root_entry_uctp(struct root_entry *re)
{ if (!(re->hi & 1)) return 0;
/* * Looks up an IOMMU-probed device using its source ID. * * Returns the pointer to the device if there is a match. Otherwise, * returns NULL. * * Note that this helper doesn't guarantee that the device won't be * released by the iommu subsystem after being returned. The caller * should use its own synchronization mechanism to avoid the device * being released during its use if its possibly the case.
*/ struct device *device_rbtree_find(struct intel_iommu *iommu, u16 rid)
{ struct device_domain_info *info = NULL; struct rb_node *node; unsignedlong flags;
spin_lock_irqsave(&iommu->device_rbtree_lock, flags);
node = rb_find(&rid, &iommu->device_rbtree, device_rid_cmp_key); if (node)
info = rb_entry(node, struct device_domain_info, node);
spin_unlock_irqrestore(&iommu->device_rbtree_lock, flags);
/* * Calculate the Supported Adjusted Guest Address Widths of an IOMMU. * Refer to 11.4.2 of the VT-d spec for the encoding of each bit of * the returned SAGAW.
*/ staticunsignedlong __iommu_calculate_sagaw(struct intel_iommu *iommu)
{ unsignedlong fl_sagaw, sl_sagaw;
/* Second level only. */ if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) return sl_sagaw;
/* First level only. */ if (!ecap_slts(iommu->ecap)) return fl_sagaw;
return fl_sagaw & sl_sagaw;
}
staticint __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
{ unsignedlong sagaw; int agaw;
sagaw = __iommu_calculate_sagaw(iommu); for (agaw = width_to_agaw(max_gaw); agaw >= 0; agaw--) { if (test_bit(agaw, &sagaw)) break;
}
return agaw;
}
/* * Calculate max SAGAW for each iommu.
*/ int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
{ return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
}
/* * calculate agaw for each iommu. * "SAGAW" may be different across iommus, use a default agaw, and * get a supported less agaw for iommus that don't support the default agaw.
*/ int iommu_calculate_agaw(struct intel_iommu *iommu)
{ return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
}
/* * Except that the caller requested to allocate a new entry, * returning a copied context entry makes no sense.
*/ if (!alloc && context_copied(iommu, bus, devfn)) return NULL;
entry = &root->lo; if (sm_supported(iommu)) { if (devfn >= 0x80) {
devfn -= 0x80;
entry = &root->hi;
}
devfn *= 2;
} if (*entry & 1)
context = phys_to_virt(*entry & VTD_PAGE_MASK); else { unsignedlong phy_addr; if (!alloc) return NULL;
context = iommu_alloc_pages_node_sz(iommu->node, GFP_ATOMIC,
SZ_4K); if (!context) return NULL;
/* We know that this device on this chipset has its own IOMMU. * If we find it under a different IOMMU, then the BIOS is lying * to us. Hope that the IOMMU for this device is actually * disabled, and it needs no translation...
*/
rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar); if (rc) { /* "can't" happen */
dev_info(&pdev->dev, "failed to run vt-d quirk\n"); returnfalse;
}
vtbar &= 0xffff0000;
/* we know that the this iommu should be at offset 0xa000 from vtbar */
drhd = dmar_find_matched_drhd_unit(pdev); if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); returntrue;
}
/* VFs aren't listed in scope tables; we need to look up
* the PF instead to find the IOMMU. */
pf_pdev = pci_physfn(pdev);
dev = &pf_pdev->dev;
segment = pci_domain_nr(pdev->bus);
} elseif (has_acpi_companion(dev))
dev = &ACPI_COMPANION(dev)->dev;
for_each_active_dev_scope(drhd->devices,
drhd->devices_cnt, i, tmp) { if (tmp == dev) { /* For a VF use its original BDF# not that of the PF * which we used for the IOMMU lookup. Strictly speaking * we could do this for all PCI devices; we only need to
* get the BDF# from the scope table for ACPI matches. */ if (pdev && pdev->is_virtfn) goto got_pdev;
/* get the pointer to the pasid table entry */
entries = get_pasid_table_from_pde(pde); if (!entries) {
pr_info("pasid table is not present\n"); return;
}
index = pasid & PASID_PTE_MASK;
pte = &entries[index]; for (i = 0; i < ARRAY_SIZE(pte->val); i++)
pr_info("pasid table entry[%d]: 0x%016llx\n", i, pte->val[i]);
if (!pasid_pte_is_present(pte)) {
pr_info("scalable mode page table is not present\n"); return;
}
tmp = 0ULL; if (!try_cmpxchg64(&pte->val, &tmp, pteval)) /* Someone else set it while we were thinking; use theirs. */
iommu_free_pages(tmp_page); else
domain_flush_cache(domain, pte, sizeof(*pte));
} if (level == 1) break;
/* return address's pte at specific level */ staticstruct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, unsignedlong pfn, int level, int *large_page)
{ struct dma_pte *parent, *pte; int total = agaw_to_level(domain->agaw); int offset;
/* * Free the page table if we're below the level we want to * retain and the range covers the entire table.
*/ if (level < retain_level && !(start_pfn > level_pfn ||
last_pfn < level_pfn + level_size(level) - 1)) {
dma_clear_pte(pte);
domain_flush_cache(domain, pte, sizeof(*pte));
iommu_free_pages(level_pte);
}
next:
pfn += level_size(level);
} while (!first_pte_in_page(++pte) && pfn <= last_pfn);
}
/* * clear last level (leaf) ptes and free page table pages below the * level we wish to keep intact.
*/ staticvoid dma_pte_free_pagetable(struct dmar_domain *domain, unsignedlong start_pfn, unsignedlong last_pfn, int retain_level)
{
dma_pte_clear_range(domain, start_pfn, last_pfn);
/* We don't need lock here; nobody else touches the iova range */
dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
domain->pgd, 0, start_pfn, last_pfn);
/* When a page at a given level is being unlinked from its parent, we don't need to *modify* it at all. All we need to do is make a list of all the pages which can be freed just as soon as we've flushed the IOTLB and we know the hardware page-walk will no longer touch them. The 'pte' argument is the *parent* PTE, pointing to the page that is to
be freed. */ staticvoid dma_pte_list_pagetables(struct dmar_domain *domain, int level, struct dma_pte *parent_pte, struct iommu_pages_list *freelist)
{ struct dma_pte *pte = phys_to_virt(dma_pte_addr(parent_pte));
iommu_pages_list_add(freelist, pte);
if (level == 1) return;
do { if (dma_pte_present(pte) && !dma_pte_superpage(pte))
dma_pte_list_pagetables(domain, level - 1, pte, freelist);
pte++;
} while (!first_pte_in_page(pte));
}
do { unsignedlong level_pfn = pfn & level_mask(level);
if (!dma_pte_present(pte)) goto next;
/* If range covers entire pagetable, free it */ if (start_pfn <= level_pfn &&
last_pfn >= level_pfn + level_size(level) - 1) { /* These suborbinate page tables are going away entirely. Don't
bother to clear them; we're just going to *free* them. */ if (level > 1 && !dma_pte_superpage(pte))
dma_pte_list_pagetables(domain, level - 1, pte, freelist);
dma_clear_pte(pte); if (!first_pte)
first_pte = pte;
last_pte = pte;
} elseif (level > 1) { /* Recurse down into a level that isn't *entirely* obsolete */
dma_pte_clear_level(domain, level - 1,
phys_to_virt(dma_pte_addr(pte)),
level_pfn, start_pfn, last_pfn,
freelist);
}
next:
pfn = level_pfn + level_size(level);
} while (!first_pte_in_page(++pte) && pfn <= last_pfn);
if (first_pte)
domain_flush_cache(domain, first_pte,
(void *)++last_pte - (void *)first_pte);
}
/* We can't just free the pages because the IOMMU may still be walking the page tables, and may have cached the intermediate levels. The
pages can only be freed after the IOTLB flush has been done. */ staticvoid domain_unmap(struct dmar_domain *domain, unsignedlong start_pfn, unsignedlong last_pfn, struct iommu_pages_list *freelist)
{ if (WARN_ON(!domain_pfn_supported(domain, last_pfn)) ||
WARN_ON(start_pfn > last_pfn)) return;
/* we don't need lock here; nobody else touches the iova range */
dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
domain->pgd, 0, start_pfn, last_pfn, freelist);
/* return value determine if we need a write buffer flush */ staticvoid __iommu_flush_context(struct intel_iommu *iommu,
u16 did, u16 source_id, u8 function_mask,
u64 type)
{
u64 val = 0; unsignedlong flag;
switch (type) { case DMA_CCMD_GLOBAL_INVL:
val = DMA_CCMD_GLOBAL_INVL; break; case DMA_CCMD_DOMAIN_INVL:
val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did); break; case DMA_CCMD_DEVICE_INVL:
val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
| DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask); break; default:
pr_warn("%s: Unexpected context-cache invalidation type 0x%llx\n",
iommu->name, type); return;
}
val |= DMA_CCMD_ICC;
switch (type) { case DMA_TLB_GLOBAL_FLUSH: /* global flush doesn't need set IVA_REG */
val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT; break; case DMA_TLB_DSI_FLUSH:
val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did); break; case DMA_TLB_PSI_FLUSH:
val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did); /* IH bit is passed in as part of address */
val_iva = size_order | addr; break; default:
pr_warn("%s: Unexpected iotlb invalidation type 0x%llx\n",
iommu->name, type); return;
}
if (cap_write_drain(iommu->cap))
val |= DMA_TLB_WRITE_DRAIN;
raw_spin_lock_irqsave(&iommu->register_lock, flag); /* Note: Only uses first TLB reg currently */ if (val_iva)
dmar_writeq(iommu->reg + tlb_offset, val_iva);
dmar_writeq(iommu->reg + tlb_offset + 8, val);
/* Make sure hardware complete it */
IOMMU_WAIT_OP(iommu, tlb_offset + 8,
dmar_readq, (!(val & DMA_TLB_IVT)), val);
/* * The extra devTLB flush quirk impacts those QAT devices with PCI device * IDs ranging from 0x4940 to 0x4943. It is exempted from risky_device() * check because it applies only to the built-in QAT devices and it doesn't * grant additional privileges.
*/ #define BUGGY_QAT_DEVID_MASK 0x4940 staticbool dev_needs_extra_dtlb_flush(struct pci_dev *pdev)
{ if (pdev->vendor != PCI_VENDOR_ID_INTEL) returnfalse;
if ((pdev->device & 0xfffc) != BUGGY_QAT_DEVID_MASK) returnfalse;
staticvoid disable_dmar_iommu(struct intel_iommu *iommu)
{ /* * All iommu domains must have been detached from the devices, * hence there should be no domain IDs in use.
*/ if (WARN_ON(!ida_is_empty(&iommu->domain_ida))) return;
if (iommu->gcmd & DMA_GCMD_TE)
iommu_disable_translation(iommu);
}
if (ecap_prs(iommu->ecap))
intel_iommu_finish_prq(iommu);
}
/* * Check and return whether first level is used by default for * DMA translation.
*/ staticbool first_level_by_default(struct intel_iommu *iommu)
{ /* Only SL is available in legacy mode */ if (!sm_supported(iommu)) returnfalse;
/* Only level (either FL or SL) is available, just use it */ if (ecap_flts(iommu->ecap) ^ ecap_slts(iommu->ecap)) return ecap_flts(iommu->ecap);
returntrue;
}
int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu)
{ struct iommu_domain_info *info, *curr; int num, ret = -ENOSPC;
if (domain->domain.type == IOMMU_DOMAIN_SVA) return 0;
info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM;
if (domain->domain.type == IOMMU_DOMAIN_SVA) return;
guard(mutex)(&iommu->did_lock);
info = xa_load(&domain->iommu_array, iommu->seq_id); if (--info->refcnt == 0) {
ida_free(&iommu->domain_ida, info->did);
xa_erase(&domain->iommu_array, iommu->seq_id);
kfree(info);
}
}
/* * For kdump cases, old valid entries may be cached due to the * in-flight DMA and copied pgtable, but there is no unmapping * behaviour for them, thus we need an explicit cache flush for * the newly-mapped device. For kdump, at this point, the device * is supposed to finish reset at its driver probe stage, so no * in-flight DMA will exist, and we don't need to worry anymore * hereafter.
*/ staticvoid copied_context_tear_down(struct intel_iommu *iommu, struct context_entry *context,
u8 bus, u8 devfn)
{
u16 did_old;
/* * It's a non-present to present mapping. If hardware doesn't cache * non-present entry we only need to flush the write-buffer. If the * _does_ cache non-present entries, then it does so in the special * domain #0, which we have to flush:
*/ staticvoid context_present_cache_flush(struct intel_iommu *iommu, u16 did,
u8 bus, u8 devfn)
{ if (cap_caching_mode(iommu->cap)) {
iommu->flush.flush_context(iommu, 0,
PCI_DEVID(bus, devfn),
DMA_CCMD_MASK_NOBIT,
DMA_CCMD_DEVICE_INVL);
iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
} else {
iommu_flush_write_buffer(iommu);
}
}
if (!dev_is_pci(dev)) return domain_context_mapping_one(domain, iommu, bus, devfn);
ret = pci_for_each_dma_alias(to_pci_dev(dev),
domain_context_mapping_cb, domain); if (ret) return ret;
iommu_enable_pci_ats(info);
return 0;
}
/* Return largest possible superpage level for a given mapping */ staticint hardware_largepage_caps(struct dmar_domain *domain, unsignedlong iov_pfn, unsignedlong phy_pfn, unsignedlong pages)
{ int support, level = 1; unsignedlong pfnmerge;
support = domain->iommu_superpage;
/* To use a large page, the virtual *and* physical addresses must be aligned to 2MiB/1GiB/etc. Lower bits set in either of them will mean we have to use smaller pages. So just
merge them and check both at once. */
pfnmerge = iov_pfn | phy_pfn;
/* * Ensure that old small page tables are removed to make room for superpage(s). * We're going to add new large pages, so make sure we don't remove their parent * tables. The IOTLB/devTLBs should be flushed if any PDE/PTEs are cleared.
*/ staticvoid switch_to_super_page(struct dmar_domain *domain, unsignedlong start_pfn, unsignedlong end_pfn, int level)
{ unsignedlong lvl_pages = lvl_to_nr_pages(level); struct dma_pte *pte = NULL;
if (WARN_ON(!IS_ALIGNED(start_pfn, lvl_pages) ||
!IS_ALIGNED(end_pfn + 1, lvl_pages))) return;
while (start_pfn <= end_pfn) { if (!pte)
pte = pfn_to_dma_pte(domain, start_pfn, &level,
GFP_ATOMIC);
if (unlikely(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1))) return -EINVAL;
if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) return -EINVAL;
if (!(prot & DMA_PTE_WRITE) && domain->nested_parent) {
pr_err_ratelimited("Read-only mapping is disallowed on the domain which serves as the parent in a nested configuration, due to HW errata (ERRATA_772415_SPR17)\n"); return -EINVAL;
}
/* If the next PTE would be the first in a new page, then we * need to flush the cache on the entries we've just written. * And then we'll need to recalculate 'pte', so clear it and * let it get set again in the if (!pte) block above. * * If we're done (!nr_pages) we need to flush the cache too. * * Also if we've been setting superpages, we may need to * recalculate 'pte' and switch back to smaller pages for the * end of the mapping, if the trailing size is not enough to * use another superpage (i.e. nr_pages < lvl_pages).
*/
pte++; if (!nr_pages || first_pte_in_page(pte) ||
(largepage_lvl > 1 && nr_pages < lvl_pages)) {
domain_flush_cache(domain, first_pte,
(void *)pte - (void *)first_pte);
pte = NULL;
}
}
/** * device_rmrr_is_relaxable - Test whether the RMRR of this device * is relaxable (ie. is allowed to be not enforced under some conditions) * @dev: device handle * * We assume that PCI USB devices with RMRRs have them largely * for historical reasons and that the RMRR space is not actively used post * boot. This exclusion may change if vendors begin to abuse it. * * The same exception is made for graphics devices, with the requirement that * any use of the RMRR regions will be torn down before assigning the device * to a guest. * * Return: true if the RMRR is relaxable, false otherwise
*/ staticbool device_rmrr_is_relaxable(struct device *dev)
{ struct pci_dev *pdev;
/* * Hardware does not support the passthrough translation mode. * Always use a dynamaic mapping domain.
*/ if (!ecap_pass_through(iommu->ecap)) return IOMMU_DOMAIN_DMA;
if (dev_is_pci(dev)) { struct pci_dev *pdev = to_pci_dev(dev);
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev)) return IOMMU_DOMAIN_IDENTITY;
}
return 0;
}
staticvoid intel_iommu_init_qi(struct intel_iommu *iommu)
{ /* * Start from the sane iommu hardware state. * If the queued invalidation is already initialized by us * (for example, while enabling interrupt-remapping) then * we got the things already rolling from a sane state.
*/ if (!iommu->qi) { /* * Clear any previous faults.
*/
dmar_fault(-1, iommu); /* * Disable queued invalidation if supported and already enabled * before OS handover.
*/
dmar_disable_qi(iommu);
}
if (dmar_enable_qi(iommu)) { /* * Queued Invalidate not enabled, use Register Based Invalidate
*/
iommu->flush.flush_context = __iommu_flush_context;
iommu->flush.flush_iotlb = __iommu_flush_iotlb;
pr_info("%s: Using Register based invalidation\n",
iommu->name);
} else {
iommu->flush.flush_context = qi_flush_context;
iommu->flush.flush_iotlb = qi_flush_iotlb;
pr_info("%s: Using Queued invalidation\n", iommu->name);
}
}
for (devfn = 0; devfn < 256; devfn++) { /* First calculate the correct index */
idx = (ext ? devfn * 2 : devfn) % 256;
if (idx == 0) { /* First save what we may have and clean up */ if (new_ce) {
tbl[tbl_idx] = new_ce;
__iommu_flush_cache(iommu, new_ce,
VTD_PAGE_SIZE);
pos = 1;
}
if (old_ce)
memunmap(old_ce);
ret = 0; if (devfn < 0x80)
old_ce_phys = root_entry_lctp(&re); else
old_ce_phys = root_entry_uctp(&re);
if (!old_ce_phys) { if (ext && devfn == 0) { /* No LCTP, try UCTP */
devfn = 0x7f; continue;
} else { goto out;
}
}
ret = -ENOMEM;
old_ce = memremap(old_ce_phys, PAGE_SIZE,
MEMREMAP_WB); if (!old_ce) goto out;
new_ce = iommu_alloc_pages_node_sz(iommu->node,
GFP_KERNEL, SZ_4K); if (!new_ce) goto out_unmap;
ret = 0;
}
/* Now copy the context entry */
memcpy(&ce, old_ce + idx, sizeof(ce));
if (!context_present(&ce)) continue;
did = context_domain_id(&ce); if (did >= 0 && did < cap_ndoms(iommu->cap))
ida_alloc_range(&iommu->domain_ida, did, did, GFP_KERNEL);
/* * The RTT bit can only be changed when translation is disabled, * but disabling translation means to open a window for data * corruption. So bail out and don't copy anything if we would * have to change the bit.
*/ if (new_ext != ext) return -EINVAL;
iommu->copied_tables = bitmap_zalloc(BIT_ULL(16), GFP_KERNEL); if (!iommu->copied_tables) return -ENOMEM;
old_rt_phys = rtaddr_reg & VTD_PAGE_MASK; if (!old_rt_phys) return -EINVAL;
old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB); if (!old_rt) return -ENOMEM;
/* This is too big for the stack - allocate it from slab */
ctxt_table_entries = ext ? 512 : 256;
ret = -ENOMEM;
ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL); if (!ctxt_tbls) goto out_unmap;
for (bus = 0; bus < 256; bus++) {
ret = copy_context_table(iommu, &old_rt[bus],
ctxt_tbls, bus, ext); if (ret) {
pr_err("%s: Failed to copy context table for bus %d\n",
iommu->name, bus); continue;
}
}
spin_lock(&iommu->lock);
/* Context tables are copied, now write them to the root_entry table */ for (bus = 0; bus < 256; bus++) { int idx = ext ? bus * 2 : bus;
u64 val;
if (ctxt_tbls[idx]) {
val = virt_to_phys(ctxt_tbls[idx]) | 1;
iommu->root_entry[bus].lo = val;
}
for_each_iommu(iommu, drhd) { if (drhd->ignored) {
iommu_disable_translation(iommu); continue;
}
/* * Find the max pasid size of all IOMMU's in the system. * We need to ensure the system pasid table is no bigger * than the smallest supported.
*/ if (pasid_supported(iommu)) {
u32 temp = 2 << ecap_pss(iommu->ecap);
if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
iommu_disable_translation(iommu);
clear_translation_pre_enabled(iommu);
pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
iommu->name);
}
/* * TBD: * we could share the same root & context tables * among all IOMMU's. Need to Split it later.
*/
ret = iommu_alloc_root_entry(iommu); if (ret) goto free_iommu;
if (translation_pre_enabled(iommu)) {
pr_info("Translation already enabled - trying to copy translation structures\n");
ret = copy_translation_tables(iommu); if (ret) { /* * We found the IOMMU with translation * enabled - but failed to copy over the * old root-entry table. Try to proceed * by disabling translation now and * allocating a clean root-entry table. * This might cause DMAR faults, but * probably the dump will still succeed.
*/
pr_err("Failed to copy translation tables from previous kernel for %s\n",
iommu->name);
iommu_disable_translation(iommu);
clear_translation_pre_enabled(iommu);
} else {
pr_info("Copied translation tables from previous kernel for %s\n",
iommu->name);
}
}
intel_svm_check(iommu);
}
/* * Now that qi is enabled on all iommus, set the root entry and flush * caches. This is required on some Intel X58 chipsets, otherwise the * flush_context function will loop forever and the boot hangs.
*/
for_each_active_iommu(iommu, drhd) {
iommu_flush_write_buffer(iommu);
iommu_set_root_entry(iommu);
}
check_tylersburg_isoch();
/* * for each drhd * enable fault log * global invalidate context cache * global invalidate iotlb * enable translation
*/
for_each_iommu(iommu, drhd) { if (drhd->ignored) { /* * we always have to disable PMRs or DMA may fail on * this device
*/ if (force_on)
iommu_disable_protect_mem_regions(iommu); continue;
}
iommu_flush_write_buffer(iommu);
if (ecap_prs(iommu->ecap)) { /* * Call dmar_alloc_hwirq() with dmar_global_lock held, * could cause possible lock race condition.
*/
up_write(&dmar_global_lock);
ret = intel_iommu_enable_prq(iommu);
down_write(&dmar_global_lock); if (ret) goto free_iommu;
}
ret = dmar_set_interrupt(iommu); if (ret) goto free_iommu;
}
for_each_drhd_unit(drhd) { if (!drhd->include_all) {
for_each_active_dev_scope(drhd->devices,
drhd->devices_cnt, i, dev) break; /* ignore DMAR unit if no devices exist */ if (i == drhd->devices_cnt)
drhd->ignored = 1;
}
}
for_each_active_drhd_unit(drhd) { if (drhd->include_all) continue;
for_each_active_dev_scope(drhd->devices,
drhd->devices_cnt, i, dev) if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev))) break; if (i < drhd->devices_cnt) continue;
/* This IOMMU has *only* gfx devices. Either bypass it or
set the gfx_mapped flag, as appropriate */
drhd->gfx_dedicated = 1; if (disable_igfx_iommu)
drhd->ignored = 1;
}
}
for_each_active_iommu(iommu, drhd) { if (iommu->qi) {
ret = dmar_reenable_qi(iommu); if (ret) return ret;
}
}
for_each_iommu(iommu, drhd) { if (drhd->ignored) { /* * we always have to disable PMRs or DMA may fail on * this device
*/ if (force_on)
iommu_disable_protect_mem_regions(iommu); continue;
}
if (init_iommu_hw()) { if (force_on)
panic("tboot: IOMMU setup failed, DMAR can not resume!\n"); else
WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); return;
}
atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL); if (!atsru) return -ENOMEM;
/* * If memory is allocated from slab by ACPI _DSM method, we need to * copy the memory content because the memory buffer will be freed * on return.
*/
atsru->hdr = (void *)(atsru + 1);
memcpy(atsru->hdr, hdr, hdr->length);
atsru->include_all = atsr->flags & 0x1; if (!atsru->include_all) {
atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
(void *)atsr + atsr->header.length,
&atsru->devices_cnt); if (atsru->devices_cnt && atsru->devices == NULL) {
kfree(atsru); return -ENOMEM;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.