<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/include/kvm, branch master</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>Merge branch kvm-arm64/cross-vcpu-sync into kvmarm-master/fixes</title>
<updated>2026-10-26T10:57:31+00:00</updated>
<author>
<name>Marc Zyngier</name>
<email>maz@kernel.org</email>
</author>
<published>2026-10-26T07:47:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=af3a65d20dbfedc2a4779833597ec133fa612e86'/>
<id>af3a65d20dbfedc2a4779833597ec133fa612e86</id>
<content type='text'>
* kvm-arm64/cross-vcpu-sync:
  : \
  : Fix a number of issues related to publication of state when a vcpu
  : is forced out of the guest, address other problems related to the
  : nesting and overhead of pausing the VM, and apply all of that to
  : some of the nasty corners of the VGIC handling.
  :
  : This eventually simplifies the handling of operations that are
  : inherently racy by pausing the involved vcpus.
  : /
  KVM: arm64: vgic-its: Remove the pending state of a discarded LPI
  KVM: arm64: vgic-its: Don't map an LPI from more than one event
  KVM: arm64: vgic-its: Stop the VM when handling MOVALL
  KVM: arm64: vgic: Stop the target vcpu when disabling LPIs
  KVM: arm64: Add helpers to halt a vCPU
  KVM: arm64: Turn vcpu-&gt;arch.pause into a counter
  KVM: arm64: Move IN_GUEST_MODE ahead of state being loaded
  KVM: arm64: Move OUTSIDE_GUEST_MODE publication past context being saved
  KVM: arm64: nv: Move L2-&gt;L1 switch on interrupt early

Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* kvm-arm64/cross-vcpu-sync:
  : \
  : Fix a number of issues related to publication of state when a vcpu
  : is forced out of the guest, address other problems related to the
  : nesting and overhead of pausing the VM, and apply all of that to
  : some of the nasty corners of the VGIC handling.
  :
  : This eventually simplifies the handling of operations that are
  : inherently racy by pausing the involved vcpus.
  : /
  KVM: arm64: vgic-its: Remove the pending state of a discarded LPI
  KVM: arm64: vgic-its: Don't map an LPI from more than one event
  KVM: arm64: vgic-its: Stop the VM when handling MOVALL
  KVM: arm64: vgic: Stop the target vcpu when disabling LPIs
  KVM: arm64: Add helpers to halt a vCPU
  KVM: arm64: Turn vcpu-&gt;arch.pause into a counter
  KVM: arm64: Move IN_GUEST_MODE ahead of state being loaded
  KVM: arm64: Move OUTSIDE_GUEST_MODE publication past context being saved
  KVM: arm64: nv: Move L2-&gt;L1 switch on interrupt early

Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: vgic: Require matching VGIC and ITS models</title>
<updated>2026-10-26T10:57:19+00:00</updated>
<author>
<name>Sascha Bischoff</name>
<email>sascha.bischoff@arm.com</email>
</author>
<published>2026-10-20T16:39:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=05620a31421935f737d16a060d2dfe731f7b2f74'/>
<id>05620a31421935f737d16a060d2dfe731f7b2f74</id>
<content type='text'>
On a GICv5 host with legacy support, KVM registers both VGICv3 and
VGICv5 devices. Without a model check, a VM can create a GICv3 ITS
alongside an incompatible VGIC, regardless of creation order.

The same problem exists for GICv2 on hosts that support a GICv3 ITS.
KVM used to allow userspace to create both devices in either order,
then ignored the ITS.

Record the VGIC model required by an ITS. Reject an ITS if the VM
already has an incompatible VGIC, and reject a VGIC if an existing
ITS requires a different model. These checks apply on every host:
a GICv2 VGIC and a GICv3 ITS now fail with -ENODEV in either order.
Allow either creation order when the models match.

Have vgic_has_its() require matching VGIC and ITS models, and drop
the separate has_its flag.

As part of this change, swap the type of vgic_model from u32 to enum
kvm_device_type. This requires updating the switch cases in
kvm_vgic_vcpu_init() and kvm_vgic_dist_destroy() to include default
cases, which we mark as unreachable().

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Reviewed-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Link: https://patch.msgid.link/20261020163923.1407856-2-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
On a GICv5 host with legacy support, KVM registers both VGICv3 and
VGICv5 devices. Without a model check, a VM can create a GICv3 ITS
alongside an incompatible VGIC, regardless of creation order.

The same problem exists for GICv2 on hosts that support a GICv3 ITS.
KVM used to allow userspace to create both devices in either order,
then ignored the ITS.

Record the VGIC model required by an ITS. Reject an ITS if the VM
already has an incompatible VGIC, and reject a VGIC if an existing
ITS requires a different model. These checks apply on every host:
a GICv2 VGIC and a GICv3 ITS now fail with -ENODEV in either order.
Allow either creation order when the models match.

Have vgic_has_its() require matching VGIC and ITS models, and drop
the separate has_its flag.

As part of this change, swap the type of vgic_model from u32 to enum
kvm_device_type. This requires updating the switch cases in
kvm_vgic_vcpu_init() and kvm_vgic_dist_destroy() to include default
cases, which we mark as unreachable().

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Reviewed-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Link: https://patch.msgid.link/20261020163923.1407856-2-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: vgic-its: Don't map an LPI from more than one event</title>
<updated>2026-10-17T08:49:59+00:00</updated>
<author>
<name>Fuad Tabba</name>
<email>fuad.tabba@linux.dev</email>
</author>
<published>2026-10-13T08:16:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=de81b28f0b83b22163d7d9a9b708d7aa912e0ef7'/>
<id>de81b28f0b83b22163d7d9a9b708d7aa912e0ef7</id>
<content type='text'>
KVM keeps one vgic_irq per LPI. A MAPTI of an LPI whose vgic_irq
already exists reuses it for the new ITE and leaves its target vCPU as
it was. Mapping one LPI from two events is UNPREDICTABLE (IHI 0069H.b,
5.2.10), but nothing stops a guest from doing it. If the first MAPTI
names a collection the guest never maps and the second a mapped one,
the LPI translates through the second event with a NULL target vCPU.

When the VMM routes an assigned device's MSI to that event on a host
with GICv4 enabled, kvm_vgic_v4_set_forwarding() takes the vPE from the
NULL target vCPU and the host oopses:

  Unable to handle kernel paging request at virtual address 0000000000001980
  [...]
  Call trace:
   its_build_vmapti_cmd (drivers/irqchip/irq-gic-v3-its.c:943) (P)
   its_irq_set_vcpu_affinity (drivers/irqchip/irq-gic-v3-its.c:1380)
   irq_set_vcpu_affinity (kernel/irq/manage.c:670)
   its_map_vlpi (drivers/irqchip/irq-gic-v4.c:326)
   kvm_vgic_v4_set_forwarding (arch/arm64/kvm/vgic/vgic-v4.c:485)
   kvm_arch_irq_bypass_add_producer (arch/arm64/kvm/arm.c:2977)
   irq_bypass_register_consumer (virt/lib/irqbypass.c:44)
   kvm_irqfd (arch/arm64/kvm/../../../virt/kvm/eventfd.c:496)
   kvm_vm_ioctl (arch/arm64/kvm/../../../virt/kvm/kvm_main.c:5270)

Track in each vgic_irq whether an ITE maps it. Drop a MAPTI of an LPI
that is already mapped, as a failed MAPTI already is. Restoring the ITS
tables keeps the first ITE it reads for each LPI and drops any later
one, so a guest saved with a double mapping still restores. Key the
check on the mapping, not on the vgic_irq. A vgic_irq outlives its ITE
while anything holds a reference to it, such as the vCPU it was last
queued on. A later MAPTI of such an LPI succeeds as before, and now
retargets it to its collection.

