Re: [PATCH v3 01/20] KVM: VMX: Macrofy 64-bit GPR swapping in __vmx_vcpu_run()

From: Paolo Bonzini

Date: Tue Apr 28 2026 - 05:45:44 EST


On 4/28/26 07:00, Chang S. Bae wrote:
mov VCPU_RBP(%_ASM_DI), %_ASM_BP
mov VCPU_RSI(%_ASM_DI), %_ASM_SI
#ifdef CONFIG_X86_64
- mov VCPU_R8 (%_ASM_DI), %r8
- mov VCPU_R9 (%_ASM_DI), %r9
- mov VCPU_R10(%_ASM_DI), %r10
- mov VCPU_R11(%_ASM_DI), %r11
- mov VCPU_R12(%_ASM_DI), %r12
- mov VCPU_R13(%_ASM_DI), %r13
- mov VCPU_R14(%_ASM_DI), %r14
- mov VCPU_R15(%_ASM_DI), %r15
+ VMX_LOAD_REGS %_ASM_DI, 8,9,10,11,12,13,14,15

Please pass in VMX_vcpu_arch_regs so that you can use the same
macro for Intel and AMD, similar to the SPEC_CTRL macros.

I would also consider using inst.h's name-to-index conversion:

.macro LOAD_GPRS src:req, regs_ofs:req, regs:vararg
.irp reg, \regs
#ifdef CONFIG_X86_64
R64_NUM reg_num \reg
#else
R32_NUM reg_num \reg
#endif
.if \reg_num <> REG_NUM_INVALID
mov (\regs_ofs + \reg_num * WORD_SIZE)(%_ASM_DI), \reg
.else
.err invalid register \reg
.endif
.endr
.endm

LOAD_GPRS %_ASM_DI, VMX_vcpu_arch_regs, \
%_ASM_AX, %_ASM_CX, %_ASM_DX, %_ASM_BX, %_ASM_BP, %_ASM_SI
#ifdef CONFIG_X86_64
LOAD_GPRS %_ASM_DI, VMX_vcpu_arch_regs, \
%r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15
#endif
/* Load guest RDI. This kills the @vmx pointer! */
LOAD_GPRS %_ASM_DI, VMX_vcpu_arch_regs, %_ASM_DI

(same for STORE_GPRS).

Note however that inst.h is currently dead code, so it would have to
move into arch/x86/kvm/ as in the patch after my signature.

Paolo


diff --git a/arch/x86/include/asm/inst.h b/arch/x86/kvm/inst.h
similarity index 66%
rename from arch/x86/include/asm/inst.h
rename to arch/x86/kvm/inst.h
index e48a00b3311d..95ca0826effd 100644
--- a/arch/x86/include/asm/inst.h
+++ b/arch/x86/kvm/inst.h
@@ -1,19 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Generate .byte code for some instructions not supported by old
- * binutils.
+ * Convert register names to their sizes and the indices used when
+ * encoding instructions.
*/
-#ifndef X86_ASM_INST_H
-#define X86_ASM_INST_H
+#ifndef X86_KVM_INST_H
+#define X86_KVM_INST_H
#ifdef __ASSEMBLER__
#define REG_NUM_INVALID 100
-#define REG_TYPE_R32 0
-#define REG_TYPE_R64 1
-#define REG_TYPE_INVALID 100
-
.macro R32_NUM opd r32
\opd = REG_NUM_INVALID
.ifc \r32,%eax
@@ -121,28 +114,6 @@
.endif
#endif
.endm
-
- .macro REG_TYPE type reg
- R32_NUM reg_type_r32 \reg
- R64_NUM reg_type_r64 \reg
- .if reg_type_r64 <> REG_NUM_INVALID
- \type = REG_TYPE_R64
- .elseif reg_type_r32 <> REG_NUM_INVALID
- \type = REG_TYPE_R32
- .else
- \type = REG_TYPE_INVALID
- .endif
- .endm
-
- .macro PFX_REX opd1 opd2 W=0
- .if ((\opd1 | \opd2) & 8) || \W
- .byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1) | (\W << 3)
- .endif
- .endm
-
- .macro MODRM mod opd1 opd2
- .byte \mod | (\opd1 & 7) | ((\opd2 & 7) << 3)
- .endm
#endif
#endif