Print this page
5042 stop using deprecated atomic functions


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #include <sys/types.h>
  29 #include <sys/errno.h>
  30 #include <sys/systm.h>
  31 #include <sys/atomic.h>
  32 #include <sys/kmem.h>
  33 #include <sys/machpcb.h>
  34 #include <sys/utrap.h>
  35 #include <sys/model.h>
  36 
  37 int
  38 install_utrap(utrap_entry_t type, utrap_handler_t new_handler,
  39         utrap_handler_t *old_handlerp)
  40 {
  41         struct proc *p = curthread->t_procp;
  42         utrap_handler_t *ov, *nv, *pv, *sv, *tmp;
  43         caddr32_t nv32;
  44         int idx;
  45 
  46         /*
  47          * Check trap number.


  64         default:
  65                 return ((int)set_errno(EINVAL));
  66         }
  67         if (get_udatamodel() == DATAMODEL_LP64)
  68                 return ((int)set_errno(EINVAL));
  69 
  70         /*
  71          * Be sure handler address is word aligned.  The uintptr_t casts are
  72          * there to prevent warnings when using a certain compiler, and the
  73          * temporary 32 bit variable is intended to ensure proper code
  74          * generation and avoid a messy quadruple cast.
  75          */
  76         nv32 = (caddr32_t)(uintptr_t)new_handler;
  77         nv = (utrap_handler_t *)(uintptr_t)nv32;
  78         if (nv != UTRAP_UTH_NOCHANGE) {
  79                 if (((uintptr_t)nv) & 0x3)
  80                         return ((int)set_errno(EINVAL));
  81         }
  82         /*
  83          * Allocate proc space for saving the addresses to these user
  84          * trap handlers, which must later be freed. Use casptr to
  85          * do this atomically.
  86          */
  87         if (p->p_utraps == NULL) {
  88                 pv = sv = kmem_zalloc((UT_PRECISE_MAXTRAPS+1) *
  89                     sizeof (utrap_handler_t *), KM_SLEEP);
  90                 tmp = casptr(&p->p_utraps, NULL, sv);
  91                 if (tmp != NULL) {
  92                         kmem_free(pv, (UT_PRECISE_MAXTRAPS+1) *
  93                             sizeof (utrap_handler_t *));
  94                 }
  95         }
  96         ASSERT(p->p_utraps != NULL);
  97 
  98         /*
  99          * Use casptr to atomically install the handler.
 100          */
 101         ov = p->p_utraps[idx];
 102         if (new_handler != (utrap_handler_t)UTRAP_UTH_NOCHANGE) {
 103                 for (;;) {
 104                         tmp = casptr(&p->p_utraps[idx], ov, nv);
 105                         if (ov == tmp)
 106                                 break;
 107                         ov = tmp;
 108                 }
 109         }
 110         if (old_handlerp != NULL) {
 111                 if (suword32(old_handlerp, (uint32_t)(uintptr_t)ov) == -1)
 112                         return ((int)set_errno(EINVAL));
 113         }
 114         return (0);
 115 }
 116 
 117 void
 118 utrap_dup(struct proc *pp, struct proc *cp)
 119 {
 120         if (pp->p_utraps != NULL) {
 121                 cp->p_utraps = kmem_alloc((UT_PRECISE_MAXTRAPS+1) *
 122                     sizeof (utrap_handler_t *), KM_SLEEP);
 123                 bcopy(pp->p_utraps, cp->p_utraps,
 124                     (UT_PRECISE_MAXTRAPS+1) * sizeof (utrap_handler_t *));


 208                 break;
 209         default:
 210                 return ((int)set_errno(EINVAL));
 211         }
 212 
 213         if (get_udatamodel() == DATAMODEL_ILP32)
 214                 return ((int)set_errno(EINVAL));
 215 
 216         /*
 217          * Be sure handler address is word aligned.
 218          * There are no deferred traps, so ignore them.
 219          */
 220         nvp = (utrap_handler_t *)new_precise;
 221         if (nvp != UTRAP_UTH_NOCHANGE) {
 222                 if (((uintptr_t)nvp) & 0x3)
 223                         return ((int)set_errno(EINVAL));
 224         }
 225 
 226         /*
 227          * Allocate proc space for saving the addresses to these user
 228          * trap handlers, which must later be freed. Use casptr to
 229          * do this atomically.
 230          */
 231         if (p->p_utraps == NULL) {
 232                 pv = sv = kmem_zalloc((UT_PRECISE_MAXTRAPS+1) *
 233                     sizeof (utrap_handler_t *), KM_SLEEP);
 234                 tmp = casptr(&p->p_utraps, NULL, sv);
 235                 if (tmp != NULL) {
 236                         kmem_free(pv, (UT_PRECISE_MAXTRAPS+1) *
 237                             sizeof (utrap_handler_t *));
 238                 }
 239         }
 240         ASSERT(p->p_utraps != NULL);
 241 
 242         /*
 243          * Use casptr to atomically install the handlers.
 244          */
 245         ov = p->p_utraps[idx];
 246         if (new_precise != (utrap_handler_t)UTH_NOCHANGE) {
 247                 for (;;) {
 248                         tmp = casptr(&p->p_utraps[idx], ov, nvp);
 249                         if (ov == tmp)
 250                                 break;
 251                         ov = tmp;
 252                 }
 253         }
 254         if (old_precise != NULL) {
 255                 if (suword64(old_precise, (uint64_t)ov) == -1)
 256                         return ((int)set_errno(EINVAL));
 257         }
 258         return (0);
 259 }


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 


  26 #include <sys/types.h>
  27 #include <sys/errno.h>
  28 #include <sys/systm.h>
  29 #include <sys/atomic.h>
  30 #include <sys/kmem.h>
  31 #include <sys/machpcb.h>
  32 #include <sys/utrap.h>
  33 #include <sys/model.h>
  34 
  35 int
  36 install_utrap(utrap_entry_t type, utrap_handler_t new_handler,
  37         utrap_handler_t *old_handlerp)
  38 {
  39         struct proc *p = curthread->t_procp;
  40         utrap_handler_t *ov, *nv, *pv, *sv, *tmp;
  41         caddr32_t nv32;
  42         int idx;
  43 
  44         /*
  45          * Check trap number.


  62         default:
  63                 return ((int)set_errno(EINVAL));
  64         }
  65         if (get_udatamodel() == DATAMODEL_LP64)
  66                 return ((int)set_errno(EINVAL));
  67 
  68         /*
  69          * Be sure handler address is word aligned.  The uintptr_t casts are
  70          * there to prevent warnings when using a certain compiler, and the
  71          * temporary 32 bit variable is intended to ensure proper code
  72          * generation and avoid a messy quadruple cast.
  73          */
  74         nv32 = (caddr32_t)(uintptr_t)new_handler;
  75         nv = (utrap_handler_t *)(uintptr_t)nv32;
  76         if (nv != UTRAP_UTH_NOCHANGE) {
  77                 if (((uintptr_t)nv) & 0x3)
  78                         return ((int)set_errno(EINVAL));
  79         }
  80         /*
  81          * Allocate proc space for saving the addresses to these user
  82          * trap handlers, which must later be freed. Use atomic_cas_ptr to
  83          * do this atomically.
  84          */
  85         if (p->p_utraps == NULL) {
  86                 pv = sv = kmem_zalloc((UT_PRECISE_MAXTRAPS+1) *
  87                     sizeof (utrap_handler_t *), KM_SLEEP);
  88                 tmp = atomic_cas_ptr(&p->p_utraps, NULL, sv);
  89                 if (tmp != NULL) {
  90                         kmem_free(pv, (UT_PRECISE_MAXTRAPS+1) *
  91                             sizeof (utrap_handler_t *));
  92                 }
  93         }
  94         ASSERT(p->p_utraps != NULL);
  95 
  96         /*
  97          * Use atomic_cas_ptr to atomically install the handler.
  98          */
  99         ov = p->p_utraps[idx];
 100         if (new_handler != (utrap_handler_t)UTRAP_UTH_NOCHANGE) {
 101                 for (;;) {
 102                         tmp = atomic_cas_ptr(&p->p_utraps[idx], ov, nv);
 103                         if (ov == tmp)
 104                                 break;
 105                         ov = tmp;
 106                 }
 107         }
 108         if (old_handlerp != NULL) {
 109                 if (suword32(old_handlerp, (uint32_t)(uintptr_t)ov) == -1)
 110                         return ((int)set_errno(EINVAL));
 111         }
 112         return (0);
 113 }
 114 
 115 void
 116 utrap_dup(struct proc *pp, struct proc *cp)
 117 {
 118         if (pp->p_utraps != NULL) {
 119                 cp->p_utraps = kmem_alloc((UT_PRECISE_MAXTRAPS+1) *
 120                     sizeof (utrap_handler_t *), KM_SLEEP);
 121                 bcopy(pp->p_utraps, cp->p_utraps,
 122                     (UT_PRECISE_MAXTRAPS+1) * sizeof (utrap_handler_t *));


 206                 break;
 207         default:
 208                 return ((int)set_errno(EINVAL));
 209         }
 210 
 211         if (get_udatamodel() == DATAMODEL_ILP32)
 212                 return ((int)set_errno(EINVAL));
 213 
 214         /*
 215          * Be sure handler address is word aligned.
 216          * There are no deferred traps, so ignore them.
 217          */
 218         nvp = (utrap_handler_t *)new_precise;
 219         if (nvp != UTRAP_UTH_NOCHANGE) {
 220                 if (((uintptr_t)nvp) & 0x3)
 221                         return ((int)set_errno(EINVAL));
 222         }
 223 
 224         /*
 225          * Allocate proc space for saving the addresses to these user
 226          * trap handlers, which must later be freed. Use atomic_cas_ptr to
 227          * do this atomically.
 228          */
 229         if (p->p_utraps == NULL) {
 230                 pv = sv = kmem_zalloc((UT_PRECISE_MAXTRAPS+1) *
 231                     sizeof (utrap_handler_t *), KM_SLEEP);
 232                 tmp = atomic_cas_ptr(&p->p_utraps, NULL, sv);
 233                 if (tmp != NULL) {
 234                         kmem_free(pv, (UT_PRECISE_MAXTRAPS+1) *
 235                             sizeof (utrap_handler_t *));
 236                 }
 237         }
 238         ASSERT(p->p_utraps != NULL);
 239 
 240         /*
 241          * Use atomic_cas_ptr to atomically install the handlers.
 242          */
 243         ov = p->p_utraps[idx];
 244         if (new_precise != (utrap_handler_t)UTH_NOCHANGE) {
 245                 for (;;) {
 246                         tmp = atomic_cas_ptr(&p->p_utraps[idx], ov, nvp);
 247                         if (ov == tmp)
 248                                 break;
 249                         ov = tmp;
 250                 }
 251         }
 252         if (old_precise != NULL) {
 253                 if (suword64(old_precise, (uint64_t)ov) == -1)
 254                         return ((int)set_errno(EINVAL));
 255         }
 256         return (0);
 257 }