direct-io.hg

changeset 10236:09d9d6e7b985

Fix MMU_NORMAL_PT_UPDATE when passed a page that is no longer of type page-table.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@dhcp93.uk.xensource.com
date Thu Jun 01 10:34:21 2006 +0100 (2006-06-01)
parents 25483d9b55d4
children 121ec8b952d3
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Wed May 31 16:07:47 2006 -0600
     1.2 +++ b/xen/arch/x86/mm.c	Thu Jun 01 10:34:21 2006 +0100
     1.3 @@ -2213,99 +2213,88 @@ int do_mmu_update(
     1.4  
     1.5              switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
     1.6              {
     1.7 -            case PGT_l1_page_table: 
     1.8 -                ASSERT( !shadow_mode_refcounts(d) );
     1.9 -                if ( likely(get_page_type(
    1.10 +            case PGT_l1_page_table:
    1.11 +            case PGT_l2_page_table:
    1.12 +            case PGT_l3_page_table:
    1.13 +            case PGT_l4_page_table:
    1.14 +            {
    1.15 +                ASSERT(!shadow_mode_refcounts(d));
    1.16 +                if ( unlikely(!get_page_type(
    1.17                      page, type_info & (PGT_type_mask|PGT_va_mask))) )
    1.18 +                    goto not_a_pt;
    1.19 +
    1.20 +                switch ( type_info & PGT_type_mask )
    1.21                  {
    1.22 -                    l1_pgentry_t l1e;
    1.23 -
    1.24 -                    /* FIXME: doesn't work with PAE */
    1.25 -                    l1e = l1e_from_intpte(req.val);
    1.26 +                case PGT_l1_page_table:
    1.27 +                {
    1.28 +                    l1_pgentry_t l1e = l1e_from_intpte(req.val);
    1.29                      okay = mod_l1_entry(va, l1e);
    1.30                      if ( okay && unlikely(shadow_mode_enabled(d)) )
    1.31                          shadow_l1_normal_pt_update(
    1.32                              d, req.ptr, l1e, &sh_mapcache);
    1.33 -                    put_page_type(page);
    1.34                  }
    1.35                  break;
    1.36 -            case PGT_l2_page_table:
    1.37 -                ASSERT( !shadow_mode_refcounts(d) );
    1.38 -                if ( likely(get_page_type(
    1.39 -                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
    1.40 +                case PGT_l2_page_table:
    1.41                  {
    1.42 -                    l2_pgentry_t l2e;
    1.43 -
    1.44 -                    /* FIXME: doesn't work with PAE */
    1.45 -                    l2e = l2e_from_intpte(req.val);
    1.46 +                    l2_pgentry_t l2e = l2e_from_intpte(req.val);
    1.47                      okay = mod_l2_entry(
    1.48                          (l2_pgentry_t *)va, l2e, mfn, type_info);
    1.49                      if ( okay && unlikely(shadow_mode_enabled(d)) )
    1.50                          shadow_l2_normal_pt_update(
    1.51                              d, req.ptr, l2e, &sh_mapcache);
    1.52 -                    put_page_type(page);
    1.53                  }
    1.54                  break;
    1.55  #if CONFIG_PAGING_LEVELS >= 3
    1.56 -            case PGT_l3_page_table:
    1.57 -                ASSERT( !shadow_mode_refcounts(d) );
    1.58 -                if ( likely(get_page_type(
    1.59 -                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
    1.60 +                case PGT_l3_page_table:
    1.61                  {
    1.62 -                    l3_pgentry_t l3e;
    1.63 -
    1.64 -                    /* FIXME: doesn't work with PAE */
    1.65 -                    l3e = l3e_from_intpte(req.val);
    1.66 +                    l3_pgentry_t l3e = l3e_from_intpte(req.val);
    1.67                      okay = mod_l3_entry(va, l3e, mfn, type_info);
    1.68                      if ( okay && unlikely(shadow_mode_enabled(d)) )
    1.69                          shadow_l3_normal_pt_update(
    1.70                              d, req.ptr, l3e, &sh_mapcache);
    1.71 -                    put_page_type(page);
    1.72                  }
    1.73                  break;
    1.74  #endif
    1.75  #if CONFIG_PAGING_LEVELS >= 4
    1.76 -            case PGT_l4_page_table:
    1.77 -                ASSERT( !shadow_mode_refcounts(d) );
    1.78 -                if ( likely(get_page_type(
    1.79 -                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
    1.80 +                case PGT_l4_page_table:
    1.81                  {
    1.82 -                    l4_pgentry_t l4e;
    1.83 -
    1.84 -                    l4e = l4e_from_intpte(req.val);
    1.85 +                    l4_pgentry_t l4e = l4e_from_intpte(req.val);
    1.86                      okay = mod_l4_entry(va, l4e, mfn, type_info);
    1.87                      if ( okay && unlikely(shadow_mode_enabled(d)) )
    1.88                          shadow_l4_normal_pt_update(
    1.89                              d, req.ptr, l4e, &sh_mapcache);
    1.90 -                    put_page_type(page);
    1.91                  }
    1.92                  break;
    1.93  #endif
    1.94 +                }
    1.95 +
    1.96 +                put_page_type(page);
    1.97 +            }
    1.98 +            break;
    1.99 +
   1.100              default:
   1.101 -                if ( likely(get_page_type(page, PGT_writable_page)) )
   1.102 +            not_a_pt:
   1.103 +            {
   1.104 +                if ( unlikely(!get_page_type(page, PGT_writable_page)) )
   1.105 +                    break;
   1.106 +
   1.107 +                if ( shadow_mode_enabled(d) )
   1.108                  {
   1.109 -                    if ( shadow_mode_enabled(d) )
   1.110 -                    {
   1.111 -                        shadow_lock(d);
   1.112 -
   1.113 -                        __mark_dirty(d, mfn);
   1.114 -
   1.115 -                        if ( page_is_page_table(page) &&
   1.116 -                             !page_out_of_sync(page) )
   1.117 -                        {
   1.118 -                            shadow_mark_mfn_out_of_sync(v, gmfn, mfn);
   1.119 -                        }
   1.120 -                    }
   1.121 -
   1.122 -                    *(intpte_t *)va = req.val;
   1.123 -                    okay = 1;
   1.124 -
   1.125 -                    if ( shadow_mode_enabled(d) )
   1.126 -                        shadow_unlock(d);
   1.127 -
   1.128 -                    put_page_type(page);
   1.129 +                    shadow_lock(d);
   1.130 +                    __mark_dirty(d, mfn);
   1.131 +                    if ( page_is_page_table(page) && !page_out_of_sync(page) )
   1.132 +                        shadow_mark_mfn_out_of_sync(v, gmfn, mfn);
   1.133                  }
   1.134 -                break;
   1.135 +
   1.136 +                *(intpte_t *)va = req.val;
   1.137 +                okay = 1;
   1.138 +
   1.139 +                if ( shadow_mode_enabled(d) )
   1.140 +                    shadow_unlock(d);
   1.141 +
   1.142 +                put_page_type(page);
   1.143 +            }
   1.144 +            break;
   1.145              }
   1.146  
   1.147              unmap_domain_page_with_cache(va, &mapcache);