linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc/pseries: Pass CPPR value to H_XIRR hcall
@ 2010-02-01  6:12 Mark Nelson
  2010-02-08  2:45 ` powerpc/pseries: Fix kexec regression caused by CPPR tracking Mark Nelson
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Nelson @ 2010-02-01  6:12 UTC (permalink / raw)
  To: linuxppc-dev

Now that we properly keep track of the CPPR value (since
49bd3647134ea47420067aea8d1401e722bf2aac, "powerpc/pseries: Track previous
CPPR values to correctly EOI interrupts") we can pass it to the
H_XIRR hcall.

This is needed because the Partition Adjunct Option of new versions of
pHyp extend the H_XIRR hcall to include the CPPR as an input parameter.
Earlier versions not supporting this option just disregard the extra
input parameter, so this doesn't cause any problems for existing systems.

The Partition Adjunct Option is required for future systems that will
support SR-IOV capable devices.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
 arch/powerpc/platforms/pseries/plpar_wrappers.h |    4 ++--
 arch/powerpc/platforms/pseries/xics.c           |    7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

Index: upstream/arch/powerpc/platforms/pseries/plpar_wrappers.h
===================================================================
--- upstream.orig/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ upstream/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -259,12 +259,12 @@ static inline long plpar_ipi(unsigned lo
 	return plpar_hcall_norets(H_IPI, servernum, mfrr);
 }
 
-static inline long plpar_xirr(unsigned long *xirr_ret)
+static inline long plpar_xirr(unsigned long *xirr_ret, unsigned char cppr)
 {
 	long rc;
 	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 
-	rc = plpar_hcall(H_XIRR, retbuf);
+	rc = plpar_hcall(H_XIRR, retbuf, cppr);
 
 	*xirr_ret = retbuf[0];
 
Index: upstream/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/pseries/xics.c
+++ upstream/arch/powerpc/platforms/pseries/xics.c
@@ -120,12 +120,12 @@ static inline void direct_qirr_info(int 
 
 /* LPAR low level accessors */
 
-static inline unsigned int lpar_xirr_info_get(void)
+static inline unsigned int lpar_xirr_info_get(unsigned char cppr)
 {
 	unsigned long lpar_rc;
 	unsigned long return_value;
 
-	lpar_rc = plpar_xirr(&return_value);
+	lpar_rc = plpar_xirr(&return_value, cppr);
 	if (lpar_rc != H_SUCCESS)
 		panic(" bad return code xirr - rc = %lx \n", lpar_rc);
 	return (unsigned int)return_value;
@@ -335,7 +335,8 @@ static unsigned int xics_get_irq_direct(
 
 static unsigned int xics_get_irq_lpar(void)
 {
-	unsigned int xirr = lpar_xirr_info_get();
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+	unsigned int xirr = lpar_xirr_info_get(os_cppr->stack[os_cppr->index]);
 	unsigned int vec = xics_xirr_vector(xirr);
 	unsigned int irq;
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* powerpc/pseries: Fix kexec regression caused by CPPR tracking
  2010-02-01  6:12 [PATCH] powerpc/pseries: Pass CPPR value to H_XIRR hcall Mark Nelson
@ 2010-02-08  2:45 ` Mark Nelson
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Nelson @ 2010-02-08  2:45 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Anton Blanchard

