summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-02-13 23:11:07 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-02-13 23:11:07 +0000
commite610c324750a4b1f80d6d4980a796439773bff0d (patch)
tree13a23c251e7c1d2f7b364539250a186ecf0c6cec /sys/dev/pci
parent3803ded5c18507905f6419a8c0b7410e9118cb82 (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.c24
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