:p
atchew
Login
The CR8_LEGACY feature was introduced in the K8 Revision F. It doesn't exist in prior revisions of the K8. Furthermore, from APM Vol2 3.1.5 CR8 (Task Priority Register, TPR): The AMD64 architecture introduces a new control register, CR8, defined as the task priority register (TPR). Additionally, from APM Vol3 4 System Instructions MOV CRn: CR8 can be read and written in 64-bit mode, using a REX prefix. CR8 can be read and written in all modes using a LOCK prefix instead of a REX prefix to specify the additional opcode bit. i.e. the LOCK prefix serves as an alternative encoding for REX.R. Switch decode_twobyte() from += 8 to |= 8 to better match the description given. Other indications that the encoding isn't additive are that the CR intercepts stop at 15, and that LOCK MOV CR8 generates #UD rather than becoming a CR0 access. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> --- CC: Jan Beulich <JBeulich@suse.com> CC: Roger Pau Monné <roger.pau@citrix.com> v2: * No dependency on LM. Also, designers never put an ADD into silicon if they can possibly avoid it, because it's large and slow compared to the single OR gate needed in this case. --- xen/arch/x86/x86_emulate/decode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/x86_emulate/decode.c b/xen/arch/x86/x86_emulate/decode.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/x86_emulate/decode.c +++ b/xen/arch/x86/x86_emulate/decode.c @@ -XXX,XX +XXX,XX @@ decode_twobyte(struct x86_emulate_state *s, case 0x20: case 0x22: /* mov to/from cr */ if ( s->lock_prefix && vcpu_has_cr8_legacy() ) { - s->modrm_reg += 8; + s->modrm_reg |= 8; s->lock_prefix = false; } - /* fall through */ + fallthrough; case 0x21: case 0x23: /* mov to/from dr */ ASSERT(s->ea.type == OP_REG); /* Early operand adjustment ensures this. */ generate_exception_if(s->lock_prefix, X86_EXC_UD); -- 2.39.5
The APM description of the AltMovCR8 feature bit is: "LOCK MOV CR0 means MOV CR8" Adjust the decode logic to behave like this. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> --- CC: Jan Beulich <jbeulich@suse.com> CC: Roger Pau Monné <roger.pau@citrix.com> CC: Teddy Astie <teddy.astie@vates.tech> v3: * Change yet again. A contact with information on the matter confirmed that it is a special case for Reg = 0, and not a general modifier to all Reg values. --- xen/arch/x86/x86_emulate/decode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/x86_emulate/decode.c b/xen/arch/x86/x86_emulate/decode.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/x86_emulate/decode.c +++ b/xen/arch/x86/x86_emulate/decode.c @@ -XXX,XX +XXX,XX @@ decode_twobyte(struct x86_emulate_state *s, break; case 0x20: case 0x22: /* mov to/from cr */ - if ( s->lock_prefix && vcpu_has_cr8_legacy() ) + if ( s->lock_prefix && vcpu_has_cr8_legacy() && s->modrm_reg == 0 ) { - s->modrm_reg += 8; + s->modrm_reg = 8; s->lock_prefix = false; } - /* fall through */ + fallthrough; case 0x21: case 0x23: /* mov to/from dr */ ASSERT(s->ea.type == OP_REG); /* Early operand adjustment ensures this. */ generate_exception_if(s->lock_prefix, X86_EXC_UD); -- 2.39.5