platform/kvm: Disable async preemption while mapping initial virtual regions.

All new mappings are handled from the SIGSYS signal handler and we have to
guarantee that the signal handler doesn't race with the code that handles
initial regions.

PiperOrigin-RevId: 453521202
This commit is contained in:
Andrei Vagin
2022-06-07 14:10:10 -07:00
committed by gVisor bot
parent 06f7b645e6
commit 2e0ff5d9d0
2 changed files with 25 additions and 0 deletions
+5
View File
@@ -318,6 +318,10 @@ func newMachine(vm int) (*machine, error) {
}
}
// handleBluepillFault takes the slot spinlock and it is called from
// seccompMmapHandler, so here we have to guarantee that mmap is not
// called while we hold the slot spinlock.
disableAsyncPreemption()
applyVirtualRegions(func(vr virtualRegion) {
if excludeVirtualRegion(vr) {
return // skip region.
@@ -331,6 +335,7 @@ func newMachine(vm int) (*machine, error) {
mapRegion(vr, 0)
})
enableAsyncPreemption()
// Initialize architecture state.
if err := m.initArchState(); err != nil {
+20
View File
@@ -240,3 +240,23 @@ func seccompMmapHandler(context unsafe.Pointer) {
}
seccompMmapHandlerCnt.Add(-1)
}
// disableAsyncPreemption disables asynchronous preemption of go-routines.
func disableAsyncPreemption() {
set := linux.MakeSignalSet(linux.SIGURG)
_, _, errno := unix.RawSyscall6(unix.SYS_RT_SIGPROCMASK, linux.SIG_BLOCK,
uintptr(unsafe.Pointer(&set)), 0, linux.SignalSetSize, 0, 0)
if errno != 0 {
panic(fmt.Sprintf("sigprocmask failed: %d", errno))
}
}
// enableAsyncPreemption enables asynchronous preemption of go-routines.
func enableAsyncPreemption() {
set := linux.MakeSignalSet(linux.SIGURG)
_, _, errno := unix.RawSyscall6(unix.SYS_RT_SIGPROCMASK, linux.SIG_UNBLOCK,
uintptr(unsafe.Pointer(&set)), 0, linux.SignalSetSize, 0, 0)
if errno != 0 {
panic(fmt.Sprintf("sigprocmask failed: %d", errno))
}
}