All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Tatashin <pasha.tatashin@soleen.com>
To: pasha.tatashin@soleen.com, jmorris@namei.org, sashal@kernel.org,
	linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
	will@kernel.org, steve.capper@arm.com,
	linux-arm-kernel@lists.infradead.org, marc.zyngier@arm.com,
	james.morse@arm.com, vladimir.murzin@arm.com,
	mark.rutland@arm.com, tglx@linutronix.de,
	gregkh@linuxfoundation.org, allison@lohutok.net, info@metux.net,
	alexios.zavras@intel.com, sstabellini@kernel.org,
	boris.ostrovsky@oracle.com, jgross@suse.com, stefan@agner.ch,
	yamada.masahiro@socionext.com, xen-devel@lists.xenproject.org,
	linux@armlinux.org.uk
Subject: [PATCH 1/3] arm/arm64/xen: use C inlines for privcmd_call
Date: Thu, 21 Nov 2019 13:48:03 -0500	[thread overview]
Message-ID: <20191121184805.414758-2-pasha.tatashin@soleen.com> (raw)
In-Reply-To: <20191121184805.414758-1-pasha.tatashin@soleen.com>

privcmd_call requires to enable access to userspace for the
duration of the hypercall.

Currently, this is done via assembly macros. Change it to C
inlines instead.

Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
 arch/arm/include/asm/assembler.h |  2 +-
 arch/arm/include/asm/uaccess.h   | 32 ++++++++++++++++++++++++++------
 arch/arm/xen/enlighten.c         |  2 +-
 arch/arm/xen/hypercall.S         | 15 ++-------------
 arch/arm64/xen/hypercall.S       | 19 ++-----------------
 include/xen/arm/hypercall.h      | 23 ++++++++++++++++++++---
 6 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 99929122dad7..8e9262a0f016 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -480,7 +480,7 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	.macro	uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/*
-	 * Whenever we re-enter userspace, the domains should always be
+	 * Whenever we re-enter kernel, the domains should always be
 	 * set appropriately.
 	 */
 	mov	\tmp, #DACR_UACCESS_DISABLE
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 98c6b91be4a8..79d4efa3eb62 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -16,6 +16,23 @@
 
 #include <asm/extable.h>
 
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+static __always_inline void uaccess_enable(void)
+{
+	unsigned long val = DACR_UACCESS_ENABLE;
+
+	asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (val));
+	isb();
+}
+
+static __always_inline void uaccess_disable(void)
+{
+	unsigned long val = DACR_UACCESS_ENABLE;
+
+	asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (val));
+	isb();
+}
+
 /*
  * These two functions allow hooking accesses to userspace to increase
  * system integrity by ensuring that the kernel can not inadvertantly
@@ -24,7 +41,6 @@
  */
 static __always_inline unsigned int uaccess_save_and_enable(void)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	unsigned int old_domain = get_domain();
 
 	/* Set the current domain access to permit user accesses */
@@ -32,18 +48,22 @@ static __always_inline unsigned int uaccess_save_and_enable(void)
 		   domain_val(DOMAIN_USER, DOMAIN_CLIENT));
 
 	return old_domain;
-#else
-	return 0;
-#endif
 }
 
 static __always_inline void uaccess_restore(unsigned int flags)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/* Restore the user access mask */
 	set_domain(flags);
-#endif
 }
