[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Attached patch avoids "Bad L1 flags 80" for VMX domains. Thanks Ian for
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 1c62a4149b11fd3af95eaf97bc35fc26292698ae # Parent a90d670c98b9df3bd32a107594882ed33c598917 Attached patch avoids "Bad L1 flags 80" for VMX domains. Thanks Ian for the suggestions. Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx> diff -r a90d670c98b9 -r 1c62a4149b11 xen/arch/x86/shadow.c --- a/xen/arch/x86/shadow.c Sun Oct 23 21:45:15 2005 +++ b/xen/arch/x86/shadow.c Mon Oct 24 07:04:38 2005 @@ -871,6 +871,7 @@ perfc_incrc(shadow_mark_mfn_out_of_sync_calls); + entry->v = v; entry->gpfn = gpfn; entry->gmfn = mfn; entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn); @@ -937,6 +938,7 @@ entry->writable_pl1e = l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va)); ASSERT( !(entry->writable_pl1e & (sizeof(l1_pgentry_t)-1)) ); + entry->va = va; // Increment shadow's page count to represent the reference // inherent in entry->writable_pl1e @@ -1340,6 +1342,7 @@ guest_l1_pgentry_t *guest1 = guest; l1_pgentry_t *shadow1 = shadow; guest_l1_pgentry_t *snapshot1 = snapshot; + int unshadow_l1 = 0; ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) || shadow_mode_write_all(d)); @@ -1358,8 +1361,15 @@ if ( (i < min_snapshot) || (i > max_snapshot) || guest_l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) ) { - need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]); - set_guest_back_ptr(d, shadow1[i], smfn, i); + int error; + + error = validate_pte_change(d, guest1[i], &shadow1[i]); + if ( error == -1 ) + unshadow_l1 = 1; + else { + need_flush |= error; + set_guest_back_ptr(d, shadow1[i], smfn, i); + } // can't update snapshots of linear page tables -- they // are used multiple times... // @@ -1371,6 +1381,19 @@ perfc_incrc(resync_l1); perfc_incr_histo(wpt_updates, changed, PT_UPDATES); perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, PT_UPDATES); + if (unshadow_l1) { + pgentry_64_t l2e; + + __shadow_get_l2e(entry->v, entry->va, &l2e); + if (entry_get_flags(l2e) & _PAGE_PRESENT) { + entry_remove_flags(l2e, _PAGE_PRESENT); + __shadow_set_l2e(entry->v, entry->va, &l2e); + + if (entry->v == current) + need_flush = 1; + } + } + break; } #if defined (__i386__) diff -r a90d670c98b9 -r 1c62a4149b11 xen/arch/x86/shadow32.c --- a/xen/arch/x86/shadow32.c Sun Oct 23 21:45:15 2005 +++ b/xen/arch/x86/shadow32.c Mon Oct 24 07:04:38 2005 @@ -1829,6 +1829,7 @@ perfc_incrc(shadow_mark_mfn_out_of_sync_calls); + entry->v = v; entry->gpfn = gpfn; entry->gmfn = mfn; entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn); @@ -1875,6 +1876,7 @@ entry->writable_pl1e = l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va)); ASSERT( !(entry->writable_pl1e & (sizeof(l1_pgentry_t)-1)) ); + entry->va = va; // Increment shadow's page count to represent the reference // inherent in entry->writable_pl1e @@ -2320,6 +2322,7 @@ l1_pgentry_t *guest1 = guest; l1_pgentry_t *shadow1 = shadow; l1_pgentry_t *snapshot1 = snapshot; + int unshadow_l1 = 0; ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) || shadow_mode_write_all(d)); @@ -2346,8 +2349,15 @@ if ( (i < min_snapshot) || (i > max_snapshot) || l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) ) { - need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]); - set_guest_back_ptr(d, shadow1[i], smfn, i); + int error; + + error = validate_pte_change(d, guest1[i], &shadow1[i]); + if ( error == -1 ) + unshadow_l1 = 1; + else { + need_flush |= error; + set_guest_back_ptr(d, shadow1[i], smfn, i); + } // can't update snapshots of linear page tables -- they // are used multiple times... @@ -2359,6 +2369,19 @@ perfc_incrc(resync_l1); perfc_incr_histo(wpt_updates, changed, PT_UPDATES); perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, PT_UPDATES); + if (unshadow_l1) { + l2_pgentry_t l2e; + + __shadow_get_l2e(entry->v, entry->va, &l2e); + if (l2e_get_flags(l2e) & _PAGE_PRESENT) { + l2e_remove_flags(l2e, _PAGE_PRESENT); + __shadow_set_l2e(entry->v, entry->va, l2e); + + if (entry->v == current) + need_flush = 1; + } + } + break; } case PGT_l2_shadow: diff -r a90d670c98b9 -r 1c62a4149b11 xen/include/asm-x86/shadow.h --- a/xen/include/asm-x86/shadow.h Sun Oct 23 21:45:15 2005 +++ b/xen/include/asm-x86/shadow.h Mon Oct 24 07:04:38 2005 @@ -302,10 +302,12 @@ struct out_of_sync_entry { struct out_of_sync_entry *next; + struct vcpu *v; unsigned long gpfn; /* why is this here? */ unsigned long gmfn; unsigned long snapshot_mfn; unsigned long writable_pl1e; /* NB: this is a machine address */ + unsigned long va; }; #define out_of_sync_extra_size 127 @@ -384,6 +386,10 @@ nl1e = l1e; l1e_remove_flags(nl1e, _PAGE_GLOBAL); + + if ( unlikely(l1e_get_flags(l1e) & L1_DISALLOW_MASK) ) + return 0; + res = get_page_from_l1e(nl1e, d); if ( unlikely(!res) && IS_PRIV(d) && !shadow_mode_translate(d) && @@ -959,13 +965,15 @@ // perfc_incrc(validate_pte_changes3); - if ( (l1e_get_flags(new_spte) & _PAGE_PRESENT) && - !shadow_get_page_from_l1e(new_spte, d) ) - new_spte = l1e_empty(); if ( l1e_get_flags(old_spte) & _PAGE_PRESENT ) { shadow_put_page_from_l1e(old_spte, d); need_flush = 1; + } + if ( (l1e_get_flags(new_spte) & _PAGE_PRESENT) && + !shadow_get_page_from_l1e(new_spte, d) ) { + new_spte = l1e_empty(); + need_flush = -1; /* need to unshadow the page */ } } else _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |