diff options
author | Frank Munzert <munzert@de.ibm.com> | 2009-03-26 10:23:43 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:03 -0400 |
commit | 099b765139929efdcf232f8870804accf8c4cdc5 (patch) | |
tree | 9869bb629def6f49d5d3b82e8e0b301cabbc1b8c /drivers/s390 | |
parent | d7fd5f1e3b195a8232b3ed768ac2809ddce8ca46 (diff) |
[S390] Automatic IPL after dump
Provide new shutdown action "dump_reipl" for automatic ipl after dump.
Signed-off-by: Frank Munzert <munzert@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/char/zcore.c | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index eefc6611412e..cfe782ee6473 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * For more information please refer to Documentation/s390/zfcpdump.txt | 6 | * For more information please refer to Documentation/s390/zfcpdump.txt |
7 | * | 7 | * |
8 | * Copyright IBM Corp. 2003,2007 | 8 | * Copyright IBM Corp. 2003,2008 |
9 | * Author(s): Michael Holzheu | 9 | * Author(s): Michael Holzheu |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -48,12 +48,19 @@ struct sys_info { | |||
48 | union save_area lc_mask; | 48 | union save_area lc_mask; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | struct ipib_info { | ||
52 | unsigned long ipib; | ||
53 | u32 checksum; | ||
54 | } __attribute__((packed)); | ||
55 | |||
51 | static struct sys_info sys_info; | 56 | static struct sys_info sys_info; |
52 | static struct debug_info *zcore_dbf; | 57 | static struct debug_info *zcore_dbf; |
53 | static int hsa_available; | 58 | static int hsa_available; |
54 | static struct dentry *zcore_dir; | 59 | static struct dentry *zcore_dir; |
55 | static struct dentry *zcore_file; | 60 | static struct dentry *zcore_file; |
56 | static struct dentry *zcore_memmap_file; | 61 | static struct dentry *zcore_memmap_file; |
62 | static struct dentry *zcore_reipl_file; | ||
63 | static struct ipl_parameter_block *ipl_block; | ||
57 | 64 | ||
58 | /* | 65 | /* |
59 | * Copy memory from HSA to kernel or user memory (not reentrant): | 66 | * Copy memory from HSA to kernel or user memory (not reentrant): |
@@ -527,6 +534,33 @@ static const struct file_operations zcore_memmap_fops = { | |||
527 | .release = zcore_memmap_release, | 534 | .release = zcore_memmap_release, |
528 | }; | 535 | }; |
529 | 536 | ||
537 | static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf, | ||
538 | size_t count, loff_t *ppos) | ||
539 | { | ||
540 | if (ipl_block) { | ||
541 | diag308(DIAG308_SET, ipl_block); | ||
542 | diag308(DIAG308_IPL, NULL); | ||
543 | } | ||
544 | return count; | ||
545 | } | ||
546 | |||
547 | static int zcore_reipl_open(struct inode *inode, struct file *filp) | ||
548 | { | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | static int zcore_reipl_release(struct inode *inode, struct file *filp) | ||
553 | { | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static const struct file_operations zcore_reipl_fops = { | ||
558 | .owner = THIS_MODULE, | ||
559 | .write = zcore_reipl_write, | ||
560 | .open = zcore_reipl_open, | ||
561 | .release = zcore_reipl_release, | ||
562 | }; | ||
563 | |||
530 | 564 | ||
531 | static void __init set_s390_lc_mask(union save_area *map) | 565 | static void __init set_s390_lc_mask(union save_area *map) |
532 | { | 566 | { |
@@ -645,6 +679,39 @@ static int __init zcore_header_init(int arch, struct zcore_header *hdr) | |||
645 | return 0; | 679 | return 0; |
646 | } | 680 | } |
647 | 681 | ||
682 | /* | ||
683 | * Provide IPL parameter information block from either HSA or memory | ||
684 | * for future reipl | ||
685 | */ | ||
686 | static int __init zcore_reipl_init(void) | ||
687 | { | ||
688 | struct ipib_info ipib_info; | ||
689 | int rc; | ||
690 | |||
691 | rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info)); | ||
692 | if (rc) | ||
693 | return rc; | ||
694 | if (ipib_info.ipib == 0) | ||
695 | return 0; | ||
696 | ipl_block = (void *) __get_free_page(GFP_KERNEL); | ||
697 | if (!ipl_block) | ||
698 | return -ENOMEM; | ||
699 | if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) | ||
700 | rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); | ||
701 | else | ||
702 | rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE); | ||
703 | if (rc) { | ||
704 | free_page((unsigned long) ipl_block); | ||
705 | return rc; | ||
706 | } | ||
707 | if (cksm(ipl_block, ipl_block->hdr.len) != ipib_info.checksum) { | ||
708 | TRACE("Checksum does not match\n"); | ||
709 | free_page((unsigned long) ipl_block); | ||
710 | ipl_block = NULL; | ||
711 | } | ||
712 | return 0; | ||
713 | } | ||
714 | |||
648 | static int __init zcore_init(void) | 715 | static int __init zcore_init(void) |
649 | { | 716 | { |
650 | unsigned char arch; | 717 | unsigned char arch; |
@@ -690,6 +757,10 @@ static int __init zcore_init(void) | |||
690 | if (rc) | 757 | if (rc) |
691 | goto fail; | 758 | goto fail; |
692 | 759 | ||
760 | rc = zcore_reipl_init(); | ||
761 | if (rc) | ||
762 | goto fail; | ||
763 | |||
693 | zcore_dir = debugfs_create_dir("zcore" , NULL); | 764 | zcore_dir = debugfs_create_dir("zcore" , NULL); |
694 | if (!zcore_dir) { | 765 | if (!zcore_dir) { |
695 | rc = -ENOMEM; | 766 | rc = -ENOMEM; |
@@ -707,9 +778,17 @@ static int __init zcore_init(void) | |||
707 | rc = -ENOMEM; | 778 | rc = -ENOMEM; |
708 | goto fail_file; | 779 | goto fail_file; |
709 | } | 780 | } |
781 | zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, | ||
782 | NULL, &zcore_reipl_fops); | ||
783 | if (!zcore_reipl_file) { | ||
784 | rc = -ENOMEM; | ||
785 | goto fail_memmap_file; | ||
786 | } | ||
710 | hsa_available = 1; | 787 | hsa_available = 1; |
711 | return 0; | 788 | return 0; |
712 | 789 | ||
790 | fail_memmap_file: | ||
791 | debugfs_remove(zcore_memmap_file); | ||
713 | fail_file: | 792 | fail_file: |
714 | debugfs_remove(zcore_file); | 793 | debugfs_remove(zcore_file); |
715 | fail_dir: | 794 | fail_dir: |
@@ -723,10 +802,15 @@ static void __exit zcore_exit(void) | |||
723 | { | 802 | { |
724 | debug_unregister(zcore_dbf); | 803 | debug_unregister(zcore_dbf); |
725 | sclp_sdias_exit(); | 804 | sclp_sdias_exit(); |
805 | free_page((unsigned long) ipl_block); | ||
806 | debugfs_remove(zcore_reipl_file); | ||
807 | debugfs_remove(zcore_memmap_file); | ||
808 | debugfs_remove(zcore_file); | ||
809 | debugfs_remove(zcore_dir); | ||
726 | diag308(DIAG308_REL_HSA, NULL); | 810 | diag308(DIAG308_REL_HSA, NULL); |
727 | } | 811 | } |
728 | 812 | ||
729 | MODULE_AUTHOR("Copyright IBM Corp. 2003,2007"); | 813 | MODULE_AUTHOR("Copyright IBM Corp. 2003,2008"); |
730 | MODULE_DESCRIPTION("zcore module for zfcpdump support"); | 814 | MODULE_DESCRIPTION("zcore module for zfcpdump support"); |
731 | MODULE_LICENSE("GPL"); | 815 | MODULE_LICENSE("GPL"); |
732 | 816 | ||