gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/mm/save_restore.go (about) 1 // Copyright 2018 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 package mm 16 17 import ( 18 goContext "context" 19 "fmt" 20 21 "gvisor.dev/gvisor/pkg/context" 22 "gvisor.dev/gvisor/pkg/sentry/pgalloc" 23 ) 24 25 // InvalidateUnsavable invokes memmap.Mappable.InvalidateUnsavable on all 26 // Mappables mapped by mm. 27 func (mm *MemoryManager) InvalidateUnsavable(ctx context.Context) error { 28 mm.mappingMu.RLock() 29 defer mm.mappingMu.RUnlock() 30 for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { 31 if vma := vseg.ValuePtr(); vma.mappable != nil { 32 if err := vma.mappable.InvalidateUnsavable(ctx); err != nil { 33 return err 34 } 35 } 36 } 37 return nil 38 } 39 40 // afterLoad is invoked by stateify. 41 func (mm *MemoryManager) afterLoad(ctx goContext.Context) { 42 mm.mf = pgalloc.MemoryFileFromContext(ctx) 43 mm.haveASIO = mm.p.SupportsAddressSpaceIO() 44 } 45 46 // afterLoad is invoked by stateify. 47 func (m *SpecialMappable) afterLoad(ctx goContext.Context) { 48 m.mf = pgalloc.MemoryFileFromContext(ctx) 49 } 50 51 const ( 52 vmaRealPermsRead = 1 << iota 53 vmaRealPermsWrite 54 vmaRealPermsExecute 55 vmaEffectivePermsRead 56 vmaEffectivePermsWrite 57 vmaEffectivePermsExecute 58 vmaMaxPermsRead 59 vmaMaxPermsWrite 60 vmaMaxPermsExecute 61 vmaPrivate 62 vmaGrowsDown 63 ) 64 65 func (v *vma) saveRealPerms() int { 66 var b int 67 if v.realPerms.Read { 68 b |= vmaRealPermsRead 69 } 70 if v.realPerms.Write { 71 b |= vmaRealPermsWrite 72 } 73 if v.realPerms.Execute { 74 b |= vmaRealPermsExecute 75 } 76 if v.effectivePerms.Read { 77 b |= vmaEffectivePermsRead 78 } 79 if v.effectivePerms.Write { 80 b |= vmaEffectivePermsWrite 81 } 82 if v.effectivePerms.Execute { 83 b |= vmaEffectivePermsExecute 84 } 85 if v.maxPerms.Read { 86 b |= vmaMaxPermsRead 87 } 88 if v.maxPerms.Write { 89 b |= vmaMaxPermsWrite 90 } 91 if v.maxPerms.Execute { 92 b |= vmaMaxPermsExecute 93 } 94 if v.private { 95 b |= vmaPrivate 96 } 97 if v.growsDown { 98 b |= vmaGrowsDown 99 } 100 return b 101 } 102 103 func (v *vma) loadRealPerms(_ goContext.Context, b int) { 104 if b&vmaRealPermsRead > 0 { 105 v.realPerms.Read = true 106 } 107 if b&vmaRealPermsWrite > 0 { 108 v.realPerms.Write = true 109 } 110 if b&vmaRealPermsExecute > 0 { 111 v.realPerms.Execute = true 112 } 113 if b&vmaEffectivePermsRead > 0 { 114 v.effectivePerms.Read = true 115 } 116 if b&vmaEffectivePermsWrite > 0 { 117 v.effectivePerms.Write = true 118 } 119 if b&vmaEffectivePermsExecute > 0 { 120 v.effectivePerms.Execute = true 121 } 122 if b&vmaMaxPermsRead > 0 { 123 v.maxPerms.Read = true 124 } 125 if b&vmaMaxPermsWrite > 0 { 126 v.maxPerms.Write = true 127 } 128 if b&vmaMaxPermsExecute > 0 { 129 v.maxPerms.Execute = true 130 } 131 if b&vmaPrivate > 0 { 132 v.private = true 133 } 134 if b&vmaGrowsDown > 0 { 135 v.growsDown = true 136 } 137 } 138 139 func (p *pma) saveFile() string { 140 mf, ok := p.file.(*pgalloc.MemoryFile) 141 if !ok { 142 // InvalidateUnsavable should have caused all such pmas to be 143 // invalidated. 144 panic(fmt.Sprintf("Can't save pma with non-MemoryFile of type %T", p.file)) 145 } 146 if !mf.IsSavable() { 147 panic(fmt.Sprintf("Can't save pma because its MemoryFile is not savable: %v", mf)) 148 } 149 return mf.RestoreID() 150 } 151 152 func (p *pma) loadFile(ctx goContext.Context, restoreID string) { 153 if restoreID == "" { 154 p.file = pgalloc.MemoryFileFromContext(ctx) 155 return 156 } 157 mfmap := pgalloc.MemoryFileMapFromContext(ctx) 158 mf, ok := mfmap[restoreID] 159 if !ok { 160 panic(fmt.Sprintf("can't restore pma because its MemoryFile's restore ID %q was not found in CtxMemoryFileMap", restoreID)) 161 } 162 p.file = mf 163 }