From: Benoît Canet <benoit.canet.cont...@gmail.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master
syscall: save/restore FPU state on syscall
As issue #798 explains, if an application uses floating point and then,
in the same function, also calls the SYSCALL instruction, the compiler
will not realize it needs to save the caller-saved floating-point state
(because it thinks it calls an x86 instruction, not a function).
So we need to do this saving in the SYSCALL implementation, before we
go on calling OSv functions which might clobber the FPU state.
The patch Uses fpu_lock to do the work of saving and restoring FPU state.
The case where this fix is actually needed is rare (in fact, we never
saw it in practice): Most applications do not in fact mix FPU use and
SYSCALL calling in a single function. But nevertheless, we add it to be
safe in case some application ever does it.
Unfortunately, the extra FPU saving means we slow down every SYSCALL
instruction. Note that it only slows down SYSCALL instructions, which
most applications do not use (golang is the notable exception), and
does NOT slow down the normal OSv ABI (the call to "system calls" as
ordinary functions). Also, we do not slow down the vDSO ABI which
golang uses instead of SYSCALL for system calls which are supposed to
be really quick.
Signed-off-by: Benoît Canet <ben...@scylladb.com>
Message-Id: <1477570022-14541-11-git-send-email-ben...@scylladb.com>
Signed-off-by: Nadav Har'El <n...@scylladb.com>
---
diff --git a/arch/x64/entry.S b/arch/x64/entry.S
--- a/arch/x64/entry.S
+++ b/arch/x64/entry.S
@@ -217,7 +217,6 @@ syscall_entry:
# From
http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64:
# "User-level applications use as integer registers for passing the
sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9. The kernel interface
uses %rdi, %rsi, %rdx, %r10, %r8 and %r9"
- # FIXME: fpu
pushq_cfi %rbx
pushq_cfi %rdx
pushq_cfi %rsi
@@ -250,6 +249,7 @@ syscall_entry:
# Because we pushed an even number of 8 bytes after aligning the stack,
# it is still 16-byte aligned and we don't need to adjust it here.
+ # FPU save/restore is done inside the wrapper
callq syscall_wrapper
popq_cfi %r9
diff --git a/linux.cc b/linux.cc
--- a/linux.cc
+++ b/linux.cc
@@ -311,6 +311,10 @@ static int sys_exit(int ret)
long syscall(long number, ...)
{
+ // Save FPU state and restore it at the end of this function
+ sched::fpu_lock fpu;
+ SCOPE_LOCK(fpu);
+
switch (number) {
SYSCALL2(open, const char *, int);
SYSCALL3(read, int, char *, size_t);
--
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 osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.