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 }