From 5f3ea06febeed5c5b2d54742a75c2b95c0983159 Mon Sep 17 00:00:00 2001 From: dongshen Date: Tue, 7 Aug 2018 18:36:43 -0700 Subject: [PATCH] HV: Implementing PCI CFG vm-exit handler for partition hypervisor V4: - If pci device is not found in the PCI mapping table, just return without throwing any error message - Added NULL pointer checking when calling cfgread/cfgwrite ops - Moved error checking code to cfgread/cfgwrite ops V3: - Do not use ASSERT - Call the cfg read/write ops defined in the vm description V2: - Fixed MISRA violations Reviewed-by: Anthony Xu Acked-by: Anthony Xu Signed-off-by: dongshen --- hypervisor/dm/vpci/pci_vdev.c | 85 +++++++++++++++++++++++++++++++++++ hypervisor/dm/vpci/vpci.c | 6 --- 2 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 hypervisor/dm/vpci/pci_vdev.c diff --git a/hypervisor/dm/vpci/pci_vdev.c b/hypervisor/dm/vpci/pci_vdev.c new file mode 100644 index 000000000..7a2b49af6 --- /dev/null +++ b/hypervisor/dm/vpci/pci_vdev.c @@ -0,0 +1,85 @@ +/*- +* 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 +#include +#include +#include +#include "pci_priv.h" + + +static struct pci_vdev *pci_vdev_find(struct vpci *vpci, uint16_t vbdf) +{ + struct vpci_vdev_array *vdev_array; + struct pci_vdev *vdev; + int i; + + vdev_array = vpci->vm->vm_desc->vpci_vdev_array; + for (i = 0; i < vdev_array->num_pci_vdev; i++) { + vdev = &vdev_array->vpci_vdev_list[i]; + if (vdev->vbdf == vbdf) { + return vdev; + } + } + + return NULL; +} + +/* PCI cfg vm-exit handler */ +void pci_vdev_cfg_handler(struct vpci *vpci, uint32_t in, uint16_t vbdf, + uint32_t offset, uint32_t bytes, uint32_t *val) +{ + struct pci_vdev *vdev; + int ret; + + vdev = pci_vdev_find(vpci, vbdf); + if (vdev == NULL) { + return; + } + + ret = -EINVAL; + if (in) { + if ((vdev->ops != NULL) && (vdev->ops->cfgread != NULL)) { + ret = vdev->ops->cfgread(vdev, offset, bytes, val); + } + } else { + if ((vdev->ops != NULL) && (vdev->ops->cfgwrite != NULL)) { + ret = vdev->ops->cfgwrite(vdev, offset, bytes, *val); + } + } + + if (ret) { + pr_dbg("pci_vdev_cfg_handler failed, ret=%d", ret); + } +} + diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index 42ea09c96..be22cdeb6 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -167,9 +167,3 @@ void vpci_cleanup(struct vm *vm) } } } - -void pci_vdev_cfg_handler(struct vpci *vpci, uint32_t in, uint16_t vbdf, - uint32_t offset, uint32_t bytes, uint32_t *val) -{ - /* vm-exit handler */ -}