[PATCH v2 00/85] target/arm: Implement FEAT_GCS

Richard Henderson posted 85 patches 3 months, 2 weeks ago
Failed in applying to current master (apply log)
There is a newer version of this series
include/exec/cputlb.h              |  32 +--
include/exec/memopidx.h            |   9 +-
include/hw/core/cpu.h              |  25 +-
linux-user/aarch64/gcs-internal.h  |  38 +++
linux-user/aarch64/target_prctl.h  |  96 +++++++
linux-user/aarch64/target_signal.h |   1 +
linux-user/loader.h                |   2 +-
linux-user/qemu.h                  |   5 +
target/arm/cpregs.h                |  46 ++-
target/arm/cpu-features.h          |  20 ++
target/arm/cpu.h                   | 242 ++--------------
target/arm/internals.h             | 170 ++---------
target/arm/mmuidx-internal.h       | 113 ++++++++
target/arm/mmuidx.h                | 241 ++++++++++++++++
target/arm/syndrome.h              |  35 +++
target/arm/tcg/translate.h         |  46 ++-
target/hppa/cpu.h                  |  28 +-
tests/tcg/aarch64/gcs.h            |  80 ++++++
accel/tcg/cputlb.c                 |  49 ++--
linux-user/aarch64/cpu_loop.c      | 158 ++++++++---
linux-user/aarch64/signal.c        | 161 ++++++++++-
linux-user/elfload.c               |  11 +-
linux-user/syscall.c               | 114 ++++++++
target/arm/cpregs-gcs.c            | 141 ++++++++++
target/arm/cpu.c                   |  17 +-
target/arm/gdbstub64.c             |   1 +
target/arm/helper.c                | 270 ++++++++++++++----
target/arm/machine.c               |  62 +++-
target/arm/mmuidx.c                |  66 +++++
target/arm/ptw.c                   | 430 +++++++++++++++++++++-------
target/arm/tcg-stubs.c             |   2 +-
target/arm/tcg/cpregs-at.c         |  69 +++--
target/arm/tcg/cpu64.c             |   4 +
target/arm/tcg/helper-a64.c        |  13 +-
target/arm/tcg/hflags.c            |  38 +++
target/arm/tcg/m_helper.c          |   4 +-
target/arm/tcg/mte_helper.c        |   2 +-
target/arm/tcg/op_helper.c         |   8 +-
target/arm/tcg/tlb-insns.c         |  47 +++-
target/arm/tcg/tlb_helper.c        |  13 +-
target/arm/tcg/translate-a64.c     | 437 ++++++++++++++++++++++++++---
target/arm/tcg/translate.c         |  78 +++--
tcg/tcg.c                          |   3 +-
tests/tcg/aarch64/gcspushm.c       |  71 +++++
tests/tcg/aarch64/gcsss.c          |  74 +++++
tests/tcg/aarch64/gcsstr.c         |  48 ++++
docs/system/arm/emulation.rst      |   5 +
target/arm/meson.build             |   9 +-
target/arm/tcg/a64.decode          |   5 +
tcg/aarch64/tcg-target.c.inc       |   2 +-
tcg/arm/tcg-target.c.inc           |   2 +-
tests/tcg/aarch64/Makefile.target  |   5 +
52 files changed, 2914 insertions(+), 734 deletions(-)
create mode 100644 linux-user/aarch64/gcs-internal.h
create mode 100644 target/arm/mmuidx-internal.h
create mode 100644 target/arm/mmuidx.h
create mode 100644 tests/tcg/aarch64/gcs.h
create mode 100644 target/arm/cpregs-gcs.c
create mode 100644 target/arm/mmuidx.c
create mode 100644 tests/tcg/aarch64/gcspushm.c
create mode 100644 tests/tcg/aarch64/gcsss.c
create mode 100644 tests/tcg/aarch64/gcsstr.c
[PATCH v2 00/85] target/arm: Implement FEAT_GCS
Posted by Richard Henderson 3 months, 2 weeks ago
Based-on: 20250727074202.83141-1-richard.henderson@linaro.org
("[PATCH for-10.2 v9 0/6] target/arm: Add FEAT_MEC to max cpu")

Tree: https://gitlab.com/rth7680/qemu/-/tree/tgt-arm-gcs

This includes the prerequisite features, ATS1A and S1PIE, and
not a prerequisite but closely related, S2PIE.

This passes the linux kselftests for gcs, with a 48-bit VA.
I also include a few smoke tests in tests/tcg/.

There's something subtly wrong with a 52-bit VA.  Most everything
works fine, but the first GCS lookup faults on a missing level 3
page table entry: a Translation fault, not a Permission fault.
The kernel then panics.  Either there's something amiss with our
implementation of FEAT_LPA2, or there's a kernel bug.

This includes a best-effort linux-user implementation.  Since we
don't have softmmu in user-only (yet), gcs stack pages get normal
read/write access.  This means we cannot write-protect the pages
in the same way the system implementation can.  But all of the
other parts of GCS work fine, which is good enough for testing.

Changes for v2:
  - Add arm_mmuidx_is_valid
  - Revise and merge back the linux-user/aarch64 changes for
    syndromes and ESR records.


r~


Richard Henderson (85):
  linux-user/aarch64: Split out signal_for_exception
  linux-user/aarch64: Check syndrome for EXCP_UDEF
  linux-user/aarch64: Generate ESR signal records
  target/arm: Add prot_check parameter to pmsav8_mpu_lookup
  target/arm: Add in_prot_check to S1Translate
  target/arm: Skip permission check from
    arm_cpu_get_phys_page_attrs_debug
  target/arm: Introduce get_phys_addr_for_at
  target/arm: Skip AF and DB updates for AccessType_AT
  target/arm: Add prot_check parameter to do_ats_write
  target/arm: Fill in HFG[RWI]TR_EL2 bits for Arm v9.5
  target/arm: Remove outdated comment for ZCR_EL12
  target/arm: Implement FEAT_ATS1A
  target/arm: Add isar feature test for FEAT_S1PIE, FEAT_S2PIE
  target/arm: Enable TCR2_ELx.PIE
  target/arm: Implement PIR_ELx, PIRE0_ELx, S2PIR_EL2 registers
  target/arm: Force HPD for stage2 translations
  target/arm: Cache NV1 early in get_phys_addr_lpae
  target/arm: Populate PIE in aa64_va_parameters
  target/arm: Implement get_S1prot_indirect
  target/arm: Implement get_S2prot_indirect
  target/arm: Do not migrate env->exception
  target/arm: Expand CPUARMState.exception.syndrome to 64 bits
  target/arm: Expand syndrome parameter to raise_exception*
  target/arm: Implement dirtybit check for PIE
  target/arm: Enable FEAT_S1PIE and FEAT_S2PIE on -cpu max
  include/hw/core/cpu: Introduce MMUIdxMap
  include/hw/core/cpu: Introduce cpu_tlb_fast
  include/hw/core/cpu: Invert the indexing into CPUTLBDescFast
  target/hppa: Adjust mmu indexes to begin with 0
  include/exec/memopidx: Adjust for 32 mmu indexes
  include/hw/core/cpu: Widen MMUIdxMap
  target/arm: Split out mmuidx.h from cpu.h
  target/arm: Convert arm_mmu_idx_to_el from switch to table
  target/arm: Remove unused env argument from regime_el
  target/arm: Convert regime_el from switch to table
  target/arm: Convert regime_has_2_ranges from switch to table
  target/arm: Remove unused env argument from regime_is_pan
  target/arm: Convert regime_is_pan from switch to table
  target/arm: Remove unused env argument from regime_is_user
  target/arm: Convert regime_is_user from switch to table
  target/arm: Convert arm_mmu_idx_is_stage1_of_2 from switch to table
  target/arm: Convert regime_is_stage2 to table
  target/arm: Introduce mmu indexes for GCS
  target/arm: Introduce regime_to_gcs
  target/arm: Support page protections for GCS mmu indexes
  target/arm: Implement gcs bit for data abort
  target/arm: Add GCS cpregs
  target/arm: Add GCS enable and trap levels to DisasContext
  target/arm: Implement FEAT_CHK
  target/arm: Expand pstate to 64 bits
  target/arm: Add syndrome data for EC_GCS
  target/arm: Implement EXLOCKException for ELR_ELx and SPSR_ELx
  target/arm: Split {arm,core}_user_mem_index
  target/arm: Introduce delay_exception{_el}
  target/arm: Emit HSTR trap exception out of line
  target/arm: Emit v7m LTPSIZE exception out of line
  target/arm: Implement GCSSTR, GCSSTTR
  target/arm: Implement GCSB
  target/arm: Implement GCSPUSHM
  target/arm: Implement GCSPOPM
  target/arm: Implement GCSPUSHX
  target/arm: Implement GCSPOPX
  target/arm: Implement GCSPOPCX
  target/arm: Implement GCSSS1
  target/arm: Implement GCSSS2
  target/arm: Add gcs record for BL
  target/arm: Add gcs record for BLR
  target/arm: Add gcs record for BLR with PAuth
  target/arm: Load gcs record for RET
  target/arm: Load gcs record for RET with PAuth
  target/arm: Copy EXLOCKEn to EXLOCK on exception to the same EL
  target/arm: Implement EXLOCK check during exception return
  target/arm: Enable FEAT_GCS with -cpu max
  linux-user/aarch64: Implement prctls for GCS
  linux-user/aarch64: Allocate new gcs stack on clone
  linux-user/aarch64: Release gcs stack on thread exit
  linux-user/aarch64: Implement map_shadow_stack syscall
  target/arm: Enable GCSPR_EL0 for read in user-mode
  linux-user/aarch64: Inject SIGSEGV for GCS faults
  linux-user/aarch64: Generate GCS signal records
  linux-user: Change exported get_elf_hwcap to abi_ulong
  linux-user/aarch64: Enable GCS in HWCAP
  tests/tcg/aarch64: Add gcsstr
  tests/tcg/aarch64: Add gcspushm
  tests/tcg/aarch64: Add gcsss

 include/exec/cputlb.h              |  32 +--
 include/exec/memopidx.h            |   9 +-
 include/hw/core/cpu.h              |  25 +-
 linux-user/aarch64/gcs-internal.h  |  38 +++
 linux-user/aarch64/target_prctl.h  |  96 +++++++
 linux-user/aarch64/target_signal.h |   1 +
 linux-user/loader.h                |   2 +-
 linux-user/qemu.h                  |   5 +
 target/arm/cpregs.h                |  46 ++-
 target/arm/cpu-features.h          |  20 ++
 target/arm/cpu.h                   | 242 ++--------------
 target/arm/internals.h             | 170 ++---------
 target/arm/mmuidx-internal.h       | 113 ++++++++
 target/arm/mmuidx.h                | 241 ++++++++++++++++
 target/arm/syndrome.h              |  35 +++
 target/arm/tcg/translate.h         |  46 ++-
 target/hppa/cpu.h                  |  28 +-
 tests/tcg/aarch64/gcs.h            |  80 ++++++
 accel/tcg/cputlb.c                 |  49 ++--
 linux-user/aarch64/cpu_loop.c      | 158 ++++++++---
 linux-user/aarch64/signal.c        | 161 ++++++++++-
 linux-user/elfload.c               |  11 +-
 linux-user/syscall.c               | 114 ++++++++
 target/arm/cpregs-gcs.c            | 141 ++++++++++
 target/arm/cpu.c                   |  17 +-
 target/arm/gdbstub64.c             |   1 +
 target/arm/helper.c                | 270 ++++++++++++++----
 target/arm/machine.c               |  62 +++-
 target/arm/mmuidx.c                |  66 +++++
 target/arm/ptw.c                   | 430 +++++++++++++++++++++-------
 target/arm/tcg-stubs.c             |   2 +-
 target/arm/tcg/cpregs-at.c         |  69 +++--
 target/arm/tcg/cpu64.c             |   4 +
 target/arm/tcg/helper-a64.c        |  13 +-
 target/arm/tcg/hflags.c            |  38 +++
 target/arm/tcg/m_helper.c          |   4 +-
 target/arm/tcg/mte_helper.c        |   2 +-
 target/arm/tcg/op_helper.c         |   8 +-
 target/arm/tcg/tlb-insns.c         |  47 +++-
 target/arm/tcg/tlb_helper.c        |  13 +-
 target/arm/tcg/translate-a64.c     | 437 ++++++++++++++++++++++++++---
 target/arm/tcg/translate.c         |  78 +++--
 tcg/tcg.c                          |   3 +-
 tests/tcg/aarch64/gcspushm.c       |  71 +++++
 tests/tcg/aarch64/gcsss.c          |  74 +++++
 tests/tcg/aarch64/gcsstr.c         |  48 ++++
 docs/system/arm/emulation.rst      |   5 +
 target/arm/meson.build             |   9 +-
 target/arm/tcg/a64.decode          |   5 +
 tcg/aarch64/tcg-target.c.inc       |   2 +-
 tcg/arm/tcg-target.c.inc           |   2 +-
 tests/tcg/aarch64/Makefile.target  |   5 +
 52 files changed, 2914 insertions(+), 734 deletions(-)
 create mode 100644 linux-user/aarch64/gcs-internal.h
 create mode 100644 target/arm/mmuidx-internal.h
 create mode 100644 target/arm/mmuidx.h
 create mode 100644 tests/tcg/aarch64/gcs.h
 create mode 100644 target/arm/cpregs-gcs.c
 create mode 100644 target/arm/mmuidx.c
 create mode 100644 tests/tcg/aarch64/gcspushm.c
 create mode 100644 tests/tcg/aarch64/gcsss.c
 create mode 100644 tests/tcg/aarch64/gcsstr.c

