Skip to content

Commit 23d6a81

Browse files
committed
mchp: Remove undefined behavior in espi msvw handlers
The code in espi_msvw[12]_interrupt relies on undefined behavior today. __builtin_ctz is specified as returning values in the range [0, 31], but we are checking for 32. This behavior may be unexpected compared to the CTZ/CLZ instruction on ARM, which use the value 32 to indicate that there are no ones in the provided input. GCC 11+ optimizes the two loops below into infinite loops, as it can see that the condition will never be met. After this change, the disassembly of espi_mswv1_interrupt can be confirmed to contain an exit behind a branch. ... // r4 is loaded with girq24_result and has bits successively cleared 1a: b90c cbnz r4, 20 <espi_mswv1_interrupt+0x20> 1c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} 20: fa94 f5a4 rbit r5, r4 ... BUG=EmbeddedController#21 BRANCH=hx20-hx30 TEST=Examined the disassembly for espi_msvw[12]_interrupt; see above Signed-off-by: Dustin L. Howett <[email protected]>
1 parent 38c1b38 commit 23d6a81

File tree

1 file changed

+4
-6
lines changed

1 file changed

+4
-6
lines changed

chip/mchp/espi.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,13 +1238,12 @@ void espi_mswv1_interrupt(void)
12381238
girq24_result = MCHP_INT_RESULT(24);
12391239
MCHP_INT_SOURCE(24) = girq24_result;
12401240

1241-
bpos = __builtin_ctz(girq24_result); /* rbit, clz sequence */
1242-
while (bpos != 32) {
1241+
while (girq24_result) {
1242+
bpos = __builtin_ctz(girq24_result); /* rbit, clz sequence */
12431243
d = *(uint8_t *)(MCHP_ESPI_MSVW_BASE + 8 +
12441244
(12 * (bpos >> 2)) + (bpos & 0x03)) & 0x01;
12451245
(girq24_vw_handlers[bpos])(d, bpos);
12461246
girq24_result &= ~(1ul << bpos);
1247-
bpos = __builtin_ctz(girq24_result);
12481247
}
12491248
}
12501249
DECLARE_IRQ(MCHP_IRQ_GIRQ24, espi_mswv1_interrupt, 2);
@@ -1259,13 +1258,12 @@ void espi_msvw2_interrupt(void)
12591258
girq25_result = MCHP_INT_RESULT(25);
12601259
MCHP_INT_SOURCE(25) = girq25_result;
12611260

1262-
bpos = __builtin_ctz(girq25_result); /* rbit, clz sequence */
1263-
while (bpos != 32) {
1261+
while (girq25_result) {
1262+
bpos = __builtin_ctz(girq25_result); /* rbit, clz sequence */
12641263
d = *(uint8_t *)(MCHP_ESPI_MSVW_BASE + (12 * 7) + 8 +
12651264
(12 * (bpos >> 2)) + (bpos & 0x03)) & 0x01;
12661265
(girq25_vw_handlers[bpos])(d, bpos);
12671266
girq25_result &= ~(1ul << bpos);
1268-
bpos = __builtin_ctz(girq25_result);
12691267
}
12701268
}
12711269
DECLARE_IRQ(MCHP_IRQ_GIRQ25, espi_msvw2_interrupt, 2);

0 commit comments

Comments
 (0)