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 |
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
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 --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;
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(-)