• Eric Ren's avatar
    KVM: arm64: vgic: Fix exit condition in scan_its_table() · c000a260
    Eric Ren authored
    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: 920a7a8f ("KVM: arm64: vgic-its: Add infrastructure for tableookup")
    Suggested-by: default avatarEric Auger <eric.auger@redhat.com>
    Signed-off-by: default avatarEric Ren <renzhengeek@gmail.com>
    [maz: commit message tidy-up]
    Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/d9c3a564af9e2c5bf63f48a7dcbf08cd593c5c0b.1665802985.git.renzhengeek@gmail.com
    c000a260
vgic-its.c 71.4 KB