diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/Makefile | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/tls.c | 77 |
2 files changed, 79 insertions, 2 deletions
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 9e0788cf3ae..f4bfc4c7cca 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -4,7 +4,7 @@ # obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ - signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o \ + signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o tls.o \ user_syms.o util.o drivers/ sys-$(SUBARCH)/ obj-$(CONFIG_MODE_SKAS) += skas/ @@ -12,7 +12,7 @@ obj-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ - process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o \ + process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o tls.o \ uaccess.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c new file mode 100644 index 00000000000..63dfcf70937 --- /dev/null +++ b/arch/um/os-Linux/tls.c @@ -0,0 +1,77 @@ +#include <errno.h> +#include <sys/ptrace.h> +#include <asm/ldt.h> +#include "uml-config.h" + +/* TLS support - we basically rely on the host's one.*/ + +/* In TT mode, this should be called only by the tracing thread, and makes sense + * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally. + * + */ + +#ifndef PTRACE_GET_THREAD_AREA +#define PTRACE_GET_THREAD_AREA 25 +#endif + +#ifndef PTRACE_SET_THREAD_AREA +#define PTRACE_SET_THREAD_AREA 26 +#endif + +int os_set_thread_area(void *data, int pid) +{ + struct user_desc *info = data; + int ret; + + ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, + (unsigned long) info); + if (ret < 0) + ret = -errno; + return ret; +} + +#ifdef UML_CONFIG_MODE_SKAS + +int os_get_thread_area(void *data, int pid) +{ + struct user_desc *info = data; + int ret; + + ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, + (unsigned long) info); + if (ret < 0) + ret = -errno; + return ret; +} + +#endif + +#ifdef UML_CONFIG_MODE_TT +#include "linux/unistd.h" + +_syscall1(int, get_thread_area, struct user_desc *, u_info); +_syscall1(int, set_thread_area, struct user_desc *, u_info); + +int do_set_thread_area_tt(struct user_desc *info) +{ + int ret; + + ret = set_thread_area(info); + if (ret < 0) { + ret = -errno; + } + return ret; +} + +int do_get_thread_area_tt(struct user_desc *info) +{ + int ret; + + ret = get_thread_area(info); + if (ret < 0) { + ret = -errno; + } + return ret; +} + +#endif /* UML_CONFIG_MODE_TT */ |