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-ia64-devel

[PATCH] Fix mca handler so as not to destroy ar(was: Re: [Xen-ia64-devel

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