Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/amd/vmcb.c
Show All 23 Lines | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_bhyve_snapshot.h" | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <machine/segments.h> | #include <machine/segments.h> | ||||
#include <machine/specialreg.h> | #include <machine/specialreg.h> | ||||
#include <machine/vmm.h> | #include <machine/vmm.h> | ||||
#include <machine/vmm_snapshot.h> | |||||
#include "vmm_ktr.h" | #include "vmm_ktr.h" | ||||
#include "vmcb.h" | #include "vmcb.h" | ||||
#include "svm.h" | #include "svm.h" | ||||
#include "svm_softc.h" | #include "svm_softc.h" | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 401 Lines • ▼ Show 20 Lines | if (reg != VM_REG_GUEST_GDTR && reg != VM_REG_GUEST_IDTR) { | ||||
if (reg != VM_REG_GUEST_CS && reg != VM_REG_GUEST_TR) { | if (reg != VM_REG_GUEST_CS && reg != VM_REG_GUEST_TR) { | ||||
if ((desc->access & 0x80) == 0) | if ((desc->access & 0x80) == 0) | ||||
desc->access |= 0x10000; /* Unusable segment */ | desc->access |= 0x10000; /* Unusable segment */ | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef BHYVE_SNAPSHOT | |||||
int | |||||
vmcb_getany(struct svm_softc *sc, int vcpu, int ident, uint64_t *val) | |||||
{ | |||||
int error = 0; | |||||
if (vcpu < 0 || vcpu >= VM_MAXCPU) { | |||||
error = EINVAL; | |||||
goto err; | |||||
} | |||||
if (ident >= VM_REG_LAST) { | |||||
xistence_0x58.com: If error is already set, why are we running `vm_get_register`? We are overwriting `error` with… | |||||
error = EINVAL; | |||||
goto err; | |||||
} | |||||
error = vm_get_register(sc->vm, vcpu, ident, val); | |||||
err: | |||||
return (error); | |||||
} | |||||
int | |||||
vmcb_setany(struct svm_softc *sc, int vcpu, int ident, uint64_t val) | |||||
{ | |||||
int error = 0; | |||||
if (vcpu < 0 || vcpu >= VM_MAXCPU) { | |||||
Done Inline ActionsThis has the same issue as the code above. xistence_0x58.com: This has the same issue as the code above. | |||||
error = EINVAL; | |||||
goto err; | |||||
} | |||||
if (ident >= VM_REG_LAST) { | |||||
error = EINVAL; | |||||
goto err; | |||||
} | |||||
error = vm_set_register(sc->vm, vcpu, ident, val); | |||||
err: | |||||
return (error); | |||||
} | |||||
int | |||||
vmcb_snapshot_desc(void *arg, int vcpu, int reg, struct vm_snapshot_meta *meta) | |||||
{ | |||||
int ret; | |||||
struct seg_desc desc; | |||||
if (meta->op == VM_SNAPSHOT_SAVE) { | |||||
ret = vmcb_getdesc(arg, vcpu, reg, &desc); | |||||
if (ret != 0) | |||||
goto done; | |||||
SNAPSHOT_VAR_OR_LEAVE(desc.base, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(desc.limit, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(desc.access, meta, ret, done); | |||||
} else if (meta->op == VM_SNAPSHOT_RESTORE) { | |||||
SNAPSHOT_VAR_OR_LEAVE(desc.base, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(desc.limit, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(desc.access, meta, ret, done); | |||||
ret = vmcb_setdesc(arg, vcpu, reg, &desc); | |||||
if (ret != 0) | |||||
goto done; | |||||
} else { | |||||
ret = EINVAL; | |||||
goto done; | |||||
} | |||||
done: | |||||
return (ret); | |||||
} | |||||
int | |||||
vmcb_snapshot_any(struct svm_softc *sc, int vcpu, int ident, | |||||
struct vm_snapshot_meta *meta) | |||||
{ | |||||
int ret; | |||||
uint64_t val; | |||||
if (meta->op == VM_SNAPSHOT_SAVE) { | |||||
ret = vmcb_getany(sc, vcpu, ident, &val); | |||||
if (ret != 0) | |||||
goto done; | |||||
SNAPSHOT_VAR_OR_LEAVE(val, meta, ret, done); | |||||
} else if (meta->op == VM_SNAPSHOT_RESTORE) { | |||||
SNAPSHOT_VAR_OR_LEAVE(val, meta, ret, done); | |||||
ret = vmcb_setany(sc, vcpu, ident, val); | |||||
if (ret != 0) | |||||
goto done; | |||||
} else { | |||||
ret = EINVAL; | |||||
goto done; | |||||
} | |||||
done: | |||||
return (ret); | |||||
} | |||||
#endif |
If error is already set, why are we running vm_get_register? We are overwriting error with the return value from vm_get_register at that point.