In preparation for adding support for SMIDR_EL1 which is only available in systems with SME factor out the FEAT_IDST injection from emulate-nested.c into a helper and use it when handling hidden ID registers, ensuring that we provide FEAT_IDST behaviour for them.
Signed-off-by: Mark Brown <[email protected]> --- arch/arm64/include/asm/kvm_emulate.h | 1 + arch/arm64/kvm/emulate-nested.c | 6 +----- arch/arm64/kvm/inject_fault.c | 15 +++++++++++++++ arch/arm64/kvm/sys_regs.c | 6 +++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 5bf3d7e1d92c..994afbf479fc 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -45,6 +45,7 @@ bool kvm_condition_valid32(const struct kvm_vcpu *vcpu); void kvm_skip_instr32(struct kvm_vcpu *vcpu); void kvm_inject_undefined(struct kvm_vcpu *vcpu); +void kvm_inject_undefined_idreg(struct kvm_vcpu *vcpu); void kvm_inject_sync(struct kvm_vcpu *vcpu, u64 esr); int kvm_inject_serror_esr(struct kvm_vcpu *vcpu, u64 esr); int kvm_inject_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr); diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c index e688bc5139c1..f49b7b311d09 100644 --- a/arch/arm64/kvm/emulate-nested.c +++ b/arch/arm64/kvm/emulate-nested.c @@ -2669,11 +2669,7 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index) * helper for the purpose of dealing with FEAT_IDST. */ if (in_feat_id_space(¶ms)) { - if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR2_EL1, IDS, IMP)) - kvm_inject_sync(vcpu, kvm_vcpu_get_esr(vcpu)); - else - kvm_inject_undefined(vcpu); - + kvm_inject_undefined_idreg(vcpu); return true; } diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index 89982bd3345f..e2f519ca3045 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -331,6 +331,21 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu) inject_undef64(vcpu); } +/** + * kvm_inject_undefined_idreg - emulate UnimplementedIDRegister() pseudocode + * @vcpu: The vCPU in which to inject the exception + * + * It is assumed that this code is called from the VCPU thread and that the + * VCPU therefore is not currently executing guest code. + */ +void kvm_inject_undefined_idreg(struct kvm_vcpu *vcpu) +{ + if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR2_EL1, IDS, IMP)) + kvm_inject_sync(vcpu, kvm_vcpu_get_esr(vcpu)); + else + kvm_inject_undefined(vcpu); +} + static bool serror_is_masked(struct kvm_vcpu *vcpu) { return (*vcpu_cpsr(vcpu) & PSR_A_BIT) && !effective_sctlr2_nmea(vcpu); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 5d5c579d4579..b352cd323e30 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -4759,7 +4759,11 @@ static void perform_access(struct kvm_vcpu *vcpu, /* Check for regs disabled by runtime config */ if (sysreg_hidden(vcpu, r)) { - kvm_inject_undefined(vcpu); + if (in_feat_id_space(params)) { + kvm_inject_undefined_idreg(vcpu); + } else { + kvm_inject_undefined(vcpu); + } return; } -- 2.47.3

