UPSTREAM: arm64: xen: Enable user access before a privcmd hvc call
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 5 Jul 2016 11:25:15 +0000 (12:25 +0100)
committerAmit Pundir <amit.pundir@linaro.org>
Mon, 16 Jan 2017 09:30:56 +0000 (15:00 +0530)
Privcmd calls are issued by the userspace. The kernel needs to enable
access to TTBR0_EL1 as the hypervisor would issue stage 1 translations
to user memory via AT instructions. Since AT instructions are not
affected by the PAN bit (ARMv8.1), we only need the explicit
uaccess_enable/disable if the TTBR0 PAN option is enabled.

Reviewed-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Bug: 31432001
Change-Id: I64d827923d869c1868702c8a18efa99ea91d3151
(cherry picked from commit 9cf09d68b89ae5fe0261dcc69464bcc676900af6)
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
arch/arm64/xen/hypercall.S

index 8bbe9401f4f011d3239adcd2d6f5251d5fe37ff0..b96db5dafec4859f976e6831e9a4c118893abee1 100644 (file)
@@ -49,6 +49,7 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/uaccess.h>
 #include <xen/interface/xen.h>
 
 
@@ -89,6 +90,20 @@ ENTRY(privcmd_call)
        mov x2, x3
        mov x3, x4
        mov x4, x5
+       /*
+        * Privcmd calls are issued by the userspace. The kernel needs to
+        * enable access to TTBR0_EL1 as the hypervisor would issue stage 1
+        * translations to user memory via AT instructions. Since AT
+        * instructions are not affected by the PAN bit (ARMv8.1), we only
+        * need the explicit uaccess_enable/disable if the TTBR0 PAN emulation
+        * is enabled (it implies that hardware UAO and PAN disabled).
+        */
+       uaccess_ttbr0_enable x6, x7
        hvc XEN_IMM
+
+       /*
+        * Disable userspace access from kernel once the hyp call completed.
+        */
+       uaccess_ttbr0_disable x6
        ret
 ENDPROC(privcmd_call);