amd64_edac_inj.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include "amd64_edac.h"
  3. static ssize_t amd64_inject_section_show(struct device *dev,
  4. struct device_attribute *mattr,
  5. char *buf)
  6. {
  7. struct mem_ctl_info *mci = to_mci(dev);
  8. struct amd64_pvt *pvt = mci->pvt_info;
  9. return sprintf(buf, "0x%x\n", pvt->injection.section);
  10. }
  11. /*
  12. * store error injection section value which refers to one of 4 16-byte sections
  13. * within a 64-byte cacheline
  14. *
  15. * range: 0..3
  16. */
  17. static ssize_t amd64_inject_section_store(struct device *dev,
  18. struct device_attribute *mattr,
  19. const char *data, size_t count)
  20. {
  21. struct mem_ctl_info *mci = to_mci(dev);
  22. struct amd64_pvt *pvt = mci->pvt_info;
  23. unsigned long value;
  24. int ret;
  25. ret = kstrtoul(data, 10, &value);
  26. if (ret < 0)
  27. return ret;
  28. if (value > 3) {
  29. amd64_warn("%s: invalid section 0x%lx\n", __func__, value);
  30. return -EINVAL;
  31. }
  32. pvt->injection.section = (u32) value;
  33. return count;
  34. }
  35. static ssize_t amd64_inject_word_show(struct device *dev,
  36. struct device_attribute *mattr,
  37. char *buf)
  38. {
  39. struct mem_ctl_info *mci = to_mci(dev);
  40. struct amd64_pvt *pvt = mci->pvt_info;
  41. return sprintf(buf, "0x%x\n", pvt->injection.word);
  42. }
  43. /*
  44. * store error injection word value which refers to one of 9 16-bit word of the
  45. * 16-byte (128-bit + ECC bits) section
  46. *
  47. * range: 0..8
  48. */
  49. static ssize_t amd64_inject_word_store(struct device *dev,
  50. struct device_attribute *mattr,
  51. const char *data, size_t count)
  52. {
  53. struct mem_ctl_info *mci = to_mci(dev);
  54. struct amd64_pvt *pvt = mci->pvt_info;
  55. unsigned long value;
  56. int ret;
  57. ret = kstrtoul(data, 10, &value);
  58. if (ret < 0)
  59. return ret;
  60. if (value > 8) {
  61. amd64_warn("%s: invalid word 0x%lx\n", __func__, value);
  62. return -EINVAL;
  63. }
  64. pvt->injection.word = (u32) value;
  65. return count;
  66. }
  67. static ssize_t amd64_inject_ecc_vector_show(struct device *dev,
  68. struct device_attribute *mattr,
  69. char *buf)
  70. {
  71. struct mem_ctl_info *mci = to_mci(dev);
  72. struct amd64_pvt *pvt = mci->pvt_info;
  73. return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
  74. }
  75. /*
  76. * store 16 bit error injection vector which enables injecting errors to the
  77. * corresponding bit within the error injection word above. When used during a
  78. * DRAM ECC read, it holds the contents of the of the DRAM ECC bits.
  79. */
  80. static ssize_t amd64_inject_ecc_vector_store(struct device *dev,
  81. struct device_attribute *mattr,
  82. const char *data, size_t count)
  83. {
  84. struct mem_ctl_info *mci = to_mci(dev);
  85. struct amd64_pvt *pvt = mci->pvt_info;
  86. unsigned long value;
  87. int ret;
  88. ret = kstrtoul(data, 16, &value);
  89. if (ret < 0)
  90. return ret;
  91. if (value & 0xFFFF0000) {
  92. amd64_warn("%s: invalid EccVector: 0x%lx\n", __func__, value);
  93. return -EINVAL;
  94. }
  95. pvt->injection.bit_map = (u32) value;
  96. return count;
  97. }
  98. /*
  99. * Do a DRAM ECC read. Assemble staged values in the pvt area, format into
  100. * fields needed by the injection registers and read the NB Array Data Port.
  101. */
  102. static ssize_t amd64_inject_read_store(struct device *dev,
  103. struct device_attribute *mattr,
  104. const char *data, size_t count)
  105. {
  106. struct mem_ctl_info *mci = to_mci(dev);
  107. struct amd64_pvt *pvt = mci->pvt_info;
  108. unsigned long value;
  109. u32 section, word_bits;
  110. int ret;
  111. ret = kstrtoul(data, 10, &value);
  112. if (ret < 0)
  113. return ret;
  114. /* Form value to choose 16-byte section of cacheline */
  115. section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section);
  116. amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
  117. word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection);
  118. /* Issue 'word' and 'bit' along with the READ request */
  119. amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
  120. edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits);
  121. return count;
  122. }
  123. /*
  124. * Do a DRAM ECC write. Assemble staged values in the pvt area and format into
  125. * fields needed by the injection registers.
  126. */
  127. static ssize_t amd64_inject_write_store(struct device *dev,
  128. struct device_attribute *mattr,
  129. const char *data, size_t count)
  130. {
  131. struct mem_ctl_info *mci = to_mci(dev);
  132. struct amd64_pvt *pvt = mci->pvt_info;
  133. u32 section, word_bits, tmp;
  134. unsigned long value;
  135. int ret;
  136. ret = kstrtoul(data, 10, &value);
  137. if (ret < 0)
  138. return ret;
  139. /* Form value to choose 16-byte section of cacheline */
  140. section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section);
  141. amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section);
  142. word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection);
  143. pr_notice_once("Don't forget to decrease MCE polling interval in\n"
  144. "/sys/bus/machinecheck/devices/machinecheck<CPUNUM>/check_interval\n"
  145. "so that you can get the error report faster.\n");
  146. on_each_cpu(disable_caches, NULL, 1);
  147. /* Issue 'word' and 'bit' along with the READ request */
  148. amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits);
  149. retry:
  150. /* wait until injection happens */
  151. amd64_read_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, &tmp);
  152. if (tmp & F10_NB_ARR_ECC_WR_REQ) {
  153. cpu_relax();
  154. goto retry;
  155. }
  156. on_each_cpu(enable_caches, NULL, 1);
  157. edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits);
  158. return count;
  159. }
  160. /*
  161. * update NUM_INJ_ATTRS in case you add new members
  162. */
  163. static DEVICE_ATTR(inject_section, S_IRUGO | S_IWUSR,
  164. amd64_inject_section_show, amd64_inject_section_store);
  165. static DEVICE_ATTR(inject_word, S_IRUGO | S_IWUSR,
  166. amd64_inject_word_show, amd64_inject_word_store);
  167. static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR,
  168. amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store);
  169. static DEVICE_ATTR(inject_write, S_IWUSR,
  170. NULL, amd64_inject_write_store);
  171. static DEVICE_ATTR(inject_read, S_IWUSR,
  172. NULL, amd64_inject_read_store);
  173. static struct attribute *amd64_edac_inj_attrs[] = {
  174. &dev_attr_inject_section.attr,
  175. &dev_attr_inject_word.attr,
  176. &dev_attr_inject_ecc_vector.attr,
  177. &dev_attr_inject_write.attr,
  178. &dev_attr_inject_read.attr,
  179. NULL
  180. };
  181. static umode_t amd64_edac_inj_is_visible(struct kobject *kobj,
  182. struct attribute *attr, int idx)
  183. {
  184. struct device *dev = kobj_to_dev(kobj);
  185. struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
  186. struct amd64_pvt *pvt = mci->pvt_info;
  187. if (pvt->fam < 0x10)
  188. return 0;
  189. return attr->mode;
  190. }
  191. const struct attribute_group amd64_edac_inj_group = {
  192. .attrs = amd64_edac_inj_attrs,
  193. .is_visible = amd64_edac_inj_is_visible,
  194. };