|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution is only permitted until one year after the first shipment ! 6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 7: * binary forms are permitted provided that: (1) source distributions retain ! 8: * this entire copyright notice and comment, and (2) distributions including ! 9: * binaries display the following acknowledgement: This product includes ! 10: * software developed by the University of California, Berkeley and its ! 11: * contributors'' in the documentation or other materials provided with the ! 12: * distribution and in all advertising materials mentioning features or use ! 13: * of this software. Neither the name of the University nor the names of ! 14: * its contributors may be used to endorse or promote products derived from ! 15: * this software without specific prior written permission. ! 16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 19: * ! 20: * @(#)vm_subr.c 7.14 (Berkeley) 6/30/90 ! 21: */ ! 22: ! 23: #include "param.h" ! 24: #include "user.h" ! 25: #include "vm.h" ! 26: #include "proc.h" ! 27: #include "vnode.h" ! 28: #include "mount.h" ! 29: #include "file.h" ! 30: #include "buf.h" ! 31: ! 32: #include "machine/pte.h" ! 33: #include "machine/mtpr.h" ! 34: ! 35: /* ! 36: * Make uarea of process p addressible at kernel virtual ! 37: * address uarea through sysmap locations starting at map. ! 38: */ ! 39: uaccess(p, map, uarea) ! 40: register struct proc *p; ! 41: struct pte *map; ! 42: register struct user *uarea; ! 43: { ! 44: register int i; ! 45: register struct pte *mp = map; ! 46: ! 47: for (i = 0; i < UPAGES; i++) { ! 48: *(int *)mp = 0; ! 49: mp->pg_pfnum = p->p_addr[i].pg_pfnum; ! 50: mp++; ! 51: } ! 52: vmaccess(map, (caddr_t)uarea, UPAGES); ! 53: } ! 54: ! 55: /* ! 56: * Validate the kernel map for size ptes which ! 57: * start at ppte in the sysmap, and which map ! 58: * kernel virtual addresses starting with vaddr. ! 59: */ ! 60: vmaccess(ppte0, vaddr, size0) ! 61: struct pte *ppte0; ! 62: register caddr_t vaddr; ! 63: int size0; ! 64: { ! 65: register struct pte *ppte = ppte0; ! 66: register int size = size0; ! 67: ! 68: while (size != 0) { ! 69: mapin(ppte, (u_int)vaddr, ppte->pg_pfnum, (int)(PG_V|PG_KW)); ! 70: #if defined(tahoe) ! 71: mtpr(P1DC, vaddr); ! 72: #endif ! 73: ppte++; ! 74: vaddr += NBPG; ! 75: --size; ! 76: } ! 77: #if defined(hp300) ! 78: DCIS(); ! 79: #endif ! 80: #if defined(i386) ! 81: tlbflush(); ! 82: #endif ! 83: } ! 84: ! 85: /* ! 86: * Convert a pte pointer to ! 87: * a virtual page number. ! 88: */ ! 89: ptetov(p, pte) ! 90: register struct proc *p; ! 91: struct pte *pte; ! 92: { ! 93: register int j; ! 94: ! 95: j = pte - p->p_p0br; ! 96: if (j < p->p_tsize + p->p_dsize + p->p_mmsize) ! 97: return (j); ! 98: return ((BTOPUSRSTACK + HIGHPAGES) - p->p_szpt * NPTEPG + j); ! 99: } ! 100: ! 101: /* ! 102: * Initialize the page tables for paging from an inode, ! 103: * by scouring up the indirect blocks in order. ! 104: * Corresponding area of memory should have been vmemfree()d ! 105: * first or just created. ! 106: */ ! 107: vinifod(p, pte, fileno, vp, bfirst, count) ! 108: struct proc *p; ! 109: register struct fpte *pte; ! 110: int fileno; ! 111: register struct vnode *vp; ! 112: daddr_t bfirst; ! 113: segsz_t count; ! 114: { ! 115: int blast = bfirst + howmany(count, CLSIZE); ! 116: register int i, j; ! 117: int bn; ! 118: int nclpbsize = vp->v_mount->mnt_stat.f_bsize / CLBYTES; ! 119: ! 120: /* ! 121: * Blocks of an executable may still be in the buffer ! 122: * cache, so we explicitly flush them out to disk ! 123: * so that the proper data will be paged in. ! 124: */ ! 125: vflushbuf(vp, B_SYNC); ! 126: /* ! 127: * Map in the appropriate block numbers for each page ! 128: * of the executable. ! 129: */ ! 130: while (bfirst < blast) { ! 131: i = bfirst % nclpbsize; ! 132: if (VOP_BMAP(vp, bfirst / nclpbsize, (struct vnode **)0, &bn)) { ! 133: swkill(p, "I/O error mapping pages"); ! 134: return; ! 135: } ! 136: for ( ; i < nclpbsize; i++) { ! 137: pte->pg_fod = 1; ! 138: pte->pg_fileno = fileno; ! 139: if (bn < 0) { ! 140: pte->pg_blkno = 0; ! 141: pte->pg_fileno = PG_FZERO; ! 142: cnt.v_nzfod += CLSIZE; ! 143: } else { ! 144: pte->pg_blkno = bn + btodb(i * CLBYTES); ! 145: cnt.v_nexfod += CLSIZE; ! 146: } ! 147: for (j = 1; j < CLSIZE; j++) ! 148: pte[j] = pte[0]; ! 149: pte += CLSIZE; ! 150: bfirst++; ! 151: if (bfirst == blast) ! 152: break; ! 153: } ! 154: } ! 155: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.