intel_ctx.c (276948) | intel_ctx.c (277023) |
---|---|
1/*- 2 * Copyright (c) 2013 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Konstantin Belousov <kib@FreeBSD.org> 6 * under sponsorship from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2013 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Konstantin Belousov <kib@FreeBSD.org> 6 * under sponsorship from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/x86/iommu/intel_ctx.c 276948 2015-01-10 22:57:08Z kib $"); | 31__FBSDID("$FreeBSD: head/sys/x86/iommu/intel_ctx.c 277023 2015-01-11 20:27:15Z kib $"); |
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/malloc.h> 36#include <sys/bus.h> 37#include <sys/interrupt.h> 38#include <sys/kernel.h> 39#include <sys/ktr.h> --- 52 unchanged lines hidden (view full) --- 92 */ 93 TD_PREP_PINNED_ASSERT; 94 ctxm = dmar_pgalloc(dmar->ctx_obj, 1 + bus, DMAR_PGF_ZERO | 95 DMAR_PGF_WAITOK); 96 re = dmar_map_pgtbl(dmar->ctx_obj, 0, DMAR_PGF_NOALLOC, &sf); 97 re += bus; 98 dmar_pte_store(&re->r1, DMAR_ROOT_R1_P | (DMAR_ROOT_R1_CTP_MASK & 99 VM_PAGE_TO_PHYS(ctxm))); | 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/malloc.h> 36#include <sys/bus.h> 37#include <sys/interrupt.h> 38#include <sys/kernel.h> 39#include <sys/ktr.h> --- 52 unchanged lines hidden (view full) --- 92 */ 93 TD_PREP_PINNED_ASSERT; 94 ctxm = dmar_pgalloc(dmar->ctx_obj, 1 + bus, DMAR_PGF_ZERO | 95 DMAR_PGF_WAITOK); 96 re = dmar_map_pgtbl(dmar->ctx_obj, 0, DMAR_PGF_NOALLOC, &sf); 97 re += bus; 98 dmar_pte_store(&re->r1, DMAR_ROOT_R1_P | (DMAR_ROOT_R1_CTP_MASK & 99 VM_PAGE_TO_PHYS(ctxm))); |
100 dmar_unmap_pgtbl(sf, DMAR_IS_COHERENT(dmar)); | 100 dmar_flush_root_to_ram(dmar, re); 101 dmar_unmap_pgtbl(sf); |
101 TD_PINNED_ASSERT; 102} 103 104static dmar_ctx_entry_t * 105dmar_map_ctx_entry(struct dmar_ctx *ctx, struct sf_buf **sfp) 106{ 107 dmar_ctx_entry_t *ctxp; 108 --- 44 unchanged lines hidden (view full) --- 153 ("ctx %p non-null pgtbl_obj", ctx)); 154 dmar_pte_store(&ctxp->ctx1, DMAR_CTX1_T_PASS | DMAR_CTX1_P); 155 } else { 156 ctx_root = dmar_pgalloc(ctx->pgtbl_obj, 0, DMAR_PGF_NOALLOC); 157 dmar_pte_store(&ctxp->ctx1, DMAR_CTX1_T_UNTR | 158 (DMAR_CTX1_ASR_MASK & VM_PAGE_TO_PHYS(ctx_root)) | 159 DMAR_CTX1_P); 160 } | 102 TD_PINNED_ASSERT; 103} 104 105static dmar_ctx_entry_t * 106dmar_map_ctx_entry(struct dmar_ctx *ctx, struct sf_buf **sfp) 107{ 108 dmar_ctx_entry_t *ctxp; 109 --- 44 unchanged lines hidden (view full) --- 154 ("ctx %p non-null pgtbl_obj", ctx)); 155 dmar_pte_store(&ctxp->ctx1, DMAR_CTX1_T_PASS | DMAR_CTX1_P); 156 } else { 157 ctx_root = dmar_pgalloc(ctx->pgtbl_obj, 0, DMAR_PGF_NOALLOC); 158 dmar_pte_store(&ctxp->ctx1, DMAR_CTX1_T_UNTR | 159 (DMAR_CTX1_ASR_MASK & VM_PAGE_TO_PHYS(ctx_root)) | 160 DMAR_CTX1_P); 161 } |
162 dmar_flush_ctx_to_ram(unit, ctxp); |
|
161} 162 163static int 164ctx_init_rmrr(struct dmar_ctx *ctx, device_t dev) 165{ 166 struct dmar_map_entries_tailq rmrr_entries; 167 struct dmar_map_entry *entry, *entry1; 168 vm_page_t *ma; --- 190 unchanged lines hidden (view full) --- 359 */ 360 ctx = dmar_find_ctx_locked(dmar, rid); 361 if (ctx == NULL) { 362 ctx = ctx1; 363 ctx->ctx_tag.owner = dev; 364 ctx->domain = alloc_unrl(dmar->domids); 365 if (ctx->domain == -1) { 366 DMAR_UNLOCK(dmar); | 163} 164 165static int 166ctx_init_rmrr(struct dmar_ctx *ctx, device_t dev) 167{ 168 struct dmar_map_entries_tailq rmrr_entries; 169 struct dmar_map_entry *entry, *entry1; 170 vm_page_t *ma; --- 190 unchanged lines hidden (view full) --- 361 */ 362 ctx = dmar_find_ctx_locked(dmar, rid); 363 if (ctx == NULL) { 364 ctx = ctx1; 365 ctx->ctx_tag.owner = dev; 366 ctx->domain = alloc_unrl(dmar->domids); 367 if (ctx->domain == -1) { 368 DMAR_UNLOCK(dmar); |
367 dmar_unmap_pgtbl(sf, true); | 369 dmar_unmap_pgtbl(sf); |
368 dmar_ctx_dtr(ctx, true, true); 369 TD_PINNED_ASSERT; 370 return (NULL); 371 } 372 ctx_tag_init(ctx, dev); 373 374 /* 375 * This is the first activated context for the --- 8 unchanged lines hidden (view full) --- 384 "dmar%d pci%d:%d:%d:%d rid %x domain %d mgaw %d " 385 "agaw %d %s-mapped\n", 386 dmar->unit, dmar->segment, bus, slot, 387 func, rid, ctx->domain, ctx->mgaw, ctx->agaw, 388 id_mapped ? "id" : "re"); 389 } else { 390 dmar_ctx_dtr(ctx1, true, true); 391 } | 370 dmar_ctx_dtr(ctx, true, true); 371 TD_PINNED_ASSERT; 372 return (NULL); 373 } 374 ctx_tag_init(ctx, dev); 375 376 /* 377 * This is the first activated context for the --- 8 unchanged lines hidden (view full) --- 386 "dmar%d pci%d:%d:%d:%d rid %x domain %d mgaw %d " 387 "agaw %d %s-mapped\n", 388 dmar->unit, dmar->segment, bus, slot, 389 func, rid, ctx->domain, ctx->mgaw, ctx->agaw, 390 id_mapped ? "id" : "re"); 391 } else { 392 dmar_ctx_dtr(ctx1, true, true); 393 } |
392 dmar_unmap_pgtbl(sf, DMAR_IS_COHERENT(dmar)); | 394 dmar_unmap_pgtbl(sf); |
393 } 394 ctx->refs++; 395 if ((ctx->flags & DMAR_CTX_RMRR) != 0) 396 ctx->refs++; /* XXXKIB */ 397 398 /* 399 * If dmar declares Caching Mode as Set, follow 11.5 "Caching 400 * Mode Consideration" and do the (global) invalidation of the --- 74 unchanged lines hidden (view full) --- 475 476 /* 477 * Other thread might have referenced the context, in which 478 * case again only the dereference should be performed. 479 */ 480 if (ctx->refs > 1) { 481 ctx->refs--; 482 DMAR_UNLOCK(dmar); | 395 } 396 ctx->refs++; 397 if ((ctx->flags & DMAR_CTX_RMRR) != 0) 398 ctx->refs++; /* XXXKIB */ 399 400 /* 401 * If dmar declares Caching Mode as Set, follow 11.5 "Caching 402 * Mode Consideration" and do the (global) invalidation of the --- 74 unchanged lines hidden (view full) --- 477 478 /* 479 * Other thread might have referenced the context, in which 480 * case again only the dereference should be performed. 481 */ 482 if (ctx->refs > 1) { 483 ctx->refs--; 484 DMAR_UNLOCK(dmar); |
483 dmar_unmap_pgtbl(sf, DMAR_IS_COHERENT(dmar)); | 485 dmar_unmap_pgtbl(sf); |
484 TD_PINNED_ASSERT; 485 return; 486 } 487 488 KASSERT((ctx->flags & DMAR_CTX_RMRR) == 0, 489 ("lost ref on RMRR ctx %p", ctx)); 490 KASSERT((ctx->flags & DMAR_CTX_DISABLED) == 0, 491 ("lost ref on disabled ctx %p", ctx)); 492 493 /* 494 * Clear the context pointer and flush the caches. 495 * XXXKIB: cannot do this if any RMRR entries are still present. 496 */ 497 dmar_pte_clear(&ctxp->ctx1); 498 ctxp->ctx2 = 0; | 486 TD_PINNED_ASSERT; 487 return; 488 } 489 490 KASSERT((ctx->flags & DMAR_CTX_RMRR) == 0, 491 ("lost ref on RMRR ctx %p", ctx)); 492 KASSERT((ctx->flags & DMAR_CTX_DISABLED) == 0, 493 ("lost ref on disabled ctx %p", ctx)); 494 495 /* 496 * Clear the context pointer and flush the caches. 497 * XXXKIB: cannot do this if any RMRR entries are still present. 498 */ 499 dmar_pte_clear(&ctxp->ctx1); 500 ctxp->ctx2 = 0; |
501 dmar_flush_ctx_to_ram(dmar, ctxp); |
|
499 dmar_inv_ctx_glob(dmar); 500 if ((dmar->hw_ecap & DMAR_ECAP_DI) != 0) { 501 if (dmar->qi_enabled) 502 dmar_qi_invalidate_iotlb_glob_locked(dmar); 503 else 504 dmar_inv_iotlb_glob(dmar); 505 } 506 LIST_REMOVE(ctx, link); 507 DMAR_UNLOCK(dmar); 508 509 /* 510 * The rest of the destruction is invisible for other users of 511 * the dmar unit. 512 */ 513 taskqueue_drain(dmar->delayed_taskqueue, &ctx->unload_task); 514 KASSERT(TAILQ_EMPTY(&ctx->unload_entries), 515 ("unfinished unloads %p", ctx)); | 502 dmar_inv_ctx_glob(dmar); 503 if ((dmar->hw_ecap & DMAR_ECAP_DI) != 0) { 504 if (dmar->qi_enabled) 505 dmar_qi_invalidate_iotlb_glob_locked(dmar); 506 else 507 dmar_inv_iotlb_glob(dmar); 508 } 509 LIST_REMOVE(ctx, link); 510 DMAR_UNLOCK(dmar); 511 512 /* 513 * The rest of the destruction is invisible for other users of 514 * the dmar unit. 515 */ 516 taskqueue_drain(dmar->delayed_taskqueue, &ctx->unload_task); 517 KASSERT(TAILQ_EMPTY(&ctx->unload_entries), 518 ("unfinished unloads %p", ctx)); |
516 dmar_unmap_pgtbl(sf, DMAR_IS_COHERENT(dmar)); | 519 dmar_unmap_pgtbl(sf); |
517 free_unr(dmar->domids, ctx->domain); 518 dmar_ctx_dtr(ctx, true, true); 519 TD_PINNED_ASSERT; 520} 521 522void 523dmar_free_ctx(struct dmar_ctx *ctx) 524{ --- 123 unchanged lines hidden --- | 520 free_unr(dmar->domids, ctx->domain); 521 dmar_ctx_dtr(ctx, true, true); 522 TD_PINNED_ASSERT; 523} 524 525void 526dmar_free_ctx(struct dmar_ctx *ctx) 527{ --- 123 unchanged lines hidden --- |