x86_64: tracks stacktop in pcpui for sysenter
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 28 Jun 2013 18:35:24 +0000 (11:35 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 28 Jun 2013 19:51:54 +0000 (12:51 -0700)
Would be nice to avoid having per-core GDTs and TSSs too, but the traps and irq
stuff pushes everthing before we get control.  Oh well.

kern/arch/x86/smp_boot.c
kern/arch/x86/trap32.c
kern/arch/x86/trap64.c
kern/arch/x86/trap64.h
kern/include/smp.h

index b9bba08..fd63d75 100644 (file)
@@ -246,7 +246,6 @@ uintptr_t smp_main(void)
 
        /* Set up our kernel stack when changing rings */
        x86_set_stacktop_tss(my_ts, my_stack_top);
-       x86_sysenter_init(my_stack_top);
        // Initialize the TSS field of my_gdt.
        syssegdesc_t *ts_slot = (syssegdesc_t*)&my_gdt[GD_TSS >> 3];
        *ts_slot = (syssegdesc_t)SEG_SYS_SMALL(STS_T32A, (uintptr_t)my_ts,
@@ -313,6 +312,8 @@ void __arch_pcpu_init(uint32_t coreid)
                write_msr(MSR_KERN_GS_BASE, (uint64_t)pcpui);
        }
 #endif
+       /* Don't try setting up til after setting GS */
+       x86_sysenter_init(x86_get_stacktop_tss(pcpui->tss));
        /* need to init perfctr before potentiall using it in timer handler */
        perfmon_init();
 }
index dbc9140..c77ea00 100644 (file)
@@ -118,10 +118,3 @@ void page_fault_handler(struct hw_trapframe *hw_tf)
                proc_destroy(current);
        }
 }
-
-void sysenter_init(void)
-{
-       write_msr(MSR_IA32_SYSENTER_CS, GD_KT);
-       write_msr(MSR_IA32_SYSENTER_ESP, ts.ts_esp0);
-       write_msr(MSR_IA32_SYSENTER_EIP, (uint32_t) &sysenter_handler);
-}
index 783b02a..af06e27 100644 (file)
@@ -88,6 +88,8 @@ void print_trapframe(struct hw_trapframe *hw_tf)
        /* Used in trapentry64.S */
        static_assert(offsetof(struct hw_trapframe, tf_cs) - 
                      offsetof(struct hw_trapframe, tf_rax) == 0x90);
+       /* Used in trap64.h */
+       static_assert(offsetof(struct per_cpu_info, stacktop) == 0);
 }
 
 void page_fault_handler(struct hw_trapframe *hw_tf)
@@ -122,10 +124,3 @@ void page_fault_handler(struct hw_trapframe *hw_tf)
                proc_destroy(current);
        }
 }
-
-void sysenter_init(void)
-{
-       //write_msr(MSR_IA32_SYSENTER_CS, GD_KT);
-       //write_msr(MSR_IA32_SYSENTER_ESP, ts.ts_esp0);
-       //write_msr(MSR_IA32_SYSENTER_EIP, (uint32_t) &sysenter_handler);
-}
index 885f8e9..dc40db1 100644 (file)
@@ -63,14 +63,14 @@ static inline void x86_fake_rdtscp(struct hw_trapframe *hw_tf)
 /* TODO: use syscall.  all of this sysenter stuff is wrong  */
 static inline void x86_sysenter_init(uintptr_t stacktop)
 {
-       write_msr(MSR_IA32_SYSENTER_CS, GD_KT);
-       write_msr(MSR_IA32_SYSENTER_ESP, stacktop);
-       write_msr(MSR_IA32_SYSENTER_EIP, (uintptr_t) &sysenter_handler);
+       //write_msr(MSR_IA32_SYSENTER_CS, GD_KT);
+       //write_msr(MSR_IA32_SYSENTER_EIP, (uintptr_t) &sysenter_handler);
+       asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
 }
 
 static inline void x86_set_sysenter_stacktop(uintptr_t stacktop)
 {
-       write_msr(MSR_IA32_SYSENTER_ESP, stacktop);
+       asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
 }
 
 static inline long x86_get_sysenter_arg0(struct hw_trapframe *hw_tf)
index 7dd15f3..501ada5 100644 (file)
@@ -23,6 +23,9 @@ typedef sharC_env_t;
 #endif
 
 struct per_cpu_info {
+#ifdef CONFIG_X86_64
+       uintptr_t stacktop;
+#endif
        spinlock_t lock;
        /* Process management */
        // cur_proc should be valid on all cores that are not management cores.