On Tue, Mar 03, 2026 at 10:25:11AM +0100, Igor Mammedov wrote:
> Changelog:
> v2:
> * ditch generic '-machine acpi-watchdog' option in favor of
> board specific variants:
> x86/q35: -machine wdat={on|off}
> arm/virt: -device sbsa_gwdt,wdat={on|off}
> * arm/virt: add FDT and GTDT ACPI entries for GWDT when it's present
> and hide GDTD one when WDAT is enabled.
> * arm/virt: add test case for GTDT
> * [18-21] optional GWDT cleanup/fixes in handling WCV register update,
> make QEMU behave according to spec (at least the way I read it and
> it appears MS also read it that way). It fixes Windows 11 reboots when
> GWDT is present (without WDAT). With that fixed it's up to MS to fix
> their driver to set sane timeout as with the current one wdatchdog
> will never trigger.
I picked the x86 patches for now.
> Windows doesn't ship built-in TCO watchdog driver, and users are
> forced to install vendor specific driver(s) if such exists.
> However the OS provides a generic watchdog driver that uses
> ACPI WDAT table [1] to abstract actual hardware behind it.
> The same applies to ARM version of Windows.
>
> This series adds
> * WDAT table tailored for TCO watchdog that Q35 already
> has as part of ICH9 chipset and a knob to enable it.
> * SBSA GWDT to arm/virt machine with WDAT table tailored
> for it and necessary tweaks to GWDT to make usable
> with WDAT driver.
> * in addition to WDAT, it also adds native variant
> with GWDT described in FDT and DTDT
> (broken on Windows/works on linux).
>
> Guest OS WDAT support is present since Windows Vista and Linux since 2016[2].
>
> One can test it launching VM with following options:
> * x86:
> -machine q35,wdat=on
> * arm/virt:
> -device sbsa_gwdt,wdat=on
>
> to trace access to TCO registers one can add to CLI:
> -trace "tco_*"
> to trace access to GWDT registers one can add to CLI:
> -trace "sbsa_gwdt*"
>
> To verify that guest uses WDAT (both Windows and Linux would use it if
> present),
> * on linux make sure that watchdog service is configured/enabled
> (use wdctl to check what watchdog device is in use) and then
> trigger kernel panic with command:
> echo c > /proc/sysrq-trigger
> * on Windows kill svchost process, running cmd in admin mode:
> taskkill /f /im svchost.exe
>
> Tested with WS2025 & RHEL9.6 & Fedora 43 (aarch64)
>
> git tree at: https://gitlab.com/imammedo/qemu/-/commits/gwdt_v2
>
> 1) http://msdn.microsoft.com/en-us/windows/hardware/gg463320.aspx
> 2) https://lwn.net/Articles/700524/
>
> PS:
> previous revision:
> https://patchew.org/QEMU/[email protected]/
>
> Igor Mammedov (21):
> acpi: add API to build WDAT instructions
> x86: q35: add 'wdat' property
> x86: q35: generate WDAT ACPI table
> tests: acpi: x86/q35: whitelist new WDAT table
> tests: acpi: x86/q35: add WDAT table test case
> tests: acpi: x86/q35: update expected WDAT blob
> arm: sbsa_gwdt: fixup default "clock-frequency"
> arm: add tracing events to sbsa_gwdt
> arm: virt: create sbsa_gwdt watchdog
> arm: sbsa_gwdt: add 'wdat' option
> arm: virt: add support for WDAT based watchdog
> tests: acpi: arm/virt: whitelist new WDAT table
> tests: acpi: arm/virt: add WDAT table test case
> tests: acpi: arm/virt: update expected WDAT blob
> tests: acpi: arm/virt: whitelist GTDT table
> tests: acpi: arm/virt: add GTDT watchdog table test case
> tests: acpi: arm/virt: update expected GTDT blob
> sbsa_gwdt: reduce code ident
> sbsa_gwdt: move all foo_REFRESH logic under REFRESH condition
> sbsa_gwdt: reschedule timer on direct WCV load
> sbsa_gwdt: limit compare_value to INT64_MAX
>
> include/hw/acpi/wdat-gwdt.h | 19 ++++
> include/hw/acpi/wdat-ich9.h | 15 ++++
> include/hw/acpi/wdat.h | 118 +++++++++++++++++++++++++
> include/hw/i386/pc.h | 1 +
> include/hw/watchdog/sbsa_gwdt.h | 1 +
> hw/acpi/aml-build.c | 14 +++
> hw/acpi/meson.build | 5 +-
> hw/acpi/wdat-gwdt-stub.c | 16 ++++
> hw/acpi/wdat-gwdt.c | 92 +++++++++++++++++++
> hw/acpi/wdat-ich9-stub.c | 15 ++++
> hw/acpi/wdat-ich9.c | 90 +++++++++++++++++++
> hw/arm/Kconfig | 1 +
> hw/arm/virt-acpi-build.c | 65 +++++++++++++-
> hw/arm/virt.c | 2 +
> hw/core/sysbus-fdt.c | 32 +++++++
> hw/i386/acpi-build.c | 12 +++
> hw/i386/pc_q35.c | 18 ++++
> hw/watchdog/sbsa_gwdt.c | 65 +++++++++-----
> hw/watchdog/trace-events | 9 ++
> tests/data/acpi/aarch64/virt/GTDT.gwdt | Bin 0 -> 132 bytes
> tests/data/acpi/aarch64/virt/WDAT.wdat | Bin 0 -> 260 bytes
> tests/data/acpi/x86/q35/WDAT.wdat | Bin 0 -> 308 bytes
> tests/qtest/bios-tables-test.c | 54 +++++++++++
> 23 files changed, 618 insertions(+), 26 deletions(-)
> create mode 100644 include/hw/acpi/wdat-gwdt.h
> create mode 100644 include/hw/acpi/wdat-ich9.h
> create mode 100644 include/hw/acpi/wdat.h
> create mode 100644 hw/acpi/wdat-gwdt-stub.c
> create mode 100644 hw/acpi/wdat-gwdt.c
> create mode 100644 hw/acpi/wdat-ich9-stub.c
> create mode 100644 hw/acpi/wdat-ich9.c
> create mode 100644 tests/data/acpi/aarch64/virt/GTDT.gwdt
> create mode 100644 tests/data/acpi/aarch64/virt/WDAT.wdat
> create mode 100644 tests/data/acpi/x86/q35/WDAT.wdat
>
> --
> 2.47.3