[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/vLAPIC: adjust types in internal read/write handling



- use 32-bit types where possible (produces slightly better code)
- drop (now) unnecessary casts
- avoid indirection where not needed
- avoid duplicate log messages in vlapic_write()
- minor other cleanup

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -556,52 +556,42 @@ static void vlapic_set_tdcr(struct vlapi
                 "timer_divisor: %d", vlapic->hw.timer_divisor);
 }
 
-static void vlapic_read_aligned(
-    struct vlapic *vlapic, unsigned int offset, unsigned int *result)
+static uint32_t vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset)
 {
     switch ( offset )
     {
     case APIC_PROCPRI:
-        *result = vlapic_get_ppr(vlapic);
-        break;
+        return vlapic_get_ppr(vlapic);
 
     case APIC_TMCCT: /* Timer CCR */
         if ( !vlapic_lvtt_oneshot(vlapic) && !vlapic_lvtt_period(vlapic) )
-        {
-            *result = 0;
             break;
-        }
-        *result = vlapic_get_tmcct(vlapic);
-        break;
+        return vlapic_get_tmcct(vlapic);
 
     case APIC_TMICT: /* Timer ICR */
         if ( !vlapic_lvtt_oneshot(vlapic) && !vlapic_lvtt_period(vlapic) )
-        {
-            *result = 0;
             break;
-        }
+        /* fall through */
     default:
-        *result = vlapic_get_reg(vlapic, offset);
-        break;
+        return vlapic_get_reg(vlapic, offset);
     }
+
+    return 0;
 }
 
 static int vlapic_read(
     struct vcpu *v, unsigned long address,
     unsigned long len, unsigned long *pval)
 {
-    unsigned int alignment;
-    unsigned int tmp;
-    unsigned long result = 0;
     struct vlapic *vlapic = vcpu_vlapic(v);
     unsigned int offset = address - vlapic_base_address(vlapic);
+    unsigned int alignment = offset & 3, tmp, result = 0;
 
     if ( offset > (APIC_TDCR + 0x3) )
         goto out;
 
-    alignment = offset & 0x3;
+    tmp = vlapic_read_aligned(vlapic, offset & ~3);
 
-    vlapic_read_aligned(vlapic, offset & ~0x3, &tmp);
     switch ( len )
     {
     case 1:
@@ -627,7 +617,7 @@ static int vlapic_read(
     }
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "offset %#x with length %#lx, "
-                "and the result is %#lx", offset, len, result);
+                "and the result is %#x", offset, len, result);
 
  out:
     *pval = result;
@@ -657,19 +647,17 @@ int hvm_x2apic_msr_read(struct vcpu *v, 
 #undef REGBLOCK
         };
     struct vlapic *vlapic = vcpu_vlapic(v);
-    uint32_t low, high = 0, reg = msr - MSR_IA32_APICBASE_MSR,
-        offset = reg << 4;
+    uint32_t high = 0, reg = msr - MSR_IA32_APICBASE_MSR, offset = reg << 4;
 
     if ( !vlapic_x2apic_mode(vlapic) ||
          (reg >= sizeof(readable) * 8) || !test_bit(reg, readable) )
         return X86EMUL_UNHANDLEABLE;
 
     if ( offset == APIC_ICR )
-        vlapic_read_aligned(vlapic, APIC_ICR2, &high);
-
-    vlapic_read_aligned(vlapic, offset, &low);
+        high = vlapic_read_aligned(vlapic, APIC_ICR2);
 
-    *msr_content = (((uint64_t)high) << 32) | low;
+    *msr_content = ((uint64_t)high << 32) |
+                   vlapic_read_aligned(vlapic, offset);
 
     return X86EMUL_OKAY;
 }
