Linux PCI subsystem development
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@amd.com>
To: dan.j.williams@intel.com, linux-coco@lists.linux.dev,
	linux-pci@vger.kernel.org
Cc: yilun.xu@linux.intel.com, aneesh.kumar@kernel.org,
	gregkh@linuxfoundation.org, Bjorn Helgaas <bhelgaas@google.com>,
	Lukas Wunner <lukas@wunner.de>, Samuel Ortiz <sameo@rivosinc.com>
Subject: Re: [PATCH v5 07/10] PCI/IDE: Add IDE establishment helpers
Date: Fri, 17 Oct 2025 15:06:28 +1100	[thread overview]
Message-ID: <3d100559-8eb8-46cb-94b3-34ca9fb6dd96@amd.com> (raw)
In-Reply-To: <68bb95a07043f_75db100bf@dwillia2-mobl4.notmuch>



On 6/9/25 12:00, dan.j.williams@intel.com wrote:
> Alexey Kardashevskiy wrote:
> [..]
>>>>
>>>> Ah this is an actual problem, this is not right. The PCIe r6.1 spec says:
>>>>
>>>> "It is permitted, but strongly not recommended, to Set the Enable bit in the IDE Extended Capability
>>>> entry for a Stream prior to the completion of key programming for that Stream".
>>>
>>> This ordering is controlled by the TSM driver though...
>>
>> yes so pci_ide_stream_enable() should just do what it was asked -
>> enable the bit, the PCIe spec says the stream does not have to go to
>> the secure state right away.
> 
> That is reasonable, I will leave the error detection to the low-level
> TSM driver.
> 
>>>> And I have a device like that where the links goes secure after the last
>>>> key is SET_GO. So it is okay to return an error here but not ok to clear
>>>> the Enabled bit.
>>>
>>> ...can you not simply wait to call pci_ide_stream_enable() until after the
>>> SET_GO?
>> Nope, if they keys are programmed without the enabled bit set, the
>> stream never goes secure on this device.
>>
>> The way to think about it (an AMD hw engineer told me): devices do not
>> have extra memory to store all these keys before deciding which stream
>> they are for, they really (really) want to write the keys to the PHYs
>> (or whatever that hardware piece is called) as they come. And after
>> the device reset, say, both link stream #0 and selective stream #0
>> have the same streamid=0.
> 
> Ah, ok.
> 
>> Now, the devices need to know which stream it is - link or selective.
>> One way is: enable a stream beforehand and then the device will store
>> keys in that streams's slot. The other way is: wait till SET_GO but
>> before that every stream on the device needs an unique stream id
>> assigned to it.
>>
>> I even have this in my tree (to fight another device):
>>
>> https://github.com/AMDESE/linux-kvm/commit/ddd1f401665a4f0b6036330eea6662aec566986b
> 
> I recall we talked about this before, not liking the lack of tracking of
> these placeholder ids which would need to be adjusted later, and not
> understanding the need for uniqueness of idle ids.
> 
> It is also actively destructive to platform-firmware established IDE
> which is possible on Intel platforms and part of the specification of
> CXL TSP.
> 
> What about something like this (but I think it should be an incremental
> patch that details this class of hardware problem that requires system
> software to manage idle ids).

(I know it is not a real patch but I gave it a try anyway)

