Skip to contentSkip to conversation

kill __KERNEL_SYSCALLS__

PATCH In review Arnd Bergmann 14 participants 45 messages Aug 27, 2006 – Aug 30, 2006

Subsystems (17)
lore
Share & tools
lore

Arnd Bergmann

author maintainer
#0 lore raw

cover kill __KERNEL_SYSCALLS__

Ok, next try. This time a full series that tries to kill off __KERNEL_SYSCALLS__, _syscallX() and the global errno for good.

Practically no testing so far, so please check if this makes sense first before applying.

I'd especially like the arch maintainers to provide better implementations of kernel_execve, since I had to rely on the inline assembly provided from _syscall3 to implement them instead of doing it the right way.

	Arnd <><
author maintainer
#1 lore raw

PATCH 1/7 introduce kernel_execve

The use of execve() in the kernel is dubious, since it relies on the __KERNEL_SYSCALLS__ mechanism that stores the result in a global errno variable. As a first step of getting rid of this, change all users to a global kernel_execve function that returns a proper error code.

This function is a terrible hack, and a later patch removes it again after the kernel syscalls are gone.

init/do_mounts_initrd.c +1 -2
Index: linux-cg/init/do_mounts_initrd.c
===================================================================
@@ -1,4 +1,3 @@
-#define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -35,7 +34,7 @@
 	(void) sys_open("/dev/console",O_RDWR,0);
 	(void) sys_dup(0);
 	(void) sys_dup(0);
-	return execve(shell, argv, envp_init);
+	return kernel_execve(shell, argv, envp_init);
 }
 
 static void __init handle_initrd(void)
kernel/kmod.c +2 -3
Index: linux-cg/kernel/kmod.c
===================================================================
@@ -18,8 +18,6 @@
 	call_usermodehelper wait flag, and remove exec_usermodehelper.
 	Rusty Russell <[email protected]>  Jan 2003
 */
-#define __KERNEL_SYSCALLS__
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/syscalls.h>
@@ -150,7 +148,8 @@
 
 	retval = -EPERM;
 	if (current->fs->root)
-		retval = execve(sub_info->path, sub_info->argv,sub_info->envp);
+		retval = kernel_execve(sub_info->path,
+				sub_info->argv, sub_info->envp);
 
 	/* Exec failed? */
 	sub_info->retval = retval;
lib/Makefile +2 -0
Index: linux-cg/lib/Makefile
===================================================================
@@ -33,6 +33,8 @@
   lib-y += dec_and_lock.o
 endif
 
+lib-y += execve.o
+
 obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o
 obj-$(CONFIG_CRC16)	+= crc16.o
 obj-$(CONFIG_CRC32)	+= crc32.o
lib/execve.c new file +23 -0
Index: linux-cg/lib/execve.c
===================================================================
@@ -0,0 +1,23 @@
+#include <asm/bug.h>
+#include <asm/uaccess.h>
+
+#define __KERNEL_SYSCALLS__
+static int errno __attribute__((unused));
+#include <asm/unistd.h>
+
+#ifdef _syscall3
+int kernel_execve (const char *filename, char *const argv[], char *const envp[])
+								__attribute__((__weak__));
+int kernel_execve (const char *filename, char *const argv[], char *const envp[])
+{
+	mm_segment_t fs = get_fs();
+	int ret;
+
+	WARN_ON(segment_eq(fs, USER_DS));
+	ret = execve(filename, (char **)argv, (char **)envp);
+	if (ret)
+		ret = -errno;
+
+	return ret;
+}
+#endif
init/main.c +1 -3
Index: linux-cg/init/main.c
===================================================================
@@ -9,8 +9,6 @@
  *  Simplified starting of init:  Michael A. Griffith <[email protected]> 
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
@@ -679,7 +677,7 @@
 static void run_init_process(char *init_filename)
 {
 	argv_init[0] = init_filename;
-	execve(init_filename, argv_init, envp_init);
+	kernel_execve(init_filename, argv_init, envp_init);
 }
 
 static int init(void * unused)
arch/sparc64/kernel/power.c +2 -3
Index: linux-cg/arch/sparc64/kernel/power.c
===================================================================
@@ -4,8 +4,6 @@
  * Copyright (C) 1999 David S. Miller ([email protected])
  */
 
-#define __KERNEL_SYSCALLS__
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -14,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/syscalls.h>
 
 #include <asm/system.h>
 #include <asm/auxio.h>
@@ -98,7 +97,7 @@
 
 	/* Ok, down we go... */
 	button_pressed = 0;
-	if (execve("/sbin/shutdown", argv, envp) < 0) {
+	if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
 		printk("powerd: shutdown execution failed\n");
 		add_wait_queue(&powerd_wait, &wait);
 		goto again;

--

author maintainer
#2 lore raw

PATCH 2/7 rename the provided execve functions to kernel_execve

In reply to Arnd Bergmann

Some architectures provide an execve function that does not set errno, but instead returns the result code directly. Rename these to kernel_execve to get the right semantics there. Moreover, there is no reasone for any of these architectures to still provide __KERNEL_SYSCALLS__ or _syscallN macros, so remove these right away.

arch/x86_64/kernel/entry.S +2 -2
Index: linux-cg/arch/x86_64/kernel/entry.S
===================================================================
@@ -1000,7 +1000,7 @@
  * do_sys_execve asm fallback arguments:
  *	rdi: name, rsi: argv, rdx: envp, fake frame on the stack
  */
-ENTRY(execve)
+ENTRY(kernel_execve)
 	CFI_STARTPROC
 	FAKE_STACK_FRAME $0
 	SAVE_ALL	
@@ -1013,7 +1013,7 @@
 	UNFAKE_STACK_FRAME
 	ret
 	CFI_ENDPROC
-ENDPROC(execve)
+ENDPROC(kernel_execve)
 
 KPROBE_ENTRY(page_fault)
 	errorentry do_page_fault
drivers/sbus/char/bbc_envctrl.c +1 -4
Index: linux-cg/drivers/sbus/char/bbc_envctrl.c
===================================================================
@@ -4,9 +4,6 @@
  * Copyright (C) 2001 David S. Miller ([email protected])
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/sched.h>
@@ -200,7 +197,7 @@
 	printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n");
 
 	shutting_down = 1;
-	if (execve("/sbin/shutdown", argv, envp) < 0)
+	if (kernel_execve("/sbin/shutdown", argv, envp) < 0)
 		printk(KERN_CRIT "envctrl: shutdown execution failed\n");
 }
 
drivers/sbus/char/envctrl.c +1 -4
Index: linux-cg/drivers/sbus/char/envctrl.c
===================================================================
@@ -19,9 +19,6 @@
  *              Daniele Bellucci <[email protected]>
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
@@ -982,7 +979,7 @@
 
 	inprog = 1;
 	printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n");
-	if (0 > execve("/sbin/shutdown", argv, envp)) {
+	if (0 > kernel_execve("/sbin/shutdown", argv, envp)) {
 		printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); 
 		inprog = 0;  /* unlikely to succeed, but we could try again */
 	}
include/asm-x86_64/unistd.h +0 -175

187 lines not on this page · raw message

arch/alpha/kernel/entry.S +5 -5
Index: linux-cg/arch/alpha/kernel/entry.S
===================================================================
@@ -655,12 +655,12 @@
 .end kernel_thread
 
 /*
- * execve(path, argv, envp)
+ * kernel_execve(path, argv, envp)
  */
 	.align	4
-	.globl	execve
-	.ent	execve
-execve:
+	.globl	kernel_execve
+	.ent	kernel_execve
+kernel_execve:
 	/* We can be called from a module.  */
 	ldgp	$gp, 0($27)
 	lda	$sp, -(32+SIZEOF_PT_REGS+8)($sp)
@@ -704,7 +704,7 @@
 
 1:	lda	$sp, 32+SIZEOF_PT_REGS+8($sp)
 	ret
-.end execve
+.end kernel_execve
 
 
 /*
arch/arm/kernel/sys_arm.c +2 -2
Index: linux-cg/arch/arm/kernel/sys_arm.c
===================================================================
@@ -279,7 +279,7 @@
 	return error;
 }
 
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
 {
 	struct pt_regs regs;
 	int ret;
@@ -317,7 +317,7 @@
  out:
 	return ret;
 }
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
 
 /*
  * Since loff_t is a 64 bit type we avoid a lot of ABI hastle
arch/arm26/kernel/sys_arm.c +2 -2
Index: linux-cg/arch/arm26/kernel/sys_arm.c
===================================================================
@@ -283,7 +283,7 @@
 }
 
 /* FIXME - see if this is correct for arm26 */
-long execve(const char *filename, char **argv, char **envp)
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
 {
 	struct pt_regs regs;
         int ret;
@@ -320,4 +320,4 @@
         return ret;
 }
 
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
arch/powerpc/kernel/misc_32.S +1 -1
Index: linux-cg/arch/powerpc/kernel/misc_32.S
===================================================================
@@ -843,7 +843,7 @@
 	addi	r1,r1,16
 	blr
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
 	li	r0,__NR_execve
 	sc
 	bnslr
arch/powerpc/kernel/misc_64.S +1 -1
Index: linux-cg/arch/powerpc/kernel/misc_64.S
===================================================================
@@ -556,7 +556,7 @@
 
 #endif /* CONFIG_ALTIVEC */
 
