More VRQ code.
@@ -723,7 +723,7 @@ | ||
723 | 723 | * @param[in] tp pointer to the thread |
724 | 724 | * @param[in] addr new address |
725 | 725 | */ |
726 | -#define __port_syscall_set_u_psp(tp, addr) (tp)->ctx.syscall.u_psp = (addr) | |
726 | +#define __port_syscall_set_u_psp(tp, addr) (tp)->ctx.syscall.u_psp = (uint32_t)(addr) | |
727 | 727 | |
728 | 728 | /** |
729 | 729 | * @brief Updates the stored system PSP address. |
@@ -731,7 +731,7 @@ | ||
731 | 731 | * @param[in] tp pointer to the thread |
732 | 732 | * @param[in] addr new address |
733 | 733 | */ |
734 | -#define __port_syscall_set_s_psp(tp, addr) (tp)->ctx.syscall.u_ssp = (addr) | |
734 | +#define __port_syscall_set_s_psp(tp, addr) (tp)->ctx.syscall.s_psp = (uint32_t)(addr) | |
735 | 735 | |
736 | 736 | /** |
737 | 737 | * @brief Returns the user PSP address. |
@@ -52,20 +52,29 @@ | ||
52 | 52 | /*===========================================================================*/ |
53 | 53 | |
54 | 54 | __STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp, |
55 | - struct port_extctx *ectxp, | |
55 | + struct port_extctx *newctxp, | |
56 | 56 | uint32_t active_mask) { |
57 | 57 | uint32_t irqn = __CLZ(active_mask); |
58 | 58 | sbp->vrq_wtmask &= ~(1U << irqn); |
59 | 59 | |
60 | 60 | /* Building the return context.*/ |
61 | - ectxp->r0 = irqn; | |
62 | - ectxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */ | |
63 | - ectxp->xpsr = 0x01000000U; | |
61 | + newctxp->r0 = irqn; | |
62 | + newctxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */ | |
63 | + newctxp->xpsr = 0x01000000U; | |
64 | 64 | #if CORTEX_USE_FPU == TRUE |
65 | - ectxp->fpscr = FPU->FPDSCR; | |
65 | + newctxp->fpscr = FPU->FPDSCR; | |
66 | 66 | #endif |
67 | 67 | } |
68 | 68 | |
69 | +/** | |
70 | + * @brief Used as a known privileged address. | |
71 | + */ | |
72 | +static void vfq_privileged_code(void) { | |
73 | + | |
74 | + while (true) { | |
75 | + } | |
76 | +} | |
77 | + | |
69 | 78 | /*===========================================================================*/ |
70 | 79 | /* Module exported functions. */ |
71 | 80 | /*===========================================================================*/ |
@@ -77,14 +86,10 @@ | ||
77 | 86 | * |
78 | 87 | * @param[in] sbp pointer to a @p sb_class_t structure |
79 | 88 | * @param[in] vmask mask of VRQs to be activated |
80 | - * @return The operation status. | |
81 | - * @retval false if the activation has succeeded. | |
82 | - * @retval true in case of sandbox stack overflow. | |
83 | 89 | * |
84 | 90 | * @special |
85 | 91 | */ |
86 | -bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) { | |
87 | - struct port_extctx *ectxp; | |
92 | +void sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) { | |
88 | 93 | |
89 | 94 | chSysLockFromISR(); |
90 | 95 |
@@ -96,47 +101,57 @@ | ||
96 | 101 | sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask; |
97 | 102 | |
98 | 103 | if (active_mask != 0U) { |
104 | + struct port_extctx *ectxp, *newctxp; | |
99 | 105 | |
100 | 106 | /* This IRQ could have preempted the sandbox itself or some other thread, |
101 | 107 | handling is different.*/ |
102 | 108 | if (sbp->tp->state == CH_STATE_CURRENT) { |
103 | 109 | /* Sandbox case, getting the current exception frame.*/ |
104 | - ectxp = (struct port_extctx *)__get_PSP() - 1; | |
110 | + ectxp = (struct port_extctx *)__get_PSP(); | |
111 | + newctxp = ectxp - 1; | |
105 | 112 | |
106 | 113 | /* Checking if the new frame is within the sandbox else failure.*/ |
107 | 114 | if (!sb_is_valid_write_range(sbp, |
108 | - (void *)ectxp, | |
115 | + (void *)newctxp, | |
109 | 116 | sizeof (struct port_extctx))) { |
117 | + /* Making the sandbox return on a privileged address, this | |
118 | + will cause a fault and sandbox termination.*/ | |
110 | 119 | chSysUnlockFromISR(); |
111 | - | |
112 | - return true; | |
120 | + ectxp->pc = (uint32_t)vfq_privileged_code; | |
121 | + return; | |
113 | 122 | } |
114 | 123 | } |
115 | 124 | else { |
116 | - ectxp = sbp->tp->ctx.sp - 1; | |
125 | + /* Other thread case, getting the pointer from the context switch | |
126 | + structure.*/ | |
127 | + ectxp = sbp->tp->ctx.sp; | |
128 | + newctxp = ectxp - 1; | |
117 | 129 | |
118 | 130 | /* Checking if the new frame is within the sandbox else failure.*/ |
119 | 131 | if (!sb_is_valid_write_range(sbp, |
120 | - (void *)ectxp, | |
132 | + (void *)newctxp, | |
121 | 133 | sizeof (struct port_extctx))) { |
134 | + /* Making the sandbox return on a privileged address, this | |
135 | + will cause a fault and sandbox termination.*/ | |
122 | 136 | chSysUnlockFromISR(); |
123 | - | |
124 | - return true; | |
137 | + ectxp->pc = (uint32_t)vfq_privileged_code; | |
138 | + return; | |
125 | 139 | } |
126 | 140 | |
127 | 141 | /* Preventing leakage of information, clearing all register values, those |
128 | 142 | would come from outside the sandbox.*/ |
129 | - memset((void *)ectxp, 0, sizeof (struct port_extctx)); | |
143 | + memset((void *)newctxp, 0, sizeof (struct port_extctx)); | |
130 | 144 | } |
131 | 145 | |
132 | 146 | /* Building the return context.*/ |
133 | - vfq_makectx(sbp, ectxp, active_mask); | |
147 | + vfq_makectx(sbp, newctxp, active_mask); | |
148 | + __port_syscall_set_u_psp(sbp->tp, newctxp); | |
134 | 149 | } |
135 | 150 | } |
136 | 151 | |
137 | 152 | chSysUnlockFromISR(); |
138 | 153 | |
139 | - return false; | |
154 | + return; | |
140 | 155 | } |
141 | 156 | |
142 | 157 | void sb_vrq_disable(struct port_extctx *ectxp) { |
@@ -169,6 +184,7 @@ | ||
169 | 184 | |
170 | 185 | /* Building the return context.*/ |
171 | 186 | vfq_makectx(sbp, ectxp, active_mask); |
187 | + __port_syscall_set_u_psp(sbp->tp, ectxp); | |
172 | 188 | } |
173 | 189 | } |
174 | 190 | } |
@@ -202,6 +218,8 @@ | ||
202 | 218 | /* Discarding the return current context, returning on the previous one.*/ |
203 | 219 | ectxp++; |
204 | 220 | } |
221 | + | |
222 | + __port_syscall_set_u_psp(sbp->tp, ectxp); | |
205 | 223 | } |
206 | 224 | |
207 | 225 | #endif /* SB_CFG_ENABLE_VRQ == TRUE */ |
@@ -65,7 +65,7 @@ | ||
65 | 65 | #ifdef __cplusplus |
66 | 66 | extern "C" { |
67 | 67 | #endif |
68 | - bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask); | |
68 | + void sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask); | |
69 | 69 | void sb_vrq_disable(struct port_extctx *ectxp); |
70 | 70 | void sb_vrq_enable(struct port_extctx *ectxp); |
71 | 71 | void sb_vrq_getisr(struct port_extctx *ectxp); |