mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user