[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-ia64-devel] [PATCH] Fix MCA error handler problems (was: Re: [patch 06/12] Kexec: Fix ia64_do_tlb_purge so that it works with XEN)



Hi Simon,

I tested MCA error handler with your patch, then some problems were
found.

> 2. Use the per_cpu variable to derive CURRENT_STACK_OFFSET rather
>    than reading it from a kernel register. See 1) for explanation
>    of why.

I added the same code in Reload DTR for stack part and also added a
code to avoid overlapping with kernel TR.

> 3. In the VHPT pruning code, don't use r25 as ia64_jump_to_sal,
>    which branches to ia64_do_tlb_purge expects r25 to be preserved.
>    There seems no reason not to use r2 as per the other purges
>    done in ia64_do_tlb_purge.  Furthermore use r16 and r18 instead
>    of r20 and r24 for consistency reasons.

The r25 kept the value of __va_ul(vcpu_vhpt_maddr(v)), and it was
referred to by the following lines.

468     // r25 = __va_ul(vcpu_vhpt_maddr(v));
469     dep r20=0,r25,0,IA64_GRANULE_SHIFT
470     movl r26=PAGE_KERNEL
471     ;;
472     mov r21=IA64_TR_VHPT
473     dep r22=0,r20,60,4              // physical address of

I defined GET_VA_VCPU_VHPT_MADDR() macro to re-calculate the value of
__va_ul(vcpu_vhpt_maddr(v)) in each part.
And I renamed the register names for same reasons.

I attached a patch that contains those fixes.

Thanks,
KAZ

Signed-off-by: Kazuhiro Suzuki <kaz@xxxxxxxxxxxxxx>


From: Simon Horman <horms@xxxxxxxxxxxx>
Subject: [patch 06/12] Kexec: Fix ia64_do_tlb_purge so that it works with XEN
Date: Thu, 27 Sep 2007 17:17:20 +0900

