aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 16:49:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 16:49:27 -0400
commite44740c1a94b5d39b093045920f543a7bc135584 (patch)
tree3dc097e078653cc520476ac997e1765b90703a56
parentd613896926be608796bb80454256a07b55fe0e87 (diff)
parentfe205bdd1321f95f8f3c35d243ea7cb22af8fbe1 (diff)
Merge tag 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML updates from Richard Weinberger: - hostfs saw a face lifting - old/broken stuff was removed (SMP, HIGHMEM, SKAS3/4) - random cleanups and bug fixes * tag 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: (26 commits) um: Print minimum physical memory requirement um: Move uml_postsetup in the init_thread stack um: add a kmsg_dumper x86, UML: fix integer overflow in ELF_ET_DYN_BASE um: hostfs: Reduce number of syscalls in readdir um: Remove broken highmem support um: Remove broken SMP support um: Remove SKAS3/4 support um: Remove ppc cruft um: Remove ia64 cruft um: Remove dead code from stacktrace hostfs: No need to box and later unbox the file mode hostfs: Use page_offset() hostfs: Set page flags in hostfs_readpage() correctly hostfs: Remove superfluous initializations in hostfs_open() hostfs: hostfs_open: Reset open flags upon each retry hostfs: Remove superfluous test in hostfs_open() hostfs: Report append flag in ->show_options() hostfs: Use __getname() in follow_link hostfs: Remove open coded strcpy() ...
-rw-r--r--arch/um/Kconfig.um42
-rw-r--r--arch/um/Makefile-ia641
-rw-r--r--arch/um/Makefile-ppc9
-rw-r--r--arch/um/include/asm/fixmap.h4
-rw-r--r--arch/um/include/asm/pgtable.h6
-rw-r--r--arch/um/include/asm/processor-generic.h8
-rw-r--r--arch/um/include/asm/smp.h26
-rw-r--r--arch/um/include/shared/as-layout.h1
-rw-r--r--arch/um/include/shared/os.h2
-rw-r--r--arch/um/include/shared/skas/proc_mm.h44
-rw-r--r--arch/um/include/shared/skas/skas.h3
-rw-r--r--arch/um/include/shared/skas_ptrace.h14
-rw-r--r--arch/um/kernel/Makefile4
-rw-r--r--arch/um/kernel/irq.c3
-rw-r--r--arch/um/kernel/kmsg_dump.c43
-rw-r--r--arch/um/kernel/mem.c66
-rw-r--r--arch/um/kernel/physmem.c41
-rw-r--r--arch/um/kernel/process.c11
-rw-r--r--arch/um/kernel/ptrace.c32
-rw-r--r--arch/um/kernel/reboot.c35
-rw-r--r--arch/um/kernel/skas/mmu.c68
-rw-r--r--arch/um/kernel/skas/process.c31
-rw-r--r--arch/um/kernel/smp.c238
-rw-r--r--arch/um/kernel/sysrq.c6
-rw-r--r--arch/um/kernel/trap.c2
-rw-r--r--arch/um/kernel/um_arch.c67
-rw-r--r--arch/um/os-Linux/process.c16
-rw-r--r--arch/um/os-Linux/skas/mem.c100
-rw-r--r--arch/um/os-Linux/skas/process.c202
-rw-r--r--arch/um/os-Linux/start_up.c154
-rw-r--r--arch/um/sys-ia64/Makefile11
-rw-r--r--arch/um/sys-ia64/sysdep/ptrace.h16
-rw-r--r--arch/um/sys-ia64/sysdep/sigcontext.h10
-rw-r--r--arch/um/sys-ia64/sysdep/skas_ptrace.h22
-rw-r--r--arch/um/sys-ia64/sysdep/syscalls.h10
-rw-r--r--arch/um/sys-ppc/Makefile65
-rw-r--r--arch/um/sys-ppc/asm/archparam.h8
-rw-r--r--arch/um/sys-ppc/asm/elf.h51
-rw-r--r--arch/um/sys-ppc/asm/processor.h15
-rw-r--r--arch/um/sys-ppc/misc.S111
-rw-r--r--arch/um/sys-ppc/miscthings.c42
-rw-r--r--arch/um/sys-ppc/ptrace.c58
-rw-r--r--arch/um/sys-ppc/ptrace_user.c29
-rw-r--r--arch/um/sys-ppc/shared/sysdep/ptrace.h93
-rw-r--r--arch/um/sys-ppc/shared/sysdep/sigcontext.h52
-rw-r--r--arch/um/sys-ppc/shared/sysdep/skas_ptrace.h22
-rw-r--r--arch/um/sys-ppc/shared/sysdep/syscalls.h43
-rw-r--r--arch/um/sys-ppc/sigcontext.c4
-rw-r--r--arch/um/sys-ppc/sysrq.c33
-rw-r--r--arch/x86/um/Makefile1
-rw-r--r--arch/x86/um/asm/barrier.h11
-rw-r--r--arch/x86/um/asm/elf.h2
-rw-r--r--arch/x86/um/ldt.c227
-rw-r--r--arch/x86/um/shared/sysdep/faultinfo_32.h3
-rw-r--r--arch/x86/um/shared/sysdep/faultinfo_64.h3
-rw-r--r--arch/x86/um/shared/sysdep/skas_ptrace.h22
-rw-r--r--fs/hostfs/hostfs.h6
-rw-r--r--fs/hostfs/hostfs_kern.c112
-rw-r--r--fs/hostfs/hostfs_user.c29
59 files changed, 323 insertions, 2067 deletions
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um
index 5dbfe3d9107c..6e67847f5272 100644
--- a/arch/um/Kconfig.um
+++ b/arch/um/Kconfig.um
@@ -95,48 +95,6 @@ config MAGIC_SYSRQ
95 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y 95 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
96 unless you really know what this hack does. 96 unless you really know what this hack does.
97 97
98config SMP
99 bool "Symmetric multi-processing support"
100 default n
101 depends on BROKEN
102 help
103 This option enables UML SMP support.
104 It is NOT related to having a real SMP box. Not directly, at least.
105
106 UML implements virtual SMP by allowing as many processes to run
107 simultaneously on the host as there are virtual processors configured.
108
109 Obviously, if the host is a uniprocessor, those processes will
110 timeshare, but, inside UML, will appear to be running simultaneously.
111 If the host is a multiprocessor, then UML processes may run
112 simultaneously, depending on the host scheduler.
113
114 This, however, is supported only in TT mode. So, if you use the SKAS
115 patch on your host, switching to TT mode and enabling SMP usually
116 gives you worse performances.
117 Also, since the support for SMP has been under-developed, there could
118 be some bugs being exposed by enabling SMP.
119
120 If you don't know what to do, say N.
121
122config NR_CPUS
123 int "Maximum number of CPUs (2-32)"
124 range 2 32
125 depends on SMP
126 default "32"
127
128config HIGHMEM
129 bool "Highmem support"
130 depends on !64BIT && BROKEN
131 default n
132 help
133 This was used to allow UML to run with big amounts of memory.
134 Currently it is unstable, so if unsure say N.
135
136 To use big amounts of memory, it is recommended enable static
137 linking (i.e. CONFIG_STATIC_LINK) - this should allow the
138 guest to use up to 2.75G of memory.
139
140config KERNEL_STACK_ORDER 98config KERNEL_STACK_ORDER
141 int "Kernel stack size order" 99 int "Kernel stack size order"
142 default 1 if 64BIT 100 default 1 if 64BIT
diff --git a/arch/um/Makefile-ia64 b/arch/um/Makefile-ia64
deleted file mode 100644
index f84dc23b0f6e..000000000000
--- a/arch/um/Makefile-ia64
+++ /dev/null
@@ -1 +0,0 @@
1START_ADDR = 0x1000000000000000
diff --git a/arch/um/Makefile-ppc b/arch/um/Makefile-ppc
deleted file mode 100644
index 66fd2003e165..000000000000
--- a/arch/um/Makefile-ppc
+++ /dev/null
@@ -1,9 +0,0 @@
1ifeq ($(CONFIG_HOST_2G_2G), y)
2START_ADDR = 0x80000000
3else
4START_ADDR = 0xc0000000
5endif
6ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
7
8# The arch is ppc, but the elf32 name is powerpc
9ELF_SUBARCH = powerpc
diff --git a/arch/um/include/asm/fixmap.h b/arch/um/include/asm/fixmap.h
index 3094ea3c73b0..1761fd75bf13 100644
--- a/arch/um/include/asm/fixmap.h
+++ b/arch/um/include/asm/fixmap.h
@@ -33,10 +33,6 @@
33 * fix-mapped? 33 * fix-mapped?
34 */ 34 */
35enum fixed_addresses { 35enum fixed_addresses {
36#ifdef CONFIG_HIGHMEM
37 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
38 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
39#endif
40 __end_of_fixed_addresses 36 __end_of_fixed_addresses
41}; 37};
42 38
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 2324b624f195..18eb9924dda3 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -47,11 +47,7 @@ extern unsigned long end_iomem;
47#define VMALLOC_OFFSET (__va_space) 47#define VMALLOC_OFFSET (__va_space)
48#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) 48#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
49#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK) 49#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
50#ifdef CONFIG_HIGHMEM 50#define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
51# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
52#else
53# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
54#endif
55#define MODULES_VADDR VMALLOC_START 51#define MODULES_VADDR VMALLOC_START
56#define MODULES_END VMALLOC_END 52#define MODULES_END VMALLOC_END
57#define MODULES_LEN (MODULES_VADDR - MODULES_END) 53#define MODULES_LEN (MODULES_VADDR - MODULES_END)
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index cbc5edd5a901..2d1e0dd5bb0b 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -98,16 +98,8 @@ struct cpuinfo_um {
98 98
99extern struct cpuinfo_um boot_cpu_data; 99extern struct cpuinfo_um boot_cpu_data;
100 100
101#define my_cpu_data cpu_data[smp_processor_id()]
102
103#ifdef CONFIG_SMP
104extern struct cpuinfo_um cpu_data[];
105#define current_cpu_data cpu_data[smp_processor_id()]
106#else
107#define cpu_data (&boot_cpu_data) 101#define cpu_data (&boot_cpu_data)
108#define current_cpu_data boot_cpu_data 102#define current_cpu_data boot_cpu_data
109#endif
110
111 103
112#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf) 104#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
113extern unsigned long get_wchan(struct task_struct *p); 105extern unsigned long get_wchan(struct task_struct *p);
diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h
index e4507938d8cf..9c3be355ed01 100644
--- a/arch/um/include/asm/smp.h
+++ b/arch/um/include/asm/smp.h
@@ -1,32 +1,6 @@
1#ifndef __UM_SMP_H 1#ifndef __UM_SMP_H
2#define __UM_SMP_H 2#define __UM_SMP_H
3 3
4#ifdef CONFIG_SMP
5
6#include <linux/bitops.h>
7#include <asm/current.h>
8#include <linux/cpumask.h>
9
10#define raw_smp_processor_id() (current_thread->cpu)
11
12#define cpu_logical_map(n) (n)
13#define cpu_number_map(n) (n)
14extern int hard_smp_processor_id(void);
15#define NO_PROC_ID -1
16
17extern int ncpus;
18
19
20static inline void smp_cpus_done(unsigned int maxcpus)
21{
22}
23
24extern struct task_struct *idle_threads[NR_CPUS];
25
26#else
27
28#define hard_smp_processor_id() 0 4#define hard_smp_processor_id() 0
29 5
30#endif 6#endif
31
32#endif
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index 41c8c774ec10..ca1843e1df15 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -56,6 +56,7 @@ extern unsigned long brk_start;
56extern unsigned long host_task_size; 56extern unsigned long host_task_size;
57 57
58extern int linux_main(int argc, char **argv); 58extern int linux_main(int argc, char **argv);
59extern void uml_finishsetup(void);
59 60
60struct siginfo; 61struct siginfo;
61extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); 62extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 08eec0b691b0..d824528f6f62 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -174,7 +174,6 @@ extern unsigned long long os_makedev(unsigned major, unsigned minor);
174 174
175/* start_up.c */ 175/* start_up.c */
176extern void os_early_checks(void); 176extern void os_early_checks(void);
177extern void can_do_skas(void);
178extern void os_check_bugs(void); 177extern void os_check_bugs(void);
179extern void check_host_supports_tls(int *supports_tls, int *tls_min); 178extern void check_host_supports_tls(int *supports_tls, int *tls_min);
180 179
@@ -187,7 +186,6 @@ extern int os_process_parent(int pid);
187extern void os_stop_process(int pid); 186extern void os_stop_process(int pid);
188extern void os_kill_process(int pid, int reap_child); 187extern void os_kill_process(int pid, int reap_child);
189extern void os_kill_ptraced_process(int pid, int reap_child); 188extern void os_kill_ptraced_process(int pid, int reap_child);
190extern long os_ptrace_ldt(long pid, long addr, long data);
191 189
192extern int os_getpid(void); 190extern int os_getpid(void);
193extern int os_getpgrp(void); 191extern int os_getpgrp(void);
diff --git a/arch/um/include/shared/skas/proc_mm.h b/arch/um/include/shared/skas/proc_mm.h
deleted file mode 100644
index 902809209603..000000000000
--- a/arch/um/include/shared/skas/proc_mm.h
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_PROC_MM_H
7#define __SKAS_PROC_MM_H
8
9#define MM_MMAP 54
10#define MM_MUNMAP 55
11#define MM_MPROTECT 56
12#define MM_COPY_SEGMENTS 57
13
14struct mm_mmap {
15 unsigned long addr;
16 unsigned long len;
17 unsigned long prot;
18 unsigned long flags;
19 unsigned long fd;
20 unsigned long offset;
21};
22
23struct mm_munmap {
24 unsigned long addr;
25 unsigned long len;
26};
27
28struct mm_mprotect {
29 unsigned long addr;
30 unsigned long len;
31 unsigned int prot;
32};
33
34struct proc_mm_op {
35 int op;
36 union {
37 struct mm_mmap mmap;
38 struct mm_munmap munmap;
39 struct mm_mprotect mprotect;
40 int copy_segments;
41 } u;
42};
43
44#endif
diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h
index c45df961c874..911f3c45ad1f 100644
--- a/arch/um/include/shared/skas/skas.h
+++ b/arch/um/include/shared/skas/skas.h
@@ -9,13 +9,10 @@
9#include <sysdep/ptrace.h> 9#include <sysdep/ptrace.h>
10 10
11extern int userspace_pid[]; 11extern int userspace_pid[];
12extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
13extern int skas_needs_stub;
14 12
15extern int user_thread(unsigned long stack, int flags); 13extern int user_thread(unsigned long stack, int flags);
16extern void new_thread_handler(void); 14extern void new_thread_handler(void);
17extern void handle_syscall(struct uml_pt_regs *regs); 15extern void handle_syscall(struct uml_pt_regs *regs);
18extern int new_mm(unsigned long stack);
19extern long execute_syscall_skas(void *r); 16extern long execute_syscall_skas(void *r);
20extern unsigned long current_stub_stack(void); 17extern unsigned long current_stub_stack(void);
21 18
diff --git a/arch/um/include/shared/skas_ptrace.h b/arch/um/include/shared/skas_ptrace.h
deleted file mode 100644
index 630a9c92b93c..000000000000
--- a/arch/um/include/shared/skas_ptrace.h
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_PTRACE_H
7#define __SKAS_PTRACE_H
8
9#define PTRACE_FAULTINFO 52
10#define PTRACE_SWITCH_MM 55
11
12#include <sysdep/skas_ptrace.h>
13
14#endif
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 2d840a070c8b..a6a5e42caaef 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -12,8 +12,8 @@ clean-files :=
12 12
13obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ 13obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
14 physmem.o process.o ptrace.o reboot.o sigio.o \ 14 physmem.o process.o ptrace.o reboot.o sigio.o \
15 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ 15 signal.o syscall.o sysrq.o time.o tlb.o trap.o \
16 um_arch.o umid.o maccess.o skas/ 16 um_arch.o umid.o maccess.o kmsg_dump.o skas/
17 17
18obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 18obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
19obj-$(CONFIG_GPROF) += gprof_syms.o 19obj-$(CONFIG_GPROF) += gprof_syms.o
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 1d8505b1e290..23cb9350d47e 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -35,9 +35,6 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
35 struct irq_fd *irq_fd; 35 struct irq_fd *irq_fd;
36 int n; 36 int n;
37 37
38 if (smp_sigio_handler())
39 return;
40
41 while (1) { 38 while (1) {
42 n = os_waiting_for_events(active_fds); 39 n = os_waiting_for_events(active_fds);
43 if (n <= 0) { 40 if (n <= 0) {
diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
new file mode 100644
index 000000000000..407d49251d6f
--- /dev/null
+++ b/arch/um/kernel/kmsg_dump.c
@@ -0,0 +1,43 @@
1#include <linux/kmsg_dump.h>
2#include <linux/console.h>
3#include <shared/init.h>
4#include <shared/kern.h>
5#include <os.h>
6
7static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
8 enum kmsg_dump_reason reason)
9{
10 static char line[1024];
11
12 size_t len = 0;
13 bool con_available = false;
14
15 /* only dump kmsg when no console is available */
16 if (!console_trylock())
17 return;
18
19 if (console_drivers != NULL)
20 con_available = true;
21
22 console_unlock();
23
24 if (con_available == true)
25 return;
26
27 printf("kmsg_dump:\n");
28 while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) {
29 line[len] = '\0';
30 printf("%s", line);
31 }
32}
33
34static struct kmsg_dumper kmsg_dumper = {
35 .dump = kmsg_dumper_stdout
36};
37
38int __init kmsg_dumper_stdout_init(void)
39{
40 return kmsg_dump_register(&kmsg_dumper);
41}
42
43__uml_postsetup(kmsg_dumper_stdout_init);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 8636e905426f..b2a2dff50b4e 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -38,19 +38,6 @@ int kmalloc_ok = 0;
38/* Used during early boot */ 38/* Used during early boot */
39static unsigned long brk_end; 39static unsigned long brk_end;
40 40
41#ifdef CONFIG_HIGHMEM
42static void setup_highmem(unsigned long highmem_start,
43 unsigned long highmem_len)
44{
45 unsigned long highmem_pfn;
46 int i;
47
48 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
49 for (i = 0; i < highmem_len >> PAGE_SHIFT; i++)
50 free_highmem_page(&mem_map[highmem_pfn + i]);
51}
52#endif
53
54void __init mem_init(void) 41void __init mem_init(void)
55{ 42{
56 /* clear the zero-page */ 43 /* clear the zero-page */
@@ -67,9 +54,6 @@ void __init mem_init(void)
67 /* this will put all low memory onto the freelists */ 54 /* this will put all low memory onto the freelists */
68 free_all_bootmem(); 55 free_all_bootmem();
69 max_low_pfn = totalram_pages; 56 max_low_pfn = totalram_pages;
70#ifdef CONFIG_HIGHMEM
71 setup_highmem(end_iomem, highmem);
72#endif
73 max_pfn = totalram_pages; 57 max_pfn = totalram_pages;
74 mem_init_print_info(NULL); 58 mem_init_print_info(NULL);
75 kmalloc_ok = 1; 59 kmalloc_ok = 1;
@@ -127,49 +111,6 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
127 } 111 }
128} 112}
129 113
130#ifdef CONFIG_HIGHMEM
131pte_t *kmap_pte;
132pgprot_t kmap_prot;
133
134#define kmap_get_fixmap_pte(vaddr) \
135 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
136 (vaddr)), (vaddr))
137
138static void __init kmap_init(void)
139{
140 unsigned long kmap_vstart;
141
142 /* cache the first kmap pte */
143 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
144 kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
145
146 kmap_prot = PAGE_KERNEL;
147}
148
149static void __init init_highmem(void)
150{
151 pgd_t *pgd;
152 pud_t *pud;
153 pmd_t *pmd;
154 pte_t *pte;
155 unsigned long vaddr;
156
157 /*
158 * Permanent kmaps:
159 */
160 vaddr = PKMAP_BASE;
161 fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
162
163 pgd = swapper_pg_dir + pgd_index(vaddr);
164 pud = pud_offset(pgd, vaddr);
165 pmd = pmd_offset(pud, vaddr);
166 pte = pte_offset_kernel(pmd, vaddr);
167 pkmap_page_table = pte;
168
169 kmap_init();
170}
171#endif /* CONFIG_HIGHMEM */
172
173static void __init fixaddr_user_init( void) 114static void __init fixaddr_user_init( void)
174{ 115{
175#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA 116#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
@@ -211,9 +152,6 @@ void __init paging_init(void)
211 152
212 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) - 153 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) -
213 (uml_physmem >> PAGE_SHIFT); 154 (uml_physmem >> PAGE_SHIFT);
214#ifdef CONFIG_HIGHMEM
215 zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
216#endif
217 free_area_init(zones_size); 155 free_area_init(zones_size);
218 156
219 /* 157 /*
@@ -224,10 +162,6 @@ void __init paging_init(void)
224 fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir); 162 fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
225 163
226 fixaddr_user_init(); 164 fixaddr_user_init();
227
228#ifdef CONFIG_HIGHMEM
229 init_highmem();
230#endif
231} 165}
232 166
233/* 167/*
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 549ecf3f5857..9034fc8056b4 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -57,22 +57,51 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
57 57
58extern int __syscall_stub_start; 58extern int __syscall_stub_start;
59 59
60/**
61 * setup_physmem() - Setup physical memory for UML
62 * @start: Start address of the physical kernel memory,
63 * i.e start address of the executable image.
64 * @reserve_end: end address of the physical kernel memory.
65 * @len: Length of total physical memory that should be mapped/made
66 * available, in bytes.
67 * @highmem: Number of highmem bytes that should be mapped/made available.
68 *
69 * Creates an unlinked temporary file of size (len + highmem) and memory maps
70 * it on the last executable image address (uml_reserved).
71 *
72 * The offset is needed as the length of the total physical memory
73 * (len + highmem) includes the size of the memory used be the executable image,
74 * but the mapped-to address is the last address of the executable image
75 * (uml_reserved == end address of executable image).
76 *
77 * The memory mapped memory of the temporary file is used as backing memory
78 * of all user space processes/kernel tasks.
79 */
60void __init setup_physmem(unsigned long start, unsigned long reserve_end, 80void __init setup_physmem(unsigned long start, unsigned long reserve_end,
61 unsigned long len, unsigned long long highmem) 81 unsigned long len, unsigned long long highmem)
62{ 82{
63 unsigned long reserve = reserve_end - start; 83 unsigned long reserve = reserve_end - start;
64 int pfn = PFN_UP(__pa(reserve_end)); 84 unsigned long pfn = PFN_UP(__pa(reserve_end));
65 int delta = (len - reserve) >> PAGE_SHIFT; 85 unsigned long delta = (len - reserve) >> PAGE_SHIFT;
66 int err, offset, bootmap_size; 86 unsigned long offset, bootmap_size;
87 long map_size;
88 int err;
89
90 offset = uml_reserved - uml_physmem;
91 map_size = len - offset;
92 if(map_size <= 0) {
93 printf("Too few physical memory! Needed=%d, given=%d\n",
94 offset, len);
95 exit(1);
96 }
67 97
68 physmem_fd = create_mem_file(len + highmem); 98 physmem_fd = create_mem_file(len + highmem);
69 99
70 offset = uml_reserved - uml_physmem;
71 err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 100 err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
72 len - offset, 1, 1, 1); 101 map_size, 1, 1, 1);
73 if (err < 0) { 102 if (err < 0) {
74 printf("setup_physmem - mapping %ld bytes of memory at 0x%p " 103 printf("setup_physmem - mapping %ld bytes of memory at 0x%p "
75 "failed - errno = %d\n", len - offset, 104 "failed - errno = %d\n", map_size,
76 (void *) uml_reserved, err); 105 (void *) uml_reserved, err);
77 exit(1); 106 exit(1);
78 } 107 }
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f17bca8ed2ce..68b9119841cd 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -259,17 +259,6 @@ int strlen_user_proc(char __user *str)
259 return strlen_user(str); 259 return strlen_user(str);
260} 260}
261 261
262int smp_sigio_handler(void)
263{
264#ifdef CONFIG_SMP
265 int cpu = current_thread_info()->cpu;
266 IPI_handler(cpu);
267 if (cpu != 0)
268 return 1;
269#endif
270 return 0;
271}
272
273int cpu(void) 262int cpu(void)
274{ 263{
275 return current_thread_info()->cpu; 264 return current_thread_info()->cpu;
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 62435ef003d9..174ee5017264 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -8,9 +8,6 @@
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <linux/tracehook.h> 9#include <linux/tracehook.h>
10#include <asm/uaccess.h> 10#include <asm/uaccess.h>
11#include <skas_ptrace.h>
12
13
14 11
15void user_enable_single_step(struct task_struct *child) 12void user_enable_single_step(struct task_struct *child)
16{ 13{
@@ -104,35 +101,6 @@ long arch_ptrace(struct task_struct *child, long request,
104 ret = ptrace_set_thread_area(child, addr, vp); 101 ret = ptrace_set_thread_area(child, addr, vp);
105 break; 102 break;
106 103
107 case PTRACE_FAULTINFO: {
108 /*
109 * Take the info from thread->arch->faultinfo,
110 * but transfer max. sizeof(struct ptrace_faultinfo).
111 * On i386, ptrace_faultinfo is smaller!
112 */
113 ret = copy_to_user(p, &child->thread.arch.faultinfo,
114 sizeof(struct ptrace_faultinfo)) ?
115 -EIO : 0;
116 break;
117 }
118
119#ifdef PTRACE_LDT
120 case PTRACE_LDT: {
121 struct ptrace_ldt ldt;
122
123 if (copy_from_user(&ldt, p, sizeof(ldt))) {
124 ret = -EIO;
125 break;
126 }
127
128 /*
129 * This one is confusing, so just punt and return -EIO for
130 * now
131 */
132 ret = -EIO;
133 break;
134 }
135#endif
136 default: 104 default:
137 ret = ptrace_request(child, request, addr, data); 105 ret = ptrace_request(child, request, addr, data);
138 if (ret == -EIO) 106 if (ret == -EIO)
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index ced8903921ae..9bdf67a092a5 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -15,28 +15,21 @@ void (*pm_power_off)(void);
15 15
16static void kill_off_processes(void) 16static void kill_off_processes(void)
17{ 17{
18 if (proc_mm) 18 struct task_struct *p;
19 /* 19 int pid;
20 * FIXME: need to loop over userspace_pids 20
21 */ 21 read_lock(&tasklist_lock);
22 os_kill_ptraced_process(userspace_pid[0], 1); 22 for_each_process(p) {
23 else { 23 struct task_struct *t;
24 struct task_struct *p; 24
25 int pid; 25 t = find_lock_task_mm(p);
26 26 if (!t)
27 read_lock(&tasklist_lock); 27 continue;
28 for_each_process(p) { 28 pid = t->mm->context.id.u.pid;
29 struct task_struct *t; 29 task_unlock(t);
30 30 os_kill_ptraced_process(pid, 1);
31 t = find_lock_task_mm(p);
32 if (!t)
33 continue;
34 pid = t->mm->context.id.u.pid;
35 task_unlock(t);
36 os_kill_ptraced_process(pid, 1);
37 }
38 read_unlock(&tasklist_lock);
39 } 31 }
32 read_unlock(&tasklist_lock);
40} 33}
41 34
42void uml_cleanup(void) 35void uml_cleanup(void)
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 007d5503f49b..94abdcc1d6ad 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -54,35 +54,22 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
54 unsigned long stack = 0; 54 unsigned long stack = 0;
55 int ret = -ENOMEM; 55 int ret = -ENOMEM;
56 56
57 if (skas_needs_stub) { 57 stack = get_zeroed_page(GFP_KERNEL);
58 stack = get_zeroed_page(GFP_KERNEL); 58 if (stack == 0)
59 if (stack == 0) 59 goto out;
60 goto out;
61 }
62 60
63 to_mm->id.stack = stack; 61 to_mm->id.stack = stack;
64 if (current->mm != NULL && current->mm != &init_mm) 62 if (current->mm != NULL && current->mm != &init_mm)
65 from_mm = &current->mm->context; 63 from_mm = &current->mm->context;
66 64
67 if (proc_mm) { 65 if (from_mm)
68 ret = new_mm(stack); 66 to_mm->id.u.pid = copy_context_skas0(stack,
69 if (ret < 0) { 67 from_mm->id.u.pid);
70 printk(KERN_ERR "init_new_context_skas - " 68 else to_mm->id.u.pid = start_userspace(stack);
71 "new_mm failed, errno = %d\n", ret); 69
72 goto out_free; 70 if (to_mm->id.u.pid < 0) {
73 } 71 ret = to_mm->id.u.pid;
74 to_mm->id.u.mm_fd = ret; 72 goto out_free;
75 }
76 else {
77 if (from_mm)
78 to_mm->id.u.pid = copy_context_skas0(stack,
79 from_mm->id.u.pid);
80 else to_mm->id.u.pid = start_userspace(stack);
81
82 if (to_mm->id.u.pid < 0) {
83 ret = to_mm->id.u.pid;
84 goto out_free;
85 }
86 } 73 }
87 74
88 ret = init_new_ldt(to_mm, from_mm); 75 ret = init_new_ldt(to_mm, from_mm);
@@ -105,9 +92,6 @@ void uml_setup_stubs(struct mm_struct *mm)
105{ 92{
106 int err, ret; 93 int err, ret;
107 94
108 if (!skas_needs_stub)
109 return;
110
111 ret = init_stub_pte(mm, STUB_CODE, 95 ret = init_stub_pte(mm, STUB_CODE,
112 (unsigned long) &__syscall_stub_start); 96 (unsigned long) &__syscall_stub_start);
113 if (ret) 97 if (ret)
@@ -154,25 +138,19 @@ void destroy_context(struct mm_struct *mm)
154{ 138{
155 struct mm_context *mmu = &mm->context; 139 struct mm_context *mmu = &mm->context;
156 140
157 if (proc_mm) 141 /*
158 os_close_file(mmu->id.u.mm_fd); 142 * If init_new_context wasn't called, this will be
159 else { 143 * zero, resulting in a kill(0), which will result in the
160 /* 144 * whole UML suddenly dying. Also, cover negative and
161 * If init_new_context wasn't called, this will be 145 * 1 cases, since they shouldn't happen either.
162 * zero, resulting in a kill(0), which will result in the 146 */
163 * whole UML suddenly dying. Also, cover negative and 147 if (mmu->id.u.pid < 2) {
164 * 1 cases, since they shouldn't happen either. 148 printk(KERN_ERR "corrupt mm_context - pid = %d\n",
165 */ 149 mmu->id.u.pid);
166 if (mmu->id.u.pid < 2) { 150 return;
167 printk(KERN_ERR "corrupt mm_context - pid = %d\n",
168 mmu->id.u.pid);
169 return;
170 }
171 os_kill_ptraced_process(mmu->id.u.pid, 1);
172 } 151 }
152 os_kill_ptraced_process(mmu->id.u.pid, 1);
173 153
174 if (skas_needs_stub) 154 free_page(mmu->id.stack);
175 free_page(mmu->id.stack);
176
177 free_ldt(mmu); 155 free_ldt(mmu);
178} 156}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 4da11b3c8ddb..527fa5881915 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -10,25 +10,6 @@
10#include <os.h> 10#include <os.h>
11#include <skas.h> 11#include <skas.h>
12 12
13int new_mm(unsigned long stack)
14{
15 int fd, err;
16
17 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
18 if (fd < 0)
19 return fd;
20
21 if (skas_needs_stub) {
22 err = map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
23 if (err) {
24 os_close_file(fd);
25 return err;
26 }
27 }
28
29 return fd;
30}
31
32extern void start_kernel(void); 13extern void start_kernel(void);
33 14
34static int __init start_kernel_proc(void *unused) 15static int __init start_kernel_proc(void *unused)
@@ -40,9 +21,7 @@ static int __init start_kernel_proc(void *unused)
40 21
41 cpu_tasks[0].pid = pid; 22 cpu_tasks[0].pid = pid;
42 cpu_tasks[0].task = current; 23 cpu_tasks[0].task = current;
43#ifdef CONFIG_SMP 24
44 init_cpu_online(get_cpu_mask(0));
45#endif
46 start_kernel(); 25 start_kernel();
47 return 0; 26 return 0;
48} 27}
@@ -55,14 +34,6 @@ int __init start_uml(void)
55{ 34{
56 stack_protections((unsigned long) &cpu0_irqstack); 35 stack_protections((unsigned long) &cpu0_irqstack);
57 set_sigstack(cpu0_irqstack, THREAD_SIZE); 36 set_sigstack(cpu0_irqstack, THREAD_SIZE);
58 if (proc_mm) {
59 userspace_pid[0] = start_userspace(0);
60 if (userspace_pid[0] < 0) {
61 printf("start_uml - start_userspace returned %d\n",
62 userspace_pid[0]);
63 exit(1);
64 }
65 }
66 37
67 init_new_thread_signals(); 38 init_new_thread_signals();
68 39
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
deleted file mode 100644
index 5c8c3ea7db7b..000000000000
--- a/arch/um/kernel/smp.c
+++ /dev/null
@@ -1,238 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/percpu.h>
7#include <asm/pgalloc.h>
8#include <asm/tlb.h>
9
10#ifdef CONFIG_SMP
11
12#include <linux/sched.h>
13#include <linux/module.h>
14#include <linux/threads.h>
15#include <linux/interrupt.h>
16#include <linux/err.h>
17#include <linux/hardirq.h>
18#include <asm/smp.h>
19#include <asm/processor.h>
20#include <asm/spinlock.h>
21#include <kern.h>
22#include <irq_user.h>
23#include <os.h>
24
25/* Per CPU bogomips and other parameters
26 * The only piece used here is the ipi pipe, which is set before SMP is
27 * started and never changed.
28 */
29struct cpuinfo_um cpu_data[NR_CPUS];
30
31/* A statistic, can be a little off */
32int num_reschedules_sent = 0;
33
34/* Not changed after boot */
35struct task_struct *idle_threads[NR_CPUS];
36
37void smp_send_reschedule(int cpu)
38{
39 os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
40 num_reschedules_sent++;
41}
42
43void smp_send_stop(void)
44{
45 int i;
46
47 printk(KERN_INFO "Stopping all CPUs...");
48 for (i = 0; i < num_online_cpus(); i++) {
49 if (i == current_thread->cpu)
50 continue;
51 os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
52 }
53 printk(KERN_CONT "done\n");
54}
55
56static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
57static cpumask_t cpu_callin_map = CPU_MASK_NONE;
58
59static int idle_proc(void *cpup)
60{
61 int cpu = (int) cpup, err;
62
63 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
64 if (err < 0)
65 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
66
67 os_set_fd_async(cpu_data[cpu].ipi_pipe[0]);
68
69 wmb();
70 if (cpu_test_and_set(cpu, cpu_callin_map)) {
71 printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
72 BUG();
73 }
74
75 while (!cpu_isset(cpu, smp_commenced_mask))
76 cpu_relax();
77
78 notify_cpu_starting(cpu);
79 set_cpu_online(cpu, true);
80 default_idle();
81 return 0;
82}
83
84static struct task_struct *idle_thread(int cpu)
85{
86 struct task_struct *new_task;
87
88 current->thread.request.u.thread.proc = idle_proc;
89 current->thread.request.u.thread.arg = (void *) cpu;
90 new_task = fork_idle(cpu);
91 if (IS_ERR(new_task))
92 panic("copy_process failed in idle_thread, error = %ld",
93 PTR_ERR(new_task));
94
95 cpu_tasks[cpu] = ((struct cpu_task)
96 { .pid = new_task->thread.mode.tt.extern_pid,
97 .task = new_task } );
98 idle_threads[cpu] = new_task;
99 panic("skas mode doesn't support SMP");
100 return new_task;
101}
102
103void smp_prepare_cpus(unsigned int maxcpus)
104{
105 struct task_struct *idle;
106 unsigned long waittime;
107 int err, cpu, me = smp_processor_id();
108 int i;
109
110 for (i = 0; i < ncpus; ++i)
111 set_cpu_possible(i, true);
112
113 set_cpu_online(me, true);
114 cpu_set(me, cpu_callin_map);
115
116 err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
117 if (err < 0)
118 panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
119
120 os_set_fd_async(cpu_data[me].ipi_pipe[0]);
121
122 for (cpu = 1; cpu < ncpus; cpu++) {
123 printk(KERN_INFO "Booting processor %d...\n", cpu);
124
125 idle = idle_thread(cpu);
126
127 init_idle(idle, cpu);
128
129 waittime = 200000000;
130 while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
131 cpu_relax();
132
133 printk(KERN_INFO "%s\n",
134 cpu_isset(cpu, cpu_calling_map) ? "done" : "failed");
135 }
136}
137
138void smp_prepare_boot_cpu(void)
139{
140 set_cpu_online(smp_processor_id(), true);
141}
142
143int __cpu_up(unsigned int cpu, struct task_struct *tidle)
144{
145 cpu_set(cpu, smp_commenced_mask);
146 while (!cpu_online(cpu))
147 mb();
148 return 0;
149}
150
151int setup_profiling_timer(unsigned int multiplier)
152{
153 printk(KERN_INFO "setup_profiling_timer\n");
154 return 0;
155}
156
157void smp_call_function_slave(int cpu);
158
159void IPI_handler(int cpu)
160{
161 unsigned char c;
162 int fd;
163
164 fd = cpu_data[cpu].ipi_pipe[0];
165 while (os_read_file(fd, &c, 1) == 1) {
166 switch (c) {
167 case 'C':
168 smp_call_function_slave(cpu);
169 break;
170
171 case 'R':
172 scheduler_ipi();
173 break;
174
175 case 'S':
176 printk(KERN_INFO "CPU#%d stopping\n", cpu);
177 while (1)
178 pause();
179 break;
180
181 default:
182 printk(KERN_ERR "CPU#%d received unknown IPI [%c]!\n",
183 cpu, c);
184 break;
185 }
186 }
187}
188
189int hard_smp_processor_id(void)
190{
191 return pid_to_processor_id(os_getpid());
192}
193
194static DEFINE_SPINLOCK(call_lock);
195static atomic_t scf_started;
196static atomic_t scf_finished;
197static void (*func)(void *info);
198static void *info;
199
200void smp_call_function_slave(int cpu)
201{
202 atomic_inc(&scf_started);
203 (*func)(info);
204 atomic_inc(&scf_finished);
205}
206
207int smp_call_function(void (*_func)(void *info), void *_info, int wait)
208{
209 int cpus = num_online_cpus() - 1;
210 int i;
211
212 if (!cpus)
213 return 0;
214
215 /* Can deadlock when called with interrupts disabled */
216 WARN_ON(irqs_disabled());
217
218 spin_lock_bh(&call_lock);
219 atomic_set(&scf_started, 0);
220 atomic_set(&scf_finished, 0);
221 func = _func;
222 info = _info;
223
224 for_each_online_cpu(i)
225 os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
226
227 while (atomic_read(&scf_started) != cpus)
228 barrier();
229
230 if (wait)
231 while (atomic_read(&scf_finished) != cpus)
232 barrier();
233
234 spin_unlock_bh(&call_lock);
235 return 0;
236}
237
238#endif
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 894c8d303cda..aa1b56f5ac68 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -29,7 +29,7 @@ static const struct stacktrace_ops stackops = {
29 29
30void show_stack(struct task_struct *task, unsigned long *stack) 30void show_stack(struct task_struct *task, unsigned long *stack)
31{ 31{
32 unsigned long *sp = stack, bp = 0; 32 unsigned long *sp = stack;
33 struct pt_regs *segv_regs = current->thread.segv_regs; 33 struct pt_regs *segv_regs = current->thread.segv_regs;
34 int i; 34 int i;
35 35
@@ -39,10 +39,6 @@ void show_stack(struct task_struct *task, unsigned long *stack)
39 return; 39 return;
40 } 40 }
41 41
42#ifdef CONFIG_FRAME_POINTER
43 bp = get_frame_pointer(task, segv_regs);
44#endif
45
46 if (!stack) 42 if (!stack)
47 sp = get_stack_pointer(task, segv_regs); 43 sp = get_stack_pointer(task, segv_regs);
48 44
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 209617302df8..8e4daf44e980 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -220,7 +220,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
220 panic("Segfault with no mm"); 220 panic("Segfault with no mm");
221 } 221 }
222 222
223 if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) 223 if (SEGV_IS_FIXABLE(&fi))
224 err = handle_page_fault(address, ip, is_write, is_user, 224 err = handle_page_fault(address, ip, is_write, is_user,
225 &si.si_code); 225 &si.si_code);
226 else { 226 else {
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 9274eae6ae7b..07f798f4bcee 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -11,6 +11,7 @@
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/utsname.h> 12#include <linux/utsname.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/kmsg_dump.h>
14#include <asm/pgtable.h> 15#include <asm/pgtable.h>
15#include <asm/processor.h> 16#include <asm/processor.h>
16#include <asm/sections.h> 17#include <asm/sections.h>
@@ -66,12 +67,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
66{ 67{
67 int index = 0; 68 int index = 0;
68 69
69#ifdef CONFIG_SMP
70 index = (struct cpuinfo_um *) v - cpu_data;
71 if (!cpu_online(index))
72 return 0;
73#endif
74
75 seq_printf(m, "processor\t: %d\n", index); 70 seq_printf(m, "processor\t: %d\n", index);
76 seq_printf(m, "vendor_id\t: User Mode Linux\n"); 71 seq_printf(m, "vendor_id\t: User Mode Linux\n");
77 seq_printf(m, "model name\t: UML\n"); 72 seq_printf(m, "model name\t: UML\n");
@@ -168,23 +163,6 @@ __uml_setup("debug", no_skas_debug_setup,
168" this flag is not needed to run gdb on UML in skas mode\n\n" 163" this flag is not needed to run gdb on UML in skas mode\n\n"
169); 164);
170 165
171#ifdef CONFIG_SMP
172static int __init uml_ncpus_setup(char *line, int *add)
173{
174 if (!sscanf(line, "%d", &ncpus)) {
175 printf("Couldn't parse [%s]\n", line);
176 return -1;
177 }
178
179 return 0;
180}
181
182__uml_setup("ncpus=", uml_ncpus_setup,
183"ncpus=<# of desired CPUs>\n"
184" This tells an SMP kernel how many virtual processors to start.\n\n"
185);
186#endif
187
188static int __init Usage(char *line, int *add) 166static int __init Usage(char *line, int *add)
189{ 167{
190 const char **p; 168 const char **p;
@@ -234,6 +212,7 @@ static void __init uml_postsetup(void)
234static int panic_exit(struct notifier_block *self, unsigned long unused1, 212static int panic_exit(struct notifier_block *self, unsigned long unused1,
235 void *unused2) 213 void *unused2)
236{ 214{
215 kmsg_dump(KMSG_DUMP_PANIC);
237 bust_spinlocks(1); 216 bust_spinlocks(1);
238 bust_spinlocks(0); 217 bust_spinlocks(0);
239 uml_exitcode = 1; 218 uml_exitcode = 1;
@@ -247,6 +226,16 @@ static struct notifier_block panic_exit_notifier = {
247 .priority = 0 226 .priority = 0
248}; 227};
249 228
229void uml_finishsetup(void)
230{
231 atomic_notifier_chain_register(&panic_notifier_list,
232 &panic_exit_notifier);
233
234 uml_postsetup();
235
236 new_thread_handler();
237}
238
250/* Set during early boot */ 239/* Set during early boot */
251unsigned long task_size; 240unsigned long task_size;
252EXPORT_SYMBOL(task_size); 241EXPORT_SYMBOL(task_size);
@@ -268,7 +257,6 @@ int __init linux_main(int argc, char **argv)
268 unsigned long stack; 257 unsigned long stack;
269 unsigned int i; 258 unsigned int i;
270 int add; 259 int add;
271 char * mode;
272 260
273 for (i = 1; i < argc; i++) { 261 for (i = 1; i < argc; i++) {
274 if ((i == 1) && (argv[i][0] == ' ')) 262 if ((i == 1) && (argv[i][0] == ' '))
@@ -291,15 +279,6 @@ int __init linux_main(int argc, char **argv)
291 /* OS sanity checks that need to happen before the kernel runs */ 279 /* OS sanity checks that need to happen before the kernel runs */
292 os_early_checks(); 280 os_early_checks();
293 281
294 can_do_skas();
295
296 if (proc_mm && ptrace_faultinfo)
297 mode = "SKAS3";
298 else
299 mode = "SKAS0";
300
301 printf("UML running in %s mode\n", mode);
302
303 brk_start = (unsigned long) sbrk(0); 282 brk_start = (unsigned long) sbrk(0);
304 283
305 /* 284 /*
@@ -334,11 +313,6 @@ int __init linux_main(int argc, char **argv)
334 if (physmem_size + iomem_size > max_physmem) { 313 if (physmem_size + iomem_size > max_physmem) {
335 highmem = physmem_size + iomem_size - max_physmem; 314 highmem = physmem_size + iomem_size - max_physmem;
336 physmem_size -= highmem; 315 physmem_size -= highmem;
337#ifndef CONFIG_HIGHMEM
338 highmem = 0;
339 printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
340 "to %Lu bytes\n", physmem_size);
341#endif
342 } 316 }
343 317
344 high_physmem = uml_physmem + physmem_size; 318 high_physmem = uml_physmem + physmem_size;
@@ -362,11 +336,6 @@ int __init linux_main(int argc, char **argv)
362 printf("Kernel virtual memory size shrunk to %lu bytes\n", 336 printf("Kernel virtual memory size shrunk to %lu bytes\n",
363 virtmem_size); 337 virtmem_size);
364 338
365 atomic_notifier_chain_register(&panic_notifier_list,
366 &panic_exit_notifier);
367
368 uml_postsetup();
369
370 stack_protections((unsigned long) &init_thread_info); 339 stack_protections((unsigned long) &init_thread_info);
371 os_flush_stdout(); 340 os_flush_stdout();
372 341
@@ -390,15 +359,3 @@ void __init check_bugs(void)
390void apply_alternatives(struct alt_instr *start, struct alt_instr *end) 359void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
391{ 360{
392} 361}
393
394#ifdef CONFIG_SMP
395void alternatives_smp_module_add(struct module *mod, char *name,
396 void *locks, void *locks_end,
397 void *text, void *text_end)
398{
399}
400
401void alternatives_smp_module_del(struct module *mod)
402{
403}
404#endif
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 33496fe2bb52..8408aba915b2 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -16,7 +16,6 @@
16#include <init.h> 16#include <init.h>
17#include <longjmp.h> 17#include <longjmp.h>
18#include <os.h> 18#include <os.h>
19#include <skas_ptrace.h>
20 19
21#define ARBITRARY_ADDR -1 20#define ARBITRARY_ADDR -1
22#define FAILURE_PID -1 21#define FAILURE_PID -1
@@ -102,21 +101,6 @@ void os_kill_process(int pid, int reap_child)
102 CATCH_EINTR(waitpid(pid, NULL, __WALL)); 101 CATCH_EINTR(waitpid(pid, NULL, __WALL));
103} 102}
104 103
105/* This is here uniquely to have access to the userspace errno, i.e. the one
106 * used by ptrace in case of error.
107 */
108
109long os_ptrace_ldt(long pid, long addr, long data)
110{
111 int ret;
112
113 ret = ptrace(PTRACE_LDT, pid, addr, data);
114
115 if (ret < 0)
116 return -errno;
117 return ret;
118}
119
120/* Kill off a ptraced child by all means available. kill it normally first, 104/* Kill off a ptraced child by all means available. kill it normally first,
121 * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from 105 * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
122 * which it can't exit directly. 106 * which it can't exit directly.
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 689b18db798f..e7f8c945a573 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -12,7 +12,6 @@
12#include <as-layout.h> 12#include <as-layout.h>
13#include <mm_id.h> 13#include <mm_id.h>
14#include <os.h> 14#include <os.h>
15#include <proc_mm.h>
16#include <ptrace_user.h> 15#include <ptrace_user.h>
17#include <registers.h> 16#include <registers.h>
18#include <skas.h> 17#include <skas.h>
@@ -46,8 +45,6 @@ static int __init init_syscall_regs(void)
46 45
47__initcall(init_syscall_regs); 46__initcall(init_syscall_regs);
48 47
49extern int proc_mm;
50
51static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) 48static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
52{ 49{
53 int n, i; 50 int n, i;
@@ -56,10 +53,6 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
56 unsigned long * syscall; 53 unsigned long * syscall;
57 int err, pid = mm_idp->u.pid; 54 int err, pid = mm_idp->u.pid;
58 55
59 if (proc_mm)
60 /* FIXME: Need to look up userspace_pid by cpu */
61 pid = userspace_pid[0];
62
63 n = ptrace_setregs(pid, syscall_regs); 56 n = ptrace_setregs(pid, syscall_regs);
64 if (n < 0) { 57 if (n < 0) {
65 printk(UM_KERN_ERR "Registers - \n"); 58 printk(UM_KERN_ERR "Registers - \n");
@@ -178,38 +171,12 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
178 int phys_fd, unsigned long long offset, int done, void **data) 171 int phys_fd, unsigned long long offset, int done, void **data)
179{ 172{
180 int ret; 173 int ret;
174 unsigned long args[] = { virt, len, prot,
175 MAP_SHARED | MAP_FIXED, phys_fd,
176 MMAP_OFFSET(offset) };
181 177
182 if (proc_mm) { 178 ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,
183 struct proc_mm_op map; 179 data, done);
184 int fd = mm_idp->u.mm_fd;
185
186 map = ((struct proc_mm_op) { .op = MM_MMAP,
187 .u =
188 { .mmap =
189 { .addr = virt,
190 .len = len,
191 .prot = prot,
192 .flags = MAP_SHARED |
193 MAP_FIXED,
194 .fd = phys_fd,
195 .offset= offset
196 } } } );
197 CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
198 if (ret != sizeof(map)) {
199 ret = -errno;
200 printk(UM_KERN_ERR "map : /proc/mm map failed, "
201 "err = %d\n", -ret);
202 }
203 else ret = 0;
204 }
205 else {
206 unsigned long args[] = { virt, len, prot,
207 MAP_SHARED | MAP_FIXED, phys_fd,
208 MMAP_OFFSET(offset) };
209
210 ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,
211 data, done);
212 }
213 180
214 return ret; 181 return ret;
215} 182}
@@ -218,32 +185,11 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
218 int done, void **data) 185 int done, void **data)
219{ 186{
220 int ret; 187 int ret;
188 unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
189 0 };
221 190
222 if (proc_mm) { 191 ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,
223 struct proc_mm_op unmap; 192 data, done);
224 int fd = mm_idp->u.mm_fd;
225
226 unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
227 .u =
228 { .munmap =
229 { .addr =
230 (unsigned long) addr,
231 .len = len } } } );
232 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
233 if (ret != sizeof(unmap)) {
234 ret = -errno;
235 printk(UM_KERN_ERR "unmap - proc_mm write returned "
236 "%d\n", ret);
237 }
238 else ret = 0;
239 }
240 else {
241 unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
242 0 };
243
244 ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,
245 data, done);
246 }
247 193
248 return ret; 194 return ret;
249} 195}
@@ -251,33 +197,11 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
251int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, 197int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
252 unsigned int prot, int done, void **data) 198 unsigned int prot, int done, void **data)
253{ 199{
254 struct proc_mm_op protect;
255 int ret; 200 int ret;
201 unsigned long args[] = { addr, len, prot, 0, 0, 0 };
256 202
257 if (proc_mm) { 203 ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,
258 int fd = mm_idp->u.mm_fd; 204 data, done);
259
260 protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
261 .u =
262 { .mprotect =
263 { .addr =
264 (unsigned long) addr,
265 .len = len,
266 .prot = prot } } } );
267
268 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
269 if (ret != sizeof(protect)) {
270 ret = -errno;
271 printk(UM_KERN_ERR "protect failed, err = %d", -ret);
272 }
273 else ret = 0;
274 }
275 else {
276 unsigned long args[] = { addr, len, prot, 0, 0, 0 };
277
278 ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,
279 data, done);
280 }
281 205
282 return ret; 206 return ret;
283} 207}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 908579f2b0ab..7a9777570a62 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -16,11 +16,9 @@
16#include <kern_util.h> 16#include <kern_util.h>
17#include <mem.h> 17#include <mem.h>
18#include <os.h> 18#include <os.h>
19#include <proc_mm.h>
20#include <ptrace_user.h> 19#include <ptrace_user.h>
21#include <registers.h> 20#include <registers.h>
22#include <skas.h> 21#include <skas.h>
23#include <skas_ptrace.h>
24#include <sysdep/stub.h> 22#include <sysdep/stub.h>
25 23
26int is_skas_winch(int pid, int fd, void *data) 24int is_skas_winch(int pid, int fd, void *data)
@@ -91,50 +89,33 @@ extern unsigned long current_stub_stack(void);
91static void get_skas_faultinfo(int pid, struct faultinfo *fi) 89static void get_skas_faultinfo(int pid, struct faultinfo *fi)
92{ 90{
93 int err; 91 int err;
92 unsigned long fpregs[FP_SIZE];
94 93
95 if (ptrace_faultinfo) { 94 err = get_fp_registers(pid, fpregs);
96 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); 95 if (err < 0) {
97 if (err) { 96 printk(UM_KERN_ERR "save_fp_registers returned %d\n",
98 printk(UM_KERN_ERR "get_skas_faultinfo - " 97 err);
99 "PTRACE_FAULTINFO failed, errno = %d\n", errno); 98 fatal_sigsegv();
100 fatal_sigsegv();
101 }
102
103 /* Special handling for i386, which has different structs */
104 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
105 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
106 sizeof(struct faultinfo) -
107 sizeof(struct ptrace_faultinfo));
108 } 99 }
109 else { 100 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
110 unsigned long fpregs[FP_SIZE]; 101 if (err) {
111 102 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
112 err = get_fp_registers(pid, fpregs); 103 "errno = %d\n", pid, errno);
113 if (err < 0) { 104 fatal_sigsegv();
114 printk(UM_KERN_ERR "save_fp_registers returned %d\n", 105 }
115 err); 106 wait_stub_done(pid);
116 fatal_sigsegv();
117 }
118 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
119 if (err) {
120 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
121 "errno = %d\n", pid, errno);
122 fatal_sigsegv();
123 }
124 wait_stub_done(pid);
125 107
126 /* 108 /*
127 * faultinfo is prepared by the stub-segv-handler at start of 109 * faultinfo is prepared by the stub-segv-handler at start of
128 * the stub stack page. We just have to copy it. 110 * the stub stack page. We just have to copy it.
129 */ 111 */
130 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); 112 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
131 113
132 err = put_fp_registers(pid, fpregs); 114 err = put_fp_registers(pid, fpregs);
133 if (err < 0) { 115 if (err < 0) {
134 printk(UM_KERN_ERR "put_fp_registers returned %d\n", 116 printk(UM_KERN_ERR "put_fp_registers returned %d\n",
135 err); 117 err);
136 fatal_sigsegv(); 118 fatal_sigsegv();
137 }
138 } 119 }
139} 120}
140 121
@@ -198,7 +179,8 @@ extern int __syscall_stub_start;
198static int userspace_tramp(void *stack) 179static int userspace_tramp(void *stack)
199{ 180{
200 void *addr; 181 void *addr;
201 int err; 182 int err, fd;
183 unsigned long long offset;
202 184
203 ptrace(PTRACE_TRACEME, 0, 0, 0); 185 ptrace(PTRACE_TRACEME, 0, 0, 0);
204 186
@@ -211,36 +193,32 @@ static int userspace_tramp(void *stack)
211 exit(1); 193 exit(1);
212 } 194 }
213 195
214 if (!proc_mm) { 196 /*
215 /* 197 * This has a pte, but it can't be mapped in with the usual
216 * This has a pte, but it can't be mapped in with the usual 198 * tlb_flush mechanism because this is part of that mechanism
217 * tlb_flush mechanism because this is part of that mechanism 199 */
218 */ 200 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
219 int fd; 201 addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
220 unsigned long long offset; 202 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
221 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); 203 if (addr == MAP_FAILED) {
222 addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE, 204 printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
223 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); 205 "errno = %d\n", STUB_CODE, errno);
206 exit(1);
207 }
208
209 if (stack != NULL) {
210 fd = phys_mapping(to_phys(stack), &offset);
211 addr = mmap((void *) STUB_DATA,
212 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
213 MAP_FIXED | MAP_SHARED, fd, offset);
224 if (addr == MAP_FAILED) { 214 if (addr == MAP_FAILED) {
225 printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, " 215 printk(UM_KERN_ERR "mapping segfault stack "
226 "errno = %d\n", STUB_CODE, errno); 216 "at 0x%lx failed, errno = %d\n",
217 STUB_DATA, errno);
227 exit(1); 218 exit(1);
228 } 219 }
229
230 if (stack != NULL) {
231 fd = phys_mapping(to_phys(stack), &offset);
232 addr = mmap((void *) STUB_DATA,
233 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
234 MAP_FIXED | MAP_SHARED, fd, offset);
235 if (addr == MAP_FAILED) {
236 printk(UM_KERN_ERR "mapping segfault stack "
237 "at 0x%lx failed, errno = %d\n",
238 STUB_DATA, errno);
239 exit(1);
240 }
241 }
242 } 220 }
243 if (!ptrace_faultinfo && (stack != NULL)) { 221 if (stack != NULL) {
244 struct sigaction sa; 222 struct sigaction sa;
245 223
246 unsigned long v = STUB_CODE + 224 unsigned long v = STUB_CODE +
@@ -286,11 +264,7 @@ int start_userspace(unsigned long stub_stack)
286 264
287 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 265 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
288 266
289 flags = CLONE_FILES; 267 flags = CLONE_FILES | SIGCHLD;
290 if (proc_mm)
291 flags |= CLONE_VM;
292 else
293 flags |= SIGCHLD;
294 268
295 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); 269 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
296 if (pid < 0) { 270 if (pid < 0) {
@@ -413,8 +387,7 @@ void userspace(struct uml_pt_regs *regs)
413 387
414 switch (sig) { 388 switch (sig) {
415 case SIGSEGV: 389 case SIGSEGV:
416 if (PTRACE_FULL_FAULTINFO || 390 if (PTRACE_FULL_FAULTINFO) {
417 !ptrace_faultinfo) {
418 get_skas_faultinfo(pid, 391 get_skas_faultinfo(pid,
419 &regs->faultinfo); 392 &regs->faultinfo);
420 (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, 393 (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si,
@@ -571,67 +544,6 @@ int copy_context_skas0(unsigned long new_stack, int pid)
571 return err; 544 return err;
572} 545}
573 546
574/*
575 * This is used only, if stub pages are needed, while proc_mm is
576 * available. Opening /proc/mm creates a new mm_context, which lacks
577 * the stub-pages. Thus, we map them using /proc/mm-fd
578 */
579int map_stub_pages(int fd, unsigned long code, unsigned long data,
580 unsigned long stack)
581{
582 struct proc_mm_op mmop;
583 int n;
584 unsigned long long code_offset;
585 int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),
586 &code_offset);
587
588 mmop = ((struct proc_mm_op) { .op = MM_MMAP,
589 .u =
590 { .mmap =
591 { .addr = code,
592 .len = UM_KERN_PAGE_SIZE,
593 .prot = PROT_EXEC,
594 .flags = MAP_FIXED | MAP_PRIVATE,
595 .fd = code_fd,
596 .offset = code_offset
597 } } });
598 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
599 if (n != sizeof(mmop)) {
600 n = errno;
601 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
602 "offset = %llx\n", code, code_fd,
603 (unsigned long long) code_offset);
604 printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for code "
605 "failed, err = %d\n", n);
606 return -n;
607 }
608
609 if (stack) {
610 unsigned long long map_offset;
611 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
612 mmop = ((struct proc_mm_op)
613 { .op = MM_MMAP,
614 .u =
615 { .mmap =
616 { .addr = data,
617 .len = UM_KERN_PAGE_SIZE,
618 .prot = PROT_READ | PROT_WRITE,
619 .flags = MAP_FIXED | MAP_SHARED,
620 .fd = map_fd,
621 .offset = map_offset
622 } } });
623 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
624 if (n != sizeof(mmop)) {
625 n = errno;
626 printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for "
627 "data failed, err = %d\n", n);
628 return -n;
629 }
630 }
631
632 return 0;
633}
634
635void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) 547void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
636{ 548{
637 (*buf)[0].JB_IP = (unsigned long) handler; 549 (*buf)[0].JB_IP = (unsigned long) handler;
@@ -674,7 +586,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
674 n = setjmp(initial_jmpbuf); 586 n = setjmp(initial_jmpbuf);
675 switch (n) { 587 switch (n) {
676 case INIT_JMP_NEW_THREAD: 588 case INIT_JMP_NEW_THREAD:
677 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; 589 (*switch_buf)[0].JB_IP = (unsigned long) uml_finishsetup;
678 (*switch_buf)[0].JB_SP = (unsigned long) stack + 590 (*switch_buf)[0].JB_SP = (unsigned long) stack +
679 UM_THREAD_SIZE - sizeof(void *); 591 UM_THREAD_SIZE - sizeof(void *);
680 break; 592 break;
@@ -728,17 +640,5 @@ void reboot_skas(void)
728 640
729void __switch_mm(struct mm_id *mm_idp) 641void __switch_mm(struct mm_id *mm_idp)
730{ 642{
731 int err; 643 userspace_pid[0] = mm_idp->u.pid;
732
733 /* FIXME: need cpu pid in __switch_mm */
734 if (proc_mm) {
735 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
736 mm_idp->u.mm_fd);
737 if (err) {
738 printk(UM_KERN_ERR "__switch_mm - PTRACE_SWITCH_MM "
739 "failed, errno = %d\n", errno);
740 fatal_sigsegv();
741 }
742 }
743 else userspace_pid[0] = mm_idp->u.pid;
744} 644}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 337518c5042a..47f1ff056a54 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -24,7 +24,6 @@
24#include <ptrace_user.h> 24#include <ptrace_user.h>
25#include <registers.h> 25#include <registers.h>
26#include <skas.h> 26#include <skas.h>
27#include <skas_ptrace.h>
28 27
29static void ptrace_child(void) 28static void ptrace_child(void)
30{ 29{
@@ -143,44 +142,6 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
143} 142}
144 143
145/* Changed only during early boot */ 144/* Changed only during early boot */
146int ptrace_faultinfo;
147static int disable_ptrace_faultinfo;
148
149int ptrace_ldt;
150static int disable_ptrace_ldt;
151
152int proc_mm;
153static int disable_proc_mm;
154
155int have_switch_mm;
156static int disable_switch_mm;
157
158int skas_needs_stub;
159
160static int __init skas0_cmd_param(char *str, int* add)
161{
162 disable_ptrace_faultinfo = 1;
163 disable_ptrace_ldt = 1;
164 disable_proc_mm = 1;
165 disable_switch_mm = 1;
166
167 return 0;
168}
169
170/* The two __uml_setup would conflict, without this stupid alias. */
171
172static int __init mode_skas0_cmd_param(char *str, int* add)
173 __attribute__((alias("skas0_cmd_param")));
174
175__uml_setup("skas0", skas0_cmd_param,
176"skas0\n"
177" Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
178
179__uml_setup("mode=skas0", mode_skas0_cmd_param,
180"mode=skas0\n"
181" Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
182
183/* Changed only during early boot */
184static int force_sysemu_disabled = 0; 145static int force_sysemu_disabled = 0;
185 146
186static int __init nosysemu_cmd_param(char *str, int* add) 147static int __init nosysemu_cmd_param(char *str, int* add)
@@ -376,121 +337,6 @@ void __init os_early_checks(void)
376 stop_ptraced_child(pid, 1, 1); 337 stop_ptraced_child(pid, 1, 1);
377} 338}
378 339
379static int __init noprocmm_cmd_param(char *str, int* add)
380{
381 disable_proc_mm = 1;
382 return 0;
383}
384
385__uml_setup("noprocmm", noprocmm_cmd_param,
386"noprocmm\n"
387" Turns off usage of /proc/mm, even if host supports it.\n"
388" To support /proc/mm, the host needs to be patched using\n"
389" the current skas3 patch.\n\n");
390
391static int __init noptracefaultinfo_cmd_param(char *str, int* add)
392{
393 disable_ptrace_faultinfo = 1;
394 return 0;
395}
396
397__uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
398"noptracefaultinfo\n"
399" Turns off usage of PTRACE_FAULTINFO, even if host supports\n"
400" it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
401" using the current skas3 patch.\n\n");
402
403static int __init noptraceldt_cmd_param(char *str, int* add)
404{
405 disable_ptrace_ldt = 1;
406 return 0;
407}
408
409__uml_setup("noptraceldt", noptraceldt_cmd_param,
410"noptraceldt\n"
411" Turns off usage of PTRACE_LDT, even if host supports it.\n"
412" To support PTRACE_LDT, the host needs to be patched using\n"
413" the current skas3 patch.\n\n");
414
415static inline void check_skas3_ptrace_faultinfo(void)
416{
417 struct ptrace_faultinfo fi;
418 int pid, n;
419
420 non_fatal(" - PTRACE_FAULTINFO...");
421 pid = start_ptraced_child();
422
423 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
424 if (n < 0) {
425 if (errno == EIO)
426 non_fatal("not found\n");
427 else
428 perror("not found");
429 } else if (disable_ptrace_faultinfo)
430 non_fatal("found but disabled on command line\n");
431 else {
432 ptrace_faultinfo = 1;
433 non_fatal("found\n");
434 }
435
436 stop_ptraced_child(pid, 1, 1);
437}
438
439static inline void check_skas3_ptrace_ldt(void)
440{
441#ifdef PTRACE_LDT
442 int pid, n;
443 unsigned char ldtbuf[40];
444 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
445 .func = 2, /* read default ldt */
446 .ptr = ldtbuf,
447 .bytecount = sizeof(ldtbuf)};
448
449 non_fatal(" - PTRACE_LDT...");
450 pid = start_ptraced_child();
451
452 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
453 if (n < 0) {
454 if (errno == EIO)
455 non_fatal("not found\n");
456 else
457 perror("not found");
458 } else if (disable_ptrace_ldt)
459 non_fatal("found, but use is disabled\n");
460 else {
461 ptrace_ldt = 1;
462 non_fatal("found\n");
463 }
464
465 stop_ptraced_child(pid, 1, 1);
466#endif
467}
468
469static inline void check_skas3_proc_mm(void)
470{
471 non_fatal(" - /proc/mm...");
472 if (access("/proc/mm", W_OK) < 0)
473 perror("not found");
474 else if (disable_proc_mm)
475 non_fatal("found but disabled on command line\n");
476 else {
477 proc_mm = 1;
478 non_fatal("found\n");
479 }
480}
481
482void can_do_skas(void)
483{
484 non_fatal("Checking for the skas3 patch in the host:\n");
485
486 check_skas3_proc_mm();
487 check_skas3_ptrace_faultinfo();
488 check_skas3_ptrace_ldt();
489
490 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
491 skas_needs_stub = 1;
492}
493
494int __init parse_iomem(char *str, int *add) 340int __init parse_iomem(char *str, int *add)
495{ 341{
496 struct iomem_region *new; 342 struct iomem_region *new;
diff --git a/arch/um/sys-ia64/Makefile b/arch/um/sys-ia64/Makefile
deleted file mode 100644
index d02f4c265232..000000000000
--- a/arch/um/sys-ia64/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1OBJ = built-in.o
2
3OBJS =
4
5all: $(OBJ)
6
7$(OBJ): $(OBJS)
8 rm -f $@
9 $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
10
11clean-files := $(OBJS) link.ld
diff --git a/arch/um/sys-ia64/sysdep/ptrace.h b/arch/um/sys-ia64/sysdep/ptrace.h
deleted file mode 100644
index 0f0f4e6fd334..000000000000
--- a/arch/um/sys-ia64/sysdep/ptrace.h
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_IA64_PTRACE_H
7#define __SYSDEP_IA64_PTRACE_H
8
9struct sys_pt_regs {
10 int foo;
11};
12
13#define EMPTY_REGS { 0 }
14
15#endif
16
diff --git a/arch/um/sys-ia64/sysdep/sigcontext.h b/arch/um/sys-ia64/sysdep/sigcontext.h
deleted file mode 100644
index 76b43161e779..000000000000
--- a/arch/um/sys-ia64/sysdep/sigcontext.h
+++ /dev/null
@@ -1,10 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_IA64_SIGCONTEXT_H
7#define __SYSDEP_IA64_SIGCONTEXT_H
8
9#endif
10
diff --git a/arch/um/sys-ia64/sysdep/skas_ptrace.h b/arch/um/sys-ia64/sysdep/skas_ptrace.h
deleted file mode 100644
index 25a38e715702..000000000000
--- a/arch/um/sys-ia64/sysdep/skas_ptrace.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_IA64_SKAS_PTRACE_H
7#define __SYSDEP_IA64_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/sys-ia64/sysdep/syscalls.h b/arch/um/sys-ia64/sysdep/syscalls.h
deleted file mode 100644
index 5f6700c41558..000000000000
--- a/arch/um/sys-ia64/sysdep/syscalls.h
+++ /dev/null
@@ -1,10 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_IA64_SYSCALLS_H
7#define __SYSDEP_IA64_SYSCALLS_H
8
9#endif
10
diff --git a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
deleted file mode 100644
index 20d363bd7004..000000000000
--- a/arch/um/sys-ppc/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
1OBJ = built-in.o
2
3.S.o:
4 $(CC) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
5
6OBJS = ptrace.o sigcontext.o checksum.o miscthings.o misc.o \
7 ptrace_user.o sysrq.o
8
9asflags-y := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel
10
11all: $(OBJ)
12
13$(OBJ): $(OBJS)
14 rm -f $@
15 $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
16
17ptrace_user.o: ptrace_user.c
18 $(CC) -D__KERNEL__ $(USER_CFLAGS) $(ccflags-y) -c -o $@ $<
19
20sigcontext.o: sigcontext.c
21 $(CC) $(USER_CFLAGS) $(ccflags-y) -c -o $@ $<
22
23checksum.S:
24 rm -f $@
25 ln -s $(srctree)/arch/ppc/lib/$@ $@
26
27mk_defs.c:
28 rm -f $@
29 ln -s $(srctree)/arch/ppc/kernel/$@ $@
30
31ppc_defs.head:
32 rm -f $@
33 ln -s $(srctree)/arch/ppc/kernel/$@ $@
34
35ppc_defs.h: mk_defs.c ppc_defs.head \
36 $(srctree)/include/asm-ppc/mmu.h \
37 $(srctree)/include/asm-ppc/processor.h \
38 $(srctree)/include/asm-ppc/pgtable.h \
39 $(srctree)/include/asm-ppc/ptrace.h
40# $(CC) $(CFLAGS) -S mk_defs.c
41 cp ppc_defs.head ppc_defs.h
42# for bk, this way we can write to the file even if it's not checked out
43 echo '#define THREAD 608' >> ppc_defs.h
44 echo '#define PT_REGS 8' >> ppc_defs.h
45 echo '#define CLONE_VM 256' >> ppc_defs.h
46# chmod u+w ppc_defs.h
47# grep '^#define' mk_defs.s >> ppc_defs.h
48# rm mk_defs.s
49
50# the asm link is horrible, and breaks the other targets. This is also
51# not going to work with parallel makes.
52
53checksum.o: checksum.S
54 rm -f asm
55 ln -s $(srctree)/include/asm-ppc asm
56 $(CC) $(asflags-y) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
57 rm -f asm
58
59misc.o: misc.S ppc_defs.h
60 rm -f asm
61 ln -s $(srctree)/include/asm-ppc asm
62 $(CC) $(asflags-y) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
63 rm -f asm
64
65clean-files := $(OBJS) ppc_defs.h checksum.S mk_defs.c
diff --git a/arch/um/sys-ppc/asm/archparam.h b/arch/um/sys-ppc/asm/archparam.h
deleted file mode 100644
index 4269d8a37b4f..000000000000
--- a/arch/um/sys-ppc/asm/archparam.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef __UM_ARCHPARAM_PPC_H
2#define __UM_ARCHPARAM_PPC_H
3
4/********* Bits for asm-um/string.h **********/
5
6#define __HAVE_ARCH_STRRCHR
7
8#endif
diff --git a/arch/um/sys-ppc/asm/elf.h b/arch/um/sys-ppc/asm/elf.h
deleted file mode 100644
index 8aacaf56508d..000000000000
--- a/arch/um/sys-ppc/asm/elf.h
+++ /dev/null
@@ -1,51 +0,0 @@
1#ifndef __UM_ELF_PPC_H
2#define __UM_ELF_PPC_H
3
4
5extern long elf_aux_hwcap;
6#define ELF_HWCAP (elf_aux_hwcap)
7
8#define SET_PERSONALITY(ex) do ; while(0)
9
10#define ELF_EXEC_PAGESIZE 4096
11
12#define elf_check_arch(x) (1)
13
14#ifdef CONFIG_64BIT
15#define ELF_CLASS ELFCLASS64
16#else
17#define ELF_CLASS ELFCLASS32
18#endif
19
20#define R_386_NONE 0
21#define R_386_32 1
22#define R_386_PC32 2
23#define R_386_GOT32 3
24#define R_386_PLT32 4
25#define R_386_COPY 5
26#define R_386_GLOB_DAT 6
27#define R_386_JMP_SLOT 7
28#define R_386_RELATIVE 8
29#define R_386_GOTOFF 9
30#define R_386_GOTPC 10
31#define R_386_NUM 11
32
33#define ELF_PLATFORM (0)
34
35#define ELF_ET_DYN_BASE (0x08000000)
36
37/* the following stolen from asm-ppc/elf.h */
38#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
39#define ELF_NFPREG 33 /* includes fpscr */
40/* General registers */
41typedef unsigned long elf_greg_t;
42typedef elf_greg_t elf_gregset_t[ELF_NGREG];
43
44/* Floating point registers */
45typedef double elf_fpreg_t;
46typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
47
48#define ELF_DATA ELFDATA2MSB
49#define ELF_ARCH EM_PPC
50
51#endif
diff --git a/arch/um/sys-ppc/asm/processor.h b/arch/um/sys-ppc/asm/processor.h
deleted file mode 100644
index 959323151229..000000000000
--- a/arch/um/sys-ppc/asm/processor.h
+++ /dev/null
@@ -1,15 +0,0 @@
1#ifndef __UM_PROCESSOR_PPC_H
2#define __UM_PROCESSOR_PPC_H
3
4#if defined(__ASSEMBLY__)
5
6#define CONFIG_PPC_MULTIPLATFORM
7#include "arch/processor.h"
8
9#else
10
11#include "asm/processor-generic.h"
12
13#endif
14
15#endif
diff --git a/arch/um/sys-ppc/misc.S b/arch/um/sys-ppc/misc.S
deleted file mode 100644
index 1364b7da578c..000000000000
--- a/arch/um/sys-ppc/misc.S
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * This file contains miscellaneous low-level functions.
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4 *
5 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
6 * and Paul Mackerras.
7 *
8 * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
9 * by Chris Emerson.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 *
16 */
17
18#include <asm/processor.h>
19#include "ppc_asm.h"
20
21#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
22#define CACHE_LINE_SIZE 16
23#define LG_CACHE_LINE_SIZE 4
24#define MAX_COPY_PREFETCH 1
25#else
26#define CACHE_LINE_SIZE 32
27#define LG_CACHE_LINE_SIZE 5
28#define MAX_COPY_PREFETCH 4
29#endif /* CONFIG_4xx || CONFIG_8xx */
30
31 .text
32
33/*
34 * Clear a page using the dcbz instruction, which doesn't cause any
35 * memory traffic (except to write out any cache lines which get
36 * displaced). This only works on cacheable memory.
37 */
38_GLOBAL(clear_page)
39 li r0,4096/CACHE_LINE_SIZE
40 mtctr r0
41#ifdef CONFIG_8xx
42 li r4, 0
431: stw r4, 0(r3)
44 stw r4, 4(r3)
45 stw r4, 8(r3)
46 stw r4, 12(r3)
47#else
481: dcbz 0,r3
49#endif
50 addi r3,r3,CACHE_LINE_SIZE
51 bdnz 1b
52 blr
53
54/*
55 * Copy a whole page. We use the dcbz instruction on the destination
56 * to reduce memory traffic (it eliminates the unnecessary reads of
57 * the destination into cache). This requires that the destination
58 * is cacheable.
59 */
60#define COPY_16_BYTES \
61 lwz r6,4(r4); \
62 lwz r7,8(r4); \
63 lwz r8,12(r4); \
64 lwzu r9,16(r4); \
65 stw r6,4(r3); \
66 stw r7,8(r3); \
67 stw r8,12(r3); \
68 stwu r9,16(r3)
69
70_GLOBAL(copy_page)
71 addi r3,r3,-4
72 addi r4,r4,-4
73 li r5,4
74
75#ifndef CONFIG_8xx
76#if MAX_COPY_PREFETCH > 1
77 li r0,MAX_COPY_PREFETCH
78 li r11,4
79 mtctr r0
8011: dcbt r11,r4
81 addi r11,r11,CACHE_LINE_SIZE
82 bdnz 11b
83#else /* MAX_COPY_PREFETCH == 1 */
84 dcbt r5,r4
85 li r11,CACHE_LINE_SIZE+4
86#endif /* MAX_COPY_PREFETCH */
87#endif /* CONFIG_8xx */
88
89 li r0,4096/CACHE_LINE_SIZE
90 mtctr r0
911:
92#ifndef CONFIG_8xx
93 dcbt r11,r4
94 dcbz r5,r3
95#endif
96 COPY_16_BYTES
97#if CACHE_LINE_SIZE >= 32
98 COPY_16_BYTES
99#if CACHE_LINE_SIZE >= 64
100 COPY_16_BYTES
101 COPY_16_BYTES
102#if CACHE_LINE_SIZE >= 128
103 COPY_16_BYTES
104 COPY_16_BYTES
105 COPY_16_BYTES
106 COPY_16_BYTES
107#endif
108#endif
109#endif
110 bdnz 1b
111 blr
diff --git a/arch/um/sys-ppc/miscthings.c b/arch/um/sys-ppc/miscthings.c
deleted file mode 100644
index 25908d26ce07..000000000000
--- a/arch/um/sys-ppc/miscthings.c
+++ /dev/null
@@ -1,42 +0,0 @@
1#include <linux/threads.h>
2#include <linux/stddef.h> // for NULL
3#include <linux/elf.h> // for AT_NULL
4
5/* The following function nicked from arch/ppc/kernel/process.c and
6 * adapted slightly */
7/*
8 * XXX ld.so expects the auxiliary table to start on
9 * a 16-byte boundary, so we have to find it and
10 * move it up. :-(
11 */
12void shove_aux_table(unsigned long sp)
13{
14 int argc;
15 char *p;
16 unsigned long e;
17 unsigned long aux_start, offset;
18
19 argc = *(int *)sp;
20 sp += sizeof(int) + (argc + 1) * sizeof(char *);
21 /* skip over the environment pointers */
22 do {
23 p = *(char **)sp;
24 sp += sizeof(char *);
25 } while (p != NULL);
26 aux_start = sp;
27 /* skip to the end of the auxiliary table */
28 do {
29 e = *(unsigned long *)sp;
30 sp += 2 * sizeof(unsigned long);
31 } while (e != AT_NULL);
32 offset = ((aux_start + 15) & ~15) - aux_start;
33 if (offset != 0) {
34 do {
35 sp -= sizeof(unsigned long);
36 e = *(unsigned long *)sp;
37 *(unsigned long *)(sp + offset) = e;
38 } while (sp > aux_start);
39 }
40}
41/* END stuff taken from arch/ppc/kernel/process.c */
42
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
deleted file mode 100644
index 8245df41b201..000000000000
--- a/arch/um/sys-ppc/ptrace.c
+++ /dev/null
@@ -1,58 +0,0 @@
1#include <linux/sched.h>
2#include "asm/ptrace.h"
3
4int putreg(struct task_struct *child, unsigned long regno,
5 unsigned long value)
6{
7 child->thread.process_regs.regs[regno >> 2] = value;
8 return 0;
9}
10
11int poke_user(struct task_struct *child, long addr, long data)
12{
13 if ((addr & 3) || addr < 0)
14 return -EIO;
15
16 if (addr < MAX_REG_OFFSET)
17 return putreg(child, addr, data);
18
19 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
20 (addr <= offsetof(struct user, u_debugreg[7]))){
21 addr -= offsetof(struct user, u_debugreg[0]);
22 addr = addr >> 2;
23 if((addr == 4) || (addr == 5)) return -EIO;
24 child->thread.arch.debugregs[addr] = data;
25 return 0;
26 }
27 return -EIO;
28}
29
30unsigned long getreg(struct task_struct *child, unsigned long regno)
31{
32 unsigned long retval = ~0UL;
33
34 retval &= child->thread.process_regs.regs[regno >> 2];
35 return retval;
36}
37
38int peek_user(struct task_struct *child, long addr, long data)
39{
40 /* read the word at location addr in the USER area. */
41 unsigned long tmp;
42
43 if ((addr & 3) || addr < 0)
44 return -EIO;
45
46 tmp = 0; /* Default return condition */
47 if(addr < MAX_REG_OFFSET){
48 tmp = getreg(child, addr);
49 }
50 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
51 (addr <= offsetof(struct user, u_debugreg[7]))){
52 addr -= offsetof(struct user, u_debugreg[0]);
53 addr = addr >> 2;
54 tmp = child->thread.arch.debugregs[addr];
55 }
56 return put_user(tmp, (unsigned long *) data);
57}
58
diff --git a/arch/um/sys-ppc/ptrace_user.c b/arch/um/sys-ppc/ptrace_user.c
deleted file mode 100644
index 4601b9296aa7..000000000000
--- a/arch/um/sys-ppc/ptrace_user.c
+++ /dev/null
@@ -1,29 +0,0 @@
1#include <errno.h>
2#include <asm/ptrace.h>
3#include <sysdep/ptrace.h>
4
5int ptrace_getregs(long pid, unsigned long *regs_out)
6{
7 int i;
8 for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
9 errno = 0;
10 regs_out->regs[i] = ptrace(PTRACE_PEEKUSR, pid, i*4, 0);
11 if (errno) {
12 return -errno;
13 }
14 }
15 return 0;
16}
17
18int ptrace_setregs(long pid, unsigned long *regs_in)
19{
20 int i;
21 for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
22 if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
23 if (ptrace(PTRACE_POKEUSR, pid, i*4, regs_in->regs[i]) < 0) {
24 return -errno;
25 }
26 }
27 }
28 return 0;
29}
diff --git a/arch/um/sys-ppc/shared/sysdep/ptrace.h b/arch/um/sys-ppc/shared/sysdep/ptrace.h
deleted file mode 100644
index efe0c1a3ea9c..000000000000
--- a/arch/um/sys-ppc/shared/sysdep/ptrace.h
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Licensed under the GPL
3 */
4
5#ifndef __SYS_PTRACE_PPC_H
6#define __SYS_PTRACE_PPC_H
7
8#include <linux/types.h>
9
10/* the following taken from <asm-ppc/ptrace.h> */
11
12#ifdef CONFIG_PPC64
13#define PPC_REG unsigned long /*long*/
14#else
15#define PPC_REG unsigned long
16#endif
17struct sys_pt_regs_s {
18 PPC_REG gpr[32];
19 PPC_REG nip;
20 PPC_REG msr;
21 PPC_REG orig_gpr3; /* Used for restarting system calls */
22 PPC_REG ctr;
23 PPC_REG link;
24 PPC_REG xer;
25 PPC_REG ccr;
26 PPC_REG mq; /* 601 only (not used at present) */
27 /* Used on APUS to hold IPL value. */
28 PPC_REG trap; /* Reason for being here */
29 PPC_REG dar; /* Fault registers */
30 PPC_REG dsisr;
31 PPC_REG result; /* Result of a system call */
32};
33
34#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
35
36struct sys_pt_regs {
37 PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
38};
39
40#define UM_MAX_REG (PT_FPR0)
41#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
42
43#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
44
45#define UM_REG(r, n) ((r)->regs[n])
46
47#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
48#define UM_SP(r) UM_REG(r, PT_R1)
49#define UM_IP(r) UM_REG(r, PT_NIP)
50#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
51#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
52#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
53#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
54#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
55#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
56#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
57#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
58
59#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
60#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
61#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
62#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
63#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
64#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
65#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
66#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
67#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
68#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
69#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
70
71#define UM_SET_SYSCALL_RETURN(_regs, result) \
72do { \
73 if (result < 0) { \
74 (_regs)->regs[PT_CCR] |= 0x10000000; \
75 UM_SYSCALL_RET((_regs)) = -result; \
76 } else { \
77 UM_SYSCALL_RET((_regs)) = result; \
78 } \
79} while(0)
80
81extern void shove_aux_table(unsigned long sp);
82#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
83
84/* These aren't actually defined. The undefs are just to make sure
85 * everyone's clear on the concept.
86 */
87#undef UML_HAVE_GETREGS
88#undef UML_HAVE_GETFPREGS
89#undef UML_HAVE_SETREGS
90#undef UML_HAVE_SETFPREGS
91
92#endif
93
diff --git a/arch/um/sys-ppc/shared/sysdep/sigcontext.h b/arch/um/sys-ppc/shared/sysdep/sigcontext.h
deleted file mode 100644
index b7286f0a1e00..000000000000
--- a/arch/um/sys-ppc/shared/sysdep/sigcontext.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYS_SIGCONTEXT_PPC_H
7#define __SYS_SIGCONTEXT_PPC_H
8
9#define DSISR_WRITE 0x02000000
10
11#define SC_FAULT_ADDR(sc) ({ \
12 struct sigcontext *_sc = (sc); \
13 long retval = -1; \
14 switch (_sc->regs->trap) { \
15 case 0x300: \
16 /* data exception */ \
17 retval = _sc->regs->dar; \
18 break; \
19 case 0x400: \
20 /* instruction exception */ \
21 retval = _sc->regs->nip; \
22 break; \
23 default: \
24 panic("SC_FAULT_ADDR: unhandled trap type\n"); \
25 } \
26 retval; \
27 })
28
29#define SC_FAULT_WRITE(sc) ({ \
30 struct sigcontext *_sc = (sc); \
31 long retval = -1; \
32 switch (_sc->regs->trap) { \
33 case 0x300: \
34 /* data exception */ \
35 retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
36 break; \
37 case 0x400: \
38 /* instruction exception: not a write */ \
39 retval = 0; \
40 break; \
41 default: \
42 panic("SC_FAULT_ADDR: unhandled trap type\n"); \
43 } \
44 retval; \
45 })
46
47#define SC_IP(sc) ((sc)->regs->nip)
48#define SC_SP(sc) ((sc)->regs->gpr[1])
49#define SEGV_IS_FIXABLE(sc) (1)
50
51#endif
52
diff --git a/arch/um/sys-ppc/shared/sysdep/skas_ptrace.h b/arch/um/sys-ppc/shared/sysdep/skas_ptrace.h
deleted file mode 100644
index d9fbbac10de0..000000000000
--- a/arch/um/sys-ppc/shared/sysdep/skas_ptrace.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_PPC_SKAS_PTRACE_H
7#define __SYSDEP_PPC_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/arch/um/sys-ppc/shared/sysdep/syscalls.h b/arch/um/sys-ppc/shared/sysdep/syscalls.h
deleted file mode 100644
index 1ff81552251c..000000000000
--- a/arch/um/sys-ppc/shared/sysdep/syscalls.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
7 unsigned long arg3, unsigned long arg4,
8 unsigned long arg5, unsigned long arg6);
9
10#define EXECUTE_SYSCALL(syscall, regs) \
11 (*sys_call_table[syscall])(UM_SYSCALL_ARG1(&regs), \
12 UM_SYSCALL_ARG2(&regs), \
13 UM_SYSCALL_ARG3(&regs), \
14 UM_SYSCALL_ARG4(&regs), \
15 UM_SYSCALL_ARG5(&regs), \
16 UM_SYSCALL_ARG6(&regs))
17
18extern syscall_handler_t sys_mincore;
19extern syscall_handler_t sys_madvise;
20
21/* old_mmap needs the correct prototype since syscall_kern.c includes
22 * this file.
23 */
24int old_mmap(unsigned long addr, unsigned long len,
25 unsigned long prot, unsigned long flags,
26 unsigned long fd, unsigned long offset);
27
28#define ARCH_SYSCALLS \
29 [ __NR_modify_ldt ] = sys_ni_syscall, \
30 [ __NR_pciconfig_read ] = sys_ni_syscall, \
31 [ __NR_pciconfig_write ] = sys_ni_syscall, \
32 [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
33 [ __NR_pivot_root ] = sys_ni_syscall, \
34 [ __NR_multiplexer ] = sys_ni_syscall, \
35 [ __NR_mmap ] = old_mmap, \
36 [ __NR_madvise ] = sys_madvise, \
37 [ __NR_mincore ] = sys_mincore, \
38 [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
39 [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
40 [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
41
42#define LAST_ARCH_SYSCALL __NR_fadvise64
43
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
deleted file mode 100644
index aac6c83fe44e..000000000000
--- a/arch/um/sys-ppc/sigcontext.c
+++ /dev/null
@@ -1,4 +0,0 @@
1#include "asm/ptrace.h"
2#include "asm/sigcontext.h"
3#include <sysdep/ptrace.h>
4
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c
deleted file mode 100644
index 1ff1ad7f27da..000000000000
--- a/arch/um/sys-ppc/sysrq.c
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Licensed under the GPL
4 */
5
6#include <linux/kernel.h>
7#include <linux/smp.h>
8#include "asm/ptrace.h"
9#include "sysrq.h"
10
11void show_regs(struct pt_regs_subarch *regs)
12{
13 printk("\n");
14 show_regs_print_info(KERN_DEFAULT);
15
16 printk("show_regs(): insert regs here.\n");
17#if 0
18 printk("\n");
19 printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
20 smp_processor_id());
21 if (regs->xcs & 3)
22 printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
23 printk(" EFLAGS: %08lx\n", regs->eflags);
24 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
25 regs->eax, regs->ebx, regs->ecx, regs->edx);
26 printk("ESI: %08lx EDI: %08lx EBP: %08lx",
27 regs->esi, regs->edi, regs->ebp);
28 printk(" DS: %04x ES: %04x\n",
29 0xffff & regs->xds, 0xffff & regs->xes);
30#endif
31
32 show_trace(current, &regs->gpr[1]);
33}
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
index eafa324eb7a5..acb384d24669 100644
--- a/arch/x86/um/Makefile
+++ b/arch/x86/um/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_BINFMT_ELF) += elfcore.o
21 21
22subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o 22subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o
23subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o 23subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o
24subarch-$(CONFIG_HIGHMEM) += ../mm/highmem_32.o
25 24
26else 25else
27 26
diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h
index 8ffd2146fa6a..7e8a1a650435 100644
--- a/arch/x86/um/asm/barrier.h
+++ b/arch/x86/um/asm/barrier.h
@@ -36,22 +36,11 @@
36#endif /* CONFIG_X86_PPRO_FENCE */ 36#endif /* CONFIG_X86_PPRO_FENCE */
37#define dma_wmb() barrier() 37#define dma_wmb() barrier()
38 38
39#ifdef CONFIG_SMP
40
41#define smp_mb() mb()
42#define smp_rmb() dma_rmb()
43#define smp_wmb() barrier()
44#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
45
46#else /* CONFIG_SMP */
47
48#define smp_mb() barrier() 39#define smp_mb() barrier()
49#define smp_rmb() barrier() 40#define smp_rmb() barrier()
50#define smp_wmb() barrier() 41#define smp_wmb() barrier()
51#define set_mb(var, value) do { var = value; barrier(); } while (0) 42#define set_mb(var, value) do { var = value; barrier(); } while (0)
52 43
53#endif /* CONFIG_SMP */
54
55#define read_barrier_depends() do { } while (0) 44#define read_barrier_depends() do { } while (0)
56#define smp_read_barrier_depends() do { } while (0) 45#define smp_read_barrier_depends() do { } while (0)
57 46
diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h
index 25a1022dd793..0a656b727b1a 100644
--- a/arch/x86/um/asm/elf.h
+++ b/arch/x86/um/asm/elf.h
@@ -210,7 +210,7 @@ extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
210 210
211#define ELF_EXEC_PAGESIZE 4096 211#define ELF_EXEC_PAGESIZE 4096
212 212
213#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) 213#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
214 214
215extern long elf_aux_hwcap; 215extern long elf_aux_hwcap;
216#define ELF_HWCAP (elf_aux_hwcap) 216#define ELF_HWCAP (elf_aux_hwcap)
diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c
index 8e08176f0bcb..5c0b711d2433 100644
--- a/arch/x86/um/ldt.c
+++ b/arch/x86/um/ldt.c
@@ -8,9 +8,7 @@
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <asm/unistd.h> 9#include <asm/unistd.h>
10#include <os.h> 10#include <os.h>
11#include <proc_mm.h>
12#include <skas.h> 11#include <skas.h>
13#include <skas_ptrace.h>
14#include <sysdep/tls.h> 12#include <sysdep/tls.h>
15 13
16extern int modify_ldt(int func, void *ptr, unsigned long bytecount); 14extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
@@ -19,105 +17,20 @@ static long write_ldt_entry(struct mm_id *mm_idp, int func,
19 struct user_desc *desc, void **addr, int done) 17 struct user_desc *desc, void **addr, int done)
20{ 18{
21 long res; 19 long res;
22 20 void *stub_addr;
23 if (proc_mm) { 21 res = syscall_stub_data(mm_idp, (unsigned long *)desc,
24 /* 22 (sizeof(*desc) + sizeof(long) - 1) &
25 * This is a special handling for the case, that the mm to 23 ~(sizeof(long) - 1),
26 * modify isn't current->active_mm. 24 addr, &stub_addr);
27 * If this is called directly by modify_ldt, 25 if (!res) {
28 * (current->active_mm->context.skas.u == mm_idp) 26 unsigned long args[] = { func,
29 * will be true. So no call to __switch_mm(mm_idp) is done. 27 (unsigned long)stub_addr,
30 * If this is called in case of init_new_ldt or PTRACE_LDT, 28 sizeof(*desc),
31 * mm_idp won't belong to current->active_mm, but child->mm. 29 0, 0, 0 };
32 * So we need to switch child's mm into our userspace, then 30 res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
33 * later switch back. 31 0, addr, done);
34 *
35 * Note: I'm unsure: should interrupts be disabled here?
36 */
37 if (!current->active_mm || current->active_mm == &init_mm ||
38 mm_idp != &current->active_mm->context.id)
39 __switch_mm(mm_idp);
40 }
41
42 if (ptrace_ldt) {
43 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
44 .func = func,
45 .ptr = desc,
46 .bytecount = sizeof(*desc)};
47 u32 cpu;
48 int pid;
49
50 if (!proc_mm)
51 pid = mm_idp->u.pid;
52 else {
53 cpu = get_cpu();
54 pid = userspace_pid[cpu];
55 }
56
57 res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op);
58
59 if (proc_mm)
60 put_cpu();
61 }
62 else {
63 void *stub_addr;
64 res = syscall_stub_data(mm_idp, (unsigned long *)desc,
65 (sizeof(*desc) + sizeof(long) - 1) &
66 ~(sizeof(long) - 1),
67 addr, &stub_addr);
68 if (!res) {
69 unsigned long args[] = { func,
70 (unsigned long)stub_addr,
71 sizeof(*desc),
72 0, 0, 0 };
73 res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
74 0, addr, done);
75 }
76 } 32 }
77 33
78 if (proc_mm) {
79 /*
80 * This is the second part of special handling, that makes
81 * PTRACE_LDT possible to implement.
82 */
83 if (current->active_mm && current->active_mm != &init_mm &&
84 mm_idp != &current->active_mm->context.id)
85 __switch_mm(&current->active_mm->context.id);
86 }
87
88 return res;
89}
90
91static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
92{
93 int res, n;
94 struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
95 .func = 0,
96 .bytecount = bytecount,
97 .ptr = kmalloc(bytecount, GFP_KERNEL)};
98 u32 cpu;
99
100 if (ptrace_ldt.ptr == NULL)
101 return -ENOMEM;
102
103 /*
104 * This is called from sys_modify_ldt only, so userspace_pid gives
105 * us the right number
106 */
107
108 cpu = get_cpu();
109 res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt);
110 put_cpu();
111 if (res < 0)
112 goto out;
113
114 n = copy_to_user(ptr, ptrace_ldt.ptr, res);
115 if (n != 0)
116 res = -EFAULT;
117
118 out:
119 kfree(ptrace_ldt.ptr);
120
121 return res; 34 return res;
122} 35}
123 36
@@ -145,9 +58,6 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
145 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; 58 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
146 err = bytecount; 59 err = bytecount;
147 60
148 if (ptrace_ldt)
149 return read_ldt_from_host(ptr, bytecount);
150
151 mutex_lock(&ldt->lock); 61 mutex_lock(&ldt->lock);
152 if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { 62 if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
153 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; 63 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
@@ -229,17 +139,11 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
229 goto out; 139 goto out;
230 } 140 }
231 141
232 if (!ptrace_ldt) 142 mutex_lock(&ldt->lock);
233 mutex_lock(&ldt->lock);
234 143
235 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); 144 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
236 if (err) 145 if (err)
237 goto out_unlock; 146 goto out_unlock;
238 else if (ptrace_ldt) {
239 /* With PTRACE_LDT available, this is used as a flag only */
240 ldt->entry_count = 1;
241 goto out;
242 }
243 147
244 if (ldt_info.entry_number >= ldt->entry_count && 148 if (ldt_info.entry_number >= ldt->entry_count &&
245 ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { 149 ldt_info.entry_number >= LDT_DIRECT_ENTRIES) {
@@ -393,91 +297,56 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
393 int i; 297 int i;
394 long page, err=0; 298 long page, err=0;
395 void *addr = NULL; 299 void *addr = NULL;
396 struct proc_mm_op copy;
397 300
398 301
399 if (!ptrace_ldt) 302 mutex_init(&new_mm->arch.ldt.lock);
400 mutex_init(&new_mm->arch.ldt.lock);
401 303
402 if (!from_mm) { 304 if (!from_mm) {
403 memset(&desc, 0, sizeof(desc)); 305 memset(&desc, 0, sizeof(desc));
404 /* 306 /*
405 * We have to initialize a clean ldt. 307 * Now we try to retrieve info about the ldt, we
308 * inherited from the host. All ldt-entries found
309 * will be reset in the following loop
406 */ 310 */
407 if (proc_mm) { 311 ldt_get_host_info();
408 /* 312 for (num_p=host_ldt_entries; *num_p != -1; num_p++) {
409 * If the new mm was created using proc_mm, host's 313 desc.entry_number = *num_p;
410 * default-ldt currently is assigned, which normally 314 err = write_ldt_entry(&new_mm->id, 1, &desc,
411 * contains the call-gates for lcall7 and lcall27. 315 &addr, *(num_p + 1) == -1);
412 * To remove these gates, we simply write an empty 316 if (err)
413 * entry as number 0 to the host. 317 break;
414 */
415 err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1);
416 }
417 else{
418 /*
419 * Now we try to retrieve info about the ldt, we
420 * inherited from the host. All ldt-entries found
421 * will be reset in the following loop
422 */
423 ldt_get_host_info();
424 for (num_p=host_ldt_entries; *num_p != -1; num_p++) {
425 desc.entry_number = *num_p;
426 err = write_ldt_entry(&new_mm->id, 1, &desc,
427 &addr, *(num_p + 1) == -1);
428 if (err)
429 break;
430 }
431 } 318 }
432 new_mm->arch.ldt.entry_count = 0; 319 new_mm->arch.ldt.entry_count = 0;
433 320
434 goto out; 321 goto out;
435 } 322 }
436 323
437 if (proc_mm) { 324 /*
438 /* 325 * Our local LDT is used to supply the data for
439 * We have a valid from_mm, so we now have to copy the LDT of 326 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
440 * from_mm to new_mm, because using proc_mm an new mm with 327 * i.e., we have to use the stub for modify_ldt, which
441 * an empty/default LDT was created in new_mm() 328 * can't handle the big read buffer of up to 64kB.
442 */ 329 */
443 copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, 330 mutex_lock(&from_mm->arch.ldt.lock);
444 .u = 331 if (from_mm->arch.ldt.entry_count <= LDT_DIRECT_ENTRIES)
445 { .copy_segments = 332 memcpy(new_mm->arch.ldt.u.entries, from_mm->arch.ldt.u.entries,
446 from_mm->id.u.mm_fd } } ); 333 sizeof(new_mm->arch.ldt.u.entries));
447 i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy)); 334 else {
448 if (i != sizeof(copy)) 335 i = from_mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE;
449 printk(KERN_ERR "new_mm : /proc/mm copy_segments " 336 while (i-->0) {
450 "failed, err = %d\n", -i); 337 page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
451 } 338 if (!page) {
452 339 err = -ENOMEM;
453 if (!ptrace_ldt) { 340 break;
454 /*
455 * Our local LDT is used to supply the data for
456 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
457 * i.e., we have to use the stub for modify_ldt, which
458 * can't handle the big read buffer of up to 64kB.
459 */
460 mutex_lock(&from_mm->arch.ldt.lock);
461 if (from_mm->arch.ldt.entry_count <= LDT_DIRECT_ENTRIES)
462 memcpy(new_mm->arch.ldt.u.entries, from_mm->arch.ldt.u.entries,
463 sizeof(new_mm->arch.ldt.u.entries));
464 else {
465 i = from_mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE;
466 while (i-->0) {
467 page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
468 if (!page) {
469 err = -ENOMEM;
470 break;
471 }
472 new_mm->arch.ldt.u.pages[i] =
473 (struct ldt_entry *) page;
474 memcpy(new_mm->arch.ldt.u.pages[i],
475 from_mm->arch.ldt.u.pages[i], PAGE_SIZE);
476 } 341 }
342 new_mm->arch.ldt.u.pages[i] =
343 (struct ldt_entry *) page;
344 memcpy(new_mm->arch.ldt.u.pages[i],
345 from_mm->arch.ldt.u.pages[i], PAGE_SIZE);
477 } 346 }
478 new_mm->arch.ldt.entry_count = from_mm->arch.ldt.entry_count;
479 mutex_unlock(&from_mm->arch.ldt.lock);
480 } 347 }
348 new_mm->arch.ldt.entry_count = from_mm->arch.ldt.entry_count;
349 mutex_unlock(&from_mm->arch.ldt.lock);
481 350
482 out: 351 out:
483 return err; 352 return err;
@@ -488,7 +357,7 @@ void free_ldt(struct mm_context *mm)
488{ 357{
489 int i; 358 int i;
490 359
491 if (!ptrace_ldt && mm->arch.ldt.entry_count > LDT_DIRECT_ENTRIES) { 360 if (mm->arch.ldt.entry_count > LDT_DIRECT_ENTRIES) {
492 i = mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE; 361 i = mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE;
493 while (i-- > 0) 362 while (i-- > 0)
494 free_page((long) mm->arch.ldt.u.pages[i]); 363 free_page((long) mm->arch.ldt.u.pages[i]);
diff --git a/arch/x86/um/shared/sysdep/faultinfo_32.h b/arch/x86/um/shared/sysdep/faultinfo_32.h
index a26086b8a800..b6f2437ec29c 100644
--- a/arch/x86/um/shared/sysdep/faultinfo_32.h
+++ b/arch/x86/um/shared/sysdep/faultinfo_32.h
@@ -27,9 +27,6 @@ struct faultinfo {
27/* This is Page Fault */ 27/* This is Page Fault */
28#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 28#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
29 29
30/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */
31#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo)
32
33#define PTRACE_FULL_FAULTINFO 0 30#define PTRACE_FULL_FAULTINFO 0
34 31
35#endif 32#endif
diff --git a/arch/x86/um/shared/sysdep/faultinfo_64.h b/arch/x86/um/shared/sysdep/faultinfo_64.h
index f811cbe15d62..ee88f88974ea 100644
--- a/arch/x86/um/shared/sysdep/faultinfo_64.h
+++ b/arch/x86/um/shared/sysdep/faultinfo_64.h
@@ -27,9 +27,6 @@ struct faultinfo {
27/* This is Page Fault */ 27/* This is Page Fault */
28#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 28#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
29 29
30/* No broken SKAS API, which doesn't pass trap_no, here. */
31#define SEGV_MAYBE_FIXABLE(fi) 0
32
33#define PTRACE_FULL_FAULTINFO 1 30#define PTRACE_FULL_FAULTINFO 1
34 31
35#endif 32#endif
diff --git a/arch/x86/um/shared/sysdep/skas_ptrace.h b/arch/x86/um/shared/sysdep/skas_ptrace.h
deleted file mode 100644
index 453febe98993..000000000000
--- a/arch/x86/um/shared/sysdep/skas_ptrace.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_X86_SKAS_PTRACE_H
7#define __SYSDEP_X86_SKAS_PTRACE_H
8
9struct ptrace_faultinfo {
10 int is_write;
11 unsigned long addr;
12};
13
14struct ptrace_ldt {
15 int func;
16 void *ptr;
17 unsigned long bytecount;
18};
19
20#define PTRACE_LDT 54
21
22#endif
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 4fcd40d6f308..91e19f9dffe5 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -66,7 +66,8 @@ extern int stat_file(const char *path, struct hostfs_stat *p, int fd);
66extern int access_file(char *path, int r, int w, int x); 66extern int access_file(char *path, int r, int w, int x);
67extern int open_file(char *path, int r, int w, int append); 67extern int open_file(char *path, int r, int w, int append);
68extern void *open_dir(char *path, int *err_out); 68extern void *open_dir(char *path, int *err_out);
69extern char *read_dir(void *stream, unsigned long long *pos, 69extern void seek_dir(void *stream, unsigned long long pos);
70extern char *read_dir(void *stream, unsigned long long *pos_out,
70 unsigned long long *ino_out, int *len_out, 71 unsigned long long *ino_out, int *len_out,
71 unsigned int *type_out); 72 unsigned int *type_out);
72extern void close_file(void *stream); 73extern void close_file(void *stream);
@@ -77,8 +78,7 @@ extern int write_file(int fd, unsigned long long *offset, const char *buf,
77 int len); 78 int len);
78extern int lseek_file(int fd, long long offset, int whence); 79extern int lseek_file(int fd, long long offset, int whence);
79extern int fsync_file(int fd, int datasync); 80extern int fsync_file(int fd, int datasync);
80extern int file_create(char *name, int ur, int uw, int ux, int gr, 81extern int file_create(char *name, int mode);
81 int gw, int gx, int or, int ow, int ox);
82extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd); 82extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd);
83extern int make_symlink(const char *from, const char *to); 83extern int make_symlink(const char *from, const char *to);
84extern int unlink_file(const char *file); 84extern int unlink_file(const char *file);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index e021188ca110..b83a0343378b 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -24,6 +24,7 @@ struct hostfs_inode_info {
24 int fd; 24 int fd;
25 fmode_t mode; 25 fmode_t mode;
26 struct inode vfs_inode; 26 struct inode vfs_inode;
27 struct mutex open_mutex;
27}; 28};
28 29
29static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) 30static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
@@ -92,16 +93,22 @@ static char *__dentry_name(struct dentry *dentry, char *name)
92 __putname(name); 93 __putname(name);
93 return NULL; 94 return NULL;
94 } 95 }
96
97 /*
98 * This function relies on the fact that dentry_path_raw() will place
99 * the path name at the end of the provided buffer.
100 */
101 BUG_ON(p + strlen(p) + 1 != name + PATH_MAX);
102
95 strlcpy(name, root, PATH_MAX); 103 strlcpy(name, root, PATH_MAX);
96 if (len > p - name) { 104 if (len > p - name) {
97 __putname(name); 105 __putname(name);
98 return NULL; 106 return NULL;
99 } 107 }
100 if (p > name + len) { 108
101 char *s = name + len; 109 if (p > name + len)
102 while ((*s++ = *p++) != '\0') 110 strcpy(name + len, p);
103 ; 111
104 }
105 return name; 112 return name;
106} 113}
107 114
@@ -135,21 +142,19 @@ static char *follow_link(char *link)
135 int len, n; 142 int len, n;
136 char *name, *resolved, *end; 143 char *name, *resolved, *end;
137 144
138 len = 64; 145 name = __getname();
139 while (1) { 146 if (!name) {
140 n = -ENOMEM; 147 n = -ENOMEM;
141 name = kmalloc(len, GFP_KERNEL); 148 goto out_free;
142 if (name == NULL)
143 goto out;
144
145 n = hostfs_do_readlink(link, name, len);
146 if (n < len)
147 break;
148 len *= 2;
149 kfree(name);
150 } 149 }
150
151 n = hostfs_do_readlink(link, name, PATH_MAX);
151 if (n < 0) 152 if (n < 0)
152 goto out_free; 153 goto out_free;
154 else if (n == PATH_MAX) {
155 n = -E2BIG;
156 goto out_free;
157 }
153 158
154 if (*name == '/') 159 if (*name == '/')
155 return name; 160 return name;
@@ -168,13 +173,12 @@ static char *follow_link(char *link)
168 } 173 }
169 174
170 sprintf(resolved, "%s%s", link, name); 175 sprintf(resolved, "%s%s", link, name);
171 kfree(name); 176 __putname(name);
172 kfree(link); 177 kfree(link);
173 return resolved; 178 return resolved;
174 179
175 out_free: 180 out_free:
176 kfree(name); 181 __putname(name);
177 out:
178 return ERR_PTR(n); 182 return ERR_PTR(n);
179} 183}
180 184
@@ -225,6 +229,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
225 hi->fd = -1; 229 hi->fd = -1;
226 hi->mode = 0; 230 hi->mode = 0;
227 inode_init_once(&hi->vfs_inode); 231 inode_init_once(&hi->vfs_inode);
232 mutex_init(&hi->open_mutex);
228 return &hi->vfs_inode; 233 return &hi->vfs_inode;
229} 234}
230 235
@@ -257,6 +262,9 @@ static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
257 if (strlen(root_path) > offset) 262 if (strlen(root_path) > offset)
258 seq_printf(seq, ",%s", root_path + offset); 263 seq_printf(seq, ",%s", root_path + offset);
259 264
265 if (append)
266 seq_puts(seq, ",append");
267
260 return 0; 268 return 0;
261} 269}
262 270
@@ -284,6 +292,7 @@ static int hostfs_readdir(struct file *file, struct dir_context *ctx)
284 if (dir == NULL) 292 if (dir == NULL)
285 return -error; 293 return -error;
286 next = ctx->pos; 294 next = ctx->pos;
295 seek_dir(dir, next);
287 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) { 296 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
288 if (!dir_emit(ctx, name, len, ino, type)) 297 if (!dir_emit(ctx, name, len, ino, type))
289 break; 298 break;
@@ -293,13 +302,12 @@ static int hostfs_readdir(struct file *file, struct dir_context *ctx)
293 return 0; 302 return 0;
294} 303}
295 304
296static int hostfs_file_open(struct inode *ino, struct file *file) 305static int hostfs_open(struct inode *ino, struct file *file)
297{ 306{
298 static DEFINE_MUTEX(open_mutex);
299 char *name; 307 char *name;
300 fmode_t mode = 0; 308 fmode_t mode;
301 int err; 309 int err;
302 int r = 0, w = 0, fd; 310 int r, w, fd;
303 311
304 mode = file->f_mode & (FMODE_READ | FMODE_WRITE); 312 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
305 if ((mode & HOSTFS_I(ino)->mode) == mode) 313 if ((mode & HOSTFS_I(ino)->mode) == mode)
@@ -308,12 +316,12 @@ static int hostfs_file_open(struct inode *ino, struct file *file)
308 mode |= HOSTFS_I(ino)->mode; 316 mode |= HOSTFS_I(ino)->mode;
309 317
310retry: 318retry:
319 r = w = 0;
320
311 if (mode & FMODE_READ) 321 if (mode & FMODE_READ)
312 r = 1; 322 r = 1;
313 if (mode & FMODE_WRITE) 323 if (mode & FMODE_WRITE)
314 w = 1; 324 r = w = 1;
315 if (w)
316 r = 1;
317 325
318 name = dentry_name(file->f_path.dentry); 326 name = dentry_name(file->f_path.dentry);
319 if (name == NULL) 327 if (name == NULL)
@@ -324,15 +332,16 @@ retry:
324 if (fd < 0) 332 if (fd < 0)
325 return fd; 333 return fd;
326 334
327 mutex_lock(&open_mutex); 335 mutex_lock(&HOSTFS_I(ino)->open_mutex);
328 /* somebody else had handled it first? */ 336 /* somebody else had handled it first? */
329 if ((mode & HOSTFS_I(ino)->mode) == mode) { 337 if ((mode & HOSTFS_I(ino)->mode) == mode) {
330 mutex_unlock(&open_mutex); 338 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
339 close_file(&fd);
331 return 0; 340 return 0;
332 } 341 }
333 if ((mode | HOSTFS_I(ino)->mode) != mode) { 342 if ((mode | HOSTFS_I(ino)->mode) != mode) {
334 mode |= HOSTFS_I(ino)->mode; 343 mode |= HOSTFS_I(ino)->mode;
335 mutex_unlock(&open_mutex); 344 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
336 close_file(&fd); 345 close_file(&fd);
337 goto retry; 346 goto retry;
338 } 347 }
@@ -342,12 +351,12 @@ retry:
342 err = replace_file(fd, HOSTFS_I(ino)->fd); 351 err = replace_file(fd, HOSTFS_I(ino)->fd);
343 close_file(&fd); 352 close_file(&fd);
344 if (err < 0) { 353 if (err < 0) {
345 mutex_unlock(&open_mutex); 354 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
346 return err; 355 return err;
347 } 356 }
348 } 357 }
349 HOSTFS_I(ino)->mode = mode; 358 HOSTFS_I(ino)->mode = mode;
350 mutex_unlock(&open_mutex); 359 mutex_unlock(&HOSTFS_I(ino)->open_mutex);
351 360
352 return 0; 361 return 0;
353} 362}
@@ -382,7 +391,7 @@ static const struct file_operations hostfs_file_fops = {
382 .read_iter = generic_file_read_iter, 391 .read_iter = generic_file_read_iter,
383 .write_iter = generic_file_write_iter, 392 .write_iter = generic_file_write_iter,
384 .mmap = generic_file_mmap, 393 .mmap = generic_file_mmap,
385 .open = hostfs_file_open, 394 .open = hostfs_open,
386 .release = hostfs_file_release, 395 .release = hostfs_file_release,
387 .fsync = hostfs_fsync, 396 .fsync = hostfs_fsync,
388}; 397};
@@ -391,6 +400,8 @@ static const struct file_operations hostfs_dir_fops = {
391 .llseek = generic_file_llseek, 400 .llseek = generic_file_llseek,
392 .iterate = hostfs_readdir, 401 .iterate = hostfs_readdir,
393 .read = generic_read_dir, 402 .read = generic_read_dir,
403 .open = hostfs_open,
404 .fsync = hostfs_fsync,
394}; 405};
395 406
396static int hostfs_writepage(struct page *page, struct writeback_control *wbc) 407static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
@@ -398,7 +409,7 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
398 struct address_space *mapping = page->mapping; 409 struct address_space *mapping = page->mapping;
399 struct inode *inode = mapping->host; 410 struct inode *inode = mapping->host;
400 char *buffer; 411 char *buffer;
401 unsigned long long base; 412 loff_t base = page_offset(page);
402 int count = PAGE_CACHE_SIZE; 413 int count = PAGE_CACHE_SIZE;
403 int end_index = inode->i_size >> PAGE_CACHE_SHIFT; 414 int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
404 int err; 415 int err;
@@ -407,7 +418,6 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
407 count = inode->i_size & (PAGE_CACHE_SIZE-1); 418 count = inode->i_size & (PAGE_CACHE_SIZE-1);
408 419
409 buffer = kmap(page); 420 buffer = kmap(page);
410 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
411 421
412 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count); 422 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
413 if (err != count) { 423 if (err != count) {
@@ -432,26 +442,29 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
432static int hostfs_readpage(struct file *file, struct page *page) 442static int hostfs_readpage(struct file *file, struct page *page)
433{ 443{
434 char *buffer; 444 char *buffer;
435 long long start; 445 loff_t start = page_offset(page);
436 int err = 0; 446 int bytes_read, ret = 0;
437 447
438 start = (long long) page->index << PAGE_CACHE_SHIFT;
439 buffer = kmap(page); 448 buffer = kmap(page);
440 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer, 449 bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
441 PAGE_CACHE_SIZE); 450 PAGE_CACHE_SIZE);
442 if (err < 0) 451 if (bytes_read < 0) {
452 ClearPageUptodate(page);
453 SetPageError(page);
454 ret = bytes_read;
443 goto out; 455 goto out;
456 }
444 457
445 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err); 458 memset(buffer + bytes_read, 0, PAGE_CACHE_SIZE - bytes_read);
446 459
447 flush_dcache_page(page); 460 ClearPageError(page);
448 SetPageUptodate(page); 461 SetPageUptodate(page);
449 if (PageError(page)) ClearPageError(page); 462
450 err = 0;
451 out: 463 out:
464 flush_dcache_page(page);
452 kunmap(page); 465 kunmap(page);
453 unlock_page(page); 466 unlock_page(page);
454 return err; 467 return ret;
455} 468}
456 469
457static int hostfs_write_begin(struct file *file, struct address_space *mapping, 470static int hostfs_write_begin(struct file *file, struct address_space *mapping,
@@ -528,11 +541,13 @@ static int read_name(struct inode *ino, char *name)
528 init_special_inode(ino, st.mode & S_IFMT, rdev); 541 init_special_inode(ino, st.mode & S_IFMT, rdev);
529 ino->i_op = &hostfs_iops; 542 ino->i_op = &hostfs_iops;
530 break; 543 break;
531 544 case S_IFREG:
532 default:
533 ino->i_op = &hostfs_iops; 545 ino->i_op = &hostfs_iops;
534 ino->i_fop = &hostfs_file_fops; 546 ino->i_fop = &hostfs_file_fops;
535 ino->i_mapping->a_ops = &hostfs_aops; 547 ino->i_mapping->a_ops = &hostfs_aops;
548 break;
549 default:
550 return -EIO;
536 } 551 }
537 552
538 ino->i_ino = st.ino; 553 ino->i_ino = st.ino;
@@ -566,10 +581,7 @@ static int hostfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
566 if (name == NULL) 581 if (name == NULL)
567 goto out_put; 582 goto out_put;
568 583
569 fd = file_create(name, 584 fd = file_create(name, mode & S_IFMT);
570 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
571 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
572 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
573 if (fd < 0) 585 if (fd < 0)
574 error = fd; 586 error = fd;
575 else 587 else
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 9765dab95cbd..9c1e0f019880 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -97,21 +97,27 @@ void *open_dir(char *path, int *err_out)
97 return dir; 97 return dir;
98} 98}
99 99
100char *read_dir(void *stream, unsigned long long *pos, 100void seek_dir(void *stream, unsigned long long pos)
101{
102 DIR *dir = stream;
103
104 seekdir(dir, pos);
105}
106
107char *read_dir(void *stream, unsigned long long *pos_out,
101 unsigned long long *ino_out, int *len_out, 108 unsigned long long *ino_out, int *len_out,
102 unsigned int *type_out) 109 unsigned int *type_out)
103{ 110{
104 DIR *dir = stream; 111 DIR *dir = stream;
105 struct dirent *ent; 112 struct dirent *ent;
106 113
107 seekdir(dir, *pos);
108 ent = readdir(dir); 114 ent = readdir(dir);
109 if (ent == NULL) 115 if (ent == NULL)
110 return NULL; 116 return NULL;
111 *len_out = strlen(ent->d_name); 117 *len_out = strlen(ent->d_name);
112 *ino_out = ent->d_ino; 118 *ino_out = ent->d_ino;
113 *type_out = ent->d_type; 119 *type_out = ent->d_type;
114 *pos = telldir(dir); 120 *pos_out = ent->d_off;
115 return ent->d_name; 121 return ent->d_name;
116} 122}
117 123
@@ -175,21 +181,10 @@ void close_dir(void *stream)
175 closedir(stream); 181 closedir(stream);
176} 182}
177 183
178int file_create(char *name, int ur, int uw, int ux, int gr, 184int file_create(char *name, int mode)
179 int gw, int gx, int or, int ow, int ox)
180{ 185{
181 int mode, fd; 186 int fd;
182 187
183 mode = 0;
184 mode |= ur ? S_IRUSR : 0;
185 mode |= uw ? S_IWUSR : 0;
186 mode |= ux ? S_IXUSR : 0;
187 mode |= gr ? S_IRGRP : 0;
188 mode |= gw ? S_IWGRP : 0;
189 mode |= gx ? S_IXGRP : 0;
190 mode |= or ? S_IROTH : 0;
191 mode |= ow ? S_IWOTH : 0;
192 mode |= ox ? S_IXOTH : 0;
193 fd = open64(name, O_CREAT | O_RDWR, mode); 188 fd = open64(name, O_CREAT | O_RDWR, mode);
194 if (fd < 0) 189 if (fd < 0)
195 return -errno; 190 return -errno;