+#else
+static __always_inline void uaccess_enable(void) {}
+static __always_inline void uaccess_disable(void) {}
+static __always_inline unsigned int uaccess_save_and_enable(void)
+{
+	return 0;
+}
+static __always_inline void uaccess_restore(unsigned int flags) {}
+#endif /* CONFIG_CPU_SW_DOMAIN_PAN */
 
 /*
  * These two are intentionally not defined anywhere - if the kernel
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index dd6804a64f1a..e87280c6d25d 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -440,4 +440,4 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op_raw);
 EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
 EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
 EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
-EXPORT_SYMBOL_GPL(privcmd_call);
+EXPORT_SYMBOL_GPL(arch_privcmd_call);
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index b11bba542fac..2f5be0dc6195 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -94,29 +94,18 @@ HYPERCALL2(multicall);
 HYPERCALL2(vm_assist);
 HYPERCALL3(dm_op);
 
-ENTRY(privcmd_call)
+ENTRY(arch_privcmd_call)
 	stmdb sp!, {r4}
 	mov r12, r0
 	mov r0, r1
 	mov r1, r2
 	mov r2, r3
 	ldr r3, [sp, #8]
-	/*
-	 * Privcmd calls are issued by the userspace. We need to allow the
-	 * kernel to access the userspace memory before issuing the hypercall.
-	 */
-	uaccess_enable r4
 
 	/* r4 is loaded now as we use it as scratch register before */
 	ldr r4, [sp, #4]
 	__HVC(XEN_IMM)
 
-	/*
-	 * Disable userspace access from kernel. This is fine to do it
-	 * unconditionally as no set_fs(KERNEL_DS) is called before.
-	 */
-	uaccess_disable r4
-
 	ldm sp!, {r4}
 	ret lr
-ENDPROC(privcmd_call);
+ENDPROC(arch_privcmd_call);
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
index c5f05c4a4d00..921611778d2a 100644
--- a/arch/arm64/xen/hypercall.S
+++ b/arch/arm64/xen/hypercall.S
@@ -49,7 +49,6 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/asm-uaccess.h>
 #include <xen/interface/xen.h>
 
 
@@ -86,27 +85,13 @@ HYPERCALL2(multicall);
 HYPERCALL2(vm_assist);
 HYPERCALL3(dm_op);
 
-ENTRY(privcmd_call)
+ENTRY(arch_privcmd_call)
 	mov x16, x0
 	mov x0, x1
 	mov x1, x2
 	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, x8
 	hvc XEN_IMM
-
-	/*
-	 * Disable userspace access from kernel once the hyp call completed.
-	 */
-	uaccess_ttbr0_disable x6, x7
 	ret
-ENDPROC(privcmd_call);
+ENDPROC(arch_privcmd_call);
diff --git a/include/xen/arm/hypercall.h b/include/xen/arm/hypercall.h
index b40485e54d80..cfb704fd78c8 100644
--- a/include/xen/arm/hypercall.h
+++ b/include/xen/arm/hypercall.h
@@ -34,16 +34,33 @@
 #define _ASM_ARM_XEN_HYPERCALL_H
 
 #include <linux/bug.h>
+#include <linux/uaccess.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/sched.h>
 #include <xen/interface/platform.h>
 
 struct xen_dm_op_buf;
+long arch_privcmd_call(unsigned int call, unsigned long a1,
+		       unsigned long a2, unsigned long a3,
+		       unsigned long a4, unsigned long a5);
 
-long privcmd_call(unsigned call, unsigned long a1,
-		unsigned long a2, unsigned long a3,
-		unsigned long a4, unsigned long a5);
+static inline long privcmd_call(unsigned int call, unsigned long a1,
+				unsigned long a2, unsigned long a3,
+				unsigned long a4, unsigned long a5)
+{
+	long rv;
+
+	/*
+	 * Privcmd calls are issued by the userspace. We need to allow the
+	 * kernel to access the userspace memory before issuing the hypercall.
+	 */
+	uaccess_enable();
+	rv = arch_privcmd_call(call, a1, a2, a3, a4, a5);
+	uaccess_disable();
+
+	return rv;
+}
 int HYPERVISOR_xen_version(int cmd, void *arg);
 int HYPERVISOR_console_io(int cmd, int count, char *str);
 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-- 
2.24.0


WARNING: multiple messages have this Message-ID (diff)
From: Pavel Tatashin <pasha.tatashin@soleen.com>
To: pasha.tatashin@soleen.com, jmorris@namei.org, sashal@kernel.org,
	linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
	will@kernel.org, steve.capper@arm.com,
	linux-arm-kernel@lists.infradead.org, marc.zyngier@arm.com,
	james.morse@arm.com, vladimir.murzin@arm.com,
	mark.rutland@arm.com, tglx@linutronix.de,
	gregkh@linuxfoundation.org, allison@lohutok.net, info@metux.net,
	alexios.zavras@intel.com, sstabellini@kernel.org,
	boris.ostrovsky@oracle.com, jgross@suse.com, stefan@agner.ch,
	yamada.masahiro@socionext.com, xen-devel@lists.xenproject.org,
	linux@armlinux.org.uk
Subject: [PATCH 1/3] arm/arm64/xen: use C inlines for privcmd_call
Date: Thu, 21 Nov 2019 13:48:03 -0500	[thread overview]
Message-ID: <20191121184805.414758-2-pasha.tatashin@soleen.com> (raw)
In-Reply-To: <20191121184805.414758-1-pasha.tatashin@soleen.com>

privcmd_call requires to enable access to userspace for the
duration of the hypercall.

Currently, this is done via assembly macros. Change it to C
inlines instead.

Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
 arch/arm/include/asm/assembler.h |  2 +-
 arch/arm/include/asm/uaccess.h   | 32 ++++++++++++++++++++++++++------
 arch/arm/xen/enlighten.c         |  2 +-
 arch/arm/xen/hypercall.S         | 15 ++-------------
 arch/arm64/xen/hypercall.S       | 19 ++-----------------
 include/xen/arm/hypercall.h      | 23 ++++++++++++++++++++---
 6 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 99929122dad7..8e9262a0f016 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -480,7 +480,7 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	.macro	uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/*
-	 * Whenever we re-enter userspace, the domains should always be
+	 * Whenever we re-enter kernel, the domains should always be
 	 * set appropriately.
 	 */
 	mov	\tmp, #DACR_UACCESS_DISABLE
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 98c6b91be4a8..79d4efa3eb62 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -16,6 +16,23 @@
 
 #include <asm/extable.h>
 
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+static __always_inline void uaccess_enable(void)
+{
+	unsigned long val = DACR_UACCESS_ENABLE;
+
+	asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (val));
+	isb();
+}
+
+static __always_inline void uaccess_disable(void)
+{
+	unsigned long val = DACR_UACCESS_ENABLE;
+
+	asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (val));
+	isb();
+}
+
 /*
  * These two functions allow hooking accesses to userspace to increase
  * system integrity by ensuring that the kernel can not inadvertantly
@@ -24,7 +41,6 @@
  */
 static __always_inline unsigned int uaccess_save_and_enable(void)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	unsigned int old_domain = get_domain();
 
 	/* Set the current domain access to permit user accesses */
