WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [IA64] Implement eager save, lazy restore

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] Implement eager save, lazy restore FP algorithm
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 09 Feb 2007 09:40:16 -0800
Delivery-date: Fri, 09 Feb 2007 09:45:57 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1169574727 25200
# Node ID d12ea0bfecce0aa5b62a9441185330b601487838
# Parent  8bfc6e85eeba6b79ffc8d1f1f8d7049afeed1e88
[IA64] Implement eager save, lazy restore FP algorithm

Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/asm-offsets.c                 |    1 
 xen/arch/ia64/asm-xsi-offsets.c             |    2 
 xen/arch/ia64/vmx/optvfault.S               |   15 +++
 xen/arch/ia64/vmx/vmx_process.c             |   66 +++++++++-----
 xen/arch/ia64/vmx/vmx_vcpu.c                |    3 
 xen/arch/ia64/xen/domain.c                  |  131 +++++++++++++++++-----------
 xen/arch/ia64/xen/faults.c                  |   20 ++++
 xen/arch/ia64/xen/hyperprivop.S             |   39 ++++++++
 xen/arch/ia64/xen/vcpu.c                    |   33 ++++++-
 xen/include/asm-ia64/domain.h               |    1 
 xen/include/asm-ia64/linux-xen/asm/percpu.h |    5 +
 xen/include/asm-ia64/vcpu.h                 |    1 
 xen/include/public/arch-ia64.h              |    4 
 13 files changed, 245 insertions(+), 76 deletions(-)

diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/asm-offsets.c       Tue Jan 23 10:52:07 2007 -0700
@@ -57,6 +57,7 @@ void foo(void)
 
        DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain));
        DEFINE(IA64_VCPU_HYPERCALL_CONTINUATION_OFS, offsetof (struct vcpu, 
arch.hypercall_continuation));
+       DEFINE(IA64_VCPU_FP_PSR_OFFSET, offsetof (struct vcpu, arch.fp_psr));
        DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu, 
arch.metaphysical_rr0));
        DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, 
arch.metaphysical_saved_rr0));
        DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, 
arch.breakimm));
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/asm-xsi-offsets.c
--- a/xen/arch/ia64/asm-xsi-offsets.c   Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/asm-xsi-offsets.c   Tue Jan 23 10:52:07 2007 -0700
@@ -61,6 +61,8 @@ void foo(void)
        DEFINE_MAPPED_REG_OFS(XSI_ITIR_OFS, itir);
        DEFINE_MAPPED_REG_OFS(XSI_ITV_OFS, itv);
        DEFINE_MAPPED_REG_OFS(XSI_PTA_OFS, pta);
+       DEFINE_MAPPED_REG_OFS(XSI_VPSR_DFH_OFS, vpsr_dfh);
+       DEFINE_MAPPED_REG_OFS(XSI_HPSR_DFH_OFS, hpsr_dfh);
        DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled);
        DEFINE_MAPPED_REG_OFS(XSI_VPSR_PP_OFS, vpsr_pp);
        DEFINE_MAPPED_REG_OFS(XSI_METAPHYS_OFS, metaphysical_mode);
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/vmx/optvfault.S
--- a/xen/arch/ia64/vmx/optvfault.S     Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/vmx/optvfault.S     Tue Jan 23 10:52:07 2007 -0700
@@ -192,6 +192,13 @@ GLOBAL_ENTRY(vmx_asm_rsm)
     ;;   
     st8 [r17]=r19
     and r20=r20,r28
+    adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
+    ;;
+    ld8 r27=[r27]
+    ;;
+    tbit.nz p8,p0= r27,IA64_PSR_DFH_BIT
+    ;;
+    (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
     ;;
     mov cr.ipsr=r20
     tbit.nz p6,p0=r23,0
@@ -359,6 +366,14 @@ vmx_asm_mov_to_psr_1:
     ;;
     add r20=r19,r20
     mov b0=r24
+    ;;
+    adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
+    ;;
+    ld8 r27=[r27]
+    ;;
+    tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT
+    ;;
+    (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
     ;;
     mov cr.ipsr=r20
     cmp.ne p6,p0=r0,r0
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/vmx/vmx_process.c   Tue Jan 23 10:52:07 2007 -0700
@@ -79,36 +79,56 @@ static u64 vec2off[68] = {0x0,0x400,0x80
 
 
 void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim,
-                              u64 vector, REGS *regs)
-{
-    u64 status;
+                              u64 vec, REGS *regs)
+{
+    u64 status, vector;
     VCPU *vcpu = current;
     u64 vpsr = VCPU(vcpu, vpsr);
-    vector=vec2off[vector];
+    
+    vector = vec2off[vec];
     if(!(vpsr&IA64_PSR_IC)&&(vector!=IA64_DATA_NESTED_TLB_VECTOR)){
         panic_domain(regs, "Guest nested fault vector=%lx!\n", vector);
     }
-    else{ // handle fpswa emulation
+
+    switch (vec) {
+
+    case 25:   // IA64_DISABLED_FPREG_VECTOR
+
+        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);
+        }
+        if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) {
+            regs->cr_ipsr &= ~IA64_PSR_DFH;
+            return;
+        }
+
+        break;       
+        
+    case 32:   // IA64_FP_FAULT_VECTOR
+        // handle fpswa emulation
         // fp fault
-        if (vector == IA64_FP_FAULT_VECTOR) {
-            status = handle_fpu_swa(1, regs, isr);
-            if (!status) {
-                vcpu_increment_iip(vcpu);
-                return;
-            } else if (IA64_RETRY == status)
-                return;
-        }
+        status = handle_fpu_swa(1, regs, isr);
+        if (!status) {
+            vcpu_increment_iip(vcpu);
+            return;
+        } else if (IA64_RETRY == status)
+            return;
+        break;
+
+    case 33:   // IA64_FP_TRAP_VECTOR
         //fp trap
-        else if (vector == IA64_FP_TRAP_VECTOR) {
-            status = handle_fpu_swa(0, regs, isr);
-            if (!status)
-                return;
-            else if (IA64_RETRY == status) {
-                vcpu_decrement_iip(vcpu);
-                return;
-            }
-        }
-    }
+        status = handle_fpu_swa(0, regs, isr);
+        if (!status)
+            return;
+        else if (IA64_RETRY == status) {
+            vcpu_decrement_iip(vcpu);
+            return;
+        }
+        break;
+    
+    } 
     VCPU(vcpu,isr)=isr;
     VCPU(vcpu,iipa) = regs->cr_iip;
     if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/vmx/vmx_vcpu.c
--- a/xen/arch/ia64/vmx/vmx_vcpu.c      Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/vmx/vmx_vcpu.c      Tue Jan 23 10:52:07 2007 -0700
@@ -140,6 +140,9 @@ vmx_vcpu_set_psr(VCPU *vcpu, unsigned lo
         IA64_PSR_VM;
 
     regs->cr_ipsr = (regs->cr_ipsr & mask ) | ( value & (~mask) );
+
+    if (FP_PSR(vcpu) & IA64_PSR_DFH)
+        regs->cr_ipsr |= IA64_PSR_DFH;
 
     check_mm_mode_switch(vcpu, old_psr, new_psr);
     return ;
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/xen/domain.c        Tue Jan 23 10:52:07 2007 -0700
@@ -68,6 +68,8 @@ DEFINE_PER_CPU(uint8_t *, current_psr_i_
 DEFINE_PER_CPU(uint8_t *, current_psr_i_addr);
 DEFINE_PER_CPU(int *, current_psr_ic_addr);
 
+DEFINE_PER_CPU(struct vcpu *, fp_owner);
+
 #include <xen/sched-if.h>
 
 static void
@@ -135,12 +137,44 @@ static void flush_vtlb_for_context_switc
        }
 }
 
+static void lazy_fp_switch(struct vcpu *prev, struct vcpu *next)
+{
+       /*
+        * Implement eager save, lazy restore
+        */
+       if (!is_idle_vcpu(prev)) {
+               if (VMX_DOMAIN(prev)) {
+                       if (FP_PSR(prev) & IA64_PSR_MFH) {
+                               __ia64_save_fpu(prev->arch._thread.fph);
+                               __ia64_per_cpu_var(fp_owner) = prev;
+                       }
+               } else {
+                       if (PSCB(prev, hpsr_mfh)) {
+                               __ia64_save_fpu(prev->arch._thread.fph);
+                               __ia64_per_cpu_var(fp_owner) = prev;
+                       }
+               }
+       }
+
+       if (!is_idle_vcpu(next)) {
+               if (VMX_DOMAIN(next)) {
+                       FP_PSR(next) = IA64_PSR_DFH;
+                       vcpu_regs(next)->cr_ipsr |= IA64_PSR_DFH;
+               } else {
+                       PSCB(next, hpsr_dfh) = 1;
+                       PSCB(next, hpsr_mfh) = 0;
+                       vcpu_regs(next)->cr_ipsr |= IA64_PSR_DFH;
+               }
+       }
+}
+
 void schedule_tail(struct vcpu *prev)
 {
        extern char ia64_ivt;
+
        context_saved(prev);
-
        ia64_disable_vhpt_walker();
+
        if (VMX_DOMAIN(current)) {
                vmx_do_launch(current);
                migrate_timer(&current->arch.arch_vmx.vtm.vtm_timer,
@@ -148,7 +182,7 @@ void schedule_tail(struct vcpu *prev)
        } else {
                ia64_set_iva(&ia64_ivt);
                load_region_regs(current);
-               ia64_set_pta(vcpu_pta(current));
+               ia64_set_pta(vcpu_pta(current));
                vcpu_load_kernel_regs(current);
                __ia64_per_cpu_var(current_psr_i_addr) = &current->domain->
                  shared_info->vcpu_info[current->vcpu_id].evtchn_upcall_mask;
@@ -165,64 +199,67 @@ void context_switch(struct vcpu *prev, s
 
     local_irq_save(spsr);
 
-    if (!is_idle_domain(prev->domain)) 
-        __ia64_save_fpu(prev->arch._thread.fph);
-    if (!is_idle_domain(next->domain)) 
-        __ia64_load_fpu(next->arch._thread.fph);
-
     if (VMX_DOMAIN(prev)) {
-       vmx_save_state(prev);
-       if (!VMX_DOMAIN(next)) {
-           /* VMX domains can change the physical cr.dcr.
-            * Restore default to prevent leakage. */
-           ia64_setreg(_IA64_REG_CR_DCR, (IA64_DCR_DP | IA64_DCR_DK
-                          | IA64_DCR_DX | IA64_DCR_DR | IA64_DCR_PP
-                          | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
-       }
+        vmx_save_state(prev);
+        if (!VMX_DOMAIN(next)) {
+            /* VMX domains can change the physical cr.dcr.
+             * Restore default to prevent leakage. */
+            ia64_setreg(_IA64_REG_CR_DCR, (IA64_DCR_DP | IA64_DCR_DK
+                           | IA64_DCR_DX | IA64_DCR_DR | IA64_DCR_PP
+                           | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
+        }
     }
     if (VMX_DOMAIN(next))
-       vmx_load_state(next);
+        vmx_load_state(next);
 
     ia64_disable_vhpt_walker();
-    /*ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next);*/
+    lazy_fp_switch(prev, current);
+
     prev = ia64_switch_to(next);
 
     /* Note: ia64_switch_to does not return here at vcpu initialization.  */
 
-    //cpu_set(smp_processor_id(), current->domain->domain_dirty_cpumask);
- 
-    if (VMX_DOMAIN(current)){
-       vmx_load_all_rr(current);
-       migrate_timer(&current->arch.arch_vmx.vtm.vtm_timer,
-                     current->processor);
+    if (VMX_DOMAIN(current)) {
+        vmx_load_all_rr(current);
+        migrate_timer(&current->arch.arch_vmx.vtm.vtm_timer,
+                      current->processor);
     } else {
-       struct domain *nd;
-       extern char ia64_ivt;
-
-       ia64_set_iva(&ia64_ivt);
-
-       nd = current->domain;
-       if (!is_idle_domain(nd)) {
-               load_region_regs(current);
-               ia64_set_pta(vcpu_pta(current));
-               vcpu_load_kernel_regs(current);
-               vcpu_set_next_timer(current);
-               if (vcpu_timer_expired(current))
-                       vcpu_pend_timer(current);
-               __ia64_per_cpu_var(current_psr_i_addr) = &nd->shared_info->
-                 vcpu_info[current->vcpu_id].evtchn_upcall_mask;
-               __ia64_per_cpu_var(current_psr_ic_addr) =
-                 (int *)(nd->arch.shared_info_va + XSI_PSR_IC_OFS);
-       } else {
-               /* When switching to idle domain, only need to disable vhpt
-                * walker. Then all accesses happen within idle context will
-                * be handled by TR mapping and identity mapping.
-                */
-               __ia64_per_cpu_var(current_psr_i_addr) = NULL;
-               __ia64_per_cpu_var(current_psr_ic_addr) = NULL;
+        struct domain *nd;
+        extern char ia64_ivt;
+
+        ia64_set_iva(&ia64_ivt);
+
+        nd = current->domain;
+        if (!is_idle_domain(nd)) {
+            load_region_regs(current);
+            ia64_set_pta(vcpu_pta(current));
+            vcpu_load_kernel_regs(current);
+            vcpu_set_next_timer(current);
+            if (vcpu_timer_expired(current))
+                vcpu_pend_timer(current);
+            __ia64_per_cpu_var(current_psr_i_addr) = &nd->shared_info->
+                vcpu_info[current->vcpu_id].evtchn_upcall_mask;
+            __ia64_per_cpu_var(current_psr_ic_addr) =
+                (int *)(nd->arch.shared_info_va + XSI_PSR_IC_OFS);
+        } else {
+            /* When switching to idle domain, only need to disable vhpt
+             * walker. Then all accesses happen within idle context will
+             * be handled by TR mapping and identity mapping.
+             */
+            __ia64_per_cpu_var(current_psr_i_addr) = NULL;
+            __ia64_per_cpu_var(current_psr_ic_addr) = NULL;
         }
     }
     local_irq_restore(spsr);
+
+    /* lazy fp */
+    if (current->processor != current->arch.last_processor) {
+        unsigned long *addr;
+        addr = (unsigned long *)per_cpu_addr(fp_owner,
+                                             current->arch.last_processor);
+        ia64_cmpxchg(acq, addr, current, 0, 8);
+    }
+   
     flush_vtlb_for_context_switch(prev, current);
     context_saved(prev);
 }
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c        Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/xen/faults.c        Tue Jan 23 10:52:07 2007 -0700
@@ -92,6 +92,9 @@ void reflect_interruption(unsigned long 
        regs->cr_iip = ((unsigned long)PSCBX(v, iva) + vector) & ~0xffUL;
        regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
 
+       if (PSCB(v, hpsr_dfh))
+               regs->cr_ipsr |= IA64_PSR_DFH;  
+       PSCB(v, vpsr_dfh) = 0;
        v->vcpu_info->evtchn_upcall_mask = 1;
        PSCB(v, interrupt_collection_enabled) = 0;
 
@@ -152,6 +155,9 @@ void reflect_event(void)
        regs->cr_iip = v->arch.event_callback_ip;
        regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
 
+       if (PSCB(v, hpsr_dfh))
+               regs->cr_ipsr |= IA64_PSR_DFH;
+       PSCB(v, vpsr_dfh) = 0;
        v->vcpu_info->evtchn_upcall_mask = 1;
        PSCB(v, interrupt_collection_enabled) = 0;
 }
@@ -261,6 +267,10 @@ void ia64_do_page_fault(unsigned long ad
                    ((unsigned long)PSCBX(current, iva) + fault) & ~0xffUL;
                regs->cr_ipsr =
                    (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
+
+               if (PSCB(current, hpsr_dfh))
+                       regs->cr_ipsr |= IA64_PSR_DFH;  
+               PSCB(current, vpsr_dfh) = 0;
                perfc_incra(slow_reflect, fault >> 8);
                return;
        }
@@ -608,6 +618,16 @@ ia64_handle_reflection(unsigned long ifa
                vector = IA64_GENEX_VECTOR;
                break;
        case 25:
+               if (PSCB(v, hpsr_dfh)) {
+                       PSCB(v, hpsr_dfh) = 0;
+                       PSCB(v, hpsr_mfh) = 1;
+                       if (__ia64_per_cpu_var(fp_owner) != v)
+                               __ia64_load_fpu(v->arch._thread.fph);
+               }
+               if (!PSCB(v, vpsr_dfh)) {
+                       regs->cr_ipsr &= ~IA64_PSR_DFH;
+                       return;
+               }
                vector = IA64_DISABLED_FPREG_VECTOR;
                break;
        case 26:
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S   Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/xen/hyperprivop.S   Tue Jan 23 10:52:07 2007 -0700
@@ -252,6 +252,10 @@ ENTRY(hyper_ssm_i)
        movl r27=~DELIVER_PSR_CLR;;
        or r29=r29,r28;;
        and r29=r29,r27;;
+       // set hpsr_dfh to ipsr
+       adds r28=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       ld1 r28=[r28];;
+       dep r29=r28,r29,IA64_PSR_DFH_BIT,1;;
        mov cr.ipsr=r29;;
        // set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
        extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
@@ -269,6 +273,12 @@ ENTRY(hyper_ssm_i)
        movl r22=THIS_CPU(current_psr_i_addr)
        adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
        ld8 r22=[r22]
+       ;;
+       adds r27=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       ld1 r28=[r27];;
+       st1 [r27]=r0
+       dep r30=r28,r30,IA64_PSR_DFH_BIT,1
+       ;;
        st8 [r21]=r30;;
        // set shared_mem interrupt_delivery_enabled to 0
        // set shared_mem interrupt_collection_enabled to 0
@@ -607,6 +617,10 @@ ENTRY(fast_reflect)
        movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
        or r29=r29,r28;;
        and r29=r29,r27;;
+       // set hpsr_dfh to ipsr
+       adds r28=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       ld1 r28=[r28];;
+       dep r29=r28,r29,IA64_PSR_DFH_BIT,1;;
        mov cr.ipsr=r29;;
        // set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
        extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
@@ -629,7 +643,13 @@ ENTRY(fast_reflect)
 (p6)   dep r30=0,r30,IA64_PSR_I_BIT,1
 (p7)   dep r30=-1,r30,IA64_PSR_I_BIT,1 ;;
        mov r22=1
-       adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
+       adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 
+       ;;
+       adds r27=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       ld1 r28=[r27];;
+       st1 [r27]=r0
+       dep r30=r28,r30,IA64_PSR_DFH_BIT,1
+       ;;
        st8 [r21]=r30 ;;
        // set shared_mem interrupt_delivery_enabled to 0
        // set shared_mem interrupt_collection_enabled to 0
@@ -1103,6 +1123,18 @@ just_do_rfi:
                  IA64_PSR_IT|IA64_PSR_BN)
        ;;
        or r21=r21,r20
+       ;;
+       adds r20=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       tbit.z p8,p9 = r21, IA64_PSR_DFH_BIT
+       ;;
+       (p9) mov r27=1;;
+       (p9) st1 [r20]=r27
+       ;;
+       (p8) st1 [r20]=r0
+       (p8) adds r20=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       (p8) ld1 r27=[r20]
+       ;;
+       (p8) dep r21=r27,r21, IA64_PSR_DFH_BIT, 1
        ;;
        mov cr.ipsr=r21
        adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
@@ -1488,6 +1520,11 @@ ENTRY(hyper_get_psr)
        ld8 r20=[r20];;
        ld1 r21=[r20];;
        dep r8=r21,r8,IA64_PSR_I_BIT,1
+       ;;
+       // set vpsr.dfh
+       adds r20=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+       ld1 r21=[r20];;
+       dep r8=r21,r8,IA64_PSR_DFH_BIT,1
        ;;
        mov r25=cr.iip
        extr.u r26=r24,41,2 ;;
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/arch/ia64/xen/vcpu.c  Tue Jan 23 10:52:07 2007 -0700
@@ -141,6 +141,9 @@ void vcpu_init_regs(struct vcpu *v)
                /* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
                /* Need to be expanded as macro */
                regs->cr_ipsr = 0x501008826008;
+               /* lazy fp */
+               FP_PSR(v) = IA64_PSR_DFH;
+               regs->cr_ipsr |= IA64_PSR_DFH;
        } else {
                regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
                    | IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
@@ -148,6 +151,10 @@ void vcpu_init_regs(struct vcpu *v)
                                   | IA64_PSR_RI | IA64_PSR_IS);
                // domain runs at PL2
                regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT;
+               // lazy fp 
+               PSCB(v, hpsr_dfh) = 1;
+               PSCB(v, hpsr_mfh) = 0;
+               regs->cr_ipsr |= IA64_PSR_DFH;
        }
        regs->cr_ifs = 1UL << 63;       /* or clear? */
        regs->ar_fpsr = FPSR_DEFAULT;
@@ -265,8 +272,10 @@ IA64FAULT vcpu_reset_psr_sm(VCPU * vcpu,
                      IA64_PSR_I | IA64_PSR_IC | IA64_PSR_DT |
                      IA64_PSR_DFL | IA64_PSR_DFH))
                return IA64_ILLOP_FAULT;
-       if (imm.dfh)
-               ipsr->dfh = 0;
+       if (imm.dfh) {
+               ipsr->dfh = PSCB(vcpu, hpsr_dfh);
+               PSCB(vcpu, vpsr_dfh) = 0;
+       }
        if (imm.dfl)
                ipsr->dfl = 0;
        if (imm.pp) {
@@ -320,8 +329,10 @@ IA64FAULT vcpu_set_psr_sm(VCPU * vcpu, u
            IA64_PSR_DT | IA64_PSR_DFL | IA64_PSR_DFH;
        if (imm24 & ~mask)
                return IA64_ILLOP_FAULT;
-       if (imm.dfh)
+       if (imm.dfh) {
+               PSCB(vcpu, vpsr_dfh) = 1;
                ipsr->dfh = 1;
+       } 
        if (imm.dfl)
                ipsr->dfl = 1;
        if (imm.pp) {
@@ -386,8 +397,13 @@ IA64FAULT vcpu_set_psr_l(VCPU * vcpu, u6
        //if (val & ~(IA64_PSR_PP | IA64_PSR_UP | IA64_PSR_SP))
        //      return IA64_ILLOP_FAULT;
        // however trying to set other bits can't be an error as it is in ssm
-       if (newpsr.dfh)
+       if (newpsr.dfh) {
                ipsr->dfh = 1;
+               PSCB(vcpu, vpsr_dfh) = 1;
+       } else {
+               ipsr->dfh = PSCB(vcpu, hpsr_dfh);
+               PSCB(vcpu, vpsr_dfh) = 0;
+       }       
        if (newpsr.dfl)
                ipsr->dfl = 1;
        if (newpsr.pp) {
@@ -466,6 +482,8 @@ IA64FAULT vcpu_get_psr(VCPU * vcpu, u64 
                newpsr.pp = 1;
        else
                newpsr.pp = 0;
+       newpsr.dfh = PSCB(vcpu, vpsr_dfh);
+
        *pval = *(unsigned long *)&newpsr;
        *pval &= (MASK(0, 32) | MASK(35, 2));
        return IA64_NO_FAULT;
@@ -497,6 +515,7 @@ u64 vcpu_get_ipsr_int_state(VCPU * vcpu,
        psr.ia64_psr.ic = PSCB(vcpu, interrupt_collection_enabled);
        psr.ia64_psr.i = !vcpu->vcpu_info->evtchn_upcall_mask;
        psr.ia64_psr.bn = PSCB(vcpu, banknum);
+       psr.ia64_psr.dfh = PSCB(vcpu, vpsr_dfh);
        psr.ia64_psr.dt = 1;
        psr.ia64_psr.it = 1;
        psr.ia64_psr.rt = 1;
@@ -1343,6 +1362,12 @@ IA64FAULT vcpu_rfi(VCPU * vcpu)
        if (psr.ia64_psr.cpl < 3)
                psr.ia64_psr.cpl = 2;
        int_enable = psr.ia64_psr.i;
+       if (psr.ia64_psr.dfh) {
+               PSCB(vcpu, vpsr_dfh) = 1;
+       } else {
+               psr.ia64_psr.dfh = PSCB(vcpu, hpsr_dfh);
+               PSCB(vcpu, vpsr_dfh) = 0;
+       }
        if (psr.ia64_psr.ic)
                PSCB(vcpu, interrupt_collection_enabled) = 1;
        if (psr.ia64_psr.dt && psr.ia64_psr.rt && psr.ia64_psr.it)
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/include/asm-ia64/domain.h     Tue Jan 23 10:52:07 2007 -0700
@@ -175,6 +175,7 @@ struct arch_vcpu {
     unsigned long metaphysical_rr4;            // from arch_domain (so is 
pinned)
     unsigned long metaphysical_saved_rr0;      // from arch_domain (so is 
pinned)
     unsigned long metaphysical_saved_rr4;      // from arch_domain (so is 
pinned)
+    unsigned long fp_psr;       // used for lazy float register
     int breakimm;                      // from arch_domain (so is pinned)
     int starting_rid;          /* first RID assigned to domain */
     int ending_rid;            /* one beyond highest RID assigned to domain */
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/include/asm-ia64/linux-xen/asm/percpu.h
--- a/xen/include/asm-ia64/linux-xen/asm/percpu.h       Tue Jan 23 09:45:26 
2007 -0700
+++ b/xen/include/asm-ia64/linux-xen/asm/percpu.h       Tue Jan 23 10:52:07 
2007 -0700
@@ -43,6 +43,9 @@ DECLARE_PER_CPU(unsigned long, local_per
 
 #define per_cpu(var, cpu)  (*RELOC_HIDE(&per_cpu__##var, 
__per_cpu_offset[cpu]))
 #define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, 
__ia64_per_cpu_var(local_per_cpu_offset)))
+#ifdef XEN
+#define per_cpu_addr(var, cpu)  (RELOC_HIDE(&per_cpu__##var, 
__per_cpu_offset[cpu]))
+#endif
 
 extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size);
 extern void setup_per_cpu_areas (void);
@@ -67,6 +70,8 @@ extern void *per_cpu_init(void);
  */
 #define __ia64_per_cpu_var(var)        (per_cpu__##var)
 
+DECLARE_PER_CPU(struct vcpu *, fp_owner);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_IA64_PERCPU_H */
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/include/asm-ia64/vcpu.h
--- a/xen/include/asm-ia64/vcpu.h       Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/include/asm-ia64/vcpu.h       Tue Jan 23 10:52:07 2007 -0700
@@ -20,6 +20,7 @@ extern u64 cycle_to_ns(u64 cycle);
 #define VCPU(_v,_x)    (_v->arch.privregs->_x)
 #define PSCB(_v,_x)    VCPU(_v,_x)
 #define PSCBX(_v,_x)   (_v->arch._x)
+#define FP_PSR(_v)     PSCBX(_v, fp_psr)
 
 #define SPURIOUS_VECTOR 0xf
 
diff -r 8bfc6e85eeba -r d12ea0bfecce xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Tue Jan 23 09:45:26 2007 -0700
+++ b/xen/include/public/arch-ia64.h    Tue Jan 23 10:52:07 2007 -0700
@@ -288,7 +288,9 @@ struct mapped_regs {
             unsigned char *interrupt_mask_addr;
             int pending_interruption;
             unsigned char vpsr_pp;
-            unsigned char reserved5_2[3];
+            unsigned char vpsr_dfh;
+            unsigned char hpsr_dfh;
+            unsigned char hpsr_mfh;
             unsigned long reserved5_1[4];
             int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual
             int banknum; // 0 or 1, which virtual register bank is active

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [IA64] Implement eager save, lazy restore FP algorithm, Xen patchbot-unstable <=