-- 
2.43.0
Re: [PATCH v2 00/85] target/arm: Implement FEAT_GCS
Posted by Thiago Jung Bauermann 3 months ago
Hello,

Richard Henderson <richard.henderson@linaro.org> writes:

> Based-on: 20250727074202.83141-1-richard.henderson@linaro.org
> ("[PATCH for-10.2 v9 0/6] target/arm: Add FEAT_MEC to max cpu")
>
> Tree: https://gitlab.com/rth7680/qemu/-/tree/tgt-arm-gcs
>
> This includes the prerequisite features, ATS1A and S1PIE, and
> not a prerequisite but closely related, S2PIE.
>
> This passes the linux kselftests for gcs, with a 48-bit VA.
> I also include a few smoke tests in tests/tcg/.
>
> There's something subtly wrong with a 52-bit VA.  Most everything
> works fine, but the first GCS lookup faults on a missing level 3
> page table entry: a Translation fault, not a Permission fault.
> The kernel then panics.  Either there's something amiss with our
> implementation of FEAT_LPA2, or there's a kernel bug.
>
> This includes a best-effort linux-user implementation.  Since we
> don't have softmmu in user-only (yet), gcs stack pages get normal
> read/write access.  This means we cannot write-protect the pages
> in the same way the system implementation can.  But all of the
> other parts of GCS work fine, which is good enough for testing.
>
> Changes for v2:
>   - Add arm_mmuidx_is_valid
>   - Revise and merge back the linux-user/aarch64 changes for
>     syndromes and ESR records.

