Annotation of researchv10no/sys/vm/vmsubr.c, revision 1.1.1.1

1.1       root        1: /*     vmsubr.c        4.6     81/05/28        */
                      2: 
                      3: #include "sys/param.h"
                      4: #include "sys/systm.h"
                      5: #include "sys/user.h"
                      6: #include "sys/vm.h"
                      7: #include "sys/proc.h"
                      8: #include "sys/mtpr.h"
                      9: #include "sys/pte.h"
                     10: #include "sys/cmap.h"
                     11: #include "sys/inode.h"
                     12: #include "sys/buf.h"
                     13: #include "sys/text.h"
                     14: 
                     15: /*
                     16:  * Make uarea of process p addressible at kernel virtual
                     17:  * address uarea through sysmap locations starting at map.
                     18:  */
                     19: uaccess(p, map, uarea)
                     20:        register struct proc *p;
                     21:        struct pte *map;
                     22:        register struct user *uarea;
                     23: {
                     24:        register int i;
                     25:        register struct pte *mp = map;
                     26: 
                     27:        for (i = 0; i < UPAGES; i++) {
                     28:                *(int *)mp = 0;
                     29:                mp->pg_pfnum = p->p_addr[i].pg_pfnum;
                     30:                mp++;
                     31:        }
                     32:        vmaccess(map, (caddr_t)uarea, UPAGES);
                     33: }
                     34: 
                     35: /*
                     36:  * Validate the kernel map for size ptes which
                     37:  * start at ppte in the sysmap, and which map
                     38:  * kernel virtual addresses starting with vaddr.
                     39:  */
                     40: vmaccess(ppte, vaddr, size)
                     41:        register struct pte *ppte;
                     42:        register caddr_t vaddr;
                     43:        register int size;
                     44: {
                     45: 
                     46:        while (size != 0) {
                     47:                *(int *)ppte++ |= PG_V|PG_KW;
                     48:                mtpr(TBIS, vaddr);
                     49:                vaddr += NBPG;
                     50:                --size;
                     51:        }
                     52: }
                     53: 
                     54: /* 
                     55:  * Convert a pte pointer to
                     56:  * a virtual page number.
                     57:  */
                     58: ptetov(p, pte)
                     59:        register struct proc *p;
                     60:        register struct pte *pte;
                     61: {
                     62: 
                     63:        if (isatpte(p, pte))
                     64:                return (tptov(p, ptetotp(p, pte)));
                     65:        else if (isadpte(p, pte))
                     66:                return (dptov(p, ptetodp(p, pte)));
                     67:        else
                     68:                return (sptov(p, ptetosp(p, pte)));
                     69: }
                     70: 
                     71: /*
                     72:  * Convert a virtual page 
                     73:  * number to a pte address.
                     74:  */
                     75: struct pte *
                     76: vtopte(p, v)
                     77:        register struct proc *p;
                     78:        register unsigned v;
                     79: {
                     80: 
                     81:        if (isatsv(p, v))
                     82:                return (tptopte(p, vtotp(p, v)));
                     83:        else if (isadsv(p, v))
                     84:                return (dptopte(p, vtodp(p, v)));
                     85:        else 
                     86:                return (sptopte(p, vtosp(p, v)));
                     87: }
                     88: 
                     89: /*
                     90:  * convert a buffer to a pte address
                     91:  * this knows about pageout conventions,
                     92:  * swapping conventions, and physio.
                     93:  */
                     94: 
                     95: struct pte *
                     96: btopte(bp)
                     97: register struct buf *bp;
                     98: {
                     99:        struct proc *rp;
                    100: 
                    101:        if (bp->b_flags & B_DIRTY)
                    102:                rp = &proc[2];          /* ugh */
                    103:        else
                    104:                rp = bp->b_proc;
                    105:        if ((bp->b_flags & B_PHYS) == 0)
                    106:                return(&Sysmap[btop(((int)bp->b_un.b_addr)&~KSTART)]);
                    107:        else if (bp->b_flags & B_UAREA)
                    108:                return(&rp->p_addr[btop(bp->b_un.b_addr)]);
                    109:        else if (bp->b_flags & B_PAGET)
                    110:                return(&Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]);
                    111:        else
                    112:                return(vtopte(rp, btop(bp->b_un.b_addr)));
                    113: }
                    114: 
                    115: struct buf *vbmap();
                    116: /*
                    117:  * Initialize the page tables for paging from an inode,
                    118:  * by scouring up the indirect blocks in order.
                    119:  * Corresponding area of memory should have been vmemfree()d
                    120:  * first or just created.
                    121:  */
                    122: vinifod(pte, ip, bstart, count)
                    123:        register struct fpte *pte;
                    124:        register struct inode *ip;
                    125:        daddr_t bstart;
                    126:        clicks_t count;
                    127: {
                    128:        register int i, j;
                    129:        struct buf *bp;
                    130:        int indx;
                    131:        register daddr_t *pp;
                    132: 
                    133:        if(ip->i_fstyp)
                    134:                panic("vinifod, fstyp");
                    135:        while (count > 0) {
                    136:                if (bstart < NADDR - 3) {
                    137:                        pte->pg_fod = 1;
                    138:                        pte->pg_source = PG_FTEXT;
                    139:                        pte->pg_blkno = ip ? ip->i_un.i_addr[bstart] : 0;
                    140:                        if (pte->pg_blkno == 0) {
                    141:                                pte->pg_source = PG_FZERO;
                    142:                                pte->pg_blkno = 0;
                    143:                                cnt.v_nzfod += CLSIZE;
                    144:                        }
                    145:                                cnt.v_nexfod += CLSIZE;
                    146:                        for (j = 1; j < CLSIZE; j++)
                    147:                                pte[j] = pte[0];
                    148:                        pte += CLSIZE;
                    149:                        bstart++;
                    150:                        count -= CLSIZE;
                    151:                } else {
                    152:                        mtpr(TBIA, 0);          /* conservative */
                    153:                        bp = vbmap(ip, bstart);
                    154:                        indx = (bstart - (NADDR - 3)) % NINDIR(ip->i_dev);
                    155:                        i = imin((NINDIR(ip->i_dev) - indx) * CLSIZE, count);
                    156:                        bstart += i / CLSIZE;
                    157:                        count -= i;
                    158:                        if (bp) {
                    159:                                pp = &bp->b_un.b_daddr[indx];
                    160:                                do {
                    161:                                        pte->pg_fod = 1;
                    162:                                        pte->pg_blkno = *pp++;
                    163:                                        if (pte->pg_blkno) {
                    164:                                                pte->pg_source = PG_FTEXT;
                    165:                                                cnt.v_nexfod += CLSIZE;
                    166:                                        } else {
                    167:                                                pte->pg_source = PG_FZERO;
                    168:                                                pte->pg_blkno = 0;
                    169:                                                cnt.v_nzfod += CLSIZE;
                    170:                                        }
                    171:                                        for (j = 1; j < CLSIZE; j++)
                    172:                                                pte[j] = pte[0];
                    173:                                        pte += CLSIZE;
                    174:                                } while ((i -= CLSIZE) > 0);
                    175:                                brelse(bp);
                    176:                        } else {
                    177:                                cnt.v_nzfod += i;
                    178:                                do {
                    179:                                        pte->pg_fod = 1;
                    180:                                        pte->pg_source = PG_FZERO;
                    181:                                        distcl(pte);
                    182:                                        pte += CLSIZE;
                    183:                                } while ((i -= CLSIZE) > 0);
                    184:                        }
                    185:                }
                    186:        }
                    187:        mtpr(TBIA, 0);          /* necessary! */
                    188: }
                    189: 
                    190: /*
                    191:  * Vbmap returns a block full of indirect pointers for a given block offset
                    192:  * in a file.  It returns 0 if a missing address block was encountered,
                    193:  * in which case the pages can be normal zfod pages.
                    194:  */
                    195: struct buf *
                    196: vbmap(ip, bn)
                    197: register struct inode *ip;
                    198: daddr_t bn;
                    199: {
                    200:        register i;
                    201:        struct buf *bp;
                    202:        int j, sh;
                    203:        daddr_t nb;
                    204:        dev_t dev = ip->i_dev;
                    205: 
                    206:        if (bn < NADDR-3)
                    207:                panic("vbmap");
                    208:        if (ip == 0)
                    209:                return (0);
                    210: 
                    211:        /*
                    212:         * addresses NADDR-3, NADDR-2, and NADDR-1
                    213:         * have single, double, triple indirect blocks.
                    214:         * the first step is to determine
                    215:         * how many levels of indirection.
                    216:         */
                    217:        sh = 0;
                    218:        nb = 1;
                    219:        bn -= NADDR-3;
                    220:        for (j = 3; j > 0; j--) {
                    221:                sh += NSHIFT(dev);
                    222:                nb <<= NSHIFT(dev);
                    223:                if(bn < nb)
                    224:                        break;
                    225:                bn -= nb;
                    226:        }
                    227:        if (j == 0)
                    228:                goto noblk;
                    229: 
                    230:        /*
                    231:         * fetch the address from the inode
                    232:         */
                    233:        nb = ip->i_un.i_addr[NADDR-j];
                    234: 
                    235:        /*
                    236:         * fetch through the indirect blocks
                    237:         */
                    238:        for (;;) {
                    239:                if (nb == 0)
                    240:                        return (0);
                    241:                bp = bread(dev, nb);
                    242:                if (bp->b_flags & B_ERROR) {
                    243:                        brelse(bp);
                    244:                        goto noblk;
                    245:                }
                    246:                if (j == 3)
                    247:                        break;
                    248:                j++;
                    249:                sh -= NSHIFT(dev);
                    250:                i = (bn>>sh) & NMASK(dev);
                    251:                nb = bp->b_un.b_daddr[i];
                    252:                brelse(bp);
                    253:                if (nb == 0)
                    254:                        goto noblk;
                    255:        }
                    256:        return (bp);
                    257: 
                    258: noblk:
                    259:        return ((struct buf *)0);
                    260: }
                    261: 
                    262: /*
                    263:  * Set a red zone in the kernel stack after the u. area.
                    264:  */
                    265: setredzone(pte, vaddr)
                    266:        register struct pte *pte;
                    267:        caddr_t vaddr;
                    268: {
                    269: 
                    270:        pte += (sizeof (struct user) + NBPG - 1) / NBPG;
                    271:        *(int *)pte &= ~PG_PROT;
                    272:        *(int *)pte |= PG_URKR;
                    273:        if (vaddr)
                    274:                mtpr(TBIS, vaddr + sizeof (struct user));
                    275: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.