Deleted Added
full compact
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 ---