@@ -32,18 +48,22 @@ static __always_inline unsigned int uaccess_save_and_enable(void)
 		   domain_val(DOMAIN_USER, DOMAIN_CLIENT));
 
 	return old_domain;
-#else
-	return 0;
-#endif
 }
 
 static __always_inline void uaccess_restore(unsigned int flags)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/* Restore the user access mask */
 	set_domain(flags);
-#endif
 }
+#else
+static __always_inline void uaccess_enable(void) {}
+static __always_inline void uaccess_disable(void) {}
+static __always_inline unsigned int uaccess_save_and_enable(void)
+{
+	return 0;
+}
+static __always_inline void uaccess_restore(unsigned int flags) {}
+#endif /* CONFIG_CPU_SW_DOMAIN_PAN */
 
 /*
  * These two are intentionally not defined anywhere - if the kernel
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index dd6804a64f1a..e87280c6d25d 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -440,4 +440,4 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op_raw);
 EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
 EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
 EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
-EXPORT_SYMBOL_GPL(privcmd_call);
+EXPORT_SYMBOL_GPL(arch_privcmd_call);
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index b11bba542fac..2f5be0dc6195 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -94,29 +94,18 @@ HYPERCALL2(multicall);
 HYPERCALL2(vm_assist);
 HYPERCALL3(dm_op);
 
-ENTRY(privcmd_call)
+ENTRY(arch_privcmd_call)
 	stmdb sp!, {r4}
 	mov r12, r0
 	mov r0, r1
 	mov r1, r2
 	mov r2, r3
 	ldr r3, [sp, #8]
-	/*
-	 * Privcmd calls are issued by the userspace. We need to allow the
-	 * kernel to access the userspace memory before issuing the hypercall.
-	 */
-	uaccess_enable r4
 
 	/* r4 is loaded now as we use it as scratch register before */
 	ldr r4, [sp, #4]
 	__HVC(XEN_IMM)
 
-	/*
-	 * Disable userspace access from kernel. This is fine to do it
-	 * unconditionally as no set_fs(KERNEL_DS) is called before.
-	 */
-	uaccess_disable r4
-
 	ldm sp!, {r4}
 	ret lr
-ENDPROC(privcmd_call);
+ENDPROC(arch_privcmd_call);
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
index c5f05c4a4d00..921611778d2a 100644
--- a/arch/arm64/xen/hypercall.S
+++ b/arch/arm64/xen/hypercall.S
@@ -49,7 +49,6 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/asm-uaccess.h>
 #include <xen/interface/xen.h>
 
 
@@ -86,27 +85,13 @@ HYPERCALL2(multicall);
 HYPERCALL2(vm_assist);
 HYPERCALL3(dm_op);
 
-ENTRY(privcmd_call)
+ENTRY(arch_privcmd_call)
 	mov x16, x0
 	mov x0, x1
 	mov x1, x2
 	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, x8
 	hvc XEN_IMM
-
-	/*
-	 * Disable userspace access from kernel once the hyp call completed.
-	 */
-	uaccess_ttbr0_disable x6, x7
 	ret
-ENDPROC(privcmd_call);
+ENDPROC(arch_privcmd_call);
diff --git a/include/xen/arm/hypercall.h b/include/xen/arm/hypercall.h
index b40485e54d80..cfb704fd78c8 100644
--- a/include/xen/arm/hypercall.h
+++ b/include/xen/arm/hypercall.h
@@ -34,16 +34,33 @@
 #define _ASM_ARM_XEN_HYPERCALL_H
 
 #include <linux/bug.h>
+#include <linux/uaccess.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/sched.h>
 #include <xen/interface/platform.h>
 
 struct xen_dm_op_buf;
+long arch_privcmd_call(unsigned int call, unsigned long a1,
+		       unsigned long a2, unsigned long a3,
+		       unsigned long a4, unsigned long a5);
 
-long privcmd_call(unsigned call, unsigned long a1,
-		unsigned long a2, unsigned long a3,
-		unsigned long a4, unsigned long a5);
+static inline long privcmd_call(unsigned int call, unsigned long a1,
+				unsigned long a2, unsigned long a3,
+				unsigned long a4, unsigned long a5)
+{
+	long rv;
+
+	/*
+	 * Privcmd calls are issued by the userspace. We need to allow the
+	 * kernel to access the userspace memory before issuing the hypercall.
+	 */
+	uaccess_enable();
+	rv = arch_privcmd_call(call, a1, a2, a3, a4, a5);
+	uaccess_disable();
+
+	return rv;
+}
 int HYPERVISOR_xen_version(int cmd, void *arg);
 int HYPERVISOR_console_io(int cmd, int count, char *str);
 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-- 
2.24.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Pavel Tatashin <pasha.tatashin@soleen.com>
To: pasha.tatashin@soleen.com, jmorris@namei.org, sashal@kernel.org,
	linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
	will@kernel.org, steve.capper@arm.com,
	linux-arm-kernel@lists.infradead.org, marc.zyngier@arm.com,
	james.morse@arm.com, vladimir.murzin@arm.com,
	mark.rutland@arm.com, tglx@linutronix.de,
	gregkh@linuxfoundation.org, allison@lohutok.net, info@metux.net,
	alexios.zavras@intel.com, sstabellini@kernel.org,
	boris.ostrovsky@oracle.com, jgross@suse.com, stefan@agner.ch,
	yamada.masahiro@socionext.com, xen-devel@lists.xenproject.org,
	linux@armlinux.org.uk
Subject: [Xen-devel] [PATCH 1/3] arm/arm64/xen: use C inlines for privcmd_call
Date: Thu, 21 Nov 2019 13:48:03 -0500	[thread overview]
Message-ID: <20191121184805.414758-2-pasha.tatashin@soleen.com> (raw)
In-Reply-To: <20191121184805.414758-1-pasha.tatashin@soleen.com>

privcmd_call requires to enable access to userspace for the
duration of the hypercall.

Currently, this is done via assembly macros. Change it to C
inlines instead.

Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
 arch/arm/include/asm/assembler.h |  2 +-
 arch/arm/include/asm/uaccess.h   | 32 ++++++++++++++++++++++++++------
 arch/arm/xen/enlighten.c         |  2 +-
 arch/arm/xen/hypercall.S         | 15 ++-------------
 arch/arm64/xen/hypercall.S       | 19 ++-----------------
 include/xen/arm/hypercall.h      | 23 ++++++++++++++++++++---
 6 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 99929122dad7..8e9262a0f016 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -480,7 +480,7 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	.macro	uaccess_disable, tmp, isb=1
 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/*
-	 * Whenever we re-enter userspace, the domains should always be
+	 * Whenever we re-enter kernel, the domains should always be
 	 * set appropriately.
 	 */
 	mov	\tmp, #DACR_UACCESS_DISABLE
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 98c6b91be4a8..79d4efa3eb62 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -16,6 +16,23 @@
 
 #include <asm/extable.h>
 
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+static __always_inline void uaccess_enable(void)
+{
+	unsigned long val = DACR_UACCESS_ENABLE;
+
+	asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (val));
+	isb();
+}
+
+static __always_inline void uaccess_disable(void)
+{
+	unsigned long val = DACR_UACCESS_ENABLE;
+
+	asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (val));
+	isb();
+}
+
 /*
  * These two functions allow hooking accesses to userspace to increase
  * system integrity by ensuring that the kernel can not inadvertantly
@@ -24,7 +41,6 @@
  */
 static __always_inline unsigned int uaccess_save_and_enable(void)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	unsigned int old_domain = get_domain();
 
 	/* Set the current domain access to permit user accesses */
