aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@citrix.com>2015-09-11 12:25:59 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2015-09-11 13:50:03 -0400
commit0b61f2c0f37983c98ed4207f3f5e265938371b68 (patch)
tree3dd23439d981eb8e93da117a6a563c797d4fe08c
parent6e8f580d1fcc18e290713984c379cb97131c015a (diff)
arm/xen: Enable user access to the kernel before issuing a privcmd call
When Xen is copying data to/from the guest it will check if the kernel has the right to do the access. If not, the hypercall will return an error. After the commit a5e090acbf545c0a3b04080f8a488b17ec41fe02 "ARM: software-based privileged-no-access support", the kernel can't access any longer the user space by default. This will result to fail on every hypercall made by the userspace (i.e via privcmd). We have to enable the userspace access and then restore the correct permission every time the privcmd is used to made an hypercall. I didn't find generic helpers to do a these operations, so the change is only arm32 specific. Reported-by: Riku Voipio <riku.voipio@linaro.org> Signed-off-by: Julien Grall <julien.grall@citrix.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/xen/hypercall.S15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index f00e08075938..10fd99c568c6 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -98,8 +98,23 @@ ENTRY(privcmd_call)
98 mov r1, r2 98 mov r1, r2
99 mov r2, r3 99 mov r2, r3
100 ldr r3, [sp, #8] 100 ldr r3, [sp, #8]
101 /*
102 * Privcmd calls are issued by the userspace. We need to allow the
103 * kernel to access the userspace memory before issuing the hypercall.
104 */
105 uaccess_enable r4
106
107 /* r4 is loaded now as we use it as scratch register before */
101 ldr r4, [sp, #4] 108 ldr r4, [sp, #4]
102 __HVC(XEN_IMM) 109 __HVC(XEN_IMM)
110
111 /*
112 * Disable userspace access from kernel. This is fine to do it
113 * unconditionally as no set_fs(KERNEL_DS)/set_fs(get_ds()) is
114 * called before.
115 */
116 uaccess_disable r4
117
103 ldm sp!, {r4} 118 ldm sp!, {r4}
104 ret lr 119 ret lr
105ENDPROC(privcmd_call); 120ENDPROC(privcmd_call);