mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
ANDROID: KVM: arm64: pkvm: Replace pkvm_loaded_state.is_shadow with is_protected
When pKVM is enabled, all the vcpus must have a shadow structure managed by the hypervisor, irrespective of theur protection status. This field thus represents the wrong abstraction. Replace it with 'pkvm_loaded_state.is_protected', which tracks whether a vcpu is part of a protected VM. pkvm_loaded_state gets also moved around for convenience with the following patches. Signed-off-by: Marc Zyngier <maz@kernel.org> Bug: 209580772 Change-Id: Ic9876fde543abb350fe8969d5b4661e30092f553 Signed-off-by: Will Deacon <willdeacon@google.com>
This commit is contained in:
committed by
Will Deacon
parent
e7d30f4c8c
commit
730d3feb51
@@ -26,6 +26,24 @@
|
||||
|
||||
#include "../../sys_regs.h"
|
||||
|
||||
struct pkvm_loaded_state {
|
||||
/* loaded vcpu is HYP VA */
|
||||
struct kvm_vcpu *vcpu;
|
||||
bool is_protected;
|
||||
|
||||
/*
|
||||
* Host FPSIMD state. Written to when the guest accesses its
|
||||
* own FPSIMD state, and read when the guest state is live and
|
||||
* that it needs to be switched back to the host.
|
||||
*
|
||||
* Only valid when the KVM_ARM64_FP_ENABLED flag is set in the
|
||||
* shadow structure.
|
||||
*/
|
||||
struct user_fpsimd_state host_fpsimd_state;
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct pkvm_loaded_state, loaded_state);
|
||||
|
||||
DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
|
||||
|
||||
struct kvm_iommu_ops kvm_iommu_ops;
|
||||
@@ -475,24 +493,6 @@ static void sync_shadow_state(struct kvm_vcpu *shadow_vcpu, u32 exit_reason)
|
||||
shadow_vcpu->arch.pkvm.exit_code = exit_reason;
|
||||
}
|
||||
|
||||
struct pkvm_loaded_state {
|
||||
/* loaded vcpu is HYP VA */
|
||||
struct kvm_vcpu *vcpu;
|
||||
bool is_shadow;
|
||||
|
||||
/*
|
||||
* Host FPSIMD state. Written to when the guest accesses its
|
||||
* own FPSIMD state, and read when the guest state is live and
|
||||
* that it needs to be switched back to the host.
|
||||
*
|
||||
* Only valid when the KVM_ARM64_FP_ENABLED flag is set in the
|
||||
* shadow structure.
|
||||
*/
|
||||
struct user_fpsimd_state host_fpsimd_state;
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct pkvm_loaded_state, loaded_state);
|
||||
|
||||
static void fpsimd_host_restore(void)
|
||||
{
|
||||
sysreg_clear_set(cptr_el2, CPTR_EL2_TZ | CPTR_EL2_TFP, 0);
|
||||
@@ -501,13 +501,11 @@ static void fpsimd_host_restore(void)
|
||||
if (unlikely(is_protected_kvm_enabled())) {
|
||||
struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state);
|
||||
|
||||
if (state->is_shadow) {
|
||||
__fpsimd_save_state(&state->vcpu->arch.ctxt.fp_regs);
|
||||
__fpsimd_restore_state(&state->host_fpsimd_state);
|
||||
__fpsimd_save_state(&state->vcpu->arch.ctxt.fp_regs);
|
||||
__fpsimd_restore_state(&state->host_fpsimd_state);
|
||||
|
||||
state->vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED;
|
||||
state->vcpu->arch.flags |= KVM_ARM64_FP_HOST;
|
||||
}
|
||||
state->vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED;
|
||||
state->vcpu->arch.flags |= KVM_ARM64_FP_HOST;
|
||||
}
|
||||
|
||||
if (system_supports_sve())
|
||||
@@ -532,18 +530,23 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
|
||||
|
||||
vcpu = kern_hyp_va(vcpu);
|
||||
|
||||
handle = vcpu->arch.pkvm.shadow_handle;
|
||||
state->vcpu = get_shadow_vcpu(handle, vcpu->vcpu_idx) ?: vcpu;
|
||||
state->is_shadow = state->vcpu != vcpu;
|
||||
handle = READ_ONCE(vcpu->arch.pkvm.shadow_handle);
|
||||
state->vcpu = get_shadow_vcpu(handle, vcpu->vcpu_idx);
|
||||
|
||||
if (state->is_shadow) {
|
||||
state->vcpu->arch.host_fpsimd_state = &state->host_fpsimd_state;
|
||||
state->vcpu->arch.flags |= KVM_ARM64_FP_HOST;
|
||||
if (!state->vcpu)
|
||||
return;
|
||||
|
||||
state->is_protected = state->vcpu->arch.pkvm.shadow_vm->arch.pkvm.enabled;
|
||||
|
||||
state->vcpu->arch.host_fpsimd_state = &state->host_fpsimd_state;
|
||||
state->vcpu->arch.flags |= KVM_ARM64_FP_HOST;
|
||||
|
||||
if (state->is_protected) {
|
||||
/* Propagate WFx trapping flags, trap ptrauth */
|
||||
state->vcpu->arch.hcr_el2 &= ~(HCR_TWE | HCR_TWI |
|
||||
HCR_API | HCR_APK);
|
||||
state->vcpu->arch.hcr_el2 |= vcpu->arch.hcr_el2 & (HCR_TWE | HCR_TWI);
|
||||
state->vcpu->arch.hcr_el2 |= vcpu->arch.hcr_el2 & (HCR_TWE |
|
||||
HCR_TWI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,8 +557,9 @@ static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
|
||||
if (unlikely(is_protected_kvm_enabled())) {
|
||||
struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state);
|
||||
|
||||
if (state->vcpu && state->is_shadow &&
|
||||
state->vcpu->arch.pkvm.host_vcpu == kern_hyp_va(vcpu)) {
|
||||
vcpu = kern_hyp_va(vcpu);
|
||||
|
||||
if (state->vcpu && state->vcpu->arch.pkvm.host_vcpu == vcpu) {
|
||||
if (state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED)
|
||||
fpsimd_host_restore();
|
||||
|
||||
@@ -575,13 +579,11 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
|
||||
if (unlikely(is_protected_kvm_enabled())) {
|
||||
struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state);
|
||||
|
||||
if (state->is_shadow)
|
||||
flush_shadow_state(state->vcpu);
|
||||
flush_shadow_state(state->vcpu);
|
||||
|
||||
ret = __kvm_vcpu_run(state->vcpu);
|
||||
|
||||
if (state->is_shadow)
|
||||
sync_shadow_state(state->vcpu, ret);
|
||||
sync_shadow_state(state->vcpu, ret);
|
||||
|
||||
if (state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
|
||||
/*
|
||||
@@ -614,7 +616,7 @@ static void handle___pkvm_host_donate_guest(struct kvm_cpu_context *host_ctxt)
|
||||
|
||||
vcpu = kern_hyp_va(vcpu);
|
||||
state = this_cpu_ptr(&loaded_state);
|
||||
if (!state->vcpu || !state->is_shadow)
|
||||
if (!state->vcpu)
|
||||
goto out;
|
||||
|
||||
/* Topup shadow memcache with the host's */
|
||||
@@ -639,7 +641,7 @@ static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
|
||||
* must have a vcpu loaded when protected mode is
|
||||
* enabled.
|
||||
*/
|
||||
if (!state->vcpu || state->is_shadow || state->vcpu != vcpu)
|
||||
if (!state->vcpu || state->is_protected)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -712,19 +714,10 @@ static struct vgic_v3_cpu_if *get_shadow_vgic_v3_cpu_if(struct vgic_v3_cpu_if *c
|
||||
if (!state->vcpu)
|
||||
return NULL;
|
||||
|
||||
if (state->is_shadow) {
|
||||
host_vcpu = state->vcpu->arch.pkvm.host_vcpu;
|
||||
host_vcpu = state->vcpu->arch.pkvm.host_vcpu;
|
||||
|
||||
if (&host_vcpu->arch.vgic_cpu.vgic_v3 != cpu_if)
|
||||
return NULL;
|
||||
|
||||
return &state->vcpu->arch.vgic_cpu.vgic_v3;
|
||||
} else {
|
||||
if (&state->vcpu->arch.vgic_cpu.vgic_v3 != cpu_if)
|
||||
return NULL;
|
||||
|
||||
return cpu_if;
|
||||
}
|
||||
if (&host_vcpu->arch.vgic_cpu.vgic_v3 != cpu_if)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cpu_if;
|
||||
|
||||
Reference in New Issue
Block a user