From patchwork Tue Nov 24 17:35:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 57263 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp2236883lbb; Tue, 24 Nov 2015 09:35:52 -0800 (PST) X-Received: by 10.67.24.97 with SMTP id ih1mr44663871pad.65.1448386552806; Tue, 24 Nov 2015 09:35:52 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q62si27889027pfq.5.2015.11.24.09.35.52; Tue, 24 Nov 2015 09:35:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dkim=neutral (body hash did not verify) header.i=@linaro-org.20150623.gappssmtp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754693AbbKXRfr (ORCPT + 2 others); Tue, 24 Nov 2015 12:35:47 -0500 Received: from mail-wm0-f47.google.com ([74.125.82.47]:36261 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754227AbbKXRfS (ORCPT ); Tue, 24 Nov 2015 12:35:18 -0500 Received: by wmww144 with SMTP id w144so148725849wmw.1 for ; Tue, 24 Nov 2015 09:35:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7JWyxn4o2oAbQcgLD+4VYZ5oi72lGtbB9M/daI4xbaY=; b=gQ+6Kd7RRyj9IaITmOr8FZAOugyeK+CqK8TWWmOFPT8d56p1htSUWxGEUzGpsbQn9/ qwJQHBAvT3rHIjaXWmoYdvwZjQ23va+EpMAQGPQO3Lm1U5DYBfZ35M4IbukN58xmF2Ir rvhVJGrrfdzPbvBsvcj2Z7fVWoCLaWil+8d+ixLGn2Ug757dCIgczC1Np6PjSbz0hbO0 VtenUkJ6F8UsovgXjyqXkc+T6C0RjqvEYSX8+AII1l4TTV40DrE6+lN4u+PuES3q744I fp0DG2yO4LtXE5G8UBm01cNpx0A43V4fFT57b/9jjGvAppA4ieVrW5vbX++TUFZZepNW xuqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7JWyxn4o2oAbQcgLD+4VYZ5oi72lGtbB9M/daI4xbaY=; b=YI6vVfa++XM5d72YlKkQpan46OaSwKcOFBXnICsxQziTvBXnA8R629EnIImlwbkARj 6kOhCTKP1OJ6wK8dOybZdDLBUeyoW04MeejKuoZ8TkVGxxlDAxW1D/7VrL3FTncwupr3 uw7iTqzHVQKjuDNhUbzsFkWtJO6n/AnVg6IX5UN6XfvV6id8N8fE7d+8kI/BTRG53mDy SMtgXz80MyHtw/8XBrEjigryDFI88IAgKIDpHLWQRJmPkdtGZPkmwmMHEj1wvshlwmOl rENRythx4YyD6rvkuxsOS6SP7CrKHv2BA1bhHL3+R5+IzYIpyOenRRw7AZvLKYzIaGWs dkEw== X-Gm-Message-State: ALoCoQlKwjU987y24pjPzxEk708zm8S6mSP1nnwtdF0yjGcaV3u4wzbz4k8Tv4Bu89f0yKwW61aG X-Received: by 10.194.109.169 with SMTP id ht9mr14537971wjb.13.1448386517366; Tue, 24 Nov 2015 09:35:17 -0800 (PST) Received: from localhost.localdomain ([94.18.191.146]) by smtp.gmail.com with ESMTPSA id jo6sm19283805wjb.48.2015.11.24.09.35.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Nov 2015 09:35:16 -0800 (PST) From: Christoffer Dall To: Paolo Bonzini Cc: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org, Ard Biesheuvel , stable@vger.kernel.org, Christoffer Dall Subject: [PULL 1/8] ARM/arm64: KVM: test properly for a PTE's uncachedness Date: Tue, 24 Nov 2015 18:35:29 +0100 Message-Id: <1448386536-30118-2-git-send-email-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.1.2.330.g565301e.dirty In-Reply-To: <1448386536-30118-1-git-send-email-christoffer.dall@linaro.org> References: <1448386536-30118-1-git-send-email-christoffer.dall@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Ard Biesheuvel The open coded tests for checking whether a PTE maps a page as uncached use a flawed '(pte_val(xxx) & CONST) != CONST' pattern, which is not guaranteed to work since the type of a mapping is not a set of mutually exclusive bits For HYP mappings, the type is an index into the MAIR table (i.e, the index itself does not contain any information whatsoever about the type of the mapping), and for stage-2 mappings it is a bit field where normal memory and device types are defined as follows: #define MT_S2_NORMAL 0xf #define MT_S2_DEVICE_nGnRE 0x1 I.e., masking *and* comparing with the latter matches on the former, and we have been getting lucky merely because the S2 device mappings also have the PTE_UXN bit set, or we would misidentify memory mappings as device mappings. Since the unmap_range() code path (which contains one instance of the flawed test) is used both for HYP mappings and stage-2 mappings, and considering the difference between the two, it is non-trivial to fix this by rewriting the tests in place, as it would involve passing down the type of mapping through all the functions. However, since HYP mappings and stage-2 mappings both deal with host physical addresses, we can simply check whether the mapping is backed by memory that is managed by the host kernel, and only perform the D-cache maintenance if this is the case. Cc: stable@vger.kernel.org Signed-off-by: Ard Biesheuvel Tested-by: Pavel Fedin Reviewed-by: Christoffer Dall Signed-off-by: Christoffer Dall --- arch/arm/kvm/mmu.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) -- 2.1.2.330.g565301e.dirty -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 6984342..7dace90 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -98,6 +98,11 @@ static void kvm_flush_dcache_pud(pud_t pud) __kvm_flush_dcache_pud(pud); } +static bool kvm_is_device_pfn(unsigned long pfn) +{ + return !pfn_valid(pfn); +} + /** * stage2_dissolve_pmd() - clear and flush huge PMD entry * @kvm: pointer to kvm structure. @@ -213,7 +218,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd, kvm_tlb_flush_vmid_ipa(kvm, addr); /* No need to invalidate the cache for device mappings */ - if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE) + if (!kvm_is_device_pfn(__phys_to_pfn(addr))) kvm_flush_dcache_pte(old_pte); put_page(virt_to_page(pte)); @@ -305,8 +310,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd, pte = pte_offset_kernel(pmd, addr); do { - if (!pte_none(*pte) && - (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE) + if (!pte_none(*pte) && !kvm_is_device_pfn(__phys_to_pfn(addr))) kvm_flush_dcache_pte(*pte); } while (pte++, addr += PAGE_SIZE, addr != end); } @@ -1037,11 +1041,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) return kvm_vcpu_dabt_iswrite(vcpu); } -static bool kvm_is_device_pfn(unsigned long pfn) -{ - return !pfn_valid(pfn); -} - /** * stage2_wp_ptes - write protect PMD range * @pmd: pointer to pmd entry