-_GLOBAL(execve)
+_GLOBAL(kernel_execve)
 	li	r0,__NR_execve
 	sc
 	bnslr
include/asm-alpha/unistd.h +0 -251

263 lines not on this page · raw message

include/asm-arm/unistd.h +0 -173

185 lines not on this page · raw message

include/asm-arm26/unistd.h +0 -156

168 lines not on this page · raw message

include/asm-parisc/unistd.h +0 -221

233 lines not on this page · raw message

include/asm-powerpc/unistd.h +0 -121

133 lines not on this page · raw message

include/asm-um/unistd.h +0 -28
Index: linux-cg/include/asm-um/unistd.h
===================================================================
@@ -37,34 +37,6 @@
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-static inline int execve(const char *filename, char *const argv[],
-			 char *const envp[])
-{
-	mm_segment_t fs;
-	int ret;
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = um_execve(filename, argv, envp);
-	set_fs(fs);
-
-	if (ret >= 0)
-		return ret;
-
-	errno = -(long)ret;
-	return -1;
-}
-
-int sys_execve(char *file, char **argv, char **env);
-
-#endif /* __KERNEL_SYSCALLS__ */
-
-#undef __KERNEL_SYSCALLS__
 #include "asm/arch/unistd.h"
 
 #endif /* _UM_UNISTD_H_*/
include/linux/syscalls.h +2 -0
Index: linux-cg/include/linux/syscalls.h
===================================================================
@@ -597,4 +597,6 @@
 asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
 				    size_t len);
 
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+
 #endif
arch/ia64/kernel/entry.S +2 -2
Index: linux-cg/arch/ia64/kernel/entry.S
===================================================================
@@ -492,11 +492,11 @@
 	br.ret.sptk.many rp
 END(prefetch_stack)
 
-GLOBAL_ENTRY(execve)
+GLOBAL_ENTRY(kernel_execve)
 	mov r15=__NR_execve			// put syscall number in place
 	break __BREAK_SYSCALL
 	br.ret.sptk.many rp
-END(execve)
+END(kernel_execve)
 
 GLOBAL_ENTRY(clone)
 	mov r15=__NR_clone			// put syscall number in place
arch/parisc/kernel/process.c +8 -1
Index: linux-cg/arch/parisc/kernel/process.c
===================================================================
@@ -368,7 +368,14 @@
 	return error;
 }
 
-unsigned long 
+extern int __execve(const char *filename, char *const argv[],
+		char *const envp[], struct task_struct *task);
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+{
+	return __execve(filename, argv, envp, current);
+}
+
+unsigned long
 get_wchan(struct task_struct *p)
 {
 	struct unwind_frame_info info;
arch/um/kernel/syscall.c +13 -0
Index: linux-cg/arch/um/kernel/syscall.c
===================================================================
@@ -164,3 +164,16 @@
 	spin_unlock(&syscall_lock);
 	return(ret);
 }
+
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	mm_segment_t fs;
+	int ret;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = um_execve(filename, argv, envp);
+	set_fs(fs);
+
+	return ret;
+}
include/asm-ia64/unistd.h +0 -72

78 lines not on this page · raw message

arch/alpha/kernel/alpha_ksyms.c +1 -2
Index: linux-cg/arch/alpha/kernel/alpha_ksyms.c
===================================================================
@@ -36,7 +36,6 @@
 #include <asm/cacheflush.h>
 #include <asm/vga.h>
 
-#define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
 
 extern struct hwrpb_struct *hwrpb;
@@ -116,7 +115,7 @@
 EXPORT_SYMBOL(sys_exit);
 EXPORT_SYMBOL(sys_write);
 EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(execve);
+EXPORT_SYMBOL(kernel_execve);
 EXPORT_SYMBOL(sys_setsid);
 EXPORT_SYMBOL(sys_wait4);
 

--

#3 lore raw

Re: [PATCH 2/7] rename the provided execve functions to kernel_execve

Quoted 13 lines · On Sun, 27 Aug 2006 23:47:36 +0200 Arnd Bergmann wrote:
drivers/sbus/char/envctrl.c +0 -3
@@ -19,9 +19,6 @@
  *              Daniele Bellucci <[email protected]>
  */
 
-#define __KERNEL_SYSCALLS__
-static int errno;
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>

drivers/sbus/char/envctrl.c line 985

Quoted 8 lines
drivers/sbus/char/envctrl.c +1 -1
@@ -982,7 +979,7 @@
 
 	inprog = 1;
 	printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n");
-	if (0 > execve("/sbin/shutdown", argv, envp)) {
+	if (0 > kernel_execve("/sbin/shutdown", argv, envp)) {
 		printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); 
 		inprog = 0;  /* unlikely to succeed, but we could try again */
 	}

Linux just educated the git mailing list (yesterday) about ordering of comparisons, so while here, please change the order inside the if() to be like the others:

	if (kernel_execv(...) < 0)

include/linux/syscalls.h line 602

Quoted 11 lines

Index: linux-cg/include/linux/syscalls.h
===================================================================

include/linux/syscalls.h +2 -0
@@ -597,4 +597,6 @@
 asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
 				    size_t len);
 
+int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+
 #endif

Question:
All other syscalls (in syscalls.h) return long or unsigned long or ssize_t etc. I.e., none of them return int. Does this one return int because it's strictly an inside-the-kernel "syscall", not exposed to userspace?

---
~Randy

author maintainer
#4 lore raw

Re: [PATCH 2/7] rename the provided execve functions to kernel_execve

Quoted 5 lines · Randy.Dunlap

Question:
All other syscalls (in syscalls.h) return long or unsigned long or ssize_t etc.  I.e., none of them return int.  Does this one return int because it's strictly an inside-the-kernel "syscall", not exposed to userspace?

Well, it's not really a system call in the first place, but I could not find any other place where it would fit. The prototype of the kernel_execve function is the one from the man execve page, and also similar to those that were generated by the _syscall3() macro before.

	Arnd <><
author maintainer
#5 lore raw

PATCH 3/7 provide kernel_execve on all architectures

In reply to Arnd Bergmann

This adds the new kernel_execve function on all architectures that were using _syscall3() to implement execve.

The implementation uses code from the _syscall3 macros provided in the unistd.h header file. I don't have cross-compilers for any of these architectures, so the patch is untested with the exception of i386.

Most architectures can probably implement this in a nicer way in assembly or by combining it with the sys_execve implementation itself, but this should do it for now.

arch/frv/kernel/sys_frv.c +16 -0
Index: linux-cg/arch/frv/kernel/sys_frv.c
===================================================================
@@ -212,3 +212,19 @@
 		return -ENOSYS;
 	}
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __scnum __asm__ ("gr7") = __NR_execve;
+	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) filename;
+	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) argv;
+	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) envp;
+	__asm__ __volatile__ ("tira gr0,#0"
+			      : "+r" (__sc0)
+			      : "r" (__scnum), "r" (__sc1), "r" (__sc2));
+	return __sc0;
+}
arch/h8300/kernel/sys_h8300.c +23 -0
Index: linux-cg/arch/h8300/kernel/sys_h8300.c
===================================================================
@@ -280,3 +280,26 @@
                ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
 }
 #endif
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long res __asm__("er0");
+	register const char * _a __asm__("er1") = filename;
+	register void *_b __asm__("er2") = argv;
+	register void *_c __asm__("er3") = envp;
+	__asm__ __volatile__ ("mov.l %1,er0\n\t"
+			"trapa	#0\n\t"
+			: "=r" (res)
+			: "g" (__NR_execve),
+			  "g" (_a),
+			  "g" (_b),
+			  "g" (_c)
+			: "cc", "memory");
+	return res;
+}
+
+
arch/i386/kernel/sys_i386.c +14 -0
Index: linux-cg/arch/i386/kernel/sys_i386.c
===================================================================
@@ -243,3 +243,17 @@
 
 	return error;
 }
+
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
+	: "=a" (__res)
+	: "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory");
+	return __res;
+}
arch/m32r/kernel/sys_m32r.c +20 -0
Index: linux-cg/arch/m32r/kernel/sys_m32r.c
===================================================================
@@ -25,6 +25,8 @@
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
 #include <asm/ipc.h>
