mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 19:57:31 +00:00
HV: instr_emul: Add new function vie_update_rflags
There are some duplicate codes in emulate_xxx functions which update rflags and it deserves a common function to deal with the situation. So, this patch introduces a new function vie_update_rflags to updating rflags accordingly. Signed-off-by: Kaige Fu <kaige.fu@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
2f3eb6723d
commit
44a175e4fe
@ -361,6 +361,26 @@ vie_update_register(struct vcpu *vcpu, enum cpu_reg_name reg,
|
||||
|
||||
#define RFLAGS_STATUS_BITS (PSL_C | PSL_PF | PSL_AF | PSL_Z | PSL_N | PSL_V)
|
||||
|
||||
static int vie_update_rflags(struct vcpu *vcpu, uint64_t rflags2, uint64_t psl)
|
||||
{
|
||||
int error;
|
||||
uint8_t size;
|
||||
uint64_t rflags;
|
||||
|
||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS, &rflags);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
rflags &= ~RFLAGS_STATUS_BITS;
|
||||
rflags |= rflags2 & psl;
|
||||
size = 8U;
|
||||
|
||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status flags that would result from doing (x - y).
|
||||
*/
|
||||
@ -832,7 +852,7 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
int error;
|
||||
uint8_t size;
|
||||
enum cpu_reg_name reg;
|
||||
uint64_t result, rflags, rflags2, val1, val2;
|
||||
uint64_t result, rflags2, val1, val2;
|
||||
|
||||
size = vie->opsize;
|
||||
error = -EINVAL;
|
||||
@ -878,11 +898,6 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
return error;
|
||||
}
|
||||
|
||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS, &rflags);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* OF and CF are cleared; the SF, ZF and PF flags are set according
|
||||
* to the result; AF is undefined.
|
||||
@ -890,10 +905,8 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
* The updated status flags are obtained by subtracting 0 from 'result'.
|
||||
*/
|
||||
rflags2 = getcc(size, result, 0UL);
|
||||
rflags &= ~RFLAGS_STATUS_BITS;
|
||||
rflags |= rflags2 & (PSL_PF | PSL_Z | PSL_N);
|
||||
size = 8U;
|
||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
error = vie_update_rflags(vcpu, rflags2, PSL_PF | PSL_Z | PSL_N);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -905,7 +918,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
int error;
|
||||
uint8_t size;
|
||||
enum cpu_reg_name reg;
|
||||
uint64_t result, rflags, rflags2, val1, val2;
|
||||
uint64_t result, rflags2, val1, val2;
|
||||
|
||||
size = vie->opsize;
|
||||
error = -EINVAL;
|
||||
@ -974,11 +987,6 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
return error;
|
||||
}
|
||||
|
||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS, &rflags);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* OF and CF are cleared; the SF, ZF and PF flags are set according
|
||||
* to the result; AF is undefined.
|
||||
@ -986,10 +994,8 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
* The updated status flags are obtained by subtracting 0 from 'result'.
|
||||
*/
|
||||
rflags2 = getcc(size, result, 0UL);
|
||||
rflags &= ~RFLAGS_STATUS_BITS;
|
||||
rflags |= rflags2 & (PSL_PF | PSL_Z | PSL_N);
|
||||
size = 8U;
|
||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
error = vie_update_rflags(vcpu, rflags2, PSL_PF | PSL_Z | PSL_N);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1001,7 +1007,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
int error;
|
||||
uint8_t size;
|
||||
enum cpu_reg_name reg;
|
||||
uint64_t val1, val2, result, rflags, rflags2;
|
||||
uint64_t val1, val2, result, rflags2;
|
||||
|
||||
size = vie->opsize;
|
||||
error = -EINVAL;
|
||||
@ -1073,11 +1079,6 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
return error;
|
||||
}
|
||||
|
||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS, &rflags);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* OF and CF are cleared; the SF, ZF and PF flags are set according
|
||||
* to the result; AF is undefined.
|
||||
@ -1085,10 +1086,8 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
* The updated status flags are obtained by subtracting 0 from 'result'.
|
||||
*/
|
||||
rflags2 = getcc(size, result, 0UL);
|
||||
rflags &= ~RFLAGS_STATUS_BITS;
|
||||
rflags |= rflags2 & (PSL_PF | PSL_Z | PSL_N);
|
||||
size = 8U;
|
||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
error = vie_update_rflags(vcpu, rflags2, PSL_PF | PSL_Z | PSL_N);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1099,7 +1098,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
{
|
||||
int error;
|
||||
uint8_t size;
|
||||
uint64_t regop, memop, op1, op2, rflags, rflags2;
|
||||
uint64_t regop, memop, op1, op2, rflags2;
|
||||
enum cpu_reg_name reg;
|
||||
|
||||
size = vie->opsize;
|
||||
@ -1184,14 +1183,9 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS, &rflags);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
rflags &= ~RFLAGS_STATUS_BITS;
|
||||
rflags |= rflags2 & RFLAGS_STATUS_BITS;
|
||||
size = 8U;
|
||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
||||
|
||||
error = vie_update_rflags(vcpu, rflags2, RFLAGS_STATUS_BITS);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1202,7 +1196,7 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
{
|
||||
int error;
|
||||
uint8_t size;
|
||||
uint64_t nval, rflags, rflags2, val1, val2;
|
||||
uint64_t nval, rflags2, val1, val2;
|
||||
enum cpu_reg_name reg;
|
||||
|
||||
size = vie->opsize;
|
||||
@ -1240,21 +1234,13 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
||||
break;
|
||||
}
|
||||
|
||||
if (error == 0) {
|
||||
rflags2 = getcc(size, val1, val2);
|
||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS,
|
||||
&rflags);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
rflags &= ~RFLAGS_STATUS_BITS;
|
||||
rflags |= rflags2 & RFLAGS_STATUS_BITS;
|
||||
size = 8U;
|
||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS,
|
||||
rflags, size);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
rflags2 = getcc(size, val1, val2);
|
||||
error = vie_update_rflags(vcpu, rflags2, RFLAGS_STATUS_BITS);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user