diff mbox series

[3/4] KVM: x86: Omit VCPU_REGS_RIP from emulator's _regs array

Message ID 20220525222604.2810054-4-seanjc@google.com (mailing list archive)
State New, archived
Headers show
Series KVM: x86: Emulator _regs fixes and cleanups | expand

Commit Message

Sean Christopherson May 25, 2022, 10:26 p.m. UTC
Omit RIP from the emulator's _regs array, which is used only for GPRs,
i.e. registers that can be referenced via ModRM and/or SIB bytes.  The
emulator uses the dedicated _eip field for RIP, and manually reads from
_eip to handle RIP-relative addressing.

Replace all open coded instances of '16' with the new NR_EMULATOR_GPRS.

See also the comments above the read_gpr() and write_gpr() declarations,
and obviously the handling in writeback_registers().

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/emulate.c     | 12 ++++++------
 arch/x86/kvm/kvm_emulate.h | 10 +++++++++-
 2 files changed, 15 insertions(+), 7 deletions(-)

Comments

kernel test robot May 26, 2022, 2:55 a.m. UTC | #1
Hi Sean,

I love your patch! Yet something to improve:

[auto build test ERROR on 90bde5bea810d766e7046bf5884f2ccf76dd78e9]

url:    https://github.com/intel-lab-lkp/linux/commits/Sean-Christopherson/KVM-x86-Emulator-_regs-fixes-and-cleanups/20220526-062734
base:   90bde5bea810d766e7046bf5884f2ccf76dd78e9
config: i386-debian-10.3-kselftests (https://download.01.org/0day-ci/archive/20220526/202205261040.m1luL6IW-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-1) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/a2e1bffa1b7c8179bed0c28ade24b1a73d7220de
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Sean-Christopherson/KVM-x86-Emulator-_regs-fixes-and-cleanups/20220526-062734
        git checkout a2e1bffa1b7c8179bed0c28ade24b1a73d7220de
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash arch/x86/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/x86/kvm/x86.h:9,
                    from arch/x86/kvm/cpuid.h:5,
                    from arch/x86/kvm/mmu.h:7,
                    from arch/x86/kvm/x86.c:22:
>> arch/x86/kvm/kvm_emulate.h:310:34: error: 'VCPU_REGS_R15' undeclared here (not in a function); did you mean 'VCPU_REGS_RIP'?
     310 | #define NR_EMULATOR_GPRS        (VCPU_REGS_R15 + 1)
         |                                  ^~~~~~~~~~~~~
   arch/x86/kvm/kvm_emulate.h:374:29: note: in expansion of macro 'NR_EMULATOR_GPRS'
     374 |         unsigned long _regs[NR_EMULATOR_GPRS];
         |                             ^~~~~~~~~~~~~~~~
--
   In file included from arch/x86/kvm/emulate.c:23:
>> arch/x86/kvm/kvm_emulate.h:310:34: error: 'VCPU_REGS_R15' undeclared here (not in a function); did you mean 'VCPU_REGS_RIP'?
     310 | #define NR_EMULATOR_GPRS        (VCPU_REGS_R15 + 1)
         |                                  ^~~~~~~~~~~~~
   arch/x86/kvm/kvm_emulate.h:374:29: note: in expansion of macro 'NR_EMULATOR_GPRS'
     374 |         unsigned long _regs[NR_EMULATOR_GPRS];
         |                             ^~~~~~~~~~~~~~~~
   arch/x86/kvm/emulate.c: In function 'reg_write':
   arch/x86/kvm/emulate.c:268:1: error: control reaches end of non-void function [-Werror=return-type]
     268 | }
         | ^
   arch/x86/kvm/emulate.c: In function 'reg_read':
   arch/x86/kvm/emulate.c:258:1: error: control reaches end of non-void function [-Werror=return-type]
     258 | }
         | ^
   cc1: some warnings being treated as errors
--
   In file included from arch/x86/kvm/vmx/../x86.h:9,
                    from arch/x86/kvm/vmx/../cpuid.h:5,
                    from arch/x86/kvm/vmx/evmcs.c:7:
>> arch/x86/kvm/vmx/../kvm_emulate.h:310:34: error: 'VCPU_REGS_R15' undeclared here (not in a function); did you mean 'VCPU_REGS_RIP'?
     310 | #define NR_EMULATOR_GPRS        (VCPU_REGS_R15 + 1)
         |                                  ^~~~~~~~~~~~~
   arch/x86/kvm/vmx/../kvm_emulate.h:374:29: note: in expansion of macro 'NR_EMULATOR_GPRS'
     374 |         unsigned long _regs[NR_EMULATOR_GPRS];
         |                             ^~~~~~~~~~~~~~~~


vim +310 arch/x86/kvm/kvm_emulate.h

   303	
   304	/*
   305	 * The emulator's _regs array tracks only the GPRs, i.e. excludes RIP.  RIP is
   306	 * tracked/accessed via _eip, and except for RIP relative addressing, which
   307	 * also uses _eip, RIP cannot be a register operand nor can it be an operand in
   308	 * a ModRM or SIB byte.
   309	 */
 > 310	#define NR_EMULATOR_GPRS	(VCPU_REGS_R15 + 1)
   311
Sean Christopherson May 26, 2022, 3:47 p.m. UTC | #2
On Thu, May 26, 2022, kernel test robot wrote:
> Hi Sean,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on 90bde5bea810d766e7046bf5884f2ccf76dd78e9]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Sean-Christopherson/KVM-x86-Emulator-_regs-fixes-and-cleanups/20220526-062734
> base:   90bde5bea810d766e7046bf5884f2ccf76dd78e9
> config: i386-debian-10.3-kselftests (https://download.01.org/0day-ci/archive/20220526/202205261040.m1luL6IW-lkp@intel.com/config)

Doh, forgot to build and test 32-bit KVM.  For this patch, I think it makes sense
to just hardcode the number of registers to 16.  But in a follow-up, that can be
reduced to 8 for 32-bit KVM, and then rsm_load_state_32() can use NR_EMULATOR_GPRS
too.
diff mbox series

Patch

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c58366ae4da2..dd1bf116a9ed 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -247,8 +247,8 @@  enum x86_transfer_type {
 
 static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr)
 {
-	if (WARN_ON_ONCE(nr >= 16))
-		nr &= 16 - 1;
+	if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS))
+		nr &= NR_EMULATOR_GPRS - 1;
 
 	if (!(ctxt->regs_valid & (1 << nr))) {
 		ctxt->regs_valid |= 1 << nr;
@@ -259,8 +259,8 @@  static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr)
 
 static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr)
 {
-	if (WARN_ON_ONCE(nr >= 16))
-		nr &= 16 - 1;
+	if (WARN_ON_ONCE(nr >= NR_EMULATOR_GPRS))
+		nr &= NR_EMULATOR_GPRS - 1;
 
 	ctxt->regs_valid |= 1 << nr;
 	ctxt->regs_dirty |= 1 << nr;
@@ -278,7 +278,7 @@  static void writeback_registers(struct x86_emulate_ctxt *ctxt)
 	unsigned long dirty = ctxt->regs_dirty;
 	unsigned reg;
 
-	for_each_set_bit(reg, &dirty, 16)
+	for_each_set_bit(reg, &dirty, NR_EMULATOR_GPRS)
 		ctxt->ops->write_gpr(ctxt, reg, ctxt->_regs[reg]);
 }
 
@@ -2495,7 +2495,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 8dff25d267b7..bdd4e9865ca9 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -301,6 +301,14 @@  struct fastop;
 
 typedef void (*fastop_t)(struct fastop *);
 
+/*
+ * The emulator's _regs array tracks only the GPRs, i.e. excludes RIP.  RIP is
+ * 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.
+ */
+#define NR_EMULATOR_GPRS	(VCPU_REGS_R15 + 1)
+
 struct x86_emulate_ctxt {
 	void *vcpu;
 	const struct x86_emulate_ops *ops;
@@ -363,7 +371,7 @@  struct x86_emulate_ctxt {
 	struct operand src2;
 	struct operand dst;
 	struct operand memop;
-	unsigned long _regs[NR_VCPU_REGS];
+	unsigned long _regs[NR_EMULATOR_GPRS];
 	struct operand *memopp;
 	struct fetch_cache fetch;
 	struct read_cache io_read;