1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #ifndef _VM_XHAT_H 28*0Sstevel@tonic-gate #define _VM_XHAT_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #ifdef __cplusplus 34*0Sstevel@tonic-gate extern "C" { 35*0Sstevel@tonic-gate #endif 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate #ifndef _ASM 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate #include <sys/types.h> 40*0Sstevel@tonic-gate #include <vm/page.h> 41*0Sstevel@tonic-gate #include <sys/kmem.h> 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate struct xhat; 44*0Sstevel@tonic-gate struct xhat_hme_blk; 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate struct xhat_ops { 47*0Sstevel@tonic-gate struct xhat *(*xhat_alloc)(void *); 48*0Sstevel@tonic-gate void (*xhat_free)(struct xhat *); 49*0Sstevel@tonic-gate void (*xhat_free_start)(struct xhat *); 50*0Sstevel@tonic-gate void (*xhat_free_end)(struct xhat *); 51*0Sstevel@tonic-gate int (*xhat_dup)(struct xhat *, struct xhat *, caddr_t, 52*0Sstevel@tonic-gate size_t, uint_t); 53*0Sstevel@tonic-gate void (*xhat_swapin)(struct xhat *); 54*0Sstevel@tonic-gate void (*xhat_swapout)(struct xhat *); 55*0Sstevel@tonic-gate void (*xhat_memload)(struct xhat *, caddr_t, struct page *, 56*0Sstevel@tonic-gate uint_t, uint_t); 57*0Sstevel@tonic-gate void (*xhat_memload_array)(struct xhat *, caddr_t, size_t, 58*0Sstevel@tonic-gate struct page **, uint_t, uint_t); 59*0Sstevel@tonic-gate void (*xhat_devload)(struct xhat *, caddr_t, size_t, pfn_t, 60*0Sstevel@tonic-gate uint_t, int); 61*0Sstevel@tonic-gate void (*xhat_unload)(struct xhat *, caddr_t, size_t, uint_t); 62*0Sstevel@tonic-gate void (*xhat_unload_callback)(struct xhat *, caddr_t, size_t, 63*0Sstevel@tonic-gate uint_t, hat_callback_t *); 64*0Sstevel@tonic-gate void (*xhat_setattr)(struct xhat *, caddr_t, size_t, uint_t); 65*0Sstevel@tonic-gate void (*xhat_clrattr)(struct xhat *, caddr_t, size_t, uint_t); 66*0Sstevel@tonic-gate void (*xhat_chgattr)(struct xhat *, caddr_t, size_t, uint_t); 67*0Sstevel@tonic-gate void (*xhat_unshare)(struct xhat *, caddr_t, size_t); 68*0Sstevel@tonic-gate void (*xhat_chgprot)(struct xhat *, caddr_t, size_t, uint_t); 69*0Sstevel@tonic-gate int (*xhat_pageunload)(struct xhat *, struct page *, uint_t, 70*0Sstevel@tonic-gate void *); 71*0Sstevel@tonic-gate }; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate #define XHAT_POPS(_p) (_p)->xhat_provider_ops 75*0Sstevel@tonic-gate #define XHAT_PROPS(_h) XHAT_POPS(((struct xhat *)(_h))->xhat_provider) 76*0Sstevel@tonic-gate #define XHAT_HOPS(hat, func, args) \ 77*0Sstevel@tonic-gate { \ 78*0Sstevel@tonic-gate if (XHAT_PROPS(hat)-> /* */ func) \ 79*0Sstevel@tonic-gate XHAT_PROPS(hat)-> /* */ func /* */ args; \ 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate #define XHAT_FREE_START(a) \ 83*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_free_start, ((struct xhat *)(a))) 84*0Sstevel@tonic-gate #define XHAT_FREE_END(a) \ 85*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_free_end, ((struct xhat *)(a))) 86*0Sstevel@tonic-gate #define XHAT_DUP(a, b, c, d, e) \ 87*0Sstevel@tonic-gate ((XHAT_PROPS(a)->xhat_dup == NULL) ? (0) : \ 88*0Sstevel@tonic-gate XHAT_PROPS(a)->xhat_dup((struct xhat *)(a), \ 89*0Sstevel@tonic-gate (struct xhat *)(b), c, d, e)) 90*0Sstevel@tonic-gate #define XHAT_SWAPIN(a) \ 91*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_swapin, ((struct xhat *)(a))) 92*0Sstevel@tonic-gate #define XHAT_SWAPOUT(a) \ 93*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_swapout, ((struct xhat *)(a))) 94*0Sstevel@tonic-gate #define XHAT_MEMLOAD(a, b, c, d, e) \ 95*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_memload, ((struct xhat *)(a), b, c, d, e)) 96*0Sstevel@tonic-gate #define XHAT_MEMLOAD_ARRAY(a, b, c, d, e, f) \ 97*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_memload_array, ((struct xhat *)(a), b, c, d, e, f)) 98*0Sstevel@tonic-gate #define XHAT_DEVLOAD(a, b, c, d, e, f) \ 99*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_devload, ((struct xhat *)(a), b, c, d, e, f)) 100*0Sstevel@tonic-gate #define XHAT_UNLOAD(a, b, c, d) \ 101*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_unload, ((struct xhat *)(a), b, c, d)) 102*0Sstevel@tonic-gate #define XHAT_UNLOAD_CALLBACK(a, b, c, d, e) \ 103*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_unload_callback, ((struct xhat *)(a), b, c, d, e)) 104*0Sstevel@tonic-gate #define XHAT_SETATTR(a, b, c, d) \ 105*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_setattr, ((struct xhat *)(a), b, c, d)) 106*0Sstevel@tonic-gate #define XHAT_CLRATTR(a, b, c, d) \ 107*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_clrattr, ((struct xhat *)(a), b, c, d)) 108*0Sstevel@tonic-gate #define XHAT_CHGATTR(a, b, c, d) \ 109*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_chgattr, ((struct xhat *)(a), b, c, d)) 110*0Sstevel@tonic-gate #define XHAT_UNSHARE(a, b, c) \ 111*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_unshare, ((struct xhat *)(a), b, c)) 112*0Sstevel@tonic-gate #define XHAT_CHGPROT(a, b, c, d) \ 113*0Sstevel@tonic-gate XHAT_HOPS(a, xhat_chgprot, ((struct xhat *)(a), b, c, d)) 114*0Sstevel@tonic-gate #define XHAT_PAGEUNLOAD(a, b, c, d) \ 115*0Sstevel@tonic-gate ((XHAT_PROPS(a)->xhat_pageunload == NULL) ? (0) : \ 116*0Sstevel@tonic-gate XHAT_PROPS(a)->xhat_pageunload((struct xhat *)(a), b, c, d)) 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate #define XHAT_PROVIDER_VERSION 1 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate /* 123*0Sstevel@tonic-gate * Provider name will be appended with "_cache" 124*0Sstevel@tonic-gate * when initializing kmem cache. 125*0Sstevel@tonic-gate * The resulting sring must be less than 126*0Sstevel@tonic-gate * KMEM_CACHE_NAMELEN 127*0Sstevel@tonic-gate */ 128*0Sstevel@tonic-gate #define XHAT_CACHE_NAMELEN 24 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate typedef struct xblk_cache { 131*0Sstevel@tonic-gate kmutex_t lock; 132*0Sstevel@tonic-gate kmem_cache_t *cache; 133*0Sstevel@tonic-gate void *free_blks; 134*0Sstevel@tonic-gate void (*reclaim)(void *); 135*0Sstevel@tonic-gate } xblk_cache_t; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate typedef struct xhat_provider { 138*0Sstevel@tonic-gate int xhat_provider_version; 139*0Sstevel@tonic-gate int xhat_provider_refcnt; 140*0Sstevel@tonic-gate struct xhat_provider *next; 141*0Sstevel@tonic-gate struct xhat_provider *prev; 142*0Sstevel@tonic-gate char xhat_provider_name[XHAT_CACHE_NAMELEN]; 143*0Sstevel@tonic-gate xblk_cache_t *xblkcache; 144*0Sstevel@tonic-gate struct xhat_ops *xhat_provider_ops; 145*0Sstevel@tonic-gate int xhat_provider_blk_size; 146*0Sstevel@tonic-gate } xhat_provider_t; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate /* 149*0Sstevel@tonic-gate * The xhat structure is protected by xhat_lock. 150*0Sstevel@tonic-gate * A particular xhat implementation is a extension of the 151*0Sstevel@tonic-gate * xhat structure and may contain its own lock(s) to 152*0Sstevel@tonic-gate * protect those additional fields. 153*0Sstevel@tonic-gate * The xhat structure is never allocated directly. 154*0Sstevel@tonic-gate * Instead its allocation is provided by the hat implementation. 155*0Sstevel@tonic-gate * The xhat provider ops xhat_alloc/xhat_free are used to 156*0Sstevel@tonic-gate * alloc/free a implementation dependant xhat structure. 157*0Sstevel@tonic-gate */ 158*0Sstevel@tonic-gate struct xhat { 159*0Sstevel@tonic-gate xhat_provider_t *xhat_provider; 160*0Sstevel@tonic-gate struct as *xhat_as; 161*0Sstevel@tonic-gate void *arg; 162*0Sstevel@tonic-gate struct xhat *prev; 163*0Sstevel@tonic-gate struct xhat *next; 164*0Sstevel@tonic-gate kmutex_t xhat_lock; 165*0Sstevel@tonic-gate int xhat_refcnt; 166*0Sstevel@tonic-gate kthread_t *holder; 167*0Sstevel@tonic-gate }; 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate /* Error codes */ 171*0Sstevel@tonic-gate #define XH_PRVDR (1) /* Provider-specific error */ 172*0Sstevel@tonic-gate #define XH_ASBUSY (2) /* Address space is busy */ 173*0Sstevel@tonic-gate #define XH_XHHELD (3) /* XHAT is being held */ 174*0Sstevel@tonic-gate #define XH_NOTATTCHD (4) /* Provider is not attached to as */ 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate int xhat_provider_register(xhat_provider_t *); 178*0Sstevel@tonic-gate int xhat_provider_unregister(xhat_provider_t *); 179*0Sstevel@tonic-gate void xhat_init(void); 180*0Sstevel@tonic-gate int xhat_attach_xhat(xhat_provider_t *, struct as *, struct xhat **, 181*0Sstevel@tonic-gate void *); 182*0Sstevel@tonic-gate int xhat_detach_xhat(xhat_provider_t *, struct as *); 183*0Sstevel@tonic-gate pfn_t xhat_insert_xhatblk(page_t *, struct xhat *, void **); 184*0Sstevel@tonic-gate int xhat_delete_xhatblk(void *, int); 185*0Sstevel@tonic-gate void xhat_hat_hold(struct xhat *); 186*0Sstevel@tonic-gate void xhat_hat_rele(struct xhat *); 187*0Sstevel@tonic-gate int xhat_hat_holders(struct xhat *); 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate void xhat_free_start_all(struct as *); 190*0Sstevel@tonic-gate void xhat_free_end_all(struct as *); 191*0Sstevel@tonic-gate int xhat_dup_all(struct as *, struct as *, caddr_t, size_t, uint_t); 192*0Sstevel@tonic-gate void xhat_swapout_all(struct as *); 193*0Sstevel@tonic-gate void xhat_unload_callback_all(struct as *, caddr_t, size_t, uint_t, 194*0Sstevel@tonic-gate hat_callback_t *); 195*0Sstevel@tonic-gate void xhat_setattr_all(struct as *, caddr_t, size_t, uint_t); 196*0Sstevel@tonic-gate void xhat_clrattr_all(struct as *, caddr_t, size_t, uint_t); 197*0Sstevel@tonic-gate void xhat_chgattr_all(struct as *, caddr_t, size_t, uint_t); 198*0Sstevel@tonic-gate void xhat_chgprot_all(struct as *, caddr_t, size_t, uint_t); 199*0Sstevel@tonic-gate void xhat_unshare_all(struct as *, caddr_t, size_t); 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate #endif /* _ASM */ 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate #ifdef __cplusplus 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate #endif 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate #endif /* _VM_XHAT_H */ 209