Commit a94a71d6 authored by Anton Blanchard's avatar Anton Blanchard

ppc64: fix sys_clone bug (paulus) and fix fork arguments (Milton Miller)

parent 646adb15
...@@ -63,10 +63,7 @@ config SMP ...@@ -63,10 +63,7 @@ config SMP
---help--- ---help---
This enables support for systems with more than one CPU. If you have This enables support for systems with more than one CPU. If you have
a system with only one CPU, say N. If you have a system with more a system with only one CPU, say N. If you have a system with more
than one CPU, say Y. Note that the kernel does not currently than one CPU, say Y.
support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
since they have inadequate hardware support for multiprocessor
operation.
If you say N here, the kernel will run on single and multiprocessor If you say N here, the kernel will run on single and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If machines, but will use only one CPU of a multiprocessor machine. If
...@@ -74,16 +71,15 @@ config SMP ...@@ -74,16 +71,15 @@ config SMP
On a single-processor machine, the kernel will run faster if you say On a single-processor machine, the kernel will run faster if you say
N here. N here.
If you don't know what to do here, say N. If you don't know what to do here, say Y.
config IRQ_ALL_CPUS config IRQ_ALL_CPUS
bool "Distribute interrupts on all CPUs by default" bool "Distribute interrupts on all CPUs by default"
depends on SMP depends on SMP && PPC_PSERIES
help help
This option gives the kernel permission to distribute IRQs across This option gives the kernel permission to distribute IRQs across
multiple CPUs. Saying N here will route all IRQs to the first multiple CPUs. Saying N here will route all IRQs to the first
CPU. Generally saying Y is safe, although some problems have been CPU.
reported with SMP Power Macintoshes with this option enabled.
config NR_CPUS config NR_CPUS
int "Maximum number of CPUs (2-64)" int "Maximum number of CPUs (2-64)"
...@@ -468,13 +464,24 @@ config VIOCONS ...@@ -468,13 +464,24 @@ config VIOCONS
config VIODASD config VIODASD
tristate "iSeries Virtual I/O disk support" tristate "iSeries Virtual I/O disk support"
help
If you are running on an iSeries system and you want to use
virtual disks created and managed by OS/400, say Y.
config VIODASD_IDE config VIODASD_IDE
bool "iSeries Virtual disk IDE emulation" bool "iSeries Virtual disk IDE emulation"
depends on VIODASD depends on VIODASD
help
This causes the iSeries virtual disks to look like IDE disks.
If you have programs or utilities that only support certain
kinds of disks, this option will cause iSeries virtual disks
to pretend to be IDE disks, which may satisfy the program.
config VIOCD config VIOCD
tristate "iSeries Virtual I/O CD support" tristate "iSeries Virtual I/O CD support"
help
If you are running Linux on an IBM iSeries system and you want to
read a CD drive owned by OS/400, say Y here.
config VIOCD_AZTECH config VIOCD_AZTECH
bool "iSeries Virtual CD Aztech emulation" bool "iSeries Virtual CD Aztech emulation"
...@@ -482,6 +489,9 @@ config VIOCD_AZTECH ...@@ -482,6 +489,9 @@ config VIOCD_AZTECH
config VIOTAPE config VIOTAPE
tristate "iSeries Virtual Tape Support" tristate "iSeries Virtual Tape Support"
help
If you are running Linux on an iSeries system and you want Linux
to read and/or write a tape drive owned by OS/400, say Y here.
config VETH config VETH
tristate "iSeries Virtual Ethernet driver support" tristate "iSeries Virtual Ethernet driver support"
...@@ -498,10 +508,17 @@ menu "Kernel hacking" ...@@ -498,10 +508,17 @@ menu "Kernel hacking"
config DEBUG_KERNEL config DEBUG_KERNEL
bool "Kernel debugging" bool "Kernel debugging"
help
Say Y here if you are developing drivers or trying to debug and
identify kernel problems.
config DEBUG_SLAB config DEBUG_SLAB
bool "Debug memory allocations" bool "Debug memory allocations"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
help
Say Y here to have the kernel do limited verification on memory
allocation as well as poisoning memory on free to catch use of freed
memory.
config MAGIC_SYSRQ config MAGIC_SYSRQ
bool "Magic SysRq key" bool "Magic SysRq key"
......
...@@ -636,7 +636,7 @@ CONFIG_XMON_DEFAULT=y ...@@ -636,7 +636,7 @@ CONFIG_XMON_DEFAULT=y
# #
# Security options # Security options
# #
CONFIG_SECURITY_CAPABILITIES=y # CONFIG_SECURITY is not set
# #
# Cryptographic options # Cryptographic options
......
...@@ -485,8 +485,10 @@ _GLOBAL(cvt_df) ...@@ -485,8 +485,10 @@ _GLOBAL(cvt_df)
_GLOBAL(kernel_thread) _GLOBAL(kernel_thread)
/* XXX fix this when we optimise syscall entry to not save volatiles */ /* XXX fix this when we optimise syscall entry to not save volatiles */
mr r6,r3 /* function */ mr r6,r3 /* function */
mr r7,r4 /* arg */
ori r3,r5,CLONE_VM /* flags */ ori r3,r5,CLONE_VM /* flags */
oris r3,r3,(CLONE_UNTRACED>>16) oris r3,r3,(CLONE_UNTRACED>>16)
li r4,0 /* new sp (unused) */
li r0,__NR_clone li r0,__NR_clone
sc sc
cmpi 0,r3,0 /* parent or child? */ cmpi 0,r3,0 /* parent or child? */
...@@ -496,7 +498,7 @@ _GLOBAL(kernel_thread) ...@@ -496,7 +498,7 @@ _GLOBAL(kernel_thread)
ld r2,8(r6) ld r2,8(r6)
ld r6,0(r6) ld r6,0(r6)
mtlr r6 /* fn addr in lr */ mtlr r6 /* fn addr in lr */
mr r3,r4 /* load arg and call fn */ mr r3,r7 /* load arg and call fn */
blrl blrl
li r0,__NR_exit /* exit after child exits */ li r0,__NR_exit /* exit after child exits */
li r3,0 li r3,0
......
...@@ -191,8 +191,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -191,8 +191,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT); set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);
#endif #endif
} else } else {
childregs->gpr[1] = usp;
p->thread.regs = childregs; p->thread.regs = childregs;
}
childregs->gpr[3] = 0; /* Result from fork() */ childregs->gpr[3] = 0; /* Result from fork() */
sp -= STACK_FRAME_OVERHEAD; sp -= STACK_FRAME_OVERHEAD;
...@@ -266,13 +268,17 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) ...@@ -266,13 +268,17 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
return put_user(val, (unsigned int *) adr); return put_user(val, (unsigned int *) adr);
} }
int sys_clone(unsigned long clone_flags, u32 p2, u32 p3, u32 p4, u32 p5, int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
u32 p6, struct pt_regs *regs) unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs)
{ {
struct task_struct *p; struct task_struct *p;
unsigned long parent_tidptr = 0; unsigned long parent_tidptr = 0;
unsigned long child_tidptr = 0; unsigned long child_tidptr = 0;
if (p2 == 0)
p2 = regs->gpr[1]; /* stack pointer for child */
if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
CLONE_CHILD_CLEARTID)) { CLONE_CHILD_CLEARTID)) {
parent_tidptr = p3; parent_tidptr = p3;
...@@ -286,12 +292,13 @@ int sys_clone(unsigned long clone_flags, u32 p2, u32 p3, u32 p4, u32 p5, ...@@ -286,12 +292,13 @@ int sys_clone(unsigned long clone_flags, u32 p2, u32 p3, u32 p4, u32 p5,
if (regs->msr & MSR_FP) if (regs->msr & MSR_FP)
giveup_fpu(current); giveup_fpu(current);
p = do_fork(clone_flags & ~CLONE_IDLETASK, regs->gpr[1], regs, 0, p = do_fork(clone_flags & ~CLONE_IDLETASK, p2, regs, 0,
(int *)parent_tidptr, (int *)child_tidptr); (int *)parent_tidptr, (int *)child_tidptr);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
int sys_fork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct task_struct *p; struct task_struct *p;
...@@ -303,7 +310,8 @@ int sys_fork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, ...@@ -303,7 +310,8 @@ int sys_fork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
int sys_vfork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
unsigned long p4, unsigned long p5, unsigned long p6,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct task_struct *p; struct task_struct *p;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment