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