aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2011-07-20 15:02:16 +0100
committerKeir Fraser <keir@xen.org>2011-07-20 15:02:16 +0100
commitf2cca23a87c7f251e2ebfcc0e4b7b8ec78a0d2c8 (patch)
treea53333de286396456af8a72f07ef96aa06a2fff1 /tools/firmware
parent30191ad44fde354e821c52f334ec43118d3d6d00 (diff)
downloadxen-f2cca23a87c7f251e2ebfcc0e4b7b8ec78a0d2c8.tar.gz
xen-f2cca23a87c7f251e2ebfcc0e4b7b8ec78a0d2c8.tar.bz2
xen-f2cca23a87c7f251e2ebfcc0e4b7b8ec78a0d2c8.zip
hvmloader: Switch to absolute addressing for calling hypercall stubs.
This is clearer and less fragile than trying to make relative calls work. In particular, the old approach failed if _start was not == HVMLOADER_PHYSICAL_ADDRESS. This was the case for some modern toolchains which reorder functions. Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/firmware')
-rw-r--r--tools/firmware/hvmloader/hypercall.h137
1 files changed, 69 insertions, 68 deletions
diff --git a/tools/firmware/hvmloader/hypercall.h b/tools/firmware/hvmloader/hypercall.h
index be420f0188..9f3d3f925e 100644
--- a/tools/firmware/hvmloader/hypercall.h
+++ b/tools/firmware/hvmloader/hypercall.h
@@ -35,84 +35,85 @@
#include <xen/xen.h>
#include "config.h"
-/*
- * NB. Hypercall address needs to be relative to a linkage symbol for
- * some version of ld to relocate the relative calls properly.
- */
-#define hypercall_pa "_start - " STR(HVMLOADER_PHYSICAL_ADDRESS) \
- " + " STR(HYPERCALL_PHYSICAL_ADDRESS)
-
-#define _hypercall0(type, name) \
-({ \
- long __res; \
- asm volatile ( \
- "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
- : "=a" (__res) \
- : \
- : "memory" ); \
- (type)__res; \
+#define hcall_addr(name) \
+ ((unsigned long)HYPERCALL_PHYSICAL_ADDRESS + __HYPERVISOR_##name * 32)
+
+#define _hypercall0(type, name) \
+({ \
+ long __res; \
+ asm volatile ( \
+ "call *%%eax" \
+ : "=a" (__res) \
+ : "0" (hcall_addr(name)) \
+ : "memory" ); \
+ (type)__res; \
})
-#define _hypercall1(type, name, a1) \
-({ \
- long __res, __ign1; \
- asm volatile ( \
- "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
- : "=a" (__res), "=b" (__ign1) \
- : "1" ((long)(a1)) \
- : "memory" ); \
- (type)__res; \
+#define _hypercall1(type, name, a1) \
+({ \
+ long __res, __ign1; \
+ asm volatile ( \
+ "call *%%eax" \
+ : "=a" (__res), "=b" (__ign1) \
+ : "0" (hcall_addr(name)), \
+ "1" ((long)(a1)) \
+ : "memory" ); \
+ (type)__res; \
})
-#define _hypercall2(type, name, a1, a2) \
-({ \
- long __res, __ign1, __ign2; \
- asm volatile ( \
- "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
- : "1" ((long)(a1)), "2" ((long)(a2)) \
- : "memory" ); \
- (type)__res; \
+#define _hypercall2(type, name, a1, a2) \
+({ \
+ long __res, __ign1, __ign2; \
+ asm volatile ( \
+ "call *%%eax" \
+ : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
+ : "0" (hcall_addr(name)), \
+ "1" ((long)(a1)), "2" ((long)(a2)) \
+ : "memory" ); \
+ (type)__res; \
})
-#define _hypercall3(type, name, a1, a2, a3) \
-({ \
- long __res, __ign1, __ign2, __ign3; \
- asm volatile ( \
- "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
- "=d" (__ign3) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)) \
- : "memory" ); \
- (type)__res; \
+#define _hypercall3(type, name, a1, a2, a3) \
+({ \
+ long __res, __ign1, __ign2, __ign3; \
+ asm volatile ( \
+ "call *%%eax" \
+ : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
+ "=d" (__ign3) \
+ : "0" (hcall_addr(name)), \
+ "1" ((long)(a1)), "2" ((long)(a2)), \
+ "3" ((long)(a3)) \
+ : "memory" ); \
+ (type)__res; \
})
-#define _hypercall4(type, name, a1, a2, a3, a4) \
-({ \
- long __res, __ign1, __ign2, __ign3, __ign4; \
- asm volatile ( \
- "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
- "=d" (__ign3), "=S" (__ign4) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)), "4" ((long)(a4)) \
- : "memory" ); \
- (type)__res; \
+#define _hypercall4(type, name, a1, a2, a3, a4) \
+({ \
+ long __res, __ign1, __ign2, __ign3, __ign4; \
+ asm volatile ( \
+ "call *%%eax" \
+ : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
+ "=d" (__ign3), "=S" (__ign4) \
+ : "0" (hcall_addr(name)), \
+ "1" ((long)(a1)), "2" ((long)(a2)), \
+ "3" ((long)(a3)), "4" ((long)(a4)) \
+ : "memory" ); \
+ (type)__res; \
})
-#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
-({ \
- long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
- asm volatile ( \
- "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
- : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
- "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
- : "1" ((long)(a1)), "2" ((long)(a2)), \
- "3" ((long)(a3)), "4" ((long)(a4)), \
- "5" ((long)(a5)) \
- : "memory" ); \
- (type)__res; \
+#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
+({ \
+ long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
+ asm volatile ( \
+ "call *%%eax" \
+ : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
+ "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
+ : "0" (hcall_addr(name)), \
+ "1" ((long)(a1)), "2" ((long)(a2)), \
+ "3" ((long)(a3)), "4" ((long)(a4)), \
+ "5" ((long)(a5)) \
+ : "memory" ); \
+ (type)__res; \
})
static inline int