vmm: Improve register get/set handling a bit
On non-amd64 platforms, check for negative register indices. This isn't required today since we match against individual register indices, but we might as well check it. On amd64, add a comment explaining why we permit negative register indices. Use mallocarray() for allocating register arrays in the ioctl layer. No functional change intended. Reviewed by: corvink MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D53143
This commit is contained in:
+2
-1
@@ -870,7 +870,7 @@ vm_assign_pptdev(struct vm *vm, int bus, int slot, int func)
|
||||
int
|
||||
vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval)
|
||||
{
|
||||
|
||||
/* Negative values represent VM control structure fields. */
|
||||
if (reg >= VM_REG_LAST)
|
||||
return (EINVAL);
|
||||
|
||||
@@ -882,6 +882,7 @@ vm_set_register(struct vcpu *vcpu, int reg, uint64_t val)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Negative values represent VM control structure fields. */
|
||||
if (reg >= VM_REG_LAST)
|
||||
return (EINVAL);
|
||||
|
||||
|
||||
+2
-3
@@ -1279,8 +1279,7 @@ vcpu_get_state(struct vcpu *vcpu, int *hostcpu)
|
||||
int
|
||||
vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval)
|
||||
{
|
||||
|
||||
if (reg >= VM_REG_LAST)
|
||||
if (reg < 0 || reg >= VM_REG_LAST)
|
||||
return (EINVAL);
|
||||
|
||||
return (vmmops_getreg(vcpu->cookie, reg, retval));
|
||||
@@ -1291,7 +1290,7 @@ vm_set_register(struct vcpu *vcpu, int reg, uint64_t val)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (reg >= VM_REG_LAST)
|
||||
if (reg < 0 || reg >= VM_REG_LAST)
|
||||
return (EINVAL);
|
||||
error = vmmops_setreg(vcpu->cookie, reg, val);
|
||||
if (error || reg != VM_REG_GUEST_PC)
|
||||
|
||||
@@ -656,10 +656,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV,
|
||||
M_WAITOK);
|
||||
regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV,
|
||||
M_WAITOK);
|
||||
regvals = mallocarray(vmregset->count, sizeof(regvals[0]),
|
||||
M_VMMDEV, M_WAITOK);
|
||||
regnums = mallocarray(vmregset->count, sizeof(regnums[0]),
|
||||
M_VMMDEV, M_WAITOK);
|
||||
error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) *
|
||||
vmregset->count);
|
||||
if (error == 0)
|
||||
@@ -682,10 +682,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV,
|
||||
M_WAITOK);
|
||||
regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV,
|
||||
M_WAITOK);
|
||||
regvals = mallocarray(vmregset->count, sizeof(regvals[0]),
|
||||
M_VMMDEV, M_WAITOK);
|
||||
regnums = mallocarray(vmregset->count, sizeof(regnums[0]),
|
||||
M_VMMDEV, M_WAITOK);
|
||||
error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) *
|
||||
vmregset->count);
|
||||
if (error == 0)
|
||||
|
||||
+2
-3
@@ -954,8 +954,7 @@ vcpu_get_state(struct vcpu *vcpu, int *hostcpu)
|
||||
int
|
||||
vm_get_register(struct vcpu *vcpu, int reg, uint64_t *retval)
|
||||
{
|
||||
|
||||
if (reg >= VM_REG_LAST)
|
||||
if (reg < 0 || reg >= VM_REG_LAST)
|
||||
return (EINVAL);
|
||||
|
||||
return (vmmops_getreg(vcpu->cookie, reg, retval));
|
||||
@@ -966,7 +965,7 @@ vm_set_register(struct vcpu *vcpu, int reg, uint64_t val)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (reg >= VM_REG_LAST)
|
||||
if (reg < 0 || reg >= VM_REG_LAST)
|
||||
return (EINVAL);
|
||||
error = vmmops_setreg(vcpu->cookie, reg, val);
|
||||
if (error || reg != VM_REG_GUEST_SEPC)
|
||||
|
||||
Reference in New Issue
Block a user