Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/iommu/intel_gas.c
Show First 20 Lines • Show All 537 Lines • ▼ Show 20 Lines | dmar_gas_alloc_region(struct dmar_domain *domain, struct dmar_map_entry *entry, | ||||
* entries. | * entries. | ||||
* | * | ||||
* XXXKIB: this does not handle a case when prev or next | * XXXKIB: this does not handle a case when prev or next | ||||
* entries are completely covered by the current one, which | * entries are completely covered by the current one, which | ||||
* extends both ways. | * extends both ways. | ||||
*/ | */ | ||||
if (prev != NULL && prev->end > entry->start && | if (prev != NULL && prev->end > entry->start && | ||||
(prev->flags & DMAR_MAP_ENTRY_PLACE) == 0) { | (prev->flags & DMAR_MAP_ENTRY_PLACE) == 0) { | ||||
if ((prev->flags & DMAR_MAP_ENTRY_RMRR) == 0) | if ((flags & DMAR_GM_RMRR) == 0 || | ||||
(prev->flags & DMAR_MAP_ENTRY_RMRR) == 0) | |||||
return (EBUSY); | return (EBUSY); | ||||
entry->start = prev->end; | entry->start = prev->end; | ||||
} | } | ||||
if (next->start < entry->end && | if (next->start < entry->end && | ||||
(next->flags & DMAR_MAP_ENTRY_PLACE) == 0) { | (next->flags & DMAR_MAP_ENTRY_PLACE) == 0) { | ||||
if ((next->flags & DMAR_MAP_ENTRY_RMRR) == 0) | if ((flags & DMAR_GM_RMRR) == 0 || | ||||
(next->flags & DMAR_MAP_ENTRY_RMRR) == 0) | |||||
return (EBUSY); | return (EBUSY); | ||||
entry->end = next->start; | entry->end = next->start; | ||||
} | } | ||||
if (entry->end == entry->start) | if (entry->end == entry->start) | ||||
return (0); | return (0); | ||||
if (prev != NULL && prev->end > entry->start) { | if (prev != NULL && prev->end > entry->start) { | ||||
/* This assumes that prev is the placeholder entry. */ | /* This assumes that prev is the placeholder entry. */ | ||||
dmar_gas_rb_remove(domain, prev); | dmar_gas_rb_remove(domain, prev); | ||||
prev = NULL; | prev = NULL; | ||||
} | } | ||||
if (next->start < entry->end) { | if (next->start < entry->end) { | ||||
dmar_gas_rb_remove(domain, next); | dmar_gas_rb_remove(domain, next); | ||||
next = NULL; | next = NULL; | ||||
} | } | ||||
found = dmar_gas_rb_insert(domain, entry); | found = dmar_gas_rb_insert(domain, entry); | ||||
KASSERT(found, ("found RMRR dup %p start %jx end %jx", | KASSERT(found, ("found RMRR dup %p start %jx end %jx", | ||||
domain, (uintmax_t)entry->start, (uintmax_t)entry->end)); | domain, (uintmax_t)entry->start, (uintmax_t)entry->end)); | ||||
if ((flags & DMAR_GM_RMRR) != 0) | |||||
entry->flags = DMAR_MAP_ENTRY_RMRR; | entry->flags = DMAR_MAP_ENTRY_RMRR; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
struct dmar_map_entry *ip, *in; | struct dmar_map_entry *ip, *in; | ||||
ip = RB_PREV(dmar_gas_entries_tree, &domain->rb_root, entry); | ip = RB_PREV(dmar_gas_entries_tree, &domain->rb_root, entry); | ||||
in = RB_NEXT(dmar_gas_entries_tree, &domain->rb_root, entry); | in = RB_NEXT(dmar_gas_entries_tree, &domain->rb_root, entry); | ||||
KASSERT(prev == NULL || ip == prev, | KASSERT(prev == NULL || ip == prev, | ||||
("RMRR %p (%jx %jx) prev %p (%jx %jx) ins prev %p (%jx %jx)", | ("RMRR %p (%jx %jx) prev %p (%jx %jx) ins prev %p (%jx %jx)", | ||||
entry, entry->start, entry->end, prev, | entry, entry->start, entry->end, prev, | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
dmar_gas_map_region(struct dmar_domain *domain, struct dmar_map_entry *entry, | dmar_gas_map_region(struct dmar_domain *domain, struct dmar_map_entry *entry, | ||||
u_int eflags, u_int flags, vm_page_t *ma) | u_int eflags, u_int flags, vm_page_t *ma) | ||||
{ | { | ||||
dmar_gaddr_t start; | dmar_gaddr_t start; | ||||
int error; | int error; | ||||
KASSERT(entry->flags == 0, ("used RMRR entry %p %p %x", domain, | KASSERT(entry->flags == 0, ("used RMRR entry %p %p %x", domain, | ||||
entry, entry->flags)); | entry, entry->flags)); | ||||
KASSERT((flags & ~(DMAR_GM_CANWAIT)) == 0, | KASSERT((flags & ~(DMAR_GM_CANWAIT | DMAR_GM_RMRR)) == 0, | ||||
("invalid flags 0x%x", flags)); | ("invalid flags 0x%x", flags)); | ||||
start = entry->start; | start = entry->start; | ||||
DMAR_DOMAIN_LOCK(domain); | DMAR_DOMAIN_LOCK(domain); | ||||
error = dmar_gas_alloc_region(domain, entry, flags); | error = dmar_gas_alloc_region(domain, entry, flags); | ||||
if (error != 0) { | if (error != 0) { | ||||
DMAR_DOMAIN_UNLOCK(domain); | DMAR_DOMAIN_UNLOCK(domain); | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines |