sev-dev-tio.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Interface to PSP for CCP/SEV-TIO/SNP-VM
  3. #include <linux/pci.h>
  4. #include <linux/tsm.h>
  5. #include <linux/psp.h>
  6. #include <linux/vmalloc.h>
  7. #include <linux/bitfield.h>
  8. #include <linux/pci-doe.h>
  9. #include <asm/sev-common.h>
  10. #include <asm/sev.h>
  11. #include <asm/page.h>
  12. #include "sev-dev.h"
  13. #include "sev-dev-tio.h"
  14. #define to_tio_status(dev_data) \
  15. (container_of((dev_data), struct tio_dsm, data)->sev->tio_status)
  16. #define SLA_PAGE_TYPE_DATA 0
  17. #define SLA_PAGE_TYPE_SCATTER 1
  18. #define SLA_PAGE_SIZE_4K 0
  19. #define SLA_PAGE_SIZE_2M 1
  20. #define SLA_SZ(s) ((s).page_size == SLA_PAGE_SIZE_2M ? SZ_2M : SZ_4K)
  21. #define SLA_SCATTER_LEN(s) (SLA_SZ(s) / sizeof(struct sla_addr_t))
  22. #define SLA_EOL ((struct sla_addr_t) { .pfn = ((1UL << 40) - 1) })
  23. #define SLA_NULL ((struct sla_addr_t) { 0 })
  24. #define IS_SLA_NULL(s) ((s).sla == SLA_NULL.sla)
  25. #define IS_SLA_EOL(s) ((s).sla == SLA_EOL.sla)
  26. static phys_addr_t sla_to_pa(struct sla_addr_t sla)
  27. {
  28. u64 pfn = sla.pfn;
  29. u64 pa = pfn << PAGE_SHIFT;
  30. return pa;
  31. }
  32. static void *sla_to_va(struct sla_addr_t sla)
  33. {
  34. void *va = __va(__sme_clr(sla_to_pa(sla)));
  35. return va;
  36. }
  37. #define sla_to_pfn(sla) (__pa(sla_to_va(sla)) >> PAGE_SHIFT)
  38. #define sla_to_page(sla) virt_to_page(sla_to_va(sla))
  39. static struct sla_addr_t make_sla(struct page *pg, bool stp)
  40. {
  41. u64 pa = __sme_set(page_to_phys(pg));
  42. struct sla_addr_t ret = {
  43. .pfn = pa >> PAGE_SHIFT,
  44. .page_size = SLA_PAGE_SIZE_4K, /* Do not do SLA_PAGE_SIZE_2M ATM */
  45. .page_type = stp ? SLA_PAGE_TYPE_SCATTER : SLA_PAGE_TYPE_DATA
  46. };
  47. return ret;
  48. }
  49. /* the BUFFER Structure */
  50. #define SLA_BUFFER_FLAG_ENCRYPTION BIT(0)
  51. /*
  52. * struct sla_buffer_hdr - Scatter list address buffer header
  53. *
  54. * @capacity_sz: Total capacity of the buffer in bytes
  55. * @payload_sz: Size of buffer payload in bytes, must be multiple of 32B
  56. * @flags: Buffer flags (SLA_BUFFER_FLAG_ENCRYPTION: buffer is encrypted)
  57. * @iv: Initialization vector used for encryption
  58. * @authtag: Authentication tag for encrypted buffer
  59. */
  60. struct sla_buffer_hdr {
  61. u32 capacity_sz;
  62. u32 payload_sz; /* The size of BUFFER_PAYLOAD in bytes. Must be multiple of 32B */
  63. u32 flags;
  64. u8 reserved1[4];
  65. u8 iv[16]; /* IV used for the encryption of this buffer */
  66. u8 authtag[16]; /* Authentication tag for this buffer */
  67. u8 reserved2[16];
  68. } __packed;
  69. enum spdm_data_type_t {
  70. DOBJ_DATA_TYPE_SPDM = 0x1,
  71. DOBJ_DATA_TYPE_SECURE_SPDM = 0x2,
  72. };
  73. struct spdm_dobj_hdr_req {
  74. struct spdm_dobj_hdr hdr; /* hdr.id == SPDM_DOBJ_ID_REQ */
  75. u8 data_type; /* spdm_data_type_t */
  76. u8 reserved2[5];
  77. } __packed;
  78. struct spdm_dobj_hdr_resp {
  79. struct spdm_dobj_hdr hdr; /* hdr.id == SPDM_DOBJ_ID_RESP */
  80. u8 data_type; /* spdm_data_type_t */
  81. u8 reserved2[5];
  82. } __packed;
  83. /* Defined in sev-dev-tio.h so sev-dev-tsm.c can read types of blobs */
  84. struct spdm_dobj_hdr_cert;
  85. struct spdm_dobj_hdr_meas;
  86. struct spdm_dobj_hdr_report;
  87. /* Used in all SPDM-aware TIO commands */
  88. struct spdm_ctrl {
  89. struct sla_addr_t req;
  90. struct sla_addr_t resp;
  91. struct sla_addr_t scratch;
  92. struct sla_addr_t output;
  93. } __packed;
  94. static size_t sla_dobj_id_to_size(u8 id)
  95. {
  96. size_t n;
  97. BUILD_BUG_ON(sizeof(struct spdm_dobj_hdr_resp) != 0x10);
  98. switch (id) {
  99. case SPDM_DOBJ_ID_REQ:
  100. n = sizeof(struct spdm_dobj_hdr_req);
  101. break;
  102. case SPDM_DOBJ_ID_RESP:
  103. n = sizeof(struct spdm_dobj_hdr_resp);
  104. break;
  105. default:
  106. WARN_ON(1);
  107. n = 0;
  108. break;
  109. }
  110. return n;
  111. }
  112. #define SPDM_DOBJ_HDR_SIZE(hdr) sla_dobj_id_to_size((hdr)->id)
  113. #define SPDM_DOBJ_DATA(hdr) ((u8 *)(hdr) + SPDM_DOBJ_HDR_SIZE(hdr))
  114. #define SPDM_DOBJ_LEN(hdr) ((hdr)->length - SPDM_DOBJ_HDR_SIZE(hdr))
  115. #define sla_to_dobj_resp_hdr(buf) ((struct spdm_dobj_hdr_resp *) \
  116. sla_to_dobj_hdr_check((buf), SPDM_DOBJ_ID_RESP))
  117. #define sla_to_dobj_req_hdr(buf) ((struct spdm_dobj_hdr_req *) \
  118. sla_to_dobj_hdr_check((buf), SPDM_DOBJ_ID_REQ))
  119. static struct spdm_dobj_hdr *sla_to_dobj_hdr(struct sla_buffer_hdr *buf)
  120. {
  121. if (!buf)
  122. return NULL;
  123. return (struct spdm_dobj_hdr *) &buf[1];
  124. }
  125. static struct spdm_dobj_hdr *sla_to_dobj_hdr_check(struct sla_buffer_hdr *buf, u32 check_dobjid)
  126. {
  127. struct spdm_dobj_hdr *hdr = sla_to_dobj_hdr(buf);
  128. if (WARN_ON_ONCE(!hdr))
  129. return NULL;
  130. if (hdr->id != check_dobjid) {
  131. pr_err("! ERROR: expected %d, found %d\n", check_dobjid, hdr->id);
  132. return NULL;
  133. }
  134. return hdr;
  135. }
  136. static void *sla_to_data(struct sla_buffer_hdr *buf, u32 dobjid)
  137. {
  138. struct spdm_dobj_hdr *hdr = sla_to_dobj_hdr(buf);
  139. if (WARN_ON_ONCE(dobjid != SPDM_DOBJ_ID_REQ && dobjid != SPDM_DOBJ_ID_RESP))
  140. return NULL;
  141. if (!hdr)
  142. return NULL;
  143. return (u8 *) hdr + sla_dobj_id_to_size(dobjid);
  144. }
  145. /*
  146. * struct sev_data_tio_status - SEV_CMD_TIO_STATUS command
  147. *
  148. * @length: Length of this command buffer in bytes
  149. * @status_paddr: System physical address of the TIO_STATUS structure
  150. */
  151. struct sev_data_tio_status {
  152. u32 length;
  153. u8 reserved[4];
  154. u64 status_paddr;
  155. } __packed;
  156. /* TIO_INIT */
  157. struct sev_data_tio_init {
  158. u32 length;
  159. u8 reserved[12];
  160. } __packed;
  161. /*
  162. * struct sev_data_tio_dev_create - TIO_DEV_CREATE command
  163. *
  164. * @length: Length in bytes of this command buffer
  165. * @dev_ctx_sla: Scatter list address pointing to a buffer to be used as a device context buffer
  166. * @device_id: PCIe Routing Identifier of the device to connect to
  167. * @root_port_id: PCIe Routing Identifier of the root port of the device
  168. * @segment_id: PCIe Segment Identifier of the device to connect to
  169. */
  170. struct sev_data_tio_dev_create {
  171. u32 length;
  172. u8 reserved1[4];
  173. struct sla_addr_t dev_ctx_sla;
  174. u16 device_id;
  175. u16 root_port_id;
  176. u8 segment_id;
  177. u8 reserved2[11];
  178. } __packed;
  179. /*
  180. * struct sev_data_tio_dev_connect - TIO_DEV_CONNECT command
  181. *
  182. * @length: Length in bytes of this command buffer
  183. * @spdm_ctrl: SPDM control structure defined in Section 5.1
  184. * @dev_ctx_sla: Scatter list address of the device context buffer
  185. * @tc_mask: Bitmask of the traffic classes to initialize for SEV-TIO usage.
  186. * Setting the kth bit of the TC_MASK to 1 indicates that the traffic
  187. * class k will be initialized
  188. * @cert_slot: Slot number of the certificate requested for constructing the SPDM session
  189. * @ide_stream_id: IDE stream IDs to be associated with this device.
  190. * Valid only if corresponding bit in TC_MASK is set
  191. */
  192. struct sev_data_tio_dev_connect {
  193. u32 length;
  194. u8 reserved1[4];
  195. struct spdm_ctrl spdm_ctrl;
  196. u8 reserved2[8];
  197. struct sla_addr_t dev_ctx_sla;
  198. u8 tc_mask;
  199. u8 cert_slot;
  200. u8 reserved3[6];
  201. u8 ide_stream_id[8];
  202. u8 reserved4[8];
  203. } __packed;
  204. /*
  205. * struct sev_data_tio_dev_disconnect - TIO_DEV_DISCONNECT command
  206. *
  207. * @length: Length in bytes of this command buffer
  208. * @flags: Command flags (TIO_DEV_DISCONNECT_FLAG_FORCE: force disconnect)
  209. * @spdm_ctrl: SPDM control structure defined in Section 5.1
  210. * @dev_ctx_sla: Scatter list address of the device context buffer
  211. */
  212. #define TIO_DEV_DISCONNECT_FLAG_FORCE BIT(0)
  213. struct sev_data_tio_dev_disconnect {
  214. u32 length;
  215. u32 flags;
  216. struct spdm_ctrl spdm_ctrl;
  217. struct sla_addr_t dev_ctx_sla;
  218. } __packed;
  219. /*
  220. * struct sev_data_tio_dev_meas - TIO_DEV_MEASUREMENTS command
  221. *
  222. * @length: Length in bytes of this command buffer
  223. * @flags: Command flags (TIO_DEV_MEAS_FLAG_RAW_BITSTREAM: request raw measurements)
  224. * @spdm_ctrl: SPDM control structure defined in Section 5.1
  225. * @dev_ctx_sla: Scatter list address of the device context buffer
  226. * @meas_nonce: Nonce for measurement freshness verification
  227. */
  228. #define TIO_DEV_MEAS_FLAG_RAW_BITSTREAM BIT(0)
  229. struct sev_data_tio_dev_meas {
  230. u32 length;
  231. u32 flags;
  232. struct spdm_ctrl spdm_ctrl;
  233. struct sla_addr_t dev_ctx_sla;
  234. u8 meas_nonce[32];
  235. } __packed;
  236. /*
  237. * struct sev_data_tio_dev_certs - TIO_DEV_CERTIFICATES command
  238. *
  239. * @length: Length in bytes of this command buffer
  240. * @spdm_ctrl: SPDM control structure defined in Section 5.1
  241. * @dev_ctx_sla: Scatter list address of the device context buffer
  242. */
  243. struct sev_data_tio_dev_certs {
  244. u32 length;
  245. u8 reserved[4];
  246. struct spdm_ctrl spdm_ctrl;
  247. struct sla_addr_t dev_ctx_sla;
  248. } __packed;
  249. /*
  250. * struct sev_data_tio_dev_reclaim - TIO_DEV_RECLAIM command
  251. *
  252. * @length: Length in bytes of this command buffer
  253. * @dev_ctx_sla: Scatter list address of the device context buffer
  254. *
  255. * This command reclaims resources associated with a device context.
  256. */
  257. struct sev_data_tio_dev_reclaim {
  258. u32 length;
  259. u8 reserved[4];
  260. struct sla_addr_t dev_ctx_sla;
  261. } __packed;
  262. static struct sla_buffer_hdr *sla_buffer_map(struct sla_addr_t sla)
  263. {
  264. struct sla_buffer_hdr *buf;
  265. BUILD_BUG_ON(sizeof(struct sla_buffer_hdr) != 0x40);
  266. if (IS_SLA_NULL(sla))
  267. return NULL;
  268. if (sla.page_type == SLA_PAGE_TYPE_SCATTER) {
  269. struct sla_addr_t *scatter = sla_to_va(sla);
  270. unsigned int i, npages = 0;
  271. for (i = 0; i < SLA_SCATTER_LEN(sla); ++i) {
  272. if (WARN_ON_ONCE(SLA_SZ(scatter[i]) > SZ_4K))
  273. return NULL;
  274. if (WARN_ON_ONCE(scatter[i].page_type == SLA_PAGE_TYPE_SCATTER))
  275. return NULL;
  276. if (IS_SLA_EOL(scatter[i])) {
  277. npages = i;
  278. break;
  279. }
  280. }
  281. if (WARN_ON_ONCE(!npages))
  282. return NULL;
  283. struct page **pp = kmalloc_objs(pp[0], npages);
  284. if (!pp)
  285. return NULL;
  286. for (i = 0; i < npages; ++i)
  287. pp[i] = sla_to_page(scatter[i]);
  288. buf = vm_map_ram(pp, npages, 0);
  289. kfree(pp);
  290. } else {
  291. struct page *pg = sla_to_page(sla);
  292. buf = vm_map_ram(&pg, 1, 0);
  293. }
  294. return buf;
  295. }
  296. static void sla_buffer_unmap(struct sla_addr_t sla, struct sla_buffer_hdr *buf)
  297. {
  298. if (!buf)
  299. return;
  300. if (sla.page_type == SLA_PAGE_TYPE_SCATTER) {
  301. struct sla_addr_t *scatter = sla_to_va(sla);
  302. unsigned int i, npages = 0;
  303. for (i = 0; i < SLA_SCATTER_LEN(sla); ++i) {
  304. if (IS_SLA_EOL(scatter[i])) {
  305. npages = i;
  306. break;
  307. }
  308. }
  309. if (!npages)
  310. return;
  311. vm_unmap_ram(buf, npages);
  312. } else {
  313. vm_unmap_ram(buf, 1);
  314. }
  315. }
  316. static void dobj_response_init(struct sla_buffer_hdr *buf)
  317. {
  318. struct spdm_dobj_hdr *dobj = sla_to_dobj_hdr(buf);
  319. dobj->id = SPDM_DOBJ_ID_RESP;
  320. dobj->version.major = 0x1;
  321. dobj->version.minor = 0;
  322. dobj->length = 0;
  323. buf->payload_sz = sla_dobj_id_to_size(dobj->id) + dobj->length;
  324. }
  325. static void sla_free(struct sla_addr_t sla, size_t len, bool firmware_state)
  326. {
  327. unsigned int npages = PAGE_ALIGN(len) >> PAGE_SHIFT;
  328. struct sla_addr_t *scatter = NULL;
  329. int ret = 0, i;
  330. if (IS_SLA_NULL(sla))
  331. return;
  332. if (firmware_state) {
  333. if (sla.page_type == SLA_PAGE_TYPE_SCATTER) {
  334. scatter = sla_to_va(sla);
  335. for (i = 0; i < npages; ++i) {
  336. if (IS_SLA_EOL(scatter[i]))
  337. break;
  338. ret = snp_reclaim_pages(sla_to_pa(scatter[i]), 1, false);
  339. if (ret)
  340. break;
  341. }
  342. } else {
  343. ret = snp_reclaim_pages(sla_to_pa(sla), 1, false);
  344. }
  345. }
  346. if (WARN_ON(ret))
  347. return;
  348. if (scatter) {
  349. for (i = 0; i < npages; ++i) {
  350. if (IS_SLA_EOL(scatter[i]))
  351. break;
  352. free_page((unsigned long)sla_to_va(scatter[i]));
  353. }
  354. }
  355. free_page((unsigned long)sla_to_va(sla));
  356. }
  357. static struct sla_addr_t sla_alloc(size_t len, bool firmware_state)
  358. {
  359. unsigned long i, npages = PAGE_ALIGN(len) >> PAGE_SHIFT;
  360. struct sla_addr_t *scatter = NULL;
  361. struct sla_addr_t ret = SLA_NULL;
  362. struct sla_buffer_hdr *buf;
  363. struct page *pg;
  364. if (npages == 0)
  365. return ret;
  366. if (WARN_ON_ONCE(npages > ((PAGE_SIZE / sizeof(struct sla_addr_t)) + 1)))
  367. return ret;
  368. BUILD_BUG_ON(PAGE_SIZE < SZ_4K);
  369. if (npages > 1) {
  370. pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
  371. if (!pg)
  372. return SLA_NULL;
  373. ret = make_sla(pg, true);
  374. scatter = page_to_virt(pg);
  375. for (i = 0; i < npages; ++i) {
  376. pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
  377. if (!pg)
  378. goto no_reclaim_exit;
  379. scatter[i] = make_sla(pg, false);
  380. }
  381. scatter[i] = SLA_EOL;
  382. } else {
  383. pg = alloc_page(GFP_KERNEL | __GFP_ZERO);
  384. if (!pg)
  385. return SLA_NULL;
  386. ret = make_sla(pg, false);
  387. }
  388. buf = sla_buffer_map(ret);
  389. if (!buf)
  390. goto no_reclaim_exit;
  391. buf->capacity_sz = (npages << PAGE_SHIFT);
  392. sla_buffer_unmap(ret, buf);
  393. if (firmware_state) {
  394. if (scatter) {
  395. for (i = 0; i < npages; ++i) {
  396. if (rmp_make_private(sla_to_pfn(scatter[i]), 0,
  397. PG_LEVEL_4K, 0, true))
  398. goto free_exit;
  399. }
  400. } else {
  401. if (rmp_make_private(sla_to_pfn(ret), 0, PG_LEVEL_4K, 0, true))
  402. goto no_reclaim_exit;
  403. }
  404. }
  405. return ret;
  406. no_reclaim_exit:
  407. firmware_state = false;
  408. free_exit:
  409. sla_free(ret, len, firmware_state);
  410. return SLA_NULL;
  411. }
  412. /* Expands a buffer, only firmware owned buffers allowed for now */
  413. static int sla_expand(struct sla_addr_t *sla, size_t *len)
  414. {
  415. struct sla_buffer_hdr *oldbuf = sla_buffer_map(*sla), *newbuf;
  416. struct sla_addr_t oldsla = *sla, newsla;
  417. size_t oldlen = *len, newlen;
  418. if (!oldbuf)
  419. return -EFAULT;
  420. newlen = oldbuf->capacity_sz;
  421. if (oldbuf->capacity_sz == oldlen) {
  422. /* This buffer does not require expansion, must be another buffer */
  423. sla_buffer_unmap(oldsla, oldbuf);
  424. return 1;
  425. }
  426. pr_notice("Expanding BUFFER from %ld to %ld bytes\n", oldlen, newlen);
  427. newsla = sla_alloc(newlen, true);
  428. if (IS_SLA_NULL(newsla))
  429. return -ENOMEM;
  430. newbuf = sla_buffer_map(newsla);
  431. if (!newbuf) {
  432. sla_free(newsla, newlen, true);
  433. return -EFAULT;
  434. }
  435. memcpy(newbuf, oldbuf, oldlen);
  436. sla_buffer_unmap(newsla, newbuf);
  437. sla_free(oldsla, oldlen, true);
  438. *sla = newsla;
  439. *len = newlen;
  440. return 0;
  441. }
  442. static int sev_tio_do_cmd(int cmd, void *data, size_t data_len, int *psp_ret,
  443. struct tsm_dsm_tio *dev_data)
  444. {
  445. int rc;
  446. *psp_ret = 0;
  447. rc = sev_do_cmd(cmd, data, psp_ret);
  448. if (WARN_ON(!rc && *psp_ret == SEV_RET_SPDM_REQUEST))
  449. return -EIO;
  450. if (rc == 0 && *psp_ret == SEV_RET_EXPAND_BUFFER_LENGTH_REQUEST) {
  451. int rc1, rc2;
  452. rc1 = sla_expand(&dev_data->output, &dev_data->output_len);
  453. if (rc1 < 0)
  454. return rc1;
  455. rc2 = sla_expand(&dev_data->scratch, &dev_data->scratch_len);
  456. if (rc2 < 0)
  457. return rc2;
  458. if (!rc1 && !rc2)
  459. /* Neither buffer requires expansion, this is wrong */
  460. return -EFAULT;
  461. *psp_ret = 0;
  462. rc = sev_do_cmd(cmd, data, psp_ret);
  463. }
  464. if ((rc == 0 || rc == -EIO) && *psp_ret == SEV_RET_SPDM_REQUEST) {
  465. struct spdm_dobj_hdr_resp *resp_hdr;
  466. struct spdm_dobj_hdr_req *req_hdr;
  467. struct sev_tio_status *tio_status = to_tio_status(dev_data);
  468. size_t resp_len = tio_status->spdm_req_size_max -
  469. (sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + sizeof(struct sla_buffer_hdr));
  470. if (!dev_data->cmd) {
  471. if (WARN_ON_ONCE(!data_len || (data_len != *(u32 *) data)))
  472. return -EINVAL;
  473. if (WARN_ON(data_len > sizeof(dev_data->cmd_data)))
  474. return -EFAULT;
  475. memcpy(dev_data->cmd_data, data, data_len);
  476. memset(&dev_data->cmd_data[data_len], 0xFF,
  477. sizeof(dev_data->cmd_data) - data_len);
  478. dev_data->cmd = cmd;
  479. }
  480. req_hdr = sla_to_dobj_req_hdr(dev_data->reqbuf);
  481. resp_hdr = sla_to_dobj_resp_hdr(dev_data->respbuf);
  482. switch (req_hdr->data_type) {
  483. case DOBJ_DATA_TYPE_SPDM:
  484. rc = PCI_DOE_FEATURE_CMA;
  485. break;
  486. case DOBJ_DATA_TYPE_SECURE_SPDM:
  487. rc = PCI_DOE_FEATURE_SSESSION;
  488. break;
  489. default:
  490. return -EINVAL;
  491. }
  492. resp_hdr->data_type = req_hdr->data_type;
  493. dev_data->spdm.req_len = req_hdr->hdr.length -
  494. sla_dobj_id_to_size(SPDM_DOBJ_ID_REQ);
  495. dev_data->spdm.rsp_len = resp_len;
  496. } else if (dev_data && dev_data->cmd) {
  497. /* For either error or success just stop the bouncing */
  498. memset(dev_data->cmd_data, 0, sizeof(dev_data->cmd_data));
  499. dev_data->cmd = 0;
  500. }
  501. return rc;
  502. }
  503. int sev_tio_continue(struct tsm_dsm_tio *dev_data)
  504. {
  505. struct spdm_dobj_hdr_resp *resp_hdr;
  506. int ret;
  507. if (!dev_data || !dev_data->cmd)
  508. return -EINVAL;
  509. resp_hdr = sla_to_dobj_resp_hdr(dev_data->respbuf);
  510. resp_hdr->hdr.length = ALIGN(sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) +
  511. dev_data->spdm.rsp_len, 32);
  512. dev_data->respbuf->payload_sz = resp_hdr->hdr.length;
  513. ret = sev_tio_do_cmd(dev_data->cmd, dev_data->cmd_data, 0,
  514. &dev_data->psp_ret, dev_data);
  515. if (ret)
  516. return ret;
  517. if (dev_data->psp_ret != SEV_RET_SUCCESS)
  518. return -EINVAL;
  519. return 0;
  520. }
  521. static void spdm_ctrl_init(struct spdm_ctrl *ctrl, struct tsm_dsm_tio *dev_data)
  522. {
  523. ctrl->req = dev_data->req;
  524. ctrl->resp = dev_data->resp;
  525. ctrl->scratch = dev_data->scratch;
  526. ctrl->output = dev_data->output;
  527. }
  528. static void spdm_ctrl_free(struct tsm_dsm_tio *dev_data)
  529. {
  530. struct sev_tio_status *tio_status = to_tio_status(dev_data);
  531. size_t len = tio_status->spdm_req_size_max -
  532. (sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) +
  533. sizeof(struct sla_buffer_hdr));
  534. struct tsm_spdm *spdm = &dev_data->spdm;
  535. sla_buffer_unmap(dev_data->resp, dev_data->respbuf);
  536. sla_buffer_unmap(dev_data->req, dev_data->reqbuf);
  537. spdm->rsp = NULL;
  538. spdm->req = NULL;
  539. sla_free(dev_data->req, len, true);
  540. sla_free(dev_data->resp, len, false);
  541. sla_free(dev_data->scratch, tio_status->spdm_scratch_size_max, true);
  542. dev_data->req.sla = 0;
  543. dev_data->resp.sla = 0;
  544. dev_data->scratch.sla = 0;
  545. dev_data->respbuf = NULL;
  546. dev_data->reqbuf = NULL;
  547. sla_free(dev_data->output, tio_status->spdm_out_size_max, true);
  548. }
  549. static int spdm_ctrl_alloc(struct tsm_dsm_tio *dev_data)
  550. {
  551. struct sev_tio_status *tio_status = to_tio_status(dev_data);
  552. struct tsm_spdm *spdm = &dev_data->spdm;
  553. int ret;
  554. dev_data->req = sla_alloc(tio_status->spdm_req_size_max, true);
  555. dev_data->resp = sla_alloc(tio_status->spdm_req_size_max, false);
  556. dev_data->scratch_len = tio_status->spdm_scratch_size_max;
  557. dev_data->scratch = sla_alloc(dev_data->scratch_len, true);
  558. dev_data->output_len = tio_status->spdm_out_size_max;
  559. dev_data->output = sla_alloc(dev_data->output_len, true);
  560. if (IS_SLA_NULL(dev_data->req) || IS_SLA_NULL(dev_data->resp) ||
  561. IS_SLA_NULL(dev_data->scratch) || IS_SLA_NULL(dev_data->dev_ctx)) {
  562. ret = -ENOMEM;
  563. goto free_spdm_exit;
  564. }
  565. dev_data->reqbuf = sla_buffer_map(dev_data->req);
  566. dev_data->respbuf = sla_buffer_map(dev_data->resp);
  567. if (!dev_data->reqbuf || !dev_data->respbuf) {
  568. ret = -EFAULT;
  569. goto free_spdm_exit;
  570. }
  571. spdm->req = sla_to_data(dev_data->reqbuf, SPDM_DOBJ_ID_REQ);
  572. spdm->rsp = sla_to_data(dev_data->respbuf, SPDM_DOBJ_ID_RESP);
  573. if (!spdm->req || !spdm->rsp) {
  574. ret = -EFAULT;
  575. goto free_spdm_exit;
  576. }
  577. dobj_response_init(dev_data->respbuf);
  578. return 0;
  579. free_spdm_exit:
  580. spdm_ctrl_free(dev_data);
  581. return ret;
  582. }
  583. int sev_tio_init_locked(void *tio_status_page)
  584. {
  585. struct sev_tio_status *tio_status = tio_status_page;
  586. struct sev_data_tio_status data_status = {
  587. .length = sizeof(data_status),
  588. };
  589. int ret, psp_ret;
  590. data_status.status_paddr = __psp_pa(tio_status_page);
  591. ret = __sev_do_cmd_locked(SEV_CMD_TIO_STATUS, &data_status, &psp_ret);
  592. if (ret)
  593. return ret;
  594. if (tio_status->length < offsetofend(struct sev_tio_status, tdictx_size) ||
  595. tio_status->reserved)
  596. return -EFAULT;
  597. if (!tio_status->tio_en && !tio_status->tio_init_done)
  598. return -ENOENT;
  599. if (tio_status->tio_init_done)
  600. return -EBUSY;
  601. struct sev_data_tio_init ti = { .length = sizeof(ti) };
  602. ret = __sev_do_cmd_locked(SEV_CMD_TIO_INIT, &ti, &psp_ret);
  603. if (ret)
  604. return ret;
  605. ret = __sev_do_cmd_locked(SEV_CMD_TIO_STATUS, &data_status, &psp_ret);
  606. if (ret)
  607. return ret;
  608. return 0;
  609. }
  610. int sev_tio_dev_create(struct tsm_dsm_tio *dev_data, u16 device_id,
  611. u16 root_port_id, u8 segment_id)
  612. {
  613. struct sev_tio_status *tio_status = to_tio_status(dev_data);
  614. struct sev_data_tio_dev_create create = {
  615. .length = sizeof(create),
  616. .device_id = device_id,
  617. .root_port_id = root_port_id,
  618. .segment_id = segment_id,
  619. };
  620. void *data_pg;
  621. int ret;
  622. dev_data->dev_ctx = sla_alloc(tio_status->devctx_size, true);
  623. if (IS_SLA_NULL(dev_data->dev_ctx))
  624. return -ENOMEM;
  625. data_pg = snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT);
  626. if (!data_pg) {
  627. ret = -ENOMEM;
  628. goto free_ctx_exit;
  629. }
  630. create.dev_ctx_sla = dev_data->dev_ctx;
  631. ret = sev_do_cmd(SEV_CMD_TIO_DEV_CREATE, &create, &dev_data->psp_ret);
  632. if (ret)
  633. goto free_data_pg_exit;
  634. dev_data->data_pg = data_pg;
  635. return 0;
  636. free_data_pg_exit:
  637. snp_free_firmware_page(data_pg);
  638. free_ctx_exit:
  639. sla_free(create.dev_ctx_sla, tio_status->devctx_size, true);
  640. return ret;
  641. }
  642. int sev_tio_dev_reclaim(struct tsm_dsm_tio *dev_data)
  643. {
  644. struct sev_tio_status *tio_status = to_tio_status(dev_data);
  645. struct sev_data_tio_dev_reclaim r = {
  646. .length = sizeof(r),
  647. .dev_ctx_sla = dev_data->dev_ctx,
  648. };
  649. int ret;
  650. if (dev_data->data_pg) {
  651. snp_free_firmware_page(dev_data->data_pg);
  652. dev_data->data_pg = NULL;
  653. }
  654. if (IS_SLA_NULL(dev_data->dev_ctx))
  655. return 0;
  656. ret = sev_do_cmd(SEV_CMD_TIO_DEV_RECLAIM, &r, &dev_data->psp_ret);
  657. sla_free(dev_data->dev_ctx, tio_status->devctx_size, true);
  658. dev_data->dev_ctx = SLA_NULL;
  659. spdm_ctrl_free(dev_data);
  660. return ret;
  661. }
  662. int sev_tio_dev_connect(struct tsm_dsm_tio *dev_data, u8 tc_mask, u8 ids[8], u8 cert_slot)
  663. {
  664. struct sev_data_tio_dev_connect connect = {
  665. .length = sizeof(connect),
  666. .tc_mask = tc_mask,
  667. .cert_slot = cert_slot,
  668. .dev_ctx_sla = dev_data->dev_ctx,
  669. .ide_stream_id = {
  670. ids[0], ids[1], ids[2], ids[3],
  671. ids[4], ids[5], ids[6], ids[7]
  672. },
  673. };
  674. int ret;
  675. if (WARN_ON(IS_SLA_NULL(dev_data->dev_ctx)))
  676. return -EFAULT;
  677. if (!(tc_mask & 1))
  678. return -EINVAL;
  679. ret = spdm_ctrl_alloc(dev_data);
  680. if (ret)
  681. return ret;
  682. spdm_ctrl_init(&connect.spdm_ctrl, dev_data);
  683. return sev_tio_do_cmd(SEV_CMD_TIO_DEV_CONNECT, &connect, sizeof(connect),
  684. &dev_data->psp_ret, dev_data);
  685. }
  686. int sev_tio_dev_disconnect(struct tsm_dsm_tio *dev_data, bool force)
  687. {
  688. struct sev_data_tio_dev_disconnect dc = {
  689. .length = sizeof(dc),
  690. .dev_ctx_sla = dev_data->dev_ctx,
  691. .flags = force ? TIO_DEV_DISCONNECT_FLAG_FORCE : 0,
  692. };
  693. if (WARN_ON_ONCE(IS_SLA_NULL(dev_data->dev_ctx)))
  694. return -EFAULT;
  695. spdm_ctrl_init(&dc.spdm_ctrl, dev_data);
  696. return sev_tio_do_cmd(SEV_CMD_TIO_DEV_DISCONNECT, &dc, sizeof(dc),
  697. &dev_data->psp_ret, dev_data);
  698. }
  699. int sev_tio_cmd_buffer_len(int cmd)
  700. {
  701. switch (cmd) {
  702. case SEV_CMD_TIO_STATUS: return sizeof(struct sev_data_tio_status);
  703. case SEV_CMD_TIO_INIT: return sizeof(struct sev_data_tio_init);
  704. case SEV_CMD_TIO_DEV_CREATE: return sizeof(struct sev_data_tio_dev_create);
  705. case SEV_CMD_TIO_DEV_RECLAIM: return sizeof(struct sev_data_tio_dev_reclaim);
  706. case SEV_CMD_TIO_DEV_CONNECT: return sizeof(struct sev_data_tio_dev_connect);
  707. case SEV_CMD_TIO_DEV_DISCONNECT: return sizeof(struct sev_data_tio_dev_disconnect);
  708. default: return 0;
  709. }
  710. }