> Fix ia64_do_tlb_purge, its broken in too many ways
> 
> 1. Call SET_PER_CPU_DATA before making any calls to GET_THIS_PADDR
>    to ensure that per-cpu data is set up correctly.
> 
> 2. Use the per_cpu variable to derive CURRENT_STACK_OFFSET rather
>    than reading it from a kernel register. See 1) for explanation
>    of why.
> 
> 3. In the VHPT pruning code, don't use r25 as ia64_jump_to_sal,
>    which branches to ia64_do_tlb_purge expects r25 to be preserved.
>    There seems no reason not to use r2 as per the other purges
>    done in ia64_do_tlb_purge.  Furthermore use r16 and r18 instead
>    of r20 and r24 for consistency reasons.
> 
> 4. Move __va_ul(vcpu_vhpt_maddr(v)) comment outside of
>    #if VHPT_ENABLED as it also applies to code further down that
>    is outside the #if
> 
> Cc: Tristan Gingold <tgingold@xxxxxxx>,
> Cc: Yutaka Ezaki <yutaka.ezaki@xxxxxxxxxxxxxx>,
> Cc: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>,
> Cc: Kazuhiro Suzuki <kaz@xxxxxxxxxxxxxx>,
> Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
> 
> ---
> Date: Thu, 13 Sep 2007 15:31:43 +0900
> From: Horms <horms@xxxxxxxxxxxx>
> 
> Fixes as suggested by SUZUKI Kazuhiro:
> - Fix up comment relating to the use of SET_PER_CPU_DATA -
>   it was describing a previous version of the fix.
> - 2.6.18 does perge the DTR for PERCPU data, so there is
>   no need to guard it with #ifdef XEN, although later
>   kernels do remove this code
> - Dereference what is at offset IA64_DOMAIN_FLAGS_OFFSET
> 
> Index: xen-unstable.hg/xen/arch/ia64/linux-xen/mca_asm.S
> ===================================================================
> --- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/mca_asm.S    2007-07-11 
> 12:05:33.000000000 +0900
> +++ xen-unstable.hg/xen/arch/ia64/linux-xen/mca_asm.S 2007-07-11 
> 13:13:56.000000000 +0900
> @@ -195,6 +195,10 @@
>   */
>  
>  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
> @@ -263,7 +269,16 @@ ia64_do_tlb_purge:
>       srlz.i
>       ;;
>       // 4. Purge DTR for stack.
> +#ifdef XEN
> +     // Kernel registers are saved in a per_cpu cpu_kr_ia64_t
> +     // to allow the kernel registers themselves to be used by domains.
> +     GET_THIS_PADDR(r2, cpu_kr);;
> +     add r2=IA64_KR_CURRENT_STACK_OFFSET,r2
> +     ;;
> +     ld8 r16=[r2]
> +#else
>       mov r16=IA64_KR(CURRENT_STACK)
> +#endif
>       ;;
>       shl r16=r16,IA64_GRANULE_SHIFT
>       movl r19=PAGE_OFFSET
> @@ -277,8 +292,8 @@ ia64_do_tlb_purge:
>       ;;
>  #ifdef XEN
>       // 5. VHPT
> +     // r2 = __va_ul(vcpu_vhpt_maddr(v));
>  #if VHPT_ENABLED
> -     // r25 = __va_ul(vcpu_vhpt_maddr(v));
>       GET_THIS_PADDR(r2,cpu_kr);;
>       add r2=IA64_KR_CURRENT_OFFSET,r2;;
>       ld8 r2=[r2];;
> @@ -289,18 +304,18 @@ ia64_do_tlb_purge:
>       add r2=IA64_VCPU_VHPT_MADDR_OFFSET,r2;;
>       dep r2=0,r2,60,4;;                      // virtual to physical
>       ld8 r2=[r2];; 
> -     dep r25=-1,r2,60,4;;                    // physical to virtual
> +     dep r2=-1,r2,60,4;;                     // physical to virtual
>       br.sptk         .percpu_vhpt_done
>  #endif
>  .not_pervcpu_vhpt:
>       GET_THIS_PADDR(r2, vhpt_paddr);; 
>       ld8 r2=[r2];; 
> -     dep r25=-1,r2,60,4;;                    // physical to virtual
> +     dep r2=-1,r2,60,4;;                     // physical to virtual
>  .percpu_vhpt_done:
> -     dep r20=0,r25,0,IA64_GRANULE_SHIFT
> -     mov r24=IA64_GRANULE_SHIFT<<2
> +     dep r16=0,r2,0,IA64_GRANULE_SHIFT
> +     mov r18=IA64_GRANULE_SHIFT<<2
>       ;;
> -     ptr.d r20,r24
> +     ptr.d r16,r18
>       ;;
>       srlz.d
>       ;;
> 
> -- 
> 
> -- 
> Horms
>   H: http://www.vergenet.net/~horms/
>   W: http://www.valinux.co.jp/en/
> 
diff -r 3165e43ce734 xen/arch/ia64/linux-xen/mca_asm.S
--- a/xen/arch/ia64/linux-xen/mca_asm.S Tue Oct 02 11:31:55 2007 -0600
+++ b/xen/arch/ia64/linux-xen/mca_asm.S Fri Oct 12 12:52:43 2007 +0900
@@ -185,6 +185,41 @@ 3: add r4 = r6, r3;;                                       
\
 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_DOMAIN_OFFSET,tmp;;                   \
+       ld8 tmp=[tmp];;                                         \
+       dep tmp=0,tmp,60,4;;                    /* V to P */    \
+       add tmp=IA64_DOMAIN_FLAGS_OFFSET,tmp;;                  \
+       ld8 tmp=[tmp];;                                         \
+       and tmp=HAS_PERVCPU_VHPT_MASK,tmp;;                     \
+       cmp.eq p6,p0=tmp,r0;                                    \
+(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 */
 
 /*
@@ -290,33 +325,8 @@ 4:
        ;;
 #ifdef XEN
        // 5. VHPT
-       // r2 = __va_ul(vcpu_vhpt_maddr(v));
 #if VHPT_ENABLED
-       GET_THIS_PADDR(r2,cpu_kr);;
-       add r2=IA64_KR_CURRENT_OFFSET,r2;;
-       ld8 r2=[r2];;
-#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
-#define HAS_PERVCPU_VHPT_MASK  0x2
-       dep r3=0,r2,60,4;;                      // virtual to physical
-       add r3=IA64_VCPU_DOMAIN_OFFSET,r3;;
-       ld8 r3=[r3];; 
-       dep r3=0,r3,60,4;;                      // virtual to physical
-       add r3=IA64_DOMAIN_FLAGS_OFFSET,r3;;
-       ld8 r3=[r3];; 
-       and r3=HAS_PERVCPU_VHPT_MASK,r3;;
-       cmp.eq p6,p0=r3,r0;;
-(p6)   br.cond.sptk    .not_pervcpu_vhpt
-       add r2=IA64_VCPU_VHPT_MADDR_OFFSET,r2;;
-       dep r2=0,r2,60,4;;                      // virtual to physical
-       ld8 r2=[r2];; 
-       dep r2=-1,r2,60,4;;                     // physical to virtual
-       br.sptk         .percpu_vhpt_done
-#endif
-.not_pervcpu_vhpt:
-       GET_THIS_PADDR(r2, vhpt_paddr);; 
-       ld8 r2=[r2];; 
-       dep r2=-1,r2,60,4;;                     // physical to virtual
-.percpu_vhpt_done:
+       GET_VA_VCPU_VHPT_MADDR(r2,r3);;
        dep r16=0,r2,0,IA64_GRANULE_SHIFT
        mov r18=IA64_GRANULE_SHIFT<<2
        ;;
@@ -443,7 +453,27 @@ ia64_reload_tr:
        srlz.i
        ;;
        // 4. Reload DTR for stack.
+#ifdef XEN
+       // avoid overlapping with kernel TR
+       movl r17=KERNEL_START
+       GET_THIS_PADDR(r2,cpu_kr);;
+       add r2=IA64_KR_CURRENT_OFFSET,r2;;
+       ld8 r16=[r2];;
+       ;;
+       dep  r16=0,r16,0,KERNEL_TR_PAGE_SHIFT
+       ;;
+       cmp.eq p7,p0=r17,r16
+(p7)   br.cond.sptk    .reload_vhpt
+       
+       // Kernel registers are saved in a per_cpu cpu_kr_ia64_t
+       // to allow the kernel registers themselves to be used by domains.
+       GET_THIS_PADDR(r2, cpu_kr);;
+       add r2=IA64_KR_CURRENT_STACK_OFFSET,r2
+       ;;
+       ld8 r16=[r2]
+#else
        mov r16=IA64_KR(CURRENT_STACK)
+#endif
        ;;
        shl r16=r16,IA64_GRANULE_SHIFT
        movl r19=PAGE_OFFSET
@@ -463,22 +493,23 @@ ia64_reload_tr:
        srlz.d
        ;;
 #ifdef XEN
+.reload_vhpt:
        // 5. VHPT
 #if VHPT_ENABLED
-       // r25 = __va_ul(vcpu_vhpt_maddr(v));
-       dep r20=0,r25,0,IA64_GRANULE_SHIFT
-       movl r26=PAGE_KERNEL
-       ;;
-       mov r21=IA64_TR_VHPT
-       dep r22=0,r20,60,4              // physical address of
+       GET_VA_VCPU_VHPT_MADDR(r2,r3);;
+       dep r16=0,r2,0,IA64_GRANULE_SHIFT
+       movl r20=PAGE_KERNEL
+       ;;
+       mov r18=IA64_TR_VHPT
+       dep r17=0,r16,60,4              // physical address of
                                        // va_vhpt & ~(IA64_GRANULE_SIZE - 1)
-       mov r24=IA64_GRANULE_SHIFT<<2
-       ;;
-       or r23=r22,r26                  // construct PA | page properties
-       mov cr.itir=r24
-       mov cr.ifa=r20
-       ;;
-       itr.d dtr[r21]=r23              // wire in new mapping...
+       mov r19=IA64_GRANULE_SHIFT<<2
+       ;;
+       or r17=r17,r20                  // construct PA | page properties
+       mov cr.itir=r19
+       mov cr.ifa=r16
+       ;;
+       itr.d dtr[r18]=r17              // wire in new mapping...
        ;;
        srlz.d
        ;;
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.