memdev.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright(c) 2020 Intel Corporation. */
  3. #include <linux/io-64-nonatomic-lo-hi.h>
  4. #include <linux/firmware.h>
  5. #include <linux/device.h>
  6. #include <linux/slab.h>
  7. #include <linux/idr.h>
  8. #include <linux/pci.h>
  9. #include <cxlmem.h>
  10. #include "trace.h"
  11. #include "core.h"
  12. static DECLARE_RWSEM(cxl_memdev_rwsem);
  13. /*
  14. * An entire PCI topology full of devices should be enough for any
  15. * config
  16. */
  17. #define CXL_MEM_MAX_DEVS 65536
  18. static int cxl_mem_major;
  19. static DEFINE_IDA(cxl_memdev_ida);
  20. static void cxl_memdev_release(struct device *dev)
  21. {
  22. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  23. ida_free(&cxl_memdev_ida, cxlmd->id);
  24. kfree(cxlmd);
  25. }
  26. static char *cxl_memdev_devnode(const struct device *dev, umode_t *mode, kuid_t *uid,
  27. kgid_t *gid)
  28. {
  29. return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev));
  30. }
  31. static ssize_t firmware_version_show(struct device *dev,
  32. struct device_attribute *attr, char *buf)
  33. {
  34. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  35. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  36. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  37. if (!mds)
  38. return sysfs_emit(buf, "\n");
  39. return sysfs_emit(buf, "%.16s\n", mds->firmware_version);
  40. }
  41. static DEVICE_ATTR_RO(firmware_version);
  42. static ssize_t payload_max_show(struct device *dev,
  43. struct device_attribute *attr, char *buf)
  44. {
  45. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  46. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  47. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  48. if (!mds)
  49. return sysfs_emit(buf, "\n");
  50. return sysfs_emit(buf, "%zu\n", cxlds->cxl_mbox.payload_size);
  51. }
  52. static DEVICE_ATTR_RO(payload_max);
  53. static ssize_t label_storage_size_show(struct device *dev,
  54. struct device_attribute *attr, char *buf)
  55. {
  56. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  57. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  58. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  59. if (!mds)
  60. return sysfs_emit(buf, "\n");
  61. return sysfs_emit(buf, "%zu\n", mds->lsa_size);
  62. }
  63. static DEVICE_ATTR_RO(label_storage_size);
  64. static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr,
  65. char *buf)
  66. {
  67. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  68. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  69. unsigned long long len = resource_size(&cxlds->ram_res);
  70. return sysfs_emit(buf, "%#llx\n", len);
  71. }
  72. static struct device_attribute dev_attr_ram_size =
  73. __ATTR(size, 0444, ram_size_show, NULL);
  74. static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
  75. char *buf)
  76. {
  77. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  78. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  79. unsigned long long len = resource_size(&cxlds->pmem_res);
  80. return sysfs_emit(buf, "%#llx\n", len);
  81. }
  82. static struct device_attribute dev_attr_pmem_size =
  83. __ATTR(size, 0444, pmem_size_show, NULL);
  84. static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
  85. char *buf)
  86. {
  87. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  88. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  89. return sysfs_emit(buf, "%#llx\n", cxlds->serial);
  90. }
  91. static DEVICE_ATTR_RO(serial);
  92. static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
  93. char *buf)
  94. {
  95. return sysfs_emit(buf, "%d\n", dev_to_node(dev));
  96. }
  97. static DEVICE_ATTR_RO(numa_node);
  98. static ssize_t security_state_show(struct device *dev,
  99. struct device_attribute *attr,
  100. char *buf)
  101. {
  102. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  103. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  104. struct cxl_mailbox *cxl_mbox = &cxlds->cxl_mbox;
  105. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  106. unsigned long state = mds->security.state;
  107. int rc = 0;
  108. /* sync with latest submission state */
  109. mutex_lock(&cxl_mbox->mbox_mutex);
  110. if (mds->security.sanitize_active)
  111. rc = sysfs_emit(buf, "sanitize\n");
  112. mutex_unlock(&cxl_mbox->mbox_mutex);
  113. if (rc)
  114. return rc;
  115. if (!(state & CXL_PMEM_SEC_STATE_USER_PASS_SET))
  116. return sysfs_emit(buf, "disabled\n");
  117. if (state & CXL_PMEM_SEC_STATE_FROZEN ||
  118. state & CXL_PMEM_SEC_STATE_MASTER_PLIMIT ||
  119. state & CXL_PMEM_SEC_STATE_USER_PLIMIT)
  120. return sysfs_emit(buf, "frozen\n");
  121. if (state & CXL_PMEM_SEC_STATE_LOCKED)
  122. return sysfs_emit(buf, "locked\n");
  123. else
  124. return sysfs_emit(buf, "unlocked\n");
  125. }
  126. static struct device_attribute dev_attr_security_state =
  127. __ATTR(state, 0444, security_state_show, NULL);
  128. static ssize_t security_sanitize_store(struct device *dev,
  129. struct device_attribute *attr,
  130. const char *buf, size_t len)
  131. {
  132. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  133. bool sanitize;
  134. ssize_t rc;
  135. if (kstrtobool(buf, &sanitize) || !sanitize)
  136. return -EINVAL;
  137. rc = cxl_mem_sanitize(cxlmd, CXL_MBOX_OP_SANITIZE);
  138. if (rc)
  139. return rc;
  140. return len;
  141. }
  142. static struct device_attribute dev_attr_security_sanitize =
  143. __ATTR(sanitize, 0200, NULL, security_sanitize_store);
  144. static ssize_t security_erase_store(struct device *dev,
  145. struct device_attribute *attr,
  146. const char *buf, size_t len)
  147. {
  148. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  149. ssize_t rc;
  150. bool erase;
  151. if (kstrtobool(buf, &erase) || !erase)
  152. return -EINVAL;
  153. rc = cxl_mem_sanitize(cxlmd, CXL_MBOX_OP_SECURE_ERASE);
  154. if (rc)
  155. return rc;
  156. return len;
  157. }
  158. static struct device_attribute dev_attr_security_erase =
  159. __ATTR(erase, 0200, NULL, security_erase_store);
  160. static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
  161. {
  162. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  163. u64 offset, length;
  164. int rc = 0;
  165. /* CXL 3.0 Spec 8.2.9.8.4.1 Separate pmem and ram poison requests */
  166. if (resource_size(&cxlds->pmem_res)) {
  167. offset = cxlds->pmem_res.start;
  168. length = resource_size(&cxlds->pmem_res);
  169. rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
  170. if (rc)
  171. return rc;
  172. }
  173. if (resource_size(&cxlds->ram_res)) {
  174. offset = cxlds->ram_res.start;
  175. length = resource_size(&cxlds->ram_res);
  176. rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
  177. /*
  178. * Invalid Physical Address is not an error for
  179. * volatile addresses. Device support is optional.
  180. */
  181. if (rc == -EFAULT)
  182. rc = 0;
  183. }
  184. return rc;
  185. }
  186. int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
  187. {
  188. struct cxl_port *port;
  189. int rc;
  190. port = cxlmd->endpoint;
  191. if (!port || !is_cxl_endpoint(port))
  192. return -EINVAL;
  193. rc = down_read_interruptible(&cxl_region_rwsem);
  194. if (rc)
  195. return rc;
  196. rc = down_read_interruptible(&cxl_dpa_rwsem);
  197. if (rc) {
  198. up_read(&cxl_region_rwsem);
  199. return rc;
  200. }
  201. if (cxl_num_decoders_committed(port) == 0) {
  202. /* No regions mapped to this memdev */
  203. rc = cxl_get_poison_by_memdev(cxlmd);
  204. } else {
  205. /* Regions mapped, collect poison by endpoint */
  206. rc = cxl_get_poison_by_endpoint(port);
  207. }
  208. up_read(&cxl_dpa_rwsem);
  209. up_read(&cxl_region_rwsem);
  210. return rc;
  211. }
  212. EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, CXL);
  213. static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa)
  214. {
  215. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  216. if (!IS_ENABLED(CONFIG_DEBUG_FS))
  217. return 0;
  218. if (!resource_size(&cxlds->dpa_res)) {
  219. dev_dbg(cxlds->dev, "device has no dpa resource\n");
  220. return -EINVAL;
  221. }
  222. if (dpa < cxlds->dpa_res.start || dpa > cxlds->dpa_res.end) {
  223. dev_dbg(cxlds->dev, "dpa:0x%llx not in resource:%pR\n",
  224. dpa, &cxlds->dpa_res);
  225. return -EINVAL;
  226. }
  227. if (!IS_ALIGNED(dpa, 64)) {
  228. dev_dbg(cxlds->dev, "dpa:0x%llx is not 64-byte aligned\n", dpa);
  229. return -EINVAL;
  230. }
  231. return 0;
  232. }
  233. int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
  234. {
  235. struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox;
  236. struct cxl_mbox_inject_poison inject;
  237. struct cxl_poison_record record;
  238. struct cxl_mbox_cmd mbox_cmd;
  239. struct cxl_region *cxlr;
  240. int rc;
  241. if (!IS_ENABLED(CONFIG_DEBUG_FS))
  242. return 0;
  243. rc = down_read_interruptible(&cxl_region_rwsem);
  244. if (rc)
  245. return rc;
  246. rc = down_read_interruptible(&cxl_dpa_rwsem);
  247. if (rc) {
  248. up_read(&cxl_region_rwsem);
  249. return rc;
  250. }
  251. rc = cxl_validate_poison_dpa(cxlmd, dpa);
  252. if (rc)
  253. goto out;
  254. inject.address = cpu_to_le64(dpa);
  255. mbox_cmd = (struct cxl_mbox_cmd) {
  256. .opcode = CXL_MBOX_OP_INJECT_POISON,
  257. .size_in = sizeof(inject),
  258. .payload_in = &inject,
  259. };
  260. rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
  261. if (rc)
  262. goto out;
  263. cxlr = cxl_dpa_to_region(cxlmd, dpa);
  264. if (cxlr)
  265. dev_warn_once(cxl_mbox->host,
  266. "poison inject dpa:%#llx region: %s\n", dpa,
  267. dev_name(&cxlr->dev));
  268. record = (struct cxl_poison_record) {
  269. .address = cpu_to_le64(dpa),
  270. .length = cpu_to_le32(1),
  271. };
  272. trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT);
  273. out:
  274. up_read(&cxl_dpa_rwsem);
  275. up_read(&cxl_region_rwsem);
  276. return rc;
  277. }
  278. EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, CXL);
  279. int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
  280. {
  281. struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox;
  282. struct cxl_mbox_clear_poison clear;
  283. struct cxl_poison_record record;
  284. struct cxl_mbox_cmd mbox_cmd;
  285. struct cxl_region *cxlr;
  286. int rc;
  287. if (!IS_ENABLED(CONFIG_DEBUG_FS))
  288. return 0;
  289. rc = down_read_interruptible(&cxl_region_rwsem);
  290. if (rc)
  291. return rc;
  292. rc = down_read_interruptible(&cxl_dpa_rwsem);
  293. if (rc) {
  294. up_read(&cxl_region_rwsem);
  295. return rc;
  296. }
  297. rc = cxl_validate_poison_dpa(cxlmd, dpa);
  298. if (rc)
  299. goto out;
  300. /*
  301. * In CXL 3.0 Spec 8.2.9.8.4.3, the Clear Poison mailbox command
  302. * is defined to accept 64 bytes of write-data, along with the
  303. * address to clear. This driver uses zeroes as write-data.
  304. */
  305. clear = (struct cxl_mbox_clear_poison) {
  306. .address = cpu_to_le64(dpa)
  307. };
  308. mbox_cmd = (struct cxl_mbox_cmd) {
  309. .opcode = CXL_MBOX_OP_CLEAR_POISON,
  310. .size_in = sizeof(clear),
  311. .payload_in = &clear,
  312. };
  313. rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
  314. if (rc)
  315. goto out;
  316. cxlr = cxl_dpa_to_region(cxlmd, dpa);
  317. if (cxlr)
  318. dev_warn_once(cxl_mbox->host,
  319. "poison clear dpa:%#llx region: %s\n", dpa,
  320. dev_name(&cxlr->dev));
  321. record = (struct cxl_poison_record) {
  322. .address = cpu_to_le64(dpa),
  323. .length = cpu_to_le32(1),
  324. };
  325. trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR);
  326. out:
  327. up_read(&cxl_dpa_rwsem);
  328. up_read(&cxl_region_rwsem);
  329. return rc;
  330. }
  331. EXPORT_SYMBOL_NS_GPL(cxl_clear_poison, CXL);
  332. static struct attribute *cxl_memdev_attributes[] = {
  333. &dev_attr_serial.attr,
  334. &dev_attr_firmware_version.attr,
  335. &dev_attr_payload_max.attr,
  336. &dev_attr_label_storage_size.attr,
  337. &dev_attr_numa_node.attr,
  338. NULL,
  339. };
  340. static ssize_t pmem_qos_class_show(struct device *dev,
  341. struct device_attribute *attr, char *buf)
  342. {
  343. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  344. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  345. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  346. return sysfs_emit(buf, "%d\n", mds->pmem_perf.qos_class);
  347. }
  348. static struct device_attribute dev_attr_pmem_qos_class =
  349. __ATTR(qos_class, 0444, pmem_qos_class_show, NULL);
  350. static struct attribute *cxl_memdev_pmem_attributes[] = {
  351. &dev_attr_pmem_size.attr,
  352. &dev_attr_pmem_qos_class.attr,
  353. NULL,
  354. };
  355. static ssize_t ram_qos_class_show(struct device *dev,
  356. struct device_attribute *attr, char *buf)
  357. {
  358. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  359. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  360. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  361. return sysfs_emit(buf, "%d\n", mds->ram_perf.qos_class);
  362. }
  363. static struct device_attribute dev_attr_ram_qos_class =
  364. __ATTR(qos_class, 0444, ram_qos_class_show, NULL);
  365. static struct attribute *cxl_memdev_ram_attributes[] = {
  366. &dev_attr_ram_size.attr,
  367. &dev_attr_ram_qos_class.attr,
  368. NULL,
  369. };
  370. static struct attribute *cxl_memdev_security_attributes[] = {
  371. &dev_attr_security_state.attr,
  372. &dev_attr_security_sanitize.attr,
  373. &dev_attr_security_erase.attr,
  374. NULL,
  375. };
  376. static umode_t cxl_memdev_visible(struct kobject *kobj, struct attribute *a,
  377. int n)
  378. {
  379. if (!IS_ENABLED(CONFIG_NUMA) && a == &dev_attr_numa_node.attr)
  380. return 0;
  381. return a->mode;
  382. }
  383. static struct attribute_group cxl_memdev_attribute_group = {
  384. .attrs = cxl_memdev_attributes,
  385. .is_visible = cxl_memdev_visible,
  386. };
  387. static umode_t cxl_ram_visible(struct kobject *kobj, struct attribute *a, int n)
  388. {
  389. struct device *dev = kobj_to_dev(kobj);
  390. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  391. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
  392. if (a == &dev_attr_ram_qos_class.attr)
  393. if (mds->ram_perf.qos_class == CXL_QOS_CLASS_INVALID)
  394. return 0;
  395. return a->mode;
  396. }
  397. static struct attribute_group cxl_memdev_ram_attribute_group = {
  398. .name = "ram",
  399. .attrs = cxl_memdev_ram_attributes,
  400. .is_visible = cxl_ram_visible,
  401. };
  402. static umode_t cxl_pmem_visible(struct kobject *kobj, struct attribute *a, int n)
  403. {
  404. struct device *dev = kobj_to_dev(kobj);
  405. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  406. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
  407. if (a == &dev_attr_pmem_qos_class.attr)
  408. if (mds->pmem_perf.qos_class == CXL_QOS_CLASS_INVALID)
  409. return 0;
  410. return a->mode;
  411. }
  412. static struct attribute_group cxl_memdev_pmem_attribute_group = {
  413. .name = "pmem",
  414. .attrs = cxl_memdev_pmem_attributes,
  415. .is_visible = cxl_pmem_visible,
  416. };
  417. static umode_t cxl_memdev_security_visible(struct kobject *kobj,
  418. struct attribute *a, int n)
  419. {
  420. struct device *dev = kobj_to_dev(kobj);
  421. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  422. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
  423. if (a == &dev_attr_security_sanitize.attr &&
  424. !test_bit(CXL_SEC_ENABLED_SANITIZE, mds->security.enabled_cmds))
  425. return 0;
  426. if (a == &dev_attr_security_erase.attr &&
  427. !test_bit(CXL_SEC_ENABLED_SECURE_ERASE, mds->security.enabled_cmds))
  428. return 0;
  429. return a->mode;
  430. }
  431. static struct attribute_group cxl_memdev_security_attribute_group = {
  432. .name = "security",
  433. .attrs = cxl_memdev_security_attributes,
  434. .is_visible = cxl_memdev_security_visible,
  435. };
  436. static const struct attribute_group *cxl_memdev_attribute_groups[] = {
  437. &cxl_memdev_attribute_group,
  438. &cxl_memdev_ram_attribute_group,
  439. &cxl_memdev_pmem_attribute_group,
  440. &cxl_memdev_security_attribute_group,
  441. NULL,
  442. };
  443. void cxl_memdev_update_perf(struct cxl_memdev *cxlmd)
  444. {
  445. sysfs_update_group(&cxlmd->dev.kobj, &cxl_memdev_ram_attribute_group);
  446. sysfs_update_group(&cxlmd->dev.kobj, &cxl_memdev_pmem_attribute_group);
  447. }
  448. EXPORT_SYMBOL_NS_GPL(cxl_memdev_update_perf, CXL);
  449. static const struct device_type cxl_memdev_type = {
  450. .name = "cxl_memdev",
  451. .release = cxl_memdev_release,
  452. .devnode = cxl_memdev_devnode,
  453. .groups = cxl_memdev_attribute_groups,
  454. };
  455. bool is_cxl_memdev(const struct device *dev)
  456. {
  457. return dev->type == &cxl_memdev_type;
  458. }
  459. EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
  460. /**
  461. * set_exclusive_cxl_commands() - atomically disable user cxl commands
  462. * @mds: The device state to operate on
  463. * @cmds: bitmap of commands to mark exclusive
  464. *
  465. * Grab the cxl_memdev_rwsem in write mode to flush in-flight
  466. * invocations of the ioctl path and then disable future execution of
  467. * commands with the command ids set in @cmds.
  468. */
  469. void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
  470. unsigned long *cmds)
  471. {
  472. down_write(&cxl_memdev_rwsem);
  473. bitmap_or(mds->exclusive_cmds, mds->exclusive_cmds, cmds,
  474. CXL_MEM_COMMAND_ID_MAX);
  475. up_write(&cxl_memdev_rwsem);
  476. }
  477. EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, CXL);
  478. /**
  479. * clear_exclusive_cxl_commands() - atomically enable user cxl commands
  480. * @mds: The device state to modify
  481. * @cmds: bitmap of commands to mark available for userspace
  482. */
  483. void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
  484. unsigned long *cmds)
  485. {
  486. down_write(&cxl_memdev_rwsem);
  487. bitmap_andnot(mds->exclusive_cmds, mds->exclusive_cmds, cmds,
  488. CXL_MEM_COMMAND_ID_MAX);
  489. up_write(&cxl_memdev_rwsem);
  490. }
  491. EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, CXL);
  492. static void cxl_memdev_shutdown(struct device *dev)
  493. {
  494. struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
  495. down_write(&cxl_memdev_rwsem);
  496. cxlmd->cxlds = NULL;
  497. up_write(&cxl_memdev_rwsem);
  498. }
  499. static void cxl_memdev_unregister(void *_cxlmd)
  500. {
  501. struct cxl_memdev *cxlmd = _cxlmd;
  502. struct device *dev = &cxlmd->dev;
  503. cdev_device_del(&cxlmd->cdev, dev);
  504. cxl_memdev_shutdown(dev);
  505. put_device(dev);
  506. }
  507. static void detach_memdev(struct work_struct *work)
  508. {
  509. struct cxl_memdev *cxlmd;
  510. cxlmd = container_of(work, typeof(*cxlmd), detach_work);
  511. device_release_driver(&cxlmd->dev);
  512. put_device(&cxlmd->dev);
  513. }
  514. static struct lock_class_key cxl_memdev_key;
  515. static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
  516. const struct file_operations *fops)
  517. {
  518. struct cxl_memdev *cxlmd;
  519. struct device *dev;
  520. struct cdev *cdev;
  521. int rc;
  522. cxlmd = kzalloc(sizeof(*cxlmd), GFP_KERNEL);
  523. if (!cxlmd)
  524. return ERR_PTR(-ENOMEM);
  525. rc = ida_alloc_max(&cxl_memdev_ida, CXL_MEM_MAX_DEVS - 1, GFP_KERNEL);
  526. if (rc < 0)
  527. goto err;
  528. cxlmd->id = rc;
  529. cxlmd->depth = -1;
  530. dev = &cxlmd->dev;
  531. device_initialize(dev);
  532. lockdep_set_class(&dev->mutex, &cxl_memdev_key);
  533. dev->parent = cxlds->dev;
  534. dev->bus = &cxl_bus_type;
  535. dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
  536. dev->type = &cxl_memdev_type;
  537. device_set_pm_not_required(dev);
  538. INIT_WORK(&cxlmd->detach_work, detach_memdev);
  539. cdev = &cxlmd->cdev;
  540. cdev_init(cdev, fops);
  541. return cxlmd;
  542. err:
  543. kfree(cxlmd);
  544. return ERR_PTR(rc);
  545. }
  546. static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
  547. unsigned long arg)
  548. {
  549. switch (cmd) {
  550. case CXL_MEM_QUERY_COMMANDS:
  551. return cxl_query_cmd(cxlmd, (void __user *)arg);
  552. case CXL_MEM_SEND_COMMAND:
  553. return cxl_send_cmd(cxlmd, (void __user *)arg);
  554. default:
  555. return -ENOTTY;
  556. }
  557. }
  558. static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
  559. unsigned long arg)
  560. {
  561. struct cxl_memdev *cxlmd = file->private_data;
  562. struct cxl_dev_state *cxlds;
  563. int rc = -ENXIO;
  564. down_read(&cxl_memdev_rwsem);
  565. cxlds = cxlmd->cxlds;
  566. if (cxlds && cxlds->type == CXL_DEVTYPE_CLASSMEM)
  567. rc = __cxl_memdev_ioctl(cxlmd, cmd, arg);
  568. up_read(&cxl_memdev_rwsem);
  569. return rc;
  570. }
  571. static int cxl_memdev_open(struct inode *inode, struct file *file)
  572. {
  573. struct cxl_memdev *cxlmd =
  574. container_of(inode->i_cdev, typeof(*cxlmd), cdev);
  575. get_device(&cxlmd->dev);
  576. file->private_data = cxlmd;
  577. return 0;
  578. }
  579. static int cxl_memdev_release_file(struct inode *inode, struct file *file)
  580. {
  581. struct cxl_memdev *cxlmd =
  582. container_of(inode->i_cdev, typeof(*cxlmd), cdev);
  583. put_device(&cxlmd->dev);
  584. return 0;
  585. }
  586. /**
  587. * cxl_mem_get_fw_info - Get Firmware info
  588. * @mds: The device data for the operation
  589. *
  590. * Retrieve firmware info for the device specified.
  591. *
  592. * Return: 0 if no error: or the result of the mailbox command.
  593. *
  594. * See CXL-3.0 8.2.9.3.1 Get FW Info
  595. */
  596. static int cxl_mem_get_fw_info(struct cxl_memdev_state *mds)
  597. {
  598. struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
  599. struct cxl_mbox_get_fw_info info;
  600. struct cxl_mbox_cmd mbox_cmd;
  601. int rc;
  602. mbox_cmd = (struct cxl_mbox_cmd) {
  603. .opcode = CXL_MBOX_OP_GET_FW_INFO,
  604. .size_out = sizeof(info),
  605. .payload_out = &info,
  606. };
  607. rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
  608. if (rc < 0)
  609. return rc;
  610. mds->fw.num_slots = info.num_slots;
  611. mds->fw.cur_slot = FIELD_GET(CXL_FW_INFO_SLOT_INFO_CUR_MASK,
  612. info.slot_info);
  613. return 0;
  614. }
  615. /**
  616. * cxl_mem_activate_fw - Activate Firmware
  617. * @mds: The device data for the operation
  618. * @slot: slot number to activate
  619. *
  620. * Activate firmware in a given slot for the device specified.
  621. *
  622. * Return: 0 if no error: or the result of the mailbox command.
  623. *
  624. * See CXL-3.0 8.2.9.3.3 Activate FW
  625. */
  626. static int cxl_mem_activate_fw(struct cxl_memdev_state *mds, int slot)
  627. {
  628. struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
  629. struct cxl_mbox_activate_fw activate;
  630. struct cxl_mbox_cmd mbox_cmd;
  631. if (slot == 0 || slot > mds->fw.num_slots)
  632. return -EINVAL;
  633. mbox_cmd = (struct cxl_mbox_cmd) {
  634. .opcode = CXL_MBOX_OP_ACTIVATE_FW,
  635. .size_in = sizeof(activate),
  636. .payload_in = &activate,
  637. };
  638. /* Only offline activation supported for now */
  639. activate.action = CXL_FW_ACTIVATE_OFFLINE;
  640. activate.slot = slot;
  641. return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
  642. }
  643. /**
  644. * cxl_mem_abort_fw_xfer - Abort an in-progress FW transfer
  645. * @mds: The device data for the operation
  646. *
  647. * Abort an in-progress firmware transfer for the device specified.
  648. *
  649. * Return: 0 if no error: or the result of the mailbox command.
  650. *
  651. * See CXL-3.0 8.2.9.3.2 Transfer FW
  652. */
  653. static int cxl_mem_abort_fw_xfer(struct cxl_memdev_state *mds)
  654. {
  655. struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
  656. struct cxl_mbox_transfer_fw *transfer;
  657. struct cxl_mbox_cmd mbox_cmd;
  658. int rc;
  659. transfer = kzalloc(struct_size(transfer, data, 0), GFP_KERNEL);
  660. if (!transfer)
  661. return -ENOMEM;
  662. /* Set a 1s poll interval and a total wait time of 30s */
  663. mbox_cmd = (struct cxl_mbox_cmd) {
  664. .opcode = CXL_MBOX_OP_TRANSFER_FW,
  665. .size_in = sizeof(*transfer),
  666. .payload_in = transfer,
  667. .poll_interval_ms = 1000,
  668. .poll_count = 30,
  669. };
  670. transfer->action = CXL_FW_TRANSFER_ACTION_ABORT;
  671. rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
  672. kfree(transfer);
  673. return rc;
  674. }
  675. static void cxl_fw_cleanup(struct fw_upload *fwl)
  676. {
  677. struct cxl_memdev_state *mds = fwl->dd_handle;
  678. mds->fw.next_slot = 0;
  679. }
  680. static int cxl_fw_do_cancel(struct fw_upload *fwl)
  681. {
  682. struct cxl_memdev_state *mds = fwl->dd_handle;
  683. struct cxl_dev_state *cxlds = &mds->cxlds;
  684. struct cxl_memdev *cxlmd = cxlds->cxlmd;
  685. int rc;
  686. rc = cxl_mem_abort_fw_xfer(mds);
  687. if (rc < 0)
  688. dev_err(&cxlmd->dev, "Error aborting FW transfer: %d\n", rc);
  689. return FW_UPLOAD_ERR_CANCELED;
  690. }
  691. static enum fw_upload_err cxl_fw_prepare(struct fw_upload *fwl, const u8 *data,
  692. u32 size)
  693. {
  694. struct cxl_memdev_state *mds = fwl->dd_handle;
  695. struct cxl_mbox_transfer_fw *transfer;
  696. struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
  697. if (!size)
  698. return FW_UPLOAD_ERR_INVALID_SIZE;
  699. mds->fw.oneshot = struct_size(transfer, data, size) <
  700. cxl_mbox->payload_size;
  701. if (cxl_mem_get_fw_info(mds))
  702. return FW_UPLOAD_ERR_HW_ERROR;
  703. /*
  704. * So far no state has been changed, hence no other cleanup is
  705. * necessary. Simply return the cancelled status.
  706. */
  707. if (test_and_clear_bit(CXL_FW_CANCEL, mds->fw.state))
  708. return FW_UPLOAD_ERR_CANCELED;
  709. return FW_UPLOAD_ERR_NONE;
  710. }
  711. static enum fw_upload_err cxl_fw_write(struct fw_upload *fwl, const u8 *data,
  712. u32 offset, u32 size, u32 *written)
  713. {
  714. struct cxl_memdev_state *mds = fwl->dd_handle;
  715. struct cxl_dev_state *cxlds = &mds->cxlds;
  716. struct cxl_mailbox *cxl_mbox = &cxlds->cxl_mbox;
  717. struct cxl_memdev *cxlmd = cxlds->cxlmd;
  718. struct cxl_mbox_transfer_fw *transfer;
  719. struct cxl_mbox_cmd mbox_cmd;
  720. u32 cur_size, remaining;
  721. size_t size_in;
  722. int rc;
  723. *written = 0;
  724. /* Offset has to be aligned to 128B (CXL-3.0 8.2.9.3.2 Table 8-57) */
  725. if (!IS_ALIGNED(offset, CXL_FW_TRANSFER_ALIGNMENT)) {
  726. dev_err(&cxlmd->dev,
  727. "misaligned offset for FW transfer slice (%u)\n",
  728. offset);
  729. return FW_UPLOAD_ERR_RW_ERROR;
  730. }
  731. /*
  732. * Pick transfer size based on mds->payload_size @size must bw 128-byte
  733. * aligned, ->payload_size is a power of 2 starting at 256 bytes, and
  734. * sizeof(*transfer) is 128. These constraints imply that @cur_size
  735. * will always be 128b aligned.
  736. */
  737. cur_size = min_t(size_t, size, cxl_mbox->payload_size - sizeof(*transfer));
  738. remaining = size - cur_size;
  739. size_in = struct_size(transfer, data, cur_size);
  740. if (test_and_clear_bit(CXL_FW_CANCEL, mds->fw.state))
  741. return cxl_fw_do_cancel(fwl);
  742. /*
  743. * Slot numbers are 1-indexed
  744. * cur_slot is the 0-indexed next_slot (i.e. 'cur_slot - 1 + 1')
  745. * Check for rollover using modulo, and 1-index it by adding 1
  746. */
  747. mds->fw.next_slot = (mds->fw.cur_slot % mds->fw.num_slots) + 1;
  748. /* Do the transfer via mailbox cmd */
  749. transfer = kzalloc(size_in, GFP_KERNEL);
  750. if (!transfer)
  751. return FW_UPLOAD_ERR_RW_ERROR;
  752. transfer->offset = cpu_to_le32(offset / CXL_FW_TRANSFER_ALIGNMENT);
  753. memcpy(transfer->data, data + offset, cur_size);
  754. if (mds->fw.oneshot) {
  755. transfer->action = CXL_FW_TRANSFER_ACTION_FULL;
  756. transfer->slot = mds->fw.next_slot;
  757. } else {
  758. if (offset == 0) {
  759. transfer->action = CXL_FW_TRANSFER_ACTION_INITIATE;
  760. } else if (remaining == 0) {
  761. transfer->action = CXL_FW_TRANSFER_ACTION_END;
  762. transfer->slot = mds->fw.next_slot;
  763. } else {
  764. transfer->action = CXL_FW_TRANSFER_ACTION_CONTINUE;
  765. }
  766. }
  767. mbox_cmd = (struct cxl_mbox_cmd) {
  768. .opcode = CXL_MBOX_OP_TRANSFER_FW,
  769. .size_in = size_in,
  770. .payload_in = transfer,
  771. .poll_interval_ms = 1000,
  772. .poll_count = 30,
  773. };
  774. rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
  775. if (rc < 0) {
  776. rc = FW_UPLOAD_ERR_RW_ERROR;
  777. goto out_free;
  778. }
  779. *written = cur_size;
  780. /* Activate FW if oneshot or if the last slice was written */
  781. if (mds->fw.oneshot || remaining == 0) {
  782. dev_dbg(&cxlmd->dev, "Activating firmware slot: %d\n",
  783. mds->fw.next_slot);
  784. rc = cxl_mem_activate_fw(mds, mds->fw.next_slot);
  785. if (rc < 0) {
  786. dev_err(&cxlmd->dev, "Error activating firmware: %d\n",
  787. rc);
  788. rc = FW_UPLOAD_ERR_HW_ERROR;
  789. goto out_free;
  790. }
  791. }
  792. rc = FW_UPLOAD_ERR_NONE;
  793. out_free:
  794. kfree(transfer);
  795. return rc;
  796. }
  797. static enum fw_upload_err cxl_fw_poll_complete(struct fw_upload *fwl)
  798. {
  799. struct cxl_memdev_state *mds = fwl->dd_handle;
  800. /*
  801. * cxl_internal_send_cmd() handles background operations synchronously.
  802. * No need to wait for completions here - any errors would've been
  803. * reported and handled during the ->write() call(s).
  804. * Just check if a cancel request was received, and return success.
  805. */
  806. if (test_and_clear_bit(CXL_FW_CANCEL, mds->fw.state))
  807. return cxl_fw_do_cancel(fwl);
  808. return FW_UPLOAD_ERR_NONE;
  809. }
  810. static void cxl_fw_cancel(struct fw_upload *fwl)
  811. {
  812. struct cxl_memdev_state *mds = fwl->dd_handle;
  813. set_bit(CXL_FW_CANCEL, mds->fw.state);
  814. }
  815. static const struct fw_upload_ops cxl_memdev_fw_ops = {
  816. .prepare = cxl_fw_prepare,
  817. .write = cxl_fw_write,
  818. .poll_complete = cxl_fw_poll_complete,
  819. .cancel = cxl_fw_cancel,
  820. .cleanup = cxl_fw_cleanup,
  821. };
  822. static void cxl_remove_fw_upload(void *fwl)
  823. {
  824. firmware_upload_unregister(fwl);
  825. }
  826. int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds)
  827. {
  828. struct cxl_dev_state *cxlds = &mds->cxlds;
  829. struct device *dev = &cxlds->cxlmd->dev;
  830. struct fw_upload *fwl;
  831. if (!test_bit(CXL_MEM_COMMAND_ID_GET_FW_INFO, mds->enabled_cmds))
  832. return 0;
  833. fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),
  834. &cxl_memdev_fw_ops, mds);
  835. if (IS_ERR(fwl))
  836. return PTR_ERR(fwl);
  837. return devm_add_action_or_reset(host, cxl_remove_fw_upload, fwl);
  838. }
  839. EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fw_upload, CXL);
  840. static const struct file_operations cxl_memdev_fops = {
  841. .owner = THIS_MODULE,
  842. .unlocked_ioctl = cxl_memdev_ioctl,
  843. .open = cxl_memdev_open,
  844. .release = cxl_memdev_release_file,
  845. .compat_ioctl = compat_ptr_ioctl,
  846. .llseek = noop_llseek,
  847. };
  848. struct cxl_memdev *devm_cxl_add_memdev(struct device *host,
  849. struct cxl_dev_state *cxlds)
  850. {
  851. struct cxl_memdev *cxlmd;
  852. struct device *dev;
  853. struct cdev *cdev;
  854. int rc;
  855. cxlmd = cxl_memdev_alloc(cxlds, &cxl_memdev_fops);
  856. if (IS_ERR(cxlmd))
  857. return cxlmd;
  858. dev = &cxlmd->dev;
  859. rc = dev_set_name(dev, "mem%d", cxlmd->id);
  860. if (rc)
  861. goto err;
  862. /*
  863. * Activate ioctl operations, no cxl_memdev_rwsem manipulation
  864. * needed as this is ordered with cdev_add() publishing the device.
  865. */
  866. cxlmd->cxlds = cxlds;
  867. cxlds->cxlmd = cxlmd;
  868. cdev = &cxlmd->cdev;
  869. rc = cdev_device_add(cdev, dev);
  870. if (rc)
  871. goto err;
  872. rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd);
  873. if (rc)
  874. return ERR_PTR(rc);
  875. return cxlmd;
  876. err:
  877. /*
  878. * The cdev was briefly live, shutdown any ioctl operations that
  879. * saw that state.
  880. */
  881. cxl_memdev_shutdown(dev);
  882. put_device(dev);
  883. return ERR_PTR(rc);
  884. }
  885. EXPORT_SYMBOL_NS_GPL(devm_cxl_add_memdev, CXL);
  886. static void sanitize_teardown_notifier(void *data)
  887. {
  888. struct cxl_memdev_state *mds = data;
  889. struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
  890. struct kernfs_node *state;
  891. /*
  892. * Prevent new irq triggered invocations of the workqueue and
  893. * flush inflight invocations.
  894. */
  895. mutex_lock(&cxl_mbox->mbox_mutex);
  896. state = mds->security.sanitize_node;
  897. mds->security.sanitize_node = NULL;
  898. mutex_unlock(&cxl_mbox->mbox_mutex);
  899. cancel_delayed_work_sync(&mds->security.poll_dwork);
  900. sysfs_put(state);
  901. }
  902. int devm_cxl_sanitize_setup_notifier(struct device *host,
  903. struct cxl_memdev *cxlmd)
  904. {
  905. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  906. struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
  907. struct kernfs_node *sec;
  908. if (!test_bit(CXL_SEC_ENABLED_SANITIZE, mds->security.enabled_cmds))
  909. return 0;
  910. /*
  911. * Note, the expectation is that @cxlmd would have failed to be
  912. * created if these sysfs_get_dirent calls fail.
  913. */
  914. sec = sysfs_get_dirent(cxlmd->dev.kobj.sd, "security");
  915. if (!sec)
  916. return -ENOENT;
  917. mds->security.sanitize_node = sysfs_get_dirent(sec, "state");
  918. sysfs_put(sec);
  919. if (!mds->security.sanitize_node)
  920. return -ENOENT;
  921. return devm_add_action_or_reset(host, sanitize_teardown_notifier, mds);
  922. }
  923. EXPORT_SYMBOL_NS_GPL(devm_cxl_sanitize_setup_notifier, CXL);
  924. __init int cxl_memdev_init(void)
  925. {
  926. dev_t devt;
  927. int rc;
  928. rc = alloc_chrdev_region(&devt, 0, CXL_MEM_MAX_DEVS, "cxl");
  929. if (rc)
  930. return rc;
  931. cxl_mem_major = MAJOR(devt);
  932. return 0;
  933. }
  934. void cxl_memdev_exit(void)
  935. {
  936. unregister_chrdev_region(MKDEV(cxl_mem_major, 0), CXL_MEM_MAX_DEVS);
  937. }