Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-ia64-devel

[Xen-ia64-devel] GET_THIS_PADDR appears to be broken

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] GET_THIS_PADDR appears to be broken
From: Horms <horms@xxxxxxxxxxxx>
Date: Wed, 27 Jun 2007 18:59:58 +0900
Cc: Yutaka Ezaki <yutaka.ezaki@xxxxxxxxxxxxxx>, Alex Williamson <alex.williamson@xxxxxx>
Delivery-date: Wed, 27 Jun 2007 02:57:57 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: mutt-ng/devel-r804 (Debian)
GET_THIS_PADDR() doesn't appear to work correclty
on xen-ia64-unstable.hg 15165:96331db61e47

Long-winded description of why

  cpu_data           = 0xf000000004410000
  ia64_tpa(cpu_data) = 0x0000000004410000
  __per_cpu_start    = 0x0003ffffffff0000

  ia64_set_kr(IA64_KR_PER_CPU_DATA,
              ia64_tpa(cpu_data) - (long) __per_cpu_start);
  ar.k3              = ia64_tpa(cpu_data) - __per_cpu_start;
                     = 0x0000000004410000 - 0xf000000004410000
                   = 0x0f00000004420000 # N.B Underflow

  #ifdef XEN
  #define GET_THIS_PADDR(reg, var)                        \
          mov        reg = IA64_KR(PER_CPU_DATA);;        \
          addl       reg = THIS_CPU(var) - PERCPU_ADDR, reg
  #else
  #define GET_THIS_PADDR(reg, var)                        \
          mov        reg = IA64_KR(PER_CPU_DATA);;        \
          addl       reg = THIS_CPU(var), reg
  #endif


  IA64_KR(PER_CPU_DATA)       = ar.k3
                              = 0x0f00000004420000
  THIS_CPU(ia64_mca_pal_base) = &per_cpu__ia64_mca_pal_bas
                              = 0xf0ffffffffff0320
  PERCPU_ADDR                 = 0xf0ffffffffff0000

  GET_THIS_PADDR(r2, ia64_mca_pal_base)
                           r2 = (THIS_CPU(ia64_mca_pal_base) - PERCPU_ADDR) +
                                IA64_KR(PER_CPU_DATA)
                              = (0xf0ffffffffff0320 - 0xf0ffffffffff0000) +
                                0x0f00000004420000
                              = 0x0000000000000320 + 0x0f00000004420000
                              = 0x0f00000004420320 # N.B Overflow

  On the machine in question 0x0f00000004420320 is not a valid
  physical address.

  But if we use the linux version of GET_THIS_PADDR, here is
  how things pan out.

  GET_THIS_PADDR(r2, ia64_mca_pal_base)
                           r2 = THIS_CPU(ia64_mca_pal_base) +
                                IA64_KR(PER_CPU_DATA)
                              = 0xf0ffffffffff0320 + 0x0f00000004420000
                              = 0x0000000004410320 # N.B Overflow

  By inspection I was able to determine that 0x0000000004410320 is the
  correct physical address.

  It can also be derived using the following calculation, which is
  in some ways a little clearer as it doesn't include underflow
  or overflow.

  r2 = (THIS_CPU(ia64_mca_pal_base) - PERCPU_ADDR) + ia64_tpa(cpu_data)
     = (0xf0ffffffffff0320 - 0xf0ffffffffff0000) + 0x0000000004410000
     = 0x0000000000000320 + 0x0000000004410000
     = 0x0000000004410320

Solution 1

Use the Linux variant of GET_THIS_PADDR(reg, var)

  #define GET_THIS_PADDR(reg, var)                        \
          mov        reg = IA64_KR(PER_CPU_DATA);;        \
          addl       reg = THIS_CPU(var), reg

This seems like a simple and logical solition that accodring to the
maths above should work. However, when I try to compile this
I get a relocation error.

ia64-unknown-linux-gnu-ld -g -T xen.lds.s -N \
                -Map map.out linux-xen/head.o 
/home/horms/work/xen/xen-ia64-unstable.hg/xen/common/built_in.o 
/home/horms/work/xen/xen-ia64-unstable.hg/xen/drivers/built_in.o 
/home/horms/work/xen/xen-ia64-unstable.hg/xen/arch/ia64/built_in.o \
                
/home/horms/work/xen/xen-ia64-unstable.hg/xen/common/symbols-dummy.o -o 
/home/horms/work/xen/xen-ia64-unstable.hg/xen/xen-syms
/home/horms/work/xen/xen-ia64-unstable.hg/xen/arch/ia64/linux-xen/mca_asm.S:271:
 relocation truncated to fit: IMM22 against symbol `per_cpu__ia64_mca_pal_base' 
defined in .data.percpu section in 
/home/horms/work/xen/xen-ia64-unstable.hg/xen/arch/ia64/built_in.o

I'm not really sure what that means, other than that
per_cpu__ia64_mca_pal_base aka THIS_CPU(ia64_mca_pal_base)
ought to be a 22bit integer, which it isn't.

I also noticed that the assembled code on xen and linux differ.
Though I'm no linker expert, so I don't understand why.

  Linux
  # objdump -D arch/ia64/kernel/built-in.o
  00000000000000f8 <per_cpu__ia64_mca_pal_base>:
  f8:   00 00 00 00 00 00                   break.i 0x0


  Xen
  # objdump -D arch/ia64/built_in.o
  00000000000000a0 <per_cpu__ia64_mca_pal_base>:
  a0:   00 00 00 00 00 00       [MII]       break.m 0x0

Solution 2

  Change the value that is stored in ar.k3
  from ia64_tpa(cpu_data) - __per_cpu_start
  to simply ia64_tpa(cpu_data)

  This reduces GET_THIS_PADDR() to
  (THIS_CPU(ia64_mca_pal_base) - PERCPU_ADDR) + ia64_tpa(cpu_data)
  which has been shown to be correct above.

  This isn't an entirely ideal solution as it uneccesarily
  diverges both ar.k3 and GET_THIS_PADDR() from the Linux versions,
  however testing shows that it does seem to work.

Previous Solutions

  Until 12448:efb346a02e70 there was a tpa based version of
  GET_THIS_PADDR().

   #define GET_THIS_PADDR(reg, var)             \
        movl    reg = THIS_CPU(var)             \
        tpa     reg = reg

  It did not appear to work in the tests I ran either.
  Even after adding ;; after THIS_CPU(var)
  But I didn't persevere for very long.


Index: xen-ia64-unstable.hg/xen/arch/ia64/linux-xen/setup.c
===================================================================
--- xen-ia64-unstable.hg.orig/xen/arch/ia64/linux-xen/setup.c   2007-06-27 
18:16:19.000000000 +0900
+++ xen-ia64-unstable.hg/xen/arch/ia64/linux-xen/setup.c        2007-06-27 
18:16:22.000000000 +0900
@@ -918,7 +918,11 @@ cpu_init (void)
         *   phys = ar.k3 + &per_cpu_var
         */
        ia64_set_kr(IA64_KR_PER_CPU_DATA,
+#ifdef XEN
+                   ia64_tpa(cpu_data));
+#else
                    ia64_tpa(cpu_data) - (long) __per_cpu_start);
+#endif
 
        get_max_cacheline_size();
 


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