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