Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto/ccp: Implement SEV-TIO PCIe IDE (phase1)

Implement the SEV-TIO (Trusted I/O) firmware interface for PCIe TDISP
(Trust Domain In-Socket Protocol). This enables secure communication
between trusted domains and PCIe devices through the PSP (Platform
Security Processor).

The implementation includes:
- Device Security Manager (DSM) operations for establishing secure links
- SPDM (Security Protocol and Data Model) over DOE (Data Object Exchange)
- IDE (Integrity Data Encryption) stream management for secure PCIe

This module bridges the SEV firmware stack with the generic PCIe TSM
framework.

This is phase1 as described in Documentation/driver-api/pci/tsm.rst.

On AMD SEV, the AMD PSP firmware acts as TSM (manages the security/trust).
The CCP driver provides the interface to it and registers in the TSM
subsystem.

Detect the PSP support (reported via FEATURE_INFO + SNP_PLATFORM_STATUS)
and enable SEV-TIO in the SNP_INIT_EX call if the hardware supports TIO.

Implement SEV TIO PSP command wrappers in sev-dev-tio.c and store
the data in the SEV-TIO-specific structs.

Implement TSM hooks and IDE setup in sev-dev-tsm.c.

Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
Link: https://patch.msgid.link/692f506bb80c9_261c11004@dwillia2-mobl4.notmuch
Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

authored by

Alexey Kardashevskiy and committed by
Dan Williams
4be42357 eeb93413

