All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org, patches@linaro.org,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Andreas Färber" <afaerber@suse.de>,
	qemu-arm@nongnu.org
Subject: Re: [PATCH 04/16] exec.c: Add address space index to CPUIOTLBEntry
Date: Fri, 6 Nov 2015 14:34:48 +0100	[thread overview]
Message-ID: <20151106133448.GD13308@toto> (raw)
In-Reply-To: <1446747358-18214-5-git-send-email-peter.maydell@linaro.org>

On Thu, Nov 05, 2015 at 06:15:46PM +0000, Peter Maydell wrote:
> Add the address space index to CPUIOTLBEntry, and use this to pass it
> to iotlb_to_region(), so that we use the correct AddressSpace when
> doing IO path lookups.

Hi Peter,

I think this works but eventually when we add support for CPUs behind
IOMMUs I think things will be easier if we store a pointer to the
AS instead of an index in the IOTLB. address_space_translate_for_iotlb()
with IOMMU support may be implemented so that it returns a different
address space as it walks tha memory hierarchy and translate things.

Do you see any issues with storing pointers to the AS instead of an
index?

Cheers,
Edgar


> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  cputlb.c                | 7 +++++--
>  exec.c                  | 4 ++--
>  include/exec/cpu-defs.h | 1 +
>  include/exec/exec-all.h | 2 +-
>  softmmu_template.h      | 4 ++--
>  5 files changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/cputlb.c b/cputlb.c
> index e753083..ae55035 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -397,6 +397,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, int asidx,
>      /* refill the tlb */
>      env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
>      env->iotlb[mmu_idx][index].attrs = attrs;
> +    env->iotlb[mmu_idx][index].asidx = asidx;
>      te->addend = addend - vaddr;
>      if (prot & PAGE_READ) {
>          te->addr_read = address;
> @@ -448,6 +449,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>      void *p;
>      MemoryRegion *mr;
>      CPUState *cpu = ENV_GET_CPU(env1);
> +    CPUIOTLBEntry *iotlbentry;
>  
>      page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
>      mmu_idx = cpu_mmu_index(env1, true);
> @@ -455,8 +457,9 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>                   (addr & TARGET_PAGE_MASK))) {
>          cpu_ldub_code(env1, addr);
>      }
> -    pd = env1->iotlb[mmu_idx][page_index].addr & ~TARGET_PAGE_MASK;
> -    mr = iotlb_to_region(cpu, pd);
> +    iotlbentry = &env1->iotlb[mmu_idx][page_index];
> +    pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
> +    mr = iotlb_to_region(cpu, pd, iotlbentry->asidx);
>      if (memory_region_is_unassigned(mr)) {
>          CPUClass *cc = CPU_GET_CLASS(cpu);
>  
> diff --git a/exec.c b/exec.c
> index 92e76fa..5e78d82 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -2228,9 +2228,9 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
>      return phys_section_add(map, &section);
>  }
>  
> -MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index)
> +MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, int asidx)
>  {
> -    CPUAddressSpace *cpuas = &cpu->cpu_ases[0];
> +    CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
>      AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch);
>      MemoryRegionSection *sections = d->map.sections;
>  
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index 5093be2..d102d79 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -129,6 +129,7 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
>  typedef struct CPUIOTLBEntry {
>      hwaddr addr;
>      MemTxAttrs attrs;
> +    int asidx;
>  } CPUIOTLBEntry;
>  
>  #define CPU_COMMON_TLB \
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 472d0fc..5dba8aa 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -398,7 +398,7 @@ extern uintptr_t tci_tb_ptr;
>  #if !defined(CONFIG_USER_ONLY)
>  
>  struct MemoryRegion *iotlb_to_region(CPUState *cpu,
> -                                     hwaddr index);
> +                                     hwaddr index, int asidx);
>  
>  void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr);
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 6803890..31a0f62 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -150,7 +150,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
>      uint64_t val;
>      CPUState *cpu = ENV_GET_CPU(env);
>      hwaddr physaddr = iotlbentry->addr;
> -    MemoryRegion *mr = iotlb_to_region(cpu, physaddr);
> +    MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->asidx);
>  
>      physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
>      cpu->mem_io_pc = retaddr;
> @@ -357,7 +357,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
>  {
>      CPUState *cpu = ENV_GET_CPU(env);
>      hwaddr physaddr = iotlbentry->addr;
> -    MemoryRegion *mr = iotlb_to_region(cpu, physaddr);
> +    MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->asidx);
>  
>      physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
>      if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
> -- 
> 1.9.1
> 

WARNING: multiple messages have this Message-ID (diff)
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: patches@linaro.org, qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Andreas Färber" <afaerber@suse.de>
Subject: Re: [Qemu-devel] [PATCH 04/16] exec.c: Add address space index to CPUIOTLBEntry
Date: Fri, 6 Nov 2015 14:34:48 +0100	[thread overview]
Message-ID: <20151106133448.GD13308@toto> (raw)
In-Reply-To: <1446747358-18214-5-git-send-email-peter.maydell@linaro.org>

On Thu, Nov 05, 2015 at 06:15:46PM +0000, Peter Maydell wrote:
> Add the address space index to CPUIOTLBEntry, and use this to pass it
> to iotlb_to_region(), so that we use the correct AddressSpace when
> doing IO path lookups.

Hi Peter,

I think this works but eventually when we add support for CPUs behind
IOMMUs I think things will be easier if we store a pointer to the
AS instead of an index in the IOTLB. address_space_translate_for_iotlb()
with IOMMU support may be implemented so that it returns a different
address space as it walks tha memory hierarchy and translate things.

Do you see any issues with storing pointers to the AS instead of an
index?

Cheers,
Edgar


> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  cputlb.c                | 7 +++++--
>  exec.c                  | 4 ++--
>  include/exec/cpu-defs.h | 1 +
>  include/exec/exec-all.h | 2 +-
>  softmmu_template.h      | 4 ++--
>  5 files changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/cputlb.c b/cputlb.c
> index e753083..ae55035 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -397,6 +397,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, int asidx,
>      /* refill the tlb */
>      env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
>      env->iotlb[mmu_idx][index].attrs = attrs;
> +    env->iotlb[mmu_idx][index].asidx = asidx;
>      te->addend = addend - vaddr;
>      if (prot & PAGE_READ) {
>          te->addr_read = address;
> @@ -448,6 +449,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>      void *p;
>      MemoryRegion *mr;
>      CPUState *cpu = ENV_GET_CPU(env1);
> +    CPUIOTLBEntry *iotlbentry;
>  
>      page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
>      mmu_idx = cpu_mmu_index(env1, true);
> @@ -455,8 +457,9 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>                   (addr & TARGET_PAGE_MASK))) {
>          cpu_ldub_code(env1, addr);
>      }
> -    pd = env1->iotlb[mmu_idx][page_index].addr & ~TARGET_PAGE_MASK;
> -    mr = iotlb_to_region(cpu, pd);
> +    iotlbentry = &env1->iotlb[mmu_idx][page_index];
> +    pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
> +    mr = iotlb_to_region(cpu, pd, iotlbentry->asidx);
>      if (memory_region_is_unassigned(mr)) {
>          CPUClass *cc = CPU_GET_CLASS(cpu);
>  
> diff --git a/exec.c b/exec.c
> index 92e76fa..5e78d82 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -2228,9 +2228,9 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
>      return phys_section_add(map, &section);
>  }
>  
> -MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index)
> +MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, int asidx)
>  {
> -    CPUAddressSpace *cpuas = &cpu->cpu_ases[0];
> +    CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
>      AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch);
>      MemoryRegionSection *sections = d->map.sections;
>  
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index 5093be2..d102d79 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -129,6 +129,7 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
>  typedef struct CPUIOTLBEntry {
>      hwaddr addr;
>      MemTxAttrs attrs;
> +    int asidx;
>  } CPUIOTLBEntry;
>  
>  #define CPU_COMMON_TLB \
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 472d0fc..5dba8aa 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -398,7 +398,7 @@ extern uintptr_t tci_tb_ptr;
>  #if !defined(CONFIG_USER_ONLY)
>  
>  struct MemoryRegion *iotlb_to_region(CPUState *cpu,
> -                                     hwaddr index);
> +                                     hwaddr index, int asidx);
>  
>  void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
>                uintptr_t retaddr);
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 6803890..31a0f62 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -150,7 +150,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
>      uint64_t val;
>      CPUState *cpu = ENV_GET_CPU(env);
>      hwaddr physaddr = iotlbentry->addr;
> -    MemoryRegion *mr = iotlb_to_region(cpu, physaddr);
> +    MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->asidx);
>  
>      physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
>      cpu->mem_io_pc = retaddr;
> @@ -357,7 +357,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
>  {
>      CPUState *cpu = ENV_GET_CPU(env);
>      hwaddr physaddr = iotlbentry->addr;
> -    MemoryRegion *mr = iotlb_to_region(cpu, physaddr);
> +    MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->asidx);
>  
>      physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
>      if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
> -- 
> 1.9.1
> 

  reply	other threads:[~2015-11-06 13:34 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-05 18:15 [PATCH 00/16] Add support for multiple address spaces per CPU and use it for ARM TrustZone Peter Maydell
2015-11-05 18:15 ` [Qemu-devel] " Peter Maydell
2015-11-05 18:15 ` [PATCH 01/16] exec.c: Don't set cpu->as until cpu_address_space_init Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:04   ` Edgar E. Iglesias
2015-11-06 13:04     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-05 18:15 ` [PATCH 02/16] exec.c: Allow target CPUs to define multiple AddressSpaces Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:21   ` Edgar E. Iglesias
2015-11-06 13:21     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-06 13:34     ` Peter Maydell
2015-11-06 13:34       ` [Qemu-devel] " Peter Maydell
2015-11-06 13:49       ` Edgar E. Iglesias
2015-11-06 13:49         ` [Qemu-devel] " Edgar E. Iglesias
2015-11-09 10:32       ` Paolo Bonzini
2015-11-09 10:32         ` [Qemu-devel] " Paolo Bonzini
2015-11-09 10:30   ` Paolo Bonzini
2015-11-09 10:30     ` [Qemu-devel] " Paolo Bonzini
2015-11-05 18:15 ` [PATCH 03/16] tlb_set_page_with_attrs: Take argument specifying AddressSpace to use Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:27   ` Edgar E. Iglesias
2015-11-06 13:27     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-06 13:41     ` Peter Maydell
2015-11-06 13:41       ` [Qemu-devel] " Peter Maydell
2015-11-06 13:49       ` Edgar E. Iglesias
2015-11-06 13:49         ` [Qemu-devel] " Edgar E. Iglesias
2015-11-06 13:52         ` Edgar E. Iglesias
2015-11-06 13:52           ` [Qemu-devel] " Edgar E. Iglesias
2015-11-09 10:44   ` Paolo Bonzini
2015-11-09 10:44     ` [Qemu-devel] " Paolo Bonzini
2015-11-09 10:49     ` Peter Maydell
2015-11-09 10:49       ` [Qemu-devel] " Peter Maydell
2015-11-10 16:13       ` Peter Maydell
2015-11-10 16:13         ` [Qemu-devel] " Peter Maydell
2015-11-05 18:15 ` [PATCH 04/16] exec.c: Add address space index to CPUIOTLBEntry Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:34   ` Edgar E. Iglesias [this message]
2015-11-06 13:34     ` Edgar E. Iglesias
2015-11-06 13:45     ` Peter Maydell
2015-11-06 13:45       ` [Qemu-devel] " Peter Maydell
2015-11-06 14:13       ` Edgar E. Iglesias
2015-11-06 14:13         ` [Qemu-devel] " Edgar E. Iglesias
2015-11-05 18:15 ` [PATCH 05/16] exec.c: Add cpu_get_address_space() Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-05 18:15 ` [PATCH 06/16] include/qom/cpu.h: Add new get_phys_page_asidx_debug method Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:37   ` Edgar E. Iglesias
2015-11-06 13:37     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-05 18:15 ` [PATCH 07/16] exec.c: Use cpu_get_phys_page_asidx_debug Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:38   ` Edgar E. Iglesias
2015-11-06 13:38     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-05 18:15 ` [PATCH 08/16] exec.c: Have one io_mem_watch per AddressSpace Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 13:45   ` Edgar E. Iglesias
2015-11-06 13:45     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-09 10:49   ` Paolo Bonzini
2015-11-09 10:49     ` [Qemu-devel] " Paolo Bonzini
2015-11-09 10:54     ` Peter Maydell
2015-11-09 10:54       ` [Qemu-devel] " Peter Maydell
2015-11-09 11:00       ` Paolo Bonzini
2015-11-09 11:00         ` [Qemu-devel] " Paolo Bonzini
2015-11-05 18:15 ` [PATCH 09/16] target-arm: Support multiple address spaces in page table walks Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 14:22   ` Edgar E. Iglesias
2015-11-06 14:22     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-09 10:51   ` Paolo Bonzini
2015-11-09 10:51     ` [Qemu-devel] " Paolo Bonzini
2015-11-09 10:58     ` Peter Maydell
2015-11-09 10:58       ` [Qemu-devel] " Peter Maydell
2015-11-09 11:03       ` Paolo Bonzini
2015-11-09 11:03         ` [Qemu-devel] " Paolo Bonzini
2015-11-09 11:09         ` Peter Maydell
2015-11-09 11:09           ` [Qemu-devel] " Peter Maydell
2015-11-09 11:19           ` Paolo Bonzini
2015-11-09 11:19             ` [Qemu-devel] " Paolo Bonzini
2015-11-09 11:22             ` Peter Maydell
2015-11-09 11:22               ` [Qemu-devel] " Peter Maydell
2015-11-13 18:51       ` Peter Maydell
2015-11-13 18:51         ` [Qemu-devel] " Peter Maydell
2015-11-05 18:15 ` [PATCH 10/16] target-arm: Implement cpu_get_phys_page_asidx_debug Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 14:23   ` Edgar E. Iglesias
2015-11-06 14:23     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-05 18:15 ` [PATCH 11/16] memory: Add address_space_init_shareable() Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 14:29   ` Edgar E. Iglesias
2015-11-06 14:29     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-06 14:49     ` Peter Maydell
2015-11-06 14:49       ` [Qemu-devel] " Peter Maydell
2015-11-09 10:55   ` Paolo Bonzini
2015-11-09 10:55     ` [Qemu-devel] " Paolo Bonzini
2015-11-09 10:59     ` Peter Maydell
2015-11-09 10:59       ` [Qemu-devel] " Peter Maydell
2015-11-09 11:02       ` Paolo Bonzini
2015-11-09 11:02         ` [Qemu-devel] " Paolo Bonzini
2015-11-05 18:15 ` [PATCH 12/16] qom/cpu: Add MemoryRegion property Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 14:31   ` Edgar E. Iglesias
2015-11-06 14:31     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-09 10:56   ` Paolo Bonzini
2015-11-09 10:56     ` [Qemu-devel] " Paolo Bonzini
2015-11-05 18:15 ` [PATCH 13/16] target-arm: Add QOM property for Secure memory region Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 14:33   ` Edgar E. Iglesias
2015-11-06 14:33     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-05 18:15 ` [PATCH 14/16] hw/arm/virt: Wire up memory region to CPUs explicitly Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-06 14:45   ` Edgar E. Iglesias
2015-11-06 14:45     ` [Qemu-devel] " Edgar E. Iglesias
2015-11-06 14:51     ` Peter Maydell
2015-11-06 14:51       ` [Qemu-devel] " Peter Maydell
2015-11-05 18:15 ` [PATCH 15/16] [RFC] hw/arm/virt: add secure memory region and UART Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell
2015-11-05 18:15 ` [PATCH 16/16] HACK: rearrange the virt memory map to suit OP-TEE Peter Maydell
2015-11-05 18:15   ` [Qemu-devel] " Peter Maydell

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=20151106133448.GD13308@toto \
    --to=edgar.iglesias@gmail.com \
    --cc=afaerber@suse.de \
    --cc=alex.bennee@linaro.org \
    --cc=patches@linaro.org \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.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.