Fixes: 196b136498b35 ("KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass")
Suggested-by: Marc Zyngier &lt;maz@kernel.org&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Reviewed-by: Oliver Upton &lt;oupton@kernel.org&gt;
Link: https://patch.msgid.link/20261013081646.933312-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
KVM keeps one vgic_irq per LPI. A MAPTI of an LPI whose vgic_irq
already exists reuses it for the new ITE and leaves its target vCPU as
it was. Mapping one LPI from two events is UNPREDICTABLE (IHI 0069H.b,
5.2.10), but nothing stops a guest from doing it. If the first MAPTI
names a collection the guest never maps and the second a mapped one,
the LPI translates through the second event with a NULL target vCPU.

When the VMM routes an assigned device's MSI to that event on a host
with GICv4 enabled, kvm_vgic_v4_set_forwarding() takes the vPE from the
NULL target vCPU and the host oopses:

  Unable to handle kernel paging request at virtual address 0000000000001980
  [...]
  Call trace:
   its_build_vmapti_cmd (drivers/irqchip/irq-gic-v3-its.c:943) (P)
   its_irq_set_vcpu_affinity (drivers/irqchip/irq-gic-v3-its.c:1380)
   irq_set_vcpu_affinity (kernel/irq/manage.c:670)
   its_map_vlpi (drivers/irqchip/irq-gic-v4.c:326)
   kvm_vgic_v4_set_forwarding (arch/arm64/kvm/vgic/vgic-v4.c:485)
   kvm_arch_irq_bypass_add_producer (arch/arm64/kvm/arm.c:2977)
   irq_bypass_register_consumer (virt/lib/irqbypass.c:44)
   kvm_irqfd (arch/arm64/kvm/../../../virt/kvm/eventfd.c:496)
   kvm_vm_ioctl (arch/arm64/kvm/../../../virt/kvm/kvm_main.c:5270)

Track in each vgic_irq whether an ITE maps it. Drop a MAPTI of an LPI
that is already mapped, as a failed MAPTI already is. Restoring the ITS
tables keeps the first ITE it reads for each LPI and drops any later
one, so a guest saved with a double mapping still restores. Key the
check on the mapping, not on the vgic_irq. A vgic_irq outlives its ITE
while anything holds a reference to it, such as the vCPU it was last
queued on. A later MAPTI of such an LPI succeeds as before, and now
retargets it to its collection.

