dm: fix deadlock between emulate_mem and un/register_mem
There is a deadlock when emulate_mem is called on the memory region of PCI extended configuration space. The call trace is something like: emulate_mem -> pci_emul_ecfg_handler -> pci_cfgrw -> pci_emul_cmdsts_write -> unregister_bar/register_bar -> modify_bar_registration -> unregister_mem/register_mem mmio_rwlock is hold in emulate_mem when calling unregister_mem/ register_mem which is trying to acquire mmio_rwlock again, and deadlock happened. It is possible that bar address is changed just between a on-going MMIO access which can bring a race condition in theroy. Guest needs to take care of the serial operation between bar addess update and MMIO access of that bar. Tracked-On: #2962 Signed-off-by: Yu Wang <yu1.wang@intel.com> Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com> Signed-off-by: Liu Shuo A <shuo.a.liu@intel.com> Acked-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
parent
d648df766c
commit
fa7f6c2c83
|
@ -182,8 +182,10 @@ emulate_mem(struct vmctx *ctx, struct mmio_request *mmio_req)
|
|||
assert(entry != NULL);
|
||||
|
||||
if (entry->enabled == false) {
|
||||
pthread_rwlock_unlock(&mmio_rwlock);
|
||||
return -1;
|
||||
}
|
||||
pthread_rwlock_unlock(&mmio_rwlock);
|
||||
|
||||
if (mmio_req->direction == REQUEST_READ)
|
||||
err = mem_read(ctx, 0, paddr, (uint64_t *)&mmio_req->value,
|
||||
|
@ -192,8 +194,6 @@ emulate_mem(struct vmctx *ctx, struct mmio_request *mmio_req)
|
|||
err = mem_write(ctx, 0, paddr, mmio_req->value,
|
||||
size, &entry->mr_param);
|
||||
|
||||
pthread_rwlock_unlock(&mmio_rwlock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue