diff options
Diffstat (limited to 'arch/um/sys-i386/bugs.c')
-rw-r--r-- | arch/um/sys-i386/bugs.c | 78 |
1 files changed, 24 insertions, 54 deletions
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c index f1bcd399ac90..0393e44813e7 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/um/sys-i386/bugs.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
@@ -13,7 +13,6 @@ | |||
13 | #include "sysdep/ptrace.h" | 13 | #include "sysdep/ptrace.h" |
14 | #include "task.h" | 14 | #include "task.h" |
15 | #include "os.h" | 15 | #include "os.h" |
16 | #include "user_util.h" | ||
17 | 16 | ||
18 | #define MAXTOKEN 64 | 17 | #define MAXTOKEN 64 |
19 | 18 | ||
@@ -32,21 +31,21 @@ static char token(int fd, char *buf, int len, char stop) | |||
32 | n = os_read_file(fd, ptr, sizeof(*ptr)); | 31 | n = os_read_file(fd, ptr, sizeof(*ptr)); |
33 | c = *ptr++; | 32 | c = *ptr++; |
34 | if(n != sizeof(*ptr)){ | 33 | if(n != sizeof(*ptr)){ |
35 | if(n == 0) return(0); | 34 | if(n == 0) |
35 | return 0; | ||
36 | printk("Reading /proc/cpuinfo failed, err = %d\n", -n); | 36 | printk("Reading /proc/cpuinfo failed, err = %d\n", -n); |
37 | if(n < 0) | 37 | if(n < 0) |
38 | return(n); | 38 | return n; |
39 | else | 39 | else return -EIO; |
40 | return(-EIO); | ||
41 | } | 40 | } |
42 | } while((c != '\n') && (c != stop) && (ptr < end)); | 41 | } while((c != '\n') && (c != stop) && (ptr < end)); |
43 | 42 | ||
44 | if(ptr == end){ | 43 | if(ptr == end){ |
45 | printk("Failed to find '%c' in /proc/cpuinfo\n", stop); | 44 | printk("Failed to find '%c' in /proc/cpuinfo\n", stop); |
46 | return(-1); | 45 | return -1; |
47 | } | 46 | } |
48 | *(ptr - 1) = '\0'; | 47 | *(ptr - 1) = '\0'; |
49 | return(c); | 48 | return c; |
50 | } | 49 | } |
51 | 50 | ||
52 | static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) | 51 | static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) |
@@ -58,48 +57,25 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) | |||
58 | while(1){ | 57 | while(1){ |
59 | c = token(fd, scratch, len - 1, ':'); | 58 | c = token(fd, scratch, len - 1, ':'); |
60 | if(c <= 0) | 59 | if(c <= 0) |
61 | return(0); | 60 | return 0; |
62 | else if(c != ':'){ | 61 | else if(c != ':'){ |
63 | printk("Failed to find ':' in /proc/cpuinfo\n"); | 62 | printk("Failed to find ':' in /proc/cpuinfo\n"); |
64 | return(0); | 63 | return 0; |
65 | } | 64 | } |
66 | 65 | ||
67 | if(!strncmp(scratch, key, strlen(key))) | 66 | if(!strncmp(scratch, key, strlen(key))) |
68 | return(1); | 67 | return 1; |
69 | 68 | ||
70 | do { | 69 | do { |
71 | n = os_read_file(fd, &c, sizeof(c)); | 70 | n = os_read_file(fd, &c, sizeof(c)); |
72 | if(n != sizeof(c)){ | 71 | if(n != sizeof(c)){ |
73 | printk("Failed to find newline in " | 72 | printk("Failed to find newline in " |
74 | "/proc/cpuinfo, err = %d\n", -n); | 73 | "/proc/cpuinfo, err = %d\n", -n); |
75 | return(0); | 74 | return 0; |
76 | } | 75 | } |
77 | } while(c != '\n'); | 76 | } while(c != '\n'); |
78 | } | 77 | } |
79 | return(0); | 78 | return 0; |
80 | } | ||
81 | |||
82 | int cpu_feature(char *what, char *buf, int len) | ||
83 | { | ||
84 | int fd, ret = 0; | ||
85 | |||
86 | fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); | ||
87 | if(fd < 0){ | ||
88 | printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); | ||
89 | return(0); | ||
90 | } | ||
91 | |||
92 | if(!find_cpuinfo_line(fd, what, buf, len)){ | ||
93 | printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); | ||
94 | goto out_close; | ||
95 | } | ||
96 | |||
97 | token(fd, buf, len, '\n'); | ||
98 | ret = 1; | ||
99 | |||
100 | out_close: | ||
101 | os_close_file(fd); | ||
102 | return(ret); | ||
103 | } | 79 | } |
104 | 80 | ||
105 | static int check_cpu_flag(char *feature, int *have_it) | 81 | static int check_cpu_flag(char *feature, int *have_it) |
@@ -119,7 +95,8 @@ static int check_cpu_flag(char *feature, int *have_it) | |||
119 | goto out; | 95 | goto out; |
120 | 96 | ||
121 | c = token(fd, buf, len - 1, ' '); | 97 | c = token(fd, buf, len - 1, ' '); |
122 | if(c < 0) goto out; | 98 | if(c < 0) |
99 | goto out; | ||
123 | else if(c != ' '){ | 100 | else if(c != ' '){ |
124 | printk("Failed to find ' ' in /proc/cpuinfo\n"); | 101 | printk("Failed to find ' ' in /proc/cpuinfo\n"); |
125 | goto out; | 102 | goto out; |
@@ -127,7 +104,8 @@ static int check_cpu_flag(char *feature, int *have_it) | |||
127 | 104 | ||
128 | while(1){ | 105 | while(1){ |
129 | c = token(fd, buf, len - 1, ' '); | 106 | c = token(fd, buf, len - 1, ' '); |
130 | if(c < 0) goto out; | 107 | if(c < 0) |
108 | goto out; | ||
131 | else if(c == '\n') break; | 109 | else if(c == '\n') break; |
132 | 110 | ||
133 | if(!strcmp(buf, feature)){ | 111 | if(!strcmp(buf, feature)){ |
@@ -136,8 +114,10 @@ static int check_cpu_flag(char *feature, int *have_it) | |||
136 | } | 114 | } |
137 | } | 115 | } |
138 | out: | 116 | out: |
139 | if(*have_it == 0) printk("No\n"); | 117 | if(*have_it == 0) |
140 | else if(*have_it == 1) printk("Yes\n"); | 118 | printk("No\n"); |
119 | else if(*have_it == 1) | ||
120 | printk("Yes\n"); | ||
141 | os_close_file(fd); | 121 | os_close_file(fd); |
142 | return 1; | 122 | return 1; |
143 | } | 123 | } |
@@ -189,12 +169,13 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) | |||
189 | /* This is testing for a cmov (0x0f 0x4x) instruction causing a | 169 | /* This is testing for a cmov (0x0f 0x4x) instruction causing a |
190 | * SIGILL in init. | 170 | * SIGILL in init. |
191 | */ | 171 | */ |
192 | if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0); | 172 | if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) |
173 | return 0; | ||
193 | 174 | ||
194 | if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) | 175 | if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) |
195 | panic("SIGILL in init, could not read instructions!\n"); | 176 | panic("SIGILL in init, could not read instructions!\n"); |
196 | if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) | 177 | if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) |
197 | return(0); | 178 | return 0; |
198 | 179 | ||
199 | if(host_has_cmov == 0) | 180 | if(host_has_cmov == 0) |
200 | panic("SIGILL caused by cmov, which this processor doesn't " | 181 | panic("SIGILL caused by cmov, which this processor doesn't " |
@@ -208,16 +189,5 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) | |||
208 | "implements it, boot a filesystem compiled for older " | 189 | "implements it, boot a filesystem compiled for older " |
209 | "processors"); | 190 | "processors"); |
210 | else panic("Bad value for host_has_cmov (%d)", host_has_cmov); | 191 | else panic("Bad value for host_has_cmov (%d)", host_has_cmov); |
211 | return(0); | 192 | return 0; |
212 | } | 193 | } |
213 | |||
214 | /* | ||
215 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
216 | * Emacs will notice this stuff at the end of the file and automatically | ||
217 | * adjust the settings for this buffer only. This must remain at the end | ||
218 | * of the file. | ||
219 | * --------------------------------------------------------------------------- | ||
220 | * Local variables: | ||
221 | * c-file-style: "linux" | ||
222 | * End: | ||
223 | */ | ||