+#include <asm/syscall.h>
+#include <asm/unistd.h>
 
 /*
  * sys_tas() - test-and-set
@@ -223,3 +225,21 @@
 	return -ENOSYS;
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __scno __asm__ ("r7") = __NR_execve;
+	register long __arg3 __asm__ ("r2") = (long)(envp);
+	register long __arg2 __asm__ ("r1") = (long)(argv);
+	register long __res __asm__ ("r0") = (long)(filename);
+	__asm__ __volatile__ (
+		"trap #" SYSCALL_VECTOR "|| nop"
+		: "=r" (__res)
+		: "r" (__scno), "0" (__res), "r" (__arg2),
+			"r" (__arg3)
+		: "memory");
+	return __res;
+}
arch/m68k/kernel/sys_m68k.c +15 -0
Index: linux-cg/arch/m68k/kernel/sys_m68k.c
===================================================================
@@ -663,3 +663,18 @@
 {
 	return PAGE_SIZE;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __res asm ("%d0") = __NR_execve;
+	register long __a asm ("%d1") = (long)(filename);
+	register long __b asm ("%d2") = (long)(argv);
+	register long __c asm ("%d3") = (long)(envp);
+	asm volatile ("trap  #0" : "+d" (__res)
+			: "d" (__a), "d" (__b), "d" (__c));
+	return __res;
+}
arch/m68knommu/kernel/sys_m68k.c +14 -0
Index: linux-cg/arch/m68knommu/kernel/sys_m68k.c
===================================================================
@@ -206,3 +206,17 @@
 	return PAGE_SIZE;
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __res asm ("%d0") = __NR_execve;
+	register long __a asm ("%d1") = (long)(filename);
+	register long __b asm ("%d2") = (long)(argv);
+	register long __c asm ("%d3") = (long)(envp);
+	asm volatile ("trap  #0" : "+d" (__res)
+			: "d" (__a), "d" (__b), "d" (__c));
+	return __res;
+}
arch/mips/kernel/syscall.c +24 -0
Index: linux-cg/arch/mips/kernel/syscall.c
===================================================================
@@ -399,3 +399,27 @@
 {
 	do_exit(SIGSEGV);
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __a0 asm("$4") = (unsigned long) filename;
+	register unsigned long __a1 asm("$5") = (unsigned long) argv;
+	register unsigned long __a2 asm("$6") = (unsigned long) envp;
+	register unsigned long __a3 asm("$7");
+	unsigned long __v0;
+	__asm__ volatile (
+	".set\tnoreorder\n\t"
+	"li\t$2, %5\t\t\t# " #name "\n\t"
+	"syscall\n\t"
+	"move\t%0, $2\n\t"
+	".set\treorder"
+	: "=&r" (__v0), "=r" (__a3)
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
+	  "memory");
+	return __v0;
+}
arch/s390/kernel/sys_s390.c +18 -0
Index: linux-cg/arch/s390/kernel/sys_s390.c
===================================================================
@@ -266,3 +266,21 @@
 	return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
 }
 
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register const char *__arg1 asm("2") = filename;
+	register void *__arg2 asm("3") = argv;
+	register void *__arg3 asm("4") = envp;
+	register long __svcres asm("2");
+	asm volatile ("svc %b1"
+		: "=d" (__svcres)
+		: "i" (__NR_execve),
+		  "0" (__arg1),
+		  "d" (__arg2),
+		  "d" (__arg3) : "1", "cc", "memory");
+	return __svcres;
+}
arch/sh/kernel/sys_sh.c +16 -0
Index: linux-cg/arch/sh/kernel/sys_sh.c
===================================================================
@@ -295,3 +295,19 @@
 				(u64)len0 << 32 | len1,	advice);
 #endif
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register long __sc0 __asm__ ("r3") = __NR_execve;
+	register long __sc4 __asm__ ("r4") = (long) filename;
+	register long __sc5 __asm__ ("r5") = (long) argv;
+	register long __sc6 __asm__ ("r6") = (long) envp;
+	__asm__ __volatile__ ("trapa	#0x13" : "=z" (__sc0)
+			: "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
+			: "memory");
+	return __sc0;
+}
arch/sh64/kernel/sys_sh64.c +18 -0
Index: linux-cg/arch/sh64/kernel/sys_sh64.c
===================================================================
@@ -283,3 +283,21 @@
 	up_read(&uts_sem);
 	return err?-EFAULT:0;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve);
+	register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename;
+	register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv;
+	register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp;
+	__asm__ __volatile__ ("trapa	%1 !\t\t\t execve(%2,%3,%4)"
+	: "=r" (__sc0)
+	: "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) );
+	__asm__ __volatile__ ("!dummy	%0 %1 %2 %3"
+	: : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory");
+	return __sc0;
+}
arch/sparc/kernel/sys_sparc.c +22 -0
Index: linux-cg/arch/sparc/kernel/sys_sparc.c
===================================================================
@@ -483,3 +483,25 @@
 	up_read(&uts_sem);
 	return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	register long __g1 __asm__ ("g1") = __NR_execve;
+	register long __o0 __asm__ ("o0") = (long)(filename);
+	register long __o1 __asm__ ("o1") = (long)(argv);
+	register long __o2 __asm__ ("o2") = (long)(envp);
+	asm volatile ("t 0x10\n\t"
+		      "bcc 1f\n\t"
+		      "mov %%o0, %0\n\t"
+		      "sub %%g0, %%o0, %0\n\t"
+		      "1:\n\t"
+		      : "=r" (__res), "=&r" (__o0)
+		      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+		      : "cc");
+	return __res;
+}
arch/sparc64/kernel/sys_sparc.c +20 -0
Index: linux-cg/arch/sparc64/kernel/sys_sparc.c
===================================================================
@@ -957,3 +957,23 @@
 	};
 	return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	register long __g1 __asm__ ("g1") = __NR_execve;
+	register long __o0 __asm__ ("o0") = (long)(filename);
+	register long __o1 __asm__ ("o1") = (long)(argv);
+	register long __o2 __asm__ ("o2") = (long)(envp);
+	asm volatile ("t 0x6d\n\t"
+		      "sub %%g0, %%o0, %0\n\t"
+		      "movcc %%xcc, %%o0, %0\n\t"
+		      : "=r" (__res), "=&r" (__o0)
+		      : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+		      : "cc");
+	return __res;
+}
arch/v850/kernel/syscalls.c +19 -0
Index: linux-cg/arch/v850/kernel/syscalls.c
===================================================================
@@ -194,3 +194,22 @@
 out:
 	return err;
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register char *__a __asm__ ("r6") = filename;
+	register void *__b __asm__ ("r7") = argv;
+	register void *__c __asm__ ("r8") = envp;
+	register unsigned long __syscall __asm__ ("r12") = __NR_execve;
+	register unsigned long __ret __asm__ ("r10");
+	__asm__ __volatile__ ("trap 0"
+			: "=r" (__ret), "=r" (__syscall)
+			: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+			: "r1", "r5", "r11", "r13", "r14",
+			  "r15", "r16", "r17", "r18", "r19");
+	return __ret;
+}
arch/xtensa/kernel/syscalls.c +20 -0
Index: linux-cg/arch/xtensa/kernel/syscalls.c
===================================================================
@@ -266,3 +266,23 @@
 	regs->areg[2] = res;
 	do_syscall_trace();
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	long __res;
+	asm volatile (
+		"  mov   a5, %2 \n"
+		"  mov   a4, %4 \n"
+		"  mov   a3, %3 \n"
+		"  movi  a2, %1 \n"
+		"  syscall      \n"
+		"  mov   %0, a2 \n"
+		: "=a" (__res)
+		: "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp)
+		: "a2", "a3", "a4", "a5");
+	return __res;
+}

--

#6 lore raw

Re: [PATCH 3/7] provide kernel_execve on all architectures

Quoted 8 lines · Arnd Bergmann

This adds the new kernel_execve function on all architectures that were using _syscall3() to implement execve.

The implementation uses code from the _syscall3 macros provided in the unistd.h header file. I don't have cross-compilers for any of these architectures, so the patch is untested with the exception of i386.

Quoted 5 lines

Most architectures can probably implement this in a nicer way in assembly or by combining it with the sys_execve implementation itself, but this should do it for now.

Two bugs in your MIPS version of kernel_execve(); the inline asm which was copying from _syscall3 macro was still using the #stringify operation. It also didn't get the result return in case of errors right - $a3 = 1 indicates an error in which case $v0 will contain the positive error number.

arch/mips/kernel/syscall.c +29 -0
index 0721314..b73b26c 100644
@@ -399,3 +399,32 @@ asmlinkage void bad_stack(void)
 {
 	do_exit(SIGSEGV);
 }
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __a0 asm("$4") = (unsigned long) filename;
+	register unsigned long __a1 asm("$5") = (unsigned long) argv;
+	register unsigned long __a2 asm("$6") = (unsigned long) envp;
+	register unsigned long __a3 asm("$7");
+	unsigned long __v0;
+
+	__asm__ volatile ("					\n"
+	"	.set	noreorder				\n"
+	"	li	$2, %5		# __NR_execve		\n"
+	"	syscall						\n"
+	"	move	%0, $2					\n"
+	"	.set	reorder					\n"
+	: "=&r" (__v0), "=r" (__a3)
+	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
+	  "memory");
+
+	if (__a3 == 0)
+		return __v0;
+
+	return -__v0;
+}
#7 lore raw

Re: [PATCH 3/7] provide kernel_execve on all architectures

In reply to Arnd Bergmann
Quoted 3 lines · Arnd Bergmann

Most architectures can probably implement this in a nicer way in assembly or by combining it with the sys_execve implementation itself, but this should do it for now.

Try applying the attached delta for FRV. Note that you didn't #include asm/unistd.h in your original patch.

---

arch/frv/kernel/Makefile +1 -1
index 91d380a..7bf175c 100644
@@ -8,7 +8,7 @@ heads-$(CONFIG_MMU)		:= head-mmu-fr451.o
 extra-y:= head.o init_task.o vmlinux.lds
 
 obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
-	 process.o traps.o ptrace.o signal.o dma.o \
+	 kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
 	 sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
 	 debug-stub.o irq.o irq-routing.o sleep.o uaccess.o atomic-ops.o
 
arch/frv/kernel/sys_frv.c +0 -16
index 944aab2..c4d4348 100644
@@ -212,19 +212,3 @@ asmlinkage long sys_ipc(unsigned long ca
 		return -ENOSYS;
 	}
 }
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename, char *const argv[], char *const envp[])
-{
-	register unsigned long __scnum __asm__ ("gr7") = __NR_execve;
-	register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) filename;
-	register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) argv;
-	register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) envp;
-	__asm__ __volatile__ ("tira gr0,#0"
-			      : "+r" (__sc0)
-			      : "r" (__scnum), "r" (__sc1), "r" (__sc2));
-	return __sc0;
-}
arch/frv/kernel/kernel_execve.S new file +33 -0
new file mode 100644
index 0000000..9b074a1
@@ -0,0 +1,33 @@
+/* in-kernel program execution
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells ([email protected])
+ *
+ * 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+
+###############################################################################
+#
+# Do a system call from kernel instead of calling sys_execve so we end up with
+# proper pt_regs.
+#
+# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+#
+# On entry: GR8/GR9/GR10: arguments to function
+# On return: GR8: syscall return.
+#
+###############################################################################
+	.globl		kernel_execve
+	.type		kernel_execve,@function
+kernel_execve:
+	setlos		__NR_execve,gr7
+	tira		gr0,#0
+	bralr
+
+	.size		kernel_execve,.-kernel_execve
author maintainer
#8 lore raw

PATCH 4/7 Remove the use of _syscallX macros in UML

In reply to Arnd Bergmann

User mode linux uses _syscallX() to call into the host kernel. The recommended way to do this is to use the syscall() function from libc.

arch/um/os-Linux/process.c +2 -3
Index: linux-cg/arch/um/os-Linux/process.c
===================================================================
@@ -12,6 +12,7 @@
 #include <sys/mman.h>
 #include <sys/wait.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include "ptrace_user.h"
 #include "os.h"
 #include "user.h"
@@ -141,11 +142,9 @@
  * syscalls, and also breaks with clone(), which does not unshare the TLS.
  */
 
