From 6e2541daa6d7413904cc107662e918a89c5dd919 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Fri, 21 Feb 2020 19:38:23 +0000 Subject: [PATCH] CET: DS Seg override is kept for CET Endranch suppress hint even if overridden by other prefixes later --- bochs/cpu/cet.cc | 2 +- bochs/cpu/decoder/fetchdecode32.cc | 11 ++++++++++- bochs/cpu/decoder/fetchdecode64.cc | 11 +++++++---- bochs/cpu/decoder/instr.h | 4 ++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/bochs/cpu/cet.cc b/bochs/cpu/cet.cc index ac4ccba2e..14d2ddf57 100644 --- a/bochs/cpu/cet.cc +++ b/bochs/cpu/cet.cc @@ -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; diff --git a/bochs/cpu/decoder/fetchdecode32.cc b/bochs/cpu/decoder/fetchdecode32.cc index 66efe8fe9..db6fcc7ea 100644 --- a/bochs/cpu/decoder/fetchdecode32.cc +++ b/bochs/cpu/decoder/fetchdecode32.cc @@ -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; diff --git a/bochs/cpu/decoder/fetchdecode64.cc b/bochs/cpu/decoder/fetchdecode64.cc index c8fdbc99a..385fed650 100644 --- a/bochs/cpu/decoder/fetchdecode64.cc +++ b/bochs/cpu/decoder/fetchdecode64.cc @@ -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; diff --git a/bochs/cpu/decoder/instr.h b/bochs/cpu/decoder/instr.h index 6756228fc..8245d2f2b 100644 --- a/bochs/cpu/decoder/instr.h +++ b/bochs/cpu/decoder/instr.h @@ -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