chris@mimsy.umd.edu (Chris Torek) (08/06/90)
In article <3729@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: (in re resuming a faulted instruction on the 680[123]0) >Part of the problem is that Motorola: >1) wouldn't commit to the the "stack puke" stored by the 680[1andup]0 > being "safe" to hand to user-mode code; i.e., they wouldn't say > "nothing you can do to the 'stack puke' is risky"; >2) wouldn't describe the format of the "stack puke" to the extent > necessary to have the kernel validate it. (the Sun-2 versus the VAX:) >The former has more context than the latter; the former has the 68010 >"stack puke", the latter has, as I remember, just the First Part Done >bit (and some of the general-purpose registers, for some of the >long-running instructions like MOVCn). > >The latter is safe and, I think, appears in the "signal context" >saved by a BSD signal, so that the instruction can be continued from >user mode without the kernel having to tuck away one or more sets of >context. Right (except that the registers do not appear in the sigcontext; the FPD bit is simply one in the PSL, and the VAX PSL is easy for the kernel to verify). (The registers are saved as part of the trap handling sequence, and ultimately restored in the `sigreturn' syscall called from the signal trampoline code in the u. area.) Basically, the problem here is that on an exception, the 680[123]0 simply pushes the entire microengine state; a return from exception reloads the microengine state so that the instruction can be continued (rather than restarted, as on the VAX; the VAX `first part done' bit allows restarting without resetting important context, e.g., the registers for the character string instructions). If there is no documented way to verify the state (as there is on the VAX), it becomes difficult for an O/S to allow user code to handle an exception: if the user code modifies the state, this could crash the machine, or allow improper privileges. The kernel can stash a copy of the exception state (the `stack puke') and compare this on return to ensure that it has not been changed, but this then limits the actions user code can take. If the user code elects not to return from the signal (e.g., to longjmp instead), the kernel may wind up carrying around useless copies of this state. In terms of computer architecture, the lesson here is that there must be a documented method to verify any state left behind. *Someone* will want it. The simplest solution is not to leave state behind. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris (New campus phone system, active sometime soon: +1 301 405 2750)
melvin@rigel (Steve Melvin) (08/08/90)
In article <25899@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: >... >Basically, the problem here is that on an exception, the 680[123]0 >simply pushes the entire microengine state; a return from exception >reloads the microengine state so that the instruction can be continued >... >If there is no documented way to verify the state (as there is on the >VAX), it becomes difficult for an O/S to allow user code to handle an >exception: if the user code modifies the state, this could crash the >machine, or allow improper privileges. >... >In terms of computer architecture, the lesson here is that there must >be a documented method to verify any state left behind. It seems that what you really must be saying is that the hardware should provide protections, becuase in this particular example, the OS has no way of verifying the register contents. If the user mangles the registers and then returns with FPD set, an access violation may result, but the hardware guarantees that the machine won't crash and no improper privileges will result. The VAX architecture specifies what the lower 2, 4 or 6 registers contain after a string instruction is finished, but not what they contain in the middle of a string instruction when an exception is taken with FPD set. (Officially, an instruction is "unpredictable" if registers are modified with FPD set or if FPD is set by software.) Most implementations have done things in similar ways, but these are not architecturally guaranteed (see below). The larger point about allowing user level access to exception handling is well taken, but that's a separate issue from forcing the exact specification of all the temporary state which an implementation may want to keep around. ---- Steve Melvin ...!ucbvax!melvin University of California, Berkeley melvin@polaris.Berkeley.EDU ---- P.S. Here's a little program I wrote several years ago which relies on differences in FPD state packing to prove that user level programs could discern different implementations. There is an 8-bit field "delta pc" packed into R0 which encodes the length of the instruction so that upon restarting, the instruction doesn't have to be decoded again. ---- /* testimpl.c */ /* Use hardware dependencies in how FPD information is packed away to * test the type of VAX implementation being run on. Depends on whether * or not the delta PC value stored in R0 should be added to the PC of * the opcode or the incremented PC. Uses the fact that the REI * instruction can be executed from unprivileged code. */ main() { if (tstimpl()) { printf("implementation is 11/780, microvax\n"); } else { printf("implementation is 8600\n"); } } /* link with the following assembly language file: .data .comm _buf1,8 .comm _buf2,8 .text .align 1 .globl _tstimpl _tstimpl: .word 0xFFC movl $0x010c,r0 movl $_buf1+4,r1 movl $0,r2 movl $_buf2+4,r3 movl $0,r4 movl $0,r5 movpsl r11 bisl2 $0x08000000, r11 pushl r11 pushl $_tst1 rei _tst1: movc3 $2,_buf1,_buf2 ret incl r0 ret */