1259 * Normal illumos binaries don't even hit the case
1260 * where we have to change permission on the last page
1261 * since their protection is typically either
1262 * PROT_USER | PROT_WRITE | PROT_READ
1263 * or
1264 * PROT_ZFOD (same as PROT_ALL).
1265 *
1266 * We need to be careful how we zero-fill the last page
1267 * if the segment protection does not include
1268 * PROT_WRITE. Using as_setprot() can cause the VM
1269 * segment code to call segvn_vpage(), which must
1270 * allocate a page struct for each page in the segment.
1271 * If we have a very large segment, this may fail, so
1272 * we have to check for that, even though we ignore
1273 * other return values from as_setprot.
1274 */
1275
1276 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
1277 seg = as_segat(curproc->p_as, (caddr_t)end);
1278 if (seg != NULL)
1279 SEGOP_GETPROT(seg, (caddr_t)end, zfoddiff - 1,
1280 &zprot);
1281 AS_LOCK_EXIT(as, &as->a_lock);
1282
1283 if (seg != NULL && (zprot & PROT_WRITE) == 0) {
1284 if (as_setprot(as, (caddr_t)end, zfoddiff - 1,
1285 zprot | PROT_WRITE) == ENOMEM) {
1286 error = ENOMEM;
1287 goto bad;
1288 }
1289 }
1290
1291 if (on_fault(&ljb)) {
1292 no_fault();
1293 if (seg != NULL && (zprot & PROT_WRITE) == 0)
1294 (void) as_setprot(as, (caddr_t)end,
1295 zfoddiff - 1, zprot);
1296 error = EFAULT;
1297 goto bad;
1298 }
1299 uzero((void *)end, zfoddiff);
|
1259 * Normal illumos binaries don't even hit the case
1260 * where we have to change permission on the last page
1261 * since their protection is typically either
1262 * PROT_USER | PROT_WRITE | PROT_READ
1263 * or
1264 * PROT_ZFOD (same as PROT_ALL).
1265 *
1266 * We need to be careful how we zero-fill the last page
1267 * if the segment protection does not include
1268 * PROT_WRITE. Using as_setprot() can cause the VM
1269 * segment code to call segvn_vpage(), which must
1270 * allocate a page struct for each page in the segment.
1271 * If we have a very large segment, this may fail, so
1272 * we have to check for that, even though we ignore
1273 * other return values from as_setprot.
1274 */
1275
1276 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
1277 seg = as_segat(curproc->p_as, (caddr_t)end);
1278 if (seg != NULL)
1279 segop_getprot(seg, (caddr_t)end, zfoddiff - 1,
1280 &zprot);
1281 AS_LOCK_EXIT(as, &as->a_lock);
1282
1283 if (seg != NULL && (zprot & PROT_WRITE) == 0) {
1284 if (as_setprot(as, (caddr_t)end, zfoddiff - 1,
1285 zprot | PROT_WRITE) == ENOMEM) {
1286 error = ENOMEM;
1287 goto bad;
1288 }
1289 }
1290
1291 if (on_fault(&ljb)) {
1292 no_fault();
1293 if (seg != NULL && (zprot & PROT_WRITE) == 0)
1294 (void) as_setprot(as, (caddr_t)end,
1295 zfoddiff - 1, zprot);
1296 error = EFAULT;
1297 goto bad;
1298 }
1299 uzero((void *)end, zfoddiff);
|