mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add more generic Ioctl helper functions for TPU pass through IOCTLs.
PiperOrigin-RevId: 617378718
This commit is contained in:
@@ -10,7 +10,6 @@ go_library(
|
||||
"devaddr_set.go",
|
||||
"device.go",
|
||||
"gasket.go",
|
||||
"gasket_unsafe.go",
|
||||
"seccomp_filters.go",
|
||||
"tpu_v4.go",
|
||||
"tpu_v4_mmap.go",
|
||||
@@ -30,6 +29,7 @@ go_library(
|
||||
"//pkg/safemem",
|
||||
"//pkg/seccomp",
|
||||
"//pkg/sentry/arch",
|
||||
"//pkg/sentry/devices/tpuproxy",
|
||||
"//pkg/sentry/fsimpl/eventfd",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/memmap",
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/errors/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/tpuproxy"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/eventfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/memmap"
|
||||
@@ -103,7 +104,7 @@ func gasketMapBufferIoctl(ctx context.Context, t *kernel.Task, hostFd int32, fd
|
||||
}
|
||||
sentryIoctlParams := userIoctlParams
|
||||
sentryIoctlParams.HostAddress = uint64(m)
|
||||
n, err := ioctlInvokePtrArg(hostFd, gasket.GASKET_IOCTL_MAP_BUFFER, &sentryIoctlParams)
|
||||
n, err := tpuproxy.IOCTLInvokePtrArg[gasket.Ioctl](hostFd, gasket.GASKET_IOCTL_MAP_BUFFER, &sentryIoctlParams)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
@@ -150,7 +151,7 @@ func gasketUnmapBufferIoctl(ctx context.Context, t *kernel.Task, hostFd int32, f
|
||||
|
||||
sentryIoctlParams := userIoctlParams
|
||||
sentryIoctlParams.HostAddress = 0 // clobber this value, it's unused.
|
||||
n, err := ioctlInvokePtrArg(hostFd, gasket.GASKET_IOCTL_UNMAP_BUFFER, &sentryIoctlParams)
|
||||
n, err := tpuproxy.IOCTLInvokePtrArg[gasket.Ioctl](hostFd, gasket.GASKET_IOCTL_UNMAP_BUFFER, &sentryIoctlParams)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
@@ -210,7 +211,7 @@ func gasketInterruptMappingIoctl(ctx context.Context, t *kernel.Task, hostFd int
|
||||
|
||||
sentryIoctlParams := userIoctlParams
|
||||
sentryIoctlParams.EventFD = uint64(eventfd)
|
||||
n, err := ioctlInvokePtrArg(hostFd, gasket.GASKET_IOCTL_REGISTER_INTERRUPT, &sentryIoctlParams)
|
||||
n, err := tpuproxy.IOCTLInvokePtrArg[gasket.Ioctl](hostFd, gasket.GASKET_IOCTL_REGISTER_INTERRUPT, &sentryIoctlParams)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
package accel
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/abi/gasket"
|
||||
)
|
||||
|
||||
func ioctlInvokePtrArg[Params any](hostFd int32, cmd gasket.Ioctl, params *Params) (uintptr, error) {
|
||||
return ioctlInvoke[uintptr](hostFd, cmd, uintptr(unsafe.Pointer(params)))
|
||||
}
|
||||
|
||||
func ioctlInvoke[Arg constraints.Integer](hostFd int32, cmd gasket.Ioctl, arg Arg) (uintptr, error) {
|
||||
n, _, errno := unix.RawSyscall(unix.SYS_IOCTL, uintptr(hostFd), uintptr(cmd), uintptr(arg))
|
||||
if errno != 0 {
|
||||
return n, errno
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/devices/tpuproxy"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/mm"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
@@ -67,7 +68,7 @@ func (fd *tpuV4FD) Release(context.Context) {
|
||||
Size: r.End - r.Start,
|
||||
HostAddress: 0,
|
||||
}
|
||||
_, err := ioctlInvokePtrArg(fd.hostFD, gasket.GASKET_IOCTL_UNMAP_BUFFER, &gpti)
|
||||
_, err := tpuproxy.IOCTLInvokePtrArg[gasket.Ioctl](fd.hostFD, gasket.GASKET_IOCTL_UNMAP_BUFFER, &gpti)
|
||||
if err != nil {
|
||||
log.Warningf("could not unmap range [%#x, %#x) (index %d) on device: %v", r.Start, r.End, v.pageTableIndex, err)
|
||||
}
|
||||
@@ -132,17 +133,17 @@ func (fd *tpuV4FD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, arg
|
||||
gasket.GASKET_IOCTL_MAP_DMA_BUF:
|
||||
return 0, linuxerr.ENOSYS
|
||||
case gasket.GASKET_IOCTL_RESET:
|
||||
return ioctlInvoke[uint64](fd.hostFD, gasket.GASKET_IOCTL_RESET, args[2].Uint64())
|
||||
return tpuproxy.IOCTLInvoke[gasket.Ioctl, uint64](fd.hostFD, gasket.GASKET_IOCTL_RESET, args[2].Uint64())
|
||||
case gasket.GASKET_IOCTL_MAP_BUFFER:
|
||||
return gasketMapBufferIoctl(ctx, t, fd.hostFD, fd, argPtr)
|
||||
case gasket.GASKET_IOCTL_UNMAP_BUFFER:
|
||||
return gasketUnmapBufferIoctl(ctx, t, fd.hostFD, fd, argPtr)
|
||||
case gasket.GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
|
||||
return ioctlInvoke(fd.hostFD, gasket.GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS, 0)
|
||||
return tpuproxy.IOCTLInvoke[gasket.Ioctl](fd.hostFD, gasket.GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS, 0)
|
||||
case gasket.GASKET_IOCTL_REGISTER_INTERRUPT:
|
||||
return gasketInterruptMappingIoctl(ctx, t, fd.hostFD, argPtr, fd.device.lite)
|
||||
case gasket.GASKET_IOCTL_UNREGISTER_INTERRUPT:
|
||||
return ioctlInvoke[uint64](fd.hostFD, gasket.GASKET_IOCTL_UNREGISTER_INTERRUPT, args[2].Uint64())
|
||||
return tpuproxy.IOCTLInvoke[gasket.Ioctl, uint64](fd.hostFD, gasket.GASKET_IOCTL_UNREGISTER_INTERRUPT, args[2].Uint64())
|
||||
default:
|
||||
return 0, linuxerr.EINVAL
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ go_library(
|
||||
name = "tpuproxy",
|
||||
srcs = [
|
||||
"device.go",
|
||||
"ioctl_unsafe.go",
|
||||
"seccomp_filter.go",
|
||||
"tpu.go",
|
||||
"tpu_mmap.go",
|
||||
"vfio.go",
|
||||
"vfio_mmap.go",
|
||||
"vfio_unsafe.go",
|
||||
],
|
||||
visibility = [
|
||||
"//pkg/sentry:internal",
|
||||
|
||||
+6
-3
@@ -21,11 +21,14 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func ioctlInvokePtrArg[Params any](hostFd int32, cmd uint32, params *Params) (uintptr, error) {
|
||||
return ioctlInvoke[uintptr](hostFd, cmd, uintptr(unsafe.Pointer(params)))
|
||||
// IOCTLInvokePtrArg makes ioctl syscalls with the command of the integer type
|
||||
// and the pointer to any given params.
|
||||
func IOCTLInvokePtrArg[Cmd constraints.Integer, Params any](hostFd int32, cmd Cmd, params *Params) (uintptr, error) {
|
||||
return IOCTLInvoke[Cmd, uintptr](hostFd, cmd, uintptr(unsafe.Pointer(params)))
|
||||
}
|
||||
|
||||
func ioctlInvoke[Arg constraints.Integer](hostFd int32, cmd uint32, arg Arg) (uintptr, error) {
|
||||
// IOCTLInvoke makes ioctl syscalls with the arg of the integer type.
|
||||
func IOCTLInvoke[Cmd, Arg constraints.Integer](hostFd int32, cmd Cmd, arg Arg) (uintptr, error) {
|
||||
n, _, errno := unix.RawSyscall(unix.SYS_IOCTL, uintptr(hostFd), uintptr(cmd), uintptr(arg))
|
||||
if errno != 0 {
|
||||
return n, errno
|
||||
@@ -115,7 +115,7 @@ func (fd *tpuFD) setContainer(ctx context.Context, t *kernel.Task, arg hostarch.
|
||||
if !ok {
|
||||
return 0, linuxerr.EINVAL
|
||||
}
|
||||
return ioctlInvokePtrArg(fd.hostFD, linux.VFIO_GROUP_SET_CONTAINER, &vfioContainer.hostFd)
|
||||
return IOCTLInvokePtrArg[uint32](fd.hostFD, linux.VFIO_GROUP_SET_CONTAINER, &vfioContainer.hostFd)
|
||||
}
|
||||
|
||||
// It will be the caller's responsibility to call the returned cleanup function.
|
||||
@@ -124,7 +124,7 @@ func (fd *tpuFD) getPciDeviceFd(t *kernel.Task, arg hostarch.Addr) (uintptr, fun
|
||||
if err != nil {
|
||||
return 0, func() {}, err
|
||||
}
|
||||
hostFD, err := ioctlInvokePtrArg(fd.hostFD, linux.VFIO_GROUP_GET_DEVICE_FD, &pciAddress)
|
||||
hostFD, err := IOCTLInvokePtrArg[uint32](fd.hostFD, linux.VFIO_GROUP_GET_DEVICE_FD, &pciAddress)
|
||||
if err != nil {
|
||||
return 0, func() {}, err
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ func (fd *vfioFd) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args
|
||||
func (fd *vfioFd) checkExtension(ext extension) (uintptr, error) {
|
||||
switch ext {
|
||||
case linux.VFIO_TYPE1_IOMMU, linux.VFIO_SPAPR_TCE_IOMMU, linux.VFIO_TYPE1v2_IOMMU:
|
||||
ret, err := ioctlInvoke[int32](fd.hostFd, linux.VFIO_CHECK_EXTENSION, int32(ext))
|
||||
ret, err := IOCTLInvoke[uint32, int32](fd.hostFd, linux.VFIO_CHECK_EXTENSION, int32(ext))
|
||||
if err != nil {
|
||||
log.Warningf("check VFIO extension %s: %v", ext, err)
|
||||
return 0, err
|
||||
@@ -114,7 +114,7 @@ func (fd *vfioFd) checkExtension(ext extension) (uintptr, error) {
|
||||
func (fd *vfioFd) setIOMMU(ext extension) (uintptr, error) {
|
||||
switch ext {
|
||||
case linux.VFIO_TYPE1_IOMMU, linux.VFIO_SPAPR_TCE_IOMMU, linux.VFIO_TYPE1v2_IOMMU:
|
||||
ret, err := ioctlInvoke[int32](fd.hostFd, linux.VFIO_SET_IOMMU, int32(ext))
|
||||
ret, err := IOCTLInvoke[uint32, int32](fd.hostFd, linux.VFIO_SET_IOMMU, int32(ext))
|
||||
if err != nil {
|
||||
log.Warningf("set the IOMMU group to %s: %v", ext, err)
|
||||
return 0, err
|
||||
|
||||
Reference in New Issue
Block a user