github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/sentry/devices/accel/device.go (about) 1 // Copyright 2023 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package accel 16 17 import ( 18 "fmt" 19 20 "golang.org/x/sys/unix" 21 "github.com/nicocha30/gvisor-ligolo/pkg/abi/linux" 22 "github.com/nicocha30/gvisor-ligolo/pkg/context" 23 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/fsimpl/devtmpfs" 24 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/vfs" 25 ) 26 27 // accelDevice implements vfs.Device for /dev/accel[0-9]+. 28 // 29 // +stateify savable 30 type accelDevice struct { 31 minor uint32 32 } 33 34 func (dev *accelDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) { 35 hostPath := fmt.Sprintf("/dev/accel%d", dev.minor) 36 hostFD, err := unix.Openat(-1, hostPath, int((opts.Flags&unix.O_ACCMODE)|unix.O_NOFOLLOW), 0) 37 if err != nil { 38 ctx.Warningf("accelDevice: failed to open host %s: %v", hostPath, err) 39 return nil, err 40 } 41 fd := &accelFD{ 42 hostFD: int32(hostFD), 43 } 44 if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{ 45 UseDentryMetadata: true, 46 }); err != nil { 47 unix.Close(hostFD) 48 return nil, err 49 } 50 return &fd.vfsfd, nil 51 } 52 53 // CreateDevtmpfsFile creates a /dev/accel[0-9]+ device file. 54 func CreateDevtmpfsFile(ctx context.Context, dev *devtmpfs.Accessor, num uint32) error { 55 return dev.CreateDeviceFile(ctx, fmt.Sprintf("accel%d", num), vfs.CharDevice, linux.ACCEL_MAJOR, num, 0666) 56 } 57 58 // Register registers all devices implemented by this package in vfsObj. 59 func Register(vfsObj *vfs.VirtualFilesystem, minor uint32) error { 60 return vfsObj.RegisterDevice(vfs.CharDevice, linux.ACCEL_MAJOR, minor, &accelDevice{ 61 minor: minor, 62 }, &vfs.RegisterDeviceOptions{ 63 GroupName: "accel", 64 }) 65 }