direct-io.hg

changeset 8414:b57ed8182812

Cleanup VTLB code
Signed-off-by Anthony Xu <anthony.xu@intel.com>
author djm@kirby.fc.hp.com
date Thu Dec 15 16:09:19 2005 -0600 (2005-12-15)
parents f998426f9069
children 2d5c57be196d
files xen/arch/ia64/vmx/vmmu.c xen/arch/ia64/vmx/vtlb.c xen/include/asm-ia64/vmmu.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vmmu.c	Thu Dec 15 16:07:47 2005 -0600
     1.2 +++ b/xen/arch/ia64/vmx/vmmu.c	Thu Dec 15 16:09:19 2005 -0600
     1.3 @@ -246,117 +246,30 @@ alloc_pmt(struct domain *d)
     1.4   */
     1.5  void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb)
     1.6  {
     1.7 -#if 0
     1.8 -    u64     saved_itir, saved_ifa;
     1.9 -#endif
    1.10 -    u64      saved_rr;
    1.11 -    u64     pages;
    1.12      u64     psr;
    1.13      thash_data_t    mtlb;
    1.14 -    ia64_rr vrr;
    1.15      unsigned int    cl = tlb->cl;
    1.16  
    1.17      mtlb.ifa = tlb->vadr;
    1.18      mtlb.itir = tlb->itir & ~ITIR_RV_MASK;
    1.19 -    vrr = vmmu_get_rr(d,mtlb.ifa);
    1.20      //vmx_vcpu_get_rr(d, mtlb.ifa, &vrr.value);
    1.21 -    pages = PSIZE(vrr.ps) >> PAGE_SHIFT;
    1.22      mtlb.page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
    1.23 -    mtlb.ppn = get_mfn(DOMID_SELF,tlb->ppn, pages);
    1.24 +    mtlb.ppn = get_mfn(DOMID_SELF,tlb->ppn, 1);
    1.25      if (mtlb.ppn == INVALID_MFN)
    1.26      panic("Machine tlb insert with invalid mfn number.\n");
    1.27  
    1.28      psr = ia64_clear_ic();
    1.29 -#if 0
    1.30 -    saved_itir = ia64_getreg(_IA64_REG_CR_ITIR);
    1.31 -    saved_ifa = ia64_getreg(_IA64_REG_CR_IFA);
    1.32 -#endif
    1.33 -    saved_rr = ia64_get_rr(mtlb.ifa);
    1.34 -    ia64_setreg(_IA64_REG_CR_ITIR, mtlb.itir);
    1.35 -    ia64_setreg(_IA64_REG_CR_IFA, mtlb.ifa);
    1.36 -    /* Only access memory stack which is mapped by TR,
    1.37 -     * after rr is switched.
    1.38 -     */
    1.39 -    ia64_set_rr(mtlb.ifa, vmx_vrrtomrr(d, vrr.rrval));
    1.40 -    ia64_srlz_d();
    1.41      if ( cl == ISIDE_TLB ) {
    1.42 -        ia64_itci(mtlb.page_flags);
    1.43 -        ia64_srlz_i();
    1.44 +        ia64_itc(1, mtlb.ifa, mtlb.page_flags, mtlb.ps);
    1.45      }
    1.46      else {
    1.47 -        ia64_itcd(mtlb.page_flags);
    1.48 -        ia64_srlz_d();
    1.49 +        ia64_itc(2, mtlb.ifa, mtlb.page_flags, mtlb.ps);
    1.50      }
    1.51 -    ia64_set_rr(mtlb.ifa,saved_rr);
    1.52 -    ia64_srlz_d();
    1.53 -#if 0
    1.54 -    ia64_setreg(_IA64_REG_CR_IFA, saved_ifa);
    1.55 -    ia64_setreg(_IA64_REG_CR_ITIR, saved_itir);
    1.56 -#endif
    1.57      ia64_set_psr(psr);
    1.58      ia64_srlz_i();
    1.59 +    return;
    1.60  }
    1.61  
    1.62 -
    1.63 -u64 machine_thash(PTA pta, u64 va, u64 rid, u64 ps)
    1.64 -{
    1.65 -    u64     saved_pta, saved_rr0;
    1.66 -    u64     hash_addr, tag;
    1.67 -    unsigned long psr;
    1.68 -    struct vcpu *v = current;
    1.69 -    ia64_rr vrr;
    1.70 -
    1.71 -    saved_pta = ia64_getreg(_IA64_REG_CR_PTA);
    1.72 -    saved_rr0 = ia64_get_rr(0);
    1.73 -    vrr.rrval = saved_rr0;
    1.74 -    vrr.rid = rid;
    1.75 -    vrr.ps = ps;
    1.76 -
    1.77 -    va = (va << 3) >> 3;    // set VRN to 0.
    1.78 -    // TODO: Set to enforce lazy mode
    1.79 -    local_irq_save(psr);
    1.80 -    ia64_setreg(_IA64_REG_CR_PTA, pta.val);
    1.81 -    ia64_set_rr(0, vmx_vrrtomrr(v, vrr.rrval));
    1.82 -    ia64_srlz_d();
    1.83 -
    1.84 -    hash_addr = ia64_thash(va);
    1.85 -    ia64_setreg(_IA64_REG_CR_PTA, saved_pta);
    1.86 -
    1.87 -    ia64_set_rr(0, saved_rr0);
    1.88 -    ia64_srlz_d();
    1.89 -    ia64_set_psr(psr);
    1.90 -    return hash_addr;
    1.91 -}
    1.92 -
    1.93 -u64 machine_ttag(PTA pta, u64 va, u64 rid, u64 ps)
    1.94 -{
    1.95 -    u64     saved_pta, saved_rr0;
    1.96 -    u64     hash_addr, tag;
    1.97 -    u64     psr;
    1.98 -    struct vcpu *v = current;
    1.99 -    ia64_rr vrr;
   1.100 -
   1.101 -    // TODO: Set to enforce lazy mode
   1.102 -    saved_pta = ia64_getreg(_IA64_REG_CR_PTA);
   1.103 -    saved_rr0 = ia64_get_rr(0);
   1.104 -    vrr.rrval = saved_rr0;
   1.105 -    vrr.rid = rid;
   1.106 -    vrr.ps = ps;
   1.107 -
   1.108 -    va = (va << 3) >> 3;    // set VRN to 0.
   1.109 -    local_irq_save(psr);
   1.110 -    ia64_setreg(_IA64_REG_CR_PTA, pta.val);
   1.111 -    ia64_set_rr(0, vmx_vrrtomrr(v, vrr.rrval));
   1.112 -    ia64_srlz_d();
   1.113 -
   1.114 -    tag = ia64_ttag(va);
   1.115 -    ia64_setreg(_IA64_REG_CR_PTA, saved_pta);
   1.116 -
   1.117 -    ia64_set_rr(0, saved_rr0);
   1.118 -    ia64_srlz_d();
   1.119 -    local_irq_restore(psr);
   1.120 -    return tag;
   1.121 -}
   1.122  /*
   1.123   *  Purge machine tlb.
   1.124   *  INPUT
   1.125 @@ -365,26 +278,53 @@ u64 machine_ttag(PTA pta, u64 va, u64 ri
   1.126   *      size:   bits format (1<<size) for the address range to purge.
   1.127   *
   1.128   */
   1.129 -void machine_tlb_purge(u64 rid, u64 va, u64 ps)
   1.130 +void machine_tlb_purge(u64 va, u64 ps)
   1.131  {
   1.132 -    u64       saved_rr0;
   1.133 -    u64       psr;
   1.134 +//    u64       psr;
   1.135 +//    psr = ia64_clear_ic();
   1.136 +    ia64_ptcl(va, ps << 2);
   1.137 +//    ia64_set_psr(psr);
   1.138 +//    ia64_srlz_i();
   1.139 +//    return;
   1.140 +}
   1.141 +
   1.142 +u64 machine_thash(PTA pta, u64 va)
   1.143 +{
   1.144 +    u64     saved_pta;
   1.145 +    u64     hash_addr, tag;
   1.146 +    unsigned long psr;
   1.147 +    struct vcpu *v = current;
   1.148      ia64_rr vrr;
   1.149  
   1.150 -    va = (va << 3) >> 3;    // set VRN to 0.
   1.151 -    saved_rr0 = ia64_get_rr(0);
   1.152 -    vrr.rrval = saved_rr0;
   1.153 -    vrr.rid = rid;
   1.154 -    vrr.ps = ps;
   1.155 -    local_irq_save(psr);
   1.156 -    ia64_set_rr( 0, vmx_vrrtomrr(current,vrr.rrval) );
   1.157 -    ia64_srlz_d();
   1.158 -    ia64_ptcl(va, ps << 2);
   1.159 -    ia64_set_rr( 0, saved_rr0 );
   1.160 -    ia64_srlz_d();
   1.161 -    local_irq_restore(psr);
   1.162 +    saved_pta = ia64_getreg(_IA64_REG_CR_PTA);
   1.163 +    psr = ia64_clear_ic();
   1.164 +    ia64_setreg(_IA64_REG_CR_PTA, pta.val);
   1.165 +    hash_addr = ia64_thash(va);
   1.166 +    ia64_setreg(_IA64_REG_CR_PTA, saved_pta);
   1.167 +    ia64_set_psr(psr);
   1.168 +    ia64_srlz_i();
   1.169 +    return hash_addr;
   1.170  }
   1.171  
   1.172 +u64 machine_ttag(PTA pta, u64 va)
   1.173 +{
   1.174 +//    u64     saved_pta;
   1.175 +//    u64     hash_addr, tag;
   1.176 +//    u64     psr;
   1.177 +//    struct vcpu *v = current;
   1.178 +
   1.179 +//    saved_pta = ia64_getreg(_IA64_REG_CR_PTA);
   1.180 +//    psr = ia64_clear_ic();
   1.181 +//    ia64_setreg(_IA64_REG_CR_PTA, pta.val);
   1.182 +//    tag = ia64_ttag(va);
   1.183 +    return ia64_ttag(va);
   1.184 +//    ia64_setreg(_IA64_REG_CR_PTA, saved_pta);
   1.185 +//    ia64_set_psr(psr);
   1.186 +//    ia64_srlz_i();
   1.187 +//    return tag;
   1.188 +}
   1.189 +
   1.190 +
   1.191  
   1.192  int vhpt_enabled(VCPU *vcpu, uint64_t vadr, vhpt_ref_t ref)
   1.193  {
     2.1 --- a/xen/arch/ia64/vmx/vtlb.c	Thu Dec 15 16:07:47 2005 -0600
     2.2 +++ b/xen/arch/ia64/vmx/vtlb.c	Thu Dec 15 16:09:19 2005 -0600
     2.3 @@ -68,8 +68,7 @@ static void cch_free(thash_cb_t *hcb, th
     2.4  static int __is_translated(thash_data_t *tlb, u64 rid, u64 va, CACHE_LINE_TYPE cl)
     2.5  {
     2.6      u64  size1,sa1,ea1;
     2.7 -
     2.8 -    if ( tlb->rid != rid || tlb->cl != cl )
     2.9 +    if ( tlb->rid != rid ||(!tlb->tc && tlb->cl != cl) )
    2.10          return 0;
    2.11      size1 = PSIZE(tlb->ps);
    2.12      sa1 = tlb->vadr & ~(size1-1);   // mask the low address bits
    2.13 @@ -89,7 +88,7 @@ static int
    2.14  {
    2.15      uint64_t size1,size2,sa1,ea1,ea2;
    2.16  
    2.17 -    if ( entry->invalid || entry->rid != rid || entry->cl != cl ) {
    2.18 +    if ( entry->invalid || entry->rid != rid || (!entry->tc && entry->cl != cl ) ) {
    2.19          return 0;
    2.20      }
    2.21      size1=PSIZE(entry->ps);
    2.22 @@ -292,8 +291,7 @@ int __tlb_to_vhpt(thash_cb_t *hcb,
    2.23      if ( mfn == INVALID_MFN ) return 0;
    2.24  
    2.25      // TODO with machine discontinuous address space issue.
    2.26 -    vhpt->etag = (hcb->vs->tag_func)( hcb->pta,
    2.27 -            tlb->vadr, tlb->rid, tlb->ps);
    2.28 +    vhpt->etag = (hcb->vs->tag_func)( hcb->pta, tlb->vadr);
    2.29      //vhpt->ti = 0;
    2.30      vhpt->itir = tlb->itir & ~ITIR_RV_MASK;
    2.31      vhpt->page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
    2.32 @@ -331,6 +329,17 @@ void thash_tr_insert(thash_cb_t *hcb, th
    2.33      rep_tr(hcb, entry, idx);
    2.34      return ;
    2.35  }
    2.36 +thash_data_t *vtlb_alloc_chain(thash_cb_t *hcb,thash_data_t *entry)
    2.37 +{
    2.38 +    thash_data_t *cch;
    2.39 +    
    2.40 +    cch = cch_alloc(hcb);
    2.41 +    if(cch == NULL){
    2.42 +        thash_purge_all(hcb);
    2.43 +    }
    2.44 +    return cch;
    2.45 +}
    2.46 + 
    2.47  
    2.48  thash_data_t *__alloc_chain(thash_cb_t *hcb,thash_data_t *entry)
    2.49  {
    2.50 @@ -365,15 +374,14 @@ void vtlb_insert(thash_cb_t *hcb, thash_
    2.51      u64 gppn;
    2.52      u64 ppns, ppne;
    2.53  
    2.54 -    hash_table = (hcb->hash_func)(hcb->pta,
    2.55 -                        va, entry->rid, entry->ps);
    2.56 +    hash_table = (hcb->hash_func)(hcb->pta, va);
    2.57      if( INVALID_ENTRY(hcb, hash_table) ) {
    2.58          *hash_table = *entry;
    2.59          hash_table->next = 0;
    2.60      }
    2.61      else {
    2.62          // TODO: Add collision chain length limitation.
    2.63 -        cch = __alloc_chain(hcb,entry);
    2.64 +        cch = vtlb_alloc_chain(hcb,entry);
    2.65          if(cch == NULL){
    2.66              *hash_table = *entry;
    2.67              hash_table->next = 0;
    2.68 @@ -415,8 +423,7 @@ static void vhpt_insert(thash_cb_t *hcb,
    2.69      if ( !__tlb_to_vhpt(hcb, entry, va, &vhpt_entry) ) {
    2.70          panic("Can't convert to machine VHPT entry\n");
    2.71      }
    2.72 -    hash_table = (hcb->hash_func)(hcb->pta,
    2.73 -                        va, entry->rid, entry->ps);
    2.74 +    hash_table = (hcb->hash_func)(hcb->pta, va);
    2.75      if( INVALID_ENTRY(hcb, hash_table) ) {
    2.76          *hash_table = vhpt_entry;
    2.77          hash_table->next = 0;
    2.78 @@ -581,9 +588,7 @@ static thash_data_t *vtlb_find_overlap(t
    2.79      priv->rid = rid;
    2.80      vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
    2.81      priv->ps = vrr.ps;
    2.82 -    hash_table = (hcb->hash_func)(hcb->pta,
    2.83 -        priv->_curva, rid, priv->ps);
    2.84 -
    2.85 +    hash_table = (hcb->hash_func)(hcb->pta, priv->_curva);
    2.86      priv->s_sect = s_sect;
    2.87      priv->cl = cl;
    2.88      priv->_tr_idx = 0;
    2.89 @@ -605,11 +610,8 @@ static thash_data_t *vhpt_find_overlap(t
    2.90      priv->rid = rid;
    2.91      vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
    2.92      priv->ps = vrr.ps;
    2.93 -    hash_table = (hcb->hash_func)( hcb->pta,
    2.94 -        priv->_curva, rid, priv->ps);
    2.95 -    tag = (hcb->vs->tag_func)( hcb->pta,
    2.96 -        priv->_curva, rid, priv->ps);
    2.97 -
    2.98 +    hash_table = (hcb->hash_func)( hcb->pta, priv->_curva);
    2.99 +    tag = (hcb->vs->tag_func)( hcb->pta, priv->_curva);
   2.100      priv->tag = tag;
   2.101      priv->hash_base = hash_table;
   2.102      priv->cur_cch = hash_table;
   2.103 @@ -671,8 +673,7 @@ static thash_data_t *vtlb_next_overlap(t
   2.104              }
   2.105          }
   2.106          priv->_curva += rr_psize;
   2.107 -        priv->hash_base = (hcb->hash_func)( hcb->pta,
   2.108 -            priv->_curva, priv->rid, priv->ps);
   2.109 +        priv->hash_base = (hcb->hash_func)( hcb->pta, priv->_curva);
   2.110          priv->cur_cch = priv->hash_base;
   2.111      }
   2.112      return NULL;
   2.113 @@ -697,10 +698,8 @@ static thash_data_t *vhpt_next_overlap(t
   2.114              }
   2.115          }
   2.116          priv->_curva += rr_psize;
   2.117 -        priv->hash_base = (hcb->hash_func)( hcb->pta,
   2.118 -            priv->_curva, priv->rid, priv->ps);
   2.119 -        priv->tag = (hcb->vs->tag_func)( hcb->pta,
   2.120 -                priv->_curva, priv->rid, priv->ps);
   2.121 +        priv->hash_base = (hcb->hash_func)( hcb->pta, priv->_curva);
   2.122 +        priv->tag = (hcb->vs->tag_func)( hcb->pta, priv->_curva);
   2.123          priv->cur_cch = priv->hash_base;
   2.124      }
   2.125      return NULL;
   2.126 @@ -771,7 +770,26 @@ void thash_purge_and_insert(thash_cb_t *
   2.127  #endif
   2.128      (hcb->ins_hash)(hcb, in, in->vadr);
   2.129  }
   2.130 -
   2.131 +/*
   2.132 + * Purge one hash line (include the entry in hash table).
   2.133 + * Can only be called by thash_purge_all.
   2.134 + * Input:
   2.135 + *  hash: The head of collision chain (hash table)
   2.136 + *
   2.137 + */
   2.138 +static void thash_purge_line(thash_cb_t *hcb, thash_data_t *hash)
   2.139 +{
   2.140 +    if ( INVALID_ENTRY(hcb, hash) ) return;
   2.141 +    thash_data_t *prev, *next;
   2.142 +    next=hash->next;
   2.143 +    while ( next ) {
   2.144 +        prev=next;
   2.145 +        next=next->next;
   2.146 +        cch_free(hcb, prev);
   2.147 +    }
   2.148 +    // Then hash table itself.
   2.149 +    INVALIDATE_HASH(hcb, hash);
   2.150 +}
   2.151  /*
   2.152   * Purge all TCs or VHPT entries including those in Hash table.
   2.153   *
   2.154 @@ -792,10 +810,17 @@ void thash_purge_all(thash_cb_t *hcb)
   2.155  #endif
   2.156  
   2.157      hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
   2.158 -    
   2.159      for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
   2.160 -        thash_rem_line(hcb, hash_table);
   2.161 +        thash_purge_line(hcb, hash_table);
   2.162      }
   2.163 +    if(hcb->ht== THASH_TLB) {
   2.164 +        hcb = hcb->ts->vhpt;
   2.165 +        hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
   2.166 +        for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
   2.167 +            thash_purge_line(hcb, hash_table);
   2.168 +        }
   2.169 +    }
   2.170 +    local_flush_tlb_all();
   2.171  }
   2.172  
   2.173  
   2.174 @@ -826,7 +851,7 @@ thash_data_t *vtlb_lookup_ex(thash_cb_t 
   2.175      if ( cch ) return cch;
   2.176  
   2.177      vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
   2.178 -    hash_table = (hcb->hash_func)( hcb->pta,va, rid, vrr.ps);
   2.179 +    hash_table = (hcb->hash_func)( hcb->pta, va);
   2.180  
   2.181      if ( INVALID_ENTRY(hcb, hash_table ) )
   2.182          return NULL;
   2.183 @@ -893,7 +918,7 @@ void tlb_remove_notifier(thash_cb_t *hcb
   2.184      
   2.185      s_sect.v = 0;
   2.186      thash_purge_entries(hcb->ts->vhpt, entry, s_sect);
   2.187 -    machine_tlb_purge(entry->rid, entry->vadr, entry->ps);
   2.188 +    machine_tlb_purge(entry->vadr, entry->ps);
   2.189  }
   2.190  
   2.191  /*
     3.1 --- a/xen/include/asm-ia64/vmmu.h	Thu Dec 15 16:07:47 2005 -0600
     3.2 +++ b/xen/include/asm-ia64/vmmu.h	Thu Dec 15 16:09:19 2005 -0600
     3.3 @@ -148,8 +148,8 @@ typedef union thash_cch_mem {
     3.4  /*
     3.5   * Use to calculate the HASH index of thash_data_t.
     3.6   */
     3.7 -typedef u64 *(THASH_FN)(PTA pta, u64 va, u64 rid, u64 ps);
     3.8 -typedef u64 *(TTAG_FN)(PTA pta, u64 va, u64 rid, u64 ps);
     3.9 +typedef u64 *(THASH_FN)(PTA pta, u64 va);
    3.10 +typedef u64 *(TTAG_FN)(PTA pta, u64 va);
    3.11  typedef u64 *(GET_MFN_FN)(domid_t d, u64 gpfn, u64 pages);
    3.12  typedef void *(REM_NOTIFIER_FN)(struct hash_cb *hcb, thash_data_t *entry);
    3.13  typedef void (RECYCLE_FN)(struct hash_cb *hc, u64 para);
    3.14 @@ -329,8 +329,8 @@ extern int thash_lock_tc(thash_cb_t *hcb
    3.15  
    3.16  #define   ITIR_RV_MASK      (((1UL<<32)-1)<<32 | 0x3)
    3.17  #define   PAGE_FLAGS_RV_MASK    (0x2 | (0x3UL<<50)|(((1UL<<11)-1)<<53))
    3.18 -extern u64 machine_ttag(PTA pta, u64 va, u64 rid, u64 ps);
    3.19 -extern u64 machine_thash(PTA pta, u64 va, u64 rid, u64 ps);
    3.20 +extern u64 machine_ttag(PTA pta, u64 va);
    3.21 +extern u64 machine_thash(PTA pta, u64 va);
    3.22  extern void purge_machine_tc_by_domid(domid_t domid);
    3.23  extern void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb);
    3.24  extern ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va);