diff options
author | Michael Holzheu <holzheu@linux.vnet.ibm.com> | 2012-03-11 11:59:32 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-03-11 11:59:29 -0400 |
commit | 3ab121ab18669226742891416fe7ecc86dadb047 (patch) | |
tree | 328ef8f1e23da33a475ce4e20c0d0490a2e63e76 /arch/s390/kernel/debug.c | |
parent | fde15c3a3adc7b65cd0610dd6bca4804ee7ffd38 (diff) |
[S390] kernel: Add z/VM LGR detection
Currently the following mechanisms are available to move active
Linux on System z instances between machines:
* z/VM 6.2 SSI (Single System Image)
* Suspend/resume
For moving Linux instances in this patch the term LGR (Linux Guest
Relocation) is used. Because such an operation is critical, it
should be detectable from Linux. With this patch for both, a live
system and a kernel dump, the information about LGRs is accessible.
To identify a guest, stsi and stfle data is used. A new function
lgr_info_log() compares the current data (lgr_info_cur) with the
last recorded one (lgr_info_last). In case the two data sets differ,
lgr_info_cur is logged to the "lgr" s390dbf.
The following trigger points call lgr_info_log():
* panic
* die
* kdump
* LGR timer
* PSW restart
* QDIO recovery
* resume
This patch also changes the s390dbf hex_ascii view. Now only printable ASCII
characters are shown.
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/debug.c')
-rw-r--r-- | arch/s390/kernel/debug.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 6848828b962e..19e5e9eba546 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * arch/s390/kernel/debug.c | 2 | * arch/s390/kernel/debug.c |
3 | * S/390 debug facility | 3 | * S/390 debug facility |
4 | * | 4 | * |
5 | * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, | 5 | * Copyright IBM Corp. 1999, 2012 |
6 | * IBM Corporation | 6 | * |
7 | * Author(s): Michael Holzheu (holzheu@de.ibm.com), | 7 | * Author(s): Michael Holzheu (holzheu@de.ibm.com), |
8 | * Holger Smolinski (Holger.Smolinski@de.ibm.com) | 8 | * Holger Smolinski (Holger.Smolinski@de.ibm.com) |
9 | * | 9 | * |
@@ -167,6 +167,7 @@ static debug_info_t *debug_area_last = NULL; | |||
167 | static DEFINE_MUTEX(debug_mutex); | 167 | static DEFINE_MUTEX(debug_mutex); |
168 | 168 | ||
169 | static int initialized; | 169 | static int initialized; |
170 | static int debug_critical; | ||
170 | 171 | ||
171 | static const struct file_operations debug_file_ops = { | 172 | static const struct file_operations debug_file_ops = { |
172 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
@@ -932,6 +933,11 @@ debug_stop_all(void) | |||
932 | } | 933 | } |
933 | 934 | ||
934 | 935 | ||
936 | void debug_set_critical(void) | ||
937 | { | ||
938 | debug_critical = 1; | ||
939 | } | ||
940 | |||
935 | /* | 941 | /* |
936 | * debug_event_common: | 942 | * debug_event_common: |
937 | * - write debug entry with given size | 943 | * - write debug entry with given size |
@@ -945,7 +951,11 @@ debug_event_common(debug_info_t * id, int level, const void *buf, int len) | |||
945 | 951 | ||
946 | if (!debug_active || !id->areas) | 952 | if (!debug_active || !id->areas) |
947 | return NULL; | 953 | return NULL; |
948 | spin_lock_irqsave(&id->lock, flags); | 954 | if (debug_critical) { |
955 | if (!spin_trylock_irqsave(&id->lock, flags)) | ||
956 | return NULL; | ||
957 | } else | ||
958 | spin_lock_irqsave(&id->lock, flags); | ||
949 | active = get_active_entry(id); | 959 | active = get_active_entry(id); |
950 | memset(DEBUG_DATA(active), 0, id->buf_size); | 960 | memset(DEBUG_DATA(active), 0, id->buf_size); |
951 | memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); | 961 | memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); |
@@ -968,7 +978,11 @@ debug_entry_t | |||
968 | 978 | ||
969 | if (!debug_active || !id->areas) | 979 | if (!debug_active || !id->areas) |
970 | return NULL; | 980 | return NULL; |
971 | spin_lock_irqsave(&id->lock, flags); | 981 | if (debug_critical) { |
982 | if (!spin_trylock_irqsave(&id->lock, flags)) | ||
983 | return NULL; | ||
984 | } else | ||
985 | spin_lock_irqsave(&id->lock, flags); | ||
972 | active = get_active_entry(id); | 986 | active = get_active_entry(id); |
973 | memset(DEBUG_DATA(active), 0, id->buf_size); | 987 | memset(DEBUG_DATA(active), 0, id->buf_size); |
974 | memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); | 988 | memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); |
@@ -1013,7 +1027,11 @@ debug_sprintf_event(debug_info_t* id, int level,char *string,...) | |||
1013 | return NULL; | 1027 | return NULL; |
1014 | numargs=debug_count_numargs(string); | 1028 | numargs=debug_count_numargs(string); |
1015 | 1029 | ||
1016 | spin_lock_irqsave(&id->lock, flags); | 1030 | if (debug_critical) { |
1031 | if (!spin_trylock_irqsave(&id->lock, flags)) | ||
1032 | return NULL; | ||
1033 | } else | ||
1034 | spin_lock_irqsave(&id->lock, flags); | ||
1017 | active = get_active_entry(id); | 1035 | active = get_active_entry(id); |
1018 | curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active); | 1036 | curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active); |
1019 | va_start(ap,string); | 1037 | va_start(ap,string); |
@@ -1047,7 +1065,11 @@ debug_sprintf_exception(debug_info_t* id, int level,char *string,...) | |||
1047 | 1065 | ||
1048 | numargs=debug_count_numargs(string); | 1066 | numargs=debug_count_numargs(string); |
1049 | 1067 | ||
1050 | spin_lock_irqsave(&id->lock, flags); | 1068 | if (debug_critical) { |
1069 | if (!spin_trylock_irqsave(&id->lock, flags)) | ||
1070 | return NULL; | ||
1071 | } else | ||
1072 | spin_lock_irqsave(&id->lock, flags); | ||
1051 | active = get_active_entry(id); | 1073 | active = get_active_entry(id); |
1052 | curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active); | 1074 | curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active); |
1053 | va_start(ap,string); | 1075 | va_start(ap,string); |
@@ -1428,10 +1450,10 @@ debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | |||
1428 | rc += sprintf(out_buf + rc, "| "); | 1450 | rc += sprintf(out_buf + rc, "| "); |
1429 | for (i = 0; i < id->buf_size; i++) { | 1451 | for (i = 0; i < id->buf_size; i++) { |
1430 | unsigned char c = in_buf[i]; | 1452 | unsigned char c = in_buf[i]; |
1431 | if (!isprint(c)) | 1453 | if (isascii(c) && isprint(c)) |
1432 | rc += sprintf(out_buf + rc, "."); | ||
1433 | else | ||
1434 | rc += sprintf(out_buf + rc, "%c", c); | 1454 | rc += sprintf(out_buf + rc, "%c", c); |
1455 | else | ||
1456 | rc += sprintf(out_buf + rc, "."); | ||
1435 | } | 1457 | } |
1436 | rc += sprintf(out_buf + rc, "\n"); | 1458 | rc += sprintf(out_buf + rc, "\n"); |
1437 | return rc; | 1459 | return rc; |