[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Implement eager save, lazy restore FP algorithm
# 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(¤t->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) = ¤t->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(¤t->arch.arch_vmx.vtm.vtm_timer, - current->processor); + if (VMX_DOMAIN(current)) { + vmx_load_all_rr(current); + migrate_timer(¤t->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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |