Fix DF-4883: implement the domain guard dc_fixpt_log's own TODO promises. sys/dev/drm/amd/display/dc/basics/fixpt31_32.c: dc_fixpt_log validates its argument only with ASSERT (a no-op in production builds, os_types.h:76). For arg <= 0 the Newton iteration diverges: for arg == 0 each step decrements res by exactly 1.0 fixpt (2^32 raw units), which can never satisfy the raw-unit exit test (abs(error) > 100), so res descends until dc_fixpt_exp(res) underflows to 0 and dc_fixpt_div(arg, 0) divides by zero (#DE panic via complete_integer_division_u64 - the DF-1949 sink); for arg < 0 divergence is immediate. Proof-of-behavior harness in this evidence pack (run.log: SIGFPE after ~21 iterations for log(0), ~2 for log(-1), while log(2) converges in 9). --- a/sys/dev/drm/amd/display/dc/basics/fixpt31_32.c +++ b/sys/dev/drm/amd/display/dc/basics/fixpt31_32.c @@ -382,9 +382,17 @@ struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg) struct fixed31_32 error; ASSERT(arg.value > 0); - /* TODO if arg is negative, return NaN */ - /* TODO if arg is zero, return -INF */ + /* + * ASSERTs are compiled out in production. For arg <= 0 the + * Newton iteration below diverges (for arg == 0 every step moves + * res by 1.0 fixpt, never satisfying the raw-unit exit test) until + * exp(res) underflows to 0 and the loop divides by zero (#DE). + * Implement the TODOs: saturate instead of hanging/panicking. + */ + if (arg.value <= 0) + /* TODO if arg is negative, return NaN */ + return (struct fixed31_32){ .value = LLONG_MIN }; /* -INF */ do { struct fixed31_32 res1 = dc_fixpt_add(