debuggers.hg

changeset 22270:a4016a257672

x86 shadow: reset up-pointers on all l3s when l3s stop being pinnable.

Walking the pinned-shadows list isn't enough: there could be an
unpinned (but still shadowed) l3 somewhere and if we later try to
unshadow it it'll have an up-pointer of PAGE_LIST_NULL:PAGE_LIST_NULL.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
author Keir Fraser <keir@xen.org>
date Sat Oct 02 15:05:50 2010 +0100 (2010-10-02)
parents 4beee5779122
children fe3018c6976d
files xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/mm/shadow/private.h
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/common.c	Sat Oct 02 15:04:21 2010 +0100
     1.2 +++ b/xen/arch/x86/mm/shadow/common.c	Sat Oct 02 15:05:50 2010 +0100
     1.3 @@ -2776,6 +2776,47 @@ sh_remove_all_shadows_and_parents(struct
     1.4  
     1.5  /**************************************************************************/
     1.6  
     1.7 +/* Reset the up-pointers of every L3 shadow to 0. 
     1.8 + * This is called when l3 shadows stop being pinnable, to clear out all
     1.9 + * the list-head bits so the up-pointer field is properly inititalised. */
    1.10 +static int sh_clear_up_pointer(struct vcpu *v, mfn_t smfn, mfn_t unused)
    1.11 +{
    1.12 +    mfn_to_page(smfn)->up = 0;
    1.13 +    return 0;
    1.14 +}
    1.15 +
    1.16 +void sh_reset_l3_up_pointers(struct vcpu *v)
    1.17 +{
    1.18 +    static hash_callback_t callbacks[SH_type_unused] = {
    1.19 +        NULL, /* none    */
    1.20 +        NULL, /* l1_32   */
    1.21 +        NULL, /* fl1_32  */
    1.22 +        NULL, /* l2_32   */
    1.23 +        NULL, /* l1_pae  */
    1.24 +        NULL, /* fl1_pae */
    1.25 +        NULL, /* l2_pae  */
    1.26 +        NULL, /* l2h_pae */
    1.27 +        NULL, /* l1_64   */
    1.28 +        NULL, /* fl1_64  */
    1.29 +        NULL, /* l2_64   */
    1.30 +        NULL, /* l2h_64  */
    1.31 +#if CONFIG_PAGING_LEVELS >= 4
    1.32 +        sh_clear_up_pointer, /* l3_64   */
    1.33 +#else
    1.34 +        NULL, /* l3_64   */
    1.35 +#endif
    1.36 +        NULL, /* l4_64   */
    1.37 +        NULL, /* p2m     */
    1.38 +        NULL  /* unused  */
    1.39 +    };
    1.40 +    static unsigned int callback_mask = 1 << SH_type_l3_64_shadow;    
    1.41 +
    1.42 +    hash_foreach(v, callback_mask, callbacks, _mfn(INVALID_MFN));
    1.43 +}
    1.44 +
    1.45 +
    1.46 +/**************************************************************************/
    1.47 +
    1.48  static void sh_update_paging_modes(struct vcpu *v)
    1.49  {
    1.50      struct domain *d = v->domain;
     2.1 --- a/xen/arch/x86/mm/shadow/multi.c	Sat Oct 02 15:04:21 2010 +0100
     2.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Sat Oct 02 15:05:50 2010 +0100
     2.3 @@ -1634,12 +1634,10 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf
     2.4              page_list_for_each_safe(sp, t, &v->domain->arch.paging.shadow.pinned_shadows)
     2.5              {
     2.6                  if ( sp->u.sh.type == SH_type_l3_64_shadow )
     2.7 -                {
     2.8                      sh_unpin(v, page_to_mfn(sp));
     2.9 -                    sp->up = 0;
    2.10 -                }
    2.11              }
    2.12              v->domain->arch.paging.shadow.opt_flags &= ~SHOPT_LINUX_L3_TOPLEVEL;
    2.13 +            sh_reset_l3_up_pointers(v);
    2.14          }
    2.15      }
    2.16  #endif
     3.1 --- a/xen/arch/x86/mm/shadow/private.h	Sat Oct 02 15:04:21 2010 +0100
     3.2 +++ b/xen/arch/x86/mm/shadow/private.h	Sat Oct 02 15:05:50 2010 +0100
     3.3 @@ -475,6 +475,12 @@ mfn_t oos_snapshot_lookup(struct vcpu *v
     3.4  
     3.5  #endif /* (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) */
     3.6  
     3.7 +
     3.8 +/* Reset the up-pointers of every L3 shadow to 0. 
     3.9 + * This is called when l3 shadows stop being pinnable, to clear out all
    3.10 + * the list-head bits so the up-pointer field is properly inititalised. */
    3.11 +void sh_reset_l3_up_pointers(struct vcpu *v);
    3.12 +
    3.13  /******************************************************************************
    3.14   * Flags used in the return value of the shadow_set_lXe() functions...
    3.15   */