All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
To: Robin Murphy <robin.murphy@arm.com>
Cc: devel@driverdev.osuosl.org, devicetree@vger.kernel.org,
	Joerg Roedel <jroedel@suse.de>,
	Manivannan Sadhasivam <mani@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Suzhuangluan <suzhuangluan@hisilicon.com>,
	linuxarm@huawei.com, Wei Xu <xuwei5@hisilicon.com>,
	linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
	Rob Herring <robh+dt@kernel.org>,
	John Stultz <john.stultz@linaro.org>,
	Chenfeng <puck.chen@hisilicon.com>,
	mauro.chehab@huawei.com, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 00/16] IOMMU driver for Kirin 960/970
Date: Tue, 18 Aug 2020 17:29:09 +0200	[thread overview]
Message-ID: <20200818172909.71f5243a@coco.lan> (raw)
In-Reply-To: <5c7918b6-c506-680b-cb0f-9e5f6a7038d9@arm.com>

Hi Robin,

Em Tue, 18 Aug 2020 15:47:55 +0100
Robin Murphy <robin.murphy@arm.com> escreveu:

> On 2020-08-17 08:49, Mauro Carvalho Chehab wrote:
> > Add a driver for the Kirin 960/970 iommu.
> > 
> > As on the past series, this starts from the original 4.9 driver from
> > the 96boards tree:
> > 
> > 	https://github.com/96boards-hikey/linux/tree/hikey970-v4.9
> > 
> > The remaining patches add SPDX headers and make it build and run with
> > the upstream Kernel.
> > 
> > Chenfeng (1):
> >    iommu: add support for HiSilicon Kirin 960/970 iommu
> > 
> > Mauro Carvalho Chehab (15):
> >    iommu: hisilicon: remove default iommu_map_sg handler
> >    iommu: hisilicon: map and unmap ops gained new arguments
> >    iommu: hisi_smmu_lpae: rebase it to work with upstream
> >    iommu: hisi_smmu: remove linux/hisi/hisi-iommu.h
> >    iommu: hisilicon: cleanup its code style
> >    iommu: hisi_smmu_lpae: get rid of IOMMU_SEC and IOMMU_DEVICE
> >    iommu: get rid of map/unmap tile functions
> >    iommu: hisi_smmu_lpae: use the right code to get domain-priv data
> >    iommu: hisi_smmu_lpae: convert it to probe_device
> >    iommu: add Hisilicon Kirin970 iommu at the building system
> >    iommu: hisi_smmu_lpae: cleanup printk macros
> >    iommu: hisi_smmu_lpae: make OF compatible more standard  
> 
> Echoing the other comments about none of the driver patches being CC'd 
> to the IOMMU list...
> 
> Still, I dug the series up on lore and frankly I'm not sure what to make 
> of it - AFAICS the "driver" is just yet another implementation of Arm 
> LPAE pagetable code, with no obvious indication of how those pagetables 
> ever get handed off to IOMMU hardware (and indeed no indication of IOMMU 
> hardware at all). Can you explain how it's supposed to work?
> 
> And as a pre-emptive strike, we really don't need any more LPAE 
> implementations - that's what the io-pgtable library is all about (which 
> incidentally has been around since 4.0...). I think that should make the 
> issue of preserving authorship largely moot since there's no need to 
> preserve most of the code anyway ;)

I didn't know about that, since I got a Hikey 970 board for the first time
about one month ago, and that's the first time I looked into iommu code.

My end goal with this is to make the DRM/KMS driver to work with upstream
Kernels.

The full patch series are at:

	https://github.com/mchehab/linux/commits/hikey970/to_upstream-2.0-v1.1

