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@xxxxxxxxxxxxxxxxxxx
> 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 <yamahata@xxxxxxxxxxxxx>
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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|