From 4be09f24f3305913a61aed38c2040993bc20bc85 Mon Sep 17 00:00:00 2001 From: dongshen Date: Tue, 25 Jun 2019 14:03:39 -0700 Subject: [PATCH] HV: enable bar emulation for sos For sos, its vbar base address is set to pbar base address (vbar gpa = pbar hpa) For pre-launched VMs, vbar base address is pre-assigned in vm_config Rename vdev_pt_remap_msix_table_bar to vdev_pt_remap_msix_table_vbar and make it a static function Remove unused function prototye vdev_pt_remap_msix_table_bar() in vpci_priv.h Tracked-On: #3241 Signed-off-by: dongshen Acked-by: Eddie Dong --- hypervisor/dm/vpci/pci_pt.c | 89 ++++++++++++++++++---------------- hypervisor/dm/vpci/vpci.c | 4 -- hypervisor/dm/vpci/vpci_priv.h | 1 - 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index cb81f8423..3c89d3b0a 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -127,14 +127,12 @@ static uint64_t get_pbar_base(const struct pci_pdev *pdev, uint32_t idx) /** * @pre vdev != NULL - * @pre vdev->vpci != NULL - * @pre vdev->vpci->vm != NULL */ int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val) { int32_t ret = -ENODEV; - if (is_prelaunched_vm(vdev->vpci->vm) && is_bar_offset(vdev->nr_bars, offset)) { + if (is_bar_offset(vdev->nr_bars, offset)) { *val = pci_vdev_read_cfg(vdev, offset, bytes); ret = 0; } @@ -149,7 +147,7 @@ int32_t vdev_pt_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t * @pre vdev->pdev != NULL * @pre vdev->pdev->msix.table_bar < vdev->nr_bars */ -void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev) +static void vdev_pt_remap_msix_table_vbar(struct pci_vdev *vdev) { uint32_t i; struct pci_msix *msix = &vdev->msix; @@ -315,7 +313,7 @@ static void vdev_pt_remap_mem_vbar(struct pci_vdev *vdev, uint32_t idx) is_msix_table_bar = (has_msix_cap(vdev) && (idx == vdev->msix.table_bar)); if (is_msix_table_bar) { - vdev_pt_remap_msix_table_bar(vdev); + vdev_pt_remap_msix_table_vbar(vdev); } else { vdev_pt_remap_generic_mem_vbar(vdev, idx); } @@ -403,17 +401,14 @@ static void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t offset, uint32_t /** * @pre vdev != NULL - * @pre vdev->vpci != NULL - * @pre vdev->vpci->vm != NULL * bar write access must be 4 bytes and offset must also be 4 bytes aligned, it will be dropped otherwise */ int32_t vdev_pt_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val) { int32_t ret = -ENODEV; - /* bar write access must be 4 bytes and offset must also be 4 bytes aligned */ - if (is_prelaunched_vm(vdev->vpci->vm) && is_bar_offset(vdev->nr_bars, offset) - && (bytes == 4U) && ((offset & 0x3U) == 0U)) { + /* bar write access must be 4 bytes and offset must also be 4 bytes aligned*/ + if (is_bar_offset(vdev->nr_bars, offset) && (bytes == 4U) && ((offset & 0x3U) == 0U)) { vdev_pt_write_vbar(vdev, offset, val); ret = 0; } @@ -457,50 +452,60 @@ void init_vdev_pt(struct pci_vdev *vdev) ASSERT(vdev->nr_bars > 0U, "vdev->nr_bars should be greater than 0!"); - if (is_prelaunched_vm(vdev->vpci->vm)) { - for (idx = 0U; idx < vdev->nr_bars; idx++) { - pbar = &vdev->pdev->bar[idx]; - vbar = &vdev->bar[idx]; + for (idx = 0U; idx < vdev->nr_bars; idx++) { + pbar = &vdev->pdev->bar[idx]; + vbar = &vdev->bar[idx]; - vbar->size = 0UL; - vbar->reg.value = pbar->reg.value; - vbar->is_64bit_high = pbar->is_64bit_high; + vbar->size = 0UL; + vbar->reg.value = pbar->reg.value; + vbar->is_64bit_high = 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!"); + if (pbar->is_64bit_high) { + ASSERT(idx > 0U, "idx for upper 32-bit of the 64-bit bar should be greater than 0!"); - if (idx > 0U) { - /* For pre-launched VMs: vbar base is predefined in vm_config */ - vbar_base = vdev->ptdev_config->vbar_base[idx - 1U]; - /* Write the upper 32-bit of a 64-bit bar */ - vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)(vbar_base >> 32U)); - } + if (is_sos_vm(vdev->vpci->vm)) { + /* For SOS: vbar base (GPA) = pbar base (HPA) */ + vbar_base = get_pbar_base(vdev->pdev, idx); + } else if (idx > 0U) { + /* For pre-launched VMs: vbar base is predefined in vm_config */ + vbar_base = vdev->ptdev_config->vbar_base[idx - 1U]; } else { - enum pci_bar_type type = pci_get_bar_type(pbar->reg.value); + vbar_base = 0UL; + } + /* Write the upper 32-bit of a 64-bit bar */ + vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)(vbar_base >> 32U)); + } else { + enum pci_bar_type type = pci_get_bar_type(pbar->reg.value); - switch (type) { - case PCIBAR_MEM32: - case PCIBAR_MEM64: - /** - * If vbar->base is 0 (unassigned), Linux kernel will reprogram the vbar on - * its bar size boundary, so in order to ensure the MMIO vbar allocated by guest - * is 4k aligned, set its size to be 4K aligned. - */ - vbar->size = round_page_up(pbar->size); + switch (type) { + case PCIBAR_MEM32: + case PCIBAR_MEM64: + /** + * If vbar->base is 0 (unassigned), Linux kernel will reprogram the vbar on + * its bar size boundary, so in order to ensure the MMIO vbar allocated by guest + * is 4k aligned, set its size to be 4K aligned. + */ + vbar->size = round_page_up(pbar->size); + if (is_sos_vm(vdev->vpci->vm)) { + /* For SOS: vbar base (GPA) = pbar base (HPA) */ + vbar_base = get_pbar_base(vdev->pdev, idx); + } else { /* For pre-launched VMs: vbar base is predefined in vm_config */ vbar_base = vdev->ptdev_config->vbar_base[idx]; - vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)vbar_base); - break; - - default: - vbar->reg.value = 0x0U; - vbar->size = 0UL; - break; } + vdev_pt_write_vbar(vdev, pci_bar_offset(idx), (uint32_t)vbar_base); + break; + + default: + vbar->reg.value = 0x0U; + vbar->size = 0UL; + break; } } + } + if (is_prelaunched_vm(vdev->vpci->vm)) { pci_command = (uint16_t)pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U); /* Disable INTX */ diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index f2777ecbd..16bc89793 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -436,10 +436,6 @@ static void init_vdev_for_pdev(struct pci_pdev *pdev, const struct acrn_vm *vm) */ init_vdev_pt(vdev); - if (has_msix_cap(vdev)) { - vdev_pt_remap_msix_table_bar(vdev); - } - /* * For pre-launched VM, the host bridge is fully virtualized and it does not have a physical * host bridge counterpart. diff --git a/hypervisor/dm/vpci/vpci_priv.h b/hypervisor/dm/vpci/vpci_priv.h index 8ecfe394d..f8b846bed 100644 --- a/hypervisor/dm/vpci/vpci_priv.h +++ b/hypervisor/dm/vpci/vpci_priv.h @@ -116,7 +116,6 @@ int32_t vmsi_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, u void deinit_vmsi(const struct pci_vdev *vdev); void init_vmsix(struct pci_vdev *vdev); -void vdev_pt_remap_msix_table_bar(struct pci_vdev *vdev); int32_t vmsix_table_mmio_access_handler(struct io_request *io_req, void *handler_private_data); int32_t vmsix_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val); int32_t vmsix_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);