Minor FPU save/restore fixes.

- Use the correct instruction in safecopy.checkXstate(). Before this CL:

```
TEXT pkg/sentry/arch/fpu/fpu.initX86FPState.abi0(SB)
  ...
  fpu_amd64.s:78        0x7661b2                480fae2f                XRSTOR64 0(DI)

TEXT pkg/safecopy/safecopy.checkXstate.abi0(SB)
  ...
  xrstor_amd64.s:54     0x7648a0                0fae2f                  XRSTOR 0(DI)
```

I'm not sure what the actual difference between XRSTOR and XRSTOR64 is, but
Linux is careful to use XRSTOR64 (arch/x86/kernel/fpu/xstate.h:XRSTOR,
REX_PREFIX) so it probably matters.

- When an AfterLoad callback fails, log the error message before the failing
  object, since the latter can be huge and prevent the error message from being
  logged.

- Include additional information in the error message emitted by
  fpu.State.AfterLoad().

PiperOrigin-RevId: 605534648
This commit is contained in:
Jamie Liu
2024-02-08 23:11:09 -08:00
committed by gVisor bot
parent 3a86eaf0d8
commit 59a057980d
3 changed files with 8 additions and 3 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ TEXT ·checkXstate(SB),NOSPLIT|NOFRAME,$0-26
MOVQ addr+0(FP), DI
MOVL $0xffffffff, AX
MOVL $0xffffffff, DX
XRSTOR (DI)
XRSTOR64 (DI)
// Restore MXCSR and the x87 control word.
LDMXCSR mxcsr+20(FP)
+6 -1
View File
@@ -199,6 +199,7 @@ const (
// xstateBVOffset is the offset in bytes of the XSTATE_BV field in an x86
// XSAVE area.
xstateBVOffset = 512
xcompBVOffset = 520
// xsaveHeaderZeroedOffset and xsaveHeaderZeroedBytes indicate parts of the
// XSAVE header that we coerce to zero: "Bytes 15:8 of the XSAVE header is
@@ -381,7 +382,11 @@ func (s *State) AfterLoad() {
}
if hostFeatureSet.UseXsave() {
if err := safecopy.CheckXstate(s.BytePointer()); err != nil {
panic(fmt.Sprintf("incompatible state: %s (%#v)", err, *s))
xcompBV := uint64(0)
if len(old) >= xcompBVOffset+8 {
xcompBV = hostarch.ByteOrder.Uint64(old[xcompBVOffset:])
}
panic(fmt.Sprintf("incompatible state: %s\nlen(old)=%d len(new)=%d supportedBV=%#x XSTATE_BV=%#x XCOMP_BV=%#x", err, len(old), len(*s), supportedBV, savedBV, xcompBV))
}
}
}
+1 -1
View File
@@ -691,7 +691,7 @@ func (ds *decodeState) Load(obj reflect.Value) {
}
}
}); err != nil {
Failf("error executing callbacks for %#v: %w", ods.obj.Interface(), err)
Failf("error executing callbacks: %w\nfor object %#v", err, ods.obj.Interface())
}
// Check if we have any remaining dependency cycles. If there are any