diff options
Diffstat (limited to 'sys/powerpc/aim/machdep.c')
-rw-r--r-- | sys/powerpc/aim/machdep.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index ac35d8f..cedcf73 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/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); +} |