From 8115857956310bb7f0d67aa1babab84732c70c86 Mon Sep 17 00:00:00 2001 From: Jian Jun Chen Date: Fri, 15 Mar 2019 16:37:56 +0800 Subject: [PATCH] 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 Acked-by: Yin Fengwei --- devicemodel/hw/pci/core.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/devicemodel/hw/pci/core.c b/devicemodel/hw/pci/core.c index 2bb62384b..ce35230d0 100644 --- a/devicemodel/hw/pci/core.c +++ b/devicemodel/hw/pci/core.c @@ -703,12 +703,23 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase, void pci_emul_free_bars(struct pci_vdev *pdi) { - int i; + int i, enabled; for (i = 0; i < PCI_BARMAX; i++) { if ((pdi->bar[i].type != PCIBAR_NONE) && (pdi->bar[i].type != PCIBAR_MEMHI64)){ - unregister_bar(pdi, i); + /* + * 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; } }