|
|
1.1 ! root 1: #include "../machine/alignment.h" ! 2: ! 3: long readable(infop, address, length) ! 4: process_info *infop; ! 5: long address, length; ! 6: /* ! 7: * Return TRUE (= -1) if the specified bytes can be read without an access ! 8: * control violation (limit and/or protection). Page faults are OK. ! 9: * If problems, return the code that would be pushed by HW on the ! 10: * stack (see the architecture manual). ! 11: * Assumption is that in most cases, access is OK, so a quick 'prober' ! 12: * will be enough. If not, we have to work harder to determine the exact ! 13: * cause and return the right code, without getting the fault here in ! 14: * the kernel !!. ! 15: * ! 16: * The address is assumed to be read for the user.! ! 17: */ ! 18: { ! 19: register long Register_12; /* Has to be first reg ! */ ! 20: register long Register_11; ! 21: register long Register_10; ! 22: register long Register_9; ! 23: register long Register_8; ! 24: register long subspace; ! 25: register long last_page; ! 26: ! 27: Register_12 = address; ! 28: Register_11 = length-1; ! 29: asm (" prober $1,(r12),$1 "); /* Yeach ... */ ! 30: asm (" beql no_access "); ! 31: asm (" addl2 r11,r12 "); /* last byte */ ! 32: asm (" prober $1,(r12),$1 "); ! 33: asm (" beql no_access "); ! 34: asm (" movl $-1,r0 "); /* TRUE */ ! 35: asm (" ret#1 "); ! 36: asm ("no_access: "); ! 37: /* ! 38: * Now the hard work. Have to check length violation first. ! 39: * If any byte (first or last) causes a length violation, report it as such. ! 40: */ ! 41: asm (" mfpr $3,r8 "); /* Get length registers. P0LR */ ! 42: asm (" mfpr $5,r9 "); /* P1LR */ ! 43: asm (" mfpr $7,r10 "); /* P2LR */ ! 44: asm (" mfpr $1,r11 "); /* SLR */ ! 45: ! 46: subspace = (address >> 30) & 3; ! 47: Register_12 = (address >> 10) & 0xfffff; /* 1'st byte page # */ ! 48: last_page = ( (address+length-1) >> 10) & 0xfffff; ! 49: switch ( subspace ) { ! 50: case 0: ! 51: if ( (Register_12 >= Register_8) || ! 52: (last_page >= Register_8) ) return (1); ! 53: break; ! 54: case 1: ! 55: if ( (Register_12 >= Register_9) || ! 56: (last_page >= Register_9) ) return (1); ! 57: break; ! 58: case 2: ! 59: if ( (Register_12 < Register_10) || ! 60: (last_page < Register_10) ) return (1); ! 61: break; ! 62: case 3: ! 63: if ( (Register_12 >= Register_11) || ! 64: (last_page >= Register_11) ) return (1); ! 65: break; ! 66: } ! 67: /* ! 68: * OK, it's not a length violation. Must have been an access problem ! 69: * (no read by user). ! 70: * ! 71: * NOTE : I definitely ignore the case of 'no PTE access' since I ! 72: * assume that's not the case for user mode. Besides, the poor ! 73: * guy will just get an access violation that will most probably ! 74: * send him into hyperspace anyway, so no need to be too acurate here. ! 75: */ ! 76: return (0); ! 77: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.