dm: refine the reserved bar framework

1. refine the name of some functions and struct
2. add the support for PIO bar reservation

Tracked-On: #6508

Signed-off-by: Liu,Junming <junming.liu@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Liu,Junming 2021-09-08 11:26:57 +00:00 committed by wenlingz
parent 2ce85a18a7
commit d700154c90
3 changed files with 31 additions and 42 deletions

View File

@ -92,7 +92,7 @@ static uint64_t pci_emul_membase64;
extern bool skip_pci_mem64bar_workaround; extern bool skip_pci_mem64bar_workaround;
struct mmio_rsvd_rgn reserved_bar_regions[REGION_NUMS]; struct io_rsvd_rgn reserved_bar_regions[REGION_NUMS];
#define PCI_EMUL_IOBASE 0x2000 #define PCI_EMUL_IOBASE 0x2000
#define PCI_EMUL_IOLIMIT 0x10000 #define PCI_EMUL_IOLIMIT 0x10000
@ -107,12 +107,12 @@ static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot,
int func, int coff, int bytes, uint32_t *val); int func, int coff, int bytes, uint32_t *val);
static void pci_emul_free_msixcap(struct pci_vdev *pdi); static void pci_emul_free_msixcap(struct pci_vdev *pdi);
int compare_mmio_rgns(const void *data1, const void *data2) int compare_io_rgns(const void *data1, const void *data2)
{ {
struct mmio_rsvd_rgn *rng1, *rng2; struct io_rsvd_rgn *rng1, *rng2;
rng1 = (struct mmio_rsvd_rgn*)data1; rng1 = (struct io_rsvd_rgn*)data1;
rng2 = (struct mmio_rsvd_rgn*)data2; rng2 = (struct io_rsvd_rgn*)data2;
if(!rng1->vdev) if(!rng1->vdev)
return 1; return 1;
@ -126,16 +126,11 @@ int compare_mmio_rgns(const void *data1, const void *data2)
* Due to we only has gvt-g to use this feature, * Due to we only has gvt-g to use this feature,
* this case rarely happen. * this case rarely happen.
*/ */
int create_mmio_rsvd_rgn(uint64_t start, int reserve_io_rgn(uint64_t start,
uint64_t end, int idx, int bar_type, struct pci_vdev *vdev) uint64_t end, int idx, int bar_type, struct pci_vdev *vdev)
{ {
int i; 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++){ for(i = 0; i < REGION_NUMS; i++){
if(reserved_bar_regions[i].vdev == NULL){ if(reserved_bar_regions[i].vdev == NULL){
reserved_bar_regions[i].start = start; reserved_bar_regions[i].start = start;
@ -145,10 +140,10 @@ int create_mmio_rsvd_rgn(uint64_t start,
reserved_bar_regions[i].vdev = vdev; reserved_bar_regions[i].vdev = vdev;
/* sort reserved_bar_regions array by "start" member, /* sort reserved_bar_regions array by "start" member,
* if this mmio_rsvd_rgn is not used, put it in the last. * if this io_rsvd_rgn is not used, put it in the last.
*/ */
qsort((void*)reserved_bar_regions, REGION_NUMS, qsort((void*)reserved_bar_regions, REGION_NUMS,
sizeof(reserved_bar_regions[0]), compare_mmio_rgns); sizeof(reserved_bar_regions[0]), compare_io_rgns);
return 0; return 0;
} }
} }
@ -157,7 +152,7 @@ int create_mmio_rsvd_rgn(uint64_t start,
return -1; return -1;
} }
void destory_mmio_rsvd_rgns(struct pci_vdev *vdev){ void destory_io_rsvd_rgns(struct pci_vdev *vdev){
int i; int i;
for(i = 0; i < REGION_NUMS; i++) for(i = 0; i < REGION_NUMS; i++)
@ -166,18 +161,18 @@ void destory_mmio_rsvd_rgns(struct pci_vdev *vdev){
} }
static bool static bool
is_mmio_rgns_overlap(uint64_t x1, uint64_t x2, uint64_t y1, uint64_t y2) is_io_rgns_overlap(uint64_t x1, uint64_t x2, uint64_t y1, uint64_t y2)
{ {
if(x1 <= y2 && y1 <= x2) if(x1 <= y2 && y1 <= x2)
return true; return true;
return false; return false;
} }
/* reserved_bar_regions has sorted mmio_rsvd_rgns. /* reserved_bar_regions has sorted io_rsvd_rgns.
* iterate all mmio_rsvd_rgn in reserved_bar_regions, * iterate all io_rsvd_rgn in reserved_bar_regions,
* if [base, base + size - 1] with any mmio_rsvd_rgn, * if [base, base + size - 1] with any io_rsvd_rgn,
* adjust base addr to ensure [base, base + size - 1] * adjust base addr to ensure [base, base + size - 1]
* won't overlap with reserved mmio_rsvd_rgn * won't overlap with reserved io_rsvd_rgn
*/ */
static void static void
adjust_bar_region(uint64_t *base, uint64_t size, int bar_type) adjust_bar_region(uint64_t *base, uint64_t size, int bar_type)
@ -188,7 +183,7 @@ adjust_bar_region(uint64_t *base, uint64_t size, int bar_type)
if(!reserved_bar_regions[i].vdev || if(!reserved_bar_regions[i].vdev ||
reserved_bar_regions[i].bar_type != bar_type) reserved_bar_regions[i].bar_type != bar_type)
continue; continue;
if(is_mmio_rgns_overlap(reserved_bar_regions[i].start, if(is_io_rgns_overlap(reserved_bar_regions[i].start,
reserved_bar_regions[i].end, *base, *base + size -1)){ reserved_bar_regions[i].end, *base, *base + size -1)){
*base = roundup2(reserved_bar_regions[i].end + 1, size); *base = roundup2(reserved_bar_regions[i].end + 1, size);
} }
@ -574,13 +569,7 @@ pci_emul_alloc_resource(uint64_t *baseptr, uint64_t limit, uint64_t size,
size = PAGE_SIZE; size = PAGE_SIZE;
base = roundup2(*baseptr, size); base = roundup2(*baseptr, size);
/* TODO:Currently, we only reserve gvt mmio regions, adjust_bar_region(&base, size, bar_type);
* 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);
if (base + size <= limit) { if (base + size <= limit) {
*addr = base; *addr = base;
@ -741,8 +730,8 @@ update_bar_address(struct vmctx *ctx, struct pci_vdev *dev, uint64_t addr,
register_bar(dev, idx); register_bar(dev, idx);
} }
static struct mmio_rsvd_rgn * static struct io_rsvd_rgn *
get_mmio_rsvd_rgn_by_vdev_idx(struct pci_vdev *pdi, int idx) get_io_rsvd_rgn_by_vdev_idx(struct pci_vdev *pdi, int idx)
{ {
int i; int i;
@ -762,7 +751,7 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
{ {
int error; int error;
uint64_t *baseptr, limit, addr, mask, lobits, bar; uint64_t *baseptr, limit, addr, mask, lobits, bar;
struct mmio_rsvd_rgn *region; struct io_rsvd_rgn *region;
if ((size & (size - 1)) != 0) if ((size & (size - 1)) != 0)
size = 1UL << flsl(size); /* round up to a power of 2 */ size = 1UL << flsl(size); /* round up to a power of 2 */
@ -831,7 +820,7 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
return -1; return -1;
} }
region = get_mmio_rsvd_rgn_by_vdev_idx(pdi, idx); region = get_io_rsvd_rgn_by_vdev_idx(pdi, idx);
if(region) if(region)
addr = region->start; addr = region->start;

View File

@ -132,13 +132,13 @@ update_gvt_bar(struct vmctx *ctx)
} }
} }
destory_mmio_rsvd_rgns(gvt_dev); destory_io_rsvd_rgns(gvt_dev);
ret = create_mmio_rsvd_rgn(bar0_start_addr, ret = reserve_io_rgn(bar0_start_addr,
bar0_end_addr, 0, PCIBAR_MEM32, gvt_dev); bar0_end_addr, 0, PCIBAR_MEM32, gvt_dev);
if(ret != 0) if(ret != 0)
return; return;
ret = create_mmio_rsvd_rgn(bar2_start_addr, ret = reserve_io_rgn(bar2_start_addr,
bar2_end_addr, 2, PCIBAR_MEM32, gvt_dev); bar2_end_addr, 2, PCIBAR_MEM32, gvt_dev);
if(ret != 0) if(ret != 0)
return; return;
@ -211,11 +211,11 @@ gvt_init_config(struct pci_gvt *gvt)
/* In GVT-g design, it only use pci bar0 and bar2, /* In GVT-g design, it only use pci bar0 and bar2,
* So we need reserve bar0 region and bar2 region only * So we need reserve bar0 region and bar2 region only
*/ */
ret = create_mmio_rsvd_rgn(bar0_start_addr, ret = reserve_io_rgn(bar0_start_addr,
bar0_end_addr, 0, PCIBAR_MEM32, gvt->gvt_pi); bar0_end_addr, 0, PCIBAR_MEM32, gvt->gvt_pi);
if(ret != 0) if(ret != 0)
return -1; return -1;
ret = create_mmio_rsvd_rgn(bar2_start_addr, ret = reserve_io_rgn(bar2_start_addr,
bar2_end_addr, 2, PCIBAR_MEM32, gvt->gvt_pi); bar2_end_addr, 2, PCIBAR_MEM32, gvt->gvt_pi);
if(ret != 0) if(ret != 0)
return -1; return -1;
@ -413,7 +413,7 @@ pci_gvt_deinit(struct vmctx *ctx, struct pci_vdev *pi, char *opts)
if (ret) if (ret)
WPRINTF(("GVT: %s: failed: errno=%d\n", __func__, ret)); WPRINTF(("GVT: %s: failed: errno=%d\n", __func__, ret));
destory_mmio_rsvd_rgns(gvt_dev); destory_io_rsvd_rgns(gvt_dev);
free(gvt); free(gvt);
pi->arg = NULL; pi->arg = NULL;
gvt_dev = NULL; gvt_dev = NULL;

View File

@ -249,19 +249,19 @@ struct pciecap {
} __attribute__((packed)); } __attribute__((packed));
static_assert(sizeof(struct pciecap) == 60, "compile-time assertion failed"); static_assert(sizeof(struct pciecap) == 60, "compile-time assertion failed");
struct mmio_rsvd_rgn { struct io_rsvd_rgn {
uint64_t start; uint64_t start;
uint64_t end; uint64_t end;
int idx; int idx;
int bar_type; int bar_type;
/* if vdev=NULL, it also indicates this mmio_rsvd_rgn is not used */ /* if vdev=NULL, it also indicates this io_rsvd_rgn is not used */
struct pci_vdev *vdev; struct pci_vdev *vdev;
}; };
extern struct mmio_rsvd_rgn reserved_bar_regions[REGION_NUMS]; extern struct io_rsvd_rgn reserved_bar_regions[REGION_NUMS];
int create_mmio_rsvd_rgn(uint64_t start, int reserve_io_rgn(uint64_t start,
uint64_t end, int idx, int bar_type, struct pci_vdev *vdev); uint64_t end, int idx, int bar_type, struct pci_vdev *vdev);
void destory_mmio_rsvd_rgns(struct pci_vdev *vdev); void destory_io_rsvd_rgns(struct pci_vdev *vdev);
/* Reserved region in e820 table for GVT /* Reserved region in e820 table for GVT
* for GVT-g use: * for GVT-g use: