[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/3] x86/hvm: Improvements to external users of decode_register()
* Rename to decode_gpr() to be more specific as to its purpose * Drop the highbyte encoding handling, as users care, and it unlikely that future users would care. * Change to a static inline, returning an unsigned long pointer. Doing so highlights that the "invalid gpr" paths in hvm_mov_{to,from}_cr() were actually unreachable. All callers already passed in-range gprs, which would have hit a BUG() previously. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Jun Nakajima <jun.nakajima@xxxxxxxxx> CC: Kevin Tian <kevin.tian@xxxxxxxxx> Future work: We should have gpr_{read,write}() helpers which suitably cast/truncate values, because all these callsites have broken corner cases, but that involves wiring the current operand size thought, which I haven't got time to do right now. --- xen/arch/x86/hvm/hvm.c | 17 ++--------------- xen/arch/x86/hvm/vmx/vvmx.c | 16 +++------------- xen/arch/x86/x86_emulate/x86_emulate.c | 2 +- xen/arch/x86/x86_emulate/x86_emulate.h | 25 +++++++++++++++++++++---- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 2689046..59ef754 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2059,16 +2059,9 @@ static void hvm_set_uc_mode(struct vcpu *v, bool_t is_in_uc_mode) int hvm_mov_to_cr(unsigned int cr, unsigned int gpr) { struct vcpu *curr = current; - unsigned long val, *reg; + unsigned long val = *decode_gpr(guest_cpu_user_regs(), gpr); int rc; - if ( (reg = decode_register(gpr, guest_cpu_user_regs(), 0)) == NULL ) - { - gdprintk(XENLOG_ERR, "invalid gpr: %u\n", gpr); - goto exit_and_crash; - } - - val = *reg; HVMTRACE_LONG_2D(CR_WRITE, cr, TRC_PAR_LONG(val)); HVM_DBG_LOG(DBG_LEVEL_1, "CR%u, value = %lx", cr, val); @@ -2109,13 +2102,7 @@ int hvm_mov_to_cr(unsigned int cr, unsigned int gpr) int hvm_mov_from_cr(unsigned int cr, unsigned int gpr) { struct vcpu *curr = current; - unsigned long val = 0, *reg; - - if ( (reg = decode_register(gpr, guest_cpu_user_regs(), 0)) == NULL ) - { - gdprintk(XENLOG_ERR, "invalid gpr: %u\n", gpr); - goto exit_and_crash; - } + unsigned long val = 0, *reg = decode_gpr(guest_cpu_user_regs(), gpr); switch ( cr ) { diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index 885eab3..dfe97b9 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -347,18 +347,14 @@ enum vmx_insn_errno set_vvmcs_real_safe(const struct vcpu *v, u32 encoding, static unsigned long reg_read(struct cpu_user_regs *regs, unsigned int index) { - unsigned long *pval = decode_register(index, regs, 0); - - return *pval; + return *decode_gpr(regs, index); } static void reg_write(struct cpu_user_regs *regs, unsigned int index, unsigned long value) { - unsigned long *pval = decode_register(index, regs, 0); - - *pval = value; + *decode_gpr(regs, index) = value; } static inline u32 __n2_pin_exec_control(struct vcpu *v) @@ -2483,14 +2479,8 @@ int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs, case VMX_CONTROL_REG_ACCESS_TYPE_MOV_TO_CR: { unsigned long gp = VMX_CONTROL_REG_ACCESS_GPR(exit_qualification); - unsigned long *reg; + val = *decode_gpr(guest_cpu_user_regs(), gp); - if ( (reg = decode_register(gp, guest_cpu_user_regs(), 0)) == NULL ) - { - gdprintk(XENLOG_ERR, "invalid gpr: %lx\n", gp); - break; - } - val = *reg; if ( cr == 0 ) { u64 cr0_gh_mask = get_vvmcs(v, CR0_GUEST_HOST_MASK); diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 3f5636f..70c38a2 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -400,7 +400,7 @@ static const uint8_t pmov_convert_delta[] = { 1, 2, 3, 1, 2, 1 }; * Map GPRs by ModRM encoding to their offset within struct cpu_user_regs. * The AH,CH,DH,BH offsets are misaligned. */ -static const uint8_t cpu_user_regs_gpr_offsets[] = { +const uint8_t cpu_user_regs_gpr_offsets[] = { offsetof(struct cpu_user_regs, r(ax)), offsetof(struct cpu_user_regs, r(cx)), offsetof(struct cpu_user_regs, r(dx)), diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h index 0c8c80a..5cdcfdd 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -25,6 +25,14 @@ #define MAX_INST_LEN 15 +#if defined(__i386__) +# define X86_NR_GPRS 8 +#elif defined(__x86_64__) +# define X86_NR_GPRS 16 +#else +# error Unknown compilation width +#endif + struct x86_emulate_ctxt; /* @@ -601,14 +609,23 @@ int x86_emulate_wrapper( #define x86_emulate x86_emulate_wrapper #endif +/* Map GPRs by ModRM encoding to their offset within struct cpu_user_regs. */ +extern const uint8_t cpu_user_regs_gpr_offsets[X86_NR_GPRS]; + /* * Given the 'reg' portion of a ModRM byte, and a register block, return a * pointer into the block that addresses the relevant register. - * @highbyte_regs specifies whether to decode AH,CH,DH,BH. */ -void * -decode_register( - uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs); +static inline unsigned long *decode_gpr(struct cpu_user_regs *regs, + unsigned int modrm) +{ + ASSERT(modrm < ARRAY_SIZE(cpu_user_regs_gpr_offsets)); + + /* For safety in release builds. Debug builds will hit the ASSERT() */ + modrm &= ARRAY_SIZE(cpu_user_regs_gpr_offsets) - 1; + + return (void *)regs + cpu_user_regs_gpr_offsets[modrm]; +} /* Unhandleable read, write or instruction fetch */ int -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |