From: Sean Christopherson Date: Thu, 26 May 2022 21:08:14 +0000 (+0000) Subject: KVM: x86: Reduce the number of emulator GPRs to '8' for 32-bit KVM X-Git-Tag: v6.0-rc1~129^2~6^2~384 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b443183a25ab61840a12de92f8822849e017b9c8;p=thirdparty%2Fkernel%2Flinux.git KVM: x86: Reduce the number of emulator GPRs to '8' for 32-bit KVM Reduce the number of GPRs emulated by 32-bit KVM from 16 to 8. KVM does not support emulating 64-bit mode on 32-bit host kernels, and so should never generate accesses to R8-15. Opportunistically use NR_EMULATOR_GPRS in rsm_load_state_{32,64}() now that it is precise and accurate for both flavors. Wrap the definition with full #ifdef ugliness; sadly, IS_ENABLED() doesn't guarantee a compile-time constant as far as BUILD_BUG_ON() is concerned. Signed-off-by: Sean Christopherson Reviewed-by: Kees Cook Message-Id: <20220526210817.3428868-6-seanjc@google.com> Signed-off-by: Paolo Bonzini --- diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5aaf1d1200af2..77161f57c8d3c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2441,7 +2441,7 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLAGS_FIXED; ctxt->_eip = GET_SMSTATE(u32, smstate, 0x7ff0); - for (i = 0; i < 8; i++) + for (i = 0; i < NR_EMULATOR_GPRS; i++) *reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4); val = GET_SMSTATE(u32, smstate, 0x7fcc); @@ -2498,7 +2498,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u16 selector; int i, r; - for (i = 0; i < 16; i++) + for (i = 0; i < NR_EMULATOR_GPRS; i++) *reg_write(ctxt, i) = GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8); ctxt->_eip = GET_SMSTATE(u64, smstate, 0x7f78); diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h index 3a65d6ea7fe6e..034c845b3c63d 100644 --- a/arch/x86/kvm/kvm_emulate.h +++ b/arch/x86/kvm/kvm_emulate.h @@ -306,11 +306,12 @@ typedef void (*fastop_t)(struct fastop *); * tracked/accessed via _eip, and except for RIP relative addressing, which * also uses _eip, RIP cannot be a register operand nor can it be an operand in * a ModRM or SIB byte. - * - * TODO: this is technically wrong for 32-bit KVM, which only supports 8 GPRs; - * R8-R15 don't exist. */ +#ifdef CONFIG_X86_64 #define NR_EMULATOR_GPRS 16 +#else +#define NR_EMULATOR_GPRS 8 +#endif struct x86_emulate_ctxt { void *vcpu;