Skip to content

Commit 37b1c13

Browse files
yisun-gitacrnsi-robot
authored andcommitted
hv: pci: refine codes to make Service VM can manage bridge
In previous codes, the bridge is owned by hypervsior if there is pre-launched VM configured. This can cause bug, e.g. the net card behind the bridge cannot get IP because the write to bridge's command register to set BusMaster bit is ignored. This patch is to refine the codes to make the bridge be managed by Service VM if the device behind the bridge is not assigned to pre-launched VM. Furthermore, it adds the parent device into struct pci_pdev to construct PCI hierarchy. Tracked-On: #8849 Signed-off-by: Yi Sun <yi.y.sun@intel.com>
1 parent bc90c7b commit 37b1c13

File tree

5 files changed

+22
-14
lines changed

5 files changed

+22
-14
lines changed

hypervisor/arch/x86/configs/pci_dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/*
1313
* @pre pdev != NULL;
1414
*/
15-
static bool allocate_to_prelaunched_vm(struct pci_pdev *pdev)
15+
bool allocate_to_prelaunched_vm(struct pci_pdev *pdev)
1616
{
1717
bool found = false;
1818
uint16_t vmid;

hypervisor/dm/vpci/vsriov.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static void create_vf(struct pci_vdev *pf_vdev, union pci_bdf vf_bdf, uint16_t v
9191
* Per VT-d 8.3.3, the VFs are under the scope of the same
9292
* remapping unit as the associated PF when SRIOV is enabled.
9393
*/
94-
vf_pdev = pci_init_pdev(vf_bdf, pf_vdev->pdev->drhd_index);
94+
vf_pdev = pci_init_pdev(vf_bdf, pf_vdev->pdev->drhd_index, pf_vdev->pdev->parent);
9595
if (vf_pdev != NULL) {
9696
struct acrn_vm_pci_dev_config *dev_cfg;
9797

hypervisor/hw/pci.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ struct pci_bdf_mapping_group {
384384
struct pci_bus_num_to_drhd_index_mapping {
385385
uint8_t bus_under_scan;
386386
uint32_t bus_drhd_index;
387+
struct pci_pdev *parent_pdev;
387388
};
388389

389390
static uint32_t pci_check_override_drhd_index(union pci_bdf pbdf,
@@ -421,16 +422,19 @@ static void scan_pci_hierarchy(uint8_t bus, uint64_t buses_visited[BUSES_BITMAP_
421422
uint8_t current_bus_index;
422423
uint32_t current_drhd_index, bdf_drhd_index;
423424
struct pci_pdev *pdev;
425+
struct pci_pdev *parent = NULL;
424426

425427
struct pci_bus_num_to_drhd_index_mapping bus_map[PCI_BUSMAX + 1U]; /* FIFO queue of buses to walk */
426428
uint32_t s = 0U, e = 0U; /* start and end index into queue */
427429

428430
bus_map[e].bus_under_scan = bus;
429431
bus_map[e].bus_drhd_index = drhd_index;
432+
bus_map[e].parent_pdev = NULL;
430433
e = e + 1U;
431434
while (s < e) {
432435
current_bus_index = bus_map[s].bus_under_scan;
433436
current_drhd_index = bus_map[s].bus_drhd_index;
437+
parent = bus_map[s].parent_pdev;
434438
s = s + 1U;
435439

436440
bitmap_set_nolock(current_bus_index,
@@ -462,12 +466,13 @@ static void scan_pci_hierarchy(uint8_t bus, uint64_t buses_visited[BUSES_BITMAP_
462466

463467
bdf_drhd_index = pci_check_override_drhd_index(pbdf, bdfs_from_drhds,
464468
current_drhd_index);
465-
pdev = pci_init_pdev(pbdf, bdf_drhd_index);
469+
pdev = pci_init_pdev(pbdf, bdf_drhd_index, parent);
466470
/* NOTE: This touch logic change: if a bridge own by HV as its children */
467471
if ((pdev != NULL) && is_bridge(pdev)) {
468472
bus_map[e].bus_under_scan =
469473
(uint8_t)pci_pdev_read_cfg(pbdf, PCIR_SECBUS_1, 1U);
470474
bus_map[e].bus_drhd_index = bdf_drhd_index;
475+
bus_map[e].parent_pdev = pdev;
471476
e = e + 1U;
472477
}
473478
}
@@ -841,11 +846,10 @@ static void pci_enumerate_cap(struct pci_pdev *pdev)
841846
*
842847
* @return If there's a successfully initialized pdev return it, otherwise return NULL;
843848
*/
844-
struct pci_pdev *pci_init_pdev(union pci_bdf bdf, uint32_t drhd_index)
849+
struct pci_pdev *pci_init_pdev(union pci_bdf bdf, uint32_t drhd_index, struct pci_pdev *parent)
845850
{
846851
uint8_t hdr_type, hdr_layout;
847852
struct pci_pdev *pdev = NULL;
848-
bool is_hv_owned = false;
849853

850854
if (num_pci_pdev < CONFIG_MAX_PCI_DEV_NUM) {
851855
hdr_type = (uint8_t)pci_pdev_read_cfg(bdf, PCIR_HDRTYPE, 1U);
@@ -855,6 +859,7 @@ struct pci_pdev *pci_init_pdev(union pci_bdf bdf, uint32_t drhd_index)
855859
pdev = &pci_pdevs[num_pci_pdev];
856860
pdev->bdf = bdf;
857861
pdev->hdr_type = hdr_type;
862+
pdev->parent = parent;
858863
pdev->base_class = (uint8_t)pci_pdev_read_cfg(bdf, PCIR_CLASS, 1U);
859864
pdev->sub_class = (uint8_t)pci_pdev_read_cfg(bdf, PCIR_SUBCLASS, 1U);
860865
pdev->nr_bars = pci_pdev_get_nr_bars(hdr_type);
@@ -864,17 +869,17 @@ struct pci_pdev *pci_init_pdev(union pci_bdf bdf, uint32_t drhd_index)
864869
pci_enumerate_cap(pdev);
865870
}
866871

867-
#if (PRE_VM_NUM != 0U)
868-
/* HV owned pdev: 1.typ1 pdev if pre-launched VM exist; 2.pci debug uart */
869-
is_hv_owned = (hdr_layout == PCIM_HDRTYPE_BRIDGE) || is_pci_dbg_uart(bdf);
870-
#else
871-
/* HV owned pdev: 1.pci debug uart */
872-
is_hv_owned = is_pci_dbg_uart(bdf);
873-
#endif
874-
if (is_hv_owned) {
872+
/* PCI debug uart and RP for EP which has been assigned to pre-launched VM are owned by HV */
873+
if (is_pci_dbg_uart(bdf)) {
875874
hv_owned_pci_pdevs[num_hv_owned_pci_pdev] = pdev;
876875
num_hv_owned_pci_pdev++;
877876
}
877+
878+
if (allocate_to_prelaunched_vm(pdev) && parent) {
879+
hv_owned_pci_pdevs[num_hv_owned_pci_pdev] = parent;
880+
num_hv_owned_pci_pdev++;
881+
}
882+
878883
hlist_add_head(&pdev->link, &pdevs_hlist_heads[hash64(bdf.value, PDEV_HLIST_HASHBITS)]);
879884
pdev->drhd_index = drhd_index;
880885
num_pci_pdev++;

hypervisor/include/arch/x86/asm/pci_dev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ extern struct acrn_vm_pci_dev_config sos_pci_devs[CONFIG_MAX_PCI_DEV_NUM];
1313

1414
struct pci_pdev;
1515
struct acrn_vm_pci_dev_config *init_one_dev_config(struct pci_pdev *pdev);
16+
bool allocate_to_prelaunched_vm(struct pci_pdev *pdev);
1617

1718
#endif /* PCI_DEV_H_ */

hypervisor/include/hw/pci.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ struct pci_pdev {
307307
bool has_flr;
308308
bool has_af_flr;
309309
struct hlist_node link;
310+
311+
struct pci_pdev *parent;
310312
};
311313

312314
struct pci_cfg_ops {
@@ -363,7 +365,7 @@ void set_mmcfg_region(struct pci_mmcfg_region *region);
363365
#endif
364366
struct pci_mmcfg_region *get_mmcfg_region(void);
365367

366-
struct pci_pdev *pci_init_pdev(union pci_bdf pbdf, uint32_t drhd_index);
368+
struct pci_pdev *pci_init_pdev(union pci_bdf pbdf, uint32_t drhd_index, struct pci_pdev *parent);
367369
uint32_t pci_pdev_read_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes);
368370
void pci_pdev_write_cfg(union pci_bdf bdf, uint32_t offset, uint32_t bytes, uint32_t val);
369371
void enable_disable_pci_intx(union pci_bdf bdf, bool enable);

0 commit comments

Comments
 (0)