[PATCH] ppc64: fix pseries hcall stubs

Anton Blanchard anton at samba.org
Tue Mar 22 04:38:06 EST 2005


Fix a number of bugs in our pseries hcall stubs:

- store parameters in the area specified by the ABI, no need to create
  stack frames.
- plpar_hcall_4out would corrupt r14
- merge multiple HVSC definitions

Signed-off-by: Anton Blanchard <anton at samba.org>

diff -puN arch/ppc64/kernel/head.S~fix_pseries_hcalls arch/ppc64/kernel/head.S
--- foobar2/arch/ppc64/kernel/head.S~fix_pseries_hcalls	2005-03-21 11:46:19.796654559 +1100
+++ foobar2-anton/arch/ppc64/kernel/head.S	2005-03-21 11:46:19.834651652 +1100
@@ -37,6 +37,7 @@
 #include <asm/bug.h>
 #include <asm/cputable.h>
 #include <asm/setup.h>
+#include <asm/hvcall.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -45,7 +46,6 @@
 /*
  * hcall interface to pSeries LPAR
  */
-#define HVSC		.long 0x44000022
 #define H_SET_ASR	0x30
 
 /*
diff -puN arch/ppc64/kernel/pSeries_hvCall.S~fix_pseries_hcalls arch/ppc64/kernel/pSeries_hvCall.S
--- foobar2/arch/ppc64/kernel/pSeries_hvCall.S~fix_pseries_hcalls	2005-03-21 11:46:19.801654177 +1100
+++ foobar2-anton/arch/ppc64/kernel/pSeries_hvCall.S	2005-03-21 11:47:44.485802897 +1100
@@ -1,7 +1,6 @@
 /*
  * arch/ppc64/kernel/pSeries_hvCall.S
  *
- *
  * This file contains the generic code to perform a call to the
  * pSeries LPAR hypervisor.
  * NOTE: this file will go away when we move to inline this work.
@@ -11,133 +10,114 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-#include <linux/sys.h>
-#include <asm/unistd.h>
-#include <asm/errno.h>
+#include <asm/hvcall.h>
 #include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cache.h>
 #include <asm/ppc_asm.h>
 	
-/*
- * hcall interface to pSeries LPAR
- */
-#define HVSC .long 0x44000022
-
-/* long plpar_hcall(unsigned long opcode,	 R3 
-		 unsigned long arg1,		 R4 
-		 unsigned long arg2,		 R5 
-		 unsigned long arg3,		 R6 
-		 unsigned long arg4,		 R7 
-		 unsigned long *out1,		 R8 
-		 unsigned long *out2,		 R9
-		 unsigned long *out3);		 R10
- */
+#define STK_PARM(i)     (48 + ((i)-3)*8)
 
 	.text
+
+/* long plpar_hcall(unsigned long opcode,		R3
+			unsigned long arg1,		R4
+			unsigned long arg2,		R5
+			unsigned long arg3,		R6
+			unsigned long arg4,		R7
+			unsigned long *out1,		R8
+			unsigned long *out2,		R9
+			unsigned long *out3);		R10
+ */
 _GLOBAL(plpar_hcall)
 	mfcr	r0
-	std	r0,-8(r1)
-	stdu	r1,-32(r1)
 
-        std     r8,-8(r1)       /* Save out ptrs. */
-        std     r9,-16(r1)
-        std     r10,-24(r1)
-	
-	HVSC                    /* invoke the hypervisor */
+	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
+	std	r9,STK_PARM(r9)(r1)
+	std	r10,STK_PARM(r10)(r1)
+
+	stw	r0,8(r1)
+
+	HVSC				/* invoke the hypervisor */
+
+	lwz	r0,8(r1)
+
+	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r6 ret args */
+	ld	r9,STK_PARM(r9)(r1)
+	ld	r10,STK_PARM(r10)(r1)
+	std	r4,0(r8)
+	std	r5,0(r9)
+	std	r6,0(r10)
 
-        ld      r10,-8(r1)      /* Fetch r4-r7 ret args. */
-        std     r4,0(r10)
-        ld      r10,-16(r1)
-        std     r5,0(r10)
-        ld      r10,-24(r1)
-        std     r6,0(r10)
-
-	ld	r1,0(r1)
-	ld	r0,-8(r1)
 	mtcrf	0xff,r0