-inline _syscall0(pid_t, getpid)
-
 int os_getpid(void)
 {
-	return(getpid());
+	return(syscall(__NR_getpid));
 }
 
 int os_getpgrp(void)
arch/um/os-Linux/sys-i386/tls.c +2 -3
Index: linux-cg/arch/um/os-Linux/sys-i386/tls.c
===================================================================
@@ -1,10 +1,9 @@
 #include <errno.h>
 #include <linux/unistd.h>
+#include <sys/syscall.h>
 #include "sysdep/tls.h"
 #include "user_util.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-
 /* Checks whether host supports TLS, and sets *tls_min according to the value
  * valid on the host.
  * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
@@ -17,7 +16,7 @@
 		user_desc_t info;
 		info.entry_number = val[i];
 
-		if (get_thread_area(&info) == 0) {
+		if (syscall(__NR_get_thread_area, &info) == 0) {
 			*tls_min = val[i];
 			*supports_tls = 1;
 			return;
arch/um/os-Linux/tls.c +3 -5
Index: linux-cg/arch/um/os-Linux/tls.c
===================================================================
@@ -1,5 +1,6 @@
 #include <errno.h>
 #include <sys/ptrace.h>
+#include <sys/syscall.h>
 #include <asm/ldt.h>
 #include "sysdep/tls.h"
 #include "uml-config.h"
@@ -48,14 +49,11 @@
 #ifdef UML_CONFIG_MODE_TT
 #include "linux/unistd.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-static _syscall1(int, set_thread_area, user_desc_t *, u_info);
-
 int do_set_thread_area_tt(user_desc_t *info)
 {
 	int ret;
 
-	ret = set_thread_area(info);
+	ret = syscall(__NR_set_thread_area,info);
 	if (ret < 0) {
 		ret = -errno;
 	}
@@ -66,7 +64,7 @@
 {
 	int ret;
 
-	ret = get_thread_area(info);
+	ret = syscall(__NR_get_thread_area,info);
 	if (ret < 0) {
 		ret = -errno;
 	}
arch/um/sys-i386/unmap.c +4 -7
Index: linux-cg/arch/um/sys-i386/unmap.c
===================================================================
@@ -5,20 +5,17 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
+#include <sys/syscall.h>
 
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-	if(munmap(to, size) < 0){
+	if (syscall(__NR_munmap, to, size) < 0){
 		return(-1);
 	}
-	if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+	if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
 		return(-1);
 	}
-	if(munmap(from, size) < 0){
+	if (syscall(__NR_munmap, from, size) < 0){
 		return(-1);
 	}
 	return(0);
arch/um/sys-x86_64/unmap.c +4 -7
Index: linux-cg/arch/um/sys-x86_64/unmap.c
===================================================================
@@ -5,20 +5,17 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
+#include <sys/syscall.h>
 
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-	if(munmap(to, size) < 0){
+	if (syscall(munmap, to, size) < 0){
 		return(-1);
 	}
-	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+	if (syscall(mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
 		return(-1);
 	}
-	if(munmap(from, size) < 0){
+	if (syscall(munmap, from, size) < 0){
 		return(-1);
 	}
 	return(0);

--

#9 lore raw

Re: [PATCH 4/7] Remove the use of _syscallX macros in UML

arch/um/sys-x86_64/unmap.c line 12

Quoted 4 lines · Arnd Bergmann

int switcheroo(int fd, int prot, void *from, void *to, int size) {

arch/um/sys-x86_64/unmap.c +1 -1
-	if(munmap(to, size) < 0){
+	if (syscall(munmap, to, size) < 0){

s/unmap/__NR_unmap/

arch/um/sys-x86_64/unmap.c line 15

Quoted 4 lines
arch/um/sys-x86_64/unmap.c +1 -1
 		return(-1);
 	}
-	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+	if (syscall(mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){

s/mmap/__NR_mmap/

arch/um/sys-x86_64/unmap.c line 18

Quoted 4 lines
arch/um/sys-x86_64/unmap.c +1 -1
 		return(-1);
 	}
-	if(munmap(from, size) < 0){
+	if (syscall(munmap, from, size) < 0){

s/unmap/__NR_unmap/

Andreas.

Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
#10 lore raw

Re: [PATCH 4/7] Remove the use of _syscallX macros in UML

In reply to Arnd Bergmann
Quoted 3 lines · Arnd Bergmann

User mode linux uses _syscallX() to call into the host kernel. The recommended way to do this is to use the syscall() function from libc.

Not really.

syscall() is a horrible botch; it is in fact unimplementable (without enormous switch statements) on a number of architectures.

-hpa

author maintainer
#11 lore raw

Re: [PATCH 4/7] Remove the use of _syscallX macros in UML

Quoted 3 lines · H. Peter Anvin

syscall() is a horrible botch; it is in fact unimplementable (without enormous switch statements) on a number of architectures.

Ok, good point. I'll leave the _syscallX() macros in for now and only remove the kernel syscalls in my next submission, so we get at least the non-controversial part done.

	Arnd <><
author maintainer
#12 lore raw

PATCH 5/7 sh64: remove the use of kernel syscalls

In reply to Arnd Bergmann

sh64 is using system call macros to call some functions from the kernel. Remove those so we can get rid of kernel syscalls.

This is probably not the best implementation and may need to be redone.

arch/sh64/kernel/process.c +14 -13
Index: linux-cg/arch/sh64/kernel/process.c
===================================================================
@@ -32,7 +32,6 @@
 #undef IDLE_TRACE
 /* Temporary flags/tests. All to be removed/undefined. END */
 
-#define __KERNEL_SYSCALLS__
 #include <stdarg.h>
 
 #include <linux/kernel.h>
@@ -230,13 +229,10 @@
 void idle_trace(void)
 {
 
-	_syscall0(int, getpid)
-	_syscall1(int, getpgid, int, pid)
-
 	if (!once) {
         	/* VM allocation/deallocation simple test */
 		test_VM();
-		pid = getpid();
+		pid = sys_getpid();
 
         	printk("Got all through to Idle !!\n");
         	printk("I'm now going to loop forever ...\n");
@@ -268,7 +264,7 @@
 		}
 		old_jiffies = jiffies;
 	}
-	pgid = getpgid(pid);
+	pgid = sys_getpgid(pid);
 	printk(".");
 }
 #else
@@ -628,18 +624,23 @@
  * a system call from a "real" process, but the process memory space will
  * not be free'd until both the parent and the child have exited.
  */
+#error please implement a working kernel_thread function like the other architectures
+/* _syscallN() does not work any more. this probably needs to call
+ * do_fork directly */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
-	/* A bit less processor dependent than older sh ... */
-	unsigned int reply;
-
-static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
-static __inline__ _syscall1(int,exit,int,ret)
+	register unsigned long reply asm ("r9") = ((0x13 << 16) | __NR_clone);
+	register unsigned long __flags asm ("r2") = flags | CLONE_VM;
+	register unsigned long __newsp asm ("r3") = 0;
+
+	__asm__ __volatile__ ("trapa	%1 !\t\t\t clone(%2,%3)"
+	: "=r" (__sc0) : "r" (__sc0), "r" (__sc2), "r" (__sc3));
+	__asm__ __volatile__ ("!dummy	%0 %1"
+	: : "r" (__sc0), "r" (__sc2), "r" (__sc3) : "memory");
 
