diff options
Diffstat (limited to 'arch/um/sys-i386/bugs.c')
-rw-r--r-- | arch/um/sys-i386/bugs.c | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index 25c1165d8093..806895d73bcc 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c | |||
@@ -1,18 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <unistd.h> | ||
7 | #include <errno.h> | 6 | #include <errno.h> |
7 | #include <signal.h> | ||
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <sys/signal.h> | 9 | #include "kern_constants.h" |
10 | #include <asm/ldt.h> | ||
11 | #include "kern_util.h" | ||
12 | #include "user.h" | ||
13 | #include "sysdep/ptrace.h" | ||
14 | #include "task.h" | ||
15 | #include "os.h" | 10 | #include "os.h" |
11 | #include "task.h" | ||
12 | #include "user.h" | ||
16 | 13 | ||
17 | #define MAXTOKEN 64 | 14 | #define MAXTOKEN 64 |
18 | 15 | ||
@@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop) | |||
30 | do { | 27 | do { |
31 | n = os_read_file(fd, ptr, sizeof(*ptr)); | 28 | n = os_read_file(fd, ptr, sizeof(*ptr)); |
32 | c = *ptr++; | 29 | c = *ptr++; |
33 | if(n != sizeof(*ptr)){ | 30 | if (n != sizeof(*ptr)) { |
34 | if(n == 0) | 31 | if (n == 0) |
35 | return 0; | 32 | return 0; |
36 | printk("Reading /proc/cpuinfo failed, err = %d\n", -n); | 33 | printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, " |
37 | if(n < 0) | 34 | "err = %d\n", -n); |
35 | if (n < 0) | ||
38 | return n; | 36 | return n; |
39 | else return -EIO; | 37 | else return -EIO; |
40 | } | 38 | } |
41 | } while((c != '\n') && (c != stop) && (ptr < end)); | 39 | } while ((c != '\n') && (c != stop) && (ptr < end)); |
42 | 40 | ||
43 | if(ptr == end){ | 41 | if (ptr == end) { |
44 | printk("Failed to find '%c' in /proc/cpuinfo\n", stop); | 42 | printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n", |
43 | stop); | ||
45 | return -1; | 44 | return -1; |
46 | } | 45 | } |
47 | *(ptr - 1) = '\0'; | 46 | *(ptr - 1) = '\0'; |
@@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) | |||
54 | char c; | 53 | char c; |
55 | 54 | ||
56 | scratch[len - 1] = '\0'; | 55 | scratch[len - 1] = '\0'; |
57 | while(1){ | 56 | while (1) { |
58 | c = token(fd, scratch, len - 1, ':'); | 57 | c = token(fd, scratch, len - 1, ':'); |
59 | if(c <= 0) | 58 | if (c <= 0) |
60 | return 0; | 59 | return 0; |
61 | else if(c != ':'){ | 60 | else if (c != ':') { |
62 | printk("Failed to find ':' in /proc/cpuinfo\n"); | 61 | printk(UM_KERN_ERR "Failed to find ':' in " |
62 | "/proc/cpuinfo\n"); | ||
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | 65 | ||
66 | if(!strncmp(scratch, key, strlen(key))) | 66 | if (!strncmp(scratch, key, strlen(key))) |
67 | return 1; | 67 | return 1; |
68 | 68 | ||
69 | do { | 69 | do { |
70 | n = os_read_file(fd, &c, sizeof(c)); | 70 | n = os_read_file(fd, &c, sizeof(c)); |
71 | if(n != sizeof(c)){ | 71 | if (n != sizeof(c)) { |
72 | printk("Failed to find newline in " | 72 | printk(UM_KERN_ERR "Failed to find newline in " |
73 | "/proc/cpuinfo, err = %d\n", -n); | 73 | "/proc/cpuinfo, err = %d\n", -n); |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | } while(c != '\n'); | 76 | } while (c != '\n'); |
77 | } | 77 | } |
78 | return 0; | 78 | return 0; |
79 | } | 79 | } |
@@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it) | |||
83 | char buf[MAXTOKEN], c; | 83 | char buf[MAXTOKEN], c; |
84 | int fd, len = ARRAY_SIZE(buf); | 84 | int fd, len = ARRAY_SIZE(buf); |
85 | 85 | ||
86 | printk("Checking for host processor %s support...", feature); | 86 | printk(UM_KERN_INFO "Checking for host processor %s support...", |
87 | feature); | ||
87 | fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); | 88 | fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); |
88 | if(fd < 0){ | 89 | if (fd < 0) { |
89 | printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); | 90 | printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n", |
91 | -fd); | ||
90 | return 0; | 92 | return 0; |
91 | } | 93 | } |
92 | 94 | ||
93 | *have_it = 0; | 95 | *have_it = 0; |
94 | if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) | 96 | if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) |
95 | goto out; | 97 | goto out; |
96 | 98 | ||
97 | c = token(fd, buf, len - 1, ' '); | 99 | c = token(fd, buf, len - 1, ' '); |
98 | if(c < 0) | 100 | if (c < 0) |
99 | goto out; | 101 | goto out; |
100 | else if(c != ' '){ | 102 | else if (c != ' ') { |
101 | printk("Failed to find ' ' in /proc/cpuinfo\n"); | 103 | printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n"); |
102 | goto out; | 104 | goto out; |
103 | } | 105 | } |
104 | 106 | ||
105 | while(1){ | 107 | while (1) { |
106 | c = token(fd, buf, len - 1, ' '); | 108 | c = token(fd, buf, len - 1, ' '); |
107 | if(c < 0) | 109 | if (c < 0) |
108 | goto out; | 110 | goto out; |
109 | else if(c == '\n') break; | 111 | else if (c == '\n') |
112 | break; | ||
110 | 113 | ||
111 | if(!strcmp(buf, feature)){ | 114 | if (!strcmp(buf, feature)) { |
112 | *have_it = 1; | 115 | *have_it = 1; |
113 | goto out; | 116 | goto out; |
114 | } | 117 | } |
115 | } | 118 | } |
116 | out: | 119 | out: |
117 | if(*have_it == 0) | 120 | if (*have_it == 0) |
118 | printk("No\n"); | 121 | printk("No\n"); |
119 | else if(*have_it == 1) | 122 | else if (*have_it == 1) |
120 | printk("Yes\n"); | 123 | printk("Yes\n"); |
121 | os_close_file(fd); | 124 | os_close_file(fd); |
122 | return 1; | 125 | return 1; |
123 | } | 126 | } |
124 | 127 | ||
125 | #if 0 /* This doesn't work in tt mode, plus it's causing compilation problems | 128 | #if 0 /* |
129 | * This doesn't work in tt mode, plus it's causing compilation problems | ||
126 | * for some people. | 130 | * for some people. |
127 | */ | 131 | */ |
128 | static void disable_lcall(void) | 132 | static void disable_lcall(void) |
@@ -135,8 +139,9 @@ static void disable_lcall(void) | |||
135 | ldt.base_addr = 0; | 139 | ldt.base_addr = 0; |
136 | ldt.limit = 0; | 140 | ldt.limit = 0; |
137 | err = modify_ldt(1, &ldt, sizeof(ldt)); | 141 | err = modify_ldt(1, &ldt, sizeof(ldt)); |
138 | if(err) | 142 | if (err) |
139 | printk("Failed to disable lcall7 - errno = %d\n", errno); | 143 | printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n", |
144 | errno); | ||
140 | } | 145 | } |
141 | #endif | 146 | #endif |
142 | 147 | ||
@@ -151,14 +156,14 @@ void arch_check_bugs(void) | |||
151 | { | 156 | { |
152 | int have_it; | 157 | int have_it; |
153 | 158 | ||
154 | if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ | 159 | if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) { |
155 | printk("/proc/cpuinfo not available - skipping CPU capability " | 160 | printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU " |
156 | "checks\n"); | 161 | "capability checks\n"); |
157 | return; | 162 | return; |
158 | } | 163 | } |
159 | if(check_cpu_flag("cmov", &have_it)) | 164 | if (check_cpu_flag("cmov", &have_it)) |
160 | host_has_cmov = have_it; | 165 | host_has_cmov = have_it; |
161 | if(check_cpu_flag("xmm", &have_it)) | 166 | if (check_cpu_flag("xmm", &have_it)) |
162 | host_has_xmm = have_it; | 167 | host_has_xmm = have_it; |
163 | } | 168 | } |
164 | 169 | ||
@@ -166,25 +171,26 @@ int arch_handle_signal(int sig, struct uml_pt_regs *regs) | |||
166 | { | 171 | { |
167 | unsigned char tmp[2]; | 172 | unsigned char tmp[2]; |
168 | 173 | ||
169 | /* This is testing for a cmov (0x0f 0x4x) instruction causing a | 174 | /* |
175 | * This is testing for a cmov (0x0f 0x4x) instruction causing a | ||
170 | * SIGILL in init. | 176 | * SIGILL in init. |
171 | */ | 177 | */ |
172 | if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) | 178 | if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) |
173 | return 0; | 179 | return 0; |
174 | 180 | ||
175 | if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) | 181 | if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) |
176 | panic("SIGILL in init, could not read instructions!\n"); | 182 | panic("SIGILL in init, could not read instructions!\n"); |
177 | if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) | 183 | if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) |
178 | return 0; | 184 | return 0; |
179 | 185 | ||
180 | if(host_has_cmov == 0) | 186 | if (host_has_cmov == 0) |
181 | panic("SIGILL caused by cmov, which this processor doesn't " | 187 | panic("SIGILL caused by cmov, which this processor doesn't " |
182 | "implement, boot a filesystem compiled for older " | 188 | "implement, boot a filesystem compiled for older " |
183 | "processors"); | 189 | "processors"); |
184 | else if(host_has_cmov == 1) | 190 | else if (host_has_cmov == 1) |
185 | panic("SIGILL caused by cmov, which this processor claims to " | 191 | panic("SIGILL caused by cmov, which this processor claims to " |
186 | "implement"); | 192 | "implement"); |
187 | else if(host_has_cmov == -1) | 193 | else if (host_has_cmov == -1) |
188 | panic("SIGILL caused by cmov, couldn't tell if this processor " | 194 | panic("SIGILL caused by cmov, couldn't tell if this processor " |
189 | "implements it, boot a filesystem compiled for older " | 195 | "implements it, boot a filesystem compiled for older " |
190 | "processors"); | 196 | "processors"); |