aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/mca_drv.c
diff options
context:
space:
mode:
authorKeith Owens <kaos@sgi.com>2005-09-11 03:22:53 -0400
committerTony Luck <tony.luck@intel.com>2005-09-11 17:08:41 -0400
commit7f613c7d2203ae137d98fc1c38abc30fd7048637 (patch)
treed8155a5cca33e4fe178625396886fcbb81f39e7a /arch/ia64/kernel/mca_drv.c
parent289d773ee89ea80dcc364ef97d1be7ad1817387e (diff)
[PATCH] MCA/INIT: use per cpu stacks
The bulk of the change. Use per cpu MCA/INIT stacks. Change the SAL to OS state (sos) to be per process. Do all the assembler work on the MCA/INIT stacks, leaving the original stack alone. Pass per cpu state data to the C handlers for MCA and INIT, which also means changing the mca_drv interfaces slightly. Lots of verification on whether the original stack is usable before converting it to a sleeping process. Signed-off-by: Keith Owens <kaos@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/mca_drv.c')
-rw-r--r--arch/ia64/kernel/mca_drv.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index abc0113a821d..6e683745af49 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -4,6 +4,8 @@
4 * 4 *
5 * Copyright (C) 2004 FUJITSU LIMITED 5 * Copyright (C) 2004 FUJITSU LIMITED
6 * Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com) 6 * Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com)
7 * Copyright (C) 2005 Silicon Graphics, Inc
8 * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
7 */ 9 */
8#include <linux/config.h> 10#include <linux/config.h>
9#include <linux/types.h> 11#include <linux/types.h>
@@ -38,10 +40,6 @@
38/* max size of SAL error record (default) */ 40/* max size of SAL error record (default) */
39static int sal_rec_max = 10000; 41static int sal_rec_max = 10000;
40 42
41/* from mca.c */
42static ia64_mca_sal_to_os_state_t *sal_to_os_handoff_state;
43static ia64_mca_os_to_sal_state_t *os_to_sal_handoff_state;
44
45/* from mca_drv_asm.S */ 43/* from mca_drv_asm.S */
46extern void *mca_handler_bhhook(void); 44extern void *mca_handler_bhhook(void);
47 45
@@ -316,7 +314,8 @@ init_record_index_pools(void)
316 */ 314 */
317 315
318static mca_type_t 316static mca_type_t
319is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci) 317is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
318 struct ia64_sal_os_state *sos)
320{ 319{
321 pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx); 320 pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx);
322 321
@@ -327,7 +326,7 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci)
327 * Therefore it is local MCA when rendezvous has not been requested. 326 * Therefore it is local MCA when rendezvous has not been requested.
328 * Failed to rendezvous, the system must be down. 327 * Failed to rendezvous, the system must be down.
329 */ 328 */
330 switch (sal_to_os_handoff_state->imsto_rendez_state) { 329 switch (sos->rv_rc) {
331 case -1: /* SAL rendezvous unsuccessful */ 330 case -1: /* SAL rendezvous unsuccessful */
332 return MCA_IS_GLOBAL; 331 return MCA_IS_GLOBAL;
333 case 0: /* SAL rendezvous not required */ 332 case 0: /* SAL rendezvous not required */
@@ -388,7 +387,8 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci)
388 */ 387 */
389 388
390static int 389static int
391recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci) 390recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci,
391 struct ia64_sal_os_state *sos)
392{ 392{
393 sal_log_mod_error_info_t *smei; 393 sal_log_mod_error_info_t *smei;
394 pal_min_state_area_t *pmsa; 394 pal_min_state_area_t *pmsa;
@@ -426,7 +426,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
426 * setup for resume to bottom half of MCA, 426 * setup for resume to bottom half of MCA,
427 * "mca_handler_bhhook" 427 * "mca_handler_bhhook"
428 */ 428 */
429 pmsa = (pal_min_state_area_t *)(sal_to_os_handoff_state->pal_min_state | (6ul<<61)); 429 pmsa = sos->pal_min_state;
430 /* pass to bhhook as 1st argument (gr8) */ 430 /* pass to bhhook as 1st argument (gr8) */
431 pmsa->pmsa_gr[8-1] = smei->target_identifier; 431 pmsa->pmsa_gr[8-1] = smei->target_identifier;
432 /* set interrupted return address (but no use) */ 432 /* set interrupted return address (but no use) */
@@ -459,7 +459,8 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec
459 */ 459 */
460 460
461static int 461static int
462recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci) 462recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci,
463 struct ia64_sal_os_state *sos)
463{ 464{
464 int status = 0; 465 int status = 0;
465 pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx); 466 pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx);
@@ -469,7 +470,7 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_
469 case 1: /* partial read */ 470 case 1: /* partial read */
470 case 3: /* full line(cpu) read */ 471 case 3: /* full line(cpu) read */
471 case 9: /* I/O space read */ 472 case 9: /* I/O space read */
472 status = recover_from_read_error(slidx, peidx, pbci); 473 status = recover_from_read_error(slidx, peidx, pbci, sos);
473 break; 474 break;
474 case 0: /* unknown */ 475 case 0: /* unknown */
475 case 2: /* partial write */ 476 case 2: /* partial write */
@@ -508,7 +509,8 @@ recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_
508 */ 509 */
509 510
510static int 511static int
511recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci) 512recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci,
513 struct ia64_sal_os_state *sos)
512{ 514{
513 pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx); 515 pal_processor_state_info_t *psp = (pal_processor_state_info_t*)peidx_psp(peidx);
514 516
@@ -545,7 +547,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *
545 * This means "there are some platform errors". 547 * This means "there are some platform errors".
546 */ 548 */
547 if (platform) 549 if (platform)
548 return recover_from_platform_error(slidx, peidx, pbci); 550 return recover_from_platform_error(slidx, peidx, pbci, sos);
549 /* 551 /*
550 * On account of strange SAL error record, we cannot recover. 552 * On account of strange SAL error record, we cannot recover.
551 */ 553 */
@@ -562,8 +564,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *
562 564
563static int 565static int
564mca_try_to_recover(void *rec, 566mca_try_to_recover(void *rec,
565 ia64_mca_sal_to_os_state_t *sal_to_os_state, 567 struct ia64_sal_os_state *sos)
566 ia64_mca_os_to_sal_state_t *os_to_sal_state)
567{ 568{
568 int platform_err; 569 int platform_err;
569 int n_proc_err; 570 int n_proc_err;
@@ -571,10 +572,6 @@ mca_try_to_recover(void *rec,
571 peidx_table_t peidx; 572 peidx_table_t peidx;
572 pal_bus_check_info_t pbci; 573 pal_bus_check_info_t pbci;
573 574
574 /* handoff state from/to mca.c */
575 sal_to_os_handoff_state = sal_to_os_state;
576 os_to_sal_handoff_state = os_to_sal_state;
577
578 /* Make index of SAL error record */ 575 /* Make index of SAL error record */
579 platform_err = mca_make_slidx(rec, &slidx); 576 platform_err = mca_make_slidx(rec, &slidx);
580 577
@@ -597,11 +594,11 @@ mca_try_to_recover(void *rec,
597 *((u64*)&pbci) = peidx_check_info(&peidx, bus_check, 0); 594 *((u64*)&pbci) = peidx_check_info(&peidx, bus_check, 0);
598 595
599 /* Check whether MCA is global or not */ 596 /* Check whether MCA is global or not */
600 if (is_mca_global(&peidx, &pbci)) 597 if (is_mca_global(&peidx, &pbci, sos))
601 return 0; 598 return 0;
602 599
603 /* Try to recover a processor error */ 600 /* Try to recover a processor error */
604 return recover_from_processor_error(platform_err, &slidx, &peidx, &pbci); 601 return recover_from_processor_error(platform_err, &slidx, &peidx, &pbci, sos);
605} 602}
606 603
607/* 604/*