}
check_pagetable( p, p->mm.pagetable, "va" ); // debug
-
+
+ /* if we're in logdirty mode, we need to note that we've updated the
+ PTE in the PT-holding page. This is a bit of a pain as we don't
+ know the physcial (machine) frame number of the page */
+ if ( p->mm.shadow_mode == SHM_logdirty )
+ mark_dirty( ¤t->mm, va_to_l1mfn(page_nr<<PAGE_SHIFT) );
}
#define linear_pg_table ((l1_pgentry_t *)LINEAR_PT_VIRT_START)
#define linear_l2_table ((l2_pgentry_t *)(LINEAR_PT_VIRT_START+(LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
+#define va_to_l1mfn(_va) (l2_pgentry_val(linear_l2_table[_va>>L2_PAGETABLE_SHIFT]) >> PAGE_SHIFT)
+
extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
extern void paging_init(void);
ASSERT(m->shadow_dirty_bitmap);
if( likely(pfn<m->shadow_dirty_bitmap_size) )
{
- // use setbit to be smp guest safe
- set_bit( pfn, m->shadow_dirty_bitmap );
+ /* use setbit to be smp guest safe. Since the same page is likely to
+ get marked dirty many times, examine the bit first before doing the
+ expensive lock-prefixed opertion */
+
+ if (! test_bit( pfn, m->shadow_dirty_bitmap ) )
+ set_bit( pfn, m->shadow_dirty_bitmap );
}
else
{
{
unsigned long res;
+ /* If we get here, we know that this domain is running in shadow mode.
+ We also know that some sort of update has happened to the underlying
+ page table page: either a PTE has been updated, or the page has
+ changed type. If we're in log dirty mode, we should set the approrpiate
+ bit in the dirty bitmap.
+ NB: the VA update path doesn't use this so needs to be handled
+ independnetly.
+ */
+
+ if( m->shadow_mode == SHM_logdirty )
+ mark_dirty( m, gpfn );
+
spin_lock(&m->shadow_lock);
res = __shadow_status( m, gpfn );
if (!res) spin_unlock(&m->shadow_lock);