hv: vpci: sos could access low severity guest pci cfg space

There're some cases the SOS (higher severity guest) needs to access the
post-launched VM (lower severity guest) PCI CFG space:
1. The SR-IOV PF needs to reset the VF
2. Some pass through device still need DM to handle some quirk.
In the case a device is assigned to a UOS and is not in a zombie state, the SOS
is able to access, if and only if the SOS has higher severity than the UOS.

Tracked-On: #4371
Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
Li Fei1 2020-03-13 10:16:12 +08:00 committed by wenlingz
parent 537f59f751
commit e5c7a96513
4 changed files with 20 additions and 5 deletions

View File

@ -23,6 +23,14 @@ struct acrn_vm_config *get_vm_config(uint16_t vm_id)
return &vm_configs[vm_id];
}
/*
* @pre vm_id < CONFIG_MAX_VM_NUM
*/
uint8_t get_vm_severity(uint16_t vm_id)
{
return vm_configs[vm_id].severity;
}
static inline bool uuid_is_equal(const uint8_t *uuid1, const uint8_t *uuid2)
{
uint64_t uuid1_h = *(const uint64_t *)uuid1;

View File

@ -119,7 +119,6 @@ static struct acrn_vm *get_highest_severity_vm(void)
{
uint16_t vm_id, highest_vm_id = 0U;
struct acrn_vm *vm = NULL;
struct acrn_vm_config *vm_config;
for (vm_id = 1U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
vm = get_vm_from_vmid(vm_id);
@ -129,8 +128,7 @@ static struct acrn_vm *get_highest_severity_vm(void)
continue;
}
vm_config = get_vm_config(vm_id);
if (vm_config->severity > get_vm_config(highest_vm_id)->severity) {
if (get_vm_severity(vm_id) > get_vm_severity(highest_vm_id)) {
highest_vm_id = vm_id;
}
}

View File

@ -353,8 +353,16 @@ static struct pci_vdev *find_available_vdev(struct acrn_vpci *vpci, union pci_bd
struct pci_vdev *vdev = pci_find_vdev(vpci, bdf);
if ((vdev != NULL) && (vdev->vpci != vpci)) {
/* If the device is assigned to other guest, we could not access it */
vdev = NULL;
/* In the case a device is assigned to a UOS and is not in a zombie state */
if ((vdev->new_owner != NULL) && (vdev->new_owner->vpci != NULL)) {
/* the SOS is able to access, if and only if the SOS has higher severity than the UOS. */
if (get_vm_severity(vpci->vm->vm_id) <
get_vm_severity(vdev->new_owner->vpci->vm->vm_id)) {
vdev = NULL;
}
} else {
vdev = NULL;
}
}
return vdev;

View File

@ -137,6 +137,7 @@ struct acrn_vm_config {
} __aligned(8);
struct acrn_vm_config *get_vm_config(uint16_t vm_id);
uint8_t get_vm_severity(uint16_t vm_id);
bool vm_has_matched_uuid(uint16_t vmid, const uint8_t *uuid);
bool sanitize_vm_config(void);