From 3fcb8c47c3ee83687d39e5f7087194132fada4b5 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 11 May 2022 09:27:20 +0000 Subject: [PATCH] More VRQ code. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15623 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/common/ports/ARMv7-M-ALT/chcore.h | 4 +- os/sb/host/sbvrq.c | 60 ++++++++++++++++++---------- os/sb/host/sbvrq.h | 2 +- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/os/common/ports/ARMv7-M-ALT/chcore.h b/os/common/ports/ARMv7-M-ALT/chcore.h index 42956424e..616fdaf41 100644 --- a/os/common/ports/ARMv7-M-ALT/chcore.h +++ b/os/common/ports/ARMv7-M-ALT/chcore.h @@ -723,7 +723,7 @@ struct port_context { * @param[in] tp pointer to the thread * @param[in] addr new address */ -#define __port_syscall_set_u_psp(tp, addr) (tp)->ctx.syscall.u_psp = (addr) +#define __port_syscall_set_u_psp(tp, addr) (tp)->ctx.syscall.u_psp = (uint32_t)(addr) /** * @brief Updates the stored system PSP address. @@ -731,7 +731,7 @@ struct port_context { * @param[in] tp pointer to the thread * @param[in] addr new address */ -#define __port_syscall_set_s_psp(tp, addr) (tp)->ctx.syscall.u_ssp = (addr) +#define __port_syscall_set_s_psp(tp, addr) (tp)->ctx.syscall.s_psp = (uint32_t)(addr) /** * @brief Returns the user PSP address. diff --git a/os/sb/host/sbvrq.c b/os/sb/host/sbvrq.c index 33031b739..1b81b3927 100644 --- a/os/sb/host/sbvrq.c +++ b/os/sb/host/sbvrq.c @@ -52,20 +52,29 @@ /*===========================================================================*/ __STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp, - struct port_extctx *ectxp, + struct port_extctx *newctxp, uint32_t active_mask) { uint32_t irqn = __CLZ(active_mask); sbp->vrq_wtmask &= ~(1U << irqn); /* Building the return context.*/ - ectxp->r0 = irqn; - ectxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */ - ectxp->xpsr = 0x01000000U; + newctxp->r0 = irqn; + newctxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */ + newctxp->xpsr = 0x01000000U; #if CORTEX_USE_FPU == TRUE - ectxp->fpscr = FPU->FPDSCR; + newctxp->fpscr = FPU->FPDSCR; #endif } +/** + * @brief Used as a known privileged address. + */ +static void vfq_privileged_code(void) { + + while (true) { + } +} + /*===========================================================================*/ /* Module exported functions. */ /*===========================================================================*/ @@ -77,14 +86,10 @@ __STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp, * * @param[in] sbp pointer to a @p sb_class_t structure * @param[in] vmask mask of VRQs to be activated - * @return The operation status. - * @retval false if the activation has succeeded. - * @retval true in case of sandbox stack overflow. * * @special */ -bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) { - struct port_extctx *ectxp; +void sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) { chSysLockFromISR(); @@ -96,47 +101,57 @@ bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) { sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask; if (active_mask != 0U) { + struct port_extctx *ectxp, *newctxp; /* This IRQ could have preempted the sandbox itself or some other thread, handling is different.*/ if (sbp->tp->state == CH_STATE_CURRENT) { /* Sandbox case, getting the current exception frame.*/ - ectxp = (struct port_extctx *)__get_PSP() - 1; + ectxp = (struct port_extctx *)__get_PSP(); + newctxp = ectxp - 1; /* Checking if the new frame is within the sandbox else failure.*/ if (!sb_is_valid_write_range(sbp, - (void *)ectxp, + (void *)newctxp, sizeof (struct port_extctx))) { + /* Making the sandbox return on a privileged address, this + will cause a fault and sandbox termination.*/ chSysUnlockFromISR(); - - return true; + ectxp->pc = (uint32_t)vfq_privileged_code; + return; } } else { - ectxp = sbp->tp->ctx.sp - 1; + /* Other thread case, getting the pointer from the context switch + structure.*/ + ectxp = sbp->tp->ctx.sp; + newctxp = ectxp - 1; /* Checking if the new frame is within the sandbox else failure.*/ if (!sb_is_valid_write_range(sbp, - (void *)ectxp, + (void *)newctxp, sizeof (struct port_extctx))) { + /* Making the sandbox return on a privileged address, this + will cause a fault and sandbox termination.*/ chSysUnlockFromISR(); - - return true; + ectxp->pc = (uint32_t)vfq_privileged_code; + return; } /* Preventing leakage of information, clearing all register values, those would come from outside the sandbox.*/ - memset((void *)ectxp, 0, sizeof (struct port_extctx)); + memset((void *)newctxp, 0, sizeof (struct port_extctx)); } /* Building the return context.*/ - vfq_makectx(sbp, ectxp, active_mask); + vfq_makectx(sbp, newctxp, active_mask); + __port_syscall_set_u_psp(sbp->tp, newctxp); } } chSysUnlockFromISR(); - return false; + return; } void sb_vrq_disable(struct port_extctx *ectxp) { @@ -169,6 +184,7 @@ void sb_vrq_enable(struct port_extctx *ectxp) { /* Building the return context.*/ vfq_makectx(sbp, ectxp, active_mask); + __port_syscall_set_u_psp(sbp->tp, ectxp); } } } @@ -202,6 +218,8 @@ void sb_vrq_return(struct port_extctx *ectxp) { /* Discarding the return current context, returning on the previous one.*/ ectxp++; } + + __port_syscall_set_u_psp(sbp->tp, ectxp); } #endif /* SB_CFG_ENABLE_VRQ == TRUE */ diff --git a/os/sb/host/sbvrq.h b/os/sb/host/sbvrq.h index 2d4d6d16d..e5a641964 100644 --- a/os/sb/host/sbvrq.h +++ b/os/sb/host/sbvrq.h @@ -65,7 +65,7 @@ #ifdef __cplusplus extern "C" { #endif - bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask); + void sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask); void sb_vrq_disable(struct port_extctx *ectxp); void sb_vrq_enable(struct port_extctx *ectxp); void sb_vrq_getisr(struct port_extctx *ectxp);