Lines Matching full:domain
90 iommu_gas_alloc_entry(struct iommu_domain *domain, u_int flags)
101 if (domain != NULL) {
102 res->domain = domain;
103 atomic_add_int(&domain->entries_cnt, 1);
112 struct iommu_domain *domain;
119 domain = entry->domain;
120 if (domain != NULL)
121 atomic_subtract_int(&domain->entries_cnt, 1);
138 " domain %p %p",
141 a->domain, b->domain));
192 iommu_gas_check_free(struct iommu_domain *domain)
197 RB_FOREACH(entry, iommu_gas_entries_tree, &domain->rb_root) {
198 KASSERT(domain == entry->domain,
199 ("mismatched free domain %p entry %p entry->domain %p",
200 domain, entry, entry->domain));
218 iommu_gas_rb_remove(struct iommu_domain *domain, struct iommu_map_entry *entry)
222 /* Removing entry may open a new free gap before domain->start_gap. */
223 if (entry->end <= domain->start_gap->end) {
230 domain->start_gap = nbr;
232 RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry);
239 return (ctx->domain);
243 iommu_gas_init_domain(struct iommu_domain *domain)
247 begin = iommu_gas_alloc_entry(domain, IOMMU_PGF_WAITOK);
248 end = iommu_gas_alloc_entry(domain, IOMMU_PGF_WAITOK);
250 IOMMU_DOMAIN_LOCK(domain);
251 KASSERT(domain->entries_cnt == 2, ("dirty domain %p", domain));
252 KASSERT(RB_EMPTY(&domain->rb_root),
253 ("non-empty entries %p", domain));
255 end->start = domain->end;
256 end->end = domain->end;
258 RB_INSERT(iommu_gas_entries_tree, &domain->rb_root, end);
263 RB_INSERT_PREV(iommu_gas_entries_tree, &domain->rb_root, end, begin);
267 domain->start_gap = begin;
268 domain->first_place = begin;
269 domain->last_place = end;
270 domain->flags |= IOMMU_DOMAIN_GAS_INITED;
271 IOMMU_DOMAIN_UNLOCK(domain);
275 iommu_gas_fini_domain(struct iommu_domain *domain)
279 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
280 KASSERT(domain->entries_cnt == 2,
281 ("domain still in use %p", domain));
283 entry = RB_MIN(iommu_gas_entries_tree, &domain->rb_root);
284 KASSERT(entry->start == 0, ("start entry start %p", domain));
285 KASSERT(entry->end == IOMMU_PAGE_SIZE, ("start entry end %p", domain));
288 ("start entry flags %p", domain));
289 iommu_gas_rb_remove(domain, entry);
292 entry = RB_MAX(iommu_gas_entries_tree, &domain->rb_root);
293 KASSERT(entry->start == domain->end, ("end entry start %p", domain));
294 KASSERT(entry->end == domain->end, ("end entry end %p", domain));
297 ("end entry flags %p", domain));
298 iommu_gas_rb_remove(domain, entry);
404 * Address-ordered first-fit search of 'domain' for free space satisfying the
407 * 'domain' is described by an rb-tree of map entries at domain->rb_root, and
408 * domain->start_gap points to a map entry less than or adjacent to the first
412 iommu_gas_find_space(struct iommu_domain *domain,
418 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
420 ("dirty entry %p %p", domain, a->entry));
428 first = domain->start_gap;
440 domain->start_gap = curr;
465 &domain->rb_root, curr, a->entry);
476 &domain->rb_root, curr, a->entry);
507 addr + 1, domain->end - 1)) {
509 &domain->rb_root, curr, a->entry);
514 addr + 1, domain->end - 1)) {
516 &domain->rb_root, curr, a->entry);
525 iommu_gas_alloc_region(struct iommu_domain *domain, struct iommu_map_entry *entry,
530 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
537 if (entry->end >= domain->end)
541 next = RB_NFIND(iommu_gas_entries_tree, &domain->rb_root, entry);
542 KASSERT(next != NULL, ("next must be non-null %p %jx", domain,
544 prev = RB_PREV(iommu_gas_entries_tree, &domain->rb_root, next);
575 iommu_gas_rb_remove(domain, prev);
579 &domain->rb_root, next, entry);
581 iommu_gas_rb_remove(domain, next);
590 ip = RB_PREV(iommu_gas_entries_tree, &domain->rb_root, entry);
591 in = RB_NEXT(iommu_gas_entries_tree, &domain->rb_root, entry);
610 struct iommu_domain *domain;
612 domain = entry->domain;
615 ("permanent entry %p %p", domain, entry));
617 IOMMU_DOMAIN_LOCK(domain);
618 iommu_gas_rb_remove(domain, entry);
622 iommu_gas_check_free(domain);
624 IOMMU_DOMAIN_UNLOCK(domain);
630 struct iommu_domain *domain;
632 domain = entry->domain;
635 ("non-RMRR entry %p %p", domain, entry));
637 IOMMU_DOMAIN_LOCK(domain);
638 if (entry != domain->first_place &&
639 entry != domain->last_place)
640 iommu_gas_rb_remove(domain, entry);
642 IOMMU_DOMAIN_UNLOCK(domain);
646 iommu_gas_remove_clip_left(struct iommu_domain *domain, iommu_gaddr_t start,
651 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
653 MPASS(end <= domain->end);
658 * asserted that start is below domain end, entry should
665 entry = RB_NFIND(iommu_gas_entries_tree, &domain->rb_root, &fentry);
677 &domain->rb_root, entry, res);
682 iommu_gas_remove_clip_right(struct iommu_domain *domain,
693 &domain->rb_root, entry, r);
698 iommu_gas_remove_unmap(struct iommu_domain *domain,
701 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
713 iommu_gas_remove_locked(struct iommu_domain *domain,
721 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
725 nentry = iommu_gas_remove_clip_left(domain, start, end, r1);
732 iommu_gas_remove_unmap(domain, entry, gc);
734 if (iommu_gas_remove_clip_right(domain, end, entry, *r2)) {
735 iommu_gas_remove_unmap(domain, *r2, gc);
740 RB_FOREACH(entry, iommu_gas_entries_tree, &domain->rb_root) {
753 iommu_gas_remove_init(struct iommu_domain *domain,
758 *r1 = iommu_gas_alloc_entry(domain, IOMMU_PGF_WAITOK);
759 *r2 = iommu_gas_alloc_entry(domain, IOMMU_PGF_WAITOK);
763 iommu_gas_remove_cleanup(struct iommu_domain *domain,
775 iommu_domain_unload(domain, gc, true);
779 * Remove specified range from the GAS of the domain. Note that the
785 iommu_gas_remove(struct iommu_domain *domain, iommu_gaddr_t start,
791 iommu_gas_remove_init(domain, &gc, &r1, &r2);
792 IOMMU_DOMAIN_LOCK(domain);
793 iommu_gas_remove_locked(domain, start, size, &gc, &r1, &r2);
794 IOMMU_DOMAIN_UNLOCK(domain);
795 iommu_gas_remove_cleanup(domain, &gc, &r1, &r2);
799 iommu_gas_map(struct iommu_domain *domain,
814 entry = iommu_gas_alloc_entry(domain,
819 IOMMU_DOMAIN_LOCK(domain);
820 error = iommu_gas_find_space(domain, &a);
822 IOMMU_DOMAIN_UNLOCK(domain);
828 iommu_gas_check_free(domain);
832 KASSERT(entry->end < domain->end, ("allocated GPA %jx, max GPA %jx",
833 (uintmax_t)entry->end, (uintmax_t)domain->end));
835 IOMMU_DOMAIN_UNLOCK(domain);
837 error = domain->ops->map(domain, entry, ma, eflags,
852 iommu_gas_map_region(struct iommu_domain *domain, struct iommu_map_entry *entry,
858 KASSERT(entry->domain == domain,
859 ("mismatched domain %p entry %p entry->domain %p", domain,
860 entry, entry->domain));
861 KASSERT(entry->flags == 0, ("used RMRR entry %p %p %x", domain,
867 IOMMU_DOMAIN_LOCK(domain);
868 error = iommu_gas_alloc_region(domain, entry, flags);
870 IOMMU_DOMAIN_UNLOCK(domain);
874 IOMMU_DOMAIN_UNLOCK(domain);
878 error = domain->ops->map(domain, entry,
893 iommu_gas_reserve_region_locked(struct iommu_domain *domain,
898 IOMMU_DOMAIN_ASSERT_LOCKED(domain);
902 error = iommu_gas_alloc_region(domain, entry, IOMMU_MF_CANWAIT);
909 iommu_gas_reserve_region(struct iommu_domain *domain, iommu_gaddr_t start,
915 entry = iommu_gas_alloc_entry(domain, IOMMU_PGF_WAITOK);
916 IOMMU_DOMAIN_LOCK(domain);
917 error = iommu_gas_reserve_region_locked(domain, start, end, entry);
918 IOMMU_DOMAIN_UNLOCK(domain);
931 iommu_gas_reserve_region_extend(struct iommu_domain *domain,
940 end = ummin(end, domain->end);
944 entry = iommu_gas_alloc_entry(domain,
948 IOMMU_DOMAIN_LOCK(domain);
949 next = RB_NFIND(iommu_gas_entries_tree, &domain->rb_root, &key);
950 KASSERT(next != NULL, ("domain %p with end %#jx has no entry "
951 "after %#jx", domain, (uintmax_t)domain->end,
954 prev = RB_PREV(iommu_gas_entries_tree, &domain->rb_root, next);
962 error = iommu_gas_reserve_region_locked(domain,
965 IOMMU_DOMAIN_UNLOCK(domain);
970 IOMMU_DOMAIN_UNLOCK(domain);
982 struct iommu_domain *domain;
984 domain = ctx->domain;
985 entry = domain->msi_entry;
989 domain->ops->unmap(domain, entry, IOMMU_PGF_WAITOK);
995 domain->msi_entry = NULL;
996 domain->msi_base = 0;
997 domain->msi_phys = 0;
1004 struct iommu_domain *domain;
1009 domain = ctx->domain;
1012 IOMMU_DOMAIN_LOCK(domain);
1013 entry = domain->msi_entry;
1014 IOMMU_DOMAIN_UNLOCK(domain);
1017 error = iommu_gas_map(domain, &ctx->tag->common, size, offset,
1019 IOMMU_DOMAIN_LOCK(domain);
1021 if (domain->msi_entry == NULL) {
1022 MPASS(domain->msi_base == 0);
1023 MPASS(domain->msi_phys == 0);
1025 domain->msi_entry = entry;
1026 domain->msi_base = entry->start;
1027 domain->msi_phys = VM_PAGE_TO_PHYS(ma[0]);
1035 } else if (domain->msi_entry != NULL) {
1042 IOMMU_DOMAIN_UNLOCK(domain);
1049 iommu_translate_msi(struct iommu_domain *domain, uint64_t *addr)
1052 *addr = (*addr - domain->msi_phys) + domain->msi_base;
1054 KASSERT(*addr >= domain->msi_entry->start,
1056 __func__, (uintmax_t)*addr, (uintmax_t)domain->msi_entry->start));
1058 KASSERT(*addr + sizeof(*addr) <= domain->msi_entry->end,
1060 __func__, (uintmax_t)*addr, (uintmax_t)domain->msi_entry->end));
1077 iommu_debug_dump_gas(struct iommu_domain *domain)
1081 db_printf("iommu_domain %p tree %p iommu %p fl %#x\n", domain,
1082 &domain->rb_root, domain->iommu, domain->flags);
1083 db_printf("iommu_domain %p tree %p\n", domain, &domain->rb_root);
1084 RB_FOREACH(entry, iommu_gas_entries_tree, &domain->rb_root) {
1091 if (entry == domain->start_gap)
1093 if (entry == domain->first_place)
1095 if (entry == domain->last_place)
1103 struct iommu_domain *domain;
1110 domain = (void *)addr;
1111 iommu_debug_dump_gas(domain);