Commit 795a0bba authored by Marc Zyngier's avatar Marc Zyngier

KVM: arm64: Add helper for last ditch idreg adjustments

We already have to perform a set of last-chance adjustments for
NV purposes. We will soon have to do the same for the GIC, so
introduce a helper for that exact purpose.
Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240827152517.3909653-5-maz@kernel.orgSigned-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 8d917e0a
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#include <kvm/arm_pmu.h> #include <kvm/arm_pmu.h>
#include <kvm/arm_psci.h> #include <kvm/arm_psci.h>
#include "sys_regs.h"
static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;
enum kvm_wfx_trap_policy { enum kvm_wfx_trap_policy {
...@@ -821,15 +823,13 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) ...@@ -821,15 +823,13 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
return ret; return ret;
} }
if (vcpu_has_nv(vcpu)) { ret = kvm_finalize_sys_regs(vcpu);
ret = kvm_init_nv_sysregs(vcpu->kvm); if (ret)
if (ret) return ret;
return ret;
}
/* /*
* This needs to happen after NV has imposed its own restrictions on * This needs to happen after any restriction has been applied
* the feature set * to the feature set.
*/ */
kvm_calculate_traps(vcpu); kvm_calculate_traps(vcpu);
......
...@@ -954,19 +954,16 @@ static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1) ...@@ -954,19 +954,16 @@ static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
int kvm_init_nv_sysregs(struct kvm *kvm) int kvm_init_nv_sysregs(struct kvm *kvm)
{ {
u64 res0, res1; u64 res0, res1;
int ret = 0;
mutex_lock(&kvm->arch.config_lock); lockdep_assert_held(&kvm->arch.config_lock);
if (kvm->arch.sysreg_masks) if (kvm->arch.sysreg_masks)
goto out; return 0;
kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)), kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)),
GFP_KERNEL_ACCOUNT); GFP_KERNEL_ACCOUNT);
if (!kvm->arch.sysreg_masks) { if (!kvm->arch.sysreg_masks)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
limit_nv_id_regs(kvm); limit_nv_id_regs(kvm);
...@@ -1195,8 +1192,6 @@ int kvm_init_nv_sysregs(struct kvm *kvm) ...@@ -1195,8 +1192,6 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1)) if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
res0 |= ~(res0 | res1); res0 |= ~(res0 | res1);
set_sysreg_masks(kvm, HAFGRTR_EL2, res0, res1); set_sysreg_masks(kvm, HAFGRTR_EL2, res0, res1);
out:
mutex_unlock(&kvm->arch.config_lock);
return ret; return 0;
} }
...@@ -4620,6 +4620,29 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu) ...@@ -4620,6 +4620,29 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
mutex_unlock(&kvm->arch.config_lock); mutex_unlock(&kvm->arch.config_lock);
} }
/*
* Perform last adjustments to the ID registers that are implied by the
* configuration outside of the ID regs themselves, as well as any
* initialisation that directly depend on these ID registers (such as
* RES0/RES1 behaviours). This is not the place to configure traps though.
*
* Because this can be called once per CPU, changes must be idempotent.
*/
int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
guard(mutex)(&kvm->arch.config_lock);
if (vcpu_has_nv(vcpu)) {
int ret = kvm_init_nv_sysregs(kvm);
if (ret)
return ret;
}
return 0;
}
int __init kvm_sys_reg_table_init(void) int __init kvm_sys_reg_table_init(void)
{ {
bool valid = true; bool valid = true;
......
...@@ -235,6 +235,8 @@ int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg, ...@@ -235,6 +235,8 @@ int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index); bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index);
int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu);
#define AA32(_x) .aarch32_map = AA32_##_x #define AA32(_x) .aarch32_map = AA32_##_x
#define Op0(_x) .Op0 = _x #define Op0(_x) .Op0 = _x
#define Op1(_x) .Op1 = _x #define Op1(_x) .Op1 = _x
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment