.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Watchdog driver for z/VM and LPAR using the diag 288 interface. |
---|
3 | 4 | * |
---|
.. | .. |
---|
25 | 26 | #include <linux/module.h> |
---|
26 | 27 | #include <linux/moduleparam.h> |
---|
27 | 28 | #include <linux/slab.h> |
---|
28 | | -#include <linux/miscdevice.h> |
---|
29 | 29 | #include <linux/watchdog.h> |
---|
30 | 30 | #include <linux/suspend.h> |
---|
31 | 31 | #include <asm/ebcdic.h> |
---|
32 | 32 | #include <asm/diag.h> |
---|
33 | 33 | #include <linux/io.h> |
---|
34 | | -#include <linux/uaccess.h> |
---|
35 | 34 | |
---|
36 | 35 | #define MAX_CMDLEN 240 |
---|
37 | 36 | #define DEFAULT_CMD "SYSTEM RESTART" |
---|
.. | .. |
---|
69 | 68 | module_param_named(nowayout, nowayout_info, bool, 0444); |
---|
70 | 69 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default = CONFIG_WATCHDOG_NOWAYOUT)"); |
---|
71 | 70 | |
---|
72 | | -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
---|
73 | 71 | MODULE_ALIAS("vmwatchdog"); |
---|
74 | 72 | |
---|
75 | 73 | static int __diag288(unsigned int func, unsigned int timeout, |
---|
.. | .. |
---|
88 | 86 | "1:\n" |
---|
89 | 87 | EX_TABLE(0b, 1b) |
---|
90 | 88 | : "+d" (err) : "d"(__func), "d"(__timeout), |
---|
91 | | - "d"(__action), "d"(__len) : "1", "cc"); |
---|
| 89 | + "d"(__action), "d"(__len) : "1", "cc", "memory"); |
---|
92 | 90 | return err; |
---|
93 | 91 | } |
---|
94 | 92 | |
---|
.. | .. |
---|
274 | 272 | char ebc_begin[] = { |
---|
275 | 273 | 194, 197, 199, 201, 213 |
---|
276 | 274 | }; |
---|
| 275 | + char *ebc_cmd; |
---|
277 | 276 | |
---|
278 | 277 | watchdog_set_nowayout(&wdt_dev, nowayout_info); |
---|
279 | 278 | |
---|
280 | 279 | if (MACHINE_IS_VM) { |
---|
281 | | - if (__diag288_vm(WDT_FUNC_INIT, 15, |
---|
282 | | - ebc_begin, sizeof(ebc_begin)) != 0) { |
---|
| 280 | + ebc_cmd = kmalloc(sizeof(ebc_begin), GFP_KERNEL); |
---|
| 281 | + if (!ebc_cmd) { |
---|
| 282 | + pr_err("The watchdog cannot be initialized\n"); |
---|
| 283 | + return -ENOMEM; |
---|
| 284 | + } |
---|
| 285 | + memcpy(ebc_cmd, ebc_begin, sizeof(ebc_begin)); |
---|
| 286 | + ret = __diag288_vm(WDT_FUNC_INIT, 15, |
---|
| 287 | + ebc_cmd, sizeof(ebc_begin)); |
---|
| 288 | + kfree(ebc_cmd); |
---|
| 289 | + if (ret != 0) { |
---|
283 | 290 | pr_err("The watchdog cannot be initialized\n"); |
---|
284 | 291 | return -EINVAL; |
---|
285 | 292 | } |
---|