ia64/xen-unstable

changeset 11210:28e9bba03425

[XEN] Work around a Linux PAE issue where it sometimes sets
the top half of a PTE without first clearing the bottom half
(to make the PTE not-present) hence the PTE fails validation
checks.

Also remove dead revalidation function after shadow2 checkin.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Aug 18 15:24:10 2006 +0100 (2006-08-18)
parents d40dfbef8e5d
children a658663ab2d0
files xen/arch/x86/mm.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Fri Aug 18 15:22:54 2006 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Fri Aug 18 15:24:10 2006 +0100
     1.3 @@ -3050,56 +3050,6 @@ long arch_memory_op(int op, XEN_GUEST_HA
     1.4   * Writable Pagetables
     1.5   */
     1.6  
     1.7 -/* Re-validate a given p.t. page, given its prior snapshot */
     1.8 -int revalidate_l1(
     1.9 -    struct domain *d, l1_pgentry_t *l1page, l1_pgentry_t *snapshot)
    1.10 -{
    1.11 -    l1_pgentry_t ol1e, nl1e;
    1.12 -    int modified = 0, i;
    1.13 -
    1.14 -    for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
    1.15 -    {
    1.16 -        ol1e = snapshot[i];
    1.17 -        nl1e = l1page[i];
    1.18 -
    1.19 -        if ( likely(l1e_get_intpte(ol1e) == l1e_get_intpte(nl1e)) )
    1.20 -            continue;
    1.21 -
    1.22 -        /* Update number of entries modified. */
    1.23 -        modified++;
    1.24 -
    1.25 -        /*
    1.26 -         * Fast path for PTEs that have merely been write-protected
    1.27 -         * (e.g., during a Unix fork()). A strict reduction in privilege.
    1.28 -         */
    1.29 -        if ( likely(l1e_get_intpte(ol1e) == (l1e_get_intpte(nl1e)|_PAGE_RW)) )
    1.30 -        {
    1.31 -            if ( likely(l1e_get_flags(nl1e) & _PAGE_PRESENT) )
    1.32 -                put_page_type(mfn_to_page(l1e_get_pfn(nl1e)));
    1.33 -            continue;
    1.34 -        }
    1.35 -
    1.36 -        if ( unlikely(!get_page_from_l1e(nl1e, d)) )
    1.37 -        {
    1.38 -            /*
    1.39 -             * Make the remaining p.t's consistent before crashing, so the
    1.40 -             * reference counts are correct.
    1.41 -             */
    1.42 -            memcpy(&l1page[i], &snapshot[i],
    1.43 -                   (L1_PAGETABLE_ENTRIES - i) * sizeof(l1_pgentry_t));
    1.44 -
    1.45 -            /* Crash the offending domain. */
    1.46 -            MEM_LOG("ptwr: Could not revalidate l1 page");
    1.47 -            domain_crash(d);
    1.48 -            break;
    1.49 -        }
    1.50 -        
    1.51 -        put_page_from_l1e(ol1e, d);
    1.52 -    }
    1.53 -
    1.54 -    return modified;
    1.55 -}
    1.56 -
    1.57  static int ptwr_emulated_update(
    1.58      unsigned long addr,
    1.59      paddr_t old,
    1.60 @@ -3167,11 +3117,28 @@ static int ptwr_emulated_update(
    1.61      nl1e = l1e_from_intpte(val);
    1.62      if ( unlikely(!get_page_from_l1e(nl1e, d)) )
    1.63      {
    1.64 -        MEM_LOG("ptwr_emulate: could not get_page_from_l1e()");
    1.65 -        return X86EMUL_UNHANDLEABLE;
    1.66 +        if ( (CONFIG_PAGING_LEVELS == 3) &&
    1.67 +             (bytes == 4) &&
    1.68 +             !do_cmpxchg &&
    1.69 +             (l1e_get_flags(nl1e) & _PAGE_PRESENT) )
    1.70 +        {
    1.71 +            /*
    1.72 +             * If this is a half-write to a PAE PTE then we assume that the
    1.73 +             * guest has simply got the two writes the wrong way round. We
    1.74 +             * zap the PRESENT bit on the assumption the bottom half will be
    1.75 +             * written immediately after we return to the guest.
    1.76 +             */
    1.77 +            MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte"\n",
    1.78 +                    l1e_get_intpte(nl1e));
    1.79 +            l1e_remove_flags(nl1e, _PAGE_PRESENT);
    1.80 +        }
    1.81 +        else
    1.82 +        {
    1.83 +            MEM_LOG("ptwr_emulate: could not get_page_from_l1e()");
    1.84 +            return X86EMUL_UNHANDLEABLE;
    1.85 +        }
    1.86      }
    1.87  
    1.88 -
    1.89      /* Checked successfully: do the update (write or cmpxchg). */
    1.90      pl1e = map_domain_page(page_to_mfn(page));
    1.91      pl1e = (l1_pgentry_t *)((unsigned long)pl1e + (addr & ~PAGE_MASK));
     2.1 --- a/xen/include/asm-x86/mm.h	Fri Aug 18 15:22:54 2006 +0100
     2.2 +++ b/xen/include/asm-x86/mm.h	Fri Aug 18 15:24:10 2006 +0100
     2.3 @@ -397,7 +397,6 @@ void memguard_guard_stack(void *p);
     2.4  
     2.5  int  ptwr_do_page_fault(struct domain *, unsigned long,
     2.6                          struct cpu_user_regs *);
     2.7 -int  revalidate_l1(struct domain *, l1_pgentry_t *, l1_pgentry_t *);
     2.8  
     2.9  int audit_adjust_pgtables(struct domain *d, int dir, int noisy);
    2.10