+1469 -3
+1
drivers/crypto/ccp/Kconfig
··· 39 39 bool "Platform Security Processor (PSP) device" 40 40 default y 41 41 depends on CRYPTO_DEV_CCP_DD && X86_64 && AMD_IOMMU 42 + select PCI_TSM 42 43 help 43 44 Provide support for the AMD Platform Security Processor (PSP). 44 45 The PSP is a dedicated processor that provides support for key
+4
drivers/crypto/ccp/Makefile
··· 16 16 hsti.o \ 17 17 sfs.o 18 18 19 + ifeq ($(CONFIG_PCI_TSM),y) 20 + ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += sev-dev-tsm.o sev-dev-tio.o 21 + endif 22 + 19 23 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o 20 24 ccp-crypto-objs := ccp-crypto-main.o \ 21 25 ccp-crypto-aes.o \
+864
drivers/crypto/ccp/sev-dev-tio.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + // Interface to PSP for CCP/SEV-TIO/SNP-VM 4 + 5 + #include <linux/pci.h> 6 + #include <linux/tsm.h> 7 + #include <linux/psp.h> 8 + #include <linux/vmalloc.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/pci-doe.h> 11 + #include <asm/sev-common.h> 12 + #include <asm/sev.h> 13 + #include <asm/page.h> 14 + #include "sev-dev.h" 15 + #include "sev-dev-tio.h" 16 + 17 + #define to_tio_status(dev_data) \ 18 + (container_of((dev_data), struct tio_dsm, data)->sev->tio_status) 19 + 20 + #define SLA_PAGE_TYPE_DATA 0 21 + #define SLA_PAGE_TYPE_SCATTER 1 22 + #define SLA_PAGE_SIZE_4K 0 23 + #define SLA_PAGE_SIZE_2M 1 24 + #define SLA_SZ(s) ((s).page_size == SLA_PAGE_SIZE_2M ? SZ_2M : SZ_4K) 25 + #define SLA_SCATTER_LEN(s) (SLA_SZ(s) / sizeof(struct sla_addr_t)) 26 + #define SLA_EOL ((struct sla_addr_t) { .pfn = ((1UL << 40) - 1) }) 27 + #define SLA_NULL ((struct sla_addr_t) { 0 }) 28 + #define IS_SLA_NULL(s) ((s).sla == SLA_NULL.sla) 29 + #define IS_SLA_EOL(s) ((s).sla == SLA_EOL.sla) 30 + 31 + static phys_addr_t sla_to_pa(struct sla_addr_t sla) 32 + { 33 + u64 pfn = sla.pfn; 34 + u64 pa = pfn << PAGE_SHIFT; 35 + 36 + return pa; 37 + } 38 + 39 + static void *sla_to_va(struct sla_addr_t sla) 40 + { 41 + void *va = __va(__sme_clr(sla_to_pa(sla))); 42 + 43 + return va; 44 + } 45 + 46 + #define sla_to_pfn(sla) (__pa(sla_to_va(sla)) >> PAGE_SHIFT) 47 + #define sla_to_page(sla) virt_to_page(sla_to_va(sla)) 48 + 49 + static struct sla_addr_t make_sla(struct page *pg, bool stp) 50 + { 51 + u64 pa = __sme_set(page_to_phys(pg)); 52 + struct sla_addr_t ret = { 53 + .pfn = pa >> PAGE_SHIFT, 54 + .page_size = SLA_PAGE_SIZE_4K, /* Do not do SLA_PAGE_SIZE_2M ATM */ 55 + .page_type = stp ? SLA_PAGE_TYPE_SCATTER : SLA_PAGE_TYPE_DATA 56 + }; 57 + 58 + return ret; 59 + } 60 + 61 + /* the BUFFER Structure */ 62 + #define SLA_BUFFER_FLAG_ENCRYPTION BIT(0) 63 + 64 + /* 65 + * struct sla_buffer_hdr - Scatter list address buffer header 66 + * 67 + * @capacity_sz: Total capacity of the buffer in bytes 68 + * @payload_sz: Size of buffer payload in bytes, must be multiple of 32B 69 + * @flags: Buffer flags (SLA_BUFFER_FLAG_ENCRYPTION: buffer is encrypted) 70 + * @iv: Initialization vector used for encryption 71 + * @authtag: Authentication tag for encrypted buffer 72 + */ 73 + struct sla_buffer_hdr { 74 + u32 capacity_sz; 75 + u32 payload_sz; /* The size of BUFFER_PAYLOAD in bytes. Must be multiple of 32B */ 76 + u32 flags; 77 + u8 reserved1[4]; 78 + u8 iv[16]; /* IV used for the encryption of this buffer */ 79 + u8 authtag[16]; /* Authentication tag for this buffer */ 80 + u8 reserved2[16]; 81 + } __packed; 82 + 83 + enum spdm_data_type_t { 84 + DOBJ_DATA_TYPE_SPDM = 0x1, 85 + DOBJ_DATA_TYPE_SECURE_SPDM = 0x2, 86 + }; 87 + 88 + struct spdm_dobj_hdr_req { 89 + struct spdm_dobj_hdr hdr; /* hdr.id == SPDM_DOBJ_ID_REQ */ 90 + u8 data_type; /* spdm_data_type_t */ 91 + u8 reserved2[5]; 92 + } __packed; 93 + 94 + struct spdm_dobj_hdr_resp { 95 + struct spdm_dobj_hdr hdr; /* hdr.id == SPDM_DOBJ_ID_RESP */ 96 + u8 data_type; /* spdm_data_type_t */ 97 + u8 reserved2[5]; 98 + } __packed; 99 + 100 + /* Defined in sev-dev-tio.h so sev-dev-tsm.c can read types of blobs */ 101 + struct spdm_dobj_hdr_cert; 102 + struct spdm_dobj_hdr_meas; 103 + struct spdm_dobj_hdr_report; 104 + 105 + /* Used in all SPDM-aware TIO commands */ 106 + struct spdm_ctrl { 107 + struct sla_addr_t req; 108 + struct sla_addr_t resp; 109 + struct sla_addr_t scratch; 110 + struct sla_addr_t output; 111 + } __packed; 112 + 113 + static size_t sla_dobj_id_to_size(u8 id) 114 + { 115 + size_t n; 116 + 117 + BUILD_BUG_ON(sizeof(struct spdm_dobj_hdr_resp) != 0x10); 118 + switch (id) { 119 + case SPDM_DOBJ_ID_REQ: 120 + n = sizeof(struct spdm_dobj_hdr_req); 121 + break; 122 + case SPDM_DOBJ_ID_RESP: 123 + n = sizeof(struct spdm_dobj_hdr_resp); 124 + break; 125 + default: 126 + WARN_ON(1); 127 + n = 0; 128 + break; 129 + } 130 + 131 + return n; 132 + } 133 + 134 + #define SPDM_DOBJ_HDR_SIZE(hdr) sla_dobj_id_to_size((hdr)->id) 135 + #define SPDM_DOBJ_DATA(hdr) ((u8 *)(hdr) + SPDM_DOBJ_HDR_SIZE(hdr)) 136 + #define SPDM_DOBJ_LEN(hdr) ((hdr)->length - SPDM_DOBJ_HDR_SIZE(hdr)) 137 + 138 + #define sla_to_dobj_resp_hdr(buf) ((struct spdm_dobj_hdr_resp *) \ 139 + sla_to_dobj_hdr_check((buf), SPDM_DOBJ_ID_RESP)) 140 + #define sla_to_dobj_req_hdr(buf) ((struct spdm_dobj_hdr_req *) \ 141 + sla_to_dobj_hdr_check((buf), SPDM_DOBJ_ID_REQ)) 142 + 143 + static struct spdm_dobj_hdr *sla_to_dobj_hdr(struct sla_buffer_hdr *buf) 144 + { 145 + if (!buf) 146 + return NULL; 147 + 148 + return (struct spdm_dobj_hdr *) &buf[1]; 149 + } 150 + 151 + static struct spdm_dobj_hdr *sla_to_dobj_hdr_check(struct sla_buffer_hdr *buf, u32 check_dobjid) 152 + { 153 + struct spdm_dobj_hdr *hdr = sla_to_dobj_hdr(buf); 154 + 155 + if (WARN_ON_ONCE(!hdr)) 156 + return NULL; 157 + 158 + if (hdr->id != check_dobjid) { 159 + pr_err("! ERROR: expected %d, found %d\n", check_dobjid, hdr->id); 160 + return NULL; 161 + } 162 + 163 + return hdr; 164 + } 165 + 166 + static void *sla_to_data(struct sla_buffer_hdr *buf, u32 dobjid) 167 + { 168 + struct spdm_dobj_hdr *hdr = sla_to_dobj_hdr(buf); 169 + 170 + if (WARN_ON_ONCE(dobjid != SPDM_DOBJ_ID_REQ && dobjid != SPDM_DOBJ_ID_RESP)) 171 + return NULL; 172 + 173 + if (!hdr) 174 + return NULL; 175 + 176 + return (u8 *) hdr + sla_dobj_id_to_size(dobjid); 177 + } 178 + 179 + /* 180 + * struct sev_data_tio_status - SEV_CMD_TIO_STATUS command 181 + * 182 + * @length: Length of this command buffer in bytes 183 + * @status_paddr: System physical address of the TIO_STATUS structure 184 + */ 185 + struct sev_data_tio_status { 186 + u32 length; 187 + u8 reserved[4]; 188 + u64 status_paddr; 189 + } __packed; 190 + 191 + /* TIO_INIT */ 192 + struct sev_data_tio_init { 193 + u32 length; 194 + u8 reserved[12]; 195 + } __packed; 196 + 197 + /* 198 + * struct sev_data_tio_dev_create - TIO_DEV_CREATE command 199 + * 200 + * @length: Length in bytes of this command buffer 201 + * @dev_ctx_sla: Scatter list address pointing to a buffer to be used as a device context buffer 202 + * @device_id: PCIe Routing Identifier of the device to connect to 203 + * @root_port_id: PCIe Routing Identifier of the root port of the device 204 + * @segment_id: PCIe Segment Identifier of the device to connect to 205 + */ 206 + struct sev_data_tio_dev_create { 207 + u32 length; 208 + u8 reserved1[4]; 209 + struct sla_addr_t dev_ctx_sla; 210 + u16 device_id; 211 + u16 root_port_id; 212 + u8 segment_id; 213 + u8 reserved2[11]; 214 + } __packed; 215 + 216 + /* 217 + * struct sev_data_tio_dev_connect - TIO_DEV_CONNECT command 218 + * 219 + * @length: Length in bytes of this command buffer 220 + * @spdm_ctrl: SPDM control structure defined in Section 5.1 221 + * @dev_ctx_sla: Scatter list address of the device context buffer 222 + * @tc_mask: Bitmask of the traffic classes to initialize for SEV-TIO usage. 223 + * Setting the kth bit of the TC_MASK to 1 indicates that the traffic 224 + * class k will be initialized 225 + * @cert_slot: Slot number of the certificate requested for constructing the SPDM session 226 + * @ide_stream_id: IDE stream IDs to be associated with this device. 227 + * Valid only if corresponding bit in TC_MASK is set 228 + */ 229 + struct sev_data_tio_dev_connect { 230 + u32 length; 231 + u8 reserved1[4]; 232 + struct spdm_ctrl spdm_ctrl; 233 + u8 reserved2[8]; 234 + struct sla_addr_t dev_ctx_sla; 235 + u8 tc_mask; 236 + u8 cert_slot; 237 + u8 reserved3[6]; 238 + u8 ide_stream_id[8]; 239 + u8 reserved4[8]; 240 + } __packed; 241 + 242 + /* 243 + * struct sev_data_tio_dev_disconnect - TIO_DEV_DISCONNECT command 244 + * 245 + * @length: Length in bytes of this command buffer 246 + * @flags: Command flags (TIO_DEV_DISCONNECT_FLAG_FORCE: force disconnect) 247 + * @spdm_ctrl: SPDM control structure defined in Section 5.1 248 + * @dev_ctx_sla: Scatter list address of the device context buffer 249 + */ 250 + #define TIO_DEV_DISCONNECT_FLAG_FORCE BIT(0) 251 + 252 + struct sev_data_tio_dev_disconnect { 253 + u32 length; 254 + u32 flags; 255 + struct spdm_ctrl spdm_ctrl; 256 + struct sla_addr_t dev_ctx_sla; 257 + } __packed; 258 + 259 + /* 260 + * struct sev_data_tio_dev_meas - TIO_DEV_MEASUREMENTS command 261 + * 262 + * @length: Length in bytes of this command buffer 263 + * @flags: Command flags (TIO_DEV_MEAS_FLAG_RAW_BITSTREAM: request raw measurements) 264 + * @spdm_ctrl: SPDM control structure defined in Section 5.1 265 + * @dev_ctx_sla: Scatter list address of the device context buffer 266 + * @meas_nonce: Nonce for measurement freshness verification 267 + */ 268 + #define TIO_DEV_MEAS_FLAG_RAW_BITSTREAM BIT(0) 269 + 270 + struct sev_data_tio_dev_meas { 271 + u32 length; 272 + u32 flags; 273 + struct spdm_ctrl spdm_ctrl; 274 + struct sla_addr_t dev_ctx_sla; 275 + u8 meas_nonce[32]; 276 + } __packed; 277 + 278 + /* 279 + * struct sev_data_tio_dev_certs - TIO_DEV_CERTIFICATES command 280 + * 281 + * @length: Length in bytes of this command buffer 282 + * @spdm_ctrl: SPDM control structure defined in Section 5.1 283 + * @dev_ctx_sla: Scatter list address of the device context buffer 284 + */ 285 + struct sev_data_tio_dev_certs { 286 + u32 length; 287 + u8 reserved[4]; 288 + struct spdm_ctrl spdm_ctrl; 289 + struct sla_addr_t dev_ctx_sla; 290 + } __packed; 291 + 292 + /* 293 + * struct sev_data_tio_dev_reclaim - TIO_DEV_RECLAIM command 294 + * 295 + * @length: Length in bytes of this command buffer 296 + * @dev_ctx_sla: Scatter list address of the device context buffer 297 + * 298 + * This command reclaims resources associated with a device context. 299 + */ 300 + struct sev_data_tio_dev_reclaim { 301 + u32 length; 302 + u8 reserved[4]; 303 + struct sla_addr_t dev_ctx_sla; 304 + } __packed; 305 + 306 + static struct sla_buffer_hdr *sla_buffer_map(struct sla_addr_t sla) 307 + { 308 + struct sla_buffer_hdr *buf; 309 + 310 + BUILD_BUG_ON(sizeof(struct sla_buffer_hdr) != 0x40); 311 + if (IS_SLA_NULL(sla)) 312 + return NULL; 313 + 314 + if (sla.page_type == SLA_PAGE_TYPE_SCATTER) { 315 + struct sla_addr_t *scatter = sla_to_va(sla); 316 + unsigned int i, npages = 0; 317 + 318 + for (i = 0; i < SLA_SCATTER_LEN(sla); ++i) { 319 + if (WARN_ON_ONCE(SLA_SZ(scatter[i]) > SZ_4K)) 320 + return NULL; 321 + 322 + if (WARN_ON_ONCE(scatter[i].page_type == SLA_PAGE_TYPE_SCATTER)) 323 + return NULL; 324 + 325 + if (IS_SLA_EOL(scatter[i])) { 326 + npages = i; 327 + break; 328 + } 329 + } 330 + if (WARN_ON_ONCE(!npages)) 331 + return NULL; 332 + 333 + struct page **pp = kmalloc_array(npages, sizeof(pp[0]), GFP_KERNEL); 334 + 335 + if (!pp) 336 + return NULL; 337 + 338 + for (i = 0; i < npages; ++i) 339 + pp[i] = sla_to_page(scatter[i]); 340 + 341 + buf = vm_map_ram(pp, npages, 0); 342 + kfree(pp); 343 + } else { 344 + struct page *pg = sla_to_page(sla); 345 + 346 + buf = vm_map_ram(&pg, 1, 0); 347 + } 348 + 349 + return buf; 350 + } 351 + 352 + static void sla_buffer_unmap(struct sla_addr_t sla, struct sla_buffer_hdr *buf) 353 + { 354 + if (!buf) 355 + return; 356 + 357 + if (sla.page_type == SLA_PAGE_TYPE_SCATTER) { 358 + struct sla_addr_t *scatter = sla_to_va(sla); 359 + unsigned int i, npages = 0; 360 + 361 + for (i = 0; i < SLA_SCATTER_LEN(sla); ++i) { 362 + if (IS_SLA_EOL(scatter[i])) { 363 + npages = i; 364 + break; 365 + } 366 + } 367 + if (!npages) 368 + return; 369 + 370 + vm_unmap_ram(buf, npages); 371 + } else { 372 + vm_unmap_ram(buf, 1); 373 + } 374 + } 375 + 376 + static void dobj_response_init(struct sla_buffer_hdr *buf) 377 + { 378 + struct spdm_dobj_hdr *dobj = sla_to_dobj_hdr(buf); 379 + 380 + dobj->id = SPDM_DOBJ_ID_RESP; 381 + dobj->version.major = 0x1; 382 + dobj->version.minor = 0; 383 + dobj->length = 0; 384 + buf->payload_sz = sla_dobj_id_to_size(dobj->id) + dobj->length; 385 + } 386 + 387 + static void sla_free(struct sla_addr_t sla, size_t len, bool firmware_state) 388 + { 389 + unsigned int npages = PAGE_ALIGN(len) >> PAGE_SHIFT; 390 + struct sla_addr_t *scatter = NULL; 391 + int ret = 0, i; 392 + 393 + if (IS_SLA_NULL(sla)) 394 + return; 395 + 396 + if (firmware_state) { 397 + if (sla.page_type == SLA_PAGE_TYPE_SCATTER) { 398 + scatter = sla_to_va(sla); 399 + 400 + for (i = 0; i < npages; ++i) { 401 + if (IS_SLA_EOL(scatter[i])) 402 + break; 403 + 404 + ret = snp_reclaim_pages(sla_to_pa(scatter[i]), 1, false); 405 + if (ret) 406 + break; 407 + } 408 + } else { 409 + ret = snp_reclaim_pages(sla_to_pa(sla), 1, false); 410 + } 411 + } 412 + 413 + if (WARN_ON(ret)) 414 + return; 415 + 416 + if (scatter) { 417 + for (i = 0; i < npages; ++i) { 418 + if (IS_SLA_EOL(scatter[i])) 419 + break; 420 + free_page((unsigned long)sla_to_va(scatter[i])); 421 + } 422 + } 423 + 424 + free_page((unsigned long)sla_to_va(sla)); 425 + } 426 + 427 + static struct sla_addr_t sla_alloc(size_t len, bool firmware_state) 428 + { 429 + unsigned long i, npages = PAGE_ALIGN(len) >> PAGE_SHIFT; 430 + struct sla_addr_t *scatter = NULL; 431 + struct sla_addr_t ret = SLA_NULL; 432 + struct sla_buffer_hdr *buf; 433 + struct page *pg; 434 + 435 + if (npages == 0) 436 + return ret; 437 + 438 + if (WARN_ON_ONCE(npages > ((PAGE_SIZE / sizeof(struct sla_addr_t)) + 1))) 439 + return ret; 440 + 441 + BUILD_BUG_ON(PAGE_SIZE < SZ_4K); 442 + 443 + if (npages > 1) { 444 + pg = alloc_page(GFP_KERNEL | __GFP_ZERO); 445 + if (!pg) 446 + return SLA_NULL; 447 + 448 + ret = make_sla(pg, true); 449 + scatter = page_to_virt(pg); 450 + for (i = 0; i < npages; ++i) { 451 + pg = alloc_page(GFP_KERNEL | __GFP_ZERO); 452 + if (!pg) 453 + goto no_reclaim_exit; 454 + 455 + scatter[i] = make_sla(pg, false); 456 + } 457 + scatter[i] = SLA_EOL; 458 + } else { 459 + pg = alloc_page(GFP_KERNEL | __GFP_ZERO); 460 + if (!pg) 461 + return SLA_NULL; 462 + 463 + ret = make_sla(pg, false); 464 + } 465 + 466 + buf = sla_buffer_map(ret); 467 + if (!buf) 468 + goto no_reclaim_exit; 469 + 470 + buf->capacity_sz = (npages << PAGE_SHIFT); 471 + sla_buffer_unmap(ret, buf); 472 + 473 + if (firmware_state) { 474 + if (scatter) { 475 + for (i = 0; i < npages; ++i) { 476 + if (rmp_make_private(sla_to_pfn(scatter[i]), 0, 477 + PG_LEVEL_4K, 0, true)) 478 + goto free_exit; 479 + } 480 + } else { 481 + if (rmp_make_private(sla_to_pfn(ret), 0, PG_LEVEL_4K, 0, true)) 482 + goto no_reclaim_exit; 483 + } 484 + } 485 + 486 + return ret; 487 + 488 + no_reclaim_exit: 489 + firmware_state = false; 490 + free_exit: 491 + sla_free(ret, len, firmware_state); 492 + return SLA_NULL; 493 + } 494 + 495 + /* Expands a buffer, only firmware owned buffers allowed for now */ 496 + static int sla_expand(struct sla_addr_t *sla, size_t *len) 497 + { 498 + struct sla_buffer_hdr *oldbuf = sla_buffer_map(*sla), *newbuf; 499 + struct sla_addr_t oldsla = *sla, newsla; 500 + size_t oldlen = *len, newlen; 501 + 502 + if (!oldbuf) 503 + return -EFAULT; 504 + 505 + newlen = oldbuf->capacity_sz; 506 + if (oldbuf->capacity_sz == oldlen) { 507 + /* This buffer does not require expansion, must be another buffer */ 508 + sla_buffer_unmap(oldsla, oldbuf); 509 + return 1; 510 + } 511 + 512 + pr_notice("Expanding BUFFER from %ld to %ld bytes\n", oldlen, newlen); 513 + 514 + newsla = sla_alloc(newlen, true); 515 + if (IS_SLA_NULL(newsla)) 516 + return -ENOMEM; 517 + 518 + newbuf = sla_buffer_map(newsla); 519 + if (!newbuf) { 520 + sla_free(newsla, newlen, true); 521 + return -EFAULT; 522 + } 523 + 524 + memcpy(newbuf, oldbuf, oldlen); 525 + 526 + sla_buffer_unmap(newsla, newbuf); 527 + sla_free(oldsla, oldlen, true); 528 + *sla = newsla; 529 + *len = newlen; 530 + 531 + return 0; 532 + } 533 + 534 + static int sev_tio_do_cmd(int cmd, void *data, size_t data_len, int *psp_ret, 535 + struct tsm_dsm_tio *dev_data) 536 + { 537 + int rc; 538 + 539 + *psp_ret = 0; 540 + rc = sev_do_cmd(cmd, data, psp_ret); 541 + 542 + if (WARN_ON(!rc && *psp_ret == SEV_RET_SPDM_REQUEST)) 543 + return -EIO; 544 + 545 + if (rc == 0 && *psp_ret == SEV_RET_EXPAND_BUFFER_LENGTH_REQUEST) { 546 + int rc1, rc2; 547 + 548 + rc1 = sla_expand(&dev_data->output, &dev_data->output_len); 549 + if (rc1 < 0) 550 + return rc1; 551 + 552 + rc2 = sla_expand(&dev_data->scratch, &dev_data->scratch_len); 553 + if (rc2 < 0) 554 + return rc2; 555 + 556 + if (!rc1 && !rc2) 557 + /* Neither buffer requires expansion, this is wrong */ 558 + return -EFAULT; 559 + 560 + *psp_ret = 0; 561 + rc = sev_do_cmd(cmd, data, psp_ret); 562 + } 563 + 564 + if ((rc == 0 || rc == -EIO) && *psp_ret == SEV_RET_SPDM_REQUEST) { 565 + struct spdm_dobj_hdr_resp *resp_hdr; 566 + struct spdm_dobj_hdr_req *req_hdr; 567 + struct sev_tio_status *tio_status = to_tio_status(dev_data); 568 + size_t resp_len = tio_status->spdm_req_size_max - 569 + (sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + sizeof(struct sla_buffer_hdr)); 570 + 571 + if (!dev_data->cmd) { 572 + if (WARN_ON_ONCE(!data_len || (data_len != *(u32 *) data))) 573 + return -EINVAL; 574 + if (WARN_ON(data_len > sizeof(dev_data->cmd_data))) 575 + return -EFAULT; 576 + memcpy(dev_data->cmd_data, data, data_len); 577 + memset(&dev_data->cmd_data[data_len], 0xFF, 578 + sizeof(dev_data->cmd_data) - data_len); 579 + dev_data->cmd = cmd; 580 + } 581 + 582 + req_hdr = sla_to_dobj_req_hdr(dev_data->reqbuf); 583 + resp_hdr = sla_to_dobj_resp_hdr(dev_data->respbuf); 584 + switch (req_hdr->data_type) { 585 + case DOBJ_DATA_TYPE_SPDM: 586 + rc = PCI_DOE_FEATURE_CMA; 587 + break; 588 + case DOBJ_DATA_TYPE_SECURE_SPDM: 589 + rc = PCI_DOE_FEATURE_SSESSION; 590 + break; 591 + default: 592 + return -EINVAL; 593 + } 594 + resp_hdr->data_type = req_hdr->data_type; 595 + dev_data->spdm.req_len = req_hdr->hdr.length - 596 + sla_dobj_id_to_size(SPDM_DOBJ_ID_REQ); 597 + dev_data->spdm.rsp_len = resp_len; 598 + } else if (dev_data && dev_data->cmd) { 599 + /* For either error or success just stop the bouncing */ 600 + memset(dev_data->cmd_data, 0, sizeof(dev_data->cmd_data)); 601 + dev_data->cmd = 0; 602 + } 603 + 604 + return rc; 605 + } 606 + 607 + int sev_tio_continue(struct tsm_dsm_tio *dev_data) 608 + { 609 + struct spdm_dobj_hdr_resp *resp_hdr; 610 + int ret; 611 + 612 + if (!dev_data || !dev_data->cmd) 613 + return -EINVAL; 614 + 615 + resp_hdr = sla_to_dobj_resp_hdr(dev_data->respbuf); 616 + resp_hdr->hdr.length = ALIGN(sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + 617 + dev_data->spdm.rsp_len, 32); 618 + dev_data->respbuf->payload_sz = resp_hdr->hdr.length; 619 + 620 + ret = sev_tio_do_cmd(dev_data->cmd, dev_data->cmd_data, 0, 621 + &dev_data->psp_ret, dev_data); 622 + if (ret) 623 + return ret; 624 + 625 + if (dev_data->psp_ret != SEV_RET_SUCCESS) 626 + return -EINVAL; 627 + 628 + return 0; 629 + } 630 + 631 + static void spdm_ctrl_init(struct spdm_ctrl *ctrl, struct tsm_dsm_tio *dev_data) 632 + { 633 + ctrl->req = dev_data->req; 634 + ctrl->resp = dev_data->resp; 635 + ctrl->scratch = dev_data->scratch; 636 + ctrl->output = dev_data->output; 637 + } 638 + 639 + static void spdm_ctrl_free(struct tsm_dsm_tio *dev_data) 640 + { 641 + struct sev_tio_status *tio_status = to_tio_status(dev_data); 642 + size_t len = tio_status->spdm_req_size_max - 643 + (sla_dobj_id_to_size(SPDM_DOBJ_ID_RESP) + 644 + sizeof(struct sla_buffer_hdr)); 645 + struct tsm_spdm *spdm = &dev_data->spdm; 646 + 647 + sla_buffer_unmap(dev_data->resp, dev_data->respbuf); 648 + sla_buffer_unmap(dev_data->req, dev_data->reqbuf); 649 + spdm->rsp = NULL; 650 + spdm->req = NULL; 651 + sla_free(dev_data->req, len, true); 652 + sla_free(dev_data->resp, len, false); 653 + sla_free(dev_data->scratch, tio_status->spdm_scratch_size_max, true); 654 + 655 + dev_data->req.sla = 0; 656 + dev_data->resp.sla = 0; 657 + dev_data->scratch.sla = 0; 658 + dev_data->respbuf = NULL; 659 + dev_data->reqbuf = NULL; 660 + sla_free(dev_data->output, tio_status->spdm_out_size_max, true); 661 + } 662 + 663 + static int spdm_ctrl_alloc(struct tsm_dsm_tio *dev_data) 664 + { 665 + struct sev_tio_status *tio_status = to_tio_status(dev_data); 666 + struct tsm_spdm *spdm = &dev_data->spdm; 667 + int ret; 668 + 669 + dev_data->req = sla_alloc(tio_status->spdm_req_size_max, true); 670 + dev_data->resp = sla_alloc(tio_status->spdm_req_size_max, false); 671 + dev_data->scratch_len = tio_status->spdm_scratch_size_max; 672 + dev_data->scratch = sla_alloc(dev_data->scratch_len, true); 673 + dev_data->output_len = tio_status->spdm_out_size_max; 674 + dev_data->output = sla_alloc(dev_data->output_len, true); 675 + 676 + if (IS_SLA_NULL(dev_data->req) || IS_SLA_NULL(dev_data->resp) || 677 + IS_SLA_NULL(dev_data->scratch) || IS_SLA_NULL(dev_data->dev_ctx)) { 678 + ret = -ENOMEM; 679 + goto free_spdm_exit; 680 + } 681 + 682 + dev_data->reqbuf = sla_buffer_map(dev_data->req); 683 + dev_data->respbuf = sla_buffer_map(dev_data->resp); 684 + if (!dev_data->reqbuf || !dev_data->respbuf) { 685 + ret = -EFAULT; 686 + goto free_spdm_exit; 687 + } 688 + 689 + spdm->req = sla_to_data(dev_data->reqbuf, SPDM_DOBJ_ID_REQ); 690 + spdm->rsp = sla_to_data(dev_data->respbuf, SPDM_DOBJ_ID_RESP); 691 + if (!spdm->req || !spdm->rsp) { 692 + ret = -EFAULT; 693 + goto free_spdm_exit; 694 + } 695 + 696 + dobj_response_init(dev_data->respbuf); 697 + 698 + return 0; 699 + 700 + free_spdm_exit: 701 + spdm_ctrl_free(dev_data); 702 + return ret; 703 + } 704 + 705 + int sev_tio_init_locked(void *tio_status_page) 706 + { 707 + struct sev_tio_status *tio_status = tio_status_page; 708 + struct sev_data_tio_status data_status = { 709 + .length = sizeof(data_status), 710 + }; 711 + int ret, psp_ret; 712 + 713 + data_status.status_paddr = __psp_pa(tio_status_page); 714 + ret = __sev_do_cmd_locked(SEV_CMD_TIO_STATUS, &data_status, &psp_ret); 715 + if (ret) 716 + return ret; 717 + 718 + if (tio_status->length < offsetofend(struct sev_tio_status, tdictx_size) || 719 + tio_status->reserved) 720 + return -EFAULT; 721 + 722 + if (!tio_status->tio_en && !tio_status->tio_init_done) 723 + return -ENOENT; 724 + 725 + if (tio_status->tio_init_done) 726 + return -EBUSY; 727 + 728 + struct sev_data_tio_init ti = { .length = sizeof(ti) }; 729 + 730 + ret = __sev_do_cmd_locked(SEV_CMD_TIO_INIT, &ti, &psp_ret); 731 + if (ret) 732 + return ret; 733 + 734 + ret = __sev_do_cmd_locked(SEV_CMD_TIO_STATUS, &data_status, &psp_ret); 735 + if (ret) 736 + return ret; 737 + 738 + return 0; 739 + } 740 + 741 + int sev_tio_dev_create(struct tsm_dsm_tio *dev_data, u16 device_id, 742 + u16 root_port_id, u8 segment_id) 743 + { 744 + struct sev_tio_status *tio_status = to_tio_status(dev_data); 745 + struct sev_data_tio_dev_create create = { 746 + .length = sizeof(create), 747 + .device_id = device_id, 748 + .root_port_id = root_port_id, 749 + .segment_id = segment_id, 750 + }; 751 + void *data_pg; 752 + int ret; 753 + 754 + dev_data->dev_ctx = sla_alloc(tio_status->devctx_size, true); 755 + if (IS_SLA_NULL(dev_data->dev_ctx)) 756 + return -ENOMEM; 757 + 758 + data_pg = snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT); 759 + if (!data_pg) { 760 + ret = -ENOMEM; 761 + goto free_ctx_exit; 762 + } 763 + 764 + create.dev_ctx_sla = dev_data->dev_ctx; 765 + ret = sev_do_cmd(SEV_CMD_TIO_DEV_CREATE, &create, &dev_data->psp_ret); 766 + if (ret) 767 + goto free_data_pg_exit; 768 + 769 + dev_data->data_pg = data_pg; 770 + 771 + return 0; 772 + 773 + free_data_pg_exit: 774 + snp_free_firmware_page(data_pg); 775 + free_ctx_exit: 776 + sla_free(create.dev_ctx_sla, tio_status->devctx_size, true); 777 + return ret; 778 + } 779 + 780 + int sev_tio_dev_reclaim(struct tsm_dsm_tio *dev_data) 781 + { 782 + struct sev_tio_status *tio_status = to_tio_status(dev_data); 783 + struct sev_data_tio_dev_reclaim r = { 784 + .length = sizeof(r), 785 + .dev_ctx_sla = dev_data->dev_ctx, 786 + }; 787 + int ret; 788 + 789 + if (dev_data->data_pg) { 790 + snp_free_firmware_page(dev_data->data_pg); 791 + dev_data->data_pg = NULL; 792 + } 793 + 794 + if (IS_SLA_NULL(dev_data->dev_ctx)) 795 + return 0; 796 + 797 + ret = sev_do_cmd(SEV_CMD_TIO_DEV_RECLAIM, &r, &dev_data->psp_ret); 798 + 799 + sla_free(dev_data->dev_ctx, tio_status->devctx_size, true); 800 + dev_data->dev_ctx = SLA_NULL; 801 + 802 + spdm_ctrl_free(dev_data); 803 + 804 + return ret; 805 + } 806 + 807 + int sev_tio_dev_connect(struct tsm_dsm_tio *dev_data, u8 tc_mask, u8 ids[8], u8 cert_slot) 808 + { 809 + struct sev_data_tio_dev_connect connect = { 810 + .length = sizeof(connect), 811 + .tc_mask = tc_mask, 812 + .cert_slot = cert_slot, 813 + .dev_ctx_sla = dev_data->dev_ctx, 814 + .ide_stream_id = { 815 + ids[0], ids[1], ids[2], ids[3], 816 + ids[4], ids[5], ids[6], ids[7] 817 + }, 818 + }; 819 + int ret; 820 + 821 + if (WARN_ON(IS_SLA_NULL(dev_data->dev_ctx))) 822 + return -EFAULT; 823 + if (!(tc_mask & 1)) 824 + return -EINVAL; 825 + 826 + ret = spdm_ctrl_alloc(dev_data); 827 + if (ret) 828 + return ret; 829 + 830 + spdm_ctrl_init(&connect.spdm_ctrl, dev_data); 831 + 832 + return sev_tio_do_cmd(SEV_CMD_TIO_DEV_CONNECT, &connect, sizeof(connect), 833 + &dev_data->psp_ret, dev_data); 834 + } 835 + 836 + int sev_tio_dev_disconnect(struct tsm_dsm_tio *dev_data, bool force) 837 + { 838 + struct sev_data_tio_dev_disconnect dc = { 839 + .length = sizeof(dc), 840 + .dev_ctx_sla = dev_data->dev_ctx, 841 + .flags = force ? TIO_DEV_DISCONNECT_FLAG_FORCE : 0, 842 + }; 843 + 844 + if (WARN_ON_ONCE(IS_SLA_NULL(dev_data->dev_ctx))) 845 + return -EFAULT; 846 + 847 + spdm_ctrl_init(&dc.spdm_ctrl, dev_data); 848 + 849 + return sev_tio_do_cmd(SEV_CMD_TIO_DEV_DISCONNECT, &dc, sizeof(dc), 850 + &dev_data->psp_ret, dev_data); 851 + } 852 + 853 + int sev_tio_cmd_buffer_len(int cmd) 854 + { 855 + switch (cmd) { 856 + case SEV_CMD_TIO_STATUS: return sizeof(struct sev_data_tio_status); 857 + case SEV_CMD_TIO_INIT: return sizeof(struct sev_data_tio_init); 858 + case SEV_CMD_TIO_DEV_CREATE: return sizeof(struct sev_data_tio_dev_create); 859 + case SEV_CMD_TIO_DEV_RECLAIM: return sizeof(struct sev_data_tio_dev_reclaim); 860 + case SEV_CMD_TIO_DEV_CONNECT: return sizeof(struct sev_data_tio_dev_connect); 861 + case SEV_CMD_TIO_DEV_DISCONNECT: return sizeof(struct sev_data_tio_dev_disconnect); 862 + default: return 0; 863 + } 864 + }
+123
drivers/crypto/ccp/sev-dev-tio.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef __PSP_SEV_TIO_H__ 3 + #define __PSP_SEV_TIO_H__ 4 + 5 + #include <linux/pci-tsm.h> 6 + #include <linux/pci-ide.h> 7 + #include <linux/tsm.h> 8 + #include <uapi/linux/psp-sev.h> 9 + 10 + struct sla_addr_t { 11 + union { 12 + u64 sla; 13 + struct { 14 + u64 page_type :1, 15 + page_size :1, 16 + reserved1 :10, 17 + pfn :40, 18 + reserved2 :12; 19 + }; 20 + }; 21 + } __packed; 22 + 23 + #define SEV_TIO_MAX_COMMAND_LENGTH 128 24 + 25 + /* SPDM control structure for DOE */ 26 + struct tsm_spdm { 27 + unsigned long req_len; 28 + void *req; 29 + unsigned long rsp_len; 30 + void *rsp; 31 + }; 32 + 33 + /* Describes TIO device */ 34 + struct tsm_dsm_tio { 35 + u8 cert_slot; 36 + struct sla_addr_t dev_ctx; 37 + struct sla_addr_t req; 38 + struct sla_addr_t resp; 39 + struct sla_addr_t scratch; 40 + struct sla_addr_t output; 41 + size_t output_len; 42 + size_t scratch_len; 43 + struct tsm_spdm spdm; 44 + struct sla_buffer_hdr *reqbuf; /* vmap'ed @req for DOE */ 45 + struct sla_buffer_hdr *respbuf; /* vmap'ed @resp for DOE */ 46 + 47 + int cmd; 48 + int psp_ret; 49 + u8 cmd_data[SEV_TIO_MAX_COMMAND_LENGTH]; 50 + void *data_pg; /* Data page for DEV_STATUS/TDI_STATUS/TDI_INFO/ASID_FENCE */ 51 + 52 + #define TIO_IDE_MAX_TC 8 53 + struct pci_ide *ide[TIO_IDE_MAX_TC]; 54 + }; 55 + 56 + /* Describes TSM structure for PF0 pointed by pci_dev->tsm */ 57 + struct tio_dsm { 58 + struct pci_tsm_pf0 tsm; 59 + struct tsm_dsm_tio data; 60 + struct sev_device *sev; 61 + }; 62 + 63 + /* Data object IDs */ 64 + #define SPDM_DOBJ_ID_NONE 0 65 + #define SPDM_DOBJ_ID_REQ 1 66 + #define SPDM_DOBJ_ID_RESP 2 67 + 68 + struct spdm_dobj_hdr { 69 + u32 id; /* Data object type identifier */ 70 + u32 length; /* Length of the data object, INCLUDING THIS HEADER */ 71 + struct { /* Version of the data object structure */ 72 + u8 minor; 73 + u8 major; 74 + } version; 75 + } __packed; 76 + 77 + /** 78 + * struct sev_tio_status - TIO_STATUS command's info_paddr buffer 79 + * 80 + * @length: Length of this structure in bytes 81 + * @tio_en: Indicates that SNP_INIT_EX initialized the RMP for SEV-TIO 82 + * @tio_init_done: Indicates TIO_INIT has been invoked 83 + * @spdm_req_size_min: Minimum SPDM request buffer size in bytes 84 + * @spdm_req_size_max: Maximum SPDM request buffer size in bytes 85 + * @spdm_scratch_size_min: Minimum SPDM scratch buffer size in bytes 86 + * @spdm_scratch_size_max: Maximum SPDM scratch buffer size in bytes 87 + * @spdm_out_size_min: Minimum SPDM output buffer size in bytes 88 + * @spdm_out_size_max: Maximum for the SPDM output buffer size in bytes 89 + * @spdm_rsp_size_min: Minimum SPDM response buffer size in bytes 90 + * @spdm_rsp_size_max: Maximum SPDM response buffer size in bytes 91 + * @devctx_size: Size of a device context buffer in bytes 92 + * @tdictx_size: Size of a TDI context buffer in bytes 93 + * @tio_crypto_alg: TIO crypto algorithms supported 94 + */ 95 + struct sev_tio_status { 96 + u32 length; 97 + u32 tio_en :1, 98 + tio_init_done :1, 99 + reserved :30; 100 + u32 spdm_req_size_min; 101 + u32 spdm_req_size_max; 102 + u32 spdm_scratch_size_min; 103 + u32 spdm_scratch_size_max; 104 + u32 spdm_out_size_min; 105 + u32 spdm_out_size_max; 106 + u32 spdm_rsp_size_min; 107 + u32 spdm_rsp_size_max; 108 + u32 devctx_size; 109 + u32 tdictx_size; 110 + u32 tio_crypto_alg; 111 + u8 reserved2[12]; 112 + } __packed; 113 + 114 + int sev_tio_init_locked(void *tio_status_page); 115 + int sev_tio_continue(struct tsm_dsm_tio *dev_data); 116 + 117 + int sev_tio_dev_create(struct tsm_dsm_tio *dev_data, u16 device_id, u16 root_port_id, 118 + u8 segment_id); 119 + int sev_tio_dev_connect(struct tsm_dsm_tio *dev_data, u8 tc_mask, u8 ids[8], u8 cert_slot); 120 + int sev_tio_dev_disconnect(struct tsm_dsm_tio *dev_data, bool force); 121 + int sev_tio_dev_reclaim(struct tsm_dsm_tio *dev_data); 122 + 123 + #endif /* __PSP_SEV_TIO_H__ */
+405
drivers/crypto/ccp/sev-dev-tsm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + // Interface to CCP/SEV-TIO for generic PCIe TDISP module 4 + 5 + #include <linux/pci.h> 6 + #include <linux/device.h> 7 + #include <linux/tsm.h> 8 + #include <linux/iommu.h> 9 + #include <linux/pci-doe.h> 10 + #include <linux/bitfield.h> 11 + #include <linux/module.h> 12 + 13 + #include <asm/sev-common.h> 14 + #include <asm/sev.h> 15 + 16 + #include "psp-dev.h" 17 + #include "sev-dev.h" 18 + #include "sev-dev-tio.h" 19 + 20 + MODULE_IMPORT_NS("PCI_IDE"); 21 + 22 + #define TIO_DEFAULT_NR_IDE_STREAMS 1 23 + 24 + static uint nr_ide_streams = TIO_DEFAULT_NR_IDE_STREAMS; 25 + module_param_named(ide_nr, nr_ide_streams, uint, 0644); 26 + MODULE_PARM_DESC(ide_nr, "Set the maximum number of IDE streams per PHB"); 27 + 28 + #define dev_to_sp(dev) ((struct sp_device *)dev_get_drvdata(dev)) 29 + #define dev_to_psp(dev) ((struct psp_device *)(dev_to_sp(dev)->psp_data)) 30 + #define dev_to_sev(dev) ((struct sev_device *)(dev_to_psp(dev)->sev_data)) 31 + #define tsm_dev_to_sev(tsmdev) dev_to_sev((tsmdev)->dev.parent) 32 + 33 + #define pdev_to_tio_dsm(pdev) (container_of((pdev)->tsm, struct tio_dsm, tsm.base_tsm)) 34 + 35 + static int sev_tio_spdm_cmd(struct tio_dsm *dsm, int ret) 36 + { 37 + struct tsm_dsm_tio *dev_data = &dsm->data; 38 + struct tsm_spdm *spdm = &dev_data->spdm; 39 + 40 + /* Check the main command handler response before entering the loop */ 41 + if (ret == 0 && dev_data->psp_ret != SEV_RET_SUCCESS) 42 + return -EINVAL; 43 + 44 + if (ret <= 0) 45 + return ret; 46 + 47 + /* ret > 0 means "SPDM requested" */ 48 + while (ret == PCI_DOE_FEATURE_CMA || ret == PCI_DOE_FEATURE_SSESSION) { 49 + ret = pci_doe(dsm->tsm.doe_mb, PCI_VENDOR_ID_PCI_SIG, ret, 50 + spdm->req, spdm->req_len, spdm->rsp, spdm->rsp_len); 51 + if (ret < 0) 52 + break; 53 + 54 + WARN_ON_ONCE(ret == 0); /* The response should never be empty */ 55 + spdm->rsp_len = ret; 56 + ret = sev_tio_continue(dev_data); 57 + } 58 + 59 + return ret; 60 + } 61 + 62 + static int stream_enable(struct pci_ide *ide) 63 + { 64 + struct pci_dev *rp = pcie_find_root_port(ide->pdev); 65 + int ret; 66 + 67 + ret = pci_ide_stream_enable(rp, ide); 68 + if (ret) 69 + return ret; 70 + 71 + ret = pci_ide_stream_enable(ide->pdev, ide); 72 + if (ret) 73 + pci_ide_stream_disable(rp, ide); 74 + 75 + return ret; 76 + } 77 + 78 + static int streams_enable(struct pci_ide **ide) 79 + { 80 + int ret = 0; 81 + 82 + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) { 83 + if (ide[i]) { 84 + ret = stream_enable(ide[i]); 85 + if (ret) 86 + break; 87 + } 88 + } 89 + 90 + return ret; 91 + } 92 + 93 + static void stream_disable(struct pci_ide *ide) 94 + { 95 + pci_ide_stream_disable(ide->pdev, ide); 96 + pci_ide_stream_disable(pcie_find_root_port(ide->pdev), ide); 97 + } 98 + 99 + static void streams_disable(struct pci_ide **ide) 100 + { 101 + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) 102 + if (ide[i]) 103 + stream_disable(ide[i]); 104 + } 105 + 106 + static void stream_setup(struct pci_ide *ide) 107 + { 108 + struct pci_dev *rp = pcie_find_root_port(ide->pdev); 109 + 110 + ide->partner[PCI_IDE_EP].rid_start = 0; 111 + ide->partner[PCI_IDE_EP].rid_end = 0xffff; 112 + ide->partner[PCI_IDE_RP].rid_start = 0; 113 + ide->partner[PCI_IDE_RP].rid_end = 0xffff; 114 + 115 + ide->pdev->ide_cfg = 0; 116 + ide->pdev->ide_tee_limit = 1; 117 + rp->ide_cfg = 1; 118 + rp->ide_tee_limit = 0; 119 + 120 + pci_warn(ide->pdev, "Forcing CFG/TEE for %s", pci_name(rp)); 121 + pci_ide_stream_setup(ide->pdev, ide); 122 + pci_ide_stream_setup(rp, ide); 123 + } 124 + 125 + static u8 streams_setup(struct pci_ide **ide, u8 *ids) 126 + { 127 + bool def = false; 128 + u8 tc_mask = 0; 129 + int i; 130 + 131 + for (i = 0; i < TIO_IDE_MAX_TC; ++i) { 132 + if (!ide[i]) { 133 + ids[i] = 0xFF; 134 + continue; 135 + } 136 + 137 + tc_mask |= BIT(i); 138 + ids[i] = ide[i]->stream_id; 139 + 140 + if (!def) { 141 + struct pci_ide_partner *settings; 142 + 143 + settings = pci_ide_to_settings(ide[i]->pdev, ide[i]); 144 + settings->default_stream = 1; 145 + def = true; 146 + } 147 + 148 + stream_setup(ide[i]); 149 + } 150 + 151 + return tc_mask; 152 + } 153 + 154 + static int streams_register(struct pci_ide **ide) 155 + { 156 + int ret = 0, i; 157 + 158 + for (i = 0; i < TIO_IDE_MAX_TC; ++i) { 159 + if (ide[i]) { 160 + ret = pci_ide_stream_register(ide[i]); 161 + if (ret) 162 + break; 163 + } 164 + } 165 + 166 + return ret; 167 + } 168 + 169 + static void streams_unregister(struct pci_ide **ide) 170 + { 171 + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) 172 + if (ide[i]) 173 + pci_ide_stream_unregister(ide[i]); 174 + } 175 + 176 + static void stream_teardown(struct pci_ide *ide) 177 + { 178 + pci_ide_stream_teardown(ide->pdev, ide); 179 + pci_ide_stream_teardown(pcie_find_root_port(ide->pdev), ide); 180 + } 181 + 182 + static void streams_teardown(struct pci_ide **ide) 183 + { 184 + for (int i = 0; i < TIO_IDE_MAX_TC; ++i) { 185 + if (ide[i]) { 186 + stream_teardown(ide[i]); 187 + pci_ide_stream_free(ide[i]); 188 + ide[i] = NULL; 189 + } 190 + } 191 + } 192 + 193 + static int stream_alloc(struct pci_dev *pdev, struct pci_ide **ide, 194 + unsigned int tc) 195 + { 196 + struct pci_dev *rp = pcie_find_root_port(pdev); 197 + struct pci_ide *ide1; 198 + 199 + if (ide[tc]) { 200 + pci_err(pdev, "Stream for class=%d already registered", tc); 201 + return -EBUSY; 202 + } 203 + 204 + /* FIXME: find a better way */ 205 + if (nr_ide_streams != TIO_DEFAULT_NR_IDE_STREAMS) 206 + pci_notice(pdev, "Enable non-default %d streams", nr_ide_streams); 207 + pci_ide_set_nr_streams(to_pci_host_bridge(rp->bus->bridge), nr_ide_streams); 208 + 209 + ide1 = pci_ide_stream_alloc(pdev); 210 + if (!ide1) 211 + return -EFAULT; 212 + 213 + /* Blindly assign streamid=0 to TC=0, and so on */ 214 + ide1->stream_id = tc; 215 + 216 + ide[tc] = ide1; 217 + 218 + return 0; 219 + } 220 + 221 + static struct pci_tsm *tio_pf0_probe(struct pci_dev *pdev, struct sev_device *sev) 222 + { 223 + struct tio_dsm *dsm __free(kfree) = kzalloc(sizeof(*dsm), GFP_KERNEL); 224 + int rc; 225 + 226 + if (!dsm) 227 + return NULL; 228 + 229 + rc = pci_tsm_pf0_constructor(pdev, &dsm->tsm, sev->tsmdev); 230 + if (rc) 231 + return NULL; 232 + 233 + pci_dbg(pdev, "TSM enabled\n"); 234 + dsm->sev = sev; 235 + return &no_free_ptr(dsm)->tsm.base_tsm; 236 + } 237 + 238 + static struct pci_tsm *dsm_probe(struct tsm_dev *tsmdev, struct pci_dev *pdev) 239 + { 240 + struct sev_device *sev = tsm_dev_to_sev(tsmdev); 241 + 242 + if (is_pci_tsm_pf0(pdev)) 243 + return tio_pf0_probe(pdev, sev); 244 + return 0; 245 + } 246 + 247 + static void dsm_remove(struct pci_tsm *tsm) 248 + { 249 + struct pci_dev *pdev = tsm->pdev; 250 + 251 + pci_dbg(pdev, "TSM disabled\n"); 252 + 253 + if (is_pci_tsm_pf0(pdev)) { 254 + struct tio_dsm *dsm = container_of(tsm, struct tio_dsm, tsm.base_tsm); 255 + 256 + pci_tsm_pf0_destructor(&dsm->tsm); 257 + kfree(dsm); 258 + } 259 + } 260 + 261 + static int dsm_create(struct tio_dsm *dsm) 262 + { 263 + struct pci_dev *pdev = dsm->tsm.base_tsm.pdev; 264 + u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0; 265 + struct pci_dev *rootport = pcie_find_root_port(pdev); 266 + u16 device_id = pci_dev_id(pdev); 267 + u16 root_port_id; 268 + u32 lnkcap = 0; 269 + 270 + if (pci_read_config_dword(rootport, pci_pcie_cap(rootport) + PCI_EXP_LNKCAP, 271 + &lnkcap)) 272 + return -ENODEV; 273 + 274 + root_port_id = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); 275 + 276 + return sev_tio_dev_create(&dsm->data, device_id, root_port_id, segment_id); 277 + } 278 + 279 + static int dsm_connect(struct pci_dev *pdev) 280 + { 281 + struct tio_dsm *dsm = pdev_to_tio_dsm(pdev); 282 + struct tsm_dsm_tio *dev_data = &dsm->data; 283 + u8 ids[TIO_IDE_MAX_TC]; 284 + u8 tc_mask; 285 + int ret; 286 + 287 + if (pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG, 288 + PCI_DOE_FEATURE_SSESSION) != dsm->tsm.doe_mb) { 289 + pci_err(pdev, "CMA DOE MB must support SSESSION\n"); 290 + return -EFAULT; 291 + } 292 + 293 + ret = stream_alloc(pdev, dev_data->ide, 0); 294 + if (ret) 295 + return ret; 296 + 297 + ret = dsm_create(dsm); 298 + if (ret) 299 + goto ide_free_exit; 300 + 301 + tc_mask = streams_setup(dev_data->ide, ids); 302 + 303 + ret = sev_tio_dev_connect(dev_data, tc_mask, ids, dev_data->cert_slot); 304 + ret = sev_tio_spdm_cmd(dsm, ret); 305 + if (ret) 306 + goto free_exit; 307 + 308 + streams_enable(dev_data->ide); 309 + 310 + ret = streams_register(dev_data->ide); 311 + if (ret) 312 + goto free_exit; 313 + 314 + return 0; 315 + 316 + free_exit: 317 + sev_tio_dev_reclaim(dev_data); 318 + 319 + streams_disable(dev_data->ide); 320 + ide_free_exit: 321 + 322 + streams_teardown(dev_data->ide); 323 + 324 + return ret; 325 + } 326 + 327 + static void dsm_disconnect(struct pci_dev *pdev) 328 + { 329 + bool force = SYSTEM_HALT <= system_state && system_state <= SYSTEM_RESTART; 330 + struct tio_dsm *dsm = pdev_to_tio_dsm(pdev); 331 + struct tsm_dsm_tio *dev_data = &dsm->data; 332 + int ret; 333 + 334 + ret = sev_tio_dev_disconnect(dev_data, force); 335 + ret = sev_tio_spdm_cmd(dsm, ret); 336 + if (ret && !force) { 337 + ret = sev_tio_dev_disconnect(dev_data, true); 338 + sev_tio_spdm_cmd(dsm, ret); 339 + } 340 + 341 + sev_tio_dev_reclaim(dev_data); 342 + 343 + streams_disable(dev_data->ide); 344 + streams_unregister(dev_data->ide); 345 + streams_teardown(dev_data->ide); 346 + } 347 + 348 + static struct pci_tsm_ops sev_tsm_ops = { 349 + .probe = dsm_probe, 350 + .remove = dsm_remove, 351 + .connect = dsm_connect, 352 + .disconnect = dsm_disconnect, 353 + }; 354 + 355 + void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page) 356 + { 357 + struct sev_tio_status *t = kzalloc(sizeof(*t), GFP_KERNEL); 358 + struct tsm_dev *tsmdev; 359 + int ret; 360 + 361 + WARN_ON(sev->tio_status); 362 + 363 + if (!t) 364 + return; 365 + 366 + ret = sev_tio_init_locked(tio_status_page); 367 + if (ret) { 368 + pr_warn("SEV-TIO STATUS failed with %d\n", ret); 369 + goto error_exit; 370 + } 371 + 372 + tsmdev = tsm_register(sev->dev, &sev_tsm_ops); 373 + if (IS_ERR(tsmdev)) 374 + goto error_exit; 375 + 376 + memcpy(t, tio_status_page, sizeof(*t)); 377 + 378 + pr_notice("SEV-TIO status: EN=%d INIT_DONE=%d rq=%d..%d rs=%d..%d " 379 + "scr=%d..%d out=%d..%d dev=%d tdi=%d algos=%x\n", 380 + t->tio_en, t->tio_init_done, 381 + t->spdm_req_size_min, t->spdm_req_size_max, 382 + t->spdm_rsp_size_min, t->spdm_rsp_size_max, 383 + t->spdm_scratch_size_min, t->spdm_scratch_size_max, 384 + t->spdm_out_size_min, t->spdm_out_size_max, 385 + t->devctx_size, t->tdictx_size, 386 + t->tio_crypto_alg); 387 + 388 + sev->tsmdev = tsmdev; 389 + sev->tio_status = t; 390 + 391 + return; 392 + 393 + error_exit: 394 + kfree(t); 395 + pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n", 396 + ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV)); 397 + } 398 + 399 + void sev_tsm_uninit(struct sev_device *sev) 400 + { 401 + if (sev->tsmdev) 402 + tsm_unregister(sev->tsmdev); 403 + 404 + sev->tsmdev = NULL; 405 + }
+53 -2
drivers/crypto/ccp/sev-dev.c
··· 75 75 module_param(psp_init_on_probe, bool, 0444); 76 76 MODULE_PARM_DESC(psp_init_on_probe, " if true, the PSP will be initialized on module init. Else the PSP will be initialized on the first command requiring it"); 77 77 78 + #if IS_ENABLED(CONFIG_PCI_TSM) 79 + static bool sev_tio_enabled = true; 80 + module_param_named(tio, sev_tio_enabled, bool, 0444); 81 + MODULE_PARM_DESC(tio, "Enables TIO in SNP_INIT_EX"); 82 + #else 83 + static const bool sev_tio_enabled = false; 84 + #endif 85 + 78 86 MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */ 79 87 MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */ 80 88 MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */ ··· 259 251 case SEV_CMD_SNP_COMMIT: return sizeof(struct sev_data_snp_commit); 260 252 case SEV_CMD_SNP_FEATURE_INFO: return sizeof(struct sev_data_snp_feature_info); 261 253 case SEV_CMD_SNP_VLEK_LOAD: return sizeof(struct sev_user_data_snp_vlek_load); 262 - default: return 0; 254 + default: return sev_tio_cmd_buffer_len(cmd); 263 255 } 264 256 265 257 return 0; ··· 1402 1394 * 1403 1395 */ 1404 1396 if (sev_version_greater_or_equal(SNP_MIN_API_MAJOR, 52)) { 1397 + bool tio_supp = !!(sev->snp_feat_info_0.ebx & SNP_SEV_TIO_SUPPORTED); 1398 + 1405 1399 /* 1406 1400 * Firmware checks that the pages containing the ranges enumerated 1407 1401 * in the RANGES structure are either in the default page state or in the ··· 1444 1434 data.init_rmp = 1; 1445 1435 data.list_paddr_en = 1; 1446 1436 data.list_paddr = __psp_pa(snp_range_list); 1437 + 1438 + data.tio_en = tio_supp && sev_tio_enabled && amd_iommu_sev_tio_supported(); 1439 + 1440 + /* 1441 + * When psp_init_on_probe is disabled, the userspace calling 1442 + * SEV ioctl can inadvertently shut down SNP and SEV-TIO causing 1443 + * unexpected state loss. 1444 + */ 1445 + if (data.tio_en && !psp_init_on_probe) 1446 + dev_warn(sev->dev, "SEV-TIO as incompatible with psp_init_on_probe=0\n"); 1447 + 1447 1448 cmd = SEV_CMD_SNP_INIT_EX; 1448 1449 } else { 1449 1450 cmd = SEV_CMD_SNP_INIT; ··· 1492 1471 1493 1472 snp_hv_fixed_pages_state_update(sev, HV_FIXED); 1494 1473 sev->snp_initialized = true; 1495 - dev_dbg(sev->dev, "SEV-SNP firmware initialized\n"); 1474 + dev_dbg(sev->dev, "SEV-SNP firmware initialized, SEV-TIO is %s\n", 1475 + data.tio_en ? "enabled" : "disabled"); 1496 1476 1497 1477 dev_info(sev->dev, "SEV-SNP API:%d.%d build:%d\n", sev->api_major, 1498 1478 sev->api_minor, sev->build); 1499 1479 1500 1480 atomic_notifier_chain_register(&panic_notifier_list, 1501 1481 &snp_panic_notifier); 1482 + 1483 + if (data.tio_en) { 1484 + /* 1485 + * This executes with the sev_cmd_mutex held so down the stack 1486 + * snp_reclaim_pages(locked=false) might be needed (which is extremely 1487 + * unlikely) but will cause a deadlock. 1488 + * Instead of exporting __snp_alloc_firmware_pages(), allocate a page 1489 + * for this one call here. 1490 + */ 1491 + void *tio_status = page_address(__snp_alloc_firmware_pages( 1492 + GFP_KERNEL_ACCOUNT | __GFP_ZERO, 0, true)); 1493 + 1494 + if (tio_status) { 1495 + sev_tsm_init_locked(sev, tio_status); 1496 + __snp_free_firmware_pages(virt_to_page(tio_status), 0, true); 1497 + } 1498 + } 1502 1499 1503 1500 sev_es_tmr_size = SNP_TMR_SIZE; 1504 1501 ··· 2797 2758 2798 2759 static void sev_firmware_shutdown(struct sev_device *sev) 2799 2760 { 2761 + /* 2762 + * Calling without sev_cmd_mutex held as TSM will likely try disconnecting 2763 + * IDE and this ends up calling sev_do_cmd() which locks sev_cmd_mutex. 2764 + */ 2765 + if (sev->tio_status) 2766 + sev_tsm_uninit(sev); 2767 + 2800 2768 mutex_lock(&sev_cmd_mutex); 2769 + 2801 2770 __sev_firmware_shutdown(sev, false); 2771 + 2772 + kfree(sev->tio_status); 2773 + sev->tio_status = NULL; 2774 + 2802 2775 mutex_unlock(&sev_cmd_mutex); 2803 2776 } 2804 2777
+9
drivers/crypto/ccp/sev-dev.h
··· 34 34 struct miscdevice misc; 35 35 }; 36 36 37 + struct sev_tio_status; 38 + 37 39 struct sev_device { 38 40 struct device *dev; 39 41 struct psp_device *psp; ··· 63 61 64 62 struct sev_user_data_snp_status snp_plat_status; 65 63 struct snp_feature_info snp_feat_info_0; 64 + 65 + struct tsm_dev *tsmdev; 66 + struct sev_tio_status *tio_status; 66 67 }; 67 68 68 69 int sev_dev_init(struct psp_device *psp); ··· 78 73 79 74 struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages); 80 75 void snp_free_hv_fixed_pages(struct page *page); 76 + 77 + void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page); 78 + void sev_tsm_uninit(struct sev_device *sev); 79 + int sev_tio_cmd_buffer_len(int cmd); 81 80 82 81 #endif /* __SEV_DEV_H */
+10 -1
include/linux/psp-sev.h
··· 109 109 SEV_CMD_SNP_VLEK_LOAD = 0x0CD, 110 110 SEV_CMD_SNP_FEATURE_INFO = 0x0CE, 111 111 112 + /* SEV-TIO commands */ 113 + SEV_CMD_TIO_STATUS = 0x0D0, 114 + SEV_CMD_TIO_INIT = 0x0D1, 115 + SEV_CMD_TIO_DEV_CREATE = 0x0D2, 116 + SEV_CMD_TIO_DEV_RECLAIM = 0x0D3, 117 + SEV_CMD_TIO_DEV_CONNECT = 0x0D4, 118 + SEV_CMD_TIO_DEV_DISCONNECT = 0x0D5, 112 119 SEV_CMD_MAX, 113 120 }; 114 121 ··· 757 750 u32 list_paddr_en:1; 758 751 u32 rapl_dis:1; 759 752 u32 ciphertext_hiding_en:1; 760 - u32 rsvd:28; 753 + u32 tio_en:1; 754 + u32 rsvd:27; 761 755 u32 rsvd1; 762 756 u64 list_paddr; 763 757 u16 max_snp_asid; ··· 858 850 } __packed; 859 851 860 852 #define SNP_CIPHER_TEXT_HIDING_SUPPORTED BIT(3) 853 + #define SNP_SEV_TIO_SUPPORTED BIT(1) /* EBX */ 861 854 862 855 #ifdef CONFIG_CRYPTO_DEV_SP_PSP 863 856