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

[Xen-ia64-devel] [PATCH] Fix MCA error handler problems (was: Re: [patch

To: horms@xxxxxxxxxxxx
Subject: [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)
From: SUZUKI Kazuhiro <kaz@xxxxxxxxxxxxxx>
Date: Fri, 12 Oct 2007 17:12:15 +0900 (JST)
Cc: alex.williamson@xxxxxx, xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Fri, 12 Oct 2007 01:13:41 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20070927081734.372026694@xxxxxxxxxxxx>
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070927073101.163912627@xxxxxxxxxxxx> <20070927081734.372026694@xxxxxxxxxxxx>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
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
<Prev in Thread] Current Thread [Next in Thread>