summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4/os/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/sun4/os/trap.c')
-rw-r--r--usr/src/uts/sun4/os/trap.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/usr/src/uts/sun4/os/trap.c b/usr/src/uts/sun4/os/trap.c
index d3a2df1e09..5b69f70ada 100644
--- a/usr/src/uts/sun4/os/trap.c
+++ b/usr/src/uts/sun4/os/trap.c
@@ -158,6 +158,9 @@ trap(struct regs *rp, caddr_t addr, uint32_t type, uint32_t mmu_fsr)
int watchpage;
extern faultcode_t pagefault(caddr_t, enum fault_type,
enum seg_rw, int);
+#ifdef sun4v
+ extern boolean_t tick_stick_emulation_active;
+#endif /* sun4v */
CPU_STATS_ADDQ(CPU, sys, trap, 1);
@@ -851,7 +854,27 @@ trap(struct regs *rp, caddr_t addr, uint32_t type, uint32_t mmu_fsr)
case T_PRIV_INSTR + T_USER: /* privileged instruction fault */
if (tudebug)
showregs(type, rp, (caddr_t)0, 0);
+
bzero(&siginfo, sizeof (siginfo));
+#ifdef sun4v
+ /*
+ * If this instruction fault is a non-privileged %tick
+ * or %stick trap, and %tick/%stick user emulation is
+ * enabled as a result of an OS suspend, then simulate
+ * the register read. We rely on simulate_rdtick to fail
+ * if the instruction is not a %tick or %stick read,
+ * causing us to fall through to the normal privileged
+ * instruction handling.
+ */
+ if (tick_stick_emulation_active &&
+ (X_FAULT_TYPE(mmu_fsr) == FT_NEW_PRVACT) &&
+ simulate_rdtick(rp) == SIMU_SUCCESS) {
+ /* skip the successfully simulated instruction */
+ rp->r_pc = rp->r_npc;
+ rp->r_npc += 4;
+ goto out;
+ }
+#endif
siginfo.si_signo = SIGILL;
siginfo.si_code = ILL_PRVOPC;
siginfo.si_addr = (caddr_t)rp->r_pc;