-	reply = clone(flags | CLONE_VM, 0);
 	if (!reply) {
 		/* Child */
-		reply = exit(fn(arg));
+		reply = sys_exit(fn(arg));
 	}
 
 	return reply;

--

#13 lore raw

Re: [PATCH 5/7] sh64: remove the use of kernel syscalls

Quoted 4 lines · Arnd Bergmann

sh64 is using system call macros to call some functions from the kernel. Remove those so we can get rid of kernel syscalls.

It makes more sense to just rip out the old debug code, since we don't really have that much of a need for it anymore, it was mostly something that was handy during the initial bringup. This also brings us closer to something that looks like readable code again..

I also added a sane kernel_thread() implementation that gets away from this, so that should take care of sh64 at least.

arch/sh64/kernel/process.c +13 -257
index dba8e14..525d0ec 100644
@@ -20,261 +20,16 @@
 /*
  * This file handles the architecture-dependent parts of process handling..
  */
-
-/* Temporary flags/tests. All to be removed/undefined. BEGIN */
-#define IDLE_TRACE
-#define VM_SHOW_TABLES
-#define VM_TEST_FAULT
-#define VM_TEST_RTLBMISS
-#define VM_TEST_WTLBMISS
-
-#undef VM_SHOW_TABLES
-#undef IDLE_TRACE
-/* Temporary flags/tests. All to be removed/undefined. END */
-
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/kernel.h>
-#include <linux/rwsem.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/unistd.h>
-#include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-
+#include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>		/* includes also <asm/registers.h> */
-#include <asm/mmu_context.h>
-#include <asm/elf.h>
-#include <asm/page.h>
-
-#include <linux/irq.h>
 
 struct task_struct *last_task_used_math = NULL;
 
-#ifdef IDLE_TRACE
-#ifdef VM_SHOW_TABLES
-/* For testing */
-static void print_PTE(long base)
-{
-	int i, skip=0;
-	long long x, y, *p = (long long *) base;
-
-	for (i=0; i< 512; i++, p++){
-		if (*p == 0) {
-			if (!skip) {
-				skip++;
-				printk("(0s) ");
-			}
-		} else {
-			skip=0;
-			x = (*p) >> 32;
-			y = (*p) & 0xffffffff;
-			printk("%08Lx%08Lx ", x, y);
-			if (!((i+1)&0x3)) printk("\n");
-		}
-	}
-}
-
-/* For testing */
-static void print_DIR(long base)
-{
-	int i, skip=0;
-	long *p = (long *) base;
-
-	for (i=0; i< 512; i++, p++){
-		if (*p == 0) {
-			if (!skip) {
-				skip++;
-				printk("(0s) ");
-			}
-		} else {
-			skip=0;
-			printk("%08lx ", *p);
-			if (!((i+1)&0x7)) printk("\n");
-		}
-	}
-}
-
-/* For testing */
-static void print_vmalloc_first_tables(void)
-{
-
-#define PRESENT	0x800	/* Bit 11 */
-
-	/*
-	 * Do it really dirty by looking at raw addresses,
-         * raw offsets, no types. If we used pgtable/pgalloc
-	 * macros/definitions we could hide potential bugs.
-	 *
-	 * Note that pointers are 32-bit for CDC.
-	 */
-	long pgdt, pmdt, ptet;
-
-	pgdt = (long) &swapper_pg_dir;
-	printk("-->PGD (0x%08lx):\n", pgdt);
-	print_DIR(pgdt);
-	printk("\n");
-
-	/* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
-	pgdt += 4;
-	pmdt = (long) (* (long *) pgdt);
-	if (!(pmdt & PRESENT)) {
-		printk("No PMD\n");
-		return;
-	} else pmdt &= 0xfffff000;
-
-	printk("-->PMD (0x%08lx):\n", pmdt);
-	print_DIR(pmdt);
-	printk("\n");
-
-	/* Get the pmdt displacement for 0xc0000000 */
-	pmdt += 2048;
-
-	/* just look at first two address ranges ... */
-        /* ... 0xc0000000 ... */
-	ptet = (long) (* (long *) pmdt);
-	if (!(ptet & PRESENT)) {
-		printk("No PTE0\n");
-		return;
-	} else ptet &= 0xfffff000;
-
-	printk("-->PTE0 (0x%08lx):\n", ptet);
-	print_PTE(ptet);
-	printk("\n");
-
-        /* ... 0xc0001000 ... */
-	ptet += 4;
-	if (!(ptet & PRESENT)) {
-		printk("No PTE1\n");
-		return;
-	} else ptet &= 0xfffff000;
-	printk("-->PTE1 (0x%08lx):\n", ptet);
-	print_PTE(ptet);
-	printk("\n");
-}
-#else
-#define print_vmalloc_first_tables()
-#endif	/* VM_SHOW_TABLES */
-
-static void test_VM(void)
-{
-	void *a, *b, *c;
-
-#ifdef VM_SHOW_TABLES
-	printk("Initial PGD/PMD/PTE\n");
-#endif
-        print_vmalloc_first_tables();
-
-	printk("Allocating 2 bytes\n");
-	a = vmalloc(2);
-        print_vmalloc_first_tables();
-
-	printk("Allocating 4100 bytes\n");
-	b = vmalloc(4100);
-        print_vmalloc_first_tables();
-
-	printk("Allocating 20234 bytes\n");
-	c = vmalloc(20234);
-        print_vmalloc_first_tables();
-
-#ifdef VM_TEST_FAULT
-	/* Here you may want to fault ! */
-
-#ifdef VM_TEST_RTLBMISS
-	printk("Ready to fault upon read.\n");
-	if (* (char *) a) {
-		printk("RTLBMISSed on area a !\n");
-	}
-	printk("RTLBMISSed on area a !\n");
-#endif
-
-#ifdef VM_TEST_WTLBMISS
-	printk("Ready to fault upon write.\n");
-	*((char *) b) = 'L';
-	printk("WTLBMISSed on area b !\n");
-#endif
-
-#endif	/* VM_TEST_FAULT */
-
-	printk("Deallocating the 4100 byte chunk\n");
-	vfree(b);
-        print_vmalloc_first_tables();
-
-	printk("Deallocating the 2 byte chunk\n");
-	vfree(a);
-        print_vmalloc_first_tables();
-
-	printk("Deallocating the last chunk\n");
-	vfree(c);
-        print_vmalloc_first_tables();
-}
-
-extern unsigned long volatile jiffies;
-int once = 0;
-unsigned long old_jiffies;
-int pid = -1, pgid = -1;
-
-void idle_trace(void)
-{
-
-	_syscall0(int, getpid)
-	_syscall1(int, getpgid, int, pid)
-
-	if (!once) {
-        	/* VM allocation/deallocation simple test */
-		test_VM();
-		pid = getpid();
-
-        	printk("Got all through to Idle !!\n");
-        	printk("I'm now going to loop forever ...\n");
-        	printk("Any ! below is a timer tick.\n");
-		printk("Any . below is a getpgid system call from pid = %d.\n", pid);
-
-
-        	old_jiffies = jiffies;
-		once++;
-	}
-
-	if (old_jiffies != jiffies) {
-		old_jiffies = jiffies - old_jiffies;
-		switch (old_jiffies) {
-		case 1:
-			printk("!");
-			break;
-		case 2:
-			printk("!!");
-			break;
-		case 3:
-			printk("!!!");
-			break;
-		case 4:
-			printk("!!!!");
-			break;
-		default:
-			printk("(%d!)", (int) old_jiffies);
-		}
-		old_jiffies = jiffies;
-	}
-	pgid = getpgid(pid);
-	printk(".");
-}
-#else
-#define idle_trace()	do { } while (0)
-#endif	/* IDLE_TRACE */
-
 static int hlt_counter = 1;
 
 #define HARD_IDLE_TIMEOUT (HZ / 3)
@@ -323,7 +78,6 @@ void cpu_idle(void)
 			local_irq_disable();
 			while (!need_resched()) {
 				local_irq_enable();
-				idle_trace();
 				hlt();
 				local_irq_disable();
 			}
@@ -619,6 +376,10 @@ void free_task_struct(struct task_struct
 /*
  * Create a kernel thread
  */
+ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+	do_exit(fn(arg));
+}
 
 /*
  * This is the mechanism for creating a new kernel thread.
@@ -630,19 +391,17 @@ void free_task_struct(struct task_struct
  */
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
-	/* A bit less processor dependent than older sh ... */
-	unsigned int reply;
+	struct pt_regs regs;
 
-static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
-static __inline__ _syscall1(int,exit,int,ret)
+	memset(&regs, 0, sizeof(regs));
+	regs.regs[2] = (unsigned long)arg;
+	regs.regs[3] = (unsigned long)fn;
 
-	reply = clone(flags | CLONE_VM, 0);
-	if (!reply) {
-		/* Child */
-		reply = exit(fn(arg));
-	}
+	regs.pc = (unsigned long)kernel_thread_helper;
+	regs.sr = (1 << 30);
 
-	return reply;
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+		       &regs, 0, NULL, NULL);
 }
 
 /*
author maintainer
#14 lore raw

PATCH 6/7 remove all remaining _syscallX macros

In reply to Arnd Bergmann

The _syscallX macros were originally used by libc implementations, but now there is no libc that can be built against an up-to-date kernel an relies on them.
The only users of these macros are the __KERNEL_SYSCALLS_, which are now gone as well, after execve has been removed from the kernel.

include/asm-cris/unistd.h +0 -61
Index: linux-cg/include/asm-cris/unistd.h
===================================================================
@@ -324,67 +324,6 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #endif
 
-#ifdef __KERNEL_SYSCALLS__
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/linkage.h>
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-
-struct pt_regs;
-asmlinkage long sys_mmap2(
-			unsigned long addr, unsigned long len,
-			unsigned long prot, unsigned long flags,
-			unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
-			long r13, long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
-			int* parent_tid, int* child_tid, long mof, long srp,
-			struct pt_regs *regs);
-asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
-			long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
-			long mof, long srp, struct pt_regs *regs);
-asmlinkage int sys_pipe(unsigned long __user *fildes);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
-				const struct sigaction __user *act,
-				struct sigaction __user *oact,
-				size_t sigsetsize);
-
-/*
- * Since we define it "external", it collides with the built-in
- * definition, which has the "noreturn" attribute and will cause
- * complaints.  We don't want to use -fno-builtin, so just use a
- * different name when in the kernel.
- */
-#define _exit kernel_syscall_exit
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-#endif /* __KERNEL_SYSCALLS__ */
-
-
 /*
  * "Conditional" syscalls
  *
include/asm-frv/unistd.h +0 -143

149 lines not on this page · raw message

include/asm-h8300/unistd.h +0 -217

229 lines not on this page · raw message

include/asm-i386/unistd.h +0 -136

148 lines not on this page · raw message

include/asm-m32r/unistd.h +0 -145

157 lines not on this page · raw message

include/asm-m68k/unistd.h +0 -102

114 lines not on this page · raw message

include/asm-m68knommu/unistd.h +0 -204

216 lines not on this page · raw message

include/asm-mips/unistd.h +0 -301

313 lines not on this page · raw message

include/asm-s390/unistd.h +0 -203

215 lines not on this page · raw message

include/asm-sh/unistd.h +0 -186

198 lines not on this page · raw message

include/asm-sh64/unistd.h +0 -165

183 lines not on this page · raw message

include/asm-sparc/unistd.h +0 -177

189 lines not on this page · raw message

include/asm-sparc64/unistd.h +0 -160

166 lines not on this page · raw message

include/asm-v850/unistd.h +0 -179

191 lines not on this page · raw message

include/asm-xtensa/unistd.h +0 -191

203 lines not on this page · raw message

--

#15 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 6 lines · Arnd Bergmann

The _syscallX macros were originally used by libc implementations, but now there is no libc that can be built against an up-to-date kernel an relies on them.
The only users of these macros are the __KERNEL_SYSCALLS_, which are now gone as well, after execve has been removed from the kernel.

I would prefer to keep them on i386/x86-64 at least because a lot of my test programs are using them.

-Andi

author maintainer
#16 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 3 lines · Andi Kleen

I would prefer to keep them on i386/x86-64 at least because a lot of my test programs are using them.

Hmm, maybe we should have an asm-generic/unistd.h then containing something like

#ifndef __KERNEL__
#include <sys/syscall.h>
#define _syscall0(type,name) \
type name(type1 arg1) \

{ \
	return syscall(__NR_ ## name); \
}
#define _syscall1(type,name,type1,arg1) \
type name(type1 arg1) \
{ \
	return syscall(__NR_ ## name, arg1); \
}
#define _syscall1(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1, type2 arg2) \
{ \
	return syscall(__NR_ ## name, arg1, arg2); \
}

// ...
#endif

	Arnd <><
#17 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 6 lines · Arnd Bergmann
Quoted 3 lines · Andi Kleen

I would prefer to keep them on i386/x86-64 at least because a lot of my test programs are using them.

Hmm, maybe we should have an asm-generic/unistd.h then containing something like

we or the (g)libc headers ?

author maintainer
#18 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 2 lines · Arjan van de Ven

we or the (g)libc headers ?

I don't think having libc do it. In order to use these macros, you always had to #include <linux/unistd.h> or <asm/unistd.h>.

Putting the headers into a libc file means that user code would need to change its includes, when it really should just use <sys/syscall.h>.

Changing the libc copy of asm/unistd.h is against our current plan to get to a point where `make headers_install' gets you a working tree. _If_ we want to have it in there, it needs to be in the kernel source.

	Arnd <><
#19 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

In reply to Arnd Bergmann
Quoted 6 lines · Arnd Bergmann
Quoted 3 lines · Andi Kleen

I would prefer to keep them on i386/x86-64 at least because a lot of my test programs are using them.

Hmm, maybe we should have an asm-generic/unistd.h then containing something like

Or just keep the current ones that work fine?

(some older glibc implementations also get some cases wrong)

-Andi

author maintainer
#20 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 2 lines · Andi Kleen

Or just keep the current ones that work fine?

Are you sure they do? Since dwmw2 did the changeset 56142536868a2be34f261ed8fdca1610f8a73fbd, they are all inside #ifdef __KERNEL__. You may argue that merging that patch was wrong and it should be reverted, but now that we have it, the code is not relevant for user space anymore.

	Arnd <><
#21 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 9 lines · Arnd Bergmann
Quoted 2 lines · Andi Kleen

Or just keep the current ones that work fine?

Are you sure they do? Since dwmw2 did the changeset 56142536868a2be34f261ed8fdca1610f8a73fbd, they are all inside #ifdef __KERNEL__. You may argue that merging that patch was wrong and it should be reverted, but now that we have it, the code is not relevant for user space anymore.

Thanks for brining it to my attention. I indeed think think the patch was wrong.

-Andi

maintainer
#22 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

From: Andi Kleen <[email protected]>
Date: Mon, 28 Aug 2006 10:03:02 +0200

Quoted 2 lines

Thanks for brining it to my attention. I indeed think think the patch was wrong.

I disagree, this stuff really doesn't have a strong argument for existence.

#23 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 8 lines · David Miller

From: Andi Kleen <[email protected]>
Date: Mon, 28 Aug 2006 10:03:02 +0200

Quoted 2 lines

Thanks for brining it to my attention. I indeed think think the patch was wrong.

I disagree, this stuff really doesn't have a strong argument for existence.

I see it as the reference implementation of the kernel system call ABI

-Andi

maintainer
#24 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

From: Andi Kleen <[email protected]>
Date: Mon, 28 Aug 2006 10:15:38 +0200

Quoted 2 lines

I see it as the reference implementation of the kernel system call ABI

I see it as duplication because the person who writes the kernel is the one who ends up writing the libc syscall bits or explains to the libc person for that arch how things work. And once one libc implmenetation of this exists, it can be used as a reference for other libc variants.

Finally, once it's done, it's done, and that's it.

#25 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 4 lines · David Miller

I see it as duplication because the person who writes the kernel is the one who ends up writing the libc syscall bits or explains to the libc person for that arch how things work.

And the way to explain it is to write the reference code.

Quoted 3 lines

And once one libc implmenetation of this exists, it can be used as a reference for other libc variants.

At least on x86-64 various glibc versions had quite buggy syscall()s, that is why I never trusted it very much.

Quoted 1 line

Finally, once it's done, it's done, and that's it.

Except if you still have to deal with old user land.

-Andi

#26 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 8 lines · Andi Kleen
Quoted 4 lines · David Miller

I see it as duplication because the person who writes the kernel is the one who ends up writing the libc syscall bits or explains to the libc person for that arch how things work.

And the way to explain it is to write the reference code.

That's a new and interesting thing to add to the list of things that /usr/include/linux is _not_:

/usr/include/linux is _not_ a place to dump "reference code" in lieu of documentation on using kernel interfaces.

Besides, the _syscallX implementations in the kernel were generally unsuitable for use in that way anyway -- I'd be much more inclined to rely on the libc version. The kernel version would do strange things like break with PIC code by using an unavailable register (i386), misalign 64-bit syscall arguments on 32-bit machines (MIPS), etc.

Quoted 6 lines
Quoted 3 lines

And once one libc implmenetation of this exists, it can be used as a reference for other libc variants.

At least on x86-64 various glibc versions had quite buggy syscall()s, that is why I never trusted it very much.

I assume these were very _early_ glibc in when the port was new?

Quoted 3 lines
Quoted 1 line

Finally, once it's done, it's done, and that's it.

Except if you still have to deal with old user land.

The limited subset of old userland which elected to use _syscallX() instead of libc's syscall(), and which can be fixed fairly easily.

Signature · 1 line
dwmw2
#27 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 4 lines

/usr/include/linux is _not_ a place to dump "reference code" in lieu of documentation on using kernel interfaces.

At least for the system call interface it was always. It is not my fault you're trying to suddenly redefine it to be something else.

Quoted 3 lines

Besides, the _syscallX implementations in the kernel were generally unsuitable for use

I disagree. I used them and they worked great for me.

Quoted 4 lines

in that way anyway -- I'd be much more inclined to
rely on the libc version. The kernel version would do strange things like break with PIC code by using an unavailable register (i386), misalign 64-bit syscall arguments on 32-bit machines (MIPS), etc.

The glibc versions would do similar things. Just try to use a 6 argument call on i386 for once.

-Andi

#28 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 6 lines · Andi Kleen
Quoted 3 lines

/usr/include/linux is _not_ a place to dump "reference code" in lieu of documentation on using kernel interfaces.

At least for the system call interface it was always. It is not my fault you're trying to suddenly redefine it to be something else.

I'm trying to 'suddenly redefine' kernel headers as something that _isn't_ just a library of random crap for people to abuse in userspace as they see fit, then whine when something breaks even though it was never really guaranteed to work when abused in that way anyway.

So far, you're just reminding me why that needed to be done.

Quoted 4 lines
Quoted 2 lines

Besides, the _syscallX implementations in the kernel were generally unsuitable for use [as a reference implementation]

I disagree. I used them and they worked great for me.

Really? You used them as a reference implementation? Didn't you already know how x86_64 syscalls work?

Or were you saying you just happened to use the x86_64 implementation of _syscallX stuff in some userspace hacks, and it happened to work? In which case go and line up behind the guy who said that about atomic.h on i386 and only ever tested it on UP. The doctor will get to you later.

Signature · 1 line
dwmw2
#29 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 8 lines · David Woodhouse
Quoted 6 lines · Andi Kleen
Quoted 3 lines

/usr/include/linux is _not_ a place to dump "reference code" in lieu of documentation on using kernel interfaces.

At least for the system call interface it was always. It is not my fault you're trying to suddenly redefine it to be something else.

Quoted 11 lines

I'm trying to 'suddenly redefine' kernel headers as something that _isn't_ just a library of random crap for people to abuse in userspace as they see fit, then whine when something breaks even though it was never really guaranteed to work when abused in that way anyway.

So far, you're just reminding me why that needed to be done.

Quoted 4 lines
Quoted 2 lines

Besides, the _syscallX implementations in the kernel were generally unsuitable for use [as a reference implementation]

I disagree. I used them and they worked great for me.

the x86_64 macros use the VDSO page? great! I didn't know that. But that would make them unusable for kernel use I suspect...

Signature · 1 line
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
#30 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 3 lines

the x86_64 macros use the VDSO page? great! I didn't know that. But that would make them unusable for kernel use I suspect...

Not sure what you're talking about. x86-64 64bit system calls don't go through a vDSO

-Andi (who is out of the thread which seems to be full of unconstructive polemics now)

author maintainer
#31 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

In reply to David Woodhouse
Quoted 4 lines · David Woodhouse

I'm trying to 'suddenly redefine' kernel headers as something that _isn't_ just a library of random crap for people to abuse in userspace as they see fit, then whine when something breaks even though it was never really guaranteed to work when abused in that way anyway.

Well, there are two points to consider here:

1. There is user space source code out that that used these macros in the past, without feeling ashamed of it. It's fairly well-documented and seems to be a common way for inexperienced people to use syscalls before they get formal libc support.

2. There is a long history of bugs with these calls. The version with more than 5 arguments is missing on some platforms, the assembly constraints break if your gcc is too old or too new, it doesn't work at all on non-gcc compiles, and libc and kernel are normally out of sync. Expect any platform other than x86 to be broken ;-).

The patch below should address both these issues, as long as the libc has a working implementation of syscall(2).

Of course, if Andi prefers, we can do this for all architectures except x86 and let him keep the old code.

include/asm-alpha/unistd.h +2 -0
Index: linux-cg/include/asm-alpha/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ALPHA_UNISTD_H
 #define _ALPHA_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 #define __NR_osf_syscall	  0	/* not implemented */
 #define __NR_exit		  1
 #define __NR_fork		  2
