ia64/xen-unstable

changeset 17074:aaf4d6d1d83e

[IA64] Handle long vhpt format for ttag and thash.

Improve tak emulation.

Signed-off-by: Tristan Gingold <tgingold@free.fr>
author Alex Williamson <alex.williamson@hp.com>
date Tue Feb 19 09:22:25 2008 -0700 (2008-02-19)
parents 031c8f407e01
children 6aa10413da5b
files xen/arch/ia64/vmx/vmmu.c
line diff
     1.1 --- a/xen/arch/ia64/vmx/vmmu.c	Tue Feb 19 08:12:28 2008 -0700
     1.2 +++ b/xen/arch/ia64/vmx/vmmu.c	Tue Feb 19 09:22:25 2008 -0700
     1.3 @@ -467,16 +467,19 @@ u64 vmx_vcpu_thash(VCPU *vcpu, u64 vadr)
     1.4      ia64_rr vrr;
     1.5      u64 pval;
     1.6      u64 vhpt_offset;
     1.7 +    u64 mask;
     1.8 +
     1.9      vpta.val = vmx_vcpu_get_pta(vcpu);
    1.10      vcpu_get_rr(vcpu, vadr, &vrr.rrval);
    1.11 -    if(vpta.vf){
    1.12 -        pval = ia64_call_vsa(PAL_VPS_THASH, vadr, vrr.rrval,
    1.13 -                             vpta.val, 0, 0, 0, 0);
    1.14 -        pval = vpta.val & ~0xffff;
    1.15 -    }else{
    1.16 -        vhpt_offset=((vadr>>vrr.ps)<<3)&((1UL<<(vpta.size))-1);
    1.17 +    mask = (1UL << vpta.size) - 1;
    1.18 +    if (vpta.vf) {
    1.19 +        vadr = (vadr & 0x1fffffffffffffffUL) >> vrr.ps;
    1.20 +        vhpt_offset = vadr ^ vrr.rid;
    1.21 +        pval = (vpta.val & ~0x7fffUL) + ((vhpt_offset << 5) & mask);
    1.22 +    } else {
    1.23 +        vhpt_offset=((vadr >> vrr.ps) << 3) & mask;
    1.24          pval = (vadr & VRN_MASK) |
    1.25 -            (vpta.val<<3>>(vpta.size+3)<<(vpta.size))|
    1.26 +            (vpta.val << 3 >> (vpta.size + 3) << vpta.size) |
    1.27              vhpt_offset;
    1.28      }
    1.29      return  pval;
    1.30 @@ -488,10 +491,13 @@ u64 vmx_vcpu_ttag(VCPU *vcpu, u64 vadr)
    1.31      ia64_rr vrr;
    1.32      PTA vpta;
    1.33      u64 pval;
    1.34 +    u64 rid;
    1.35      vpta.val = vmx_vcpu_get_pta(vcpu);
    1.36      vcpu_get_rr(vcpu, vadr, &vrr.rrval);
    1.37      if(vpta.vf){
    1.38 -        pval = ia64_call_vsa(PAL_VPS_TTAG, vadr, vrr.rrval, 0, 0, 0, 0, 0);
    1.39 +        vadr = (vadr & 0x1fffffffffffffffUL) >> vrr.ps;
    1.40 +        rid = vrr.rid;
    1.41 +        pval = vadr ^ (rid << 39);
    1.42      }else{
    1.43          pval = 1;
    1.44      }
    1.45 @@ -507,83 +513,85 @@ IA64FAULT vmx_vcpu_tpa(VCPU *vcpu, u64 v
    1.46      REGS *regs;
    1.47      u64 vhpt_adr, madr;
    1.48      IA64_PSR vpsr;
    1.49 -    regs=vcpu_regs(vcpu);
    1.50 -    pt_isr.val=VMX(vcpu,cr_isr);
    1.51 -    visr.val=0;
    1.52 -    visr.ei=pt_isr.ei;
    1.53 -    visr.ir=pt_isr.ir;
    1.54 +
    1.55 +    regs = vcpu_regs(vcpu);
    1.56 +    pt_isr.val = VMX(vcpu, cr_isr);
    1.57 +    visr.val = 0;
    1.58 +    visr.ei = pt_isr.ei;
    1.59 +    visr.ir = pt_isr.ir;
    1.60      vpsr.val = VCPU(vcpu, vpsr);
    1.61 -    visr.na=1;
    1.62 +    visr.na = 1;
    1.63 +
    1.64 +    /* First look in VTLB.  */
    1.65      data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
    1.66 -    if(data){
    1.67 -        if(data->p==0){
    1.68 +    if (data) {
    1.69 +        if (data->p == 0) {
    1.70              vcpu_set_isr(vcpu,visr.val);
    1.71              data_page_not_present(vcpu, vadr);
    1.72              return IA64_FAULT;
    1.73 -        }else if(data->ma == VA_MATTR_NATPAGE){
    1.74 +        } else if (data->ma == VA_MATTR_NATPAGE) {
    1.75              vcpu_set_isr(vcpu, visr.val);
    1.76              dnat_page_consumption(vcpu, vadr);
    1.77              return IA64_FAULT;
    1.78 -        }else{
    1.79 +        } else {
    1.80              *padr = ((data->ppn >> (data->ps - 12)) << data->ps) |
    1.81                      (vadr & (PSIZE(data->ps) - 1));
    1.82              return IA64_NO_FAULT;
    1.83          }
    1.84      }
    1.85 +
    1.86 +    /* Look in mVHPT.  */
    1.87      data = vhpt_lookup(vadr);
    1.88 -    if(data){
    1.89 -        if(data->p==0){
    1.90 +    if (data) {
    1.91 +        if (data->p == 0) {
    1.92              vcpu_set_isr(vcpu,visr.val);
    1.93              data_page_not_present(vcpu, vadr);
    1.94              return IA64_FAULT;
    1.95 -        }else if(data->ma == VA_MATTR_NATPAGE){
    1.96 +        } else if (data->ma == VA_MATTR_NATPAGE) {
    1.97              vcpu_set_isr(vcpu, visr.val);
    1.98              dnat_page_consumption(vcpu, vadr);
    1.99              return IA64_FAULT;
   1.100 -        }else{
   1.101 +        } else {
   1.102              madr = (data->ppn >> (data->ps - 12) << data->ps) |
   1.103                     (vadr & (PSIZE(data->ps) - 1));
   1.104              *padr = __mpa_to_gpa(madr);
   1.105              return IA64_NO_FAULT;
   1.106          }
   1.107      }
   1.108 -    else{
   1.109 -        if(!vhpt_enabled(vcpu, vadr, NA_REF)){
   1.110 -            if(vpsr.ic){
   1.111 -                vcpu_set_isr(vcpu, visr.val);
   1.112 -                alt_dtlb(vcpu, vadr);
   1.113 -                return IA64_FAULT;
   1.114 -            }
   1.115 -            else{
   1.116 -                nested_dtlb(vcpu);
   1.117 -                return IA64_FAULT;
   1.118 -            }
   1.119 +
   1.120 +    /* If VHPT is not enabled, inject fault.  */
   1.121 +    if (!vhpt_enabled(vcpu, vadr, NA_REF)) {
   1.122 +        if (vpsr.ic) {
   1.123 +            vcpu_set_isr(vcpu, visr.val);
   1.124 +            alt_dtlb(vcpu, vadr);
   1.125 +            return IA64_FAULT;
   1.126 +        } else {
   1.127 +            nested_dtlb(vcpu);
   1.128 +            return IA64_FAULT;
   1.129          }
   1.130 -        else{
   1.131 -            vhpt_adr = vmx_vcpu_thash(vcpu, vadr);
   1.132 -            data = vtlb_lookup(vcpu, vhpt_adr, DSIDE_TLB);
   1.133 -            if(data){
   1.134 -                if(vpsr.ic){
   1.135 -                    vcpu_set_isr(vcpu, visr.val);
   1.136 -                    dtlb_fault(vcpu, vadr);
   1.137 -                    return IA64_FAULT;
   1.138 -                }
   1.139 -                else{
   1.140 -                    nested_dtlb(vcpu);
   1.141 -                    return IA64_FAULT;
   1.142 -                }
   1.143 -            }
   1.144 -            else{
   1.145 -                if(vpsr.ic){
   1.146 -                    vcpu_set_isr(vcpu, visr.val);
   1.147 -                    dvhpt_fault(vcpu, vadr);
   1.148 -                    return IA64_FAULT;
   1.149 -                }
   1.150 -                else{
   1.151 -                    nested_dtlb(vcpu);
   1.152 -                    return IA64_FAULT;
   1.153 -                }
   1.154 -            }
   1.155 +    }
   1.156 +
   1.157 +    /* Get gVHPT entry.  */
   1.158 +    vhpt_adr = vmx_vcpu_thash(vcpu, vadr);
   1.159 +    data = vtlb_lookup(vcpu, vhpt_adr, DSIDE_TLB);
   1.160 +    if (data) {
   1.161 +        /* FIXME: we should read gadr from the entry!  */
   1.162 +        if (vpsr.ic) {
   1.163 +            vcpu_set_isr(vcpu, visr.val);
   1.164 +            dtlb_fault(vcpu, vadr);
   1.165 +            return IA64_FAULT;
   1.166 +        } else {
   1.167 +            nested_dtlb(vcpu);
   1.168 +            return IA64_FAULT;
   1.169 +        }
   1.170 +    } else {
   1.171 +        if (vpsr.ic) {
   1.172 +            vcpu_set_isr(vcpu, visr.val);
   1.173 +            dvhpt_fault(vcpu, vadr);
   1.174 +            return IA64_FAULT;
   1.175 +        } else {
   1.176 +            nested_dtlb(vcpu);
   1.177 +            return IA64_FAULT;
   1.178          }
   1.179      }
   1.180  }
   1.181 @@ -598,12 +606,25 @@ u64 vmx_vcpu_tak(VCPU *vcpu, u64 vadr)
   1.182          return key;
   1.183      }
   1.184  
   1.185 -    /* FIXME: if psr.dt is set, look in the guest VHPT.  */
   1.186      data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
   1.187 -    if (!data || !data->p)
   1.188 -        key = 1;
   1.189 -    else
   1.190 -        key = data->key << 8;
   1.191 +    if (data) {
   1.192 +        if (data->p)
   1.193 +            return data->key << 8;
   1.194 +        else
   1.195 +            return 1;
   1.196 +    }
   1.197  
   1.198 -    return key;
   1.199 +    data = vhpt_lookup(vadr);
   1.200 +    if (data) {
   1.201 +        if (data->p)
   1.202 +            return data->key << 8;	/* FIXME: possible mangling/masking.  */
   1.203 +        else
   1.204 +            return 1;
   1.205 +    }
   1.206 +
   1.207 +    if (!vhpt_enabled(vcpu, vadr, NA_REF))
   1.208 +        return 1;
   1.209 +
   1.210 +    /* FIXME: look in the guest VHPT.  */
   1.211 +    return 1;
   1.212  }