[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] fix a fetch code bug
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |