* [PATCH] sys_indirect kernel implementation for PowerPC
@ 2007-11-21 3:08 Paul Mackerras
2007-11-21 3:29 ` Stephen Rothwell
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Paul Mackerras @ 2007-11-21 3:08 UTC (permalink / raw)
To: Ulrich Drepper, linuxppc-dev
This implements sys_indirect for 32-bit and 64-bit powerpc machines,
including a 32-bit compatibility implementation for 64-bit powerpc.
I decided to use assembly language for call_syscall because on 64-bit
powerpc the system call table has the addresses of the function text
rather than pointers to function descriptors; hence the system call
functions can't be called from C via the system call table.
Signed-off-by: Paul Mackerras <paulus@samba•org>
---
This patch applies on top of Ulrich Drepper's series adding the
generic and x86-specific code for sys_indirect.
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 69a91bd..fd6781c 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -461,6 +461,25 @@ ppc_swapcontext:
b sys_swapcontext
/*
+ * long call_compat_syscall(struct indirect_registers32 *regs)
+ * This function assumes that regs->syscall_nr has already been validated.
+ */
+_GLOBAL(call_syscall)
+ lwz r0,0(r3) /* system call number */
+ lis r11,sys_call_table@ha
+ addi r11,r11,sys_call_table@l
+ slwi r0,r0,2
+ lwzx r10,r11,r0
+ mtctr r10
+ lwz r4,8(r3)
+ lwz r5,12(r3)
+ lwz r6,16(r3)
+ lwz r7,20(r3)
+ lwz r8,24(r3)
+ lwz r3,4(r3)
+ bctr
+
+/*
* Top-level page fault handling.
* This is in assembler because if do_page_fault tells us that
* it is a bad kernel page fault, we want to save the non-volatile
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 148a354..516ee70 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -315,6 +315,43 @@ _GLOBAL(ret_from_fork)
b syscall_exit
/*
+ * long call_syscall(struct indirect_registers *regs)
+ * This function assumes that regs->syscall_nr has already been validated.
+ */
+_GLOBAL(call_syscall)
+ ld r11,.SYS_CALL_TABLE@toc(2)
+ ld r0,0(r3) /* system call number */
+ sldi r0,r0,4
+ ldx r10,r11,r0
+ mtctr r10
+ ld r4,16(r3)
+ ld r5,24(r3)
+ ld r6,32(r3)
+ ld r7,40(r3)
+ ld r8,48(r3)
+ ld r3,8(r3)
+ bctr
+
+/*
+ * long call_compat_syscall(struct indirect_registers32 *regs)
+ * This function assumes that regs->syscall_nr has already been validated.
+ */
+_GLOBAL(call_compat_syscall)
+ ld r11,.SYS_CALL_TABLE@toc(2)
+ lwz r0,0(r3) /* system call number */
+ sldi r0,r0,4
+ addi r11,r11,8
+ ldx r10,r11,r0
+ mtctr r10
+ lwz r4,8(r3)
+ lwz r5,12(r3)
+ lwz r6,16(r3)
+ lwz r7,20(r3)
+ lwz r8,24(r3)
+ lwz r3,4(r3)
+ bctr
+
+/*
* This routine switches between two different tasks. The process
* state of one is saved on its kernel stack. Then the state
* of the other is restored from its kernel stack. The memory
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 4a4f5c6..fcaf0b2 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -826,3 +826,37 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags,
return sys_sync_file_range(fd, offset, nbytes, flags);
}
+
+long compat_sys_indirect(struct indirect_registers32 __user *userregs,
+ void __user *userparams, size_t paramslen,
+ int flags)
+{
+ struct indirect_registers32 regs;
+ long result;
+
+ if (unlikely(flags != 0))
+ return -EINVAL;
+
+ if (copy_from_user(®s, userregs, sizeof(regs)))
+ return -EFAULT;
+
+ switch (regs.syscall_nr) {
+#define INDSYSCALL(name) __NR_##name
+#include <linux/indirect.h>
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (paramslen > sizeof(union indirect_params))
+ return -EINVAL;
+
+ result = -EFAULT;
+ if (!copy_from_user(¤t->indirect_params, userparams, paramslen))
+ result = call_compat_syscall(®s);
+
+ memset(¤t->indirect_params, '\0', paramslen);
+
+ return result;
+}
diff --git a/include/asm-powerpc/indirect.h b/include/asm-powerpc/indirect.h
new file mode 100644
index 0000000..fcc6729
--- /dev/null
+++ b/include/asm-powerpc/indirect.h
@@ -0,0 +1,32 @@
+#ifndef _ASM_POWERPC_INDIRECT_H_
+#define _ASM_POWERPC_INDIRECT_H_
+/*
+ * Copyright 2007 Paul Mackerras <paulus@au1•ibm.com>, IBM Corporation.
+ *
+ * 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.
+ */
+
+struct indirect_registers {
+ unsigned long syscall_nr;
+ unsigned long args[6];
+};
+
+extern long call_syscall(struct indirect_registers *regs);
+
+#define INDIRECT_SYSCALL(regs) (regs)->syscall_nr
+#define CALL_INDIRECT(regs) call_syscall(regs)
+
+#ifdef CONFIG_PPC64
+struct indirect_registers32 {
+ unsigned int syscall_nr;
+ unsigned int args[6];
+};
+
+extern long call_compat_syscall(struct indirect_registers32 *regs);
+
+#endif /* CONFIG_PPC64 */
+
+#endif /* _ASM_POWERPC_INDIRECT_H_ */
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index 11d5383..de2f4d7 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -313,3 +313,4 @@ COMPAT_SYS_SPU(timerfd)
SYSCALL_SPU(eventfd)
COMPAT_SYS_SPU(sync_file_range2)
COMPAT_SYS(fallocate)
+COMPAT_SYS(indirect)
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 97d82b6..400e4a6 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -332,10 +332,11 @@
#define __NR_eventfd 307
#define __NR_sync_file_range2 308
#define __NR_fallocate 309
+#define __NR_indirect 310
#ifdef __KERNEL__
-#define __NR_syscalls 310
+#define __NR_syscalls 311
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] sys_indirect kernel implementation for PowerPC
2007-11-21 3:08 [PATCH] sys_indirect kernel implementation for PowerPC Paul Mackerras
@ 2007-11-21 3:29 ` Stephen Rothwell
2007-11-21 3:42 ` Stephen Rothwell
2007-11-21 4:45 ` Kumar Gala
2 siblings, 0 replies; 6+ messages in thread
From: Stephen Rothwell @ 2007-11-21 3:29 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Ulrich Drepper
[-- Attachment #1: Type: text/plain, Size: 476 bytes --]
On Wed, 21 Nov 2007 14:08:46 +1100 Paul Mackerras <paulus@samba•org> wrote:
>
> +++ b/arch/powerpc/kernel/entry_32.S
> @@ -461,6 +461,25 @@ ppc_swapcontext:
> b sys_swapcontext
>
> /*
> + * long call_compat_syscall(struct indirect_registers32 *regs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Presumably a copy and paste glitch.
--
Cheers,
Stephen Rothwell sfr@canb•auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] sys_indirect kernel implementation for PowerPC
2007-11-21 3:08 [PATCH] sys_indirect kernel implementation for PowerPC Paul Mackerras
2007-11-21 3:29 ` Stephen Rothwell
@ 2007-11-21 3:42 ` Stephen Rothwell
2007-11-21 3:49 ` Stephen Rothwell
2007-11-27 22:57 ` Arnd Bergmann
2007-11-21 4:45 ` Kumar Gala
2 siblings, 2 replies; 6+ messages in thread
From: Stephen Rothwell @ 2007-11-21 3:42 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Ulrich Drepper
[-- Attachment #1: Type: text/plain, Size: 597 bytes --]
On Wed, 21 Nov 2007 14:08:46 +1100 Paul Mackerras <paulus@samba•org> wrote:
>
> +#ifdef CONFIG_PPC64
Use CONFIG_COMPAT?
> +struct indirect_registers32 {
> + unsigned int syscall_nr;
> + unsigned int args[6];
These could (should?) be compat_ulong_t
> +++ b/include/asm-powerpc/systbl.h
> @@ -313,3 +313,4 @@ COMPAT_SYS_SPU(timerfd)
> SYSCALL_SPU(eventfd)
> COMPAT_SYS_SPU(sync_file_range2)
> COMPAT_SYS(fallocate)
> +COMPAT_SYS(indirect)
Do the SPUs want this?
--
Cheers,
Stephen Rothwell sfr@canb•auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] sys_indirect kernel implementation for PowerPC
2007-11-21 3:42 ` Stephen Rothwell
@ 2007-11-21 3:49 ` Stephen Rothwell
2007-11-27 22:57 ` Arnd Bergmann
1 sibling, 0 replies; 6+ messages in thread
From: Stephen Rothwell @ 2007-11-21 3:49 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Ulrich Drepper
[-- Attachment #1: Type: text/plain, Size: 302 bytes --]
On Wed, 21 Nov 2007 14:08:46 +1100 Paul Mackerras <paulus@samba•org> wrote:
>
> +struct indirect_registers32 {
In fact, you should probably call this struct compat_indirect_registers ...
--
Cheers,
Stephen Rothwell sfr@canb•auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] sys_indirect kernel implementation for PowerPC
2007-11-21 3:08 [PATCH] sys_indirect kernel implementation for PowerPC Paul Mackerras
2007-11-21 3:29 ` Stephen Rothwell
2007-11-21 3:42 ` Stephen Rothwell
@ 2007-11-21 4:45 ` Kumar Gala
2 siblings, 0 replies; 6+ messages in thread
From: Kumar Gala @ 2007-11-21 4:45 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
On Nov 20, 2007, at 9:08 PM, Paul Mackerras wrote:
> This implements sys_indirect for 32-bit and 64-bit powerpc machines,
> including a 32-bit compatibility implementation for 64-bit powerpc.
> I decided to use assembly language for call_syscall because on 64-bit
> powerpc the system call table has the addresses of the function text
> rather than pointers to function descriptors; hence the system call
> functions can't be called from C via the system call table.
Admit it you were bored and wanted to write some PPC asm ;)
- k
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] sys_indirect kernel implementation for PowerPC
2007-11-21 3:42 ` Stephen Rothwell
2007-11-21 3:49 ` Stephen Rothwell
@ 2007-11-27 22:57 ` Arnd Bergmann
1 sibling, 0 replies; 6+ messages in thread
From: Arnd Bergmann @ 2007-11-27 22:57 UTC (permalink / raw)
To: linuxppc-dev
On Wednesday 21 November 2007, Stephen Rothwell wrote:
> > +++ b/include/asm-powerpc/systbl.h
> > @@ -313,3 +313,4 @@ COMPAT_SYS_SPU(timerfd)
> > =A0SYSCALL_SPU(eventfd)
> > =A0COMPAT_SYS_SPU(sync_file_range2)
> > =A0COMPAT_SYS(fallocate)
> > +COMPAT_SYS(indirect)
>=20
> Do the SPUs want this?
Excellent question. Sorry for being late in my reply here. The calls
that are marked non-spu capable are those that are harmful when run
on the SPU, e.g. because they modify the signal mask -- the SPU cannot
receive signals itself.
sys_indirect is potentially very useful on the SPU, but we can't allow
it if it gives you access to all other syscalls. If we want to use it
on the SPU at some point, we may have to provide an alternative
implementation that walks the spu_syscall_table instead.
OTOH, if sys_indirect is mostly useful for the eventual addition of
syslets, we can leave it out, because syslets don't make sense if
you have no multithreading capability.
Arnd <><
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-11-27 22:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-21 3:08 [PATCH] sys_indirect kernel implementation for PowerPC Paul Mackerras
2007-11-21 3:29 ` Stephen Rothwell
2007-11-21 3:42 ` Stephen Rothwell
2007-11-21 3:49 ` Stephen Rothwell
2007-11-27 22:57 ` Arnd Bergmann
2007-11-21 4:45 ` Kumar Gala
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox