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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user