diff --git a/share/man/man9/fetch.9 b/share/man/man9/fetch.9 index 7e13cbc51c45..1d46784ed310 100644 --- a/share/man/man9/fetch.9 +++ b/share/man/man9/fetch.9 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 21, 2014 +.Dd October 29, 2014 .Dt FETCH 9 .Os .Sh NAME @@ -53,21 +53,21 @@ .In sys/types.h .In sys/systm.h .Ft int -.Fn fubyte "const void *base" +.Fn fubyte "volatile const void *base" .Ft long -.Fn fuword "const void *base" +.Fn fuword "volatile const void *base" .Ft int -.Fn fuword16 "void *base" +.Fn fuword16 "volatile const void *base" .Ft int32_t -.Fn fuword32 "const void *base" +.Fn fuword32 "volatile const void *base" .Ft int64_t -.Fn fuword64 "const void *base" +.Fn fuword64 "volatile const void *base" .Ft long -.Fn fueword "const void *base" "long *val" +.Fn fueword "volatile const void *base" "long *val" .Ft int32_t -.Fn fueword32 "const void *base" "int32_t *val" +.Fn fueword32 "volatile const void *base" "int32_t *val" .Ft int64_t -.Fn fueword64 "const void *base" "int64_t *val" +.Fn fueword64 "volatile const void *base" "int64_t *val" .In sys/resourcevar.h .Ft int .Fn fuswintr "void *base" diff --git a/share/man/man9/store.9 b/share/man/man9/store.9 index d333eff03315..cc442f25f47c 100644 --- a/share/man/man9/store.9 +++ b/share/man/man9/store.9 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 5, 2009 +.Dd October 29, 2014 .Dt STORE 9 .Os .Sh NAME @@ -48,15 +48,15 @@ .In sys/time.h .In sys/systm.h .Ft int -.Fn subyte "void *base" "int byte" +.Fn subyte "volatile void *base" "int byte" .Ft int -.Fn suword "void *base" "long word" +.Fn suword "volatile void *base" "long word" .Ft int -.Fn suword16 "void *base" "int word" +.Fn suword16 "volatile void *base" "int word" .Ft int -.Fn suword32 "void *base" "int32_t word" +.Fn suword32 "volatile void *base" "int32_t word" .Ft int -.Fn suword64 "void *base" "int64_t word" +.Fn suword64 "volatile void *base" "int64_t word" .In sys/resourcevar.h .Ft int .Fn suswintr "void *base" "int word" @@ -64,6 +64,8 @@ The .Nm functions are designed to copy small amounts of data to user-space. +If write is successful, it is performed atomically. +The data written must be naturally aligned. .Pp The .Nm diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 58e76bc90b64..33fdf71e5ebe 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -942,7 +942,7 @@ do_lock_normal(struct thread *td, struct umutex *m, uint32_t flags, * can fault on any access. */ for (;;) { - rv = fueword32(__DEVOLATILE(void *, &m->m_owner), &owner); + rv = fueword32(&m->m_owner, &owner); if (rv == -1) return (EFAULT); if (mode == _UMUTEX_WAIT) { @@ -1057,7 +1057,7 @@ do_unlock_normal(struct thread *td, struct umutex *m, uint32_t flags) /* * Make sure we own this mtx. */ - error = fueword32(__DEVOLATILE(uint32_t *, &m->m_owner), &owner); + error = fueword32(&m->m_owner, &owner); if (error == -1) return (EFAULT); @@ -1115,7 +1115,7 @@ do_wake_umutex(struct thread *td, struct umutex *m) int error; int count; - error = fueword32(__DEVOLATILE(uint32_t *, &m->m_owner), &owner); + error = fueword32(&m->m_owner, &owner); if (error == -1) return (EFAULT); @@ -1192,8 +1192,7 @@ do_wake2_umutex(struct thread *td, struct umutex *m, uint32_t flags) * any memory. */ if (count > 1) { - error = fueword32(__DEVOLATILE(uint32_t *, &m->m_owner), - &owner); + error = fueword32(&m->m_owner, &owner); if (error == -1) error = EFAULT; while (error == 0 && (owner & UMUTEX_CONTESTED) == 0) { @@ -1211,8 +1210,7 @@ do_wake2_umutex(struct thread *td, struct umutex *m, uint32_t flags) break; } } else if (count == 1) { - error = fueword32(__DEVOLATILE(uint32_t *, &m->m_owner), - &owner); + error = fueword32(&m->m_owner, &owner); if (error == -1) error = EFAULT; while (error == 0 && (owner & ~UMUTEX_CONTESTED) != 0 && @@ -1776,7 +1774,7 @@ do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags) /* * Make sure we own this mtx. */ - error = fueword32(__DEVOLATILE(uint32_t *, &m->m_owner), &owner); + error = fueword32(&m->m_owner, &owner); if (error == -1) return (EFAULT); @@ -2008,7 +2006,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags) /* * Make sure we own this mtx. */ - error = fueword32(__DEVOLATILE(uint32_t *, &m->m_owner), &owner); + error = fueword32(&m->m_owner, &owner); if (error == -1) return (EFAULT); @@ -2040,8 +2038,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags) * to lock the mutex, it is necessary because thread priority * has to be adjusted for such mutex. */ - error = suword32(__DEVOLATILE(uint32_t *, &m->m_owner), - UMUTEX_CONTESTED); + error = suword32(&m->m_owner, UMUTEX_CONTESTED); umtxq_lock(&key); if (error == 0) @@ -2116,8 +2113,7 @@ do_set_ceiling(struct thread *td, struct umutex *m, uint32_t ceiling, if (owner == UMUTEX_CONTESTED) { suword32(&m->m_ceilings[0], ceiling); - suword32(__DEVOLATILE(uint32_t *, &m->m_owner), - UMUTEX_CONTESTED); + suword32(&m->m_owner, UMUTEX_CONTESTED); error = 0; break; } @@ -2263,10 +2259,9 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, * Set c_has_waiters to 1 before releasing user mutex, also * don't modify cache line when unnecessary. */ - error = fueword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), - &hasw); + error = fueword32(&cv->c_has_waiters, &hasw); if (error == 0 && hasw == 0) - suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 1); + suword32(&cv->c_has_waiters, 1); umtxq_unbusy_unlocked(&uq->uq_key); @@ -2296,9 +2291,7 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, umtxq_remove(uq); if (oldlen == 1) { umtxq_unlock(&uq->uq_key); - suword32( - __DEVOLATILE(uint32_t *, - &cv->c_has_waiters), 0); + suword32(&cv->c_has_waiters, 0); umtxq_lock(&uq->uq_key); } } @@ -2333,8 +2326,7 @@ do_cv_signal(struct thread *td, struct ucond *cv) nwake = umtxq_signal(&key, 1); if (cnt <= nwake) { umtxq_unlock(&key); - error = suword32( - __DEVOLATILE(uint32_t *, &cv->c_has_waiters), 0); + error = suword32(&cv->c_has_waiters, 0); if (error == -1) error = EFAULT; umtxq_lock(&key); @@ -2363,7 +2355,7 @@ do_cv_broadcast(struct thread *td, struct ucond *cv) umtxq_signal(&key, INT_MAX); umtxq_unlock(&key); - error = suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 0); + error = suword32(&cv->c_has_waiters, 0); if (error == -1) error = EFAULT; @@ -2399,8 +2391,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, struct _umtx wrflags |= URWLOCK_WRITE_WAITERS; for (;;) { - rv = fueword32(__DEVOLATILE(int32_t *, &rwlock->rw_state), - &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) { umtx_key_release(&uq->uq_key); return (EFAULT); @@ -2440,8 +2431,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, struct _umtx * re-read the state, in case it changed between the try-lock above * and the check below */ - rv = fueword32(__DEVOLATILE(int32_t *, &rwlock->rw_state), - &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) error = EFAULT; @@ -2499,8 +2489,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, struct _umtx umtxq_unlock(&uq->uq_key); if (error) break; - rv = fueword32(__DEVOLATILE(int32_t *, - &rwlock->rw_state), &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) { error = EFAULT; break; @@ -2517,8 +2506,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, struct _umtx } suword32(&rwlock->rw_blocked_readers, blocked_readers-1); if (blocked_readers == 1) { - rv = fueword32(__DEVOLATILE(int32_t *, - &rwlock->rw_state), &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) error = EFAULT; while (error == 0) { @@ -2569,8 +2557,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, struct _umtx_time *timeo blocked_readers = 0; for (;;) { - rv = fueword32(__DEVOLATILE(int32_t *, &rwlock->rw_state), - &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) { umtx_key_release(&uq->uq_key); return (EFAULT); @@ -2614,8 +2601,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, struct _umtx_time *timeo * re-read the state, in case it changed between the try-lock above * and the check below */ - rv = fueword32(__DEVOLATILE(int32_t *, &rwlock->rw_state), - &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) error = EFAULT; @@ -2670,8 +2656,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, struct _umtx_time *timeo umtxq_unlock(&uq->uq_key); if (error) break; - rv = fueword32(__DEVOLATILE(int32_t *, - &rwlock->rw_state), &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) { error = EFAULT; break; @@ -2687,8 +2672,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, struct _umtx_time *timeo } suword32(&rwlock->rw_blocked_writers, blocked_writers-1); if (blocked_writers == 1) { - rv = fueword32(__DEVOLATILE(int32_t *, - &rwlock->rw_state), &state); + rv = fueword32(&rwlock->rw_state, &state); if (rv == -1) { umtxq_unbusy_unlocked(&uq->uq_key); error = EFAULT; @@ -2748,7 +2732,7 @@ do_rw_unlock(struct thread *td, struct urwlock *rwlock) if (error != 0) return (error); - error = fueword32(__DEVOLATILE(int32_t *, &rwlock->rw_state), &state); + error = fueword32(&rwlock->rw_state, &state); if (error == -1) { error = EFAULT; goto out; @@ -2856,7 +2840,7 @@ do_sem_wait(struct thread *td, struct _usem *sem, struct _umtx_time *timeout) umtxq_unlock(&uq->uq_key); rv = casueword32(&sem->_has_waiters, 0, &count1, 1); if (rv == 0) - rv = fueword32(__DEVOLATILE(uint32_t *, &sem->_count), &count); + rv = fueword32(&sem->_count, &count); if (rv == -1 || count != 0) { umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key); @@ -2911,8 +2895,7 @@ do_sem_wake(struct thread *td, struct _usem *sem) */ if (cnt == 1) { umtxq_unlock(&key); - error = suword32( - __DEVOLATILE(uint32_t *, &sem->_has_waiters), 0); + error = suword32(&sem->_has_waiters, 0); umtxq_lock(&key); if (error == -1) error = EFAULT; @@ -2946,7 +2929,7 @@ do_sem2_wait(struct thread *td, struct _usem2 *sem, struct _umtx_time *timeout) umtxq_busy(&uq->uq_key); umtxq_insert(uq); umtxq_unlock(&uq->uq_key); - rv = fueword32(__DEVOLATILE(uint32_t *, &sem->_count), &count); + rv = fueword32(&sem->_count, &count); if (rv == -1) { umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key); @@ -3024,8 +3007,7 @@ do_sem2_wake(struct thread *td, struct _usem2 *sem) */ if (cnt == 1) { umtxq_unlock(&key); - rv = fueword32(__DEVOLATILE(uint32_t *, &sem->_count), - &count); + rv = fueword32(&sem->_count, &count); while (rv != -1 && count & USEM_HAS_WAITERS) rv = casueword32(&sem->_count, count, &count, count & ~USEM_HAS_WAITERS); diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index f2bbb0cdff12..87892fd82798 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -453,7 +453,7 @@ copyout_unmap(struct thread *td, vm_offset_t addr, size_t sz) */ int -fueword(const void *base, long *val) +fueword(volatile const void *base, long *val) { long res; @@ -465,7 +465,7 @@ fueword(const void *base, long *val) } int -fueword32(const void *base, int32_t *val) +fueword32(volatile const void *base, int32_t *val) { int32_t res; @@ -478,7 +478,7 @@ fueword32(const void *base, int32_t *val) #ifdef _LP64 int -fueword64(const void *base, int64_t *val) +fueword64(volatile const void *base, int64_t *val) { int32_t res; @@ -516,7 +516,7 @@ casueword(volatile u_long *p, u_long oldval, u_long *oldvalp, u_long newval) } #else /* NO_FUEWORD */ int32_t -fuword32(const void *addr) +fuword32(volatile const void *addr) { int rv; int32_t val; @@ -527,7 +527,7 @@ fuword32(const void *addr) #ifdef _LP64 int64_t -fuword64(const void *addr) +fuword64(volatile const void *addr) { int rv; int64_t val; @@ -538,7 +538,7 @@ fuword64(const void *addr) #endif /* _LP64 */ long -fuword(const void *addr) +fuword(volatile const void *addr) { long val; int rv; diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c index a337c8b73495..fdee51da056e 100644 --- a/sys/powerpc/powerpc/copyinout.c +++ b/sys/powerpc/powerpc/copyinout.c @@ -80,7 +80,7 @@ int setfault(faultbuf); /* defined in locore.S */ #ifdef __powerpc64__ static __inline void -set_user_sr(pmap_t pm, const void *addr) +set_user_sr(pmap_t pm, volatile const void *addr) { struct slb *slb; register_t slbv; @@ -113,7 +113,7 @@ set_user_sr(pmap_t pm, const void *addr) } #else static __inline void -set_user_sr(pmap_t pm, const void *addr) +set_user_sr(pmap_t pm, volatile const void *addr) { register_t vsid; @@ -135,7 +135,7 @@ set_user_sr(pmap_t pm, const void *addr) #endif static __inline int -map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen, +map_user_ptr(pmap_t pm, volatile const void *uaddr, void **kaddr, size_t ulen, size_t *klen) { size_t l; @@ -156,7 +156,7 @@ map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen, } #else /* Book-E uses a combined kernel/user mapping */ static __inline int -map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen, +map_user_ptr(pmap_t pm, volatile const void *uaddr, void **kaddr, size_t ulen, size_t *klen) { @@ -281,7 +281,7 @@ copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done) } int -subyte(void *addr, int byte) +subyte(volatile void *addr, int byte) { struct thread *td; pmap_t pm; @@ -309,7 +309,7 @@ subyte(void *addr, int byte) #ifdef __powerpc64__ int -suword32(void *addr, int word) +suword32(volatile void *addr, int word) { struct thread *td; pmap_t pm; @@ -337,7 +337,7 @@ suword32(void *addr, int word) #endif int -suword(void *addr, long word) +suword(volatile void *addr, long word) { struct thread *td; pmap_t pm; @@ -365,20 +365,20 @@ suword(void *addr, long word) #ifdef __powerpc64__ int -suword64(void *addr, int64_t word) +suword64(volatile void *addr, int64_t word) { return (suword(addr, (long)word)); } #else int -suword32(void *addr, int32_t word) +suword32(volatile void *addr, int32_t word) { return (suword(addr, (long)word)); } #endif int -fubyte(const void *addr) +fubyte(volatile const void *addr) { struct thread *td; pmap_t pm; @@ -406,7 +406,7 @@ fubyte(const void *addr) } int -fuword16(const void *addr) +fuword16(volatile const void *addr) { struct thread *td; pmap_t pm; @@ -433,7 +433,7 @@ fuword16(const void *addr) } int -fueword32(const void *addr, int32_t *val) +fueword32(volatile const void *addr, int32_t *val) { struct thread *td; pmap_t pm; @@ -461,7 +461,7 @@ fueword32(const void *addr, int32_t *val) #ifdef __powerpc64__ int -fueword64(const void *addr, int64_t *val) +fueword64(volatile const void *addr, int64_t *val) { struct thread *td; pmap_t pm; @@ -489,7 +489,7 @@ fueword64(const void *addr, int64_t *val) #endif int -fueword(const void *addr, long *val) +fueword(volatile const void *addr, long *val) { struct thread *td; pmap_t pm; diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 6f2e86d4225a..d3833d0f7df6 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -252,19 +252,19 @@ int copyout(const void * __restrict kaddr, void * __restrict udaddr, int copyout_nofault(const void * __restrict kaddr, void * __restrict udaddr, size_t len) __nonnull(1) __nonnull(2); -int fubyte(const void *base); -long fuword(const void *base); -int fuword16(const void *base); -int32_t fuword32(const void *base); -int64_t fuword64(const void *base); -int fueword(const void *base, long *val); -int fueword32(const void *base, int32_t *val); -int fueword64(const void *base, int64_t *val); -int subyte(void *base, int byte); -int suword(void *base, long word); -int suword16(void *base, int word); -int suword32(void *base, int32_t word); -int suword64(void *base, int64_t word); +int fubyte(volatile const void *base); +long fuword(volatile const void *base); +int fuword16(volatile const void *base); +int32_t fuword32(volatile const void *base); +int64_t fuword64(volatile const void *base); +int fueword(volatile const void *base, long *val); +int fueword32(volatile const void *base, int32_t *val); +int fueword64(volatile const void *base, int64_t *val); +int subyte(volatile void *base, int byte); +int suword(volatile void *base, long word); +int suword16(volatile void *base, int word); +int suword32(volatile void *base, int32_t word); +int suword64(volatile void *base, int64_t word); uint32_t casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval); u_long casuword(volatile u_long *p, u_long oldval, u_long newval); int casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp,