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)));
}
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
*/

View File

@ -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 */

View File

@ -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) {

View File

@ -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]);
}
}

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_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);