Add type qualifier volatile to the base (userspace) address argument

of fuword(9) and suword(9).  This makes the functions type-compatible
with volatile objects and does not require devolatile force, e.g. in
kern_umtx.c.

Requested by:	bde
Reviewed by:	jhb
Sponsored by:	The FreeBSD Foundation
MFC after:	3 weeks
This commit is contained in:
Konstantin Belousov 2014-10-31 17:43:21 +00:00
parent 3a4c61c2fd
commit 2361c6d135
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=273911
6 changed files with 77 additions and 93 deletions

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,