ia64/xen-unstable

changeset 15102:807f374e720d

x86: ptwr adjustments

Make sure MFN read from pte is valid before accessing the page info
structure associated with it. Drop guest-to-machine-physical
translation from ptwr code.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Tue May 15 10:12:02 2007 +0100 (2007-05-15)
parents b2adb797900a
children eb027b704dc5
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Tue May 15 10:08:20 2007 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Tue May 15 10:12:02 2007 +0100
     1.3 @@ -3238,13 +3238,14 @@ static int ptwr_emulated_update(
     1.4  
     1.5      /* We are looking only for read-only mappings of p.t. pages. */
     1.6      ASSERT((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) == _PAGE_PRESENT);
     1.7 +    ASSERT(mfn_valid(mfn));
     1.8      ASSERT((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table);
     1.9      ASSERT((page->u.inuse.type_info & PGT_count_mask) != 0);
    1.10      ASSERT(page_get_owner(page) == d);
    1.11  
    1.12      /* Check the new PTE. */
    1.13      nl1e = l1e_from_intpte(val);
    1.14 -    if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) )
    1.15 +    if ( unlikely(!get_page_from_l1e(nl1e, d)) )
    1.16      {
    1.17          if ( (CONFIG_PAGING_LEVELS >= 3) && is_pv_32bit_domain(d) &&
    1.18               (bytes == 4) && (addr & 4) && !do_cmpxchg &&
    1.19 @@ -3270,7 +3271,7 @@ static int ptwr_emulated_update(
    1.20      adjust_guest_l1e(nl1e, d);
    1.21  
    1.22      /* Checked successfully: do the update (write or cmpxchg). */
    1.23 -    pl1e = map_domain_page(page_to_mfn(page));
    1.24 +    pl1e = map_domain_page(mfn);
    1.25      pl1e = (l1_pgentry_t *)((unsigned long)pl1e + (addr & ~PAGE_MASK));
    1.26      if ( do_cmpxchg )
    1.27      {
    1.28 @@ -3285,21 +3286,21 @@ static int ptwr_emulated_update(
    1.29          if ( !okay )
    1.30          {
    1.31              unmap_domain_page(pl1e);
    1.32 -            put_page_from_l1e(gl1e_to_ml1e(d, nl1e), d);
    1.33 +            put_page_from_l1e(nl1e, d);
    1.34              return X86EMUL_CMPXCHG_FAILED;
    1.35          }
    1.36      }
    1.37      else
    1.38      {
    1.39          ol1e = *pl1e;
    1.40 -        if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, page_to_mfn(page), v) )
    1.41 +        if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, mfn, v) )
    1.42              BUG();
    1.43      }
    1.44  
    1.45      unmap_domain_page(pl1e);
    1.46  
    1.47      /* Finally, drop the old PTE. */
    1.48 -    put_page_from_l1e(gl1e_to_ml1e(d, ol1e), d);
    1.49 +    put_page_from_l1e(ol1e, d);
    1.50  
    1.51      return X86EMUL_OKAY;
    1.52  }
    1.53 @@ -3365,17 +3366,13 @@ int ptwr_do_page_fault(struct vcpu *v, u
    1.54  
    1.55      LOCK_BIGLOCK(d);
    1.56  
    1.57 -    /*
    1.58 -     * Attempt to read the PTE that maps the VA being accessed. By checking for
    1.59 -     * PDE validity in the L2 we avoid many expensive fixups in __get_user().
    1.60 -     */
    1.61 +    /* Attempt to read the PTE that maps the VA being accessed. */
    1.62      guest_get_eff_l1e(v, addr, &pte);
    1.63 -    if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
    1.64 -        goto bail;
    1.65      page = l1e_get_page(pte);
    1.66  
    1.67      /* We are looking only for read-only mappings of p.t. pages. */
    1.68      if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) ||
    1.69 +         !mfn_valid(l1e_get_pfn(pte)) ||
    1.70           ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) ||
    1.71           ((page->u.inuse.type_info & PGT_count_mask) == 0) ||
    1.72           (page_get_owner(page) != d) )