Add the KVM_CAP_ARM_RME_CREATE_FD ioctl to create a realm. This involves
delegating pages to the RMM to hold the Realm Descriptor (RD) and for
the base level of the Realm Translation Tables (RTT). A VMID also need
to be picked, since the RMM has a separate VMID address space a
dedicated allocator is added for this purpose.
KVM_CAP_ARM_RME_CONFIG_REALM is provided to allow configuring the realm
before it is created.
Co-developed-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
Signed-off-by: Steven Price <steven.price@xxxxxxx>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
---
arch/arm64/include/asm/kvm_emulate.h | 5 +
arch/arm64/include/asm/kvm_rme.h | 19 ++
arch/arm64/kvm/arm.c | 18 ++
arch/arm64/kvm/mmu.c | 15 +-
arch/arm64/kvm/rme.c | 282 +++++++++++++++++++++++++++
5 files changed, 337 insertions(+), 2 deletions(-)
@@ -1014,6 +1018,13 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
struct kvm_pgtable *pgt = NULL;
write_lock(&kvm->mmu_lock);
+ if (kvm_is_realm(kvm) &&
+ (kvm_realm_state(kvm) != REALM_STATE_DEAD &&
+ kvm_realm_state(kvm) != REALM_STATE_NONE)) {
+ /* TODO: teardown rtts */
+ write_unlock(&kvm->mmu_lock);
+ return;
+ }
pgt = mmu->pgt;
if (pgt) {
mmu->pgd_phys = 0;
+
+void kvm_destroy_realm(struct kvm *kvm)
+{
+ for (i = 0; i < pgt->pgd_pages; i++) {
+ phys_addr_t pgd_phys = kvm->arch.mmu.pgd_phys + i * PAGE_SIZE;
+
+ if (WARN_ON(rmi_granule_undelegate(pgd_phys)))
+ return;
+ }
+
+ WRITE_ONCE(realm->state, REALM_STATE_DEAD);
+
+ kvm_free_stage2_pgd(&kvm->arch.mmu);
+}
+
+int kvm_init_realm_vm(struct kvm *kvm)
+{
+ struct realm_params *params;
+
+ params = (struct realm_params *)get_zeroed_page(GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
+
+ /* Default parameters, not exposed to user space */
+ params->s2sz = VTCR_EL2_IPA(kvm->arch.mmu.vtcr);
+ kvm->arch.realm.params = params;
+ return 0;
+}
+
int kvm_init_rme(void)
{
+ int ret;
+
if (PAGE_SIZE != SZ_4K)
/* Only 4k page size on the host is supported */
return 0;
@@ -46,6 +321,13 @@ int kvm_init_rme(void)
/* Continue without realm support */
return 0;
+ if (WARN_ON(rmi_features(0, &rmm_feat_reg0)))
+ return 0;
+
+ ret = rme_vmid_init();
+ if (ret)
+ return ret;
+
/* Future patch will enable static branch kvm_rme_is_available */
return 0;