KVM: x86: Reduce the number of emulator GPRs to '8' for 32-bit KVM
authorSean Christopherson <seanjc@google.com>
Thu, 26 May 2022 21:08:14 +0000 (21:08 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 10 Jun 2022 14:01:31 +0000 (10:01 -0400)
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 <seanjc@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Message-Id: <20220526210817.3428868-6-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/emulate.c
arch/x86/kvm/kvm_emulate.h

index 5aaf1d1200af26c682dd126c7f26d2a5d4955391..77161f57c8d3cb26d7782ca8d672b521652a40d2 100644 (file)
@@ -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);
index 3a65d6ea7fe6ec9c11ffa80fd97c3f6c341978cc..034c845b3c63d6489a4616ca00e06ca501fd50dc 100644 (file)
@@ -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;