Avoid hypervisor statistics calculation in real mode
PATCH 1/1 Avoid hypervisor statistics calculation in real mode
kexec invokes plpar_hcall hypervisor call in real mode. plpar_hcall refers per cpu variable for accounting hypervisor statistics. These variables may not be present in the RMO region. So it results in 0x300 exception.
The following patch fixes this problem by using raw hypervisor call which does not update the hypervisor call statistics. Thanks to Anton for suggesting this idea.
--- arch/powerpc/platforms/pseries/hvCall.S | 34 ++++++++++++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 2 - arch/powerpc/platforms/pseries/plpar_wrappers.h | 19 +++++++++++++ include/asm-powerpc/hvcall.h | 15 ++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-)
arch/powerpc/platforms/pseries/hvCall.S +34 -0
@@ -123,6 +123,40 @@ _GLOBAL(plpar_hcall) blr /* return r3 = status */ + +/* plpar_hcall_raw can be called in real mode. kexec/kdump need some + * hypervisor calls to be executed in real mode. So plpar_hcall_raw + * does not access the per cpu hypervisor call statistics variables, + * since these variables may not be present in the RMO region. + */ +_GLOBAL(plpar_hcall_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + + HVSC /* invoke the hypervisor */ + + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ + _GLOBAL(plpar_hcall9) HMT_MEDIUM
arch/powerpc/platforms/pseries/lpar.c +1 -1
@@ -378,7 +378,7 @@ static void pSeries_lpar_hptab_clear(voi/* TODO: Use bulk call */ for (i =0 ; i < hpte_count; i++) -plpar_pte_remove (0 , i,0 , &dummy1, &dummy2); +plpar_pte_remove_raw (0 , i,0 , &dummy1, &dummy2); }/*
arch/powerpc/platforms/pseries/plpar_wrappers.h +19 -0
@@ -78,6 +78,25 @@ static inline long plpar_pte_remove(unsireturn rc; } + +/* plpar_pte_remove_raw can be called in real mode. +* It calls plpar_hcall_raw. +*/ +static inline long plpar_pte_remove_raw (unsigned long flags,unsigned long ptex, +unsigned long avpn,unsigned long *old_pteh_ret, +unsigned long *old_ptel_ret) +{ +long rc; +unsigned long retbuf[PLPAR_HCALL_BUFSIZE ]; + + rc =plpar_hcall_raw (H_REMOVE , retbuf, flags, ptex, avpn); + + *old_pteh_ret = retbuf[0 ]; + *old_ptel_ret = retbuf[1 ]; + +return rc; +} +static inline long plpar_pte_read (unsigned long flags,unsigned long ptex,unsigned long *old_pteh_ret,unsigned long *old_ptel_ret) {
include/asm-powerpc/hvcall.h +15 -0
@@ -237,6 +237,21 @@ long plpar_hcall_norets(unsigned long oplong plpar_hcall (unsigned long opcode,unsigned long *retbuf, ...);/** +* plpar_hcall_raw: - Make a pseries hypervisor call, but don't calculate +* hypervisor call statistics. +* @opcode: The hypervisor call to make. +* @retbuf: Buffer to store up to 4 return arguments in. +* +* This call supports up to 6 arguments and 4 return arguments. Use +* PLPAR_HCALL_BUFSIZE to size the return argument buffer. +* +* Used when phyp interface needs to be called in real mode. Similar to +* plpar_hcall, but plpar_hcall_raw works in real mode and does not +* calculate hypervisor call statistics. +*/ +long plpar_hcall_raw (unsigned long opcode,unsigned long *retbuf, ...); + +/** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments * @opcode: The hypervisor call to make. * @retbuf: Buffer to store up to 9 return arguments in.
Quoted 14 lines · On Tue, 20 Mar 2007 19:05:47 +0530 Mohan Kumar M wrote:
Cc Anton Blanchard <[email protected]>Signed-off-by Mohan Kumar M <[email protected]>--- arch/powerpc/platforms/pseries/hvCall.S | 34 ++++++++++++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 2 - arch/powerpc/platforms/pseries/plpar_wrappers.h | 19 +++++++++++++ include/asm-powerpc/hvcall.h | 15 ++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-)Index:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/hvCall.S
===================================================================
arch/powerpc/platforms/pseries/hvCall.S _GLOBAL(plpar_hcall) · line 131
Quoted 9 lines
arch/powerpc/platforms/pseries/hvCall.S +6
-0@@ -123,6 +123,40 @@ _GLOBAL(plpar_hcall) blr /* return r3 = status */ + +/* plpar_hcall_raw can be called in real mode. kexec/kdump need some + * hypervisor calls to be executed in real mode. So plpar_hcall_raw + * does not access the per cpu hypervisor call statistics variables, + * since these variables may not be present in the RMO region. + */
Hi,
Please use regular kernel long comment style (when not using kernel-doc). E.g.:
/*
* foo
* bar
* this is a long comment (several lines)
*/
Quoted 37 lines
arch/powerpc/platforms/pseries/hvCall.S +28
-0+_GLOBAL(plpar_hcall_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + + HVSC /* invoke the hypervisor */ + + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ + _GLOBAL(plpar_hcall9) HMT_MEDIUMIndex:
linux-2.6.21-rc4/include/asm-powerpc/hvcall.h
===================================================================
include/asm-powerpc/hvcall.h long plpar_hcall_norets(unsigned long op · line 241
Quoted 5 lines
include/asm-powerpc/hvcall.h +2
-0@@ -237,6 +237,21 @@ long plpar_hcall_norets(unsigned long oplong plpar_hcall (unsigned long opcode,unsigned long *retbuf, ...);/** +* plpar_hcall_raw: - Make a pseries hypervisor call, but don't calculate +* hypervisor call statistics.
For kernel-doc, the first line must be:
* function - short description (one line only)
More detailed description can follow the parameters (like you have done below).
Quoted 6 lines
include/asm-powerpc/hvcall.h +6
-0+* @opcode: The hypervisor call to make. +* @retbuf: Buffer to store up to 4 return arguments in. +* +* This call supports up to 6 arguments and 4 return arguments. Use +* PLPAR_HCALL_BUFSIZE to size the return argument buffer. +*
include/asm-powerpc/hvcall.h long plpar_hcall_norets(unsigned long op · line 257
Quoted 10 lines
include/asm-powerpc/hvcall.h +7
-0+* Used when phyp interface needs to be called in real mode. Similar to +* plpar_hcall, but plpar_hcall_raw works in real mode and does not +* calculate hypervisor call statistics. +*/ +long plpar_hcall_raw (unsigned long opcode,unsigned long *retbuf, ...); + +/** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments * @opcode: The hypervisor call to make. * @retbuf: Buffer to store up to 9 return arguments in.
Thanks.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Thanks Randy.
I updated the patch as per your suggestions.
kexec invokes plpar_hcall hypervisor call in real mode. plpar_hcall refers per cpu variable for accounting hypervisor statistics. These variables may not be present in the RMO region. So it results in 0x300 exception.
The following patch fixes this problem by using raw hypervisor call which does not update the hypervisor call statistics. Thanks to Anton for suggesting this idea.
--- arch/powerpc/platforms/pseries/hvCall.S | 34 ++++++++++++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 2 - arch/powerpc/platforms/pseries/plpar_wrappers.h | 16 +++++++++++ include/asm-powerpc/hvcall.h | 14 +++++++++ 4 files changed, 65 insertions(+), 1 deletion(-)
arch/powerpc/platforms/pseries/hvCall.S +34 -0
@@ -123,6 +123,40 @@ _GLOBAL(plpar_hcall) blr /* return r3 = status */ +/* + * plpar_hcall_raw can be called in real mode. kexec/kdump need some + * hypervisor calls to be executed in real mode. So plpar_hcall_raw + * does not access the per cpu hypervisor call statistics variables, + * since these variables may not be present in the RMO region. + */ +_GLOBAL(plpar_hcall_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + + HVSC /* invoke the hypervisor */ + + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ + _GLOBAL(plpar_hcall9) HMT_MEDIUM
arch/powerpc/platforms/pseries/lpar.c +1 -1
@@ -378,7 +378,7 @@ static void pSeries_lpar_hptab_clear(voi/* TODO: Use bulk call */ for (i =0 ; i < hpte_count; i++) -plpar_pte_remove (0 , i,0 , &dummy1, &dummy2); +plpar_pte_remove_raw (0 , i,0 , &dummy1, &dummy2); }/*
arch/powerpc/platforms/pseries/plpar_wrappers.h +16 -0
@@ -78,6 +78,22 @@ static inline long plpar_pte_remove(unsireturn rc; } +/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */ +static inline long plpar_pte_remove_raw (unsigned long flags,unsigned long ptex, +unsigned long avpn,unsigned long *old_pteh_ret, +unsigned long *old_ptel_ret) +{ +long rc; +unsigned long retbuf[PLPAR_HCALL_BUFSIZE ]; + + rc =plpar_hcall_raw (H_REMOVE , retbuf, flags, ptex, avpn); + + *old_pteh_ret = retbuf[0 ]; + *old_ptel_ret = retbuf[1 ]; + +return rc; +} +static inline long plpar_pte_read (unsigned long flags,unsigned long ptex,unsigned long *old_pteh_ret,unsigned long *old_ptel_ret) {
include/asm-powerpc/hvcall.h +14 -0
@@ -237,6 +237,20 @@ long plpar_hcall_norets(unsigned long oplong plpar_hcall (unsigned long opcode,unsigned long *retbuf, ...);/** +* plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats +* @opcode: The hypervisor call to make. +* @retbuf: Buffer to store up to 4 return arguments in. +* +* This call supports up to 6 arguments and 4 return arguments. Use +* PLPAR_HCALL_BUFSIZE to size the return argument buffer. +* +* Used when phyp interface needs to be called in real mode. Similar to +* plpar_hcall, but plpar_hcall_raw works in real mode and does not +* calculate hypervisor call statistics. +*/ +long plpar_hcall_raw (unsigned long opcode,unsigned long *retbuf, ...); + +/** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments * @opcode: The hypervisor call to make. * @retbuf: Buffer to store up to 9 return arguments in.
Quoted 4 lines · On Wed, 21 Mar 2007 11:21:32 +0530 Mohan Kumar M wrote:
Thanks Randy.
I updated the patch as per your suggestions.
Thanks, looks fine to me.
Quoted 128 lines
kexec invokes
plpar_hcallhypervisor call in real mode.plpar_hcallrefers per cpu variable for accounting hypervisor statistics. These variables may not be present in the RMO region. So it results in0x300exception.The following patch fixes this problem by using raw hypervisor call which does not update the hypervisor call statistics. Thanks to Anton for suggesting this idea.
Cc Anton Blanchard <[email protected]>Signed-off-by Mohan Kumar M <[email protected]>--- arch/powerpc/platforms/pseries/hvCall.S | 34 ++++++++++++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 2 - arch/powerpc/platforms/pseries/plpar_wrappers.h | 16 +++++++++++ include/asm-powerpc/hvcall.h | 14 +++++++++ 4 files changed, 65 insertions(+), 1 deletion(-)Index:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/hvCall.S
===================================================================arch/powerpc/platforms/pseries/hvCall.S +34
-0@@ -123,6 +123,40 @@ _GLOBAL(plpar_hcall) blr /* return r3 = status */ +/* + * plpar_hcall_raw can be called in real mode. kexec/kdump need some + * hypervisor calls to be executed in real mode. So plpar_hcall_raw + * does not access the per cpu hypervisor call statistics variables, + * since these variables may not be present in the RMO region. + */ +_GLOBAL(plpar_hcall_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + + HVSC /* invoke the hypervisor */ + + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ + _GLOBAL(plpar_hcall9) HMT_MEDIUMIndex:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/lpar.c
===================================================================arch/powerpc/platforms/pseries/lpar.c +1
-1@@ -378,7 +378,7 @@ static void pSeries_lpar_hptab_clear(voi/* TODO: Use bulk call */ for (i =0 ; i < hpte_count; i++) -plpar_pte_remove (0 , i,0 , &dummy1, &dummy2); +plpar_pte_remove_raw (0 , i,0 , &dummy1, &dummy2); }/* Index:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/plpar_wrappers.h
===================================================================arch/powerpc/platforms/pseries/plpar_wrappers.h +16
-0@@ -78,6 +78,22 @@ static inline long plpar_pte_remove(unsireturn rc; } +/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */ +static inline long plpar_pte_remove_raw (unsigned long flags,unsigned long ptex, +unsigned long avpn,unsigned long *old_pteh_ret, +unsigned long *old_ptel_ret) +{ +long rc; +unsigned long retbuf[PLPAR_HCALL_BUFSIZE ]; + + rc =plpar_hcall_raw (H_REMOVE , retbuf, flags, ptex, avpn); + + *old_pteh_ret = retbuf[0 ]; + *old_ptel_ret = retbuf[1 ]; + +return rc; +} +static inline long plpar_pte_read (unsigned long flags,unsigned long ptex,unsigned long *old_pteh_ret,unsigned long *old_ptel_ret) {Index:
linux-2.6.21-rc4/include/asm-powerpc/hvcall.h
===================================================================include/asm-powerpc/hvcall.h +14
-0@@ -237,6 +237,20 @@ long plpar_hcall_norets(unsigned long oplong plpar_hcall (unsigned long opcode,unsigned long *retbuf, ...);/** +* plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats +* @opcode: The hypervisor call to make. +* @retbuf: Buffer to store up to 4 return arguments in. +* +* This call supports up to 6 arguments and 4 return arguments. Use +* PLPAR_HCALL_BUFSIZE to size the return argument buffer. +* +* Used when phyp interface needs to be called in real mode. Similar to +* plpar_hcall, but plpar_hcall_raw works in real mode and does not +* calculate hypervisor call statistics. +*/ +long plpar_hcall_raw (unsigned long opcode,unsigned long *retbuf, ...); + +/** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments * @opcode: The hypervisor call to make. * @retbuf: Buffer to store up to 9 return arguments in.
Quoted 5 lines
_______________________________________________
fastboot mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/fastboot
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Quoted 5 lines · Mohan Kumar M
Thanks Randy.
I updated the patch as per your suggestions.
Quoted 8 lines
kexec invokes
plpar_hcallhypervisor call in real mode.plpar_hcallrefers per cpu variable for accounting hypervisor statistics. These variables may not be present in the RMO region. So it results in0x300exception.The following patch fixes this problem by using raw hypervisor call which does not update the hypervisor call statistics. Thanks to Anton for suggesting this idea.
This seems like a lot of code for a very slight variation on an existing call. But I guess its cleaner than doing an "if" inside the assembler.
Funtionality-wise, it seems fine to me. Though I am most defianatly not an authority on power.
I have put a minor comment inline.
Quoted 14 lines
Cc Anton Blanchard <[email protected]>Signed-off-by Mohan Kumar M <[email protected]>--- arch/powerpc/platforms/pseries/hvCall.S | 34 ++++++++++++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 2 - arch/powerpc/platforms/pseries/plpar_wrappers.h | 16 +++++++++++ include/asm-powerpc/hvcall.h | 14 +++++++++ 4 files changed, 65 insertions(+), 1 deletion(-)Index:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/hvCall.S
===================================================================
arch/powerpc/platforms/pseries/hvCall.S _GLOBAL(plpar_hcall) · line 131
Quoted 9 lines
arch/powerpc/platforms/pseries/hvCall.S +6
-0@@ -123,6 +123,40 @@ _GLOBAL(plpar_hcall) blr /* return r3 = status */ +/* + * plpar_hcall_raw can be called in real mode. kexec/kdump need some + * hypervisor calls to be executed in real mode. So plpar_hcall_raw + * does not access the per cpu hypervisor call statistics variables, + * since these variables may not be present in the RMO region. + */
This text makes a little more sense to me:
/*
* plpar_hcall_raw may be called in real mode. In particular this may occur
* during kexec/kdump. plpar_hcall_raw is a variation of plpar_hcall that
* does not access the per cpu hypervisor call statistics variables, as
* these variables may not be present in the RMO region.
*/
Signature · 3 lines
Horms H: http://www.vergenet.net/~horms/ W: http://www.valinux.co.jp/en/
Quoted 100 lines
arch/powerpc/platforms/pseries/hvCall.S +28
-0+_GLOBAL(plpar_hcall_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + + HVSC /* invoke the hypervisor */ + + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ + _GLOBAL(plpar_hcall9) HMT_MEDIUMIndex:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/lpar.c
===================================================================arch/powerpc/platforms/pseries/lpar.c +1
-1@@ -378,7 +378,7 @@ static void pSeries_lpar_hptab_clear(voi/* TODO: Use bulk call */ for (i =0 ; i < hpte_count; i++) -plpar_pte_remove (0 , i,0 , &dummy1, &dummy2); +plpar_pte_remove_raw (0 , i,0 , &dummy1, &dummy2); }/* Index:
linux-2.6.21-rc4/arch/powerpc/platforms/pseries/plpar_wrappers.h
===================================================================arch/powerpc/platforms/pseries/plpar_wrappers.h +16
-0@@ -78,6 +78,22 @@ static inline long plpar_pte_remove(unsireturn rc; } +/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */ +static inline long plpar_pte_remove_raw (unsigned long flags,unsigned long ptex, +unsigned long avpn,unsigned long *old_pteh_ret, +unsigned long *old_ptel_ret) +{ +long rc; +unsigned long retbuf[PLPAR_HCALL_BUFSIZE ]; + + rc =plpar_hcall_raw (H_REMOVE , retbuf, flags, ptex, avpn); + + *old_pteh_ret = retbuf[0 ]; + *old_ptel_ret = retbuf[1 ]; + +return rc; +} +static inline long plpar_pte_read (unsigned long flags,unsigned long ptex,unsigned long *old_pteh_ret,unsigned long *old_ptel_ret) {Index:
linux-2.6.21-rc4/include/asm-powerpc/hvcall.h
===================================================================include/asm-powerpc/hvcall.h +14
-0@@ -237,6 +237,20 @@ long plpar_hcall_norets(unsigned long oplong plpar_hcall (unsigned long opcode,unsigned long *retbuf, ...);/** +* plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats +* @opcode: The hypervisor call to make. +* @retbuf: Buffer to store up to 4 return arguments in. +* +* This call supports up to 6 arguments and 4 return arguments. Use +* PLPAR_HCALL_BUFSIZE to size the return argument buffer. +* +* Used when phyp interface needs to be called in real mode. Similar to +* plpar_hcall, but plpar_hcall_raw works in real mode and does not +* calculate hypervisor call statistics. +*/ +long plpar_hcall_raw (unsigned long opcode,unsigned long *retbuf, ...); + +/** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments * @opcode: The hypervisor call to make. * @retbuf: Buffer to store up to 9 return arguments in. _______________________________________________
fastboot mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/fastboot