diff --git a/hypervisor/Makefile b/hypervisor/Makefile index cf76e50cc..c0d5a6fed 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -221,10 +221,8 @@ C_SRCS += dm/vpci/vpci.c ifeq ($(CONFIG_PARTITION_MODE),y) C_SRCS += dm/vmptable.c endif -C_SRCS += dm/vpci/partition_mode.c C_SRCS += dm/vpci/vhostbridge.c C_SRCS += dm/vpci/pci_pt.c -C_SRCS += dm/vpci/sharing_mode.c C_SRCS += dm/vpci/vmsi.c C_SRCS += dm/vpci/vmsix.c diff --git a/hypervisor/dm/vpci/partition_mode.c b/hypervisor/dm/vpci/partition_mode.c deleted file mode 100644 index b21579f8a..000000000 --- a/hypervisor/dm/vpci/partition_mode.c +++ /dev/null @@ -1,182 +0,0 @@ -/*- -* Copyright (c) 2011 NetApp, Inc. -* Copyright (c) 2018 Intel Corporation -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE -* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -* $FreeBSD$ -*/ - -/* Virtual PCI device related operations (read/write, etc) */ - -#include -#include -#include "vpci_priv.h" - - -static inline bool is_hostbridge(const struct pci_vdev *vdev) -{ - return (vdev->vbdf.value == 0U); -} - -static inline bool is_valid_bar_type(const struct pci_bar *bar) -{ - return (bar->type == PCIBAR_MEM32) || (bar->type == PCIBAR_MEM64); -} - -static inline bool is_valid_bar_size(const struct pci_bar *bar) -{ - return (bar->size > 0UL) && (bar->size <= 0xffffffffU); -} - -/* Only MMIO is supported and bar size cannot be greater than 4GB */ -static inline bool is_valid_bar(const struct pci_bar *bar) -{ - return (is_valid_bar_type(bar) && is_valid_bar_size(bar)); -} - -/** - * @pre vdev != NULL - */ -static void partition_mode_pdev_init(struct pci_vdev *vdev, union pci_bdf pbdf) -{ - struct pci_pdev *pdev; - uint32_t idx; - struct pci_bar *pbar, *vbar; - - pdev = find_pci_pdev(pbdf); - ASSERT(pdev != NULL, "pdev is NULL"); - - vdev->pdev = pdev; - - /* Sanity checking for vbar */ - for (idx = 0U; idx < (uint32_t)PCI_BAR_COUNT; idx++) { - pbar = &vdev->pdev->bar[idx]; - vbar = &vdev->bar[idx]; - - if (is_valid_bar(pbar)) { - vbar->size = (pbar->size < 0x1000U) ? 0x1000U : pbar->size; - vbar->type = PCIBAR_MEM32; - } else { - /* Mark this vbar as invalid */ - vbar->size = 0UL; - vbar->type = PCIBAR_NONE; - } - } - - vdev_pt_init(vdev); -} - -/** - * @pre vm != NULL - * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM - */ -int32_t partition_mode_vpci_init(const struct acrn_vm *vm) -{ - struct acrn_vpci *vpci = (struct acrn_vpci *)&(vm->vpci); - struct pci_vdev *vdev; - struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); - struct acrn_vm_pci_ptdev_config *ptdev_config; - uint32_t i; - - vpci->pci_vdev_cnt = vm_config->pci_ptdev_num; - - for (i = 0U; i < vpci->pci_vdev_cnt; i++) { - vdev = &vpci->pci_vdevs[i]; - vdev->vpci = vpci; - ptdev_config = &vm_config->pci_ptdevs[i]; - vdev->vbdf.value = ptdev_config->vbdf.value; - - if (is_hostbridge(vdev)) { - vdev_hostbridge_init(vdev); - } else { - partition_mode_pdev_init(vdev, ptdev_config->pbdf); - } - } - - return 0; -} - -/** - * @pre vm != NULL - * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM - */ -void partition_mode_vpci_deinit(const struct acrn_vm *vm) -{ - struct pci_vdev *vdev; - uint32_t i; - - for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { - vdev = (struct pci_vdev *) &(vm->vpci.pci_vdevs[i]); - - if (is_hostbridge(vdev)) { - vdev_hostbridge_deinit(vdev); - } else { - vdev_pt_deinit(vdev); - } - } -} - -/** - * @pre vpci != NULL - */ -void partition_mode_cfgread(const struct acrn_vpci *vpci, union pci_bdf vbdf, - uint32_t offset, uint32_t bytes, uint32_t *val) -{ - struct pci_vdev *vdev = pci_find_vdev_by_vbdf(vpci, vbdf); - - if (vdev != NULL) { - if (is_hostbridge(vdev)) { - if (vdev_hostbridge_cfgread(vdev, offset, bytes, val) != 0) { - pr_err("vdev_hostbridge_cfgread failed!"); - } - } else { - if (vdev_pt_cfgread(vdev, offset, bytes, val) != 0) { - /* Not handled by any handlers, passthru to physical device */ - *val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes); - } - } - } -} - -/** - * @pre vpci != NULL - */ -void partition_mode_cfgwrite(const struct acrn_vpci *vpci, union pci_bdf vbdf, - uint32_t offset, uint32_t bytes, uint32_t val) -{ - struct pci_vdev *vdev = pci_find_vdev_by_vbdf(vpci, vbdf); - - if (vdev != NULL) { - if (is_hostbridge(vdev)) { - if (vdev_hostbridge_cfgwrite(vdev, offset, bytes, val) != 0) { - pr_err("vdev_hostbridge_cfgwrite failed!"); - } - } else { - if (vdev_pt_cfgwrite(vdev, offset, bytes, val) != 0){ - /* Not handled by any handlers, passthru to physical device */ - pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val); - } - } - } -} diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index c3d84f322..a4e30fe68 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -70,7 +70,7 @@ static int32_t validate(const struct pci_vdev *vdev) * @pre vdev->vpci != NULL * @pre vdev->vpci->vm != NULL */ -void vdev_pt_init(struct pci_vdev *vdev) +void vdev_pt_init(const struct pci_vdev *vdev) { int32_t ret; struct acrn_vm *vm = vdev->vpci->vm; diff --git a/hypervisor/dm/vpci/sharing_mode.c b/hypervisor/dm/vpci/sharing_mode.c deleted file mode 100644 index d100d572e..000000000 --- a/hypervisor/dm/vpci/sharing_mode.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2011 NetApp, Inc. - * Copyright (c) 2018 Intel Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include "vpci_priv.h" - - -static struct pci_vdev *sharing_mode_find_vdev_sos(union pci_bdf pbdf) -{ - struct acrn_vm *vm; - - vm = get_sos_vm(); - - return pci_find_vdev_by_pbdf(&vm->vpci, pbdf); -} - -void sharing_mode_cfgread(__unused struct acrn_vpci *vpci, union pci_bdf bdf, - uint32_t offset, uint32_t bytes, uint32_t *val) -{ - struct pci_vdev *vdev = sharing_mode_find_vdev_sos(bdf); - - *val = ~0U; - - /* vdev == NULL: Could be hit for PCI enumeration from guests */ - if (vdev != NULL) { - if ((vmsi_cfgread(vdev, offset, bytes, val) != 0) - && (vmsix_cfgread(vdev, offset, bytes, val) != 0) - ) { - /* Not handled by any handlers, passthru to physical device */ - *val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes); - } - } -} - -void sharing_mode_cfgwrite(__unused struct acrn_vpci *vpci, union pci_bdf bdf, - uint32_t offset, uint32_t bytes, uint32_t val) -{ - struct pci_vdev *vdev = sharing_mode_find_vdev_sos(bdf); - - if (vdev != NULL) { - if ((vmsi_cfgwrite(vdev, offset, bytes, val) != 0) - && (vmsix_cfgwrite(vdev, offset, bytes, val) != 0) - ) { - /* Not handled by any handlers, passthru to physical device */ - pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val); - } - } -} - -/** - * @pre pdev != NULL - * @pre vm != NULL - * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM - */ -static void init_vdev_for_pdev(struct pci_pdev *pdev, const void *vm) -{ - struct pci_vdev *vdev = NULL; - struct acrn_vpci *vpci = &(((struct acrn_vm *)vm)->vpci); - - if (vpci->pci_vdev_cnt < CONFIG_MAX_PCI_DEV_NUM) { - vdev = &vpci->pci_vdevs[vpci->pci_vdev_cnt]; - vpci->pci_vdev_cnt++; - - vdev->vpci = vpci; - /* vbdf equals to pbdf otherwise remapped */ - vdev->vbdf = pdev->bdf; - vdev->pdev = pdev; - - vmsi_init(vdev); - - vmsix_init(vdev); - } -} - - -/** - * @pre vm != NULL - * @pre is_sos_vm(vm) == true - */ -int32_t sharing_mode_vpci_init(const struct acrn_vm *vm) -{ - /* Build up vdev array for sos_vm */ - pci_pdev_foreach(init_vdev_for_pdev, vm); - - return 0; -} - -/** - * @pre vm != NULL - * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM - * @pre is_sos_vm(vm) == true - */ -void sharing_mode_vpci_deinit(const struct acrn_vm *vm) -{ - struct pci_vdev *vdev; - uint32_t i; - - for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { - vdev = (struct pci_vdev *)&(vm->vpci.pci_vdevs[i]); - - vmsi_deinit(vdev); - - vmsix_deinit(vdev); - } -} - -void vpci_set_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf) -{ - struct pci_vdev *vdev; - union pci_bdf bdf; - - bdf.value = pbdf; - vdev = sharing_mode_find_vdev_sos(bdf); - if (vdev == NULL) { - pr_err("%s, can't find PCI device for vm%d, vbdf (0x%x) pbdf (0x%x)", __func__, - target_vm->vm_id, vbdf, pbdf); - } else { - /* UOS may do BDF mapping */ - vdev->vpci = (struct acrn_vpci *)&(target_vm->vpci); - vdev->vbdf.value = vbdf; - vdev->pdev->bdf.value = pbdf; - } -} - -void vpci_reset_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf) -{ - struct pci_vdev *vdev; - struct acrn_vm *vm; - union pci_bdf bdf; - - bdf.value = pbdf; - vdev = sharing_mode_find_vdev_sos(bdf); - if (vdev == NULL) { - pr_err("%s, can't find PCI device for vm%d, vbdf (0x%x) pbdf (0x%x)", __func__, - target_vm->vm_id, vbdf, pbdf); - } else { - /* Return this PCI device to SOS */ - if (vdev->vpci->vm == target_vm) { - vm = get_sos_vm(); - - if (vm != NULL) { - vdev->vpci = &vm->vpci; - /* vbdf equals to pbdf in sos */ - vdev->vbdf.value = vdev->pdev->bdf.value; - } - } - } -} diff --git a/hypervisor/dm/vpci/vmsix.c b/hypervisor/dm/vpci/vmsix.c index 84ffe23ca..271109cdd 100644 --- a/hypervisor/dm/vpci/vmsix.c +++ b/hypervisor/dm/vpci/vmsix.c @@ -210,9 +210,13 @@ int32_t vmsix_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, u return ret; } -static void vmsix_table_rw(struct pci_vdev *vdev, struct mmio_request *mmio, uint32_t offset) +/** + * @pre vdev != NULL + * @pre mmio != NULL + */ +static void vmsix_table_rw(const struct pci_vdev *vdev, struct mmio_request *mmio, uint32_t offset) { - struct msix_table_entry *entry; + const struct msix_table_entry *entry; uint32_t vector_control, entry_offset, table_offset, index; bool message_changed = false; bool unmasked; diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index beec35978..97966b934 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -32,6 +32,9 @@ #include #include "vpci_priv.h" +/** + * @pre pi != NULL + */ static void pci_cfg_clear_cache(struct pci_addr_info *pi) { pi->cached_bdf.value = 0xFFFFU; @@ -240,3 +243,312 @@ void vpci_cleanup(const struct acrn_vm *vm) break; } } + +/** + * @pre vdev != NULL + */ +static inline bool is_hostbridge(const struct pci_vdev *vdev) +{ + return (vdev->vbdf.value == 0U); +} + +/** + * @pre bar != NULL + */ +static inline bool is_valid_bar_type(const struct pci_bar *bar) +{ + return (bar->type == PCIBAR_MEM32) || (bar->type == PCIBAR_MEM64); +} + +/** + * @pre bar != NULL + */ +static inline bool is_valid_bar_size(const struct pci_bar *bar) +{ + return (bar->size > 0UL) && (bar->size <= 0xffffffffU); +} + +/** + * Only MMIO is supported and bar size cannot be greater than 4GB + * @pre bar != NULL + */ +static inline bool is_valid_bar(const struct pci_bar *bar) +{ + return (is_valid_bar_type(bar) && is_valid_bar_size(bar)); +} + +/** + * @pre vdev != NULL + */ +static void partition_mode_pdev_init(struct pci_vdev *vdev, union pci_bdf pbdf) +{ + struct pci_pdev *pdev; + uint32_t idx; + struct pci_bar *pbar, *vbar; + + pdev = find_pci_pdev(pbdf); + ASSERT(pdev != NULL, "pdev is NULL"); + + vdev->pdev = pdev; + + /* Sanity checking for vbar */ + for (idx = 0U; idx < (uint32_t)PCI_BAR_COUNT; idx++) { + pbar = &vdev->pdev->bar[idx]; + vbar = &vdev->bar[idx]; + + if (is_valid_bar(pbar)) { + vbar->size = (pbar->size < 0x1000U) ? 0x1000U : pbar->size; + vbar->type = PCIBAR_MEM32; + } else { + /* Mark this vbar as invalid */ + vbar->size = 0UL; + vbar->type = PCIBAR_NONE; + } + } + + vdev_pt_init(vdev); +} + +/** + * @pre vm != NULL + * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM + */ +int32_t partition_mode_vpci_init(const struct acrn_vm *vm) +{ + struct acrn_vpci *vpci = (struct acrn_vpci *)&(vm->vpci); + struct pci_vdev *vdev; + struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); + struct acrn_vm_pci_ptdev_config *ptdev_config; + uint32_t i; + + vpci->pci_vdev_cnt = vm_config->pci_ptdev_num; + + for (i = 0U; i < vpci->pci_vdev_cnt; i++) { + vdev = &vpci->pci_vdevs[i]; + vdev->vpci = vpci; + ptdev_config = &vm_config->pci_ptdevs[i]; + vdev->vbdf.value = ptdev_config->vbdf.value; + + if (is_hostbridge(vdev)) { + vdev_hostbridge_init(vdev); + } else { + partition_mode_pdev_init(vdev, ptdev_config->pbdf); + } + } + + return 0; +} + +/** + * @pre vm != NULL + * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM + */ +void partition_mode_vpci_deinit(const struct acrn_vm *vm) +{ + struct pci_vdev *vdev; + uint32_t i; + + for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { + vdev = (struct pci_vdev *) &(vm->vpci.pci_vdevs[i]); + + if (is_hostbridge(vdev)) { + vdev_hostbridge_deinit(vdev); + } else { + vdev_pt_deinit(vdev); + } + } +} + +/** + * @pre vpci != NULL + */ +void partition_mode_cfgread(const struct acrn_vpci *vpci, union pci_bdf vbdf, + uint32_t offset, uint32_t bytes, uint32_t *val) +{ + struct pci_vdev *vdev = pci_find_vdev_by_vbdf(vpci, vbdf); + + if (vdev != NULL) { + if (is_hostbridge(vdev)) { + (void)vdev_hostbridge_cfgread(vdev, offset, bytes, val); + } else { + if (vdev_pt_cfgread(vdev, offset, bytes, val) != 0) { + /* Not handled by any handlers, passthru to physical device */ + *val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes); + } + } + } +} + +/** + * @pre vpci != NULL + */ +void partition_mode_cfgwrite(const struct acrn_vpci *vpci, union pci_bdf vbdf, + uint32_t offset, uint32_t bytes, uint32_t val) +{ + struct pci_vdev *vdev = pci_find_vdev_by_vbdf(vpci, vbdf); + + if (vdev != NULL) { + if (is_hostbridge(vdev)) { + (void)vdev_hostbridge_cfgwrite(vdev, offset, bytes, val); + } else { + if (vdev_pt_cfgwrite(vdev, offset, bytes, val) != 0){ + /* Not handled by any handlers, passthru to physical device */ + pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val); + } + } + } +} + +static struct pci_vdev *sharing_mode_find_vdev_sos(union pci_bdf pbdf) +{ + struct acrn_vm *vm; + + vm = get_sos_vm(); + + return pci_find_vdev_by_pbdf(&vm->vpci, pbdf); +} + +/** + * @pre vpci != NULL + */ +void sharing_mode_cfgread(__unused struct acrn_vpci *vpci, union pci_bdf bdf, + uint32_t offset, uint32_t bytes, uint32_t *val) +{ + struct pci_vdev *vdev = sharing_mode_find_vdev_sos(bdf); + + *val = ~0U; + + /* vdev == NULL: Could be hit for PCI enumeration from guests */ + if (vdev != NULL) { + if ((vmsi_cfgread(vdev, offset, bytes, val) != 0) + && (vmsix_cfgread(vdev, offset, bytes, val) != 0) + ) { + /* Not handled by any handlers, passthru to physical device */ + *val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes); + } + } +} + +/** + * @pre vpci != NULL + */ +void sharing_mode_cfgwrite(__unused struct acrn_vpci *vpci, union pci_bdf bdf, + uint32_t offset, uint32_t bytes, uint32_t val) +{ + struct pci_vdev *vdev = sharing_mode_find_vdev_sos(bdf); + + if (vdev != NULL) { + if ((vmsi_cfgwrite(vdev, offset, bytes, val) != 0) + && (vmsix_cfgwrite(vdev, offset, bytes, val) != 0) + ) { + /* Not handled by any handlers, passthru to physical device */ + pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val); + } + } +} + +/** + * @pre pdev != NULL + * @pre vm != NULL + * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM + */ +static void init_vdev_for_pdev(struct pci_pdev *pdev, const void *vm) +{ + struct pci_vdev *vdev = NULL; + struct acrn_vpci *vpci = &(((struct acrn_vm *)vm)->vpci); + + if (vpci->pci_vdev_cnt < CONFIG_MAX_PCI_DEV_NUM) { + vdev = &vpci->pci_vdevs[vpci->pci_vdev_cnt]; + vpci->pci_vdev_cnt++; + + vdev->vpci = vpci; + /* vbdf equals to pbdf otherwise remapped */ + vdev->vbdf = pdev->bdf; + vdev->pdev = pdev; + + vmsi_init(vdev); + + vmsix_init(vdev); + } +} + + +/** + * @pre vm != NULL + * @pre is_sos_vm(vm) == true + */ +int32_t sharing_mode_vpci_init(const struct acrn_vm *vm) +{ + /* Build up vdev array for sos_vm */ + pci_pdev_foreach(init_vdev_for_pdev, vm); + + return 0; +} + +/** + * @pre vm != NULL + * @pre vm->vpci.pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM + * @pre is_sos_vm(vm) == true + */ +void sharing_mode_vpci_deinit(const struct acrn_vm *vm) +{ + struct pci_vdev *vdev; + uint32_t i; + + for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { + vdev = (struct pci_vdev *)&(vm->vpci.pci_vdevs[i]); + + vmsi_deinit(vdev); + + vmsix_deinit(vdev); + } +} + +/** + * @pre target_vm != NULL + */ +void vpci_set_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf) +{ + struct pci_vdev *vdev; + union pci_bdf bdf; + + bdf.value = pbdf; + vdev = sharing_mode_find_vdev_sos(bdf); + if (vdev == NULL) { + pr_err("%s, can't find PCI device for vm%d, vbdf (0x%x) pbdf (0x%x)", __func__, + target_vm->vm_id, vbdf, pbdf); + } else { + /* UOS may do BDF mapping */ + vdev->vpci = (struct acrn_vpci *)&(target_vm->vpci); + vdev->vbdf.value = vbdf; + vdev->pdev->bdf.value = pbdf; + } +} + +/** + * @pre target_vm != NULL + */ +void vpci_reset_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf) +{ + struct pci_vdev *vdev; + struct acrn_vm *vm; + union pci_bdf bdf; + + bdf.value = pbdf; + vdev = sharing_mode_find_vdev_sos(bdf); + if (vdev == NULL) { + pr_err("%s, can't find PCI device for vm%d, vbdf (0x%x) pbdf (0x%x)", __func__, + target_vm->vm_id, vbdf, pbdf); + } else { + /* Return this PCI device to SOS */ + if (vdev->vpci->vm == target_vm) { + vm = get_sos_vm(); + + if (vm != NULL) { + vdev->vpci = &vm->vpci; + /* vbdf equals to pbdf in sos */ + vdev->vbdf.value = vdev->pdev->bdf.value; + } + } + } +} diff --git a/hypervisor/dm/vpci/vpci_priv.h b/hypervisor/dm/vpci/vpci_priv.h index cc5debbf5..be7709d73 100644 --- a/hypervisor/dm/vpci/vpci_priv.h +++ b/hypervisor/dm/vpci/vpci_priv.h @@ -27,8 +27,8 @@ * $FreeBSD$ */ -#ifndef PCI_PRIV_H_ -#define PCI_PRIV_H_ +#ifndef VPCI_PRIV_H_ +#define VPCI_PRIV_H_ #include @@ -72,7 +72,7 @@ int32_t vdev_hostbridge_cfgread(const struct pci_vdev *vdev, uint32_t offset, ui int32_t vdev_hostbridge_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); void vdev_hostbridge_deinit(__unused const struct pci_vdev *vdev); -void vdev_pt_init(struct pci_vdev *vdev); +void vdev_pt_init(const struct pci_vdev *vdev); int32_t vdev_pt_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val); int32_t vdev_pt_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); void vdev_pt_deinit(const struct pci_vdev *vdev); @@ -93,4 +93,18 @@ struct pci_vdev *pci_find_vdev_by_vbdf(const struct acrn_vpci *vpci, union pci_b struct pci_vdev *pci_find_vdev_by_pbdf(const struct acrn_vpci *vpci, union pci_bdf pbdf); -#endif /* PCI_PRIV_H_ */ +int32_t partition_mode_vpci_init(const struct acrn_vm *vm); +void partition_mode_cfgread(const struct acrn_vpci *vpci, union pci_bdf vbdf, + uint32_t offset, uint32_t bytes, uint32_t *val); +void partition_mode_cfgwrite(const struct acrn_vpci *vpci, union pci_bdf vbdf, + uint32_t offset, uint32_t bytes, uint32_t val); +void partition_mode_vpci_deinit(const struct acrn_vm *vm); + +int32_t sharing_mode_vpci_init(const struct acrn_vm *vm); +void sharing_mode_cfgread(struct acrn_vpci *vpci, union pci_bdf bdf, + uint32_t offset, uint32_t bytes, uint32_t *val); +void sharing_mode_cfgwrite(__unused struct acrn_vpci *vpci, union pci_bdf bdf, + uint32_t offset, uint32_t bytes, uint32_t val); +void sharing_mode_vpci_deinit(const struct acrn_vm *vm); + +#endif /* VPCI_PRIV_H_ */ diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index c49604ba9..e3bb5c571 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -93,20 +93,6 @@ struct acrn_vpci { struct pci_vdev pci_vdevs[CONFIG_MAX_PCI_DEV_NUM]; }; -int32_t partition_mode_vpci_init(const struct acrn_vm *vm); -void partition_mode_cfgread(const struct acrn_vpci *vpci, union pci_bdf vbdf, - uint32_t offset, uint32_t bytes, uint32_t *val); -void partition_mode_cfgwrite(const struct acrn_vpci *vpci, union pci_bdf vbdf, - uint32_t offset, uint32_t bytes, uint32_t val); -void partition_mode_vpci_deinit(const struct acrn_vm *vm); - -int32_t sharing_mode_vpci_init(const struct acrn_vm *vm); -void sharing_mode_cfgread(struct acrn_vpci *vpci, union pci_bdf bdf, - uint32_t offset, uint32_t bytes, uint32_t *val); -void sharing_mode_cfgwrite(__unused struct acrn_vpci *vpci, union pci_bdf bdf, - uint32_t offset, uint32_t bytes, uint32_t val); -void sharing_mode_vpci_deinit(const struct acrn_vm *vm); - void vpci_init(struct acrn_vm *vm); void vpci_cleanup(const struct acrn_vm *vm); void vpci_set_ptdev_intr_info(const struct acrn_vm *target_vm, uint16_t vbdf, uint16_t pbdf);