Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Oct 2017 12:53:54 +0000 (UTC)
From:      Michal Meloun <mmel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r324660 - in head: lib/libc/arm/gen sys/arm/arm sys/arm/include
Message-ID:  <201710161253.v9GCrsRI011425@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mmel
Date: Mon Oct 16 12:53:54 2017
New Revision: 324660
URL: https://svnweb.freebsd.org/changeset/base/324660

Log:
  Save VFP state in getcontext(3) on ARM.
  This is a last followup of r315974, which fixes userland part
  of VFP save/restore problems described in PR 217611.
  
  PR:		217611
  MFC after:	2 weeks

Added:
  head/lib/libc/arm/gen/getcontextx.c   (contents, props changed)
Modified:
  head/lib/libc/arm/gen/Makefile.inc
  head/sys/arm/arm/machdep.c
  head/sys/arm/arm/sys_machdep.c
  head/sys/arm/include/machdep.h
  head/sys/arm/include/sysarch.h

Modified: head/lib/libc/arm/gen/Makefile.inc
==============================================================================
--- head/lib/libc/arm/gen/Makefile.inc	Mon Oct 16 12:32:57 2017	(r324659)
+++ head/lib/libc/arm/gen/Makefile.inc	Mon Oct 16 12:53:54 2017	(r324660)
@@ -5,7 +5,7 @@ SRCS+=	_ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.
 	infinity.c ldexp.c makecontext.c \
 	__aeabi_read_tp.S setjmp.S signalcontext.c sigsetjmp.S flt_rounds.c \
 	arm_initfini.c \
-	trivial-getcontextx.c
+	getcontextx.c
 
 .if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
 SRCS+=	fpgetmask_vfp.c fpgetround_vfp.c fpgetsticky_vfp.c fpsetmask_vfp.c \

Added: head/lib/libc/arm/gen/getcontextx.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/arm/gen/getcontextx.c	Mon Oct 16 12:53:54 2017	(r324660)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017 Michal Meloun <mmel@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <machine/sysarch.h>
+
+struct ucontextx {
+	ucontext_t	ucontext;
+	mcontext_vfp_t	mcontext_vfp;
+};
+
+int
+__getcontextx_size(void)
+{
+
+	return (sizeof(struct ucontextx));
+}
+
+int
+__fillcontextx2(char *ctx)
+{
+	struct ucontextx *ucxp;
+	ucontext_t	 *ucp;
+	mcontext_vfp_t	 *mvp;
+	struct arm_get_vfpstate_args vfp_arg;
+
+	ucxp = (struct ucontextx *)ctx;
+	ucp = &ucxp->ucontext;
+	mvp = &ucxp->mcontext_vfp;
+
+	vfp_arg.mc_vfp_size = sizeof(mcontext_vfp_t);
+	vfp_arg.mc_vfp = mvp;
+	if (sysarch(ARM_GET_VFPSTATE, &vfp_arg) == -1)
+			return (-1);
+	ucp->uc_mcontext.mc_vfp_size = sizeof(mcontext_vfp_t);
+	ucp->uc_mcontext.mc_vfp_ptr = mvp;
+	return (0);
+}
+
+int
+__fillcontextx(char *ctx)
+{
+	struct ucontextx *ucxp;
+
+	ucxp = (struct ucontextx *)ctx;
+	if (getcontext(&ucxp->ucontext) == -1)
+		return (-1);
+	__fillcontextx2(ctx);
+	return (0);
+}
+
+__weak_reference(__getcontextx, getcontextx);
+
+ucontext_t *
+__getcontextx(void)
+{
+	char *ctx;
+	int error;
+
+	ctx = malloc(__getcontextx_size());
+	if (ctx == NULL)
+		return (NULL);
+	if (__fillcontextx(ctx) == -1) {
+		error = errno;
+		free(ctx);
+		errno = error;
+		return (NULL);
+	}
+	return ((ucontext_t *)ctx);
+}

Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c	Mon Oct 16 12:32:57 2017	(r324659)
+++ head/sys/arm/arm/machdep.c	Mon Oct 16 12:53:54 2017	(r324660)
@@ -443,6 +443,30 @@ set_vfpcontext(struct thread *td, mcontext_vfp_t *vfp)
 }
 #endif
 
