kernel: don't allocate extra buffer to copy fpu state from user-memory

We don't care about corrupting the current state, because sigreturn
syscalls never report errors and they queue SIGSEGV in case of any
problems.

Here are results fro the signal_benchmark on the kvm platform:
Before:
BM_FaultSignalFixup/real_time       6127 ns         6087 ns       111708
After:
BM_FaultSignalFixup/real_time       3661 ns         3654 ns       199755
PiperOrigin-RevId: 462021118
This commit is contained in:
Andrei Vagin
2022-07-19 18:12:52 -07:00
committed by gVisor bot
parent d9c66eb769
commit 21981a2bda
2 changed files with 6 additions and 4 deletions
+2 -4
View File
@@ -304,12 +304,10 @@ func (c *Context64) SignalRestore(st *Stack, rt bool, featureSet cpuid.FeatureSe
if uc.MContext.Fpstate == 0 {
c.fpState.Reset()
} else {
fpSize, _ := featureSet.ExtendedStateSize()
f := make([]byte, fpSize)
if _, err := st.IO.CopyIn(context.Background(), hostarch.Addr(uc.MContext.Fpstate), f, usermem.IOOpts{}); err != nil {
if _, err := st.IO.CopyIn(context.Background(), hostarch.Addr(uc.MContext.Fpstate), c.fpState, usermem.IOOpts{}); err != nil {
c.fpState.Reset()
return 0, linux.SignalStack{}, err
}
copy(c.fpState, f)
c.fpState.SanitizeUser(featureSet)
}
+4
View File
@@ -305,6 +305,10 @@ func (t *Task) SignalReturn(rt bool) (*SyscallControl, error) {
st := t.Stack()
sigset, alt, err := t.Arch().SignalRestore(st, rt, t.k.featureSet)
if err != nil {
// sigreturn syscalls never return errors.
t.Debugf("failed to restore from a signal frame: %v", err)
t.forceSignal(linux.SIGSEGV, false /* unconditional */)
t.SendSignal(SignalInfoPriv(linux.SIGSEGV))
return nil, err
}