diff --git a/pkg/abi/linux/vfio.go b/pkg/abi/linux/vfio.go index 15fe9c1a2..a778f42c7 100644 --- a/pkg/abi/linux/vfio.go +++ b/pkg/abi/linux/vfio.go @@ -61,6 +61,14 @@ const ( VFIO_REGION_INFO_FLAG_CAPS ) +// VFIOIrqInfo flags. +const ( + VFIO_IRQ_INFO_EVENTFD = 1 << iota + VFIO_IRQ_INFO_MASKABLE + VFIO_IRQ_INFO_AUTOMASKED + VFIO_IRQ_INFO_NORESIZE +) + // IOCTLs for VFIO file descriptor from include/uapi/linux/vfio.h. var ( VFIO_CHECK_EXTENSION = IO(VFIO_TYPE, VFIO_BASE+1) @@ -69,6 +77,7 @@ var ( 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) + VFIO_DEVICE_GET_IRQ_INFO = IO(VFIO_TYPE, VFIO_BASE+9) ) // VFIODeviceInfo is analogous to vfio_device_info @@ -102,3 +111,14 @@ type VFIORegionInfo struct { // Region offset from start of device fd. Offset uint64 } + +// VFIOIrqInfo is analogous to vfio_irq_info +// from include/uapi/linux/vfio.h. +// +// +marshal +type VFIOIrqInfo struct { + Argsz uint32 + Flags uint32 + Index uint32 + Count uint32 +} diff --git a/pkg/sentry/devices/tpuproxy/seccomp_filter.go b/pkg/sentry/devices/tpuproxy/seccomp_filter.go index 6920450bd..851235c0f 100644 --- a/pkg/sentry/devices/tpuproxy/seccomp_filter.go +++ b/pkg/sentry/devices/tpuproxy/seccomp_filter.go @@ -77,6 +77,10 @@ func Filters() seccomp.SyscallRules { seccomp.NonNegativeFD{}, seccomp.EqualTo(linux.VFIO_DEVICE_GET_REGION_INFO), }, + seccomp.PerArg{ + seccomp.NonNegativeFD{}, + seccomp.EqualTo(linux.VFIO_DEVICE_GET_IRQ_INFO), + }, }, }) } diff --git a/pkg/sentry/devices/tpuproxy/tpu.go b/pkg/sentry/devices/tpuproxy/tpu.go index 96beb8bce..64d9fefd8 100644 --- a/pkg/sentry/devices/tpuproxy/tpu.go +++ b/pkg/sentry/devices/tpuproxy/tpu.go @@ -229,6 +229,8 @@ func (fd *pciDeviceFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, return fd.vfioDeviceInfo(ctx, t, args[2].Pointer()) case linux.VFIO_DEVICE_GET_REGION_INFO: return fd.vfioRegionInfo(ctx, t, args[2].Pointer()) + case linux.VFIO_DEVICE_GET_IRQ_INFO: + return fd.vfioIrqInfo(ctx, t, args[2].Pointer()) } return 0, linuxerr.ENOSYS } @@ -278,3 +280,23 @@ func (fd *pciDeviceFD) vfioDeviceInfo(ctx context.Context, t *kernel.Task, arg h } return ret, nil } + +// Retrieve the device's interrupt information. +func (fd *pciDeviceFD) vfioIrqInfo(ctx context.Context, t *kernel.Task, arg hostarch.Addr) (uintptr, error) { + var irqInfo linux.VFIOIrqInfo + if _, err := irqInfo.CopyIn(t, arg); err != nil { + return 0, err + } + // Callers must set the payload's size. + if irqInfo.Argsz == 0 { + return 0, linuxerr.EINVAL + } + ret, err := IOCTLInvokePtrArg[uint32](fd.hostFD, linux.VFIO_DEVICE_GET_IRQ_INFO, &irqInfo) + if err != nil { + return 0, err + } + if _, err := irqInfo.CopyOut(t, arg); err != nil { + return 0, err + } + return ret, nil +}