From patchwork Tue Oct 8 09:36:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 11179251 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F36E21709 for ; Tue, 8 Oct 2019 09:37:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD41B206BB for ; Tue, 8 Oct 2019 09:37:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="izNZubVL" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CD41B206BB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=cGXnibQ0eArWeiy2pi+E7h/QNlPN4KJGGsLh+VCkr8g=; b=izNZubVLbai2lRg10m79ASKf+J 3CUgACqUQhSCp92/WJi05kjS60KNrKf1yWvweG/jbZLFF17N4Dyy4LHcUDWYhgWswIGMLw2YdjLhv 1GRk9n0daETZI6h1VcYy1wIHoZk3HtXhbjyLTfxudSJuQ0hrHQ8Zgiemo/1FuY6wrc1i5fr8qCaCO w8PNI4E/d+iorbA7ewDOtmbD1/SvuafXVilP2Wp4iDhjeCAwqia9BI6hJC9U/2Usv3pOQyB0EyCzg ZHtZxs7tAoV0YsI33d7R3DhUeGyY7sVsTCrendXkh0G2d+NmG4jOEQE1fyL+3+fHcs9k09XDrEACy hGugTDvQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iHlwB-0005bb-SX; Tue, 08 Oct 2019 09:37:47 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iHlvI-0004VC-IY for linux-arm-kernel@lists.infradead.org; Tue, 08 Oct 2019 09:36:54 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 62E7015A2; Tue, 8 Oct 2019 02:36:52 -0700 (PDT) Received: from localhost (e113682-lin.copenhagen.arm.com [10.32.145.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EB5593F6C4; Tue, 8 Oct 2019 02:36:51 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu Subject: [kvmtool v2 5/5] arm: Inject external data aborts when accessing holes in the memory map Date: Tue, 8 Oct 2019 11:36:40 +0200 Message-Id: <20191008093640.26519-6-christoffer.dall@arm.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20191008093640.26519-1-christoffer.dall@arm.com> References: <20191008093640.26519-1-christoffer.dall@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191008_023652_706994_6512F1BF X-CRM114-Status: GOOD ( 12.88 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , =?utf-8?q?Daniel_P=2E_Berrang?= =?utf-8?q?=C3=A9?= , Suzuki K Poulose , Marc Zyngier , Christoffer Dall , James Morse , Julien Thierry , Stefan Hajnoczi , Heinrich Schuchardt , Alexander Graf , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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 --- 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 */