Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/iommu/intel_ctx.c
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
#include <x86/include/busdma_impl.h> | #include <x86/include/busdma_impl.h> | ||||
#include <dev/iommu/busdma_iommu.h> | #include <dev/iommu/busdma_iommu.h> | ||||
#include <x86/iommu/intel_reg.h> | #include <x86/iommu/intel_reg.h> | ||||
#include <x86/iommu/intel_dmar.h> | #include <x86/iommu/intel_dmar.h> | ||||
static MALLOC_DEFINE(M_DMAR_CTX, "dmar_ctx", "Intel DMAR Context"); | static MALLOC_DEFINE(M_DMAR_CTX, "dmar_ctx", "Intel DMAR Context"); | ||||
static MALLOC_DEFINE(M_DMAR_DOMAIN, "dmar_dom", "Intel DMAR Domain"); | static MALLOC_DEFINE(M_DMAR_DOMAIN, "dmar_dom", "Intel DMAR Domain"); | ||||
static void dmar_domain_unload_task(void *arg, int pending); | |||||
static void dmar_unref_domain_locked(struct dmar_unit *dmar, | static void dmar_unref_domain_locked(struct dmar_unit *dmar, | ||||
struct dmar_domain *domain); | struct dmar_domain *domain); | ||||
static void dmar_domain_destroy(struct dmar_domain *domain); | static void dmar_domain_destroy(struct dmar_domain *domain); | ||||
static void | static void | ||||
dmar_ensure_ctx_page(struct dmar_unit *dmar, int bus) | dmar_ensure_ctx_page(struct dmar_unit *dmar, int bus) | ||||
{ | { | ||||
struct sf_buf *sf; | struct sf_buf *sf; | ||||
▲ Show 20 Lines • Show All 243 Lines • ▼ Show 20 Lines | dmar_domain_alloc(struct dmar_unit *dmar, bool id_mapped) | ||||
id = alloc_unr(dmar->domids); | id = alloc_unr(dmar->domids); | ||||
if (id == -1) | if (id == -1) | ||||
return (NULL); | return (NULL); | ||||
domain = malloc(sizeof(*domain), M_DMAR_DOMAIN, M_WAITOK | M_ZERO); | domain = malloc(sizeof(*domain), M_DMAR_DOMAIN, M_WAITOK | M_ZERO); | ||||
iodom = DOM2IODOM(domain); | iodom = DOM2IODOM(domain); | ||||
unit = DMAR2IOMMU(dmar); | unit = DMAR2IOMMU(dmar); | ||||
domain->domain = id; | domain->domain = id; | ||||
LIST_INIT(&domain->contexts); | LIST_INIT(&domain->contexts); | ||||
TASK_INIT(&domain->iodom.unload_task, 0, dmar_domain_unload_task, | |||||
domain); | |||||
iommu_domain_init(unit, iodom, &dmar_domain_map_ops); | iommu_domain_init(unit, iodom, &dmar_domain_map_ops); | ||||
domain->dmar = dmar; | domain->dmar = dmar; | ||||
/* | /* | ||||
* 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 | ||||
▲ Show 20 Lines • Show All 523 Lines • ▼ Show 20 Lines | dmar_domain_unload(struct dmar_domain *domain, | ||||
DMAR_LOCK(unit); | DMAR_LOCK(unit); | ||||
TAILQ_FOREACH(entry, entries, dmamap_link) { | TAILQ_FOREACH(entry, entries, dmamap_link) { | ||||
dmar_qi_invalidate_locked(domain, entry->start, entry->end - | dmar_qi_invalidate_locked(domain, entry->start, entry->end - | ||||
entry->start, &entry->gseq, | entry->start, &entry->gseq, | ||||
dmar_domain_unload_emit_wait(domain, entry)); | dmar_domain_unload_emit_wait(domain, entry)); | ||||
} | } | ||||
TAILQ_CONCAT(&unit->tlb_flush_entries, entries, dmamap_link); | TAILQ_CONCAT(&unit->tlb_flush_entries, entries, dmamap_link); | ||||
DMAR_UNLOCK(unit); | DMAR_UNLOCK(unit); | ||||
} | |||||
static void | |||||
dmar_domain_unload_task(void *arg, int pending) | |||||
{ | |||||
struct dmar_domain *domain; | |||||
struct iommu_map_entries_tailq entries; | |||||
domain = arg; | |||||
TAILQ_INIT(&entries); | |||||
for (;;) { | |||||
DMAR_DOMAIN_LOCK(domain); | |||||
TAILQ_SWAP(&domain->iodom.unload_entries, &entries, | |||||
iommu_map_entry, dmamap_link); | |||||
DMAR_DOMAIN_UNLOCK(domain); | |||||
if (TAILQ_EMPTY(&entries)) | |||||
break; | |||||
dmar_domain_unload(domain, &entries, true); | |||||
} | |||||
} | } | ||||
struct iommu_ctx * | struct iommu_ctx * | ||||
iommu_get_ctx(struct iommu_unit *iommu, device_t dev, uint16_t rid, | iommu_get_ctx(struct iommu_unit *iommu, device_t dev, uint16_t rid, | ||||
bool id_mapped, bool rmrr_init) | bool id_mapped, bool rmrr_init) | ||||
{ | { | ||||
struct dmar_unit *dmar; | struct dmar_unit *dmar; | ||||
struct dmar_ctx *ret; | struct dmar_ctx *ret; | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |