[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.