github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/cpuid/static_amd64.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 amd64
    16  // +build amd64
    17  
    18  package cpuid
    19  
    20  // Static is a static CPUID function.
    21  //
    22  // +stateify savable
    23  type Static map[In]Out
    24  
    25  // Fixed converts the FeatureSet to a fixed set.
    26  func (fs FeatureSet) Fixed() FeatureSet {
    27  	return fs.ToStatic().ToFeatureSet()
    28  }
    29  
    30  // ToStatic converts a FeatureSet to a Static function.
    31  //
    32  // You can create a new static feature set as:
    33  //
    34  //	fs := otherFeatureSet.ToStatic().ToFeatureSet()
    35  func (fs FeatureSet) ToStatic() Static {
    36  	s := make(Static)
    37  
    38  	// Save all allowed top-level functions.
    39  	for fn, allowed := range allowedBasicFunctions {
    40  		if allowed {
    41  			in := In{Eax: uint32(fn)}
    42  			s[in] = fs.Query(in)
    43  		}
    44  	}
    45  
    46  	// Save all allowed extended functions.
    47  	for fn, allowed := range allowedExtendedFunctions {
    48  		if allowed {
    49  			in := In{Eax: uint32(fn) + uint32(extendedStart)}
    50  			s[in] = fs.Query(in)
    51  		}
    52  	}
    53  
    54  	// Save all features (may be redundant).
    55  	for feature := range allFeatures {
    56  		feature.set(s, fs.HasFeature(feature))
    57  	}
    58  
    59  	// Processor Extended State Enumeration.
    60  	for i := uint32(0); i < xSaveInfoNumLeaves; i++ {
    61  		in := In{Eax: uint32(xSaveInfo), Ecx: i}
    62  		s[in] = fs.Query(in)
    63  	}
    64  
    65  	// Save all cache information.
    66  	out := fs.Query(In{Eax: uint32(featureInfo)})
    67  	for i := uint32(0); i < out.Ecx; i++ {
    68  		in := In{Eax: uint32(intelDeterministicCacheParams), Ecx: i}
    69  		out := fs.Query(in)
    70  		s[in] = out
    71  		if CacheType(out.Eax&0xf) == cacheNull {
    72  			break
    73  		}
    74  	}
    75  
    76  	return s
    77  }
    78  
    79  // ToFeatureSet converts a static specification to a FeatureSet.
    80  //
    81  // This overloads some local values, where required.
    82  func (s Static) ToFeatureSet() FeatureSet {
    83  	// Make a copy.
    84  	ns := make(Static)
    85  	for k, v := range s {
    86  		ns[k] = v
    87  	}
    88  	ns.normalize()
    89  	return FeatureSet{ns, hwCap{}}
    90  }
    91  
    92  // afterLoad calls normalize.
    93  func (s Static) afterLoad() {
    94  	s.normalize()
    95  }
    96  
    97  // normalize normalizes FPU sizes.
    98  func (s Static) normalize() {
    99  	// Override local FPU sizes, which must be fixed.
   100  	fs := FeatureSet{s, hwCap{}}
   101  	if fs.HasFeature(X86FeatureXSAVE) {
   102  		in := In{Eax: uint32(xSaveInfo)}
   103  		out := s[in]
   104  		out.Ecx = maxXsaveSize
   105  		out.Ebx = xsaveSize
   106  		s[in] = out
   107  	}
   108  }
   109  
   110  // Add adds a feature.
   111  func (s Static) Add(feature Feature) Static {
   112  	feature.set(s, true)
   113  	return s
   114  }
   115  
   116  // Remove removes a feature.
   117  func (s Static) Remove(feature Feature) Static {
   118  	feature.set(s, false)
   119  	return s
   120  }
   121  
   122  // Set implements ChangeableSet.Set.
   123  func (s Static) Set(in In, out Out) {
   124  	s[in] = out
   125  }
   126  
   127  // Query implements Function.Query.
   128  func (s Static) Query(in In) Out {
   129  	in.normalize()
   130  	return s[in]
   131  }