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 <[email protected]>
---
 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 <linux/io.h>
 #include <linux/hugetlb.h>
 #include <linux/sched/signal.h>
+#include <linux/kasan.h>
 #include <trace/events/kvm.h>
 #include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
@@ -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

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to