mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
ANDROID: KVM: arm64: Sanity check the input to pKVM module mm APIs
Now that the pKVM memory-management module APIs are exposed outside of core pKVM, make sure to sanity check the input to __pkvm_map_module_page() which expects a VA that was previously allocated in the private range. We can't easily check that each private VA page is used to map the module it was allocated for, but we can at least check that all module pages fall in the private range, which is still desirable to enforce some degree of consitency. This is all best effort really. Bug: 264070847 Change-Id: Ib95e464f57beaf0c32d15075938ca283fe52f720 Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
@@ -102,13 +102,40 @@ int __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NVHE_EL2_DEBUG
|
||||
static unsigned long mod_range_start = ULONG_MAX;
|
||||
static unsigned long mod_range_end;
|
||||
|
||||
static void update_mod_range(unsigned long addr, size_t size)
|
||||
{
|
||||
mod_range_start = min(mod_range_start, addr);
|
||||
mod_range_end = max(mod_range_end, addr + size);
|
||||
}
|
||||
|
||||
static void assert_in_mod_range(unsigned long addr)
|
||||
{
|
||||
/*
|
||||
* This is not entirely watertight if there are private range
|
||||
* allocations between modules being loaded, but in practice that is
|
||||
* probably going to be allocation initiated by the modules themselves.
|
||||
*/
|
||||
WARN_ON(addr < mod_range_start || mod_range_end <= addr);
|
||||
}
|
||||
#else
|
||||
static inline void update_mod_range(unsigned long addr, size_t size) { }
|
||||
static inline void assert_in_mod_range(unsigned long addr) { }
|
||||
#endif
|
||||
|
||||
void *__pkvm_alloc_module_va(u64 nr_pages)
|
||||
{
|
||||
size_t size = nr_pages << PAGE_SHIFT;
|
||||
unsigned long addr = 0;
|
||||
|
||||
pkvm_modules_lock();
|
||||
if (pkvm_modules_enabled())
|
||||
pkvm_alloc_private_va_range(nr_pages << PAGE_SHIFT, &addr);
|
||||
if (pkvm_modules_enabled()) {
|
||||
if (!pkvm_alloc_private_va_range(size, &addr))
|
||||
update_mod_range(addr, size);
|
||||
}
|
||||
pkvm_modules_unlock();
|
||||
|
||||
return (void *)addr;
|
||||
@@ -116,10 +143,13 @@ void *__pkvm_alloc_module_va(u64 nr_pages)
|
||||
|
||||
int __pkvm_map_module_page(u64 pfn, void *va, enum kvm_pgtable_prot prot)
|
||||
{
|
||||
unsigned long addr = (unsigned long)va;
|
||||
int ret = -EACCES;
|
||||
|
||||
pkvm_modules_lock();
|
||||
|
||||
assert_in_mod_range(addr);
|
||||
|
||||
if (!pkvm_modules_enabled())
|
||||
goto err;
|
||||
|
||||
@@ -127,7 +157,7 @@ int __pkvm_map_module_page(u64 pfn, void *va, enum kvm_pgtable_prot prot)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = __pkvm_create_mappings((unsigned long)va, PAGE_SIZE, hyp_pfn_to_phys(pfn), prot);
|
||||
ret = __pkvm_create_mappings(addr, PAGE_SIZE, hyp_pfn_to_phys(pfn), prot);
|
||||
err:
|
||||
pkvm_modules_unlock();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user