Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144592973
D42822.id131503.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D42822.id131503.diff
View Options
diff --git a/sys/compat/linuxkpi/common/include/linux/compat.h b/sys/compat/linuxkpi/common/include/linux/compat.h
--- a/sys/compat/linuxkpi/common/include/linux/compat.h
+++ b/sys/compat/linuxkpi/common/include/linux/compat.h
@@ -33,6 +33,10 @@
#include <sys/proc.h>
#include <sys/malloc.h>
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+#define LKPI_HAVE_FPU_CTX
+#endif
+
struct domainset;
struct thread;
struct task_struct;
@@ -40,6 +44,7 @@
extern int linux_alloc_current(struct thread *, int flags);
extern void linux_free_current(struct task_struct *);
extern struct domainset *linux_get_vm_domain_set(int node);
+extern int linux_set_fpu_ctx(struct task_struct *);
static inline void
linux_set_current(struct thread *td)
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -64,6 +64,7 @@
#define TASK_COMM_LEN (MAXCOMLEN + 1)
struct seq_file;
+struct fpu_kern_ctx;
struct work_struct;
struct task_struct {
@@ -89,6 +90,7 @@
struct task_struct *group_leader;
unsigned rcu_section[TS_RCU_TYPE_MAX];
unsigned int fpu_ctx_level;
+ struct fpu_kern_ctx *fpu_ctx;
};
#define current ({ \
diff --git a/sys/compat/linuxkpi/common/src/linux_current.c b/sys/compat/linuxkpi/common/src/linux_current.c
--- a/sys/compat/linuxkpi/common/src/linux_current.c
+++ b/sys/compat/linuxkpi/common/src/linux_current.c
@@ -43,6 +43,10 @@
#include <sys/sysctl.h>
#include <vm/uma.h>
+#ifdef LKPI_HAVE_FPU_CTX
+#include <machine/fpu.h>
+#endif
+
#ifdef DEV_APIC
extern u_int first_msi_irq, num_msi_irqs;
#endif
@@ -153,6 +157,21 @@
return (0);
}
+int linux_set_fpu_ctx(struct task_struct *task)
+{
+#ifdef LKPI_HAVE_FPU_CTX
+ uint flags = 0;
+
+ if (task->fpu_ctx == NULL) {
+ if ((curthread->td_pflags & TDP_ITHREAD) != 0 ||
+ !THREAD_CAN_SLEEP())
+ flags |= FPU_KERN_NOWAIT;
+ task->fpu_ctx = fpu_kern_alloc_ctx(flags);
+ }
+#endif
+ return (task->fpu_ctx != NULL ? 0 : ENOMEM);
+}
+
struct mm_struct *
linux_get_task_mm(struct task_struct *task)
{
@@ -176,6 +195,10 @@
linux_free_current(struct task_struct *ts)
{
mmput(ts->mm);
+#ifdef LKPI_HAVE_FPU_CTX
+ if (ts->fpu_ctx != NULL)
+ fpu_kern_free_ctx(ts->fpu_ctx);
+#endif
uma_zfree(linux_current_zone, ts);
}
diff --git a/sys/compat/linuxkpi/common/src/linux_fpu.c b/sys/compat/linuxkpi/common/src/linux_fpu.c
--- a/sys/compat/linuxkpi/common/src/linux_fpu.c
+++ b/sys/compat/linuxkpi/common/src/linux_fpu.c
@@ -30,11 +30,12 @@
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <linux/compat.h>
#include <linux/sched.h>
#include <asm/fpu/api.h>
-#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+#ifdef LKPI_HAVE_FPU_CTX
#include <machine/fpu.h>
@@ -47,15 +48,20 @@
void
lkpi_kernel_fpu_begin(void)
{
- if ((current->fpu_ctx_level)++ == 0)
- fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+ int err;
+
+ if ((current->fpu_ctx_level)++ == 0) {
+ err = linux_set_fpu_ctx(current);
+ fpu_kern_enter(curthread, current->fpu_ctx,
+ err == 0 ? FPU_KERN_KTHR : FPU_KERN_NOCTX);
+ }
}
void
lkpi_kernel_fpu_end(void)
{
if (--(current->fpu_ctx_level) == 0)
- fpu_kern_leave(curthread, NULL);
+ fpu_kern_leave(curthread, current->fpu_ctx);
}
#else
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 11, 12:37 AM (18 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28634500
Default Alt Text
D42822.id131503.diff (3 KB)
Attached To
Mode
D42822: LinuxKPI: Add explicit software context to FPU sections
Attached
Detach File
Event Timeline
Log In to Comment