On 11/17/25 1:12 PM, Kees Cook wrote:
Implement RISC-V-specific KCFI backend. Nothing is conceptually rv64
specific, but using an alternative set of instructions for rv32 would be
needed, and at present the only user of KCFI on riscv is the rv64 build
of the Linux kernel.

- Scratch register allocation using t1/t2 (x6/x7) following RISC-V
   procedure call standard for temporary registers (already
   caller-saved), and t3 (x8) when either t1 or t2 is already the call
   target register.

- Incompatible with -ffixed-t1, -ffixed-t2, or -ffixed-t3.

- Integration with .kcfi_traps section for debugger/runtime metadata
   (like x86_64).

Assembly Code Pattern for RISC-V:
   lw      t1, -4(target_reg)         ; Load actual type ID from preamble
   lui     t2, %hi(expected_type)     ; Load expected type (upper 20 bits)
   addiw   t2, t2, %lo(expected_type) ; Add lower 12 bits (sign-extended)
   beq     t1, t2, .Lkcfi_call        ; Branch if types match
   .Lkcfi_trap: ebreak                ; Environment break trap on mismatch
   .Lkcfi_call: jalr/jr target_reg    ; Execute validated indirect transfer

Build and run tested with Linux kernel ARCH=riscv.

gcc/ChangeLog:

        config/riscv/riscv-protos.h: Declare KCFI helpers.
        config/riscv/riscv.cc (riscv_maybe_wrap_call_with_kcfi): New
        function, to wrap calls.
        (riscv_maybe_wrap_call_value_with_kcfi): New function, to
        wrap calls with return values.
        (riscv_output_kcfi_insn): New function to emit KCFI assembly.
        config/riscv/riscv.md: Add KCFI RTL patterns and hook expansion.
        doc/invoke.texi: Document riscv nuances.

gcc/testsuite/ChangeLog:

        * gcc.dg/kcfi/kcfi-adjacency.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-basics.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-call-sharing.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-complex-addressing.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-move-preservation.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-no-sanitize-inline.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-no-sanitize.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-offset-validation.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-patchable-entry-only.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-patchable-large.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-patchable-medium.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-patchable-prefix-only.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-tail-calls.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-trap-section.c: Add riscv patterns.
        * gcc.dg/kcfi/kcfi-riscv-fixed-t1.c: New test.
        * gcc.dg/kcfi/kcfi-riscv-fixed-t2.c: New test.
        * gcc.dg/kcfi/kcfi-riscv-fixed-t3.c: New test.
Note there's still review work to do on the RISC-V bits. But it's worth noting your patch triggers ICEs in the RISC-V testsuite. See:

https://github.com/ewlu/gcc-precommit-ci/issues/4115#issuecomment-3543758441

Jeff

Reply via email to