dm: ensure identical mapping of pass-thru dev PIO bar
For pass-thru dev PIO bar,ensure it's identical mapping (guest PIO bar start address equals to host PIO bar start address). Then in HV side, set the corresponding VMCS io bitmap to pass-thru these io ports for performance. Tracked-On: #6508 Signed-off-by: Fei Li <fei1.li@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
d700154c90
commit
30d2915309
|
@ -1371,7 +1371,7 @@ init_pci(struct vmctx *ctx)
|
||||||
struct slotinfo *si;
|
struct slotinfo *si;
|
||||||
struct funcinfo *fi;
|
struct funcinfo *fi;
|
||||||
int bus, slot, func, i;
|
int bus, slot, func, i;
|
||||||
int success_cnt = 0;
|
int success_cnt[2] = {0}; /* 0 for passthru and 1 for others */
|
||||||
int error;
|
int error;
|
||||||
uint64_t bus0_memlimit;
|
uint64_t bus0_memlimit;
|
||||||
|
|
||||||
|
@ -1393,25 +1393,40 @@ init_pci(struct vmctx *ctx)
|
||||||
bi->membase32 = pci_emul_membase32;
|
bi->membase32 = pci_emul_membase32;
|
||||||
bi->membase64 = pci_emul_membase64;
|
bi->membase64 = pci_emul_membase64;
|
||||||
|
|
||||||
for (slot = 0; slot < MAXSLOTS; slot++) {
|
/*
|
||||||
si = &bi->slotinfo[slot];
|
* Initialize pass-thru devices firstly to reserve PIO bar regions.
|
||||||
for (func = 0; func < MAXFUNCS; func++) {
|
* For pass-thru devices, ACRN-DM need to ensure PIO bar regions identical mapping
|
||||||
fi = &si->si_funcs[func];
|
* (guest PIO bar start address equals to host PIO bar start address).
|
||||||
if (fi->fi_name == NULL)
|
*
|
||||||
continue;
|
* Then initialize non pass-thru devices.
|
||||||
ops = pci_emul_finddev(fi->fi_name);
|
*/
|
||||||
if (!ops) {
|
for (i = 0; i < 2; i++) {
|
||||||
pr_warn("No driver for device [%s]\n", fi->fi_name);
|
for (slot = 0; slot < MAXSLOTS; slot++) {
|
||||||
continue;
|
si = &bi->slotinfo[slot];
|
||||||
|
for (func = 0; func < MAXFUNCS; func++) {
|
||||||
|
fi = &si->si_funcs[func];
|
||||||
|
if (fi->fi_name == NULL)
|
||||||
|
continue;
|
||||||
|
ops = pci_emul_finddev(fi->fi_name);
|
||||||
|
if (!ops) {
|
||||||
|
pr_warn("No driver for device [%s]\n", fi->fi_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i == 0) && strcmp(ops->class_name, "passthru")) {
|
||||||
|
continue;
|
||||||
|
} else if ((i == 1) && !strcmp(ops->class_name, "passthru")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_notice("pci init %s\r\n", fi->fi_name);
|
||||||
|
error = pci_emul_init(ctx, ops, bus, slot, func, fi);
|
||||||
|
if (error) {
|
||||||
|
pr_err("pci %s init failed\n", fi->fi_name);
|
||||||
|
goto pci_emul_init_fail;
|
||||||
|
}
|
||||||
|
success_cnt[i]++;
|
||||||
}
|
}
|
||||||
pr_notice("pci init %s\r\n", fi->fi_name);
|
|
||||||
error = pci_emul_init(ctx, ops, bus, slot,
|
|
||||||
func, fi);
|
|
||||||
if (error) {
|
|
||||||
pr_err("pci %s init failed\n", fi->fi_name);
|
|
||||||
goto pci_emul_init_fail;
|
|
||||||
}
|
|
||||||
success_cnt++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1452,6 +1467,19 @@ init_pci(struct vmctx *ctx)
|
||||||
}
|
}
|
||||||
bi->memlimit32 = bus0_memlimit;
|
bi->memlimit32 = bus0_memlimit;
|
||||||
|
|
||||||
|
/* Update the PIO window in the guest ACPI DSDT table */
|
||||||
|
for (i = 0; i < REGION_NUMS; i++) {
|
||||||
|
if (reserved_bar_regions[i].vdev &&
|
||||||
|
reserved_bar_regions[i].bar_type == PCIBAR_IO) {
|
||||||
|
if (reserved_bar_regions[i].start < bi->iobase) {
|
||||||
|
bi->iobase = reserved_bar_regions[i].start;
|
||||||
|
}
|
||||||
|
if ((reserved_bar_regions[i].end + 1) > bi->iolimit) {
|
||||||
|
bi->iolimit = reserved_bar_regions[i].end + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error = check_gsi_sharing_violation();
|
error = check_gsi_sharing_violation();
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto pci_emul_init_fail;
|
goto pci_emul_init_fail;
|
||||||
|
@ -1532,25 +1560,34 @@ init_pci(struct vmctx *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pci_emul_init_fail:
|
pci_emul_init_fail:
|
||||||
for (bus = 0; bus < MAXBUSES && success_cnt > 0; bus++) {
|
for (i = 0; i < 2; i++) {
|
||||||
bi = pci_businfo[bus];
|
for (bus = 0; bus < MAXBUSES && success_cnt[i] > 0; bus++) {
|
||||||
if (bi == NULL)
|
bi = pci_businfo[bus];
|
||||||
continue;
|
if (bi == NULL)
|
||||||
for (slot = 0; slot < MAXSLOTS && success_cnt > 0; slot++) {
|
continue;
|
||||||
si = &bi->slotinfo[slot];
|
for (slot = 0; slot < MAXSLOTS && success_cnt[i] > 0; slot++) {
|
||||||
for (func = 0; func < MAXFUNCS; func++) {
|
si = &bi->slotinfo[slot];
|
||||||
fi = &si->si_funcs[func];
|
for (func = 0; func < MAXFUNCS; func++) {
|
||||||
if (fi->fi_name == NULL)
|
fi = &si->si_funcs[func];
|
||||||
continue;
|
if (fi->fi_name == NULL)
|
||||||
if (success_cnt-- <= 0)
|
continue;
|
||||||
break;
|
if (success_cnt[i]-- <= 0)
|
||||||
ops = pci_emul_finddev(fi->fi_name);
|
break;
|
||||||
if (!ops) {
|
ops = pci_emul_finddev(fi->fi_name);
|
||||||
pr_warn("No driver for device [%s]\n", fi->fi_name);
|
if (!ops) {
|
||||||
continue;
|
pr_warn("No driver for device [%s]\n", fi->fi_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i == 0) && strcmp(ops->class_name, "passthru")) {
|
||||||
|
continue;
|
||||||
|
} else if ((i == 1) && !strcmp(ops->class_name, "passthru")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_emul_deinit(ctx, ops, bus, slot,
|
||||||
|
func, fi);
|
||||||
}
|
}
|
||||||
pci_emul_deinit(ctx, ops, bus, slot,
|
|
||||||
func, fi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,12 @@ cfginitbar(struct vmctx *ctx, struct passthru_dev *ptdev)
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Allocate the BAR in the guest I/O or MMIO space */
|
if (bartype == PCIBAR_IO)
|
||||||
|
error = reserve_io_rgn(base, base + size - 1, i, PCIBAR_IO, dev);
|
||||||
|
if (error)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Allocate the BAR in the guest MMIO space */
|
||||||
error = pci_emul_alloc_pbar(dev, i, base, bartype, size);
|
error = pci_emul_alloc_pbar(dev, i, base, bartype, size);
|
||||||
if (error)
|
if (error)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -750,6 +755,8 @@ passthru_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destory_io_rsvd_rgns(dev);
|
||||||
|
|
||||||
ptdev = (struct passthru_dev *) dev->arg;
|
ptdev = (struct passthru_dev *) dev->arg;
|
||||||
|
|
||||||
pr_info("vm_reset_ptdev_intx:0x%x-%x, ioapic virpin=%d.\n",
|
pr_info("vm_reset_ptdev_intx:0x%x-%x, ioapic virpin=%d.\n",
|
||||||
|
|
|
@ -51,10 +51,8 @@
|
||||||
#define SOFTWARE_SRAM_MAX_SIZE 0x00800000UL
|
#define SOFTWARE_SRAM_MAX_SIZE 0x00800000UL
|
||||||
#define SOFTWARE_SRAM_BASE_GPA (PCI_EMUL_MEMBASE32 - SOFTWARE_SRAM_MAX_SIZE)
|
#define SOFTWARE_SRAM_BASE_GPA (PCI_EMUL_MEMBASE32 - SOFTWARE_SRAM_MAX_SIZE)
|
||||||
|
|
||||||
/* Currently,only gvt need reserved bar regions,
|
/* GVT BARs + PTDEV IO BARs */
|
||||||
* so just hardcode REGION_NUMS=5 here
|
#define REGION_NUMS 32
|
||||||
*/
|
|
||||||
#define REGION_NUMS 5
|
|
||||||
|
|
||||||
struct vmctx;
|
struct vmctx;
|
||||||
struct pci_vdev;
|
struct pci_vdev;
|
||||||
|
|
Loading…
Reference in New Issue