From: Samaresh Kumar Singh Date: Sat, 28 Mar 2026 21:38:35 +0000 (-0500) Subject: test/chacha: added ELFv2 ABI FPR preservation check for POWER10 8x path X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=831f9b7f3831fe4b6629a5cfa539655fd8b66c8a;p=thirdparty%2Fopenssl.git test/chacha: added ELFv2 ABI FPR preservation check for POWER10 8x path On POWER10, ChaCha20_ctr32_vsx_8x is activated for buffers over 255 bytes and uses vxxlor to alias FPR14-FPR25 as temporary storage. Add a test to chacha_internal_test that pins known values in f14-f25 via inline asm, calls through ChaCha20_ctr32 with a 512-byte buffer to trigger the 8x path, and verifies the registers still hold their original values. The test is gated on PPC_BRD31 (POWER10 capability flag) so it is skipped silently on older hardware. Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale MergeDate: Sat Apr 11 20:06:05 2026 (Merged from https://github.com/openssl/openssl/pull/30587) --- diff --git a/test/chacha_internal_test.c b/test/chacha_internal_test.c index d316bfd7b3..5875f3ce59 100644 --- a/test/chacha_internal_test.c +++ b/test/chacha_internal_test.c @@ -16,6 +16,9 @@ #include #include "testutil.h" #include "crypto/chacha.h" +#if defined(__powerpc64__) && !defined(OPENSSL_SYS_AIX) && !defined(OPENSSL_SYS_MACOSX) +# include "crypto/ppc_arch.h" +#endif static const unsigned int key[] = { 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, @@ -179,6 +182,70 @@ static int test_cha_cha_internal(int n) return 1; } +#if defined(__powerpc64__) && !defined(OPENSSL_SYS_AIX) && !defined(OPENSSL_SYS_MACOSX) +/* + * Test that ChaCha20_ctr32_vsx_8x (the POWER10 8-block path, triggered for + * buffers > 255 bytes) preserves callee-saved FPRs f14-f25 as required by + * the ELFv2 ABI. The function uses vxxlor to spill VMX values into + * VSR0-VSR25, which aliases FPR0-FPR25; without explicit saves/restores + * the caller's floating-point state is silently corrupted. + */ +__attribute__((noinline)) +static int test_chacha20_p10_fpr_abi(void) +{ + /* + * Use a buffer larger than 255 bytes to ensure the 8x path is taken. + * The input content doesn't matter for this ABI test. + */ + static unsigned char in[512], out[512]; + int ok = 1; + + register double r14 asm("fr14"); + register double r15 asm("fr15"); + register double r16 asm("fr16"); + register double r17 asm("fr17"); + register double r18 asm("fr18"); + register double r19 asm("fr19"); + register double r20 asm("fr20"); + register double r21 asm("fr21"); + register double r22 asm("fr22"); + register double r23 asm("fr23"); + register double r24 asm("fr24"); + register double r25 asm("fr25"); + + r14 = 14.0; r15 = 15.0; r16 = 16.0; r17 = 17.0; + r18 = 18.0; r19 = 19.0; r20 = 20.0; r21 = 21.0; + r22 = 22.0; r23 = 23.0; r24 = 24.0; r25 = 25.0; + + /* Force the values into the actual FPR registers before the call */ + asm volatile("" : "+d"(r14), "+d"(r15), "+d"(r16), "+d"(r17)); + asm volatile("" : "+d"(r18), "+d"(r19), "+d"(r20), "+d"(r21)); + asm volatile("" : "+d"(r22), "+d"(r23), "+d"(r24), "+d"(r25)); + + ChaCha20_ctr32(out, in, sizeof(in), key, ivp); + + /* Read back from the FPR registers after the call */ + asm volatile("" : "+d"(r14), "+d"(r15), "+d"(r16), "+d"(r17)); + asm volatile("" : "+d"(r18), "+d"(r19), "+d"(r20), "+d"(r21)); + asm volatile("" : "+d"(r22), "+d"(r23), "+d"(r24), "+d"(r25)); + + ok &= TEST_double_eq(r14, 14.0); + ok &= TEST_double_eq(r15, 15.0); + ok &= TEST_double_eq(r16, 16.0); + ok &= TEST_double_eq(r17, 17.0); + ok &= TEST_double_eq(r18, 18.0); + ok &= TEST_double_eq(r19, 19.0); + ok &= TEST_double_eq(r20, 20.0); + ok &= TEST_double_eq(r21, 21.0); + ok &= TEST_double_eq(r22, 22.0); + ok &= TEST_double_eq(r23, 23.0); + ok &= TEST_double_eq(r24, 24.0); + ok &= TEST_double_eq(r25, 25.0); + + return ok; +} +#endif + int setup_tests(void) { #ifdef OPENSSL_CPUID_OBJ @@ -186,5 +253,10 @@ int setup_tests(void) #endif ADD_ALL_TESTS(test_cha_cha_internal, sizeof(ref)); +#if defined(__powerpc64__) && !defined(OPENSSL_SYS_AIX) && !defined(OPENSSL_SYS_MACOSX) + /* Only run the ABI test when the POWER10 8x path is available */ + if (OPENSSL_ppccap_P & PPC_BRD31) + ADD_TEST(test_chacha20_p10_fpr_abi); +#endif return 1; }