Fixes: 196b136498b35 ("KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass")
Suggested-by: Marc Zyngier &lt;maz@kernel.org&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Reviewed-by: Oliver Upton &lt;oupton@kernel.org&gt;
Link: https://patch.msgid.link/20261013081646.933312-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch kvm-arm64/cca-7.4 into kvmarm-master/next</title>
<updated>2026-10-11T10:03:27+00:00</updated>
<author>
<name>Marc Zyngier</name>
<email>maz@kernel.org</email>
</author>
<published>2026-10-11T10:03:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=dd0bc00e3e9201fd49b62ff9cc07890c89003afe'/>
<id>dd0bc00e3e9201fd49b62ff9cc07890c89003afe</id>
<content type='text'>
* kvm-arm64/cca-7.4:
  : \
  : Preliminary changes that pave the way for CCA in a future revision
  : of Linux, introducing some required abstractions (vcpu ops, S2 ops)
  : and making some concepts common with pKVM.
  :
  : Patches courtesy of Suzuki Poulose.
  : /
  KVM: arm64: Prevent unsupported vcpu features for VM types
  KVM: arm64: Mandate VGIC v3 for pKVM VMs and Realms
  KVM: arm64: Abstract out memory abort handling
  KVM: arm64: Use a local kvm pointer in kvm_handle_guest_abort()
  KVM: arm64: Add VM specific callback for S2 MMU operations
  KVM: arm64: Consolidate stage2 unmap range into kvm_stage2_unmap_range
  KVM: arm64: Add vcpu load/put call backs for flavors
  KVM: arm64: Refactor the vcpu_load to allow for VM specific callbacks
  KVM: arm64: Don't call vcpu_set_pauth_traps for pKVM host
  KVM: arm64: Track the type of VM in kvm_arch
  KVM: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h
  KVM: arm64: Include kvm_emulate.h in kvm/arm_psci.h
  KVM: arm64: protected VM: Handle user writes to CNTVCT_EL0/CNTPCT_EL0

Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* kvm-arm64/cca-7.4:
  : \
  : Preliminary changes that pave the way for CCA in a future revision
  : of Linux, introducing some required abstractions (vcpu ops, S2 ops)
  : and making some concepts common with pKVM.
  :
  : Patches courtesy of Suzuki Poulose.
  : /
  KVM: arm64: Prevent unsupported vcpu features for VM types
  KVM: arm64: Mandate VGIC v3 for pKVM VMs and Realms
  KVM: arm64: Abstract out memory abort handling
  KVM: arm64: Use a local kvm pointer in kvm_handle_guest_abort()
  KVM: arm64: Add VM specific callback for S2 MMU operations
  KVM: arm64: Consolidate stage2 unmap range into kvm_stage2_unmap_range
  KVM: arm64: Add vcpu load/put call backs for flavors
  KVM: arm64: Refactor the vcpu_load to allow for VM specific callbacks
  KVM: arm64: Don't call vcpu_set_pauth_traps for pKVM host
  KVM: arm64: Track the type of VM in kvm_arch
  KVM: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h
  KVM: arm64: Include kvm_emulate.h in kvm/arm_psci.h
  KVM: arm64: protected VM: Handle user writes to CNTVCT_EL0/CNTPCT_EL0

Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch kvm-arm64/misc-7.4 into kvmarm-master/next</title>
<updated>2026-10-11T09:44:26+00:00</updated>
<author>
<name>Marc Zyngier</name>
<email>maz@kernel.org</email>
</author>
<published>2026-10-11T09:44:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=fddb6720020f3b7552f1d17f08cc063dc2e0a9d0'/>
<id>fddb6720020f3b7552f1d17f08cc063dc2e0a9d0</id>
<content type='text'>
* kvm-arm64/misc-7.4:
  : \
  : Misc KVM/arm64 fixes for 7.4:
  :
  : - Correctly report SMCCC_VERSION and SMCCC_ARCH_FEATURES as implemented
  :
  : - Don't register a page table dumper for pKVM VMs, as S2 is not
  :   accessible when in protected mode
  :
  : - Drop PAGE_SIZE alignment requirement for hyp trace event sections
  :
  : - Tighten PMUv3 being disabled for the guest even if vcpus were created
  :   with one.
  :
  : - Fix timer emulation when the HW doesn't support offsetting of the
  :   counter.
  : /
  KVM: arm64: selftests: Test a timer set past the counter's wrap
  KVM: arm64: nv: Read a guest hypervisor's CNTV_CVAL_EL0 from memory on x1e
  KVM: arm64: timers: Compute an offset-applied CVAL from the current count
  KVM: arm64: Check ID_AA64DFR0_EL1.PMUVer in pmu_visibility()
  KVM: arm64: Handle ID_AA64DFR0_EL1.PMUVer == NI in __kvm_pmu_event_mask()
  KVM: arm64: Remove PAGE_SIZE alignment for hyp event ELF sections
  KVM: arm64: Disable stage-2 ptdump of pKVM
  KVM: arm64: selftests: Check the mandatory SMCCC_ARCH_FEATURES queries
  KVM: arm64: Report SMCCC_VERSION and SMCCC_ARCH_FEATURES as implemented

Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* kvm-arm64/misc-7.4:
  : \
  : Misc KVM/arm64 fixes for 7.4:
  :
  : - Correctly report SMCCC_VERSION and SMCCC_ARCH_FEATURES as implemented
  :
  : - Don't register a page table dumper for pKVM VMs, as S2 is not
  :   accessible when in protected mode
  :
  : - Drop PAGE_SIZE alignment requirement for hyp trace event sections
  :
  : - Tighten PMUv3 being disabled for the guest even if vcpus were created
  :   with one.
  :
  : - Fix timer emulation when the HW doesn't support offsetting of the
  :   counter.
  : /
  KVM: arm64: selftests: Test a timer set past the counter's wrap
  KVM: arm64: nv: Read a guest hypervisor's CNTV_CVAL_EL0 from memory on x1e
  KVM: arm64: timers: Compute an offset-applied CVAL from the current count
  KVM: arm64: Check ID_AA64DFR0_EL1.PMUVer in pmu_visibility()
  KVM: arm64: Handle ID_AA64DFR0_EL1.PMUVer == NI in __kvm_pmu_event_mask()
  KVM: arm64: Remove PAGE_SIZE alignment for hyp event ELF sections
  KVM: arm64: Disable stage-2 ptdump of pKVM
  KVM: arm64: selftests: Check the mandatory SMCCC_ARCH_FEATURES queries
  KVM: arm64: Report SMCCC_VERSION and SMCCC_ARCH_FEATURES as implemented

Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: Include kvm_emulate.h in kvm/arm_psci.h</title>
<updated>2026-10-07T12:30:28+00:00</updated>
<author>
<name>Suzuki K Poulose</name>
<email>suzuki.poulose@arm.com</email>
</author>
<published>2026-10-07T07:35:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=22adb9c3543cc702516c18f0a28e3a8dfcdbeecc'/>
<id>22adb9c3543cc702516c18f0a28e3a8dfcdbeecc</id>
<content type='text'>
Fix a potential build error (like below, when asm/kvm_emulate.h gets
included after the kvm/arm_psci.h) by including the missing header file
in kvm/arm_psci.h:

