[Xen-ia64-devel] [PATCH 0/5] fix fpswa and related issues.
Hi. This patch series addresses the bug reported as http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 Please test it. It includes some clean ups and a reimplementation of fpswa hypercall. When fp fault/trap occurs, xen vmm tries to get a bundle in question from guest virtual address space. It sometimes fails because of I/D tlb cache. In that case inject the fault/trap into a guest and let a guest to call fpswa hypercall. thanks ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
[Xen-ia64-devel] [PATCH 1/5] use symbolic constant instead of magic number
IA64: use symbolic constant for hypercall. define symbolic names for hypercall number and use them. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/dom_fw_asm.S b/xen/arch/ia64/xen/dom_fw_asm.S --- a/xen/arch/ia64/xen/dom_fw_asm.S +++ b/xen/arch/ia64/xen/dom_fw_asm.S @@ -1,3 +1,5 @@ +#include + // moved from xenasm.S to be shared by xen and libxc /* * Assembly support routines for Xen/ia64 @@ -26,14 +28,14 @@ xen_ia64_pal_call_stub: xen_ia64_pal_call_stub: { .mii - addl r2=0x1000,r0 // Hypercall number (Value is patched). + addl r2=FW_HYPERCALL_PAL_CALL_ASM,r0// Hypercall number (Value is patched). mov r9=256 ;; cmp.gtu p7,p8=r9,r28/* r32 <= 255? */ } { .mbb - break 0x1000// Hypercall vector (Value is patched). + break __IA64_XEN_HYPERCALL_DEFAULT // Hypercall vector (Value is patched). (p7) br.cond.sptk.few rp (p8) br.ret.sptk.few rp } diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -561,7 +561,7 @@ int arch_domain_create(struct domain *d, // the following will eventually need to be negotiated dynamically d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR; - d->arch.breakimm = 0x1000; + d->arch.breakimm = __IA64_XEN_HYPERCALL_DEFAULT; for (i = 0; i < NR_CPUS; i++) { d->arch.last_vcpu[i].vcpu_id = INVALID_VCPU_ID; } diff --git a/xen/include/asm-ia64/dom_fw.h b/xen/include/asm-ia64/dom_fw.h --- a/xen/include/asm-ia64/dom_fw.h +++ b/xen/include/asm-ia64/dom_fw.h @@ -4,6 +4,9 @@ * Copyright (C) 2004 Hewlett-Packard Co * Dan Magenheimer ([EMAIL PROTECTED]) */ + +#define __IA64_XEN_HYPERCALL_DEFAULT 0x1000 +#define __IA64_XEN_HYPERCALL_DEFAULT_STR "0x1000" /* Portion of guest physical memory space reserved for PAL/SAL/EFI/ACPI data and code. */ @@ -65,6 +68,7 @@ #define FW_HYPERCALL_PAL_CALL_INDEX0x80UL #define FW_HYPERCALL_PAL_CALL_PADDR FW_HYPERCALL_PADDR(FW_HYPERCALL_PAL_CALL_INDEX) #define FW_HYPERCALL_PAL_CALL 0x1000UL +#define FW_HYPERCALL_PAL_CALL_ASM 0x1000 /* * SAL consists of a table of descriptors, one of which (type=0) @@ -164,6 +168,7 @@ #define FW_HYPERCALL_FPSWA_ENTRY_PADDR FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_ENTRY_INDEX) #define FW_HYPERCALL_FPSWA_PATCH_PADDR FW_HYPERCALL_PADDR(FW_HYPERCALL_FPSWA_PATCH_INDEX) #define FW_HYPERCALL_FPSWA 0x500UL +#define FW_HYPERCALL_FPSWA_STR "0x500" /* Set the shared_info base virtual address. */ #define FW_HYPERCALL_SET_SHARED_INFO_VA0x600UL @@ -186,7 +191,7 @@ /* Additionnal OEM SAL. */ #define SAL_XEN_SAL_RETURN 0x0200 -#ifdef __XEN__ +#if defined(__XEN__) && !defined(__ASSEMBLY__) #include extern struct ia64_pal_retval xen_pal_emulator(u64, u64, u64, u64); extern struct sal_ret_values sal_emulator (long index, unsigned long in1, unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, unsigned long in6, unsigned long in7); IA64: use symbolic constant for hypercall. define symbolic names for hypercall number and use them. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/dom_fw_asm.S b/xen/arch/ia64/xen/dom_fw_asm.S --- a/xen/arch/ia64/xen/dom_fw_asm.S +++ b/xen/arch/ia64/xen/dom_fw_asm.S @@ -1,3 +1,5 @@ +#include + // moved from xenasm.S to be shared by xen and libxc /* * Assembly support routines for Xen/ia64 @@ -26,14 +28,14 @@ xen_ia64_pal_call_stub: xen_ia64_pal_call_stub: { .mii - addl r2=0x1000,r0 // Hypercall number (Value is patched). + addl r2=FW_HYPERCALL_PAL_CALL_ASM,r0 // Hypercall number (Value is patched). mov r9=256 ;; cmp.gtu p7,p8=r9,r28 /* r32 <= 255? */ } { .mbb - break 0x1000 // Hypercall vector (Value is patched). + break __IA64_XEN_HYPERCALL_DEFAULT // Hypercall vector (Value is patched). (p7) br.cond.sptk.few rp (p8) br.ret.sptk.few rp } diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -561,7 +561,7 @@ int arch_domain_create(struct domain *d, // the following will eventually need to be negotiated dynamically d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR; - d->arch.breakimm = 0x1000; + d->arch.breakimm = __IA64_XEN_HYPERCALL_DEFAULT; for (i = 0; i < NR_CPUS; i++) { d->arch.last_vcpu[i].vcpu_id = INVALID_VCPU_ID; } diff --git a/xen/include/asm-ia64/dom_fw.h b/xen/include/asm-ia64/dom_fw.h --- a/xen/include/asm-ia64/dom_fw.h +++ b/xen/include/asm-ia64/dom_fw.h @@ -4,6 +4,9 @@ * Copyright (C) 2004 Hewlett-Packard Co * Dan Magenheimer ([EMAIL PROTECTED]) */ + +#define __IA64_XEN_HYPERCALL_DEFAULT 0x1000 +#defi
[Xen-ia64-devel] [PATCH 4/5] fix fp fault/trap handler
IA64: fix fp fault/trap handler. This patch is a part of fixes to bug reported as http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 When fpswa handler fails to get a bundle in guest, fp fault/trap should be injected into the guest and let a guest to handle it. When the fpswa library return a error, there is no way to pass the value to the guest. In that case, revert the change and inject the fp fault/trap. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c --- a/xen/arch/ia64/vmx/vmx_fault.c +++ b/xen/arch/ia64/vmx/vmx_fault.c @@ -122,8 +122,7 @@ void vmx_reflect_interruption(u64 ifa, u if (!status) { vcpu_increment_iip(vcpu); return; -} else if (IA64_RETRY == status) -return; +} break; case 33: // IA64_FP_TRAP_VECTOR @@ -133,10 +132,6 @@ void vmx_reflect_interruption(u64 ifa, u status = handle_fpu_swa(0, regs, isr); if (!status) return; -else if (IA64_RETRY == status) { -vcpu_decrement_iip(vcpu); -return; -} break; case 29: // IA64_DEBUG_VECTOR diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -314,11 +314,15 @@ unsigned long unsigned long handle_fpu_swa(int fp_fault, struct pt_regs *regs, unsigned long isr) { - struct vcpu *v = current; IA64_BUNDLE bundle; unsigned long fault_ip; fpswa_ret_t ret; unsigned long rc; + + unsigned long ipsr_save; + unsigned long fpsr_save; + unsigned long pr_save; + struct ia64_fpreg fp_save[6]; fault_ip = regs->cr_iip; /* @@ -344,11 +348,22 @@ handle_fpu_swa(int fp_fault, struct pt_r return IA64_RETRY; } + /* If fpswa returns error, fp falut/trap is reflected and + a guest will call fpswa itself. So we have to revert the effect + to avoid calling fpswa twice. */ + ipsr_save = regs->cr_ipsr; + fpsr_save = regs->ar_fpsr; + pr_save = regs->pr; + memcpy(fp_save, ®s->f6, sizeof(fp_save)); + ret = fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr, ®s->cr_ifs, regs); if (ret.status) { - PSCBX(v, fpswa_ret) = ret; + regs->cr_ipsr = ipsr_save; + regs->ar_fpsr = fpsr_save; + regs->pr = pr_save; + memcpy(®s->f6, fp_save, sizeof(fp_save)); printk("%s(%s): fp_emulate() returned %ld\n", __FUNCTION__, fp_fault ? "fault" : "trap", ret.status); } @@ -688,9 +703,6 @@ ia64_handle_reflection(unsigned long ifa vcpu_increment_iip(v); return; } - // fetch code fail - if (IA64_RETRY == status) - return; printk("ia64_handle_reflection: handling FP fault\n"); vector = IA64_FP_FAULT_VECTOR; break; @@ -698,11 +710,6 @@ ia64_handle_reflection(unsigned long ifa status = handle_fpu_swa(0, regs, isr); if (!status) return; - // fetch code fail - if (IA64_RETRY == status) { - vcpu_decrement_iip(v); - return; - } printk("ia64_handle_reflection: handling FP trap\n"); vector = IA64_FP_TRAP_VECTOR; break; diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -288,7 +288,6 @@ struct arch_vcpu { char irq_new_condition;// vpsr.i/vtpr change, check for pending VHPI char hypercall_continuation; -fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */ struct timer hlt_timer; struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ IA64: fix fp fault/trap handler. This patch is a part of fixes to bug reported as http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 When fpswa handler fails to get a bundle in guest, fp fault/trap should be injected into the guest and let a guest to handle it. When the fpswa library return a error, there is no way to pass the value to the guest. In that case, revert the change and inject the fp fault/trap. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c --- a/xen/arch/ia64/vmx/vmx_fault.c +++ b/xen/arch/ia64/vmx/vmx_fault.c @@ -122,8 +122,7 @@ void vmx_reflect_interruption(u64 ifa, u if (!status) { vcpu_increment_iip(vcpu); return; -} else if (IA64_RETRY == status) -return; +}
[Xen-ia64-devel] [PATCH 2/5] improve handle_fpu_swa()
IA64: improve handle_fpu_swa() It tries to get a bundle in guest. Make it more robust using vmx_get_domain_bundle() instead of __get_domain_bundle(). Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -318,6 +318,7 @@ handle_fpu_swa(int fp_fault, struct pt_r IA64_BUNDLE bundle; unsigned long fault_ip; fpswa_ret_t ret; + unsigned long rc; fault_ip = regs->cr_iip; /* @@ -329,15 +330,18 @@ handle_fpu_swa(int fp_fault, struct pt_r fault_ip -= 16; if (VMX_DOMAIN(current)) { - if (IA64_RETRY == __vmx_get_domain_bundle(fault_ip, &bundle)) - return IA64_RETRY; - } else - bundle = __get_domain_bundle(fault_ip); - - if (!bundle.i64[0] && !bundle.i64[1]) { - printk("%s: floating-point bundle at 0x%lx not mapped\n", - __FUNCTION__, fault_ip); - return -1; + rc = __vmx_get_domain_bundle(fault_ip, &bundle); + } else { + rc = 0; + if (vcpu_get_domain_bundle(current, regs, fault_ip, + &bundle) == 0) + rc = IA64_RETRY; + } + if (rc == IA64_RETRY) { + gdprintk(XENLOG_DEBUG, +"%s(%s): floating-point bundle at 0x%lx not mapped\n", +__FUNCTION__, fp_fault ? "fault" : "trap", fault_ip); + return IA64_RETRY; } ret = fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr, @@ -689,8 +693,10 @@ ia64_handle_reflection(unsigned long ifa if (!status) return; // fetch code fail - if (IA64_RETRY == status) + if (IA64_RETRY == status) { + vcpu_decrement_iip(v); return; + } printk("ia64_handle_reflection: handling FP trap\n"); vector = IA64_FP_TRAP_VECTOR; break; diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -1355,6 +1355,26 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS // copy its value to the variable, tr, before use. TR_ENTRY tr; + // fast path: + // try to access gip with guest virtual address directly. + // This may cause tlb miss. see vcpu_translate(). Be careful! + swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode)); + if (swap_rr0) { + set_virtual_rr0(); + } + *bundle = __get_domain_bundle(gip); + if (swap_rr0) { + set_metaphysical_rr0(); + } + + if (!bundle->i64[0] && !bundle->i64[1]) { + dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip); + } else { + // Okay, mDTC successed + return 1; + } + // mDTC failed, so try vTLB. + trp = vcpu_tr_lookup(vcpu, gip, rid, 0); if (trp != NULL) { tr = *trp; @@ -1374,28 +1394,13 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS tr = *trp; goto found; } -#if 0 tr = PSCBX(vcpu, dtlb); if (vcpu_match_tr_entry(&tr, gip, rid)) { goto found; } -#endif - // try to access gip with guest virtual address - // This may cause tlb miss. see vcpu_translate(). Be careful! - swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode)); - if (swap_rr0) { - set_virtual_rr0(); - } - *bundle = __get_domain_bundle(gip); - if (swap_rr0) { - set_metaphysical_rr0(); - } - if (bundle->i64[0] == 0 && bundle->i64[1] == 0) { - dprintk(XENLOG_INFO, "%s gip 0x%lx\n", __func__, gip); - return 0; - } - return 1; + // mDTC and vTLB failed. so reflect tlb miss into the guest. + return 0; found: gpip = ((tr.pte.ppn >> (tr.ps - 12)) << tr.ps) | IA64: improve handle_fpu_swa() It tries to get a bundle in guest. Make it more robust using vmx_get_domain_bundle() instead of __get_domain_bundle(). Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -318,6 +318,7 @@ handle_fpu_swa(int fp_fault
[Xen-ia64-devel] [PATCH 5/5] fix efi_emulate_set_virtual_address_map()
IA64: fix efi_emulate_set_virtual_address_map() get_page() before touching guest pages. Otherwise pages may be freed during those operations. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/fw_emul.c b/xen/arch/ia64/xen/fw_emul.c --- a/xen/arch/ia64/xen/fw_emul.c +++ b/xen/arch/ia64/xen/fw_emul.c @@ -1334,6 +1334,10 @@ efi_emulate_set_virtual_address_map( efi_desc_size = sizeof(efi_memory_desc_t); for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + struct page_info *efi_runtime_page = NULL; + struct page_info *fpswa_inf_page = NULL; + struct page_info *fw_table_page = NULL; + if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) { printk ("efi_emulate_set_virtual_address_map: copy_from_user() fault. addr=0x%p\n", p); return EFI_UNSUPPORTED; @@ -1342,6 +1346,27 @@ efi_emulate_set_virtual_address_map( /* skip over non-PAL_CODE memory descriptors; EFI_RUNTIME is included in PAL_CODE. */ if (md->type != EFI_PAL_CODE) continue; + + /* get pages to prevend them from being freed +* during touching them. +* those entres are in [FW_TABLES_BASE_PADDR, ...] +* see dom_fw.h for its layout. +*/ + efi_runtime_page = virt_to_page(efi_runtime); + fpswa_inf_page = virt_to_page(fpswa_inf); + fw_table_page = virt_to_page( + domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR)); + if (get_page(efi_runtime_page, d) == 0) + return EFI_INVALID_PARAMETER; + if (get_page(fpswa_inf_page, d) == 0) { + put_page(efi_runtime_page); + return EFI_INVALID_PARAMETER; + } + if (get_page(fw_table_page, d) == 0) { + put_page(fpswa_inf_page); + put_page(efi_runtime_page); + return EFI_INVALID_PARAMETER; + } #define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \ do { \ @@ -1365,6 +1390,10 @@ efi_emulate_set_virtual_address_map( *vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr; *vfn = 0; fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 16UL + md->virt_addr); + + put_page(fw_table_page); + put_page(fpswa_inf_page); + put_page(efi_runtime_page); break; } IA64: fix efi_emulate_set_virtual_address_map() get_page() before touching guest pages. Otherwise pages may be freed during those operations. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/fw_emul.c b/xen/arch/ia64/xen/fw_emul.c --- a/xen/arch/ia64/xen/fw_emul.c +++ b/xen/arch/ia64/xen/fw_emul.c @@ -1334,6 +1334,10 @@ efi_emulate_set_virtual_address_map( efi_desc_size = sizeof(efi_memory_desc_t); for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + struct page_info *efi_runtime_page = NULL; + struct page_info *fpswa_inf_page = NULL; + struct page_info *fw_table_page = NULL; + if (copy_from_user(&entry, p, sizeof(efi_memory_desc_t))) { printk ("efi_emulate_set_virtual_address_map: copy_from_user() fault. addr=0x%p\n", p); return EFI_UNSUPPORTED; @@ -1342,6 +1346,27 @@ efi_emulate_set_virtual_address_map( /* skip over non-PAL_CODE memory descriptors; EFI_RUNTIME is included in PAL_CODE. */ if (md->type != EFI_PAL_CODE) continue; + + /* get pages to prevend them from being freed + * during touching them. + * those entres are in [FW_TABLES_BASE_PADDR, ...] + * see dom_fw.h for its layout. + */ + efi_runtime_page = virt_to_page(efi_runtime); + fpswa_inf_page = virt_to_page(fpswa_inf); + fw_table_page = virt_to_page( + domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR)); + if (get_page(efi_runtime_page, d) == 0) + return EFI_INVALID_PARAMETER; + if (get_page(fpswa_inf_page, d) == 0) { + put_page(efi_runtime_page); + return EFI_INVALID_PARAMETER; + } + if (get_page(fw_table_page, d) == 0) { + put_page(fpswa_inf_page); + put_page(efi_runtime_page); + return EFI_INVALID_PARAMETER; + } #define EFI_HYPERCALL_PATCH_TO_VIRT(tgt,call) \ do { \ @@ -1365,6 +1390,10 @@ efi_emulate_set_virtual_address_map( *vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr; *vfn = 0; fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 16UL + md->virt_addr); + + put_page(fw_table_page); + put_page(fpswa_inf_page); + put_page(efi_runtime_page); break; } ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
[Xen-ia64-devel] [PATCH 3/5] fix fp emulation
IA64: fix emulation of fp emulation in pv domain This patch is a part of fixes to bug reported as http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 When vmm fails to get a bundle in a question during fpswa processing, there is no way, but a guest provides the bundle. On the other hand the current implementation just returns random value. This patch make the fpswa hypercall calling convention complicated and pass necessary informations to the hypervisor. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/vmx/vmx_fault.c b/xen/arch/ia64/vmx/vmx_fault.c --- a/xen/arch/ia64/vmx/vmx_fault.c +++ b/xen/arch/ia64/vmx/vmx_fault.c @@ -74,7 +74,14 @@ static const u16 vec2off[68] = {0x0,0x40 0x7f00 }; - +void vmx_lazy_load_fpu(struct vcpu *vcpu) +{ +if (FP_PSR(vcpu) & IA64_PSR_DFH) { +FP_PSR(vcpu) = IA64_PSR_MFH; +if (__ia64_per_cpu_var(fp_owner) != vcpu) +__ia64_load_fpu(vcpu->arch._thread.fph); +} +} void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim, u64 vec, REGS *regs) @@ -98,11 +105,7 @@ void vmx_reflect_interruption(u64 ifa, u case 25: // IA64_DISABLED_FPREG_VECTOR if (!(vpsr & IA64_PSR_IC)) goto nested_fault; -if (FP_PSR(vcpu) & IA64_PSR_DFH) { -FP_PSR(vcpu) = IA64_PSR_MFH; -if (__ia64_per_cpu_var(fp_owner) != vcpu) -__ia64_load_fpu(vcpu->arch._thread.fph); -} +vmx_lazy_load_fpu(vcpu); if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) { regs->cr_ipsr &= ~IA64_PSR_DFH; return; diff --git a/xen/arch/ia64/xen/dom_fw_common.c b/xen/arch/ia64/xen/dom_fw_common.c --- a/xen/arch/ia64/xen/dom_fw_common.c +++ b/xen/arch/ia64/xen/dom_fw_common.c @@ -142,6 +142,117 @@ build_pal_hypercall_bundles(uint64_t *im ia64_fc(imva + 3); } +/* xen fpswa call stub. 14 bundles */ +extern const unsigned long xen_ia64_fpswa_call_stub[]; +extern const unsigned long xen_ia64_fpswa_call_stub_end[]; +extern const unsigned long xen_ia64_fpswa_call_stub_patch[]; +asm( + ".align 32\n" + ".proc xen_ia64_fpswa_call_stub;\n" + "xen_ia64_fpswa_call_stub:\n" + ".prologue\n" + "alloc r3 = ar.pfs, 8, 0, 0, 0\n" + ".body\n" + "mov r14 = in0\n" + "ld8 r15 = [in1], 8\n" + ";;\n" + "ld8 r16 = [in1]\n" + "ld8 r17 = [in2]\n" + "ld8 r18 = [in3]\n" + "ld8 r19 = [in4]\n" + "ld8 r20 = [in5]\n" + "ld8 r21 = [in6]\n" + "ld8 r22 = [in7], 8\n" + ";;\n" + "ld8 r23 = [in7], 8\n" + ";;\n" + "ld8 r24 = [in7], 8\n" + ";;\n" + "cmp.ne p6, p0 = r24, r0\n" + "ld8 r25 = [in7], 8\n" + ";;\n" + "(p6) tpa r24 = r24\n" + "cmp.ne p7, p0 = r25, r0\n" + "ld8 r26 = [in7], 8\n" + ";;\n" + "(p7)tpa r25 = r25\n" + "cmp.ne p8, p0 = r26, r0\n" + "ld8 r27 = [in7], 8\n" + ";;\n" + "(p8)tpa r26 = r26\n" + "cmp.ne p9, p0 = r27, r0\n" + ";;\n" + "tpa r27 = r27\n" + "xen_ia64_fpswa_call_stub_patch:" + "{\n" + "mov r2 = " FW_HYPERCALL_FPSWA_STR "\n" + "break " __IA64_XEN_HYPERCALL_DEFAULT_STR "\n" + "nop.i 0\n" + "}\n" + "st8 [in2] = r17\n" + "st8 [in3] = r18\n" + "st8 [in4] = r19\n" + "st8 [in5] = r20\n" + "st8 [in6] = r21\n" + "br.ret.sptk.many rp\n" + "xen_ia64_fpswa_call_stub_end:" + ".endp xen_ia64_fpswa_call_stub\n" +); + +static void +build_fpswa_hypercall_bundle(uint64_t *imva, uint64_t brkimm, uint64_t hypnum) +{ + INST64_A5 slot0; + INST64_I19 slot1; + INST64_I18 slot2; + IA64_BUNDLE bundle; + + /* slot0: mov r2 = hypnum (low 20 bits) */ + slot0.inst = 0; + slot0.qp = 0; + slot0.r1 = 2; + slot0.r3 = 0; + slot0.major = 0x9; + + slot0.s = 0; + slot0.imm9d = hypnum >> 7; + slot0.imm5c = hypnum >> 16; + slot0.imm7b = hypnum; + + /* slot1: break brkimm */ + slot1.inst = 0; + slot1.qp = 0; + slot1.x6 = 0; + slot1.x3 = 0; + slot1.major = 0x0; + slot1.i = brkimm >> 20; + slot1.imm20 = brkimm; + + /* slot2: nop.i */ + slot2.inst = 0; + slot2.qp = 0; + slot2.imm20 = 0; + slot2.y = 0; + slot2.x6 = 1; + slot2.x3 = 0; + slot2.i = 0; + slot2.major = 0; + + /* MII bundle */ + bundle.i64[0] = 0; + bundle.i64[1] = 0; + bundle.template = 0x0; /* MII */ + bundle.slot0 = slot0.inst; + bundle.slot1a = slot1.inst; + bundle.slot1b = slot1.inst >> 18; + bundle.slot2 = slot2.inst; + + imva[0] = bundle.i64[0]; + imva[1] = bundle.i64[1]; + ia64_fc(imva); + ia64_fc(imva + 1); +} + // builds a hypercall bundle at domain physical address static void dom_fpswa_hypercall_patch(uint64_t brkimm, unsigned long
RE: [Xen-ia64-devel] [Test Report] Xen/IPF Unstable CS#18860 Status --- Dom0 Crash
On Monday, December 08, 2008 2:10 PM, "Isaku Yamahata" wrote: > On Mon, Dec 08, 2008 at 01:52:38PM +0800, Zhang, Jingke wrote: >> Isaku Yamahata wrote: >>> On Mon, Dec 08, 2008 at 11:31:15AM +0800, Zhang, Jingke wrote: Hi Isaku, We re-get the detail information from serial port, please see below. Two comments add: >>> >>> Thank you. >>> >>> 1. We can be sure the Cset#18832 works well on the same tiger4 machine. But we did not do regression test between 18832 and this 18860. 2. It is strange that on another Tiger4 box, dom0 will NOT crash. Do you have any idea from the serial log? Thanks! >>> >>> I haven't hit this crash. And Kuwamura-san's test seems that >>> he haven't hit it either. Kuwamura-san, is it correct? >>> Hmm... it seems to depend on hw configuration? >>> I'm inclined to suspect masking/unmasking interruption race. >>> event channel issues? But that's just only my very vague guess. >>> >>> The difference between 18832 and 18860 means the merging >>> xen-unstable into xen-ia64-unstable. Looking the log, I suspect >>> linux-2.6.18-xen instead of xen. >>> Could you provide the linux c/s which corresponds to 18832 and >>> 18860? >> >> >> Hi Isaku, >> Yes, some of our machines do not crash. I am afraid there may be >> some potential issue. By testing 18832, we use linux#742. While >> 18860 uses linux#753. Thanks! > > Thank you. Taking rough look at them those change sets doesn't > seem culprit. > I agree with you that this may indicate some potential bugs... Hi All, This bug is stably reproduced, if providing "dom0_mem=2048M" in append option. And if setting dom0_mem to 1024M or 4096M, the crashing doesn't happen. We tried #18869 Xen + #742 Dom0, system is okay. So the problem might be in Linux tree between #742~#753 Best Regards, Yongkang You ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
[Xen-ia64-devel] Re: [PATCH 0/5] fix fpswa and related issues.
On Tue, 2008-12-09 at 18:29 +0900, Isaku Yamahata wrote: > Hi. This patch series addresses the bug reported as > http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 > Please test it. > > It includes some clean ups and a reimplementation of fpswa hypercall. > When fp fault/trap occurs, xen vmm tries to get a bundle in question > from guest virtual address space. It sometimes fails because of > I/D tlb cache. In that case inject the fault/trap into a guest > and let a guest to call fpswa hypercall. Hi Isaku, I've been testing this for a few hours today (over 25k iterations) and it seems to fix the problem for me. Thanks! Alex -- Alex Williamson HP Open Source & Linux Org. ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
[Xen-ia64-devel] RE: [PATCH 0/5] fix fpswa and related issues.
Alex Williamson wrote: > On Tue, 2008-12-09 at 18:29 +0900, Isaku Yamahata wrote: >> Hi. This patch series addresses the bug reported as >> http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 >> Please test it. >> >> It includes some clean ups and a reimplementation of fpswa hypercall. >> When fp fault/trap occurs, xen vmm tries to get a bundle in question >> from guest virtual address space. It sometimes fails because of >> I/D tlb cache. In that case inject the fault/trap into a guest >> and let a guest to call fpswa hypercall. > > Hi Isaku, > > I've been testing this for a few hours today (over 25k iterations) and > it seems to fix the problem for me. Thanks! Hi, Alex Have you verified vmx domain as well ? Xiantao ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
[Xen-ia64-devel] RE: [PATCH 0/5] fix fpswa and related issues.
On Wed, 2008-12-10 at 10:51 +0800, Zhang, Xiantao wrote: > > I've been testing this for a few hours today (over 25k iterations) > and > > it seems to fix the problem for me. Thanks! > > Hi, Alex > Have you verified vmx domain as well ? Good point, no I was just testing in dom0. Alex -- Alex Williamson HP Open Source & Linux Org. ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] [Fwd: [Xen-bugs] [Bug 1392] New: Problems with denormalized floating point numbers on XEN-virtualized Linux/IA64]
On Sat, Dec 06, 2008 at 11:10:22AM +0800, Zhang, Xiantao wrote: > > If we fail to get a bundle in a guest when FP trap, > > we can't reexecute the instruction. We have to inject floating > > point trap into guest. > > For HVM, injecting it to guest should be the right way to go. Another issue. When fpswa library in xen VMM returns status > 0, what should we do for PV/HVM domain? I suppose this case hasn't been tested. The current implementation just inject FP trap/fault into guest, and guest calls fpswa itself. In such a case, fpswa is called twice. I tried to revert the effect of fpswa library call with the new patch series, but it wasn't enough. In order to revert the effect, all the fp register must be saved before the call. It would impose unacceptable performance overhead. Some considerations: - let fpswa library be called twice. Is it safe to call fpswa library twice? If this answer is yes, this option can be taken. However I'm not sure. the specification[1] doesn't tell much. Looking at the linux trap handler, might it be sufficent for fpswa to return error > 0 on the second call? [1] "Itanium Processor floating-point software assistance and floating-point exception handling." - Ignore this issue. Are there any applications which depend on SIGFPE process signal? If no, we might be able to ignore this case. On native Linux, SIGPFE is delivered to the process when fpswa returns status > 0. If there is no application to use SIGPFE to recover its computation, we might be able to ignore this issue (until an unfortunate application developers complains). - save the result of fpswa call in xen VMM and return the value when fpswa hypercall is issued assuming the guest kernel is none preemptive. This is only for PV domain. The first thing which comes into my mind is that the guest kernel might be preemptive. The previous implementation (before my patch) assumes that the PV guest kernel is none preemptive, and it calls fpswa library call right after the fp fault/trap. So it saves the result of fpswa call in Xen VMM and returned the return values. The Linux fp fault/trap handler assumes not to be preempted between fault/trap occurrence and fpswa library call because it uses processor's f2-f5, f12-f127. As for HVM domain case, guest firmware uses its own fpswa library, the call isn't hooked to Xen VMM. So this isn't an option for HVM domain. - abandon to handle fp trap/fault in Xen VMM. Always inject the fp trap/fault into a guest without calling fpswa library in Xen VMM. This should work and the implementation would become simple. But how about performance? thanks, -- yamahata ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] RE: [PATCH 0/5] fix fpswa and related issues.
On Tue, Dec 09, 2008 at 09:23:01PM -0700, Alex Williamson wrote: > On Wed, 2008-12-10 at 10:51 +0800, Zhang, Xiantao wrote: > > > I've been testing this for a few hours today (over 25k iterations) > > and > > > it seems to fix the problem for me. Thanks! > > > > Hi, Alex > > Have you verified vmx domain as well ? > > Good point, no I was just testing in dom0. You may want to test with two PV guest because of eager safe/lazy restore fp. I wrote the code to address it, but it hasn't been tested very well. -- yamahata ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] [PATCH 0/5] fix fpswa and related issues.
On Tue, Dec 09, 2008 at 06:29:41PM +0900, Isaku Yamahata wrote: > > Hi. This patch series addresses the bug reported as > http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1392 > Please test it. > > It includes some clean ups and a reimplementation of fpswa hypercall. > When fp fault/trap occurs, xen vmm tries to get a bundle in question > from guest virtual address space. It sometimes fails because of > I/D tlb cache. In that case inject the fault/trap into a guest > and let a guest to call fpswa hypercall. > > thanks > > ___ > Xen-ia64-devel mailing list > Xen-ia64-devel@lists.xensource.com > http://lists.xensource.com/xen-ia64-devel > I'd like to add one more patch. It seems to take a while to address the case that fpswa returns status > 0. So keep the previous behavior in such cases for now. IA64: make the fpswa emulation keep the previous behaviour. When fpswa library return statue > 0, keep the previous behavior. This case should be addressed somehow later, but it seems somewhat difficult to resolve, so keep the previous behavor for now. Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]> diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -319,11 +319,6 @@ handle_fpu_swa(int fp_fault, struct pt_r fpswa_ret_t ret; unsigned long rc; - unsigned long ipsr_save; - unsigned long fpsr_save; - unsigned long pr_save; - struct ia64_fpreg fp_save[6]; - fault_ip = regs->cr_iip; /* * When the FP trap occurs, the trapping instruction is completed. @@ -342,28 +337,18 @@ handle_fpu_swa(int fp_fault, struct pt_r rc = IA64_RETRY; } if (rc == IA64_RETRY) { + PSCBX(v, fpswa_ret) = (fpswa_ret_t){IA64_RETRY, 0, 0, 0}; gdprintk(XENLOG_DEBUG, "%s(%s): floating-point bundle at 0x%lx not mapped\n", __FUNCTION__, fp_fault ? "fault" : "trap", fault_ip); return IA64_RETRY; } - /* If fpswa returns error, fp falut/trap is reflected and - a guest will call fpswa itself. So we have to revert the effect - to avoid calling fpswa twice. */ - ipsr_save = regs->cr_ipsr; - fpsr_save = regs->ar_fpsr; - pr_save = regs->pr; - memcpy(fp_save, ®s->f6, sizeof(fp_save)); - ret = fp_emulate(fp_fault, &bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr, ®s->cr_ifs, regs); if (ret.status) { - regs->cr_ipsr = ipsr_save; - regs->ar_fpsr = fpsr_save; - regs->pr = pr_save; - memcpy(®s->f6, fp_save, sizeof(fp_save)); + PSCBX(v, fpswa_ret) = ret; printk("%s(%s): fp_emulate() returned %ld\n", __FUNCTION__, fp_fault ? "fault" : "trap", ret.status); } diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -164,6 +164,13 @@ fw_hypercall_fpswa (struct vcpu *v, stru struct page_info *hp_page = NULL; struct page_info *hv_page = NULL; XEN_EFI_RR_DECLARE(rr6, rr7); + + if (unlikely(PSCBX(v, fpswa_ret).status != 0 && +PSCBX(v, fpswa_ret).status != IA64_RETRY)) { + ret = PSCBX(v, fpswa_ret); + PSCBX(v, fpswa_ret) = (fpswa_ret_t){0, 0, 0, 0}; + return ret; + } if (!fpswa_interface) goto error; diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -288,6 +288,7 @@ struct arch_vcpu { char irq_new_condition;// vpsr.i/vtpr change, check for pending VHPI char hypercall_continuation; +fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */ struct timer hlt_timer; struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ -- yamahata ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel