cio_inject.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * CIO inject interface
  4. *
  5. * Copyright IBM Corp. 2021
  6. * Author(s): Vineeth Vijayan <vneethv@linux.ibm.com>
  7. */
  8. #define KMSG_COMPONENT "cio"
  9. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  10. #include <linux/slab.h>
  11. #include <linux/spinlock.h>
  12. #include <linux/mm.h>
  13. #include <linux/debugfs.h>
  14. #include <asm/chpid.h>
  15. #include "cio_inject.h"
  16. #include "cio_debug.h"
  17. static DEFINE_SPINLOCK(crw_inject_lock);
  18. DEFINE_STATIC_KEY_FALSE(cio_inject_enabled);
  19. static struct crw *crw_inject_data;
  20. /**
  21. * crw_inject : Initiate the artificial CRW inject
  22. * @crw: The data which needs to be injected as new CRW.
  23. *
  24. * The CRW handler is called, which will use the provided artificial
  25. * data instead of the CRW from the underlying hardware.
  26. *
  27. * Return: 0 on success
  28. */
  29. static int crw_inject(struct crw *crw)
  30. {
  31. int rc = 0;
  32. struct crw *copy;
  33. unsigned long flags;
  34. copy = kmemdup(crw, sizeof(*crw), GFP_KERNEL);
  35. if (!copy)
  36. return -ENOMEM;
  37. spin_lock_irqsave(&crw_inject_lock, flags);
  38. if (crw_inject_data) {
  39. kfree(copy);
  40. rc = -EBUSY;
  41. } else {
  42. crw_inject_data = copy;
  43. }
  44. spin_unlock_irqrestore(&crw_inject_lock, flags);
  45. if (!rc)
  46. crw_handle_channel_report();
  47. return rc;
  48. }
  49. /**
  50. * stcrw_get_injected: Copy the artificial CRW data to CRW struct.
  51. * @crw: The target CRW pointer.
  52. *
  53. * Retrieve an injected CRW data. Return 0 on success, 1 if no
  54. * injected-CRW is available. The function reproduces the return
  55. * code of the actual STCRW function.
  56. */
  57. int stcrw_get_injected(struct crw *crw)
  58. {
  59. int rc = 1;
  60. unsigned long flags;
  61. spin_lock_irqsave(&crw_inject_lock, flags);
  62. if (crw_inject_data) {
  63. memcpy(crw, crw_inject_data, sizeof(*crw));
  64. kfree(crw_inject_data);
  65. crw_inject_data = NULL;
  66. rc = 0;
  67. }
  68. spin_unlock_irqrestore(&crw_inject_lock, flags);
  69. return rc;
  70. }
  71. /* The debugfs write handler for crw_inject nodes operation */
  72. static ssize_t crw_inject_write(struct file *file, const char __user *buf,
  73. size_t lbuf, loff_t *ppos)
  74. {
  75. u32 slct, oflw, chn, rsc, anc, erc, rsid;
  76. struct crw crw;
  77. char *buffer;
  78. int rc;
  79. if (!static_branch_likely(&cio_inject_enabled)) {
  80. pr_warn("CIO inject is not enabled - ignoring CRW inject\n");
  81. return -EINVAL;
  82. }
  83. buffer = memdup_user_nul(buf, lbuf);
  84. if (IS_ERR(buffer))
  85. return -ENOMEM;
  86. rc = sscanf(buffer, "%x %x %x %x %x %x %x", &slct, &oflw, &chn, &rsc, &anc,
  87. &erc, &rsid);
  88. kvfree(buffer);
  89. if (rc != 7) {
  90. pr_warn("crw_inject: Invalid format (need <solicited> <overflow> <chaining> <rsc> <ancillary> <erc> <rsid>)\n");
  91. return -EINVAL;
  92. }
  93. memset(&crw, 0, sizeof(crw));
  94. crw.slct = slct;
  95. crw.oflw = oflw;
  96. crw.chn = chn;
  97. crw.rsc = rsc;
  98. crw.anc = anc;
  99. crw.erc = erc;
  100. crw.rsid = rsid;
  101. rc = crw_inject(&crw);
  102. if (rc)
  103. return rc;
  104. return lbuf;
  105. }
  106. /* Debugfs write handler for inject_enable node*/
  107. static ssize_t enable_inject_write(struct file *file, const char __user *buf,
  108. size_t lbuf, loff_t *ppos)
  109. {
  110. unsigned long en = 0;
  111. int rc;
  112. rc = kstrtoul_from_user(buf, lbuf, 10, &en);
  113. if (rc)
  114. return rc;
  115. switch (en) {
  116. case 0:
  117. static_branch_disable(&cio_inject_enabled);
  118. break;
  119. case 1:
  120. static_branch_enable(&cio_inject_enabled);
  121. break;
  122. }
  123. return lbuf;
  124. }
  125. static const struct file_operations crw_fops = {
  126. .owner = THIS_MODULE,
  127. .write = crw_inject_write,
  128. };
  129. static const struct file_operations cio_en_fops = {
  130. .owner = THIS_MODULE,
  131. .write = enable_inject_write,
  132. };
  133. static int __init cio_inject_init(void)
  134. {
  135. /* enable_inject node enables the static branching */
  136. debugfs_create_file("enable_inject", 0200, cio_debugfs_dir,
  137. NULL, &cio_en_fops);
  138. debugfs_create_file("crw_inject", 0200, cio_debugfs_dir,
  139. NULL, &crw_fops);
  140. return 0;
  141. }
  142. device_initcall(cio_inject_init);