On Mon, Apr 07, 2025 at 11:33:01AM +0800, Yicong Yang wrote: > On 2025/4/2 0:13, Oliver Upton wrote: > > On Mon, Mar 31, 2025 at 05:43:20PM +0800, Yicong Yang wrote: > >> @@ -1658,6 +1658,25 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, > >> phys_addr_t fault_ipa, > > Keep in mind that data aborts with DFSC == 0x35 can happen for a lot > > more than LS64 instructions, e.g. an atomic on a Device-* mapping. > > > > got it. 0x35 should be caused by LS64* or IMPLEMENTATION DEFINED fault, but no > further hint to distinguish between these two faults. hope it's also the right > behaviour to inject a DABT back for the latter case.
There isn't exactly a 'right' behavior here. The abort could either be due to a bug in the guest (doing an access on something knows it can't) or the VMM creating / describing the IPA memory map incorrectly. Since KVM can't really work out who's to blame in this situation we should probably exit to userspace + provide a way to reinject the abort. > >> @@ -1919,6 +1939,21 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) > >> goto out_unlock; > >> } > >> > >> + /* > >> + * If instructions of FEAT_{LS64, LS64_V} operated on > >> + * unsupported memory regions, a DABT for unsupported > >> + * Exclusive or atomic access is generated. It's > >> + * implementation defined whether the exception will > >> + * be taken to, a stage-1 DABT or the final enabled > >> + * stage of translation (stage-2 in this case as we > >> + * hit here). Inject a DABT to the guest to handle it > >> + * if it's implemented as a stage-2 DABT. > >> + */ > >> + if (esr_fsc_is_excl_atomic_fault(esr)) { > >> + kvm_inject_dabt_excl_atomic(vcpu, > >> kvm_vcpu_get_hfar(vcpu)); > >> + return 1; > >> + } > >> + > > > > A precondition of taking such a data abort is having a valid mapping at > > stage-2. If KVM can't resolve the HVA of the fault then there couldn't > > have been a stage-2 mapping. > > > > Here's handling the case for emulated mmio, I thought there's no valid > stage-2 mapping > for the emulated MMIO? so this check is put just before entering > io_mem_abort(). should > it be put into io_mem_abort() or we just don't handle the emulated case? Right -- there's no valid stage-2 translation for _most_ MMIO. If KVM cannot find an HVA for the fault (look at the condition that gets us here) then we know there isn't a stage-2 mapping. How would we know what to map? In that case I would expect to take a Translation fault with instruction syndrome that can can be used to construct an exit to the VMM. Marc had some patches on list to do exactly that [*]. However, after reading this again there's a rather ugly catch. The KVM ABI has it that writes to a RO memlot generate an MMIO exit, so it *is* possible to get here w/ a stage-2 mapping. Unfortunately there's no instruction syndrome with DFSC = 0x35 so no way to decode the access. This is starting to sound similar an nISV MMIO abort... [*]: https://lore.kernel.org/kvmarm/20240815125959.2097734-1-...@kernel.org/ Thanks, Oliver