I finally managed to test your branch with my GDB patches for GCS
support in Linux userspace.

Most of the GDB tests pass. The only failure is in a test which sets the
GCSPR in a process to a bogus value. This causes the process to get a
SIGBUS:

(gdb) set $gcspr = 0xbadc0ffee
(gdb) continue
Continuing.

Program received signal SIGBUS, Bus error.
normal_function0 () at /path/to/gdb/testsuite/gdb.arch/aarch64-gcs.c:121
121	  __asm__ volatile ("ret\n");

In the FVP emulator, the process gets a SIGSEGV instead, so that is what
my test expects:

(gdb) set $gcspr = 0xbadc0ffee
(gdb) continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
normal_function0 () at /path/to/gdb/testsuite/gdb.arch/aarch64-gcs.c:121
121	  __asm__ volatile ("ret\n");

I don't know whether this is a bug or just a different permissible
behaviour, in which case I can easily adjust my test to expect either
signal.

I'm using Linux v6.16.0-rc7.

-- 
Thiago
Re: [PATCH v2 00/85] target/arm: Implement FEAT_GCS
Posted by Richard Henderson 3 months ago
On 8/12/25 13:46, Thiago Jung Bauermann wrote:
> Most of the GDB tests pass. The only failure is in a test which sets the
> GCSPR in a process to a bogus value. This causes the process to get a
> SIGBUS:
> 
> (gdb) set $gcspr = 0xbadc0ffee
> (gdb) continue
> Continuing.
> 
> Program received signal SIGBUS, Bus error.
> normal_function0 () at /path/to/gdb/testsuite/gdb.arch/aarch64-gcs.c:121
> 121	  __asm__ volatile ("ret\n");
> 
> In the FVP emulator, the process gets a SIGSEGV instead, so that is what
> my test expects:
> 
> (gdb) set $gcspr = 0xbadc0ffee
> (gdb) continue
> Continuing.
> 
> Program received signal SIGSEGV, Segmentation fault.
> normal_function0 () at /path/to/gdb/testsuite/gdb.arch/aarch64-gcs.c:121
> 121	  __asm__ volatile ("ret\n");
> 
> I don't know whether this is a bug or just a different permissible
> behaviour, in which case I can easily adjust my test to expect either
> signal.

