Browse Source

[IA64] ia64/pv_ops/pv_cpu_ops: fix _IA64_REG_IP case.

pv_cpu_ops.getreg(_IA64_REG_IP) returned constant.
But the returned ip valued should be the one in the caller, not of the callee.
This patch fixes that.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Isaku Yamahata 16 years ago
parent
commit
93fe10b670

+ 1 - 1
arch/ia64/include/asm/intrinsics.h

@@ -226,7 +226,7 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
 /************************************************/
 #define ia64_ssm			IA64_INTRINSIC_MACRO(ssm)
 #define ia64_rsm			IA64_INTRINSIC_MACRO(rsm)
-#define ia64_getreg			IA64_INTRINSIC_API(getreg)
+#define ia64_getreg			IA64_INTRINSIC_MACRO(getreg)
 #define ia64_setreg			IA64_INTRINSIC_API(setreg)
 #define ia64_set_rr			IA64_INTRINSIC_API(set_rr)
 #define ia64_get_rr			IA64_INTRINSIC_API(get_rr)

+ 13 - 0
arch/ia64/include/asm/paravirt_privop.h

@@ -78,6 +78,19 @@ extern unsigned long ia64_native_getreg_func(int regnum);
 			ia64_native_rsm(mask);	\
 	} while (0)
 
+/* returned ip value should be the one in the caller,
+ * not in __paravirt_getreg() */
+#define paravirt_getreg(reg)					\
+	({							\
+		unsigned long res;				\
+		BUILD_BUG_ON(!__builtin_constant_p(reg));	\
+		if ((reg) == _IA64_REG_IP)			\
+			res = ia64_native_getreg(_IA64_REG_IP); \
+		else						\
+			res = pv_cpu_ops.getreg(reg);		\
+		res;						\
+	})
+
 /******************************************************************************
  * replacement of hand written assembly codes.
  */

+ 1 - 1
arch/ia64/kernel/paravirt.c

@@ -130,7 +130,7 @@ ia64_native_getreg_func(int regnum)
 	unsigned long res = -1;
 	switch (regnum) {
 	CASE_GET_REG(GP);
-	CASE_GET_REG(IP);
+	/*CASE_GET_REG(IP);*/ /* returned ip value shouldn't be constant */
 	CASE_GET_REG(PSR);
 	CASE_GET_REG(TP);
 	CASE_GET_REG(SP);