direct-io.hg

changeset 11682:82983c636549

[HVM] Mov to/from CR8 must be gated on whether VLAPIC device is created.

If APIC=0 in VMX configuration file, VLAPIC(v) in
mov_from_cr()/mov_to_cr() will be NULL, so calling
vlapic_get_reg()/vlapic_set_reg()/vlapic_update_ppr()
would crash Xen.

Original patch from Dexuan Cui <dexuan.cui@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Sep 30 11:30:09 2006 +0100 (2006-09-30)
parents 96a6649fa691
children 02311d8aba86
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Sat Sep 30 11:11:54 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Sat Sep 30 11:30:09 2006 +0100
     1.3 @@ -57,7 +57,7 @@
     1.4  extern void do_nmi(struct cpu_user_regs *, unsigned long);
     1.5  extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
     1.6                                  int inst_len);
     1.7 - extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
     1.8 +extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
     1.9  extern asmlinkage void do_IRQ(struct cpu_user_regs *);
    1.10  extern void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
    1.11                           unsigned long count, int size, long value, int dir, int pvalid);
    1.12 @@ -904,9 +904,9 @@ static void svm_relinquish_guest_resourc
    1.13  
    1.14          destroy_vmcb(&v->arch.hvm_svm);
    1.15          kill_timer(&v->arch.hvm_vcpu.hlt_timer);
    1.16 -        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
    1.17 +        if ( VLAPIC(v) != NULL )
    1.18          {
    1.19 -            kill_timer( &(VLAPIC(v)->vlapic_timer) );
    1.20 +            kill_timer(&VLAPIC(v)->vlapic_timer);
    1.21              unmap_domain_page_global(VLAPIC(v)->regs);
    1.22              free_domheap_page(VLAPIC(v)->regs_page);
    1.23              xfree(VLAPIC(v));
    1.24 @@ -930,12 +930,13 @@ static void svm_migrate_timers(struct vc
    1.25      struct periodic_time *pt = 
    1.26          &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
    1.27  
    1.28 -    if ( pt->enabled ) {
    1.29 -        migrate_timer( &pt->timer, v->processor );
    1.30 -        migrate_timer( &v->arch.hvm_vcpu.hlt_timer, v->processor );
    1.31 +    if ( pt->enabled )
    1.32 +    {
    1.33 +        migrate_timer(&pt->timer, v->processor);
    1.34 +        migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
    1.35      }
    1.36 -    if ( hvm_apic_support(v->domain) && VLAPIC( v ))
    1.37 -        migrate_timer( &(VLAPIC(v)->vlapic_timer ), v->processor );
    1.38 +    if ( VLAPIC(v) != NULL )
    1.39 +        migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
    1.40  }
    1.41  
    1.42  
    1.43 @@ -1634,9 +1635,11 @@ static void mov_from_cr(int cr, int gp, 
    1.44      case 4:
    1.45          value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
    1.46          if (svm_dbg_on)
    1.47 -            printk( "CR4 read=%lx\n", value );
    1.48 +            printk("CR4 read=%lx\n", value);
    1.49          break;
    1.50      case 8:
    1.51 +        if ( vlapic == NULL )
    1.52 +            break;
    1.53          value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
    1.54          value = (value & 0xF0) >> 4;
    1.55          break;
    1.56 @@ -1814,6 +1817,8 @@ static int mov_to_cr(int gpreg, int cr, 
    1.57  
    1.58      case 8:
    1.59      {
    1.60 +        if ( vlapic == NULL )
    1.61 +            break;
    1.62          vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
    1.63          vlapic_update_ppr(vlapic);
    1.64          break;
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Sat Sep 30 11:11:54 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Sat Sep 30 11:30:09 2006 +0100
     2.3 @@ -135,7 +135,7 @@ static void vmx_relinquish_guest_resourc
     2.4          if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     2.5              continue;
     2.6          kill_timer(&v->arch.hvm_vcpu.hlt_timer);
     2.7 -        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
     2.8 +        if ( VLAPIC(v) != NULL )
     2.9          {
    2.10              kill_timer(&VLAPIC(v)->vlapic_timer);
    2.11              unmap_domain_page_global(VLAPIC(v)->regs);
    2.12 @@ -495,12 +495,13 @@ void vmx_migrate_timers(struct vcpu *v)
    2.13  {
    2.14      struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
    2.15  
    2.16 -    if ( pt->enabled ) {
    2.17 +    if ( pt->enabled )
    2.18 +    {
    2.19          migrate_timer(&pt->timer, v->processor);
    2.20          migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
    2.21      }
    2.22 -    if ( hvm_apic_support(v->domain) && VLAPIC(v))
    2.23 -        migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
    2.24 +    if ( VLAPIC(v) != NULL )
    2.25 +        migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
    2.26  }
    2.27  
    2.28  static void vmx_store_cpu_guest_regs(
    2.29 @@ -1767,6 +1768,8 @@ static int mov_to_cr(int gp, int cr, str
    2.30      }
    2.31      case 8:
    2.32      {
    2.33 +        if ( vlapic == NULL )
    2.34 +            break;
    2.35          vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
    2.36          vlapic_update_ppr(vlapic);
    2.37          break;
    2.38 @@ -1788,15 +1791,19 @@ static void mov_from_cr(int cr, int gp, 
    2.39      struct vcpu *v = current;
    2.40      struct vlapic *vlapic = VLAPIC(v);
    2.41  
    2.42 -    if ( cr != 3 && cr != 8)
    2.43 -        __hvm_bug(regs);
    2.44 -
    2.45 -    if ( cr == 3 )
    2.46 -        value = (unsigned long) v->arch.hvm_vmx.cpu_cr3;
    2.47 -    else if ( cr == 8 )
    2.48 +    switch ( cr )
    2.49      {
    2.50 +    case 3:
    2.51 +        value = (unsigned long)v->arch.hvm_vmx.cpu_cr3;
    2.52 +        break;
    2.53 +    case 8:
    2.54 +        if ( vlapic == NULL )
    2.55 +            break;
    2.56          value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
    2.57          value = (value & 0xF0) >> 4;
    2.58 +        break;
    2.59 +    default:
    2.60 +        __hvm_bug(regs);
    2.61      }
    2.62  
    2.63      switch ( gp ) {