To understand the context for this patch, observe that the following is
the case in stock Xen/PPC:

 $ nm xen-syms | egrep ' per_cpu__|__per_cpu' | sort
 000000000044c680 d per_cpu__domain_shuttingdown
 000000000044c688 D per_cpu__mc_state
 000000000044c700 d per_cpu__t_timer
 ...
 000000000045cc80 D per_cpu__tlbflush_time
 000000000045d2b0 A __per_cpu_data_end
 000000000045d2b0 A __per_cpu_start
 0000000000460000 A __per_cpu_end

So __per_cpu_start and __per_cpu_data_end are identical, and none of the
per_cpu variable are actually between __per_cpu_start and __per_cpu_end.

When CPU #20 on a Xen/PPC SMP system tries to load or store to 
its t_timer per-cpu variable, a calculation like this will take place:

 address = 0x44c700 + (20 << 12)

So the address is 0x460700, which beyond __per_cpu_end among other
problems.  For my configuration, it lies in the __hypercall_table, so
when init_timer(per_cpu(t_timer)) is run, a portion of the hypercall
table is memset to zero and then some timer-related function pointers
are written to it.  Many cycles later, when init_hcalls is run, a
garbage pointer is dereferenced and a 0x200 exception occurs.

Also, the linker script has a bogus assumption that the per-cpu
section size can be calculated by adding (NR_CPUS << PERCPU_SHIFT) to
__per_cpu_start.  It needs to use __per_cpu_data_end instead, or a
different instance of memory corruption can occur.

Also, a .data.percpu section was not actually being created in the final
linked object.

This patch fixes the three issues described above.  Tested on
systemsim-gpul, JS20 and JS21.

Signed-off-by: Amos Waterland <[EMAIL PROTECTED]>

---

 arch/powerpc/xen.lds.S       |   15 +++++++++------
 include/asm-powerpc/percpu.h |    5 +++--
 2 files changed, 12 insertions(+), 8 deletions(-)

diff -r 539a1e666982 xen/arch/powerpc/xen.lds.S
--- a/xen/arch/powerpc/xen.lds.S        Fri Aug 18 14:07:50 2006 -0400
+++ b/xen/arch/powerpc/xen.lds.S        Sat Aug 19 01:53:55 2006 -0400
@@ -124,12 +124,15 @@ SECTIONS
   .inithcall.text : { *(.inithcall.text) }
   __inithcall_end = .;
 
-  __per_cpu_start = .;
-  .data.percpu : { *(.data.percpu) }
-  __per_cpu_data_end = .;
-  . = __per_cpu_start + (NR_CPUS << PERCPU_SHIFT);
-  . = ALIGN(STACK_SIZE);
-  __per_cpu_end = .;
+  .data.percpu : {
+    __per_cpu_start = .;
+    *(__per_cpu)
+    __per_cpu_data_end = .;
+    . = __per_cpu_data_end + (NR_CPUS << PERCPU_SHIFT);
+    __per_cpu_multiple_end = .; 
+    . = ALIGN(STACK_SIZE);
+    __per_cpu_end = .; 
+  }
 
   /* end Xen addition */
 
diff -r 539a1e666982 xen/include/asm-powerpc/percpu.h
--- a/xen/include/asm-powerpc/percpu.h  Fri Aug 18 14:07:50 2006 -0400
+++ b/xen/include/asm-powerpc/percpu.h  Sat Aug 19 01:07:21 2006 -0400
@@ -8,8 +8,9 @@
 
 /* Separate out the type, so (int[3], foo) works. */
 #define DEFINE_PER_CPU(type, name)                      \
-    __attribute__((__section__(".data.percpu")))        \
-    __typeof__(type) per_cpu__##name
+    __typeof__(type) per_cpu__##name \
+    __attribute__((section("__per_cpu")))
+
 
 /* var is in discarded region: offset to particular copy we want */
 #define per_cpu(var, cpu)  \

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to