[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 3/4] 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 no users currently 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, and out-of-range GPRs would have hit the BUG() previously. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- v2: * Fix commit message --- xen/arch/x86/hvm/hvm.c | 17 ++--------------- xen/arch/x86/hvm/vmx/vvmx.c | 16 +++------------- xen/arch/x86/x86_emulate/x86_emulate.c | 15 ++------------- xen/arch/x86/x86_emulate/x86_emulate.h | 29 +++++++++++++++++++++++++---- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 8d67851..18d721d 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2061,16 +2061,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); @@ -2111,13 +2104,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 123d941..3766b7a 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1936,7 +1936,7 @@ load_seg( } /* Map GPRs by ModRM encoding to their offset within struct cpu_user_regs. */ -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)), @@ -1973,18 +1973,7 @@ decode_register( }; if ( !highbyte_regs ) - { - /* Check that the array is a power of two. */ - BUILD_BUG_ON(ARRAY_SIZE(cpu_user_regs_gpr_offsets) & - (ARRAY_SIZE(cpu_user_regs_gpr_offsets) - 1)); - - ASSERT(modrm_reg < ARRAY_SIZE(cpu_user_regs_gpr_offsets)); - - /* For safety in release builds. Debug builds will hit the ASSERT() */ - modrm_reg &= ARRAY_SIZE(cpu_user_regs_gpr_offsets) - 1; - - return (void *)regs + cpu_user_regs_gpr_offsets[modrm_reg]; - } + return decode_gpr(regs, modrm_reg); /* Check that the array is a power of two. */ BUILD_BUG_ON(ARRAY_SIZE(byteop_offsets) & diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h index 0c8c80a..ab5ef41 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,27 @@ 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) +{ + /* Check that the array is a power of two. */ + BUILD_BUG_ON(ARRAY_SIZE(cpu_user_regs_gpr_offsets) & + (ARRAY_SIZE(cpu_user_regs_gpr_offsets) - 1)); + + 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 |