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.
|
* @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)) {
|
} else if (sriovcap_access(vdev, offset)) {
|
||||||
write_sriov_cap_reg(vdev, offset, bytes, val);
|
write_sriov_cap_reg(vdev, offset, bytes, val);
|
||||||
} else {
|
} else {
|
||||||
if (!is_quirk_ptdev(vdev)) {
|
if (offset != vdev->pdev->sriov.pre_pos) {
|
||||||
/* passthru to physical device */
|
if (!is_quirk_ptdev(vdev)) {
|
||||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
/* passthru to physical device */
|
||||||
} else {
|
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||||
ret = -ENODEV;
|
} 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)) {
|
} else if (sriovcap_access(vdev, offset)) {
|
||||||
read_sriov_cap_reg(vdev, offset, bytes, val);
|
read_sriov_cap_reg(vdev, offset, bytes, val);
|
||||||
} else {
|
} 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 */
|
/* passthru to physical device */
|
||||||
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
||||||
} else {
|
} 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);
|
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 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_ */
|
#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)
|
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 */
|
if (!vdev->pdev->sriov.hide_sriov) {
|
||||||
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes);
|
/* 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;
|
uint32_t reg;
|
||||||
|
|
||||||
reg = offset - vdev->sriov.capoff;
|
reg = offset - vdev->sriov.capoff;
|
||||||
if (reg == PCIR_SRIOV_CONTROL) {
|
if (!vdev->pdev->sriov.hide_sriov) {
|
||||||
bool enable;
|
if (reg == PCIR_SRIOV_CONTROL) {
|
||||||
|
bool enable;
|
||||||
|
|
||||||
enable = (((val & PCIM_SRIOV_VF_ENABLE) != 0U) ? true : false);
|
enable = (((val & PCIM_SRIOV_VF_ENABLE) != 0U) ? true : false);
|
||||||
if (enable != is_vf_enabled(vdev)) {
|
if (enable != is_vf_enabled(vdev)) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
/*
|
/*
|
||||||
* set VF_ENABLE to PF physical device before enable_vfs
|
* set VF_ENABLE to PF physical device before enable_vfs
|
||||||
* since need to ask hardware to create VF physical
|
* since need to ask hardware to create VF physical
|
||||||
* devices firstly
|
* devices firstly
|
||||||
*/
|
*/
|
||||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||||
enable_vfs(vdev);
|
enable_vfs(vdev);
|
||||||
|
} else {
|
||||||
|
disable_vfs(vdev);
|
||||||
|
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||||
|
}
|
||||||
} else {
|
} 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);
|
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
|
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) {
|
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;
|
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) {
|
if (PCI_ECAP_ID(hdr) == PCIZ_SRIOV) {
|
||||||
pdev->sriov.capoff = pos;
|
pdev->sriov.capoff = pos;
|
||||||
pdev->sriov.caplen = PCI_SRIOV_CAP_LEN;
|
pdev->sriov.caplen = PCI_SRIOV_CAP_LEN;
|
||||||
|
pdev->sriov.pre_pos = pre_pos;
|
||||||
}
|
}
|
||||||
|
pre_pos = pos;
|
||||||
pos = PCI_ECAP_NEXT(hdr);
|
pos = PCI_ECAP_NEXT(hdr);
|
||||||
if (pos == 0U) {
|
if (pos == 0U) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,8 @@ struct pci_msix_cap {
|
|||||||
struct pci_sriov_cap {
|
struct pci_sriov_cap {
|
||||||
uint32_t capoff;
|
uint32_t capoff;
|
||||||
uint32_t caplen;
|
uint32_t caplen;
|
||||||
|
uint32_t pre_pos;
|
||||||
|
bool hide_sriov;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pci_pdev {
|
struct pci_pdev {
|
||||||
|
Loading…
Reference in New Issue
Block a user