From 860d5ea687a248d6c1ac27bf77221d7df11124f9 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Mon, 19 Sep 2022 22:07:40 -0700 Subject: [PATCH] Go 1.18 support for the KVM platform It is similar with 36a17a814bf9 ("Go 1.17 support for the KVM platform") that fixed the same problem for x86. Go 1.18 adds the support of the register-based calling convention on aarch64. Signed-off-by: Andrei Vagin --- pkg/ring0/entry_arm64.go | 8 ++++--- pkg/ring0/entry_arm64.s | 20 ++++++++++++---- .../platform/kvm/machine_arm64_unsafe.go | 4 ++-- .../platform/kvm/testutil/testutil_arm64.s | 24 +++++++++---------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/pkg/ring0/entry_arm64.go b/pkg/ring0/entry_arm64.go index 299036478..a04b9b2f6 100644 --- a/pkg/ring0/entry_arm64.go +++ b/pkg/ring0/entry_arm64.go @@ -47,12 +47,14 @@ func El0_irq_invalid() func El0_fiq_invalid() func El0_error_invalid() -func Vectors() +func vectors() +func AddrOfVectors() uintptr -// Start is the CPU entrypoint. +// start is the CPU entrypoint. // // The CPU state will be set to c.Registers(). -func Start() +func start() +func AddrOfStart() uintptr func kernelExitToEl1() func kernelExitToEl0() diff --git a/pkg/ring0/entry_arm64.s b/pkg/ring0/entry_arm64.s index 18385d8c0..8878bcb2a 100644 --- a/pkg/ring0/entry_arm64.s +++ b/pkg/ring0/entry_arm64.s @@ -611,8 +611,8 @@ TEXT ·kernelExitToEl1(SB),NOSPLIT,$0 ERET() -// Start is the CPU entrypoint. -TEXT ·Start(SB),NOSPLIT,$0 +// start is the CPU entrypoint. +TEXT ·start(SB),NOSPLIT,$0 // Init. WORD $0xd508871f // __tlbi(vmalle1) DSB $7 // dsb(nsh) @@ -646,6 +646,12 @@ TEXT ·Start(SB),NOSPLIT,$0 B ·kernelExitToEl1(SB) +// func AddrOfStart() uintptr +TEXT ·AddrOfStart(SB), $0-8 + MOVD $·start(SB), R0 + MOVD R0, ret+0(FP) + RET + // El1_sync_invalid is the handler for an invalid EL1_sync. TEXT ·El1_sync_invalid(SB),NOSPLIT,$0 B ·Shutdown(SB) @@ -839,12 +845,12 @@ TEXT ·El0_fiq_invalid(SB),NOSPLIT,$0 TEXT ·El0_error_invalid(SB),NOSPLIT,$0 B ·Shutdown(SB) -// Vectors implements exception vector table. +// vectors implements exception vector table. // The start address of exception vector table should be 11-bits aligned. // For detail, please refer to arm developer document: // https://developer.arm.com/documentation/100933/0100/AArch64-exception-vector-table // Also can refer to the code in linux kernel: arch/arm64/kernel/entry.S -TEXT ·Vectors(SB),NOSPLIT,$0 +TEXT ·vectors(SB),NOSPLIT,$0 PCALIGN $2048 B ·El1_sync_invalid(SB) PCALIGN $128 @@ -880,3 +886,9 @@ TEXT ·Vectors(SB),NOSPLIT,$0 B ·El0_fiq_invalid(SB) PCALIGN $128 B ·El0_error_invalid(SB) + +// func AddrOfVectors() uintptr +TEXT ·AddrOfVectors(SB), $0-8 + MOVD $·vectors(SB), R0 + MOVD R0, ret+0(FP) + RET diff --git a/pkg/sentry/platform/kvm/machine_arm64_unsafe.go b/pkg/sentry/platform/kvm/machine_arm64_unsafe.go index cd0f28635..1c4b80769 100644 --- a/pkg/sentry/platform/kvm/machine_arm64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_arm64_unsafe.go @@ -122,7 +122,7 @@ func (c *vCPU) initArchState() error { // pc reg.id = _KVM_ARM64_REGS_PC - data = uint64(reflect.ValueOf(ring0.Start).Pointer()) + data = uint64(ring0.AddrOfStart()) if err := c.setOneRegister(®); err != nil { return err } @@ -136,7 +136,7 @@ func (c *vCPU) initArchState() error { // vbar_el1 reg.id = _KVM_ARM64_REGS_VBAR_EL1 - vectorLocation := reflect.ValueOf(ring0.Vectors).Pointer() + vectorLocation := ring0.AddrOfVectors() data = uint64(ring0.KernelStartAddress | vectorLocation) if err := c.setOneRegister(®); err != nil { return err diff --git a/pkg/sentry/platform/kvm/testutil/testutil_arm64.s b/pkg/sentry/platform/kvm/testutil/testutil_arm64.s index 42876245a..1d7c4d02f 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_arm64.s +++ b/pkg/sentry/platform/kvm/testutil/testutil_arm64.s @@ -33,7 +33,7 @@ TEXT ·AddrOfGetpid(SB),NOSPLIT,$0-8 MOVD R0, ret+0(FP) RET -TEXT ·Touch(SB),NOSPLIT,$0 +TEXT ·touch(SB),NOSPLIT,$0 start: MOVD 0(R8), R1 MOVD $SYS_GETPID, R8 // getpid @@ -41,37 +41,37 @@ start: B start TEXT ·AddrOfTouch(SB),NOSPLIT,$0-8 - MOVD $·Touch(SB), R0 + MOVD $·touch(SB), R0 MOVD R0, ret+0(FP) RET -TEXT ·HaltLoop(SB),NOSPLIT,$0 +TEXT ·haltLoop(SB),NOSPLIT,$0 start: HLT B start TEXT ·AddOfHaltLoop(SB),NOSPLIT,$0-8 - MOVD $·HaltLoop(SB), R0 + MOVD $·haltLoop(SB), R0 MOVD R0, ret+0(FP) RET // This function simulates a loop of syscall. -TEXT ·SyscallLoop(SB),NOSPLIT,$0 +TEXT ·syscallLoop(SB),NOSPLIT,$0 start: SVC B start TEXT ·AddrOfSyscallLoop(SB),NOSPLIT,$0-8 - MOVD $·SyscallLoop(SB), R0 + MOVD $·syscallLoop(SB), R0 MOVD R0, ret+0(FP) RET -TEXT ·SpinLoop(SB),NOSPLIT,$0 +TEXT ·spinLoop(SB),NOSPLIT,$0 start: B start TEXT ·AddrOfSpinLoop(SB),NOSPLIT,$0-8 - MOVD $·SpinLoop(SB), R0 + MOVD $·spinLoop(SB), R0 MOVD R0, ret+0(FP) RET @@ -143,7 +143,7 @@ isNaN: MVN R29, R29; \ MVN R30, R30; -TEXT ·TwiddleRegsSyscall(SB),NOSPLIT,$0 +TEXT ·twiddleRegsSyscall(SB),NOSPLIT,$0 TWIDDLE_REGS() MSR R10, TPIDR_EL0 // Trapped in el0_svc. @@ -151,11 +151,11 @@ TEXT ·TwiddleRegsSyscall(SB),NOSPLIT,$0 RET // never reached TEXT ·AddrOfTwiddleRegsSyscall(SB),NOSPLIT,$0-8 - MOVD $·TwiddleRegsSyscall(SB), R0 + MOVD $·twiddleRegsSyscall(SB), R0 MOVD R0, ret+0(FP) RET -TEXT ·TwiddleRegsFault(SB),NOSPLIT,$0 +TEXT ·twiddleRegsFault(SB),NOSPLIT,$0 TWIDDLE_REGS() MSR R10, TPIDR_EL0 // Trapped in el0_ia. @@ -164,6 +164,6 @@ TEXT ·TwiddleRegsFault(SB),NOSPLIT,$0 RET // never reached TEXT ·AddrOfTwiddleRegsFault(SB),NOSPLIT,$0-8 - MOVD $·TwiddleRegsFault(SB), R0 + MOVD $·twiddleRegsFault(SB), R0 MOVD R0, ret+0(FP) RET