Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/iommu/intel_ctx.c
Show First 20 Lines • Show All 335 Lines • ▼ Show 20 Lines | dmar_domain_alloc(struct dmar_unit *dmar, bool id_mapped) | ||||
LIST_INIT(&domain->contexts); | LIST_INIT(&domain->contexts); | ||||
RB_INIT(&domain->iodom.rb_root); | RB_INIT(&domain->iodom.rb_root); | ||||
TAILQ_INIT(&domain->iodom.unload_entries); | TAILQ_INIT(&domain->iodom.unload_entries); | ||||
TASK_INIT(&domain->iodom.unload_task, 0, dmar_domain_unload_task, | TASK_INIT(&domain->iodom.unload_task, 0, dmar_domain_unload_task, | ||||
domain); | domain); | ||||
mtx_init(&domain->iodom.lock, "dmardom", NULL, MTX_DEF); | mtx_init(&domain->iodom.lock, "dmardom", NULL, MTX_DEF); | ||||
domain->dmar = dmar; | domain->dmar = dmar; | ||||
domain->iodom.iommu = &dmar->iommu; | domain->iodom.iommu = &dmar->iommu; | ||||
domain_pgtbl_init(domain); | |||||
/* | /* | ||||
* For now, use the maximal usable physical address of the | * For now, use the maximal usable physical address of the | ||||
* installed memory to calculate the mgaw on id_mapped domain. | * installed memory to calculate the mgaw on id_mapped domain. | ||||
* It is useful for the identity mapping, and less so for the | * It is useful for the identity mapping, and less so for the | ||||
* virtualized bus address space. | * virtualized bus address space. | ||||
*/ | */ | ||||
domain->iodom.end = id_mapped ? ptoa(Maxmem) : BUS_SPACE_MAXADDR; | domain->iodom.end = id_mapped ? ptoa(Maxmem) : BUS_SPACE_MAXADDR; | ||||
▲ Show 20 Lines • Show All 485 Lines • ▼ Show 20 Lines | dmar_domain_unload_emit_wait(struct dmar_domain *domain, | ||||
return (domain->batch_no++ % dmar_batch_coalesce == 0); | return (domain->batch_no++ % dmar_batch_coalesce == 0); | ||||
} | } | ||||
void | void | ||||
dmar_domain_unload(struct dmar_domain *domain, | dmar_domain_unload(struct dmar_domain *domain, | ||||
struct iommu_map_entries_tailq *entries, bool cansleep) | struct iommu_map_entries_tailq *entries, bool cansleep) | ||||
{ | { | ||||
struct dmar_unit *unit; | struct dmar_unit *unit; | ||||
struct iommu_domain *iodom; | |||||
struct iommu_map_entry *entry, *entry1; | struct iommu_map_entry *entry, *entry1; | ||||
int error; | int error; | ||||
iodom = (struct iommu_domain *)domain; | |||||
unit = (struct dmar_unit *)domain->iodom.iommu; | unit = (struct dmar_unit *)domain->iodom.iommu; | ||||
TAILQ_FOREACH_SAFE(entry, entries, dmamap_link, entry1) { | TAILQ_FOREACH_SAFE(entry, entries, dmamap_link, entry1) { | ||||
KASSERT((entry->flags & IOMMU_MAP_ENTRY_MAP) != 0, | KASSERT((entry->flags & IOMMU_MAP_ENTRY_MAP) != 0, | ||||
("not mapped entry %p %p", domain, entry)); | ("not mapped entry %p %p", domain, entry)); | ||||
error = domain_unmap_buf(domain, entry->start, entry->end - | error = iodom->ops->unmap(iodom, entry->start, entry->end - | ||||
entry->start, cansleep ? IOMMU_PGF_WAITOK : 0); | entry->start, cansleep ? IOMMU_PGF_WAITOK : 0); | ||||
KASSERT(error == 0, ("unmap %p error %d", domain, error)); | KASSERT(error == 0, ("unmap %p error %d", domain, error)); | ||||
if (!unit->qi_enabled) { | if (!unit->qi_enabled) { | ||||
domain_flush_iotlb_sync(domain, entry->start, | domain_flush_iotlb_sync(domain, entry->start, | ||||
entry->end - entry->start); | entry->end - entry->start); | ||||
TAILQ_REMOVE(entries, entry, dmamap_link); | TAILQ_REMOVE(entries, entry, dmamap_link); | ||||
dmar_domain_free_entry(entry, true); | dmar_domain_free_entry(entry, true); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines |