Annotation of researchv10dc/lsys/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, fileno, ip, bstart, count)
                    123:        register struct fpte *pte;
                    124:        int fileno;
                    125:        register struct inode *ip;
                    126:        daddr_t bstart;
                    127:        clicks_t count;
                    128: {
                    129:        register int i, j;
                    130:        struct buf *bp;
                    131:        int indx;
                    132:        register daddr_t *pp;
                    133: 
                    134:        if(ip->i_fstyp)
                    135:                panic("vinifod, fstyp");
                    136:        if(fileno < PG_FMIN)
                    137:                panic("vinifod, fileno");
                    138:        while (count > 0) {
                    139:                if (bstart < NADDR - 3) {
                    140:                        ((struct pte *)pte)->pg_vreadm = 0;
                    141:                        pte->pg_fod = 1;
                    142:                        pte->pg_source = fileno - PG_FMIN;
                    143:                        pte->pg_blkno = ip ? ip->i_un.i_addr[bstart] : 0;
                    144:                        if (pte->pg_blkno == 0) {
                    145:                                pte->pg_source = PG_FZERO - PG_FMIN;
                    146:                                pte->pg_blkno = 0;
                    147:                                cnt.v_nzfod += CLSIZE;
                    148:                        } else if (fileno == PG_FTEXT)
                    149:                                cnt.v_nexfod += CLSIZE;
                    150:                        else
                    151:                                panic("vinifod, vrpages set");
                    152:                        for (j = 1; j < CLSIZE; j++)
                    153:                                pte[j] = pte[0];
                    154:                        pte += CLSIZE;
                    155:                        bstart++;
                    156:                        count -= CLSIZE;
                    157:                } else {
                    158:                        mtpr(TBIA, 0);          /* conservative */
                    159:                        bp = vbmap(ip, bstart);
                    160:                        indx = (bstart - (NADDR - 3)) % NINDIR(ip->i_dev);
                    161:                        i = imin((NINDIR(ip->i_dev) - indx) * CLSIZE, count);
                    162:                        bstart += i / CLSIZE;
                    163:                        count -= i;
                    164:                        if (bp) {
                    165:                                pp = &bp->b_un.b_daddr[indx];
                    166:                                do {
                    167:                                        ((struct pte *)pte)->pg_vreadm = 0;
                    168:                                        pte->pg_fod = 1;
                    169:                                        pte->pg_blkno = *pp++;
                    170:                                        if (pte->pg_blkno) {
                    171:                                                pte->pg_source = fileno - PG_FMIN;
                    172:                                                if (fileno == PG_FTEXT)
                    173:                                                        cnt.v_nexfod += CLSIZE;
                    174:                                                else
                    175:                                                        panic("vinifod, vrpages set");
                    176:                                        } else {
                    177:                                                pte->pg_source = PG_FZERO - PG_FMIN;
                    178:                                                pte->pg_blkno = 0;
                    179:                                                cnt.v_nzfod += CLSIZE;
                    180:                                        }
                    181:                                        for (j = 1; j < CLSIZE; j++)
                    182:                                                pte[j] = pte[0];
                    183:                                        pte += CLSIZE;
                    184:                                } while ((i -= CLSIZE) > 0);
                    185:                                brelse(bp);
                    186:                        } else {
                    187:                                cnt.v_nzfod += i;
                    188:                                do {
                    189:                                        ((struct pte *)pte)->pg_vreadm = 0;
                    190:                                        pte->pg_fod = 1;
                    191:                                        pte->pg_source = PG_FZERO - PG_FMIN;
                    192:                                        distcl(pte);
                    193:                                        pte += CLSIZE;
                    194:                                } while ((i -= CLSIZE) > 0);
                    195:                        }
                    196:                }
                    197:        }
                    198:        mtpr(TBIA, 0);          /* necessary! */
                    199: }
                    200: 
                    201: /*
                    202:  * Vbmap returns a block full of indirect pointers for a given block offset
                    203:  * in a file.  It returns 0 if a missing address block was encountered,
                    204:  * in which case the pages can be normal zfod pages.
                    205:  */
                    206: struct buf *
                    207: vbmap(ip, bn)
                    208: register struct inode *ip;
                    209: daddr_t bn;
                    210: {
                    211:        register i;
                    212:        struct buf *bp;
                    213:        int j, sh;
                    214:        daddr_t nb;
                    215:        dev_t dev = ip->i_dev;
                    216: 
                    217:        if (bn < NADDR-3)
                    218:                panic("vbmap");
                    219:        if (ip == 0)
                    220:                return (0);
                    221: 
                    222:        /*
                    223:         * addresses NADDR-3, NADDR-2, and NADDR-1
                    224:         * have single, double, triple indirect blocks.
                    225:         * the first step is to determine
                    226:         * how many levels of indirection.
                    227:         */
                    228:        sh = 0;
                    229:        nb = 1;
                    230:        bn -= NADDR-3;
                    231:        for (j = 3; j > 0; j--) {
                    232:                sh += NSHIFT(dev);
                    233:                nb <<= NSHIFT(dev);
                    234:                if(bn < nb)
                    235:                        break;
                    236:                bn -= nb;
                    237:        }
                    238:        if (j == 0)
                    239:                goto noblk;
                    240: 
                    241:        /*
                    242:         * fetch the address from the inode
                    243:         */
                    244:        nb = ip->i_un.i_addr[NADDR-j];
                    245: 
                    246:        /*
                    247:         * fetch through the indirect blocks
                    248:         */
                    249:        for (;;) {
                    250:                if (nb == 0)
                    251:                        return (0);
                    252:                bp = bread(dev, nb);
                    253:                if (bp->b_flags & B_ERROR) {
                    254:                        brelse(bp);
                    255:                        goto noblk;
                    256:                }
                    257:                if (j == 3)
                    258:                        break;
                    259:                j++;
                    260:                sh -= NSHIFT(dev);
                    261:                i = (bn>>sh) & NMASK(dev);
                    262:                nb = bp->b_un.b_daddr[i];
                    263:                brelse(bp);
                    264:                if (nb == 0)
                    265:                        goto noblk;
                    266:        }
                    267:        return (bp);
                    268: 
                    269: noblk:
                    270:        return ((struct buf *)0);
                    271: }
                    272: 
                    273: /*
                    274:  * Set a red zone in the kernel stack after the u. area.
                    275:  */
                    276: setredzone(pte, vaddr)
                    277:        register struct pte *pte;
                    278:        caddr_t vaddr;
                    279: {
                    280: 
                    281:        pte += (sizeof (struct user) + NBPG - 1) / NBPG;
                    282:        *(int *)pte &= ~PG_PROT;
                    283:        *(int *)pte |= PG_URKR;
                    284:        if (vaddr)
                    285:                mtpr(TBIS, vaddr + sizeof (struct user));
                    286: }

unix.superglobalmegacorp.com

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