-	blr                     /* return r3 = status */
+	blr				/* return r3 = status */
 
 
 /* Simple interface with no output values (other than status) */
 _GLOBAL(plpar_hcall_norets)
 	mfcr	r0
-	std	r0,-8(r1)
-	HVSC                    /* invoke the hypervisor */
-	ld	r0,-8(r1)
-	mtcrf	0xff,r0
-	blr                     /* return r3 = status */
+	stw	r0,8(r1)
 
+	HVSC				/* invoke the hypervisor */
 
-/* long plpar_hcall_8arg_2ret(unsigned long opcode,		 R3 
-			     unsigned long arg1,		 R4 
-		 	     unsigned long arg2,		 R5 
-			     unsigned long arg3,		 R6 
-	 		     unsigned long arg4,		 R7 
-	 		     unsigned long arg5,		 R8 
-			     unsigned long arg6,		 R9 
-	 		     unsigned long arg7,		 R10 
-	 		     unsigned long arg8,		 112(R1)
-	 		     unsigned long *out1);		 120(R1)
+	lwz	r0,8(r1)
+	mtcrf	0xff,r0
+	blr				/* return r3 = status */
 
- */
 
-	.text
+/* long plpar_hcall_8arg_2ret(unsigned long opcode,	R3
+			unsigned long arg1,		R4
+			unsigned long arg2,		R5
+			unsigned long arg3,		R6
+			unsigned long arg4,		R7
+			unsigned long arg5,		R8
+			unsigned long arg6,		R9
+			unsigned long arg7,		R10
+			unsigned long arg8,		112(R1)
+			unsigned long *out1);		120(R1)
+ */
 _GLOBAL(plpar_hcall_8arg_2ret)
 	mfcr	r0
+	ld	r11,STK_PARM(r11)(r1)	/* put arg8 in R11 */
+	stw	r0,8(r1)
 
-	ld              r11, 112(r1) /* put arg8 and out1 in R11 and R12 */
-	ld              r12, 120(r1)
-
-	std	r0,-8(r1)
-	stdu	r1,-32(r1)
+	HVSC				/* invoke the hypervisor */
 
-        std     r12,-8(r1)      /* Save out ptr */
-	
-	HVSC                    /* invoke the hypervisor */
-
-        ld      r10,-8(r1)      /* Fetch r4 ret arg */
-        std     r4,0(r10)
-
-	ld	r1,0(r1)
-	ld	r0,-8(r1)
+	lwz	r0,8(r1)
+	ld	r10,STK_PARM(r12)(r1)	/* Fetch r4 ret arg */
+	std	r4,0(r10)
 	mtcrf	0xff,r0
-	blr                     /* return r3 = status */
+	blr				/* return r3 = status */
 
 
-/* long plpar_hcall_4out(unsigned long opcode,	 R3 
-		 unsigned long arg1,		 R4 
-		 unsigned long arg2,		 R5 
-		 unsigned long arg3,		 R6 
-		 unsigned long arg4,		 R7 
-		 unsigned long *out1,	(r4)	 R8 
-		 unsigned long *out2,	(r5)	 R9
-		 unsigned long *out3,   (r6)     R10
-		 unsigned long *out4);	(r7)	 112(R1). From Parameter save area. 
+/* long plpar_hcall_4out(unsigned long opcode,		R3
+		 	unsigned long arg1,		R4
+		 	unsigned long arg2,		R5
+		 	unsigned long arg3,		R6
+		 	unsigned long arg4,		R7
+		 	unsigned long *out1,		R8
+		 	unsigned long *out2,		R9
+		 	unsigned long *out3,		R10
+		 	unsigned long *out4);		112(R1)
  */
 _GLOBAL(plpar_hcall_4out)
 	mfcr	r0
-	std	r0,-8(r1)
-	ld      r14,112(r1)
-	stdu	r1,-48(r1) 
-
-	std     r8,32(r1)       /* Save out ptrs. */
-	std     r9,24(r1)
-	std     r10,16(r1)
-	std     r14,8(r1)
-	
-	HVSC                    /* invoke the hypervisor */
+	stw	r0,8(r1)
 
