Lazy-fpsimd support patch series#1: add Arm64-fpsimd support to arch module

This patch defines the structures and
adds the implementations for fpsimd initialization.

Signed-off-by: Bin Lu <bin.lu@arm.com>
This commit is contained in:
Bin Lu 2020-01-29 04:33:06 -05:00
parent 4cb55a7a3b
commit a369c88c0c
3 changed files with 48 additions and 17 deletions

View File

@ -32,29 +32,35 @@ import (
const (
// SyscallWidth is the width of insturctions.
SyscallWidth = 4
// fpsimdMagic is the magic number which is used in fpsimd_context.
fpsimdMagic = 0x46508001
// fpsimdContextSize is the size of fpsimd_context.
fpsimdContextSize = 0x210
)
// aarch64FPState is aarch64 floating point state.
type aarch64FPState []byte
// initAarch64FPState (defined in asm files) sets up initial state.
func initAarch64FPState(data *FloatingPointData) {
// TODO(gvisor.dev/issue/1238): floating-point is not supported.
// initAarch64FPState sets up initial state.
func initAarch64FPState(data aarch64FPState) {
binary.LittleEndian.PutUint32(data, fpsimdMagic)
binary.LittleEndian.PutUint32(data[4:], fpsimdContextSize)
}
func newAarch64FPStateSlice() []byte {
return alignedBytes(4096, 32)[:4096]
return alignedBytes(4096, 16)[:fpsimdContextSize]
}
// newAarch64FPState returns an initialized floating point state.
//
// The returned state is large enough to store all floating point state
// supported by host, even if the app won't use much of it due to a restricted
// FeatureSet. Since they may still be able to see state not advertised by
// CPUID we must ensure it does not contain any sentry state.
// FeatureSet.
func newAarch64FPState() aarch64FPState {
f := aarch64FPState(newAarch64FPStateSlice())
initAarch64FPState(f.FloatingPointData())
initAarch64FPState(f)
return f
}
@ -133,10 +139,10 @@ func (s State) Proto() *rpb.Registers {
// Fork creates and returns an identical copy of the state.
func (s *State) Fork() State {
// TODO(gvisor.dev/issue/1238): floating-point is not supported.
return State{
Regs: s.Regs,
FeatureSet: s.FeatureSet,
Regs: s.Regs,
aarch64FPState: s.aarch64FPState.fork(),
FeatureSet: s.FeatureSet,
}
}
@ -285,8 +291,10 @@ func New(arch Arch, fs *cpuid.FeatureSet) Context {
case ARM64:
return &context64{
State{
FeatureSet: fs,
aarch64FPState: newAarch64FPState(),
FeatureSet: fs,
},
[]aarch64FPState(nil),
}
}
panic(fmt.Sprintf("unknown architecture %v", arch))

View File

@ -68,6 +68,7 @@ const (
// context64 represents an ARM64 context.
type context64 struct {
State
sigFPState []aarch64FPState // fpstate to be restored on sigreturn.
}
// Arch implements Context.Arch.
@ -75,10 +76,19 @@ func (c *context64) Arch() Arch {
return ARM64
}
func (c *context64) copySigFPState() []aarch64FPState {
var sigfps []aarch64FPState
for _, s := range c.sigFPState {
sigfps = append(sigfps, s.fork())
}
return sigfps
}
// Fork returns an exact copy of this context.
func (c *context64) Fork() Context {
return &context64{
State: c.State.Fork(),
State: c.State.Fork(),
sigFPState: c.copySigFPState(),
}
}
@ -137,8 +147,8 @@ func (c *context64) SetTLS(value uintptr) bool {
return false
}
// SetRSEQInterruptedIP implements Context.SetRSEQInterruptedIP.
func (c *context64) SetRSEQInterruptedIP(value uintptr) {
// SetOldRSeqInterruptedIP implements Context.SetOldRSeqInterruptedIP.
func (c *context64) SetOldRSeqInterruptedIP(value uintptr) {
c.Regs.Regs[3] = uint64(value)
}

View File

@ -30,14 +30,27 @@ type SignalContext64 struct {
Sp uint64
Pc uint64
Pstate uint64
_pad [8]byte // __attribute__((__aligned__(16)))
Reserved [4096]uint8
_pad [8]byte // __attribute__((__aligned__(16)))
Fpsimd64 FpsimdContext // size = 528
Reserved [3568]uint8
}
type aarch64Ctx struct {
Magic uint32
Size uint32
}
type FpsimdContext struct {
Head aarch64Ctx
Fpsr uint32
Fpcr uint32
Vregs [64]uint64 // actually [32]uint128
}
// UContext64 is equivalent to ucontext on arm64(arch/arm64/include/uapi/asm/ucontext.h).
type UContext64 struct {
Flags uint64
Link *UContext64
Link uint64
Stack SignalStack
Sigset linux.SignalSet
// glibc uses a 1024-bit sigset_t