struct mm_iommu_table_group_mem_t { struct list_head next; struct rcu_head rcu; unsignedlong used;
atomic64_t mapped; unsignedint pageshift;
u64 ua; /* userspace address */
u64 entries; /* number of entries in hpas/hpages[] */ /* * in mm_iommu_get we temporarily use this to store * struct page address. * * We need to convert ua to hpa in real mode. Make it * simpler by storing physical address.
*/ union { struct page **hpages; /* vmalloc'ed */
phys_addr_t *hpas;
}; #define MM_IOMMU_TABLE_INVALID_HPA ((uint64_t)-1)
u64 dev_hpa; /* Device memory base address */
};
/* * For a starting point for a maximum page size calculation * we use @ua and @entries natural alignment to allow IOMMU pages * smaller than huge pages but still bigger than PAGE_SIZE.
*/
mem->pageshift = __ffs(ua | (entries << PAGE_SHIFT));
mem->hpas = vzalloc(array_size(entries, sizeof(mem->hpas[0]))); if (!mem->hpas) {
kfree(mem);
ret = -ENOMEM; goto unlock_exit;
}
if (mem->dev_hpa == MM_IOMMU_TABLE_INVALID_HPA) { /* * Allow to use larger than 64k IOMMU pages. Only do that * if we are backed by hugetlb. Skip device memory as it is not * backed with page structs.
*/
pageshift = PAGE_SHIFT; for (i = 0; i < entries; ++i) { struct page *page = mem->hpages[i];
if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page))
pageshift = page_shift(compound_head(page));
mem->pageshift = min(mem->pageshift, pageshift); /* * We don't need struct page reference any more, switch * to physical address.
*/
mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT;
}
}
rcu_read_lock();
list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) { if (mem->dev_hpa == MM_IOMMU_TABLE_INVALID_HPA) continue;
end = mem->dev_hpa + (mem->entries << PAGE_SHIFT); if ((mem->dev_hpa <= hpa) && (hpa < end)) { /* * Since the IOMMU page size might be bigger than * PAGE_SIZE, the amount of preregistered memory * starting from @hpa might be smaller than 1<<pageshift * and the caller needs to distinguish this situation.
*/
*size = min(1UL << pageshift, end - hpa); returntrue;
}
}
rcu_read_unlock();
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.