mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-01-05 15:45:05 +00:00
hv: guest: fix "Procedure has more than one exit point"
IEC 61508,ISO 26262 standards highly recommend single-exit rule. Reduce the count of the "return entries". Fix the violations which is comply with the cases list below: 1.Function has 2 return entries. 2.The first return entry is used to return the error code of checking variable whether is valid. Fix the violations in "if else" format. Tracked-On: #861 Signed-off-by: Huihuang Shi <huihuang.shi@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -1462,13 +1462,11 @@ static int emulate_sub(struct acrn_vcpu *vcpu, const struct instr_emul_vie *vie)
|
||||
break;
|
||||
}
|
||||
|
||||
if (error != 0) {
|
||||
return error;
|
||||
if (error == 0) {
|
||||
rflags2 = getcc(size, val1, val2);
|
||||
vie_update_rflags(vcpu, rflags2, RFLAGS_STATUS_BITS);
|
||||
}
|
||||
|
||||
rflags2 = getcc(size, val1, val2);
|
||||
vie_update_rflags(vcpu, rflags2, RFLAGS_STATUS_BITS);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1494,11 +1492,12 @@ static int emulate_group1(struct acrn_vcpu *vcpu, const struct instr_emul_vie *v
|
||||
return error;
|
||||
}
|
||||
|
||||
static int emulate_bittest(struct acrn_vcpu *vcpu, const struct instr_emul_vie *vie)
|
||||
static int32_t emulate_bittest(struct acrn_vcpu *vcpu, const struct instr_emul_vie *vie)
|
||||
{
|
||||
uint64_t val, rflags, bitmask;
|
||||
uint64_t bitoff;
|
||||
uint8_t size;
|
||||
int32_t ret;
|
||||
|
||||
/*
|
||||
* 0F BA is a Group 8 extended opcode.
|
||||
@@ -1506,31 +1505,32 @@ static int emulate_bittest(struct acrn_vcpu *vcpu, const struct instr_emul_vie *
|
||||
* Currently we only emulate the 'Bit Test' instruction which is
|
||||
* identified by a ModR/M:reg encoding of 100b.
|
||||
*/
|
||||
if ((vie->reg & 7U) != 4U) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((vie->reg & 7U) == 4U) {
|
||||
rflags = vm_get_register(vcpu, CPU_REG_RFLAGS);
|
||||
|
||||
rflags = vm_get_register(vcpu, CPU_REG_RFLAGS);
|
||||
vie_mmio_read(vcpu, &val);
|
||||
|
||||
vie_mmio_read(vcpu, &val);
|
||||
/*
|
||||
* Intel SDM, Vol 2, Table 3-2:
|
||||
* "Range of Bit Positions Specified by Bit Offset Operands"
|
||||
*/
|
||||
bitmask = ((uint64_t)vie->opsize * 8UL) - 1UL;
|
||||
bitoff = (uint64_t)vie->immediate & bitmask;
|
||||
|
||||
/*
|
||||
* Intel SDM, Vol 2, Table 3-2:
|
||||
* "Range of Bit Positions Specified by Bit Offset Operands"
|
||||
*/
|
||||
bitmask = ((uint64_t)vie->opsize * 8UL) - 1UL;
|
||||
bitoff = (uint64_t)vie->immediate & bitmask;
|
||||
|
||||
/* Copy the bit into the Carry flag in %rflags */
|
||||
if ((val & (1UL << bitoff)) != 0U) {
|
||||
rflags |= PSL_C;
|
||||
/* Copy the bit into the Carry flag in %rflags */
|
||||
if ((val & (1UL << bitoff)) != 0U) {
|
||||
rflags |= PSL_C;
|
||||
} else {
|
||||
rflags &= ~PSL_C;
|
||||
}
|
||||
size = 8U;
|
||||
vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
ret = 0;
|
||||
} else {
|
||||
rflags &= ~PSL_C;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
size = 8U;
|
||||
vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vmm_emulate_instruction(struct instr_emul_ctxt *ctxt)
|
||||
@@ -1539,48 +1539,50 @@ static int vmm_emulate_instruction(struct instr_emul_ctxt *ctxt)
|
||||
struct acrn_vcpu *vcpu = ctxt->vcpu;
|
||||
int error;
|
||||
|
||||
if (vie->decoded == 0U) {
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (vie->op.op_type) {
|
||||
case VIE_OP_TYPE_GROUP1:
|
||||
error = emulate_group1(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_CMP:
|
||||
error = emulate_cmp(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_MOV:
|
||||
error = emulate_mov(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_MOVSX:
|
||||
case VIE_OP_TYPE_MOVZX:
|
||||
error = emulate_movx(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_MOVS:
|
||||
error = emulate_movs(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_STOS:
|
||||
error = emulate_stos(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_AND:
|
||||
error = emulate_and(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_TEST:
|
||||
error = emulate_test(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_OR:
|
||||
error = emulate_or(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_SUB:
|
||||
error = emulate_sub(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_BITTEST:
|
||||
error = emulate_bittest(vcpu, vie);
|
||||
break;
|
||||
default:
|
||||
if (vie->decoded != 0U) {
|
||||
switch (vie->op.op_type) {
|
||||
case VIE_OP_TYPE_GROUP1:
|
||||
error = emulate_group1(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_CMP:
|
||||
error = emulate_cmp(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_MOV:
|
||||
error = emulate_mov(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_MOVSX:
|
||||
case VIE_OP_TYPE_MOVZX:
|
||||
error = emulate_movx(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_MOVS:
|
||||
error = emulate_movs(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_STOS:
|
||||
error = emulate_stos(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_AND:
|
||||
error = emulate_and(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_TEST:
|
||||
error = emulate_test(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_OR:
|
||||
error = emulate_or(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_SUB:
|
||||
error = emulate_sub(vcpu, vie);
|
||||
break;
|
||||
case VIE_OP_TYPE_BITTEST:
|
||||
error = emulate_bittest(vcpu, vie);
|
||||
break;
|
||||
default:
|
||||
error = -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
error = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -2141,19 +2143,21 @@ static int local_decode_instruction(enum vm_cpu_mode cpu_mode,
|
||||
}
|
||||
|
||||
/* for instruction MOVS/STO, check the gva gotten from DI/SI. */
|
||||
static int instr_check_di(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt)
|
||||
static int32_t instr_check_di(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt)
|
||||
{
|
||||
int ret;
|
||||
int32_t ret;
|
||||
struct instr_emul_vie *vie = &emul_ctxt->vie;
|
||||
uint64_t gva;
|
||||
|
||||
ret = get_gva_di_check(vcpu, vie, vie->addrsize, &gva);
|
||||
|
||||
if (ret < 0) {
|
||||
return -EFAULT;
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int instr_check_gva(struct acrn_vcpu *vcpu, struct instr_emul_ctxt *emul_ctxt,
|
||||
@@ -2305,14 +2309,17 @@ int decode_instruction(struct acrn_vcpu *vcpu)
|
||||
return (int)(emul_ctxt->vie.opsize);
|
||||
}
|
||||
|
||||
int emulate_instruction(const struct acrn_vcpu *vcpu)
|
||||
int32_t emulate_instruction(const struct acrn_vcpu *vcpu)
|
||||
{
|
||||
struct instr_emul_ctxt *ctxt = &per_cpu(g_inst_ctxt, vcpu->pcpu_id);
|
||||
int32_t ret;
|
||||
|
||||
if (ctxt == NULL) {
|
||||
pr_err("%s: Failed to get instr_emul_ctxt", __func__);
|
||||
return -1;
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = vmm_emulate_instruction(ctxt);
|
||||
}
|
||||
|
||||
return vmm_emulate_instruction(ctxt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user