diff --git a/pkg/hostsyscall/BUILD b/pkg/hostsyscall/BUILD new file mode 100644 index 000000000..b0a9212e6 --- /dev/null +++ b/pkg/hostsyscall/BUILD @@ -0,0 +1,17 @@ +load("//tools:defs.bzl", "go_library") + +package( + default_applicable_licenses = ["//:license"], + licenses = ["notice"], +) + +go_library( + name = "hostsyscall", + srcs = [ + "hostsyscall.go", + "hostsyscall_amd64.s", + "hostsyscall_arm64.s", + ], + visibility = ["//:sandbox"], + deps = ["@org_golang_x_sys//unix:go_default_library"], +) diff --git a/pkg/hostsyscall/hostsyscall.go b/pkg/hostsyscall/hostsyscall.go new file mode 100644 index 000000000..bf1881be1 --- /dev/null +++ b/pkg/hostsyscall/hostsyscall.go @@ -0,0 +1,45 @@ +// Copyright 2024 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. + +//go:build linux +// +build linux + +// Package hostsyscall provides functions like unix.RawSyscall, but without the +// overhead of multiple stack frame allocations. +// +// This is mostly relevant for platform/kvm which needs to execute some function +// call chains in a go:nosplit environment. Debug builds specifically make using +// unix.RawSyscall variants infeasible. +package hostsyscall + +import ( + "golang.org/x/sys/unix" +) + +// RawSyscall6 is a copy of runtime.Syscall6. +func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, errno unix.Errno) + +// RawSyscall is a copy of runtime.Syscall6, but only uses the first three arguments. +func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, errno unix.Errno) + +// Variants of runtime.Syscall6 that use slightly less stack space by only +// returning errno. + +// RawSyscallErrno6 is like RawSyscall6, but only returns errno, +// and 0 if successful. +func RawSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) unix.Errno + +// RawSyscallErrno is like RawSyscall, but only returns errno, +// and 0 if successful. +func RawSyscallErrno(trap, a1, a2, a3 uintptr) unix.Errno diff --git a/pkg/hostsyscall/hostsyscall_amd64.s b/pkg/hostsyscall/hostsyscall_amd64.s new file mode 100644 index 000000000..80444c8f2 --- /dev/null +++ b/pkg/hostsyscall/hostsyscall_amd64.s @@ -0,0 +1,100 @@ +// Copyright 2024 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. + +#include "textflag.h" + +// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno) +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ a4+32(FP), R10 + MOVQ a5+40(FP), R8 + MOVQ a6+48(FP), R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS ok + MOVQ $-1, r1+56(FP) + MOVQ $0, r2+64(FP) + NEGQ AX + MOVQ AX, errno+72(FP) + RET +ok: + MOVQ AX, r1+56(FP) + MOVQ DX, r2+64(FP) + MOVQ $0, errno+72(FP) + RET + +// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, errno) +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ $0, R10 + MOVQ $0, R8 + MOVQ $0, R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS ok + MOVQ $-1, r1+32(FP) + MOVQ $0, r2+40(FP) + NEGQ AX + MOVQ AX, errno+48(FP) + RET +ok: + MOVQ AX, r1+32(FP) + MOVQ DX, r2+40(FP) + MOVQ $0, errno+48(FP) + RET + + +// func RawSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) (ret unix.Errno) +TEXT ·RawSyscallErrno6(SB),NOSPLIT,$0-64 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ a4+32(FP), R10 + MOVQ a5+40(FP), R8 + MOVQ a6+48(FP), R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS ok + NEGQ AX + MOVQ AX, ret+56(FP) + RET +ok: + MOVQ $0, ret+56(FP) + RET + +// func RawSyscallErrno(trap, a1, a2, a3 uintptr) (ret unix.Errno) +TEXT ·RawSyscallErrno(SB),NOSPLIT,$0-40 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ $0, R10 + MOVQ $0, R8 + MOVQ $0, R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS ok + NEGQ AX + MOVQ AX, ret+32(FP) + RET +ok: + MOVQ $0, ret+32(FP) + RET diff --git a/pkg/hostsyscall/hostsyscall_arm64.s b/pkg/hostsyscall/hostsyscall_arm64.s new file mode 100644 index 000000000..6477d6f3d --- /dev/null +++ b/pkg/hostsyscall/hostsyscall_arm64.s @@ -0,0 +1,101 @@ +// Copyright 2024 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. + +#include "textflag.h" + +// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + MOVD trap+0(FP), R8 // syscall entry + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD a4+32(FP), R3 + MOVD a5+40(FP), R4 + MOVD a6+48(FP), R5 + SVC + CMN $4095, R0 + BCC ok + MOVD $-1, R4 + MOVD R4, r1+56(FP) + MOVD ZR, r2+64(FP) + NEG R0, R0 + MOVD R0, errno+72(FP) + RET +ok: + MOVD R0, r1+56(FP) + MOVD R1, r2+64(FP) + MOVD ZR, errno+72(FP) + RET + +// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, errno uintptr) +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + MOVD trap+0(FP), R8 // syscall entry + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD ZR, R3 + MOVD ZR, R4 + MOVD ZR, R5 + SVC + CMN $4095, R0 + BCC ok + MOVD $-1, R4 + MOVD R4, r1+32(FP) + MOVD ZR, r2+40(FP) + NEG R0, R0 + MOVD R0, errno+48(FP) + RET +ok: + MOVD R0, r1+32(FP) + MOVD R1, r2+40(FP) + MOVD ZR, errno+48(FP) + RET + +// func RawSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) (errno unix.Errno) +TEXT ·RawSyscallErrno6(SB),NOSPLIT,$0-64 + MOVD trap+0(FP), R8 // syscall entry + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD a4+32(FP), R3 + MOVD a5+40(FP), R4 + MOVD a6+48(FP), R5 + SVC + CMN $4095, R0 + BCC ok + NEG R0, R0 + MOVD R0, ret+56(FP) // errno + RET +ok: + MOVD ZR, ret+56(FP) // errno + RET + +// func RawSyscallErrno(trap, a1, a2, a3 uintptr) (errno unix.Errno) +TEXT ·RawSyscallErrno(SB),NOSPLIT,$0-40 + MOVD trap+0(FP), R8 // syscall entry + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD ZR, R3 + MOVD ZR, R4 + MOVD ZR, R5 + SVC + CMN $4095, R0 + BCC ok + NEG R0, R0 + MOVD R0, ret+32(FP) // errno + RET +ok: + MOVD ZR, ret+32(FP) // errno + RET diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD index 4b680fe51..8578affd7 100644 --- a/pkg/sentry/platform/kvm/BUILD +++ b/pkg/sentry/platform/kvm/BUILD @@ -93,6 +93,7 @@ go_library( "//pkg/fd", "//pkg/hostarch", "//pkg/hostos", + "//pkg/hostsyscall", "//pkg/hosttid", "//pkg/log", "//pkg/metric", diff --git a/pkg/sentry/platform/kvm/bluepill.go b/pkg/sentry/platform/kvm/bluepill.go index 1cb9d1e6e..3454b7f8f 100644 --- a/pkg/sentry/platform/kvm/bluepill.go +++ b/pkg/sentry/platform/kvm/bluepill.go @@ -16,6 +16,7 @@ package kvm import ( "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/hostsyscall" "gvisor.dev/gvisor/pkg/ring0" "gvisor.dev/gvisor/pkg/sentry/arch" ) @@ -70,7 +71,7 @@ const _SYS_KVM_RETURN_TO_HOST = ^uintptr(0) // //go:nosplit func redpill() { - kvmSyscallErrno(_SYS_KVM_RETURN_TO_HOST, 0, 0, 0) + hostsyscall.RawSyscallErrno(_SYS_KVM_RETURN_TO_HOST, 0, 0, 0) } // dieHandler is called by dieTrampoline. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.s b/pkg/sentry/platform/kvm/bluepill_amd64.s index 7852bfae1..07106b182 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.s +++ b/pkg/sentry/platform/kvm/bluepill_amd64.s @@ -91,38 +91,3 @@ TEXT ·currentCPU(SB), $0-8 MOVQ ENTRY_CPU_SELF(GS), AX MOVQ AX, ret+0(FP) RET - -// func kvmSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) (ret unix.Errno) -TEXT ·kvmSyscallErrno6(SB),NOSPLIT,$0-64 - MOVQ a1+8(FP), DI - MOVQ a2+16(FP), SI - MOVQ a3+24(FP), DX - MOVQ a4+32(FP), R10 - MOVQ a5+40(FP), R8 - MOVQ a6+48(FP), R9 - MOVQ trap+0(FP), AX // syscall entry - SYSCALL - CMPQ AX, $0xfffffffffffff001 - JLS ok - NEGQ AX - MOVQ AX, ret+56(FP) // ret - RET -ok: - MOVQ $0, ret+56(FP) // ret - RET - -// func kvmSyscallErrno(trap, a1, a2, a3 uintptr) (ret unix.Errno) -TEXT ·kvmSyscallErrno(SB),NOSPLIT,$0-40 - MOVQ a1+8(FP), DI - MOVQ a2+16(FP), SI - MOVQ a3+24(FP), DX - MOVQ trap+0(FP), AX // syscall entry - SYSCALL - CMPQ AX, $0xfffffffffffff001 - JLS ok - NEGQ AX - MOVQ AX, ret+32(FP) // ret - RET -ok: - MOVQ $0, ret+32(FP) // ret - RET diff --git a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go index f202beebd..de0ee59c5 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go @@ -25,6 +25,7 @@ import ( "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/cpuid" "gvisor.dev/gvisor/pkg/hostarch" + "gvisor.dev/gvisor/pkg/hostsyscall" "gvisor.dev/gvisor/pkg/ring0" "gvisor.dev/gvisor/pkg/sentry/arch" "gvisor.dev/gvisor/pkg/sigframe" @@ -74,7 +75,7 @@ func getHypercallID(addr uintptr) int { func bluepillStopGuest(c *vCPU) { // Interrupt: we must have requested an interrupt // window; set the interrupt line. - if errno := kvmSyscallErrno( + if errno := hostsyscall.RawSyscallErrno( unix.SYS_IOCTL, uintptr(c.fd), KVM_INTERRUPT, @@ -89,7 +90,7 @@ func bluepillStopGuest(c *vCPU) { // //go:nosplit func bluepillSigBus(c *vCPU) { - if errno := kvmSyscallErrno( + if errno := hostsyscall.RawSyscallErrno( unix.SYS_IOCTL, uintptr(c.fd), KVM_NMI, 0); errno != 0 { diff --git a/pkg/sentry/platform/kvm/bluepill_arm64.s b/pkg/sentry/platform/kvm/bluepill_arm64.s index 32f678937..52cb7f830 100644 --- a/pkg/sentry/platform/kvm/bluepill_arm64.s +++ b/pkg/sentry/platform/kvm/bluepill_arm64.s @@ -145,38 +145,3 @@ TEXT ·addrOfDieTrampoline(SB), $0-8 MOVD $·dieTrampoline(SB), R0 MOVD R0, ret+0(FP) RET - -// func kvmSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) (errno unix.Errno) -TEXT ·kvmSyscallErrno6(SB),NOSPLIT,$0-64 - MOVD trap+0(FP), R8 // syscall entry - MOVD a1+8(FP), R0 - MOVD a2+16(FP), R1 - MOVD a3+24(FP), R2 - MOVD a4+32(FP), R3 - MOVD a5+40(FP), R4 - MOVD a6+48(FP), R5 - SVC - CMN $4095, R0 - BCC ok - NEG R0, R0 - MOVD R0, ret+56(FP) - RET -ok: - MOVD $0, ret+56(FP) - RET - -// func kvmSyscallErrno(trap, a1, a2, a3 uintptr) (errno unix.Errno) -TEXT ·kvmSyscallErrno(SB),NOSPLIT,$0-40 - MOVD trap+0(FP), R8 // syscall entry - MOVD a1+8(FP), R0 - MOVD a2+16(FP), R1 - MOVD a3+24(FP), R2 - SVC - CMN $4095, R0 - BCC ok - NEG R0, R0 - MOVD R0, ret+32(FP) - RET -ok: - MOVD ZR, ret+32(FP) - RET diff --git a/pkg/sentry/platform/kvm/bluepill_arm64_unsafe.go b/pkg/sentry/platform/kvm/bluepill_arm64_unsafe.go index 456350336..97fba4e64 100644 --- a/pkg/sentry/platform/kvm/bluepill_arm64_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_arm64_unsafe.go @@ -21,6 +21,7 @@ import ( "unsafe" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/hostsyscall" "gvisor.dev/gvisor/pkg/ring0" "gvisor.dev/gvisor/pkg/sentry/arch" ) @@ -88,7 +89,7 @@ func bluepillStopGuest(c *vCPU) { }, } - if errno := kvmSyscallErrno( // escapes: no. + if errno := hostsyscall.RawSyscallErrno( // escapes: no. unix.SYS_IOCTL, uintptr(c.fd), KVM_SET_VCPU_EVENTS, @@ -111,7 +112,7 @@ func bluepillSigBus(c *vCPU) { } // Host must support ARM64_HAS_RAS_EXTN. - if errno := kvmSyscallErrno( // escapes: no. + if errno := hostsyscall.RawSyscallErrno( // escapes: no. unix.SYS_IOCTL, uintptr(c.fd), KVM_SET_VCPU_EVENTS, @@ -134,7 +135,7 @@ func bluepillExtDabt(c *vCPU) { }, } - if errno := kvmSyscallErrno( // escapes: no. + if errno := hostsyscall.RawSyscallErrno( // escapes: no. unix.SYS_IOCTL, uintptr(c.fd), KVM_SET_VCPU_EVENTS, diff --git a/pkg/sentry/platform/kvm/bluepill_fault.go b/pkg/sentry/platform/kvm/bluepill_fault.go index d0e93d4ea..3d5a8cd1a 100644 --- a/pkg/sentry/platform/kvm/bluepill_fault.go +++ b/pkg/sentry/platform/kvm/bluepill_fault.go @@ -19,6 +19,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/hostarch" + "gvisor.dev/gvisor/pkg/hostsyscall" ) var ( @@ -40,7 +41,7 @@ var ( // //go:nosplit func yield() { - kvmSyscallErrno(unix.SYS_SCHED_YIELD, 0, 0, 0) + hostsyscall.RawSyscallErrno(unix.SYS_SCHED_YIELD, 0, 0, 0) } // calculateBluepillFault calculates the fault address range. diff --git a/pkg/sentry/platform/kvm/bluepill_unsafe.go b/pkg/sentry/platform/kvm/bluepill_unsafe.go index b6ba6ca96..8de434c1f 100644 --- a/pkg/sentry/platform/kvm/bluepill_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_unsafe.go @@ -25,17 +25,10 @@ import ( "unsafe" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/hostsyscall" "gvisor.dev/gvisor/pkg/sentry/arch" ) -// Local variants of unix.RawSyscall that use slightly less stack space. - -// kvmSyscallErrno6 only returns errno, and 0 if successful. -func kvmSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) unix.Errno - -// kvmSyscallErrno only returns errno, and 0 if successful. -func kvmSyscallErrno(trap, a1, a2, a3 uintptr) unix.Errno - //go:linkname throw runtime.throw func throw(s string) @@ -99,8 +92,8 @@ func printHex(title []byte, val uint64) { } str[0] = ' ' str[17] = '\n' - kvmSyscallErrno(unix.SYS_WRITE, uintptr(unix.Stderr), uintptr(unsafe.Pointer(&title[0])), uintptr(len(title))) - kvmSyscallErrno(unix.SYS_WRITE, uintptr(unix.Stderr), uintptr(unsafe.Pointer(&str)), 18) + hostsyscall.RawSyscallErrno(unix.SYS_WRITE, uintptr(unix.Stderr), uintptr(unsafe.Pointer(&title[0])), uintptr(len(title))) + hostsyscall.RawSyscallErrno(unix.SYS_WRITE, uintptr(unix.Stderr), uintptr(unsafe.Pointer(&str)), 18) } // bluepillHandler is called from the signal stub. diff --git a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go index 490e5350b..aff0b13d8 100644 --- a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go @@ -23,6 +23,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/hostsyscall" ) // loadSegments copies the current segments. @@ -132,7 +133,7 @@ func (c *vCPU) setTSC(value uint64) error { // //go:nosplit func (c *vCPU) setUserRegisters(uregs *userRegs) unix.Errno { - if errno := kvmSyscallErrno( + if errno := hostsyscall.RawSyscallErrno( unix.SYS_IOCTL, uintptr(c.fd), KVM_SET_REGS, @@ -148,7 +149,7 @@ func (c *vCPU) setUserRegisters(uregs *userRegs) unix.Errno { // //go:nosplit func (c *vCPU) getUserRegisters(uregs *userRegs) unix.Errno { - if errno := kvmSyscallErrno( // escapes: no. + if errno := hostsyscall.RawSyscallErrno( // escapes: no. unix.SYS_IOCTL, uintptr(c.fd), KVM_GET_REGS, @@ -160,7 +161,7 @@ func (c *vCPU) getUserRegisters(uregs *userRegs) unix.Errno { // setSystemRegisters sets system registers. func (c *vCPU) setSystemRegisters(sregs *systemRegs) error { - if errno := kvmSyscallErrno( + if errno := hostsyscall.RawSyscallErrno( unix.SYS_IOCTL, uintptr(c.fd), KVM_SET_SREGS, @@ -174,7 +175,7 @@ func (c *vCPU) setSystemRegisters(sregs *systemRegs) error { // //go:nosplit func (c *vCPU) getSystemRegisters(sregs *systemRegs) unix.Errno { - if errno := kvmSyscallErrno( + if errno := hostsyscall.RawSyscallErrno( unix.SYS_IOCTL, uintptr(c.fd), KVM_GET_SREGS, @@ -189,9 +190,9 @@ func seccompMmapSyscall(context unsafe.Pointer) (uintptr, uintptr, unix.Errno) { ctx := bluepillArchContext(context) // MAP_DENYWRITE is deprecated and ignored by kernel. We use it only for seccomp filters. - addr, _, e := unix.RawSyscall6(uintptr(ctx.Rax), uintptr(ctx.Rdi), uintptr(ctx.Rsi), + addr, _, e := hostsyscall.RawSyscall6(uintptr(ctx.Rax), uintptr(ctx.Rdi), uintptr(ctx.Rsi), uintptr(ctx.Rdx), uintptr(ctx.R10)|unix.MAP_DENYWRITE, uintptr(ctx.R8), uintptr(ctx.R9)) ctx.Rax = uint64(addr) - return addr, uintptr(ctx.Rsi), e + return addr, uintptr(ctx.Rsi), unix.Errno(e) } diff --git a/pkg/sentry/platform/kvm/machine_arm64_unsafe.go b/pkg/sentry/platform/kvm/machine_arm64_unsafe.go index f9ef16722..dbfe9f525 100644 --- a/pkg/sentry/platform/kvm/machine_arm64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_arm64_unsafe.go @@ -25,6 +25,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/hostarch" + "gvisor.dev/gvisor/pkg/hostsyscall" "gvisor.dev/gvisor/pkg/ring0" "gvisor.dev/gvisor/pkg/ring0/pagetables" "gvisor.dev/gvisor/pkg/sentry/platform" @@ -354,9 +355,9 @@ func seccompMmapSyscall(context unsafe.Pointer) (uintptr, uintptr, unix.Errno) { ctx := bluepillArchContext(context) // MAP_DENYWRITE is deprecated and ignored by kernel. We use it only for seccomp filters. - addr, _, e := unix.RawSyscall6(uintptr(ctx.Regs[8]), uintptr(ctx.Regs[0]), uintptr(ctx.Regs[1]), + addr, _, e := hostsyscall.RawSyscall6(uintptr(ctx.Regs[8]), uintptr(ctx.Regs[0]), uintptr(ctx.Regs[1]), uintptr(ctx.Regs[2]), uintptr(ctx.Regs[3])|unix.MAP_DENYWRITE, uintptr(ctx.Regs[4]), uintptr(ctx.Regs[5])) ctx.Regs[0] = uint64(addr) - return addr, uintptr(ctx.Regs[1]), e + return addr, uintptr(ctx.Regs[1]), unix.Errno(e) } diff --git a/pkg/sentry/platform/kvm/machine_unsafe.go b/pkg/sentry/platform/kvm/machine_unsafe.go index 17a338c09..6548cbf6f 100644 --- a/pkg/sentry/platform/kvm/machine_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_unsafe.go @@ -31,6 +31,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/atomicbitops" + "gvisor.dev/gvisor/pkg/hostsyscall" ) //go:linkname entersyscall runtime.entersyscall @@ -55,7 +56,7 @@ func (m *machine) setMemoryRegion(slot int, physical, length, virtual uintptr, f } // Set the region. - errno := kvmSyscallErrno( + errno := hostsyscall.RawSyscallErrno( unix.SYS_IOCTL, uintptr(m.fd), KVM_SET_USER_MEMORY_REGION, @@ -119,7 +120,7 @@ func (a *atomicAddressSpace) get() *addressSpace { // //go:nosplit func (c *vCPU) notify() { - errno := kvmSyscallErrno6( // escapes: no. + errno := hostsyscall.RawSyscallErrno6( // escapes: no. unix.SYS_FUTEX, uintptr(unsafe.Pointer(&c.state)), linux.FUTEX_WAKE|linux.FUTEX_PRIVATE_FLAG, @@ -178,7 +179,7 @@ func (c *vCPU) setSignalMask() error { // instances. var seccompMmapHandlerCnt atomicbitops.Int64 -// seccompMmapSync waits for all currently runnuing seccompMmapHandler +// seccompMmapSync waits for all currently running seccompMmapHandler // instances. // // The standard locking primitives can't be used in this case since diff --git a/pkg/sigframe/BUILD b/pkg/sigframe/BUILD index fc9dc39c3..9e6766880 100644 --- a/pkg/sigframe/BUILD +++ b/pkg/sigframe/BUILD @@ -14,6 +14,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/abi/linux", + "//pkg/hostsyscall", "//pkg/sentry/arch", "@org_golang_x_sys//unix:go_default_library", ], diff --git a/pkg/sigframe/sigframe_amd64.s b/pkg/sigframe/sigframe_amd64.s index bb86ba7e5..2252232e4 100644 --- a/pkg/sigframe/sigframe_amd64.s +++ b/pkg/sigframe/sigframe_amd64.s @@ -88,22 +88,3 @@ TEXT ·retjmp(SB),NOSPLIT,$0-0 MOVQ 8(SP), BP ADDQ $0x10,SP RET - -// func kvmSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) (ret unix.Errno) -TEXT ·kvmSyscallErrno6(SB),NOSPLIT,$0-64 - MOVQ a1+8(FP), DI - MOVQ a2+16(FP), SI - MOVQ a3+24(FP), DX - MOVQ a4+32(FP), R10 - MOVQ a5+40(FP), R8 - MOVQ a6+48(FP), R9 - MOVQ trap+0(FP), AX // syscall entry - SYSCALL - CMPQ AX, $0xfffffffffffff001 - JLS ok - NEGQ AX - MOVQ AX, ret+56(FP) // ret - RET -ok: - MOVQ $0, ret+56(FP) // ret - RET diff --git a/pkg/sigframe/sigframe_amd64_unsafe.go b/pkg/sigframe/sigframe_amd64_unsafe.go index fbcbfb747..a58e085a6 100644 --- a/pkg/sigframe/sigframe_amd64_unsafe.go +++ b/pkg/sigframe/sigframe_amd64_unsafe.go @@ -22,6 +22,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/hostsyscall" "gvisor.dev/gvisor/pkg/sentry/arch" ) @@ -30,9 +31,6 @@ func callWithSignalFrame(stack uintptr, handler uintptr, sigframe *arch.UContext //go:linkname throw runtime.throw func throw(s string) -// kvmSyscallErrno6 only returns errno, and 0 if successful. -func kvmSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) unix.Errno - // CallWithSignalFrame sets up a signal frame on the stack and executes a // user-defined callback function within that context. // @@ -41,7 +39,7 @@ func kvmSyscallErrno6(trap, a1, a2, a3, a4, a5, a6 uintptr) unix.Errno // //go:nosplit func CallWithSignalFrame(stack uintptr, handlerAddr uintptr, sigframe *arch.UContext64, fpstate uintptr, sigmask *linux.SignalSet) error { - errno := kvmSyscallErrno6( + errno := hostsyscall.RawSyscallErrno6( unix.SYS_RT_SIGPROCMASK, linux.SIG_BLOCK, uintptr(unsafe.Pointer(sigmask)), uintptr(unsafe.Pointer(&sigframe.Sigset)),