X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=kernel%2Finclude%2Farch-x86%2Fusercopy.h;fp=kernel%2Finclude%2Farch-x86%2Fusercopy.h;h=2b72f42c59c5c55b5e0415bca6085b9e72b8917a;hp=f220cd9963867b43e76b5e356b7a8bc338bfcb00;hb=1ac390fe1e18444008857b056c947710be9621a8;hpb=6e64b28821757af60447c790ae52a91831a9d4f0 diff --git a/kernel/include/arch-x86/usercopy.h b/kernel/include/arch-x86/usercopy.h index f220cd9..2b72f42 100644 --- a/kernel/include/arch-x86/usercopy.h +++ b/kernel/include/arch-x86/usercopy.h @@ -6,38 +6,79 @@ namespace Arch { template - static inline T copyin(T *ptr) + static inline void copyin(T *uptr, T *kdata, int count) { - // FIXME - return *ptr; + // OPT: use alignof for movsw and movsl versions + ulong bytes = sizeof(*kdata) * count; + int cause; + + if ((ulong)uptr + bytes >= PHYSMEM_START || + (ulong)uptr + bytes < (ulong)uptr) { + cause = 1; + goto bad; + } + + asm("1: rep; movsb\n" + "2:\n" + ".section .extable,\"a\"\n" + ".align 4\n" + ".long 1b\n" + ".long 2b\n" + ".previous\n" : "+c" (bytes), "+D" (kdata), "+S" (uptr), "=d" (cause)); + + if (bytes != 0) { + bad: + throw_idl(MemoryFault, reinterpret_cast(uptr), + 0, NULL, NULL, cause); + } } template - static inline void copyin(T *ptr, T &data) + static inline void copyin(T *uptr, T &kdata) { - // FIXME - data = *ptr; + // OPT: special versions for common small sizes + copyin(uptr, &kdata, 1); } template - static inline void copyin(T *ptr, T *data, int count) + static inline T copyin(T *uptr) { - // FIXME - memcpy(data, ptr, count * sizeof(T)); + T kdata; + copyin(uptr, kdata); + return kdata; } template - static inline void copyout(T *ptr, T &data) + static inline void copyout(T *uptr, T *kdata, int count) { - // FIXME - *ptr = data; + // OPT: use alignof for movsw and movsl versions + ulong bytes = sizeof(*kdata) * count; + int cause; + + if ((ulong)uptr + bytes >= PHYSMEM_START || + (ulong)uptr + bytes < (ulong)uptr) { + cause = 1; + goto bad; + } + + asm("1: rep; movsb\n" + "2:\n" + ".section .extable,\"a\"\n" + ".long 1b\n" + ".long 2b\n" + ".previous\n" : "+c" (bytes), "+S" (kdata), "+D" (uptr), "=d" (cause)); + + if (bytes != 0) { + bad: + throw_idl(MemoryFault, reinterpret_cast(uptr), + 0, NULL, NULL, cause); + } } template - static inline void copyout(T *ptr, T *data, int count) + static inline void copyout(T *uptr, T &kdata) { - // FIXME - memcpy(ptr, data, count * sizeof(T)); + copyout(uptr, &kdata, sizeof(kdata)); } }