On Fri, May 16, 2025 at 8:33 AM Marc Zyngier maz@kernel.org wrote:
On Mon, 05 May 2025 17:14:08 +0100, Jiaqi Yan jiaqiyan@google.com wrote:
Certain microarchitectures (e.g. Neoverse V2) do not keep track of the faulting address for a memory load that consumes poisoned data and results in a synchronous external abort (SEA). This means the faulting guest physical address is unavailable when KVM handles such
Actually this is not relevant to the code, I think it is just sufficient to say "This means that FAR_EL2 holds a garbage value and therefore kvm_vcpu_get_hfar holds a garbage value too".
SEA in EL2, and FAR_EL2 just holds a garbage value.
I don't understand. FAR_ELx holds a *virtual* address, and never a physical address (that'd be PFAR_ELx).
Sorry my writing is misleading. If you are still interested, the scenario I meant to describe is 1. There is a SEA taken by KVM when memory load from the guest consumes poisoned data. 2. The guest physical address (or IPA) of the poisoned data will not be available in HPFAR_EL2 per architecture register documentation [1]. 3. Although HPFAR_EL2 is unusable, KVM can still attempt address translation with the guest virtual address in FAR_EL2 to get the poisoned IPA. 4. However, FAR_EL2 is not valid on certain microarchitectures (e.g. Neoverse V2), so in the end it is just impossible for KVM to know the poisoned IPA.
Does this clarify things? But again, it is confusing and will be removed.
[1] https://developer.arm.com/documentation/ddi0601/2025-03/AArch64-Registers/HP...
In case VMM later asks KVM to synchronously inject a SEA into the guest, KVM should set FnV bit
- in VCPU's ESR_EL1 to let guest kernel know that FAR_EL1 is invalid and holds garbage value
- in VCPU's ESR_EL2 to let nested virtualization know that FAR_EL2 is invalid and holds garbage value
Signed-off-by: Jiaqi Yan jiaqiyan@google.com
arch/arm64/kvm/inject_fault.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index a640e839848e6..b4f9a09952ead 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -81,6 +81,9 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr if (!is_iabt) esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
if (!kvm_vcpu_sea_far_valid(vcpu))
esr |= ESR_ELx_FnV;
I don't understand what this has anything to do with the uarch details you talk about in the commit message. If the VMM inject an exception, surely it has populated the exception context itself. I don't even see how we'd end-up here (__kvm_arm_vcpu_set_events? seems unlikely).
KVM_SET_VCPU_EVENTS is indeed the case this commit wants to fix. Instead of populating the exception registers itself, VMM can use KVM_SET_VCPU_EVENTS to let KVM do that per existing KVM doc [2], e.g. when VMM handles the KVM_EXIT_ARM_SEA introduced in the previous commit. The intent is to tell guest, for example, to not use FAR_EL1.
[2] https://www.kernel.org/doc/html/v5.10/virt/kvm/api.html#id3
M.
-- Without deviation from the norm, progress is not possible.