dm: vRTC: fix a bug that waag can't update RTC

Through it is best to halt the RTC before changing date/time, still some
OSes just write date/time while RTC is not halted. Currently the DM vRTC
has already dealt the situation where openBSD writes century byte out
side of vRTC halt by updating vRTC time on century byte writes.

Now WaaG is found writing all date/time regs outside of vRTC halt.
Because those date/time writes are not updated instantly, WaaG’s vRTC
time is not actually changed.

This bug has not affected anything till now when we are adding support
to RTC change vm_event.

To make WaaG’s vRTC work properly, this patch adds vRTC time update on
all date/time writes outside of vRTC halt.

Tracked-On: #8547
Signed-off-by: Wu Zhou <wu.zhou@intel.com>
Reviewed-by: Jian Jun Chen <jian.jun.chen@intel.com>
This commit is contained in:
Wu Zhou 2023-08-08 16:47:21 +08:00 committed by acrnsi-robot
parent 9530207970
commit 85e5dc788d

View File

@ -882,6 +882,12 @@ vrtc_addr_handler(struct vmctx *ctx, int vcpu, int in, int port,
return 0;
}
static inline bool vrtc_is_time_register(uint32_t offset)
{
return ((offset == RTC_SEC) || (offset == RTC_MIN) || (offset == RTC_HRS) || (offset == RTC_DAY)
|| (offset == RTC_MONTH) || (offset == RTC_YEAR) || (offset == RTC_CENTURY));
}
int
vrtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port,
int bytes, uint32_t *eax, void *arg)
@ -960,10 +966,11 @@ vrtc_data_handler(struct vmctx *ctx, int vcpu, int in, int port,
}
/*
* XXX some guests (e.g. OpenBSD) write the century byte
* outside of RTCSB_HALT so re-calculate the RTC date/time.
* Some guests (e.g. OpenBSD) write the century byte outside of RTCSB_HALT,
* and some guests (e.g. WaaG) write all date/time outside of RTCSB_HALT,
* so re-calculate the RTC date/time.
*/
if (offset == RTC_CENTURY && !rtc_halted(vrtc)) {
if (vrtc_is_time_register(offset) && !rtc_halted(vrtc)) {
curtime = rtc_to_secs(vrtc);
error = vrtc_time_update(vrtc, curtime, time(NULL));
if ((error != 0) || (curtime == VRTC_BROKEN_TIME && rtc_flag_broken_time))