ia64/xen-unstable

changeset 16636:181483b8e959

hvm: Some cleanups to vlapic emulation.
Some of this was suggested by Dexuan Cui.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 19 11:14:05 2007 +0000 (2007-12-19)
parents 9d447ba0c99a
children 9b37cabe0485
files xen/arch/x86/hvm/vlapic.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vlapic.c	Wed Dec 19 10:11:54 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/vlapic.c	Wed Dec 19 11:14:05 2007 +0000
     1.3 @@ -472,7 +472,7 @@ static unsigned long vlapic_read(struct 
     1.4      struct vlapic *vlapic = vcpu_vlapic(v);
     1.5      unsigned int offset = address - vlapic_base_address(vlapic);
     1.6  
     1.7 -    if ( offset > APIC_TDCR )
     1.8 +    if ( offset > (APIC_TDCR + 0x3) )
     1.9          return 0;
    1.10  
    1.11      alignment = offset & 0x3;
    1.12 @@ -535,7 +535,7 @@ static void vlapic_write(struct vcpu *v,
    1.13       * According to the IA32 Manual, all accesses should be 32 bits.
    1.14       * Some OSes do 8- or 16-byte accesses, however.
    1.15       */
    1.16 -    val &= 0xffffffff;
    1.17 +    val = (uint32_t)val;
    1.18      if ( len != 4 )
    1.19      {
    1.20          unsigned int tmp;
    1.21 @@ -549,32 +549,27 @@ static void vlapic_write(struct vcpu *v,
    1.22          switch ( len )
    1.23          {
    1.24          case 1:
    1.25 -            val = (tmp & ~(0xff << (8*alignment))) |
    1.26 -                  ((val & 0xff) << (8*alignment));
    1.27 +            val = ((tmp & ~(0xff << (8*alignment))) |
    1.28 +                   ((val & 0xff) << (8*alignment)));
    1.29              break;
    1.30  
    1.31          case 2:
    1.32              if ( alignment & 1 )
    1.33 -            {
    1.34 -                gdprintk(XENLOG_ERR, "Uneven alignment error for "
    1.35 -                         "2-byte vlapic access\n");
    1.36 -                goto exit_and_crash;
    1.37 -            }
    1.38 -
    1.39 -            val = (tmp & ~(0xffff << (8*alignment))) |
    1.40 -                  ((val & 0xffff) << (8*alignment));
    1.41 +                goto unaligned_exit_and_crash;
    1.42 +            val = ((tmp & ~(0xffff << (8*alignment))) |
    1.43 +                   ((val & 0xffff) << (8*alignment)));
    1.44              break;
    1.45  
    1.46          default:
    1.47              gdprintk(XENLOG_ERR, "Local APIC write with len = %lx, "
    1.48                       "should be 4 instead\n", len);
    1.49 -        exit_and_crash:
    1.50 -            domain_crash(v->domain);
    1.51 -            return;
    1.52 +            goto exit_and_crash;
    1.53          }
    1.54      }
    1.55 +    else if ( (offset & 0x3) != 0 )
    1.56 +        goto unaligned_exit_and_crash;
    1.57  
    1.58 -    offset &= 0xff0;
    1.59 +    offset &= ~0x3;
    1.60  
    1.61      switch ( offset )
    1.62      {
    1.63 @@ -671,6 +666,14 @@ static void vlapic_write(struct vcpu *v,
    1.64                   "Local APIC Write to read-only register 0x%x\n", offset);
    1.65          break;
    1.66      }
    1.67 +
    1.68 +    return;
    1.69 +
    1.70 + unaligned_exit_and_crash:
    1.71 +    gdprintk(XENLOG_ERR, "Unaligned LAPIC write len=0x%lx at offset=0x%x.\n",
    1.72 +             len, offset);
    1.73 + exit_and_crash:
    1.74 +    domain_crash(v->domain);
    1.75  }
    1.76  
    1.77  static int vlapic_range(struct vcpu *v, unsigned long addr)