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