Commit a0b2fc70 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://are.twiddle.net/axp-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents ff143d5c e60ef815
......@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/gfp.h>
#include <linux/string.h>
#include <linux/elf.h>
#include <asm/cpufeature.h>
#include <asm/msr.h>
......@@ -52,11 +53,47 @@ void enable_sep_cpu(void *info)
static int __init sysenter_setup(void)
{
static const char int80[] = {
static const char __initdata int80[] = {
0xcd, 0x80, /* int $0x80 */
0xc3 /* ret */
};
static const char sysent[] = {
/* Unwind information for the int80 code. Keep track of
where the return address is stored. */
static const char __initdata int80_eh_frame[] = {
/* First the Common Information Entry (CIE): */
0x14, 0x00, 0x00, 0x00, /* Length of the CIE */
0x00, 0x00, 0x00, 0x00, /* CIE Identifier Tag */
0x01, /* CIE Version */
'z', 'R', 0x00, /* CIE Augmentation */
0x01, /* CIE Code Alignment Factor */
0x7c, /* CIE Data Alignment Factor */
0x08, /* CIE RA Column */
0x01, /* Augmentation size */
0x1b, /* FDE Encoding (pcrel sdata4) */
0x0c, /* DW_CFA_def_cfa */
0x04,
0x04,
0x88, /* DW_CFA_offset, column 0x8 */
0x01,
0x00, /* padding */
0x00,
/* Now the FDE which contains the instructions for the frame. */
0x0a, 0x00, 0x00, 0x00, /* FDE Length */
0x1c, 0x00, 0x00, 0x00, /* FDE CIE offset */
/* The PC-relative offset to the beginning of the code this
FDE covers. The computation below assumes that the offset
can be represented in one byte. Change if this is not true
anymore. The offset from the beginning of the .eh_frame
is represented by EH_FRAME_OFFSET. The word with the offset
starts at byte 0x20 of the .eh_frame. */
0x100 - (EH_FRAME_OFFSET + 0x20),
0xff, 0xff, 0xff, /* FDE initial location */
3, /* FDE address range */
0x00 /* Augmentation size */
/* The code does not change the stack pointer. We need not
record any operations. */
};
static const char __initdata sysent[] = {
0x51, /* push %ecx */
0x52, /* push %edx */
0x55, /* push %ebp */
......@@ -76,13 +113,71 @@ static int __init sysenter_setup(void)
0x59, /* pop %ecx */
0xc3 /* ret */
};
static const char sigreturn[] = {
/* Unwind information for the sysenter code. Keep track of
where the return address is stored. */
static const char __initdata sysent_eh_frame[] = {
/* First the Common Information Entry (CIE): */
0x14, 0x00, 0x00, 0x00, /* Length of the CIE */
0x00, 0x00, 0x00, 0x00, /* CIE Identifier Tag */
0x01, /* CIE Version */
'z', 'R', 0x00, /* CIE Augmentation */
0x01, /* CIE Code Alignment Factor */
0x7c, /* CIE Data Alignment Factor */
0x08, /* CIE RA Column */
0x01, /* Augmentation size */
0x1b, /* FDE Encoding (pcrel sdata4) */
0x0c, /* DW_CFA_def_cfa */
0x04,
0x04,
0x88, /* DW_CFA_offset, column 0x8 */
0x01,
0x00, /* padding */
0x00,
/* Now the FDE which contains the instructions for the frame. */
0x22, 0x00, 0x00, 0x00, /* FDE Length */
0x1c, 0x00, 0x00, 0x00, /* FDE CIE offset */
/* The PC-relative offset to the beginning of the code this
FDE covers. The computation below assumes that the offset
can be represented in one byte. Change if this is not true
anymore. The offset from the beginning of the .eh_frame
is represented by EH_FRAME_OFFSET. The word with the offset
starts at byte 0x20 of the .eh_frame. */
0x100 - (EH_FRAME_OFFSET + 0x20),
0xff, 0xff, 0xff, /* FDE initial location */
0x14, 0x00, 0x00, 0x00, /* FDE address range */
0x00, /* Augmentation size */
/* What follows are the instructions for the table generation.
We have to record all changes of the stack pointer and
callee-saved registers. */
0x41, /* DW_CFA_advance_loc+1, push %ecx */
0x0e, /* DW_CFA_def_cfa_offset */
0x08, /* RA at offset 8 now */
0x41, /* DW_CFA_advance_loc+1, push %edx */
0x0e, /* DW_CFA_def_cfa_offset */
0x0c, /* RA at offset 12 now */
0x41, /* DW_CFA_advance_loc+1, push %ebp */
0x0e, /* DW_CFA_def_cfa_offset */
0x10, /* RA at offset 16 now */
0x85, 0x04, /* DW_CFA_offset %ebp -16 */
/* Finally the epilogue. */
0x4e, /* DW_CFA_advance_loc+14, pop %ebx */
0x0e, /* DW_CFA_def_cfa_offset */
0x12, /* RA at offset 12 now */
0xc5, /* DW_CFA_restore %ebp */
0x41, /* DW_CFA_advance_loc+1, pop %edx */
0x0e, /* DW_CFA_def_cfa_offset */
0x08, /* RA at offset 8 now */
0x41, /* DW_CFA_advance_loc+1, pop %ecx */
0x0e, /* DW_CFA_def_cfa_offset */
0x04 /* RA at offset 4 now */
};
static const char __initdata sigreturn[] = {
/* 32: sigreturn point */
0x58, /* popl %eax */
0xb8, __NR_sigreturn, 0, 0, 0, /* movl $__NR_sigreturn, %eax */
0xcd, 0x80, /* int $0x80 */
};
static const char rt_sigreturn[] = {
static const char __initdata rt_sigreturn[] = {
/* 64: rt_sigreturn point */
0xb8, __NR_rt_sigreturn, 0, 0, 0, /* movl $__NR_rt_sigreturn, %eax */
0xcd, 0x80, /* int $0x80 */
......@@ -93,10 +188,14 @@ static int __init sysenter_setup(void)
memcpy((void *) page, int80, sizeof(int80));
memcpy((void *)(page + 32), sigreturn, sizeof(sigreturn));
memcpy((void *)(page + 64), rt_sigreturn, sizeof(rt_sigreturn));
memcpy((void *)(page + EH_FRAME_OFFSET), int80_eh_frame,
sizeof(int80_eh_frame));
if (!boot_cpu_has(X86_FEATURE_SEP))
return 0;
memcpy((void *) page, sysent, sizeof(sysent));
memcpy((void *)(page + EH_FRAME_OFFSET), sysent_eh_frame,
sizeof(sysent_eh_frame));
on_each_cpu(enable_sep_cpu, NULL, 1, 1);
return 0;
}
......
......@@ -101,6 +101,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
* for more of them, start the x86-specific ones at 32.
*/
#define AT_SYSINFO 32
#define AT_SYSINFO_EH_FRAME 33
#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
......@@ -118,9 +119,15 @@ extern void dump_smp_unlazy_fpu(void);
#define ELF_CORE_SYNC dump_smp_unlazy_fpu
#endif
/* Offset from the beginning of the page where the .eh_frame information
for the code in the vsyscall page starts. */
#define EH_FRAME_OFFSET 96
#define ARCH_DLINFO \
do { \
NEW_AUX_ENT(AT_SYSINFO, 0xffffe000); \
NEW_AUX_ENT(AT_SYSINFO_EH_FRAME, \
0xffffe000 + EH_FRAME_OFFSET); \
} while (0)
#endif
......
......@@ -39,7 +39,7 @@
#define MAY_LOCK 32
#define MAY_OWNER_OVERRIDE 64
#define MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
#if (MAY_SATTR | MAY_TRUNC | MAY_LOCK | MAX_OWNER_OVERRIDE | MAY_LOCAL_ACCESS) & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_OWNER_OVERRIDE)
#if (MAY_SATTR | MAY_TRUNC | MAY_LOCK | MAY_OWNER_OVERRIDE | MAY_LOCAL_ACCESS) & (MAY_READ | MAY_WRITE | MAY_EXEC)
# error "please use a different value for MAY_SATTR or MAY_TRUNC or MAY_LOCK or MAY_OWNER_OVERRIDE."
#endif
#define MAY_CREATE (MAY_EXEC|MAY_WRITE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment