diff --git a/pkg/abi/linux/vfio.go b/pkg/abi/linux/vfio.go index d77a5a367..ed821a6d8 100644 --- a/pkg/abi/linux/vfio.go +++ b/pkg/abi/linux/vfio.go @@ -115,6 +115,7 @@ var ( VFIO_CHECK_EXTENSION = IO(VFIO_TYPE, VFIO_BASE+1) VFIO_SET_IOMMU = IO(VFIO_TYPE, VFIO_BASE+2) VFIO_GROUP_SET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+4) + VFIO_GROUP_UNSET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+5) VFIO_GROUP_GET_DEVICE_FD = IO(VFIO_TYPE, VFIO_BASE+6) VFIO_DEVICE_GET_INFO = IO(VFIO_TYPE, VFIO_BASE+7) VFIO_DEVICE_GET_REGION_INFO = IO(VFIO_TYPE, VFIO_BASE+8) diff --git a/pkg/sentry/devices/tpuproxy/seccomp_filter.go b/pkg/sentry/devices/tpuproxy/seccomp_filter.go index 696e20e70..561a952df 100644 --- a/pkg/sentry/devices/tpuproxy/seccomp_filter.go +++ b/pkg/sentry/devices/tpuproxy/seccomp_filter.go @@ -92,6 +92,10 @@ func Filters() seccomp.SyscallRules { seccomp.NonNegativeFD{}, seccomp.EqualTo(linux.VFIO_GROUP_SET_CONTAINER), }, + seccomp.PerArg{ + seccomp.NonNegativeFD{}, + seccomp.EqualTo(linux.VFIO_GROUP_UNSET_CONTAINER), + }, seccomp.PerArg{ seccomp.NonNegativeFD{}, seccomp.EqualTo(linux.VFIO_IOMMU_MAP_DMA), diff --git a/pkg/sentry/devices/tpuproxy/vfio/pci_device_fd.go b/pkg/sentry/devices/tpuproxy/vfio/pci_device_fd.go index 61ce17d68..f446de3b2 100644 --- a/pkg/sentry/devices/tpuproxy/vfio/pci_device_fd.go +++ b/pkg/sentry/devices/tpuproxy/vfio/pci_device_fd.go @@ -23,6 +23,7 @@ import ( "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/fdnotifier" "gvisor.dev/gvisor/pkg/hostarch" + "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/marshal/primitive" "gvisor.dev/gvisor/pkg/sentry/arch" "gvisor.dev/gvisor/pkg/sentry/devices/tpuproxy/util" @@ -67,7 +68,9 @@ func (fd *pciDeviceFD) Release(context.Context) { } fdnotifier.RemoveFD(fd.hostFD) fd.queue.Notify(waiter.EventHUp) - unix.Close(int(fd.hostFD)) + if err := unix.Close(int(fd.hostFD)); err != nil { + log.Warningf("close(%d) pciDeviceFD failed: %v", fd.hostFD, err) + } } // EventRegister implements waiter.Waitable.EventRegister. diff --git a/pkg/sentry/devices/tpuproxy/vfio/tpu_fd.go b/pkg/sentry/devices/tpuproxy/vfio/tpu_fd.go index e1f193d7b..7d101261e 100644 --- a/pkg/sentry/devices/tpuproxy/vfio/tpu_fd.go +++ b/pkg/sentry/devices/tpuproxy/vfio/tpu_fd.go @@ -23,6 +23,7 @@ import ( "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/fdnotifier" "gvisor.dev/gvisor/pkg/hostarch" + "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/marshal/primitive" "gvisor.dev/gvisor/pkg/sentry/arch" "gvisor.dev/gvisor/pkg/sentry/devices/tpuproxy/util" @@ -80,7 +81,9 @@ func (fd *tpuFD) Release(context.Context) { } fdnotifier.RemoveFD(fd.hostFD) fd.queue.Notify(waiter.EventHUp) - unix.Close(int(fd.hostFD)) + if err := unix.Close(int(fd.hostFD)); err != nil { + log.Warningf("close(%d) tpuFD failed: %v", fd.hostFD, err) + } } // EventRegister implements waiter.Waitable.EventRegister. @@ -134,6 +137,8 @@ func (fd *tpuFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args switch cmd { case linux.VFIO_GROUP_SET_CONTAINER: return fd.setContainer(ctx, t, args[2].Pointer()) + case linux.VFIO_GROUP_UNSET_CONTAINER: + return util.IOCTLInvoke[uint32, uintptr](fd.hostFD, linux.VFIO_GROUP_UNSET_CONTAINER, 0) case linux.VFIO_GROUP_GET_DEVICE_FD: ret, cleanup, err := fd.getPciDeviceFd(t, args[2].Pointer()) defer cleanup() @@ -194,6 +199,7 @@ func (fd *tpuFD) getPciDeviceFd(t *kernel.Task, arg hostarch.Addr) (uintptr, fun if err := fdnotifier.AddFD(int32(hostFD), &fd.queue); err != nil { return 0, cleanup, err } + defer pciDevFD.vfsfd.DecRef(t) newFD, err := t.NewFDFrom(0, &pciDevFD.vfsfd, kernel.FDFlags{}) if err != nil { return 0, cleanup, err diff --git a/pkg/sentry/devices/tpuproxy/vfio/vfio_fd.go b/pkg/sentry/devices/tpuproxy/vfio/vfio_fd.go index cf99c6702..25eb6fc9d 100644 --- a/pkg/sentry/devices/tpuproxy/vfio/vfio_fd.go +++ b/pkg/sentry/devices/tpuproxy/vfio/vfio_fd.go @@ -72,7 +72,9 @@ func (fd *vfioFD) Release(context.Context) { fd.unpinRange(DevAddrRange{0, ^uint64(0)}) fdnotifier.RemoveFD(fd.hostFD) fd.queue.Notify(waiter.EventHUp) - unix.Close(int(fd.hostFD)) + if err := unix.Close(int(fd.hostFD)); err != nil { + log.Warningf("close(%d) vfioFD failed: %v", fd.hostFD, err) + } } // EventRegister implements waiter.Waitable.EventRegister.