mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-10 04:28:31 +00:00
hv: vPCI: cache PCI BAR physical base address
PCI BAR physical base address will never changed. Cache it to avoid calculating it every time when we access it. Tracked-On: #3475 Signed-off-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
parent
5083aba379
commit
6ebc22210b
@ -115,17 +115,6 @@ static uint64_t get_vbar_base(const struct pci_vdev *vdev, uint32_t idx)
|
|||||||
return pci_bar_2_bar_base(&vdev->bar[0], vdev->nr_bars, idx);
|
return pci_bar_2_bar_base(&vdev->bar[0], vdev->nr_bars, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get pbar's full address in 64-bit
|
|
||||||
* For 64-bit MMIO bar, its lower 32-bits base address and upper 32-bits base are combined
|
|
||||||
* into one 64-bit base address
|
|
||||||
* @pre pdev != NULL
|
|
||||||
*/
|
|
||||||
static uint64_t get_pbar_base(const struct pci_pdev *pdev, uint32_t idx)
|
|
||||||
{
|
|
||||||
return pci_bar_2_bar_base(&pdev->bar[0], pdev->nr_bars, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vdev != NULL
|
* @pre vdev != NULL
|
||||||
*/
|
*/
|
||||||
@ -143,17 +132,12 @@ void vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t byt
|
|||||||
* @pre vdev != NULL
|
* @pre vdev != NULL
|
||||||
* @pre vdev->vpci != NULL
|
* @pre vdev->vpci != NULL
|
||||||
* @pre vdev->vpci->vm != NULL
|
* @pre vdev->vpci->vm != NULL
|
||||||
* @pre vdev->pdev != NULL
|
|
||||||
* @pre vdev->pdev->msix.table_bar < vdev->nr_bars
|
|
||||||
*/
|
*/
|
||||||
static void vdev_pt_remap_msix_table_vbar(struct pci_vdev *vdev)
|
static void vdev_pt_remap_msix_table_vbar(struct pci_vdev *vdev)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct pci_msix *msix = &vdev->msix;
|
struct pci_msix *msix = &vdev->msix;
|
||||||
struct pci_pdev *pdev = vdev->pdev;
|
struct pci_bar *vbar;
|
||||||
struct pci_bar *pbar;
|
|
||||||
|
|
||||||
ASSERT(vdev->pdev->msix.table_bar < vdev->nr_bars, "msix->table_bar is out of range");
|
|
||||||
|
|
||||||
/* Mask all table entries */
|
/* Mask all table entries */
|
||||||
for (i = 0U; i < msix->table_count; i++) {
|
for (i = 0U; i < msix->table_count; i++) {
|
||||||
@ -162,9 +146,9 @@ static void vdev_pt_remap_msix_table_vbar(struct pci_vdev *vdev)
|
|||||||
msix->table_entries[i].data = 0U;
|
msix->table_entries[i].data = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
pbar = &pdev->bar[msix->table_bar];
|
vbar = &vdev->bar[msix->table_bar];
|
||||||
if (pbar != NULL) {
|
if (vbar->size != 0UL) {
|
||||||
uint64_t pbar_base = get_pbar_base(pdev, msix->table_bar); /* pbar (hpa) */
|
uint64_t pbar_base = vbar->base_hpa; /* pbar (hpa) */
|
||||||
|
|
||||||
msix->mmio_hpa = pbar_base;
|
msix->mmio_hpa = pbar_base;
|
||||||
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
if (is_prelaunched_vm(vdev->vpci->vm)) {
|
||||||
@ -172,7 +156,7 @@ static void vdev_pt_remap_msix_table_vbar(struct pci_vdev *vdev)
|
|||||||
} else {
|
} else {
|
||||||
msix->mmio_gpa = sos_vm_hpa2gpa(pbar_base);
|
msix->mmio_gpa = sos_vm_hpa2gpa(pbar_base);
|
||||||
}
|
}
|
||||||
msix->mmio_size = pbar->size;
|
msix->mmio_size = vbar->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -279,7 +263,7 @@ static void vdev_pt_remap_generic_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
|
|||||||
/* If a new vbar is set (nonzero), set the EPT mapping accordingly */
|
/* If a new vbar is set (nonzero), set the EPT mapping accordingly */
|
||||||
if (vbar_base != 0UL) {
|
if (vbar_base != 0UL) {
|
||||||
uint64_t hpa = gpa2hpa(vdev->vpci->vm, vbar_base);
|
uint64_t hpa = gpa2hpa(vdev->vpci->vm, vbar_base);
|
||||||
uint64_t pbar_base = get_pbar_base(vdev->pdev, idx); /* pbar (hpa) */
|
uint64_t pbar_base = vbar->base_hpa; /* pbar (hpa) */
|
||||||
|
|
||||||
if (hpa != pbar_base) {
|
if (hpa != pbar_base) {
|
||||||
/* Unmap the existing mapping for new vbar */
|
/* Unmap the existing mapping for new vbar */
|
||||||
@ -489,13 +473,14 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
|||||||
vbar->size = 0UL;
|
vbar->size = 0UL;
|
||||||
vbar->reg.value = pbar->reg.value;
|
vbar->reg.value = pbar->reg.value;
|
||||||
vbar->is_64bit_high = pbar->is_64bit_high;
|
vbar->is_64bit_high = pbar->is_64bit_high;
|
||||||
|
vbar->base_hpa = pbar->base_hpa;
|
||||||
|
|
||||||
if (pbar->is_64bit_high) {
|
if (pbar->is_64bit_high) {
|
||||||
ASSERT(idx > 0U, "idx for upper 32-bit of the 64-bit bar should be greater than 0!");
|
ASSERT(idx > 0U, "idx for upper 32-bit of the 64-bit bar should be greater than 0!");
|
||||||
|
|
||||||
if (is_sos_vm(vdev->vpci->vm)) {
|
if (is_sos_vm(vdev->vpci->vm)) {
|
||||||
/* For SOS: vbar base (GPA) = pbar base (HPA) */
|
/* For SOS: vbar base (GPA) = pbar base (HPA) */
|
||||||
vbar_base = get_pbar_base(vdev->pdev, idx);
|
vbar_base = vdev->bar[idx - 1U].base_hpa;
|
||||||
} else if (idx > 0U) {
|
} else if (idx > 0U) {
|
||||||
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
||||||
vbar_base = vdev->pci_dev_config->vbar_base[idx - 1U];
|
vbar_base = vdev->pci_dev_config->vbar_base[idx - 1U];
|
||||||
@ -519,7 +504,7 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
|||||||
|
|
||||||
if (is_sos_vm(vdev->vpci->vm)) {
|
if (is_sos_vm(vdev->vpci->vm)) {
|
||||||
/* For SOS: vbar base (GPA) = pbar base (HPA) */
|
/* For SOS: vbar base (GPA) = pbar base (HPA) */
|
||||||
vbar_base = get_pbar_base(vdev->pdev, idx);
|
vbar_base = vbar->base_hpa;
|
||||||
} else {
|
} else {
|
||||||
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
/* For pre-launched VMs: vbar base is predefined in vm_config */
|
||||||
vbar_base = vdev->pci_dev_config->vbar_base[idx];
|
vbar_base = vdev->pci_dev_config->vbar_base[idx];
|
||||||
@ -529,7 +514,7 @@ void init_vdev_pt(struct pci_vdev *vdev)
|
|||||||
|
|
||||||
case PCIBAR_IO_SPACE:
|
case PCIBAR_IO_SPACE:
|
||||||
vbar->size = pbar->size;
|
vbar->size = pbar->size;
|
||||||
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)get_pbar_base(vdev->pdev, idx));
|
vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)vbar->base_hpa);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -327,15 +327,14 @@ static struct pci_vdev *find_vdev(const struct acrn_vpci *vpci, union pci_bdf bd
|
|||||||
|
|
||||||
static void vpci_init_pt_dev(struct pci_vdev *vdev)
|
static void vpci_init_pt_dev(struct pci_vdev *vdev)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* init_vdev_pt() must be called before init_vmsix() because init_vmsix
|
||||||
|
* assigns BAR base hpa to MSI-X mmio_hpa which is initialized in init_vdev_pt().
|
||||||
|
*/
|
||||||
|
init_vdev_pt(vdev);
|
||||||
init_vmsi(vdev);
|
init_vmsi(vdev);
|
||||||
init_vmsix(vdev);
|
init_vmsix(vdev);
|
||||||
|
|
||||||
/*
|
|
||||||
* Here init_vdev_pt() needs to be called after init_vmsix() for the following reason:
|
|
||||||
* init_vdev_pt() will indirectly call has_msix_cap(), which
|
|
||||||
* requires init_vmsix() to be called first.
|
|
||||||
*/
|
|
||||||
init_vdev_pt(vdev);
|
|
||||||
assign_vdev_pt_iommu_domain(vdev);
|
assign_vdev_pt_iommu_domain(vdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +288,7 @@ static uint32_t pci_pdev_read_bar(union pci_bdf bdf, uint32_t idx, struct pci_ba
|
|||||||
}
|
}
|
||||||
|
|
||||||
bar->size = size;
|
bar->size = size;
|
||||||
|
bar->base_hpa = base;
|
||||||
|
|
||||||
return (type == PCIBAR_MEM64)?2U:1U;
|
return (type == PCIBAR_MEM64)?2U:1U;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,7 @@ struct pci_bar {
|
|||||||
/* Base Address Register */
|
/* Base Address Register */
|
||||||
union pci_bar_reg reg;
|
union pci_bar_reg reg;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
uint64_t base_hpa;
|
||||||
bool is_64bit_high; /* true if this is the upper 32-bit of a 64-bit bar */
|
bool is_64bit_high; /* true if this is the upper 32-bit of a 64-bit bar */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user