xcp-1.6-updates/xen-4.1.hg

changeset 23245:b9e672d78cec

x86/mm: Don't check for invalid bits in non-present PTEs.

If _PAGE_PRESENT is clean in a pagetable entry, any pattern of bits
is valid in the rest of the entry. OSes that special-case
PFEC_invalid_bits (since it should never happen) will be confused
by our setting it in this way.

Signed-off-by: Tim Deegan <tim@xen.org>
xen-unstable changeset: 24883:adcd6ab160fa
xen-unstable date: Thu Feb 23 10:29:27 2012 +0000
author Tim Deegan <tim@xen.org>
date Wed Mar 07 08:32:29 2012 +0000 (2012-03-07)
parents d4ae43e71dcf
children 8f927378135a
files xen/arch/x86/mm/guest_walk.c
line diff
     1.1 --- a/xen/arch/x86/mm/guest_walk.c	Wed Mar 07 08:29:53 2012 +0000
     1.2 +++ b/xen/arch/x86/mm/guest_walk.c	Wed Mar 07 08:32:29 2012 +0000
     1.3 @@ -162,8 +162,11 @@ guest_walk_tables(struct vcpu *v, struct
     1.4      l4p = (guest_l4e_t *) top_map;
     1.5      gw->l4e = l4p[guest_l4_table_offset(va)];
     1.6      gflags = guest_l4e_get_flags(gw->l4e) ^ iflags;
     1.7 +    if ( !(gflags & _PAGE_PRESENT) ) {
     1.8 +        rc |= _PAGE_PRESENT;
     1.9 +        goto out;
    1.10 +    }
    1.11      rc |= ((gflags & mflags) ^ mflags);
    1.12 -    if ( rc & _PAGE_PRESENT ) goto out;
    1.13  
    1.14      /* Map the l3 table */
    1.15      l3p = map_domain_gfn(p2m, 
    1.16 @@ -176,9 +179,11 @@ guest_walk_tables(struct vcpu *v, struct
    1.17      /* Get the l3e and check its flags*/
    1.18      gw->l3e = l3p[guest_l3_table_offset(va)];
    1.19      gflags = guest_l3e_get_flags(gw->l3e) ^ iflags;
    1.20 +    if ( !(gflags & _PAGE_PRESENT) ) {
    1.21 +        rc |= _PAGE_PRESENT;
    1.22 +        goto out;
    1.23 +    }
    1.24      rc |= ((gflags & mflags) ^ mflags);
    1.25 -    if ( rc & _PAGE_PRESENT )
    1.26 -        goto out;
    1.27  
    1.28  #else /* PAE only... */
    1.29  
    1.30 @@ -213,9 +218,11 @@ guest_walk_tables(struct vcpu *v, struct
    1.31  #endif /* All levels... */
    1.32  
    1.33      gflags = guest_l2e_get_flags(gw->l2e) ^ iflags;
    1.34 +    if ( !(gflags & _PAGE_PRESENT) ) {
    1.35 +        rc |= _PAGE_PRESENT;
    1.36 +        goto out;
    1.37 +    }
    1.38      rc |= ((gflags & mflags) ^ mflags);
    1.39 -    if ( rc & _PAGE_PRESENT )
    1.40 -        goto out;
    1.41  
    1.42      pse = (guest_supports_superpages(v) && 
    1.43             (guest_l2e_get_flags(gw->l2e) & _PAGE_PSE)); 
    1.44 @@ -277,6 +284,10 @@ guest_walk_tables(struct vcpu *v, struct
    1.45              goto out;
    1.46          gw->l1e = l1p[guest_l1_table_offset(va)];
    1.47          gflags = guest_l1e_get_flags(gw->l1e) ^ iflags;
    1.48 +        if ( !(gflags & _PAGE_PRESENT) ) {
    1.49 +            rc |= _PAGE_PRESENT;
    1.50 +            goto out;
    1.51 +        }
    1.52          rc |= ((gflags & mflags) ^ mflags);
    1.53      }
    1.54