From ea131eea413a7a10c073e0fe19d8db8c7ecbceb0 Mon Sep 17 00:00:00 2001 From: Alexander Merritt Date: Thu, 31 Oct 2019 23:58:27 -0700 Subject: [PATCH] HV: add DRHD index to pci_pdev We add new member pci_pdev.drhd_idx associating the DRHD (IOMMU) with this pdev, and a method to convert a pbdf of a device to this index by searching the pdev list. Partial patch: drhd_index initialization handled in subsequent patch. Tracked-On: #4134 Signed-off-by: Alexander Merritt Signed-off-by: Sainath Grandhi Reviewed-by: Eddie Dong Reviewed-by: Jason Chen CJ --- hypervisor/hw/pci.c | 23 +++++++++++++++++++++++ hypervisor/include/arch/x86/vtd.h | 2 ++ hypervisor/include/hw/pci.h | 13 +++++++++++++ 3 files changed, 38 insertions(+) diff --git a/hypervisor/hw/pci.c b/hypervisor/hw/pci.c index 94b3bb3e5..e76800fa6 100644 --- a/hypervisor/hw/pci.c +++ b/hypervisor/hw/pci.c @@ -45,6 +45,29 @@ static struct pci_pdev pci_pdev_array[CONFIG_MAX_PCI_DEV_NUM]; static void init_pdev(uint16_t pbdf); +/* @brief: Find the DRHD index corresponding to a PCI device + * Runs through the pci_pdev_array and returns the value in drhd_idx + * member from pdev strucutre that matches matches B:D.F + * + * @pbdf[in] B:D.F of a PCI device + * + * @return if there is a matching pbdf in pci_pdev_array, pdev->drhd_idx, else INVALID_DRHD_INDEX + */ + +uint32_t pci_lookup_drhd_for_pbdf(uint16_t pbdf) +{ + uint32_t drhd_index = INVALID_DRHD_INDEX; + uint32_t index; + + for (index = 0U; index < num_pci_pdev; index++) { + if (pci_pdev_array[index].bdf.value == pbdf) { + drhd_index = pci_pdev_array[index].drhd_index; + break; + } + } + + return drhd_index; +} static uint32_t pci_pdev_calc_address(union pci_bdf bdf, uint32_t offset) { diff --git a/hypervisor/include/arch/x86/vtd.h b/hypervisor/include/arch/x86/vtd.h index ea2c14625..50dd97724 100644 --- a/hypervisor/include/arch/x86/vtd.h +++ b/hypervisor/include/arch/x86/vtd.h @@ -10,6 +10,8 @@ #include #include +#define INVALID_DRHD_INDEX 0xFFFFFFFFU + /* * Intel IOMMU register specification per version 1.0 public spec. */ diff --git a/hypervisor/include/hw/pci.h b/hypervisor/include/hw/pci.h index 6e8afdd05..b856ef7e7 100644 --- a/hypervisor/include/hw/pci.h +++ b/hypervisor/include/hw/pci.h @@ -165,6 +165,9 @@ struct pci_msix_cap { }; struct pci_pdev { + /* IOMMU responsible for DMA and Interrupt Remapping for this device */ + uint32_t drhd_index; + /* The bar info of the physical PCI device. */ uint32_t nr_bars; /* 6 for normal device, 2 for bridge, 1 for cardbus */ @@ -236,6 +239,16 @@ void enable_disable_pci_intx(union pci_bdf bdf, bool enable); void init_pci_pdev_list(void); +/* @brief: Find the DRHD index corresponding to a PCI device + * Runs through the pci_pdev_array and returns the value in drhd_idx + * member from pdev strucutre that matches matches B:D.F + * + * @pbdf[in] B:D.F of a PCI device + * + * @return if there is a matching pbdf in pci_pdev_array, pdev->drhd_idx, else -1U + */ +uint32_t pci_lookup_drhd_for_pbdf(uint16_t pbdf); + static inline bool is_pci_vendor_valid(uint32_t vendor_id) { return !((vendor_id == 0xFFFFFFFFU) || (vendor_id == 0U) ||