Skip to content

Commit 811d1fe

Browse files
chejianjwenlingz
authored andcommitted
dm: pci: update MMIO EPT mapping when update BAR address
For PCI passthrough device when guest OS updates the BAR address the corresponding EPT mapping should be updated as well. Tracked-On: #2962 Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com> Signed-off-by: Liu Shuo A <shuo.a.liu@intel.com> Reviewed-by: Binbin Wu <binbin.wu@intel.com> Acked-by: Yin Fengwei <fengwei.yin@intel.com>
1 parent cee2f8b commit 811d1fe

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

devicemodel/hw/pci/core.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,11 @@ memen(struct pci_vdev *dev)
594594
* the address range decoded by the BAR register.
595595
*/
596596
static void
597-
update_bar_address(struct pci_vdev *dev, uint64_t addr, int idx, int type)
597+
update_bar_address(struct vmctx *ctx, struct pci_vdev *dev, uint64_t addr,
598+
int idx, int type)
598599
{
599600
bool decode;
601+
uint64_t orig_addr = dev->bar[idx].addr;
600602

601603
if (dev->bar[idx].type == PCIBAR_IO)
602604
decode = porten(dev);
@@ -625,6 +627,10 @@ update_bar_address(struct pci_vdev *dev, uint64_t addr, int idx, int type)
625627

626628
if (decode)
627629
register_bar(dev, idx);
630+
631+
/* update bar mapping */
632+
if (dev->dev_ops->vdev_update_bar_map)
633+
dev->dev_ops->vdev_update_bar_map(ctx, dev, idx, orig_addr);
628634
}
629635

630636
int
@@ -2136,15 +2142,15 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
21362142
* Register the new BAR value for interception
21372143
*/
21382144
if (addr != dev->bar[idx].addr) {
2139-
update_bar_address(dev, addr, idx,
2145+
update_bar_address(ctx, dev, addr, idx,
21402146
PCIBAR_IO);
21412147
}
21422148
break;
21432149
case PCIBAR_MEM32:
21442150
addr = bar = *eax & mask;
21452151
bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32;
21462152
if (addr != dev->bar[idx].addr) {
2147-
update_bar_address(dev, addr, idx,
2153+
update_bar_address(ctx, dev, addr, idx,
21482154
PCIBAR_MEM32);
21492155
}
21502156
break;
@@ -2153,7 +2159,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
21532159
bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 |
21542160
PCIM_BAR_MEM_PREFETCH;
21552161
if (addr != (uint32_t)dev->bar[idx].addr) {
2156-
update_bar_address(dev, addr, idx,
2162+
update_bar_address(ctx, dev, addr, idx,
21572163
PCIBAR_MEM64);
21582164
}
21592165
break;
@@ -2163,7 +2169,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
21632169
addr = ((uint64_t)*eax << 32) & mask;
21642170
bar = addr >> 32;
21652171
if (bar != dev->bar[idx - 1].addr >> 32) {
2166-
update_bar_address(dev, addr, idx - 1,
2172+
update_bar_address(ctx, dev, addr, idx - 1,
21672173
PCIBAR_MEMHI64);
21682174
}
21692175
break;

devicemodel/hw/pci/passthrough.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,39 @@ passthru_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
938938
vm_unassign_ptdev(ctx, bus, slot, func);
939939
}
940940

941+
static void
942+
passthru_update_bar_map(struct vmctx *ctx, struct pci_vdev *dev,
943+
int idx, uint64_t orig_addr)
944+
{
945+
struct passthru_dev *ptdev;
946+
947+
if (!dev->arg) {
948+
warnx("%s: passthru_dev is NULL", __func__);
949+
return;
950+
}
951+
952+
ptdev = (struct passthru_dev *)dev->arg;
953+
954+
if (ptdev->bar[idx].size == 0 ||
955+
idx == ptdev_msix_table_bar(ptdev) ||
956+
ptdev->bar[idx].type == PCIBAR_IO)
957+
return;
958+
959+
if (dev->bar[idx].addr + dev->bar[idx].size > PCI_EMUL_MEMLIMIT64 ||
960+
orig_addr + dev->bar[idx].size > PCI_EMUL_MEMLIMIT64)
961+
return;
962+
963+
vm_unmap_ptdev_mmio(ctx, ptdev->sel.bus,
964+
ptdev->sel.dev, ptdev->sel.func,
965+
orig_addr, ptdev->bar[idx].size,
966+
ptdev->bar[idx].addr);
967+
968+
vm_map_ptdev_mmio(ctx, ptdev->sel.bus,
969+
ptdev->sel.dev, ptdev->sel.func,
970+
dev->bar[idx].addr, ptdev->bar[idx].size,
971+
ptdev->bar[idx].addr);
972+
}
973+
941974
/* bind pin info for pass-through device */
942975
static void
943976
passthru_bind_irq(struct vmctx *ctx, struct pci_vdev *dev)
@@ -1767,6 +1800,7 @@ struct pci_vdev_ops passthru = {
17671800
.vdev_barwrite = passthru_write,
17681801
.vdev_barread = passthru_read,
17691802
.vdev_phys_access = passthru_bind_irq,
1803+
.vdev_update_bar_map = passthru_update_bar_map,
17701804
.vdev_write_dsdt = passthru_write_dsdt,
17711805
};
17721806
DEFINE_PCI_DEVTYPE(passthru);

devicemodel/include/pci_core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ struct pci_vdev_ops {
6464
/* ops related to physical resources */
6565
void (*vdev_phys_access)(struct vmctx *ctx, struct pci_vdev *dev);
6666

67+
/* update BAR map callback */
68+
void (*vdev_update_bar_map)(struct vmctx *ctx,
69+
struct pci_vdev *dev, int idx,
70+
uint64_t orig_addr);
71+
6772
/* config space read/write callbacks */
6873
int (*vdev_cfgwrite)(struct vmctx *ctx, int vcpu,
6974
struct pci_vdev *pi, int offset,

0 commit comments

Comments
 (0)