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 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 #ifndef _ASM
  35 
  36 #include <sys/types.h>
  37 #include <vm/page.h>
  38 #include <sys/kmem.h>
  39 
  40 struct xhat;
  41 struct xhat_hme_blk;
  42 
  43 struct xhat_ops {
  44         struct xhat     *(*xhat_alloc)(void *);
  45         void            (*xhat_free)(struct xhat *);
  46         void            (*xhat_free_start)(struct xhat *);
  47         void            (*xhat_free_end)(struct xhat *);
  48         int             (*xhat_dup)(struct xhat *, struct xhat *, caddr_t,
  49             size_t, uint_t);
  50         void            (*xhat_memload)(struct xhat *, caddr_t, struct page *,
  51                             uint_t, uint_t);
  52         void            (*xhat_memload_array)(struct xhat *, caddr_t, size_t,
  53                             struct page **, uint_t, uint_t);
  54         void            (*xhat_devload)(struct xhat *, caddr_t, size_t, pfn_t,
  55             uint_t, int);
  56         void            (*xhat_unload)(struct xhat *, caddr_t, size_t, uint_t);
  57         void            (*xhat_unload_callback)(struct xhat *, caddr_t, size_t,
  58             uint_t, hat_callback_t *);
  59         void            (*xhat_setattr)(struct xhat *, caddr_t, size_t, uint_t);
  60         void            (*xhat_clrattr)(struct xhat *, caddr_t, size_t, uint_t);
  61         void            (*xhat_chgattr)(struct xhat *, caddr_t, size_t, uint_t);
  62         void            (*xhat_unshare)(struct xhat *, caddr_t, size_t);
  63         void            (*xhat_chgprot)(struct xhat *, caddr_t, size_t, uint_t);
  64         int             (*xhat_pageunload)(struct xhat *, struct page *, uint_t,
  65                             void *);
  66 };
  67 
  68 
  69 #define XHAT_POPS(_p)   (_p)->xhat_provider_ops
  70 #define XHAT_PROPS(_h)  XHAT_POPS(((struct xhat *)(_h))->xhat_provider)
  71 #define XHAT_HOPS(hat, func, args) \
  72         { \
  73                 if (XHAT_PROPS(hat)-> /* */ func) \
  74                         XHAT_PROPS(hat)-> /* */ func /* */ args; \
  75         }
  76 
  77 #define XHAT_FREE_START(a) \
  78         XHAT_HOPS(a, xhat_free_start, ((struct xhat *)(a)))
  79 #define XHAT_FREE_END(a) \
  80         XHAT_HOPS(a, xhat_free_end, ((struct xhat *)(a)))
  81 #define XHAT_DUP(a, b, c, d, e) \
  82         ((XHAT_PROPS(a)->xhat_dup == NULL) ? (0) : \
  83         XHAT_PROPS(a)->xhat_dup((struct xhat *)(a), \
  84                                 (struct xhat *)(b), c, d, e))
  85 #define XHAT_MEMLOAD(a, b, c, d, e) \
  86         XHAT_HOPS(a, xhat_memload, ((struct xhat *)(a), b, c, d, e))
  87 #define XHAT_MEMLOAD_ARRAY(a, b, c, d, e, f) \
  88         XHAT_HOPS(a, xhat_memload_array, ((struct xhat *)(a), b, c, d, e, f))
  89 #define XHAT_DEVLOAD(a, b, c, d, e, f) \
  90         XHAT_HOPS(a, xhat_devload, ((struct xhat *)(a), b, c, d, e, f))
  91 #define XHAT_UNLOAD(a, b, c, d) \
  92         XHAT_HOPS(a, xhat_unload, ((struct xhat *)(a), b, c, d))
  93 #define XHAT_UNLOAD_CALLBACK(a, b, c, d, e) \
  94         XHAT_HOPS(a, xhat_unload_callback, ((struct xhat *)(a), b, c, d, e))
  95 #define XHAT_SETATTR(a, b, c, d) \
  96         XHAT_HOPS(a, xhat_setattr, ((struct xhat *)(a), b, c, d))
  97 #define XHAT_CLRATTR(a, b, c, d) \
  98         XHAT_HOPS(a, xhat_clrattr, ((struct xhat *)(a), b, c, d))
  99 #define XHAT_CHGATTR(a, b, c, d) \
 100         XHAT_HOPS(a, xhat_chgattr, ((struct xhat *)(a), b, c, d))
 101 #define XHAT_UNSHARE(a, b, c) \
 102         XHAT_HOPS(a, xhat_unshare, ((struct xhat *)(a), b, c))
 103 #define XHAT_CHGPROT(a, b, c, d) \
 104         XHAT_HOPS(a, xhat_chgprot, ((struct xhat *)(a), b, c, d))
 105 #define XHAT_PAGEUNLOAD(a, b, c, d) \
 106         ((XHAT_PROPS(a)->xhat_pageunload == NULL) ? (0) : \
 107         XHAT_PROPS(a)->xhat_pageunload((struct xhat *)(a), b, c, d))
 108 
 109 
 110 
 111 #define XHAT_PROVIDER_VERSION   1
 112 
 113 /*
 114  * Provider name will be appended with "_cache"
 115  * when initializing kmem cache.
 116  * The resulting sring must be less than
 117  * KMEM_CACHE_NAMELEN
 118  */
 119 #define XHAT_CACHE_NAMELEN      24
 120 
 121 typedef struct xblk_cache {
 122         kmutex_t        lock;
 123         kmem_cache_t    *cache;
 124         void            *free_blks;
 125         void            (*reclaim)(void *);
 126 } xblk_cache_t;
 127 
 128 typedef struct xhat_provider {
 129         int             xhat_provider_version;
 130         int             xhat_provider_refcnt;
 131         struct xhat_provider *next;
 132         struct xhat_provider *prev;
 133         char            xhat_provider_name[XHAT_CACHE_NAMELEN];
 134         xblk_cache_t    *xblkcache;
 135         struct xhat_ops *xhat_provider_ops;
 136         int             xhat_provider_blk_size;
 137 } xhat_provider_t;
 138 
 139 /*
 140  * The xhat structure is protected by xhat_lock.
 141  * A particular xhat implementation is a extension of the
 142  * xhat structure and may contain its own lock(s) to
 143  * protect those additional fields.
 144  * The xhat structure is never allocated directly.
 145  * Instead its allocation is provided by the hat implementation.
 146  * The xhat provider ops xhat_alloc/xhat_free are used to
 147  * alloc/free a implementation dependant xhat structure.
 148  */
 149 struct xhat {
 150         xhat_provider_t         *xhat_provider;
 151         struct as               *xhat_as;
 152         void                    *arg;
 153         struct xhat             *prev;
 154         struct xhat             *next;
 155         kmutex_t                xhat_lock;
 156         int                     xhat_refcnt;
 157         kthread_t               *holder;
 158 };
 159 
 160 
 161 /* Error codes */
 162 #define XH_PRVDR        (1)     /* Provider-specific error */
 163 #define XH_ASBUSY       (2)     /* Address space is busy */
 164 #define XH_XHHELD       (3)     /* XHAT is being held */
 165 #define XH_NOTATTCHD    (4)     /* Provider is not attached to as */
 166 
 167 
 168 int     xhat_provider_register(xhat_provider_t *);
 169 int     xhat_provider_unregister(xhat_provider_t *);
 170 void    xhat_init(void);
 171 int     xhat_attach_xhat(xhat_provider_t *, struct as *, struct xhat **,
 172     void *);
 173 int     xhat_detach_xhat(xhat_provider_t *, struct as *);
 174 pfn_t   xhat_insert_xhatblk(page_t *, struct xhat *, void **);
 175 int     xhat_delete_xhatblk(void *, int);
 176 void    xhat_hat_hold(struct xhat *);
 177 void    xhat_hat_rele(struct xhat *);
 178 int     xhat_hat_holders(struct xhat *);
 179 
 180 void    xhat_free_start_all(struct as *);
 181 void    xhat_free_end_all(struct as *);
 182 int     xhat_dup_all(struct as *, struct as *, caddr_t, size_t, uint_t);
 183 void    xhat_unload_callback_all(struct as *, caddr_t, size_t, uint_t,
 184     hat_callback_t *);
 185 void    xhat_setattr_all(struct as *, caddr_t, size_t, uint_t);
 186 void    xhat_clrattr_all(struct as *, caddr_t, size_t, uint_t);
 187 void    xhat_chgattr_all(struct as *, caddr_t, size_t, uint_t);
 188 void    xhat_chgprot_all(struct as *, caddr_t, size_t, uint_t);
 189 void    xhat_unshare_all(struct as *, caddr_t, size_t);
 190 
 191 
 192 #endif /* _ASM */
 193 
 194 #ifdef  __cplusplus
 195 }
 196 #endif
 197 
 198 #endif  /* _VM_XHAT_H */