diff options
author | Dave Voutila <dv@cvs.openbsd.org> | 2024-04-13 21:57:23 +0000 |
---|---|---|
committer | Dave Voutila <dv@cvs.openbsd.org> | 2024-04-13 21:57:23 +0000 |
commit | d5099c55a37a6e9ed2c726cebdf85453b3a0448e (patch) | |
tree | 1771e99f1cac3a684fbd832e9e8c6438a4e97166 /sys/arch | |
parent | 9061f6c775cd143bd7d7239efc211be444410f3d (diff) |
vmm: protect vmm activation with the vmm_softc rwlock.
Syzbot found a race when enabling vmm mode on multiprocessor systems.
Protect the vmm start/stop lifecycle by taking the write lock used
for protecting the status of the vmm device.
Reported-by: syzbot+6ae9cec00bbe45fd7782@syzkaller.appspotmail.com
ok gnezdo@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/vmm_machdep.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c index 02f2c3cb655..4769837796f 100644 --- a/sys/arch/amd64/amd64/vmm_machdep.c +++ b/sys/arch/amd64/amd64/vmm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm_machdep.c,v 1.23 2024/04/09 21:55:16 dv Exp $ */ +/* $OpenBSD: vmm_machdep.c,v 1.24 2024/04/13 21:57:22 dv Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -941,6 +941,7 @@ vmx_pmap_find_pte_ept(pmap_t pmap, paddr_t addr) int vmm_start(void) { + int rv = 0; struct cpu_info *self = curcpu(); #ifdef MULTIPROCESSOR struct cpu_info *ci; @@ -950,16 +951,19 @@ vmm_start(void) #endif /* MP_LOCKDEBUG */ #endif /* MULTIPROCESSOR */ + rw_enter_write(&vmm_softc->sc_slock); + /* VMM is already running */ if (self->ci_flags & CPUF_VMM) - return (0); + goto unlock; /* Start VMM on this CPU */ start_vmm_on_cpu(self); if (!(self->ci_flags & CPUF_VMM)) { printf("%s: failed to enter VMM mode\n", self->ci_dev->dv_xname); - return (EIO); + rv = EIO; + goto unlock; } #ifdef MULTIPROCESSOR @@ -984,8 +988,9 @@ vmm_start(void) } } #endif /* MULTIPROCESSOR */ - - return (0); +unlock: + rw_exit_write(&vmm_softc->sc_slock); + return (rv); } /* @@ -996,6 +1001,7 @@ vmm_start(void) int vmm_stop(void) { + int rv = 0; struct cpu_info *self = curcpu(); #ifdef MULTIPROCESSOR struct cpu_info *ci; @@ -1005,16 +1011,19 @@ vmm_stop(void) #endif /* MP_LOCKDEBUG */ #endif /* MULTIPROCESSOR */ + rw_enter_write(&vmm_softc->sc_slock); + /* VMM is not running */ if (!(self->ci_flags & CPUF_VMM)) - return (0); + goto unlock; /* Stop VMM on this CPU */ stop_vmm_on_cpu(self); if (self->ci_flags & CPUF_VMM) { printf("%s: failed to exit VMM mode\n", self->ci_dev->dv_xname); - return (EIO); + rv = EIO; + goto unlock; } #ifdef MULTIPROCESSOR @@ -1039,7 +1048,8 @@ vmm_stop(void) } } #endif /* MULTIPROCESSOR */ - +unlock: + rw_exit_write(&vmm_softc->sc_slock); return (0); } |