direct-io.hg

changeset 7795:dd754654d427

Better fix for flushing conflicting batched ptwr state
before emulating a PT access.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Nov 14 19:45:32 2005 +0100 (2005-11-14)
parents 4f03592bc7f5
children ed2ef64fdc33
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Mon Nov 14 18:27:11 2005 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Mon Nov 14 19:45:32 2005 +0100
     1.3 @@ -3063,7 +3063,7 @@ static int ptwr_emulated_update(
     1.4      unsigned int bytes,
     1.5      unsigned int do_cmpxchg)
     1.6  {
     1.7 -    unsigned long pfn;
     1.8 +    unsigned long pfn, l1va;
     1.9      struct pfn_info *page;
    1.10      l1_pgentry_t pte, ol1e, nl1e, *pl1e;
    1.11      struct domain *d = current->domain;
    1.12 @@ -3100,6 +3100,17 @@ static int ptwr_emulated_update(
    1.13          old  |= full;
    1.14      }
    1.15  
    1.16 +    /*
    1.17 +     * We must not emulate an update to a PTE that is temporarily marked
    1.18 +     * writable by the batched ptwr logic, else we can corrupt page refcnts! 
    1.19 +     */
    1.20 +    if ( ((l1va = d->arch.ptwr[PTWR_PT_ACTIVE].l1va) != 0) &&
    1.21 +         (l1_linear_offset(l1va) == l1_linear_offset(addr)) )
    1.22 +        ptwr_flush(d, PTWR_PT_ACTIVE);
    1.23 +    if ( ((l1va = d->arch.ptwr[PTWR_PT_INACTIVE].l1va) != 0) &&
    1.24 +         (l1_linear_offset(l1va) == l1_linear_offset(addr)) )
    1.25 +        ptwr_flush(d, PTWR_PT_INACTIVE);
    1.26 +
    1.27      /* Read the PTE that maps the page being updated. */
    1.28      if (__copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
    1.29                           sizeof(pte)))
    1.30 @@ -3358,13 +3369,6 @@ int ptwr_do_page_fault(struct domain *d,
    1.31      return EXCRET_fault_fixed;
    1.32  
    1.33   emulate:
    1.34 -    /*
    1.35 -     * Cleaning up avoids emulating an update to a PTE that is temporarily
    1.36 -     * marked writable (_PAGE_RW) by the batched ptwr logic. If this were
    1.37 -     * performance critical then the check could compare addr against l1va's in
    1.38 -     * ptwr_emulated_update(). Without this flush we can corrupt page refcnts!
    1.39 -     */
    1.40 -    cleanup_writable_pagetable(d);
    1.41      if ( x86_emulate_memop(guest_cpu_user_regs(), addr,
    1.42                             &ptwr_mem_emulator, BITS_PER_LONG/8) )
    1.43          return 0;