[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] Fix mca handler so as not to destroy ar(was: Re: [Xen-ia64-devel] Re: mca handler)
Hi, The following patch fixes the mca handler so as not to destroy ar and some bugs. Thanks, KAZ Signed-off-by: Kazuhiro Suzuki <kaz@xxxxxxxxxxxxxx> From: SUZUKI Kazuhiro <kaz@xxxxxxxxxxxxxx> Subject: [Xen-ia64-devel] Re: mca handler Date: Wed, 23 Jul 2008 11:10:57 +0900 (JST) > Hi, > > You are right. The ar registers should not be destroyed. > So, I will try to make a patch which fixes it. > > Thanks, > KAZ > > From: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> > Subject: mca handler > Date: Thu, 17 Jul 2008 11:54:46 +0900 > > > Hi. > > While I was debugging kexec/kdump, I have a question about the mca > > handler. I cited the related hunks below. Could you please clarify them? > > > > On mca the firmware saves non-banked and banked general registers > > and the most of ar registers must be unchanged. > > However before ia64_os_mca_proc_state_dump saves such registers, > > the cited hunks unconditionally overwrite ar.k[36] so that > > they are destroyed. Am I missing anything? > > > > > > changeset: 12447:2afdc0066df6 > > user: awilliam@xxxxxxxxxxx > > date: Sun Oct 29 09:27:11 2006 -0700 > > files: xen/arch/ia64/linux-xen/mca_asm.S > > description: > > [IA64] MCA support - Add percpu data physical addr mca_asm.S > > > > Signed-off-by: Yutaka Ezaki <yutaka.ezaki@xxxxxxxxxxxxxx> > > Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx> > > Signed-off-by: Kazuhiro Suzuki <kaz@xxxxxxxxxxxxxx> > > ... > > ... > > @@ -132,7 +153,40 @@ > > .text > > .align 16 > > > > -#ifndef XEN > > +#ifdef XEN > > +/* > > + * void set_per_cpu_data(void) > > + * { > > + * int i; > > + * for (i = 0; i < 64; i++) { > > + * if (ia64_mca_tlb_list[i].cr_lid == ia64_getreg(_IA64_REG_CR_LID)) { > > + * ia64_set_kr(IA64_KR_PER_CPU_DATA, > > ia64_mca_tlb_list[i].percpu_paddr); > > + * return; > > + * } > > + * } > > + * while(1); // Endless loop on error > > + * } > > + */ > > +#define SET_PER_CPU_DATA() \ > > + LOAD_PHYSICAL(p0,r2,ia64_mca_tlb_list);; \ > > + mov r7 = r0; \ > > + mov r6 = r0;; \ > > + adds r3 = IA64_MCA_PERCPU_OFFSET, r2; \ > > +1: add r4 = r6, r2; \ > > + mov r5=cr.lid;; \ > > + adds r7 = 1, r7; \ > > + ld8 r4 = [r4];; \ > > + cmp.ne p6, p7 = r5, r4; \ > > + cmp4.lt p8, p9 = NR_CPUS-1, r7; \ > > +(p7) br.cond.dpnt 3f; \ > > + adds r6 = 16, r6; \ > > +(p9) br.cond.sptk 1b; \ > > +2: br 2b;; /* Endless loop on error */ \ > > +3: add r4 = r6, r3;; \ > > + ld8 r4 = [r4];; \ > > + mov ar.k3=r4 > > +#endif /* XEN */ > > + > > ... > > @@ -235,6 +327,9 @@ > > cmp.ne p6,p0=r4,r0 > > (p6) br ia64_os_mca_spin > > > > +#ifdef XEN > > + SET_PER_CPU_DATA();; > > +#endif > > // Save the SAL to OS MCA handoff state as defined > > // by SAL SPEC 3.0 > > // NOTE : The order in which the state gets saved > > @@ -250,7 +345,19 @@ > > > > ia64_os_mca_done_dump: > > > > +#ifdef XEN > > + // Set current to ar.k6 > > + GET_THIS_PADDR(r2,cpu_kr);; > > + add r2=IA64_KR_CURRENT_OFFSET,r2;; > > + ld8 r2=[r2];; > > + mov ar.k6=r2;; > > + > > + GET_THIS_PADDR(r2,ia64_sal_to_os_handoff_state_addr);; > > + ld8 r2=[r2];; > > + adds r16=56,r2 > > +#else > > LOAD_PHYSICAL(p0,r16,ia64_sal_to_os_handoff_state+56) > > +#endif > > ;; > > ld8 r18=[r16] // Get processor state parameter on > > existing PA > > LE_CHECK. > > ;; > > ... > > @@ -874,12 +1003,6 @@ > > br ia64_os_mca_done_restore;; > > > > > > //EndStub///////////////////////////////////////////////////////////////////// > > / > > -#else > > -ia64_os_mca_dispatch: > > -1: > > - br.sptk 1b > > -ia64_os_mca_dispatch_end: > > -#endif /* !XEN */ > > > > > > // ok, the issue here is that we need to save state information so > > @@ -911,6 +1034,15 @@ > > > > GLOBAL_ENTRY(ia64_monarch_init_handler) > > .prologue > > +#ifdef XEN /* Need in ia64_monarch_init_handler? */ > > + SET_PER_CPU_DATA();; > > + > > + // Set current to ar.k6 > > + GET_THIS_PADDR(r2,cpu_kr);; > > + add r2=IA64_KR_CURRENT_OFFSET,r2;; > > + ld8 r2=[r2];; > > + mov ar.k6=r2;; > > +#endif > > // stash the information the SAL passed to os > > SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2) > > ;; > > > > > > > > -- > > yamahata > > _______________________________________________ > Xen-ia64-devel mailing list > Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-ia64-devel diff -r 1970781956c7 xen/arch/ia64/linux-xen/mca_asm.S --- a/xen/arch/ia64/linux-xen/mca_asm.S Wed Jul 23 12:10:20 2008 +0900 +++ b/xen/arch/ia64/linux-xen/mca_asm.S Fri Jul 25 16:37:51 2008 +0900 @@ -154,71 +154,6 @@ .text .align 16 -#ifdef XEN -/* - * void set_per_cpu_data(void) - * { - * int i; - * for (i = 0; i < 64; i++) { - * if (ia64_mca_tlb_list[i].cr_lid == ia64_getreg(_IA64_REG_CR_LID)) { - * ia64_set_kr(IA64_KR_PER_CPU_DATA, ia64_mca_tlb_list[i].percpu_paddr); - * return; - * } - * } - * while(1); // Endless loop on error - * } - */ -#define SET_PER_CPU_DATA() \ - LOAD_PHYSICAL(p0,r2,ia64_mca_tlb_list);; \ - mov r7 = r0; \ - mov r6 = r0;; \ - adds r3 = IA64_MCA_PERCPU_OFFSET, r2; \ -1: add r4 = r6, r2; \ - mov r5=cr.lid;; \ - adds r7 = 1, r7; \ - ld8 r4 = [r4];; \ - cmp.ne p6, p7 = r5, r4; \ - cmp4.lt p8, p9 = NR_CPUS-1, r7; \ -(p7) br.cond.dpnt 3f; \ - adds r6 = 16, r6; \ -(p9) br.cond.sptk 1b; \ -2: br 2b;; /* Endless loop on error */ \ -3: add r4 = r6, r3;; \ - ld8 r4 = [r4];; \ - mov ar.k3=r4 - -/* - * GET_VA_VCPU_VHPT_MADDR() emulates 'reg = __va_ul(vcpu_vhpt_maddr(v))'. - */ -#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT -#define HAS_PERVCPU_VHPT_MASK 0x2 -#define GET_VA_VCPU_VHPT_MADDR(reg,tmp) \ - GET_THIS_PADDR(reg,cpu_kr);; \ - add reg=IA64_KR_CURRENT_OFFSET,reg;; \ - ld8 reg=[reg];; \ - dep tmp=0,reg,60,4;; /* V to P */ \ - add tmp=IA64_VCPU_VHPT_PAGE_OFFSET,tmp;; \ - ld8 tmp=[tmp];; \ - cmp.eq p6,p0=tmp,r0; /* v->arch.vhpt_page == NULL */ \ -(p6) br.cond.sptk 1f; \ - add reg=IA64_VCPU_VHPT_MADDR_OFFSET,reg;; \ - dep reg=0,reg,60,4;; /* V to P */ \ - ld8 reg=[reg];; \ - dep reg=-1,reg,60,4; /* P to V */ \ - br.sptk 2f; \ -1: \ - GET_THIS_PADDR(reg, vhpt_paddr);; \ - ld8 reg=[reg];; \ - dep reg=-1,reg,60,4; /* P to V */ \ -2: -#else /* CONFIG_XEN_IA64_PERVCPU_VHPT */ -#define GET_VA_VCPU_VHPT_MADDR(reg,tmp) \ - GET_THIS_PADDR(reg, vhpt_paddr);; \ - ld8 reg=[reg];; \ - dep reg=-1,reg,60,4 /* P to V */ -#endif /* CONFIG_XEN_IA64_PERVCPU_VHPT */ -#endif /* XEN */ - /* * Just the TLB purge part is moved to a separate function * so we can re-use the code for cpu hotplug code as well @@ -227,10 +162,6 @@ 2: */ ia64_do_tlb_purge: -#ifdef XEN - // This needs to be called in order for GET_THIS_PADDR to work - SET_PER_CPU_DATA();; -#endif #define O(member) IA64_CPUINFO_##member##_OFFSET GET_THIS_PADDR(r2, cpu_info) // load phys addr of cpu_info into r2 @@ -346,15 +277,19 @@ 4: // a VMX domain hasn't been started since boot GET_THIS_PADDR(r2, inserted_vpd);; ld8 r16=[r2] - mov r18=XMAPPEDREGS_SHIFT<<2 - ;; - cmp.eq p7,p0=r2,r0 + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + cmp.eq p7,p0=r16,r0 ;; (p7) br.cond.sptk .vpd_not_mapped ;; ptr.i r16,r18 ;; + ptr.d r16,r18 + ;; srlz.i + ;; + srlz.d ;; .vpd_not_mapped: @@ -362,6 +297,7 @@ 4: // GET_VA_VCPU_VHPT_MADDR() may not give the // value of the VHPT currently pinned into the TLB GET_THIS_PADDR(r2, inserted_vhpt);; + ld8 r2=[r2] ;; cmp.eq p7,p0=r2,r0 ;; @@ -389,9 +325,6 @@ ia64_os_mca_spin: cmp.ne p6,p0=r4,r0 (p6) br ia64_os_mca_spin -#ifdef XEN - SET_PER_CPU_DATA();; -#endif // Save the SAL to OS MCA handoff state as defined // by SAL SPEC 3.0 // NOTE : The order in which the state gets saved @@ -524,24 +457,111 @@ ia64_reload_tr: srlz.d ;; #ifdef XEN -.reload_vhpt: - // 5. VHPT - GET_THIS_PADDR(r1, inserted_vhpt);; - cmp.eq p7,p0=r2,r0 -(p7) br.cond.sptk .overlap_vhpt // vhpt isn't mapped. + // 5. shared_info + GET_THIS_PADDR(r2, inserted_shared_info);; + ld8 r16=[r2] + mov r18=XSI_SHIFT<<2 + movl r20=__pgprot(__DIRTY_BITS | _PAGE_PL_PRIV | _PAGE_AR_RW) + ;; + GET_THIS_PADDR(r2, domain_shared_info);; + ld8 r17=[r2] + ;; + dep r17=0,r17,60,4 + ;; + or r17=r17,r20 // construct PA | page properties + mov cr.itir=r18 + mov cr.ifa=r16 + ;; + mov r16=IA64_TR_SHARED_INFO + ;; + itr.d dtr[r16]=r17 // wire in new mapping... + ;; + srlz.d + ;; + + // 6. mapped_regs + GET_THIS_PADDR(r2, inserted_mapped_regs);; + ld8 r16=[r2] + mov r18=XMAPPEDREGS_SHIFT<<2 + ;; + GET_THIS_PADDR(r2,cpu_kr);; + add r2=IA64_KR_CURRENT_OFFSET,r2 + ;; + ld8 r2=[r2] + ;; + dep r2=0,r2,60,4 + ;; + add r2=IA64_VPD_BASE_OFFSET,r2 + ;; + ld8 r17=[r2] + ;; + dep r17=0,r17,60,4 + ;; + or r17=r17,r20 // construct PA | page properties + mov cr.itir=r18 + mov cr.ifa=r16 + ;; + mov r16=IA64_TR_MAPPED_REGS + ;; + itr.d dtr[r16]=r17 // wire in new mapping... + ;; + srlz.d + ;; + + // 7. VPD + // The VPD will not be mapped in the case where + // a VMX domain hasn't been started since boot + GET_THIS_PADDR(r2, inserted_vpd);; + ld8 r16=[r2] + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + cmp.eq p7,p0=r16,r0 + ;; +(p7) br.cond.sptk .reload_vpd_not_mapped + dep r17=0,r16,60,4 + ;; + dep r17=0,r17,0,IA64_GRANULE_SHIFT + ;; + movl r20=PAGE_KERNEL + ;; + or r17=r20,r17 // construct PA | page properties + ;; + mov cr.itir=r18 + mov cr.ifa=r16 + ;; + mov r16=IA64_TR_VPD + mov r18=IA64_TR_MAPPED_REGS + ;; + itr.i itr[r16]=r17 + ;; + itr.d dtr[r18]=r17 + ;; + srlz.i + ;; + srlz.d + ;; +.reload_vpd_not_mapped: + + // 8. VHPT + GET_THIS_PADDR(r2, inserted_vhpt);; + ld8 r2=[r2] + ;; + cmp.eq p7,p0=r2,r0 + ;; +(p7) br.cond.sptk .overlap_vhpt // vhpt isn't mapped. // avoid overlapping with stack TR - shr.u r17=r2,IA64_GRANULE_SHIFT - GET_THIS_PADDR(r3, cpu_kr);; - add r3=IA64_KR_CURRENT_STACK_OFFSET,r3 - ;; - ld8 r3=[r3] - ;; - cmp.eq p7,p0=r3,r17 + dep r16=0,r2,0,IA64_GRANULE_SHIFT + ;; + GET_THIS_PADDR(r2,cpu_kr);; + add r2=IA64_KR_CURRENT_OFFSET,r2 + ;; + ld8 r2=[r2] + ;; + dep r17=0,r2,0,IA64_GRANULE_SHIFT + ;; + cmp.eq p7,p0=r16,r17 (p7) br.cond.sptk .overlap_vhpt - ;; - - dep r16=0,r2,0,IA64_GRANULE_SHIFT movl r20=PAGE_KERNEL ;; mov r18=IA64_TR_VHPT @@ -1123,8 +1143,6 @@ GLOBAL_ENTRY(ia64_monarch_init_handler) GLOBAL_ENTRY(ia64_monarch_init_handler) .prologue #ifdef XEN /* Need in ia64_monarch_init_handler? */ - SET_PER_CPU_DATA();; - // Set current to ar.k6 GET_THIS_PADDR(r2,cpu_kr);; add r2=IA64_KR_CURRENT_OFFSET,r2;; diff -r 1970781956c7 xen/arch/ia64/xen/regionreg.c --- a/xen/arch/ia64/xen/regionreg.c Wed Jul 23 12:10:20 2008 +0900 +++ b/xen/arch/ia64/xen/regionreg.c Fri Jul 25 10:19:03 2008 +0900 @@ -52,6 +52,7 @@ static unsigned int domain_rid_bits_defa static unsigned int domain_rid_bits_default = IA64_MIN_IMPL_RID_BITS; integer_param("dom_rid_bits", domain_rid_bits_default); +DEFINE_PER_CPU(unsigned long, domain_shared_info); DEFINE_PER_CPU(unsigned long, inserted_vhpt); DEFINE_PER_CPU(unsigned long, inserted_shared_info); DEFINE_PER_CPU(unsigned long, inserted_mapped_regs); @@ -270,6 +271,7 @@ int set_one_rr(unsigned long rr, unsigne if (!PSCB(v,metaphysical_mode)) set_rr(rr,newrrv.rrval); } else if (rreg == 7) { + __get_cpu_var(domain_shared_info) = v->domain->shared_info; #if VHPT_ENABLED __get_cpu_var(inserted_vhpt) = __va_ul(vcpu_vhpt_maddr(v)); #endif diff -r 1970781956c7 xen/include/asm-ia64/linux-xen/asm/mca_asm.h --- a/xen/include/asm-ia64/linux-xen/asm/mca_asm.h Wed Jul 23 12:10:20 2008 +0900 +++ b/xen/include/asm-ia64/linux-xen/asm/mca_asm.h Thu Jul 24 11:08:11 2008 +0900 @@ -58,8 +58,35 @@ #endif #ifdef XEN +/* + * void set_per_cpu_data(*ret) + * { + * int i; + * for (i = 0; i < 64; i++) { + * if (ia64_mca_tlb_list[i].cr_lid == ia64_getreg(_IA64_REG_CR_LID)) { + * *ret = ia64_mca_tlb_list[i].percpu_paddr; + * return; + * } + * } + * while(1); // Endless loop on error + * } + */ +#define SET_PER_CPU_DATA(reg,_tmp1,_tmp2,_tmp3) \ + LOAD_PHYSICAL(p0,reg,ia64_mca_tlb_list);;\ + mov _tmp1 = ar.lc;; \ + mov ar.lc = NR_CPUS-1; \ + mov _tmp2 = cr.lid;; \ +10: ld8 _tmp3 = [reg],16;; \ + cmp.ne p6, p7 = _tmp3, _tmp2;; \ +(p7) br.cond.dpnt 30f;; \ + br.cloop.sptk.few 10b;; \ +20: br 20b;;/* Endless loop on error */ \ +30: mov ar.lc = _tmp1; \ + adds reg = IA64_MCA_PERCPU_OFFSET-16, reg;;\ + ld8 reg = [reg] + #define GET_THIS_PADDR(reg, var) \ - mov reg = IA64_KR(PER_CPU_DATA);; \ + SET_PER_CPU_DATA(reg,r5,r6,r7);; \ addl reg = THIS_CPU(var) - PERCPU_ADDR, reg #else #define GET_THIS_PADDR(reg, var) \ diff -r 1970781956c7 xen/include/asm-ia64/regionreg.h --- a/xen/include/asm-ia64/regionreg.h Wed Jul 23 12:10:20 2008 +0900 +++ b/xen/include/asm-ia64/regionreg.h Fri Jul 25 10:36:14 2008 +0900 @@ -36,6 +36,7 @@ typedef union ia64_rr { #define RR_RID(arg) (((arg) & 0x0000000000ffffff) << 8) #define RR_RID_MASK 0x00000000ffffff00L +DECLARE_PER_CPU(unsigned long, domain_shared_info); DECLARE_PER_CPU(unsigned long, inserted_vhpt); DECLARE_PER_CPU(unsigned long, inserted_shared_info); DECLARE_PER_CPU(unsigned long, inserted_mapped_regs); _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ia64-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |