diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-10-08 23:26:15 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-10-08 23:26:15 +0000 |
commit | 6dbae823016113920fa330f4a90c08cce10a5b88 (patch) | |
tree | 8e9f45249240ff80ed1bcc0b2586bd9f74a8a594 /pkg/sentry/syscalls/linux | |
parent | 0482839af380d44348da12e87886f83b9ccf4393 (diff) | |
parent | 6bad4851d4a04b5f56ade1f8ba68bd9c16471533 (diff) |
Merge release-20200928.0-72-g6bad4851d (automated)
Diffstat (limited to 'pkg/sentry/syscalls/linux')
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_membarrier.go | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_membarrier.go b/pkg/sentry/syscalls/linux/sys_membarrier.go index 288cd8512..63ee5d435 100644 --- a/pkg/sentry/syscalls/linux/sys_membarrier.go +++ b/pkg/sentry/syscalls/linux/sys_membarrier.go @@ -24,47 +24,80 @@ import ( // Membarrier implements syscall membarrier(2). func Membarrier(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { cmd := args[0].Int() - flags := args[1].Int() - - p := t.Kernel().Platform - if !p.HaveGlobalMemoryBarrier() { - // Event for applications that want membarrier on a configuration that - // doesn't support them. - t.Kernel().EmitUnimplementedEvent(t) - return 0, nil, syserror.ENOSYS - } - - if flags != 0 { - return 0, nil, syserror.EINVAL - } + flags := args[1].Uint() switch cmd { case linux.MEMBARRIER_CMD_QUERY: - const supportedCommands = linux.MEMBARRIER_CMD_GLOBAL | - linux.MEMBARRIER_CMD_GLOBAL_EXPEDITED | - linux.MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED | - linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED | - linux.MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED + if flags != 0 { + return 0, nil, syserror.EINVAL + } + var supportedCommands uintptr + if t.Kernel().Platform.HaveGlobalMemoryBarrier() { + supportedCommands |= linux.MEMBARRIER_CMD_GLOBAL | + linux.MEMBARRIER_CMD_GLOBAL_EXPEDITED | + linux.MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED | + linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED | + linux.MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED + } + if t.RSeqAvailable() { + supportedCommands |= linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ | + linux.MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ + } return supportedCommands, nil, nil - case linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED: - if !t.MemoryManager().IsMembarrierPrivateEnabled() { + case linux.MEMBARRIER_CMD_GLOBAL, linux.MEMBARRIER_CMD_GLOBAL_EXPEDITED, linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED: + if flags != 0 { + return 0, nil, syserror.EINVAL + } + if !t.Kernel().Platform.HaveGlobalMemoryBarrier() { + return 0, nil, syserror.EINVAL + } + if cmd == linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED && !t.MemoryManager().IsMembarrierPrivateEnabled() { return 0, nil, syserror.EPERM } - fallthrough - case linux.MEMBARRIER_CMD_GLOBAL, linux.MEMBARRIER_CMD_GLOBAL_EXPEDITED: - return 0, nil, p.GlobalMemoryBarrier() + return 0, nil, t.Kernel().Platform.GlobalMemoryBarrier() case linux.MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: + if flags != 0 { + return 0, nil, syserror.EINVAL + } + if !t.Kernel().Platform.HaveGlobalMemoryBarrier() { + return 0, nil, syserror.EINVAL + } // no-op return 0, nil, nil case linux.MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: + if flags != 0 { + return 0, nil, syserror.EINVAL + } + if !t.Kernel().Platform.HaveGlobalMemoryBarrier() { + return 0, nil, syserror.EINVAL + } t.MemoryManager().EnableMembarrierPrivate() return 0, nil, nil - case linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, linux.MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: - // We're aware of these, but they aren't implemented since no platform - // supports them yet. - t.Kernel().EmitUnimplementedEvent(t) - fallthrough + case linux.MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ: + if flags&^linux.MEMBARRIER_CMD_FLAG_CPU != 0 { + return 0, nil, syserror.EINVAL + } + if !t.RSeqAvailable() { + return 0, nil, syserror.EINVAL + } + if !t.MemoryManager().IsMembarrierRSeqEnabled() { + return 0, nil, syserror.EPERM + } + // MEMBARRIER_CMD_FLAG_CPU and cpu_id are ignored since we don't have + // the ability to preempt specific CPUs. + return 0, nil, t.Kernel().Platform.PreemptAllCPUs() + case linux.MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: + if flags != 0 { + return 0, nil, syserror.EINVAL + } + if !t.RSeqAvailable() { + return 0, nil, syserror.EINVAL + } + t.MemoryManager().EnableMembarrierRSeq() + return 0, nil, nil default: + // Probably a command we don't implement. + t.Kernel().EmitUnimplementedEvent(t) return 0, nil, syserror.EINVAL } } |