Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/intel/vmcs.c
Show All 22 Lines | |||||
* 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. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include "opt_bhyve_snapshot.h" | |||||
#include "opt_ddb.h" | #include "opt_ddb.h" | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/pcpu.h> | #include <sys/pcpu.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <machine/segments.h> | #include <machine/segments.h> | ||||
#include <machine/vmm.h> | #include <machine/vmm.h> | ||||
#include <machine/vmm_snapshot.h> | |||||
#include "vmm_host.h" | #include "vmm_host.h" | ||||
#include "vmx_cpufunc.h" | #include "vmx_cpufunc.h" | ||||
#include "vmcs.h" | #include "vmcs.h" | ||||
#include "ept.h" | #include "ept.h" | ||||
#include "vmx.h" | #include "vmx.h" | ||||
#ifdef DDB | #ifdef DDB | ||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | ||||
▲ Show 20 Lines • Show All 370 Lines • ▼ Show 20 Lines | vmcs_init(struct vmcs *vmcs) | ||||
/* link pointer */ | /* link pointer */ | ||||
if ((error = vmwrite(VMCS_LINK_POINTER, ~0)) != 0) | if ((error = vmwrite(VMCS_LINK_POINTER, ~0)) != 0) | ||||
goto done; | goto done; | ||||
done: | done: | ||||
VMCLEAR(vmcs); | VMCLEAR(vmcs); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef BHYVE_SNAPSHOT | |||||
int | |||||
vmcs_getany(struct vmcs *vmcs, int running, int ident, uint64_t *val) | |||||
{ | |||||
int error; | |||||
if (!running) | |||||
VMPTRLD(vmcs); | |||||
error = vmread(ident, val); | |||||
if (!running) | |||||
VMCLEAR(vmcs); | |||||
return (error); | |||||
} | |||||
int | |||||
vmcs_setany(struct vmcs *vmcs, int running, int ident, uint64_t val) | |||||
{ | |||||
int error; | |||||
if (!running) | |||||
VMPTRLD(vmcs); | |||||
error = vmwrite(ident, val); | |||||
if (!running) | |||||
VMCLEAR(vmcs); | |||||
return (error); | |||||
} | |||||
int | |||||
vmcs_snapshot_reg(struct vmcs *vmcs, int running, int ident, | |||||
struct vm_snapshot_meta *meta) | |||||
{ | |||||
int ret; | |||||
uint64_t val; | |||||
if (meta->op == VM_SNAPSHOT_SAVE) { | |||||
ret = vmcs_getreg(vmcs, running, 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 = vmcs_setreg(vmcs, running, ident, val); | |||||
if (ret != 0) | |||||
dab: There is no need for this `if` and `goto`; the code will fall through to done naturally. | |||||
Not Done Inline ActionsThe decision was made to keep things symmetrical on all branches of the if (similar to breaks for all cases of a switch-case), and also as a precaution in case more code is added after the if. darius.mihaim_gmail.com: The decision was made to keep things symmetrical on all branches of the if (similar to breaks… | |||||
Done Inline ActionsI prefer the simpler (and less verbose) code, but can see your point. dab: I prefer the simpler (and less verbose) code, but can see your point. | |||||
goto done; | |||||
} else { | |||||
ret = EINVAL; | |||||
Not Done Inline ActionsThere is no need for this goto; the code will fall through to done naturally. dab: There is no need for this `goto`; the code will fall through to done naturally. | |||||
Done Inline ActionsSame as the previous case. darius.mihaim_gmail.com: Same as the previous case. | |||||
goto done; | |||||
} | |||||
done: | |||||
return (ret); | |||||
} | |||||
int | |||||
vmcs_snapshot_desc(struct vmcs *vmcs, int running, int seg, | |||||
struct vm_snapshot_meta *meta) | |||||
{ | |||||
int ret; | |||||
struct seg_desc desc; | |||||
if (meta->op == VM_SNAPSHOT_SAVE) { | |||||
ret = vmcs_getdesc(vmcs, running, seg, &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 = vmcs_setdesc(vmcs, running, seg, &desc); | |||||
if (ret != 0) | |||||
goto done; | |||||
} else { | |||||
ret = EINVAL; | |||||
Not Done Inline ActionsSee comments in function above. dab: See comments in function above. | |||||
Done Inline ActionsSame observations. darius.mihaim_gmail.com: Same observations. | |||||
goto done; | |||||
} | |||||
done: | |||||
return (ret); | |||||
} | |||||
int | |||||
vmcs_snapshot_any(struct vmcs *vmcs, int running, int ident, | |||||
struct vm_snapshot_meta *meta) | |||||
{ | |||||
int ret; | |||||
uint64_t val; | |||||
if (meta->op == VM_SNAPSHOT_SAVE) { | |||||
ret = vmcs_getany(vmcs, running, 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 = vmcs_setany(vmcs, running, ident, val); | |||||
if (ret != 0) | |||||
goto done; | |||||
} else { | |||||
ret = EINVAL; | |||||
Not Done Inline ActionsSee comments in function above. dab: See comments in function above. | |||||
Done Inline ActionsSame observations. darius.mihaim_gmail.com: Same observations. | |||||
goto done; | |||||
} | |||||
done: | |||||
return (ret); | |||||
} | |||||
#endif | |||||
#ifdef DDB | #ifdef DDB | ||||
extern int vmxon_enabled[]; | extern int vmxon_enabled[]; | ||||
DB_SHOW_COMMAND(vmcs, db_show_vmcs) | DB_SHOW_COMMAND(vmcs, db_show_vmcs) | ||||
{ | { | ||||
uint64_t cur_vmcs, val; | uint64_t cur_vmcs, val; | ||||
uint32_t exit; | uint32_t exit; | ||||
▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines |
There is no need for this if and goto; the code will fall through to done naturally.