-	ld      r14,32(r1)      /* Fetch r4-r7 ret args. */
-	std     r4,0(r14)
-	ld      r14,24(r1)
-	std     r5,0(r14)
-	ld      r14,16(r1)
-	std     r6,0(r14)
-	ld      r14,8(r1)
-	std     r7,0(r14)
+	std	r8,STK_PARM(r8)(r1)	/* Save out ptrs */
+	std	r9,STK_PARM(r9)(r1)
+	std	r10,STK_PARM(r10)(r1)
+
+	HVSC				/* invoke the hypervisor */
+
+	lwz	r0,8(r1)
+
+	ld	r8,STK_PARM(r8)(r1)	/* Fetch r4-r7 ret args */
+	ld	r9,STK_PARM(r9)(r1)
+	ld	r10,STK_PARM(r10)(r1)
+	ld	r11,STK_PARM(r11)(r1)
+	std	r4,0(r8)
+	std	r5,0(r9)
+	std	r6,0(r10)
+	std	r7,0(r11)
 
-	ld	r1,0(r1) 
-	ld	r0,-8(r1)
 	mtcrf	0xff,r0
-	blr                     /* return r3 = status */
+	blr				/* return r3 = status */
diff -puN include/asm-ppc64/hvcall.h~fix_pseries_hcalls include/asm-ppc64/hvcall.h
--- foobar2/include/asm-ppc64/hvcall.h~fix_pseries_hcalls	2005-03-21 11:46:19.806653794 +1100
+++ foobar2-anton/include/asm-ppc64/hvcall.h	2005-03-21 11:46:19.829652035 +1100
@@ -1,6 +1,8 @@
 #ifndef _PPC64_HVCALL_H
 #define _PPC64_HVCALL_H
 
+#define HVSC			.long 0x44000022
+
 #define H_Success	0
 #define H_Busy		1	/* Hardware busy -- retry later */
 #define H_Constrained	4	/* Resource request constrained to max allowed */
@@ -41,7 +43,7 @@
 
 /* Flags */
 #define H_LARGE_PAGE		(1UL<<(63-16))
-#define H_EXACT		    (1UL<<(63-24))	/* Use exact PTE or return H_PTEG_FULL */
+#define H_EXACT			(1UL<<(63-24))	/* Use exact PTE or return H_PTEG_FULL */
 #define H_R_XLATE		(1UL<<(63-25))	/* include a valid logical page num in the pte if the valid bit is set */
 #define H_READ_4		(1UL<<(63-26))	/* Return 4 PTEs */
 #define H_AVPN			(1UL<<(63-32))	/* An avpn is provided as a sanity test */
@@ -54,8 +56,6 @@
 #define H_PP1			(1UL<<(63-62))
 #define H_PP2			(1UL<<(63-63))
 
-
-
 /* pSeries hypervisor opcodes */
 #define H_REMOVE		0x04
 #define H_ENTER			0x08
@@ -108,6 +108,8 @@
 #define H_FREE_VTERM		0x158
 #define H_POLL_PENDING	        0x1D8
 
+#ifndef __ASSEMBLY__
+
 /* plpar_hcall() -- Generic call interface using above opcodes
  *
  * The actual call interface is a hypervisor call instruction with
@@ -125,8 +127,6 @@ long plpar_hcall(unsigned long opcode,
 		 unsigned long *out2,
 		 unsigned long *out3);
 
-#define HVSC			".long 0x44000022\n"
-
 /* Same as plpar_hcall but for those opcodes that return no values
  * other than status.  Slightly more efficient.
  */
@@ -147,9 +147,6 @@ long plpar_hcall_8arg_2ret(unsigned long
 			   unsigned long arg7,
 			   unsigned long arg8,
 			   unsigned long *out1);
-
-
- 
  
 /* plpar_hcall_4out()
  *
@@ -166,4 +163,5 @@ long plpar_hcall_4out(unsigned long opco
 		      unsigned long *out3,
 		      unsigned long *out4);
 
+#endif /* __ASSEMBLY__ */
 #endif /* _PPC64_HVCALL_H */
_



More information about the Linuxppc64-dev mailing list