Skip to content

Commit f16469e

Browse files
committed
PCI/IDE: Enumerate Selective Stream IDE capabilities
Link encryption is a new PCIe feature enumerated by "PCIe r7.0 section 7.9.26 IDE Extended Capability". It is both a standalone port + endpoint capability, and a building block for the security protocol defined by "PCIe r7.0 section 11 TEE Device Interface Security Protocol (TDISP)". That protocol coordinates device security setup between a platform TSM (TEE Security Manager) and a device DSM (Device Security Manager). While the platform TSM can allocate resources like Stream ID and manage keys, it still requires system software to manage the IDE capability register block. Add register definitions and basic enumeration in preparation for Selective IDE Stream establishment. A follow on change selects the new CONFIG_PCI_IDE symbol. Note that while the IDE specification defines both a point-to-point "Link Stream" and a Root Port to endpoint "Selective Stream", only "Selective Stream" is considered for Linux as that is the predominant mode expected by Trusted Execution Environment Security Managers (TSMs), and it is the security model that limits the number of PCI components within the TCB in a PCIe topology with switches. Co-developed-by: Alexey Kardashevskiy <aik@amd.com> Signed-off-by: Alexey Kardashevskiy <aik@amd.com> Co-developed-by: Xu Yilun <yilun.xu@linux.intel.com> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Alexey Kardashevskiy <aik@amd.com> Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@kernel.org> Link: https://patch.msgid.link/20251031212902.2256310-3-dan.j.williams@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 603c646 commit f16469e

7 files changed

Lines changed: 187 additions & 0 deletions

File tree

drivers/pci/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ config XEN_PCIDEV_FRONTEND
122122
config PCI_ATS
123123
bool
124124

125+
config PCI_IDE
126+
bool
127+
125128
config PCI_DOE
126129
bool "Enable PCI Data Object Exchange (DOE) support"
127130
help

drivers/pci/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ obj-$(CONFIG_PCI_P2PDMA) += p2pdma.o
3434
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
3535
obj-$(CONFIG_VGA_ARB) += vgaarb.o
3636
obj-$(CONFIG_PCI_DOE) += doe.o
37+
obj-$(CONFIG_PCI_IDE) += ide.o
3738
obj-$(CONFIG_PCI_DYNAMIC_OF_NODES) += of_property.o
3839
obj-$(CONFIG_PCI_NPEM) += npem.o
3940
obj-$(CONFIG_PCIE_TPH) += tph.o

