1*1f9bb31eSNicholas Piggin // SPDX-License-Identifier: GPL-2.0-or-later 2*1f9bb31eSNicholas Piggin /* 3*1f9bb31eSNicholas Piggin * Copyright IBM Corp. 2020 4*1f9bb31eSNicholas Piggin * 5*1f9bb31eSNicholas Piggin * This test attempts to cause a FP denormal exception on POWER8 CPUs. Unfortunately 6*1f9bb31eSNicholas Piggin * if the denormal handler is not configured or working properly, this can cause a bad 7*1f9bb31eSNicholas Piggin * crash in kernel mode when the kernel tries to save FP registers when the process 8*1f9bb31eSNicholas Piggin * exits. 9*1f9bb31eSNicholas Piggin */ 10*1f9bb31eSNicholas Piggin 11*1f9bb31eSNicholas Piggin #include <stdio.h> 12*1f9bb31eSNicholas Piggin #include <string.h> 13*1f9bb31eSNicholas Piggin 14*1f9bb31eSNicholas Piggin #include "utils.h" 15*1f9bb31eSNicholas Piggin test_denormal_fpu(void)16*1f9bb31eSNicholas Pigginstatic int test_denormal_fpu(void) 17*1f9bb31eSNicholas Piggin { 18*1f9bb31eSNicholas Piggin unsigned int m32; 19*1f9bb31eSNicholas Piggin unsigned long m64; 20*1f9bb31eSNicholas Piggin volatile float f; 21*1f9bb31eSNicholas Piggin volatile double d; 22*1f9bb31eSNicholas Piggin 23*1f9bb31eSNicholas Piggin /* try to induce lfs <denormal> ; stfd */ 24*1f9bb31eSNicholas Piggin 25*1f9bb31eSNicholas Piggin m32 = 0x00715fcf; /* random denormal */ 26*1f9bb31eSNicholas Piggin memcpy((float *)&f, &m32, sizeof(f)); 27*1f9bb31eSNicholas Piggin d = f; 28*1f9bb31eSNicholas Piggin memcpy(&m64, (double *)&d, sizeof(d)); 29*1f9bb31eSNicholas Piggin 30*1f9bb31eSNicholas Piggin FAIL_IF((long)(m64 != 0x380c57f3c0000000)); /* renormalised value */ 31*1f9bb31eSNicholas Piggin 32*1f9bb31eSNicholas Piggin return 0; 33*1f9bb31eSNicholas Piggin } 34*1f9bb31eSNicholas Piggin main(int argc,char * argv[])35*1f9bb31eSNicholas Pigginint main(int argc, char *argv[]) 36*1f9bb31eSNicholas Piggin { 37*1f9bb31eSNicholas Piggin return test_harness(test_denormal_fpu, "fpu_denormal"); 38*1f9bb31eSNicholas Piggin } 39