mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 12:42:54 +00:00
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;
|
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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user