@@ -32,18 +48,22 @@ static __always_inline unsigned int uaccess_save_and_enable(void)
 		   domain_val(DOMAIN_USER, DOMAIN_CLIENT));
 
 	return old_domain;
-#else
-	return 0;
-#endif
 }
 
 static __always_inline void uaccess_restore(unsigned int flags)
 {
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 	/* Restore the user access mask */
 	set_domain(flags);
-#endif
 }
+#else
+static __always_inline void uaccess_enable(void) {}
+static __always_inline void uaccess_disable(void) {}
+static __always_inline unsigned int uaccess_save_and_enable(void)
+{
+	return 0;
+}
+static __always_inline void uaccess_restore(unsigned int flags) {}
+#endif /* CONFIG_CPU_SW_DOMAIN_PAN */
 
 /*
  * These two are intentionally not defined anywhere - if the kernel
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index dd6804a64f1a..e87280c6d25d 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -440,4 +440,4 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op_raw);
 EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
 EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
 EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
-EXPORT_SYMBOL_GPL(privcmd_call);
+EXPORT_SYMBOL_GPL(arch_privcmd_call);
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index b11bba542fac..2f5be0dc6195 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -94,29 +94,18 @@ HYPERCALL2(multicall);
 HYPERCALL2(vm_assist);
 HYPERCALL3(dm_op);
 
-ENTRY(privcmd_call)
+ENTRY(arch_privcmd_call)
 	stmdb sp!, {r4}
 	mov r12, r0
 	mov r0, r1
 	mov r1, r2
 	mov r2, r3
 	ldr r3, [sp, #8]
-	/*
-	 * Privcmd calls are issued by the userspace. We need to allow the
-	 * kernel to access the userspace memory before issuing the hypercall.
-	 */
-	uaccess_enable r4
 
 	/* r4 is loaded now as we use it as scratch register before */
 	ldr r4, [sp, #4]
 	__HVC(XEN_IMM)
 
-	/*
-	 * Disable userspace access from kernel. This is fine to do it
-	 * unconditionally as no set_fs(KERNEL_DS) is called before.
-	 */
-	uaccess_disable r4
-
 	ldm sp!, {r4}
 	ret lr
-ENDPROC(privcmd_call);
+ENDPROC(arch_privcmd_call);
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
index c5f05c4a4d00..921611778d2a 100644
--- a/arch/arm64/xen/hypercall.S
+++ b/arch/arm64/xen/hypercall.S
@@ -49,7 +49,6 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/asm-uaccess.h>
 #include <xen/interface/xen.h>
 
 
@@ -86,27 +85,13 @@ HYPERCALL2(multicall);
 HYPERCALL2(vm_assist);
 HYPERCALL3(dm_op);
 
-ENTRY(privcmd_call)
+ENTRY(arch_privcmd_call)
 	mov x16, x0
 	mov x0, x1
 	mov x1, x2
 	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, x8
 	hvc XEN_IMM
-
-	/*
-	 * Disable userspace access from kernel once the hyp call completed.
-	 */
-	uaccess_ttbr0_disable x6, x7
 	ret
-ENDPROC(privcmd_call);
+ENDPROC(arch_privcmd_call);
diff --git a/include/xen/arm/hypercall.h b/include/xen/arm/hypercall.h
index b40485e54d80..cfb704fd78c8 100644
--- a/include/xen/arm/hypercall.h
+++ b/include/xen/arm/hypercall.h
@@ -34,16 +34,33 @@
 #define _ASM_ARM_XEN_HYPERCALL_H
 
 #include <linux/bug.h>
+#include <linux/uaccess.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/sched.h>
 #include <xen/interface/platform.h>
 
 struct xen_dm_op_buf;
+long arch_privcmd_call(unsigned int call, unsigned long a1,
+		       unsigned long a2, unsigned long a3,
+		       unsigned long a4, unsigned long a5);
 
-long privcmd_call(unsigned call, unsigned long a1,
-		unsigned long a2, unsigned long a3,
-		unsigned long a4, unsigned long a5);
+static inline long privcmd_call(unsigned int call, unsigned long a1,
+				unsigned long a2, unsigned long a3,
+				unsigned long a4, unsigned long a5)
+{
+	long rv;
+
+	/*
+	 * Privcmd calls are issued by the userspace. We need to allow the
+	 * kernel to access the userspace memory before issuing the hypercall.
+	 */
+	uaccess_enable();
+	rv = arch_privcmd_call(call, a1, a2, a3, a4, a5);
+	uaccess_disable();
+
+	return rv;
+}
 int HYPERVISOR_xen_version(int cmd, void *arg);
 int HYPERVISOR_console_io(int cmd, int count, char *str);
 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-- 
2.24.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2019-11-21 18:48 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-21 18:48 [PATCH 0/3] Use C inlines for uaccess Pavel Tatashin
2019-11-21 18:48 ` [Xen-devel] " Pavel Tatashin
2019-11-21 18:48 ` Pavel Tatashin
2019-11-21 18:48 ` Pavel Tatashin [this message]
2019-11-21 18:48   ` [Xen-devel] [PATCH 1/3] arm/arm64/xen: use C inlines for privcmd_call Pavel Tatashin
2019-11-21 18:48   ` Pavel Tatashin
2019-11-22  0:22   ` Russell King - ARM Linux admin
2019-11-22  0:22     ` [Xen-devel] " Russell King - ARM Linux admin
2019-11-22  0:22     ` Russell King - ARM Linux admin
2019-11-22  0:30     ` Pavel Tatashin
2019-11-22  0:30       ` [Xen-devel] " Pavel Tatashin
2019-11-22  0:30       ` Pavel Tatashin
2019-11-22  0:34       ` Russell King - ARM Linux admin
2019-11-22  0:34         ` [Xen-devel] " Russell King - ARM Linux admin
2019-11-22  0:34         ` Russell King - ARM Linux admin
2019-11-22  0:35         ` Russell King - ARM Linux admin
2019-11-22  0:35           ` [Xen-devel] " Russell King - ARM Linux admin
2019-11-22  0:35           ` Russell King - ARM Linux admin
2019-11-22  0:39           ` Pavel Tatashin
2019-11-22  0:39             ` [Xen-devel] " Pavel Tatashin
2019-11-22  0:39             ` Pavel Tatashin
2019-11-22  0:53             ` Russell King - ARM Linux admin
2019-11-22  0:53               ` [Xen-devel] " Russell King - ARM Linux admin
2019-11-22  0:53               ` Russell King - ARM Linux admin
2019-11-21 18:48 ` [PATCH 2/3] arm64: remove uaccess_ttbr0 asm macros from cache functions Pavel Tatashin
2019-11-21 18:48   ` [Xen-devel] " Pavel Tatashin
2019-11-21 18:48   ` Pavel Tatashin
2019-11-21 18:48 ` [PATCH 3/3] arm64: remove the rest of asm-uaccess.h Pavel Tatashin
2019-11-21 18:48   ` [Xen-devel] " Pavel Tatashin
2019-11-21 18:48   ` Pavel Tatashin
2019-11-22  1:26   ` Max Filippov
2019-11-22  1:26     ` [Xen-devel] " Max Filippov
2019-11-22  1:26     ` Max Filippov
2019-11-22  2:20     ` Pavel Tatashin
2019-11-22  2:20       ` [Xen-devel] " Pavel Tatashin
2019-11-22  2:20       ` Pavel Tatashin
2019-11-27 18:44 [PATCH 0/3] Use C inlines for uaccess Pavel Tatashin
2019-11-27 18:44 ` [PATCH 1/3] arm/arm64/xen: use C inlines for privcmd_call Pavel Tatashin
2019-11-27 18:44   ` Pavel Tatashin
2019-11-29 15:05   ` Julien Grall
2019-11-29 15:05     ` Julien Grall
2019-12-04 17:58     ` Pavel Tatashin
2019-12-04 17:58       ` Pavel Tatashin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191121184805.414758-2-pasha.tatashin@soleen.com \
    --to=pasha.tatashin@soleen.com \
    --cc=alexios.zavras@intel.com \
    --cc=allison@lohutok.net \
    --cc=boris.ostrovsky@oracle.com \
    --cc=catalin.marinas@arm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=info@metux.net \
    --cc=james.morse@arm.com \
    --cc=jgross@suse.com \
    --cc=jmorris@namei.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=sashal@kernel.org \
    --cc=sstabellini@kernel.org \
    --cc=stefan@agner.ch \
    --cc=steve.capper@arm.com \
    --cc=tglx@linutronix.de \
    --cc=vladimir.murzin@arm.com \
    --cc=will@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    --cc=yamada.masahiro@socionext.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.