hv: vpci: hv: vpci: refine pci device assignment logic

Now Host Bridge and PCI Bridge could only be added to SOS's acrn_vm_pci_dev_config.
So For UOS, we always emualte Host Bridge and PCI Bridge for it and assign PCI device
to it; for SOS, if it's the highest severity VM, we will assign Host Bridge and PCI
Bridge to it directly, otherwise, we will emulate them same as UOS.

Tracked-On: #4550
Signed-off-by: Li Fei1 <fei1.li@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Li Fei1 2020-06-02 15:50:46 +08:00 committed by wenlingz
parent b8f151a55f
commit ae4fa40adc
5 changed files with 20 additions and 24 deletions

View File

@ -138,15 +138,12 @@ bool is_pi_capable(const struct acrn_vm *vm)
return (platform_caps.pi && (!is_lapic_pt_configured(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; 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++) { for (vm_id = 1U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
vm = get_vm_from_vmid(vm_id); if (runtime && is_poweroff_vm(get_vm_from_vmid(vm_id))) {
if (is_poweroff_vm(vm)) {
/* If vm is non-existed or shutdown, it's not highest severity VM */ /* If vm is non-existed or shutdown, it's not highest severity VM */
continue; continue;
} }
@ -159,14 +156,6 @@ static struct acrn_vm *get_highest_severity_vm(void)
return get_vm_from_vmid(highest_vm_id); 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 * @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
*/ */

View File

@ -84,7 +84,7 @@ static bool handle_common_reset_reg_write(struct acrn_vm *vm, bool reset)
bool ret = true; bool ret = true;
if (reset) { if (reset) {
if (is_highest_severity_vm(vm)) { if (get_highest_severity_vm(true) == vm) {
reset_host(); reset_host();
} else if (is_postlaunched_vm(vm)) { } else if (is_postlaunched_vm(vm)) {
/* re-inject to DM */ /* re-inject to DM */

View File

@ -441,6 +441,7 @@ static void read_cfg_header(const struct pci_vdev *vdev,
*val = ~0U; *val = ~0U;
} }
} else { } else {
/* ToDo: add cfg_hdr_perm for Type 1 device */
if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) { if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) {
*val = pci_pdev_read_cfg(vdev->pdev->bdf, offset, bytes); *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.ro_mask)) {
if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) { if (bitmap32_test(((uint16_t)offset) >> 2U, &cfg_hdr_perm.pt_mask)) {
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val); pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
@ -623,6 +625,9 @@ struct pci_vdev *vpci_init_vdev(struct acrn_vpci *vpci, struct acrn_vm_pci_dev_c
if (dev_config->vdev_ops != NULL) { if (dev_config->vdev_ops != NULL) {
vdev->vdev_ops = dev_config->vdev_ops; vdev->vdev_ops = dev_config->vdev_ops;
} else {
if (get_highest_severity_vm(false) == vpci2vm(vpci)) {
vdev->vdev_ops = &pci_pt_dev_ops;
} else { } else {
if (is_bridge(vdev->pdev)) { if (is_bridge(vdev->pdev)) {
vdev->vdev_ops = &vpci_bridge_ops; vdev->vdev_ops = &vpci_bridge_ops;
@ -631,6 +636,7 @@ struct pci_vdev *vpci_init_vdev(struct acrn_vpci *vpci, struct acrn_vm_pci_dev_c
} else { } else {
vdev->vdev_ops = &pci_pt_dev_ops; vdev->vdev_ops = &pci_pt_dev_ops;
} }
}
ASSERT(dev_config->emu_type == PCI_DEV_TYPE_PTDEV, ASSERT(dev_config->emu_type == PCI_DEV_TYPE_PTDEV,
"Only PCI_DEV_TYPE_PTDEV could not configure vdev_ops"); "Only PCI_DEV_TYPE_PTDEV could not configure vdev_ops");
@ -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. * For now, we don't support assignment of PF to a UOS.
*/ */
if ((vdev_in_sos != NULL) && (vdev_in_sos->user == vdev_in_sos) && 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 */ /* ToDo: Each PT device must support one type reset */
if (!vdev_in_sos->pdev->has_pm_reset && !vdev_in_sos->pdev->has_flr && if (!vdev_in_sos->pdev->has_pm_reset && !vdev_in_sos->pdev->has_flr &&
!vdev_in_sos->pdev->has_af_flr) { !vdev_in_sos->pdev->has_af_flr) {

View File

@ -229,7 +229,7 @@ bool pdev_need_bar_restore(const struct pci_pdev *pdev)
bool need_restore = false; bool need_restore = false;
uint32_t idx, bar; 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); bar = pci_pdev_read_cfg(pdev->bdf, pci_bar_offset(idx), 4U);
if (bar != pdev->bars[idx]) { if (bar != pdev->bars[idx]) {
need_restore = true; need_restore = true;
@ -244,7 +244,7 @@ static inline void pdev_save_bar(struct pci_pdev *pdev)
{ {
uint32_t idx; 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); 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; 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]); pci_pdev_write_cfg(pdev->bdf, pci_bar_offset(idx), 4U, pdev->bars[idx]);
} }
} }

View File

@ -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_rt_vm(const struct acrn_vm *vm);
bool is_pi_capable(const struct acrn_vm *vm); bool is_pi_capable(const struct acrn_vm *vm);
bool has_rt_vm(void); 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); bool vm_hide_mtrr(const struct acrn_vm *vm);
void update_vm_vlapic_state(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); enum vm_vlapic_state check_vm_vlapic_state(const struct acrn_vm *vm);