All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Dan Williams <dan.j.williams@intel.com>
Cc: <linux-coco@lists.linux.dev>, <linux-pci@vger.kernel.org>,
	<gregkh@linuxfoundation.org>, <lukas@wunner.de>,
	<aneesh.kumar@kernel.org>, <suzuki.poulose@arm.com>,
	<sameo@rivosinc.com>, <aik@amd.com>, <jgg@nvidia.com>,
	<zhiw@nvidia.com>, Bjorn Helgaas <bhelgaas@google.com>,
	Yilun Xu <yilun.xu@linux.intel.com>
Subject: Re: [PATCH v3 08/13] PCI/IDE: Add IDE establishment helpers
Date: Tue, 17 Jun 2025 15:04:34 +0100	[thread overview]
Message-ID: <20250617150434.00003a91@huawei.com> (raw)
In-Reply-To: <20250516054732.2055093-9-dan.j.williams@intel.com>

On Thu, 15 May 2025 22:47:27 -0700
Dan Williams <dan.j.williams@intel.com> wrote:

> There are two components to establishing an encrypted link, provisioning
> the stream in Partner Port config-space, and programming the keys into
> the link layer via IDE_KM (IDE Key Management). This new library,
> drivers/pci/ide.c, enables the former. IDE_KM, via a TSM low-level
> driver, is saved for later.
> 
> With the platform TSM implementations of SEV-TIO and TDX Connect in mind
> this library abstracts small differences in those implementations. For
> example, TDX Connect handles Root Port register setup while SEV-TIO
> expects System Software to update the Root Port registers. This is the
> rationale for fine-grained 'setup' + 'enable' verbs.
> 
> The other design detail for TSM-coordinated IDE establishment is that
> the TSM may manage allocation of Stream IDs, this is why the Stream ID
> value is passed in to pci_ide_stream_setup().
> 
> The flow is:
> 
> pci_ide_stream_alloc()
>   Allocate a Selective IDE Stream Register Block in each Partner Port
>   (Endpoint + Root Port), and reserve a host bridge / platform stream
>   slot. Gather Partner Port specific stream settings like Requester ID.
> pci_ide_stream_register()
>   Publish the stream in sysfs after allocating a Stream ID. In the TSM
>   case the TSM allocates the Stream ID for the Partner Port pair.
> pci_ide_stream_setup()
>   Program the stream settings to a Partner Port. Caller is responsible
>   for optionally calling this for the Root Port as well if the TSM
>   implementation requires it.
> pci_ide_stream_enable()
>   Try to run the stream after IDE_KM.
> 
> In support of system administrators auditing where platform, Root Port,
> and Endpoint IDE stream resources are being spent, the allocated stream
> is reflected as a symlink from the host bridge to the endpoint with the
> name:
> 
>     stream%d.%d.%d:%s
> 
> Where the tuple of integers reflects the allocated platform, Root Port,
> and Endpoint stream index (Selective IDE Stream Register Block) values,
> and the %s is the endpoint device name.
> 
> Thanks to Wu Hao for a draft implementation of this infrastructure.
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Lukas Wunner <lukas@wunner.de>
> Cc: Samuel Ortiz <sameo@rivosinc.com>
> Co-developed-by: Alexey Kardashevskiy <aik@amd.com>
> Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
> Co-developed-by: Yilun Xu <yilun.xu@linux.intel.com>
> Signed-off-by: Yilun Xu <yilun.xu@linux.intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
A few little comments inline.

Thanks,

Jonathan

> ---
>  .../ABI/testing/sysfs-devices-pci-host-bridge |  38 ++
>  MAINTAINERS                                   |   1 +
>  drivers/pci/ide.c                             | 366 ++++++++++++++++++
>  include/linux/pci-ide.h                       |  76 ++++
>  include/linux/pci.h                           |   6 +
>  include/uapi/linux/pci_regs.h                 |   2 +
>  6 files changed, 489 insertions(+)
>  create mode 100644 Documentation/ABI/testing/sysfs-devices-pci-host-bridge
>  create mode 100644 include/linux/pci-ide.h
> 
> diff --git a/Documentation/ABI/testing/sysfs-devices-pci-host-bridge b/Documentation/ABI/testing/sysfs-devices-pci-host-bridge
> new file mode 100644
> index 000000000000..d592b68c7333
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-devices-pci-host-bridge
> @@ -0,0 +1,38 @@
> +What:		/sys/devices/pciDDDD:BB
> +		/sys/devices/.../pciDDDD:BB
> +Date:		December, 2024
> +Contact:	linux-pci@vger.kernel.org
> +Description:
> +		A PCI host bridge device parents a PCI bus device topology. PCI
> +		controllers may also parent host bridges. The DDDD:BB format
> +		conveys the PCI domain (ACPI segment) number and root bus number
> +		(in hexadecimal) of the host bridge. Note that the domain number
> +		may be larger than the 16-bits that the "DDDD" format implies
> +		for emulated host-bridges.
> +
> +What:		pciDDDD:BB/firmware_node
> +Date:		December, 2024
> +Contact:	linux-pci@vger.kernel.org
> +Description:
> +		(RO) Symlink to the platform firmware device object "companion"
> +		of the host bridge. For example, an ACPI device with an _HID of
> +		PNP0A08 (/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00). See
> +		/sys/devices/pciDDDD:BB entry for details about the DDDD:BB
> +		format.

No problem with this documentation but not I think related to this patch and
could go upstream before this?

> +
> +What:		pciDDDD:BB/streamH.R.E:DDDD:BB:DD:F
> +Date:		December, 2024
> +Contact:	linux-pci@vger.kernel.org
> +Description:
> +		(RO) When a platform has established a secure connection, PCIe
> +		IDE, between two Partner Ports, this symlink appears. The
> +		primary function is to account the stream slot / resources
> +		consumed in each of the (H)ost bridge, (R)oot Port and
> +		(E)ndpoint that will be freed when invoking the tsm/disconnect
> +		flow. The link points to the endpoint PCI device at domain:DDDD
> +		bus:BB device:DD function:F. Where R and E represent the
> +		assigned Selective IDE Stream Register Block in the Root Port
> +		and Endpoint, and H represents a platform specific pool of
> +		stream resources shared by the Root Ports in a host bridge.  See
> +		/sys/devices/pciDDDD:BB entry for details about the DDDD:BB
> +		format.

> diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c
> index 98a51596e329..a529926647f4 100644
> --- a/drivers/pci/ide.c
> +++ b/drivers/pci/ide.c

