I haven't looked at the relevant versions of SunOS, so I can't say for sure which method they chose, but I'm aware of three methods for dealing with this problem.
The first method uses two CPUs. You basically run one CPU one instruction behind the other. When the leader encounters a page fault, you halt the follower, handle the page fault, then unhalt the second to execute the instruction that caused the fault (and the former lead now becomes the follower).
The second method is based on the observation that the instructions that cause problems are those that use autoincrement or autodecrement addressing. So you simply write your compiler to never generate instructions that use autoincrement/autodecrement addressing. As @supercat points out, there may be a few other restrictions, but the basic idea remains: just avoid generating instructions that cause problems.
The third method is to have your fault handler disassemble the faulting instruction, check whether it used autoincrement/autodecrement addressing, and if so adjust the appropriate register to undo the state change that had already happened from the partially executed instruction.
In both the second and third methods, after you've handled the fault, you restart execution starting from the instruction that faulted.
Apollo used the first (dual CPU) method. But to my knowledge, they were the only ones to do so (and I seem to recall their having gotten a patent on it, so it's particularly doubtful that anybody else did it).
Apple used the second method in the LISA. If you (for example) used a third party assembler to generate autodecrement/autoincrement instructions on your own...well, you were on your own.
I think Sun used the third implementation, but as I said up front, I'm not certain of that. But also note that the difference between the second and third is entirely in software, so it's possible to switch between them without changing hardware.
One final note: the third method (and to a lesser extent, the second) does depend on behavior I'm reasonably certain Motorola didn't actually document. So you needed to start by testing the processor to be sure what it was doing, and act accordingly. And basically anytime Motorola did even the slightest update, you needed to rerun acceptance tests, since you were depending on behavior they didn't guarantee (but as far as I know, they didn't actually change).