1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Watchdog driver for z/VM and LPAR using the diag 288 interface. 4 * 5 * Under z/VM, expiration of the watchdog will send a "system restart" command 6 * to CP. 7 * 8 * The command can be altered using the module parameter "cmd". This is 9 * not recommended because it's only supported on z/VM but not whith LPAR. 10 * 11 * On LPAR, the watchdog will always trigger a system restart. the module 12 * paramter cmd is meaningless here. 13 * 14 * 15 * Copyright IBM Corp. 2004, 2013 16 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 17 * Philipp Hachtmann (phacht@de.ibm.com) 18 * 19 */ 20 21 #define KMSG_COMPONENT "diag288_wdt" 22 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 23 24 #include <linux/init.h> 25 #include <linux/kernel.h> 26 #include <linux/module.h> 27 #include <linux/moduleparam.h> 28 #include <linux/slab.h> 29 #include <linux/watchdog.h> 30 #include <asm/ebcdic.h> 31 #include <asm/diag.h> 32 #include <linux/io.h> 33 34 #define MAX_CMDLEN 240 35 #define DEFAULT_CMD "SYSTEM RESTART" 36 37 #define MIN_INTERVAL 15 /* Minimal time supported by diag88 */ 38 #define MAX_INTERVAL 3600 /* One hour should be enough - pure estimation */ 39 40 #define WDT_DEFAULT_TIMEOUT 30 41 42 /* Function codes - init, change, cancel */ 43 #define WDT_FUNC_INIT 0 44 #define WDT_FUNC_CHANGE 1 45 #define WDT_FUNC_CANCEL 2 46 #define WDT_FUNC_CONCEAL 0x80000000 47 48 /* Action codes for LPAR watchdog */ 49 #define LPARWDT_RESTART 0 50 51 static char wdt_cmd[MAX_CMDLEN] = DEFAULT_CMD; 52 static bool conceal_on; 53 static bool nowayout_info = WATCHDOG_NOWAYOUT; 54 55 MODULE_LICENSE("GPL"); 56 MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>"); 57 MODULE_AUTHOR("Philipp Hachtmann <phacht@de.ibm.com>"); 58 59 MODULE_DESCRIPTION("System z diag288 Watchdog Timer"); 60 61 module_param_string(cmd, wdt_cmd, MAX_CMDLEN, 0644); 62 MODULE_PARM_DESC(cmd, "CP command that is run when the watchdog triggers (z/VM only)"); 63 64 module_param_named(conceal, conceal_on, bool, 0644); 65 MODULE_PARM_DESC(conceal, "Enable the CONCEAL CP option while the watchdog is active (z/VM only)"); 66 67 module_param_named(nowayout, nowayout_info, bool, 0444); 68 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default = CONFIG_WATCHDOG_NOWAYOUT)"); 69 70 MODULE_ALIAS("vmwatchdog"); 71 72 static int __diag288(unsigned int func, unsigned int timeout, 73 unsigned long action, unsigned int len) 74 { 75 union register_pair r1 = { .even = func, .odd = timeout, }; 76 union register_pair r3 = { .even = action, .odd = len, }; 77 int err; 78 79 err = -EINVAL; 80 asm volatile( 81 " diag %[r1],%[r3],0x288\n" 82 "0: la %[err],0\n" 83 "1:\n" 84 EX_TABLE(0b, 1b) 85 : [err] "+d" (err) 86 : [r1] "d" (r1.pair), [r3] "d" (r3.pair) 87 : "cc", "memory"); 88 return err; 89 } 90 91 static int __diag288_vm(unsigned int func, unsigned int timeout, 92 char *cmd, size_t len) 93 { 94 diag_stat_inc(DIAG_STAT_X288); 95 return __diag288(func, timeout, virt_to_phys(cmd), len); 96 } 97 98 static int __diag288_lpar(unsigned int func, unsigned int timeout, 99 unsigned long action) 100 { 101 diag_stat_inc(DIAG_STAT_X288); 102 return __diag288(func, timeout, action, 0); 103 } 104 105 static int wdt_start(struct watchdog_device *dev) 106 { 107 char *ebc_cmd; 108 size_t len; 109 int ret; 110 unsigned int func; 111 112 if (MACHINE_IS_VM) { 113 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL); 114 if (!ebc_cmd) 115 return -ENOMEM; 116 len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN); 117 ASCEBC(ebc_cmd, MAX_CMDLEN); 118 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN); 119 120 func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL) 121 : WDT_FUNC_INIT; 122 ret = __diag288_vm(func, dev->timeout, ebc_cmd, len); 123 WARN_ON(ret != 0); 124 kfree(ebc_cmd); 125 } else { 126 ret = __diag288_lpar(WDT_FUNC_INIT, 127 dev->timeout, LPARWDT_RESTART); 128 } 129 130 if (ret) { 131 pr_err("The watchdog cannot be activated\n"); 132 return ret; 133 } 134 return 0; 135 } 136 137 static int wdt_stop(struct watchdog_device *dev) 138 { 139 int ret; 140 141 diag_stat_inc(DIAG_STAT_X288); 142 ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0); 143 144 return ret; 145 } 146 147 static int wdt_ping(struct watchdog_device *dev) 148 { 149 char *ebc_cmd; 150 size_t len; 151 int ret; 152 unsigned int func; 153 154 if (MACHINE_IS_VM) { 155 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL); 156 if (!ebc_cmd) 157 return -ENOMEM; 158 len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN); 159 ASCEBC(ebc_cmd, MAX_CMDLEN); 160 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN); 161 162 /* 163 * It seems to be ok to z/VM to use the init function to 164 * retrigger the watchdog. On LPAR WDT_FUNC_CHANGE must 165 * be used when the watchdog is running. 166 */ 167 func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL) 168 : WDT_FUNC_INIT; 169 170 ret = __diag288_vm(func, dev->timeout, ebc_cmd, len); 171 WARN_ON(ret != 0); 172 kfree(ebc_cmd); 173 } else { 174 ret = __diag288_lpar(WDT_FUNC_CHANGE, dev->timeout, 0); 175 } 176 177 if (ret) 178 pr_err("The watchdog timer cannot be started or reset\n"); 179 return ret; 180 } 181 182 static int wdt_set_timeout(struct watchdog_device * dev, unsigned int new_to) 183 { 184 dev->timeout = new_to; 185 return wdt_ping(dev); 186 } 187 188 static const struct watchdog_ops wdt_ops = { 189 .owner = THIS_MODULE, 190 .start = wdt_start, 191 .stop = wdt_stop, 192 .ping = wdt_ping, 193 .set_timeout = wdt_set_timeout, 194 }; 195 196 static const struct watchdog_info wdt_info = { 197 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 198 .firmware_version = 0, 199 .identity = "z Watchdog", 200 }; 201 202 static struct watchdog_device wdt_dev = { 203 .parent = NULL, 204 .info = &wdt_info, 205 .ops = &wdt_ops, 206 .bootstatus = 0, 207 .timeout = WDT_DEFAULT_TIMEOUT, 208 .min_timeout = MIN_INTERVAL, 209 .max_timeout = MAX_INTERVAL, 210 }; 211 212 static int __init diag288_init(void) 213 { 214 int ret; 215 char ebc_begin[] = { 216 194, 197, 199, 201, 213 217 }; 218 char *ebc_cmd; 219 220 watchdog_set_nowayout(&wdt_dev, nowayout_info); 221 222 if (MACHINE_IS_VM) { 223 ebc_cmd = kmalloc(sizeof(ebc_begin), GFP_KERNEL); 224 if (!ebc_cmd) { 225 pr_err("The watchdog cannot be initialized\n"); 226 return -ENOMEM; 227 } 228 memcpy(ebc_cmd, ebc_begin, sizeof(ebc_begin)); 229 ret = __diag288_vm(WDT_FUNC_INIT, 15, 230 ebc_cmd, sizeof(ebc_begin)); 231 kfree(ebc_cmd); 232 if (ret != 0) { 233 pr_err("The watchdog cannot be initialized\n"); 234 return -EINVAL; 235 } 236 } else { 237 if (__diag288_lpar(WDT_FUNC_INIT, 30, LPARWDT_RESTART)) { 238 pr_err("The watchdog cannot be initialized\n"); 239 return -EINVAL; 240 } 241 } 242 243 if (__diag288_lpar(WDT_FUNC_CANCEL, 0, 0)) { 244 pr_err("The watchdog cannot be deactivated\n"); 245 return -EINVAL; 246 } 247 248 return watchdog_register_device(&wdt_dev); 249 } 250 251 static void __exit diag288_exit(void) 252 { 253 watchdog_unregister_device(&wdt_dev); 254 } 255 256 module_init(diag288_init); 257 module_exit(diag288_exit); 258