ANDROID: iommu/arm-smmu-v3-kvm: Support EL1 compiling as module

This includes
- Loading of EL2 code
- Using module token to get hyp va

Bug: 357781595
Bug: 384432312

Change-Id: I70cb6b1f848042bf9d98afd671400afa5fe15f78
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Mostafa Saleh
2023-08-17 21:44:05 +00:00
parent db3f87c61c
commit 25dfae8459
3 changed files with 35 additions and 1 deletions
+2
View File
@@ -25,6 +25,7 @@ int kvm_iommu_register_driver(struct kvm_iommu_driver *kern_ops)
*/
return cmpxchg_release(&iommu_driver, NULL, kern_ops) ? -EBUSY : 0;
}
EXPORT_SYMBOL(kvm_iommu_register_driver);
int kvm_iommu_init_hyp(struct kvm_iommu_ops *hyp_ops)
{
@@ -51,6 +52,7 @@ int kvm_iommu_init_driver(void)
return iommu_driver->init_driver();
}
EXPORT_SYMBOL(kvm_iommu_init_driver);
void kvm_iommu_remove_driver(void)
{
+1
View File
@@ -1140,3 +1140,4 @@ int __pkvm_topup_hyp_alloc_mgt_gfp(unsigned long id, unsigned long nr_pages,
return ret;
}
EXPORT_SYMBOL(__pkvm_topup_hyp_alloc_mgt_gfp);
@@ -45,6 +45,18 @@ struct kvm_arm_smmu_domain {
#define to_kvm_smmu_domain(_domain) \
container_of(_domain, struct kvm_arm_smmu_domain, domain)
#ifdef MODULE
static unsigned long pkvm_module_token;
#define ksym_ref_addr_nvhe(x) \
((typeof(kvm_nvhe_sym(x)) *)(pkvm_el2_mod_va(&kvm_nvhe_sym(x), pkvm_module_token)))
int kvm_nvhe_sym(smmu_init_hyp_module)(const struct pkvm_module_ops *ops);
#else
#define ksym_ref_addr_nvhe(x) \
((typeof(kvm_nvhe_sym(x)) *)(kern_hyp_va(lm_alias(&kvm_nvhe_sym(x)))))
#endif
static size_t kvm_arm_smmu_cur;
static size_t kvm_arm_smmu_count;
static struct hyp_arm_smmu_v3_device *kvm_arm_smmu_array;
@@ -959,6 +971,15 @@ static int kvm_arm_smmu_v3_init_drv(void)
goto err_free;
}
#ifdef MODULE
ret = pkvm_load_el2_module(kvm_nvhe_sym(smmu_init_hyp_module),
&pkvm_module_token);
if (ret) {
pr_err("Failed to load SMMUv3 IOMMU EL2 module: %d\n", ret);
return ret;
}
#endif
/*
* These variables are stored in the nVHE image, and won't be accessible
* after KVM initialization. Ownership of kvm_arm_smmu_array will be
@@ -967,7 +988,7 @@ static int kvm_arm_smmu_v3_init_drv(void)
kvm_hyp_arm_smmu_v3_smmus = kvm_arm_smmu_array;
kvm_hyp_arm_smmu_v3_count = kvm_arm_smmu_count;
ret = kvm_iommu_init_hyp(kern_hyp_va(lm_alias(&kvm_nvhe_sym(smmu_ops))));
ret = kvm_iommu_init_hyp(ksym_ref_addr_nvhe(smmu_ops));
if (ret)
return ret;
return kvm_arm_smmu_v3_post_init();
@@ -995,5 +1016,15 @@ static int kvm_arm_smmu_v3_register(void)
return kvm_iommu_register_driver(&kvm_smmu_v3_ops);
};
/*
* Register must be run before de-privliage before kvm_iommu_init_driver
* for module case, it should be loaded using pKVM early loading which
* loads it before this point.
* For builtin drivers we use core_initcall
*/
#ifdef MODULE
module_init(kvm_arm_smmu_v3_register);
#else
core_initcall(kvm_arm_smmu_v3_register);
#endif
MODULE_LICENSE("GPL v2");