include/asm-arm/unistd.h +2 -0
Index: linux-cg/include/asm-arm/unistd.h
===================================================================
@@ -13,6 +13,8 @@
 #ifndef __ASM_ARM_UNISTD_H
 #define __ASM_ARM_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 #define __NR_OABI_SYSCALL_BASE	0x900000
 
 #if defined(__thumb__) || defined(__ARM_EABI__)
include/asm-arm26/unistd.h +2 -0
Index: linux-cg/include/asm-arm26/unistd.h
===================================================================
@@ -14,6 +14,8 @@
 #ifndef __ASM_ARM_UNISTD_H
 #define __ASM_ARM_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 #define __NR_SYSCALL_BASE	0x900000
 
 /*
include/asm-cris/unistd.h +1 -0
Index: linux-cg/include/asm-cris/unistd.h
===================================================================
@@ -1,6 +1,7 @@
 #ifndef _ASM_CRIS_UNISTD_H_
 #define _ASM_CRIS_UNISTD_H_
 
+#include <asm-generic/unistd.h>
 #include <asm/arch/unistd.h>
 
 /*
include/asm-frv/unistd.h +2 -0
Index: linux-cg/include/asm-frv/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_UNISTD_H_
 #define _ASM_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-generic/Kbuild +1 -1
Index: linux-cg/include/asm-generic/Kbuild
===================================================================
@@ -1,3 +1,3 @@
 header-y += atomic.h errno-base.h errno.h fcntl.h ioctl.h ipc.h mman.h \
-	signal.h statfs.h
+	signal.h statfs.h unistd.h
 unifdef-y := resource.h siginfo.h
include/asm-generic/unistd.h new file +76 -0

76 lines not on this page · raw message

include/asm-h8300/unistd.h +2 -0
Index: linux-cg/include/asm-h8300/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_H8300_UNISTD_H_
 #define _ASM_H8300_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-i386/unistd.h +2 -0
Index: linux-cg/include/asm-i386/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_I386_UNISTD_H_
 #define _ASM_I386_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-ia64/unistd.h +1 -0
Index: linux-cg/include/asm-ia64/unistd.h
===================================================================
@@ -9,6 +9,7 @@
  */
 
 #include <asm/break.h>
+#include <asm-generic/unistd.h>
 
 #define __BREAK_SYSCALL			__IA64_BREAK_SYSCALL
 
include/asm-m32r/unistd.h +1 -0
Index: linux-cg/include/asm-m32r/unistd.h
===================================================================
@@ -4,6 +4,7 @@
 /* $Id$ */
 
 #include <asm/syscall.h>	/* SYSCALL_* */
+#include <asm-generic/unistd.h>
 
 /*
  * This file contains the system call numbers.
include/asm-m68k/unistd.h +2 -0
Index: linux-cg/include/asm-m68k/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_M68K_UNISTD_H_
 #define _ASM_M68K_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-m68knommu/unistd.h +2 -0
Index: linux-cg/include/asm-m68knommu/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_M68K_UNISTD_H_
 #define _ASM_M68K_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-mips/unistd.h +1 -0
Index: linux-cg/include/asm-mips/unistd.h
===================================================================
@@ -13,6 +13,7 @@
 #define _ASM_UNISTD_H
 
 #include <asm/sgidefs.h>
+#include <asm-generic/unistd.h>
 
 #if _MIPS_SIM == _MIPS_SIM_ABI32
 
include/asm-parisc/unistd.h +2 -0
Index: linux-cg/include/asm-parisc/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_PARISC_UNISTD_H_
 #define _ASM_PARISC_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-powerpc/unistd.h +2 -0
Index: linux-cg/include/asm-powerpc/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_PPC_UNISTD_H_
 #define _ASM_PPC_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  *
include/asm-s390/unistd.h +2 -0
Index: linux-cg/include/asm-s390/unistd.h
===================================================================
@@ -9,6 +9,8 @@
 #ifndef _ASM_S390_UNISTD_H_
 #define _ASM_S390_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file contains the system call numbers.
  */
include/asm-sh/unistd.h +2 -0
Index: linux-cg/include/asm-sh/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH_UNISTD_H
 #define __ASM_SH_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 /*
  * Copyright (C) 1999  Niibe Yutaka
  */
include/asm-sh64/unistd.h +2 -0
Index: linux-cg/include/asm-sh64/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH64_UNISTD_H
 #define __ASM_SH64_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 /*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
include/asm-sparc/unistd.h +2 -0
Index: linux-cg/include/asm-sparc/unistd.h
===================================================================
@@ -2,6 +2,8 @@
 #ifndef _SPARC_UNISTD_H
 #define _SPARC_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 /*
  * System calls under the Sparc.
  *
include/asm-sparc64/unistd.h +2 -0
Index: linux-cg/include/asm-sparc64/unistd.h
===================================================================
@@ -2,6 +2,8 @@
 #ifndef _SPARC64_UNISTD_H
 #define _SPARC64_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 /*
  * System calls under the Sparc.
  *
include/asm-v850/unistd.h +2 -0
Index: linux-cg/include/asm-v850/unistd.h
===================================================================
@@ -14,6 +14,8 @@
 #ifndef __V850_UNISTD_H__
 #define __V850_UNISTD_H__
 
+#include <asm-generic/unistd.h>
+
 #define __NR_restart_syscall	  0
 #define __NR_exit		  1
 #define __NR_fork		  2
include/asm-x86_64/unistd.h +2 -0
Index: linux-cg/include/asm-x86_64/unistd.h
===================================================================
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_64_UNISTD_H_
 #define _ASM_X86_64_UNISTD_H_
 
+#include <asm-generic/unistd.h>
+
 #ifndef __SYSCALL
 #define __SYSCALL(a,b) 
 #endif
include/asm-xtensa/unistd.h +2 -0
Index: linux-cg/include/asm-xtensa/unistd.h
===================================================================
@@ -11,6 +11,8 @@
 #ifndef _XTENSA_UNISTD_H
 #define _XTENSA_UNISTD_H
 
+#include <asm-generic/unistd.h>
+
 #define __NR_spill		  0
 #define __NR_exit		  1
 #define __NR_read		  3
#32 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 2 lines · Arnd Bergmann

The patch below should address both these issues, as long as the libc has a working implementation of syscall(2).

I would prefer the _syscall() macros to stay independent of the actual glibc version. Or what do you do otherwise on a system with old glibc? Upgrading glibc is normally a major PITA.

-Andi

#33 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 8 lines · Andi Kleen
Quoted 2 lines · Arnd Bergmann

The patch below should address both these issues, as long as the libc has a working implementation of syscall(2).

I would prefer the _syscall() macros to stay independent of the actual glibc version. Or what do you do otherwise on a system with old glibc? Upgrading glibc is normally a major PITA.

This would only be required if you'd upgrade the userspace kernel headers on this system to a version not matching the ones glibc was built against - and this has never been considered a good idea (it should work in theory, but not with our current header mess).

Quoted 1 line

-Andi

cu
Adrian

Signature · 6 lines
    Gentoo kernels are 42 times more popular than SUSE kernels among
    KLive users  (a service by SUSE contractor Andrea Arcangeli that
    gathers data about kernels from many users worldwide).

       There are three kinds of lies: Lies, Damn Lies, and Statistics.
                                                    Benjamin Disraeli
#34 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 5 lines

This would only be required if you'd upgrade the userspace kernel headers on this system to a version not matching the ones glibc was built against - and this has never been considered a good idea (it should work in theory, but not with our current header mess).

Sorry, but that's just utterly wrong. It has always worked. The kernel ABI is stable on this level.

-Andi

#35 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 8 lines · Andi Kleen
Quoted 5 lines

This would only be required if you'd upgrade the userspace kernel headers on this system to a version not matching the ones glibc was built against - and this has never been considered a good idea (it should work in theory, but not with our current header mess).

Sorry, but that's just utterly wrong. It has always worked. The kernel ABI is stable on this level.

In this area, the ABI is much more stable than the API.

Try compiling glibc-2.0.1 with 2.6.17 kernel headers...

Quoted 1 line

-Andi

cu
Adrian

Signature · 4 lines
       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed
#36 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

In reply to Andi Kleen
Quoted 8 lines · Andi Kleen
Quoted 2 lines · Arnd Bergmann

The patch below should address both these issues, as long as the libc has a working implementation of syscall(2).

I would prefer the _syscall() macros to stay independent of the actual glibc version. Or what do you do otherwise on a system with old glibc? Upgrading glibc is normally a major PITA.

Could just this macro layer be explicitly BSD (or at least LGPL) licensed? If not, it looks like a SCOX-whining-over-errno.h thing in the making in case somebody wants to build a non-GPL libc on top...

Signature · 4 lines
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513
author maintainer
#37 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Am Monday 28 August 2006 22:20 schrieb Horst H. von Brand:

Quoted 3 lines

Could just this macro layer be explicitly BSD (or at least LGPL) licensed? If not, it looks like a SCOX-whining-over-errno.h thing in the making in case somebody wants to build a non-GPL libc on top...

klibc comes with a BSD licensed version of these macros.

	Arnd <><
#38 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

In reply to Andi Kleen
Quoted 8 lines · Andi Kleen
Quoted 2 lines · Arnd Bergmann

The patch below should address both these issues, as long as the libc has a working implementation of syscall(2).

I would prefer the _syscall() macros to stay independent of the actual glibc version. Or what do you do otherwise on a system with old glibc? Upgrading glibc is normally a major PITA.

Why don't you just have a private version of the macros?

syscall(2) is, again, a horrible botch -- on architectures which requires alignment for register pairs, the extra register buggers up the alignment. One *can* work around it by making the syscall number 64 bits, but I think it's safe to say that no libc does that currently.

-hpa

#39 lore raw

Re: [PATCH 6/7] remove all remaining _syscallX macros

Quoted 2 lines

Why don't you just have a private version of the macros?

Because I don't write a libc, just test programs, preferably without a huge amount of cut'n'pasted code

-Andi

author maintainer
#40 lore raw

PATCH 7/7 remove the global errno from the kernel

In reply to Arnd Bergmann

The last in-kernel user of errno is gone, so we should remove the definition and everything referring to it. This also removes the now-unused lib/execve.c file that was introduced earlier.

Also remove a few bogus definitions of __KERNEL_SYSCALLS__ that were already unused.

lib/Makefile +1 -1
Index: linux-cg/lib/Makefile
===================================================================
@@ -2,7 +2,7 @@
 # Makefile for some libs needed in the kernel.
 #
 
-lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+lib-y := ctype.o string.o vsprintf.o cmdline.o \
 	 bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
 	 idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
 	 sha1.o
lib/execve.c deleted +0 -23
Index: linux-cg/lib/execve.c
===================================================================
@@ -1,23 +0,0 @@
-#include <asm/bug.h>
-#include <asm/uaccess.h>
-
-#define __KERNEL_SYSCALLS__
-static int errno __attribute__((unused));
-#include <asm/unistd.h>
-
-#ifdef _syscall3
-int kernel_execve (const char *filename, char *const argv[], char *const envp[])
-								__attribute__((__weak__));
-int kernel_execve (const char *filename, char *const argv[], char *const envp[])
-{
-	mm_segment_t fs = get_fs();
-	int ret;
-
-	WARN_ON(segment_eq(fs, USER_DS));
-	ret = execve(filename, (char **)argv, (char **)envp);
-	if (ret)
-		ret = -errno;
-
-	return ret;
-}
-#endif
include/linux/unistd.h +1 -5
Index: linux-cg/include/linux/unistd.h
===================================================================
@@ -1,12 +1,8 @@
 #ifndef _LINUX_UNISTD_H_
 #define _LINUX_UNISTD_H_
 
-#ifdef __KERNEL__
-extern int errno;
-#endif
-
 /*
- * Include machine specific syscallX macros
+ * Include machine specific syscall numbers
  */
 #include <asm/unistd.h>
 
lib/errno.c deleted +0 -7
Index: linux-cg/lib/errno.c
===================================================================
@@ -1,7 +0,0 @@
-/*
- *  linux/lib/errno.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-int errno;
arch/ia64/kernel/process.c +0 -2
Index: linux-cg/arch/ia64/kernel/process.c
===================================================================
@@ -8,8 +8,6 @@
  * 2005-10-07 Keith Owens <[email protected]>
  *	      Add notify_die() hooks.
  */
-#define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
-
 #include <linux/cpu.h>
 #include <linux/pm.h>
 #include <linux/elf.h>
drivers/media/dvb/dvb-core/dvb_ringbuffer.c +0 -1
Index: linux-cg/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
===================================================================
@@ -26,7 +26,6 @@
 
 
 
-#define __KERNEL_SYSCALLS__
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
drivers/net/wireless/ipw2100.c +0 -1
Index: linux-cg/drivers/net/wireless/ipw2100.c
===================================================================
@@ -150,7 +150,6 @@
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#define __KERNEL_SYSCALLS__
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/slab.h>

--

#41 lore raw

Re: [PATCH 7/7] remove the global errno from the kernel

Quoted 4 lines · Arnd Bergmann

The last in-kernel user of errno is gone, so we should remove the definition and everything referring to it. This also removes the now-unused lib/execve.c file that was introduced earlier.

CC lib/execve.o
frv-linux-gnu-gcc: lib/execve.c: No such file or directory
frv-linux-gnu-gcc: no input files

You perchance forgot to remove something added in patch 1/7.

David

#42 lore raw
In reply to Arnd Bergmann
Quoted 3 lines · Arnd Bergmann

Ok, next try. This time a full series that tries to kill off __KERNEL_SYSCALLS__, _syscallX() and the global errno for good.

Have you checked uClibc? Does that use _syscallX()?

David

#43 lore raw
Quoted 7 lines · David Howells
Quoted 3 lines · Arnd Bergmann

Ok, next try. This time a full series that tries to kill off __KERNEL_SYSCALLS__, _syscallX() and the global errno for good.

Have you checked uClibc? Does that use _syscallX()?

At least the latest version provides its own set of _syscallX() macros. I removed _syscallX() from the AVR32 kernel a few weeks ago as suggested by David Woodhouse, and uClibc doesn't seem to have a problem with it.

Haavard

author maintainer
#44 lore raw
In reply to David Howells
Quoted 5 lines · David Howells
Quoted 3 lines

Ok, next try. This time a full series that tries to kill off __KERNEL_SYSCALLS__, _syscallX() and the global errno for good.

Have you checked uClibc?  Does that use _syscallX()?

uClibc has its own copy of these macros.

	Arnd <><