> +/**
> + * pci_ide_stream_enable() - after setup, enable the stream
> + * @pdev: PCIe device object for either a Root Port or Endpoint Partner Port
> + * @ide: registered and setup IDE settings descriptor
> + *
> + * Activate the stream by writing to the Selective IDE Stream Control Register.
> + */
> +int pci_ide_stream_enable(struct pci_dev *pdev, struct pci_ide *ide)
> +{
> +	struct pci_ide_partner *settings = pci_ide_to_settings(pdev, ide);
> +	int pos;
> +	u32 val;
> +
> +	if (!settings)
> +		return -ENXIO;
> +
> +	pos = sel_ide_offset(pdev, settings);
> +
> +	set_ide_sel_ctl(pdev, ide, pos, true);
> +
> +	pci_read_config_dword(pdev, pos + PCI_IDE_SEL_STS, &val);
> +	if (FIELD_GET(PCI_IDE_SEL_STS_STATE_MASK, val) !=
> +	    PCI_IDE_SEL_STS_STATE_SECURE)
> +		return -ENXIO;

Trivial but blank line here would I think help readability a tiny bit.

> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(pci_ide_stream_enable);

> diff --git a/include/linux/pci-ide.h b/include/linux/pci-ide.h
> new file mode 100644
> index 000000000000..0753c3cd752a
> --- /dev/null
> +++ b/include/linux/pci-ide.h
> @@ -0,0 +1,76 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
> +
> +/* PCIe 6.2 section 6.33 Integrity & Data Encryption (IDE) */
> +
> +#ifndef __PCI_IDE_H__
> +#define __PCI_IDE_H__
> +
> +#include <linux/range.h>

Needed?  I'm guessing it was and isn't any more.

> +
> +#define SEL_ADDR1_LOWER_MASK GENMASK(31, 20)
> +#define SEL_ADDR_UPPER_MASK GENMASK_ULL(63, 32)
> +#define PREP_PCI_IDE_SEL_ADDR1(base, limit)                    \

ADDR_1 would be more consistent.

However, unless we are going to see a lot of these I'd personally prefer
to see this lot inline in the code.

> +	(FIELD_PREP(PCI_IDE_SEL_ADDR_1_VALID, 1) |             \
> +	 FIELD_PREP(PCI_IDE_SEL_ADDR_1_BASE_LOW_MASK,          \
> +		    FIELD_GET(SEL_ADDR1_LOWER_MASK, (base))) | \

This is a case I'd just not use FIELD_PREP / GET for. Just ends up
confusing and needs definitions that make little sense on their own.
	lower_32_bits(base) & PCI_IDE_SEL_ADDR_1_BASE_LOW_MASK
perhaps.

> +	 FIELD_PREP(PCI_IDE_SEL_ADDR_1_LIMIT_LOW_MASK,         \
> +		    FIELD_GET(SEL_ADDR1_LOWER_MASK, (limit))))

Maybe use upper_32_bits() for this one.

However it is an odd macro and I can't immediately find where it is used
so maybe just drop it?

> +
> +#define PREP_PCI_IDE_SEL_RID_2(base, domain)               \
> +	(FIELD_PREP(PCI_IDE_SEL_RID_2_VALID, 1) |          \
> +	 FIELD_PREP(PCI_IDE_SEL_RID_2_BASE_MASK, (base)) | \
> +	 FIELD_PREP(PCI_IDE_SEL_RID_2_SEG_MASK, (domain)))
This one I'd prefer to see inline.

> +/**
> + * struct pci_ide_partner - Per port IDE Stream settings
> + * @rid_start: Partner Port Requester ID range start
> + * @rid_start: Partner Port Requester ID range end
> + * @stream_index: Selective IDE Stream Register Block selection
> + */
> +struct pci_ide_partner {
> +	u16 rid_start;
> +	u16 rid_end;
> +	u8 stream_index;
> +};
> +
> +/**
> + * struct pci_ide - PCIe Selective IDE Stream descriptor
> + * @pdev: PCIe Endpoint for the stream
> + * @partner: settings for both partner ports in a stream
> + * @host_bridge_stream: track platform Stream index

Why the capital S?  Seems a little inconsistent across different comments.


> + * @stream_id: unique id (within Partner Port pairing) for the stream
> + * @name: name of the stream in sysfs
> + *
> + * Negative @stream_id values indicate "uninitialized" on the
> + * expectation that with TSM established IDE the TSM owns the stream_id
> + * allocation.
> + */
> +struct pci_ide {
> +	struct pci_dev *pdev;
> +	struct pci_ide_partner partner[PCI_IDE_PARTNER_MAX];
> +	u8 host_bridge_stream;
> +	int stream_id;
> +	const char *name;
> +};


  reply	other threads:[~2025-06-17 14:04 UTC|newest]

Thread overview: 173+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-16  5:47 [PATCH v3 00/13] PCI/TSM: Core infrastructure for PCI device security (TDISP) Dan Williams
2025-05-16  5:47 ` [PATCH v3 01/13] coco/tsm: Introduce a core device for TEE Security Managers Dan Williams
2025-06-02 13:18   ` Jason Gunthorpe
2025-06-04  0:42     ` Dan Williams
2025-06-04  1:15       ` Dan Williams
2025-06-04 12:15         ` Jason Gunthorpe
2025-06-04 12:14       ` Jason Gunthorpe
2025-06-06  3:33         ` Alexey Kardashevskiy
2025-06-06  2:09     ` Alexey Kardashevskiy
2025-05-16  5:47 ` [PATCH v3 02/13] PCI/IDE: Enumerate Selective Stream IDE capabilities Dan Williams
2025-06-17 12:16   ` Jonathan Cameron
2025-07-12 22:31     ` dan.j.williams
2025-05-16  5:47 ` [PATCH v3 03/13] PCI/TSM: Authenticate devices via platform TSM Dan Williams
2025-05-21 15:32   ` Aneesh Kumar K.V
2025-06-03 19:53     ` Dan Williams
2025-06-04  8:04       ` Aneesh Kumar K.V
2025-06-17 12:51   ` Jonathan Cameron
2025-07-12 22:07     ` dan.j.williams
2025-08-26  1:31   ` Alexey Kardashevskiy
2025-08-26 23:54     ` dan.j.williams
2025-08-27  4:44       ` Alexey Kardashevskiy
2025-08-28 19:27         ` dan.j.williams
2025-08-26  3:08   ` Alexey Kardashevskiy
2025-08-26 23:58     ` dan.j.williams
2025-08-27  5:06       ` Alexey Kardashevskiy
2025-08-26 10:22   ` Alexey Kardashevskiy
2025-08-27  0:15     ` dan.j.williams
2025-08-27  5:02       ` Alexey Kardashevskiy
2025-08-28 19:32         ` dan.j.williams
2025-05-16  5:47 ` [PATCH v3 04/13] PCI: Enable host-bridge emulation for PCI_DOMAINS_GENERIC platforms Dan Williams
2025-05-16  5:47 ` [PATCH v3 05/13] PCI: vmd: Switch to pci_bus_find_emul_domain_nr() Dan Williams
2025-05-16  5:47 ` [PATCH v3 06/13] samples/devsec: Introduce a PCI device-security bus + endpoint sample Dan Williams
2025-06-17 13:30   ` Jonathan Cameron
2025-07-13  1:58     ` dan.j.williams
2025-05-16  5:47 ` [PATCH v3 07/13] PCI: Add PCIe Device 3 Extended Capability enumeration Dan Williams
2025-06-17 13:36   ` Jonathan Cameron
2025-05-16  5:47 ` [PATCH v3 08/13] PCI/IDE: Add IDE establishment helpers Dan Williams
2025-06-17 14:04   ` Jonathan Cameron [this message]
2025-07-14 18:25     ` dan.j.williams
2025-07-03  2:59   ` Alexey Kardashevskiy
2025-05-16  5:47 ` [PATCH v3 09/13] PCI/IDE: Report available IDE streams Dan Williams
2025-05-18 12:48   ` kernel test robot
2025-06-17 14:16   ` Jonathan Cameron
2025-07-14 20:16     ` dan.j.williams
2025-05-16  5:47 ` [PATCH v3 10/13] PCI/TSM: Report active " Dan Williams
2025-06-17 14:21   ` Jonathan Cameron
2025-07-14 20:49     ` dan.j.williams
2025-05-16  5:47 ` [PATCH v3 11/13] samples/devsec: Add sample IDE establishment Dan Williams
2025-06-17 14:26   ` Jonathan Cameron
2025-07-14 20:59     ` dan.j.williams
2025-05-16  5:47 ` [PATCH v3 12/13] PCI/TSM: support TDI related operations for host TSM driver Dan Williams
2025-05-16  6:52   ` Xu Yilun
2025-05-20  7:17     ` Aneesh Kumar K.V
2025-05-21  9:35       ` Xu Yilun
2025-05-26  5:05         ` Aneesh Kumar K.V
2025-05-26  7:52           ` Alexey Kardashevskiy
2025-05-26 15:44             ` Aneesh Kumar K.V
2025-05-27  1:01               ` Alexey Kardashevskiy
2025-05-27 11:48                 ` Aneesh Kumar K.V
2025-05-27 13:06                   ` Jason Gunthorpe
2025-05-27 14:26                     ` Aneesh Kumar K.V
2025-05-27 14:45                       ` Jason Gunthorpe
2025-05-28 12:17                         ` Aneesh Kumar K.V
2025-05-28 16:42                           ` Jason Gunthorpe
2025-05-28 16:52                             ` Jason Gunthorpe
2025-05-29  9:30                               ` Xu Yilun
2025-05-29 13:43                               ` Aneesh Kumar K.V
2025-05-29 14:09                                 ` Jason Gunthorpe
2025-05-30  3:00                                   ` Alexey Kardashevskiy
2025-05-30 13:21                                     ` Jason Gunthorpe
2025-05-29 13:49                             ` Xu Yilun
2025-05-29 14:05                               ` Jason Gunthorpe
2025-05-29  3:03                   ` Alexey Kardashevskiy
2025-05-29 13:34                     ` Aneesh Kumar K.V
2025-05-29 13:37                       ` [RFC PATCH 1/3] coco: tsm: Add tsm_bind/unbind helpers Aneesh Kumar K.V (Arm)
2025-05-29 13:37                         ` [RFC PATCH 2/3] iommufd/viommu: Add support to associate viommu with kvm instance Aneesh Kumar K.V (Arm)
2025-05-29 14:13                           ` Jason Gunthorpe
2025-05-29 13:37                         ` [RFC PATCH 3/3] iommufd/tsm: Add tsm_bind/unbind iommufd ioctls Aneesh Kumar K.V (Arm)
2025-05-29 14:32                           ` Jason Gunthorpe
2025-05-30  8:33                             ` Aneesh Kumar K.V
2025-05-30 18:18                               ` Jason Gunthorpe
2025-05-31 16:25                           ` Xu Yilun
2025-06-02  4:52                             ` Alexey Kardashevskiy
2025-06-02 17:17                               ` Xu Yilun
2025-06-04  1:47                                 ` Alexey Kardashevskiy
2025-06-04  5:02                                   ` Xu Yilun
2025-06-04 12:37                                   ` Jason Gunthorpe
2025-06-06 15:40                                     ` Xu Yilun
2025-06-06 16:34                                       ` Jason Gunthorpe
2025-06-09  4:47                                         ` Xu Yilun
2025-06-02 11:08                             ` Aneesh Kumar K.V
2025-06-02 16:25                               ` Xu Yilun
2025-06-02 16:48                                 ` Jason Gunthorpe
2025-06-03  4:05                                   ` Xu Yilun
2025-06-03 12:11                                     ` Jason Gunthorpe
2025-06-04  5:58                                       ` Xu Yilun
2025-06-04 12:36                                         ` Jason Gunthorpe
2025-06-05  3:05                                           ` Xu Yilun
2025-06-10  7:05                                           ` Alexey Kardashevskiy
2025-06-10 18:19                                             ` Jason Gunthorpe
2025-06-11  1:26                                               ` Alexey Kardashevskiy
2025-06-10  4:47                                     ` Alexey Kardashevskiy
2025-06-10 18:21                                       ` Jason Gunthorpe
2025-06-12  4:15                                       ` Xu Yilun
2025-06-03  5:00                                 ` Aneesh Kumar K.V
2025-06-03 10:50                                   ` Xu Yilun
2025-06-03 12:14                                     ` Jason Gunthorpe
2025-06-04  5:31                                       ` Xu Yilun
2025-06-04 12:31                                         ` Jason Gunthorpe
2025-06-05  3:25                                           ` Xu Yilun
2025-06-05 14:54                                             ` Jason Gunthorpe
2025-06-09  6:10                                               ` Xu Yilun
2025-06-09 16:42                                                 ` Suzuki K Poulose
2025-06-09 18:07                                                   ` Jason Gunthorpe
2025-06-10  7:31                                         ` Alexey Kardashevskiy
2025-06-12  5:44                                           ` Xu Yilun
2025-06-03 12:18                                   ` Jason Gunthorpe
2025-06-04  1:06                                     ` Dan Williams
2025-06-04 12:18                                       ` Jason Gunthorpe
2025-06-02 12:47                             ` Jason Gunthorpe
2025-06-03  3:47                               ` Xu Yilun
2025-06-03 12:08                                 ` Jason Gunthorpe
2025-06-04  6:39                                   ` Xu Yilun
2025-06-04 12:39                                     ` Jason Gunthorpe
2025-06-05  1:56                                       ` Xu Yilun
2025-07-15 10:29                           ` Xu Yilun
2025-07-15 13:09                             ` Jason Gunthorpe
2025-07-16 15:41                               ` Xu Yilun
2025-07-16 16:31                                 ` Jason Gunthorpe
2025-07-17  8:28                                   ` Xu Yilun
2025-07-17 12:43                                     ` Jason Gunthorpe
2025-07-18  9:15                                       ` Xu Yilun
2025-07-18 12:26                                         ` Jason Gunthorpe
2025-07-20  2:37                                           ` Xu Yilun
2025-05-30  2:44                       ` [PATCH v3 12/13] PCI/TSM: support TDI related operations for host TSM driver Alexey Kardashevskiy
2025-05-27 10:25               ` Suzuki K Poulose
2025-06-03 22:47                 ` Dan Williams
2025-06-04  1:35                   ` Alexey Kardashevskiy
2025-06-04  1:52                     ` Dan Williams
2025-06-04  1:54                       ` Dan Williams
2025-06-05 10:56                         ` Alexey Kardashevskiy
2025-06-07  1:56                           ` Dan Williams
2025-06-11  4:40                             ` Alexey Kardashevskiy
2025-06-13  3:06                               ` Dan Williams
2025-06-03 22:40             ` Dan Williams
2025-05-19 10:20   ` Alexey Kardashevskiy
2025-05-20 20:12     ` Dan Williams
2025-05-21  9:28       ` Xu Yilun
2025-05-26  8:08         ` Alexey Kardashevskiy
2025-05-29 14:20           ` Xu Yilun
2025-05-30  2:54             ` Alexey Kardashevskiy
2025-05-31 15:26               ` Xu Yilun
2025-06-02  4:51                 ` Alexey Kardashevskiy
2025-06-02 18:51                   ` Xu Yilun
2025-06-03 19:12         ` Dan Williams
2025-07-07  7:17     ` Aneesh Kumar K.V
2025-05-20  5:20   ` Aneesh Kumar K.V
2025-05-20 21:12     ` Dan Williams
2025-05-16  5:47 ` [PATCH v3 13/13] PCI/TSM: Add Guest TSM Support Dan Williams
2025-05-19 10:20   ` Alexey Kardashevskiy
2025-05-20 21:11     ` Dan Williams
2025-05-22  4:07       ` Alexey Kardashevskiy
2025-06-03 22:26         ` Dan Williams
2025-06-03 22:33           ` Jason Gunthorpe
2025-06-10  8:31           ` Alexey Kardashevskiy
2025-07-11 23:04             ` dan.j.williams
2025-05-20  9:25   ` Aneesh Kumar K.V
2025-05-20 21:27     ` Dan Williams
2025-05-20 11:00   ` Aneesh Kumar K.V
2025-05-20 21:31     ` Dan Williams
2025-06-03 19:07       ` Dan Williams
2025-05-21 15:03   ` Xu Yilun
2025-06-03 19:20     ` 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=20250617150434.00003a91@huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=aik@amd.com \
    --cc=aneesh.kumar@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=dan.j.williams@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jgg@nvidia.com \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=sameo@rivosinc.com \
    --cc=suzuki.poulose@arm.com \
    --cc=yilun.xu@linux.intel.com \
    --cc=zhiw@nvidia.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.