Vector Extension Support for RISC-V Linux

This document briefly outlines the interface provided to userspace by Linux inorder to support the use of the RISC-V Vector Extension.

1. prctl() Interface

Two newprctl() calls are added to allow programs to manage the enablementstatus for the use of Vector in userspace. The intended usage guideline forthese interfaces is to give init systems a way to modify the availability of Vfor processes running under its domain. Calling these interfaces is notrecommended in libraries routines because libraries should not override policiesconfigured from the parent process. Also, users must note that these interfacesare not portable to non-Linux, nor non-RISC-V environments, so it is discourageto use in a portable code. To get the availability of V in an ELF program,please readCOMPAT_HWCAP_ISA_V bit ofELF_HWCAP in theauxiliary vector.

  • prctl(PR_RISCV_V_SET_CONTROL, unsigned long arg)

    Sets the Vector enablement status of the calling thread, where the controlargument consists of two 2-bit enablement statuses and a bit for inheritancemode. Other threads of the calling process are unaffected.

    Enablement status is a tri-state value each occupying 2-bit of space inthe control argument:

    • PR_RISCV_V_VSTATE_CTRL_DEFAULT: Use the system-wide defaultenablement status on execve(). The system-wide default setting can becontrolled via sysctl interface (see sysctl section below).

    • PR_RISCV_V_VSTATE_CTRL_ON: Allow Vector to be run for thethread.

    • PR_RISCV_V_VSTATE_CTRL_OFF: Disallow Vector. Executing Vectorinstructions under such condition will trap and casuse the termination of the thread.

    arg: The control argument is a 5-bit value consisting of 3 parts, andaccessed by 3 masks respectively.

    The 3 masks, PR_RISCV_V_VSTATE_CTRL_CUR_MASK,PR_RISCV_V_VSTATE_CTRL_NEXT_MASK, and PR_RISCV_V_VSTATE_CTRL_INHERITrepresents bit[1:0], bit[3:2], and bit[4]. bit[1:0] accounts for theenablement status of current thread, and the setting at bit[3:2] takes placeat next execve(). bit[4] defines the inheritance mode of the setting inbit[3:2].

    • PR_RISCV_V_VSTATE_CTRL_CUR_MASK: bit[1:0]: Account for theVector enablement status for the calling thread. The calling thread isnot able to turn off Vector once it has been enabled. Theprctl() callfails with EPERM if the value in this mask is PR_RISCV_V_VSTATE_CTRL_OFFbut the current enablement status is not off. SettingPR_RISCV_V_VSTATE_CTRL_DEFAULT here takes no effect but to set backthe original enablement status.

    • PR_RISCV_V_VSTATE_CTRL_NEXT_MASK: bit[3:2]: Account for theVector enablement setting for the calling thread at the next execve()system call. If PR_RISCV_V_VSTATE_CTRL_DEFAULT is used in this mask,then the enablement status will be decided by the system-wideenablement status when execve() happen.

    • PR_RISCV_V_VSTATE_CTRL_INHERIT: bit[4]: the inheritancemode for the setting at PR_RISCV_V_VSTATE_CTRL_NEXT_MASK. If the bitis set then the following execve() will not clear the setting in bothPR_RISCV_V_VSTATE_CTRL_NEXT_MASK and PR_RISCV_V_VSTATE_CTRL_INHERIT.This setting persists across changes in the system-wide default value.

    Return value:
    • 0 on success;

    • EINVAL: Vector not supported, invalid enablement status for current ornext mask;

    • EPERM: Turning off Vector in PR_RISCV_V_VSTATE_CTRL_CUR_MASK if Vectorwas enabled for the calling thread.

    On success:
    • A valid setting for PR_RISCV_V_VSTATE_CTRL_CUR_MASK takes placeimmediately. The enablement status specified inPR_RISCV_V_VSTATE_CTRL_NEXT_MASK happens at the next execve() call, orall following execve() calls if PR_RISCV_V_VSTATE_CTRL_INHERIT bit isset.

    • Every successful call overwrites a previous setting for the callingthread.

  • prctl(PR_RISCV_V_GET_CONTROL)

    Gets the same Vector enablement status for the calling thread. Setting fornext execve() call and the inheritance bit are all OR-ed together.

    Note that ELF programs are able to get the availability of V for itself byreadingCOMPAT_HWCAP_ISA_V bit ofELF_HWCAP in theauxiliary vector.

    Return value:
    • a nonnegative value on success;

    • EINVAL: Vector not supported.

2. System runtime configuration (sysctl)

To mitigate the ABI impact of expansion of the signal stack, apolicy mechanism is provided to the administrators, distro maintainers, anddevelopers to control the default Vector enablement status for userspaceprocesses in form of sysctl knob:

  • /proc/sys/abi/riscv_v_default_allow

    Writing the text representation of 0 or 1 to this file sets the defaultsystem enablement status for new starting userspace programs. Valid valuesare:

    • 0: Do not allow Vector code to be executed as the default for new processes.

    • 1: Allow Vector code to be executed as the default for new processes.

    Reading this file returns the current system default enablement status.

    At every execve() call, a new enablement status of the new process is set tothe system default, unless:

    • PR_RISCV_V_VSTATE_CTRL_INHERIT is set for the calling process, and thesetting in PR_RISCV_V_VSTATE_CTRL_NEXT_MASK is notPR_RISCV_V_VSTATE_CTRL_DEFAULT. Or,

    • The setting in PR_RISCV_V_VSTATE_CTRL_NEXT_MASK is notPR_RISCV_V_VSTATE_CTRL_DEFAULT.

    Modifying the system default enablement status does not affect the enablementstatus of any existing process of thread that do not make an execve() call.

3. Vector Register State Across System Calls

As indicated by version 1.0 of the V extension [1], vector registers areclobbered by system calls.

1:https://github.com/riscv/riscv-v-spec/blob/master/calling-convention.adoc