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
|