direct-io.hg

changeset 15390:69658f935cc7

32-on-64: Fix error path where we fail to successfully switch a guest
into compat mode.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Jun 20 13:38:48 2007 +0100 (2007-06-20)
parents 07be0266f6d8
children fe3df33e2761
files xen/arch/x86/domain.c
line diff
     1.1 --- a/xen/arch/x86/domain.c	Wed Jun 20 13:38:22 2007 +0100
     1.2 +++ b/xen/arch/x86/domain.c	Wed Jun 20 13:38:48 2007 +0100
     1.3 @@ -232,7 +232,7 @@ static int setup_compat_l4(struct vcpu *
     1.4      l4_pgentry_t *l4tab;
     1.5      int rc;
     1.6  
     1.7 -    if ( !pg )
     1.8 +    if ( pg == NULL )
     1.9          return -ENOMEM;
    1.10  
    1.11      /* This page needs to look like a pagetable so that it can be shadowed */
    1.12 @@ -244,8 +244,6 @@ static int setup_compat_l4(struct vcpu *
    1.13      l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] =
    1.14          l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3),
    1.15                         __PAGE_HYPERVISOR);
    1.16 -    v->arch.guest_table = pagetable_from_page(pg);
    1.17 -    v->arch.guest_table_user = v->arch.guest_table;
    1.18  
    1.19      if ( (rc = setup_arg_xlat_area(v, l4tab)) < 0 )
    1.20      {
    1.21 @@ -253,6 +251,9 @@ static int setup_compat_l4(struct vcpu *
    1.22          return rc;
    1.23      }
    1.24  
    1.25 +    v->arch.guest_table = pagetable_from_page(pg);
    1.26 +    v->arch.guest_table_user = v->arch.guest_table;
    1.27 +
    1.28      return 0;
    1.29  }
    1.30  
    1.31 @@ -318,11 +319,11 @@ int switch_compat(struct domain *d)
    1.32      gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
    1.33      for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ )
    1.34      {
    1.35 +        if ( (d->vcpu[vcpuid] != NULL) &&
    1.36 +             (setup_compat_l4(d->vcpu[vcpuid]) != 0) )
    1.37 +            goto undo_and_fail;
    1.38          d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
    1.39                                   FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
    1.40 -        if (d->vcpu[vcpuid]
    1.41 -            && setup_compat_l4(d->vcpu[vcpuid]) != 0)
    1.42 -            return -ENOMEM;
    1.43      }
    1.44  
    1.45      d->arch.physaddr_bitsize =
    1.46 @@ -330,6 +331,19 @@ int switch_compat(struct domain *d)
    1.47          + (PAGE_SIZE - 2);
    1.48  
    1.49      return 0;
    1.50 +
    1.51 + undo_and_fail:
    1.52 +    d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0;
    1.53 +    release_arg_xlat_area(d);
    1.54 +    gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
    1.55 +    while ( vcpuid-- != 0 )
    1.56 +    {
    1.57 +        if ( d->vcpu[vcpuid] != NULL )
    1.58 +            release_compat_l4(d->vcpu[vcpuid]);
    1.59 +        d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
    1.60 +                                 FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
    1.61 +    }
    1.62 +    return -ENOMEM;
    1.63  }
    1.64  
    1.65  #else