summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powerpc/machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/powerpc/powerpc/machdep.c')
-rw-r--r--sys/powerpc/powerpc/machdep.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c
index ac35d8f..cedcf73 100644
--- a/sys/powerpc/powerpc/machdep.c
+++ b/sys/powerpc/powerpc/machdep.c
@@ -961,3 +961,33 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
pcpu->pc_current_asngen = 1;
}
+
+/*
+ * kcopy(const void *src, void *dst, size_t len);
+ *
+ * Copy len bytes from src to dst, aborting if we encounter a fatal
+ * page fault.
+ *
+ * kcopy() _must_ save and restore the old fault handler since it is
+ * called by uiomove(), which may be in the path of servicing a non-fatal
+ * page fault.
+ */
+int
+kcopy(const void *src, void *dst, size_t len)
+{
+ struct thread *td;
+ faultbuf env, *oldfault;
+ int rv;
+
+ td = PCPU_GET(curthread);
+ oldfault = td->td_pcb->pcb_onfault;
+ if ((rv = setfault(env)) != 0) {
+ td->td_pcb->pcb_onfault = oldfault;
+ return rv;
+ }
+
+ memcpy(dst, src, len);
+
+ td->td_pcb->pcb_onfault = oldfault;
+ return (0);
+}
OpenPOWER on IntegriCloud