ia64/xen-unstable

changeset 3798:b5a5aa93e24f

bitkeeper revision 1.1186 (420cff94zgt9FYAF2LFRO_Xztduveg)

Ensure coherency of guest-PDE 'accessed' bits when using shadow page
tables. There is no issue with 'dirty' bits because only PTEs and
super-page PDEs (which we do not support) have 'dirty' bits.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Fri Feb 11 18:55:16 2005 +0000 (2005-02-11)
parents 7561a06348cf
children 16e48b864f0f
files xen/arch/x86/shadow.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/xen/arch/x86/shadow.c	Fri Feb 11 18:04:56 2005 +0000
     1.2 +++ b/xen/arch/x86/shadow.c	Fri Feb 11 18:55:16 2005 +0000
     1.3 @@ -11,12 +11,6 @@
     1.4  
     1.5  /********
     1.6  
     1.7 -To use these shadow page tables, guests must not rely on the ACCESSED
     1.8 -and DIRTY bits on L2 pte's being accurate -- they will typically all be set.
     1.9 -
    1.10 -I doubt this will break anything. (If guests want to use the va_update
    1.11 -mechanism they've signed up for this anyhow...)
    1.12 -
    1.13  There's a per-domain shadow table spin lock which works fine for SMP
    1.14  hosts. We don't have to worry about interrupts as no shadow operations
    1.15  happen in an interrupt context. It's probably not quite ready for SMP
    1.16 @@ -484,8 +478,9 @@ unsigned long shadow_l2_table(
    1.17          spl2e = (l2_pgentry_t *)map_domain_mem(spfn << PAGE_SHIFT);
    1.18          /*
    1.19           * We could proactively fill in PDEs for pages that are already
    1.20 -         * shadowed. However, we tried it and it didn't help performance.
    1.21 -         * This is simpler.
    1.22 +         * shadowed *and* where the guest PDE has _PAGE_ACCESSED set
    1.23 +         * (restriction required for coherence of the accessed bit). However,
    1.24 +         * we tried it and it didn't help performance. This is simpler. 
    1.25           */
    1.26          memset(spl2e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE*sizeof(l2_pgentry_t));
    1.27  
    1.28 @@ -498,7 +493,8 @@ unsigned long shadow_l2_table(
    1.29          spl2e[SH_LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
    1.30              mk_l2_pgentry((spfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
    1.31          spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
    1.32 -            mk_l2_pgentry(__pa(page_get_owner(&frame_table[gpfn])->arch.mm_perdomain_pt) |
    1.33 +            mk_l2_pgentry(__pa(page_get_owner(
    1.34 +                &frame_table[gpfn])->arch.mm_perdomain_pt) |
    1.35                            __PAGE_HYPERVISOR);
    1.36      }
    1.37  #endif
    1.38 @@ -727,7 +723,7 @@ void shadow_l1_normal_pt_update(
    1.39  
    1.40  void shadow_l2_normal_pt_update(unsigned long pa, unsigned long gpde)
    1.41  {
    1.42 -    unsigned long sl2mfn, spde;
    1.43 +    unsigned long sl2mfn, spde = 0;
    1.44      l2_pgentry_t *spl2e;
    1.45      unsigned long sl1mfn;
    1.46  
    1.47 @@ -736,11 +732,17 @@ void shadow_l2_normal_pt_update(unsigned
    1.48  
    1.49      sl2mfn = __shadow_status(current->domain, pa >> PAGE_SHIFT) & PSH_pfn_mask;
    1.50  
    1.51 -    sl1mfn = (gpde & _PAGE_PRESENT) ?
    1.52 -        __shadow_status(current->domain, gpde >> PAGE_SHIFT) : 0;
    1.53 +    /*
    1.54 +     * Only propagate to shadow if _PAGE_ACCESSED is set in the guest.
    1.55 +     * Otherwise, to ensure coherency, we blow away the existing shadow value.
    1.56 +     */
    1.57 +    if ( gpde & _PAGE_ACCESSED )
    1.58 +    {
    1.59 +        sl1mfn = (gpde & _PAGE_PRESENT) ?
    1.60 +            __shadow_status(current->domain, gpde >> PAGE_SHIFT) : 0;
    1.61 +        l2pde_general(current->domain, &gpde, &spde, sl1mfn);
    1.62 +    }
    1.63  
    1.64 -    /* XXXX Should mark guest pte as DIRTY and ACCESSED too! */
    1.65 -    l2pde_general(current->domain, &gpde, &spde, sl1mfn);
    1.66      spl2e = (l2_pgentry_t *)map_domain_mem(sl2mfn << PAGE_SHIFT);
    1.67      spl2e[(pa & ~PAGE_MASK) / sizeof(l2_pgentry_t)] = mk_l2_pgentry(spde);
    1.68      unmap_domain_mem(spl2e);
     2.1 --- a/xen/include/asm-x86/shadow.h	Fri Feb 11 18:04:56 2005 +0000
     2.2 +++ b/xen/include/asm-x86/shadow.h	Fri Feb 11 18:55:16 2005 +0000
     2.3 @@ -331,7 +331,7 @@ static inline void l2pde_general(
     2.4      {
     2.5          spde = (gpde & ~PAGE_MASK) | (sl1mfn << PAGE_SHIFT) | 
     2.6              _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY;
     2.7 -        gpde |= _PAGE_ACCESSED | _PAGE_DIRTY;
     2.8 +        gpde |= _PAGE_ACCESSED; /* N.B. PDEs do not have a dirty bit. */
     2.9  
    2.10          /* Detect linear p.t. mappings and write-protect them. */
    2.11          if ( (frame_table[sl1mfn].u.inuse.type_info & PGT_type_mask) ==