dm: register_bar/unregister_bar when bar enable/disable

Sometimes guest OS writes PCIR_COMMAND register to disable the device,
then update the bar address followed by a write to PCIR_COMMAND register
to enable the device again. In this case unregister_bar/register_bar
should be called otherwise the IO/MMIO regions monitored by device model
will not be updated accordingly.

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:
Liu Shuo A 2018-12-17 15:06:53 +08:00 committed by wenlingz
parent b838e9b720
commit d648df766c
1 changed files with 5 additions and 65 deletions

View File

@ -541,66 +541,6 @@ register_bar(struct pci_vdev *dev, int idx)
modify_bar_registration(dev, idx, 1);
}
static void
enable_bar(struct pci_vdev *dev, int idx)
{
int error = 0;
struct inout_port iop;
struct mem_range mr;
switch (dev->bar[idx].type) {
case PCIBAR_IO:
bzero(&iop, sizeof(struct inout_port));
iop.name = dev->name;
iop.port = dev->bar[idx].addr;
iop.size = dev->bar[idx].size;
error = enable_inout(&iop);
break;
case PCIBAR_MEM32:
case PCIBAR_MEM64:
bzero(&mr, sizeof(struct mem_range));
mr.name = dev->name;
mr.base = dev->bar[idx].addr;
mr.size = dev->bar[idx].size;
error = enable_mem(&mr);
break;
default:
error = EINVAL;
break;
}
assert(error == 0);
}
static void
disable_bar(struct pci_vdev *dev, int idx)
{
int error = 0;
struct inout_port iop;
struct mem_range mr;
switch (dev->bar[idx].type) {
case PCIBAR_IO:
bzero(&iop, sizeof(struct inout_port));
iop.name = dev->name;
iop.port = dev->bar[idx].addr;
iop.size = dev->bar[idx].size;
error = disable_inout(&iop);
break;
case PCIBAR_MEM32:
case PCIBAR_MEM64:
bzero(&mr, sizeof(struct mem_range));
mr.name = dev->name;
mr.base = dev->bar[idx].addr;
mr.size = dev->bar[idx].size;
error = disable_mem(&mr);
break;
default:
error = EINVAL;
break;
}
assert(error == 0);
}
/* Are we decoding i/o port accesses for the emulated pci device? */
static int
porten(struct pci_vdev *dev)
@ -2023,9 +1963,9 @@ pci_emul_cmdsts_write(struct pci_vdev *dev, int coff, uint32_t new, int bytes)
/* I/O address space decoding changed? */
if (changed & PCIM_CMD_PORTEN) {
if (porten(dev))
enable_bar(dev, i);
register_bar(dev, i);
else
disable_bar(dev, i);
unregister_bar(dev, i);
}
break;
case PCIBAR_MEM32:
@ -2033,10 +1973,10 @@ pci_emul_cmdsts_write(struct pci_vdev *dev, int coff, uint32_t new, int bytes)
/* MMIO address space decoding changed? */
if (changed & PCIM_CMD_MEMEN) {
if (memen(dev))
enable_bar(dev, i);
register_bar(dev, i);
else
disable_bar(dev, i);
}
unregister_bar(dev, i);
}
break;
default:
assert(0);