Skip to content

Commit 5663dd7

Browse files
fyin1lijinxia
authored andcommitted
hv: extend the decode_modrm
If rm show there is no SIB following rm field, we should get base_register info from rm. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 3b6ccf0 commit 5663dd7

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

hypervisor/arch/x86/guest/instr_emul.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,11 @@ static int vie_init(struct instr_emul_vie *vie, struct vcpu *vcpu)
16361636

16371637
(void)memset(vie, 0U, sizeof(struct instr_emul_vie));
16381638

1639+
/* init register fields in vie. */
1640+
vie->base_register = CPU_REG_LAST;
1641+
vie->index_register = CPU_REG_LAST;
1642+
vie->segment_register = CPU_REG_LAST;
1643+
16391644
err_code = PAGE_FAULT_ID_FLAG;
16401645
ret = copy_from_gva(vcpu, vie->inst, guest_rip_gva,
16411646
inst_len, &err_code, &fault_addr);
@@ -1859,6 +1864,42 @@ static int decode_modrm(struct instr_emul_vie *vie, enum vm_cpu_mode cpu_mode)
18591864

18601865
vie->reg |= (vie->rex_r << 3);
18611866

1867+
/* SIB */
1868+
if (vie->mod != VIE_MOD_DIRECT && vie->rm == VIE_RM_SIB) {
1869+
goto done;
1870+
}
1871+
1872+
vie->base_register = vie->rm;
1873+
1874+
switch (vie->mod) {
1875+
case VIE_MOD_INDIRECT_DISP8:
1876+
vie->disp_bytes = 1U;
1877+
break;
1878+
case VIE_MOD_INDIRECT_DISP32:
1879+
vie->disp_bytes = 4U;
1880+
break;
1881+
case VIE_MOD_INDIRECT:
1882+
if (vie->rm == VIE_RM_DISP32) {
1883+
vie->disp_bytes = 4U;
1884+
/*
1885+
* Table 2-7. RIP-Relative Addressing
1886+
*
1887+
* In 64-bit mode mod=00 r/m=101 implies [rip] + disp32
1888+
* whereas in compatibility mode it just implies disp32.
1889+
*/
1890+
1891+
if (cpu_mode == CPU_MODE_64BIT) {
1892+
vie->base_register = CPU_REG_RIP;
1893+
pr_err("VM exit with RIP as indirect access");
1894+
}
1895+
else {
1896+
vie->base_register = CPU_REG_LAST;
1897+
}
1898+
}
1899+
break;
1900+
}
1901+
1902+
done:
18621903
vie_advance(vie);
18631904

18641905
return 0;
@@ -1935,7 +1976,7 @@ static int decode_sib(struct instr_emul_vie *vie)
19351976
}
19361977

19371978
/* 'scale' makes sense only in the context of an index register */
1938-
if (vie->index_register <= CPU_REG_LAST) {
1979+
if (vie->index_register < CPU_REG_LAST) {
19391980
vie->scale = 1U << vie->ss;
19401981
}
19411982

0 commit comments

Comments
 (0)