CET: DS Seg override is kept for CET Endranch suppress hint even if overridden by other prefixes later

This commit is contained in:
Stanislav Shwartsman 2020-02-21 19:38:23 +00:00
parent fb0dafa06c
commit 6e2541daa6
4 changed files with 20 additions and 8 deletions

View File

@ -88,7 +88,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::track_indirect(unsigned cpl)
void BX_CPP_AttrRegparmN(2) BX_CPU_C::track_indirect_if_not_suppressed(bxInstruction_c *i, unsigned cpl)
{
if (EndbranchEnabledAndNotSuppressed(cpl)) {
if (i->segOverride() == BX_SEG_REG_DS && (BX_CPU_THIS_PTR msr.ia32_cet_control[cpl==3] & BX_CET_ENABLE_NO_TRACK_INDIRECT_BRANCH_PREFIX) != 0)
if (i->segOverrideCet() == BX_SEG_REG_DS && (BX_CPU_THIS_PTR msr.ia32_cet_control[cpl==3] & BX_CET_ENABLE_NO_TRACK_INDIRECT_BRANCH_PREFIX) != 0)
return;
BX_CPU_THIS_PTR msr.ia32_cet_control[cpl==3] |= BX_CET_WAIT_FOR_ENBRANCH;

View File

@ -2380,6 +2380,9 @@ int fetchDecode32(const Bit8u *iptr, bx_bool is_32, bxInstruction_c *i, unsigned
unsigned b1;
int ia_opcode = BX_IA_ERROR;
unsigned seg_override = BX_SEG_REG_NULL;
#if BX_SUPPORT_CET
unsigned seg_override_cet = BX_SEG_REG_NULL;
#endif
bx_bool os_32 = is_32, lock = 0;
unsigned sse_prefix = SSE_PREFIX_NONE;
@ -2390,6 +2393,12 @@ fetch_b1:
b1 = *iptr++;
remain--;
#if BX_SUPPORT_CET
// DS prefix is still recorded for CET Endranch suppress hint even if overridden by other prefixes later
if (b1 == 0x3e)
seg_override_cet = BX_SEG_REG_DS;
#endif
switch (b1) {
case 0x0f: // 2-byte escape
if (remain != 0) {
@ -2458,7 +2467,7 @@ fetch_b1:
i->setSeg(BX_SEG_REG_DS); // default segment is DS:
#if BX_SUPPORT_CET
i->setSegOverride(seg_override);
i->setCetSegOverride(seg_override_cet);
#endif
i->modRMForm.Id = 0;

View File

@ -1879,6 +1879,9 @@ int fetchDecode64(const Bit8u *iptr, bxInstruction_c *i, unsigned remainingInPag
unsigned b1;
int ia_opcode = BX_IA_ERROR;
unsigned seg_override = BX_SEG_REG_NULL;
#if BX_SUPPORT_CET
unsigned seg_override_cet = BX_SEG_REG_NULL;
#endif
bx_bool lock = 0;
unsigned sse_prefix = SSE_PREFIX_NONE;
unsigned rex_prefix = 0;
@ -1894,8 +1897,9 @@ fetch_b1:
#if BX_SUPPORT_CET
// in 64-bit mode DS prefix is ignored but still recorded for CET Endranch suppress hint
// keep it even if overridden by FS: or GS:
if (b1 == 0x3e)
seg_override = BX_SEG_REG_DS;
seg_override_cet = BX_SEG_REG_DS;
#endif
switch (b1) {
@ -1998,7 +2002,7 @@ fetch_b1:
i->setSeg(BX_SEG_REG_DS); // default segment is DS:
#if BX_SUPPORT_CET
i->setSegOverride(seg_override);
i->setCetSegOverride(seg_override_cet);
#endif
i->modRMForm.Id = 0;
@ -2012,8 +2016,7 @@ fetch_b1:
i->setIaOpcode(ia_opcode);
// assign memory segment override
if (seg_override == BX_SEG_REG_FS || seg_override == BX_SEG_REG_GS)
i->setSeg(seg_override);
i->setSeg(seg_override);
Bit32u op_flags = BxOpcodesTable[ia_opcode].opflags;

View File

@ -153,10 +153,10 @@ public:
}
#if BX_SUPPORT_CET
BX_CPP_INLINE unsigned segOverride(void) const {
BX_CPP_INLINE unsigned segOverrideCet(void) const {
return metaData[BX_INSTR_METADATA_CET_SEGOVERRIDE];
}
BX_CPP_INLINE void setSegOverride(unsigned val) {
BX_CPP_INLINE void setCetSegOverride(unsigned val) {
metaData[BX_INSTR_METADATA_CET_SEGOVERRIDE] = val;
}
#endif