ia64/xen-unstable

changeset 2984:23770b4d28fc

bitkeeper revision 1.1159.174.1 (4199ea78WRqMUotnBDHybojMaiF37w)

Add more required sanity checks to writable p.t. code in Xen.
author kaf24@freefall.cl.cam.ac.uk
date Tue Nov 16 11:54:32 2004 +0000 (2004-11-16)
parents b49a4a760280
children cc82b01c185b
files xen/arch/x86/memory.c
line diff
     1.1 --- a/xen/arch/x86/memory.c	Mon Nov 15 15:33:15 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Tue Nov 16 11:54:32 2004 +0000
     1.3 @@ -1577,7 +1577,7 @@ void ptwr_flush(const int which)
     1.4  {
     1.5      unsigned long  sstat, spte, pte, *ptep, l1va;
     1.6      l1_pgentry_t  *sl1e = NULL, *pl1e, ol1e, nl1e;
     1.7 -    l2_pgentry_t  *pl2e, nl2e;
     1.8 +    l2_pgentry_t  *pl2e;
     1.9      int            i, cpu = smp_processor_id();
    1.10      struct domain *d = current;
    1.11  
    1.12 @@ -1691,8 +1691,7 @@ void ptwr_flush(const int which)
    1.13      if ( (which == PTWR_PT_ACTIVE) && likely(!d->mm.shadow_mode) )
    1.14      {
    1.15          pl2e = &linear_l2_table[ptwr_info[cpu].ptinfo[which].l2_idx];
    1.16 -        nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
    1.17 -        update_l2e(pl2e, *pl2e, nl2e);
    1.18 +        *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); 
    1.19      }
    1.20  
    1.21      /*
    1.22 @@ -1711,9 +1710,9 @@ void ptwr_flush(const int which)
    1.23  /* Write page fault handler: check if guest is trying to modify a PTE. */
    1.24  int ptwr_do_page_fault(unsigned long addr)
    1.25  {
    1.26 -    unsigned long    pte, pfn;
    1.27 +    unsigned long    pte, pfn, l2e;
    1.28      struct pfn_info *page;
    1.29 -    l2_pgentry_t    *pl2e, nl2e;
    1.30 +    l2_pgentry_t    *pl2e;
    1.31      int              which, cpu = smp_processor_id();
    1.32      u32              l2_idx;
    1.33  
    1.34 @@ -1739,14 +1738,34 @@ int ptwr_do_page_fault(unsigned long add
    1.35      if ( unlikely(l2_idx >= PGT_va_unknown) )
    1.36          domain_crash(); /* Urk! This L1 is mapped in multiple L2 slots! */
    1.37      l2_idx >>= PGT_va_shift;
    1.38 -        
    1.39 +
    1.40 +    if ( l2_idx == (addr >> L2_PAGETABLE_SHIFT) )
    1.41 +    {
    1.42 +        MEM_LOG("PTWR failure! Pagetable maps itself at %08lx\n", addr);
    1.43 +        domain_crash();
    1.44 +    }
    1.45 +
    1.46      /*
    1.47       * Is the L1 p.t. mapped into the current address space? If so we call it
    1.48       * an ACTIVE p.t., otherwise it is INACTIVE.
    1.49       */
    1.50      pl2e = &linear_l2_table[l2_idx];
    1.51 -    which = (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) ?
    1.52 -        PTWR_PT_INACTIVE : PTWR_PT_ACTIVE;
    1.53 +    l2e  = l2_pgentry_val(*pl2e);
    1.54 +    which = PTWR_PT_INACTIVE;
    1.55 +    if ( (l2e >> PAGE_SHIFT) == pfn )
    1.56 +    {
    1.57 +        /*
    1.58 +         * If the PRESENT bit is clear, we may be conflicting with the current 
    1.59 +         * ACTIVE p.t. (it may be the same p.t. mapped at another virt addr).
    1.60 +         */
    1.61 +        if ( unlikely(!(l2e & _PAGE_PRESENT)) &&
    1.62 +             ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va )
    1.63 +            ptwr_flush(PTWR_PT_ACTIVE);
    1.64 +        
    1.65 +        /* Now do a final check of the PRESENT bit to set ACTIVE. */
    1.66 +        if ( likely(l2e & _PAGE_PRESENT) )
    1.67 +            which = PTWR_PT_ACTIVE;
    1.68 +    }
    1.69      
    1.70      PTWR_PRINTK("[%c] page_fault on l1 pt at va %08lx, pt for %08x, "
    1.71                  "pfn %08lx\n", PTWR_PRINT_WHICH,
    1.72 @@ -1765,8 +1784,7 @@ int ptwr_do_page_fault(unsigned long add
    1.73      /* For safety, disconnect the L1 p.t. page from current space. */
    1.74      if ( (which == PTWR_PT_ACTIVE) && likely(!current->mm.shadow_mode) )
    1.75      {
    1.76 -        nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT);
    1.77 -        update_l2e(pl2e, *pl2e, nl2e);
    1.78 +        *pl2e = mk_l2_pgentry(l2e & ~_PAGE_PRESENT);
    1.79          flush_tlb(); /* XXX Multi-CPU guests? */
    1.80      }
    1.81