x86 Floating point exceptions - incorrect support?
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Expired
|
Undecided
|
Unassigned |
Bug Description
It seems that qemu does not correctly emulate the x86 support for optionally causing a floating-point exception (#FP) when, for example, dividing by zero. Reports such as:
https:/
http://
suggest that setting the exception mask in the fpu cw or mxcsr (e.g., using a function like feenableexcept() in the guest OS) does not generate floating point exceptions on divide by zero. The problem only happens on pure QEMU - when a QEMU/KVM combination is used, the actual hardware does the floating point work, and does throw the exception on divide by zero if so requested.
Looking at the qemu (2.8.0) source code, it seems to me it really lacks support for generating fpu exceptions: For example, helper_fdiv() in target-
Hi,
This problem still exists on QEMU 5.0.0 both for i386 and x86_64;
floating-point zero division is not trapped at all, while integer
one is trapped correctly.
This seriously affects NetBSD project, which carries out periodic
regression tests on QEMU:
https:/ /releng. netbsd. org/test- results. html
Tests including floating-point zero division are falling on QEMU,
while they are successfully passing on real hardwares.
HOW TO REPEAT:
Compile and run this program on Unix like operating systems:
---
#include <fenv.h>
#include <stdlib.h>
#include <unistd.h>
int
main(void)
{
volatile double a = getpid();
volatile double b = atoi("0");
return 0;
}
---
It crashes by SIGFPE on real hardware, but normally exits on QEMU.
I ran this program on NetBSD 9.0 for x86_64 and i386 on QEMU 5.0.0:
(1) Obtain NetBSD 9.0 release from here:
For x86_64: cdn.netbsd. org/pub/ NetBSD/ NetBSD- 9.0/images/ NetBSD- 9.0-amd64. iso
http://
For i386: cdn.netbsd. org/pub/ NetBSD/ NetBSD- 9.0/images/ NetBSD- 9.0-i386. iso
http://
(2) Install it for disk image.
(3) qemu-system-x86_64 NetBSD.qcow2 or qemu-system-i386 NetBSD.qcow2
(4) Compile and run the test program above:
# cc fpe.c -lm -o fpe
# ./fpe
(5) Then, it exits normally, while it should abort due to SIGFPE.