Subject: [PATCH 00/16] arm64: Use EL2 virtual timer when running VHE

From: Marc Zyngier <[email-masked]>
Date: Thu, 7 May 2026 13:55:28 +0100

This series aims at making the kernel use the EL2 virtual timer rather
than the EL2 physical timer when running VHE. It doesn't change
anything when running bare-metal, but is significantly better when
running as a guest as CNTVOFF_EL2 virtualises correctly, while
CNTPOFF_EL2 doesn't.

The first patch teaches the ACPI GTDT parsing about the EL2 vtimer
interrupt. The table was specified years ago, just that nobody added
the necessary logic to the parser.

The second patch is the important one. It changes the PPI selection
logic to pick the EL2 vtimer over the EL2 ptimer *if* the interrupt
exists in the firmware tables.

As usual, firmware is in a sorry state (both DT and ACPI alike), but
given that this is to run as a guest, who cares as long as the VMM is
doing the right thing.

The following patches are totally optional and can be dropped as
necessary: they clean up the DT binding to make it crystal clear that
no, you can't decide to drop an interrupt while copy-pasting your DT
from somewhere else.

They finally add missing EL2 vtimer interrupts to a bunch of DTs where
I could guess the PPI number based on the other interrupts. I've left
the Marvell AC5 crap behind as they have been creative in the PPI
assignment, and life is too short to care about it.

This has been tested both as a KVM guest and on bare metal (QC X1e and
Amlogic SM1).

Marc Zyngier (16):
  ACPI: GTDT: Parse information related to the EL2 virtual timer
  clocksource/drivers/arm_arch_timer: Default to EL2 virtual timer when
    running VHE
  dt-bindings: timer: arm,arch_timer: Fix requirements for interrupt
    description
  arm64: dts: allwinner: Add EL2 virtual timer interrupt
  arm64: dts: amlogic: Add EL2 virtual timer interrupt
  arm64: dts: bst: Add EL2 virtual timer interrupt
  arm64: dts: exynos: Add EL2 virtual timer interrupt
  arm64: dts: freescale: Add EL2 virtual timer interrupt
  arm64: dts: intel: Add EL2 virtual timer interrupt
  arm64: dts: mediatek: Add EL2 virtual timer interrupt
  arm64: dts: nvidia: Add EL2 virtual timer interrupt
  arm64: dts: qcom: Add EL2 virtual timer interrupt
  arm64: dts: realtek: Add EL2 virtual timer interrupt
  arm64: dts: rockchip: Add EL2 virtual timer interrupt
  arm64: dts: sprd: Add EL2 virtual timer interrupt
  arm64: dts: xilinx: Add EL2 virtual timer interrupt

 .../bindings/timer/arm,arch_timer.yaml        | 21 ++++-----
 .../arm64/boot/dts/allwinner/sun55i-a523.dtsi |  3 +-
 .../boot/dts/amlogic/amlogic-a4-common.dtsi   |  8 ----
 arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi   |  8 ++++
 arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi   |  9 ++++
 arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi   |  3 +-
 arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi   |  3 +-
 arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi  |  3 +-
 .../boot/dts/amlogic/meson-g12-common.dtsi    | 13 ------
 arch/arm64/boot/dts/amlogic/meson-g12.dtsi    |  9 ++++
 arch/arm64/boot/dts/amlogic/meson-sm1.dtsi    | 10 +++++
 arch/arm64/boot/dts/bst/bstc1200.dtsi         |  3 +-
 arch/arm64/boot/dts/exynos/axis/artpec9.dtsi  |  3 +-
 arch/arm64/boot/dts/exynos/exynos2200.dtsi    |  3 +-
 arch/arm64/boot/dts/exynos/exynos990.dtsi     |  3 +-
 arch/arm64/boot/dts/exynos/exynosautov9.dtsi  |  3 +-
 arch/arm64/boot/dts/exynos/google/gs101.dtsi  |  3 +-
 .../boot/dts/freescale/imx91_93_common.dtsi   |  3 +-
 arch/arm64/boot/dts/freescale/imx94.dtsi      |  3 +-
 arch/arm64/boot/dts/freescale/imx95.dtsi      |  3 +-
 arch/arm64/boot/dts/freescale/imx952.dtsi     |  3 +-
 arch/arm64/boot/dts/freescale/s32n79.dtsi     |  3 +-
 .../arm64/boot/dts/intel/socfpga_agilex5.dtsi |  3 +-
 arch/arm64/boot/dts/mediatek/mt6779.dtsi      |  3 +-
 arch/arm64/boot/dts/mediatek/mt8186.dtsi      |  3 +-
 arch/arm64/boot/dts/mediatek/mt8188.dtsi      |  3 +-
 arch/arm64/boot/dts/mediatek/mt8192.dtsi      |  3 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      |  3 +-
 arch/arm64/boot/dts/nvidia/tegra194.dtsi      |  2 +
 arch/arm64/boot/dts/nvidia/tegra234.dtsi      |  3 +-
 arch/arm64/boot/dts/qcom/eliza.dtsi           |  3 +-
 arch/arm64/boot/dts/qcom/hamoa.dtsi           |  3 +-
 arch/arm64/boot/dts/qcom/kaanapali.dtsi       |  3 +-
 arch/arm64/boot/dts/qcom/kodiak.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/lemans.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/milos.dtsi           |  1 +
 arch/arm64/boot/dts/qcom/monaco.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sar2130p.dtsi        |  3 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sc8180x.dtsi         |  3 +-
 arch/arm64/boot/dts/qcom/sc8280xp.dtsi        |  3 +-
 arch/arm64/boot/dts/qcom/sdm670.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sdm845.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sdx75.dtsi           |  1 +
 arch/arm64/boot/dts/qcom/sm4450.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm6350.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm6375.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8150.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8350.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8450.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8550.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8650.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/sm8750.dtsi          |  3 +-
 arch/arm64/boot/dts/qcom/talos.dtsi           |  3 +-
 arch/arm64/boot/dts/realtek/rtd16xx.dtsi      |  3 +-
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi |  3 +-
 arch/arm64/boot/dts/sprd/sc9863a.dtsi         |  3 +-
 arch/arm64/boot/dts/sprd/ums512.dtsi          |  3 +-
 arch/arm64/boot/dts/sprd/ums9620.dtsi         |  3 +-
 arch/arm64/boot/dts/xilinx/versal-net.dtsi    |  3 +-
 drivers/acpi/arm64/gtdt.c                     | 25 +++++++++++
 drivers/clocksource/arm_arch_timer.c          | 44 +++++++++++--------
 63 files changed, 200 insertions(+), 104 deletions(-)

-- 
2.47.3