From: Ingo Molnar <mingo@elte.hu>
To: linux-kernel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Arjan van de Ven <arjan@infradead.org>,
Christoph Hellwig <hch@infradead.org>,
Andrew Morton <akpm@zip.com.au>,
Alan Cox <alan@lxorguk.ukuu.org.uk>,
Ulrich Drepper <drepper@redhat.com>,
Zach Brown <zach.brown@oracle.com>,
Evgeniy Polyakov <johnpol@2ka.mipt.ru>,
"David S. Miller" <davem@davemloft.net>,
Suparna Bhattacharya <suparna@in.ibm.com>,
Davide Libenzi <davidel@xmailserver.org>,
Jens Axboe <jens.axboe@oracle.com>,
Thomas Gleixner <tglx@linutronix.de>
Subject: [patch 12/12] syslets: x86_64: add syslet/threadlet support
Date: Wed, 28 Feb 2007 22:42:37 +0100 [thread overview]
Message-ID: <20070228214237.GL2305@elte.hu> (raw)
In-Reply-To: <20070228213938.GA945@elte.hu>
From: Ingo Molnar <mingo@elte.hu>
add the arch specific bits of syslet/threadlet support to x86_64.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86_64/Kconfig | 4 ++
arch/x86_64/ia32/ia32entry.S | 20 ++++++++++-
arch/x86_64/kernel/entry.S | 72 ++++++++++++++++++++++++++++++++++++++++-
arch/x86_64/kernel/process.c | 11 ++++++
include/asm-x86_64/processor.h | 16 +++++++++
include/asm-x86_64/system.h | 12 ++++++
include/asm-x86_64/unistd.h | 29 +++++++++++++++-
7 files changed, 160 insertions(+), 4 deletions(-)
Index: linux/arch/x86_64/Kconfig
===================================================================
--- linux.orig/arch/x86_64/Kconfig
+++ linux/arch/x86_64/Kconfig
@@ -36,6 +36,10 @@ config ZONE_DMA32
bool
default y
+config ASYNC_SUPPORT
+ bool
+ default y
+
config LOCKDEP_SUPPORT
bool
default y
Index: linux/arch/x86_64/ia32/ia32entry.S
===================================================================
--- linux.orig/arch/x86_64/ia32/ia32entry.S
+++ linux/arch/x86_64/ia32/ia32entry.S
@@ -368,6 +368,14 @@ quiet_ni_syscall:
PTREGSCALL stub32_vfork, sys_vfork, %rdi
PTREGSCALL stub32_iopl, sys_iopl, %rsi
PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx
+ /*
+ * sys_async_thread() and sys_async_exec() both take 2 parameters,
+ * none of which is ptregs - but the syscalls rely on being able to
+ * modify ptregs. So we put ptregs into the 3rd parameter - so it's
+ * unused and it also does not mess up the first 2 parameters:
+ */
+ PTREGSCALL stub32_compat_async_exec, compat_sys_async_exec, %rdx
+ PTREGSCALL stub32_compat_async_thread, sys_async_thread, %rdx
ENTRY(ia32_ptregs_common)
popq %r11
@@ -394,6 +402,9 @@ END(ia32_ptregs_common)
.section .rodata,"a"
.align 8
+.globl compat_sys_call_table
+compat_sys_call_table:
+.globl ia32_sys_call_table
ia32_sys_call_table:
.quad sys_restart_syscall
.quad sys_exit
@@ -714,9 +725,16 @@ ia32_sys_call_table:
.quad compat_sys_get_robust_list
.quad sys_splice
.quad sys_sync_file_range
- .quad sys_tee
+ .quad sys_tee /* 315 */
.quad compat_sys_vmsplice
.quad compat_sys_move_pages
.quad sys_getcpu
.quad sys_epoll_pwait
+ .quad stub32_compat_async_exec /* 320 */
+ .quad sys_async_wait
+ .quad sys_umem_add
+ .quad stub32_compat_async_thread
+ .quad sys_threadlet_on
+ .quad sys_threadlet_off /* 325 */
+.globl ia32_syscall_end
ia32_syscall_end:
Index: linux/arch/x86_64/kernel/entry.S
===================================================================
--- linux.orig/arch/x86_64/kernel/entry.S
+++ linux/arch/x86_64/kernel/entry.S
@@ -410,6 +410,14 @@ END(\label)
PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx
PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
PTREGSCALL stub_iopl, sys_iopl, %rsi
+ /*
+ * sys_async_thread() and sys_async_exec() both take 2 parameters,
+ * none of which is ptregs - but the syscalls rely on being able to
+ * modify ptregs. So we put ptregs into the 3rd parameter - so it's
+ * unused and it also does not mess up the first 2 parameters:
+ */
+ PTREGSCALL stub_async_thread, sys_async_thread, %rdx
+ PTREGSCALL stub_async_exec, sys_async_exec, %rdx
ENTRY(ptregscall_common)
popq %r11
@@ -430,7 +438,7 @@ ENTRY(ptregscall_common)
ret
CFI_ENDPROC
END(ptregscall_common)
-
+
ENTRY(stub_execve)
CFI_STARTPROC
popq %r11
@@ -990,6 +998,68 @@ child_rip:
ENDPROC(child_rip)
/*
+ * Create an async kernel thread.
+ *
+ * C extern interface:
+ * extern long create_async_thread(int (*fn)(void *), void * arg, unsigned long flags)
+ *
+ * asm input arguments:
+ * rdi: fn, rsi: arg, rdx: flags
+ */
+ENTRY(create_async_thread)
+ CFI_STARTPROC
+ FAKE_STACK_FRAME $async_child_rip
+ SAVE_ALL
+
+ # rdi: flags, rsi: usp, rdx: will be &pt_regs
+ movq %rdx,%rdi
+ movq $-1, %rsi
+ movq %rsp, %rdx
+
+ xorl %r8d,%r8d
+ xorl %r9d,%r9d
+
+ # clone now
+ call do_fork
+ movq %rax,RAX(%rsp)
+ xorl %edi,%edi
+
+ /*
+ * It isn't worth to check for reschedule here,
+ * so internally to the x86_64 port you can rely on kernel_thread()
+ * not to reschedule the child before returning, this avoids the need
+ * of hacks for example to fork off the per-CPU idle tasks.
+ * [Hopefully no generic code relies on the reschedule -AK]
+ */
+ RESTORE_ALL
+ UNFAKE_STACK_FRAME
+ ret
+ CFI_ENDPROC
+ENDPROC(async_kernel_thread)
+
+async_child_rip:
+ CFI_STARTPROC
+
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ call *%rax
+
+ /*
+ * Fix up the PDA - we might return with sysexit:
+ */
+ RESTORE_TOP_OF_STACK %r11
+
+ /*
+ * return to user-space:
+ */
+ movq %rax, RAX(%rsp)
+ RESTORE_REST
+ jmp int_ret_from_sys_call
+
+ CFI_ENDPROC
+ENDPROC(async_child_rip)
+
+/*
* execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
*
* C extern interface:
Index: linux/arch/x86_64/kernel/process.c
===================================================================
--- linux.orig/arch/x86_64/kernel/process.c
+++ linux/arch/x86_64/kernel/process.c
@@ -418,6 +418,17 @@ void release_thread(struct task_struct *
}
}
+/*
+ * Move user-space context from one kernel thread to another.
+ * Callers must make sure that neither task is running user context
+ * at the moment:
+ */
+void
+move_user_context(struct task_struct *new_task, struct task_struct *old_task)
+{
+ *task_pt_regs(new_task) = *task_pt_regs(old_task);
+}
+
static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
{
struct user_desc ud = {
Index: linux/include/asm-x86_64/processor.h
===================================================================
--- linux.orig/include/asm-x86_64/processor.h
+++ linux/include/asm-x86_64/processor.h
@@ -322,6 +322,11 @@ extern void prepare_to_copy(struct task_
extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
+ * create an async thread:
+ */
+extern long create_async_thread(long (*fn)(void *), void * arg, unsigned long flags);
+
+/*
* Return saved PC of a blocked thread.
* What is this good for? it will be always the scheduler or ret_from_fork.
*/
@@ -332,6 +337,17 @@ extern unsigned long get_wchan(struct ta
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
+/*
+ * Register access methods for async syscall support.
+ *
+ * Note, task_stack_reg() must not be an lvalue, hence this macro:
+ */
+#define task_stack_reg(t) \
+ ({ unsigned long __rsp = task_pt_regs(t)->rsp; __rsp; })
+#define set_task_stack_reg(t, new_stack) \
+ do { task_pt_regs(t)->rsp = (new_stack); } while (0)
+#define task_ip_reg(t) task_pt_regs(t)->rip
+#define task_ret_reg(t) task_pt_regs(t)->rax
struct microcode_header {
unsigned int hdrver;
Index: linux/include/asm-x86_64/system.h
===================================================================
--- linux.orig/include/asm-x86_64/system.h
+++ linux/include/asm-x86_64/system.h
@@ -20,6 +20,8 @@
#define __EXTRA_CLOBBER \
,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"
+struct task_struct;
+
/* Save restore flags to clear handle leaking NT */
#define switch_to(prev,next,last) \
asm volatile(SAVE_CONTEXT \
@@ -42,7 +44,15 @@
[thread_info] "i" (offsetof(struct task_struct, thread_info)), \
[pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
: "memory", "cc" __EXTRA_CLOBBER)
-
+
+
+/*
+ * Move user-space context from one kernel thread to another.
+ * This includes registers and FPU state for now:
+ */
+extern void
+move_user_context(struct task_struct *new_task, struct task_struct *old_task);
+
extern void load_gs_index(unsigned);
/*
Index: linux/include/asm-x86_64/unistd.h
===================================================================
--- linux.orig/include/asm-x86_64/unistd.h
+++ linux/include/asm-x86_64/unistd.h
@@ -619,8 +619,21 @@ __SYSCALL(__NR_sync_file_range, sys_sync
__SYSCALL(__NR_vmsplice, sys_vmsplice)
#define __NR_move_pages 279
__SYSCALL(__NR_move_pages, sys_move_pages)
+#define __NR_async_exec 280
+__SYSCALL(__NR_async_exec, stub_async_exec)
+#define __NR_async_wait 281
+__SYSCALL(__NR_async_wait, sys_async_wait)
+#define __NR_umem_add 282
+__SYSCALL(__NR_umem_add, sys_umem_add)
+#define __NR_async_thread 283
+__SYSCALL(__NR_async_thread, stub_async_thread)
+#define __NR_threadlet_on 284
+__SYSCALL(__NR_threadlet_on, sys_threadlet_on)
+#define __NR_threadlet_off 285
+__SYSCALL(__NR_threadlet_off, sys_threadlet_off)
-#define __NR_syscall_max __NR_move_pages
+#define __NR_syscall_max __NR_threadlet_off
+#define NR_syscalls __NR_syscall_max
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
@@ -654,6 +667,20 @@ __SYSCALL(__NR_move_pages, sys_move_page
#include <linux/types.h>
#include <asm/ptrace.h>
+typedef asmlinkage long (*syscall_fn_t)(long, long, long, long, long, long);
+
+extern syscall_fn_t sys_call_table[NR_syscalls];
+
+#ifdef CONFIG_COMPAT
+
+extern syscall_fn_t compat_sys_call_table[];
+extern syscall_fn_t ia32_syscall_end;
+extern syscall_fn_t ia32_sys_call_table;
+
+#define compat_NR_syscalls (&ia32_syscall_end - compat_sys_call_table)
+
+#endif
+
asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
struct sigaction;
next prev parent reply other threads:[~2007-02-28 21:51 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-28 21:39 [patch 00/12] Syslets, Threadlets, generic AIO support, v5 Ingo Molnar
2007-02-28 21:41 ` [patch 01/12] syslets: add async.h include file, kernel-side API definitions Ingo Molnar
2007-02-28 21:41 ` [patch 02/12] syslets: add syslet.h include file, user API/ABI definitions Ingo Molnar
2007-03-01 3:05 ` Kevin O'Connor
2007-03-01 9:18 ` Ingo Molnar
2007-02-28 21:41 ` [patch 03/12] syslets: generic kernel bits Ingo Molnar
2007-02-28 21:41 ` [patch 04/12] syslets: core code Ingo Molnar
2007-02-28 21:41 ` [patch 05/12] syslets: core, documentation Ingo Molnar
2007-02-28 21:41 ` [patch 06/12] x86: split FPU state from task state Ingo Molnar
2007-02-28 21:42 ` [patch 07/12] syslets: x86, add create_async_thread() method Ingo Molnar
2007-02-28 21:42 ` [patch 08/12] syslets: x86, add move_user_context() method Ingo Molnar
2007-02-28 21:42 ` [patch 09/12] syslets: x86, mark async unsafe syscalls Ingo Molnar
2007-02-28 21:42 ` [patch 10/12] syslets: x86: enable ASYNC_SUPPORT Ingo Molnar
2007-02-28 21:42 ` [patch 11/12] syslets: x86, wire up the syslet system calls Ingo Molnar
2007-02-28 21:42 ` Ingo Molnar [this message]
2007-03-01 9:36 ` [patch 00/12] Syslets, Threadlets, generic AIO support, v5 Stephen Rothwell
2007-03-07 20:10 ` Anton Blanchard
2007-03-13 7:05 ` Milton Miller
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=20070228214237.GL2305@elte.hu \
--to=mingo@elte.hu \
--cc=akpm@zip.com.au \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=arjan@infradead.org \
--cc=davem@davemloft.net \
--cc=davidel@xmailserver.org \
--cc=drepper@redhat.com \
--cc=hch@infradead.org \
--cc=jens.axboe@oracle.com \
--cc=johnpol@2ka.mipt.ru \
--cc=linux-kernel@vger.kernel.org \
--cc=suparna@in.ibm.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=zach.brown@oracle.com \
/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.