(I need to put a new version there, after some changes due to recent
upstream discussions at the regulator's part of the code)

Basically, the DT binding has this, for IOMMU:


	smmu_lpae {
		compatible = "hisilicon,smmu-lpae";
	};

...
	dpe: dpe@e8600000 {
		compatible = "hisilicon,kirin970-dpe";
		memory-region = <&drm_dma_reserved>;
...
		iommu_info {
			start-addr = <0x8000>;
			size = <0xbfff8000>;
		};
	}

This is used by kirin9xx_drm_dss.c in order to enable and use
the iommu:


	static int dss_enable_iommu(struct platform_device *pdev, struct dss_hw_ctx *ctx)
	{
		struct device *dev = NULL;

		dev = &pdev->dev;

		/* create iommu domain */
		ctx->mmu_domain = iommu_domain_alloc(dev->bus);
		if (!ctx->mmu_domain) {
			pr_err("iommu_domain_alloc failed!\n");
			return -EINVAL;
		}

		iommu_attach_device(ctx->mmu_domain, dev);

		return 0;
	}

The only place where the IOMMU domain is used is on this part of the
code(error part simplified here) [1]:

	void hisi_dss_smmu_on(struct dss_hw_ctx *ctx) 
	{
		uint64_t fama_phy_pgd_base;
		uint32_t phy_pgd_base;
...
		fama_phy_pgd_base = iommu_iova_to_phys(ctx->mmu_domain, 0);
		phy_pgd_base = (uint32_t)fama_phy_pgd_base;
		if (WARN_ON(!phy_pgd_base))
			return;

		set_reg(smmu_base + SMMU_CB_TTBR0, phy_pgd_base, 32, 0);
	}

[1] https://github.com/mchehab/linux/commit/36da105e719b47bbe9d6cb7e5619b30c7f3eb1bd

In other words, the driver needs to get the physical address of the frame
buffer (mapped via iommu) in order to set some DRM-specific register.

Yeah, the above code is somewhat hackish. I would love to replace 
this part by a more standard approach.

Thanks,
Mauro
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

WARNING: multiple messages have this Message-ID (diff)
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
To: Robin Murphy <robin.murphy@arm.com>
Cc: devel@driverdev.osuosl.org, devicetree@vger.kernel.org,
	Joerg Roedel <jroedel@suse.de>,
	Manivannan Sadhasivam <mani@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Suzhuangluan <suzhuangluan@hisilicon.com>,
	linuxarm@huawei.com, Wei Xu <xuwei5@hisilicon.com>,
	linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
	Rob Herring <robh+dt@kernel.org>,
	John Stultz <john.stultz@linaro.org>,
	Chenfeng <puck.chen@hisilicon.com>,
	mauro.chehab@huawei.com, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 00/16] IOMMU driver for Kirin 960/970
Date: Tue, 18 Aug 2020 17:29:09 +0200	[thread overview]
Message-ID: <20200818172909.71f5243a@coco.lan> (raw)
In-Reply-To: <5c7918b6-c506-680b-cb0f-9e5f6a7038d9@arm.com>

Hi Robin,

Em Tue, 18 Aug 2020 15:47:55 +0100
Robin Murphy <robin.murphy@arm.com> escreveu:

> On 2020-08-17 08:49, Mauro Carvalho Chehab wrote:
> > Add a driver for the Kirin 960/970 iommu.
> > 
> > As on the past series, this starts from the original 4.9 driver from
> > the 96boards tree:
> > 
> > 	https://github.com/96boards-hikey/linux/tree/hikey970-v4.9
> > 
> > The remaining patches add SPDX headers and make it build and run with
> > the upstream Kernel.
> > 
> > Chenfeng (1):
> >    iommu: add support for HiSilicon Kirin 960/970 iommu
> > 
> > Mauro Carvalho Chehab (15):
> >    iommu: hisilicon: remove default iommu_map_sg handler
> >    iommu: hisilicon: map and unmap ops gained new arguments
> >    iommu: hisi_smmu_lpae: rebase it to work with upstream
> >    iommu: hisi_smmu: remove linux/hisi/hisi-iommu.h
> >    iommu: hisilicon: cleanup its code style
> >    iommu: hisi_smmu_lpae: get rid of IOMMU_SEC and IOMMU_DEVICE
> >    iommu: get rid of map/unmap tile functions
> >    iommu: hisi_smmu_lpae: use the right code to get domain-priv data
> >    iommu: hisi_smmu_lpae: convert it to probe_device
> >    iommu: add Hisilicon Kirin970 iommu at the building system
> >    iommu: hisi_smmu_lpae: cleanup printk macros
> >    iommu: hisi_smmu_lpae: make OF compatible more standard  
> 
> Echoing the other comments about none of the driver patches being CC'd 
> to the IOMMU list...
> 
> Still, I dug the series up on lore and frankly I'm not sure what to make 
> of it - AFAICS the "driver" is just yet another implementation of Arm 
> LPAE pagetable code, with no obvious indication of how those pagetables 
> ever get handed off to IOMMU hardware (and indeed no indication of IOMMU 
> hardware at all). Can you explain how it's supposed to work?
> 
> And as a pre-emptive strike, we really don't need any more LPAE 
> implementations - that's what the io-pgtable library is all about (which 
> incidentally has been around since 4.0...). I think that should make the 
> issue of preserving authorship largely moot since there's no need to 
> preserve most of the code anyway ;)

I didn't know about that, since I got a Hikey 970 board for the first time
about one month ago, and that's the first time I looked into iommu code.

My end goal with this is to make the DRM/KMS driver to work with upstream
Kernels.

The full patch series are at:

	https://github.com/mchehab/linux/commits/hikey970/to_upstream-2.0-v1.1

(I need to put a new version there, after some changes due to recent
upstream discussions at the regulator's part of the code)

Basically, the DT binding has this, for IOMMU:


	smmu_lpae {
		compatible = "hisilicon,smmu-lpae";
	};

...
	dpe: dpe@e8600000 {
		compatible = "hisilicon,kirin970-dpe";
		memory-region = <&drm_dma_reserved>;
...
		iommu_info {
			start-addr = <0x8000>;
			size = <0xbfff8000>;
		};
	}

This is used by kirin9xx_drm_dss.c in order to enable and use
the iommu:


	static int dss_enable_iommu(struct platform_device *pdev, struct dss_hw_ctx *ctx)
	{
		struct device *dev = NULL;

		dev = &pdev->dev;

		/* create iommu domain */
		ctx->mmu_domain = iommu_domain_alloc(dev->bus);
		if (!ctx->mmu_domain) {
			pr_err("iommu_domain_alloc failed!\n");
			return -EINVAL;
		}

		iommu_attach_device(ctx->mmu_domain, dev);

		return 0;
	}

The only place where the IOMMU domain is used is on this part of the
code(error part simplified here) [1]:

	void hisi_dss_smmu_on(struct dss_hw_ctx *ctx) 
	{
		uint64_t fama_phy_pgd_base;
		uint32_t phy_pgd_base;
...
		fama_phy_pgd_base = iommu_iova_to_phys(ctx->mmu_domain, 0);
		phy_pgd_base = (uint32_t)fama_phy_pgd_base;
		if (WARN_ON(!phy_pgd_base))
			return;

		set_reg(smmu_base + SMMU_CB_TTBR0, phy_pgd_base, 32, 0);
	}

[1] https://github.com/mchehab/linux/commit/36da105e719b47bbe9d6cb7e5619b30c7f3eb1bd

In other words, the driver needs to get the physical address of the frame
buffer (mapped via iommu) in order to set some DRM-specific register.

Yeah, the above code is somewhat hackish. I would love to replace 
this part by a more standard approach.

Thanks,
Mauro

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
To: Robin Murphy <robin.murphy@arm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	devel@driverdev.osuosl.org, devicetree@vger.kernel.org,
	Joerg Roedel <jroedel@suse.de>,
	Manivannan Sadhasivam <mani@kernel.org>,
	Chenfeng <puck.chen@hisilicon.com>,
	linuxarm@huawei.com, Wei Xu <xuwei5@hisilicon.com>,
	linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
	Rob Herring <robh+dt@kernel.org>,
	John Stultz <john.stultz@linaro.org>,
	mauro.chehab@huawei.com,
	Suzhuangluan <suzhuangluan@hisilicon.com>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 00/16] IOMMU driver for Kirin 960/970
Date: Tue, 18 Aug 2020 17:29:09 +0200	[thread overview]
Message-ID: <20200818172909.71f5243a@coco.lan> (raw)
In-Reply-To: <5c7918b6-c506-680b-cb0f-9e5f6a7038d9@arm.com>

Hi Robin,

Em Tue, 18 Aug 2020 15:47:55 +0100
Robin Murphy <robin.murphy@arm.com> escreveu:

> On 2020-08-17 08:49, Mauro Carvalho Chehab wrote:
> > Add a driver for the Kirin 960/970 iommu.
> > 
> > As on the past series, this starts from the original 4.9 driver from
> > the 96boards tree:
> > 
> > 	https://github.com/96boards-hikey/linux/tree/hikey970-v4.9
> > 
> > The remaining patches add SPDX headers and make it build and run with
> > the upstream Kernel.
> > 
> > Chenfeng (1):
> >    iommu: add support for HiSilicon Kirin 960/970 iommu
> > 
> > Mauro Carvalho Chehab (15):
> >    iommu: hisilicon: remove default iommu_map_sg handler
> >    iommu: hisilicon: map and unmap ops gained new arguments
> >    iommu: hisi_smmu_lpae: rebase it to work with upstream
> >    iommu: hisi_smmu: remove linux/hisi/hisi-iommu.h
> >    iommu: hisilicon: cleanup its code style
> >    iommu: hisi_smmu_lpae: get rid of IOMMU_SEC and IOMMU_DEVICE
> >    iommu: get rid of map/unmap tile functions
> >    iommu: hisi_smmu_lpae: use the right code to get domain-priv data
> >    iommu: hisi_smmu_lpae: convert it to probe_device
> >    iommu: add Hisilicon Kirin970 iommu at the building system
> >    iommu: hisi_smmu_lpae: cleanup printk macros
> >    iommu: hisi_smmu_lpae: make OF compatible more standard  
> 
> Echoing the other comments about none of the driver patches being CC'd 
> to the IOMMU list...
> 
> Still, I dug the series up on lore and frankly I'm not sure what to make 
> of it - AFAICS the "driver" is just yet another implementation of Arm 
> LPAE pagetable code, with no obvious indication of how those pagetables 
> ever get handed off to IOMMU hardware (and indeed no indication of IOMMU 
> hardware at all). Can you explain how it's supposed to work?
> 
> And as a pre-emptive strike, we really don't need any more LPAE 
> implementations - that's what the io-pgtable library is all about (which 
> incidentally has been around since 4.0...). I think that should make the 
> issue of preserving authorship largely moot since there's no need to 
> preserve most of the code anyway ;)

I didn't know about that, since I got a Hikey 970 board for the first time
about one month ago, and that's the first time I looked into iommu code.

My end goal with this is to make the DRM/KMS driver to work with upstream
Kernels.

The full patch series are at:

	https://github.com/mchehab/linux/commits/hikey970/to_upstream-2.0-v1.1

