hv: hypercall: prevent sos can touch hv/pre-launched VM resource

Current implementation, SOS may allocate the memory region belonging to
hypervisor/pre-launched VM to a post-launched VM. Because it only verifies
the start address rather than the entire memory region.

This patch verifies the validity of the entire memory region before
allocating to a post-launched VM so that the specified memory can only
be allocated to a post-launched VM if the entire memory region is mapped
in SOS’s EPT.

Tracked-On: #5555
Signed-off-by: Li Fei1 <fei1.li@intel.com>
Reviewed-by: Yonghua Huang  <yonghua.huang@intel.com>
This commit is contained in:
Li Fei1
2021-02-01 11:29:14 +08:00
committed by wenlingz
parent 0b6840d1be
commit 94a980c923
4 changed files with 117 additions and 86 deletions

View File

@@ -19,6 +19,10 @@
#define DBG_LEVEL_EPT 6U
/*
* to be deprecated, don't use
* Check whether pagetable pages is reserved enough for the GPA range or not.
*/
bool ept_is_mr_valid(const struct acrn_vm *vm, uint64_t base, uint64_t size)
{
bool valid = true;
@@ -31,6 +35,34 @@ bool ept_is_mr_valid(const struct acrn_vm *vm, uint64_t base, uint64_t size)
return valid;
}
/*
* To enable the identical map and support of legacy devices/ACPI method in SOS,
* ACRN presents the entire host 0-4GB memory region to SOS, except the memory
* regions explicitly assigned to pre-launched VMs or HV (DRAM and MMIO). However,
* virtual e820 only contains the known DRAM regions. For this reason,
* we can't know if the GPA range is guest valid or not, by checking with
* its ve820 tables only.
*
* instead, we Check if the GPA range is guest valid by whether the GPA range is mapped
* in EPT pagetable or not
*/
bool ept_is_valid_mr(struct acrn_vm *vm, uint64_t mr_base_gpa, uint64_t mr_size)
{
bool present = true;
uint32_t sz;
uint64_t end = mr_base_gpa + mr_size, address = mr_base_gpa;
while (address < end) {
if (local_gpa2hpa(vm, address, &sz) == INVALID_HPA) {
present = false;
break;
}
address += sz;
}
return present;
}
void destroy_ept(struct acrn_vm *vm)
{
/* Destroy secure world */