aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2014-10-28 15:22:13 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2014-10-28 15:22:13 +0000
commit4f3dc900231ae7975a614581b973ce530836a0c9 (patch)
treea9e1676cf19a623c0f4086b90ec27b3fff07041b /sys/kern
parent156ebc2878353594d637734ccbd2f841b3747003 (diff)
downloadsrc-4f3dc900231ae7975a614581b973ce530836a0c9.tar.gz
src-4f3dc900231ae7975a614581b973ce530836a0c9.zip
Add fueword(9) and casueword(9) functions. They are like fuword(9)
and casuword(9), but do not mix value read and indication of fault. I know (or remember) enough assembly to handle x86 and powerpc. For arm, mips and sparc64, implement fueword() and casueword() as wrappers around fuword() and casuword(), which means that the functions cannot distinguish between -1 and fault. On architectures where fueword() and casueword() are native, implement fuword() and casuword() using fueword() and casuword(), to reduce assembly code duplication. Sponsored by: The FreeBSD Foundation Tested by: pho MFC after: 2 weeks (ia64 needs treating)
Notes
Notes: svn path=/head/; revision=273783
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_uio.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c
index f2e6e3275cd6..f2bbb0cdff12 100644
--- a/sys/kern/subr_uio.c
+++ b/sys/kern/subr_uio.c
@@ -7,6 +7,11 @@
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
+ * Copyright (c) 2014 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -438,3 +443,128 @@ copyout_unmap(struct thread *td, vm_offset_t addr, size_t sz)
return (0);
}
+
+#ifdef NO_FUEWORD
+/*
+ * XXXKIB The temporal implementation of fue*() functions which do not
+ * handle usermode -1 properly, mixing it with the fault code. Keep
+ * this until MD code is written. Currently sparc64, mips and arm do
+ * not have proper implementation.
+ */
+
+int
+fueword(const void *base, long *val)
+{
+ long res;
+
+ res = fuword(base);
+ if (res == -1)
+ return (-1);
+ *val = res;
+ return (0);
+}
+
+int
+fueword32(const void *base, int32_t *val)
+{
+ int32_t res;
+
+ res = fuword32(base);
+ if (res == -1)
+ return (-1);
+ *val = res;
+ return (0);
+}
+
+#ifdef _LP64
+int
+fueword64(const void *base, int64_t *val)
+{
+ int32_t res;
+
+ res = fuword64(base);
+ if (res == -1)
+ return (-1);
+ *val = res;
+ return (0);
+}
+#endif
+
+int
+casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,
+ uint32_t newval)
+{
+ int32_t ov;
+
+ ov = casuword32(base, oldval, newval);
+ if (ov == -1)
+ return (-1);
+ *oldvalp = ov;
+ return (0);
+}
+
+int
+casueword(volatile u_long *p, u_long oldval, u_long *oldvalp, u_long newval)
+{
+ u_long ov;
+
+ ov = casuword(p, oldval, newval);
+ if (ov == -1)
+ return (-1);
+ *oldvalp = ov;
+ return (0);
+}
+#else /* NO_FUEWORD */
+int32_t
+fuword32(const void *addr)
+{
+ int rv;
+ int32_t val;
+
+ rv = fueword32(addr, &val);
+ return (rv == -1 ? -1 : val);
+}
+
+#ifdef _LP64
+int64_t
+fuword64(const void *addr)
+{
+ int rv;
+ int64_t val;
+
+ rv = fueword64(addr, &val);
+ return (rv == -1 ? -1 : val);
+}
+#endif /* _LP64 */
+
+long
+fuword(const void *addr)
+{
+ long val;
+ int rv;
+
+ rv = fueword(addr, &val);
+ return (rv == -1 ? -1 : val);
+}
+
+uint32_t
+casuword32(volatile uint32_t *addr, uint32_t old, uint32_t new)
+{
+ int rv;
+ uint32_t val;
+
+ rv = casueword32(addr, old, &val, new);
+ return (rv == -1 ? -1 : val);
+}
+
+u_long
+casuword(volatile u_long *addr, u_long old, u_long new)
+{
+ int rv;
+ u_long val;
+
+ rv = casueword(addr, old, &val, new);
+ return (rv == -1 ? -1 : val);
+}
+
+#endif /* NO_FUEWORD */