diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index bb50e8ca9..6ebe6396f 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -138,15 +138,12 @@ bool is_pi_capable(const struct acrn_vm *vm) return (platform_caps.pi && (!is_lapic_pt_configured(vm))); } -static struct acrn_vm *get_highest_severity_vm(void) +struct acrn_vm *get_highest_severity_vm(bool runtime) { uint16_t vm_id, highest_vm_id = 0U; - struct acrn_vm *vm = NULL; for (vm_id = 1U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { - vm = get_vm_from_vmid(vm_id); - - if (is_poweroff_vm(vm)) { + if (runtime && is_poweroff_vm(get_vm_from_vmid(vm_id))) { /* If vm is non-existed or shutdown, it's not highest severity VM */ continue; } @@ -159,14 +156,6 @@ static struct acrn_vm *get_highest_severity_vm(void) return get_vm_from_vmid(highest_vm_id); } -/** - * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM - */ -bool is_highest_severity_vm(const struct acrn_vm *vm) -{ - return (get_highest_severity_vm() == vm); -} - /** * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM */ diff --git a/hypervisor/arch/x86/guest/vm_reset.c b/hypervisor/arch/x86/guest/vm_reset.c index bd7fade2a..8fa532714 100644 --- a/hypervisor/arch/x86/guest/vm_reset.c +++ b/hypervisor/arch/x86/guest/vm_reset.c @@ -84,7 +84,7 @@ static bool handle_common_reset_reg_write(struct acrn_vm *vm, bool reset) bool ret = true; if (reset) { - if (is_highest_severity_vm(vm)) { + if (get_highest_severity_vm(true) == vm) { reset_host(); } else if (is_postlaunched_vm(vm)) { /* re-inject to DM */ diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index d7ed33307..7cbf1172b 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -441,6 +441,7 @@ static void read_cfg_header(const struct pci_vdev *vdev, *val = ~0U; } } else { + /* ToDo: add cfg_hdr_perm for Type 1 device */ if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) { *val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes); @@ -478,6 +479,7 @@ static void write_cfg_header(struct pci_vdev *vdev, } } + /* ToDo: add cfg_hdr_perm for Type 1 device */ if (!bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.ro_mask)) { if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) { pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val); @@ -624,12 +626,16 @@ struct pci_vdev *vpci_init_vdev(struct acrn_vpci *vpci, struct acrn_vm_pci_dev_c if (dev_config->vdev_ops != NULL) { vdev->vdev_ops = dev_config->vdev_ops; } else { - if (is_bridge(vdev->pdev)) { - vdev->vdev_ops = &vpci_bridge_ops; - } else if (is_host_bridge(vdev->pdev)) { - vdev->vdev_ops = &vhostbridge_ops; - } else { + if (get_highest_severity_vm(false) == vpci2vm(vpci)) { vdev->vdev_ops = &pci_pt_dev_ops; + } else { + if (is_bridge(vdev->pdev)) { + vdev->vdev_ops = &vpci_bridge_ops; + } else if (is_host_bridge(vdev->pdev)) { + vdev->vdev_ops = &vhostbridge_ops; + } else { + vdev->vdev_ops = &pci_pt_dev_ops; + } } ASSERT(dev_config->emu_type == PCI_DEV_TYPE_PTDEV, @@ -682,7 +688,8 @@ int32_t vpci_assign_pcidev(struct acrn_vm *tgt_vm, struct acrn_assign_pcidev *pc * For now, we don't support assignment of PF to a UOS. */ if ((vdev_in_sos != NULL) && (vdev_in_sos->user == vdev_in_sos) && - (vdev_in_sos->pdev != NULL) && (!has_sriov_cap(vdev_in_sos))) { + (vdev_in_sos->pdev != NULL) && (!has_sriov_cap(vdev_in_sos)) && + !is_host_bridge(vdev_in_sos->pdev) && !is_bridge(vdev_in_sos->pdev)) { /* ToDo: Each PT device must support one type reset */ if (!vdev_in_sos->pdev->has_pm_reset && !vdev_in_sos->pdev->has_flr && !vdev_in_sos->pdev->has_af_flr) { diff --git a/hypervisor/hw/pci.c b/hypervisor/hw/pci.c index e0f891655..12c67fe7b 100644 --- a/hypervisor/hw/pci.c +++ b/hypervisor/hw/pci.c @@ -229,7 +229,7 @@ bool pdev_need_bar_restore(const struct pci_pdev *pdev) bool need_restore = false; uint32_t idx, bar; - for (idx = 0U; idx < PCI_STD_NUM_BARS; idx++) { + for (idx = 0U; idx < pdev->nr_bars; idx++) { bar = pci_pdev_read_cfg(pdev->bdf, pci_bar_offset(idx), 4U); if (bar != pdev->bars[idx]) { need_restore = true; @@ -244,7 +244,7 @@ static inline void pdev_save_bar(struct pci_pdev *pdev) { uint32_t idx; - for (idx = 0U; idx < PCI_STD_NUM_BARS; idx++) { + for (idx = 0U; idx < pdev->nr_bars; idx++) { pdev->bars[idx] = pci_pdev_read_cfg(pdev->bdf, pci_bar_offset(idx), 4U); } } @@ -253,7 +253,7 @@ void pdev_restore_bar(const struct pci_pdev *pdev) { uint32_t idx; - for (idx = 0U; idx < PCI_STD_NUM_BARS; idx++) { + for (idx = 0U; idx < pdev->nr_bars; idx++) { pci_pdev_write_cfg(pdev->bdf, pci_bar_offset(idx), 4U, pdev->bars[idx]); } } diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index 6f80fbbf9..b65ce04b7 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -254,7 +254,7 @@ bool is_lapic_pt_configured(const struct acrn_vm *vm); bool is_rt_vm(const struct acrn_vm *vm); bool is_pi_capable(const struct acrn_vm *vm); bool has_rt_vm(void); -bool is_highest_severity_vm(const struct acrn_vm *vm); +struct acrn_vm *get_highest_severity_vm(bool runtime); bool vm_hide_mtrr(const struct acrn_vm *vm); void update_vm_vlapic_state(struct acrn_vm *vm); enum vm_vlapic_state check_vm_vlapic_state(const struct acrn_vm *vm);