From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: pbonzini@redhat.com, seanjc@google.com, chao.gao@intel.com,
zhao1.liu@intel.com, chang.seok.bae@intel.com
Subject: [PATCH RFC v1 10/20] KVM: x86: Refactor REX prefix handling in instruction emulation
Date: Mon, 10 Nov 2025 18:01:21 +0000 [thread overview]
Message-ID: <20251110180131.28264-11-chang.seok.bae@intel.com> (raw)
In-Reply-To: <20251110180131.28264-1-chang.seok.bae@intel.com>
Restructure how to represent and interpret REX fields. Specifically,
* Repurpose the existing rex_prefix field to identify the prefix type
* Introduce a new union to hold both REX and REX2 bitfields
* Update decoder logic to interpret the unified data type
Historically, REX used the upper four bits of a signle byte as a fixed
identifier, with the lower bits encoded. REX2 extends this to two bytes.
The first byte identifies the prefix, and the second encodes additional
bits, preserving compatibility with legacy REX encoding.
Previously, the emulator stored the REX byte as-is, which cannot capture
REX2 semantics. This refactor prepares for REX2 decoding while preserving
current behavior.
No functional changes intended.
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
---
arch/x86/kvm/emulate.c | 33 ++++++++++++++++++---------------
arch/x86/kvm/kvm_emulate.h | 31 ++++++++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4e3da5b497b8..763fbd139242 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -924,7 +924,7 @@ static void *decode_register(struct x86_emulate_ctxt *ctxt, u8 modrm_reg,
int byteop)
{
void *p;
- int highbyte_regs = (ctxt->rex_prefix == 0) && byteop;
+ int highbyte_regs = (ctxt->rex_prefix == REX_NONE) && byteop;
if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8)
p = (unsigned char *)reg_rmw(ctxt, modrm_reg & 3) + 1;
@@ -1080,10 +1080,12 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
{
unsigned int reg;
- if (ctxt->d & ModRM)
+ if (ctxt->d & ModRM) {
reg = ctxt->modrm_reg;
- else
- reg = (ctxt->b & 7) | ((ctxt->rex_prefix & 1) << 3);
+ } else {
+ reg = (ctxt->b & 7) |
+ (ctxt->rex.bits.b3 * BIT(3));
+ }
if (ctxt->d & Sse) {
op->type = OP_XMM;
@@ -1122,9 +1124,9 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
int rc = X86EMUL_CONTINUE;
ulong modrm_ea = 0;
- ctxt->modrm_reg = ((ctxt->rex_prefix << 1) & 8); /* REX.R */
- index_reg = (ctxt->rex_prefix << 2) & 8; /* REX.X */
- base_reg = (ctxt->rex_prefix << 3) & 8; /* REX.B */
+ ctxt->modrm_reg = ctxt->rex.bits.r3 * BIT(3);
+ index_reg = ctxt->rex.bits.x3 * BIT(3);
+ base_reg = ctxt->rex.bits.b3 * BIT(3);
ctxt->modrm_mod = (ctxt->modrm & 0xc0) >> 6;
ctxt->modrm_reg |= (ctxt->modrm & 0x38) >> 3;
@@ -2466,7 +2468,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
setup_syscalls_segments(&cs, &ss);
- if ((ctxt->rex_prefix & 0x8) != 0x0)
+ if (ctxt->rex.bits.w)
usermode = X86EMUL_MODE_PROT64;
else
usermode = X86EMUL_MODE_PROT32;
@@ -4851,7 +4853,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int
case 0x40 ... 0x4f: /* REX */
if (mode != X86EMUL_MODE_PROT64)
goto done_prefixes;
- ctxt->rex_prefix = ctxt->b;
+ ctxt->rex_prefix = REX_PREFIX;
+ ctxt->rex.raw = 0x0f & ctxt->b;
continue;
case 0xf0: /* LOCK */
ctxt->lock_prefix = 1;
@@ -4865,15 +4868,14 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int
}
/* Any legacy prefix after a REX prefix nullifies its effect. */
-
- ctxt->rex_prefix = 0;
+ ctxt->rex_prefix = REX_NONE;
+ ctxt->rex.raw = 0;
}
done_prefixes:
- /* REX prefix. */
- if (ctxt->rex_prefix & 8)
- ctxt->op_bytes = 8; /* REX.W */
+ if (ctxt->rex.bits.w)
+ ctxt->op_bytes = 8;
/* Opcode byte(s). */
opcode = opcode_table[ctxt->b];
@@ -5137,7 +5139,8 @@ void init_decode_cache(struct x86_emulate_ctxt *ctxt)
{
/* Clear fields that are set conditionally but read without a guard. */
ctxt->rip_relative = false;
- ctxt->rex_prefix = 0;
+ ctxt->rex_prefix = REX_NONE;
+ ctxt->rex.raw = 0;
ctxt->lock_prefix = 0;
ctxt->rep_prefix = 0;
ctxt->regs_valid = 0;
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index 153c70ea5561..b285299ebfa4 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -317,6 +317,32 @@ typedef void (*fastop_t)(struct fastop *);
#define NR_EMULATOR_GPRS 8
#endif
+/*
+ * REX prefix type to distinguish between no prefix, legacy REX, REX2,
+ * or an invalid REX2 sequence.
+ */
+enum rex_type {
+ REX_NONE,
+ REX_PREFIX,
+ REX2_PREFIX,
+ REX2_INVALID
+};
+
+/* Unified representation for REX/REX2 prefix bits */
+union rex_field {
+ struct {
+ u8 b3 :1, /* REX2.B3 or REX.B */
+ x3 :1, /* REX2.X3 or REX.X */
+ r3 :1, /* REX2.R3 or REX.R */
+ w :1, /* REX2.W or REX.W */
+ b4 :1, /* REX2.B4 */
+ x4 :1, /* REX2.X4 */
+ r4 :1, /* REX2.R4 */
+ m0 :1; /* REX2.M0 */
+ } bits;
+ u8 raw;
+};
+
struct x86_emulate_ctxt {
void *vcpu;
const struct x86_emulate_ops *ops;
@@ -357,7 +383,10 @@ struct x86_emulate_ctxt {
int (*check_perm)(struct x86_emulate_ctxt *ctxt);
bool rip_relative;
- u8 rex_prefix;
+ /* Type of REX prefix (none, REX, REX2) */
+ enum rex_type rex_prefix;
+ /* Rex bits */
+ union rex_field rex;
u8 lock_prefix;
u8 rep_prefix;
/* bitmaps of registers in _regs[] that can be read */
--
2.51.0
next prev parent reply other threads:[~2025-11-10 18:24 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-10 18:01 [PATCH RFC v1 00/20] KVM: x86: Support APX feature for guests Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 01/20] KVM: x86: Rename register accessors to be GPR-specific Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 02/20] KVM: x86: Refactor GPR accessors to differentiate register access types Chang S. Bae
2025-11-11 18:08 ` Paolo Bonzini
2025-11-13 23:19 ` Chang S. Bae
2025-11-11 18:11 ` Paolo Bonzini
2025-11-13 23:18 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 03/20] KVM: x86: Implement accessors for extended GPRs Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 04/20] KVM: VMX: Introduce unified instruction info structure Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 05/20] KVM: VMX: Refactor instruction information retrieval Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 06/20] KVM: VMX: Refactor GPR index retrieval from exit qualification Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 07/20] KVM: nVMX: Support the extended instruction info field Chang S. Bae
2025-11-11 17:48 ` Paolo Bonzini
2025-11-12 1:54 ` Chao Gao
2025-11-13 23:21 ` Chang S. Bae
2025-11-17 23:29 ` Paolo Bonzini
2025-11-18 1:39 ` Chao Gao
2025-11-18 10:33 ` Paolo Bonzini
2025-11-13 23:20 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 08/20] KVM: VMX: Support extended register index in exit handling Chang S. Bae
2025-11-11 17:45 ` Paolo Bonzini
2025-11-13 23:22 ` Chang S. Bae
2025-11-13 23:40 ` Paolo Bonzini
2025-11-10 18:01 ` [PATCH RFC v1 09/20] KVM: x86: Support EGPR accessing and tracking for instruction emulation Chang S. Bae
2025-11-10 18:01 ` Chang S. Bae [this message]
2025-11-11 18:17 ` [PATCH RFC v1 10/20] KVM: x86: Refactor REX prefix handling in " Paolo Bonzini
2025-11-13 23:23 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 11/20] KVM: x86: Refactor opcode table lookup " Chang S. Bae
2025-11-11 16:55 ` Paolo Bonzini
2025-11-13 23:24 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 12/20] KVM: x86: Support REX2-extended register index in the decoder Chang S. Bae
2025-11-11 16:53 ` Paolo Bonzini
2025-11-13 23:26 ` Chang S. Bae
2025-11-11 16:53 ` Paolo Bonzini
2025-11-10 18:01 ` [PATCH RFC v1 13/20] KVM: x86: Add REX2 opcode tables to the instruction decoder Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 14/20] KVM: x86: Emulate REX2-prefixed 64-bit absolute jump Chang S. Bae
2025-11-11 16:39 ` Paolo Bonzini
2025-11-13 23:27 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 15/20] KVM: x86: Reject EVEX-prefix instructions in the emulator Chang S. Bae
2025-11-11 16:37 ` Paolo Bonzini
2025-11-13 23:28 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 16/20] KVM: x86: Decode REX2 prefix " Chang S. Bae
2025-11-11 17:55 ` Paolo Bonzini
2025-11-13 23:30 ` Chang S. Bae
2025-11-13 23:34 ` Paolo Bonzini
2025-11-17 20:01 ` Chang S. Bae
2025-11-17 23:33 ` Paolo Bonzini
2025-11-10 18:01 ` [PATCH RFC v1 17/20] KVM: x86: Prepare APX state setting in XCR0 Chang S. Bae
2025-11-11 16:59 ` Paolo Bonzini
2025-11-13 23:32 ` Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 18/20] KVM: x86: Expose APX foundational feature bit to guests Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 19/20] KVM: x86: Expose APX sub-features " Chang S. Bae
2025-11-10 18:01 ` [PATCH RFC v1 20/20] KVM: selftests: Add APX state handling and XCR0 sanity checks Chang S. Bae
2025-11-10 18:50 ` [PATCH RFC v1 00/20] KVM: x86: Support APX feature for guests Chang S. Bae
2025-11-11 18:14 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251110180131.28264-11-chang.seok.bae@intel.com \
--to=chang.seok.bae@intel.com \
--cc=chao.gao@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®