I may have forgotten to set the gcs bit in the iss2 field along the unaligned access path. 
  I'll see if I can verify this hypothesis.


r~
Re: [PATCH v2 00/85] target/arm: Implement FEAT_GCS
Posted by Richard Henderson 3 months ago
On 8/12/25 22:07, Richard Henderson wrote:
> On 8/12/25 13:46, Thiago Jung Bauermann wrote:
>> Most of the GDB tests pass. The only failure is in a test which sets the
>> GCSPR in a process to a bogus value. This causes the process to get a
>> SIGBUS:
>>
>> (gdb) set $gcspr = 0xbadc0ffee
>> (gdb) continue
>> Continuing.
>>
>> Program received signal SIGBUS, Bus error.
>> normal_function0 () at /path/to/gdb/testsuite/gdb.arch/aarch64-gcs.c:121
>> 121      __asm__ volatile ("ret\n");
>>
>> In the FVP emulator, the process gets a SIGSEGV instead, so that is what
>> my test expects:
>>
>> (gdb) set $gcspr = 0xbadc0ffee
>> (gdb) continue
>> Continuing.
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> normal_function0 () at /path/to/gdb/testsuite/gdb.arch/aarch64-gcs.c:121
>> 121      __asm__ volatile ("ret\n");
>>
>> I don't know whether this is a bug or just a different permissible
>> behaviour, in which case I can easily adjust my test to expect either
>> signal.
> 
> I may have forgotten to set the gcs bit in the iss2 field along the unaligned access path. 
>   I'll see if I can verify this hypothesis.

Thanks for the off-list test case.

I now see what the problem is: there is no such thing as an unaligned GCS access.  The 
pseudocode for GetCurrentGCSPointer() forces the low 3 bits to 0.

Thus your bad pointer 0xbadc0fee becomes 0xbadc0fe8, which then produces a SEGV 
referencing a bogus page.

I'll re-work the patch set to correct this.


r~