diff options
Diffstat (limited to 'pkg/sentry/hostcpu/hostcpu.go')
-rw-r--r-- | pkg/sentry/hostcpu/hostcpu.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/pkg/sentry/hostcpu/hostcpu.go b/pkg/sentry/hostcpu/hostcpu.go new file mode 100644 index 000000000..fa46499ad --- /dev/null +++ b/pkg/sentry/hostcpu/hostcpu.go @@ -0,0 +1,67 @@ +// Copyright 2018 Google Inc. +// +// 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 hostcpu provides utilities for working with CPU information provided +// by a host Linux kernel. +package hostcpu + +import ( + "fmt" + "io/ioutil" + "strconv" + "strings" + "unicode" +) + +// GetCPU returns the caller's current CPU number, without using the Linux VDSO +// (which is not available to the sentry) or the getcpu(2) system call (which +// is relatively slow). +func GetCPU() uint32 + +// MaxPossibleCPU returns the highest possible CPU number, which is guaranteed +// not to change for the lifetime of the host kernel. +func MaxPossibleCPU() (uint32, error) { + const path = "/sys/devices/system/cpu/possible" + data, err := ioutil.ReadFile(path) + if err != nil { + return 0, err + } + str := string(data) + // Linux: drivers/base/cpu.c:show_cpus_attr() => + // include/linux/cpumask.h:cpumask_print_to_pagebuf() => + // lib/bitmap.c:bitmap_print_to_pagebuf() + i, err := maxValueInLinuxBitmap(str) + if err != nil { + return 0, fmt.Errorf("invalid %s (%q): %v", path, str, err) + } + return uint32(i), nil +} + +// maxValueInLinuxBitmap returns the maximum value specified in str, which is a +// string emitted by Linux's lib/bitmap.c:bitmap_print_to_pagebuf(list=true). +func maxValueInLinuxBitmap(str string) (uint64, error) { + str = strings.TrimSpace(str) + // Find the last decimal number in str. + idx := strings.LastIndexFunc(str, func(c rune) bool { + return !unicode.IsDigit(c) + }) + if idx != -1 { + str = str[idx+1:] + } + i, err := strconv.ParseUint(str, 10, 64) + if err != nil { + return 0, err + } + return i, nil +} |