gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/cpuid/native_arm64.go (about) 1 // Copyright 2019 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 //go:build arm64 16 // +build arm64 17 18 package cpuid 19 20 import ( 21 "io/ioutil" 22 "runtime" 23 "strconv" 24 "strings" 25 26 "gvisor.dev/gvisor/pkg/log" 27 ) 28 29 // hostFeatureSet is initialized at startup. 30 // 31 // This is copied for HostFeatureSet, below. 32 var hostFeatureSet FeatureSet 33 34 // HostFeatureSet returns a copy of the host FeatureSet. 35 func HostFeatureSet() FeatureSet { 36 return hostFeatureSet 37 } 38 39 // Fixed returns the same feature set. 40 func (fs FeatureSet) Fixed() FeatureSet { 41 return fs 42 } 43 44 // Reads CPU information from host /proc/cpuinfo. 45 // 46 // Must run before syscall filter installation. This value is used to create 47 // the fake /proc/cpuinfo from a FeatureSet. 48 func initCPUInfo() { 49 if runtime.GOOS != "linux" { 50 // Don't try to read Linux-specific /proc files or 51 // warn about them not existing. 52 return 53 } 54 cpuinfob, err := ioutil.ReadFile("/proc/cpuinfo") 55 if err != nil { 56 // Leave everything at 0, nothing can be done. 57 log.Warningf("Could not read /proc/cpuinfo: %v", err) 58 return 59 } 60 cpuinfo := string(cpuinfob) 61 62 // We get the value straight from host /proc/cpuinfo. 63 for _, line := range strings.Split(cpuinfo, "\n") { 64 switch { 65 case strings.Contains(line, "BogoMIPS"): 66 splitMHz := strings.Split(line, ":") 67 if len(splitMHz) < 2 { 68 log.Warningf("Could not read /proc/cpuinfo: malformed BogoMIPS") 69 break 70 } 71 72 // If there was a problem, leave cpuFreqMHz as 0. 73 var err error 74 hostFeatureSet.cpuFreqMHz, err = strconv.ParseFloat(strings.TrimSpace(splitMHz[1]), 64) 75 if err != nil { 76 hostFeatureSet.cpuFreqMHz = 0.0 77 log.Warningf("Could not parse BogoMIPS value %v: %v", splitMHz[1], err) 78 } 79 case strings.Contains(line, "CPU implementer"): 80 splitImpl := strings.Split(line, ":") 81 if len(splitImpl) < 2 { 82 log.Warningf("Could not read /proc/cpuinfo: malformed CPU implementer") 83 break 84 } 85 86 // If there was a problem, leave cpuImplHex as 0. 87 var err error 88 hostFeatureSet.cpuImplHex, err = strconv.ParseUint(strings.TrimSpace(splitImpl[1]), 0, 64) 89 if err != nil { 90 hostFeatureSet.cpuImplHex = 0 91 log.Warningf("Could not parse CPU implementer value %v: %v", splitImpl[1], err) 92 } 93 case strings.Contains(line, "CPU architecture"): 94 splitArch := strings.Split(line, ":") 95 if len(splitArch) < 2 { 96 log.Warningf("Could not read /proc/cpuinfo: malformed CPU architecture") 97 break 98 } 99 100 // If there was a problem, leave cpuArchDec as 0. 101 var err error 102 hostFeatureSet.cpuArchDec, err = strconv.ParseUint(strings.TrimSpace(splitArch[1]), 0, 64) 103 if err != nil { 104 hostFeatureSet.cpuArchDec = 0 105 log.Warningf("Could not parse CPU architecture value %v: %v", splitArch[1], err) 106 } 107 case strings.Contains(line, "CPU variant"): 108 splitVar := strings.Split(line, ":") 109 if len(splitVar) < 2 { 110 log.Warningf("Could not read /proc/cpuinfo: malformed CPU variant") 111 break 112 } 113 114 // If there was a problem, leave cpuVarHex as 0. 115 var err error 116 hostFeatureSet.cpuVarHex, err = strconv.ParseUint(strings.TrimSpace(splitVar[1]), 0, 64) 117 if err != nil { 118 hostFeatureSet.cpuVarHex = 0 119 log.Warningf("Could not parse CPU variant value %v: %v", splitVar[1], err) 120 } 121 case strings.Contains(line, "CPU part"): 122 splitPart := strings.Split(line, ":") 123 if len(splitPart) < 2 { 124 log.Warningf("Could not read /proc/cpuinfo: malformed CPU part") 125 break 126 } 127 128 // If there was a problem, leave cpuPartHex as 0. 129 var err error 130 hostFeatureSet.cpuPartHex, err = strconv.ParseUint(strings.TrimSpace(splitPart[1]), 0, 64) 131 if err != nil { 132 hostFeatureSet.cpuPartHex = 0 133 log.Warningf("Could not parse CPU part value %v: %v", splitPart[1], err) 134 } 135 case strings.Contains(line, "CPU revision"): 136 splitRev := strings.Split(line, ":") 137 if len(splitRev) < 2 { 138 log.Warningf("Could not read /proc/cpuinfo: malformed CPU revision") 139 break 140 } 141 142 // If there was a problem, leave cpuRevDec as 0. 143 var err error 144 hostFeatureSet.cpuRevDec, err = strconv.ParseUint(strings.TrimSpace(splitRev[1]), 0, 64) 145 if err != nil { 146 hostFeatureSet.cpuRevDec = 0 147 log.Warningf("Could not parse CPU revision value %v: %v", splitRev[1], err) 148 } 149 } 150 } 151 } 152 153 // archInitialize initializes hostFeatureSet. 154 func archInitialize() { 155 initCPUInfo() 156 initHWCap() 157 }