On Tue, Oct 08, 2019 at 02:03:07PM +0200, Alexander Graf wrote:
>
>
> On 08.10.19 11:36, Christoffer Dall wrote:
> > In some scenarios, such as buggy guest or incorrect configuration of the
> > VMM and firmware description data, userspace will detect a memory access
> > to a portion of the IPA, which is not mapped to any MMIO region.
> >
> > For this purpose, the appropriate action is to inject an external abort
> > to the guest. The kernel already has functionality to inject an
> > external abort, but we need to wire up a signal from user space that
> > lets user space tell the kernel to do this.
> >
> > It turns out, we already have the set event functionality which we can
> > perfectly reuse for this.
> >
> > Signed-off-by: Christoffer Dall
> > ---
> > Documentation/virt/kvm/api.txt| 18 +-
> > arch/arm/include/uapi/asm/kvm.h | 3 ++-
> > arch/arm/kvm/guest.c | 3 +++
> > arch/arm64/include/uapi/asm/kvm.h | 3 ++-
> > arch/arm64/kvm/guest.c| 3 +++
> > arch/arm64/kvm/inject_fault.c | 4 ++--
> > include/uapi/linux/kvm.h | 1 +
> > virt/kvm/arm/arm.c| 1 +
> > 8 files changed, 31 insertions(+), 5 deletions(-)
> >
> > diff --git a/Documentation/virt/kvm/api.txt b/Documentation/virt/kvm/api.txt
> > index 7403f15657c2..10ebe8cfda29 100644
> > --- a/Documentation/virt/kvm/api.txt
> > +++ b/Documentation/virt/kvm/api.txt
> > @@ -968,6 +968,8 @@ The following bits are defined in the flags field:
> > ARM/ARM64:
> > +User space may need to inject several types of events to the guest.
> > +
> > If the guest accesses a device that is being emulated by the host kernel
> > in
> > such a way that a real device would generate a physical SError, KVM may
> > make
> > a virtual SError pending for that VCPU. This system error interrupt
> > remains
> > @@ -1002,12 +1004,26 @@ Specifying exception.has_esr on a system that does
> > not support it will return
> > -EINVAL. Setting anything other than the lower 24bits of
> > exception.serror_esr
> > will return -EINVAL.
> > +If the guest performed an access to I/O memory which could not be handled
> > by
> > +userspace, for example because of missing instruction syndrome decode
> > +information or because there is no device mapped at the accessed IPA, then
> > +userspace can ask the kernel to inject an external abort using the address
> > +from the exiting fault on the VCPU. It is a programming error to set
> > +ext_dabt_pending at the same time as any of the serror fields, or to set
> > +ext_dabt_pending after an exit which was not either KVM_EXIT_MMIO or
> > +KVM_EXIT_ARM_NISV. This feature is only available if the system supports
> > +KVM_CAP_ARM_INJECT_EXT_DABT. This is a helper which provides commonality in
> > +how userspace reports accesses for the above cases to guests, across
> > different
> > +userspace implementations. Nevertheless, userspace can still emulate all
> > Arm
> > +exceptions by manipulating individual registers using the KVM_SET_ONE_REG
> > API.
> > +
> > struct kvm_vcpu_events {
> > struct {
> > __u8 serror_pending;
> > __u8 serror_has_esr;
> > + __u8 ext_dabt_pending;
> > /* Align it to 8 bytes */
> > - __u8 pad[6];
> > + __u8 pad[5];
> > __u64 serror_esr;
> > } exception;
> > __u32 reserved[12];
> > diff --git a/arch/arm/include/uapi/asm/kvm.h
> > b/arch/arm/include/uapi/asm/kvm.h
> > index 2769360f195c..03cd7c19a683 100644
> > --- a/arch/arm/include/uapi/asm/kvm.h
> > +++ b/arch/arm/include/uapi/asm/kvm.h
> > @@ -131,8 +131,9 @@ struct kvm_vcpu_events {
> > struct {
> > __u8 serror_pending;
> > __u8 serror_has_esr;
> > + __u8 ext_dabt_pending;
> > /* Align it to 8 bytes */
> > - __u8 pad[6];
> > + __u8 pad[5];
> > __u64 serror_esr;
> > } exception;
> > __u32 reserved[12];
> > diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
> > index 684cf64b4033..4154c5589501 100644
> > --- a/arch/arm/kvm/guest.c
> > +++ b/arch/arm/kvm/guest.c
> > @@ -263,11 +263,14 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
> > {
> > bool serror_pending = events->exception.serror_pending;
> > bool has_esr = events->exception.serror_has_esr;
> > + bool has_ext_dabt_pending = events->exception.ext_dabt_pending;
> > if (serror_pending && has_esr)
> > return -EINVAL;
> > else if (serror_pending)
> > kvm_inject_vabt(vcpu);
> > + else if (has_ext_dabt_pending)
> > + kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
> > return 0;
> > }
> > diff --git a/arch/arm64/include/uapi/asm/kvm.h
> > b/arch/arm64/include/uapi/asm/kvm.h
> > index 67c21f9bdbad..d49c17a80491 100644
> > --- a/arch/arm64/include/uapi/asm/kvm.h
> > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > @@ -164,8 +164,9 @@ struct kvm_vcpu_events {
> >