Implement pass through ioctl command VFIO_DEVICE_GET_IRQ_INFO.

PiperOrigin-RevId: 618034948
This commit is contained in:
Jing Chen
2024-03-21 19:40:16 -07:00
committed by gVisor bot
parent 641a1a56b8
commit 24251f576d
3 changed files with 46 additions and 0 deletions
+20
View File
@@ -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
}
@@ -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),
},
},
})
}
+22
View File
@@ -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
}