Add more generic Ioctl helper functions for TPU pass through IOCTLs.

PiperOrigin-RevId: 617378718
This commit is contained in:
Jing Chen
2024-03-19 20:27:56 -07:00
committed by gVisor bot
parent 687c542721
commit 9d2a513de1
8 changed files with 21 additions and 51 deletions
+1 -1
View File
@@ -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",
+4 -3
View File
@@ -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
}
-35
View File
@@ -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
}
+5 -4
View File
@@ -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
}
+1 -1
View File
@@ -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",
@@ -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
+2 -2
View File
@@ -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
}
+2 -2
View File
@@ -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