Activity log for bug #1888918

Date Who What changed Old value New value Message
2020-07-25 02:33:47 Matthieu Bucchianeri bug added bug
2020-07-25 02:33:47 Matthieu Bucchianeri attachment added Linux userspace application to reproduce the issue https://bugs.launchpad.net/bugs/1888918/+attachment/5395638/+files/spe-bug.c
2020-07-25 02:43:39 Matthieu Bucchianeri attachment added SPE test module https://bugs.launchpad.net/qemu/+bug/1888918/+attachment/5395639/+files/spe-test.tar.gz
2020-07-25 02:47:49 Matthieu Bucchianeri attachment added Results on real hardware (MPC8548) https://bugs.launchpad.net/qemu/+bug/1888918/+attachment/5395640/+files/result_mpc8548.txt
2020-07-25 02:53:36 Matthieu Bucchianeri attachment added Results on QEMU https://bugs.launchpad.net/qemu/+bug/1888918/+attachment/5395641/+files/result_qemu_no_fix.txt
2020-07-25 03:01:17 Matthieu Bucchianeri qemu: assignee Matthieu Bucchianeri (matthieu-bucchianeri)
2020-07-25 04:15:07 Matthieu Bucchianeri summary qemu-ppc: Floating point instructions do not properly generate the SPE/Embedded Floating-Point Unavailable interrupt qemu-system-ppc: Floating point instructions do not properly generate the SPE/Embedded Floating-Point Unavailable interrupt
2020-07-25 04:16:28 Matthieu Bucchianeri description When emulating certain floating point instructions or vector instructions on PowerPC machines, QEMU does not properly generate the SPE/Embedded Floating-Point Unavailable interrupt. As described in the Signal Processing Engine (SPE) Programming Environments Manual, Rev. 0, available at https://www.nxp.com/docs/en/reference-manual/SPEPEM.pdf: > An SPE/embedded floating-point unavailable exception occurs on an attempt to execute any of the > following instructions and MSR[SPV] is not set: > * SPE instruction (except brinc) > * An embedded scalar double-precision instruction > * A vector single-precision floating-point instructions > It is not used by embedded scalar single-precision floating-point instructions This behavior was partially reported in Bug #1611394, however the issue is larger than what is described in that bug. As mentioned in that bug, some single-precision instructions generate the exception (while they should not), which is incorrect but does not typically produce an incorrect output. What is more of an issue is that several double-precision and vector instructions do not generate the exception (while they should), and this break support for lazy FPU/vector context switching in Linux (for example). The upper 32-bit of the double-precision/vector registers (which are in fact hidden in the general purpose registers) is not properly saved/restored, and this causes arithmetic errors. This was observed very frequently on a commercial project that does a lot of double-precision computations. The application works perfectly fine on an MPC8548 CPU, but fails often with QEMU. The issue can be reproduced using the attached Linux program "spe-bug.c". This program properly prints the number 42 (as the result of some very simple double-precision computation) on real PowerPC hardware, but prints an incorrect result (typically 0) on QEMU. This issue was first discovered in an older version of QEMU, but is also reproduced in the latest: # git rev-parse HEAD 7adfbea8fd1efce36019a0c2f198ca73be9d3f18 # ppc-softmmu/qemu-system-ppc --version QEMU emulator version 5.0.91 (v5.1.0-rc1-28-g7adfbea8fd-dirty) Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers Upon further analysis a total of 39 instructions are misbehaving: efsabs: raised: 1, expected: 0 efsnabs: raised: 1, expected: 0 efsneg: raised: 1, expected: 0 efdcfs: raised: 0, expected: 1 efdcfsf: raised: 0, expected: 1 efdcfsi: raised: 0, expected: 1 efdcfuf: raised: 0, expected: 1 efdcfui: raised: 0, expected: 1 efdctsf: raised: 0, expected: 1 efdctsi: raised: 0, expected: 1 efdctsiz: raised: 0, expected: 1 efdctuf: raised: 0, expected: 1 efdctui: raised: 0, expected: 1 efdctuiz: raised: 0, expected: 1 efscfd: raised: 0, expected: 1 evfscfsf: raised: 0, expected: 1 evfscfsi: raised: 0, expected: 1 evfscfuf: raised: 0, expected: 1 evfscfui: raised: 0, expected: 1 evfsctsf: raised: 0, expected: 1 evfsctsi: raised: 0, expected: 1 evfsctsiz: raised: 0, expected: 1 evfsctuf: raised: 0, expected: 1 evfsctui: raised: 0, expected: 1 evfsctuiz: raised: 0, expected: 1 brinc: raised: 0, expected: 1 efsadd: raised: 1, expected: 0 efsdiv: raised: 1, expected: 0 efsmul: raised: 1, expected: 0 efssub: raised: 1, expected: 0 evsplatfi: raised: 0, expected: 1 evsplati: raised: 0, expected: 1 efscmpeq: raised: 1, expected: 0 efscmpgt: raised: 1, expected: 0 efscmplt: raised: 1, expected: 0 efststeq: raised: 1, expected: 0 efststgt: raised: 1, expected: 0 efststlt: raised: 1, expected: 0 evsel: raised: 0, expected: 1 When "raised" is 0 and "expected" is 1, this means that the SPE/Embedded Floating-Point Unavailable interrupt was not generated while it should have. When "raised" is 1 and "expected" is 0, this means that the SPE/Embedded Floating-Point Unavailable interrupt was generated while it should not have (Bug #1611394). A comprehensive program testing all the instructions listed in the Signal Processing Engine (SPE) Programming Environments Manual, Rev. 0 is posted in the comments of this ticket, and can be used to reproduce the issue, and validate the future fix. When emulating certain floating point instructions or vector instructions on PowerPC machines, QEMU does not properly generate the SPE/Embedded Floating-Point Unavailable interrupt. As described in the Signal Processing Engine (SPE) Programming Environments Manual, Rev. 0, available at https://www.nxp.com/docs/en/reference-manual/SPEPEM.pdf: > An SPE/embedded floating-point unavailable exception occurs on an attempt to execute any of the > following instructions and MSR[SPV] is not set: > * SPE instruction (except brinc) > * An embedded scalar double-precision instruction > * A vector single-precision floating-point instructions > It is not used by embedded scalar single-precision floating-point instructions This behavior was partially reported in Bug #1611394, however the issue is larger than what is described in that bug. As mentioned in that bug, some single-precision instructions generate the exception (while they should not), which is incorrect but does not typically produce an incorrect output. What is more of an issue is that several double-precision and vector instructions do not generate the exception (while they should), and this breaks support for lazy FPU/vector context switching in Linux (for example). The upper 32-bit of the double-precision/vector registers (which are in fact hidden in the general purpose registers) is not properly saved/restored, and this causes arithmetic errors. This was observed very frequently on a commercial project that does a lot of double-precision computations. The application works perfectly fine on an MPC8548 CPU, but fails often with QEMU. This is only an issue with full platform emulation - the SPE/Embedded Floating-Point Unavailable interrupt is not relevant for application emulation. The issue can be reproduced using the attached Linux program "spe-bug.c". This program properly prints the number 42 (as the result of some very simple double-precision computation) on real PowerPC hardware, but prints an incorrect result (typically 0) on QEMU. This issue was first discovered in an older version of QEMU, but is also reproduced in the latest: # git rev-parse HEAD 7adfbea8fd1efce36019a0c2f198ca73be9d3f18 # ppc-softmmu/qemu-system-ppc --version QEMU emulator version 5.0.91 (v5.1.0-rc1-28-g7adfbea8fd-dirty) Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers Upon further analysis a total of 39 instructions are misbehaving: efsabs: raised: 1, expected: 0 efsnabs: raised: 1, expected: 0 efsneg: raised: 1, expected: 0 efdcfs: raised: 0, expected: 1 efdcfsf: raised: 0, expected: 1 efdcfsi: raised: 0, expected: 1 efdcfuf: raised: 0, expected: 1 efdcfui: raised: 0, expected: 1 efdctsf: raised: 0, expected: 1 efdctsi: raised: 0, expected: 1 efdctsiz: raised: 0, expected: 1 efdctuf: raised: 0, expected: 1 efdctui: raised: 0, expected: 1 efdctuiz: raised: 0, expected: 1 efscfd: raised: 0, expected: 1 evfscfsf: raised: 0, expected: 1 evfscfsi: raised: 0, expected: 1 evfscfuf: raised: 0, expected: 1 evfscfui: raised: 0, expected: 1 evfsctsf: raised: 0, expected: 1 evfsctsi: raised: 0, expected: 1 evfsctsiz: raised: 0, expected: 1 evfsctuf: raised: 0, expected: 1 evfsctui: raised: 0, expected: 1 evfsctuiz: raised: 0, expected: 1 brinc: raised: 0, expected: 1 efsadd: raised: 1, expected: 0 efsdiv: raised: 1, expected: 0 efsmul: raised: 1, expected: 0 efssub: raised: 1, expected: 0 evsplatfi: raised: 0, expected: 1 evsplati: raised: 0, expected: 1 efscmpeq: raised: 1, expected: 0 efscmpgt: raised: 1, expected: 0 efscmplt: raised: 1, expected: 0 efststeq: raised: 1, expected: 0 efststgt: raised: 1, expected: 0 efststlt: raised: 1, expected: 0 evsel: raised: 0, expected: 1 When "raised" is 0 and "expected" is 1, this means that the SPE/Embedded Floating-Point Unavailable interrupt was not generated while it should have. When "raised" is 1 and "expected" is 0, this means that the SPE/Embedded Floating-Point Unavailable interrupt was generated while it should not have (Bug #1611394). A comprehensive program testing all the instructions listed in the Signal Processing Engine (SPE) Programming Environments Manual, Rev. 0 is posted in the comments of this ticket, and can be used to reproduce the issue, and validate the future fix.
2020-07-25 19:26:41 Matthieu Bucchianeri attachment added Test results on QEMU with the fix https://bugs.launchpad.net/qemu/+bug/1888918/+attachment/5395780/+files/result_qemu_with_fix.txt
2020-07-25 19:41:30 Matthieu Bucchianeri qemu: status New In Progress
2020-11-04 22:54:45 John Snow qemu: status In Progress Fix Committed
2020-12-10 08:59:49 Thomas Huth qemu: status Fix Committed Fix Released