Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/iommu/intel_gas.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | dmar_gas_alloc_entry(struct dmar_domain *domain, u_int flags) | ||||
KASSERT((flags & ~(DMAR_PGF_WAITOK)) == 0, | KASSERT((flags & ~(DMAR_PGF_WAITOK)) == 0, | ||||
("unsupported flags %x", flags)); | ("unsupported flags %x", flags)); | ||||
res = uma_zalloc(iommu_map_entry_zone, ((flags & DMAR_PGF_WAITOK) != | res = uma_zalloc(iommu_map_entry_zone, ((flags & DMAR_PGF_WAITOK) != | ||||
0 ? M_WAITOK : M_NOWAIT) | M_ZERO); | 0 ? M_WAITOK : M_NOWAIT) | M_ZERO); | ||||
if (res != NULL) { | if (res != NULL) { | ||||
res->domain = (struct iommu_domain *)domain; | res->domain = (struct iommu_domain *)domain; | ||||
atomic_add_int(&domain->entries_cnt, 1); | atomic_add_int(&domain->iodom.entries_cnt, 1); | ||||
} | } | ||||
return (res); | return (res); | ||||
} | } | ||||
void | void | ||||
dmar_gas_free_entry(struct dmar_domain *domain, struct iommu_map_entry *entry) | dmar_gas_free_entry(struct dmar_domain *domain, struct iommu_map_entry *entry) | ||||
{ | { | ||||
KASSERT(domain == (struct dmar_domain *)entry->domain, | KASSERT(domain == (struct dmar_domain *)entry->domain, | ||||
("mismatched free domain %p entry %p entry->domain %p", domain, | ("mismatched free domain %p entry %p entry->domain %p", domain, | ||||
entry, entry->domain)); | entry, entry->domain)); | ||||
atomic_subtract_int(&domain->entries_cnt, 1); | atomic_subtract_int(&domain->iodom.entries_cnt, 1); | ||||
uma_zfree(iommu_map_entry_zone, entry); | uma_zfree(iommu_map_entry_zone, entry); | ||||
} | } | ||||
static int | static int | ||||
dmar_gas_cmp_entries(struct iommu_map_entry *a, struct iommu_map_entry *b) | dmar_gas_cmp_entries(struct iommu_map_entry *a, struct iommu_map_entry *b) | ||||
{ | { | ||||
/* Last entry have zero size, so <= */ | /* Last entry have zero size, so <= */ | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
dmar_gas_init_domain(struct dmar_domain *domain) | dmar_gas_init_domain(struct dmar_domain *domain) | ||||
{ | { | ||||
struct iommu_map_entry *begin, *end; | struct iommu_map_entry *begin, *end; | ||||
begin = dmar_gas_alloc_entry(domain, DMAR_PGF_WAITOK); | begin = dmar_gas_alloc_entry(domain, DMAR_PGF_WAITOK); | ||||
end = dmar_gas_alloc_entry(domain, DMAR_PGF_WAITOK); | end = dmar_gas_alloc_entry(domain, DMAR_PGF_WAITOK); | ||||
DMAR_DOMAIN_LOCK(domain); | DMAR_DOMAIN_LOCK(domain); | ||||
KASSERT(domain->entries_cnt == 2, ("dirty domain %p", domain)); | KASSERT(domain->iodom.entries_cnt == 2, ("dirty domain %p", domain)); | ||||
KASSERT(RB_EMPTY(&domain->rb_root), ("non-empty entries %p", domain)); | KASSERT(RB_EMPTY(&domain->rb_root), ("non-empty entries %p", domain)); | ||||
begin->start = 0; | begin->start = 0; | ||||
begin->end = DMAR_PAGE_SIZE; | begin->end = DMAR_PAGE_SIZE; | ||||
begin->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED; | begin->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED; | ||||
dmar_gas_rb_insert(domain, begin); | dmar_gas_rb_insert(domain, begin); | ||||
end->start = domain->end; | end->start = domain->end; | ||||
end->end = domain->end; | end->end = domain->end; | ||||
end->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED; | end->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED; | ||||
dmar_gas_rb_insert(domain, end); | dmar_gas_rb_insert(domain, end); | ||||
domain->first_place = begin; | domain->first_place = begin; | ||||
domain->last_place = end; | domain->last_place = end; | ||||
domain->flags |= DMAR_DOMAIN_GAS_INITED; | domain->flags |= DMAR_DOMAIN_GAS_INITED; | ||||
DMAR_DOMAIN_UNLOCK(domain); | DMAR_DOMAIN_UNLOCK(domain); | ||||
} | } | ||||
void | void | ||||
dmar_gas_fini_domain(struct dmar_domain *domain) | dmar_gas_fini_domain(struct dmar_domain *domain) | ||||
{ | { | ||||
struct iommu_map_entry *entry, *entry1; | struct iommu_map_entry *entry, *entry1; | ||||
DMAR_DOMAIN_ASSERT_LOCKED(domain); | DMAR_DOMAIN_ASSERT_LOCKED(domain); | ||||
KASSERT(domain->entries_cnt == 2, ("domain still in use %p", domain)); | KASSERT(domain->iodom.entries_cnt == 2, | ||||
("domain still in use %p", domain)); | |||||
entry = RB_MIN(dmar_gas_entries_tree, &domain->rb_root); | entry = RB_MIN(dmar_gas_entries_tree, &domain->rb_root); | ||||
KASSERT(entry->start == 0, ("start entry start %p", domain)); | KASSERT(entry->start == 0, ("start entry start %p", domain)); | ||||
KASSERT(entry->end == DMAR_PAGE_SIZE, ("start entry end %p", domain)); | KASSERT(entry->end == DMAR_PAGE_SIZE, ("start entry end %p", domain)); | ||||
KASSERT(entry->flags == IOMMU_MAP_ENTRY_PLACE, | KASSERT(entry->flags == IOMMU_MAP_ENTRY_PLACE, | ||||
("start entry flags %p", domain)); | ("start entry flags %p", domain)); | ||||
RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry); | RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry); | ||||
dmar_gas_free_entry(domain, entry); | dmar_gas_free_entry(domain, entry); | ||||
▲ Show 20 Lines • Show All 491 Lines • Show Last 20 Lines |