mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 12:12:16 +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)
|
#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).
|
* 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;
|
int error;
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
enum cpu_reg_name reg;
|
enum cpu_reg_name reg;
|
||||||
uint64_t result, rflags, rflags2, val1, val2;
|
uint64_t result, rflags2, val1, val2;
|
||||||
|
|
||||||
size = vie->opsize;
|
size = vie->opsize;
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
@ -878,11 +898,6 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
return error;
|
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
|
* OF and CF are cleared; the SF, ZF and PF flags are set according
|
||||||
* to the result; AF is undefined.
|
* 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'.
|
* The updated status flags are obtained by subtracting 0 from 'result'.
|
||||||
*/
|
*/
|
||||||
rflags2 = getcc(size, result, 0UL);
|
rflags2 = getcc(size, result, 0UL);
|
||||||
rflags &= ~RFLAGS_STATUS_BITS;
|
error = vie_update_rflags(vcpu, rflags2, PSL_PF | PSL_Z | PSL_N);
|
||||||
rflags |= rflags2 & (PSL_PF | PSL_Z | PSL_N);
|
|
||||||
size = 8U;
|
|
||||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,7 +918,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
int error;
|
int error;
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
enum cpu_reg_name reg;
|
enum cpu_reg_name reg;
|
||||||
uint64_t result, rflags, rflags2, val1, val2;
|
uint64_t result, rflags2, val1, val2;
|
||||||
|
|
||||||
size = vie->opsize;
|
size = vie->opsize;
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
@ -974,11 +987,6 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
return error;
|
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
|
* OF and CF are cleared; the SF, ZF and PF flags are set according
|
||||||
* to the result; AF is undefined.
|
* 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'.
|
* The updated status flags are obtained by subtracting 0 from 'result'.
|
||||||
*/
|
*/
|
||||||
rflags2 = getcc(size, result, 0UL);
|
rflags2 = getcc(size, result, 0UL);
|
||||||
rflags &= ~RFLAGS_STATUS_BITS;
|
error = vie_update_rflags(vcpu, rflags2, PSL_PF | PSL_Z | PSL_N);
|
||||||
rflags |= rflags2 & (PSL_PF | PSL_Z | PSL_N);
|
|
||||||
size = 8U;
|
|
||||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,7 +1007,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
int error;
|
int error;
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
enum cpu_reg_name reg;
|
enum cpu_reg_name reg;
|
||||||
uint64_t val1, val2, result, rflags, rflags2;
|
uint64_t val1, val2, result, rflags2;
|
||||||
|
|
||||||
size = vie->opsize;
|
size = vie->opsize;
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
@ -1073,11 +1079,6 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
return error;
|
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
|
* OF and CF are cleared; the SF, ZF and PF flags are set according
|
||||||
* to the result; AF is undefined.
|
* 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'.
|
* The updated status flags are obtained by subtracting 0 from 'result'.
|
||||||
*/
|
*/
|
||||||
rflags2 = getcc(size, result, 0UL);
|
rflags2 = getcc(size, result, 0UL);
|
||||||
rflags &= ~RFLAGS_STATUS_BITS;
|
error = vie_update_rflags(vcpu, rflags2, PSL_PF | PSL_Z | PSL_N);
|
||||||
rflags |= rflags2 & (PSL_PF | PSL_Z | PSL_N);
|
|
||||||
size = 8U;
|
|
||||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1099,7 +1098,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
uint64_t regop, memop, op1, op2, rflags, rflags2;
|
uint64_t regop, memop, op1, op2, rflags2;
|
||||||
enum cpu_reg_name reg;
|
enum cpu_reg_name reg;
|
||||||
|
|
||||||
size = vie->opsize;
|
size = vie->opsize;
|
||||||
@ -1184,14 +1183,9 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS, &rflags);
|
|
||||||
if (error != 0) {
|
error = vie_update_rflags(vcpu, rflags2, RFLAGS_STATUS_BITS);
|
||||||
return error;
|
|
||||||
}
|
|
||||||
rflags &= ~RFLAGS_STATUS_BITS;
|
|
||||||
rflags |= rflags2 & RFLAGS_STATUS_BITS;
|
|
||||||
size = 8U;
|
|
||||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS, rflags, size);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1202,7 +1196,7 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
uint64_t nval, rflags, rflags2, val1, val2;
|
uint64_t nval, rflags2, val1, val2;
|
||||||
enum cpu_reg_name reg;
|
enum cpu_reg_name reg;
|
||||||
|
|
||||||
size = vie->opsize;
|
size = vie->opsize;
|
||||||
@ -1240,20 +1234,12 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct vie *vie,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == 0) {
|
|
||||||
rflags2 = getcc(size, val1, val2);
|
|
||||||
error = vie_read_register(vcpu, CPU_REG_RFLAGS,
|
|
||||||
&rflags);
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rflags &= ~RFLAGS_STATUS_BITS;
|
rflags2 = getcc(size, val1, val2);
|
||||||
rflags |= rflags2 & RFLAGS_STATUS_BITS;
|
error = vie_update_rflags(vcpu, rflags2, RFLAGS_STATUS_BITS);
|
||||||
size = 8U;
|
|
||||||
error = vie_update_register(vcpu, CPU_REG_RFLAGS,
|
|
||||||
rflags, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user