All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrii Anisov <andrii.anisov@gmail.com>
To: Julien Grall <julien.grall@arm.com>, xen-devel@lists.xenproject.org
Cc: Oleksandr_Tyshchenko@epam.com, sstabellini@kernel.org,
	Andrii_Anisov@epam.com
Subject: Re: [PATCH 6/7] xen/arm: tlbflush: Rework TLB helpers
Date: Thu, 25 Apr 2019 21:01:26 +0300	[thread overview]
Message-ID: <4de7931e-27e0-be57-51e0-f2807aeff7bd@gmail.com> (raw)
In-Reply-To: <20190417175815.16905-7-julien.grall@arm.com>



On 17.04.19 20:58, Julien Grall wrote:
> All the TLBs helpers invalidate all the TLB entries are using the same
> pattern:
>      DSB SY
>      TLBI ...
>      DSB SY
>      ISB
> 
> This pattern is following pattern recommended by the Arm Arm to ensure
> visibility of updates to translation tables (see K10-5610 in ARM DDI
> 0487.A.k).

I can't find 0487.A.k, only aj [1], next one is b.
I guess you are referring `Ensuring the visibility of updates to translation tables for a multiprocessor`?

[1] https://developer.arm.com/docs/ddi0487/aj

> 
> We have been a bit too eager in Xen and use system-wide DSBs when this
> can be limited to the inner-shareable domain.
> 
> Furthermore, the first DSB can be restrict further to only store in the
> inner-shareable domain. This is because the DSB is here to ensure
> visibility of the update to translation table walks.
> 
> Lastly, there are a lack of documentation in most of the TLBs helper.
> 
> Rather than trying to update the helpers one by one, this patch
> introduce a per-arch macro to generate the TLB helpers. This will be
> easier to update the TLBs helper in the future and the documentation.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> ---
>   xen/include/asm-arm/arm32/flushtlb.h | 73 ++++++++++++++--------------------
>   xen/include/asm-arm/arm64/flushtlb.h | 76 +++++++++++++++---------------------
>   2 files changed, 60 insertions(+), 89 deletions(-)
> 
> diff --git a/xen/include/asm-arm/arm32/flushtlb.h b/xen/include/asm-arm/arm32/flushtlb.h
> index b629db61cb..9085e65011 100644
> --- a/xen/include/asm-arm/arm32/flushtlb.h
> +++ b/xen/include/asm-arm/arm32/flushtlb.h
> @@ -1,59 +1,44 @@
>   #ifndef __ASM_ARM_ARM32_FLUSHTLB_H__
>   #define __ASM_ARM_ARM32_FLUSHTLB_H__
>   
> -/* Flush local TLBs, current VMID only */
> -static inline void flush_guest_tlb_local(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALL);
> -
> -    dsb(sy);
> -    isb();
> +/*
> + * Every invalidation operation use the following patterns:
> + *
> + * DSB ISHST        // Ensure prior page-tables updates have completed
> + * TLBI...          // Invalidate the TLB
> + * DSB ISH          // Ensure the TLB invalidation has completed
> + * ISB              // See explanation below
> + *
> + * For Xen page-tables the ISB will discard any instructions fetched
> + * from the old mappings.
> + *
> + * For the Stage-2 page-tables the ISB ensures the completion of the DSB
> + * (and therefore the TLB invalidation) before continuing. So we know
> + * the TLBs cannot contain an entry for a mapping we may have removed.
> + */
> +#define TLB_HELPER(name, tlbop) \
> +static inline void name(void)   \
> +{                               \
> +    dsb(ishst);                 \
> +    WRITE_CP32(0, tlbop);       \
> +    dsb(ish);                   \
> +    isb();                      \
>   }
>   
> -/* Flush inner shareable TLBs, current VMID only */
> -static inline void flush_guest_tlb(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALLIS);
> +/* Flush local TLBs, current VMID only */
> +TLB_HELPER(flush_guest_tlb_local, TLBIALL);
>   
> -    dsb(sy);
> -    isb();
> -}
> +/* Flush inner shareable TLBs, current VMID only */
> +TLB_HELPER(flush_guest_tlb, TLBIALLIS);
>   
>   /* Flush local TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb_local(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALLNSNH);
> -
> -    dsb(sy);
> -    isb();
> -}
> +TLB_HELPER(flush_all_guests_tlb_local, TLBIALLNSNH);
>   
>   /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALLNSNHIS);
> -
> -    dsb(sy);
> -    isb();
> -}
> +TLB_HELPER(flush_all_guests_tlb, TLBIALLNSNHIS);
>   
>   /* Flush all hypervisor mappings from the TLB of the local processor. */
> -static inline void flush_xen_tlb_local(void)
> -{
> -    asm volatile("dsb;" /* Ensure preceding are visible */
> -                 CMD_CP32(TLBIALLH)
> -                 "dsb;" /* Ensure completion of the TLB flush */
> -                 "isb;"
> -                 : : : "memory");
> -}
> +TLB_HELPER(flush_xen_tlb_local, TLBIALLH);
>   
>   /* Flush TLB of local processor for address va. */
>   static inline void __flush_xen_tlb_one_local(vaddr_t va)
> diff --git a/xen/include/asm-arm/arm64/flushtlb.h b/xen/include/asm-arm/arm64/flushtlb.h
> index 2fed34b2ec..ceec59542e 100644
> --- a/xen/include/asm-arm/arm64/flushtlb.h
> +++ b/xen/include/asm-arm/arm64/flushtlb.h
> @@ -1,60 +1,46 @@
>   #ifndef __ASM_ARM_ARM64_FLUSHTLB_H__
>   #define __ASM_ARM_ARM64_FLUSHTLB_H__
>   
> -/* Flush local TLBs, current VMID only */
> -static inline void flush_guest_tlb_local(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi vmalls12e1;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> +/*
> + * Every invalidation operation use the following patterns:
> + *
> + * DSB ISHST        // Ensure prior page-tables updates have completed
> + * TLBI...          // Invalidate the TLB
> + * DSB ISH          // Ensure the TLB invalidation has completed
> + * ISB              // See explanation below
> + *
> + * For Xen page-tables the ISB will discard any instructions fetched
> + * from the old mappings.
> + *
> + * For the Stage-2 page-tables the ISB ensures the completion of the DSB
> + * (and therefore the TLB invalidation) before continuing. So we know
> + * the TLBs cannot contain an entry for a mapping we may have removed.
> + */
> +#define TLB_HELPER(name, tlbop) \
> +static inline void name(void)   \
> +{                               \
> +    asm volatile(               \
> +        "dsb  ishst;"           \
> +        "tlbi "  # tlbop  ";"   \
> +        "dsb  ish;"             \
> +        "isb;"                  \
> +        : : : "memory");        \
>   }
>   
> +/* Flush local TLBs, current VMID only. */
> +TLB_HELPER(flush_guest_tlb_local, vmalls12e1);
> +
>   /* Flush innershareable TLBs, current VMID only */
> -static inline void flush_guest_tlb(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi vmalls12e1is;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_guest_tlb, vmalls12e1is);
>   
>   /* Flush local TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb_local(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi alle1;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_all_guests_tlb_local, alle1);
>   
>   /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi alle1is;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_all_guests_tlb, alle1is);
>   
>   /* Flush all hypervisor mappings from the TLB of the local processor. */
> -static inline void flush_xen_tlb_local(void)
> -{
> -    asm volatile (
> -        "dsb    sy;"                    /* Ensure visibility of PTE writes */
> -        "tlbi   alle2;"                 /* Flush hypervisor TLB */
> -        "dsb    sy;"                    /* Ensure completion of TLB flush */
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_xen_tlb_local, alle2);
>   
>   /* Flush TLB of local processor for address va. */
>   static inline void  __flush_xen_tlb_one_local(vaddr_t va)
> 

With minor notes,

Reviewed-by: Andrii Anisov <andrii_anisov@epam.com>

-- 
Sincerely,
Andrii Anisov.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

WARNING: multiple messages have this Message-ID (diff)
From: Andrii Anisov <andrii.anisov@gmail.com>
To: Julien Grall <julien.grall@arm.com>, xen-devel@lists.xenproject.org
Cc: Oleksandr_Tyshchenko@epam.com, sstabellini@kernel.org,
	Andrii_Anisov@epam.com
Subject: Re: [Xen-devel] [PATCH 6/7] xen/arm: tlbflush: Rework TLB helpers
Date: Thu, 25 Apr 2019 21:01:26 +0300	[thread overview]
Message-ID: <4de7931e-27e0-be57-51e0-f2807aeff7bd@gmail.com> (raw)
Message-ID: <20190425180126.AkhkweP-0Luz3Di4rFReZX1iMfPXqQTzhUNDfnxYw68@z> (raw)
In-Reply-To: <20190417175815.16905-7-julien.grall@arm.com>



On 17.04.19 20:58, Julien Grall wrote:
> All the TLBs helpers invalidate all the TLB entries are using the same
> pattern:
>      DSB SY
>      TLBI ...
>      DSB SY
>      ISB
> 
> This pattern is following pattern recommended by the Arm Arm to ensure
> visibility of updates to translation tables (see K10-5610 in ARM DDI
> 0487.A.k).

I can't find 0487.A.k, only aj [1], next one is b.
I guess you are referring `Ensuring the visibility of updates to translation tables for a multiprocessor`?

[1] https://developer.arm.com/docs/ddi0487/aj

> 
> We have been a bit too eager in Xen and use system-wide DSBs when this
> can be limited to the inner-shareable domain.
> 
> Furthermore, the first DSB can be restrict further to only store in the
> inner-shareable domain. This is because the DSB is here to ensure
> visibility of the update to translation table walks.
> 
> Lastly, there are a lack of documentation in most of the TLBs helper.
> 
> Rather than trying to update the helpers one by one, this patch
> introduce a per-arch macro to generate the TLB helpers. This will be
> easier to update the TLBs helper in the future and the documentation.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> ---
>   xen/include/asm-arm/arm32/flushtlb.h | 73 ++++++++++++++--------------------
>   xen/include/asm-arm/arm64/flushtlb.h | 76 +++++++++++++++---------------------
>   2 files changed, 60 insertions(+), 89 deletions(-)
> 
> diff --git a/xen/include/asm-arm/arm32/flushtlb.h b/xen/include/asm-arm/arm32/flushtlb.h
> index b629db61cb..9085e65011 100644
> --- a/xen/include/asm-arm/arm32/flushtlb.h
> +++ b/xen/include/asm-arm/arm32/flushtlb.h
> @@ -1,59 +1,44 @@
>   #ifndef __ASM_ARM_ARM32_FLUSHTLB_H__
>   #define __ASM_ARM_ARM32_FLUSHTLB_H__
>   
> -/* Flush local TLBs, current VMID only */
> -static inline void flush_guest_tlb_local(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALL);
> -
> -    dsb(sy);
> -    isb();
> +/*
> + * Every invalidation operation use the following patterns:
> + *
> + * DSB ISHST        // Ensure prior page-tables updates have completed
> + * TLBI...          // Invalidate the TLB
> + * DSB ISH          // Ensure the TLB invalidation has completed
> + * ISB              // See explanation below
> + *
> + * For Xen page-tables the ISB will discard any instructions fetched
> + * from the old mappings.
> + *
> + * For the Stage-2 page-tables the ISB ensures the completion of the DSB
> + * (and therefore the TLB invalidation) before continuing. So we know
> + * the TLBs cannot contain an entry for a mapping we may have removed.
> + */
> +#define TLB_HELPER(name, tlbop) \
> +static inline void name(void)   \
> +{                               \
> +    dsb(ishst);                 \
> +    WRITE_CP32(0, tlbop);       \
> +    dsb(ish);                   \
> +    isb();                      \
>   }
>   
> -/* Flush inner shareable TLBs, current VMID only */
> -static inline void flush_guest_tlb(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALLIS);
> +/* Flush local TLBs, current VMID only */
> +TLB_HELPER(flush_guest_tlb_local, TLBIALL);
>   
> -    dsb(sy);
> -    isb();
> -}
> +/* Flush inner shareable TLBs, current VMID only */
> +TLB_HELPER(flush_guest_tlb, TLBIALLIS);
>   
>   /* Flush local TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb_local(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALLNSNH);
> -
> -    dsb(sy);
> -    isb();
> -}
> +TLB_HELPER(flush_all_guests_tlb_local, TLBIALLNSNH);
>   
>   /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb(void)
> -{
> -    dsb(sy);
> -
> -    WRITE_CP32((uint32_t) 0, TLBIALLNSNHIS);
> -
> -    dsb(sy);
> -    isb();
> -}
> +TLB_HELPER(flush_all_guests_tlb, TLBIALLNSNHIS);
>   
>   /* Flush all hypervisor mappings from the TLB of the local processor. */
> -static inline void flush_xen_tlb_local(void)
> -{
> -    asm volatile("dsb;" /* Ensure preceding are visible */
> -                 CMD_CP32(TLBIALLH)
> -                 "dsb;" /* Ensure completion of the TLB flush */
> -                 "isb;"
> -                 : : : "memory");
> -}
> +TLB_HELPER(flush_xen_tlb_local, TLBIALLH);
>   
>   /* Flush TLB of local processor for address va. */
>   static inline void __flush_xen_tlb_one_local(vaddr_t va)
> diff --git a/xen/include/asm-arm/arm64/flushtlb.h b/xen/include/asm-arm/arm64/flushtlb.h
> index 2fed34b2ec..ceec59542e 100644
> --- a/xen/include/asm-arm/arm64/flushtlb.h
> +++ b/xen/include/asm-arm/arm64/flushtlb.h
> @@ -1,60 +1,46 @@
>   #ifndef __ASM_ARM_ARM64_FLUSHTLB_H__
>   #define __ASM_ARM_ARM64_FLUSHTLB_H__
>   
> -/* Flush local TLBs, current VMID only */
> -static inline void flush_guest_tlb_local(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi vmalls12e1;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> +/*
> + * Every invalidation operation use the following patterns:
> + *
> + * DSB ISHST        // Ensure prior page-tables updates have completed
> + * TLBI...          // Invalidate the TLB
> + * DSB ISH          // Ensure the TLB invalidation has completed
> + * ISB              // See explanation below
> + *
> + * For Xen page-tables the ISB will discard any instructions fetched
> + * from the old mappings.
> + *
> + * For the Stage-2 page-tables the ISB ensures the completion of the DSB
> + * (and therefore the TLB invalidation) before continuing. So we know
> + * the TLBs cannot contain an entry for a mapping we may have removed.
> + */
> +#define TLB_HELPER(name, tlbop) \
> +static inline void name(void)   \
> +{                               \
> +    asm volatile(               \
> +        "dsb  ishst;"           \
> +        "tlbi "  # tlbop  ";"   \
> +        "dsb  ish;"             \
> +        "isb;"                  \
> +        : : : "memory");        \
>   }
>   
> +/* Flush local TLBs, current VMID only. */
> +TLB_HELPER(flush_guest_tlb_local, vmalls12e1);
> +
>   /* Flush innershareable TLBs, current VMID only */
> -static inline void flush_guest_tlb(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi vmalls12e1is;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_guest_tlb, vmalls12e1is);
>   
>   /* Flush local TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb_local(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi alle1;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_all_guests_tlb_local, alle1);
>   
>   /* Flush innershareable TLBs, all VMIDs, non-hypervisor mode */
> -static inline void flush_all_guests_tlb(void)
> -{
> -    asm volatile(
> -        "dsb sy;"
> -        "tlbi alle1is;"
> -        "dsb sy;"
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_all_guests_tlb, alle1is);
>   
>   /* Flush all hypervisor mappings from the TLB of the local processor. */
> -static inline void flush_xen_tlb_local(void)
> -{
> -    asm volatile (
> -        "dsb    sy;"                    /* Ensure visibility of PTE writes */
> -        "tlbi   alle2;"                 /* Flush hypervisor TLB */
> -        "dsb    sy;"                    /* Ensure completion of TLB flush */
> -        "isb;"
> -        : : : "memory");
> -}
> +TLB_HELPER(flush_xen_tlb_local, alle2);
>   
>   /* Flush TLB of local processor for address va. */
>   static inline void  __flush_xen_tlb_one_local(vaddr_t va)
> 

With minor notes,

Reviewed-by: Andrii Anisov <andrii_anisov@epam.com>

-- 
Sincerely,
Andrii Anisov.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2019-04-25 18:01 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-17 17:58 [PATCH 0/7] xen/arm: TLB flush helpers rework Julien Grall
2019-04-17 17:58 ` [Xen-devel] " Julien Grall
2019-04-17 17:58 ` [PATCH 1/7] xen/arm: mm: Consolidate setting SCTLR_EL2.WXN in a single place Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:00   ` Andrii Anisov
2019-04-25 18:00     ` [Xen-devel] " Andrii Anisov
2019-04-25 20:26     ` Julien Grall
2019-04-25 20:26       ` [Xen-devel] " Julien Grall
2019-04-26 13:48       ` Andrii Anisov
2019-04-26 13:48         ` [Xen-devel] " Andrii Anisov
2019-04-17 17:58 ` [PATCH 2/7] xen/arm: Remove flush_xen_text_tlb_local() Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:00   ` Andrii Anisov
2019-04-25 18:00     ` [Xen-devel] " Andrii Anisov
2019-04-25 20:37     ` Julien Grall
2019-04-25 20:37       ` [Xen-devel] " Julien Grall
2019-04-26 13:50       ` Andrii Anisov
2019-04-26 13:50         ` [Xen-devel] " Andrii Anisov
2019-04-26 14:15         ` Andrii Anisov
2019-04-26 14:15           ` [Xen-devel] " Andrii Anisov
2019-04-26 14:31           ` Julien Grall
2019-04-26 14:31             ` [Xen-devel] " Julien Grall
2019-04-26 15:08             ` Andrii Anisov
2019-04-26 15:08               ` [Xen-devel] " Andrii Anisov
2019-04-17 17:58 ` [PATCH 3/7] xen/arm: tlbflush: Clarify the TLB helpers name Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:00   ` Andrii Anisov
2019-04-25 18:00     ` [Xen-devel] " Andrii Anisov
2019-04-17 17:58 ` [PATCH 4/7] xen/arm: page: Clarify the Xen TLBs " Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:00   ` Andrii Anisov
2019-04-25 18:00     ` [Xen-devel] " Andrii Anisov
2019-04-17 17:58 ` [PATCH 5/7] xen/arm: Gather all TLB flush helpers in tlbflush.h Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:01   ` Andrii Anisov
2019-04-25 18:01     ` [Xen-devel] " Andrii Anisov
2019-04-17 17:58 ` [PATCH 6/7] xen/arm: tlbflush: Rework TLB helpers Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:01   ` Andrii Anisov [this message]
2019-04-25 18:01     ` Andrii Anisov
2019-04-25 20:42     ` Julien Grall
2019-04-25 20:42       ` [Xen-devel] " Julien Grall
2019-04-26 13:49       ` Andrii Anisov
2019-04-26 13:49         ` [Xen-devel] " Andrii Anisov
2019-04-26 14:06         ` Julien Grall
2019-04-26 14:06           ` [Xen-devel] " Julien Grall
2019-04-26 15:17           ` Andrii Anisov
2019-04-26 15:17             ` [Xen-devel] " Andrii Anisov
2019-04-17 17:58 ` [PATCH 7/7] xen/arm: mm: Flush the TLBs even if a mapping failed in create_xen_entries Julien Grall
2019-04-17 17:58   ` [Xen-devel] " Julien Grall
2019-04-25 18:03   ` Andrii Anisov
2019-04-25 18:03     ` [Xen-devel] " Andrii Anisov

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=4de7931e-27e0-be57-51e0-f2807aeff7bd@gmail.com \
    --to=andrii.anisov@gmail.com \
    --cc=Andrii_Anisov@epam.com \
    --cc=Oleksandr_Tyshchenko@epam.com \
    --cc=julien.grall@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /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.