Implement pass through ioctl command VFIO_DEVICE_GET_REGION_INFO.

PiperOrigin-RevId: 617760440
This commit is contained in:
Jing Chen
2024-03-21 01:27:48 -07:00
committed by gVisor bot
parent add4c98c28
commit 8739b58b61
3 changed files with 63 additions and 6 deletions
+34 -5
View File
@@ -49,13 +49,26 @@ const (
VFIO_DEVICE_FLAGS_CDX
)
// VFIO region info flags.
const (
// Region supports read.
VFIO_REGION_INFO_FLAG_READ = 1 << iota
// Region supports write.
VFIO_REGION_INFO_FLAG_WRITE
// Region supports mmap.
VFIO_REGION_INFO_FLAG_MMAP
// Info supports caps.
VFIO_REGION_INFO_FLAG_CAPS
)
// IOCTLs for VFIO file descriptor from include/uapi/linux/vfio.h.
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_GET_DEVICE_FD = IO(VFIO_TYPE, VFIO_BASE+6)
VFIO_DEVICE_GET_INFO = IO(VFIO_TYPE, VFIO_BASE+7)
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_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)
)
// VFIODeviceInfo is analogous to vfio_device_info
@@ -73,3 +86,19 @@ type VFIODeviceInfo struct {
CapOffset uint32
pad uint32
}
// VFIORegionInfo is analogous to vfio_region_info
// from include/uapi/linux/vfio.h.
//
// +marshal
type VFIORegionInfo struct {
Argsz uint32
Flags uint32
Index uint32
// Offset within info struct of first cap.
capOffset uint32
// Region size in bytes.
Size uint64
// Region offset from start of device fd.
Offset uint64
}
@@ -73,6 +73,10 @@ func Filters() seccomp.SyscallRules {
seccomp.NonNegativeFD{},
seccomp.EqualTo(linux.VFIO_DEVICE_GET_INFO),
},
seccomp.PerArg{
seccomp.NonNegativeFD{},
seccomp.EqualTo(linux.VFIO_DEVICE_GET_REGION_INFO),
},
},
})
}
+25 -1
View File
@@ -224,18 +224,42 @@ func (fd *pciDeviceFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr,
panic("Ioctl should be called from a task context")
}
switch cmd {
// TODO(b/299303493): consider making VFIO's GET_INFO commands more generic.
case linux.VFIO_DEVICE_GET_INFO:
return fd.vfioDeviceInfo(ctx, t, args[2].Pointer())
case linux.VFIO_DEVICE_GET_REGION_INFO:
return fd.vfioRegionInfo(ctx, t, args[2].Pointer())
}
return 0, linuxerr.ENOSYS
}
// Retrieve the host TPU device's region information, which could be used by
// vfio driver to setup mappings.
func (fd *pciDeviceFD) vfioRegionInfo(ctx context.Context, t *kernel.Task, arg hostarch.Addr) (uintptr, error) {
var regionInfo linux.VFIORegionInfo
if _, err := regionInfo.CopyIn(t, arg); err != nil {
return 0, err
}
if regionInfo.Argsz == 0 {
return 0, linuxerr.EINVAL
}
ret, err := IOCTLInvokePtrArg[uint32](fd.hostFD, linux.VFIO_DEVICE_GET_REGION_INFO, &regionInfo)
if err != nil {
return 0, err
}
if _, err := regionInfo.CopyOut(t, arg); err != nil {
return 0, err
}
return ret, nil
}
// Retrieve the host TPU device's information.
func (fd *pciDeviceFD) vfioDeviceInfo(ctx context.Context, t *kernel.Task, arg hostarch.Addr) (uintptr, error) {
var deviceInfo linux.VFIODeviceInfo
if _, err := deviceInfo.CopyIn(t, arg); err != nil {
return 0, err
}
// Callers must set VFIODevice.Argsz.
// Callers must set VFIODeviceInfo.Argsz.
if deviceInfo.Argsz == 0 {
return 0, linuxerr.EINVAL
}