# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID bfc69471550ed272b11df29903b268292f4857f5
# Parent 15498beef5d816c171938dff9b1f5bfa7a513c28
[IA64] fix a fetch code bug
Fetch code may fail, if there is no corresponding tlb entry
in THASH-VTLB. This patch adds "retry mechanism" to resolve
this issue.
Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
xen/arch/ia64/vmx/mmio.c | 5 ++++-
xen/arch/ia64/vmx/vmmu.c | 24 +++++++++++++-----------
xen/arch/ia64/vmx/vmx_virt.c | 9 ++++-----
xen/arch/ia64/xen/faults.c | 20 ++++++++++++++++----
xen/include/asm-ia64/bundle.h | 2 +-
xen/include/asm-ia64/vmmu.h | 3 ++-
6 files changed, 40 insertions(+), 23 deletions(-)
diff -r 15498beef5d8 -r bfc69471550e xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c Tue Aug 08 14:42:34 2006 -0600
+++ b/xen/arch/ia64/vmx/mmio.c Wed Aug 09 08:01:52 2006 -0600
@@ -433,7 +433,10 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
u64 data, value,post_update, slot1a, slot1b, temp;
INST64 inst;
regs=vcpu_regs(vcpu);
- bundle = __vmx_get_domain_bundle(regs->cr_iip);
+ if (IA64_RETRY == __vmx_get_domain_bundle(regs->cr_iip, &bundle)) {
+ /* if fetch code fail, return and try again */
+ return;
+ }
slot = ((struct ia64_psr *)&(regs->cr_ipsr))->ri;
if (!slot) inst.inst = bundle.slot0;
else if (slot == 1){
diff -r 15498beef5d8 -r bfc69471550e xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Tue Aug 08 14:42:34 2006 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c Wed Aug 09 08:01:52 2006 -0600
@@ -305,13 +305,13 @@ int unimplemented_gva(VCPU *vcpu,u64 vad
/*
- * Prefetch guest bundle code.
+ * Fetch guest bundle code.
* INPUT:
- * code: buffer pointer to hold the read data.
- * num: number of dword (8byts) to read.
- */
-int
-fetch_code(VCPU *vcpu, u64 gip, u64 *code1, u64 *code2)
+ * gip: guest ip
+ * pbundle: used to return fetched bundle.
+ */
+unsigned long
+fetch_code(VCPU *vcpu, u64 gip, IA64_BUNDLE *pbundle)
{
u64 gpip=0; // guest physical IP
u64 *vpa;
@@ -336,8 +336,10 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
maddr = (mfn << PAGE_SHIFT) | (gpip & (PAGE_SIZE - 1));
}else{
tlb = vhpt_lookup(gip);
- if( tlb == NULL)
- panic_domain(vcpu_regs(vcpu),"No entry found in ITLB and DTLB\n");
+ if (tlb == NULL) {
+ ia64_ptcl(gip, ARCH_PAGE_SHIFT << 2);
+ return IA64_RETRY;
+ }
mfn = tlb->ppn >> (PAGE_SHIFT - ARCH_PAGE_SHIFT);
maddr = (tlb->ppn >> (tlb->ps - 12) << tlb->ps) |
(gip & (PSIZE(tlb->ps) - 1));
@@ -354,10 +356,10 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
}
vpa = (u64 *)__va(maddr);
- *code1 = *vpa++;
- *code2 = *vpa;
+ pbundle->i64[0] = *vpa++;
+ pbundle->i64[1] = *vpa;
put_page(page);
- return 1;
+ return IA64_NO_FAULT;
}
IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
diff -r 15498beef5d8 -r bfc69471550e xen/arch/ia64/vmx/vmx_virt.c
--- a/xen/arch/ia64/vmx/vmx_virt.c Tue Aug 08 14:42:34 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_virt.c Wed Aug 09 08:01:52 2006 -0600
@@ -1334,11 +1334,10 @@ IA64FAULT vmx_emul_mov_from_cr(VCPU *vcp
//#define BYPASS_VMAL_OPCODE
extern IA64_SLOT_TYPE slot_types[0x20][3];
-IA64_BUNDLE __vmx_get_domain_bundle(u64 iip)
-{
- IA64_BUNDLE bundle;
- fetch_code( current, iip, &bundle.i64[0], &bundle.i64[1]);
- return bundle;
+unsigned long
+__vmx_get_domain_bundle(u64 iip, IA64_BUNDLE *pbundle)
+{
+ return fetch_code(current, iip, pbundle);
}
/** Emulate a privileged operation.
diff -r 15498beef5d8 -r bfc69471550e xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c Tue Aug 08 14:42:34 2006 -0600
+++ b/xen/arch/ia64/xen/faults.c Wed Aug 09 08:01:52 2006 -0600
@@ -323,8 +323,10 @@ handle_fpu_swa (int fp_fault, struct pt_
if (!fp_fault && (ia64_psr(regs)->ri == 0))
fault_ip -= 16;
- if (VMX_DOMAIN(current))
- bundle = __vmx_get_domain_bundle(fault_ip);
+ if (VMX_DOMAIN(current)) {
+ if (IA64_RETRY == __vmx_get_domain_bundle(fault_ip, &bundle))
+ return IA64_RETRY;
+ }
else
bundle = __get_domain_bundle(fault_ip);
@@ -555,6 +557,7 @@ ia64_handle_reflection (unsigned long if
struct vcpu *v = current;
unsigned long check_lazy_cover = 0;
unsigned long psr = regs->cr_ipsr;
+ unsigned long status;
/* Following faults shouldn'g be seen from Xen itself */
BUG_ON (!(psr & IA64_PSR_CPL));
@@ -615,14 +618,23 @@ ia64_handle_reflection (unsigned long if
// FIXME: Should we handle unaligned refs in Xen??
vector = IA64_UNALIGNED_REF_VECTOR; break;
case 32:
- if (!(handle_fpu_swa(1, regs, isr))) {
+ status = handle_fpu_swa(1, regs, isr);
+ if (!status) {
vcpu_increment_iip(v);
return;
}
+ // fetch code fail
+ if (IA64_RETRY == status)
+ return;
printf("ia64_handle_reflection: handling FP fault\n");
vector = IA64_FP_FAULT_VECTOR; break;
case 33:
- if (!(handle_fpu_swa(0, regs, isr))) return;
+ status = handle_fpu_swa(0, regs, isr);
+ if (!status)
+ return;
+ // fetch code fail
+ if (IA64_RETRY == status)
+ return;
printf("ia64_handle_reflection: handling FP trap\n");
vector = IA64_FP_TRAP_VECTOR; break;
case 34:
diff -r 15498beef5d8 -r bfc69471550e xen/include/asm-ia64/bundle.h
--- a/xen/include/asm-ia64/bundle.h Tue Aug 08 14:42:34 2006 -0600
+++ b/xen/include/asm-ia64/bundle.h Wed Aug 09 08:01:52 2006 -0600
@@ -223,7 +223,7 @@ typedef union U_INST64 {
INST64_M47 M47; // purge translation entry
} INST64;
-extern IA64_BUNDLE __vmx_get_domain_bundle(unsigned long iip);
+extern unsigned long __vmx_get_domain_bundle(unsigned long iip, IA64_BUNDLE
*pbundle);
extern IA64_BUNDLE __get_domain_bundle(unsigned long iip);
#define MASK_41 ((unsigned long)0x1ffffffffff)
diff -r 15498beef5d8 -r bfc69471550e xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h Tue Aug 08 14:42:34 2006 -0600
+++ b/xen/include/asm-ia64/vmmu.h Wed Aug 09 08:01:52 2006 -0600
@@ -40,6 +40,7 @@
#include <asm/tlb.h>
#include <asm/regionreg.h>
#include <asm/vmx_mm_def.h>
+#include <asm/bundle.h>
//#define THASH_TLB_TR 0
//#define THASH_TLB_TC 1
@@ -299,7 +300,7 @@ extern thash_data_t * vsa_thash(PTA vpta
extern thash_data_t * vsa_thash(PTA vpta, u64 va, u64 vrr, u64 *tag);
extern thash_data_t * vhpt_lookup(u64 va);
extern void machine_tlb_purge(u64 va, u64 ps);
-extern int fetch_code(struct vcpu *vcpu, u64 gip, u64 *code1, u64 *code2);
+extern unsigned long fetch_code(struct vcpu *vcpu, u64 gip, IA64_BUNDLE
*pbundle);
extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma);
extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
extern void vtlb_insert(struct vcpu *vcpu, u64 pte, u64 itir, u64 va);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|