diff options
author | jeff <jeff@FreeBSD.org> | 2003-04-01 00:18:55 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2003-04-01 00:18:55 +0000 |
commit | 420a77ecd5237fe6d8d85dfc52e0e7050554b768 (patch) | |
tree | d76cda4e540786cf76f11bcb84ebefd1fd2bfd17 /sys | |
parent | 56865cc54968bbe0d21f2909d13cfade62bb789d (diff) | |
download | FreeBSD-src-420a77ecd5237fe6d8d85dfc52e0e7050554b768.zip FreeBSD-src-420a77ecd5237fe6d8d85dfc52e0e7050554b768.tar.gz |
- Define a new md function 'casuptr'. This atomically compares and sets
a pointer that is in user space. It will be used as the basic primitive
for a kernel supported user space lock implementation.
- Implement this function in x86's support.s
- Provide stubs that return -1 in all other architectures. Implementations
will follow along shortly.
Reviewed by: jake
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/alpha/machdep.c | 6 | ||||
-rw-r--r-- | sys/amd64/amd64/support.S | 31 | ||||
-rw-r--r-- | sys/amd64/amd64/support.s | 31 | ||||
-rw-r--r-- | sys/i386/i386/support.s | 31 | ||||
-rw-r--r-- | sys/ia64/ia64/machdep.c | 7 | ||||
-rw-r--r-- | sys/pc98/i386/machdep.c | 8 | ||||
-rw-r--r-- | sys/pc98/pc98/machdep.c | 8 | ||||
-rw-r--r-- | sys/powerpc/aim/machdep.c | 8 | ||||
-rw-r--r-- | sys/powerpc/powerpc/machdep.c | 8 | ||||
-rw-r--r-- | sys/sparc64/sparc64/machdep.c | 7 | ||||
-rw-r--r-- | sys/sys/systm.h | 1 |
11 files changed, 146 insertions, 0 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index 055d3f8..50627d9 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -2324,3 +2324,9 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) pcpu->pc_idlepcb.apcb_ptbr = thread0.td_pcb->pcb_hw.apcb_ptbr; pcpu->pc_current_asngen = 1; } + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 5e57315..cc53683 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -1173,6 +1173,37 @@ fastmove_tail_fault: #endif /* I586_CPU && defined(DEV_NPX) */ /* + * casuptr. Compare and set user pointer. Returns -1 or the current value. + */ +ENTRY(casuptr) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx /* dst */ + movl 8(%esp),%eax /* old */ + movl 12(%esp),%ecx /* new */ + + cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */ + ja fusufault + +#if defined(SMP) + lock cmpxchgl %ecx, (%edx) /* Compare and set. */ +#else /* !SMP */ + cmpxchgl %ecx, (%edx) +#endif /* !SMP */ + + /* + * We store the current value regardless of the success of the + * cmpxchg. Calling code checks for new == return to determine + * success. + */ + movl (%edx), %eax + + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl $0,PCB_ONFAULT(%ecx) + ret + +/* * fu{byte,sword,word} - MP SAFE * * Fetch a byte (sword, word) from user memory diff --git a/sys/amd64/amd64/support.s b/sys/amd64/amd64/support.s index 5e57315..cc53683 100644 --- a/sys/amd64/amd64/support.s +++ b/sys/amd64/amd64/support.s @@ -1173,6 +1173,37 @@ fastmove_tail_fault: #endif /* I586_CPU && defined(DEV_NPX) */ /* + * casuptr. Compare and set user pointer. Returns -1 or the current value. + */ +ENTRY(casuptr) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx /* dst */ + movl 8(%esp),%eax /* old */ + movl 12(%esp),%ecx /* new */ + + cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */ + ja fusufault + +#if defined(SMP) + lock cmpxchgl %ecx, (%edx) /* Compare and set. */ +#else /* !SMP */ + cmpxchgl %ecx, (%edx) +#endif /* !SMP */ + + /* + * We store the current value regardless of the success of the + * cmpxchg. Calling code checks for new == return to determine + * success. + */ + movl (%edx), %eax + + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl $0,PCB_ONFAULT(%ecx) + ret + +/* * fu{byte,sword,word} - MP SAFE * * Fetch a byte (sword, word) from user memory diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s index 5e57315..cc53683 100644 --- a/sys/i386/i386/support.s +++ b/sys/i386/i386/support.s @@ -1173,6 +1173,37 @@ fastmove_tail_fault: #endif /* I586_CPU && defined(DEV_NPX) */ /* + * casuptr. Compare and set user pointer. Returns -1 or the current value. + */ +ENTRY(casuptr) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx /* dst */ + movl 8(%esp),%eax /* old */ + movl 12(%esp),%ecx /* new */ + + cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */ + ja fusufault + +#if defined(SMP) + lock cmpxchgl %ecx, (%edx) /* Compare and set. */ +#else /* !SMP */ + cmpxchgl %ecx, (%edx) +#endif /* !SMP */ + + /* + * We store the current value regardless of the success of the + * cmpxchg. Calling code checks for new == return to determine + * success. + */ + movl (%edx), %eax + + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl $0,PCB_ONFAULT(%ecx) + ret + +/* * fu{byte,sword,word} - MP SAFE * * Fetch a byte (sword, word) from user memory diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index bdc8dca..fb16a72 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -1444,3 +1444,10 @@ ia64_rse_previous_frame(u_int64_t *bsp, int size) return bsp - size - rnats; } + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} + diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 2b2b979..ac597ff 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -2803,3 +2803,11 @@ outb(u_int port, u_char data) } #endif /* DDB */ + + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} + diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 2b2b979..ac597ff 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -2803,3 +2803,11 @@ outb(u_int port, u_char data) } #endif /* DDB */ + + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} + diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 54661aa..e904fa3 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -752,3 +752,11 @@ kcopy(const void *src, void *dst, size_t len) td->td_pcb->pcb_onfault = oldfault; return (0); } + + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} + diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c index 54661aa..e904fa3 100644 --- a/sys/powerpc/powerpc/machdep.c +++ b/sys/powerpc/powerpc/machdep.c @@ -752,3 +752,11 @@ kcopy(const void *src, void *dst, size_t len) td->td_pcb->pcb_onfault = oldfault; return (0); } + + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} + diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index fa2ba40..b662961 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -703,3 +703,10 @@ set_fpregs(struct thread *td, struct fpreg *fpregs) tf->tf_gsr = fpregs->fr_gsr; return (0); } + +intptr_t +casuptr(intptr_t *p, intptr_t old, intptr_t new) +{ + return (-1); +} + diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 5443d01..698ff07 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -197,6 +197,7 @@ 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); +intptr_t casuptr(intptr_t *p, intptr_t old, intptr_t new); void realitexpire(void *); |