diff --git a/hypervisor/Makefile b/hypervisor/Makefile index d724e0960..d223a81f4 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -220,14 +220,13 @@ C_SRCS += dm/vpci/vdev.c 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/hostbridge.c C_SRCS += dm/vpci/pci_pt.c -else C_SRCS += dm/vpci/sharing_mode.c C_SRCS += dm/vpci/msi.c C_SRCS += dm/vpci/msix.c -endif C_SRCS += bsp/firmware_wrapper.c C_SRCS += bsp/firmware_sbl.c diff --git a/hypervisor/dm/vpci/msix.c b/hypervisor/dm/vpci/msix.c index 87aae3235..93da7d97b 100644 --- a/hypervisor/dm/vpci/msix.c +++ b/hypervisor/dm/vpci/msix.c @@ -279,6 +279,10 @@ static void vmsix_table_rw(struct pci_vdev *vdev, struct mmio_request *mmio, uin } +/** + * @pre io_req != NULL + * @pre handler_private_data != NULL + */ static int32_t vmsix_table_mmio_access_handler(struct io_request *io_req, void *handler_private_data) { struct mmio_request *mmio = &io_req->reqs.mmio; diff --git a/hypervisor/dm/vpci/partition_mode.c b/hypervisor/dm/vpci/partition_mode.c index 72a520769..e186c7f2f 100644 --- a/hypervisor/dm/vpci/partition_mode.c +++ b/hypervisor/dm/vpci/partition_mode.c @@ -137,7 +137,10 @@ void partition_mode_vpci_deinit(const struct acrn_vm *vm) } } -void partition_mode_cfgread(struct acrn_vpci *vpci, union pci_bdf vbdf, +/** + * @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); @@ -156,7 +159,10 @@ void partition_mode_cfgread(struct acrn_vpci *vpci, union pci_bdf vbdf, } } -void partition_mode_cfgwrite(struct acrn_vpci *vpci, union pci_bdf vbdf, +/** + * @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); diff --git a/hypervisor/dm/vpci/pci_priv.h b/hypervisor/dm/vpci/pci_priv.h index 27d130c8d..cc5debbf5 100644 --- a/hypervisor/dm/vpci/pci_priv.h +++ b/hypervisor/dm/vpci/pci_priv.h @@ -67,7 +67,6 @@ static inline void pci_vdev_write_cfg_u32(struct pci_vdev *vdev, uint32_t offset vdev->cfgdata.data_32[offset >> 2U] = val; } -#ifdef CONFIG_PARTITION_MODE void vdev_hostbridge_init(struct pci_vdev *vdev); int32_t vdev_hostbridge_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val); int32_t vdev_hostbridge_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); @@ -78,7 +77,6 @@ int32_t vdev_pt_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t b 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); -#else void vmsi_init(struct pci_vdev *vdev); int32_t vmsi_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val); int32_t vmsi_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); @@ -87,7 +85,6 @@ void vmsix_init(struct pci_vdev *vdev); int32_t vmsix_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val); int32_t vmsix_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); void vmsix_deinit(const struct pci_vdev *vdev); -#endif uint32_t pci_vdev_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes); void pci_vdev_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val); diff --git a/hypervisor/dm/vpci/pci_pt.c b/hypervisor/dm/vpci/pci_pt.c index 8c761eaa8..2df3c7c59 100644 --- a/hypervisor/dm/vpci/pci_pt.c +++ b/hypervisor/dm/vpci/pci_pt.c @@ -42,6 +42,10 @@ static inline uint32_t pci_bar_base(uint32_t bar) return bar & PCIM_BAR_MEM_BASE; } +#if defined(HV_DEBUG) +/** + * @pre vdev != NULL + */ static int32_t validate(const struct pci_vdev *vdev) { uint32_t idx; @@ -59,7 +63,13 @@ static int32_t validate(const struct pci_vdev *vdev) return ret; } +#endif +/** + * @pre vdev != NULL + * @pre vdev->vpci != NULL + * @pre vdev->vpci->vm != NULL + */ void vdev_pt_init(struct pci_vdev *vdev) { int32_t ret; @@ -90,6 +100,11 @@ void vdev_pt_init(struct pci_vdev *vdev) pci_pdev_write_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U, pci_command); } +/** + * @pre vdev != NULL + * @pre vdev->vpci != NULL + * @pre vdev->vpci->vm != NULL + */ void vdev_pt_deinit(const struct pci_vdev *vdev) { int32_t ret; @@ -102,6 +117,9 @@ void vdev_pt_deinit(const struct pci_vdev *vdev) } } +/** + * @pre vdev != NULL + */ int32_t vdev_pt_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val) { @@ -116,7 +134,12 @@ int32_t vdev_pt_cfgread(const struct pci_vdev *vdev, uint32_t offset, return ret; } -static void vdev_pt_remap_bar(struct pci_vdev *vdev, uint32_t idx, +/** + * @pre vdev != NULL + * @pre vdev->vpci != NULL + * @pre vdev->vpci->vm != NULL + */ +static void vdev_pt_remap_bar(const struct pci_vdev *vdev, uint32_t idx, uint32_t new_base) { struct acrn_vm *vm = vdev->vpci->vm; @@ -137,6 +160,9 @@ static void vdev_pt_remap_bar(struct pci_vdev *vdev, uint32_t idx, } } +/** + * @pre vdev != NULL + */ static void vdev_pt_cfgwrite_bar(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t new_bar_uos) { @@ -176,6 +202,9 @@ static void vdev_pt_cfgwrite_bar(struct pci_vdev *vdev, uint32_t offset, pci_vdev_write_cfg_u32(vdev, offset, new_bar); } +/** + * @pre vdev != NULL + */ int32_t vdev_pt_cfgwrite(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val) { diff --git a/hypervisor/dm/vpci/sharing_mode.c b/hypervisor/dm/vpci/sharing_mode.c index ecd31f0d7..4201b76d0 100644 --- a/hypervisor/dm/vpci/sharing_mode.c +++ b/hypervisor/dm/vpci/sharing_mode.c @@ -28,7 +28,6 @@ */ #include -#include #include #include "pci_priv.h" @@ -100,40 +99,35 @@ static void init_vdev_for_pdev(struct pci_pdev *pdev, const void *vm) } } + +/** + * @pre vm != NULL + * @pre is_sos_vm(vm) == true + */ int32_t sharing_mode_vpci_init(const struct acrn_vm *vm) { - int32_t ret = -ENODEV; + /* Build up vdev array for sos_vm */ + pci_pdev_foreach(init_vdev_for_pdev, vm); - /* - * Only set up IO bitmap for SOS. - * IO/MMIO requests from non-sos_vm guests will be injected to device model. - */ - if (is_sos_vm(vm)) { - /* Build up vdev array for sos_vm */ - pci_pdev_foreach(init_vdev_for_pdev, vm); - ret = 0; - } - - return ret; + 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; - if (is_sos_vm(vm)) { - for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { - vdev = (struct pci_vdev *)&(vm->vpci.pci_vdevs[i]); + for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { + vdev = (struct pci_vdev *)&(vm->vpci.pci_vdevs[i]); - vmsi_deinit(vdev); + vmsi_deinit(vdev); - vmsix_deinit(vdev); - } + vmsix_deinit(vdev); } } diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index cea7dc917..1df34cd7b 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -28,6 +28,8 @@ */ #include +#include +#include #include "pci_priv.h" static void pci_cfg_clear_cache(struct pci_addr_info *pi) @@ -37,6 +39,9 @@ static void pci_cfg_clear_cache(struct pci_addr_info *pi) pi->cached_enable = false; } +/** + * @pre vm != NULL + */ static uint32_t pci_cfgaddr_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes) { uint32_t val = ~0U; @@ -55,6 +60,9 @@ static uint32_t pci_cfgaddr_io_read(struct acrn_vm *vm, uint16_t addr, size_t by return val; } +/** + * @pre vm != NULL + */ static void pci_cfgaddr_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val) { struct acrn_vpci *vpci = &vm->vpci; @@ -82,20 +90,36 @@ static inline bool vpci_is_valid_access(uint32_t offset, uint32_t bytes) return (vpci_is_valid_access_byte(bytes) && vpci_is_valid_access_offset(offset, bytes)); } +/** + * @pre vm != NULL + * @pre vm->vm_id < CONFIG_MAX_VM_NUM + * @pre (get_vm_config(vm->vm_id)->type == PRE_LAUNCHED_VM) || (get_vm_config(vm->vm_id)->type == SOS_VM) + */ static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes) { struct acrn_vpci *vpci = &vm->vpci; struct pci_addr_info *pi = &vpci->addr_info; uint16_t offset = addr - PCI_CONFIG_DATA; uint32_t val = ~0U; + struct acrn_vm_config *vm_config; if (pi->cached_enable) { if (vpci_is_valid_access(pi->cached_reg + offset, bytes)) { -#ifdef CONFIG_PARTITION_MODE - partition_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val); -#else - sharing_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val); -#endif + vm_config = get_vm_config(vm->vm_id); + + switch (vm_config->type) { + case PRE_LAUNCHED_VM: + partition_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val); + break; + + case SOS_VM: + sharing_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val); + break; + + default: + ASSERT(false, "Error, pci_cfgdata_io_read should only be called for PRE_LAUNCHED_VM and SOS_VM"); + break; + } } pci_cfg_clear_cache(pi); } @@ -103,28 +127,49 @@ static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t by return val; } +/** + * @pre vm != NULL + * @pre vm->vm_id < CONFIG_MAX_VM_NUM + * @pre (get_vm_config(vm->vm_id)->type == PRE_LAUNCHED_VM) || (get_vm_config(vm->vm_id)->type == SOS_VM) + */ static void pci_cfgdata_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val) { struct acrn_vpci *vpci = &vm->vpci; struct pci_addr_info *pi = &vpci->addr_info; uint16_t offset = addr - PCI_CONFIG_DATA; + struct acrn_vm_config *vm_config; + if (pi->cached_enable) { if (vpci_is_valid_access(pi->cached_reg + offset, bytes)) { -#ifdef CONFIG_PARTITION_MODE - partition_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val); -#else - sharing_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val); -#endif + vm_config = get_vm_config(vm->vm_id); + + switch (vm_config->type) { + case PRE_LAUNCHED_VM: + partition_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val); + break; + + case SOS_VM: + sharing_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val); + break; + + default: + ASSERT(false, "Error, pci_cfgdata_io_write should only be called for PRE_LAUNCHED_VM and SOS_VM"); + break; + } } pci_cfg_clear_cache(pi); } } +/** + * @pre vm != NULL + * @pre vm->vm_id < CONFIG_MAX_VM_NUM + */ void vpci_init(struct acrn_vm *vm) { struct acrn_vpci *vpci = &vm->vpci; - int32_t ret; + int32_t ret = -EINVAL; struct vm_io_range pci_cfgaddr_range = { .flags = IO_ATTR_RW, @@ -138,13 +183,24 @@ void vpci_init(struct acrn_vm *vm) .len = 4U }; + struct acrn_vm_config *vm_config; + vpci->vm = vm; -#ifdef CONFIG_PARTITION_MODE - ret = partition_mode_vpci_init(vm); -#else - ret = sharing_mode_vpci_init(vm); -#endif + vm_config = get_vm_config(vm->vm_id); + switch (vm_config->type) { + case PRE_LAUNCHED_VM: + ret = partition_mode_vpci_init(vm); + break; + + case SOS_VM: + ret = sharing_mode_vpci_init(vm); + break; + + default: + /* Nothing to do for other vm types */ + break; + } if (ret == 0) { /* @@ -161,11 +217,26 @@ void vpci_init(struct acrn_vm *vm) } } +/** + * @pre vm != NULL + * @pre vm->vm_id < CONFIG_MAX_VM_NUM + */ void vpci_cleanup(const struct acrn_vm *vm) { -#ifdef CONFIG_PARTITION_MODE - partition_mode_vpci_deinit(vm); -#else - sharing_mode_vpci_deinit(vm); -#endif + struct acrn_vm_config *vm_config; + + vm_config = get_vm_config(vm->vm_id); + switch (vm_config->type) { + case PRE_LAUNCHED_VM: + partition_mode_vpci_deinit(vm); + break; + + case SOS_VM: + sharing_mode_vpci_deinit(vm); + break; + + default: + /* Nothing to do for other vm types */ + break; + } } diff --git a/hypervisor/include/dm/vpci.h b/hypervisor/include/dm/vpci.h index 7aa187a2d..c49604ba9 100644 --- a/hypervisor/include/dm/vpci.h +++ b/hypervisor/include/dm/vpci.h @@ -76,10 +76,8 @@ struct pci_vdev { /* The bar info of the virtual PCI device. */ struct pci_bar bar[PCI_BAR_COUNT]; -#ifndef CONFIG_PARTITION_MODE struct pci_msi msi; struct pci_msix msix; -#endif }; struct pci_addr_info { @@ -96,9 +94,9 @@ struct acrn_vpci { }; int32_t partition_mode_vpci_init(const struct acrn_vm *vm); -void partition_mode_cfgread(struct acrn_vpci *vpci, union pci_bdf vbdf, +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(struct acrn_vpci *vpci, union pci_bdf vbdf, +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);