|
|
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.