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