> 
> -- 8< --
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 0183ca6f6954..2dd90c0703e0 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -125,17 +125,6 @@ config PCI_ATS
>   config PCI_IDE
>   	bool
>   
> -config PCI_IDE_STREAM_MAX
> -	int "Maximum number of Selective IDE Streams supported per host bridge" if EXPERT
> -	depends on PCI_IDE
> -	range 1 256
> -	default 64
> -	help
> -	  Set a kernel max for the number of IDE streams the PCI core supports
> -	  per device. While the PCI specification max is 256, the hardware
> -	  platform capability for the foreseeable future is 4 to 8 streams. Bump
> -	  this value up if you have an expert testing need.
> -
>   config PCI_TSM
>   	bool "PCI TSM: Device security protocol support"
>   	select PCI_IDE
> diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c
> index 610603865d9e..e8a9c5fd8a36 100644
> --- a/drivers/pci/ide.c
> +++ b/drivers/pci/ide.c
> @@ -36,7 +36,7 @@ static int sel_ide_offset(struct pci_dev *pdev,
>   
>   void pci_ide_init(struct pci_dev *pdev)
>   {
> -	u8 nr_link_ide, nr_ide_mem, nr_streams;
> +	u8 nr_link_ide, nr_ide_mem, nr_streams, reserved_id;
>   	u16 ide_cap;
>   	u32 val;
>   
> @@ -74,14 +74,13 @@ void pci_ide_init(struct pci_dev *pdev)
>   		nr_link_ide = 0;
>   
>   	nr_ide_mem = 0;
> -	nr_streams = min(1 + FIELD_GET(PCI_IDE_CAP_SEL_NUM, val),
> -			 CONFIG_PCI_IDE_STREAM_MAX);
> +	nr_streams = 1 + FIELD_GET(PCI_IDE_CAP_SEL_NUM, val);
>   	for (u8 i = 0; i < nr_streams; i++) {
>   		int pos = __sel_ide_offset(ide_cap, nr_link_ide, i, nr_ide_mem);
>   		int nr_assoc;
>   		u32 val;
>   
> -		pci_read_config_dword(pdev, pos, &val);
> +		pci_read_config_dword(pdev, pos + PCI_IDE_SEL_CAP, &val);
>   
>   		/*
>   		 * Let's not entertain streams that do not have a
> @@ -95,7 +94,65 @@ void pci_ide_init(struct pci_dev *pdev)
>   		}
>   
>   		nr_ide_mem = nr_assoc;
> +
> +		/* Reserve stream-ids that are already active on the device */
> +		pci_read_config_dword(pdev, pos + PCI_IDE_SEL_CAP, &val);


PCI_IDE_SEL_CTL


> +		if (val & PCI_IDE_SEL_CTL_EN) {
> +			u8 id = FIELD_GET(PCI_IDE_SEL_CTL_ID, val);
> +
> +			pci_info(pdev, "Selective Stream %d id: %d active at init\n", i, id);
> +			set_bit(id, pdev->ide_stream_map);
> +		}
> +	}
> +
> +	/* Reserve link stream-ids that are already active on the device */
> +	for (int i = 0; i < nr_link_ide; ++i) {
> +		int pos = ide_cap + PCI_IDE_LINK_STREAM_0 + i * PCI_IDE_LINK_BLOCK_SIZE;
> +
> +		pci_read_config_dword(pdev, pos, &val);
> +		if (val & PCI_IDE_LINK_CTL_EN) {
> +			u8 id = FIELD_GET(PCI_IDE_LINK_CTL_ID, val);
> +
> +			pci_info(pdev, "Link Stream %d id: %d active at init\n",
> +				 i, id);
> +			set_bit(id, pdev->ide_stream_map);
> +		}
> +	}
> +
> +	/*
> +	 * Now that in use ids are known, grab and assign a free id for idle
> +	 * streams to remove ambiguity of which key slot is being activated by a
> +	 * K_SET_GO event (PCIe r7.0 section 6.33.3 IDE Key Management (IDE_KM))
> +	 */
> +	reserved_id = find_first_zero_bit(pdev->ide_stream_map, U8_MAX);


pci_ide_init() is called when PCI is probing and at that point no stream is enabled so reserved_id ends up as 0.

Since my platform only wants 1 stream, should I have called pci_ide_init_nr_streams() with "2", not "1"?

pci_ide_stream_alloc() fails to find a stream - fails in:

  struct stream_index *ep_stream __free(free_stream) = alloc_stream_index(
          pdev->ide_stream_map, pdev->nr_sel_ide, &__stream[PCI_IDE_EP]);

as nr_sel_ide==1 (my EP has just one stream). If I go with reserved_id==0 and set ide->stream_id=1 in the PSP TSM driver, then streamindex#1 gets programmed (which is beyond the end of IDE cap) with streamid=0. As if reserved_id is actually reserved_index but the device wants me to reserve an ID.

We could simplify it by assigning something like "255" to all unused+disabled streams. Thanks,


> +	if (reserved_id == U8_MAX) {
> +		pci_info(pdev, "No available Stream IDs, disable IDE\n");
> +		return;
> +	}
> +
> +	for (u8 i = 0; i < nr_streams; i++) {
> +		int pos = __sel_ide_offset(ide_cap, nr_link_ide, i, nr_ide_mem);
> +
> +		pci_read_config_dword(pdev, pos + PCI_IDE_SEL_CAP, &val);
> +		if (val & PCI_IDE_SEL_CTL_EN)
> +			continue;
> +		val &= ~PCI_IDE_SEL_CTL_ID;
> +		val |= FIELD_PREP(PCI_IDE_SEL_CTL_ID, reserved_id);
> +		pci_write_config_dword(pdev, pos + PCI_IDE_SEL_CTL, val);
> +	}
> +
> +	for (int i = 0; i < nr_link_ide; ++i) {
> +		int pos = ide_cap + PCI_IDE_LINK_STREAM_0 +
> +			  i * PCI_IDE_LINK_BLOCK_SIZE;
> +
> +		pci_read_config_dword(pdev, pos, &val);
> +		if (val & PCI_IDE_LINK_CTL_EN)
> +			continue;
> +		val &= ~PCI_IDE_LINK_CTL_ID;
> +		val |= FIELD_PREP(PCI_IDE_LINK_CTL_ID, reserved_id);
> +		pci_write_config_dword(pdev, pos, val);
>   	}
> +	set_bit(reserved_id, pdev->ide_stream_map);
>   
>   	pdev->ide_cap = ide_cap;
>   	pdev->nr_link_ide = nr_link_ide;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 45360ba87538..6d16278e2d94 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -545,7 +545,7 @@ struct pci_dev {
>   	u8		nr_ide_mem;	/* Address association resources for streams */
>   	u8		nr_link_ide;	/* Link Stream count (Selective Stream offset) */
>   	u8		nr_sel_ide;	/* Selective Stream count (register block allocator) */
> -	DECLARE_BITMAP(ide_stream_map, CONFIG_PCI_IDE_STREAM_MAX);
> +	DECLARE_BITMAP(ide_stream_map, U8_MAX);
>   	unsigned int	ide_cfg:1;	/* Config cycles over IDE */
>   	unsigned int	ide_tee_limit:1; /* Disallow T=0 traffic over IDE */
>   #endif
> @@ -617,7 +617,7 @@ struct pci_host_bridge {
>   	struct list_head dma_ranges;	/* dma ranges resource list */
>   #ifdef CONFIG_PCI_IDE
>   	u8 nr_ide_streams; /* Max streams possibly active in @ide_stream_map */
> -	DECLARE_BITMAP(ide_stream_map, CONFIG_PCI_IDE_STREAM_MAX);
> +	DECLARE_BITMAP(ide_stream_map, U8_MAX);
>   #endif
>   	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
>   	int (*map_irq)(const struct pci_dev *, u8, u8);

-- 
Alexey


  parent reply	other threads:[~2025-10-17  4:07 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-27  3:51 [PATCH v5 00/10] PCI/TSM: Core infrastructure for PCI device security (TDISP) Dan Williams
2025-08-27  3:51 ` [PATCH v5 01/10] coco/tsm: Introduce a core device for TEE Security Managers Dan Williams
2025-08-27  3:51 ` [PATCH v5 02/10] PCI/IDE: Enumerate Selective Stream IDE capabilities Dan Williams
2025-09-15 16:18   ` Jonathan Cameron
2025-09-19 23:32     ` dan.j.williams
2025-08-27  3:51 ` [PATCH v5 03/10] PCI: Introduce pci_walk_bus_reverse(), for_each_pci_dev_reverse() Dan Williams
2025-08-27  3:51 ` [PATCH v5 04/10] PCI/TSM: Authenticate devices via platform TSM Dan Williams
2025-08-27 13:25   ` Alexey Kardashevskiy
2025-08-29  1:06     ` dan.j.williams
2025-08-29  1:58       ` Alexey Kardashevskiy
2025-09-05  0:50         ` dan.j.williams
2025-09-05  3:34           ` Alexey Kardashevskiy
2025-09-06  2:07             ` dan.j.williams
2025-09-08  6:13               ` Alexey Kardashevskiy
2025-09-09  0:41                 ` dan.j.williams
2025-09-09  1:35                   ` Alexey Kardashevskiy
2025-09-09  1:52                     ` dan.j.williams
2025-09-10 10:55                       ` Alexey Kardashevskiy
2025-09-10 15:45                         ` dan.j.williams
2025-08-28 11:43   ` Alexey Kardashevskiy
2025-08-29  1:23     ` dan.j.williams
2025-08-30 13:26   ` Alexey Kardashevskiy
2025-09-05  0:51     ` dan.j.williams
2025-09-02 15:08   ` Aneesh Kumar K.V
2025-09-03  2:03     ` Alexey Kardashevskiy
2025-09-05 20:06       ` dan.j.williams
2025-09-05 19:13     ` dan.j.williams
2025-09-02 15:13   ` Aneesh Kumar K.V
2025-09-03  2:07     ` Alexey Kardashevskiy
2025-09-05 20:13       ` dan.j.williams
2025-09-08 11:19         ` Alexey Kardashevskiy
2025-09-05 20:03     ` dan.j.williams
2025-09-03  2:17   ` Alexey Kardashevskiy
2025-09-05 20:35     ` dan.j.williams
2025-08-27  3:51 ` [PATCH v5 05/10] samples/devsec: Introduce a PCI device-security bus + endpoint sample Dan Williams
2025-08-27  3:51 ` [PATCH v5 06/10] PCI: Add PCIe Device 3 Extended Capability enumeration Dan Williams
2025-08-27  3:51 ` [PATCH v5 07/10] PCI/IDE: Add IDE establishment helpers Dan Williams
2025-09-02  1:29   ` Alexey Kardashevskiy
2025-09-02  1:54     ` Alexey Kardashevskiy
2025-09-05  1:40       ` dan.j.williams
2025-09-05  2:14         ` Alexey Kardashevskiy
2025-09-06  2:00           ` dan.j.williams
2025-09-08  6:25             ` Alexey Kardashevskiy
2025-09-09  0:42               ` dan.j.williams
2025-09-15 11:46             ` Alexey Kardashevskiy
2025-10-17  4:06             ` Alexey Kardashevskiy [this message]
2025-10-17  4:40               ` dan.j.williams
2025-10-17 11:15                 ` Alexey Kardashevskiy
2025-09-05  1:27     ` dan.j.williams
2025-09-05  2:23       ` Alexey Kardashevskiy
2025-10-17 11:31       ` Alexey Kardashevskiy
2025-10-17 19:18         ` dan.j.williams
2025-10-28 23:00         ` dan.j.williams
2025-10-29  8:04           ` Alexey Kardashevskiy
2025-08-27  3:51 ` [PATCH v5 08/10] PCI/IDE: Report available IDE streams Dan Williams
2025-08-27  3:51 ` [PATCH v5 09/10] PCI/TSM: Report active " Dan Williams
2025-08-27  3:51 ` [PATCH v5 10/10] samples/devsec: Add sample IDE establishment Dan Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3d100559-8eb8-46cb-94b3-34ca9fb6dd96@amd.com \
    --to=aik@amd.com \
    --cc=aneesh.kumar@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=dan.j.williams@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=sameo@rivosinc.com \
    --cc=yilun.xu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox