Skip to content

Commit

Permalink
target/ppc: Fix decrementer time underflow and infinite timer loop
Browse files Browse the repository at this point in the history
It is possible to store a very large value to the decrementer that it
does not raise the decrementer exception so the timer is scheduled, but
the next time value wraps and is treated as in the past.

This can occur if (u64)-1 is stored on a zero-triggered exception, or
(u64)-1 is stored twice on an underflow-triggered exception, for
example.

If such a value is set in DECAR, it gets stored to the decrementer by
the timer function, which then immediately causes another timer, which
hangs QEMU.

Clamp the decrementer to the implemented width, and use that as the
value for the timer calculation, effectively preventing this overflow.

Reported-by: sdicaro@DDCI.com
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Message-Id: <20230530131214.373524-1-npiggin@gmail.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
(cherry picked from commit 09d2db9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
  • Loading branch information
npiggin authored and Michael Tokarev committed Jun 30, 2023
1 parent 78c4994 commit 4d8459c
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions hw/ppc/ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
int64_t signed_decr;

/* Truncate value to decr_width and sign extend for simplicity */
value = extract64(value, 0, nr_bits);
decr = extract64(decr, 0, nr_bits);
signed_value = sextract64(value, 0, nr_bits);
signed_decr = sextract64(decr, 0, nr_bits);

Expand Down

0 comments on commit 4d8459c

Please sign in to comment.