diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-02-13 23:11:07 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-02-13 23:11:07 +0000 |
commit | e610c324750a4b1f80d6d4980a796439773bff0d (patch) | |
tree | 13a23c251e7c1d2f7b364539250a186ecf0c6cec /sys/dev/pci | |
parent | 3803ded5c18507905f6419a8c0b7410e9118cb82 (diff) |
Some Linux i915 drm "fast" path code relies on being able to "disable" page
faults to avoid sleeping. Implement this functionality for i386 and amd64
for faults in the user address space. If the ci_inatomic flag is set in
struct cpu_info, copyin(9) and copyout(9) will return EFAULT when a user-space
address needs to be faulted in. Use this to properly implement
__copy_to_user_inatomic() and __copy_from_user_inatomic_nocache() in the
inteldrm(4) code.
ok krw@, guenther@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/drm/i915/i915_gem.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/sys/dev/pci/drm/i915/i915_gem.c b/sys/dev/pci/drm/i915/i915_gem.c index 6ec39493257..24d995811d3 100644 --- a/sys/dev/pci/drm/i915/i915_gem.c +++ b/sys/dev/pci/drm/i915/i915_gem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_gem.c,v 1.69 2014/02/05 10:41:32 kettenis Exp $ */ +/* $OpenBSD: i915_gem.c,v 1.70 2014/02/13 23:11:05 kettenis Exp $ */ /* * Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org> * @@ -368,9 +368,14 @@ __copy_to_user(void *to, const void *from, unsigned len) static inline unsigned long __copy_to_user_inatomic(void *to, const void *from, unsigned len) { - if (copyout(from, to, len)) - return len; - return 0; + struct cpu_info *ci = curcpu(); + int error; + + ci->ci_inatomic = 1; + error = copyout(from, to, len); + ci->ci_inatomic = 0; + + return (error ? len : 0); } static inline int @@ -410,9 +415,14 @@ __copy_from_user(void *to, const void *from, unsigned len) static inline unsigned long __copy_from_user_inatomic_nocache(void *to, const void *from, unsigned len) { - if (copyin(from, to, len)) - return len; - return 0; + struct cpu_info *ci = curcpu(); + int error; + + ci->ci_inatomic = 1; + error = copyin(from, to, len); + ci->ci_inatomic = 0; + + return (error ? len : 0); } static inline int |