android_kernel_asus_sm8350/virt/kvm/arm/vgic
Eric Ren fd596e7371 KVM: arm64: vgic: Fix exit condition in scan_its_table()
commit c000a2607145d28b06c697f968491372ea56c23a upstream.

With some PCIe topologies, restoring a guest fails while
parsing the ITS device tables.

Reproducer hints:
1. Create ARM virt VM with pxb-pcie bus which adds
   extra host bridges, with qemu command like:

```
  -device pxb-pcie,bus_nr=8,id=pci.x,numa_node=0,bus=pcie.0 \
  -device pcie-root-port,..,bus=pci.x \
  ...
  -device pxb-pcie,bus_nr=37,id=pci.y,numa_node=1,bus=pcie.0 \
  -device pcie-root-port,..,bus=pci.y \
  ...

```
2. Ensure the guest uses 2-level device table
3. Perform VM migration which calls save/restore device tables

In that setup, we get a big "offset" between 2 device_ids,
which makes unsigned "len" round up a big positive number,
causing the scan loop to continue with a bad GPA. For example:

1. L1 table has 2 entries;
2. and we are now scanning at L2 table entry index 2075 (pointed
   to by L1 first entry)
3. if next device id is 9472, we will get a big offset: 7397;
4. with unsigned 'len', 'len -= offset * esz', len will underflow to a
   positive number, mistakenly into next iteration with a bad GPA;
   (It should break out of the current L2 table scanning, and jump
   into the next L1 table entry)
5. that bad GPA fails the guest read.

Fix it by stopping the L2 table scan when the next device id is
outside of the current table, allowing the scan to continue from
the next L1 table entry.

Thanks to Eric Auger for the fix suggestion.

Fixes: 920a7a8fa9 ("KVM: arm64: vgic-its: Add infrastructure for tableookup")
Suggested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Eric Ren <renzhengeek@gmail.com>
[maz: commit message tidy-up]
Signed-off-by: Marc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/d9c3a564af9e2c5bf63f48a7dcbf08cd593c5c0b.1665802985.git.renzhengeek@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-10-29 10:20:35 +02:00
..
trace.h KVM: arm/arm64: vgic: Use the appropriate TRACE_INCLUDE_PATH 2019-09-11 16:36:19 +01:00
vgic-debug.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 234 2019-06-19 17:09:07 +02:00
vgic-init.c KVM: arm64: vgic-v3: Retire all pending LPIs on vcpu destroy 2020-10-01 13:17:56 +02:00
vgic-irqfd.c KVM: arm/arm64: vgic-irqfd: Implement kvm_arch_set_irq_inatomic 2019-08-18 18:38:54 +01:00
vgic-its.c KVM: arm64: vgic: Fix exit condition in scan_its_table() 2022-10-29 10:20:35 +02:00
vgic-kvm-device.c KVM: arm/arm64: Fix KVM_VGIC_V3_ADDR_TYPE_REDIST read 2021-06-23 14:41:31 +02:00
vgic-mmio-v2.c KVM: arm: vgic: Synchronize the whole guest on GIC{D,R}_I{S,C}ACTIVER read 2020-05-20 08:20:04 +02:00
vgic-mmio-v3.c KVM: arm64: vgic-v3: Drop the reporting of GICR_TYPER.Last for userspace 2020-12-02 08:49:46 +01:00
vgic-mmio.c KVM: arm: vgic: Synchronize the whole guest on GIC{D,R}_I{S,C}ACTIVER read 2020-05-20 08:20:04 +02:00
vgic-mmio.h KVM: arm: vgic: Synchronize the whole guest on GIC{D,R}_I{S,C}ACTIVER read 2020-05-20 08:20:04 +02:00
vgic-v2.c * s390: ioctl hardening, selftests 2019-09-18 09:49:13 -07:00
vgic-v3.c KVM: arm/arm64: vgic: Don't rely on the wrong pending table 2019-12-13 08:43:00 +01:00
vgic-v4.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 234 2019-06-19 17:09:07 +02:00
vgic.c * s390: ioctl hardening, selftests 2019-09-18 09:49:13 -07:00
vgic.h KVM: arm/arm64: vgic-its: Check the LPI translation cache on MSI injection 2019-08-18 18:38:53 +01:00