Skip to content

Commit 1fddf94

Browse files
lifeixwenlingz
authored andcommitted
hv: vpci: restore PCI BARs when doing AF FLR
ACRN hypervisor should trap guest doing PCI AF FLR. Besides, it should save some status before doing the FLR and restore them later, only BARs values for now. This patch will trap guest Conventional PCI Advanced Features Control Register write operation if the device supports Conventional PCI Advanced Features Capability and check whether it wants to do device AF FLR. If it does, call pdev_do_flr to do the job. Tracked-On: #3465 Signed-off-by: Li Fei1 <fei1.li@intel.com>
1 parent a90e0f6 commit 1fddf94

File tree

5 files changed

+26
-5
lines changed

5 files changed

+26
-5
lines changed

hypervisor/dm/vpci/pci_pt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ void init_vdev_pt(struct pci_vdev *vdev)
235235

236236
vdev->has_flr = vdev->pdev->has_flr;
237237
vdev->pcie_capoff = vdev->pdev->pcie_capoff;
238+
vdev->has_af_flr = vdev->pdev->has_af_flr;
239+
vdev->af_capoff = vdev->pdev->af_capoff;
238240

239241
for (idx = 0U; idx < vdev->nr_bars; idx++) {
240242
vbar = &vdev->bar[idx];

hypervisor/dm/vpci/vpci.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,9 @@ static int32_t vpci_write_pt_dev_cfg(struct pci_vdev *vdev, uint32_t offset,
337337
vmsi_write_cfg(vdev, offset, bytes, val);
338338
} else if (msixcap_access(vdev, offset)) {
339339
vmsix_write_cfg(vdev, offset, bytes, val);
340-
} else if (vdev->has_flr && ((vdev->pcie_capoff + PCIR_PCIE_DEVCTRL) == offset) &&
341-
((val & PCIM_PCIE_FLR) != 0U)) {
340+
} else if ((vdev->has_flr && ((vdev->pcie_capoff + PCIR_PCIE_DEVCTRL) == offset) &&
341+
((val & PCIM_PCIE_FLR) != 0U)) || (vdev->has_af_flr &&
342+
((vdev->af_capoff + PCIR_AF_CTRL) == offset) && ((val & PCIM_AF_FLR) != 0U))) {
342343
/* Assume that guest write FLR must be 4 bytes aligned */
343344
pdev_do_flr(vdev->pdev->bdf, offset, bytes, val);
344345
} else {

hypervisor/hw/pci.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,15 @@ static void pci_read_cap(struct pci_pdev *pdev)
418418
uint32_t msgctrl;
419419
uint32_t len, offset, idx;
420420
uint32_t table_info;
421-
uint32_t pcie_devcap;
421+
uint32_t pcie_devcap, val;
422422

423423
ptr = (uint8_t)pci_pdev_read_cfg(pdev->bdf, PCIR_CAP_PTR, 1U);
424424

425425
while ((ptr != 0U) && (ptr != 0xFFU)) {
426426
cap = (uint8_t)pci_pdev_read_cfg(pdev->bdf, ptr + PCICAP_ID, 1U);
427427

428428
/* Ignore all other Capability IDs for now */
429-
if ((cap == PCIY_MSI) || (cap == PCIY_MSIX) || (cap == PCIY_PCIE)) {
429+
if ((cap == PCIY_MSI) || (cap == PCIY_MSIX) || (cap == PCIY_PCIE) || (cap == PCIY_AF)) {
430430
offset = ptr;
431431
if (cap == PCIY_MSI) {
432432
pdev->msi_capoff = offset;
@@ -451,11 +451,16 @@ static void pci_read_cap(struct pci_pdev *pdev)
451451
for (idx = 0U; idx < len; idx++) {
452452
pdev->msix.cap[idx] = (uint8_t)pci_pdev_read_cfg(pdev->bdf, offset + idx, 1U);
453453
}
454-
} else {
454+
} else if (cap == PCIY_PCIE) {
455455
/* PCI Express Capability */
456456
pdev->pcie_capoff = offset;
457457
pcie_devcap = pci_pdev_read_cfg(pdev->bdf, offset + PCIR_PCIE_DEVCAP, 4U);
458458
pdev->has_flr = ((pcie_devcap & PCIM_PCIE_FLRCAP) != 0U) ? true : false;
459+
} else {
460+
/* Conventional PCI Advanced Features Capability */
461+
pdev->af_capoff = offset;
462+
val = pci_pdev_read_cfg(pdev->bdf, offset, 4U);
463+
pdev->has_af_flr = ((val & PCIM_AF_FLR_CAP) != 0U) ? true : false;
459464
}
460465
}
461466

hypervisor/include/dm/vpci.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ struct pci_vdev {
102102
bool has_flr;
103103
uint32_t pcie_capoff;
104104

105+
bool has_af_flr;
106+
uint32_t af_capoff;
107+
105108
/* Pointer to corresponding PCI device's vm_config */
106109
struct acrn_vm_pci_dev_config *pci_dev_config;
107110

hypervisor/include/hw/pci.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@
138138
#define PCIM_PCIE_FLRCAP (0x1U << 28U)
139139
#define PCIM_PCIE_FLR (0x1U << 15U)
140140

141+
/* Conventional PCI Advanced Features Capability */
142+
#define PCIY_AF 0x13U
143+
#define PCIM_AF_FLR_CAP (0x1U << 25U)
144+
#define PCIR_AF_CTRL 0x4U
145+
#define PCIM_AF_FLR 0x1U
146+
141147
#define HOST_BRIDGE_BDF 0U
142148
#define PCI_STD_NUM_BARS 6U
143149

@@ -189,6 +195,10 @@ struct pci_pdev {
189195
/* Function Level Reset Capability */
190196
bool has_flr;
191197
uint32_t pcie_capoff;
198+
199+
/* Conventional PCI Advanced Features FLR Capability */
200+
bool has_af_flr;
201+
uint32_t af_capoff;
192202
};
193203

194204
static inline uint32_t pci_bar_offset(uint32_t idx)

0 commit comments

Comments
 (0)