Hi,
Add core dump support for MTE tags. When a core file is generated and
the user has mappings with PROT_MTE, segments with the PT_ARM_MEMTAG_MTE
type are dumped. These correspond to the PT_LOAD segments for the same
virtual addresses.
The last patch documents the core file format. The tags are dumped
packed, two tags per byte (unlike ptrace where we have one tag per byte)
and there is no header to define the format, it's all fixed for the
PT_ARM_MEMTAG_MTE type.
Below you can see the output of 'readelf -a core' for a program mapping
two regions with PROT_MTE, one 2-page and the other 4-page long. Half of
the first page in each range was filled with 0xa and 0xb tags
respectively.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
...
LOAD 0x030000 0x0000ffff80034000 0x0000000000000000 0x000000 0x002000 RW 0x1000
LOAD 0x030000 0x0000ffff80036000 0x0000000000000000 0x004000 0x004000 RW 0x1000
...
LOPROC+0x5441470 0x05b000 0x0000ffff80034000 0x0000000000000000 0x000100 0x002000 0
LOPROC+0x5441470 0x05b100 0x0000ffff80036000 0x0000000000000000 0x000200 0x004000 0
The relevant 'od -tx1 core' output:
05b000 bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb
*
05b040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
05b100 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
*
05b140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
05b300
Catalin Marinas (5):
elfcore: Replace CONFIG_{IA64,UML} checks with a new option
elf: Introduce the ARM MTE ELF segment type
arm64: mte: Define the number of bytes for storing the tags in a page
arm64: mte: Dump the MTE tags in the core file
arm64: mte: Document the core dump file format
.../arm64/memory-tagging-extension.rst | 22 ++++
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/mte-def.h | 1 +
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/elfcore.c | 123 ++++++++++++++++++
arch/arm64/lib/mte.S | 4 +-
arch/arm64/mm/mteswap.c | 2 +-
arch/ia64/Kconfig | 1 +
arch/x86/um/Kconfig | 1 +
fs/Kconfig.binfmt | 3 +
include/linux/elfcore.h | 4 +-
include/uapi/linux/elf.h | 3 +
12 files changed, 161 insertions(+), 5 deletions(-)
create mode 100644 arch/arm64/kernel/elfcore.c
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
As arm64 is about to introduce MTE-specific phdrs in the core dump, add
a common CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS option currently selectable
by UML_X86 and IA64.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Eric Biederman <redacted>
---
arch/ia64/Kconfig | 1 +
arch/x86/um/Kconfig | 1 +
fs/Kconfig.binfmt | 3 +++
include/linux/elfcore.h | 4 ++--
4 files changed, 7 insertions(+), 2 deletions(-)
@@ -8,6 +8,7 @@ menu "Processor type and features"configIA64bool+selectARCH_BINFMT_ELF_EXTRA_PHDRSselectARCH_HAS_DMA_MARK_CLEANselectARCH_HAS_STRNCPY_FROM_USERselectARCH_HAS_STRNLEN_USER
Memory tags will be dumped in the core file as segments with their own
type. Discussions with the binutils and the generic ABI community
settled on using new definitions in the PT_*PROC space (and to be
documented in the processor-specific ABIs).
Introduce PT_ARM_MEMTAG_MTE as (PT_LOPROC + 0x1). Not included in this
patch since there is no upstream support but the CHERI/BSD community
will also reserve:
#define PT_ARM_MEMTAG_CHERI (PT_LOPROC + 0x2)
#define PT_RISCV_MEMTAG_CHERI (PT_LOPROC + 0x3)
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
include/uapi/linux/elf.h | 3 +++
1 file changed, 3 insertions(+)
Rather than explicitly calculating the number of bytes for a compact tag
storage format corresponding to a page, just add a MTE_PAGE_TAG_STORAGE
macro. With the current MTE implementation of 4 bits per tag, we store
2 tags in a byte.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/mte-def.h | 1 +
arch/arm64/lib/mte.S | 4 ++--
arch/arm64/mm/mteswap.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
For each vma mapped with PROT_MTE (the VM_MTE flag set), generate a
PT_ARM_MEMTAG_MTE segment in the core file and dump the corresponding
tags. The in-file size for such segments is 128 bytes per page.
For pages in a VM_MTE vma which are not present in the user page tables
or don't have the PG_mte_tagged flag set (e.g. execute-only), just write
zeros in the core file.
An example of program headers for two vmas, one 2-page, the other 4-page
long:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
...
LOAD 0x030000 0x0000ffff80034000 0x0000000000000000 0x000000 0x002000 RW 0x1000
LOAD 0x030000 0x0000ffff80036000 0x0000000000000000 0x004000 0x004000 RW 0x1000
...
LOPROC+0x1 0x05b000 0x0000ffff80034000 0x0000000000000000 0x000100 0x002000 0
LOPROC+0x1 0x05b100 0x0000ffff80036000 0x0000000000000000 0x000200 0x004000 0
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/elfcore.c | 123 ++++++++++++++++++++++++++++++++++++
3 files changed, 125 insertions(+)
create mode 100644 arch/arm64/kernel/elfcore.c
Add the program header definition and data layout for the
PT_ARM_MEMTAG_MTE segments.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
.../arm64/memory-tagging-extension.rst | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
@@ -213,6 +213,28 @@ address ABI control and MTE configuration of a process as per the Documentation/arm64/tagged-address-abi.rst and above. The corresponding``regset`` is 1 element of 8 bytes (``sizeof(long))``).+Core dump support+-----------------++The allocation tags for user memory mapped with ``PROT_MTE`` are dumped+in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The+program header for such segment is defined as:++:``p_type``:``PT_ARM_MEMTAG_MTE``+:``p_flags``: 0+:``p_offset``: segment file offset+:``p_vaddr``: segment virtual address, same as the corresponding+``PT_LOAD`` segment+:``p_paddr``: 0+:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 16 / 2``+:``p_memsz``: segment size in memory, same as the corresponding+``PT_LOAD`` segment+:``p_align``: 0++The tags are stored in the core file at ``p_offset`` as two 4-bit tags+in a byte. With the tag granule of 16 bytes, a 4K page requires 128+bytes in the core file.+ Example of correct usage ========================
From: Luis Machado <hidden> Date: 2022-01-03 17:29:39
On 12/8/21 9:19 AM, Catalin Marinas wrote:
quoted hunk
Add the program header definition and data layout for the
PT_ARM_MEMTAG_MTE segments.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
.../arm64/memory-tagging-extension.rst | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
@@ -213,6 +213,28 @@ address ABI control and MTE configuration of a process as per the Documentation/arm64/tagged-address-abi.rst and above. The corresponding``regset`` is 1 element of 8 bytes (``sizeof(long))``).+Core dump support+-----------------++The allocation tags for user memory mapped with ``PROT_MTE`` are dumped+in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The+program header for such segment is defined as:++:``p_type``:``PT_ARM_MEMTAG_MTE``+:``p_flags``: 0+:``p_offset``: segment file offset+:``p_vaddr``: segment virtual address, same as the corresponding+``PT_LOAD`` segment+:``p_paddr``: 0+:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 16 / 2``
For the sake of making things extra clear, I'd describe what the
constants (16 and 2) mean.
+:``p_memsz``: segment size in memory, same as the corresponding
+ ``PT_LOAD`` segment
+:``p_align``: 0
+
+The tags are stored in the core file at ``p_offset`` as two 4-bit tags
+in a byte. With the tag granule of 16 bytes, a 4K page requires 128
+bytes in the core file.
+
Example of correct usage
========================
From: Luis Machado <hidden> Date: 2022-01-03 17:29:39
On 12/8/21 9:19 AM, Catalin Marinas wrote:
quoted hunk
For each vma mapped with PROT_MTE (the VM_MTE flag set), generate a
PT_ARM_MEMTAG_MTE segment in the core file and dump the corresponding
tags. The in-file size for such segments is 128 bytes per page.
For pages in a VM_MTE vma which are not present in the user page tables
or don't have the PG_mte_tagged flag set (e.g. execute-only), just write
zeros in the core file.
An example of program headers for two vmas, one 2-page, the other 4-page
long:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
...
LOAD 0x030000 0x0000ffff80034000 0x0000000000000000 0x000000 0x002000 RW 0x1000
LOAD 0x030000 0x0000ffff80036000 0x0000000000000000 0x004000 0x004000 RW 0x1000
...
LOPROC+0x1 0x05b000 0x0000ffff80034000 0x0000000000000000 0x000100 0x002000 0
LOPROC+0x1 0x05b100 0x0000ffff80036000 0x0000000000000000 0x000200 0x004000 0
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/elfcore.c | 123 ++++++++++++++++++++++++++++++++++++
3 files changed, 125 insertions(+)
create mode 100644 arch/arm64/kernel/elfcore.c
From: Luis Machado <hidden> Date: 2022-01-03 17:29:54
On 12/8/21 9:19 AM, Catalin Marinas wrote:
quoted hunk
Rather than explicitly calculating the number of bytes for a compact tag
storage format corresponding to a page, just add a MTE_PAGE_TAG_STORAGE
macro. With the current MTE implementation of 4 bits per tag, we store
2 tags in a byte.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/mte-def.h | 1 +
arch/arm64/lib/mte.S | 4 ++--
arch/arm64/mm/mteswap.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
From: Luis Machado <hidden> Date: 2022-01-03 17:30:40
On 12/8/21 9:19 AM, Catalin Marinas wrote:
quoted hunk
Memory tags will be dumped in the core file as segments with their own
type. Discussions with the binutils and the generic ABI community
settled on using new definitions in the PT_*PROC space (and to be
documented in the processor-specific ABIs).
Introduce PT_ARM_MEMTAG_MTE as (PT_LOPROC + 0x1). Not included in this
patch since there is no upstream support but the CHERI/BSD community
will also reserve:
#define PT_ARM_MEMTAG_CHERI (PT_LOPROC + 0x2)
#define PT_RISCV_MEMTAG_CHERI (PT_LOPROC + 0x3)
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
include/uapi/linux/elf.h | 3 +++
1 file changed, 3 insertions(+)
@@ -40,6 +40,9 @@ typedef __s64 Elf64_Sxword;#define PT_GNU_STACK (PT_LOOS + 0x474e551)+/* ARM MTE memory tag segment type */+#define PT_ARM_MEMTAG_MTE (PT_LOPROC + 0x1)+/**ExtendedNumbering*
Sorry for the delay. This looks good from the debugger's side.
Acked-by: Luis Machado <redacted>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
@@ -213,6 +213,28 @@ address ABI control and MTE configuration of a process as per the Documentation/arm64/tagged-address-abi.rst and above. The corresponding``regset`` is 1 element of 8 bytes (``sizeof(long))``).+Core dump support+-----------------++The allocation tags for user memory mapped with ``PROT_MTE`` are dumped+in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The+program header for such segment is defined as:++:``p_type``:``PT_ARM_MEMTAG_MTE``+:``p_flags``: 0+:``p_offset``: segment file offset+:``p_vaddr``: segment virtual address, same as the corresponding+``PT_LOAD`` segment+:``p_paddr``: 0+:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 16 / 2``
For the sake of making things extra clear, I'd describe what the constants
(16 and 2) mean.
I'll rewrite this as: "``p_mem_sz / 32`` (two 4-bit tags cover 32 bytes
of memory)". I find the "16 / 2" more confusing.