[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>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2006-09-30 11:30:09 +01:00
1 parent 137a9ce8c7
commit 963edd2c4e
2 files changed
+31 -19

No files matched your search

+14 -9
View File
@@ -57,7 +57,7 @@
extern void do_nmi(struct cpu_user_regs *, unsigned long);
extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
int inst_len);
extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
extern asmlinkage void do_IRQ(struct cpu_user_regs *);
extern void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
unsigned long count, int size, long value, int dir, int pvalid);
@@ -904,9 +904,9 @@ static void svm_relinquish_guest_resources(struct domain *d)
destroy_vmcb(&v->arch.hvm_svm);
kill_timer(&v->arch.hvm_vcpu.hlt_timer);
if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
if ( VLAPIC(v) != NULL )
{
kill_timer( &(VLAPIC(v)->vlapic_timer) );
kill_timer(&VLAPIC(v)->vlapic_timer);
unmap_domain_page_global(VLAPIC(v)->regs);
free_domheap_page(VLAPIC(v)->regs_page);
xfree(VLAPIC(v));
@@ -930,12 +930,13 @@ static void svm_migrate_timers(struct vcpu *v)
struct periodic_time *pt =
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
if ( pt->enabled ) {
migrate_timer( &pt->timer, v->processor );
migrate_timer( &v->arch.hvm_vcpu.hlt_timer, v->processor );
if ( pt->enabled )
{
migrate_timer(&pt->timer, v->processor);
migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
}
if ( hvm_apic_support(v->domain) && VLAPIC( v ))
migrate_timer( &(VLAPIC(v)->vlapic_timer ), v->processor );
if ( VLAPIC(v) != NULL )
migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
}
@@ -1634,9 +1635,11 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
case 4:
value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
if (svm_dbg_on)
printk( "CR4 read=%lx\n", value );
printk("CR4 read=%lx\n", value);
break;
case 8:
if ( vlapic == NULL )
break;
value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
value = (value & 0xF0) >> 4;
break;
@@ -1814,6 +1817,8 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
case 8:
{
if ( vlapic == NULL )
break;
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
vlapic_update_ppr(vlapic);
break;
+17 -10
View File
@@ -135,7 +135,7 @@ static void vmx_relinquish_guest_resources(struct domain *d)
if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
continue;
kill_timer(&v->arch.hvm_vcpu.hlt_timer);
if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
if ( VLAPIC(v) != NULL )
{
kill_timer(&VLAPIC(v)->vlapic_timer);
unmap_domain_page_global(VLAPIC(v)->regs);
@@ -495,12 +495,13 @@ void vmx_migrate_timers(struct vcpu *v)
{
struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
if ( pt->enabled ) {
if ( pt->enabled )
{
migrate_timer(&pt->timer, v->processor);
migrate_timer(&v->arch.hvm_vcpu.hlt_timer, v->processor);
}
if ( hvm_apic_support(v->domain) && VLAPIC(v))
migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
if ( VLAPIC(v) != NULL )
migrate_timer(&VLAPIC(v)->vlapic_timer, v->processor);
}
static void vmx_store_cpu_guest_regs(
@@ -1767,6 +1768,8 @@ static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
}
case 8:
{
if ( vlapic == NULL )
break;
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
vlapic_update_ppr(vlapic);
break;
@@ -1788,15 +1791,19 @@ static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
struct vcpu *v = current;
struct vlapic *vlapic = VLAPIC(v);
if ( cr != 3 && cr != 8)
__hvm_bug(regs);
if ( cr == 3 )
value = (unsigned long) v->arch.hvm_vmx.cpu_cr3;
else if ( cr == 8 )
switch ( cr )
{
case 3:
value = (unsigned long)v->arch.hvm_vmx.cpu_cr3;
break;
case 8:
if ( vlapic == NULL )
break;
value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
value = (value & 0xF0) >> 4;
break;
default:
__hvm_bug(regs);
}
switch ( gp ) {
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.