From 96085d960fd80451a38fda4b5600e915ae710ba2 Mon Sep 17 00:00:00 2001 From: Yin Fengwei Date: Fri, 13 Apr 2018 18:03:02 +0800 Subject: [PATCH] DM: release mem range allocated in init_pci Two memory ranges are allocated: - PCI ECFG - PCI hole They should be released when deinit_pci. Old code mark this two ranges not unregistered. Which is wrong for warm reboot case. Make them could be unregistered. Signed-off-by: Yin Fengwei Acked-by: Anthony Xu --- devicemodel/core/mem.c | 28 ++++++++++++++++++++++++++++ devicemodel/hw/pci/core.c | 21 +++++++++++++++++++-- devicemodel/include/mem.h | 1 + 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/devicemodel/core/mem.c b/devicemodel/core/mem.c index 74b0dbfa1..11118dbd3 100644 --- a/devicemodel/core/mem.c +++ b/devicemodel/core/mem.c @@ -234,6 +234,34 @@ register_mem_fallback(struct mem_range *memp) return register_mem_int(&mmio_rb_fallback, memp); } +int +unregister_mem_fallback(struct mem_range *memp) +{ + struct mem_range *mr; + struct mmio_rb_range *entry = NULL; + int err; + + pthread_rwlock_wrlock(&mmio_rwlock); + err = mmio_rb_lookup(&mmio_rb_fallback, memp->base, &entry); + if (err == 0) { + mr = &entry->mr_param; + assert(mr->name == memp->name); + assert(mr->base == memp->base && mr->size == memp->size); + assert((mr->flags & MEM_F_IMMUTABLE) == 0); + RB_REMOVE(mmio_rb_tree, &mmio_rb_fallback, entry); + + /* flush Per-VM cache */ + if (mmio_hint == entry) + mmio_hint = NULL; + } + pthread_rwlock_unlock(&mmio_rwlock); + + if (entry) + free(entry); + + return err; +} + int unregister_mem(struct mem_range *memp) { diff --git a/devicemodel/hw/pci/core.c b/devicemodel/hw/pci/core.c index b28b00088..9391248b4 100644 --- a/devicemodel/hw/pci/core.c +++ b/devicemodel/hw/pci/core.c @@ -1204,7 +1204,7 @@ init_pci(struct vmctx *ctx) lowmem = vm_get_lowmem_size(ctx); bzero(&mr, sizeof(struct mem_range)); mr.name = "PCI hole"; - mr.flags = MEM_F_RW | MEM_F_IMMUTABLE; + mr.flags = MEM_F_RW; mr.base = lowmem; mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; mr.handler = pci_emul_fallback_handler; @@ -1214,7 +1214,7 @@ init_pci(struct vmctx *ctx) /* PCI extended config space */ bzero(&mr, sizeof(struct mem_range)); mr.name = "PCI ECFG"; - mr.flags = MEM_F_RW | MEM_F_IMMUTABLE; + mr.flags = MEM_F_RW; mr.base = PCI_EMUL_ECFG_BASE; mr.size = PCI_EMUL_ECFG_SIZE; mr.handler = pci_emul_ecfg_handler; @@ -1232,6 +1232,23 @@ deinit_pci(struct vmctx *ctx) struct slotinfo *si; struct funcinfo *fi; int bus, slot, func; + size_t lowmem; + struct mem_range mr; + + /* Release PCI extended config space */ + bzero(&mr, sizeof(struct mem_range)); + mr.name = "PCI ECFG"; + mr.base = PCI_EMUL_ECFG_BASE; + mr.size = PCI_EMUL_ECFG_SIZE; + unregister_mem(&mr); + + /* Release PCI hole space */ + lowmem = vm_get_lowmem_size(ctx); + bzero(&mr, sizeof(struct mem_range)); + mr.name = "PCI hole"; + mr.base = lowmem; + mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; + unregister_mem_fallback(&mr); for (bus = 0; bus < MAXBUSES; bus++) { bi = pci_businfo[bus]; diff --git a/devicemodel/include/mem.h b/devicemodel/include/mem.h index 15572053b..5240102b1 100644 --- a/devicemodel/include/mem.h +++ b/devicemodel/include/mem.h @@ -53,5 +53,6 @@ int emulate_mem(struct vmctx *ctx, struct mmio_request *mmio_req); int register_mem(struct mem_range *memp); int register_mem_fallback(struct mem_range *memp); int unregister_mem(struct mem_range *memp); +int unregister_mem_fallback(struct mem_range *memp); #endif /* _MEM_H_ */