1: /* 2: * Copyright (c) 1982, 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)kern_mman.c 7.1 (Berkeley) 6/5/86 7: */ 8: 9: #include "../machine/reg.h" 10: #include "../machine/psl.h" 11: #include "../machine/pte.h" 12: 13: #include "param.h" 14: #include "systm.h" 15: #include "map.h" 16: #include "dir.h" 17: #include "user.h" 18: #include "proc.h" 19: #include "buf.h" 20: #include "inode.h" 21: #include "seg.h" 22: #include "acct.h" 23: #include "wait.h" 24: #include "vm.h" 25: #include "text.h" 26: #include "file.h" 27: #include "vadvise.h" 28: #include "cmap.h" 29: #include "trace.h" 30: #include "mman.h" 31: #include "conf.h" 32: 33: sbrk() 34: { 35: 36: } 37: 38: sstk() 39: { 40: 41: } 42: 43: getpagesize() 44: { 45: 46: u.u_r.r_val1 = NBPG * CLSIZE; 47: } 48: 49: smmap() 50: { 51: #ifdef notdef 52: struct a { 53: caddr_t addr; 54: int len; 55: int prot; 56: int share; 57: int fd; 58: off_t pos; 59: } *uap = (struct a *)u.u_ap; 60: register struct file *fp; 61: register struct inode *ip; 62: register struct fpte *pte; 63: int off; 64: int fv, lv, pm; 65: dev_t dev; 66: int (*mapfun)(); 67: extern struct file *getinode(); 68: 69: fp = getinode(uap->fd); 70: if (fp == NULL) 71: return; 72: ip = (struct inode *)fp->f_data; 73: if ((ip->i_mode & IFMT) != IFCHR) { 74: u.u_error = EINVAL; 75: return; 76: } 77: dev = ip->i_rdev; 78: mapfun = cdevsw[major(dev)].d_mmap; 79: if (mapfun == NULL) { 80: u.u_error = EINVAL; 81: return; 82: } 83: if (((int)uap->addr & CLOFSET) || (uap->len & CLOFSET) || 84: (uap->pos & CLOFSET)) { 85: u.u_error = EINVAL; 86: return; 87: } 88: if ((uap->prot & PROT_WRITE) && (fp->f_flag&FWRITE) == 0) { 89: u.u_error = EINVAL; 90: return; 91: } 92: if ((uap->prot & PROT_READ) && (fp->f_flag&FREAD) == 0) { 93: u.u_error = EINVAL; 94: return; 95: } 96: if (uap->share != MAP_SHARED) { 97: u.u_error = EINVAL; 98: return; 99: } 100: fv = btop(uap->addr); 101: lv = btop(uap->addr + uap->len - 1); 102: if (lv < fv || !isadsv(u.u_procp, fv) || !isadsv(u.u_procp, lv)) { 103: u.u_error = EINVAL; 104: return; 105: } 106: for (off=0; off<uap->len; off += NBPG) { 107: if ((*mapfun)(dev, uap->pos+off, uap->prot) == -1) { 108: u.u_error = EINVAL; 109: return; 110: } 111: } 112: if (uap->prot & PROT_WRITE) 113: pm = PG_UW; 114: else 115: pm = PG_URKR; 116: for (off = 0; off < uap->len; off += NBPG) { 117: pte = (struct fpte *)vtopte(u.u_procp, fv); 118: u.u_procp->p_rssize -= vmemfree(pte, 1); 119: *(int *)pte = pm; 120: pte->pg_v = 1; 121: pte->pg_fod = 1; 122: pte->pg_fileno = uap->fd; 123: pte->pg_blkno = (*mapfun)(dev, uap->pos+off, uap->prot); 124: fv++; 125: } 126: u.u_procp->p_flag |= SPTECHG; 127: u.u_pofile[uap->fd] |= UF_MAPPED; 128: #endif 129: } 130: 131: mremap() 132: { 133: 134: } 135: 136: munmap() 137: { 138: #ifdef notdef 139: register struct a { 140: caddr_t addr; 141: int len; 142: } *uap = (struct a *)u.u_ap; 143: int off; 144: int fv, lv; 145: register struct pte *pte; 146: 147: if (((int)uap->addr & CLOFSET) || (uap->len & CLOFSET)) { 148: u.u_error = EINVAL; 149: return; 150: } 151: fv = btop(uap->addr); 152: lv = btop(uap->addr + uap->len - 1); 153: if (lv < fv || !isadsv(u.u_procp, fv) || !isadsv(u.u_procp, lv)) { 154: u.u_error = EINVAL; 155: return; 156: } 157: for (off = 0; off < uap->len; off += NBPG) { 158: pte = vtopte(u.u_procp, fv); 159: u.u_procp->p_rssize -= vmemfree(pte, 1); 160: *(int *)pte = (PG_UW|PG_FOD); 161: ((struct fpte *)pte)->pg_fileno = PG_FZERO; 162: fv++; 163: } 164: u.u_procp->p_flag |= SPTECHG; 165: #endif 166: } 167: 168: munmapfd(fd) 169: { 170: #ifdef notdef 171: register struct fpte *pte; 172: register int i; 173: 174: for (i = 0; i < u.u_dsize; i++) { 175: pte = (struct fpte *)dptopte(u.u_procp, i); 176: if (pte->pg_v && pte->pg_fod && pte->pg_fileno == fd) { 177: *(int *)pte = (PG_UW|PG_FOD); 178: pte->pg_fileno = PG_FZERO; 179: } 180: } 181: #endif 182: u.u_pofile[fd] &= ~UF_MAPPED; 183: 184: } 185: 186: mprotect() 187: { 188: 189: } 190: 191: madvise() 192: { 193: 194: } 195: 196: mincore() 197: { 198: 199: } 200: 201: /* BEGIN DEFUNCT */ 202: obreak() 203: { 204: struct a { 205: char *nsiz; 206: }; 207: register size_t n, d, ds; 208: 209: /* 210: * set n to new data size 211: */ 212: n = btoc(((struct a *)u.u_ap)->nsiz) - ctos(u.u_tsize) * stoc(1); 213: if (n < 0) 214: n = 0; 215: /* 216: * since we can't pass a -ve argument for the difference to chksize, 217: * if d is negative, make ds equal to the final value and clear d. 218: * keep the real difference in n for later use in expand. 219: */ 220: ds = u.u_dsize; 221: if ((n = d = clrnd(n - u.u_dsize)) < 0) { 222: ds += d; 223: d = 0; 224: } 225: if (ctob(ds + d) > u.u_rlimit[RLIMIT_DATA].rlim_cur) { 226: u.u_error = ENOMEM; 227: return; 228: } 229: if (chksize((u_int)u.u_tsize, (u_int)ds, (u_int)d, (u_int)u.u_ssize)) 230: return; 231: if (swpexpand(ds + d, u.u_ssize, &u.u_dmap, &u.u_smap) == 0) 232: return; 233: expand((int)n, 0); 234: } 235: 236: int both; 237: 238: ovadvise() 239: { 240: register struct a { 241: int anom; 242: } *uap; 243: register struct proc *rp = u.u_procp; 244: int oanom = rp->p_flag & SUANOM; 245: register struct pte *pte; 246: register struct cmap *c; 247: register unsigned i; 248: 249: #ifdef lint 250: both = 0; 251: #endif 252: uap = (struct a *)u.u_ap; 253: trace(TR_VADVISE, uap->anom, u.u_procp->p_pid); 254: rp->p_flag &= ~(SSEQL|SUANOM); 255: switch (uap->anom) { 256: 257: case VA_ANOM: 258: rp->p_flag |= SUANOM; 259: break; 260: 261: case VA_SEQL: 262: rp->p_flag |= SSEQL; 263: break; 264: } 265: if ((oanom && (rp->p_flag & SUANOM) == 0) || uap->anom == VA_FLUSH) { 266: for (i = 0; i < rp->p_dsize; i += CLSIZE) { 267: pte = dptopte(rp, i); 268: if (pte->pg_v) { 269: c = &cmap[pgtocm(pte->pg_pfnum)]; 270: if (c->c_lock) 271: continue; 272: pte->pg_v = 0; 273: if (anycl(pte, pg_m)) 274: pte->pg_m = 1; 275: distcl(pte); 276: } 277: } 278: } 279: if (uap->anom == VA_FLUSH) { /* invalidate all pages */ 280: for (i = 1; i < rp->p_ssize; i += CLSIZE) { 281: pte = sptopte(rp, i); 282: if (pte->pg_v) { 283: c = &cmap[pgtocm(pte->pg_pfnum)]; 284: if (c->c_lock) 285: continue; 286: pte->pg_v = 0; 287: if (anycl(pte, pg_m)) 288: pte->pg_m = 1; 289: distcl(pte); 290: } 291: } 292: for (i = 0; i < rp->p_tsize; i += CLSIZE) { 293: pte = tptopte(rp, i); 294: if (pte->pg_v) { 295: c = &cmap[pgtocm(pte->pg_pfnum)]; 296: if (c->c_lock) 297: continue; 298: pte->pg_v = 0; 299: if (anycl(pte, pg_m)) 300: pte->pg_m = 1; 301: distcl(pte); 302: distpte(rp->p_textp, i, pte); 303: } 304: } 305: } 306: #ifdef vax 307: #include "../vax/mtpr.h" /* XXX */ 308: mtpr(TBIA, 0); 309: #endif 310: } 311: /* END DEFUNCT */ 312: 313: /* 314: * grow the stack to include the SP 315: * true return if successful. 316: */ 317: grow(sp) 318: unsigned sp; 319: { 320: register int si; 321: 322: if (sp >= USRSTACK-ctob(u.u_ssize)) 323: return (0); 324: si = clrnd(btoc((USRSTACK-sp)) - u.u_ssize + SINCR); 325: if (ctob(si) > u.u_rlimit[RLIMIT_STACK].rlim_cur) 326: return (0); 327: if (chksize((u_int)u.u_tsize, (u_int)u.u_dsize, (u_int)0, 328: (u_int)u.u_ssize+si)) 329: return (0); 330: if (swpexpand(u.u_dsize, u.u_ssize+si, &u.u_dmap, &u.u_smap)==0) 331: return (0); 332: 333: expand(si, 1); 334: return (1); 335: }