Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: m-labs/linux-milkymist
base: d5f28d5a11f0
...
head fork: m-labs/linux-milkymist
compare: 0ca475bc9227
  • 7 commits
  • 17 files changed
  • 0 commit comments
  • 2 contributors
Commits on Feb 23, 2013
Lars-Peter Clausen larsclausen lm32: Drop unused debugger_info field from thread_info struct
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
37807cf
Lars-Peter Clausen larsclausen Drop __devinit/__devexit from milkymist drivers
These will be gone in upstream v3.8

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
b0017d7
Lars-Peter Clausen larsclausen lm32: Implement user_stack_pointer()
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
a756401
Lars-Peter Clausen larsclausen lm32: Switch to GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
50af5f9
Lars-Peter Clausen larsclausen lm32: switch to generic sys_execve()
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
aab9d67
Al Viro generic sys_fork / sys_vfork / sys_clone
... and get rid of idiotic struct pt_regs * in asm-generic/syscalls.h
prototypes of the same, while we are at it.  Eventually we want those
in linux/syscalls.h, of course, but that'll have to wait a bit.

Note that there are *three* variants of sys_clone() order of arguments.
Braindamage galore...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
e1bbf3a
Lars-Peter Clausen larsclausen lm32: switch to generic clone(2)
Unfortunately lm32 has yet another crazy sys_clone parameter order. We need to
fix this at some point. This will break all existing userspace though.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
0ca475b
17 arch/Kconfig
View
@@ -341,4 +341,21 @@ config MODULES_USE_ELF_REL
Modules only use ELF REL relocations. Modules with ELF RELA
relocations will give an error.
+#
+# ABI hall of shame
+#
+config CLONE_BACKWARDS
+ bool
+ help
+ Architecture has tls passed as the 4th argument of clone(2),
+ not the 5th one.
+
+config CLONE_BACKWARDS2
+ bool
+ help
+ Architecture has the first two arguments of clone(2) swapped.
+
+config CLONE_BACKWARDS3
+ bool
+
source "kernel/gcov/Kconfig"
3  arch/lm32/Kconfig
View
@@ -13,6 +13,9 @@ config LM32
select HAVE_MEMBLOCK
select MODULES_USE_ELF_REL
select MODULES_USE_ELF_RELA
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
+ select CLONE_BACKWARDS3
config GENERIC_GPIO
bool
1  arch/lm32/include/asm/processor.h
View
@@ -63,7 +63,6 @@ struct thread_struct {
unsigned long ksp; /* kernel stack pointer */
unsigned long usp; /* user stack pointer */
unsigned long which_stack; /* 0 if we are on kernel stack, 1 if we are on user stack */
- void * debuggerinfo;
};
#define KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + THREAD_SIZE - 32)
1  arch/lm32/include/asm/ptrace.h
View
@@ -70,6 +70,7 @@ struct pt_regs {
#ifdef __KERNEL__
#define user_mode(regs) ((regs)->pt_mode == PT_MODE_USER)
+#define user_stack_pointer(regs) ((regs)->sp)
#define instruction_pointer(regs) ((regs)->ea)
#define profile_pc(regs) instruction_pointer(regs)
2  arch/lm32/include/asm/unistd.h
View
@@ -5,6 +5,8 @@
#define __ARCH_WANT_SYSCALL_NO_FLAGS
#define __ARCH_WANT_SYSCALL_OFF_T
#define __ARCH_WANT_SYSCALL_DEPRECATED
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_SYS_CLONE
#include <asm-generic/unistd.h>
2  arch/lm32/kernel/Makefile
View
@@ -4,7 +4,7 @@
extra-y := head.o vmlinux.lds
obj-y := \
- sys_lm32.o setup.o traps.o signal.o time.o \
+ setup.o traps.o signal.o time.o \
ptrace.o irq.o process.o entry.o \
flat.o cpuinfo.o prom.o platform.o
18 arch/lm32/kernel/entry.S
View
@@ -154,14 +154,18 @@ EXCEPTION_RETURN_PATH(_return_from_exception, _restore_and_return_exception)
/* returns to continuation(arg1, arg2) */
ENTRY(ret_from_fork)
calli schedule_tail
- mv r1, r11
- mv r2, r12
- mv ra, r13
- ret
+ mvi r1, 0
+ bi syscall_tail
-ENTRY(sys_execve)
- mv r4, r7
- bi lm32_execve
+/* ret_from_fork(arg1, arg2, continuation) */
+/* calls schedule_tail and then manage_signals */
+/* returns to continuation(arg1, arg2) */
+ENTRY(ret_from_kernel_thread)
+ calli schedule_tail
+ mv r1, r12
+ mvhi ra, hi(syscall_tail)
+ ori ra, ra, lo(syscall_tail)
+ b r11
ENTRY(sys_rt_sigreturn)
mv r1, r7
50 arch/lm32/kernel/process.c
View
@@ -47,6 +47,7 @@
#include <asm/pgtable.h>
asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
asmlinkage void syscall_tail(void);
struct thread_info* lm32_current_thread;
@@ -127,32 +128,6 @@ void show_regs(struct pt_regs *regs)
printk("%3s: 0x%lx\n", lm32_reg_names[i], reg[i]);
}
-static void kernel_thread_helper(int (*fn)(void*), void* arg)
-{
- do_exit(fn(arg));
-}
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- /* prepare registers from which a child task switch frame will be copied */
- struct pt_regs regs;
-
- set_fs(KERNEL_DS);
-
- memset(&regs, 0, sizeof(regs));
-
- //printk("kernel_thread fn=%x arg=%x regs=%x\n", fn, arg, &regs);
-
- regs.r11 = (unsigned long)fn;
- regs.r12 = (unsigned long)arg;
- regs.r13 = (unsigned long)kernel_thread_helper;
- regs.pt_mode = PT_MODE_KERNEL;
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-
void flush_thread(void)
{
}
@@ -169,24 +144,23 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
}
int copy_thread(unsigned long clone_flags,
- unsigned long usp, unsigned long stk_size,
- struct task_struct * p, struct pt_regs * regs)
+ unsigned long usp_thread_fn, unsigned long thread_fn_arg,
+ struct task_struct *p, struct pt_regs *unused)
{
unsigned long child_tos = KSTK_TOS(p);
- struct pt_regs *childregs;
+ struct pt_regs *childregs = task_pt_regs(p);
- if (!user_mode(regs)) {
+ if (p->flags & PF_KTHREAD) {
/* kernel thread */
- if( usp != 0 )
- panic("trying to start kernel thread with usp != 0");
-
- /* childregs = full task switch frame on kernel stack of child */
childregs = (struct pt_regs *)(child_tos) - 1;
- *childregs = *regs;
+ memset(childregs, 0, sizeof(childregs));
+ childregs->r11 = usp_thread_fn;
+ childregs->r12 = thread_fn_arg;
+ /* childregs = full task switch frame on kernel stack of child */
/* return via ret_from_fork */
- childregs->ra = (unsigned long)ret_from_fork;
+ childregs->ra = (unsigned long)ret_from_kernel_thread;
/* setup ksp/usp */
p->thread.ksp = (unsigned long)childregs - 4; /* perhaps not necessary */
@@ -204,14 +178,14 @@ int copy_thread(unsigned long clone_flags,
/* childsyscallregs = full syscall frame on kernel stack of child */
childsyscallregs = (struct pt_regs *)(child_tos) - 1; /* 32 = safety */
/* child shall have same syscall context to restore as parent has ... */
- *childsyscallregs = *regs;
+ *childsyscallregs = *current_pt_regs();
/* childregs = full task switch frame on kernel stack of child below * childsyscallregs */
childregs = childsyscallregs - 1;
memset(childregs, 0, sizeof(childregs));
/* user stack pointer is shared with the parent per definition of vfork */
- p->thread.usp = usp;
+ p->thread.usp = usp_thread_fn;
/* kernel stack pointer is not shared with parent, it is the beginning of
* the just created new task switch segment on the kernel stack */
98 arch/lm32/kernel/sys_lm32.c
View
@@ -1,98 +0,0 @@
-/*
- * (C) Copyright 2007
- * Theobroma Systems <www.theobroma-systems.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/utsname.h>
-
-#include <asm/uaccess.h>
-#include <asm/unistd.h>
-
-asmlinkage int lm32_execve(const char __user *ufilename,
- const char __user *const __user *uargv,
- const char __user *const __user *uenvp,
- struct pt_regs *regs)
-{
- int error;
- struct filename *filename;
-
- filename = getname(ufilename);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
-
- error = do_execve(filename->name, uargv, uenvp, regs);
- putname(filename);
-out:
- return error;
-}
-
-int kernel_execve(const char *filename, const char *const argv[], const char *const envp[])
-{
- register unsigned long _r8 asm("r8") = __NR_execve;
- register unsigned long _r1 asm("r1") = (unsigned long)filename;
- register unsigned long _r2 asm("r2") = (unsigned long)argv;
- register unsigned long _r3 asm("r3") = (unsigned long)envp;
-
- __asm__ __volatile__ ("scall\n"
- : "=r"(_r1)
- : "r"(_r8),
- "0"(_r1), "r"(_r2), "r"(_r3) );
-
- if(_r1 >=(unsigned long) -4095) {
- _r1 = (unsigned long) -1;
- }
-
- return (int) _r1;
-}
-EXPORT_SYMBOL(kernel_execve);
-
-/* the args to sys_lm32_clone try to match the libc call to avoid register
- * reshuffling:
- * int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
-asmlinkage int sys_clone(
- int _unused_fn,
- unsigned long newsp,
- unsigned long clone_flags,
- int _unused_arg,
- unsigned long _unused_r5,
- int _unused_r6,
- struct pt_regs *regs)
-{
- if (!newsp)
- newsp = current->thread.usp;
-
- return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
-}
-
6 arch/lm32/platforms/milkymist/gpio.c
View
@@ -94,7 +94,7 @@ static int milkymist_gpio_direction_output(struct gpio_chip *gc,
return 0;
}
-static int __devinit milkymist_gpio_probe(struct platform_device *ofdev)
+static int milkymist_gpio_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct milkymist_gpio_chip *chip;
@@ -148,7 +148,7 @@ static int __devinit milkymist_gpio_probe(struct platform_device *ofdev)
return ret;
}
-static int __devexit milkymist_gpio_remove(struct platform_device *ofdev)
+static int milkymist_gpio_remove(struct platform_device *ofdev)
{
struct milkymist_gpio_chip *chip = platform_get_drvdata(ofdev);
@@ -173,7 +173,7 @@ static struct platform_driver milkymist_gpio_driver = {
.of_match_table = milkymist_gpio_match,
},
.probe = milkymist_gpio_probe,
- .remove = __devexit_p(milkymist_gpio_remove),
+ .remove = milkymist_gpio_remove,
};
static int __init milkymist_gpio_init(void)
6 drivers/input/keyboard/softusb.c
View
@@ -125,7 +125,7 @@ printk(" ");
return IRQ_HANDLED;
}
-static int __devinit softusb_probe(struct platform_device *pdev)
+static int softusb_probe(struct platform_device *pdev)
{
struct input_dev *dev;
int i, nwords, err;
@@ -189,7 +189,7 @@ static int __devinit softusb_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit softusb_remove(struct platform_device *pdev)
+static int softusb_remove(struct platform_device *pdev)
{
struct input_dev *dev = platform_get_drvdata(pdev);
@@ -207,7 +207,7 @@ static const struct of_device_id softusb_of_ids[] = {
static struct platform_driver softusb_driver = {
.probe = softusb_probe,
- .remove = __devexit_p(softusb_remove),
+ .remove = softusb_remove,
.driver = {
.name = "softusb",
.of_match_table = softusb_of_ids,
6 drivers/input/serio/milkbd.c
View
@@ -84,7 +84,7 @@ static void milkbd_close(struct serio *port)
* Allocate and initialize serio structure for subsequent registration
* with serio core.
*/
-static int __devinit milkbd_probe(struct platform_device *dev)
+static int milkbd_probe(struct platform_device *dev)
{
struct serio *serio;
@@ -105,7 +105,7 @@ static int __devinit milkbd_probe(struct platform_device *dev)
return 0;
}
-static int __devexit milkbd_remove(struct platform_device *dev)
+static int milkbd_remove(struct platform_device *dev)
{
struct serio *serio = platform_get_drvdata(dev);
serio_unregister_port(serio);
@@ -114,7 +114,7 @@ static int __devexit milkbd_remove(struct platform_device *dev)
static struct platform_driver milkbd_driver = {
.probe = milkbd_probe,
- .remove = __devexit_p(milkbd_remove),
+ .remove = milkbd_remove,
.driver = {
.name = "milkbd",
},
6 drivers/input/serio/milkmouse.c
View
@@ -84,7 +84,7 @@ static void milkmouse_close(struct serio *port)
* Allocate and initialize serio structure for subsequent registration
* with serio core.
*/
-static int __devinit milkmouse_probe(struct platform_device *dev)
+static int milkmouse_probe(struct platform_device *dev)
{
struct serio *serio;
@@ -105,7 +105,7 @@ static int __devinit milkmouse_probe(struct platform_device *dev)
return 0;
}
-static int __devexit milkmouse_remove(struct platform_device *dev)
+static int milkmouse_remove(struct platform_device *dev)
{
struct serio *serio = platform_get_drvdata(dev);
serio_unregister_port(serio);
@@ -114,7 +114,7 @@ static int __devexit milkmouse_remove(struct platform_device *dev)
static struct platform_driver milkmouse_driver = {
.probe = milkmouse_probe,
- .remove = __devexit_p(milkmouse_remove),
+ .remove = milkmouse_remove,
.driver = {
.name = "milkmouse",
},
8 drivers/tty/serial/milkymist_uart.c
View
@@ -342,7 +342,7 @@ static void milkymist_uart_console_write(struct console *co, const char *s,
spin_unlock_irqrestore(&port->lock, flags);
}
-static int __devinit milkymist_uart_console_setup(struct console *co,
+static int milkymist_uart_console_setup(struct console *co,
char *options)
{
struct uart_port *port;
@@ -399,7 +399,7 @@ static struct uart_driver milkymist_uart_driver = {
#endif
};
-static int __devinit milkymist_uart_probe(struct platform_device *op)
+static int milkymist_uart_probe(struct platform_device *op)
{
struct uart_port *port;
struct device_node *np = op->dev.of_node;
@@ -482,7 +482,7 @@ static int __devinit milkymist_uart_probe(struct platform_device *op)
return 0;
}
-static int __devexit milkymist_uart_remove(struct platform_device *dev)
+static int milkymist_uart_remove(struct platform_device *dev)
{
struct uart_port *port = dev_get_drvdata(&dev->dev);
@@ -506,7 +506,7 @@ static struct platform_driver milkymist_uart_of_driver = {
.of_match_table = milkymist_uart_match,
},
.probe = milkymist_uart_probe,
- .remove = __devexit_p(milkymist_uart_remove),
+ .remove = milkymist_uart_remove,
};
static int __init milkymist_uart_init(void)
6 drivers/video/milkymistfb.c
View
@@ -248,7 +248,7 @@ static struct fb_ops milkymistfb_ops = {
#endif
};
-static int __devinit milkymistfb_probe(struct platform_device *ofdev)
+static int milkymistfb_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
struct fb_info *info;
@@ -328,7 +328,7 @@ static int __devinit milkymistfb_probe(struct platform_device *ofdev)
return ret;
}
-static int __devexit milkymistfb_remove(struct platform_device *ofdev)
+static int milkymistfb_remove(struct platform_device *ofdev)
{
struct milkymistfb *milkymistfb = platform_get_drvdata(ofdev);
struct fb_info *info = milkymistfb->fb;
@@ -360,7 +360,7 @@ static struct platform_driver milkymist_vgafb_of_driver = {
.of_match_table = milkymist_vgafb_match,
},
.probe = milkymistfb_probe,
- .remove = __devexit_p(milkymistfb_remove),
+ .remove = milkymistfb_remove,
};
#ifndef MODULE
7 include/asm-generic/syscalls.h
View
@@ -10,16 +10,15 @@
*/
#ifndef sys_clone
asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tid, void __user *child_tid,
- struct pt_regs *regs);
+ void __user *parent_tid, void __user *child_tid);
#endif
#ifndef sys_fork
-asmlinkage long sys_fork(struct pt_regs *regs);
+asmlinkage long sys_fork(void);
#endif
#ifndef sys_vfork
-asmlinkage long sys_vfork(struct pt_regs *regs);
+asmlinkage long sys_vfork(void);
#endif
#ifndef sys_execve
48 kernel/fork.c
View
@@ -1645,6 +1645,54 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
}
#endif
+#ifdef __ARCH_WANT_SYS_FORK
+SYSCALL_DEFINE0(fork)
+{
+#ifdef CONFIG_MMU
+ return do_fork(SIGCHLD, 0, current_pt_regs(), 0, NULL, NULL);
+#else
+ /* can not support in nommu mode */
+ return(-EINVAL);
+#endif
+}
+#endif
+
+#ifdef __ARCH_WANT_SYS_VFORK
+SYSCALL_DEFINE0(vfork)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, current_pt_regs(),
+ 0, NULL, NULL);
+}
+#endif
+
+#ifdef __ARCH_WANT_SYS_CLONE
+#ifdef CONFIG_CLONE_BACKWARDS
+SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
+ int __user *, parent_tidptr,
+ int, tls_val,
+ int __user *, child_tidptr)
+#elif defined(CONFIG_CLONE_BACKWARDS2)
+SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
+ int __user *, parent_tidptr,
+ int __user *, child_tidptr,
+ int, tls_val)
+#elif defined(CONFIG_CLONE_BACKWARDS3)
+SYSCALL_DEFINE6(clone, unsigned int, unused, unsigned long, newsp, unsigned long, clone_flags,
+ int __user *, parent_tidptr,
+ int __user *, child_tidptr,
+ int, tls_val)
+#else
+SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
+ int __user *, parent_tidptr,
+ int __user *, child_tidptr,
+ int, tls_val)
+#endif
+{
+ return do_fork(clone_flags, newsp, current_pt_regs(), 0,
+ parent_tidptr, child_tidptr);
+}
+#endif
+
#ifndef ARCH_MIN_MMSTRUCT_ALIGN
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif

No commit comments for this range

Something went wrong with that request. Please try again.