Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>

*** 22,32 **** * 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 (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ --- 22,32 ---- * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved. ! * Copyright 2018 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */
*** 362,372 **** --- 362,457 ---- #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)