aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_64/traps.c
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-10 18:02:55 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-10 18:02:55 +0100
commit369bafdb1c1dcd2b323206befd7fc4ac5e20816f (patch)
tree79ce88cf129a2b2afa76b7776ce89a95145eb13e /xen/arch/x86/x86_64/traps.c
parent46f15346a6a2121c6319ec186114a2f5c1838e83 (diff)
downloadxen-369bafdb1c1dcd2b323206befd7fc4ac5e20816f.tar.gz
xen-369bafdb1c1dcd2b323206befd7fc4ac5e20816f.tar.bz2
xen-369bafdb1c1dcd2b323206befd7fc4ac5e20816f.zip
xen: Big changes to x86 start-of-day:
1. x86/64 Xen now relocates itself to physical high memory. This is useful if we have devices that need very low memory, or if in future we want to grant a 1:1 mapping of low physical memory to a special 'native client domain'. 2. We now only map low 16MB RAM statically. All other RAM is mapped dynamically within the constraints of the e820 map. It is recommended never to map MMIO regions, and this change means that Xen now obeys this constraint. 3. The CPU bootup trampoline is now permanently installed at 0x90000. This is necessary prereq for CPU hotplug. 4. Start-of-day asm is generally cleaned up and diff between x86/32 and x86/64 is reduced. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/x86_64/traps.c')
-rw-r--r--xen/arch/x86/x86_64/traps.c114
1 files changed, 46 insertions, 68 deletions
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 4fddba2758..e23ed82c75 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -19,9 +19,12 @@
#include <asm/shared.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
-
#include <public/callback.h>
+asmlinkage void syscall_enter(void);
+asmlinkage void compat_hypercall(void);
+asmlinkage void int80_direct_trap(void);
+
static void print_xen_info(void)
{
char taint_str[TAINT_STRING_MAX_LEN];
@@ -246,9 +249,42 @@ unsigned long do_iret(void)
return 0;
}
-asmlinkage void syscall_enter(void);
-asmlinkage void compat_hypercall(void);
-asmlinkage void int80_direct_trap(void);
+static int write_stack_trampoline(
+ char *stack, char *stack_bottom, uint16_t cs_seg)
+{
+ /* movq %rsp, saversp(%rip) */
+ stack[0] = 0x48;
+ stack[1] = 0x89;
+ stack[2] = 0x25;
+ *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
+
+ /* leaq saversp(%rip), %rsp */
+ stack[7] = 0x48;
+ stack[8] = 0x8d;
+ stack[9] = 0x25;
+ *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
+
+ /* pushq %r11 */
+ stack[14] = 0x41;
+ stack[15] = 0x53;
+
+ /* pushq $<cs_seg> */
+ stack[16] = 0x68;
+ *(u32 *)&stack[17] = cs_seg;
+
+ /* movq $syscall_enter,%r11 */
+ stack[21] = 0x49;
+ stack[22] = 0xbb;
+ *(void **)&stack[23] = (void *)syscall_enter;
+
+ /* jmpq *%r11 */
+ stack[31] = 0x41;
+ stack[32] = 0xff;
+ stack[33] = 0xe3;
+
+ return 34;
+}
+
void __init percpu_traps_init(void)
{
char *stack_bottom, *stack;
@@ -280,74 +316,16 @@ void __init percpu_traps_init(void)
/* NMI handler has its own per-CPU 1kB stack. */
init_tss[cpu].ist[1] = (unsigned long)&stack[3072];
- /*
- * Trampoline for SYSCALL entry from long mode.
- */
-
- /* Skip the NMI and DF stacks. */
- stack = &stack[3072];
+ /* Trampoline for SYSCALL entry from long mode. */
+ stack = &stack[3072]; /* Skip the NMI and DF stacks. */
wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
+ stack += write_stack_trampoline(stack, stack_bottom, FLAT_KERNEL_CS64);
- /* movq %rsp, saversp(%rip) */
- stack[0] = 0x48;
- stack[1] = 0x89;
- stack[2] = 0x25;
- *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
-
- /* leaq saversp(%rip), %rsp */
- stack[7] = 0x48;
- stack[8] = 0x8d;
- stack[9] = 0x25;
- *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
-
- /* pushq %r11 */
- stack[14] = 0x41;
- stack[15] = 0x53;
-
- /* pushq $FLAT_KERNEL_CS64 */
- stack[16] = 0x68;
- *(u32 *)&stack[17] = FLAT_KERNEL_CS64;
-
- /* jmp syscall_enter */
- stack[21] = 0xe9;
- *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
-
- /*
- * Trampoline for SYSCALL entry from compatibility mode.
- */
-
- /* Skip the long-mode entry trampoline. */
- stack = &stack[26];
+ /* Trampoline for SYSCALL entry from compatibility mode. */
wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32));
+ stack += write_stack_trampoline(stack, stack_bottom, FLAT_KERNEL_CS32);
- /* movq %rsp, saversp(%rip) */
- stack[0] = 0x48;
- stack[1] = 0x89;
- stack[2] = 0x25;
- *(u32 *)&stack[3] = (stack_bottom - &stack[7]) - 16;
-
- /* leaq saversp(%rip), %rsp */
- stack[7] = 0x48;
- stack[8] = 0x8d;
- stack[9] = 0x25;
- *(u32 *)&stack[10] = (stack_bottom - &stack[14]) - 16;
-
- /* pushq %r11 */
- stack[14] = 0x41;
- stack[15] = 0x53;
-
- /* pushq $FLAT_KERNEL_CS32 */
- stack[16] = 0x68;
- *(u32 *)&stack[17] = FLAT_KERNEL_CS32;
-
- /* jmp syscall_enter */
- stack[21] = 0xe9;
- *(u32 *)&stack[22] = (char *)syscall_enter - &stack[26];
-
- /*
- * Common SYSCALL parameters.
- */
-
+ /* Common SYSCALL parameters. */
wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
}