|
|
1.1 ! root 1: ! 2: #include "definitions" ! 3: ! 4: extern long iob0, iob1, iob2, iob3, ss1; ! 5: extern long unused, u0p1pt, u0p2pt, scb, savvec4, savvec5, savvec6, savvec7; ! 6: extern long *p_ptr, exp_par0, exp_par1, exp_par2, exp_par3; ! 7: ! 8: long Failpc, test_va, Tpsl; ! 9: ! 10: /* This test will test access protections on PTE in TAHOE memory ! 11: management scheme. ! 12: The main loop of the test running in USER space, KERNEL privilege. ! 13: */ ! 14: ! 15: protect() ! 16: { long *temp, pg_no, pte, saved_pte, pte_sys, pte_p0, pte_p1, pte_p2; ! 17: ! 18: if (ss1) writes("** Subtest2 : Access protection fault\n"); ! 19: pg_no = 0; ! 20: asm("mfpr $SBR,_savvec4"); ! 21: savvec4 |= 0xc0000000; ! 22: asm("mtpr _savvec4,$P0BR"); /* Double map P0 into System space */ ! 23: asm("mfpr $SLR,_savvec4"); ! 24: asm("mtpr _savvec4,$P0LR"); ! 25: ! 26: asm("mtpr $3,$DCK"); ! 27: asm("mtpr $0,$TBIA"); ! 28: asm("mtpr $0,$PADC"); ! 29: asm("mtpr $1,$MME"); ! 30: asm("jmp *$0f"); /* Go virtual */ ! 31: asm("0:"); ! 32: ! 33: /* Set up SPT */ ! 34: pg_no = TEST_PTESYS; /* Map 1st unused PTE to */ ! 35: pte = IOB0; /* physical page iob0 (22) */ ! 36: fixpfn_pte(SBR,pg_no, &pte_sys, pte); ! 37: ! 38: /* Set up P0PT */ ! 39: pg_no = TEST_PTEP0; /* Map PTE. 60 in P0PT */ ! 40: pte = IOB1; /* physical page iob1 (23) */ ! 41: fixpfn_pte(P0BR,pg_no, &pte_p0, pte); ! 42: ! 43: /* Set up P1PT */ ! 44: temp = &u0p1pt; /* Map PTE. 0 in P1PT */ ! 45: *temp = IOB2; /* physical page iob2 (24) */ ! 46: savvec4 = ((long)temp) | SADDR; ! 47: asm("mtpr _savvec4,$P1BR"); ! 48: asm("mtpr $1,$P1LR"); ! 49: ! 50: /* Set up P2PT */ ! 51: temp = &u0p2pt; /* Map PTE. 0 in P2PT */ ! 52: *temp = IOB3; /* physical page iob3 (25) */ ! 53: savvec4 = ((long)temp) | SADDR; ! 54: savvec4 -= (LAST_VPGNO << 2); ! 55: asm("mtpr _savvec4, $P2BR"); ! 56: asm("mtpr $0xffffe, $P2LR"); /* Use only 1 entry */ ! 57: ! 58: /* Map test area to allow USER to execute code */ ! 59: asm("movab rd_access,_savvec4"); ! 60: pg_no = (savvec4 >> PGSHIFT) & 0xfffff; ! 61: fixpv_pte(SBR, pg_no, &saved_pte, PTE_UW | PTE_V); ! 62: fixpv_pte(SBR, pg_no+1, &saved_pte, PTE_UW | PTE_V); ! 63: ! 64: prot(); /* Do test .. */ ! 65: ! 66: fixpv_pte(SBR, pg_no, &saved_pte, PTE_KW | PTE_V); ! 67: fixpv_pte(SBR, pg_no+1, &saved_pte, PTE_KW | PTE_V); ! 68: ! 69: /* Restore original PTEs */ ! 70: pg_no = TEST_PTESYS; ! 71: pte = IOB0; ! 72: fixpfn_pte(SBR,pg_no, &pte_sys, pte_sys&0x3fffff); ! 73: pg_no = TEST_PTEP0; ! 74: pte = IOB1; ! 75: fixpfn_pte(P0BR,pg_no, &pte_p0, pte_p0&0x3fffff); ! 76: pg_no = TEST_PTEP1; ! 77: pte = IOB2; ! 78: fixpfn_pte(P1BR,pg_no, &pte_p1, pte_p1&0x3fffff); ! 79: pg_no = TEST_PTEP2; ! 80: pte = IOB3; ! 81: fixpfn_pte(P2BR,pg_no, &pte_p2, pte_p2&0x3fffff); ! 82: ! 83: asm("mtpr $0,$MME"); /* Back to physical */ ! 84: asm("mtpr $0,$P0LR"); /* Invalidate P0BR */ ! 85: } ! 86: ! 87: prot() ! 88: { long access_md, privilege, exp_int; ! 89: ! 90: ! 91: /* PTE : No Access */ ! 92: access_md = PTE_NOACC | PTE_V; ! 93: /* Try all privileges with R/W access on all tables */ ! 94: exp_int = TRUE; ! 95: for(privilege=USER; privilege>=KERNEL; privilege--) ! 96: chmaps_prot(access_md,privilege,"rw",exp_int); ! 97: ! 98: /* PTE : Kernel Read */ ! 99: access_md = PTE_KR | PTE_V; ! 100: chmaps_prot(access_md,USER,"rw",exp_int); ! 101: chmaps_prot(access_md,KERNEL,"w",exp_int); ! 102: exp_int = FALSE; ! 103: chmaps_prot(access_md,KERNEL,"r",exp_int); ! 104: ! 105: /* PTE : Kernel Write */ ! 106: access_md = PTE_KW | PTE_V; ! 107: exp_int = TRUE; ! 108: chmaps_prot(access_md,USER,"rw",exp_int); ! 109: exp_int = FALSE; ! 110: chmaps_prot(access_md,0,"rw",exp_int); ! 111: ! 112: ! 113: /* PTE : User Read/Kernel Read */ ! 114: access_md = PTE_URKR | PTE_V; ! 115: exp_int = TRUE; ! 116: chmaps_prot(access_md,USER,"w",exp_int); ! 117: chmaps_prot(access_md,KERNEL,"w",exp_int); ! 118: exp_int = FALSE; ! 119: chmaps_prot(access_md,USER,"r",exp_int); ! 120: chmaps_prot(access_md,KERNEL,"r",exp_int); ! 121: ! 122: ! 123: /* PTE : User Read/ Kernel Read/Write */ ! 124: access_md = PTE_URKW | PTE_V; ! 125: exp_int = TRUE; ! 126: chmaps_prot(access_md,USER,"w",exp_int); ! 127: exp_int = FALSE; ! 128: chmaps_prot(access_md,USER,"r",exp_int); ! 129: chmaps_prot(access_md,KERNEL,"rw",exp_int); ! 130: ! 131: /* PTE : User Read/Write/ Kernel Read/Write */ ! 132: access_md = PTE_UW | PTE_V; ! 133: exp_int = FALSE; ! 134: for(privilege=USER; privilege>=KERNEL; privilege--) ! 135: chmaps_prot(access_md,privilege,"rw",exp_int); ! 136: ! 137: } ! 138: ! 139: char *spc_str; ! 140: ! 141: chmaps_prot(access_md,priv,run_access,exp_int) ! 142: long access_md, priv, exp_int; ! 143: char *run_access; ! 144: { long pg_table, pte_no, space; ! 145: ! 146: for (pg_table=SBR; pg_table<=P2BR; pg_table += 2) ! 147: { ! 148: if (pg_table == SBR) { ! 149: pte_no = TEST_PTESYS; ! 150: space = SADDR; } ! 151: if (pg_table == P0BR) { ! 152: pte_no = TEST_PTEP0; ! 153: space = P0ADDR; } ! 154: if (pg_table == P1BR) { ! 155: pte_no = TEST_PTEP1; ! 156: space = P1ADDR; } ! 157: if (pg_table == P2BR) { ! 158: pte_no = TEST_PTEP2; ! 159: space = P2ADDR; } ! 160: force_flt(pg_table,pte_no,access_md,priv,run_access,space,exp_int); ! 161: } ! 162: } ! 163: ! 164: /* This routine forces protection faults with read and write access ! 165: to page table specified by tbl_no . The access bits of this PTE ! 166: is set to value of pte_access, the process that access this PTE ! 167: is running in the mode specified by rum_mode. ! 168: tbl_no : (0,1,2,3) corresponding to P0PT, P1PT, P2PT, SPT. ! 169: which_pte : PTE to be accessed ! 170: pte_access : valid and protection bits to be set on PTE ! 171: access : "r", "rw", "w"/ "R", "RW", "W" ! 172: run_mode : privilege of process when access PTE ! 173: */ ! 174: ! 175: force_flt(tbl_no, which_pte, pte_access, run_mode, access, addr_space, exp_int) ! 176: long tbl_no, which_pte, pte_access, run_mode, addr_space, exp_int; ! 177: char *access; ! 178: { ! 179: long *st_base, saved_vec1,saved_vec2,saved_pte,test_adr,tflag; ! 180: long ix, handler_adr; ! 181: char *acc_str, *pmode_str; ! 182: ! 183: /* Set protection bits of target PTE */ ! 184: fixpv_pte(tbl_no,which_pte,&saved_pte,pte_access); ! 185: ! 186: /* Get virtual address of test location */ ! 187: test_adr = (which_pte<<PGSHIFT)|addr_space; ! 188: ! 189: for(ix=0;ix<2;ix++) ! 190: { ! 191: if (access[ix]==NULL) break; ! 192: /* Set handler of protection fault */ ! 193: if (exp_int==TRUE) ! 194: asm("movab pro_flt1,_savvec4"); ! 195: else ! 196: asm("movab pro_flt2,_savvec4"); ! 197: handler_adr = savvec4; ! 198: set_handler(PROT_VEC,&saved_vec1,handler_adr); ! 199: ! 200: /* Set handler for DATA ALIGNMENT FAULT */ ! 201: asm("movab chmk_hd,_savvec4"); ! 202: handler_adr = savvec4; ! 203: set_handler(ALIGN_FLT,&saved_vec2,handler_adr); ! 204: ! 205: /* Set expected parameter words */ ! 206: exp_par1 = exp_par2 = exp_par3 = 0; ! 207: exp_par1 = test_adr; ! 208: if ((access[ix]=='r') || (access[ix]=='R')) ! 209: { /* protection violation, read access */ ! 210: asm("movab rd_access,_exp_par2"); /* Expected PC */ ! 211: exp_par0 = 0; ! 212: } ! 213: else ! 214: { /* protection violation, write access */ ! 215: asm("movab wr_access,_exp_par2"); ! 216: exp_par0 = 4; ! 217: } ! 218: ! 219: asm("mtpr $0xbfffb3fc,$USP"); /* Set up user stack */ ! 220: asm("movab (sp),_savvec5"); ! 221: savvec5 -= 40; /* KSP is 10 longword after ISP */ ! 222: asm("mtpr _savvec5,$KSP"); ! 223: ! 224: /* set up to change privilege */ ! 225: exp_par3 = run_mode << 24; ! 226: Tpsl = exp_par3; /* PSL when force fault */ ! 227: Failpc = exp_par2; /* PC to force fault */ ! 228: asm("pushl _exp_par3"); ! 229: asm("pushl _exp_par2"); /* Push PSL, PC on current stack */ ! 230: ! 231: /* Change mode */ ! 232: test_va = savvec5 = test_adr; ! 233: asm("movl _savvec5,r0"); ! 234: ! 235: /* Enable false */ ! 236: asm("mtpr $64,$DCR"); ! 237: asm("rei"); /* Go : Amem ... */ ! 238: asm("halt"); /* REI fails ... */ ! 239: ! 240: asm("rtn0_p0:"); ! 241: asm("movl r0,_savvec5"); /* flag indicate where return from */ ! 242: tflag = savvec5; ! 243: st_base = &scb; ! 244: ! 245: /* Restore Prot_fault, ALIGN_FLT vectors */ ! 246: *(st_base + PROT_VEC) = saved_vec1; ! 247: *(st_base + ALIGN_FLT) = saved_vec2; ! 248: ! 249: if (tflag && exp_int) ! 250: { /* Error : expected event did not happen */ ! 251: writes("** Expected protection fault didnot occured\n"); ! 252: ac_error1(); ! 253: asm("halt"); ! 254: } ! 255: ! 256: /* check fault parameters pushed on stack */ ! 257: if ((exp_int==TRUE)&&(tflag==FALSE)) chk_fpars(""); ! 258: } ! 259: ! 260: /* Restore tested PTE's */ ! 261: savvec5 = tbl_no; ! 262: asm("mfpr _savvec5,_savvec6"); ! 263: st_base = (long *)savvec6; ! 264: st_base += which_pte; ! 265: *st_base = saved_pte; ! 266: } ! 267: ! 268: ! 269: /* Handler of protection fault exception. */ ! 270: ptfx_handler() ! 271: { ! 272: asm(".align 2"); ! 273: asm("pro_flt1:"); /* EXPECTED INTERRUPT */ ! 274: ! 275: asm("mtpr $0x1f,$IPL"); ! 276: asm("movab (sp),_savvec5"); /* set pointer to parameters */ ! 277: p_ptr = (long *)savvec5; ! 278: asm("svpctx"); /* switch back to ISP */ ! 279: asm("clrl r0"); ! 280: asm("jmp rtn0_p0"); /* return to test */ ! 281: ! 282: asm(".align 2"); ! 283: asm("pro_flt2:"); /* UNEXPECTED INTERRUPT */ ! 284: asm("mtpr $0x1f,$IPL"); ! 285: asm("movab (sp),_savvec5"); /* set pointer to parameters */ ! 286: asm("movl fp,_saved_fp"); /* save fp */ ! 287: asm("movab (sp),fp"); /* set new frame pointer for next CALLS */ ! 288: p_ptr = (long *)savvec5; ! 289: ! 290: writes("** Unexpected protection fault\n"); ! 291: ac_error1(); ! 292: prt_par("** Parameters : ",p_ptr); /* print fault parameters */ ! 293: asm("svpctx"); /* switch back to ISP */ ! 294: asm("clrl r0"); ! 295: asm("movl _saved_fp,fp"); /* restore fp */ ! 296: asm("halt"); ! 297: asm("jmp rtn0_p0"); /* return to test */ ! 298: } ! 299: ! 300: chmk_handler() ! 301: { ! 302: asm(".align 2"); ! 303: asm("chmk_hd:"); /* Come here by causing a data not align fault */ ! 304: /* return to test */ ! 305: asm("mtpr $0x1f,$IPL"); /* Set IPL to HIGH */ ! 306: asm("svpctx"); /* switch back to ISP */ ! 307: asm("movl $1,r0"); /* set flag to indicate return from here */ ! 308: asm("jmp rtn0_p0"); ! 309: } ! 310: ! 311: TEST_AREA() ! 312: { ! 313: ! 314: asm("rd_access:"); ! 315: asm("movl (r0),r12"); /* should cause protection fault exception !! */ ! 316: ! 317: /* Get back KERNEL privilege by causing a data not align fault */ ! 318: asm("movl align_f,r10"); ! 319: asm("halt"); /* otherwise HALT .... */ ! 320: ! 321: asm("wr_access:"); ! 322: asm("movl $1,(r0)"); /* should cause protection fault exception !! */ ! 323: ! 324: /* Get back KERNEL privilege by causing a data not align fault */ ! 325: asm("movl align_f,r10"); ! 326: asm("halt"); /* otherwise HALT .... */ ! 327: asm(".align 1"); /* Word align */ ! 328: asm("align_f:"); ! 329: asm(".long 0"); ! 330: } ! 331: ! 332: /* Print fault parameters of memory management exceptions */ ! 333: prt_par(str,par) ! 334: char *str; ! 335: long *par; ! 336: { ! 337: writes(str); ! 338: writeh(*par++); writes(" "); ! 339: writeh(*par++); writes(" "); ! 340: writeh(*par++); writes(" "); ! 341: writeh(*par); writec('\n'); ! 342: } ! 343: ! 344: /* This routine assumes that global pointer p_ptr points to the actual ! 345: parameters pushed on the stack, and exp_par0 is the 1 of the expected ! 346: parameters. ! 347: */ ! 348: chk_fpars(msg) ! 349: char *msg; ! 350: { long *pars, *e_pars; ! 351: long act_param0, act_param1, act_param2, act_param3; ! 352: ! 353: e_pars = &exp_par0; /* pointer to expected parameters */ ! 354: pars = p_ptr; /* pointer to actual parameters */ ! 355: act_param0 = *pars++; ! 356: act_param1 = *pars++; ! 357: act_param2 = *pars++; ! 358: act_param3 = (*pars) & 0xffffffc0; /* Mask out PSW flags */ ! 359: if ((exp_par0 != act_param0) || (exp_par1 != act_param1) || ! 360: (exp_par2 != act_param2) || (exp_par3 != act_param3)) { ! 361: writes(msg); ! 362: writes("** Error in fault paramters\n"); ! 363: ac_error1(); ! 364: prt_par("** Expected : ",&exp_par0); ! 365: prt_par("** Actual : ",p_ptr); ! 366: asm("halt"); ! 367: } ! 368: } ! 369: ! 370: ac_error1() ! 371: { ! 372: writes("** PC : "); writeh(Failpc); writec('\n'); ! 373: writes("** VA : "); writeh(test_va); writec('\n'); ! 374: writes("** PSL : "); writeh(Tpsl); writec('\n'); ! 375: prt_base(test_va); ! 376: } ! 377:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.