drivers/pci/ide.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright(c) 2024-2025 Intel Corporation. All rights reserved. */
3+
4+
/* PCIe r7.0 section 6.33 Integrity & Data Encryption (IDE) */
5+
6+
#define dev_fmt(fmt) "PCI/IDE: " fmt
7+
#include <linux/bitfield.h>
8+
#include <linux/pci.h>
9+
#include <linux/pci_regs.h>
10+
11+
#include "pci.h"
12+
13+
static int __sel_ide_offset(u16 ide_cap, u8 nr_link_ide, u8 stream_index,
14+
u8 nr_ide_mem)
15+
{
16+
u32 offset = ide_cap + PCI_IDE_LINK_STREAM_0 +
17+
nr_link_ide * PCI_IDE_LINK_BLOCK_SIZE;
18+
19+
/*
20+
* Assume a constant number of address association resources per stream
21+
* index
22+
*/
23+
return offset + stream_index * PCI_IDE_SEL_BLOCK_SIZE(nr_ide_mem);
24+
}
25+
26+
void pci_ide_init(struct pci_dev *pdev)
27+
{
28+
u16 nr_link_ide, nr_ide_mem, nr_streams;
29+
u16 ide_cap;
30+
u32 val;
31+
32+
if (!pci_is_pcie(pdev))
33+
return;
34+
35+
ide_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_IDE);
36+
if (!ide_cap)
37+
return;
38+
39+
pci_read_config_dword(pdev, ide_cap + PCI_IDE_CAP, &val);
40+
if ((val & PCI_IDE_CAP_SELECTIVE) == 0)
41+
return;
42+
43+
/*
44+
* Require endpoint IDE capability to be paired with IDE Root Port IDE
45+
* capability.
46+
*/
47+
if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ENDPOINT) {
48+
struct pci_dev *rp = pcie_find_root_port(pdev);
49+
50+
if (!rp->ide_cap)
51+
return;
52+
}
53+
54+
pdev->ide_cfg = FIELD_GET(PCI_IDE_CAP_SEL_CFG, val);
55+
pdev->ide_tee_limit = FIELD_GET(PCI_IDE_CAP_TEE_LIMITED, val);
56+
57+
if (val & PCI_IDE_CAP_LINK)
58+
nr_link_ide = 1 + FIELD_GET(PCI_IDE_CAP_LINK_TC_NUM, val);
59+
else
60+
nr_link_ide = 0;
61+
62+
nr_ide_mem = 0;
63+
nr_streams = 1 + FIELD_GET(PCI_IDE_CAP_SEL_NUM, val);
64+
for (u16 i = 0; i < nr_streams; i++) {
65+
int pos = __sel_ide_offset(ide_cap, nr_link_ide, i, nr_ide_mem);
66+
int nr_assoc;
67+
u32 val;
68+
69+
pci_read_config_dword(pdev, pos + PCI_IDE_SEL_CAP, &val);
70+
71+
/*
72+
* Let's not entertain streams that do not have a constant
73+
* number of address association blocks
74+
*/
75+
nr_assoc = FIELD_GET(PCI_IDE_SEL_CAP_ASSOC_NUM, val);
76+
if (i && (nr_assoc != nr_ide_mem)) {
77+
pci_info(pdev, "Unsupported Selective Stream %d capability, SKIP the rest\n", i);
78+
nr_streams = i;
79+
break;
80+
}
81+
82+
nr_ide_mem = nr_assoc;
83+
}
84+
85+
pdev->ide_cap = ide_cap;
86+
pdev->nr_link_ide = nr_link_ide;
87+
pdev->nr_ide_mem = nr_ide_mem;
88+
}

drivers/pci/pci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,12 @@ static inline void pci_doe_sysfs_init(struct pci_dev *pdev) { }
613613
static inline void pci_doe_sysfs_teardown(struct pci_dev *pdev) { }
614614
#endif
615615

616+
#ifdef CONFIG_PCI_IDE
617+
void pci_ide_init(struct pci_dev *dev);
618+
#else
619+
static inline void pci_ide_init(struct pci_dev *dev) { }
620+
#endif
621+
616622
/**
617623
* pci_dev_set_io_state - Set the new error state if possible.
618624
*

drivers/pci/probe.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,6 +2667,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
26672667
pci_doe_init(dev); /* Data Object Exchange */
26682668
pci_tph_init(dev); /* TLP Processing Hints */
26692669
pci_rebar_init(dev); /* Resizable BAR */
2670+
pci_ide_init(dev); /* Link Integrity and Data Encryption */
26702671

26712672
pcie_report_downtraining(dev);
26722673
pci_init_reset_methods(dev);

