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