github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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  	"github.com/nicocha30/gvisor-ligolo/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  }