linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Maciej W. Rozycki" <macro@imgtec.com>
To: <linux-mips@linux-mips.org>
Cc: Ralf Baechle <ralf@linux-mips.org>,
	Matthew Fortune <Matthew.Fortune@imgtec.com>,
	Daniel Sanders <Daniel.Sanders@imgtec.com>,
	Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>,
	<linux-kernel@vger.kernel.org>
Subject: [RFC PATCH 4/4] prctl: Add MIPS IEEE Std 754 compliance mode switching
Date: Mon, 16 Nov 2015 14:35:17 +0000	[thread overview]
Message-ID: <alpine.DEB.2.00.1511161413370.7097@tp.orcam.me.uk> (raw)
In-Reply-To: <alpine.DEB.2.00.1511161358211.7097@tp.orcam.me.uk>

Implement the prctl(2) interface for IEEE Std 754 NaN interlinking, as 
per "MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking" 
<https://dmz-portal.mips.com/wiki/MIPS_ABI_-_NaN_Interlinking>:

* interpret the PR_SET_IEEE754_MODE request,

* accept or reject the new mode requested according to FP hardware or
  emulator capabilities and any `ieee754=' kernel parameter in effect,

* set the values of the FCSR ABS2008 and NAN2008 bits according to the
  NaN encoding requested, either PR_IEEE754_MODE_NAN_LEGACY or 
  PR_IEEE754_MODE_NAN_2008, if writable,

* on success return bits 31:24 of the auxiliary vector's AT_FLAGS value 
  corresponding to the new mode in effect, in bits 7:0 of the result.

Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
---
linux-mips-nan-interlink-prctl.diff
Index: linux-sfr-test/arch/mips/include/asm/processor.h
===================================================================
--- linux-sfr-test.orig/arch/mips/include/asm/processor.h	2015-11-11 12:34:46.131650000 +0000
+++ linux-sfr-test/arch/mips/include/asm/processor.h	2015-11-11 13:14:09.208745000 +0000
@@ -402,4 +402,13 @@ extern int mips_set_process_fp_mode(stru
 #define GET_FP_MODE(task)		mips_get_process_fp_mode(task)
 #define SET_FP_MODE(task,value)		mips_set_process_fp_mode(task, value)
 
+/*
+ * Likewise the PR_SET_IEEE754_MODE option.
+ */
+extern int mips_set_process_ieee754_mode(struct task_struct *task,
+					 unsigned int mode, unsigned int what);
+
+#define SET_IEEE754_MODE(task, mode, what) \
+	mips_set_process_ieee754_mode((task), (mode), (what))
+
 #endif /* _ASM_PROCESSOR_H */
Index: linux-sfr-test/arch/mips/kernel/process.c
===================================================================
--- linux-sfr-test.orig/arch/mips/kernel/process.c	2015-11-11 12:34:46.154646000 +0000
+++ linux-sfr-test/arch/mips/kernel/process.c	2015-11-11 13:17:14.564231000 +0000
@@ -9,6 +9,7 @@
  * Copyright (C) 2004 Thiemo Seufer
  * Copyright (C) 2013  Imagination Technologies Ltd.
  */
+#include <linux/elf.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/tick.h>
@@ -39,7 +40,6 @@
 #include <asm/reg.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#include <asm/elf.h>
 #include <asm/isadep.h>
 #include <asm/inst.h>
 #include <asm/stacktrace.h>
@@ -682,3 +682,76 @@ int mips_set_process_fp_mode(struct task
 
 	return 0;
 }
+
+/*
+ * Set the process's IEEE 754 compliance mode according to MODE, either
+ * strict or relaxed, affecting WHAT, either legacy or 2008 NaN.  On
+ * success return an updated bit pattern as in bits 31:24 of the value
+ * of of of the AT_FLAGS auxiliary vector entry upon program startup,
+ * shifted into bits 7:0 of the result.
+ */
+int mips_set_process_ieee754_mode(struct task_struct *task,
+				  unsigned int mode, unsigned int what)
+{
+	struct cpuinfo_mips *c = &boot_cpu_data;
+	struct task_struct *t;
+	bool nan_2008;
+	bool relaxed;
+
+	switch (mode) {
+	case PR_IEEE754_MODE_LEGACY:
+		relaxed = mips_default_ieee754_relaxed;
+		break;
+	case PR_IEEE754_MODE_STRICT:
+		relaxed = false;
+		break;
+	case PR_IEEE754_MODE_RELAXED:
+		if (mips_accept_ieee754_relaxed)
+			relaxed = true;
+		else
+			return -EOPNOTSUPP;
+		break;
+	default:
+		return -EINVAL;
+	}
+	switch (what) {
+	case PR_IEEE754_MODE_NAN_LEGACY:
+		if (relaxed || mips_use_nan_legacy)
+			nan_2008 = false;
+		else
+			return -ENXIO;
+		break;
+	case PR_IEEE754_MODE_NAN_2008:
+		if (relaxed || mips_use_nan_2008)
+			nan_2008 = true;
+		else
+			return -ENXIO;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mips_get_fp_context(task);
+
+	for_each_thread(task, t) {
+		if (relaxed)
+			set_thread_flag(TIF_IEEE754_RELAXED);
+		else
+			clear_thread_flag(TIF_IEEE754_RELAXED);
+		if (nan_2008) {
+			if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
+				t->thread.fpu.fcr31 |= FPU_CSR_NAN2008;
+			if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
+				t->thread.fpu.fcr31 |= FPU_CSR_ABS2008;
+		} else {
+			if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
+				t->thread.fpu.fcr31 &= ~FPU_CSR_NAN2008;
+			if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
+				t->thread.fpu.fcr31 &= ~FPU_CSR_ABS2008;
+		}
+	}
+
+	mips_put_fp_context(task);
+
+	return ELF_FLAGS >> AV_FLAGS_SYSTEM_SHIFT;
+}
Index: linux-sfr-test/include/uapi/linux/prctl.h
===================================================================
--- linux-sfr-test.orig/include/uapi/linux/prctl.h	2015-11-11 12:34:46.157647000 +0000
+++ linux-sfr-test/include/uapi/linux/prctl.h	2015-11-11 13:14:09.286746000 +0000
@@ -197,4 +197,16 @@ struct prctl_mm_map {
 # define PR_CAP_AMBIENT_LOWER		3
 # define PR_CAP_AMBIENT_CLEAR_ALL	4
 
+/*
+ * Control MIPS IEEE 754 compliance modes.
+ */
+#define PR_SET_IEEE754_MODE	48
+
+# define PR_IEEE754_MODE_LEGACY		0	/* Legacy mode.  */
+# define PR_IEEE754_MODE_STRICT		1	/* Strict mode.  */
+# define PR_IEEE754_MODE_RELAXED	2	/* Relaxed mode.  */
+
+# define PR_IEEE754_MODE_NAN_LEGACY	0	/* Set legacy NaN encoding.  */
+# define PR_IEEE754_MODE_NAN_2008	1	/* Set 2008 NaN encoding.  */
+
 #endif /* _LINUX_PRCTL_H */
Index: linux-sfr-test/kernel/sys.c
===================================================================
--- linux-sfr-test.orig/kernel/sys.c	2015-11-11 12:34:46.159650000 +0000
+++ linux-sfr-test/kernel/sys.c	2015-11-11 13:14:09.342744000 +0000
@@ -103,6 +103,9 @@
 #ifndef SET_FP_MODE
 # define SET_FP_MODE(a,b)	(-EINVAL)
 #endif
+#ifndef SET_IEEE754_MODE
+# define SET_IEEE754_MODE(a, b, c)	(-EINVAL)
+#endif
 
 /*
  * this is where the system-wide overflow UID and GID are defined, for
@@ -2266,6 +2269,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
 	case PR_GET_FP_MODE:
 		error = GET_FP_MODE(me);
 		break;
+	case PR_SET_IEEE754_MODE:
+		error = SET_IEEE754_MODE(me, arg2, arg3);
+		break;
 	default:
 		error = -EINVAL;
 		break;

      parent reply	other threads:[~2015-11-16 14:35 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-16 14:34 [RFC PATCH 0/4] MIPS: IEEE Std 754 NaN interlinking support Maciej W. Rozycki
2015-11-16 14:34 ` [RFC PATCH 1/4] ELF: Add platform-specific AT_FLAGS initialisation support Maciej W. Rozycki
2015-11-16 14:34 ` [RFC PATCH 2/4] MIPS: Factor out FP context preemption Maciej W. Rozycki
2015-11-16 14:35 ` [RFC PATCH 3/4] MIPS: Implement IEEE Std 754 NaN interlinking support Maciej W. Rozycki
2015-11-16 14:35 ` Maciej W. Rozycki [this message]

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=alpine.DEB.2.00.1511161413370.7097@tp.orcam.me.uk \
    --to=macro@imgtec.com \
    --cc=Daniel.Sanders@imgtec.com \
    --cc=Leonid.Yegoshin@imgtec.com \
    --cc=Matthew.Fortune@imgtec.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).