From a5dba9bc0552785b91315d457b9397ebd833224b Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 12 Jul 2021 10:31:35 +0200 Subject: [PATCH 1/3] vfio: Fix CID 1458134 in vfio_register_ram_discard_listener() CID 1458134: Integer handling issues (BAD_SHIFT) In expression "1 << ctz64(container->pgsizes)", left shifting by more than 31 bits has undefined behavior. The shift amount, "ctz64(container->pgsizes)", is 64. Commit 5e3b981c330c ("vfio: Support for RamDiscardManager in the !vIOMMU case") added an assertion that our granularity is at least as big as the page size. Although unlikely, we could have a page size that does not fit into 32 bit. In that case, we'd try shifting by more than 31 bit. Let's use 1ULL instead and make sure we're not shifting by more than 63 bit by asserting that any bit in container->pgsizes is set. Fixes: CID 1458134 Cc: Alex Williamson Cc: Eduardo Habkost Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Dr. David Alan Gilbert Cc: Igor Mammedov Cc: Pankaj Gupta Cc: Peter Xu Cc: Auger Eric Cc: Wei Yang Cc: teawater Cc: Marek Kedzierski Signed-off-by: David Hildenbrand Reviewed-by: Igor Mammedov Reviewed-by: Pankaj Gupta Link: https://lore.kernel.org/r/20210712083135.15755-1-david@redhat.com Signed-off-by: Alex Williamson --- hw/vfio/common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 3f0d111360..8728d4d5c2 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -783,7 +783,8 @@ static void vfio_register_ram_discard_listener(VFIOContainer *container, section->mr); g_assert(vrdl->granularity && is_power_of_2(vrdl->granularity)); - g_assert(vrdl->granularity >= 1 << ctz64(container->pgsizes)); + g_assert(container->pgsizes && + vrdl->granularity >= 1ULL << ctz64(container->pgsizes)); ram_discard_listener_init(&vrdl->listener, vfio_ram_discard_notify_populate, From 936555bc4f9efce1a9d35466845169c2c7566794 Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Tue, 13 Jul 2021 09:48:31 +0800 Subject: [PATCH 2/3] vfio/pci: Change to use vfio_pci_is() Make use of vfio_pci_is() helper function. Signed-off-by: Cai Huoqing Link: https://lore.kernel.org/r/20210713014831.742-1-caihuoqing@baidu.com [aw: commit log wording] Signed-off-by: Alex Williamson --- hw/vfio/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index ab4077aad2..971273fd45 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3058,14 +3058,14 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) } } - if (vdev->vendor_id == PCI_VENDOR_ID_NVIDIA) { + if (vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID)) { ret = vfio_pci_nvidia_v100_ram_init(vdev, errp); if (ret && ret != -ENODEV) { error_report("Failed to setup NVIDIA V100 GPU RAM"); } } - if (vdev->vendor_id == PCI_VENDOR_ID_IBM) { + if (vfio_pci_is(vdev, PCI_VENDOR_ID_IBM, PCI_ANY_ID)) { ret = vfio_pci_nvlink2_init(vdev, errp); if (ret && ret != -ENODEV) { error_report("Failed to setup NVlink2 bridge"); From 1bd9f1b14d1e9c1498bb03faf4e2bb945cf6542d Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Tue, 13 Jul 2021 17:37:43 +0800 Subject: [PATCH 3/3] vfio/pci: Add pba_offset PCI quirk for BAIDU KUNLUN AI processor Fix pba_offset initialization value for BAIDU KUNLUN Virtual Function device. The KUNLUN hardware returns an incorrect value for the VF PBA offset, and add a quirk to instead return a hardcoded value of 0xb400. Signed-off-by: Cai Huoqing Link: https://lore.kernel.org/r/20210713093743.942-1-caihuoqing@baidu.com [aw: comment & whitespace tuning] Signed-off-by: Alex Williamson --- hw/vfio/pci.c | 8 ++++++++ include/hw/pci/pci_ids.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 971273fd45..e1ea1d8a23 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1499,6 +1499,14 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp) if (vdev->vendor_id == PCI_VENDOR_ID_CHELSIO && (vdev->device_id & 0xff00) == 0x5800) { msix->pba_offset = 0x1000; + /* + * BAIDU KUNLUN Virtual Function devices for KUNLUN AI processor + * return an incorrect value of 0x460000 for the VF PBA offset while + * the BAR itself is only 0x10000. The correct value is 0xb400. + */ + } else if (vfio_pci_is(vdev, PCI_VENDOR_ID_BAIDU, + PCI_DEVICE_ID_KUNLUN_VF)) { + msix->pba_offset = 0xb400; } else if (vdev->msix_relo == OFF_AUTOPCIBAR_OFF) { error_setg(errp, "hardware reports invalid configuration, " "MSIX PBA outside of specified BAR"); diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index 5c14681b82..11abe22d46 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -227,6 +227,9 @@ #define PCI_VENDOR_ID_FREESCALE 0x1957 #define PCI_DEVICE_ID_MPC8533E 0x0030 +#define PCI_VENDOR_ID_BAIDU 0x1d22 +#define PCI_DEVICE_ID_KUNLUN_VF 0x3685 + #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82378 0x0484 #define PCI_DEVICE_ID_INTEL_82441 0x1237