From: Christoffer Dall <christoffer.dall@arm.com> To: kvmarm@lists.cs.columbia.edu Cc: "Daniel P. Berrangé" <berrange@redhat.com>, "Marc Zyngier" <maz@kernel.org>, "Stefan Hajnoczi" <stefanha@redhat.com>, "Heinrich Schuchardt" <xypron.glpk@gmx.de>, linux-arm-kernel@lists.infradead.org Subject: [kvmtool v3 5/5] arm: Inject external data aborts when accessing holes in the memory map Date: Fri, 11 Oct 2019 13:07:09 +0200 [thread overview] Message-ID: <20191011110709.2764-6-christoffer.dall@arm.com> (raw) In-Reply-To: <20191011110709.2764-1-christoffer.dall@arm.com> Occasionally guests will attempt to access parts of the guest memory map where there is... nothing at all. Until now, we've handled this by either forcefully killing the guest, or silently (unless a debug option was enabled) ignoring the access. Neither is very helpful to a user, who is most likely running either a broken or misconfigured guest. A more appropriate action is to inject an external abort to the guest. Luckily, with KVM_CAP_ARM_INJECT_EXT_DABT, we can use the set event mechanism and ask KVM to do this for us. So we add an architecture specific hook to handle accesses to MMIO regions which cannot be found, and allow them to return if the invalid access was handled or not. Signed-off-by: Christoffer Dall <christoffer.dall@arm.com> --- arm/include/arm-common/kvm-cpu-arch.h | 16 ++++++++++++++++ arm/kvm-cpu.c | 2 +- mips/include/kvm/kvm-cpu-arch.h | 5 +++++ mmio.c | 3 ++- powerpc/include/kvm/kvm-cpu-arch.h | 5 +++++ x86/include/kvm/kvm-cpu-arch.h | 5 +++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/arm/include/arm-common/kvm-cpu-arch.h b/arm/include/arm-common/kvm-cpu-arch.h index 923d2c4..33defa2 100644 --- a/arm/include/arm-common/kvm-cpu-arch.h +++ b/arm/include/arm-common/kvm-cpu-arch.h @@ -57,6 +57,22 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); } +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + struct kvm_vcpu_events events = { + .exception.ext_dabt_pending = 1, + }; + int err; + + if (!kvm__supports_extension(vcpu->kvm, KVM_CAP_ARM_INJECT_EXT_DABT)) + return false; + + err = ioctl(vcpu->vcpu_fd, KVM_SET_VCPU_EVENTS, &events); + if (err) + die("failed to inject external abort"); + return true; +} + unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu); #endif /* ARM_COMMON__KVM_CPU_ARCH_H */ diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c index 25bd3ed..321a3e4 100644 --- a/arm/kvm-cpu.c +++ b/arm/kvm-cpu.c @@ -142,7 +142,7 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) if (!arm_addr_in_ioport_region(phys_addr) && !kvm__mmio_exists(vcpu, phys_addr)) - die("Guest accessed memory outside RAM and IO ranges"); + return kvm_cpu__mmio_not_found(vcpu, phys_addr); /* * We cannot fetch and decode instructions from a KVM guest, diff --git a/mips/include/kvm/kvm-cpu-arch.h b/mips/include/kvm/kvm-cpu-arch.h index 45e69f6..512ab34 100644 --- a/mips/include/kvm/kvm-cpu-arch.h +++ b/mips/include/kvm/kvm-cpu-arch.h @@ -40,4 +40,9 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); } +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + return false; +} + #endif /* KVM__KVM_CPU_ARCH_H */ diff --git a/mmio.c b/mmio.c index 2ab7fa7..d6df303 100644 --- a/mmio.c +++ b/mmio.c @@ -130,7 +130,8 @@ bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u if (mmio) mmio->mmio_fn(vcpu, phys_addr, data, len, is_write, mmio->ptr); else { - if (vcpu->kvm->cfg.mmio_debug) + if (!kvm_cpu__mmio_not_found(vcpu, phys_addr) && + vcpu->kvm->cfg.mmio_debug) fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n", to_direction(is_write), (unsigned long long)phys_addr, len); diff --git a/powerpc/include/kvm/kvm-cpu-arch.h b/powerpc/include/kvm/kvm-cpu-arch.h index a69e0cc..64b69b1 100644 --- a/powerpc/include/kvm/kvm-cpu-arch.h +++ b/powerpc/include/kvm/kvm-cpu-arch.h @@ -76,4 +76,9 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *dat bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write); +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + return false; +} + #endif /* KVM__KVM_CPU_ARCH_H */ diff --git a/x86/include/kvm/kvm-cpu-arch.h b/x86/include/kvm/kvm-cpu-arch.h index 05e5bb6..10cbe6e 100644 --- a/x86/include/kvm/kvm-cpu-arch.h +++ b/x86/include/kvm/kvm-cpu-arch.h @@ -47,4 +47,9 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); } +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + return false; +} + #endif /* KVM__KVM_CPU_ARCH_H */ -- 2.18.0 _______________________________________________ kvmarm mailing list kvmarm@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
WARNING: multiple messages have this Message-ID (diff)
From: Christoffer Dall <christoffer.dall@arm.com> To: kvmarm@lists.cs.columbia.edu Cc: "Peter Maydell" <peter.maydell@linaro.org>, "Daniel P. Berrangé" <berrange@redhat.com>, "Suzuki K Poulose" <suzuki.poulose@arm.com>, "Marc Zyngier" <maz@kernel.org>, "Christoffer Dall" <christoffer.dall@arm.com>, "James Morse" <james.morse@arm.com>, "Julien Thierry" <julien.thierry.kdev@gmail.com>, "Stefan Hajnoczi" <stefanha@redhat.com>, "Heinrich Schuchardt" <xypron.glpk@gmx.de>, "Alexander Graf" <graf@amazon.com>, linux-arm-kernel@lists.infradead.org Subject: [kvmtool v3 5/5] arm: Inject external data aborts when accessing holes in the memory map Date: Fri, 11 Oct 2019 13:07:09 +0200 [thread overview] Message-ID: <20191011110709.2764-6-christoffer.dall@arm.com> (raw) In-Reply-To: <20191011110709.2764-1-christoffer.dall@arm.com> Occasionally guests will attempt to access parts of the guest memory map where there is... nothing at all. Until now, we've handled this by either forcefully killing the guest, or silently (unless a debug option was enabled) ignoring the access. Neither is very helpful to a user, who is most likely running either a broken or misconfigured guest. A more appropriate action is to inject an external abort to the guest. Luckily, with KVM_CAP_ARM_INJECT_EXT_DABT, we can use the set event mechanism and ask KVM to do this for us. So we add an architecture specific hook to handle accesses to MMIO regions which cannot be found, and allow them to return if the invalid access was handled or not. Signed-off-by: Christoffer Dall <christoffer.dall@arm.com> --- arm/include/arm-common/kvm-cpu-arch.h | 16 ++++++++++++++++ arm/kvm-cpu.c | 2 +- mips/include/kvm/kvm-cpu-arch.h | 5 +++++ mmio.c | 3 ++- powerpc/include/kvm/kvm-cpu-arch.h | 5 +++++ x86/include/kvm/kvm-cpu-arch.h | 5 +++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/arm/include/arm-common/kvm-cpu-arch.h b/arm/include/arm-common/kvm-cpu-arch.h index 923d2c4..33defa2 100644 --- a/arm/include/arm-common/kvm-cpu-arch.h +++ b/arm/include/arm-common/kvm-cpu-arch.h @@ -57,6 +57,22 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); } +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + struct kvm_vcpu_events events = { + .exception.ext_dabt_pending = 1, + }; + int err; + + if (!kvm__supports_extension(vcpu->kvm, KVM_CAP_ARM_INJECT_EXT_DABT)) + return false; + + err = ioctl(vcpu->vcpu_fd, KVM_SET_VCPU_EVENTS, &events); + if (err) + die("failed to inject external abort"); + return true; +} + unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu); #endif /* ARM_COMMON__KVM_CPU_ARCH_H */ diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c index 25bd3ed..321a3e4 100644 --- a/arm/kvm-cpu.c +++ b/arm/kvm-cpu.c @@ -142,7 +142,7 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) if (!arm_addr_in_ioport_region(phys_addr) && !kvm__mmio_exists(vcpu, phys_addr)) - die("Guest accessed memory outside RAM and IO ranges"); + return kvm_cpu__mmio_not_found(vcpu, phys_addr); /* * We cannot fetch and decode instructions from a KVM guest, diff --git a/mips/include/kvm/kvm-cpu-arch.h b/mips/include/kvm/kvm-cpu-arch.h index 45e69f6..512ab34 100644 --- a/mips/include/kvm/kvm-cpu-arch.h +++ b/mips/include/kvm/kvm-cpu-arch.h @@ -40,4 +40,9 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); } +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + return false; +} + #endif /* KVM__KVM_CPU_ARCH_H */ diff --git a/mmio.c b/mmio.c index 2ab7fa7..d6df303 100644 --- a/mmio.c +++ b/mmio.c @@ -130,7 +130,8 @@ bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u if (mmio) mmio->mmio_fn(vcpu, phys_addr, data, len, is_write, mmio->ptr); else { - if (vcpu->kvm->cfg.mmio_debug) + if (!kvm_cpu__mmio_not_found(vcpu, phys_addr) && + vcpu->kvm->cfg.mmio_debug) fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n", to_direction(is_write), (unsigned long long)phys_addr, len); diff --git a/powerpc/include/kvm/kvm-cpu-arch.h b/powerpc/include/kvm/kvm-cpu-arch.h index a69e0cc..64b69b1 100644 --- a/powerpc/include/kvm/kvm-cpu-arch.h +++ b/powerpc/include/kvm/kvm-cpu-arch.h @@ -76,4 +76,9 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *dat bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write); +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + return false; +} + #endif /* KVM__KVM_CPU_ARCH_H */ diff --git a/x86/include/kvm/kvm-cpu-arch.h b/x86/include/kvm/kvm-cpu-arch.h index 05e5bb6..10cbe6e 100644 --- a/x86/include/kvm/kvm-cpu-arch.h +++ b/x86/include/kvm/kvm-cpu-arch.h @@ -47,4 +47,9 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); } +static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr) +{ + return false; +} + #endif /* KVM__KVM_CPU_ARCH_H */ -- 2.18.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-10-11 11:07 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-10-11 11:07 [PATCH v3 0/2] Improve handling of stage 2 aborts without instruction decode Christoffer Dall 2019-10-11 11:07 ` Christoffer Dall 2019-10-11 11:07 ` [PATCH v3 1/2] KVM: arm/arm64: Allow reporting non-ISV data aborts to userspace Christoffer Dall 2019-10-11 11:07 ` Christoffer Dall 2019-10-11 11:07 ` [PATCH v3 2/2] KVM: arm/arm64: Allow user injection of external data aborts Christoffer Dall 2019-10-11 11:07 ` Christoffer Dall 2019-10-21 20:21 ` Alexander Graf 2019-10-21 20:21 ` Alexander Graf 2019-10-11 11:07 ` [kvmtool v3 3/5] update headers: Update the KVM headers for new Arm fault reporting features Christoffer Dall 2019-10-11 11:07 ` Christoffer Dall 2019-10-11 11:07 ` [kvmtool v3 4/5] arm: Handle exits from undecoded load/store instructions Christoffer Dall 2019-10-11 11:07 ` Christoffer Dall 2019-10-11 11:07 ` Christoffer Dall [this message] 2019-10-11 11:07 ` [kvmtool v3 5/5] arm: Inject external data aborts when accessing holes in the memory map Christoffer Dall 2019-10-20 10:25 ` [PATCH v3 0/2] Improve handling of stage 2 aborts without instruction decode Marc Zyngier 2019-10-20 10:25 ` Marc Zyngier 2019-10-21 13:37 ` Christoffer Dall 2019-10-21 13:37 ` Christoffer Dall 2019-10-21 13:59 ` Marc Zyngier 2019-10-21 13:59 ` Marc Zyngier
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20191011110709.2764-6-christoffer.dall@arm.com \ --to=christoffer.dall@arm.com \ --cc=berrange@redhat.com \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=maz@kernel.org \ --cc=stefanha@redhat.com \ --cc=xypron.glpk@gmx.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.