(I need to put a new version there, after some changes due to recent
upstream discussions at the regulator's part of the code)

Basically, the DT binding has this, for IOMMU:


	smmu_lpae {
		compatible = "hisilicon,smmu-lpae";
	};

...
	dpe: dpe@e8600000 {
		compatible = "hisilicon,kirin970-dpe";
		memory-region = <&drm_dma_reserved>;
...
		iommu_info {
			start-addr = <0x8000>;
			size = <0xbfff8000>;
		};
	}

This is used by kirin9xx_drm_dss.c in order to enable and use
the iommu:


	static int dss_enable_iommu(struct platform_device *pdev, struct dss_hw_ctx *ctx)
	{
		struct device *dev = NULL;

		dev = &pdev->dev;

		/* create iommu domain */
		ctx->mmu_domain = iommu_domain_alloc(dev->bus);
		if (!ctx->mmu_domain) {
			pr_err("iommu_domain_alloc failed!\n");
			return -EINVAL;
		}

		iommu_attach_device(ctx->mmu_domain, dev);

		return 0;
	}

The only place where the IOMMU domain is used is on this part of the
code(error part simplified here) [1]:

	void hisi_dss_smmu_on(struct dss_hw_ctx *ctx) 
	{
		uint64_t fama_phy_pgd_base;
		uint32_t phy_pgd_base;
...
		fama_phy_pgd_base = iommu_iova_to_phys(ctx->mmu_domain, 0);
		phy_pgd_base = (uint32_t)fama_phy_pgd_base;
		if (WARN_ON(!phy_pgd_base))
			return;

		set_reg(smmu_base + SMMU_CB_TTBR0, phy_pgd_base, 32, 0);
	}

[1] https://github.com/mchehab/linux/commit/36da105e719b47bbe9d6cb7e5619b30c7f3eb1bd

In other words, the driver needs to get the physical address of the frame
buffer (mapped via iommu) in order to set some DRM-specific register.

Yeah, the above code is somewhat hackish. I would love to replace 
this part by a more standard approach.

Thanks,
Mauro

  reply	other threads:[~2020-08-18 15:29 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-17  7:49 [PATCH 00/16] IOMMU driver for Kirin 960/970 Mauro Carvalho Chehab
2020-08-17  7:49 ` Mauro Carvalho Chehab
2020-08-17  7:49 ` Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 01/16] iommu: add support for HiSilicon Kirin 960/970 iommu Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 02/16] iommu: hisilicon: remove default iommu_map_sg handler Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 03/16] iommu: hisilicon: map and unmap ops gained new arguments Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 04/16] iommu: hisi_smmu_lpae: rebase it to work with upstream Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 05/16] iommu: hisi_smmu: remove linux/hisi/hisi-iommu.h Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 06/16] iommu: hisilicon: cleanup its code style Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 07/16] iommu: hisi_smmu_lpae: get rid of IOMMU_SEC and IOMMU_DEVICE Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 08/16] iommu: get rid of map/unmap tile functions Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 09/16] iommu: hisi_smmu_lpae: use the right code to get domain-priv data Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 10/16] iommu: hisi_smmu_lpae: convert it to probe_device Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 11/16] iommu: add Hisilicon Kirin970 iommu at the building system Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 12/16] iommu: hisi_smmu_lpae: cleanup printk macros Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 13/16] iommu: hisi_smmu_lpae: make OF compatible more standard Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 14/16] dt: add an spec for the Kirin36x0 SMMU Mauro Carvalho Chehab
2020-08-17  7:50   ` Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 15/16] dt: hi3670-hikey970.dts: load the SMMU driver on Hikey970 Mauro Carvalho Chehab
2020-08-17  7:50   ` Mauro Carvalho Chehab
2020-08-17  7:50 ` [PATCH 16/16] staging: hikey9xx: add an item about the iommu driver Mauro Carvalho Chehab
2020-08-17  8:21 ` [PATCH 00/16] IOMMU driver for Kirin 960/970 Christoph Hellwig
2020-08-17  8:21   ` Christoph Hellwig
2020-08-17  8:21   ` Christoph Hellwig
2020-08-17  9:27   ` Mauro Carvalho Chehab
2020-08-17  9:27     ` Mauro Carvalho Chehab
2020-08-17  9:27     ` Mauro Carvalho Chehab
2020-08-17  9:31     ` Christoph Hellwig
2020-08-17  9:31       ` Christoph Hellwig
2020-08-17  9:31       ` Christoph Hellwig
2020-08-17  9:37     ` Greg Kroah-Hartman
2020-08-17  9:37       ` Greg Kroah-Hartman
2020-08-17  9:37       ` Greg Kroah-Hartman
2020-08-17 10:46       ` Mauro Carvalho Chehab
2020-08-17 10:46         ` Mauro Carvalho Chehab
2020-08-17 10:46         ` Mauro Carvalho Chehab
2020-08-17 10:53         ` Greg Kroah-Hartman
2020-08-17 10:53           ` Greg Kroah-Hartman
2020-08-17 10:53           ` Greg Kroah-Hartman
2020-08-17 12:59           ` Joerg Roedel
2020-08-17 12:59             ` Joerg Roedel
2020-08-17 12:59             ` Joerg Roedel
2020-08-18 14:47 ` Robin Murphy
2020-08-18 14:47   ` Robin Murphy
2020-08-18 14:47   ` Robin Murphy
2020-08-18 15:29   ` Mauro Carvalho Chehab [this message]
2020-08-18 15:29     ` Mauro Carvalho Chehab
2020-08-18 15:29     ` Mauro Carvalho Chehab
2020-08-18 16:26     ` Robin Murphy
2020-08-18 16:26       ` Robin Murphy
2020-08-18 16:26       ` Robin Murphy
2020-08-18 22:02       ` John Stultz
2020-08-18 22:02         ` John Stultz
2020-08-18 22:02         ` John Stultz
2020-08-19 10:12         ` Robin Murphy
2020-08-19 10:12           ` Robin Murphy
2020-08-19 10:12           ` Robin Murphy
2020-08-19 10:28         ` Mauro Carvalho Chehab
2020-08-19 10:28           ` Mauro Carvalho Chehab
2020-08-19 10:28           ` Mauro Carvalho Chehab
2020-08-19 11:33           ` Robin Murphy
2020-08-19 11:33             ` Robin Murphy
2020-08-19 11:33             ` Robin Murphy

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=20200818172909.71f5243a@coco.lan \
    --to=mchehab+huawei@kernel.org \
    --cc=devel@driverdev.osuosl.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=john.stultz@linaro.org \
    --cc=jroedel@suse.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=mani@kernel.org \
    --cc=mauro.chehab@huawei.com \
    --cc=puck.chen@hisilicon.com \
    --cc=robh+dt@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=suzhuangluan@hisilicon.com \
    --cc=xuwei5@hisilicon.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.