diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index fa4009aae..e29655591 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -1,4 +1,5 @@ -load("//tools:defs.bzl", "go_library", "go_test") +load("//tools:defs.bzl", "arch_genrule", "go_library", "go_test") +load("//tools/nogo:defs.bzl", "nogo_facts") # Package linux contains the constants and types needed to interface with a # Linux kernel. It should be used instead of syscall or golang.org/x/sys/unix @@ -6,6 +7,19 @@ load("//tools:defs.bzl", "go_library", "go_test") package(licenses = ["notice"]) +nogo_facts( + name = "iouring_offsets", + srcs = ["iouring.go"], + output = "iouring_offsets_impl.go", + template = "iouring_offsets.tmpl", +) + +arch_genrule( + name = "iouring_offsets_arch", + src = ":iouring_offsets", + template = "iouring_offsets_%s.go", +) + go_library( name = "linux", srcs = [ @@ -74,6 +88,7 @@ go_library( "utsname.go", "wait.go", "xattr.go", + ":iouring_offsets_arch", ], marshal = True, visibility = ["//visibility:public"], diff --git a/pkg/abi/linux/iouring.go b/pkg/abi/linux/iouring.go index b13056cad..691701af2 100644 --- a/pkg/abi/linux/iouring.go +++ b/pkg/abi/linux/iouring.go @@ -14,11 +14,6 @@ package linux -import ( - "fmt" - "reflect" -) - // Constants for io_uring_setup(2). See include/uapi/linux/io_uring.h. const ( IORING_SETUP_IOPOLL = (1 << 0) @@ -156,36 +151,3 @@ type IORings struct { // Linux has an additional field struct io_uring_cqe cqes[], which represents // a dynamic array. We don't include it here in order to enable marshalling. } - -// PreComputedIOSqRingOffsets stores precomputed values for IOSqRingOffsets. -var PreComputedIOSqRingOffsets IOSqRingOffsets - -// PreComputedIOCqRingOffsets stores precomputed values for IOCqRingOffsets. -var PreComputedIOCqRingOffsets IOCqRingOffsets - -func init() { - ioRingsType := reflect.TypeOf((*IORings)(nil)).Elem() - ioUringType := reflect.TypeOf((*IOUring)(nil)).Elem() - - offsetof := func(ty reflect.Type, name string) uint32 { - if f, ok := ty.FieldByName(name); ok { - return uint32(f.Offset) - } - panic(fmt.Sprintf("In type %q, no field named %q", ty.Name(), name)) - } - - PreComputedIOSqRingOffsets.Head = offsetof(ioRingsType, "sq") + offsetof(ioUringType, "head") - PreComputedIOSqRingOffsets.Tail = offsetof(ioRingsType, "sq") + offsetof(ioUringType, "tail") - PreComputedIOSqRingOffsets.RingMask = offsetof(ioRingsType, "sqRingMask") - PreComputedIOSqRingOffsets.RingEntries = offsetof(ioRingsType, "sqRingEntries") - PreComputedIOSqRingOffsets.Flags = offsetof(ioRingsType, "sqFlags") - PreComputedIOSqRingOffsets.Dropped = offsetof(ioRingsType, "sqDropped") - - PreComputedIOCqRingOffsets.Head = offsetof(ioRingsType, "cq") + offsetof(ioUringType, "head") - PreComputedIOCqRingOffsets.Tail = offsetof(ioRingsType, "cq") + offsetof(ioUringType, "tail") - PreComputedIOCqRingOffsets.RingMask = offsetof(ioRingsType, "cqRingMask") - PreComputedIOCqRingOffsets.RingEntries = offsetof(ioRingsType, "cqRingEntries") - PreComputedIOCqRingOffsets.Overflow = offsetof(ioRingsType, "cqOverflow") - PreComputedIOCqRingOffsets.Flags = offsetof(ioRingsType, "cqFlags") - -} diff --git a/pkg/abi/linux/iouring_offsets.tmpl b/pkg/abi/linux/iouring_offsets.tmpl new file mode 100644 index 000000000..61f581c85 --- /dev/null +++ b/pkg/abi/linux/iouring_offsets.tmpl @@ -0,0 +1,39 @@ +// Copyright 2022 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package linux + +// PreComputedIOSqRingOffsets returns precomputed values for IOSqRingOffsets. +func PreComputedIOSqRingOffsets() IOSqRingOffsets { + return IOSqRingOffsets{ + Head: {{ .IORings.sq.Offset }} + {{ .IOUring.head.Offset }}, + Tail: {{ .IORings.sq.Offset }} + {{ .IOUring.tail.Offset }}, + RingMask: {{ .IORings.sqRingMask.Offset }}, + RingEntries: {{ .IORings.sqRingEntries.Offset }}, + Flags: {{ .IORings.sqFlags.Offset }}, + Dropped: {{ .IORings.sqDropped.Offset }}, + } +} + +// PreComputedIOCqRingOffsets returns precomputed values for IOCqRingOffsets. +func PreComputedIOCqRingOffsets() IOCqRingOffsets { + return IOCqRingOffsets { + Head: {{ .IORings.cq.Offset }} + {{ .IOUring.head.Offset }}, + Tail: {{ .IORings.cq.Offset }} + {{ .IOUring.tail.Offset }}, + RingMask: {{ .IORings.cqRingMask.Offset }}, + RingEntries: {{ .IORings.cqRingEntries.Offset }}, + Overflow: {{ .IORings.cqOverflow.Offset }}, + Flags: {{ .IORings.cqFlags.Offset }}, + } +} diff --git a/pkg/sentry/fsimpl/iouringfs/iouringfs.go b/pkg/sentry/fsimpl/iouringfs/iouringfs.go index 7ba8d525b..1c870fbdd 100644 --- a/pkg/sentry/fsimpl/iouringfs/iouringfs.go +++ b/pkg/sentry/fsimpl/iouringfs/iouringfs.go @@ -137,7 +137,7 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par return nil, linuxerr.EOVERFLOW } - params.SqOff = linux.PreComputedIOSqRingOffsets + params.SqOff = linux.PreComputedIOSqRingOffsets() params.SqOff.Array = uint32(arrayOffset) cqesOffset := uint64(hostarch.Addr((*linux.IORings)(nil).SizeBytes())) @@ -146,7 +146,7 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par return nil, linuxerr.EOVERFLOW } - params.CqOff = linux.PreComputedIOCqRingOffsets + params.CqOff = linux.PreComputedIOCqRingOffsets() params.CqOff.Cqes = uint32(cqesOffset) // Set features supported by the current IO_URING implementation.