edea138584
Tidy kern_util.h. It turns out that most of the function declarations aren't used, so they can go away. os.h no longer includes kern_util.h, so files which got it through os.h now need to include it directly. A number of other files never needed it, so these includes are deleted. The structure which was used to pass signal handlers from the kernel side to the userspace side is gone. Instead, the handlers are declared here, and used directly from libc code. This allows arch/um/os-Linux/trap.c to be deleted, with its remnants being moved to arch/um/os-Linux/skas/trap.c. arch/um/os-Linux/tty.c had its inclusions changed, and it needed some style attention, so it got tidied. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
76 lines
1.8 KiB
C
76 lines
1.8 KiB
C
/*
|
|
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
|
* Licensed under the GPL
|
|
*/
|
|
|
|
#include <signal.h>
|
|
#include "kern_constants.h"
|
|
#include "kern_util.h"
|
|
#include "longjmp.h"
|
|
#include "task.h"
|
|
#include "user.h"
|
|
#include "sysdep/ptrace.h"
|
|
|
|
/* Set during early boot */
|
|
int host_has_cmov = 1;
|
|
static jmp_buf cmov_test_return;
|
|
|
|
static void cmov_sigill_test_handler(int sig)
|
|
{
|
|
host_has_cmov = 0;
|
|
longjmp(cmov_test_return, 1);
|
|
}
|
|
|
|
void arch_check_bugs(void)
|
|
{
|
|
struct sigaction old, new;
|
|
|
|
printk(UM_KERN_INFO "Checking for host processor cmov support...");
|
|
new.sa_handler = cmov_sigill_test_handler;
|
|
|
|
/* Make sure that SIGILL is enabled after the handler longjmps back */
|
|
new.sa_flags = SA_NODEFER;
|
|
sigemptyset(&new.sa_mask);
|
|
sigaction(SIGILL, &new, &old);
|
|
|
|
if (setjmp(cmov_test_return) == 0) {
|
|
unsigned long foo = 0;
|
|
__asm__ __volatile__("cmovz %0, %1" : "=r" (foo) : "0" (foo));
|
|
printk(UM_KERN_CONT "Yes\n");
|
|
} else
|
|
printk(UM_KERN_CONT "No\n");
|
|
|
|
sigaction(SIGILL, &old, &new);
|
|
}
|
|
|
|
void arch_examine_signal(int sig, struct uml_pt_regs *regs)
|
|
{
|
|
unsigned char tmp[2];
|
|
|
|
/*
|
|
* This is testing for a cmov (0x0f 0x4x) instruction causing a
|
|
* SIGILL in init.
|
|
*/
|
|
if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
|
|
return;
|
|
|
|
if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) {
|
|
printk(UM_KERN_ERR "SIGILL in init, could not read "
|
|
"instructions!\n");
|
|
return;
|
|
}
|
|
|
|
if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
|
|
return;
|
|
|
|
if (host_has_cmov == 0)
|
|
printk(UM_KERN_ERR "SIGILL caused by cmov, which this "
|
|
"processor doesn't implement. Boot a filesystem "
|
|
"compiled for older processors");
|
|
else if (host_has_cmov == 1)
|
|
printk(UM_KERN_ERR "SIGILL caused by cmov, which this "
|
|
"processor claims to implement");
|
|
else
|
|
printk(UM_KERN_ERR "Bad value for host_has_cmov (%d)",
|
|
host_has_cmov);
|
|
}
|