int riscv_v_setup_vsize(void)
{ unsignedlong this_vsize;
/* * There are 32 vector registers with vlenb length. * * If the thead,vlenb property was provided by the firmware, use that * instead of probing the CSRs.
*/ if (thead_vlenb_of) {
riscv_v_vsize = thead_vlenb_of * 32; return 0;
}
/* * All V-related instructions, including CSR operations are 4-Byte. So, * do not handle if the instruction length is not 4-Byte.
*/ if (unlikely(GET_INSN_LENGTH(insn_buf) != 4)) returnfalse;
switch (opcode) { case RVV_OPCODE_VECTOR: returntrue; case RVV_OPCODE_VL: case RVV_OPCODE_VS:
width = RVV_EXRACT_VL_VS_WIDTH(insn_buf); if (width == RVV_VL_VS_WIDTH_8 || width == RVV_VL_VS_WIDTH_16 ||
width == RVV_VL_VS_WIDTH_32 || width == RVV_VL_VS_WIDTH_64) returntrue;
if (!(has_vector() || has_xtheadvector())) returnfalse;
/* Do not handle if V is not supported, or disabled */ if (!riscv_v_vstate_ctrl_user_allowed()) returnfalse;
/* If V has been enabled then it is not the first-use trap */ if (riscv_v_vstate_query(regs)) returnfalse;
/* Get the instruction */ if (!insn) { if (__get_user(insn, epc)) returnfalse;
}
/* Filter out non-V instructions */ if (!insn_is_vector(insn)) returnfalse;
/* Sanity check. datap should be null by the time of the first-use trap */
WARN_ON(current->thread.vstate.datap);
/* * Now we sure that this is a V instruction. And it executes in the * context where VS has been off. So, try to allocate the user's V * context and resume execution.
*/ if (riscv_v_thread_zalloc(riscv_v_user_cachep, ¤t->thread.vstate)) {
force_sig(SIGBUS); returntrue;
}
riscv_v_vstate_on(regs);
riscv_v_vstate_set_restore(current, regs); returntrue;
}
void riscv_v_vstate_ctrl_init(struct task_struct *tsk)
{ bool inherit; int cur, next;
if (!(has_vector() || has_xtheadvector())) return;
next = riscv_v_ctrl_get_next(tsk); if (!next) { if (READ_ONCE(riscv_v_implicit_uacc))
cur = PR_RISCV_V_VSTATE_CTRL_ON; else
cur = PR_RISCV_V_VSTATE_CTRL_OFF;
} else {
cur = next;
} /* Clear next mask if inherit-bit is not set */
inherit = riscv_v_ctrl_test_inherit(tsk); if (!inherit)
next = PR_RISCV_V_VSTATE_CTRL_DEFAULT;
riscv_v_ctrl_set(tsk, cur, next, inherit);
}
long riscv_v_vstate_ctrl_get_current(void)
{ if (!(has_vector() || has_xtheadvector())) return -EINVAL;
long riscv_v_vstate_ctrl_set_current(unsignedlong arg)
{ bool inherit; int cur, next;
if (!(has_vector() || has_xtheadvector())) return -EINVAL;
if (arg & ~PR_RISCV_V_VSTATE_CTRL_MASK) return -EINVAL;
cur = VSTATE_CTRL_GET_CUR(arg); switch (cur) { case PR_RISCV_V_VSTATE_CTRL_OFF: /* Do not allow user to turn off V if current is not off */ if (riscv_v_ctrl_get_cur(current) != PR_RISCV_V_VSTATE_CTRL_OFF) return -EPERM;
break; case PR_RISCV_V_VSTATE_CTRL_ON: break; case PR_RISCV_V_VSTATE_CTRL_DEFAULT:
cur = riscv_v_ctrl_get_cur(current); break; default: return -EINVAL;
}
next = VSTATE_CTRL_GET_NEXT(arg);
inherit = VSTATE_CTRL_GET_INHERIT(arg); switch (next) { case PR_RISCV_V_VSTATE_CTRL_DEFAULT: case PR_RISCV_V_VSTATE_CTRL_OFF: case PR_RISCV_V_VSTATE_CTRL_ON:
riscv_v_ctrl_set(current, cur, next, inherit); return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.