# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 64d9190320012e88270a4bbbd418feecb81ede42
# Parent 4d1d9f7ebcfc79f96631382ea812ca986c7156dd
# Parent 8952af4fc166b5b0057b42f7d48505c96630ab90
Merged.
diff -r 4d1d9f7ebcfc -r 64d919032001 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c Thu Nov 24 15:57:36 2005
+++ b/tools/libxc/xc_linux_save.c Thu Nov 24 15:57:45 2005
@@ -727,8 +727,8 @@
/* Domain is still running at this point */
- if (live && (pt_levels != 2)) {
- ERR("Live migration supported only for 32-bit non-pae");
+ if (live && (pt_levels == 4)) {
+ ERR("Live migration not supported for 64-bit guests");
live = 0;
}
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c Thu Nov 24 15:57:36 2005
+++ b/xen/arch/x86/audit.c Thu Nov 24 15:57:45 2005
@@ -472,13 +472,6 @@
errors++;
}
- if ( (page->u.inuse.type_info & PGT_pinned) !=
PGT_pinned )
- {
- printk("Audit %d: L2 mfn=%lx not pinned t=%"
- PRtype_info "\n",
- d->domain_id, mfn, page->u.inuse.type_info);
- errors++;
- }
}
}
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Nov 24 15:57:36 2005
+++ b/xen/arch/x86/mm.c Thu Nov 24 15:57:45 2005
@@ -1289,6 +1289,11 @@
int alloc_page_type(struct pfn_info *page, unsigned long type)
{
+ struct domain *owner = page_get_owner(page);
+
+ if ( owner != NULL )
+ mark_dirty(owner, page_to_pfn(page));
+
switch ( type & PGT_type_mask )
{
case PGT_l1_page_table:
@@ -1318,16 +1323,14 @@
struct domain *owner = page_get_owner(page);
unsigned long gpfn;
- if ( owner != NULL )
- {
+ if ( unlikely((owner != NULL) && shadow_mode_enabled(owner)) )
+ {
+ mark_dirty(owner, page_to_pfn(page));
if ( unlikely(shadow_mode_refcounts(owner)) )
return;
- if ( unlikely(shadow_mode_enabled(owner)) )
- {
- gpfn = __mfn_to_gpfn(owner, page_to_pfn(page));
- ASSERT(VALID_M2P(gpfn));
- remove_shadow(owner, gpfn, type & PGT_type_mask);
- }
+ gpfn = __mfn_to_gpfn(owner, page_to_pfn(page));
+ ASSERT(VALID_M2P(gpfn));
+ remove_shadow(owner, gpfn, type & PGT_type_mask);
}
switch ( type & PGT_type_mask )
@@ -2203,8 +2206,7 @@
{
shadow_lock(d);
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, mfn);
+ __mark_dirty(d, mfn);
if ( page_is_page_table(page) &&
!page_out_of_sync(page) )
@@ -2263,13 +2265,7 @@
set_pfn_from_mfn(mfn, gpfn);
okay = 1;
- /*
- * If in log-dirty mode, mark the corresponding
- * page as dirty.
- */
- if ( unlikely(shadow_mode_log_dirty(FOREIGNDOM)) &&
- mark_dirty(FOREIGNDOM, mfn) )
- FOREIGNDOM->arch.shadow_dirty_block_count++;
+ mark_dirty(FOREIGNDOM, mfn);
put_page(&frame_table[mfn]);
break;
@@ -2841,8 +2837,7 @@
{
shadow_lock(dom);
- if ( shadow_mode_log_dirty(dom) )
- __mark_dirty(dom, mfn);
+ __mark_dirty(dom, mfn);
if ( page_is_page_table(page) && !page_out_of_sync(page) )
shadow_mark_mfn_out_of_sync(current, gpfn, mfn);
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Thu Nov 24 15:57:36 2005
+++ b/xen/arch/x86/shadow.c Thu Nov 24 15:57:45 2005
@@ -1757,6 +1757,7 @@
struct out_of_sync_entry *entry;
int need_flush = 0;
l1_pgentry_t *ppte, opte, npte;
+ cpumask_t other_vcpus_mask;
perfc_incrc(shadow_sync_all);
@@ -1789,23 +1790,15 @@
unmap_domain_page(ppte);
}
- // XXX mafetter: SMP
- //
- // With the current algorithm, we've gotta flush all the TLBs
- // before we can safely continue. I don't think we want to
- // do it this way, so I think we should consider making
- // entirely private copies of the shadow for each vcpu, and/or
- // possibly having a mix of private and shared shadow state
- // (any path from a PTE that grants write access to an out-of-sync
- // page table page needs to be vcpu private).
- //
-#if 0 // this should be enabled for SMP guests...
- flush_tlb_mask(cpu_online_map);
-#endif
+ /* Other VCPUs mustn't use the revoked writable mappings. */
+ other_vcpus_mask = d->cpumask;
+ cpu_clear(smp_processor_id(), other_vcpus_mask);
+ flush_tlb_mask(other_vcpus_mask);
+
+ /* Flush ourself later. */
need_flush = 1;
- // Second, resync all L1 pages, then L2 pages, etc...
- //
+ /* Second, resync all L1 pages, then L2 pages, etc... */
need_flush |= resync_all(d, PGT_l1_shadow);
#if CONFIG_PAGING_LEVELS == 2
@@ -1858,8 +1851,7 @@
SH_VVLOG("l1pte_write_fault: updating spte=0x%" PRIpte " gpte=0x%" PRIpte,
l1e_get_intpte(spte), l1e_get_intpte(gpte));
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, gmfn);
+ __mark_dirty(d, gmfn);
if ( mfn_is_page_table(gmfn) )
shadow_mark_va_out_of_sync(v, gpfn, gmfn, va);
@@ -2021,9 +2013,7 @@
domain_crash_synchronous();
}
- // if necessary, record the page table page as dirty
- if ( unlikely(shadow_mode_log_dirty(d)) )
- __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
+ __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
}
shadow_set_l1e(va, spte, 1);
@@ -2082,8 +2072,7 @@
* the PTE in the PT-holding page. We need the machine frame number
* for this.
*/
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, va_to_l1mfn(v, va));
+ __mark_dirty(d, va_to_l1mfn(v, va));
shadow_unlock(d);
@@ -3189,11 +3178,7 @@
l1e_remove_flags(sl1e, _PAGE_RW);
}
} else {
- /* log dirty*/
- /*
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, gmfn);
- */
+ /* __mark_dirty(d, gmfn); */
}
// printk("<%s> gpfn: %lx, mfn: %lx, sl1e: %lx\n", __func__, gpfn, mfn,
l1e_get_intpte(sl1e));
/* The shadow entrys need setup before shadow_mark_va_out_of_sync()*/
@@ -3476,9 +3461,7 @@
if (unlikely(!__guest_set_l1e(v, va, &gl1e)))
domain_crash_synchronous();
- // if necessary, record the page table page as dirty
- if ( unlikely(shadow_mode_log_dirty(d)) )
- __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gl2e)));
+ __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gl2e)));
}
shadow_set_l1e_64(va, (pgentry_64_t *)&sl1e, 1);
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Thu Nov 24 15:57:36 2005
+++ b/xen/arch/x86/shadow32.c Thu Nov 24 15:57:45 2005
@@ -1274,8 +1274,6 @@
d->arch.shadow_fault_count = 0;
d->arch.shadow_dirty_count = 0;
- d->arch.shadow_dirty_net_count = 0;
- d->arch.shadow_dirty_block_count = 0;
break;
@@ -1284,13 +1282,9 @@
sc->stats.fault_count = d->arch.shadow_fault_count;
sc->stats.dirty_count = d->arch.shadow_dirty_count;
- sc->stats.dirty_net_count = d->arch.shadow_dirty_net_count;
- sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
d->arch.shadow_fault_count = 0;
d->arch.shadow_dirty_count = 0;
- d->arch.shadow_dirty_net_count = 0;
- d->arch.shadow_dirty_block_count = 0;
if ( (sc->dirty_bitmap == NULL) ||
(d->arch.shadow_dirty_bitmap == NULL) )
@@ -1327,9 +1321,6 @@
case DOM0_SHADOW_CONTROL_OP_PEEK:
sc->stats.fault_count = d->arch.shadow_fault_count;
sc->stats.dirty_count = d->arch.shadow_dirty_count;
- sc->stats.dirty_net_count = d->arch.shadow_dirty_net_count;
- sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
-
if ( (sc->dirty_bitmap == NULL) ||
(d->arch.shadow_dirty_bitmap == NULL) )
@@ -2563,6 +2554,7 @@
struct out_of_sync_entry *entry;
int need_flush = 0;
l1_pgentry_t *ppte, opte, npte;
+ cpumask_t other_vcpus_mask;
perfc_incrc(shadow_sync_all);
@@ -2595,23 +2587,15 @@
unmap_domain_page(ppte);
}
- // XXX mafetter: SMP
- //
- // With the current algorithm, we've gotta flush all the TLBs
- // before we can safely continue. I don't think we want to
- // do it this way, so I think we should consider making
- // entirely private copies of the shadow for each vcpu, and/or
- // possibly having a mix of private and shared shadow state
- // (any path from a PTE that grants write access to an out-of-sync
- // page table page needs to be vcpu private).
- //
-#if 0 // this should be enabled for SMP guests...
- flush_tlb_mask(cpu_online_map);
-#endif
+ /* Other VCPUs mustn't use the revoked writable mappings. */
+ other_vcpus_mask = d->cpumask;
+ cpu_clear(smp_processor_id(), other_vcpus_mask);
+ flush_tlb_mask(other_vcpus_mask);
+
+ /* Flush ourself later. */
need_flush = 1;
- // Second, resync all L1 pages, then L2 pages, etc...
- //
+ /* Second, resync all L1 pages, then L2 pages, etc... */
need_flush |= resync_all(d, PGT_l1_shadow);
if ( shadow_mode_translate(d) )
need_flush |= resync_all(d, PGT_hl2_shadow);
@@ -2738,9 +2722,7 @@
domain_crash_synchronous();
}
- // if necessary, record the page table page as dirty
- if ( unlikely(shadow_mode_log_dirty(d)) )
- __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
+ __mark_dirty(d, __gpfn_to_mfn(d, l2e_get_pfn(gpde)));
}
shadow_set_l1e(va, spte, 1);
@@ -2837,8 +2819,6 @@
shadow_lock(d);
- //printk("%s(va=%p, val=%p)\n", __func__, (void *)va, (void
*)l1e_get_intpte(val));
-
// This is actually overkill - we don't need to sync the L1 itself,
// just everything involved in getting to this L1 (i.e. we need
// linear_pg_table[l1_linear_offset(va)] to be in sync)...
@@ -2853,10 +2833,8 @@
* the PTE in the PT-holding page. We need the machine frame number
* for this.
*/
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, va_to_l1mfn(v, va));
-
-// out:
+ __mark_dirty(d, va_to_l1mfn(v, va));
+
shadow_unlock(d);
return rc;
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Thu Nov 24 15:57:36 2005
+++ b/xen/arch/x86/shadow_public.c Thu Nov 24 15:57:45 2005
@@ -1183,8 +1183,6 @@
d->arch.shadow_fault_count = 0;
d->arch.shadow_dirty_count = 0;
- d->arch.shadow_dirty_net_count = 0;
- d->arch.shadow_dirty_block_count = 0;
break;
@@ -1193,15 +1191,10 @@
sc->stats.fault_count = d->arch.shadow_fault_count;
sc->stats.dirty_count = d->arch.shadow_dirty_count;
- sc->stats.dirty_net_count = d->arch.shadow_dirty_net_count;
- sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
d->arch.shadow_fault_count = 0;
d->arch.shadow_dirty_count = 0;
- d->arch.shadow_dirty_net_count = 0;
- d->arch.shadow_dirty_block_count = 0;
-
if ( (sc->dirty_bitmap == NULL) ||
(d->arch.shadow_dirty_bitmap == NULL) )
{
@@ -1236,8 +1229,6 @@
case DOM0_SHADOW_CONTROL_OP_PEEK:
sc->stats.fault_count = d->arch.shadow_fault_count;
sc->stats.dirty_count = d->arch.shadow_dirty_count;
- sc->stats.dirty_net_count = d->arch.shadow_dirty_net_count;
- sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
if ( (sc->dirty_bitmap == NULL) ||
(d->arch.shadow_dirty_bitmap == NULL) )
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/common/trace.c
--- a/xen/common/trace.c Thu Nov 24 15:57:36 2005
+++ b/xen/common/trace.c Thu Nov 24 15:57:45 2005
@@ -89,7 +89,6 @@
{
buf = t_bufs[i] = (struct t_buf *)&rawbuf[i*opt_tbuf_size*PAGE_SIZE];
buf->cons = buf->prod = 0;
- buf->nr_recs = nr_recs;
t_recs[i] = (struct t_rec *)(buf + 1);
}
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Thu Nov 24 15:57:36 2005
+++ b/xen/include/asm-x86/domain.h Thu Nov 24 15:57:45 2005
@@ -49,8 +49,6 @@
unsigned int shadow_fault_count;
unsigned int shadow_dirty_count;
- unsigned int shadow_dirty_net_count;
- unsigned int shadow_dirty_block_count;
/* full shadow mode */
struct out_of_sync_entry *out_of_sync; /* list of out-of-sync pages */
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h Thu Nov 24 15:57:36 2005
+++ b/xen/include/asm-x86/grant_table.h Thu Nov 24 15:57:45 2005
@@ -33,10 +33,6 @@
#define gnttab_shared_mfn(d, t, i) \
((virt_to_phys((t)->shared) >> PAGE_SHIFT) + (i))
-#define gnttab_log_dirty(d, f) \
- do { \
- if ( unlikely(shadow_mode_log_dirty((d))) ) \
- mark_dirty((d), (f)); \
- } while ( 0 )
+#define gnttab_log_dirty(d, f) mark_dirty((d), (f))
#endif /* __ASM_GRANT_TABLE_H__ */
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h Thu Nov 24 15:57:36 2005
+++ b/xen/include/asm-x86/shadow.h Thu Nov 24 15:57:45 2005
@@ -343,19 +343,15 @@
#define SHADOW_REFLECTS_SNAPSHOT _PAGE_AVAIL0
#endif
-#ifdef VERBOSE
+#if SHADOW_VERBOSE_DEBUG
#define SH_LOG(_f, _a...) \
printk("DOM%uP%u: SH_LOG(%d): " _f "\n", \
current->domain->domain_id , current->processor, __LINE__ , ## _a )
-#else
-#define SH_LOG(_f, _a...) ((void)0)
-#endif
-
-#if SHADOW_VERBOSE_DEBUG
#define SH_VLOG(_f, _a...) \
printk("DOM%uP%u: SH_VLOG(%d): " _f "\n", \
current->domain->domain_id, current->processor, __LINE__ , ## _a )
#else
+#define SH_LOG(_f, _a...) ((void)0)
#define SH_VLOG(_f, _a...) ((void)0)
#endif
@@ -468,21 +464,18 @@
/************************************************************************/
-static inline int __mark_dirty(struct domain *d, unsigned long mfn)
+static inline void __mark_dirty(struct domain *d, unsigned long mfn)
{
unsigned long pfn;
- int rc = 0;
ASSERT(shadow_lock_is_acquired(d));
+
+ if ( likely(!shadow_mode_log_dirty(d)) || !VALID_MFN(mfn) )
+ return;
+
ASSERT(d->arch.shadow_dirty_bitmap != NULL);
- if ( !VALID_MFN(mfn) )
- return rc;
-
- // N.B. This doesn't use __mfn_to_gpfn().
- // This wants the nice compact set of PFNs from 0..domain's max,
- // which __mfn_to_gpfn() only returns for translated domains.
- //
+ /* We /really/ mean PFN here, even for non-translated guests. */
pfn = get_pfn_from_mfn(mfn);
/*
@@ -491,16 +484,13 @@
* Nothing to do here...
*/
if ( unlikely(IS_INVALID_M2P_ENTRY(pfn)) )
- return rc;
-
- if ( likely(pfn < d->arch.shadow_dirty_bitmap_size) )
- {
- /* N.B. Can use non-atomic TAS because protected by shadow_lock. */
- if ( !__test_and_set_bit(pfn, d->arch.shadow_dirty_bitmap) )
- {
- d->arch.shadow_dirty_count++;
- rc = 1;
- }
+ return;
+
+ /* N.B. Can use non-atomic TAS because protected by shadow_lock. */
+ if ( likely(pfn < d->arch.shadow_dirty_bitmap_size) &&
+ !__test_and_set_bit(pfn, d->arch.shadow_dirty_bitmap) )
+ {
+ d->arch.shadow_dirty_count++;
}
#ifndef NDEBUG
else if ( mfn < max_page )
@@ -513,18 +503,17 @@
frame_table[mfn].u.inuse.type_info );
}
#endif
-
- return rc;
-}
-
-
-static inline int mark_dirty(struct domain *d, unsigned int mfn)
-{
- int rc;
- shadow_lock(d);
- rc = __mark_dirty(d, mfn);
- shadow_unlock(d);
- return rc;
+}
+
+
+static inline void mark_dirty(struct domain *d, unsigned int mfn)
+{
+ if ( unlikely(shadow_mode_log_dirty(d)) )
+ {
+ shadow_lock(d);
+ __mark_dirty(d, mfn);
+ shadow_unlock(d);
+ }
}
@@ -566,8 +555,7 @@
if ( unlikely(shadow_mode_translate(d)) )
update_hl2e(v, va);
- if ( unlikely(shadow_mode_log_dirty(d)) )
- __mark_dirty(d, pagetable_get_pfn(v->arch.guest_table));
+ __mark_dirty(d, pagetable_get_pfn(v->arch.guest_table));
}
static inline void
@@ -608,8 +596,8 @@
if ( need_flush )
{
perfc_incrc(update_hl2e_invlpg);
- // SMP BUG???
- local_flush_tlb_one(&linear_pg_table[l1_linear_offset(va)]);
+ flush_tlb_one_mask(v->domain->cpumask,
+ &linear_pg_table[l1_linear_offset(va)]);
}
}
}
@@ -787,8 +775,7 @@
SH_VVLOG("l1pte_write_fault: updating spte=0x%" PRIpte " gpte=0x%" PRIpte,
l1e_get_intpte(spte), l1e_get_intpte(gpte));
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, gmfn);
+ __mark_dirty(d, gmfn);
if ( mfn_is_page_table(gmfn) )
shadow_mark_va_out_of_sync(v, gpfn, gmfn, va);
@@ -1325,46 +1312,6 @@
return pttype;
}
-/*
- * N.B. We can make this locking more fine grained (e.g., per shadow page) if
- * it ever becomes a problem, but since we need a spin lock on the hash table
- * anyway it's probably not worth being too clever.
- */
-static inline unsigned long get_shadow_status(
- struct domain *d, unsigned long gpfn, unsigned long stype)
-{
- unsigned long res;
-
- ASSERT(shadow_mode_enabled(d));
-
- /*
- * If we get here we 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
- * appropriate bit in the dirty bitmap.
- * N.B. The VA update path doesn't use this and is handled independently.
- *
- * XXX need to think this through for vmx guests, but probably OK
- */
-
- shadow_lock(d);
-
- if ( shadow_mode_log_dirty(d) )
- __mark_dirty(d, __gpfn_to_mfn(d, gpfn));
-
- if ( !(res = __shadow_status(d, gpfn, stype)) )
- shadow_unlock(d);
-
- return res;
-}
-
-
-static inline void put_shadow_status(struct domain *d)
-{
- shadow_unlock(d);
-}
-
-
static inline void delete_shadow_status(
struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int
stype)
{
diff -r 4d1d9f7ebcfc -r 64d919032001 xen/include/public/trace.h
--- a/xen/include/public/trace.h Thu Nov 24 15:57:36 2005
+++ b/xen/include/public/trace.h Thu Nov 24 15:57:45 2005
@@ -74,7 +74,6 @@
struct t_buf {
unsigned int cons; /* Next item to be consumed by control tools. */
unsigned int prod; /* Next item to be produced by Xen. */
- unsigned int nr_recs; /* Number of records in this trace buffer. */
/* 'nr_recs' records follow immediately after the meta-data header. */
};
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|