direct-io.hg

changeset 13470:8835443fa3b3

[IA64] Resolve a race in tlb_track_search_and_remove()

When tlb_track_search_and_remove() is about to remove a found entry,
another cpu might update p2m entry and insert the entry right before that.
It must be aware of it.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild2.aw
date Fri Jan 12 12:03:38 2007 -0700 (2007-01-12)
parents 9cbb1d6fb34a
children 5d328ef9da71
files xen/arch/ia64/xen/tlb_track.c
line diff
     1.1 --- a/xen/arch/ia64/xen/tlb_track.c	Thu Jan 11 17:03:25 2007 -0700
     1.2 +++ b/xen/arch/ia64/xen/tlb_track.c	Fri Jan 12 12:03:38 2007 -0700
     1.3 @@ -454,6 +454,31 @@ tlb_track_search_and_remove(struct tlb_t
     1.4              continue;
     1.5  
     1.6          if (pte_pfn(entry->pte_val) == mfn) {
     1.7 +            /*
     1.8 +             * PARANOIA
     1.9 +             * We're here after zapping p2m entry.  However another pCPU
    1.10 +             * may update the same p2m entry entry the same mfn at the
    1.11 +             * same time in theory.  In such a case, we can't determine
    1.12 +             * whether this entry is for us or for the racy p2m update.
    1.13 +             * Such a guest domain's racy behaviour doesn't make sense,
    1.14 +             * but is allowed.  Go the very pessimistic way.  Leave this
    1.15 +             * entry to be found later and do full flush at this time.
    1.16 +             *
    1.17 +             * NOTE: Updating tlb tracking hash is protected by spin lock and
    1.18 +             *       setting _PAGE_TLB_INSERTED and_PAGE_TLB_INSERTED_MANY bits
    1.19 +             *       is serialized by the same spin lock.
    1.20 +             *       See tlb_track_insert_or_dirty().
    1.21 +             */
    1.22 +            pte_t current_pte = *ptep;
    1.23 +            if (unlikely(pte_pfn(current_pte) == mfn &&
    1.24 +                         pte_tlb_tracking(current_pte) &&
    1.25 +                         pte_tlb_inserted(current_pte))) {
    1.26 +                BUG_ON(pte_tlb_inserted_many(current_pte));
    1.27 +                spin_unlock(&tlb_track->hash_lock);
    1.28 +                perfc_incrc(tlb_track_sar_many);
    1.29 +                return TLB_TRACK_MANY;
    1.30 +            }
    1.31 +
    1.32              list_del(&entry->list);
    1.33              spin_unlock(&tlb_track->hash_lock);
    1.34              *entryp = entry;