supporting lazy-fpsimd in guest on Arm64

Several jobs were finished in this patch:
1, provide functions to get/set fpcr/fpsr/vregs
2, support lazy-fpsimd-context-switch in el1

Signed-off-by: Bin Lu <bin.lu@arm.com>
This commit is contained in:
Bin Lu
2019-12-18 16:45:15 +08:00
parent 80b7ba0c97
commit eb868be743
6 changed files with 169 additions and 6 deletions
+1
View File
@@ -71,6 +71,7 @@ go_library(
"lib_amd64.go",
"lib_amd64.s",
"lib_arm64.go",
"lib_arm64.s",
"ring0.go",
],
importpath = "gvisor.dev/gvisor/pkg/sentry/platform/ring0",
+3
View File
@@ -73,6 +73,9 @@ type CPUArchState struct {
// application context pointer.
appAddr uintptr
// lazyVFP is the value of cpacr_el1.
lazyVFP uintptr
}
// ErrorCode returns the last error code.
+26
View File
@@ -31,6 +31,11 @@
#define RSV_REG R18_PLATFORM
#define RSV_REG_APP R9
#define FPEN_NOTRAP 0x3
#define FPEN_SHIFT 20
#define FPEN_ENABLE (FPEN_NOTRAP << FPEN_SHIFT)
#define REGISTERS_SAVE(reg, offset) \
MOVD R0, offset+PTRACE_R0(reg); \
MOVD R1, offset+PTRACE_R1(reg); \
@@ -279,6 +284,16 @@
#define IRQ_DISABLE \
MSR $2, DAIFClr;
#define VFP_ENABLE \
MOVD $FPEN_ENABLE, R0; \
WORD $0xd5181040; \ //MSR R0, CPACR_EL1
ISB $15;
#define VFP_DISABLE \
MOVD $0x0, R0; \
WORD $0xd5181040; \ //MSR R0, CPACR_EL1
ISB $15;
#define KERNEL_ENTRY_FROM_EL0 \
SUB $16, RSP, RSP; \ // step1, save r18, r9 into kernel temporary stack.
STP (RSV_REG, RSV_REG_APP), 16*0(RSP); \
@@ -318,6 +333,11 @@ TEXT ·Halt(SB),NOSPLIT,$0
BNE mmio_exit
MOVD $0, CPU_REGISTERS+PTRACE_R9(RSV_REG)
mmio_exit:
// Disable fpsimd.
WORD $0xd5381041 // MRS CPACR_EL1, R1
MOVD R1, CPU_LAZY_VFP(RSV_REG)
VFP_DISABLE
// MMIO_EXIT.
MOVD $0, R9
MOVD R0, 0xffff000000001000(R9)
@@ -382,6 +402,8 @@ TEXT ·El1_sync(SB),NOSPLIT,$0
BEQ el1_svc
CMP $ESR_ELx_EC_BREAKPT_CUR, R24
BGE el1_dbg
CMP $ESR_ELx_EC_FP_ASIMD, R24
BEQ el1_fpsimd_acc
B el1_invalid
el1_da:
@@ -402,6 +424,10 @@ el1_svc:
el1_dbg:
B ·Shutdown(SB)
el1_fpsimd_acc:
VFP_ENABLE
B ·kernelExitToEl1(SB) // Resume.
el1_invalid:
B ·Shutdown(SB)
+20 -6
View File
@@ -16,10 +16,24 @@
package ring0
// LoadFloatingPoint loads floating point state by the most efficient mechanism
// available (set by Init).
var LoadFloatingPoint func(*byte)
// CPACREL1 returns the value of the CPACR_EL1 register.
func CPACREL1() (value uintptr)
// SaveFloatingPoint saves floating point state by the most efficient mechanism
// available (set by Init).
var SaveFloatingPoint func(*byte)
// GetFPCR returns the value of FPCR register.
func GetFPCR() (value uintptr)
// SetFPCR writes the FPCR value.
func SetFPCR(value uintptr)
// GetFPSR returns the value of FPSR register.
func GetFPSR() (value uintptr)
// SetFPSR writes the FPSR value.
func SetFPSR(value uintptr)
// SaveVRegs saves V0-V31 registers.
// V0-V31: 32 128-bit registers for floating point and simd.
func SaveVRegs(*byte)
// LoadVRegs loads V0-V31 registers.
func LoadVRegs(*byte)
+118
View File
@@ -0,0 +1,118 @@
// Copyright 2019 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
TEXT ·CPACREL1(SB),NOSPLIT,$0-8
WORD $0xd5381041 // MRS CPACR_EL1, R1
MOVD R1, ret+0(FP)
RET
TEXT ·GetFPCR(SB),NOSPLIT,$0-8
WORD $0xd53b4201 // MRS NZCV, R1
MOVD R1, ret+0(FP)
RET
TEXT ·GetFPSR(SB),NOSPLIT,$0-8
WORD $0xd53b4421 // MRS FPSR, R1
MOVD R1, ret+0(FP)
RET
TEXT ·SetFPCR(SB),NOSPLIT,$0-8
MOVD addr+0(FP), R1
WORD $0xd51b4201 // MSR R1, NZCV
RET
TEXT ·SetFPSR(SB),NOSPLIT,$0-8
MOVD addr+0(FP), R1
WORD $0xd51b4421 // MSR R1, FPSR
RET
TEXT ·SaveVRegs(SB),NOSPLIT,$0-8
MOVD addr+0(FP), R0
// Skip aarch64_ctx, fpsr, fpcr.
FMOVD F0, 16*1(R0)
FMOVD F1, 16*2(R0)
FMOVD F2, 16*3(R0)
FMOVD F3, 16*4(R0)
FMOVD F4, 16*5(R0)
FMOVD F5, 16*6(R0)
FMOVD F6, 16*7(R0)
FMOVD F7, 16*8(R0)
FMOVD F8, 16*9(R0)
FMOVD F9, 16*10(R0)
FMOVD F10, 16*11(R0)
FMOVD F11, 16*12(R0)
FMOVD F12, 16*13(R0)
FMOVD F13, 16*14(R0)
FMOVD F14, 16*15(R0)
FMOVD F15, 16*16(R0)
FMOVD F16, 16*17(R0)
FMOVD F17, 16*18(R0)
FMOVD F18, 16*19(R0)
FMOVD F19, 16*20(R0)
FMOVD F20, 16*21(R0)
FMOVD F21, 16*22(R0)
FMOVD F22, 16*23(R0)
FMOVD F23, 16*24(R0)
FMOVD F24, 16*25(R0)
FMOVD F25, 16*26(R0)
FMOVD F26, 16*27(R0)
FMOVD F27, 16*28(R0)
FMOVD F28, 16*29(R0)
FMOVD F29, 16*30(R0)
FMOVD F30, 16*31(R0)
FMOVD F31, 16*32(R0)
ISB $15
RET
TEXT ·LoadVRegs(SB),NOSPLIT,$0-8
MOVD addr+0(FP), R0
// Skip aarch64_ctx, fpsr, fpcr.
FMOVD 16*1(R0), F0
FMOVD 16*2(R0), F1
FMOVD 16*3(R0), F2
FMOVD 16*4(R0), F3
FMOVD 16*5(R0), F4
FMOVD 16*6(R0), F5
FMOVD 16*7(R0), F6
FMOVD 16*8(R0), F7
FMOVD 16*9(R0), F8
FMOVD 16*10(R0), F9
FMOVD 16*11(R0), F10
FMOVD 16*12(R0), F11
FMOVD 16*13(R0), F12
FMOVD 16*14(R0), F13
FMOVD 16*15(R0), F14
FMOVD 16*16(R0), F15
FMOVD 16*17(R0), F16
FMOVD 16*18(R0), F17
FMOVD 16*19(R0), F18
FMOVD 16*20(R0), F19
FMOVD 16*21(R0), F20
FMOVD 16*22(R0), F21
FMOVD 16*23(R0), F22
FMOVD 16*24(R0), F23
FMOVD 16*25(R0), F24
FMOVD 16*26(R0), F25
FMOVD 16*27(R0), F26
FMOVD 16*28(R0), F27
FMOVD 16*29(R0), F28
FMOVD 16*30(R0), F29
FMOVD 16*31(R0), F30
FMOVD 16*32(R0), F31
ISB $15
RET
@@ -39,6 +39,7 @@ func Emit(w io.Writer) {
fmt.Fprintf(w, "#define CPU_TTBR0_APP 0x%02x\n", reflect.ValueOf(&c.ttbr0App).Pointer()-reflect.ValueOf(c).Pointer())
fmt.Fprintf(w, "#define CPU_VECTOR_CODE 0x%02x\n", reflect.ValueOf(&c.vecCode).Pointer()-reflect.ValueOf(c).Pointer())
fmt.Fprintf(w, "#define CPU_APP_ADDR 0x%02x\n", reflect.ValueOf(&c.appAddr).Pointer()-reflect.ValueOf(c).Pointer())
fmt.Fprintf(w, "#define CPU_LAZY_VFP 0x%02x\n", reflect.ValueOf(&c.lazyVFP).Pointer()-reflect.ValueOf(c).Pointer())
fmt.Fprintf(w, "\n// Bits.\n")
fmt.Fprintf(w, "#define _KERNEL_FLAGS 0x%02x\n", KernelFlagsSet)