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:
parent
2ce85a18a7
commit
d700154c90
|
@ -92,7 +92,7 @@ static uint64_t pci_emul_membase64;
|
|||
|
||||
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_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);
|
||||
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;
|
||||
rng2 = (struct mmio_rsvd_rgn*)data2;
|
||||
rng1 = (struct io_rsvd_rgn*)data1;
|
||||
rng2 = (struct io_rsvd_rgn*)data2;
|
||||
|
||||
if(!rng1->vdev)
|
||||
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,
|
||||
* 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)
|
||||
{
|
||||
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;
|
||||
|
@ -145,10 +140,10 @@ int create_mmio_rsvd_rgn(uint64_t start,
|
|||
reserved_bar_regions[i].vdev = vdev;
|
||||
|
||||
/* 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,
|
||||
sizeof(reserved_bar_regions[0]), compare_mmio_rgns);
|
||||
sizeof(reserved_bar_regions[0]), compare_io_rgns);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +152,7 @@ int create_mmio_rsvd_rgn(uint64_t start,
|
|||
return -1;
|
||||
}
|
||||
|
||||
void destory_mmio_rsvd_rgns(struct pci_vdev *vdev){
|
||||
void destory_io_rsvd_rgns(struct pci_vdev *vdev){
|
||||
int i;
|
||||
|
||||
for(i = 0; i < REGION_NUMS; i++)
|
||||
|
@ -166,18 +161,18 @@ void destory_mmio_rsvd_rgns(struct pci_vdev *vdev){
|
|||
}
|
||||
|
||||
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)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* reserved_bar_regions has sorted mmio_rsvd_rgns.
|
||||
* iterate all mmio_rsvd_rgn in reserved_bar_regions,
|
||||
* if [base, base + size - 1] with any mmio_rsvd_rgn,
|
||||
/* reserved_bar_regions has sorted io_rsvd_rgns.
|
||||
* iterate all io_rsvd_rgn in reserved_bar_regions,
|
||||
* if [base, base + size - 1] with any io_rsvd_rgn,
|
||||
* 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
|
||||
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 ||
|
||||
reserved_bar_regions[i].bar_type != bar_type)
|
||||
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)){
|
||||
*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;
|
||||
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;
|
||||
|
@ -741,8 +730,8 @@ update_bar_address(struct vmctx *ctx, struct pci_vdev *dev, uint64_t addr,
|
|||
register_bar(dev, idx);
|
||||
}
|
||||
|
||||
static struct mmio_rsvd_rgn *
|
||||
get_mmio_rsvd_rgn_by_vdev_idx(struct pci_vdev *pdi, int idx)
|
||||
static struct io_rsvd_rgn *
|
||||
get_io_rsvd_rgn_by_vdev_idx(struct pci_vdev *pdi, int idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -762,7 +751,7 @@ pci_emul_alloc_pbar(struct pci_vdev *pdi, int idx, uint64_t hostbase,
|
|||
{
|
||||
int error;
|
||||
uint64_t *baseptr, limit, addr, mask, lobits, bar;
|
||||
struct mmio_rsvd_rgn *region;
|
||||
struct io_rsvd_rgn *region;
|
||||
|
||||
if ((size & (size - 1)) != 0)
|
||||
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;
|
||||
}
|
||||
|
||||
region = get_mmio_rsvd_rgn_by_vdev_idx(pdi, idx);
|
||||
region = get_io_rsvd_rgn_by_vdev_idx(pdi, idx);
|
||||
if(region)
|
||||
addr = region->start;
|
||||
|
||||
|
|
|
@ -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);
|
||||
if(ret != 0)
|
||||
return;
|
||||
ret = create_mmio_rsvd_rgn(bar2_start_addr,
|
||||
ret = reserve_io_rgn(bar2_start_addr,
|
||||
bar2_end_addr, 2, PCIBAR_MEM32, gvt_dev);
|
||||
if(ret != 0)
|
||||
return;
|
||||
|
@ -211,11 +211,11 @@ gvt_init_config(struct pci_gvt *gvt)
|
|||
/* In GVT-g design, it only use pci bar0 and bar2,
|
||||
* 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);
|
||||
if(ret != 0)
|
||||
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);
|
||||
if(ret != 0)
|
||||
return -1;
|
||||
|
@ -413,7 +413,7 @@ pci_gvt_deinit(struct vmctx *ctx, struct pci_vdev *pi, char *opts)
|
|||
if (ret)
|
||||
WPRINTF(("GVT: %s: failed: errno=%d\n", __func__, ret));
|
||||
|
||||
destory_mmio_rsvd_rgns(gvt_dev);
|
||||
destory_io_rsvd_rgns(gvt_dev);
|
||||
free(gvt);
|
||||
pi->arg = NULL;
|
||||
gvt_dev = NULL;
|
||||
|
|
|
@ -249,19 +249,19 @@ struct pciecap {
|
|||
} __attribute__((packed));
|
||||
static_assert(sizeof(struct pciecap) == 60, "compile-time assertion failed");
|
||||
|
||||
struct mmio_rsvd_rgn {
|
||||
struct io_rsvd_rgn {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
int idx;
|
||||
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;
|
||||
};
|
||||
|
||||
extern struct mmio_rsvd_rgn reserved_bar_regions[REGION_NUMS];
|
||||
int create_mmio_rsvd_rgn(uint64_t start,
|
||||
extern struct io_rsvd_rgn reserved_bar_regions[REGION_NUMS];
|
||||
int reserve_io_rgn(uint64_t start,
|
||||
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
|
||||
* for GVT-g use:
|
||||
|
|
Loading…
Reference in New Issue