[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PULL v3 24/42] target/riscv: Implementation of enhanced PMP (ePMP)
From: |
Alistair Francis |
Subject: |
Re: [PULL v3 24/42] target/riscv: Implementation of enhanced PMP (ePMP) |
Date: |
Fri, 21 May 2021 08:38:47 +1000 |
On Thu, May 20, 2021 at 11:51 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Tue, 11 May 2021 at 11:21, Alistair Francis <alistair.francis@wdc.com>
> wrote:
> >
> > From: Hou Weiying <weiying_hou@outlook.com>
> >
> > This commit adds support for ePMP v0.9.1.
> >
> > The ePMP spec can be found in:
> > https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
> >
> > Signed-off-by: Hongzheng-Li <Ethan.Lee.QNL@gmail.com>
> > Signed-off-by: Hou Weiying <weiying_hou@outlook.com>
> > Signed-off-by: Myriad-Dreamin <camiyoru@gmail.com>
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> > Message-id:
> > fef23b885f9649a4d54e7c98b168bdec5d297bb1.1618812899.git.alistair.francis@wdc.com
> > [ Changes by AF:
> > - Rebase on master
> > - Update to latest spec
> > - Use a switch case to handle ePMP MML permissions
> > - Fix a few bugs
> > ]
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
>
> Hi; this code confuses Coverity into thinking that the pmp_hart_has_privs()
> function might read the value pointed to by 'allowed_privs' when
> it is uninitialized (CID 1453108):
>
>
> > @@ -294,13 +351,94 @@ bool pmp_hart_has_privs(CPURISCVState *env,
> > target_ulong addr,
> > pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
> >
> > /*
> > - * If the PMP entry is not off and the address is in range, do the
> > priv
> > - * check
> > + * Convert the PMP permissions to match the truth table in the
> > + * ePMP spec.
> > */
> > + const uint8_t epmp_operation =
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
> > + (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
>
> Here we construct a value which can only be in the range [0,15],
> but we do it in a way that Coverity isn't clever enough to figure out...
>
> > +
> > if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
> > - *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > - if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> > - *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> > + /*
> > + * If the PMP entry is not off and the address is in range,
> > + * do the priv check
> > + */
> > + if (!MSECCFG_MML_ISSET(env)) {
> > + /*
> > + * If mseccfg.MML Bit is not set, do pmp priv check
> > + * This will always apply to regular PMP.
> > + */
> > + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > + if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> > + *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> > + }
> > + } else {
> > + /*
> > + * If mseccfg.MML Bit set, do the enhanced pmp priv check
> > + */
> > + if (mode == PRV_M) {
> > + switch (epmp_operation) {
> > + case 0:
> > + case 1:
> > + case 4:
> > + case 5:
> > + case 6:
> > + case 7:
> > + case 8:
> > + *allowed_privs = 0;
> > + break;
> > + case 2:
> > + case 3:
> > + case 14:
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + break;
> > + case 9:
> > + case 10:
> > + *allowed_privs = PMP_EXEC;
> > + break;
> > + case 11:
> > + case 13:
> > + *allowed_privs = PMP_READ | PMP_EXEC;
> > + break;
> > + case 12:
> > + case 15:
> > + *allowed_privs = PMP_READ;
> > + break;
>
> ...so coverity thinks that "via the 'default' case" is a valid flow
> of control in these switch() statements...
>
> > + }
> > + } else {
> > + switch (epmp_operation) {
> > + case 0:
> > + case 8:
> > + case 9:
> > + case 12:
> > + case 13:
> > + case 14:
> > + *allowed_privs = 0;
> > + break;
> > + case 1:
> > + case 10:
> > + case 11:
> > + *allowed_privs = PMP_EXEC;
> > + break;
> > + case 2:
> > + case 4:
> > + case 15:
> > + *allowed_privs = PMP_READ;
> > + break;
> > + case 3:
> > + case 6:
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + break;
> > + case 5:
> > + *allowed_privs = PMP_READ | PMP_EXEC;
> > + break;
> > + case 7:
> > + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > + break;
> > + }
> > + }
> > }
> >
> > ret = ((privs & *allowed_privs) == privs);
>
> ...and that we can get to here without having ever set *allowed_privs.
>
>
> Adding
> default:
> g_assert_not_reached();
>
> to both switches should clarify to both Coverity and human readers that
> the cases in the switch are a complete enumeration of the possibilities.
Thanks Peter, I'll send a fix.
Alistair
>
> thanks
> -- PMM
- [PULL v3 16/42] hw/riscv: Enable VIRTIO_VGA for RISC-V virt machine, (continued)
- [PULL v3 16/42] hw/riscv: Enable VIRTIO_VGA for RISC-V virt machine, Alistair Francis, 2021/05/11
- [PULL v3 17/42] riscv: don't look at SUM when accessing memory from a debugger context, Alistair Francis, 2021/05/11
- [PULL v3 19/42] docs: Add documentation for shakti_c machine, Alistair Francis, 2021/05/11
- [PULL v3 18/42] target/riscv: Fixup saturate subtract function, Alistair Francis, 2021/05/11
- [PULL v3 20/42] target/riscv: Fix the PMP is locked check when using TOR, Alistair Francis, 2021/05/11
- [PULL v3 21/42] target/riscv: Define ePMP mseccfg, Alistair Francis, 2021/05/11
- [PULL v3 22/42] target/riscv: Add the ePMP feature, Alistair Francis, 2021/05/11
- [PULL v3 23/42] target/riscv: Add ePMP CSR access functions, Alistair Francis, 2021/05/11
- [PULL v3 24/42] target/riscv: Implementation of enhanced PMP (ePMP), Alistair Francis, 2021/05/11
- [PULL v3 25/42] target/riscv: Add a config option for ePMP, Alistair Francis, 2021/05/11
- [PULL v3 28/42] target/riscv: fix vrgather macro index variable type bug, Alistair Francis, 2021/05/11
- [PULL v3 27/42] target/riscv: Add ePMP support for the Ibex CPU, Alistair Francis, 2021/05/11
- [PULL v3 26/42] target/riscv/pmp: Remove outdated comment, Alistair Francis, 2021/05/11
- [PULL v3 30/42] hw/riscv: Fix OT IBEX reset vector, Alistair Francis, 2021/05/11
- [PULL v3 31/42] fpu/softfloat: set invalid excp flag for RISC-V muladd instructions, Alistair Francis, 2021/05/11
- [PULL v3 29/42] target/riscv: fix exception index on instruction access fault, Alistair Francis, 2021/05/11
- [PULL v3 32/42] target/riscv: fix a typo with interrupt names, Alistair Francis, 2021/05/11
- [PULL v3 34/42] target/riscv: Remove the hardcoded SSTATUS_SD macro, Alistair Francis, 2021/05/11
- [PULL v3 33/42] target/riscv: Remove the hardcoded RVXLEN macro, Alistair Francis, 2021/05/11