Re: [PATCH] sys_indirect kernel implementation for PowerPC

2007-11-27 Thread Arnd Bergmann
On Wednesday 21 November 2007, Stephen Rothwell wrote:
> > +++ 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?

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 <><
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] sys_indirect kernel implementation for PowerPC

2007-11-20 Thread Kumar Gala

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
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] sys_indirect kernel implementation for PowerPC

2007-11-20 Thread Stephen Rothwell
On Wed, 21 Nov 2007 14:08:46 +1100 Paul Mackerras <[EMAIL PROTECTED]> wrote:
>
> +struct indirect_registers32 {

In fact, you should probably call this struct compat_indirect_registers ...

-- 
Cheers,
Stephen Rothwell[EMAIL PROTECTED]
http://www.canb.auug.org.au/~sfr/


pgpoyI3Chia72.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Re: [PATCH] sys_indirect kernel implementation for PowerPC

2007-11-20 Thread Stephen Rothwell
On Wed, 21 Nov 2007 14:08:46 +1100 Paul Mackerras <[EMAIL PROTECTED]> 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[EMAIL PROTECTED]
http://www.canb.auug.org.au/~sfr/


pgpPEUUEvOGRF.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Re: [PATCH] sys_indirect kernel implementation for PowerPC

2007-11-20 Thread Stephen Rothwell
On Wed, 21 Nov 2007 14:08:46 +1100 Paul Mackerras <[EMAIL PROTECTED]> 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[EMAIL PROTECTED]
http://www.canb.auug.org.au/~sfr/


pgpX9SY3gMUXQ.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

[PATCH] sys_indirect kernel implementation for PowerPC

2007-11-20 Thread Paul Mackerras
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 <[EMAIL PROTECTED]>
---
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,[EMAIL PROTECTED]
+   addir11,r11,[EMAIL PROTECTED]
+   slwir0,r0,2
+   lwzxr10,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,[EMAIL PROTECTED](2)
+   ld  r0,0(r3)/* system call number */
+   sldir0,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,[EMAIL PROTECTED](2)
+   lwz r0,0(r3)/* system call number */
+   sldir0,r0,4
+   addir11,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 
+   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 000..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 <[EMAIL PROTECTED]>, 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 lon