mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-11 13:03:15 +00:00
HV: vdev passthough hidding SRIOV
Support hide SRIOV extend capability for passthough device Tracked-On: #5041 Signed-off-by: Tao Yuhong <yuhong.tao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com> Reviewed-by: Fei Li <fei1.li@intel.com>
This commit is contained in:
parent
585c652f81
commit
eb36337622
@ -345,6 +345,21 @@ static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar)
|
||||
}
|
||||
}
|
||||
|
||||
void vdev_pt_hide_sriov_cap(struct pci_vdev *vdev)
|
||||
{
|
||||
uint32_t pre_pos = vdev->pdev->sriov.pre_pos;
|
||||
uint32_t pre_hdr, hdr, vhdr;
|
||||
|
||||
pre_hdr = pci_pdev_read_cfg(vdev->pdev->bdf, pre_pos, 4U);
|
||||
hdr = pci_pdev_read_cfg(vdev->pdev->bdf, vdev->pdev->sriov.capoff, 4U);
|
||||
|
||||
vhdr = pre_hdr & 0xfffffU;
|
||||
vhdr |= hdr & 0xfff00000U;
|
||||
pci_vdev_write_vcfg(vdev, pre_pos, 4U, vhdr);
|
||||
vdev->pdev->sriov.hide_sriov = true;
|
||||
|
||||
pr_acrnlog("Hide sriov cap for %02x:%02x.%x", vdev->pdev->bdf.bits.b, vdev->pdev->bdf.bits.d, vdev->pdev->bdf.bits.f);
|
||||
}
|
||||
/*
|
||||
* @brief Initialize a specified passthrough vdev structure.
|
||||
*
|
||||
|
@ -494,11 +494,13 @@ static int32_t write_pt_dev_cfg(struct pci_vdev *vdev, uint32_t offset,
|
||||
} else if (sriovcap_access(vdev, offset)) {
|
||||
write_sriov_cap_reg(vdev, offset, bytes, val);
|
||||
} else {
|
||||
if (!is_quirk_ptdev(vdev)) {
|
||||
/* passthru to physical device */
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
if (offset != vdev->pdev->sriov.pre_pos) {
|
||||
if (!is_quirk_ptdev(vdev)) {
|
||||
/* passthru to physical device */
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,7 +521,9 @@ static int32_t read_pt_dev_cfg(const struct pci_vdev *vdev, uint32_t offset,
|
||||
} else if (sriovcap_access(vdev, offset)) {
|
||||
read_sriov_cap_reg(vdev, offset, bytes, val);
|
||||
} else {
|
||||
if (!is_quirk_ptdev(vdev)) {
|
||||
if (offset == vdev->pdev->sriov.pre_pos) {
|
||||
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
|
||||
} else if (!is_quirk_ptdev(vdev)) {
|
||||
/* passthru to physical device */
|
||||
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
||||
} else {
|
||||
|
@ -156,4 +156,6 @@ void pci_vdev_write_vcfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes,
|
||||
|
||||
uint32_t pci_vdev_read_vbar(const struct pci_vdev *vdev, uint32_t idx);
|
||||
void pci_vdev_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val);
|
||||
|
||||
void vdev_pt_hide_sriov_cap(struct pci_vdev *vdev);
|
||||
#endif /* VPCI_PRIV_H_ */
|
||||
|
@ -273,8 +273,12 @@ void init_vsriov(struct pci_vdev *vdev)
|
||||
*/
|
||||
void read_sriov_cap_reg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val)
|
||||
{
|
||||
/* no need to do emulation, passthrough to physical device directly */
|
||||
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
||||
if (!vdev->pdev->sriov.hide_sriov) {
|
||||
/* no need to do emulation, passthrough to physical device directly */
|
||||
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
||||
} else {
|
||||
*val = 0xffffffffU;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,41 +291,43 @@ void write_sriov_cap_reg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes,
|
||||
uint32_t reg;
|
||||
|
||||
reg = offset - vdev->sriov.capoff;
|
||||
if (reg == PCIR_SRIOV_CONTROL) {
|
||||
bool enable;
|
||||
if (!vdev->pdev->sriov.hide_sriov) {
|
||||
if (reg == PCIR_SRIOV_CONTROL) {
|
||||
bool enable;
|
||||
|
||||
enable = (((val & PCIM_SRIOV_VF_ENABLE) != 0U) ? true : false);
|
||||
if (enable != is_vf_enabled(vdev)) {
|
||||
if (enable) {
|
||||
/*
|
||||
* set VF_ENABLE to PF physical device before enable_vfs
|
||||
* since need to ask hardware to create VF physical
|
||||
* devices firstly
|
||||
*/
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
enable_vfs(vdev);
|
||||
enable = (((val & PCIM_SRIOV_VF_ENABLE) != 0U) ? true : false);
|
||||
if (enable != is_vf_enabled(vdev)) {
|
||||
if (enable) {
|
||||
/*
|
||||
* set VF_ENABLE to PF physical device before enable_vfs
|
||||
* since need to ask hardware to create VF physical
|
||||
* devices firstly
|
||||
*/
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
enable_vfs(vdev);
|
||||
} else {
|
||||
disable_vfs(vdev);
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
}
|
||||
} else {
|
||||
disable_vfs(vdev);
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
}
|
||||
} else if (reg == PCIR_SRIOV_NUMVFS) {
|
||||
uint16_t total;
|
||||
|
||||
total = read_sriov_reg(vdev, PCIR_SRIOV_TOTAL_VFS);
|
||||
/*
|
||||
* sanity check for NumVFs register based on PCE Express Base 4.0 9.3.3.7 chapter
|
||||
* The results are undefined if NumVFs is set to a value greater than TotalVFs
|
||||
* NumVFs may only be written while VF Enable is Clear
|
||||
* If NumVFs is written when VF Enable is Set, the results are undefined
|
||||
*/
|
||||
if ((((uint16_t)(val & 0xFFU)) <= total) && (!is_vf_enabled(vdev))) {
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
}
|
||||
} else {
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
}
|
||||
} else if (reg == PCIR_SRIOV_NUMVFS) {
|
||||
uint16_t total;
|
||||
|
||||
total = read_sriov_reg(vdev, PCIR_SRIOV_TOTAL_VFS);
|
||||
/*
|
||||
* sanity check for NumVFs register based on PCE Express Base 4.0 9.3.3.7 chapter
|
||||
* The results are undefined if NumVFs is set to a value greater than TotalVFs
|
||||
* NumVFs may only be written while VF Enable is Clear
|
||||
* If NumVFs is written when VF Enable is Set, the results are undefined
|
||||
*/
|
||||
if ((((uint16_t)(val & 0xFFU)) <= total) && (!is_vf_enabled(vdev))) {
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
}
|
||||
} else {
|
||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,7 +663,7 @@ static inline uint32_t pci_pdev_get_nr_bars(uint8_t hdr_type)
|
||||
*/
|
||||
static void pci_enumerate_ext_cap(struct pci_pdev *pdev) {
|
||||
|
||||
uint32_t hdr, pos;
|
||||
uint32_t hdr, pos, pre_pos = 0U;
|
||||
|
||||
pos = PCI_ECAP_BASE_PTR;
|
||||
|
||||
@ -673,12 +673,13 @@ static void pci_enumerate_ext_cap(struct pci_pdev *pdev) {
|
||||
if (PCI_ECAP_ID(hdr) == PCIZ_SRIOV) {
|
||||
pdev->sriov.capoff = pos;
|
||||
pdev->sriov.caplen = PCI_SRIOV_CAP_LEN;
|
||||
pdev->sriov.pre_pos = pre_pos;
|
||||
}
|
||||
pre_pos = pos;
|
||||
pos = PCI_ECAP_NEXT(hdr);
|
||||
if (pos == 0U) {
|
||||
break;
|
||||
}
|
||||
|
||||
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
||||
};
|
||||
}
|
||||
|
@ -221,6 +221,8 @@ struct pci_msix_cap {
|
||||
struct pci_sriov_cap {
|
||||
uint32_t capoff;
|
||||
uint32_t caplen;
|
||||
uint32_t pre_pos;
|
||||
bool hide_sriov;
|
||||
};
|
||||
|
||||
struct pci_pdev {
|
||||
|
Loading…
Reference in New Issue
Block a user