ia64/xen-unstable

changeset 13311:96dacd72fdbe

Preliminary, likely incomplete and/or wrong, adjustments to shadow code.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Emmanuel Ackaouy <ack@xensource.com>
date Fri Jan 05 17:34:41 2007 +0000 (2007-01-05)
parents b8eeb4537e09
children 973e4d233461
files xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Jan 05 17:34:41 2007 +0000
     1.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Jan 05 17:34:41 2007 +0000
     1.3 @@ -2443,9 +2443,10 @@ static void sh_update_paging_modes(struc
     1.4          /// PV guest
     1.5          ///
     1.6  #if CONFIG_PAGING_LEVELS == 4
     1.7 -        /* When 32-on-64 PV guests are supported, they must choose 
     1.8 -         * a different mode here */
     1.9 -        v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4);
    1.10 +        if ( pv_32bit_guest(v) )
    1.11 +            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
    1.12 +        else
    1.13 +            v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4);
    1.14  #elif CONFIG_PAGING_LEVELS == 3
    1.15          v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
    1.16  #elif CONFIG_PAGING_LEVELS == 2
     2.1 --- a/xen/arch/x86/mm/shadow/multi.c	Fri Jan 05 17:34:41 2007 +0000
     2.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Fri Jan 05 17:34:41 2007 +0000
     2.3 @@ -1422,7 +1422,7 @@ void sh_install_xen_entries_in_l4(struct
     2.4  }
     2.5  #endif
     2.6  
     2.7 -#if CONFIG_PAGING_LEVELS == 3 && GUEST_PAGING_LEVELS == 3
     2.8 +#if (CONFIG_PAGING_LEVELS == 3 || defined(CONFIG_COMPAT)) && GUEST_PAGING_LEVELS == 3
     2.9  // For 3-on-3 PV guests, we need to make sure the xen mappings are in
    2.10  // place, which means that we need to populate the l2h entry in the l3
    2.11  // table.
    2.12 @@ -1432,12 +1432,20 @@ void sh_install_xen_entries_in_l2h(struc
    2.13  {
    2.14      struct domain *d = v->domain;
    2.15      shadow_l2e_t *sl2e;
    2.16 +#if CONFIG_PAGING_LEVELS == 3
    2.17      int i;
    2.18 +#else
    2.19 +
    2.20 +    if ( !pv_32bit_guest(v) )
    2.21 +        return;
    2.22 +#endif
    2.23  
    2.24      sl2e = sh_map_domain_page(sl2hmfn);
    2.25      ASSERT(sl2e != NULL);
    2.26      ASSERT(sizeof (l2_pgentry_t) == sizeof (shadow_l2e_t));
    2.27      
    2.28 +#if CONFIG_PAGING_LEVELS == 3
    2.29 +
    2.30      /* Copy the common Xen mappings from the idle domain */
    2.31      memcpy(&sl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)],
    2.32             &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT],
    2.33 @@ -1478,6 +1486,15 @@ void sh_install_xen_entries_in_l2h(struc
    2.34          }
    2.35          sh_unmap_domain_page(p2m);
    2.36      }
    2.37 +
    2.38 +#else
    2.39 +
    2.40 +    /* Copy the common Xen mappings from the idle domain */
    2.41 +    memcpy(&sl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)],
    2.42 +           &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
    2.43 +           COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*sl2e));
    2.44 +
    2.45 +#endif
    2.46      
    2.47      sh_unmap_domain_page(sl2e);
    2.48  }
    2.49 @@ -1660,6 +1677,19 @@ sh_make_monitor_table(struct vcpu *v)
    2.50              l4e = sh_map_domain_page(m4mfn);
    2.51              l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR);
    2.52              sh_unmap_domain_page(l4e);
    2.53 +            if ( pv_32bit_guest(v) )
    2.54 +            {
    2.55 +                // Install a monitor l2 table in slot 3 of the l3 table.
    2.56 +                // This is used for all Xen entries.
    2.57 +                mfn_t m2mfn;
    2.58 +                l3_pgentry_t *l3e;
    2.59 +                m2mfn = shadow_alloc(d, SH_type_monitor_table, 0);
    2.60 +                mfn_to_page(m2mfn)->shadow_flags = 2;
    2.61 +                l3e = sh_map_domain_page(m3mfn);
    2.62 +                l3e[3] = l3e_from_pfn(mfn_x(m2mfn), _PAGE_PRESENT);
    2.63 +                sh_install_xen_entries_in_l2h(v, m2mfn);
    2.64 +                sh_unmap_domain_page(l3e);
    2.65 +            }
    2.66          }
    2.67  #endif /* SHADOW_PAGING_LEVELS < 4 */
    2.68          return m4mfn;
    2.69 @@ -2067,7 +2097,16 @@ void sh_destroy_monitor_table(struct vcp
    2.70      {
    2.71          l4_pgentry_t *l4e = sh_map_domain_page(mmfn);
    2.72          ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT);
    2.73 -        shadow_free(d, _mfn(l4e_get_pfn(l4e[0])));
    2.74 +        mmfn = _mfn(l4e_get_pfn(l4e[0]));
    2.75 +        if ( pv_32bit_guest(v) )
    2.76 +        {
    2.77 +            /* Need to destroy the l2 monitor page in slot 3 too */
    2.78 +            l3_pgentry_t *l3e = sh_map_domain_page(mmfn);
    2.79 +            ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT);
    2.80 +            shadow_free(d, _mfn(l3e_get_pfn(l3e[3])));
    2.81 +            sh_unmap_domain_page(l3e);
    2.82 +        }
    2.83 +        shadow_free(d, mmfn);
    2.84          sh_unmap_domain_page(l4e);
    2.85      }
    2.86  #elif CONFIG_PAGING_LEVELS == 3
    2.87 @@ -3044,12 +3083,15 @@ sh_update_linear_entries(struct vcpu *v)
    2.88  
    2.89  #elif (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS == 3)
    2.90  
    2.91 -    /* This case only exists in HVM.  To give ourselves a linear map of the 
    2.92 -     * shadows, we need to extend a PAE shadow to 4 levels.  We do this by 
    2.93 -     * having a monitor l3 in slot 0 of the monitor l4 table, and 
    2.94 -     * copying the PAE l3 entries into it.  Then, by having the monitor l4e
    2.95 -     * for shadow pagetables also point to the monitor l4, we can use it
    2.96 -     * to access the shadows. */
    2.97 +    /* PV: XXX
    2.98 +     *
    2.99 +     * HVM: To give ourselves a linear map of the  shadows, we need to
   2.100 +     * extend a PAE shadow to 4 levels.  We do this by  having a monitor
   2.101 +     * l3 in slot 0 of the monitor l4 table, and  copying the PAE l3
   2.102 +     * entries into it.  Then, by having the monitor l4e for shadow
   2.103 +     * pagetables also point to the monitor l4, we can use it to access
   2.104 +     * the shadows.
   2.105 +     */
   2.106  
   2.107      if ( shadow_mode_external(d) )
   2.108      {
   2.109 @@ -3092,6 +3134,8 @@ sh_update_linear_entries(struct vcpu *v)
   2.110          if ( v != current ) 
   2.111              sh_unmap_domain_page(ml3e);
   2.112      }
   2.113 +    else
   2.114 +        domain_crash(d); /* XXX */
   2.115  
   2.116  #elif CONFIG_PAGING_LEVELS == 3
   2.117  
   2.118 @@ -3404,7 +3448,7 @@ sh_update_cr3(struct vcpu *v, int do_loc
   2.119                     (unsigned long)pagetable_get_pfn(v->arch.guest_table));
   2.120  
   2.121  #if GUEST_PAGING_LEVELS == 4
   2.122 -    if ( !(v->arch.flags & TF_kernel_mode) )
   2.123 +    if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) )
   2.124          gmfn = pagetable_get_mfn(v->arch.guest_table_user);
   2.125      else
   2.126  #endif
     3.1 --- a/xen/include/asm-x86/shadow.h	Fri Jan 05 17:34:41 2007 +0000
     3.2 +++ b/xen/include/asm-x86/shadow.h	Fri Jan 05 17:34:41 2007 +0000
     3.3 @@ -67,6 +67,14 @@
     3.4   * It is also true for all vcpus of translated PV domains. */
     3.5  #define shadow_vcpu_mode_translate(_v) ((_v)->arch.shadow.translate_enabled)
     3.6  
     3.7 +/*
     3.8 + * 32on64 support
     3.9 + */
    3.10 +#ifdef __x86_64__
    3.11 +#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain))
    3.12 +#else
    3.13 +#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v))
    3.14 +#endif
    3.15  
    3.16  /******************************************************************************
    3.17   * With shadow pagetables, the different kinds of address start