]>
Commit | Line | Data |
---|---|---|
a0402406 GKH |
1 | From f8324e20f8289dffc646d64366332e05eaacab25 Mon Sep 17 00:00:00 2001 |
2 | From: Mikael Pettersson <mikpe@it.uu.se> | |
3 | Date: Tue, 20 Jul 2010 18:45:14 -0700 | |
4 | Subject: math-emu: correct test for downshifting fraction in _FP_FROM_INT() | |
5 | ||
6 | From: Mikael Pettersson <mikpe@it.uu.se> | |
7 | ||
8 | commit f8324e20f8289dffc646d64366332e05eaacab25 upstream. | |
9 | ||
10 | The kernel's math-emu code contains a macro _FP_FROM_INT() which is | |
11 | used to convert an integer to a raw normalized floating-point value. | |
12 | It does this basically in three steps: | |
13 | ||
14 | 1. Compute the exponent from the number of leading zero bits. | |
15 | 2. Downshift large fractions to put the MSB in the right position | |
16 | for normalized fractions. | |
17 | 3. Upshift small fractions to put the MSB in the right position. | |
18 | ||
19 | There is an boundary error in step 2, causing a fraction with its | |
20 | MSB exactly one bit above the normalized MSB position to not be | |
21 | downshifted. This results in a non-normalized raw float, which when | |
22 | packed becomes a massively inaccurate representation for that input. | |
23 | ||
24 | The impact of this depends on a number of arch-specific factors, | |
25 | but it is known to have broken emulation of FXTOD instructions | |
26 | on UltraSPARC III, which was originally reported as GCC bug 44631 | |
27 | <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44631>. | |
28 | ||
29 | Any arch which uses math-emu to emulate conversions from integers to | |
30 | same-size floats may be affected. | |
31 | ||
32 | The fix is simple: the exponent comparison used to determine if the | |
33 | fraction should be downshifted must be "<=" not "<". | |
34 | ||
35 | I'm sending a kernel module to test this as a reply to this message. | |
36 | There are also SPARC user-space test cases in the GCC bug entry. | |
37 | ||
38 | Signed-off-by: Mikael Pettersson <mikpe@it.uu.se> | |
39 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
40 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
41 | ||
42 | --- | |
43 | include/math-emu/op-common.h | 2 +- | |
44 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
45 | ||
46 | --- a/include/math-emu/op-common.h | |
47 | +++ b/include/math-emu/op-common.h | |
48 | @@ -799,7 +799,7 @@ do { \ | |
49 | X##_e -= (_FP_W_TYPE_SIZE - rsize); \ | |
50 | X##_e = rsize - X##_e - 1; \ | |
51 | \ | |
52 | - if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \ | |
53 | + if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e) \ | |
54 | __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\ | |
55 | _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ | |
56 | if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0) \ |