Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
x86
um
bugs_32.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3
* Licensed under the GPL
4
*/
5
6
#include <signal.h>
7
#include <
kern_util.h
>
8
#include <
longjmp.h
>
9
#include <sysdep/ptrace.h>
10
#include <generated/asm-offsets.h>
11
12
/* Set during early boot */
13
static
int
host_has_cmov
= 1;
14
static
jmp_buf
cmov_test_return;
15
16
static
void
cmov_sigill_test_handler(
int
sig
)
17
{
18
host_has_cmov
= 0;
19
longjmp
(cmov_test_return, 1);
20
}
21
22
void
arch_check_bugs
(
void
)
23
{
24
struct
sigaction
old, new;
25
26
printk
(
UM_KERN_INFO
"Checking for host processor cmov support..."
);
27
new
.sa_handler = cmov_sigill_test_handler;
28
29
/* Make sure that SIGILL is enabled after the handler longjmps back */
30
new
.sa_flags =
SA_NODEFER
;
31
sigemptyset(&
new
.
sa_mask
);
32
sigaction
(
SIGILL
, &
new
, &old);
33
34
if
(
setjmp
(cmov_test_return) == 0) {
35
unsigned
long
foo
= 0;
36
__asm__
__volatile__(
"cmovz %0, %1"
:
"=r"
(foo) :
"0"
(foo));
37
printk
(
UM_KERN_CONT
"Yes\n"
);
38
}
else
39
printk
(
UM_KERN_CONT
"No\n"
);
40
41
sigaction
(
SIGILL
, &old, &
new
);
42
}
43
44
void
arch_examine_signal
(
int
sig
,
struct
uml_pt_regs
*
regs
)
45
{
46
unsigned
char
tmp
[2];
47
48
/*
49
* This is testing for a cmov (0x0f 0x4x) instruction causing a
50
* SIGILL in init.
51
*/
52
if
((sig !=
SIGILL
) || (
get_current_pid
() != 1))
53
return
;
54
55
if
(
copy_from_user_proc
(tmp, (
void
*)
UPT_IP
(regs), 2)) {
56
printk
(
UM_KERN_ERR
"SIGILL in init, could not read "
57
"instructions!\n"
);
58
return
;
59
}
60
61
if
((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
62
return
;
63
64
if
(
host_has_cmov
== 0)
65
printk
(
UM_KERN_ERR
"SIGILL caused by cmov, which this "
66
"processor doesn't implement. Boot a filesystem "
67
"compiled for older processors"
);
68
else
if
(
host_has_cmov
== 1)
69
printk
(
UM_KERN_ERR
"SIGILL caused by cmov, which this "
70
"processor claims to implement"
);
71
else
72
printk
(
UM_KERN_ERR
"Bad value for host_has_cmov (%d)"
,
73
host_has_cmov
);
74
}
Generated on Thu Jan 10 2013 13:21:51 for Linux Kernel by
1.8.2