RISC-V Linux 向量擴充套件支援

本文件簡要概述了 Linux 提供給使用者空間的介面,以便支援 RISC-V 向量擴充套件的使用。

1. prctl() 介面

添加了兩個新的 prctl() 呼叫,以允許程式管理使用者空間中向量使用的啟用狀態。 這些介面的預期使用指南是為 init 系統提供一種修改在其域下執行的程序的 V 可用性的方法。 不建議在庫例程中呼叫這些介面,因為庫不應覆蓋從父程序配置的策略。 此外,使用者必須注意這些介面不可移植到非 Linux 或非 RISC-V 環境,因此不鼓勵在可移植程式碼中使用。 要獲取 ELF 程式中 V 的可用性,請讀取輔助向量中 COMPAT_HWCAP_ISA_VELF_HWCAP 位。

  • prctl(PR_RISCV_V_SET_CONTROL, unsigned long arg)

    設定呼叫執行緒的向量啟用狀態,其中 control 引數由兩個 2 位啟用狀態和一個用於繼承模式的位組成。 呼叫程序的其他執行緒不受影響。

    啟用狀態是一個三態值,每個值在 control 引數中佔據 2 位空間

    • PR_RISCV_V_VSTATE_CTRL_DEFAULT: 在 execve() 上使用系統範圍的預設啟用狀態。 系統範圍的預設設定可以透過 sysctl 介面進行控制(請參閱下面的 sysctl 部分)。

    • PR_RISCV_V_VSTATE_CTRL_ON: 允許執行緒執行向量。

    • PR_RISCV_V_VSTATE_CTRL_OFF: 禁止向量。 在這種情況下執行向量指令將陷入並導致執行緒終止。

    arg:control 引數是一個 5 位值,由 3 部分組成,分別由 3 個掩碼訪問。

    這3個掩碼,PR_RISCV_V_VSTATE_CTRL_CUR_MASK、PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 和 PR_RISCV_V_VSTATE_CTRL_INHERIT 分別代表 bit[1:0]、bit[3:2] 和 bit[4]。 bit[1:0] 表示當前執行緒的啟用狀態,bit[3:2] 中的設定在下一次 execve() 時生效。 bit[4] 定義了 bit[3:2] 中設定的繼承模式。

    • PR_RISCV_V_VSTATE_CTRL_CUR_MASK: bit[1:0]:表示呼叫執行緒的向量啟用狀態。 一旦啟用向量,呼叫執行緒就無法關閉向量。 如果此掩碼中的值為 PR_RISCV_V_VSTATE_CTRL_OFF 但當前啟用狀態未關閉,則 prctl() 呼叫將失敗並返回 EPERM。 在此處設定 PR_RISCV_V_VSTATE_CTRL_DEFAULT 不起作用,只會設定回原始啟用狀態。

    • PR_RISCV_V_VSTATE_CTRL_NEXT_MASK: bit[3:2]:表示下一次 execve() 系統呼叫時呼叫執行緒的向量啟用設定。 如果此掩碼中使用 PR_RISCV_V_VSTATE_CTRL_DEFAULT,則啟用狀態將在 execve() 發生時由系統範圍的啟用狀態決定。

    • PR_RISCV_V_VSTATE_CTRL_INHERIT: bit[4]:PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 中設定的繼承模式。 如果設定了該位,則後續的 execve() 將不會清除 PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 和 PR_RISCV_V_VSTATE_CTRL_INHERIT 中的設定。 此設定在系統範圍的預設值發生更改時仍然有效。

    返回值
    • 成功時返回 0;

    • EINVAL:不支援向量,當前或下一個掩碼的啟用狀態無效;

    • EPERM:如果為呼叫執行緒啟用了向量,則在 PR_RISCV_V_VSTATE_CTRL_CUR_MASK 中關閉向量。

    成功時
    • PR_RISCV_V_VSTATE_CTRL_CUR_MASK 的有效設定會立即生效。 PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 中指定的啟用狀態會在下一次 execve() 呼叫時生效,如果設定了 PR_RISCV_V_VSTATE_CTRL_INHERIT 位,則會在所有後續的 execve() 呼叫中生效。

    • 每次成功呼叫都會覆蓋呼叫執行緒的先前設定。

  • prctl(PR_RISCV_V_GET_CONTROL)

    獲取呼叫執行緒的相同向量啟用狀態。 下一次 execve() 呼叫的設定和繼承位都進行 OR 運算。

    請注意,ELF 程式可以透過讀取輔助向量中 COMPAT_HWCAP_ISA_VELF_HWCAP 位來獲取 V 對自身的可用性。

    返回值
    • 成功時返回一個非負值;

    • EINVAL:不支援向量。

2. 系統執行時配置 (sysctl)

為了減輕訊號堆疊擴充套件對 ABI 的影響,我們向管理員、發行版維護者和開發人員提供了一種策略機制,用於以 sysctl knob 的形式控制使用者空間程序的預設向量啟用狀態

  • /proc/sys/abi/riscv_v_default_allow

    將 0 或 1 的文字表示形式寫入此檔案可為新的啟動使用者空間程式設定預設系統啟用狀態。 有效值為

    • 0:不允許將向量程式碼作為新程序的預設值執行。

    • 1:允許將向量程式碼作為新程序的預設值執行。

    讀取此檔案會返回當前的系統預設啟用狀態。

    在每次 execve() 呼叫時,新程序的新啟用狀態都設定為系統預設值,除非

    • 為呼叫程序設定了 PR_RISCV_V_VSTATE_CTRL_INHERIT,並且 PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 中的設定不是 PR_RISCV_V_VSTATE_CTRL_DEFAULT。 或者,

    • PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 中的設定不是 PR_RISCV_V_VSTATE_CTRL_DEFAULT。

    修改系統預設啟用狀態不會影響任何不進行 execve() 呼叫的現有程序或執行緒的啟用狀態。

3. 跨系統呼叫的向量暫存器狀態

正如 V 擴充套件 1.0 版 [1] 所指示的那樣,向量暫存器會被系統呼叫破壞。

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