include/linux/pci.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,13 @@ struct pci_dev {
539539
#endif
540540
#ifdef CONFIG_PCI_NPEM
541541
struct npem *npem; /* Native PCIe Enclosure Management */
542+
#endif
543+
#ifdef CONFIG_PCI_IDE
544+
u16 ide_cap; /* Link Integrity & Data Encryption */
545+
u8 nr_ide_mem; /* Address association resources for streams */
546+
u8 nr_link_ide; /* Link Stream count (Selective Stream offset) */
547+
unsigned int ide_cfg:1; /* Config cycles over IDE */
548+
unsigned int ide_tee_limit:1; /* Disallow T=0 traffic over IDE */
542549
#endif
543550
u16 acs_cap; /* ACS Capability offset */
544551
u8 supported_speeds; /* Supported Link Speeds Vector */

include/uapi/linux/pci_regs.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@
754754
#define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */
755755
#define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */
756756
#define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */
757+
#define PCI_EXT_CAP_ID_IDE 0x30 /* Integrity and Data Encryption */
757758
#define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */
758759
#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT
759760

@@ -1249,4 +1250,84 @@
12491250
#define PCI_DVSEC_CXL_PORT_CTL 0x0c
12501251
#define PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR 0x00000001
12511252

1253+
/* Integrity and Data Encryption Extended Capability */
1254+
#define PCI_IDE_CAP 0x04
1255+
#define PCI_IDE_CAP_LINK 0x1 /* Link IDE Stream Supported */
1256+
#define PCI_IDE_CAP_SELECTIVE 0x2 /* Selective IDE Streams Supported */
1257+
#define PCI_IDE_CAP_FLOWTHROUGH 0x4 /* Flow-Through IDE Stream Supported */
1258+
#define PCI_IDE_CAP_PARTIAL_HEADER_ENC 0x8 /* Partial Header Encryption Supported */
1259+
#define PCI_IDE_CAP_AGGREGATION 0x10 /* Aggregation Supported */
1260+
#define PCI_IDE_CAP_PCRC 0x20 /* PCRC Supported */
1261+
#define PCI_IDE_CAP_IDE_KM 0x40 /* IDE_KM Protocol Supported */
1262+
#define PCI_IDE_CAP_SEL_CFG 0x80 /* Selective IDE for Config Request Support */
1263+
#define PCI_IDE_CAP_ALG __GENMASK(12, 8) /* Supported Algorithms */
1264+
#define PCI_IDE_CAP_ALG_AES_GCM_256 0 /* AES-GCM 256 key size, 96b MAC */
1265+
#define PCI_IDE_CAP_LINK_TC_NUM __GENMASK(15, 13) /* Link IDE TCs */
1266+
#define PCI_IDE_CAP_SEL_NUM __GENMASK(23, 16) /* Supported Selective IDE Streams */
1267+
#define PCI_IDE_CAP_TEE_LIMITED 0x1000000 /* TEE-Limited Stream Supported */
1268+
#define PCI_IDE_CTL 0x08
1269+
#define PCI_IDE_CTL_FLOWTHROUGH_IDE 0x4 /* Flow-Through IDE Stream Enabled */
1270+
1271+
#define PCI_IDE_LINK_STREAM_0 0xc /* First Link Stream Register Block */
1272+
#define PCI_IDE_LINK_BLOCK_SIZE 8
1273+
/* Link IDE Stream block, up to PCI_IDE_CAP_LINK_TC_NUM */
1274+
#define PCI_IDE_LINK_CTL_0 0x00 /* First Link Control Register Offset in block */
1275+
#define PCI_IDE_LINK_CTL_EN 0x1 /* Link IDE Stream Enable */
1276+
#define PCI_IDE_LINK_CTL_TX_AGGR_NPR __GENMASK(3, 2) /* Tx Aggregation Mode NPR */
1277+
#define PCI_IDE_LINK_CTL_TX_AGGR_PR __GENMASK(5, 4) /* Tx Aggregation Mode PR */
1278+
#define PCI_IDE_LINK_CTL_TX_AGGR_CPL __GENMASK(7, 6) /* Tx Aggregation Mode CPL */
1279+
#define PCI_IDE_LINK_CTL_PCRC_EN 0x100 /* PCRC Enable */
1280+
#define PCI_IDE_LINK_CTL_PART_ENC __GENMASK(13, 10) /* Partial Header Encryption Mode */
1281+
#define PCI_IDE_LINK_CTL_ALG __GENMASK(18, 14) /* Selection from PCI_IDE_CAP_ALG */
1282+
#define PCI_IDE_LINK_CTL_TC __GENMASK(21, 19) /* Traffic Class */
1283+
#define PCI_IDE_LINK_CTL_ID __GENMASK(31, 24) /* Stream ID */
1284+
#define PCI_IDE_LINK_STS_0 0x4 /* First Link Status Register Offset in block */
1285+
#define PCI_IDE_LINK_STS_STATE __GENMASK(3, 0) /* Link IDE Stream State */
1286+
#define PCI_IDE_LINK_STS_IDE_FAIL 0x80000000 /* IDE fail message received */
1287+
1288+
/* Selective IDE Stream block, up to PCI_IDE_CAP_SELECTIVE_STREAMS_NUM */
1289+
/* Selective IDE Stream Capability Register */
1290+
#define PCI_IDE_SEL_CAP 0x00
1291+
#define PCI_IDE_SEL_CAP_ASSOC_NUM __GENMASK(3, 0)
1292+
/* Selective IDE Stream Control Register */
1293+
#define PCI_IDE_SEL_CTL 0x04
1294+
#define PCI_IDE_SEL_CTL_EN 0x1 /* Selective IDE Stream Enable */
1295+
#define PCI_IDE_SEL_CTL_TX_AGGR_NPR __GENMASK(3, 2) /* Tx Aggregation Mode NPR */
1296+
#define PCI_IDE_SEL_CTL_TX_AGGR_PR __GENMASK(5, 4) /* Tx Aggregation Mode PR */
1297+
#define PCI_IDE_SEL_CTL_TX_AGGR_CPL __GENMASK(7, 6) /* Tx Aggregation Mode CPL */
1298+
#define PCI_IDE_SEL_CTL_PCRC_EN 0x100 /* PCRC Enable */
1299+
#define PCI_IDE_SEL_CTL_CFG_EN 0x200 /* Selective IDE for Configuration Requests */
1300+
#define PCI_IDE_SEL_CTL_PART_ENC __GENMASK(13, 10) /* Partial Header Encryption Mode */
1301+
#define PCI_IDE_SEL_CTL_ALG __GENMASK(18, 14) /* Selection from PCI_IDE_CAP_ALG */
1302+
#define PCI_IDE_SEL_CTL_TC __GENMASK(21, 19) /* Traffic Class */
1303+
#define PCI_IDE_SEL_CTL_DEFAULT 0x400000 /* Default Stream */
1304+
#define PCI_IDE_SEL_CTL_TEE_LIMITED 0x800000 /* TEE-Limited Stream */
1305+
#define PCI_IDE_SEL_CTL_ID __GENMASK(31, 24) /* Stream ID */
1306+
#define PCI_IDE_SEL_CTL_ID_MAX 255
1307+
/* Selective IDE Stream Status Register */
1308+
#define PCI_IDE_SEL_STS 0x08
1309+
#define PCI_IDE_SEL_STS_STATE __GENMASK(3, 0) /* Selective IDE Stream State */
1310+
#define PCI_IDE_SEL_STS_STATE_INSECURE 0
1311+
#define PCI_IDE_SEL_STS_STATE_SECURE 2
1312+
#define PCI_IDE_SEL_STS_IDE_FAIL 0x80000000 /* IDE fail message received */
1313+
/* IDE RID Association Register 1 */
1314+
#define PCI_IDE_SEL_RID_1 0x0c
1315+
#define PCI_IDE_SEL_RID_1_LIMIT __GENMASK(23, 8)
1316+
/* IDE RID Association Register 2 */
1317+
#define PCI_IDE_SEL_RID_2 0x10
1318+
#define PCI_IDE_SEL_RID_2_VALID 0x1
1319+
#define PCI_IDE_SEL_RID_2_BASE __GENMASK(23, 8)
1320+
#define PCI_IDE_SEL_RID_2_SEG __GENMASK(31, 24)
1321+
/* Selective IDE Address Association Register Block, up to PCI_IDE_SEL_CAP_ASSOC_NUM */
1322+
#define PCI_IDE_SEL_ADDR_BLOCK_SIZE 12
1323+
#define PCI_IDE_SEL_ADDR_1(x) (20 + (x) * PCI_IDE_SEL_ADDR_BLOCK_SIZE)
1324+
#define PCI_IDE_SEL_ADDR_1_VALID 0x1
1325+
#define PCI_IDE_SEL_ADDR_1_BASE_LOW __GENMASK(19, 8)
1326+
#define PCI_IDE_SEL_ADDR_1_LIMIT_LOW __GENMASK(31, 20)
1327+
/* IDE Address Association Register 2 is "Memory Limit Upper" */
1328+
#define PCI_IDE_SEL_ADDR_2(x) (24 + (x) * PCI_IDE_SEL_ADDR_BLOCK_SIZE)
1329+
/* IDE Address Association Register 3 is "Memory Base Upper" */
1330+
#define PCI_IDE_SEL_ADDR_3(x) (28 + (x) * PCI_IDE_SEL_ADDR_BLOCK_SIZE)
1331+
#define PCI_IDE_SEL_BLOCK_SIZE(nr_assoc) (20 + PCI_IDE_SEL_ADDR_BLOCK_SIZE * (nr_assoc))
1332+
12521333
#endif /* LINUX_PCI_REGS_H */

0 commit comments

Comments
 (0)