IA64: make the fpswa emulation keep the previous behaviour.
authorIsaku Yamahata <yamahata@valinux.co.jp>
Fri, 12 Dec 2008 01:35:58 +0000 (10:35 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Fri, 12 Dec 2008 01:35:58 +0000 (10:35 +0900)
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.
It is assumed that a guest kernel calls fpswa library
without preemption. This assumption breaks if a guest kernel is
preemptive.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/ia64/xen/faults.c
xen/arch/ia64/xen/hypercall.c
xen/include/asm-ia64/domain.h

index d1327e8681e3387d563a0bf2b80c87cc467422cd..7aec52d3b0c07e0cbd33510f9c1018fcb20d130d 100644 (file)
@@ -337,6 +337,7 @@ handle_fpu_swa(int fp_fault, struct pt_regs *regs, unsigned long isr)
                        rc = IA64_RETRY;
        }
        if (rc == IA64_RETRY) {
+               PSCBX(current, 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);
@@ -347,6 +348,7 @@ handle_fpu_swa(int fp_fault, struct pt_regs *regs, unsigned long isr)
                         &isr, &regs->pr, &regs->cr_ifs, regs);
 
        if (ret.status) {
+               PSCBX(current, fpswa_ret) = ret;
                printk("%s(%s): fp_emulate() returned %ld\n",
                       __FUNCTION__, fp_fault ? "fault" : "trap", ret.status);
        }
index 0ae317e96e0d4b428c9a2c84a602119e3315d84f..f727729746357d6d8e1a5edec95db1c23c73dd6b 100644 (file)
@@ -165,6 +165,13 @@ fw_hypercall_fpswa (struct vcpu *v, struct pt_regs *regs)
        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;
 
index 2c9f21f0896d56f93b3e33f7a199a53b9ab41617..f04ed5b7901d3dd4e709adc8fd0f2792d721abea 100644 (file)
@@ -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 */