diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 16:49:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-15 16:49:27 -0400 |
commit | e44740c1a94b5d39b093045920f543a7bc135584 (patch) | |
tree | 3dc097e078653cc520476ac997e1765b90703a56 | |
parent | d613896926be608796bb80454256a07b55fe0e87 (diff) | |
parent | fe205bdd1321f95f8f3c35d243ea7cb22af8fbe1 (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()
...
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 | ||
98 | config 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 | |||
122 | config NR_CPUS | ||
123 | int "Maximum number of CPUs (2-32)" | ||
124 | range 2 32 | ||
125 | depends on SMP | ||
126 | default "32" | ||
127 | |||
128 | config 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 | |||
140 | config KERNEL_STACK_ORDER | 98 | config 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 @@ | |||
1 | START_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 @@ | |||
1 | ifeq ($(CONFIG_HOST_2G_2G), y) | ||
2 | START_ADDR = 0x80000000 | ||
3 | else | ||
4 | START_ADDR = 0xc0000000 | ||
5 | endif | ||
6 | ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__ | ||
7 | |||
8 | # The arch is ppc, but the elf32 name is powerpc | ||
9 | ELF_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 | */ |
35 | enum fixed_addresses { | 35 | enum 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 | ||
99 | extern struct cpuinfo_um boot_cpu_data; | 99 | extern struct cpuinfo_um boot_cpu_data; |
100 | 100 | ||
101 | #define my_cpu_data cpu_data[smp_processor_id()] | ||
102 | |||
103 | #ifdef CONFIG_SMP | ||
104 | extern 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) |
113 | extern unsigned long get_wchan(struct task_struct *p); | 105 | extern 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) | ||
14 | extern int hard_smp_processor_id(void); | ||
15 | #define NO_PROC_ID -1 | ||
16 | |||
17 | extern int ncpus; | ||
18 | |||
19 | |||
20 | static inline void smp_cpus_done(unsigned int maxcpus) | ||
21 | { | ||
22 | } | ||
23 | |||
24 | extern 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; | |||
56 | extern unsigned long host_task_size; | 56 | extern unsigned long host_task_size; |
57 | 57 | ||
58 | extern int linux_main(int argc, char **argv); | 58 | extern int linux_main(int argc, char **argv); |
59 | extern void uml_finishsetup(void); | ||
59 | 60 | ||
60 | struct siginfo; | 61 | struct siginfo; |
61 | extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); | 62 | extern 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 */ |
176 | extern void os_early_checks(void); | 176 | extern void os_early_checks(void); |
177 | extern void can_do_skas(void); | ||
178 | extern void os_check_bugs(void); | 177 | extern void os_check_bugs(void); |
179 | extern void check_host_supports_tls(int *supports_tls, int *tls_min); | 178 | extern void check_host_supports_tls(int *supports_tls, int *tls_min); |
180 | 179 | ||
@@ -187,7 +186,6 @@ extern int os_process_parent(int pid); | |||
187 | extern void os_stop_process(int pid); | 186 | extern void os_stop_process(int pid); |
188 | extern void os_kill_process(int pid, int reap_child); | 187 | extern void os_kill_process(int pid, int reap_child); |
189 | extern void os_kill_ptraced_process(int pid, int reap_child); | 188 | extern void os_kill_ptraced_process(int pid, int reap_child); |
190 | extern long os_ptrace_ldt(long pid, long addr, long data); | ||
191 | 189 | ||
192 | extern int os_getpid(void); | 190 | extern int os_getpid(void); |
193 | extern int os_getpgrp(void); | 191 | extern 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 | |||
14 | struct 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 | |||
23 | struct mm_munmap { | ||
24 | unsigned long addr; | ||
25 | unsigned long len; | ||
26 | }; | ||
27 | |||
28 | struct mm_mprotect { | ||
29 | unsigned long addr; | ||
30 | unsigned long len; | ||
31 | unsigned int prot; | ||
32 | }; | ||
33 | |||
34 | struct 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 | ||
11 | extern int userspace_pid[]; | 11 | extern int userspace_pid[]; |
12 | extern int proc_mm, ptrace_faultinfo, ptrace_ldt; | ||
13 | extern int skas_needs_stub; | ||
14 | 12 | ||
15 | extern int user_thread(unsigned long stack, int flags); | 13 | extern int user_thread(unsigned long stack, int flags); |
16 | extern void new_thread_handler(void); | 14 | extern void new_thread_handler(void); |
17 | extern void handle_syscall(struct uml_pt_regs *regs); | 15 | extern void handle_syscall(struct uml_pt_regs *regs); |
18 | extern int new_mm(unsigned long stack); | ||
19 | extern long execute_syscall_skas(void *r); | 16 | extern long execute_syscall_skas(void *r); |
20 | extern unsigned long current_stub_stack(void); | 17 | extern 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 | ||
13 | obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ | 13 | obj-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 | ||
18 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 18 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
19 | obj-$(CONFIG_GPROF) += gprof_syms.o | 19 | obj-$(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 | |||
7 | static 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 | |||
34 | static struct kmsg_dumper kmsg_dumper = { | ||
35 | .dump = kmsg_dumper_stdout | ||
36 | }; | ||
37 | |||
38 | int __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 */ |
39 | static unsigned long brk_end; | 39 | static unsigned long brk_end; |
40 | 40 | ||
41 | #ifdef CONFIG_HIGHMEM | ||
42 | static 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 | |||
54 | void __init mem_init(void) | 41 | void __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 | ||
131 | pte_t *kmap_pte; | ||
132 | pgprot_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 | |||
138 | static 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 | |||
149 | static 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 | |||
173 | static void __init fixaddr_user_init( void) | 114 | static 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 | ||
58 | extern int __syscall_stub_start; | 58 | extern 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 | */ | ||
60 | void __init setup_physmem(unsigned long start, unsigned long reserve_end, | 80 | void __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 | ||
262 | int 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 | |||
273 | int cpu(void) | 262 | int 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 | ||
15 | void user_enable_single_step(struct task_struct *child) | 12 | void 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 | ||
16 | static void kill_off_processes(void) | 16 | static 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 | ||
42 | void uml_cleanup(void) | 35 | void 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 = ¤t->mm->context; | 63 | from_mm = ¤t->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 | ||
13 | int 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 | |||
32 | extern void start_kernel(void); | 13 | extern void start_kernel(void); |
33 | 14 | ||
34 | static int __init start_kernel_proc(void *unused) | 15 | static 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 | */ | ||
29 | struct cpuinfo_um cpu_data[NR_CPUS]; | ||
30 | |||
31 | /* A statistic, can be a little off */ | ||
32 | int num_reschedules_sent = 0; | ||
33 | |||
34 | /* Not changed after boot */ | ||
35 | struct task_struct *idle_threads[NR_CPUS]; | ||
36 | |||
37 | void smp_send_reschedule(int cpu) | ||
38 | { | ||
39 | os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); | ||
40 | num_reschedules_sent++; | ||
41 | } | ||
42 | |||
43 | void 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 | |||
56 | static cpumask_t smp_commenced_mask = CPU_MASK_NONE; | ||
57 | static cpumask_t cpu_callin_map = CPU_MASK_NONE; | ||
58 | |||
59 | static 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 | |||
84 | static 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 | |||
103 | void 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 | |||
138 | void smp_prepare_boot_cpu(void) | ||
139 | { | ||
140 | set_cpu_online(smp_processor_id(), true); | ||
141 | } | ||
142 | |||
143 | int __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 | |||
151 | int setup_profiling_timer(unsigned int multiplier) | ||
152 | { | ||
153 | printk(KERN_INFO "setup_profiling_timer\n"); | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | void smp_call_function_slave(int cpu); | ||
158 | |||
159 | void 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 | |||
189 | int hard_smp_processor_id(void) | ||
190 | { | ||
191 | return pid_to_processor_id(os_getpid()); | ||
192 | } | ||
193 | |||
194 | static DEFINE_SPINLOCK(call_lock); | ||
195 | static atomic_t scf_started; | ||
196 | static atomic_t scf_finished; | ||
197 | static void (*func)(void *info); | ||
198 | static void *info; | ||
199 | |||
200 | void smp_call_function_slave(int cpu) | ||
201 | { | ||
202 | atomic_inc(&scf_started); | ||
203 | (*func)(info); | ||
204 | atomic_inc(&scf_finished); | ||
205 | } | ||
206 | |||
207 | int 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 | ||
30 | void show_stack(struct task_struct *task, unsigned long *stack) | 30 | void 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 | ||
172 | static 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 | |||
188 | static int __init Usage(char *line, int *add) | 166 | static 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) | |||
234 | static int panic_exit(struct notifier_block *self, unsigned long unused1, | 212 | static 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 | ||
229 | void 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 */ |
251 | unsigned long task_size; | 240 | unsigned long task_size; |
252 | EXPORT_SYMBOL(task_size); | 241 | EXPORT_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) | |||
390 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | 359 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) |
391 | { | 360 | { |
392 | } | 361 | } |
393 | |||
394 | #ifdef CONFIG_SMP | ||
395 | void alternatives_smp_module_add(struct module *mod, char *name, | ||
396 | void *locks, void *locks_end, | ||
397 | void *text, void *text_end) | ||
398 | { | ||
399 | } | ||
400 | |||
401 | void 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 | |||
109 | long 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 | ||
49 | extern int proc_mm; | ||
50 | |||
51 | static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | 48 | static 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, | |||
251 | int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, | 197 | int 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 | ||
26 | int is_skas_winch(int pid, int fd, void *data) | 24 | int is_skas_winch(int pid, int fd, void *data) |
@@ -91,50 +89,33 @@ extern unsigned long current_stub_stack(void); | |||
91 | static void get_skas_faultinfo(int pid, struct faultinfo *fi) | 89 | static 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; | |||
198 | static int userspace_tramp(void *stack) | 179 | static 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 | ®s->faultinfo); | 392 | ®s->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 | */ | ||
579 | int 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 | |||
635 | void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) | 547 | void 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 | ||
729 | void __switch_mm(struct mm_id *mm_idp) | 641 | void __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 | ||
29 | static void ptrace_child(void) | 28 | static 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 */ |
146 | int ptrace_faultinfo; | ||
147 | static int disable_ptrace_faultinfo; | ||
148 | |||
149 | int ptrace_ldt; | ||
150 | static int disable_ptrace_ldt; | ||
151 | |||
152 | int proc_mm; | ||
153 | static int disable_proc_mm; | ||
154 | |||
155 | int have_switch_mm; | ||
156 | static int disable_switch_mm; | ||
157 | |||
158 | int skas_needs_stub; | ||
159 | |||
160 | static 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 | |||
172 | static 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 */ | ||
184 | static int force_sysemu_disabled = 0; | 145 | static int force_sysemu_disabled = 0; |
185 | 146 | ||
186 | static int __init nosysemu_cmd_param(char *str, int* add) | 147 | static 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 | ||
379 | static 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 | |||
391 | static 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 | |||
403 | static 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 | |||
415 | static 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 | |||
439 | static 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 | |||
469 | static 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 | |||
482 | void 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 | |||
494 | int __init parse_iomem(char *str, int *add) | 340 | int __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 @@ | |||
1 | OBJ = built-in.o | ||
2 | |||
3 | OBJS = | ||
4 | |||
5 | all: $(OBJ) | ||
6 | |||
7 | $(OBJ): $(OBJS) | ||
8 | rm -f $@ | ||
9 | $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@ | ||
10 | |||
11 | clean-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 | |||
9 | struct 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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 @@ | |||
1 | OBJ = built-in.o | ||
2 | |||
3 | .S.o: | ||
4 | $(CC) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o | ||
5 | |||
6 | OBJS = ptrace.o sigcontext.o checksum.o miscthings.o misc.o \ | ||
7 | ptrace_user.o sysrq.o | ||
8 | |||
9 | asflags-y := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel | ||
10 | |||
11 | all: $(OBJ) | ||
12 | |||
13 | $(OBJ): $(OBJS) | ||
14 | rm -f $@ | ||
15 | $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@ | ||
16 | |||
17 | ptrace_user.o: ptrace_user.c | ||
18 | $(CC) -D__KERNEL__ $(USER_CFLAGS) $(ccflags-y) -c -o $@ $< | ||
19 | |||
20 | sigcontext.o: sigcontext.c | ||
21 | $(CC) $(USER_CFLAGS) $(ccflags-y) -c -o $@ $< | ||
22 | |||
23 | checksum.S: | ||
24 | rm -f $@ | ||
25 | ln -s $(srctree)/arch/ppc/lib/$@ $@ | ||
26 | |||
27 | mk_defs.c: | ||
28 | rm -f $@ | ||
29 | ln -s $(srctree)/arch/ppc/kernel/$@ $@ | ||
30 | |||
31 | ppc_defs.head: | ||
32 | rm -f $@ | ||
33 | ln -s $(srctree)/arch/ppc/kernel/$@ $@ | ||
34 | |||
35 | ppc_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 | |||
53 | checksum.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 | |||
59 | misc.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 | |||
65 | clean-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 | |||
5 | extern 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 */ | ||
41 | typedef unsigned long elf_greg_t; | ||
42 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
43 | |||
44 | /* Floating point registers */ | ||
45 | typedef double elf_fpreg_t; | ||
46 | typedef 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 | ||
43 | 1: stw r4, 0(r3) | ||
44 | stw r4, 4(r3) | ||
45 | stw r4, 8(r3) | ||
46 | stw r4, 12(r3) | ||
47 | #else | ||
48 | 1: 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 | ||
80 | 11: 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 | ||
91 | 1: | ||
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 | */ | ||
12 | void 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 | |||
4 | int 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 | |||
11 | int 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 | |||
30 | unsigned 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 | |||
38 | int 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 | |||
5 | int 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 | |||
18 | int 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 | ||
17 | struct 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 | |||
36 | struct 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) \ | ||
72 | do { \ | ||
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 | |||
81 | extern 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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 | |||
6 | typedef 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(®s), \ | ||
12 | UM_SYSCALL_ARG2(®s), \ | ||
13 | UM_SYSCALL_ARG3(®s), \ | ||
14 | UM_SYSCALL_ARG4(®s), \ | ||
15 | UM_SYSCALL_ARG5(®s), \ | ||
16 | UM_SYSCALL_ARG6(®s)) | ||
17 | |||
18 | extern syscall_handler_t sys_mincore; | ||
19 | extern syscall_handler_t sys_madvise; | ||
20 | |||
21 | /* old_mmap needs the correct prototype since syscall_kern.c includes | ||
22 | * this file. | ||
23 | */ | ||
24 | int 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 | |||
11 | void 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, ®s->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 | ||
22 | subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o | 22 | subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o |
23 | subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o | 23 | subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o |
24 | subarch-$(CONFIG_HIGHMEM) += ../mm/highmem_32.o | ||
25 | 24 | ||
26 | else | 25 | else |
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 | ||
215 | extern long elf_aux_hwcap; | 215 | extern 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 | ||
16 | extern int modify_ldt(int func, void *ptr, unsigned long bytecount); | 14 | extern 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 != ¤t->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 != ¤t->active_mm->context.id) | ||
85 | __switch_mm(¤t->active_mm->context.id); | ||
86 | } | ||
87 | |||
88 | return res; | ||
89 | } | ||
90 | |||
91 | static 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, ©, 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 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct 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); | |||
66 | extern int access_file(char *path, int r, int w, int x); | 66 | extern int access_file(char *path, int r, int w, int x); |
67 | extern int open_file(char *path, int r, int w, int append); | 67 | extern int open_file(char *path, int r, int w, int append); |
68 | extern void *open_dir(char *path, int *err_out); | 68 | extern void *open_dir(char *path, int *err_out); |
69 | extern char *read_dir(void *stream, unsigned long long *pos, | 69 | extern void seek_dir(void *stream, unsigned long long pos); |
70 | extern 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); |
72 | extern void close_file(void *stream); | 73 | extern 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); |
78 | extern int lseek_file(int fd, long long offset, int whence); | 79 | extern int lseek_file(int fd, long long offset, int whence); |
79 | extern int fsync_file(int fd, int datasync); | 80 | extern int fsync_file(int fd, int datasync); |
80 | extern int file_create(char *name, int ur, int uw, int ux, int gr, | 81 | extern int file_create(char *name, int mode); |
81 | int gw, int gx, int or, int ow, int ox); | ||
82 | extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd); | 82 | extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd); |
83 | extern int make_symlink(const char *from, const char *to); | 83 | extern int make_symlink(const char *from, const char *to); |
84 | extern int unlink_file(const char *file); | 84 | extern 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 | ||
29 | static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) | 30 | static 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 | ||
296 | static int hostfs_file_open(struct inode *ino, struct file *file) | 305 | static 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 | ||
310 | retry: | 318 | retry: |
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 | ||
396 | static int hostfs_writepage(struct page *page, struct writeback_control *wbc) | 407 | static 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) | |||
432 | static int hostfs_readpage(struct file *file, struct page *page) | 442 | static 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 | ||
457 | static int hostfs_write_begin(struct file *file, struct address_space *mapping, | 470 | static 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 | ||
100 | char *read_dir(void *stream, unsigned long long *pos, | 100 | void seek_dir(void *stream, unsigned long long pos) |
101 | { | ||
102 | DIR *dir = stream; | ||
103 | |||
104 | seekdir(dir, pos); | ||
105 | } | ||
106 | |||
107 | char *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 | ||
178 | int file_create(char *name, int ur, int uw, int ux, int gr, | 184 | int 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; |