./include/kvm/arm_psci.h: In function ‘kvm_psci_version’:
./include/kvm/arm_psci.h:29:13: error: implicit declaration of function
   ‘vcpu_has_feature’; did you mean ‘cpu_have_feature’? [-Werror=implicit-function-declaration]
   29 |         if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2)) {
	         |             ^~~~~~~~~~~~~~~~
			       |             cpu_have_feature

Reviewed-by: Gavin Shan &lt;gshan@redhat.com&gt;
Reviewed-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Reviewed-by: Jonathan Cameron &lt;jonathan.cameron@oss.qualcomm.com&gt;
Tested-by: Gavin Shan &lt;gshan@redhat.com&gt;
Signed-off-by: Suzuki K Poulose &lt;suzuki.poulose@arm.com&gt;
Link: https://patch.msgid.link/20261007073537.2454351-4-suzuki.poulose@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix a potential build error (like below, when asm/kvm_emulate.h gets
included after the kvm/arm_psci.h) by including the missing header file
in kvm/arm_psci.h:

./include/kvm/arm_psci.h: In function ‘kvm_psci_version’:
./include/kvm/arm_psci.h:29:13: error: implicit declaration of function
   ‘vcpu_has_feature’; did you mean ‘cpu_have_feature’? [-Werror=implicit-function-declaration]
   29 |         if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2)) {
	         |             ^~~~~~~~~~~~~~~~
			       |             cpu_have_feature

Reviewed-by: Gavin Shan &lt;gshan@redhat.com&gt;
Reviewed-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Reviewed-by: Jonathan Cameron &lt;jonathan.cameron@oss.qualcomm.com&gt;
Tested-by: Gavin Shan &lt;gshan@redhat.com&gt;
Signed-off-by: Suzuki K Poulose &lt;suzuki.poulose@arm.com&gt;
Link: https://patch.msgid.link/20261007073537.2454351-4-suzuki.poulose@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: timers: Compute an offset-applied CVAL from the current count</title>
<updated>2026-10-07T10:43:11+00:00</updated>
<author>
<name>Fuad Tabba</name>
<email>fuad.tabba@linux.dev</email>
</author>
<published>2026-10-07T07:43:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=49930b1b557ceb698e0ab7f985ea41c99dc8bf22'/>
<id>49930b1b557ceb698e0ab7f985ea41c99dc8bf22</id>
<content type='text'>
When the hardware won't apply a timer's offset, KVM programs CVAL +
offset and lets it compare that against the raw counter. The compare is
unsigned (IsTimerConditionMet, DDI0487M_c J1.4.3.29):

  condition_met = (UInt(PhysicalCountInt() - offset) -
                   UInt(compare_value)) &gt;= 0;

so adding the offset to both sides holds only while both sums wrap or
neither does. A guest whose counter is ahead of the host's by more than
CVAL has an expired timer that never fires, and one behind it can have
a far-future timer fire at once.

On a CNTPOFF_EL2 host the first case livelocks: each entry reloads the
guest's CVAL, the timer fires, and the exit rewrites it as CVAL + offset
before the host can take the interrupt. Without CNTPOFF_EL2 the timer
hangs until the vCPU is next loaded, which is what Zenghui reported on
a Kunpeng920.

Program the value from the current count instead: CVAL + offset while
the deadline is ahead, 0 once the timer has expired for the guest, ~0
past the counter's wrap. KVM recomputes it at load, at exit and on a
trapped CVAL write, and an expired timer stays expired in between. The
value can't be inverted, so with an offset timer_save_state() keeps the
memory copy, and kvm_hyp_handle_timer() returns that copy for a guest
hypervisor's read of its physical CVAL rather than subtracting the
offset back out.

Fixes: c605ee245097 ("KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2")
Fixes: 9404673293b0 ("KVM: arm64: timers: Correctly handle TGE flip with CNTPOFF_EL2")
Fixes: 0bc9a9e85fcf ("KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity")
Reported-by: Zenghui Yu &lt;yuzenghui@huawei.com&gt;
Closes: https://lore.kernel.org/r/460258be-0102-e922-c342-4e87cd94b9e5@huawei.com
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Link: https://patch.msgid.link/20261007074343.324269-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When the hardware won't apply a timer's offset, KVM programs CVAL +
offset and lets it compare that against the raw counter. The compare is
unsigned (IsTimerConditionMet, DDI0487M_c J1.4.3.29):

  condition_met = (UInt(PhysicalCountInt() - offset) -
                   UInt(compare_value)) &gt;= 0;

so adding the offset to both sides holds only while both sums wrap or
neither does. A guest whose counter is ahead of the host's by more than
CVAL has an expired timer that never fires, and one behind it can have
a far-future timer fire at once.

On a CNTPOFF_EL2 host the first case livelocks: each entry reloads the
guest's CVAL, the timer fires, and the exit rewrites it as CVAL + offset
before the host can take the interrupt. Without CNTPOFF_EL2 the timer
hangs until the vCPU is next loaded, which is what Zenghui reported on
a Kunpeng920.

Program the value from the current count instead: CVAL + offset while
the deadline is ahead, 0 once the timer has expired for the guest, ~0
past the counter's wrap. KVM recomputes it at load, at exit and on a
trapped CVAL write, and an expired timer stays expired in between. The
value can't be inverted, so with an offset timer_save_state() keeps the
memory copy, and kvm_hyp_handle_timer() returns that copy for a guest
hypervisor's read of its physical CVAL rather than subtracting the
offset back out.

Fixes: c605ee245097 ("KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2")
Fixes: 9404673293b0 ("KVM: arm64: timers: Correctly handle TGE flip with CNTPOFF_EL2")
Fixes: 0bc9a9e85fcf ("KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity")
Reported-by: Zenghui Yu &lt;yuzenghui@huawei.com&gt;
Closes: https://lore.kernel.org/r/460258be-0102-e922-c342-4e87cd94b9e5@huawei.com
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba &lt;fuad.tabba@linux.dev&gt;
Link: https://patch.msgid.link/20261007074343.324269-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: gic-v5: Handle userspace accesses to IRS MMIO region</title>
<updated>2026-09-14T09:49:09+00:00</updated>
<author>
<name>Sascha Bischoff</name>
<email>Sascha.Bischoff@arm.com</email>
</author>
<published>2026-09-04T11:50:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=71091136d1452b6125579b210d29efec3e79681a'/>
<id>71091136d1452b6125579b210d29efec3e79681a</id>
<content type='text'>
As part of saving and restoring the state of a GICv5-based system,
userspace must save and restore the IRS MMIO registers. These include
important information such as the guest IST configuration, and KVM
must present consistent state to the guest after migration.

Introduce KVM_DEV_ARM_VGIC_GRP_IRS_REGS and provide accessors to read
and write the virtual IRS register state. This is modelled on the
GICv3 ITS register interface, as the migration requirements are
broadly the same.

Reuse the guest MMIO handlers where userspace and guest accesses have
the same semantics. Add userspace-specific handling where restoring a
register image must not trigger the operation associated with a guest
MMIO write.

Validate restored ID register fields against the capabilities KVM and
the host can support. Restore the emulated IST configuration without
allocating or freeing a host IST, and report operation status
registers as idle. Accept writes to IRS_SPI_CFGR, IRS_IIDR, and
IRS_AIDR without changing their state, allowing userspace to replay
the values it previously read.

Restoring IRS_IST_BASER.Valid recreates the guest-visible
configuration, but the host LPI IST cannot be allocated until
userspace supplies its contents. Track this as a pending LPI IST
restore and reject guest entry until userspace restores the IST
through KVM_DEV_ARM_VGIC_GRP_IST.

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Link: https://patch.msgid.link/20260904113404.4051341-33-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As part of saving and restoring the state of a GICv5-based system,
userspace must save and restore the IRS MMIO registers. These include
important information such as the guest IST configuration, and KVM
must present consistent state to the guest after migration.

Introduce KVM_DEV_ARM_VGIC_GRP_IRS_REGS and provide accessors to read
and write the virtual IRS register state. This is modelled on the
GICv3 ITS register interface, as the migration requirements are
broadly the same.

Reuse the guest MMIO handlers where userspace and guest accesses have
the same semantics. Add userspace-specific handling where restoring a
register image must not trigger the operation associated with a guest
MMIO write.

Validate restored ID register fields against the capabilities KVM and
the host can support. Restore the emulated IST configuration without
allocating or freeing a host IST, and report operation status
registers as idle. Accept writes to IRS_SPI_CFGR, IRS_IIDR, and
IRS_AIDR without changing their state, allowing userspace to replay
the values it previously read.

Restoring IRS_IST_BASER.Valid recreates the guest-visible
configuration, but the host LPI IST cannot be allocated until
userspace supplies its contents. Track this as a pending LPI IST
restore and reject guest entry until userspace restores the IST
through KVM_DEV_ARM_VGIC_GRP_IST.

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Link: https://patch.msgid.link/20260904113404.4051341-33-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: gic-v5: Mask per-vCPU PPI state in vgic_v5_finalize_ppi_state()</title>
<updated>2026-09-14T09:49:09+00:00</updated>
<author>
<name>Sascha Bischoff</name>
<email>Sascha.Bischoff@arm.com</email>
</author>
<published>2026-09-04T11:49:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=589d6072f25d0690ab9bace88b0d77a06e6ff22d'/>
<id>589d6072f25d0690ab9bace88b0d77a06e6ff22d</id>
<content type='text'>
Only a subset of the possible PPIs are exposed to a guest when running
with a vGICv5. First of all, only the architected PPIs are considered
by KVM. Secondly, only a set of those is exposed to a guest: those
corresponding to devices that KVM emulates, such as the timers and
PMU, and the GICv5 SW_PPI.

The finalisation of exposed PPIs happens on first vCPU run, as this is
the first time when the full set of exposed devices is known. At this
stage a mask is calculated, and this mask is applied both to hide
non-exposed PPI state from the guest and to reduce overhead when
iterating over the PPIs.

While preparing userspace access to the GICv5 system registers, it
became apparent that restoring the GICv5 PPI registers can result in a
mismatch between the state supplied by userspace and the state KVM
intends to expose. Userspace can provide Enable, Active, and Pending
state for PPIs that KVM has chosen to hide from the guest.

Userspace must restore PPI state before any vCPU runs. The userspace
access path added subsequently enforces this ordering. Rework
vgic_v5_finalize_ppi_state() to calculate the mask of exposed PPIs and
clear any state belonging to non-exposed PPIs. This ensures that only
the state KVM intends to expose is visible to the guest.

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Link: https://patch.msgid.link/20260904113404.4051341-31-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Only a subset of the possible PPIs are exposed to a guest when running
with a vGICv5. First of all, only the architected PPIs are considered
by KVM. Secondly, only a set of those is exposed to a guest: those
corresponding to devices that KVM emulates, such as the timers and
PMU, and the GICv5 SW_PPI.

The finalisation of exposed PPIs happens on first vCPU run, as this is
the first time when the full set of exposed devices is known. At this
stage a mask is calculated, and this mask is applied both to hide
non-exposed PPI state from the guest and to reduce overhead when
iterating over the PPIs.

While preparing userspace access to the GICv5 system registers, it
became apparent that restoring the GICv5 PPI registers can result in a
mismatch between the state supplied by userspace and the state KVM
intends to expose. Userspace can provide Enable, Active, and Pending
state for PPIs that KVM has chosen to hide from the guest.

Userspace must restore PPI state before any vCPU runs. The userspace
access path added subsequently enforces this ordering. Rework
vgic_v5_finalize_ppi_state() to calculate the mask of exposed PPIs and
clear any state belonging to non-exposed PPIs. This ensures that only
the state KVM intends to expose is visible to the guest.

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Link: https://patch.msgid.link/20260904113404.4051341-31-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>KVM: arm64: gic: Introduce set_pending_state() to irq_ops</title>
<updated>2026-09-14T09:49:08+00:00</updated>
<author>
<name>Sascha Bischoff</name>
<email>Sascha.Bischoff@arm.com</email>
</author>
<published>2026-09-04T11:47:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=7e9e2aaca2f84e7a549737edf4f9fa5262c10b84'/>
<id>7e9e2aaca2f84e7a549737edf4f9fa5262c10b84</id>
<content type='text'>
There are times, such as with GICv5 SPIs and LPIs, where the hardware
itself manages parts of the interrupt lifecycle. This means that
pending state can be directly communicated to the hardware instead of
being represented only in the VGIC shadow state.

In order to accommodate cases where the hardware handles pending state
directly, add a new set_pending_state() function pointer to
irq_ops. The intent is for this to be used after the VGIC shadow
pending state has changed, allowing the backend to mirror the updated
state into hardware.

This new function is plumbed into kvm_vgic_inject_irq(), and is only
called if irq_ops are provided and this function pointer is explicitly
set. In the general case, this has no effect.

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Link: https://patch.msgid.link/20260904113404.4051341-27-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There are times, such as with GICv5 SPIs and LPIs, where the hardware
itself manages parts of the interrupt lifecycle. This means that
pending state can be directly communicated to the hardware instead of
being represented only in the VGIC shadow state.

In order to accommodate cases where the hardware handles pending state
directly, add a new set_pending_state() function pointer to
irq_ops. The intent is for this to be used after the VGIC shadow
pending state has changed, allowing the backend to mirror the updated
state into hardware.

This new function is plumbed into kvm_vgic_inject_irq(), and is only
called if irq_ops are provided and this function pointer is explicitly
set. In the general case, this has no effect.

Signed-off-by: Sascha Bischoff &lt;sascha.bischoff@arm.com&gt;
Link: https://patch.msgid.link/20260904113404.4051341-27-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier &lt;maz@kernel.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
