We need to set up the LSTAR MSR and friends on each processor - it is not
enough to do it on processor 0. Otherwise, a system call instruction will
always fails if happens to run on any vcpu other than the first one.

With this patch, tst-syscall now passes on my machine with the release
compilation, on both single vcpu (run.py -c1) and many (-c4).
With debug build, the patch still fails - I have other fixes to make it
work.

Refs #791.

Signed-off-by: Nadav Har'El <[email protected]>
---
 arch/x64/arch-cpu.hh   | 2 ++
 arch/x64/processor.hh  | 2 ++
 arch/x64/arch-setup.cc | 6 +++---
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x64/arch-cpu.hh b/arch/x64/arch-cpu.hh
index 808ff2a..b1cb0bf 100644
--- a/arch/x64/arch-cpu.hh
+++ b/arch/x64/arch-cpu.hh
@@ -174,6 +174,8 @@ inline void arch_cpu::init_on_cpu()
     // We can't trust the FPU and the MXCSR to be always initialized to 
default values.
     // In at least one particular version of Xen it is not, leading to SIMD 
exceptions.
     processor::init_fpu();
+
+    processor::init_syscall();
 }
 
 struct exception_guard {
diff --git a/arch/x64/processor.hh b/arch/x64/processor.hh
index 89bc9fc..250153b 100644
--- a/arch/x64/processor.hh
+++ b/arch/x64/processor.hh
@@ -394,6 +394,8 @@ inline void init_fpu()
     asm volatile ("ldmxcsr %0" : : "m" (csr));
 }
 
+void init_syscall();
+
 inline void lfence()
 {
     asm volatile("lfence");
diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc
index 0994de5..0fabfec 100644
--- a/arch/x64/arch-setup.cc
+++ b/arch/x64/arch-setup.cc
@@ -224,8 +224,8 @@ static const int CS_SELECTOR_SHIFT = 3;
 // syscall shift
 static const int IA_32_STAR_SYSCALL_SHIFT = 32;
 
-static void setup_syscall()
-{
+namespace processor {
+void init_syscall() {
     unsigned long cs = gdt_cs;
     processor::wrmsr(msr::IA32_STAR,  (cs << CS_SELECTOR_SHIFT) << 
IA_32_STAR_SYSCALL_SHIFT);
     // lstar is where syscall set rip so we set it to syscall_entry
@@ -236,6 +236,7 @@ static void setup_syscall()
     processor::wrmsr(msr::IA32_FMASK, 0);
     processor::wrmsr(msr::IA32_EFER,  processor::rdmsr(msr::IA32_EFER) | 
IA32_EFER_SCE);
 }
+}
 
 void arch_init_premain()
 {
@@ -244,7 +245,6 @@ void arch_init_premain()
        debug_early_u64("Error reading disk (real mode): ", 
static_cast<u64>(omb.disk_err));
 
     disable_pic();
-    setup_syscall();
 }
 
 #include "drivers/driver.hh"
-- 
2.7.4

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to