dm:gvt:update gvt bars before other pci devices write bar address

The current design has the following problem:
uos kernel may update gvt bars' regions,
but ACRN-DM doesn't know this update.
ACRN-DM only know out-of-date gvt bar regions,
For simplicity, mark these bar regions as OOD bar regions.
uos kernel may allocate OOD bar regions for
other pci devices, which will result in ACRN-DM
bar regions inconsistency with uos kernel.

The new design is the following:
When other pci device update bar regions
(1) ACRN-DM updates gvt bars' regions
provided by a system file.
(2) ACRN-DM updates this pci device bar regions

v5 -> v6:
	* add more comments

v4 -> v5:
	* remove & for callback func assignment

v3 -> v4:
	* compare gpu bar address to avoid unnecessary
	* unregistered/registered operation

v2 -> v3:
	* call unregister_bar and register_bar when update gvt bars
	* update gvt reserved regions when update gvt bars

Tracked-On: projectacrn#4005

Signed-off-by: Junming Liu <junming.liu@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
Reviewed-by: Liu XinYun <xinyun.liu@intel.com>
Reviewed-by: Shuo A Liu <shuo.a.liu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Junming Liu
2019-11-12 21:19:39 +00:00
committed by wenlingz
parent f27d47542a
commit 89908bf510
4 changed files with 106 additions and 19 deletions

View File

@@ -710,6 +710,19 @@ update_bar_address(struct vmctx *ctx, struct pci_vdev *dev, uint64_t addr,
if (decode)
unregister_bar(dev, idx);
/* TODO:Currently, we only reserve gvt mmio regions,
* so ignore PCIBAR_IO when adjust_bar_region_with_reserved_bars.
* If other devices also use reserved bar regions later,
* need remove pcibar_type != PCIBAR_IO condition
*/
if(type != PCIBAR_IO && ctx->gvt_enabled)
/* uos kernel may update gvt bars' value,
* but ACRN-DM doesn't know this update.
* When other pci devices write bar address,
* ACRN-DM need update vgpu bars' info.
*/
ctx->update_gvt_bar(ctx);
switch (type) {
case PCIBAR_IO:
case PCIBAR_MEM32:
@@ -867,30 +880,36 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
return 0;
}
void
pci_emul_free_bar(struct pci_vdev *pdi, int idx)
{
bool enabled;
if ((pdi->bar[idx].type != PCIBAR_NONE) &&
(pdi->bar[idx].type != PCIBAR_MEMHI64)){
/*
* Check whether the bar is enabled or not,
* if it is disabled then it should have been
* unregistered in pci_emul_cmdsts_write.
*/
if (pdi->bar[idx].type == PCIBAR_IO)
enabled = porten(pdi);
else
enabled = memen(pdi);
if (enabled)
unregister_bar(pdi, idx);
pdi->bar[idx].type = PCIBAR_NONE;
}
}
void
pci_emul_free_bars(struct pci_vdev *pdi)
{
int i;
bool enabled;
for (i = 0; i < PCI_BARMAX; i++) {
if ((pdi->bar[i].type != PCIBAR_NONE) &&
(pdi->bar[i].type != PCIBAR_MEMHI64)){
/*
* Check whether the bar is enabled or not,
* if it is disabled then it should have been
* unregistered in pci_emul_cmdsts_write.
*/
if (pdi->bar[i].type == PCIBAR_IO)
enabled = porten(pdi);
else
enabled = memen(pdi);
if (enabled)
unregister_bar(pdi, i);
pdi->bar[i].type = PCIBAR_NONE;
}
}
for (i = 0; i < PCI_BARMAX; i++)
pci_emul_free_bar(pdi, i);
}
#define CAP_START_OFFSET 0x40