root/drivers/watchdog/diag288_wdt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __diag288
  2. __diag288_vm
  3. __diag288_lpar
  4. wdt_start
  5. wdt_stop
  6. wdt_ping
  7. wdt_set_timeout
  8. wdt_suspend
  9. wdt_resume
  10. wdt_power_event
  11. diag288_init
  12. diag288_exit

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

/* [<][>][^][v][top][bottom][index][help] */