diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 1499c2d54a87..c17aee87de91 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -164,6 +164,7 @@ struct kvm_pinned_page { struct kvm_protected_vm { bool enabled; int shadow_handle; + struct mutex shadow_lock; struct kvm_hyp_memcache teardown_mc; struct list_head pinned_pages; }; diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index efb54331fd6f..f96f8fa7059e 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -16,6 +16,8 @@ #define HYP_MEMBLOCK_REGIONS 128 +int create_el2_shadow(struct kvm *kvm); + /* * Definitions for features to be allowed or restricted for guest virtual * machines, depending on the mode KVM is running in and on the type of guest diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 97b40bd1d429..4ed14cf9ad13 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -774,6 +774,9 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) static_branch_inc(&userspace_irqchip_in_use); } + if (is_protected_kvm_enabled()) + ret = create_el2_shadow(kvm); + return ret; } diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 90d4a15e9cd9..431b85575dc0 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -118,16 +118,13 @@ static void update_vcpu_state(struct kvm_vcpu *vcpu, int shadow_handle) * * Return 0 on success, negative error code on failure. */ -static int create_el2_shadow(struct kvm *kvm) +static int __create_el2_shadow(struct kvm *kvm) { size_t pgd_sz, shadow_sz; void *pgd, *shadow_addr; int shadow_handle; int ret, i; - if (kvm->arch.pkvm.shadow_handle) - return -EEXIST; - if (kvm->created_vcpus < 1) return -EINVAL; @@ -174,20 +171,14 @@ free_pgd: return ret; } -int pkvm_init_el2_context(struct kvm *kvm) +int create_el2_shadow(struct kvm *kvm) { int ret = 0; - mutex_lock(&kvm->lock); - ret = create_el2_shadow(kvm); - mutex_unlock(&kvm->lock); + mutex_lock(&kvm->arch.pkvm.shadow_lock); + if (!kvm->arch.pkvm.shadow_handle) + ret = __create_el2_shadow(kvm); + mutex_unlock(&kvm->arch.pkvm.shadow_lock); - if (ret < 0) { - kvm_err("Creating shadow structures for protected VM failed: %d\n", - ret); - return ret; - } - - kvm_pr_unimpl("Stage-2 protection is a work-in-progress: civilization phase III\n"); - return 0; + return ret; }