From 9e121327b37b751ef66e6f57e2d02dd568955148 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Wed, 11 Jul 2007 10:22:16 -0500 Subject: [IA64] add sn_register_pmi_handler oemcall Add wrapper function to make SN_SAL_REGISTER_PMI_HANDLER ia64_sal_oemcall. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- include/asm-ia64/sn/sn_sal.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include/asm-ia64') diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index d3566a298fa..676b31a08c6 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -32,6 +32,7 @@ #define SN_SAL_NO_FAULT_ZONE_VIRTUAL 0x02000010 #define SN_SAL_NO_FAULT_ZONE_PHYSICAL 0x02000011 #define SN_SAL_PRINT_ERROR 0x02000012 +#define SN_SAL_REGISTER_PMI_HANDLER 0x02000014 #define SN_SAL_SET_ERROR_HANDLING_FEATURES 0x0200001a // reentrant #define SN_SAL_GET_FIT_COMPT 0x0200001b // reentrant #define SN_SAL_GET_SAPIC_INFO 0x0200001d @@ -679,6 +680,25 @@ sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr, return ret_stuff.status; } +/* + * Register or unregister a function to handle a PMI received by a CPU. + * Before calling the registered handler, SAL sets r1 to the value that + * was passed in as the global_pointer. + * + * If the handler pointer is NULL, then the currently registered handler + * will be unregistered. + * + * Returns 0 on success, or a negative value if an error occurred. + */ +static inline int +sn_register_pmi_handler(u64 handler, u64 global_pointer) +{ + struct ia64_sal_retval ret_stuff; + ia64_sal_oemcall(&ret_stuff, SN_SAL_REGISTER_PMI_HANDLER, handler, + global_pointer, 0, 0, 0, 0, 0); + return ret_stuff.status; +} + /* * Change or query the coherence domain for this partition. Each cpu-based * nasid is represented by a bit in an array of 64-bit words: -- cgit v1.2.3 From 1612b18ccb2318563ba51268289dc3271a6052f7 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Fri, 18 May 2007 17:17:17 -0500 Subject: [IA64] Support multiple CPUs going through OS_MCA Linux does not gracefully deal with multiple processors going through OS_MCA aa part of the same MCA event. The first cpu into OS_MCA grabs the ia64_mca_serialize lock. Subsequent cpus wait for that lock, preventing them from reporting in as rendezvoused. The first cpu waits 5 seconds then complains that all the cpus have not rendezvoused. The first cpu then handles its MCA and frees up all the rendezvoused cpus and releases the ia64_mca_serialize lock. One of the subsequent cpus going thought OS_MCA then gets the ia64_mca_serialize lock, waits another 5 seconds and then complains that none of the other cpus have rendezvoused. This patch allows multiple CPUs to gracefully go through OS_MCA. The first CPU into ia64_mca_handler() grabs a mca_count lock. Subsequent CPUs into ia64_mca_handler() are added to a list of cpus that need to go through OS_MCA (a bit set in mca_cpu), and report in as rendezvoused, and but spin waiting their turn. The first CPU sees everyone rendezvous, handles his MCA, wakes up one of the other CPUs waiting to process their MCA (by clearing one mca_cpu bit), and then waits for the other cpus to complete their MCA handling. The next CPU handles his MCA and the process repeats until all the CPUs have handled their MCA. When the last CPU has handled it's MCA, it sets monarch_cpu to -1, releasing all the CPUs. In testing this works more reliably and faster. Thanks to Keith Owens for suggesting numerous improvements to this code. Signed-off-by: Russ Anderson Signed-off-by: Tony Luck --- include/asm-ia64/mca.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-ia64') diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h index 41098f45968..edd5d01028d 100644 --- a/include/asm-ia64/mca.h +++ b/include/asm-ia64/mca.h @@ -48,6 +48,7 @@ enum { IA64_MCA_RENDEZ_CHECKIN_NOTDONE = 0x0, IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1, IA64_MCA_RENDEZ_CHECKIN_INIT = 0x2, + IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA = 0x3, }; /* Information maintained by the MC infrastructure */ -- cgit v1.2.3