+int
+arm_get_vfpstate(struct thread *td, void *args)
+{
+	int rv;
+	struct arm_get_vfpstate_args ua;
+	mcontext_vfp_t	mcontext_vfp;
+
+	rv = copyin(args, &ua, sizeof(ua));
+	if (rv != 0)
+		return (rv);
+	if (ua.mc_vfp_size != sizeof(mcontext_vfp_t))
+		return (EINVAL);
+#ifdef VFP
+	get_vfpcontext(td, &mcontext_vfp);
+#else
+	bzero(&mcontext_vfp, sizeof(mcontext_vfp));
+#endif
+
+	rv = copyout(&mcontext_vfp, ua.mc_vfp,  sizeof(mcontext_vfp));
+	if (rv != 0)
+		return (rv);
+	return (0);
+}
+
 /*
  * Get machine context.
  */

Modified: head/sys/arm/arm/sys_machdep.c
==============================================================================
--- head/sys/arm/arm/sys_machdep.c	Mon Oct 16 12:32:57 2017	(r324659)
+++ head/sys/arm/arm/sys_machdep.c	Mon Oct 16 12:53:54 2017	(r324660)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/cpu.h>
 #include <machine/sysarch.h>
+#include <machine/machdep.h>
 #include <machine/vmparam.h>
 
 #ifndef _SYS_SYSPROTO_H_
@@ -204,6 +205,7 @@ sysarch(struct thread *td, struct sysarch_args *uap)
 		case ARM_DRAIN_WRITEBUF:
 		case ARM_SET_TP:
 		case ARM_GET_TP:
+		case ARM_GET_VFPSTATE:
 			break;
 
 		default:
@@ -228,6 +230,9 @@ sysarch(struct thread *td, struct sysarch_args *uap)
 		break;
 	case ARM_GET_TP:
 		error = arm32_get_tp(td, uap->parms);
+		break;
+	case ARM_GET_VFPSTATE:
+		error = arm_get_vfpstate(td, uap->parms);
 		break;
 	default:
 		error = EINVAL;

Modified: head/sys/arm/include/machdep.h
==============================================================================
--- head/sys/arm/include/machdep.h	Mon Oct 16 12:32:57 2017	(r324659)
+++ head/sys/arm/include/machdep.h	Mon Oct 16 12:53:54 2017	(r324660)
@@ -40,6 +40,7 @@ void arm_parse_fdt_bootargs(void);
 void arm_print_kenv(void);
 
 void arm_generic_initclocks(void);
+int arm_get_vfpstate(struct thread *td, void *args);
 
 /* Board-specific attributes */
 void board_set_serial(uint64_t);

Modified: head/sys/arm/include/sysarch.h
==============================================================================
--- head/sys/arm/include/sysarch.h	Mon Oct 16 12:32:57 2017	(r324659)
+++ head/sys/arm/include/sysarch.h	Mon Oct 16 12:53:54 2017	(r324660)
@@ -78,10 +78,16 @@
 #define ARM_DRAIN_WRITEBUF	1
 #define ARM_SET_TP		2
 #define ARM_GET_TP		3
+#define ARM_GET_VFPSTATE	4
 
 struct arm_sync_icache_args {
 	uintptr_t	addr;		/* Virtual start address */
 	size_t		len;		/* Region size */
+};
+
+struct arm_get_vfpstate_args {
+	size_t		mc_vfp_size;
+	void 		*mc_vfp;
 };
 
 #ifndef _KERNEL



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201710161253.v9GCrsRI011425>