// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2019, Gustavo Romero, Michael Neuling, IBM Corp. * * This test will spawn two processes. Both will be attached to the same * CPU (CPU 0). The child will be in a loop writing to FP register f31 and * VMX/VEC/Altivec register vr31 a known value, called poison, calling * sched_yield syscall after to allow the parent to switch on the CPU. * Parent will set f31 and vr31 to 1 and in a loop will check if f31 and * vr31 remain 1 as expected until a given timeout (2m). If the issue is * present child's poison will leak into parent's f31 or vr31 registers, * otherwise, poison will never leak into parent's f31 and vr31 registers.
*/
/** * parent
*/ asm ( /* * Set r3, r4, and f31 to known value 1 before entering * in transaction. They won't be written after that.
*/ " li 3, 0x1 ;" " li 4, 0x1 ;" " mtvsrd 31, 4 ;"
/* * The Time Base (TB) is a 64-bit counter register that is * independent of the CPU clock and which is incremented * at a frequency of 512000000 Hz, so every 1.953125ns. * So it's necessary 120s/0.000000001953125s = 61440000000 * increments to get a 2 minutes timeout. Below we set that * value in r5 and then use r6 to track initial TB value, * updating TB values in r7 at every iteration and comparing it * to r6. When r7 (current) - r6 (initial) > 61440000000 we bail * out since for sure we spent already 2 minutes in the loop. * SPR 268 is the TB register.
*/ " lis 5, 14 ;" " ori 5, 5, 19996 ;" " sldi 5, 5, 16 ;"// r5 = 61440000000
/* * On leak 'unknown' will contain 'poison' value from child, * otherwise (no leak) 'unknown' will contain the same value * as r3 before entering in transactional mode, i.e. 0x1.
*/
fail_fp = unknown != 0x1; if (fail_fp)
printf("Unknown value %#"PRIx64" leaked into f31!\n", unknown); else
printf("Good, no poison or leaked value into FP registers\n");
asm ( /* * Set r3, r4, and vr31 to known value 1 before entering * in transaction. They won't be written after that.
*/ " li 3, 0x1 ;" " li 4, 0x1 ;" " mtvsrd 63, 4 ;"
/* * On leak 'unknown' will contain 'poison' value from child, * otherwise (no leak) 'unknown' will contain the same value * as r3 before entering in transactional mode, i.e. 0x1.
*/
fail_vr = unknown != 0x1; if (fail_vr)
printf("Unknown value %#"PRIx64" leaked into vr31!\n", unknown); else
printf("Good, no poison or leaked value into VEC registers\n");
kill(pid, SIGKILL);
return (fail_fp | fail_vr);
}
int main(int argc, char *argv[])
{ /* Test completes in about 4m */
test_harness_set_timeout(250); return test_harness(tm_poison_test, "tm_poison_test");
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
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.