From 25130d6183d399fc3bfa93385aeba6819437ea6c Mon Sep 17 00:00:00 2001 From: Robin Luk Date: Thu, 14 Jan 2021 16:50:52 +0800 Subject: arm64: clean code In order to improve the performance and stability, I reorg 2 modules slightly. arch: no red zone on Arm64. ring0: use stp instead of movd, and set RSV_REG_APP=R19. Signed-off-by: Robin Luk --- pkg/ring0/defs_arm64.go | 2 +- pkg/ring0/entry_arm64.s | 113 ++++++++++++++-------------------------- pkg/sentry/arch/signal_arm64.go | 9 ++-- 3 files changed, 44 insertions(+), 80 deletions(-) (limited to 'pkg') diff --git a/pkg/ring0/defs_arm64.go b/pkg/ring0/defs_arm64.go index dcb255fc8..4b2375b71 100644 --- a/pkg/ring0/defs_arm64.go +++ b/pkg/ring0/defs_arm64.go @@ -38,7 +38,7 @@ type KernelArchState struct { // CPUArchState contains CPU-specific arch state. type CPUArchState struct { // stack is the stack used for interrupts on this CPU. - stack [512]byte + stack [128]byte // errorCode is the error code from the last exception. errorCode uintptr diff --git a/pkg/ring0/entry_arm64.s b/pkg/ring0/entry_arm64.s index b2bb18257..4a656de8e 100644 --- a/pkg/ring0/entry_arm64.s +++ b/pkg/ring0/entry_arm64.s @@ -35,7 +35,7 @@ #define RSV_REG R18_PLATFORM // RSV_REG_APP is a register that holds el0 information temporarily. -#define RSV_REG_APP R9 +#define RSV_REG_APP R19 #define FPEN_NOTRAP 0x3 #define FPEN_SHIFT 20 @@ -63,36 +63,22 @@ // This is a macro because it may need to executed in contents where a stack is // not available for calls. // -// The following registers are not saved: R9, R18. +// The following registers are not saved: R18, R19. #define REGISTERS_SAVE(reg, offset) \ - MOVD R0, offset+PTRACE_R0(reg); \ - MOVD R1, offset+PTRACE_R1(reg); \ - MOVD R2, offset+PTRACE_R2(reg); \ - MOVD R3, offset+PTRACE_R3(reg); \ - MOVD R4, offset+PTRACE_R4(reg); \ - MOVD R5, offset+PTRACE_R5(reg); \ - MOVD R6, offset+PTRACE_R6(reg); \ - MOVD R7, offset+PTRACE_R7(reg); \ - MOVD R8, offset+PTRACE_R8(reg); \ - MOVD R10, offset+PTRACE_R10(reg); \ - MOVD R11, offset+PTRACE_R11(reg); \ - MOVD R12, offset+PTRACE_R12(reg); \ - MOVD R13, offset+PTRACE_R13(reg); \ - MOVD R14, offset+PTRACE_R14(reg); \ - MOVD R15, offset+PTRACE_R15(reg); \ - MOVD R16, offset+PTRACE_R16(reg); \ - MOVD R17, offset+PTRACE_R17(reg); \ - MOVD R19, offset+PTRACE_R19(reg); \ - MOVD R20, offset+PTRACE_R20(reg); \ - MOVD R21, offset+PTRACE_R21(reg); \ - MOVD R22, offset+PTRACE_R22(reg); \ - MOVD R23, offset+PTRACE_R23(reg); \ - MOVD R24, offset+PTRACE_R24(reg); \ - MOVD R25, offset+PTRACE_R25(reg); \ - MOVD R26, offset+PTRACE_R26(reg); \ - MOVD R27, offset+PTRACE_R27(reg); \ - MOVD g, offset+PTRACE_R28(reg); \ - MOVD R29, offset+PTRACE_R29(reg); \ +STP (R0, R1), offset+PTRACE_R0(reg); \ + STP (R2, R3), offset+PTRACE_R2(reg); \ + STP (R4, R5), offset+PTRACE_R4(reg); \ + STP (R6, R7), offset+PTRACE_R6(reg); \ + STP (R8, R9), offset+PTRACE_R8(reg); \ + STP (R10, R11), offset+PTRACE_R10(reg); \ + STP (R12, R13), offset+PTRACE_R12(reg); \ + STP (R14, R15), offset+PTRACE_R14(reg); \ + STP (R16, R17), offset+PTRACE_R16(reg); \ + STP (R20, R21), offset+PTRACE_R20(reg); \ + STP (R22, R23), offset+PTRACE_R22(reg); \ + STP (R24, R25), offset+PTRACE_R24(reg); \ + STP (R26, R27), offset+PTRACE_R26(reg); \ + STP (g, R29), offset+PTRACE_R28(reg); \ MOVD R30, offset+PTRACE_R30(reg); // Loads a register set. @@ -100,36 +86,22 @@ // This is a macro because it may need to executed in contents where a stack is // not available for calls. // -// The following registers are not loaded: R9, R18. +// The following registers are not loaded: R18, R19. #define REGISTERS_LOAD(reg, offset) \ - MOVD offset+PTRACE_R0(reg), R0; \ - MOVD offset+PTRACE_R1(reg), R1; \ - MOVD offset+PTRACE_R2(reg), R2; \ - MOVD offset+PTRACE_R3(reg), R3; \ - MOVD offset+PTRACE_R4(reg), R4; \ - MOVD offset+PTRACE_R5(reg), R5; \ - MOVD offset+PTRACE_R6(reg), R6; \ - MOVD offset+PTRACE_R7(reg), R7; \ - MOVD offset+PTRACE_R8(reg), R8; \ - MOVD offset+PTRACE_R10(reg), R10; \ - MOVD offset+PTRACE_R11(reg), R11; \ - MOVD offset+PTRACE_R12(reg), R12; \ - MOVD offset+PTRACE_R13(reg), R13; \ - MOVD offset+PTRACE_R14(reg), R14; \ - MOVD offset+PTRACE_R15(reg), R15; \ - MOVD offset+PTRACE_R16(reg), R16; \ - MOVD offset+PTRACE_R17(reg), R17; \ - MOVD offset+PTRACE_R19(reg), R19; \ - MOVD offset+PTRACE_R20(reg), R20; \ - MOVD offset+PTRACE_R21(reg), R21; \ - MOVD offset+PTRACE_R22(reg), R22; \ - MOVD offset+PTRACE_R23(reg), R23; \ - MOVD offset+PTRACE_R24(reg), R24; \ - MOVD offset+PTRACE_R25(reg), R25; \ - MOVD offset+PTRACE_R26(reg), R26; \ - MOVD offset+PTRACE_R27(reg), R27; \ - MOVD offset+PTRACE_R28(reg), g; \ - MOVD offset+PTRACE_R29(reg), R29; \ +LDP offset+PTRACE_R0(reg), (R0, R1); \ + LDP offset+PTRACE_R2(reg), (R2, R3); \ + LDP offset+PTRACE_R4(reg), (R4, R5); \ + LDP offset+PTRACE_R6(reg), (R6, R7); \ + LDP offset+PTRACE_R8(reg), (R8, R9); \ + LDP offset+PTRACE_R10(reg), (R10, R11); \ + LDP offset+PTRACE_R12(reg), (R12, R13); \ + LDP offset+PTRACE_R14(reg), (R14, R15); \ + LDP offset+PTRACE_R16(reg), (R16, R17); \ + LDP offset+PTRACE_R20(reg), (R20, R21); \ + LDP offset+PTRACE_R22(reg), (R22, R23); \ + LDP offset+PTRACE_R24(reg), (R24, R25); \ + LDP offset+PTRACE_R26(reg), (R26, R27); \ + LDP offset+PTRACE_R28(reg), (g, R29); \ MOVD offset+PTRACE_R30(reg), R30; #define ESR_ELx_EC_UNKNOWN (0x00) @@ -310,7 +282,7 @@ TEXT ·DisableVFP(SB),NOSPLIT,$0 // KERNEL_ENTRY_FROM_EL0 is the entry code of the vcpu from el0 to el1. #define KERNEL_ENTRY_FROM_EL0 \ - SUB $16, RSP, RSP; \ // step1, save r18, r9 into kernel temporary stack. + SUB $16, RSP, RSP; \ // step1, save r18, r19 into kernel temporary stack. STP (RSV_REG, RSV_REG_APP), 16*0(RSP); \ WORD $0xd538d092; \ // MRS TPIDR_EL1, R18 MOVD CPU_APP_ADDR(RSV_REG), RSV_REG_APP; \ // step2, load app context pointer. @@ -318,8 +290,7 @@ TEXT ·DisableVFP(SB),NOSPLIT,$0 MOVD RSV_REG_APP, R20; \ LDP 16*0(RSP), (RSV_REG, RSV_REG_APP); \ ADD $16, RSP, RSP; \ - MOVD RSV_REG, PTRACE_R18(R20); \ - MOVD RSV_REG_APP, PTRACE_R9(R20); \ + STP (RSV_REG, RSV_REG_APP), PTRACE_R18(R20); \ MRS TPIDR_EL0, R3; \ MOVD R3, PTRACE_TLS(R20); \ WORD $0xd5384003; \ // MRS SPSR_EL1, R3 @@ -333,7 +304,7 @@ TEXT ·DisableVFP(SB),NOSPLIT,$0 #define KERNEL_ENTRY_FROM_EL1 \ WORD $0xd538d092; \ //MRS TPIDR_EL1, R18 REGISTERS_SAVE(RSV_REG, CPU_REGISTERS); \ // Save sentry context. - MOVD RSV_REG_APP, CPU_REGISTERS+PTRACE_R9(RSV_REG); \ + MOVD RSV_REG_APP, CPU_REGISTERS+PTRACE_R19(RSV_REG); \ MRS TPIDR_EL0, R4; \ MOVD R4, CPU_REGISTERS+PTRACE_TLS(RSV_REG); \ WORD $0xd5384004; \ // MRS SPSR_EL1, R4 @@ -372,16 +343,11 @@ TEXT ·storeAppASID(SB),NOSPLIT,$0-8 // Halt halts execution. TEXT ·Halt(SB),NOSPLIT,$0 - // Clear bluepill. - WORD $0xd538d092 //MRS TPIDR_EL1, R18 - CMP RSV_REG, R9 - 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) + DSB $15 + VFP_DISABLE // Trigger MMIO_EXIT/_KVM_HYPERCALL_VMEXIT. @@ -440,7 +406,7 @@ TEXT ·kernelExitToEl0(SB),NOSPLIT,$0 // Step1, save sentry context into memory. MRS TPIDR_EL1, RSV_REG REGISTERS_SAVE(RSV_REG, CPU_REGISTERS) - MOVD RSV_REG_APP, CPU_REGISTERS+PTRACE_R9(RSV_REG) + MOVD RSV_REG_APP, CPU_REGISTERS+PTRACE_R19(RSV_REG) MRS TPIDR_EL0, R3 MOVD R3, CPU_REGISTERS+PTRACE_TLS(RSV_REG) @@ -483,8 +449,7 @@ do_exit_to_el0: MSR RSV_REG, TPIDR_EL0 // switch to user pagetable. - MOVD PTRACE_R18(RSV_REG_APP), RSV_REG - MOVD PTRACE_R9(RSV_REG_APP), RSV_REG_APP + LDP PTRACE_R18(RSV_REG_APP), (RSV_REG, RSV_REG_APP) SUB $STACK_FRAME_SIZE, RSP, RSP STP (RSV_REG, RSV_REG_APP), 16*0(RSP) @@ -521,7 +486,7 @@ TEXT ·kernelExitToEl1(SB),NOSPLIT,$0 SWITCH_TO_KVM_PAGETABLE() MRS TPIDR_EL1, RSV_REG - MOVD CPU_REGISTERS+PTRACE_R9(RSV_REG), RSV_REG_APP + MOVD CPU_REGISTERS+PTRACE_R19(RSV_REG), RSV_REG_APP ERET() diff --git a/pkg/sentry/arch/signal_arm64.go b/pkg/sentry/arch/signal_arm64.go index 7fde5d34e..71596130d 100644 --- a/pkg/sentry/arch/signal_arm64.go +++ b/pkg/sentry/arch/signal_arm64.go @@ -36,7 +36,6 @@ type SignalContext64 struct { Pstate uint64 _pad [8]byte // __attribute__((__aligned__(16))) Fpsimd64 FpsimdContext // size = 528 - Reserved [3568]uint8 } // +marshal @@ -86,10 +85,6 @@ func (c *context64) NewSignalStack() NativeSignalStack { func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt *SignalStack, sigset linux.SignalSet) error { sp := st.Bottom - if !(alt.IsEnabled() && sp == alt.Top()) { - sp -= 128 - } - // Construct the UContext64 now since we need its size. uc := &UContext64{ Flags: 0, @@ -102,6 +97,10 @@ func (c *context64) SignalSetup(st *Stack, act *SignalAct, info *SignalInfo, alt }, Sigset: sigset, } + if linux.Signal(info.Signo) == linux.SIGSEGV || linux.Signal(info.Signo) == linux.SIGBUS { + uc.MContext.FaultAddr = info.Addr() + } + ucSize := uc.SizeBytes() // frameSize = ucSize + sizeof(siginfo). -- cgit v1.2.3