From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoffer Dall Subject: [PATCH v2 1/3] KVM: ARM: Check for overlaps of mapped io addresses Date: Sat, 20 Oct 2012 10:14:18 -0400 Message-ID: <20121020141418.24046.45036.stgit@ubuntu> References: <20121020141255.24046.20020.stgit@ubuntu> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org To: kvmarm@lists.cs.columbia.edu Return-path: Received: from mail-vc0-f174.google.com ([209.85.220.174]:52888 "EHLO mail-vc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754780Ab2JTOOJ (ORCPT ); Sat, 20 Oct 2012 10:14:09 -0400 Received: by mail-vc0-f174.google.com with SMTP id fk26so1480447vcb.19 for ; Sat, 20 Oct 2012 07:14:09 -0700 (PDT) In-Reply-To: <20121020141255.24046.20020.stgit@ubuntu> Sender: kvm-owner@vger.kernel.org List-ID: When calling stage2_set_pte from kvm_phys_addr_ioremap we pass an argument to say that this is an IO mapping, and that we expect the adress range to be free, otherwise return an error. This should catch errors earlier when user space supplies guest physical addresses that overlap. Signed-off-by: Christoffer Dall --- arch/arm/kvm/mmu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 0ab098e..e5ace0e 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -422,7 +422,7 @@ static void stage2_clear_pte(struct kvm *kvm, phys_addr_t addr) } static void stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, - phys_addr_t addr, const pte_t *new_pte) + phys_addr_t addr, const pte_t *new_pte, bool iomap) { pgd_t *pgd; pud_t *pud; @@ -454,6 +454,9 @@ static void stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, } else pte = pte_offset_kernel(pmd, addr); + if (iomap && pte_present(old_pte)) + return -EFAULT; + /* Create 2nd stage page table mapping - Level 3 */ old_pte = *pte; set_pte_ext(pte, *new_pte, 0); @@ -489,7 +492,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, if (ret) goto out; spin_lock(&kvm->mmu_lock); - stage2_set_pte(kvm, &cache, addr, &pte); + stage2_set_pte(kvm, &cache, addr, &pte, true); spin_unlock(&kvm->mmu_lock); pfn++; @@ -565,7 +568,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, pte_val(new_pte) |= L_PTE_S2_RDWR; kvm_set_pfn_dirty(pfn); } - stage2_set_pte(vcpu->kvm, memcache, fault_ipa, &new_pte); + stage2_set_pte(vcpu->kvm, memcache, fault_ipa, &new_pte, false); out_unlock: spin_unlock(&vcpu->kvm->mmu_lock); @@ -716,7 +719,7 @@ static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data) { pte_t *pte = (pte_t *)data; - stage2_set_pte(kvm, NULL, gpa, pte); + stage2_set_pte(kvm, NULL, gpa, pte, false); }