Print this page
patch as-lock-macro-simplification


 152 
 153                 if (ddi_copyin(umme, mme, sizeof (*mme), mode)) {
 154                         error = EFAULT;
 155                         break;
 156                 }
 157 
 158                 DTRACE_XPV3(mmap__entry, ulong_t, mme->va, ulong_t, mme->mfn,
 159                     ulong_t, mme->npages);
 160 
 161                 if (mme->mfn == MFN_INVALID) {
 162                         error = EINVAL;
 163                         break;
 164                 }
 165 
 166                 addr = (caddr_t)mme->va;
 167 
 168                 /*
 169                  * Find the segment we want to mess with, then add
 170                  * the mfn range to the segment.
 171                  */
 172                 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
 173                 if ((seg = as_findseg(as, addr, 0)) == NULL ||
 174                     addr + mmu_ptob(mme->npages) > seg->s_base + seg->s_size)
 175                         error = EINVAL;
 176                 else
 177                         error = segmf_add_mfns(seg, addr,
 178                             mme->mfn, mme->npages, mmc->dom);
 179                 AS_LOCK_EXIT(as, &as->a_lock);
 180 
 181                 if (error != 0)
 182                         break;
 183         }
 184 
 185 done:
 186         DTRACE_XPV1(mmap__end, int, error);
 187 
 188         return (error);
 189 }
 190 
 191 /*
 192  * Set up the address range to map to an array of mfns in
 193  * a foreign domain.  Used in the following way:
 194  *
 195  *      privcmd_mmap_batch_t p;
 196  *
 197  *      addr = mmap(NULL, size, prot, MAP_SHARED, fd, 0);
 198  *      p.num = number of pages
 199  *      p.dom = domid


 202  *      ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &p);
 203  */
 204 /*ARGSUSED2*/
 205 static int
 206 do_privcmd_mmapbatch(void *uarg, int mode, cred_t *cr)
 207 {
 208         privcmd_mmapbatch_t __mmapbatch, *mmb = &__mmapbatch;
 209         struct as *as = curproc->p_as;
 210         struct seg *seg;
 211         int i, error = 0;
 212         caddr_t addr;
 213         ulong_t *ulp;
 214 
 215         if (ddi_copyin(uarg, mmb, sizeof (*mmb), mode))
 216                 return (EFAULT);
 217 
 218         DTRACE_XPV3(mmapbatch__start, domid_t, mmb->dom, int, mmb->num,
 219             caddr_t, mmb->addr);
 220 
 221         addr = (caddr_t)mmb->addr;
 222         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
 223         if ((seg = as_findseg(as, addr, 0)) == NULL ||
 224             addr + ptob(mmb->num) > seg->s_base + seg->s_size) {
 225                 error = EINVAL;
 226                 goto done;
 227         }
 228 
 229         for (i = 0, ulp = mmb->arr;
 230             i < mmb->num; i++, addr += PAGESIZE, ulp++) {
 231                 mfn_t mfn;
 232 
 233                 if (fulword(ulp, &mfn) != 0) {
 234                         error = EFAULT;
 235                         break;
 236                 }
 237 
 238                 if (mfn == MFN_INVALID) {
 239                         /*
 240                          * This mfn is invalid and should not be added to
 241                          * segmf, as we'd only cause an immediate EFAULT when
 242                          * we tried to fault it in.
 243                          */
 244                         mfn |= XEN_DOMCTL_PFINFO_XTAB;
 245                         continue;
 246                 }
 247 
 248                 if (segmf_add_mfns(seg, addr, mfn, 1, mmb->dom) == 0)
 249                         continue;
 250 
 251                 /*
 252                  * Tell the process that this MFN could not be mapped, so it
 253                  * won't later try to access it.
 254                  */
 255                 mfn |= XEN_DOMCTL_PFINFO_XTAB;
 256                 if (sulword(ulp, mfn) != 0) {
 257                         error = EFAULT;
 258                         break;
 259                 }
 260         }
 261 
 262 done:
 263         AS_LOCK_EXIT(as, &as->a_lock);
 264 
 265         DTRACE_XPV3(mmapbatch__end, int, error, struct seg *, seg, caddr_t,
 266             mmb->addr);
 267 
 268         return (error);
 269 }
 270 
 271 /*ARGSUSED*/
 272 static int
 273 privcmd_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rval)
 274 {
 275         if (secpolicy_xvm_control(cr))
 276                 return (EPERM);
 277 
 278         /*
 279          * Everything is a -native- data type.
 280          */
 281         if ((mode & FMODELS) != FNATIVE)
 282                 return (EOVERFLOW);
 283 




 152 
 153                 if (ddi_copyin(umme, mme, sizeof (*mme), mode)) {
 154                         error = EFAULT;
 155                         break;
 156                 }
 157 
 158                 DTRACE_XPV3(mmap__entry, ulong_t, mme->va, ulong_t, mme->mfn,
 159                     ulong_t, mme->npages);
 160 
 161                 if (mme->mfn == MFN_INVALID) {
 162                         error = EINVAL;
 163                         break;
 164                 }
 165 
 166                 addr = (caddr_t)mme->va;
 167 
 168                 /*
 169                  * Find the segment we want to mess with, then add
 170                  * the mfn range to the segment.
 171                  */
 172                 AS_LOCK_ENTER(as, RW_READER);
 173                 if ((seg = as_findseg(as, addr, 0)) == NULL ||
 174                     addr + mmu_ptob(mme->npages) > seg->s_base + seg->s_size)
 175                         error = EINVAL;
 176                 else
 177                         error = segmf_add_mfns(seg, addr,
 178                             mme->mfn, mme->npages, mmc->dom);
 179                 AS_LOCK_EXIT(as);
 180 
 181                 if (error != 0)
 182                         break;
 183         }
 184 
 185 done:
 186         DTRACE_XPV1(mmap__end, int, error);
 187 
 188         return (error);
 189 }
 190 
 191 /*
 192  * Set up the address range to map to an array of mfns in
 193  * a foreign domain.  Used in the following way:
 194  *
 195  *      privcmd_mmap_batch_t p;
 196  *
 197  *      addr = mmap(NULL, size, prot, MAP_SHARED, fd, 0);
 198  *      p.num = number of pages
 199  *      p.dom = domid


 202  *      ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &p);
 203  */
 204 /*ARGSUSED2*/
 205 static int
 206 do_privcmd_mmapbatch(void *uarg, int mode, cred_t *cr)
 207 {
 208         privcmd_mmapbatch_t __mmapbatch, *mmb = &__mmapbatch;
 209         struct as *as = curproc->p_as;
 210         struct seg *seg;
 211         int i, error = 0;
 212         caddr_t addr;
 213         ulong_t *ulp;
 214 
 215         if (ddi_copyin(uarg, mmb, sizeof (*mmb), mode))
 216                 return (EFAULT);
 217 
 218         DTRACE_XPV3(mmapbatch__start, domid_t, mmb->dom, int, mmb->num,
 219             caddr_t, mmb->addr);
 220 
 221         addr = (caddr_t)mmb->addr;
 222         AS_LOCK_ENTER(as, RW_READER);
 223         if ((seg = as_findseg(as, addr, 0)) == NULL ||
 224             addr + ptob(mmb->num) > seg->s_base + seg->s_size) {
 225                 error = EINVAL;
 226                 goto done;
 227         }
 228 
 229         for (i = 0, ulp = mmb->arr;
 230             i < mmb->num; i++, addr += PAGESIZE, ulp++) {
 231                 mfn_t mfn;
 232 
 233                 if (fulword(ulp, &mfn) != 0) {
 234                         error = EFAULT;
 235                         break;
 236                 }
 237 
 238                 if (mfn == MFN_INVALID) {
 239                         /*
 240                          * This mfn is invalid and should not be added to
 241                          * segmf, as we'd only cause an immediate EFAULT when
 242                          * we tried to fault it in.
 243                          */
 244                         mfn |= XEN_DOMCTL_PFINFO_XTAB;
 245                         continue;
 246                 }
 247 
 248                 if (segmf_add_mfns(seg, addr, mfn, 1, mmb->dom) == 0)
 249                         continue;
 250 
 251                 /*
 252                  * Tell the process that this MFN could not be mapped, so it
 253                  * won't later try to access it.
 254                  */
 255                 mfn |= XEN_DOMCTL_PFINFO_XTAB;
 256                 if (sulword(ulp, mfn) != 0) {
 257                         error = EFAULT;
 258                         break;
 259                 }
 260         }
 261 
 262 done:
 263         AS_LOCK_EXIT(as);
 264 
 265         DTRACE_XPV3(mmapbatch__end, int, error, struct seg *, seg, caddr_t,
 266             mmb->addr);
 267 
 268         return (error);
 269 }
 270 
 271 /*ARGSUSED*/
 272 static int
 273 privcmd_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rval)
 274 {
 275         if (secpolicy_xvm_control(cr))
 276                 return (EPERM);
 277 
 278         /*
 279          * Everything is a -native- data type.
 280          */
 281         if ((mode & FMODELS) != FNATIVE)
 282                 return (EOVERFLOW);
 283