Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/vmm_dev.c
Show All 20 Lines | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | |||||
#include "opt_bhyve_snapshot.h" | #include "opt_bhyve_snapshot.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/jail.h> | #include <sys/jail.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
vcpu_lock_one(struct vcpu *vcpu) | vcpu_lock_one(struct vcpu *vcpu) | ||||
{ | { | ||||
return (vcpu_set_state(vcpu, VCPU_FROZEN, true)); | return (vcpu_set_state(vcpu, VCPU_FROZEN, true)); | ||||
} | } | ||||
static void | static void | ||||
vcpu_unlock_one(struct vmmdev_softc *sc, int vcpuid, struct vcpu *vcpu) | vcpu_unlock_one(struct vcpu *vcpu) | ||||
{ | { | ||||
enum vcpu_state state; | enum vcpu_state state; | ||||
state = vcpu_get_state(vcpu, NULL); | state = vcpu_get_state(vcpu, NULL); | ||||
if (state != VCPU_FROZEN) { | if (state != VCPU_FROZEN) { | ||||
panic("vcpu %s(%d) has invalid state %d", vm_name(sc->vm), | panic("vcpu %s(%d) has invalid state %d", | ||||
vcpuid, state); | vm_name(vcpu_vm(vcpu)), vcpu_vcpuid(vcpu), state); | ||||
} | } | ||||
vcpu_set_state(vcpu, VCPU_IDLE, false); | vcpu_set_state(vcpu, VCPU_IDLE, false); | ||||
} | } | ||||
static int | static int | ||||
vcpu_lock_all(struct vmmdev_softc *sc) | vcpu_lock_all(struct vmmdev_softc *sc) | ||||
{ | { | ||||
Show All 13 Lines | if (error) | ||||
break; | break; | ||||
} | } | ||||
if (error) { | if (error) { | ||||
for (j = 0; j < i; j++) { | for (j = 0; j < i; j++) { | ||||
vcpu = vm_vcpu(sc->vm, j); | vcpu = vm_vcpu(sc->vm, j); | ||||
if (vcpu == NULL) | if (vcpu == NULL) | ||||
continue; | continue; | ||||
vcpu_unlock_one(sc, j, vcpu); | vcpu_unlock_one(vcpu); | ||||
} | } | ||||
vm_unlock_vcpus(sc->vm); | vm_unlock_vcpus(sc->vm); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static void | static void | ||||
vcpu_unlock_all(struct vmmdev_softc *sc) | vcpu_unlock_all(struct vmmdev_softc *sc) | ||||
{ | { | ||||
struct vcpu *vcpu; | struct vcpu *vcpu; | ||||
uint16_t i, maxcpus; | uint16_t i, maxcpus; | ||||
maxcpus = vm_get_maxcpus(sc->vm); | maxcpus = vm_get_maxcpus(sc->vm); | ||||
for (i = 0; i < maxcpus; i++) { | for (i = 0; i < maxcpus; i++) { | ||||
vcpu = vm_vcpu(sc->vm, i); | vcpu = vm_vcpu(sc->vm, i); | ||||
if (vcpu == NULL) | if (vcpu == NULL) | ||||
continue; | continue; | ||||
vcpu_unlock_one(sc, i, vcpu); | vcpu_unlock_one(vcpu); | ||||
} | } | ||||
vm_unlock_vcpus(sc->vm); | vm_unlock_vcpus(sc->vm); | ||||
} | } | ||||
static struct vmmdev_softc * | static struct vmmdev_softc * | ||||
vmmdev_lookup(const char *name) | vmmdev_lookup(const char *name) | ||||
{ | { | ||||
struct vmmdev_softc *sc; | struct vmmdev_softc *sc; | ||||
▲ Show 20 Lines • Show All 850 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
default: | default: | ||||
error = ENOTTY; | error = ENOTTY; | ||||
break; | break; | ||||
} | } | ||||
done: | done: | ||||
if (vcpus_locked == SINGLE) | if (vcpus_locked == SINGLE) | ||||
vcpu_unlock_one(sc, vcpuid, vcpu); | vcpu_unlock_one(vcpu); | ||||
else if (vcpus_locked == ALL) | else if (vcpus_locked == ALL) | ||||
vcpu_unlock_all(sc); | vcpu_unlock_all(sc); | ||||
if (memsegs_locked) | if (memsegs_locked) | ||||
vm_unlock_memsegs(sc->vm); | vm_unlock_memsegs(sc->vm); | ||||
/* | /* | ||||
* Make sure that no handler returns a kernel-internal | * Make sure that no handler returns a kernel-internal | ||||
* error value to userspace. | * error value to userspace. | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | if (sc == NULL || sc->cdev == NULL) { | ||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* Setting 'sc->cdev' to NULL is used to indicate that the VM | * Setting 'sc->cdev' to NULL is used to indicate that the VM | ||||
* is scheduled for destruction. | * is scheduled for destruction. | ||||
*/ | */ | ||||
cdev = sc->cdev; | cdev = sc->cdev; | ||||
sc->cdev = NULL; | sc->cdev = NULL; | ||||
mtx_unlock(&vmmdev_mtx); | mtx_unlock(&vmmdev_mtx); | ||||
/* | /* | ||||
* Destroy all cdevs: | * Destroy all cdevs: | ||||
* | * | ||||
* - any new operations on the 'cdev' will return an error (ENXIO). | * - any new operations on the 'cdev' will return an error (ENXIO). | ||||
* | * | ||||
* - the 'devmem' cdevs are destroyed before the virtual machine 'cdev' | * - the 'devmem' cdevs are destroyed before the virtual machine 'cdev' | ||||
▲ Show 20 Lines • Show All 213 Lines • Show Last 20 Lines |