aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2011-08-18 15:06:39 -0400
committerRichard Weinberger <richard@nod.at>2011-11-02 09:15:05 -0400
commit5c48b108ecbf6505d929e64d50dace13ac2bdf34 (patch)
tree016904f84fbe05aa301c5cdfe712d90f6bb828fe /arch/um/os-Linux
parent7bbe7204e93734fe79d8aac3e08a7cb4624b5004 (diff)
um: take arch/um/sys-x86 to arch/x86/um
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/Makefile2
-rw-r--r--arch/um/os-Linux/sys-x86/Makefile13
-rw-r--r--arch/um/os-Linux/sys-x86/mcontext.c31
-rw-r--r--arch/um/os-Linux/sys-x86/prctl.c12
-rw-r--r--arch/um/os-Linux/sys-x86/registers.c111
-rw-r--r--arch/um/os-Linux/sys-x86/task_size.c150
-rw-r--r--arch/um/os-Linux/sys-x86/tls.c35
7 files changed, 1 insertions, 353 deletions
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 7879e76e998f..015d00057663 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -5,7 +5,7 @@
5 5
6obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ 6obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
7 registers.o sigio.o signal.o start_up.o time.o tty.o \ 7 registers.o sigio.o signal.o start_up.o time.o tty.o \
8 umid.o tls.o user_syms.o util.o drivers/ sys-$(HEADER_ARCH)/ skas/ 8 umid.o tls.o user_syms.o util.o drivers/ skas/
9 9
10obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o 10obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
11 11
diff --git a/arch/um/os-Linux/sys-x86/Makefile b/arch/um/os-Linux/sys-x86/Makefile
deleted file mode 100644
index 253bfb8cb702..000000000000
--- a/arch/um/os-Linux/sys-x86/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
1#
2# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3# Licensed under the GPL
4#
5
6obj-y = registers.o task_size.o mcontext.o
7
8obj-$(CONFIG_X86_32) += tls.o
9obj-$(CONFIG_64BIT) += prctl.o
10
11USER_OBJS := $(obj-y)
12
13include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/sys-x86/mcontext.c b/arch/um/os-Linux/sys-x86/mcontext.c
deleted file mode 100644
index 1d33d72c6284..000000000000
--- a/arch/um/os-Linux/sys-x86/mcontext.c
+++ /dev/null
@@ -1,31 +0,0 @@
1#include <sys/ucontext.h>
2#define __FRAME_OFFSETS
3#include <asm/ptrace.h>
4#include <sysdep/ptrace.h>
5
6void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
7{
8#ifdef __i386__
9#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y]
10#define COPY(X) regs->gp[X] = mc->gregs[REG_##X]
11#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff;
12#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3;
13 COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS);
14 COPY(EDI); COPY(ESI); COPY(EBP);
15 COPY2(UESP, ESP); /* sic */
16 COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX);
17 COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS);
18#else
19#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y]
20#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X]
21 COPY(R8); COPY(R9); COPY(R10); COPY(R11);
22 COPY(R12); COPY(R13); COPY(R14); COPY(R15);
23 COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX);
24 COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP);
25 COPY(RIP);
26 COPY2(EFLAGS, EFL);
27 COPY2(CS, CSGSFS);
28 regs->gp[CS / sizeof(unsigned long)] &= 0xffff;
29 regs->gp[CS / sizeof(unsigned long)] |= 3;
30#endif
31}
diff --git a/arch/um/os-Linux/sys-x86/prctl.c b/arch/um/os-Linux/sys-x86/prctl.c
deleted file mode 100644
index 9d34eddb517f..000000000000
--- a/arch/um/os-Linux/sys-x86/prctl.c
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
3 * Licensed under the GPL
4 */
5
6#include <sys/ptrace.h>
7#include <linux/ptrace.h>
8
9int os_arch_prctl(int pid, int code, unsigned long *addr)
10{
11 return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code);
12}
diff --git a/arch/um/os-Linux/sys-x86/registers.c b/arch/um/os-Linux/sys-x86/registers.c
deleted file mode 100644
index 3a9b6247bbbc..000000000000
--- a/arch/um/os-Linux/sys-x86/registers.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * Copyright (C) 2004 PathScale, Inc
3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL
5 */
6
7#include <errno.h>
8#include <sys/ptrace.h>
9#include <sys/user.h>
10#include "longjmp.h"
11#include "sysdep/ptrace_user.h"
12
13int save_fp_registers(int pid, unsigned long *fp_regs)
14{
15 if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
16 return -errno;
17 return 0;
18}
19
20int restore_fp_registers(int pid, unsigned long *fp_regs)
21{
22 if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
23 return -errno;
24 return 0;
25}
26
27#ifdef __i386__
28int have_fpx_regs = 1;
29int save_fpx_registers(int pid, unsigned long *fp_regs)
30{
31 if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0)
32 return -errno;
33 return 0;
34}
35
36int restore_fpx_registers(int pid, unsigned long *fp_regs)
37{
38 if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
39 return -errno;
40 return 0;
41}
42
43int get_fp_registers(int pid, unsigned long *regs)
44{
45 if (have_fpx_regs)
46 return save_fpx_registers(pid, regs);
47 else
48 return save_fp_registers(pid, regs);
49}
50
51int put_fp_registers(int pid, unsigned long *regs)
52{
53 if (have_fpx_regs)
54 return restore_fpx_registers(pid, regs);
55 else
56 return restore_fp_registers(pid, regs);
57}
58
59void arch_init_registers(int pid)
60{
61 struct user_fpxregs_struct fpx_regs;
62 int err;
63
64 err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
65 if (!err)
66 return;
67
68 if (errno != EIO)
69 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
70 errno);
71
72 have_fpx_regs = 0;
73}
74#else
75
76int get_fp_registers(int pid, unsigned long *regs)
77{
78 return save_fp_registers(pid, regs);
79}
80
81int put_fp_registers(int pid, unsigned long *regs)
82{
83 return restore_fp_registers(pid, regs);
84}
85
86#endif
87
88unsigned long get_thread_reg(int reg, jmp_buf *buf)
89{
90 switch (reg) {
91#ifdef __i386__
92 case EIP:
93 return buf[0]->__eip;
94 case UESP:
95 return buf[0]->__esp;
96 case EBP:
97 return buf[0]->__ebp;
98#else
99 case RIP:
100 return buf[0]->__rip;
101 case RSP:
102 return buf[0]->__rsp;
103 case RBP:
104 return buf[0]->__rbp;
105#endif
106 default:
107 printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
108 reg);
109 return 0;
110 }
111}
diff --git a/arch/um/os-Linux/sys-x86/task_size.c b/arch/um/os-Linux/sys-x86/task_size.c
deleted file mode 100644
index efb16c5c9bcf..000000000000
--- a/arch/um/os-Linux/sys-x86/task_size.c
+++ /dev/null
@@ -1,150 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <sys/mman.h>
5#include "longjmp.h"
6
7#ifdef __i386__
8
9static jmp_buf buf;
10
11static void segfault(int sig)
12{
13 longjmp(buf, 1);
14}
15
16static int page_ok(unsigned long page)
17{
18 unsigned long *address = (unsigned long *) (page << UM_KERN_PAGE_SHIFT);
19 unsigned long n = ~0UL;
20 void *mapped = NULL;
21 int ok = 0;
22
23 /*
24 * First see if the page is readable. If it is, it may still
25 * be a VDSO, so we go on to see if it's writable. If not
26 * then try mapping memory there. If that fails, then we're
27 * still in the kernel area. As a sanity check, we'll fail if
28 * the mmap succeeds, but gives us an address different from
29 * what we wanted.
30 */
31 if (setjmp(buf) == 0)
32 n = *address;
33 else {
34 mapped = mmap(address, UM_KERN_PAGE_SIZE,
35 PROT_READ | PROT_WRITE,
36 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
37 if (mapped == MAP_FAILED)
38 return 0;
39 if (mapped != address)
40 goto out;
41 }
42
43 /*
44 * Now, is it writeable? If so, then we're in user address
45 * space. If not, then try mprotecting it and try the write
46 * again.
47 */
48 if (setjmp(buf) == 0) {
49 *address = n;
50 ok = 1;
51 goto out;
52 } else if (mprotect(address, UM_KERN_PAGE_SIZE,
53 PROT_READ | PROT_WRITE) != 0)
54 goto out;
55
56 if (setjmp(buf) == 0) {
57 *address = n;
58 ok = 1;
59 }
60
61 out:
62 if (mapped != NULL)
63 munmap(mapped, UM_KERN_PAGE_SIZE);
64 return ok;
65}
66
67unsigned long os_get_top_address(void)
68{
69 struct sigaction sa, old;
70 unsigned long bottom = 0;
71 /*
72 * A 32-bit UML on a 64-bit host gets confused about the VDSO at
73 * 0xffffe000. It is mapped, is readable, can be reprotected writeable
74 * and written. However, exec discovers later that it can't be
75 * unmapped. So, just set the highest address to be checked to just
76 * below it. This might waste some address space on 4G/4G 32-bit
77 * hosts, but shouldn't hurt otherwise.
78 */
79 unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
80 unsigned long test, original;
81
82 printf("Locating the bottom of the address space ... ");
83 fflush(stdout);
84
85 /*
86 * We're going to be longjmping out of the signal handler, so
87 * SA_DEFER needs to be set.
88 */
89 sa.sa_handler = segfault;
90 sigemptyset(&sa.sa_mask);
91 sa.sa_flags = SA_NODEFER;
92 if (sigaction(SIGSEGV, &sa, &old)) {
93 perror("os_get_top_address");
94 exit(1);
95 }
96
97 /* Manually scan the address space, bottom-up, until we find
98 * the first valid page (or run out of them).
99 */
100 for (bottom = 0; bottom < top; bottom++) {
101 if (page_ok(bottom))
102 break;
103 }
104
105 /* If we've got this far, we ran out of pages. */
106 if (bottom == top) {
107 fprintf(stderr, "Unable to determine bottom of address "
108 "space.\n");
109 exit(1);
110 }
111
112 printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
113 printf("Locating the top of the address space ... ");
114 fflush(stdout);
115
116 original = bottom;
117
118 /* This could happen with a 4G/4G split */
119 if (page_ok(top))
120 goto out;
121
122 do {
123 test = bottom + (top - bottom) / 2;
124 if (page_ok(test))
125 bottom = test;
126 else
127 top = test;
128 } while (top - bottom > 1);
129
130out:
131 /* Restore the old SIGSEGV handling */
132 if (sigaction(SIGSEGV, &old, NULL)) {
133 perror("os_get_top_address");
134 exit(1);
135 }
136 top <<= UM_KERN_PAGE_SHIFT;
137 printf("0x%x\n", top);
138
139 return top;
140}
141
142#else
143
144unsigned long os_get_top_address(void)
145{
146 /* The old value of CONFIG_TOP_ADDR */
147 return 0x7fc0000000;
148}
149
150#endif
diff --git a/arch/um/os-Linux/sys-x86/tls.c b/arch/um/os-Linux/sys-x86/tls.c
deleted file mode 100644
index 281e83ecce3d..000000000000
--- a/arch/um/os-Linux/sys-x86/tls.c
+++ /dev/null
@@ -1,35 +0,0 @@
1#include <errno.h>
2#include <linux/unistd.h>
3
4#include <sys/syscall.h>
5#include <unistd.h>
6
7#include "sysdep/tls.h"
8
9/* Checks whether host supports TLS, and sets *tls_min according to the value
10 * valid on the host.
11 * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
12void check_host_supports_tls(int *supports_tls, int *tls_min) {
13 /* Values for x86 and x86_64.*/
14 int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64};
15 int i;
16
17 for (i = 0; i < ARRAY_SIZE(val); i++) {
18 user_desc_t info;
19 info.entry_number = val[i];
20
21 if (syscall(__NR_get_thread_area, &info) == 0) {
22 *tls_min = val[i];
23 *supports_tls = 1;
24 return;
25 } else {
26 if (errno == EINVAL)
27 continue;
28 else if (errno == ENOSYS)
29 *supports_tls = 0;
30 return;
31 }
32 }
33
34 *supports_tls = 0;
35}