diff --git a/hypervisor/arch/x86/configs/vm_config.c b/hypervisor/arch/x86/configs/vm_config.c index 6930c5ca7..3aafe0f7f 100644 --- a/hypervisor/arch/x86/configs/vm_config.c +++ b/hypervisor/arch/x86/configs/vm_config.c @@ -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; diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 08b9bbc01..f8a309bb3 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -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; } } diff --git a/hypervisor/dm/vpci/vpci.c b/hypervisor/dm/vpci/vpci.c index e4ac8200e..ad47a1cd1 100644 --- a/hypervisor/dm/vpci/vpci.c +++ b/hypervisor/dm/vpci/vpci.c @@ -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; diff --git a/hypervisor/include/arch/x86/vm_config.h b/hypervisor/include/arch/x86/vm_config.h index 0cbbd1058..2d1c28ba7 100644 --- a/hypervisor/include/arch/x86/vm_config.h +++ b/hypervisor/include/arch/x86/vm_config.h @@ -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);