From cf345269d9f7fab2dd253e7aaf9c8f343cce74ad Mon Sep 17 00:00:00 2001 From: Fei Li Date: Tue, 31 Aug 2021 16:32:26 +0800 Subject: [PATCH] dm: identical mapping of pass-thru dev PIO bar For pass-thru dev PIO bar,keep identical mapping Tracked-On: #6508 Signed-off-by: Fei Li --- devicemodel/hw/pci/core.c | 126 +++++++++++++++++++------------ devicemodel/hw/pci/passthrough.c | 7 +- devicemodel/include/pci_core.h | 6 +- 3 files changed, 85 insertions(+), 54 deletions(-) diff --git a/devicemodel/hw/pci/core.c b/devicemodel/hw/pci/core.c index 5ad84151c..85c569945 100644 --- a/devicemodel/hw/pci/core.c +++ b/devicemodel/hw/pci/core.c @@ -131,11 +131,6 @@ int create_mmio_rsvd_rgn(uint64_t start, { int i; - if(bar_type == PCIBAR_IO){ - pr_err("fail to create PCIBAR_IO bar_type\n"); - return -1; - } - for(i = 0; i < REGION_NUMS; i++){ if(reserved_bar_regions[i].vdev == NULL){ reserved_bar_regions[i].start = start; @@ -574,13 +569,7 @@ pci_emul_alloc_resource(uint64_t *baseptr, uint64_t limit, uint64_t size, size = PAGE_SIZE; base = roundup2(*baseptr, size); - /* TODO:Currently, we only reserve gvt mmio regions, - * so ignore PCIBAR_IO when adjust_bar_region. - * If other devices also use reserved bar regions later, - * need remove pcibar_type != PCIBAR_IO condition - */ - if(bar_type != PCIBAR_IO) - adjust_bar_region(&base, size, bar_type); + adjust_bar_region(&base, size, bar_type); if (base + size <= limit) { *addr = base; @@ -1381,8 +1370,8 @@ init_pci(struct vmctx *ctx) struct businfo *bi; struct slotinfo *si; struct funcinfo *fi; - int bus, slot, func, i; - int success_cnt = 0; + int bus, slot, func, i,j; + int success_cnt[2] = {0}; /* 0 for passthru and 1 for others */ int error; uint64_t bus0_memlimit; @@ -1404,25 +1393,34 @@ init_pci(struct vmctx *ctx) bi->membase32 = pci_emul_membase32; bi->membase64 = pci_emul_membase64; - for (slot = 0; slot < MAXSLOTS; slot++) { - 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; + for (j = 0; j < 2; j++) { + for (slot = 0; slot < MAXSLOTS; slot++) { + 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 ((j == 0) && strcmp(ops->class_name, "passthru")) { + pr_warn("init passthru first to reserve PIO BAR\n"); + continue; + } else if ((j == 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[j]++; } - 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++; } } @@ -1463,6 +1461,24 @@ init_pci(struct vmctx *ctx) } bi->memlimit32 = bus0_memlimit; + 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; + break; + } + } + + for (i = REGION_NUMS - 1; i >= 0; i--) { + if(reserved_bar_regions[i].vdev && + reserved_bar_regions[i].bar_type == PCIBAR_IO) { + if (reserved_bar_regions[i].end + 1 > bi->iolimit) + bi->iolimit = reserved_bar_regions[i].end + 1; + break; + } + } + error = check_gsi_sharing_violation(); if (error < 0) goto pci_emul_init_fail; @@ -1543,25 +1559,35 @@ init_pci(struct vmctx *ctx) return 0; pci_emul_init_fail: - for (bus = 0; bus < MAXBUSES && success_cnt > 0; bus++) { - bi = pci_businfo[bus]; - if (bi == NULL) - continue; - for (slot = 0; slot < MAXSLOTS && success_cnt > 0; slot++) { - si = &bi->slotinfo[slot]; - for (func = 0; func < MAXFUNCS; func++) { - fi = &si->si_funcs[func]; - if (fi->fi_name == NULL) - continue; - if (success_cnt-- <= 0) - break; - ops = pci_emul_finddev(fi->fi_name); - if (!ops) { - pr_warn("No driver for device [%s]\n", fi->fi_name); - continue; + for (j = 0; j < 2; j++) { + for (bus = 0; bus < MAXBUSES && success_cnt[j] > 0; bus++) { + bi = pci_businfo[bus]; + if (bi == NULL) + continue; + for (slot = 0; slot < MAXSLOTS && success_cnt[j] > 0; slot++) { + si = &bi->slotinfo[slot]; + for (func = 0; func < MAXFUNCS; func++) { + fi = &si->si_funcs[func]; + if (fi->fi_name == NULL) + continue; + if (success_cnt[j]-- <= 0) + break; + ops = pci_emul_finddev(fi->fi_name); + if (!ops) { + pr_warn("No driver for device [%s]\n", fi->fi_name); + continue; + } + + if ((j == 0) && strcmp(ops->class_name, "passthru")) { + pr_warn("init passthru first to reserve PIO BAR\n"); + continue; + } else if ((j == 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); } } } diff --git a/devicemodel/hw/pci/passthrough.c b/devicemodel/hw/pci/passthrough.c index 00584a93c..1fbe6a26f 100644 --- a/devicemodel/hw/pci/passthrough.c +++ b/devicemodel/hw/pci/passthrough.c @@ -243,7 +243,12 @@ cfginitbar(struct vmctx *ctx, struct passthru_dev *ptdev) if (size == 0) continue; - /* Allocate the BAR in the guest I/O or MMIO space */ + if (bartype == PCIBAR_IO) + error = create_mmio_rsvd_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); if (error) return -1; diff --git a/devicemodel/include/pci_core.h b/devicemodel/include/pci_core.h index c61895757..c21a39f54 100644 --- a/devicemodel/include/pci_core.h +++ b/devicemodel/include/pci_core.h @@ -51,10 +51,10 @@ #define SOFTWARE_SRAM_MAX_SIZE 0x00800000UL #define SOFTWARE_SRAM_BASE_GPA (PCI_EMUL_MEMBASE32 - SOFTWARE_SRAM_MAX_SIZE) -/* Currently,only gvt need reserved bar regions, - * so just hardcode REGION_NUMS=5 here +/* + * GVT BARs + PTDEV IO BARs */ -#define REGION_NUMS 5 +#define REGION_NUMS 32 struct vmctx; struct pci_vdev;