From 73cff9ef083e8bf28b85ca8b2166e92e1f9e3db9 Mon Sep 17 00:00:00 2001 From: dongshen Date: Mon, 20 May 2019 14:54:15 -0700 Subject: [PATCH] HV: predefine pci vbar's base address for pre-launched VMs in vm_config For pre-launched VMs, currently we set all vbars to 0s initially in bar emulation code, guest OS will reprogram the bars when it sees the bars are uninited (0s). We consider this is not the right solution, change to populate the vbars (to non zero valid pci hole address) based on the vbar base addresses predefined in vm_config. Store a pointer to acrn_vm_pci_ptdev_config in struct pci_vdev Tracked-On: #3022 Signed-off-by: dongshen Acked-by: Eddie Dong --- hypervisor/dm/vpci/pci_pt.c | 6 ++++++ hypervisor/dm/vpci/vpci.c | 9 ++++++++- hypervisor/include/arch/x86/vm_config.h | 1 + hypervisor/include/dm/vpci.h | 3 +++ hypervisor/scenarios/logical_partition/pt_dev.c | 6 ++++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index ecb2b699b..26fa84813 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -311,6 +311,7 @@ void init_vdev_pt(struct pci_vdev *vdev) pbar = &vdev->pdev->bar[idx]; vbar = &vdev->bar[idx]; + vbar->base = 0UL; if (is_bar_supported(pbar)) { /** * If vbar->base is 0 (unassigned), Linux kernel will reprogram the vbar on @@ -324,6 +325,11 @@ void init_vdev_pt(struct pci_vdev *vdev) * are reported to guest as PCIBAR_MEM32 */ vbar->type = PCIBAR_MEM32; + + /* Set the new vbar base */ + if (vdev->ptdev_config->vbar[idx] != 0UL) { + vdev_pt_write_vbar(vdev, pci_bar_offset(idx), 4U, (uint32_t)(vdev->ptdev_config->vbar[idx])); + } } else { vbar->size = 0UL; vbar->type = PCIBAR_NONE; diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index 298b41ed7..2c3174bce 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -415,6 +415,7 @@ static void init_vdev_for_pdev(struct pci_pdev *pdev, const void *vm) vdev->vpci = vpci; vdev->pdev = pdev; + vdev->ptdev_config = ptdev_config; if (ptdev_config != NULL) { /* vbdf is defined in vm_config */ @@ -425,10 +426,16 @@ static void init_vdev_for_pdev(struct pci_pdev *pdev, const void *vm) } init_vhostbridge(vdev); - init_vdev_pt(vdev); init_vmsi(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); + if (has_msix_cap(vdev)) { vdev_pt_remap_msix_table_bar(vdev); } diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index 75872e73d..6a199e192 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -68,6 +68,7 @@ struct acrn_vm_os_config { struct acrn_vm_pci_ptdev_config { union pci_bdf vbdf; /* virtual BDF of PCI PT device */ union pci_bdf pbdf; /* physical BDF of PCI PT device */ + uint64_t vbar[PCI_BAR_COUNT]; /* vbar base address of PCI PT device */ } __aligned(8); struct acrn_vm_config { diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index e3bb5c571..3b7b93a19 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -78,6 +78,9 @@ struct pci_vdev { struct pci_msi msi; struct pci_msix msix; + + /* Pointer to corresponding PCI PT device's vm_config */ + struct acrn_vm_pci_ptdev_config *ptdev_config; }; struct pci_addr_info { diff --git a/hypervisor/scenarios/logical_partition/pt_dev.c b/hypervisor/scenarios/logical_partition/pt_dev.c index 04b3b27b3..bdecdcbf1 100644 --- a/hypervisor/scenarios/logical_partition/pt_dev.c +++ b/hypervisor/scenarios/logical_partition/pt_dev.c @@ -14,10 +14,15 @@ struct acrn_vm_pci_ptdev_config vm0_pci_ptdevs[VM0_CONFIG_PCI_PTDEV_NUM] = { }, { .vbdf.bits = {.b = 0x00U, .d = 0x01U, .f = 0x00U}, + .vbar[0] = 0xc0084000UL, + .vbar[1] = 0xc0086000UL, + .vbar[5] = 0xc0087000UL, VM0_STORAGE_CONTROLLER }, { .vbdf.bits = {.b = 0x00U, .d = 0x02U, .f = 0x00U}, + .vbar[0] = 0xc0000000UL, + .vbar[3] = 0xc0080000UL, VM0_NETWORK_CONTROLLER }, }; @@ -29,6 +34,7 @@ struct acrn_vm_pci_ptdev_config vm1_pci_ptdevs[VM1_CONFIG_PCI_PTDEV_NUM] = { }, { .vbdf.bits = {.b = 0x00U, .d = 0x01U, .f = 0x00U}, + .vbar[0] = 0xc0000000UL, VM1_STORAGE_CONTROLLER }, #if defined(VM1_NETWORK_CONTROLLER)