hv: vpci: add PCI BAR re-program address check

In theory, guest could re-program PCI BAR address to any address. However, ACRN
hypervisor only support [0, top_address_space) EPT memory mapping. So we need to
check whether the PCI BAR re-program address is within this scope.

Tracked-On: #3475
Signed-off-by: Li, Fei1 <fei1.li@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Li, Fei1 2019-10-14 23:26:57 +08:00 committed by wenlingz
parent dab14856c2
commit dc1e2adaec
4 changed files with 37 additions and 11 deletions

View File

@ -18,6 +18,18 @@
#define ACRN_DBG_EPT 6U
bool ept_is_mr_valid(const struct acrn_vm *vm, uint64_t base, uint64_t size)
{
bool valid = true;
uint64_t end = base + size;
uint64_t top_address_space = vm->arch_vm.ept_mem_ops.info->ept.top_address_space;
if ((end <= base) || (end > top_address_space)) {
valid = false;
}
return valid;
}
void destroy_ept(struct acrn_vm *vm)
{
/* Destroy secure world */

View File

@ -626,7 +626,6 @@ static int32_t add_vm_memory_region(struct acrn_vm *vm, struct acrn_vm *target_v
static int32_t set_vm_memory_region(struct acrn_vm *vm,
struct acrn_vm *target_vm, const struct vm_memory_region *region)
{
uint64_t gpa_end;
uint64_t *pml4_page;
int32_t ret;
@ -635,8 +634,7 @@ static int32_t set_vm_memory_region(struct acrn_vm *vm,
__func__, target_vm->vm_id, region->size);
ret = -EINVAL;
} else {
gpa_end = region->gpa + region->size;
if (gpa_end > target_vm->arch_vm.ept_mem_ops.info->ept.top_address_space) {
if (!ept_is_mr_valid(target_vm, region->gpa, region->size)) {
pr_err("%s, invalid gpa: 0x%llx, size: 0x%llx, top_address_space: 0x%llx", __func__,
region->gpa, region->size,
target_vm->arch_vm.ept_mem_ops.info->ept.top_address_space);

View File

@ -248,6 +248,7 @@ static void vdev_pt_remap_generic_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
vbar->size);
}
if (ept_is_mr_valid(vm, vbar_base, vbar->size)) {
/* Map the physical BAR in the guest MMIO space */
ept_add_mr(vm, (uint64_t *)(vm->arch_vm.nworld_eptp),
pbar_base, /* HPA (pbar) */
@ -257,6 +258,10 @@ static void vdev_pt_remap_generic_mem_vbar(struct pci_vdev *vdev, uint32_t idx)
/* Remember the previously mapped MMIO vbar */
vdev->bar_base_mapped[idx] = vbar_base;
} else {
pr_fatal("%s, %x:%x.%x set invalid bar[%d] address: 0x%llx\n", __func__,
vdev->bdf.bits.b, vdev->bdf.bits.d, vdev->bdf.bits.f, idx, vbar_base);
}
}
}
}

View File

@ -18,6 +18,17 @@ typedef void (*pge_handler)(uint64_t *pgentry, uint64_t size);
#define INVALID_HPA (0x1UL << 52U)
#define INVALID_GPA (0x1UL << 52U)
/* External Interfaces */
/**
* @brief Check guest-physical memory region mapping valid
*
* @param[in] vm the pointer that points to VM data structure
* @param[in] base The specified start guest physical address of guest
* physical memory region
* @param[in] size The size of guest physical memory region
*
* @retval true if the guest-physical memory region mapping valid, false otherwise.
*/
bool ept_is_mr_valid(const struct acrn_vm *vm, uint64_t base, uint64_t size);
/**
* @brief EPT page tables destroy
*