hw/char/pl011: add post_load hook for backwards-compatibility
Previous change slightly modified the way we handle data writes when FIFO is disabled. Previously we kept incrementing read_pos and were storing data at that position, although we only have a single-register-deep FIFO now. Then we changed it to always store data at pos 0. If guest disables FIFO and the proceeds to read data, it will work out fine, because we still read from current read_pos before setting it to 0. However, to make code less fragile, introduce a post_load hook for PL011State and move fixup read FIFO state when FIFO is disabled. Since we are introducing a post_load hook, also do some sanity checking on untrusted incoming input state. Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com> Message-id: 20230123162304.26254-3-eiakovlev@linux.microsoft.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
9d88935cb1
commit
13ea96fa34
@ -352,10 +352,35 @@ static const VMStateDescription vmstate_pl011_clock = {
|
||||
}
|
||||
};
|
||||
|
||||
static int pl011_post_load(void *opaque, int version_id)
|
||||
{
|
||||
PL011State* s = opaque;
|
||||
|
||||
/* Sanity-check input state */
|
||||
if (s->read_pos >= ARRAY_SIZE(s->read_fifo) ||
|
||||
s->read_count > ARRAY_SIZE(s->read_fifo)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!pl011_is_fifo_enabled(s) && s->read_count > 0 && s->read_pos > 0) {
|
||||
/*
|
||||
* Older versions of PL011 didn't ensure that the single
|
||||
* character in the FIFO in FIFO-disabled mode is in
|
||||
* element 0 of the array; convert to follow the current
|
||||
* code's assumptions.
|
||||
*/
|
||||
s->read_fifo[0] = s->read_fifo[s->read_pos];
|
||||
s->read_pos = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_pl011 = {
|
||||
.name = "pl011",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.post_load = pl011_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(readbuff, PL011State),
|
||||
VMSTATE_UINT32(flags, PL011State),
|
||||
|
Loading…
Reference in New Issue
Block a user