dm:keep pci bar property unchanged when updating pci bar address

When update pci bar addr,
DM may change the bar property by func pci_cfgrw.
PCI spec chapter 'Base Addresses' shows
bits 0~3 are readonly of memeory space BAR,
so this change won't happen.

This patch ensures pci bar property unchanged
when update pci bar addr.

Tracked-On: #4282

Signed-off-by: Junming Liu <junming.liu@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
Reviewed-by: Shuo A Liu <shuo.a.liu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Junming Liu 2020-01-10 14:56:41 +00:00 committed by wenlingz
parent b59e5a870a
commit ceb197c993
1 changed files with 10 additions and 3 deletions

View File

@ -2236,6 +2236,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
int idx, needcfg; int idx, needcfg;
uint64_t addr, bar, mask; uint64_t addr, bar, mask;
bool decode, ignore_reg_unreg = false; bool decode, ignore_reg_unreg = false;
uint8_t mmio_bar_prop;
bi = pci_businfo[bus]; bi = pci_businfo[bus];
if (bi != NULL) { if (bi != NULL) {
@ -2342,6 +2343,11 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
} }
} }
/* save the bar property for MMIO pci bar. */
mmio_bar_prop = pci_get_cfgdata32(dev, PCIR_BAR(idx)) &
(PCIM_BAR_SPACE | PCIM_BAR_MEM_TYPE |
PCIM_BAR_MEM_PREFETCH);
switch (dev->bar[idx].type) { switch (dev->bar[idx].type) {
case PCIBAR_NONE: case PCIBAR_NONE:
dev->bar[idx].addr = bar = 0; dev->bar[idx].addr = bar = 0;
@ -2361,7 +2367,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
break; break;
case PCIBAR_MEM32: case PCIBAR_MEM32:
addr = bar = *eax & mask; addr = bar = *eax & mask;
bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; /* Restore the readonly fields for mmio bar */
bar |= mmio_bar_prop;
if (addr != dev->bar[idx].addr) { if (addr != dev->bar[idx].addr) {
update_bar_address(ctx, dev, addr, idx, update_bar_address(ctx, dev, addr, idx,
PCIBAR_MEM32, PCIBAR_MEM32,
@ -2370,8 +2377,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
break; break;
case PCIBAR_MEM64: case PCIBAR_MEM64:
addr = bar = *eax & mask; addr = bar = *eax & mask;
bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | /* Restore the readonly fields for mmio bar */
PCIM_BAR_MEM_PREFETCH; bar |= mmio_bar_prop;
if (addr != (uint32_t)dev->bar[idx].addr) { if (addr != (uint32_t)dev->bar[idx].addr) {
update_bar_address(ctx, dev, addr, idx, update_bar_address(ctx, dev, addr, idx,
PCIBAR_MEM64, PCIBAR_MEM64,