From 3feb88562d149f078319e5a1b2f7acaa10251a5c Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Fri, 31 Mar 2006 02:30:25 -0800 Subject: [PATCH] uml: check for differences in host support If running on a host not supporting TLS (for instance 2.4) we should report that cleanly to the user, instead of printing not comprehensible "error 5" for that. Additionally, i386 and x86_64 support different ranges for user_desc->entry_number, and we must account for that; we couldn't pass ourselves -1 because we need to override previously existing TLS descriptors which glibc has possibly set, so test at startup the range to use. x86 and x86_64 existing ranges are hardcoded. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Acked-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/sys-i386/Makefile | 2 +- arch/um/os-Linux/sys-i386/tls.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 arch/um/os-Linux/sys-i386/tls.c (limited to 'arch/um/os-Linux/sys-i386') diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile index 340ef26f594..b3213613c41 100644 --- a/arch/um/os-Linux/sys-i386/Makefile +++ b/arch/um/os-Linux/sys-i386/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-$(CONFIG_MODE_SKAS) = registers.o +obj-$(CONFIG_MODE_SKAS) = registers.o tls.o USER_OBJS := $(obj-y) diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c new file mode 100644 index 00000000000..ba21f0e04a2 --- /dev/null +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -0,0 +1,33 @@ +#include +#include "sysdep/tls.h" +#include "user_util.h" + +static _syscall1(int, get_thread_area, user_desc_t *, u_info); + +/* Checks whether host supports TLS, and sets *tls_min according to the value + * valid on the host. + * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ +void check_host_supports_tls(int *supports_tls, int *tls_min) { + /* Values for x86 and x86_64.*/ + int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; + int i; + + for (i = 0; i < ARRAY_SIZE(val); i++) { + user_desc_t info; + info.entry_number = val[i]; + + if (get_thread_area(&info) == 0) { + *tls_min = val[i]; + *supports_tls = 1; + return; + } else { + if (errno == EINVAL) + continue; + else if (errno == ENOSYS) + *supports_tls = 0; + return; + } + } + + *supports_tls = 0; +} -- cgit v1.2.3