The code to track the CPPR values added by commit
49bd3647134ea47420067aea8d1401e722bf2aac ("powerpc/pseries: Track previous
CPPR values to correctly EOI interrupts") broke kexec on pseries because
the kexec code in xics.c calls xics_set_cpu_priority() before the IPI has
been EOI'ed. This wasn't a problem previously but it now triggers a BUG_ON
in xics_set_cpu_priority() because os_cppr->index isn't 0:

Oops: Exception in kernel mode, sig: 5 [#1]             
SMP NR_CPUS=128 NUMA                                    
kernel BUG at arch/powerpc/platforms/pseries/xics.c:791!
pSeries                                                 
Modules linked in: ehea dm_mirror dm_region_hash dm_log dm_zero dm_snapshot parport_pc parport dm_multipath autofs4
NIP: c0000000000461bc LR: c000000000046260 CTR: c00000000004bc08                                                   
REGS: c00000000fffb770 TRAP: 0700   Not tainted  (2.6.33-rc6-autokern1)                                            
MSR: 8000000000021032 <ME,CE,IR,DR>  CR: 48000022  XER: 00000001                                                   
TASK = c000000000aef700[0] 'swapper' THREAD: c000000000bcc000 CPU: 0                                               
GPR00: 0000000000000001 c00000000fffb9f0 c000000000bcc9e8 0000000000000000                                         
GPR04: 0000000000000000 0000000000000000 00000000000000dc 0000000000000002                                         
GPR08: c0000000040036e8 c000000004002e40 0000000000000898 0000000000000000                                         
GPR12: 0000000000000002 c000000000bf8480 0000000003500000 c000000000792f28                                         
GPR16: c0000000007915e0 0000000000000000 0000000000419000 0000000003da8990                                         
GPR20: c0000000008a8990 0000000000000010 c000000000ae92c0 0000000000000010                                         
GPR24: 0000000000000000 c000000000be2380 0000000000000000 0000000000200200                                         
GPR28: 0000000000000001 0000000000000001 c000000000b249e8 0000000000000000                                         
NIP [c0000000000461bc] .xics_set_cpu_priority+0x38/0xb8                                                            
LR [c000000000046260] .xics_teardown_cpu+0x24/0xa4                                                                 
Call Trace:                                                                                                        
[c00000000fffb9f0] [00000000ffffebf3] 0xffffebf3 (unreliable)                                                      
[c00000000fffba60] [c000000000046260] .xics_teardown_cpu+0x24/0xa4                                                 
[c00000000fffbae0] [c000000000046330] .xics_kexec_teardown_cpu+0x18/0xb4                                           
[c00000000fffbb60] [c00000000004a150] .pseries_kexec_cpu_down_xics+0x20/0x38                                       
[c00000000fffbbf0] [c00000000002e5b8] .kexec_smp_down+0x48/0x7c                                                    
[c00000000fffbc70] [c0000000000b2dd0] .generic_smp_call_function_interrupt+0xf4/0x1b4                              
[c00000000fffbd20] [c00000000002aed0] .smp_message_recv+0x48/0x100                                                 
[c00000000fffbda0] [c000000000046ae0] .xics_ipi_dispatch+0x84/0x148                                                
[c00000000fffbe30] [c0000000000d62dc] .handle_IRQ_event+0xc8/0x248                                                 
[c00000000fffbf00] [c0000000000d8eb4] .handle_percpu_irq+0x80/0xf4                                                 
[c00000000fffbf90] [c000000000029048] .call_handle_irq+0x1c/0x2c                                                   
[c000000000bcfa30] [c00000000000ec84] .do_IRQ+0x1b8/0x2a4                                                          
[c000000000bcfae0] [c000000000004804] hardware_interrupt_entry+0x1c/0x98

Fix this problem by setting the index on the CPPR stack to 0 before calling
xics_set_cpu_priority() in xics_teardown_cpu().

Also make it clear that we only want to set the priority when there's just
one CPPR value in the stack, and enforce it by updating the value of
os_cppr->stack[0] rather than os_cppr->stack[os_cppr->index].

While we're at it change the BUG_ON to a WARN_ON.

Reported-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
Ben, if it's not too late for 2.6.33 this would be really nice to have
as without it we can't kexec on pseries.

 arch/powerpc/platforms/pseries/xics.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Index: upstream/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- upstream.orig/arch/powerpc/platforms/pseries/xics.c
+++ upstream/arch/powerpc/platforms/pseries/xics.c
@@ -784,9 +784,13 @@ static void xics_set_cpu_priority(unsign
 {
 	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
 
-	BUG_ON(os_cppr->index != 0);
+	/*
+	 * we only really want to set the priority when there's
+	 * just one cppr value on the stack
+	 */
+	WARN_ON(os_cppr->index != 0);
 
-	os_cppr->stack[os_cppr->index] = cppr;
+	os_cppr->stack[0] = cppr;
 
 	if (firmware_has_feature(FW_FEATURE_LPAR))
 		lpar_cppr_info(cppr);
@@ -821,8 +825,14 @@ void xics_setup_cpu(void)
 
 void xics_teardown_cpu(void)
 {
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
 	int cpu = smp_processor_id();
 
+	/*
+	 * we have to reset the cppr index to 0 because we're
+	 * not going to return from the IPI
+	 */
+	os_cppr->index = 0;
 	xics_set_cpu_priority(0);
 
 	/* Clear any pending IPI request */

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-02-08  2:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-01  6:12 [PATCH] powerpc/pseries: Pass CPPR value to H_XIRR hcall Mark Nelson
2010-02-08  2:45 ` powerpc/pseries: Fix kexec regression caused by CPPR tracking Mark Nelson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).