From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f197.google.com (mail-wr0-f197.google.com [209.85.128.197]) by kanga.kvack.org (Postfix) with ESMTP id C935F6B0260 for ; Fri, 23 Mar 2018 14:06:18 -0400 (EDT) Received: by mail-wr0-f197.google.com with SMTP id 31so6426029wrr.2 for ; Fri, 23 Mar 2018 11:06:18 -0700 (PDT) Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id b11sor4864662wrf.40.2018.03.23.11.06.17 for (Google Transport Security); Fri, 23 Mar 2018 11:06:17 -0700 (PDT) From: Andrey Konovalov Subject: [RFC PATCH v2 09/15] khwasan, kvm: untag pointers in kern_hyp_va Date: Fri, 23 Mar 2018 19:05:45 +0100 Message-Id: <0e4b9cc6f99e2aabc8df77773c3d7e9649a6f2b7.1521828274.git.andreyknvl@google.com> In-Reply-To: References: In-Reply-To: References: Sender: owner-linux-mm@kvack.org List-ID: To: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Jonathan Corbet , Catalin Marinas , Will Deacon , Christoffer Dall , Marc Zyngier , Christopher Li , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Masahiro Yamada , Michal Marek , "GitAuthor : Andrey Konovalov" , Mark Rutland , Ard Biesheuvel , Yury Norov , Nick Desaulniers , Suzuki K Poulose , Kristina Martsenko , Punit Agrawal , Dave Martin , Michael Weiser , James Morse , Julien Thierry , Steve Capper , Tyler Baicar , "Eric W . Biederman" , Stephen Boyd , Thomas Gleixner , Ingo Molnar , Paul Lawrence , Greg Kroah-Hartman , David Woodhouse , Sandipan Das , Kees Cook , Herbert Xu , Geert Uytterhoeven , Josh Poimboeuf , Arnd Bergmann , kasan-dev@googlegroups.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-sparse@vger.kernel.org, linux-mm@kvack.org, linux-kbuild@vger.kernel.org Cc: Kostya Serebryany , Evgeniy Stepanov , Lee Smith , Ramana Radhakrishnan , Jacob Bramley , Ruben Ayrapetyan , Kees Cook , Jann Horn , Mark Brand kern_hyp_va that converts kernel VA into a HYP VA relies on the top byte of kernel pointers being 0xff. Untag pointers passed to it with KHWASAN enabled. Also fix create_hyp_mappings() and create_hyp_io_mappings(), to use the untagged kernel pointers for address computations. Signed-off-by: Andrey Konovalov --- arch/arm64/include/asm/kvm_mmu.h | 8 ++++++++ virt/kvm/arm/mmu.c | 20 +++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 7faed6e48b46..5149ff83b4c4 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -97,6 +97,9 @@ * Should be completely invisible on any viable CPU. */ .macro kern_hyp_va reg +#ifdef CONFIG_KASAN_TAGS + orr \reg, \reg, #KASAN_PTR_TAG_MASK +#endif alternative_if_not ARM64_HAS_VIRT_HOST_EXTN and \reg, \reg, #HYP_PAGE_OFFSET_HIGH_MASK alternative_else_nop_endif @@ -115,6 +118,11 @@ alternative_else_nop_endif static inline unsigned long __kern_hyp_va(unsigned long v) { +#ifdef CONFIG_KASAN_TAGS + asm volatile("orr %0, %0, %1" + : "+r" (v) + : "i" (KASAN_PTR_TAG_MASK)); +#endif asm volatile(ALTERNATIVE("and %0, %0, %1", "nop", ARM64_HAS_VIRT_HOST_EXTN) diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index b960acdd0c05..3dba9b60e0a0 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -683,9 +684,13 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr) int create_hyp_mappings(void *from, void *to, pgprot_t prot) { phys_addr_t phys_addr; - unsigned long virt_addr; - unsigned long start = kern_hyp_va((unsigned long)from); - unsigned long end = kern_hyp_va((unsigned long)to); + unsigned long virt_addr, start, end; + + from = khwasan_reset_tag(from); + to = khwasan_reset_tag(to); + + start = kern_hyp_va((unsigned long)from); + end = kern_hyp_va((unsigned long)to); if (is_kernel_in_hyp_mode()) return 0; @@ -719,8 +724,13 @@ int create_hyp_mappings(void *from, void *to, pgprot_t prot) */ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) { - unsigned long start = kern_hyp_va((unsigned long)from); - unsigned long end = kern_hyp_va((unsigned long)to); + unsigned long start, end; + + from = khwasan_reset_tag(from); + to = khwasan_reset_tag(to); + + start = kern_hyp_va((unsigned long)from); + end = kern_hyp_va((unsigned long)to); if (is_kernel_in_hyp_mode()) return 0; -- 2.17.0.rc0.231.g781580f067-goog