@@ -687,7 +675,7 @@ static void vlapic_tdt_pt_cb(struct vcpu
 }
 
 static int vlapic_reg_write(struct vcpu *v,
-                            unsigned int offset, unsigned long val)
+                            unsigned int offset, uint32_t val)
 {
     struct vlapic *vlapic = vcpu_vlapic(v);
     int rc = X86EMUL_OKAY;
@@ -797,8 +785,7 @@ static int vlapic_reg_write(struct vcpu 
             break;
         }
 
-        period = ((uint64_t)APIC_BUS_CYCLE_NS *
-                  (uint32_t)val * vlapic->hw.timer_divisor);
+        period = (uint64_t)APIC_BUS_CYCLE_NS * val * vlapic->hw.timer_divisor;
         TRACE_2_LONG_3D(TRC_HVM_EMUL_LAPIC_START_TIMER, TRC_PAR_LONG(period),
                  TRC_PAR_LONG(vlapic_lvtt_period(vlapic) ? period : 0LL),
                  vlapic->pt.irq);
@@ -811,7 +798,7 @@ static int vlapic_reg_write(struct vcpu 
 
         HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                     "bus cycle is %uns, "
-                    "initial count %lu, period %"PRIu64"ns",
+                    "initial count %u, period %"PRIu64"ns",
                     APIC_BUS_CYCLE_NS, val, period);
     }
     break;
@@ -847,47 +834,41 @@ static int vlapic_write(struct vcpu *v, 
      * According to the IA32 Manual, all accesses should be 32 bits.
      * Some OSes do 8- or 16-byte accesses, however.
      */
-    val = (uint32_t)val;
-    if ( len != 4 )
+    if ( unlikely(len != 4) )
     {
-        unsigned int tmp;
-        unsigned char alignment;
-
-        gdprintk(XENLOG_INFO, "Notice: Local APIC write with len = %lx\n",len);
-
-        alignment = offset & 0x3;
-        (void)vlapic_read_aligned(vlapic, offset & ~0x3, &tmp);
+        unsigned int tmp = vlapic_read_aligned(vlapic, offset & ~3);
+        unsigned char alignment = (offset & 3) * 8;
 
         switch ( len )
         {
         case 1:
-            val = ((tmp & ~(0xff << (8*alignment))) |
-                   ((val & 0xff) << (8*alignment)));
+            val = ((tmp & ~(0xff << alignment)) |
+                   ((val & 0xff) << alignment));
             break;
 
         case 2:
             if ( alignment & 1 )
                 goto unaligned_exit_and_crash;
-            val = ((tmp & ~(0xffff << (8*alignment))) |
-                   ((val & 0xffff) << (8*alignment)));
+            val = ((tmp & ~(0xffff << alignment)) |
+                   ((val & 0xffff) << alignment));
             break;
 
         default:
-            gdprintk(XENLOG_ERR, "Local APIC write with len = %lx, "
-                     "should be 4 instead\n", len);
+            gprintk(XENLOG_ERR, "LAPIC write with len %lx\n", len);
             goto exit_and_crash;
         }
+
+        gdprintk(XENLOG_INFO, "Notice: LAPIC write with len %lx\n", len);
+        offset &= ~3;
     }
-    else if ( (offset & 0x3) != 0 )
+    else if ( unlikely(offset & 3) )
         goto unaligned_exit_and_crash;
 
-    offset &= ~0x3;
-
     return vlapic_reg_write(v, offset, val);
 
  unaligned_exit_and_crash:
-    gdprintk(XENLOG_ERR, "Unaligned LAPIC write len=%#lx at offset=%#x.\n",
-             len, offset);
+    gprintk(XENLOG_ERR, "Unaligned LAPIC write: len=%#lx offset=%#x.\n",
+            len, offset);
  exit_and_crash:
     domain_crash(v->domain);
     return rc;
@@ -983,7 +964,7 @@ int hvm_x2apic_msr_write(struct vcpu *v,
             return X86EMUL_UNHANDLEABLE;
     }
 
-    return vlapic_reg_write(v, offset, (uint32_t)msr_content);
+    return vlapic_reg_write(v, offset, msr_content);
 }
 
 static int vlapic_range(struct vcpu *v, unsigned long addr)


Attachment: x86-vLAPIC-read-write-types.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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