From: Maxim Kuvyrkov <maxim@codesourcery.com>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Andreas Schwab <schwab@linux-m68k.org>, linux-m68k@vger.kernel.org
Subject: Add private syscalls to support NPTL
Date: Tue, 18 Aug 2009 01:48:39 +0400 [thread overview]
Message-ID: <4A89D037.7090807@codesourcery.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 994 bytes --]
Hello Geert,
The attached patches add kernel support for userspace NPTL bits for m68k.
Since the draft m68k/ColdFire NPTL ABI was posted at
http://marc.info/?l=linux-m68k&m=119644992713696&w=2 several issues
surfaced that called for syscall equivalents of the vDSO helpers; the
main reason for the syscalls is that GLIBC does not support linking in
vDSO for static binaries.
Another reason is that I'm having problems implementing user-space
atomic_cmpxchg (for ColdFire) and context switching for user-space TP
(both m68k and ColdFire). I've spent quite some time trying to figure
these two out, but couldn't make everything work reliably. I'll follow
up on this in a different thread.
These patches were tested on a ColdFire board running a 2.6.29 kernel,
and the system passed GLIBC's nptl tests.
The one issue I know of with this patch is that strace needs update to
pretty print the new [negative] syscalls.
Does the patches look fine?
Thanks,
--
Maxim K.
CodeSourcery
[-- Attachment #2: 0001-Add-syscalls-to-support-m68k-NPTL.patch --]
[-- Type: text/plain, Size: 5581 bytes --]
>From fda8fc4e5706e93f527c2cbc554813f090a1a3fe Mon Sep 17 00:00:00 2001
From: Maxim Kuvyrkov <maxim@codesourcery.com>
Date: Mon, 17 Aug 2009 12:16:36 -0700
Subject: [PATCH 1/2] Add syscalls to support m68k NPTL.
This patch adds several syscalls, private to M68K, that provide necessary
functionality to support NPTL.
The syscalls are read_tp, write_tp, atomic_cmpxchg_32 and atomic_barrier.
The cmpxchg syscall is required for ColdFire as it doesn't support 'cas'
instruction.
Signed-off-by: Maxim Kuvyrkov <maxim@codesourcery.com>
---
arch/m68k/include/asm/thread_info_mm.h | 1 +
arch/m68k/include/asm/unistd.h | 7 +++
arch/m68k/kernel/entry.S | 10 ++++-
arch/m68k/kernel/sys_m68k.c | 78 ++++++++++++++++++++++++++++++++
4 files changed, 95 insertions(+), 1 deletions(-)
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
index 6ea5c33..c24a353 100644
--- a/arch/m68k/include/asm/thread_info_mm.h
+++ b/arch/m68k/include/asm/thread_info_mm.h
@@ -10,6 +10,7 @@ struct thread_info {
struct exec_domain *exec_domain; /* execution domain */
int preempt_count; /* 0 => preemptable, <0 => BUG */
__u32 cpu; /* should always be 0 on m68k */
+ unsigned long tp_value;
struct restart_block restart_block;
};
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index aa29a86..619677c 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -335,9 +335,16 @@
#define __NR_preadv 329
#define __NR_pwritev 330
+/* Private syscalls. */
+#define __M68K_NR_read_tp 0xffffffff
+#define __M68K_NR_write_tp 0xfffffffe
+#define __M68K_NR_atomic_cmpxchg_32 0xfffffffd
+#define __M68K_NR_atomic_barrier 0xfffffffc
+
#ifdef __KERNEL__
#define NR_syscalls 331
+#define M68K_NR_syscalls 0xfffffffb
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 8744f60..fc834d6 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -86,6 +86,8 @@ do_trace_entry:
movel %sp@(PT_ORIG_D0),%d0
cmpl #NR_syscalls,%d0
jcs syscall
+ cmpl #M68K_NR_syscalls,%d0
+ jcc syscall
badsys:
movel #-ENOSYS,%sp@(PT_D0)
jra ret_from_syscall
@@ -124,7 +126,9 @@ ENTRY(system_call)
tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
jmi do_trace_entry
cmpl #NR_syscalls,%d0
- jcc badsys
+ jcs syscall
+ cmpl #M68K_NR_syscalls,%d0
+ jcs badsys
syscall:
jbsr @(sys_call_table,%d0:l:4)@(0)
movel %d0,%sp@(PT_D0) | save the return value
@@ -423,6 +427,10 @@ resume:
.data
ALIGN
+ .long m68k_sys_atomic_barrier /* 0xfffffffc */
+ .long m68k_sys_atomic_cmpxchg_32 /* 0xfffffffd */
+ .long m68k_sys_write_tp /* 0xfffffffe */
+ .long m68k_sys_read_tp /* 0xffffffff */
sys_call_table:
.long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
.long sys_exit
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 7f54efa..bc39ce6 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -29,6 +29,8 @@
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/unistd.h>
+#include <linux/elf.h>
+#include <asm/tlb.h>
/* common code for old and new mmaps */
static inline long do_mmap2(
@@ -663,3 +665,79 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
: "d" (__a), "d" (__b), "d" (__c));
return __res;
}
+
+asmlinkage unsigned long
+m68k_sys_read_tp(void)
+{
+ return current_thread_info()->tp_value;
+}
+
+asmlinkage void
+m68k_sys_write_tp(unsigned long tp)
+{
+ current_thread_info()->tp_value = tp;
+}
+
+/* This syscall gets its arguments in A0 (mem), A1 (oldval) and
+ D1 (newval). */
+asmlinkage int
+m68k_sys_atomic_cmpxchg_32(unsigned long newval, int d2, int d3, int d4, int d5,
+ unsigned long __user *mem, unsigned long oldval)
+{
+ /* This was borrowed from ARM's implementation. */
+ for(;;) {
+ struct mm_struct *mm = current->mm;
+ pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+ spinlock_t *ptl;
+ unsigned long mem_value;
+
+ down_read(&mm->mmap_sem);
+ pgd = pgd_offset(mm, (unsigned long)mem);
+ if (!pgd_present(*pgd))
+ goto bad_access;
+ pmd = pmd_offset(pgd, (unsigned long)mem);
+ if (!pmd_present(*pmd))
+ goto bad_access;
+ pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
+ if (!pte_present(*pte) || !pte_dirty(*pte)) {
+ pte_unmap_unlock(pte, ptl);
+ goto bad_access;
+ }
+
+ mem_value = *mem;
+ if (mem_value == oldval)
+ *mem = newval;
+
+ pte_unmap_unlock(pte, ptl);
+ up_read(&mm->mmap_sem);
+ return mem_value;
+
+ bad_access:
+ up_read(&mm->mmap_sem);
+ /* This is not necessarily a bad access, we can get here if
+ a memory we're trying to write to should be copied-on-write.
+ Make the kernel do the necessary page stuff, then re-iterate.
+ Simulate a write access fault to do that. */
+ {
+ int do_page_fault(struct pt_regs *, unsigned long,
+ unsigned long);
+ /* The first argument of the function corresponds to
+ D1, which is the first field of struct pt_regs. */
+ struct pt_regs *fp = (struct pt_regs *)&newval;
+
+ /* '3' is an RMW flag. */
+ if (do_page_fault(fp, (unsigned long)mem, 3))
+ /* If the do_page_fault() failed, we don't
+ have anything meaningful to return.
+ There should be a SIGSEGV pending for
+ the process. */
+ return 0xdeadbeef;
+ }
+ }
+}
+
+asmlinkage void
+m68k_sys_atomic_barrier(void)
+{
+ /* no code needed for uniprocs */
+}
--
1.6.2.4
[-- Attachment #3: 0002-Update-m68k-s-clone_thread.patch --]
[-- Type: text/plain, Size: 961 bytes --]
>From 14291fcace3b39c5302716f0b1972e586d2b991a Mon Sep 17 00:00:00 2001
From: Maxim Kuvyrkov <maxim@codesourcery.com>
Date: Mon, 17 Aug 2009 12:40:56 -0700
Subject: [PATCH 2/2] Update m68k's clone_thread.
This patch adds handling of CLONE_SETTLS flag to m68k's clone_thread.
Signed-off-by: Maxim Kuvyrkov <maxim@codesourcery.com>
---
arch/m68k/kernel/process.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 72bad65..0d7f9ff 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -251,6 +251,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
+
+ if (clone_flags & CLONE_SETTLS)
+ task_thread_info(p)->tp_value = regs->d5;
+
/*
* Must save the current SFC/DFC value, NOT the value when
* the parent was last descheduled - RGH 10-08-96
--
1.6.2.4
next reply other threads:[~2009-08-17 21:55 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-17 21:48 Maxim Kuvyrkov [this message]
2009-08-17 22:11 ` Add private syscalls to support NPTL Andreas Schwab
2009-08-18 7:15 ` Maxim Kuvyrkov
2009-08-18 8:06 ` Andreas Schwab
2009-08-18 8:56 ` Maxim Kuvyrkov
2009-08-18 9:22 ` Geert Uytterhoeven
2009-08-18 9:36 ` Maxim Kuvyrkov
2009-08-18 18:18 ` Andreas Schwab
2009-08-23 20:21 ` Maxim Kuvyrkov
2009-08-25 19:43 ` Maxim Kuvyrkov
2009-08-28 10:51 ` Maxim Kuvyrkov
2009-10-02 9:59 ` Maxim Kuvyrkov
2009-10-26 15:01 ` Maxim Kuvyrkov
2009-10-28 1:19 ` Finn Thain
2009-10-28 6:54 ` Maxim Kuvyrkov
2009-10-28 16:38 ` Finn Thain
2009-11-06 8:38 ` Finn Thain
2009-11-06 8:59 ` Maxim Kuvyrkov
2009-11-10 4:07 ` Finn Thain
2009-11-10 4:20 ` Brad Boyer
2009-11-10 10:51 ` Maxim Kuvyrkov
2009-11-10 16:11 ` Finn Thain
2009-08-17 22:18 ` Andreas Schwab
2009-08-18 7:10 ` Maxim Kuvyrkov
2009-08-18 2:28 ` Brad Boyer
2009-08-18 7:07 ` Maxim Kuvyrkov
2009-08-18 23:40 ` Brad Boyer
2009-08-19 8:06 ` Maxim Kuvyrkov
2009-08-19 8:35 ` Andreas Schwab
2009-12-07 8:38 ` Maxim Kuvyrkov
2009-12-09 10:25 ` Klaus Kuehnhammer
2009-12-09 11:05 ` Maxim Kuvyrkov
[not found] ` <DBFD40BF-19FC-47DF-8A7C-B71261AFBD85@parq.net>
[not found] ` <4B1F9492.6030604@codesourcery.com>
2009-12-09 15:44 ` Klaus Kuehnhammer
2009-12-10 9:18 ` Maxim Kuvyrkov
2009-12-11 14:01 ` Geert Uytterhoeven
2009-12-11 16:23 ` Maxim Kuvyrkov
2009-12-17 17:53 ` Maxim Kuvyrkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A89D037.7090807@codesourcery.com \
--to=maxim@codesourcery.com \
--cc=geert@linux-m68k.org \
--cc=linux-m68k@vger.kernel.org \
--cc=schwab@linux-m68k.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.