ia64/xen-unstable

changeset 10877:4acc6d51f389

[IA64] Optimize windows boot

Better handle multiple page size on the same region in windows OS,
Windows can boot within 2 minute in my box.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author awilliam@xenbuild.aw
date Tue Aug 01 14:58:20 2006 -0600 (2006-08-01)
parents 27ccf13dc3b7
children b76e86966e7e
files xen/arch/ia64/vmx/vtlb.c xen/include/asm-ia64/vmmu.h xen/include/asm-ia64/vmx_vpd.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vtlb.c	Tue Aug 01 14:44:04 2006 -0600
     1.2 +++ b/xen/arch/ia64/vmx/vtlb.c	Tue Aug 01 14:58:20 2006 -0600
     1.3 @@ -242,26 +242,31 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
     1.4  
     1.5  void vtlb_purge(VCPU *v, u64 va, u64 ps)
     1.6  {
     1.7 +    thash_data_t *cur;
     1.8 +    u64 start, end, curadr, size, psbits, tag, def_size;
     1.9 +    ia64_rr vrr;
    1.10      thash_cb_t *hcb = &v->arch.vtlb;
    1.11 -    thash_data_t *cur;
    1.12 -    u64 start, end, size, tag, rid, def_size;
    1.13 -    ia64_rr vrr;
    1.14      vcpu_get_rr(v, va, &vrr.rrval);
    1.15 -    rid = vrr.rid;
    1.16 +    psbits = VMX(v, psbits[(va >> 61)]);
    1.17      size = PSIZE(ps);
    1.18      start = va & (-size);
    1.19      end = start + size;
    1.20 -    def_size = PSIZE(vrr.ps);
    1.21 -    while(start < end){
    1.22 -        cur = vsa_thash(hcb->pta, start, vrr.rrval, &tag);
    1.23 -        while (cur) {
    1.24 -            if (cur->etag == tag)
    1.25 -                 cur->etag = 1UL << 63;
    1.26 -            cur = cur->next;
    1.27 +    while (psbits) {
    1.28 +        curadr = start;
    1.29 +        ps = __ffs(psbits);
    1.30 +        psbits &= ~(1UL << ps);
    1.31 +        def_size = PSIZE(ps);
    1.32 +        vrr.ps = ps;
    1.33 +        while (curadr < end) {
    1.34 +            cur = vsa_thash(hcb->pta, curadr, vrr.rrval, &tag);
    1.35 +            while (cur) {
    1.36 +                if (cur->etag == tag && cur->ps == ps)
    1.37 +                    cur->etag = 1UL << 63;
    1.38 +                cur = cur->next;
    1.39 +            }
    1.40 +            curadr += def_size;
    1.41          }
    1.42 -        start += def_size;
    1.43      }
    1.44 -//    machine_tlb_purge(va, ps);
    1.45  }
    1.46  
    1.47  
    1.48 @@ -333,14 +338,15 @@ thash_data_t *__alloc_chain(thash_cb_t *
    1.49   *  3: The caller need to make sure the new entry will not overlap
    1.50   *     with any existed entry.
    1.51   */
    1.52 -void vtlb_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 va)
    1.53 +void vtlb_insert(VCPU *v, u64 pte, u64 itir, u64 va)
    1.54  {
    1.55 -    thash_data_t    *hash_table, *cch;
    1.56 +    thash_data_t *hash_table, *cch;
    1.57      /* int flag; */
    1.58      ia64_rr vrr;
    1.59      /* u64 gppn, ppns, ppne; */
    1.60      u64 tag, len;
    1.61 -    vcpu_get_rr(current, va, &vrr.rrval);
    1.62 +    thash_cb_t *hcb = &v->arch.vtlb;
    1.63 +    vcpu_get_rr(v, va, &vrr.rrval);
    1.64  #ifdef VTLB_DEBUG    
    1.65      if (vrr.ps != itir_ps(itir)) {
    1.66  //        machine_tlb_insert(hcb->vcpu, entry);
    1.67 @@ -349,6 +355,8 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt
    1.68          return;
    1.69      }
    1.70  #endif
    1.71 +    vrr.ps = itir_ps(itir);
    1.72 +    VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps);
    1.73      hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
    1.74      if( INVALID_TLB(hash_table) ) {
    1.75          len = hash_table->len;
    1.76 @@ -446,9 +454,10 @@ void thash_purge_and_insert(VCPU *v, u64
    1.77  {
    1.78      u64 ps;//, va;
    1.79      u64 phy_pte;
    1.80 -    ia64_rr vrr;
    1.81 +    ia64_rr vrr, mrr;
    1.82      ps = itir_ps(itir);
    1.83      vcpu_get_rr(current, ifa, &vrr.rrval);
    1.84 +    mrr.rrval = ia64_get_rr(ifa);
    1.85  //    if (vrr.ps != itir_ps(itir)) {
    1.86  //        printf("not preferred ps with va: 0x%lx vrr.ps=%d ps=%ld\n",
    1.87  //               ifa, vrr.ps, itir_ps(itir));
    1.88 @@ -462,30 +471,33 @@ void thash_purge_and_insert(VCPU *v, u64
    1.89              pte &= ~_PAGE_MA_MASK;
    1.90  
    1.91          phy_pte = translate_phy_pte(v, &pte, itir, ifa);
    1.92 -        if (vrr.ps <= PAGE_SHIFT) {
    1.93 +        vtlb_purge(v, ifa, ps);
    1.94 +        vhpt_purge(v, ifa, ps);
    1.95 +        if (ps == mrr.ps) {
    1.96              if(!(pte&VTLB_PTE_IO)){
    1.97 -                vhpt_purge(v, ifa, ps);
    1.98                  vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
    1.99              }
   1.100              else{
   1.101 -                vhpt_purge(v, ifa, ps);
   1.102 -                vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
   1.103 +                vtlb_insert(v, pte, itir, ifa);
   1.104                  vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
   1.105              }
   1.106          }
   1.107 -        else{
   1.108 -            vhpt_purge(v, ifa, ps);
   1.109 -            vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
   1.110 +        else if (ps > mrr.ps) {
   1.111 +            vtlb_insert(v, pte, itir, ifa);
   1.112              vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
   1.113              if(!(pte&VTLB_PTE_IO)){
   1.114                  vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
   1.115              }
   1.116          }
   1.117 +        else {
   1.118 +            // ps < mrr.ps, this is not supported
   1.119 +            panic_domain(NULL, "%s: ps (%lx) < mrr.ps \n", __func__, ps);
   1.120 +        }
   1.121      }
   1.122      else{
   1.123          phy_pte = translate_phy_pte(v, &pte, itir, ifa);
   1.124          if(ps!=PAGE_SHIFT){
   1.125 -            vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
   1.126 +            vtlb_insert(v, pte, itir, ifa);
   1.127              vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
   1.128          }
   1.129          machine_tlb_purge(ifa, ps);
   1.130 @@ -507,11 +519,15 @@ void thash_purge_all(VCPU *v)
   1.131      vtlb =&v->arch.vtlb;
   1.132      vhpt =&v->arch.vhpt;
   1.133  
   1.134 +    for (num = 0; num < 8; num++)
   1.135 +        VMX(v, psbits[num]) = 0;
   1.136 +    
   1.137      head=vtlb->hash;
   1.138      num = (vtlb->hash_sz/sizeof(thash_data_t));
   1.139      do{
   1.140          head->page_flags = 0;
   1.141          head->etag = 1UL<<63;
   1.142 +        head->itir = 0;
   1.143          head->next = 0;
   1.144          head++;
   1.145          num--;
   1.146 @@ -543,7 +559,7 @@ void thash_purge_all(VCPU *v)
   1.147  thash_data_t *vtlb_lookup(VCPU *v, u64 va,int is_data)
   1.148  {
   1.149      thash_data_t  *cch;
   1.150 -    u64     tag;
   1.151 +    u64     psbits, ps, tag;
   1.152      ia64_rr vrr;
   1.153      thash_cb_t * hcb= &v->arch.vtlb;
   1.154  
   1.155 @@ -552,15 +568,19 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
   1.156  
   1.157      if(vcpu_quick_region_check(v->arch.tc_regions,va)==0)
   1.158          return NULL;
   1.159 -    
   1.160 +    psbits = VMX(v, psbits[(va >> 61)]);
   1.161      vcpu_get_rr(v,va,&vrr.rrval);
   1.162 -    cch = vsa_thash( hcb->pta, va, vrr.rrval, &tag);
   1.163 -
   1.164 -    do{
   1.165 -        if(cch->etag == tag)
   1.166 -            return cch;
   1.167 -        cch = cch->next;
   1.168 -    }while(cch);
   1.169 +    while (psbits) {
   1.170 +        ps = __ffs(psbits);
   1.171 +        psbits &= ~(1UL << ps);
   1.172 +        vrr.ps = ps;
   1.173 +        cch = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
   1.174 +        do {
   1.175 +            if (cch->etag == tag && cch->ps == ps)
   1.176 +                return cch;
   1.177 +            cch = cch->next;
   1.178 +        } while(cch);
   1.179 +    }
   1.180      return NULL;
   1.181  }
   1.182  
     2.1 --- a/xen/include/asm-ia64/vmmu.h	Tue Aug 01 14:44:04 2006 -0600
     2.2 +++ b/xen/include/asm-ia64/vmmu.h	Tue Aug 01 14:58:20 2006 -0600
     2.3 @@ -302,7 +302,7 @@ extern void machine_tlb_purge(u64 va, u6
     2.4  extern int fetch_code(struct vcpu *vcpu, u64 gip, u64 *code1, u64 *code2);
     2.5  extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma);
     2.6  extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
     2.7 -extern void  vtlb_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 va);
     2.8 +extern void vtlb_insert(struct vcpu *vcpu, u64 pte, u64 itir, u64 va);
     2.9  extern u64 translate_phy_pte(struct vcpu *v, u64 *pte, u64 itir, u64 va);
    2.10  extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa);
    2.11  extern u64 guest_vhpt_lookup(u64 iha, u64 *pte);
     3.1 --- a/xen/include/asm-ia64/vmx_vpd.h	Tue Aug 01 14:44:04 2006 -0600
     3.2 +++ b/xen/include/asm-ia64/vmx_vpd.h	Tue Aug 01 14:58:20 2006 -0600
     3.3 @@ -77,6 +77,9 @@ struct arch_vmx_struct {
     3.4      vtime_t	    vtm;
     3.5      struct vlapic   vlapic;
     3.6      unsigned long   vrr[8];
     3.7 +    /* if the corresponding bit is 1, then this page size is
     3.8 +       used in this region */
     3.9 +    unsigned long   psbits[8];
    3.10      unsigned long   vkr[8];
    3.11      unsigned long   cr_iipa;   /* for emulation */
    3.12      unsigned long   cr_isr;    /* for emulation */