mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 12:12:16 +00:00
hv: instr_emul: use cs segment when fetching instructions
In non-64-bit mode, CS segment base address should be considered when determining the linear address of the vcpu's instruction pointer. Use vie_calculate_gla() for instruction address translation which also takes care of 64-bit mode. Tracked-On: #4064 Signed-off-by: Peter Fang <peter.fang@intel.com>
This commit is contained in:
parent
05bb56291b
commit
b7329f10a5
@ -560,14 +560,13 @@ static bool is_desc_valid(const struct seg_desc *desc, uint32_t prot)
|
||||
*@pre prot must be PROT_READ or PROT_WRITE
|
||||
*/
|
||||
static void vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg,
|
||||
const struct seg_desc *desc, uint64_t offset_arg, uint8_t addrsize, uint64_t *gla)
|
||||
const struct seg_desc *desc, uint64_t offset, uint8_t addrsize, uint64_t *gla)
|
||||
{
|
||||
uint64_t firstoff, segbase;
|
||||
uint64_t offset = offset_arg;
|
||||
uint8_t glasize;
|
||||
|
||||
firstoff = offset;
|
||||
glasize = (cpu_mode == CPU_MODE_64BIT) ? 8U: 4U;
|
||||
glasize = (cpu_mode == CPU_MODE_64BIT) ? 8U : 4U;
|
||||
|
||||
/*
|
||||
* In 64-bit mode all segments except %fs and %gs have a segment
|
||||
@ -1643,8 +1642,10 @@ static int32_t emulate_bittest(struct acrn_vcpu *vcpu, const struct instr_emul_v
|
||||
|
||||
static int32_t vie_init(struct instr_emul_vie *vie, struct acrn_vcpu *vcpu)
|
||||
{
|
||||
uint64_t guest_rip_gva = vcpu_get_rip(vcpu);
|
||||
uint32_t inst_len = vcpu->arch.inst_len;
|
||||
enum vm_cpu_mode cpu_mode;
|
||||
struct seg_desc desc;
|
||||
uint64_t guest_rip_gva;
|
||||
uint32_t err_code;
|
||||
uint64_t fault_addr;
|
||||
int32_t ret;
|
||||
@ -1660,6 +1661,13 @@ static int32_t vie_init(struct instr_emul_vie *vie, struct acrn_vcpu *vcpu)
|
||||
vie->index_register = CPU_REG_LAST;
|
||||
vie->segment_register = CPU_REG_LAST;
|
||||
|
||||
cpu_mode = get_vcpu_mode(vcpu);
|
||||
vm_get_seg_desc(CPU_REG_CS, &desc);
|
||||
|
||||
/* VMX_GUEST_RIP is a natural-width field */
|
||||
vie_calculate_gla(cpu_mode, CPU_REG_CS, &desc, vcpu_get_rip(vcpu),
|
||||
8U, &guest_rip_gva);
|
||||
|
||||
err_code = PAGE_FAULT_ID_FLAG;
|
||||
ret = copy_from_gva(vcpu, vie->inst, guest_rip_gva, inst_len, &err_code, &fault_addr);
|
||||
if (ret < 0) {
|
||||
@ -2301,12 +2309,12 @@ int32_t decode_instruction(struct acrn_vcpu *vcpu)
|
||||
|
||||
emul_ctxt = &vcpu->inst_ctxt;
|
||||
retval = vie_init(&emul_ctxt->vie, vcpu);
|
||||
|
||||
if (retval < 0) {
|
||||
if (retval != -EFAULT) {
|
||||
pr_err("init vie failed @ 0x%016lx:", vcpu_get_rip(vcpu));
|
||||
}
|
||||
} else {
|
||||
|
||||
csar = exec_vmread32(VMX_GUEST_CS_ATTR);
|
||||
cpu_mode = get_vcpu_mode(vcpu);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user