# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1203438145 25200
# Node ID aaf4d6d1d83e8a5ef5b2f644a90950ac7994fcb5
# Parent 031c8f407e01de2c410276fcad63c640ae412742
[IA64] Handle long vhpt format for ttag and thash.
Improve tak emulation.
Signed-off-by: Tristan Gingold <tgingold@xxxxxxx>
---
xen/arch/ia64/vmx/vmmu.c | 183 ++++++++++++++++++++++++++---------------------
1 files changed, 102 insertions(+), 81 deletions(-)
diff -r 031c8f407e01 -r aaf4d6d1d83e xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Tue Feb 19 08:12:28 2008 -0700
+++ b/xen/arch/ia64/vmx/vmmu.c Tue Feb 19 09:22:25 2008 -0700
@@ -467,31 +467,37 @@ u64 vmx_vcpu_thash(VCPU *vcpu, u64 vadr)
ia64_rr vrr;
u64 pval;
u64 vhpt_offset;
+ u64 mask;
+
+ vpta.val = vmx_vcpu_get_pta(vcpu);
+ vcpu_get_rr(vcpu, vadr, &vrr.rrval);
+ mask = (1UL << vpta.size) - 1;
+ if (vpta.vf) {
+ vadr = (vadr & 0x1fffffffffffffffUL) >> vrr.ps;
+ vhpt_offset = vadr ^ vrr.rid;
+ pval = (vpta.val & ~0x7fffUL) + ((vhpt_offset << 5) & mask);
+ } else {
+ vhpt_offset=((vadr >> vrr.ps) << 3) & mask;
+ pval = (vadr & VRN_MASK) |
+ (vpta.val << 3 >> (vpta.size + 3) << vpta.size) |
+ vhpt_offset;
+ }
+ return pval;
+}
+
+
+u64 vmx_vcpu_ttag(VCPU *vcpu, u64 vadr)
+{
+ ia64_rr vrr;
+ PTA vpta;
+ u64 pval;
+ u64 rid;
vpta.val = vmx_vcpu_get_pta(vcpu);
vcpu_get_rr(vcpu, vadr, &vrr.rrval);
if(vpta.vf){
- pval = ia64_call_vsa(PAL_VPS_THASH, vadr, vrr.rrval,
- vpta.val, 0, 0, 0, 0);
- pval = vpta.val & ~0xffff;
- }else{
- vhpt_offset=((vadr>>vrr.ps)<<3)&((1UL<<(vpta.size))-1);
- pval = (vadr & VRN_MASK) |
- (vpta.val<<3>>(vpta.size+3)<<(vpta.size))|
- vhpt_offset;
- }
- return pval;
-}
-
-
-u64 vmx_vcpu_ttag(VCPU *vcpu, u64 vadr)
-{
- ia64_rr vrr;
- PTA vpta;
- u64 pval;
- vpta.val = vmx_vcpu_get_pta(vcpu);
- vcpu_get_rr(vcpu, vadr, &vrr.rrval);
- if(vpta.vf){
- pval = ia64_call_vsa(PAL_VPS_TTAG, vadr, vrr.rrval, 0, 0, 0, 0, 0);
+ vadr = (vadr & 0x1fffffffffffffffUL) >> vrr.ps;
+ rid = vrr.rid;
+ pval = vadr ^ (rid << 39);
}else{
pval = 1;
}
@@ -507,83 +513,85 @@ IA64FAULT vmx_vcpu_tpa(VCPU *vcpu, u64 v
REGS *regs;
u64 vhpt_adr, madr;
IA64_PSR vpsr;
- regs=vcpu_regs(vcpu);
- pt_isr.val=VMX(vcpu,cr_isr);
- visr.val=0;
- visr.ei=pt_isr.ei;
- visr.ir=pt_isr.ir;
+
+ regs = vcpu_regs(vcpu);
+ pt_isr.val = VMX(vcpu, cr_isr);
+ visr.val = 0;
+ visr.ei = pt_isr.ei;
+ visr.ir = pt_isr.ir;
vpsr.val = VCPU(vcpu, vpsr);
- visr.na=1;
+ visr.na = 1;
+
+ /* First look in VTLB. */
data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
- if(data){
- if(data->p==0){
+ if (data) {
+ if (data->p == 0) {
vcpu_set_isr(vcpu,visr.val);
data_page_not_present(vcpu, vadr);
return IA64_FAULT;
- }else if(data->ma == VA_MATTR_NATPAGE){
+ } else if (data->ma == VA_MATTR_NATPAGE) {
vcpu_set_isr(vcpu, visr.val);
dnat_page_consumption(vcpu, vadr);
return IA64_FAULT;
- }else{
+ } else {
*padr = ((data->ppn >> (data->ps - 12)) << data->ps) |
(vadr & (PSIZE(data->ps) - 1));
return IA64_NO_FAULT;
}
}
+
+ /* Look in mVHPT. */
data = vhpt_lookup(vadr);
- if(data){
- if(data->p==0){
+ if (data) {
+ if (data->p == 0) {
vcpu_set_isr(vcpu,visr.val);
data_page_not_present(vcpu, vadr);
return IA64_FAULT;
- }else if(data->ma == VA_MATTR_NATPAGE){
+ } else if (data->ma == VA_MATTR_NATPAGE) {
vcpu_set_isr(vcpu, visr.val);
dnat_page_consumption(vcpu, vadr);
return IA64_FAULT;
- }else{
+ } else {
madr = (data->ppn >> (data->ps - 12) << data->ps) |
(vadr & (PSIZE(data->ps) - 1));
*padr = __mpa_to_gpa(madr);
return IA64_NO_FAULT;
}
}
- else{
- if(!vhpt_enabled(vcpu, vadr, NA_REF)){
- if(vpsr.ic){
- vcpu_set_isr(vcpu, visr.val);
- alt_dtlb(vcpu, vadr);
- return IA64_FAULT;
- }
- else{
- nested_dtlb(vcpu);
- return IA64_FAULT;
- }
- }
- else{
- vhpt_adr = vmx_vcpu_thash(vcpu, vadr);
- data = vtlb_lookup(vcpu, vhpt_adr, DSIDE_TLB);
- if(data){
- if(vpsr.ic){
- vcpu_set_isr(vcpu, visr.val);
- dtlb_fault(vcpu, vadr);
- return IA64_FAULT;
- }
- else{
- nested_dtlb(vcpu);
- return IA64_FAULT;
- }
- }
- else{
- if(vpsr.ic){
- vcpu_set_isr(vcpu, visr.val);
- dvhpt_fault(vcpu, vadr);
- return IA64_FAULT;
- }
- else{
- nested_dtlb(vcpu);
- return IA64_FAULT;
- }
- }
+
+ /* If VHPT is not enabled, inject fault. */
+ if (!vhpt_enabled(vcpu, vadr, NA_REF)) {
+ if (vpsr.ic) {
+ vcpu_set_isr(vcpu, visr.val);
+ alt_dtlb(vcpu, vadr);
+ return IA64_FAULT;
+ } else {
+ nested_dtlb(vcpu);
+ return IA64_FAULT;
+ }
+ }
+
+ /* Get gVHPT entry. */
+ vhpt_adr = vmx_vcpu_thash(vcpu, vadr);
+ data = vtlb_lookup(vcpu, vhpt_adr, DSIDE_TLB);
+ if (data) {
+ /* FIXME: we should read gadr from the entry! */
+ if (vpsr.ic) {
+ vcpu_set_isr(vcpu, visr.val);
+ dtlb_fault(vcpu, vadr);
+ return IA64_FAULT;
+ } else {
+ nested_dtlb(vcpu);
+ return IA64_FAULT;
+ }
+ } else {
+ if (vpsr.ic) {
+ vcpu_set_isr(vcpu, visr.val);
+ dvhpt_fault(vcpu, vadr);
+ return IA64_FAULT;
+ } else {
+ nested_dtlb(vcpu);
+ return IA64_FAULT;
}
}
}
@@ -598,12 +606,25 @@ u64 vmx_vcpu_tak(VCPU *vcpu, u64 vadr)
return key;
}
- /* FIXME: if psr.dt is set, look in the guest VHPT. */
data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
- if (!data || !data->p)
- key = 1;
- else
- key = data->key << 8;
-
- return key;
-}
+ if (data) {
+ if (data->p)
+ return data->key << 8;
+ else
+ return 1;
+ }
+
+ data = vhpt_lookup(vadr);
+ if (data) {
+ if (data->p)
+ return data->key << 8; /* FIXME: possible mangling/masking. */
+ else
+ return 1;
+ }
+
+ if (!vhpt_enabled(vcpu, vadr, NA_REF))
+ return 1;
+
+ /* FIXME: look in the guest VHPT. */
+ return 1;
+}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|