Blame view

kernel/linux-rt-4.4.41/arch/x86/um/os-Linux/tls.c 1.35 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  #include <errno.h>
  #include <linux/unistd.h>
  
  #include <sys/ptrace.h>
  #include <sys/syscall.h>
  #include <unistd.h>
  
  #include <sysdep/tls.h>
  
  #ifndef PTRACE_GET_THREAD_AREA
  #define PTRACE_GET_THREAD_AREA 25
  #endif
  
  #ifndef PTRACE_SET_THREAD_AREA
  #define PTRACE_SET_THREAD_AREA 26
  #endif
  
  /* 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 (syscall(__NR_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;
  }
  
  int os_set_thread_area(user_desc_t *info, int pid)
  {
  	int ret;
  
  	ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number,
  		     (unsigned long) info);
  	if (ret < 0)
  		ret = -errno;
  	return ret;
  }
  
  int os_get_thread_area(user_desc_t *info, int pid)
  {
  	int ret;
  
  	ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number,
  		     (unsigned long) info);
  	if (ret < 0)
  		ret = -errno;
  	return ret;
  }