diff options
author | Keith Owens <kaos@sgi.com> | 2005-09-11 03:22:53 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-09-11 17:08:41 -0400 |
commit | 7f613c7d2203ae137d98fc1c38abc30fd7048637 (patch) | |
tree | d8155a5cca33e4fe178625396886fcbb81f39e7a /arch/ia64/kernel/mca_drv.c | |
parent | 289d773ee89ea80dcc364ef97d1be7ad1817387e (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.c | 37 |
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) */ |
39 | static int sal_rec_max = 10000; | 41 | static int sal_rec_max = 10000; |
40 | 42 | ||
41 | /* from mca.c */ | ||
42 | static ia64_mca_sal_to_os_state_t *sal_to_os_handoff_state; | ||
43 | static 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 */ |
46 | extern void *mca_handler_bhhook(void); | 44 | extern void *mca_handler_bhhook(void); |
47 | 45 | ||
@@ -316,7 +314,8 @@ init_record_index_pools(void) | |||
316 | */ | 314 | */ |
317 | 315 | ||
318 | static mca_type_t | 316 | static mca_type_t |
319 | is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci) | 317 | is_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 | ||
390 | static int | 389 | static int |
391 | recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci) | 390 | recover_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 | ||
461 | static int | 461 | static int |
462 | recover_from_platform_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci) | 462 | recover_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 | ||
510 | static int | 511 | static int |
511 | recover_from_processor_error(int platform, slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci) | 512 | recover_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 | ||
563 | static int | 565 | static int |
564 | mca_try_to_recover(void *rec, | 566 | mca_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 | /* |