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.