kernel: Move current_fp field out of z_kernel

The current_fp field in the z_kernel structure is only used
by 32-bit x86 (which does not support SMP). As such, it should
reside in the arch specific of section of _kernel.cpus[0].

This also changes the name of 'current_fp' to 'fpu_owner' to
be more consistent with other architectures.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
This commit is contained in:
Peter Mitsis 2025-03-07 11:54:06 -08:00 committed by Benjamin Cabé
commit c6bc09223e
9 changed files with 53 additions and 30 deletions

View file

@ -194,7 +194,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options)
* must be preserved).
*/
fp_owner = _kernel.current_fp;
fp_owner = _kernel.cpus[0].arch.fpu_owner;
if (fp_owner != NULL) {
if ((fp_owner->arch.flags & X86_THREAD_FLAG_ALL) != 0) {
FpCtxSave(fp_owner);
@ -215,7 +215,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options)
* (The FP context is "live" in hardware, not saved in TCS.)
*/
_kernel.current_fp = thread;
_kernel.cpus[0].arch.fpu_owner = thread;
} else {
/*
* When enabling FP support for someone else, assign ownership
@ -230,7 +230,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options)
* to its original state.
*/
_kernel.current_fp = thread;
_kernel.cpus[0].arch.fpu_owner = thread;
z_FpAccessDisable();
} else {
/*
@ -280,10 +280,10 @@ int z_float_disable(struct k_thread *thread)
if (thread == _current) {
z_FpAccessDisable();
_kernel.current_fp = (struct k_thread *)0;
_kernel.cpus[0].arch.fpu_owner = (struct k_thread *)0;
} else {
if (_kernel.current_fp == thread) {
_kernel.current_fp = (struct k_thread *)0;
if (_kernel.cpus[0].arch.fpu_owner == thread) {
_kernel.cpus[0].arch.fpu_owner = (struct k_thread *)0;
}
}

View file

@ -50,7 +50,7 @@
* Floating point registers are handled using a lazy save/restore mechanism
* since it's expected relatively few threads will be created with the
* K_FP_REGS or K_SSE_REGS option bits. The kernel data structure maintains a
* 'current_fp' field to keep track of the thread that "owns" the floating
* 'fpu_owner' field to keep track of the thread that "owns" the floating
* point registers. Floating point registers consist of ST0->ST7 (x87 FPU and
* MMX registers) and XMM0 -> XMM7.
*
@ -176,7 +176,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap)
* If so, there there is no need to restore the floating point context.
*/
movl _kernel_offset_to_current_fp(%edi), %ebx
movl _kernel_offset_to_fpu_owner(%edi), %ebx
cmpl %ebx, %eax
je restoreContext_NoFloatSwap
@ -265,7 +265,7 @@ restoreContext_NoFloatRestore:
/* record that the incoming thread "owns" the floating point registers */
movl %eax, _kernel_offset_to_current_fp(%edi)
movl %eax, _kernel_offset_to_fpu_owner(%edi)
/*

View file

@ -33,6 +33,12 @@
GEN_OFFSET_SYM(_thread_arch_t, excNestCount);
#endif
#if defined(CONFIG_FPU_SHARING)
GEN_OFFSET_SYM(_kernel_t, cpus);
GEN_OFFSET_SYM(_cpu_t, arch);
GEN_OFFSET_SYM(_cpu_arch_t, fpu_owner);
#endif
#ifdef CONFIG_USERSPACE
GEN_OFFSET_SYM(_thread_arch_t, psp);
#ifndef CONFIG_X86_COMMON_PAGE_TABLE

View file

@ -14,6 +14,9 @@
#define _kernel_offset_to_isf \
(___kernel_t_arch_OFFSET + ___kernel_arch_t_isf_OFFSET)
#define _kernel_offset_to_fpu_owner \
(___kernel_t_cpus_OFFSET + ___cpu_t_arch_OFFSET + ___cpu_arch_t_fpu_owner_OFFSET)
/* end - kernel */
/* threads */

View file

@ -29,6 +29,8 @@
#include <zephyr/arch/riscv/structs.h>
#elif defined(CONFIG_ARM)
#include <zephyr/arch/arm/structs.h>
#elif defined(CONFIG_X86) && !defined(CONFIG_X86_64)
#include <zephyr/arch/x86/ia32/structs.h>
#else
/* Default definitions when no architecture specific definitions exist. */

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2025 Intel
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_X86_STRUCTS_H_
#define ZEPHYR_INCLUDE_X86_STRUCTS_H_
#include <stdint.h>
struct k_thread;
/* Per CPU architecture specifics (empty) */
struct _cpu_arch {
#if defined(CONFIG_FPU_SHARING)
/*
* A 'sse_owner' field does not exist in addition to the 'fpu_owner'
* field since it's not possible to divide the IA-32 non-integer
* registers into 2 distinct blocks owned by differing threads. In
* other words, given that the 'fxnsave/fxrstor' instructions
* save/restore both the X87 FPU and XMM registers, it's not possible
* for a thread to only "own" the XMM registers.
*/
struct k_thread *fpu_owner;
#elif defined(__cplusplus)
/* Ensure this struct does not have a size of 0 which is not allowed in C++. */
uint8_t dummy;
#endif
};
#endif /* ZEPHYR_INCLUDE_X86_STRUCTS_H_ */

View file

@ -217,20 +217,6 @@ struct z_kernel {
struct _ready_q ready_q;
#endif
#ifdef CONFIG_FPU_SHARING
/*
* A 'current_sse' field does not exist in addition to the 'current_fp'
* field since it's not possible to divide the IA-32 non-integer
* registers into 2 distinct blocks owned by differing threads. In
* other words, given that the 'fxnsave/fxrstor' instructions
* save/restore both the X87 FPU and XMM registers, it's not possible
* for a thread to only "own" the XMM registers.
*/
/* thread that owns the FP regs */
struct k_thread *current_fp;
#endif
#if defined(CONFIG_THREAD_MONITOR)
struct k_thread *threads; /* singly linked list of ALL threads */
#endif

View file

@ -48,10 +48,6 @@ GEN_OFFSET_SYM(_kernel_t, ready_q);
GEN_OFFSET_SYM(_ready_q_t, cache);
#endif /* CONFIG_SMP */
#ifdef CONFIG_FPU_SHARING
GEN_OFFSET_SYM(_kernel_t, current_fp);
#endif /* CONFIG_FPU_SHARING */
GEN_OFFSET_SYM(_thread_base_t, user_options);
GEN_OFFSET_SYM(_thread_t, base);

View file

@ -34,9 +34,6 @@
#define _kernel_offset_to_idle \
(___kernel_t_idle_OFFSET)
#define _kernel_offset_to_current_fp \
(___kernel_t_current_fp_OFFSET)
#define _kernel_offset_to_ready_q_cache \
(___kernel_t_ready_q_OFFSET + ___ready_q_t_cache_OFFSET)