direct-io.hg

changeset 7481:1c62a4149b11

Attached patch avoids "Bad L1 flags 80" for VMX domains. Thanks Ian for
the suggestions.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Oct 24 08:04:38 2005 +0100 (2005-10-24)
parents a90d670c98b9
children e6591119fda0
files xen/arch/x86/shadow.c xen/arch/x86/shadow32.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/xen/arch/x86/shadow.c	Sun Oct 23 22:45:15 2005 +0100
     1.2 +++ b/xen/arch/x86/shadow.c	Mon Oct 24 08:04:38 2005 +0100
     1.3 @@ -871,6 +871,7 @@ mark_mfn_out_of_sync(struct vcpu *v, uns
     1.4  
     1.5      perfc_incrc(shadow_mark_mfn_out_of_sync_calls);
     1.6  
     1.7 +    entry->v = v;
     1.8      entry->gpfn = gpfn;
     1.9      entry->gmfn = mfn;
    1.10      entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
    1.11 @@ -937,6 +938,7 @@ static void shadow_mark_va_out_of_sync(
    1.12      entry->writable_pl1e =
    1.13          l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va));
    1.14      ASSERT( !(entry->writable_pl1e & (sizeof(l1_pgentry_t)-1)) );
    1.15 +    entry->va = va;
    1.16  
    1.17      // Increment shadow's page count to represent the reference
    1.18      // inherent in entry->writable_pl1e
    1.19 @@ -1340,6 +1342,7 @@ static int resync_all(struct domain *d, 
    1.20              guest_l1_pgentry_t *guest1 = guest;
    1.21              l1_pgentry_t *shadow1 = shadow;
    1.22              guest_l1_pgentry_t *snapshot1 = snapshot;
    1.23 +            int unshadow_l1 = 0;
    1.24  
    1.25              ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) ||
    1.26                     shadow_mode_write_all(d));
    1.27 @@ -1358,8 +1361,15 @@ static int resync_all(struct domain *d, 
    1.28                  if ( (i < min_snapshot) || (i > max_snapshot) ||
    1.29                       guest_l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) )
    1.30                  {
    1.31 -                    need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]);
    1.32 -                    set_guest_back_ptr(d, shadow1[i], smfn, i);
    1.33 +                    int error; 
    1.34 +
    1.35 +                    error = validate_pte_change(d, guest1[i], &shadow1[i]);
    1.36 +                    if ( error ==  -1 ) 
    1.37 +                        unshadow_l1 = 1;
    1.38 +                    else {
    1.39 +                        need_flush |= error;
    1.40 +                        set_guest_back_ptr(d, shadow1[i], smfn, i);
    1.41 +                    }
    1.42                      // can't update snapshots of linear page tables -- they
    1.43                      // are used multiple times...
    1.44                      //
    1.45 @@ -1371,6 +1381,19 @@ static int resync_all(struct domain *d, 
    1.46              perfc_incrc(resync_l1);
    1.47              perfc_incr_histo(wpt_updates, changed, PT_UPDATES);
    1.48              perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, PT_UPDATES);
    1.49 +            if (unshadow_l1) {
    1.50 +                pgentry_64_t l2e;
    1.51 +
    1.52 +                __shadow_get_l2e(entry->v, entry->va, &l2e);
    1.53 +                if (entry_get_flags(l2e) & _PAGE_PRESENT) {
    1.54 +                    entry_remove_flags(l2e, _PAGE_PRESENT);
    1.55 +                    __shadow_set_l2e(entry->v, entry->va, &l2e);
    1.56 +
    1.57 +                    if (entry->v == current)
    1.58 +                        need_flush = 1;
    1.59 +                }
    1.60 +            }
    1.61 +
    1.62              break;
    1.63          }
    1.64  #if defined (__i386__)
     2.1 --- a/xen/arch/x86/shadow32.c	Sun Oct 23 22:45:15 2005 +0100
     2.2 +++ b/xen/arch/x86/shadow32.c	Mon Oct 24 08:04:38 2005 +0100
     2.3 @@ -1829,6 +1829,7 @@ shadow_mark_mfn_out_of_sync(struct vcpu 
     2.4  
     2.5      perfc_incrc(shadow_mark_mfn_out_of_sync_calls);
     2.6  
     2.7 +    entry->v = v;
     2.8      entry->gpfn = gpfn;
     2.9      entry->gmfn = mfn;
    2.10      entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn);
    2.11 @@ -1875,6 +1876,7 @@ void shadow_mark_va_out_of_sync(
    2.12      entry->writable_pl1e =
    2.13          l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va));
    2.14      ASSERT( !(entry->writable_pl1e & (sizeof(l1_pgentry_t)-1)) );
    2.15 +    entry->va = va;
    2.16  
    2.17      // Increment shadow's page count to represent the reference
    2.18      // inherent in entry->writable_pl1e
    2.19 @@ -2320,6 +2322,7 @@ static int resync_all(struct domain *d, 
    2.20              l1_pgentry_t *guest1 = guest;
    2.21              l1_pgentry_t *shadow1 = shadow;
    2.22              l1_pgentry_t *snapshot1 = snapshot;
    2.23 +            int unshadow_l1 = 0;
    2.24  
    2.25              ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) ||
    2.26                     shadow_mode_write_all(d));
    2.27 @@ -2346,8 +2349,15 @@ static int resync_all(struct domain *d, 
    2.28                  if ( (i < min_snapshot) || (i > max_snapshot) ||
    2.29                       l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) )
    2.30                  {
    2.31 -                    need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]);
    2.32 -                    set_guest_back_ptr(d, shadow1[i], smfn, i);
    2.33 +                    int error;
    2.34 +
    2.35 +                    error = validate_pte_change(d, guest1[i], &shadow1[i]);
    2.36 +                    if ( error ==  -1 ) 
    2.37 +                        unshadow_l1 = 1;
    2.38 +                    else {
    2.39 +                        need_flush |= error;
    2.40 +                        set_guest_back_ptr(d, shadow1[i], smfn, i);
    2.41 +                    }
    2.42  
    2.43                      // can't update snapshots of linear page tables -- they
    2.44                      // are used multiple times...
    2.45 @@ -2359,6 +2369,19 @@ static int resync_all(struct domain *d, 
    2.46              perfc_incrc(resync_l1);
    2.47              perfc_incr_histo(wpt_updates, changed, PT_UPDATES);
    2.48              perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, PT_UPDATES);
    2.49 +            if (unshadow_l1) {
    2.50 +                l2_pgentry_t l2e;
    2.51 +
    2.52 +                __shadow_get_l2e(entry->v, entry->va, &l2e);
    2.53 +                if (l2e_get_flags(l2e) & _PAGE_PRESENT) {
    2.54 +                    l2e_remove_flags(l2e, _PAGE_PRESENT);
    2.55 +                    __shadow_set_l2e(entry->v, entry->va, l2e);
    2.56 +
    2.57 +                    if (entry->v == current)
    2.58 +                        need_flush = 1;
    2.59 +                }
    2.60 +            }
    2.61 +
    2.62              break;
    2.63          }
    2.64          case PGT_l2_shadow:
     3.1 --- a/xen/include/asm-x86/shadow.h	Sun Oct 23 22:45:15 2005 +0100
     3.2 +++ b/xen/include/asm-x86/shadow.h	Mon Oct 24 08:04:38 2005 +0100
     3.3 @@ -302,10 +302,12 @@ struct shadow_status {
     3.4  
     3.5  struct out_of_sync_entry {
     3.6      struct out_of_sync_entry *next;
     3.7 +    struct vcpu   *v;
     3.8      unsigned long gpfn;    /* why is this here? */
     3.9      unsigned long gmfn;
    3.10      unsigned long snapshot_mfn;
    3.11      unsigned long writable_pl1e; /* NB: this is a machine address */
    3.12 +    unsigned long va;
    3.13  };
    3.14  
    3.15  #define out_of_sync_extra_size 127
    3.16 @@ -384,6 +386,10 @@ shadow_get_page_from_l1e(l1_pgentry_t l1
    3.17  
    3.18      nl1e = l1e;
    3.19      l1e_remove_flags(nl1e, _PAGE_GLOBAL);
    3.20 +
    3.21 +    if ( unlikely(l1e_get_flags(l1e) & L1_DISALLOW_MASK) )
    3.22 +        return 0;
    3.23 +
    3.24      res = get_page_from_l1e(nl1e, d);
    3.25  
    3.26      if ( unlikely(!res) && IS_PRIV(d) && !shadow_mode_translate(d) &&
    3.27 @@ -959,14 +965,16 @@ validate_pte_change(
    3.28              //
    3.29              perfc_incrc(validate_pte_changes3);
    3.30  
    3.31 -            if ( (l1e_get_flags(new_spte) & _PAGE_PRESENT) &&
    3.32 -                 !shadow_get_page_from_l1e(new_spte, d) )
    3.33 -                new_spte = l1e_empty();
    3.34              if ( l1e_get_flags(old_spte) & _PAGE_PRESENT )
    3.35              {
    3.36                  shadow_put_page_from_l1e(old_spte, d);
    3.37                  need_flush = 1;
    3.38              }
    3.39 +            if ( (l1e_get_flags(new_spte) & _PAGE_PRESENT) &&
    3.40 +                 !shadow_get_page_from_l1e(new_spte, d) ) {
    3.41 +                new_spte = l1e_empty();
    3.42 +                need_flush = -1; /* need to unshadow the page */
    3.43 +            }
    3.44          }
    3.45          else
    3.46          {