dm: pci: unregister bars which are still enabled in pci_emul_free_bars

Guest OS for example Windows will disable bars before shutdown. Bars
are unregistered when they are disabled. Trying to unregister a bar
which has been unregistered causes a assertion. In pci_emul_free_bars
only those enabled bars should be unregistered.

Tracked-On: #2962
Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
Acked-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
Jian Jun Chen 2019-03-15 16:37:56 +08:00 committed by wenlingz
parent fd389cb15c
commit 8115857956
1 changed files with 13 additions and 2 deletions

View File

@ -703,11 +703,22 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
void void
pci_emul_free_bars(struct pci_vdev *pdi) pci_emul_free_bars(struct pci_vdev *pdi)
{ {
int i; int i, enabled;
for (i = 0; i < PCI_BARMAX; i++) { for (i = 0; i < PCI_BARMAX; i++) {
if ((pdi->bar[i].type != PCIBAR_NONE) && if ((pdi->bar[i].type != PCIBAR_NONE) &&
(pdi->bar[i].type != PCIBAR_MEMHI64)){ (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); unregister_bar(pdi, i);
pdi->bar[i].type = PCIBAR_NONE; pdi->bar[i].type = PCIBAR_NONE;
} }