From ede52bb8fecbe9a443a92332800b49bce63df2dc Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 7 Jul 2022 15:48:53 +0100 Subject: [PATCH] Revert "ANDROID: KVM: arm64: Make the use of host or shadow vcpu less error prone" This reverts commit 0b9114c308bb731647f1d2077cfab40c10a976ab. Bug: 233587962 Signed-off-by: Will Deacon Change-Id: Ibbfa7f977bddab8123c27d016af32b3ab360a1fe --- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 139 +++++++++++------------------ 1 file changed, 51 insertions(+), 88 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 49345929af0d..bd84430e9fb3 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -696,63 +696,21 @@ static void handle___pkvm_vcpu_sync_state(struct kvm_cpu_context *host_ctxt) } } -static struct kvm_vcpu *__get_current_vcpu(struct kvm_vcpu *vcpu, - struct pkvm_loaded_state **state) -{ - struct pkvm_loaded_state *sstate = NULL; - - vcpu = kern_hyp_va(vcpu); - - if (unlikely(is_protected_kvm_enabled())) { - sstate = this_cpu_ptr(&loaded_state); - - if (!sstate || vcpu != sstate->vcpu->arch.pkvm.host_vcpu) { - sstate = NULL; - vcpu = NULL; - } - } - - *state = sstate; - return vcpu; -} - -#define get_current_vcpu(ctxt, regnr, statepp) \ - ({ \ - DECLARE_REG(struct kvm_vcpu *, __vcpu, ctxt, regnr); \ - __get_current_vcpu(__vcpu, statepp); \ - }) - -#define get_current_vcpu_from_cpu_if(ctxt, regnr, statepp) \ - ({ \ - DECLARE_REG(struct vgic_v3_cpu_if *, cif, ctxt, regnr); \ - struct kvm_vcpu *__vcpu; \ - __vcpu = container_of(cif, \ - struct kvm_vcpu, \ - arch.vgic_cpu.vgic_v3); \ - \ - __get_current_vcpu(__vcpu, statepp); \ - }) - static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) { - struct pkvm_loaded_state *shadow_state; - struct kvm_vcpu *vcpu; + DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); int ret; - vcpu = get_current_vcpu(host_ctxt, 1, &shadow_state); - if (!vcpu) { - cpu_reg(host_ctxt, 1) = -EINVAL; - return; - } + if (unlikely(is_protected_kvm_enabled())) { + struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state); - if (unlikely(shadow_state)) { - flush_shadow_state(shadow_state); + flush_shadow_state(state); - ret = __kvm_vcpu_run(shadow_state->vcpu); + ret = __kvm_vcpu_run(state->vcpu); - sync_shadow_state(shadow_state, ret); + sync_shadow_state(state, ret); - if (shadow_state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED) { + if (state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED) { /* * The guest has used the FP, trap all accesses * from the host (both FP and SVE). @@ -764,7 +722,7 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) sysreg_clear_set(cptr_el2, 0, reg); } } else { - ret = __kvm_vcpu_run(vcpu); + ret = __kvm_vcpu_run(kern_hyp_va(vcpu)); } cpu_reg(host_ctxt, 1) = ret; @@ -801,19 +759,20 @@ out: static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt) { - struct pkvm_loaded_state *shadow_state; - struct kvm_vcpu *vcpu; + DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); - vcpu = get_current_vcpu(host_ctxt, 1, &shadow_state); - if (!vcpu) - return; + vcpu = kern_hyp_va(vcpu); - if (shadow_state) { - /* This only applies to non-protected VMs */ - if (shadow_state->is_protected) + if (unlikely(is_protected_kvm_enabled())) { + struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state); + + /* + * A shadow vcpu can never be updated from EL1, and we + * must have a vcpu loaded when protected mode is + * enabled. + */ + if (!state->vcpu || state->is_protected) return; - - vcpu = shadow_state->vcpu; } __kvm_adjust_pc(vcpu); @@ -876,50 +835,56 @@ static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 1) = __kvm_get_mdcr_el2(); } +static struct vgic_v3_cpu_if *get_shadow_vgic_v3_cpu_if(struct vgic_v3_cpu_if *cpu_if) +{ + if (unlikely(is_protected_kvm_enabled())) { + struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state); + struct kvm_vcpu *host_vcpu; + + if (!state->vcpu) + return NULL; + + host_vcpu = state->vcpu->arch.pkvm.host_vcpu; + + if (&host_vcpu->arch.vgic_cpu.vgic_v3 != cpu_if) + return NULL; + } + + return cpu_if; +} + static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt) { - struct pkvm_loaded_state *shadow_state; - struct kvm_vcpu *vcpu; + DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); + struct vgic_v3_cpu_if *shadow_cpu_if; - vcpu = get_current_vcpu_from_cpu_if(host_ctxt, 1, &shadow_state); - if (!vcpu) - return; + cpu_if = kern_hyp_va(cpu_if); + shadow_cpu_if = get_shadow_vgic_v3_cpu_if(cpu_if); - if (shadow_state) { - struct vgic_v3_cpu_if *shadow_cpu_if, *cpu_if; + __vgic_v3_save_vmcr_aprs(shadow_cpu_if); + + if (cpu_if != shadow_cpu_if) { int i; - shadow_cpu_if = &shadow_state->vcpu->arch.vgic_cpu.vgic_v3; - __vgic_v3_save_vmcr_aprs(shadow_cpu_if); - - cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; - cpu_if->vgic_vmcr = shadow_cpu_if->vgic_vmcr; for (i = 0; i < ARRAY_SIZE(cpu_if->vgic_ap0r); i++) { cpu_if->vgic_ap0r[i] = shadow_cpu_if->vgic_ap0r[i]; cpu_if->vgic_ap1r[i] = shadow_cpu_if->vgic_ap1r[i]; } - } else { - __vgic_v3_save_vmcr_aprs(&vcpu->arch.vgic_cpu.vgic_v3); } } static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt) { - struct pkvm_loaded_state *shadow_state; - struct kvm_vcpu *vcpu; + DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); + struct vgic_v3_cpu_if *shadow_cpu_if; - vcpu = get_current_vcpu_from_cpu_if(host_ctxt, 1, &shadow_state); - if (!vcpu) - return; + cpu_if = kern_hyp_va(cpu_if); + shadow_cpu_if = get_shadow_vgic_v3_cpu_if(cpu_if); - if (shadow_state) { - struct vgic_v3_cpu_if *shadow_cpu_if, *cpu_if; + if (cpu_if != shadow_cpu_if) { int i; - shadow_cpu_if = &shadow_state->vcpu->arch.vgic_cpu.vgic_v3; - cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; - shadow_cpu_if->vgic_vmcr = cpu_if->vgic_vmcr; /* Should be a one-off */ shadow_cpu_if->vgic_sre = (ICC_SRE_EL1_DIB | @@ -929,11 +894,9 @@ static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt shadow_cpu_if->vgic_ap0r[i] = cpu_if->vgic_ap0r[i]; shadow_cpu_if->vgic_ap1r[i] = cpu_if->vgic_ap1r[i]; } - - __vgic_v3_restore_vmcr_aprs(shadow_cpu_if); - } else { - __vgic_v3_restore_vmcr_aprs(&vcpu->arch.vgic_cpu.vgic_v3); } + + __vgic_v3_restore_vmcr_aprs(shadow_cpu_if); } static void handle___pkvm_init(struct kvm_cpu_context *host_ctxt)