Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
@@ -22,11 +22,11 @@
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -362,11 +362,96 @@
#define CONTIG_LOCK() mutex_enter(&contig_lock);
#define CONTIG_UNLOCK() mutex_exit(&contig_lock);
#define PFN_16M (mmu_btop((uint64_t)0x1000000))
+caddr_t
+i86devmap(pfn_t pf, pgcnt_t pgcnt, uint_t prot)
+{
+ caddr_t addr;
+ caddr_t addr1;
+ page_t *pp;
+
+ addr1 = addr = vmem_alloc(heap_arena, mmu_ptob(pgcnt), VM_SLEEP);
+
+ for (; pgcnt != 0; addr += MMU_PAGESIZE, ++pf, --pgcnt) {
+ pp = page_numtopp_nolock(pf);
+ if (pp == NULL) {
+ hat_devload(kas.a_hat, addr, MMU_PAGESIZE, pf,
+ prot | HAT_NOSYNC, HAT_LOAD_LOCK);
+ } else {
+ hat_memload(kas.a_hat, addr, pp,
+ prot | HAT_NOSYNC, HAT_LOAD_LOCK);
+ }
+ }
+
+ return (addr1);
+}
+
/*
+ * This routine is like page_numtopp, but accepts only free pages, which
+ * it allocates (unfrees) and returns with the exclusive lock held.
+ * It is used by machdep.c/dma_init() to find contiguous free pages.
+ */
+page_t *
+page_numtopp_alloc(pfn_t pfnum)
+{
+ page_t *pp;
+
+retry:
+ pp = page_numtopp_nolock(pfnum);
+ if (pp == NULL) {
+ return (NULL);
+ }
+
+ if (!page_trylock(pp, SE_EXCL)) {
+ return (NULL);
+ }
+
+ if (page_pptonum(pp) != pfnum) {
+ page_unlock(pp);
+ goto retry;
+ }
+
+ if (!PP_ISFREE(pp)) {
+ page_unlock(pp);
+ return (NULL);
+ }
+ if (pp->p_szc) {
+ page_demote_free_pages(pp);
+ page_unlock(pp);
+ goto retry;
+ }
+
+ /* If associated with a vnode, destroy mappings */
+
+ if (pp->p_vnode) {
+
+ page_destroy_free(pp);
+
+ if (!page_lock(pp, SE_EXCL, (kmutex_t *)NULL, P_NO_RECLAIM)) {
+ return (NULL);
+ }
+
+ if (page_pptonum(pp) != pfnum) {
+ page_unlock(pp);
+ goto retry;
+ }
+ }
+
+ if (!PP_ISFREE(pp)) {
+ page_unlock(pp);
+ return (NULL);
+ }
+
+ if (!page_reclaim(pp, (kmutex_t *)NULL))
+ return (NULL);
+
+ return (pp);
+}
+
+/*
* Return the optimum page size for a given mapping
*/
/*ARGSUSED*/
size_t
map_pgsz(int maptype, struct proc *p, caddr_t addr, size_t len, int memcntl)