@@ -18,6 +18,7 @@ import (
1818 "fmt"
1919
2020 "gvisor.dev/gvisor/pkg/context"
21+ "gvisor.dev/gvisor/pkg/errors/linuxerr"
2122 "gvisor.dev/gvisor/pkg/hostarch"
2223 "gvisor.dev/gvisor/pkg/sentry/memmap"
2324 "gvisor.dev/gvisor/pkg/sentry/pgalloc"
@@ -172,7 +173,7 @@ func (mm *MemoryManager) Deactivate() {
172173// - ar.Length() != 0.
173174// - ar must be page-aligned.
174175// - pseg == mm.pmas.LowerBoundSegment(ar.Start).
175- func (mm * MemoryManager ) mapASLocked (pseg pmaIterator , ar hostarch.AddrRange , platformEffect memmap.MMapPlatformEffect ) error {
176+ func (mm * MemoryManager ) mapASLocked (ctx context. Context , pseg pmaIterator , ar hostarch.AddrRange , platformEffect memmap.MMapPlatformEffect ) error {
176177 // By default, map entire pmas at a time, under the assumption that there
177178 // is no cost to mapping more of a pma than necessary.
178179 mapAR := hostarch.AddrRange {0 , ^ hostarch .Addr (hostarch .PageSize - 1 )}
@@ -217,8 +218,28 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar hostarch.AddrRange, pl
217218 perms .Write = false
218219 }
219220 if perms .Any () { // MapFile precondition
220- if err := mm .as .MapFile (pmaMapAR .Start , pma .file , pseg .fileRangeOf (pmaMapAR ), perms , platformEffect == memmap .PlatformEffectCommit ); err != nil {
221- return err
221+ // If the length of the mapping exceeds singleMapThreshold, call
222+ // AddressSpace.MapFile() on singleMapThreshold-aligned chunks so
223+ // we can check ctx.Killed() reasonably frequently.
224+ const singleMapThreshold = 1 << 30
225+ if pmaMapAR .Length () <= singleMapThreshold {
226+ if err := mm .as .MapFile (pmaMapAR .Start , pma .file , pseg .fileRangeOf (pmaMapAR ), perms , platformEffect == memmap .PlatformEffectCommit ); err != nil {
227+ return err
228+ }
229+ if ctx .Killed () {
230+ return linuxerr .EINTR
231+ }
232+ } else {
233+ for windowStart := pmaMapAR .Start &^ (singleMapThreshold - 1 ); windowStart < pmaMapAR .End ; windowStart += singleMapThreshold {
234+ windowAR := hostarch.AddrRange {windowStart , windowStart + singleMapThreshold }
235+ thisMapAR := pmaMapAR .Intersect (windowAR )
236+ if err := mm .as .MapFile (thisMapAR .Start , pma .file , pseg .fileRangeOf (thisMapAR ), perms , platformEffect == memmap .PlatformEffectCommit ); err != nil {
237+ return err
238+ }
239+ if ctx .Killed () {
240+ return linuxerr .EINTR
241+ }
242+ }
222243 }
223244 }
224245 pseg = pseg .NextSegment ()
0 commit comments