2015-04-10 16:44:37 -07:00
|
|
|
/*
|
2015-08-20 11:04:01 -04:00
|
|
|
* Copyright (c) 2011-2015 Wind River Systems, Inc.
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2017-01-18 17:01:01 -08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
|
2015-12-04 10:09:39 -05:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
* @brief Exception management support for IA-32 architecture
|
|
|
|
|
*
|
|
|
|
|
* This module implements assembly routines to manage exceptions (synchronous
|
|
|
|
|
* interrupts) on the Intel IA-32 architecture. More specifically,
|
|
|
|
|
* exceptions are implemented in this module. The stubs are invoked when entering
|
|
|
|
|
* and exiting a C exception handler.
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2022-05-09 13:56:13 +02:00
|
|
|
#include <zephyr/arch/x86/ia32/asm.h>
|
|
|
|
|
#include <zephyr/arch/x86/ia32/arch.h> /* For MK_ISR_NAME */
|
2016-11-08 10:36:50 -05:00
|
|
|
#include <offsets_short.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* exports (internal APIs) */
|
|
|
|
|
|
2016-09-26 14:34:33 -07:00
|
|
|
GTEXT(_exception_enter)
|
2017-04-18 15:22:54 -07:00
|
|
|
GTEXT(_kernel_oops_handler)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
/* externs (internal APIs) */
|
2019-12-18 14:12:54 -08:00
|
|
|
GTEXT(z_x86_do_kernel_oops)
|
2017-04-18 15:22:54 -07:00
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
|
|
|
|
*
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Inform the kernel of an exception
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
|
* This function is called from the exception stub created by nanoCpuExcConnect()
|
|
|
|
|
* to inform the kernel of an exception. This routine currently does
|
2015-08-20 11:04:01 -04:00
|
|
|
* _not_ increment a thread/interrupt specific exception count. Also,
|
2015-07-01 17:22:39 -04:00
|
|
|
* execution of the exception handler occurs on the current stack, i.e.
|
2016-09-26 14:34:33 -07:00
|
|
|
* this does not switch to another stack. The volatile integer
|
2015-07-01 17:22:39 -04:00
|
|
|
* registers are saved on the stack, and control is returned back to the
|
|
|
|
|
* exception stub.
|
|
|
|
|
*
|
|
|
|
|
* WARNINGS
|
|
|
|
|
*
|
|
|
|
|
* Host-based tools and the target-based GDB agent depend on the stack frame
|
|
|
|
|
* created by this routine to determine the locations of volatile registers.
|
|
|
|
|
* These tools must be updated to reflect any changes to the stack frame.
|
|
|
|
|
*
|
|
|
|
|
* C function prototype:
|
|
|
|
|
*
|
2020-05-27 11:26:57 -05:00
|
|
|
* void _exception_enter(uint32_t error_code, void *handler)
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
kernel: mmu: remove LINKER_USE_PINNED_SECTION and __pinned_* tagging
CONFIG_LINKER_USE_PINNED_SECTION is the second half of the selective
kernel-pinning model removed in issue #108773. With the kernel image
now always resident at boot (previous commit), the __pinned_*
attribute family is a no-op: every page they would have segregated is
already pinned by z_mem_manage_init()'s whole-image loop, so the
tagging contract neither adds safety nor remains maintainable.
Drop it.
Mechanical removals:
* All ~219 in-tree uses of __pinned_text, __pinned_rodata,
__pinned_data, __pinned_bss, __pinned_noinit, and __pinned_func
across arch/x86, drivers/interrupt_controller, drivers/timer,
arch/common, kernel, lib/libc, subsys/portability/posix, tests, and
the syscall code generator (scripts/build/gen_syscalls.py).
* The assembly aliases PINNED_TEXT/RODATA/DATA/BSS/NOINIT used in
arch/x86/core/ia32/*.S and drivers/interrupt_controller/
intc_loapic_spurious.S become plain TEXT/RODATA/DATA/BSS/NOINIT.
* K_KERNEL_PINNED_STACK_DEFINE, K_KERNEL_PINNED_STACK_ARRAY_DEFINE,
K_KERNEL_PINNED_STACK_ARRAY_DECLARE, K_THREAD_PINNED_STACK_DEFINE,
and K_THREAD_PINNED_STACK_ARRAY_DEFINE are removed. The few
in-tree callers (kernel/init.c, arch/arm/core/cortex_a_r/smp.c,
arch/arm64/core/fatal.c, arch/rx/core/prep_c.c,
arch/x86/core/prep_c.c, kernel/include/kernel_internal.h,
tests/bluetooth/hci_uart_async) move to the corresponding
non-pinned macros.
Machinery removals:
* Kconfig.zephyr drops CONFIG_LINKER_USE_PINNED_SECTION.
qemu_x86_tiny and qemu_x86_atom_virt drop their =y overrides.
* include/zephyr/linker/section_tags.h drops the __pinned_* macro
definitions (both arms). __isr collapses to an empty macro since
its only purpose was to alias __pinned_func.
* include/zephyr/linker/sections.h drops PINNED_TEXT_SECTION_NAME,
PINNED_BSS_SECTION_NAME, etc. and the bare PINNED_TEXT/RODATA/etc.
forwarders, plus the _APP_SMEM_PINNED_SECTION_NAME constant.
* include/zephyr/linker/linker-defs.h drops the lnkr_pinned_*
externs, the _app_smem_pinned_* externs, and the lnkr_is_pinned()
/ lnkr_is_region_pinned() inline helpers.
* include/zephyr/linker/utils.h drops the lnkr_pinned_rodata branch
in linker_is_in_rodata().
* include/zephyr/linker/app_smem_pinned{,_aligned,_unaligned}.ld
are deleted; cmake/linker/ld/target_configure.cmake stops
configuring them.
* boards/qemu/x86/qemu_x86_tiny.ld and
include/zephyr/arch/x86/ia32/linker.ld drop their pinned-section
blocks and the now-redundant #ifndef CONFIG_LINKER_USE_PINNED_SECTION
conditionals throughout the body. The
LIB_KERNEL_IN_SECT / LIB_ARCH_X86_IN_SECT / LIB_ZEPHYR_IN_SECT /
LIB_C_IN_SECT / LIB_DRIVERS_IN_SECT / LIB_SUBSYS_LOGGING_IN_SECT /
LIB_ZEPHYR_OBJECT_FILE_IN_SECT / ZEPHYR_KERNEL_FUNCS_IN_SECT macros
in qemu_x86_tiny.ld are deleted; they existed only to feed the
pinned text/rodata/data/bss/noinit sections.
* kernel/mmu.c drops the mark_linker_section_pinned(lnkr_pinned_start,
...) call. The mark_linker_section_pinned() helper survives but is
now gated only on CONFIG_LINKER_USE_BOOT_SECTION.
* arch/common/init.c and include/zephyr/arch/common/init.h drop
arch_bss_zero_pinned(); arch/x86/core/ia32/crt0.S drops the call
to it.
* arch/x86/core/userspace.c drops the eager k_mem_page_in() of the
thread's privileged stack on user-mode entry. With the kernel
image fully resident the stack is already mapped.
* arch/x86/gen_mmu.py drops map_region("lnkr_pinned") and the
set_region_perms() calls for lnkr_pinned_text / lnkr_pinned_rodata.
* CMakeLists.txt drops the LINKER_USE_PINNED_SECTION block that
generated APP_SMEM_PINNED_* variables and the
pinned_partitions target property feeding gen_app_partitions.py.
cmake/modules/extensions.cmake removes the PINNED_RODATA /
PINNED_RAM_SECTIONS / PINNED_DATA_SECTIONS zephyr_linker_sources()
location keywords and their snippet files.
scripts/build/gen_app_partitions.py drops --pinoutput /
--pinpartitions arguments and the pinned-output branch.
subsys/testsuite/coverage/CMakeLists.txt drops its
CONFIG_DEMAND_PAGING-conditional fork.
* scripts/build/gen_kobject_list.py drops the
app_smem_pinned_start / _end fallback for kobject placement
validation.
* tests/arch/x86/pagetables and tests/kernel/mem_protect/userspace
drop their lnkr_pinned_text / lnkr_pinned_rodata branches.
* include/zephyr/arch/x86/ia32/arch.h folds IRQSTUBS_TEXT_SECTION
to the unconditional ".text.irqstubs" form.
* tests/subsys/llext/src/syscalls_ext.c drops a stale comment about
syscalls landing in .pinned_text.
Targeted retentions:
* arch/x86/core/bootargs.c keeps multiboot_cmdline and efi_bootargs
in .noinit (was __pinned_noinit, which decayed to __noinit when
LINKER_USE_PINNED_SECTION was unset). The multiboot and zefi loader
paths write these buffers before Zephyr's BSS-zero step, so
zeroing them at boot loses the cmdline.
* arch/x86/core/ia32/fatal.c keeps _df_esf and _df_stack in .noinit.
They are scratch space written by the double-fault handler and have
no zero-init requirement; keeping them in .noinit also preserves
the historical post-noinit alignment that gen_mmu.py relies on
(z_mapped_size is computed before CMake-injected iterable sections
are appended to the linker script, so the post-noinit page padding
is what keeps those sections within the mapped region).
* include/zephyr/arch/x86/ia32/syscall.h and
include/zephyr/arch/x86/arch.h wrap the per-arch
arch_syscall_invoke* / arch_is_user_context / arch_k_cycle_get_*
implementations in @cond INTERNAL_HIDDEN. The public Doxygen
contract lives on the prototypes in
include/zephyr/arch/arch_interface.h; the per-arch implementations
are internal. Without this, removing the __pinned_func attribute
exposes the implementations to the doxygen-coverage delta check
as 10 newly-undocumented APIs.
Documentation updates are deferred to a separate commit.
Issue: #108773
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-05-15 16:33:20 -04:00
|
|
|
SECTION_FUNC(TEXT, _exception_enter)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
/*
|
2016-08-01 15:59:10 -07:00
|
|
|
* The gen_idt tool creates an interrupt-gate descriptor for
|
2015-04-10 16:44:37 -07:00
|
|
|
* all connections. The processor will automatically clear the IF
|
|
|
|
|
* bit in the EFLAGS register upon execution of the handler, thus
|
2016-09-26 14:34:33 -07:00
|
|
|
* this does need not issue an 'cli' as the first instruction.
|
|
|
|
|
*
|
2015-04-10 16:44:37 -07:00
|
|
|
* Note that the processor has pushed both the EFLAGS register
|
|
|
|
|
* and the linear return address (cs:eip) onto the stack prior
|
|
|
|
|
* to invoking the handler specified in the IDT.
|
|
|
|
|
*
|
|
|
|
|
* Clear the direction flag. It is automatically restored when the
|
|
|
|
|
* exception exits.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
cld
|
|
|
|
|
|
2019-02-06 15:35:24 -08:00
|
|
|
#ifdef CONFIG_X86_KPTI
|
|
|
|
|
call z_x86_trampoline_to_kernel
|
|
|
|
|
#endif
|
2015-04-10 16:44:37 -07:00
|
|
|
/*
|
2016-09-26 14:34:33 -07:00
|
|
|
* Swap ecx and handler function on the current stack;
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
2016-01-14 16:22:28 -08:00
|
|
|
xchgl %ecx, (%esp)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
x86: remove dynamically generated IRQ and exception code
We are interested in supporting some XIP x86 platforms which are
unable to fetch CPU instructions from system RAM. This requires
refactoring our dynamic IRQ/exc code which currently synthesizes
assembly language instructions to create IRQ stubs on-the-fly.
Instead, a new approach is taken. Given that the configuration at
build time specifies the number of required stubs, use this
to generate a build time a set of tiny stub functions which simply
push a 'stub id' and then call common dynamic interrupt code.
The handler function and handler argument is saved in a table keyed by
this stub id.
CONFIG_EOI_HANDLER_SUPPORTED removed, the code hasn't been conditionally
compiled for some time and in all cases we call _loapic_eoi() when
finished with an interrupt.
Some other out-of-date verbiage in comments related to supporting
non-APIC removed.
Previously, when dynamic exceptions were created a pointer would
be passed in by the caller reserving ram for the stub code. Since
this is no longer feasible, two new Kconfig options have been added.
CONFIG_NUM_DYNAMIC_EXC_STUBS and CONFIG_NUM_DYNAMIC_EXC_NO_ERR_STUBS
control how many stubs are created for exceptions that push
an error code, and no error code, respectively.
SW Interrupts are no longer triggered by "int <vector>" hard-coded
assembly instructions. Instead this is done by sending a self-directed
inter-processor interrupt from the LOAPIC, using a new API
loapic_int_vect_trigger(). In this way we get rid of dynamically
generated code in irq_test_common.h.
All interrupts call _loapic_eoi() when finished, since this is now
the right thing to do for all IRQs, including SW interrupts.
_irq_handler_set() for x86 no longer requires the old function pointer
to be supplied.
Change-Id: I78993d3d00dd153c9051c518b417cce8d3acee9e
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2015-10-19 14:10:53 -07:00
|
|
|
/* By the time we get here, the stack should look like this:
|
2016-01-14 16:22:28 -08:00
|
|
|
* ESP -> ECX (excepting task)
|
|
|
|
|
* Exception Error code (or junk)
|
x86: remove dynamically generated IRQ and exception code
We are interested in supporting some XIP x86 platforms which are
unable to fetch CPU instructions from system RAM. This requires
refactoring our dynamic IRQ/exc code which currently synthesizes
assembly language instructions to create IRQ stubs on-the-fly.
Instead, a new approach is taken. Given that the configuration at
build time specifies the number of required stubs, use this
to generate a build time a set of tiny stub functions which simply
push a 'stub id' and then call common dynamic interrupt code.
The handler function and handler argument is saved in a table keyed by
this stub id.
CONFIG_EOI_HANDLER_SUPPORTED removed, the code hasn't been conditionally
compiled for some time and in all cases we call _loapic_eoi() when
finished with an interrupt.
Some other out-of-date verbiage in comments related to supporting
non-APIC removed.
Previously, when dynamic exceptions were created a pointer would
be passed in by the caller reserving ram for the stub code. Since
this is no longer feasible, two new Kconfig options have been added.
CONFIG_NUM_DYNAMIC_EXC_STUBS and CONFIG_NUM_DYNAMIC_EXC_NO_ERR_STUBS
control how many stubs are created for exceptions that push
an error code, and no error code, respectively.
SW Interrupts are no longer triggered by "int <vector>" hard-coded
assembly instructions. Instead this is done by sending a self-directed
inter-processor interrupt from the LOAPIC, using a new API
loapic_int_vect_trigger(). In this way we get rid of dynamically
generated code in irq_test_common.h.
All interrupts call _loapic_eoi() when finished, since this is now
the right thing to do for all IRQs, including SW interrupts.
_irq_handler_set() for x86 no longer requires the old function pointer
to be supplied.
Change-Id: I78993d3d00dd153c9051c518b417cce8d3acee9e
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2015-10-19 14:10:53 -07:00
|
|
|
* EIP (excepting task)
|
|
|
|
|
* CS (excepting task)
|
|
|
|
|
* EFLAGS (excepting task)
|
|
|
|
|
* ...
|
|
|
|
|
*
|
2016-09-26 14:34:33 -07:00
|
|
|
* ECX now contains the address of the handler function */
|
x86: remove dynamically generated IRQ and exception code
We are interested in supporting some XIP x86 platforms which are
unable to fetch CPU instructions from system RAM. This requires
refactoring our dynamic IRQ/exc code which currently synthesizes
assembly language instructions to create IRQ stubs on-the-fly.
Instead, a new approach is taken. Given that the configuration at
build time specifies the number of required stubs, use this
to generate a build time a set of tiny stub functions which simply
push a 'stub id' and then call common dynamic interrupt code.
The handler function and handler argument is saved in a table keyed by
this stub id.
CONFIG_EOI_HANDLER_SUPPORTED removed, the code hasn't been conditionally
compiled for some time and in all cases we call _loapic_eoi() when
finished with an interrupt.
Some other out-of-date verbiage in comments related to supporting
non-APIC removed.
Previously, when dynamic exceptions were created a pointer would
be passed in by the caller reserving ram for the stub code. Since
this is no longer feasible, two new Kconfig options have been added.
CONFIG_NUM_DYNAMIC_EXC_STUBS and CONFIG_NUM_DYNAMIC_EXC_NO_ERR_STUBS
control how many stubs are created for exceptions that push
an error code, and no error code, respectively.
SW Interrupts are no longer triggered by "int <vector>" hard-coded
assembly instructions. Instead this is done by sending a self-directed
inter-processor interrupt from the LOAPIC, using a new API
loapic_int_vect_trigger(). In this way we get rid of dynamically
generated code in irq_test_common.h.
All interrupts call _loapic_eoi() when finished, since this is now
the right thing to do for all IRQs, including SW interrupts.
_irq_handler_set() for x86 no longer requires the old function pointer
to be supplied.
Change-Id: I78993d3d00dd153c9051c518b417cce8d3acee9e
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2015-10-19 14:10:53 -07:00
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
|
* Push the remaining volatile registers on the existing stack.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-01-14 16:22:28 -08:00
|
|
|
pushl %eax
|
2015-04-10 16:44:37 -07:00
|
|
|
pushl %edx
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Push the cooperative registers on the existing stack as they are
|
|
|
|
|
* required by debug tools.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
pushl %edi
|
|
|
|
|
pushl %esi
|
|
|
|
|
pushl %ebx
|
|
|
|
|
pushl %ebp
|
|
|
|
|
|
2019-02-14 13:43:47 -08:00
|
|
|
#ifdef CONFIG_USERSPACE
|
|
|
|
|
/* Test if interrupted context was in ring 3 */
|
|
|
|
|
testb $3, 36(%esp)
|
|
|
|
|
jz 1f
|
|
|
|
|
/* It was. The original stack pointer is on the stack 44 bytes
|
|
|
|
|
* from the current top
|
|
|
|
|
*/
|
|
|
|
|
pushl 44(%esp)
|
|
|
|
|
jmp 2f
|
|
|
|
|
1:
|
|
|
|
|
#endif
|
2016-01-14 16:22:28 -08:00
|
|
|
leal 44(%esp), %eax /* Calculate ESP before interrupt occurred */
|
|
|
|
|
pushl %eax /* Save calculated ESP */
|
2019-02-14 13:43:47 -08:00
|
|
|
#ifdef CONFIG_USERSPACE
|
|
|
|
|
2:
|
2020-05-21 16:55:28 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_GDBSTUB
|
|
|
|
|
pushl %ds
|
|
|
|
|
pushl %es
|
|
|
|
|
pushl %fs
|
|
|
|
|
pushl %gs
|
|
|
|
|
pushl %ss
|
2019-02-14 13:43:47 -08:00
|
|
|
#endif
|
2015-04-10 16:44:37 -07:00
|
|
|
/* ESP is pointing to the ESF at this point */
|
|
|
|
|
|
2020-05-03 18:18:37 +09:00
|
|
|
#if defined(CONFIG_LAZY_FPU_SHARING)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-11-08 10:36:50 -05:00
|
|
|
movl _kernel + _kernel_offset_to_current, %edx
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-11-08 10:36:50 -05:00
|
|
|
/* inc exception nest count */
|
|
|
|
|
incl _thread_offset_to_excNestCount(%edx)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
/*
|
2019-09-18 19:30:39 -04:00
|
|
|
* Set X86_THREAD_FLAG_EXC in the current thread. This enables
|
|
|
|
|
* z_swap() to preserve the thread's FP registers (where needed)
|
|
|
|
|
* if the exception handler causes a context switch. It also
|
|
|
|
|
* indicates to debug tools that an exception is being handled
|
|
|
|
|
* in the event of a context switch.
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
|
2019-09-18 19:30:39 -04:00
|
|
|
orb $X86_THREAD_FLAG_EXC, _thread_offset_to_flags(%edx)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2020-05-03 18:18:37 +09:00
|
|
|
#endif /* CONFIG_LAZY_FPU_SHARING */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
/*
|
2016-09-26 14:34:33 -07:00
|
|
|
* restore interrupt enable state, then call the handler
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
|
|
|
|
* interrupts are enabled only if they were allowed at the time
|
|
|
|
|
* the exception was triggered -- this protects kernel level code
|
|
|
|
|
* that mustn't be interrupted
|
|
|
|
|
*
|
|
|
|
|
* Test IF bit of saved EFLAGS and re-enable interrupts if IF=1.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* ESP is still pointing to the ESF at this point */
|
|
|
|
|
|
2024-06-03 18:02:05 +08:00
|
|
|
testl $0x200, __struct_arch_esf_eflags_OFFSET(%esp)
|
2015-04-10 16:44:37 -07:00
|
|
|
je allDone
|
|
|
|
|
sti
|
|
|
|
|
|
2016-08-18 09:25:00 -07:00
|
|
|
allDone:
|
2024-06-03 18:02:05 +08:00
|
|
|
pushl %esp /* push struct_arch_esf * parameter */
|
2019-12-18 15:11:59 -08:00
|
|
|
call *%ecx /* call exception handler */
|
2016-09-26 14:34:33 -07:00
|
|
|
addl $0x4, %esp
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2020-05-03 18:18:37 +09:00
|
|
|
#if defined(CONFIG_LAZY_FPU_SHARING)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-11-08 10:36:50 -05:00
|
|
|
movl _kernel + _kernel_offset_to_current, %ecx
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Must lock interrupts to prevent outside interference.
|
|
|
|
|
* (Using "lock" prefix would be nicer, but this won't work
|
2015-07-27 12:19:36 -04:00
|
|
|
* on platforms that don't respect the CPU's bus lock signal.)
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
cli
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Determine whether exiting from a nested interrupt.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-11-08 10:36:50 -05:00
|
|
|
decl _thread_offset_to_excNestCount(%ecx)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-11-08 10:36:50 -05:00
|
|
|
cmpl $0, _thread_offset_to_excNestCount(%ecx)
|
2015-04-10 16:44:37 -07:00
|
|
|
jne nestedException
|
|
|
|
|
|
|
|
|
|
/*
|
2019-09-18 19:30:39 -04:00
|
|
|
* Clear X86_THREAD_FLAG_EXC in the k_thread of the current execution
|
2016-11-08 10:36:50 -05:00
|
|
|
* context if we are not in a nested exception (ie, when we exit the
|
|
|
|
|
* outermost exception).
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
|
2019-09-18 19:30:39 -04:00
|
|
|
andb $~X86_THREAD_FLAG_EXC, _thread_offset_to_flags(%ecx)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-08-18 09:25:00 -07:00
|
|
|
nestedException:
|
2020-05-03 18:18:37 +09:00
|
|
|
#endif /* CONFIG_LAZY_FPU_SHARING */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2020-05-21 16:55:28 -07:00
|
|
|
#ifdef CONFIG_GDBSTUB
|
|
|
|
|
popl %ss
|
|
|
|
|
popl %gs
|
|
|
|
|
popl %fs
|
|
|
|
|
popl %es
|
|
|
|
|
popl %ds
|
|
|
|
|
#endif
|
2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
|
* Pop the non-volatile registers from the stack.
|
|
|
|
|
* Note that debug tools may have altered the saved register values while
|
|
|
|
|
* the task was stopped, and we want to pick up the altered values.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-10-05 10:48:46 -04:00
|
|
|
popl %ebp /* Discard saved ESP */
|
2015-04-10 16:44:37 -07:00
|
|
|
popl %ebp
|
|
|
|
|
popl %ebx
|
|
|
|
|
popl %esi
|
|
|
|
|
popl %edi
|
|
|
|
|
|
|
|
|
|
/* restore edx and ecx which are always saved on the stack */
|
|
|
|
|
|
|
|
|
|
popl %edx
|
|
|
|
|
popl %eax
|
2016-01-14 16:22:28 -08:00
|
|
|
popl %ecx
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
addl $4, %esp /* "pop" error code */
|
|
|
|
|
|
|
|
|
|
/* Pop of EFLAGS will re-enable interrupts and restore direction flag */
|
2019-02-06 15:35:24 -08:00
|
|
|
KPTI_IRET
|
2015-04-10 16:44:37 -07:00
|
|
|
|
kernel: mmu: remove LINKER_USE_PINNED_SECTION and __pinned_* tagging
CONFIG_LINKER_USE_PINNED_SECTION is the second half of the selective
kernel-pinning model removed in issue #108773. With the kernel image
now always resident at boot (previous commit), the __pinned_*
attribute family is a no-op: every page they would have segregated is
already pinned by z_mem_manage_init()'s whole-image loop, so the
tagging contract neither adds safety nor remains maintainable.
Drop it.
Mechanical removals:
* All ~219 in-tree uses of __pinned_text, __pinned_rodata,
__pinned_data, __pinned_bss, __pinned_noinit, and __pinned_func
across arch/x86, drivers/interrupt_controller, drivers/timer,
arch/common, kernel, lib/libc, subsys/portability/posix, tests, and
the syscall code generator (scripts/build/gen_syscalls.py).
* The assembly aliases PINNED_TEXT/RODATA/DATA/BSS/NOINIT used in
arch/x86/core/ia32/*.S and drivers/interrupt_controller/
intc_loapic_spurious.S become plain TEXT/RODATA/DATA/BSS/NOINIT.
* K_KERNEL_PINNED_STACK_DEFINE, K_KERNEL_PINNED_STACK_ARRAY_DEFINE,
K_KERNEL_PINNED_STACK_ARRAY_DECLARE, K_THREAD_PINNED_STACK_DEFINE,
and K_THREAD_PINNED_STACK_ARRAY_DEFINE are removed. The few
in-tree callers (kernel/init.c, arch/arm/core/cortex_a_r/smp.c,
arch/arm64/core/fatal.c, arch/rx/core/prep_c.c,
arch/x86/core/prep_c.c, kernel/include/kernel_internal.h,
tests/bluetooth/hci_uart_async) move to the corresponding
non-pinned macros.
Machinery removals:
* Kconfig.zephyr drops CONFIG_LINKER_USE_PINNED_SECTION.
qemu_x86_tiny and qemu_x86_atom_virt drop their =y overrides.
* include/zephyr/linker/section_tags.h drops the __pinned_* macro
definitions (both arms). __isr collapses to an empty macro since
its only purpose was to alias __pinned_func.
* include/zephyr/linker/sections.h drops PINNED_TEXT_SECTION_NAME,
PINNED_BSS_SECTION_NAME, etc. and the bare PINNED_TEXT/RODATA/etc.
forwarders, plus the _APP_SMEM_PINNED_SECTION_NAME constant.
* include/zephyr/linker/linker-defs.h drops the lnkr_pinned_*
externs, the _app_smem_pinned_* externs, and the lnkr_is_pinned()
/ lnkr_is_region_pinned() inline helpers.
* include/zephyr/linker/utils.h drops the lnkr_pinned_rodata branch
in linker_is_in_rodata().
* include/zephyr/linker/app_smem_pinned{,_aligned,_unaligned}.ld
are deleted; cmake/linker/ld/target_configure.cmake stops
configuring them.
* boards/qemu/x86/qemu_x86_tiny.ld and
include/zephyr/arch/x86/ia32/linker.ld drop their pinned-section
blocks and the now-redundant #ifndef CONFIG_LINKER_USE_PINNED_SECTION
conditionals throughout the body. The
LIB_KERNEL_IN_SECT / LIB_ARCH_X86_IN_SECT / LIB_ZEPHYR_IN_SECT /
LIB_C_IN_SECT / LIB_DRIVERS_IN_SECT / LIB_SUBSYS_LOGGING_IN_SECT /
LIB_ZEPHYR_OBJECT_FILE_IN_SECT / ZEPHYR_KERNEL_FUNCS_IN_SECT macros
in qemu_x86_tiny.ld are deleted; they existed only to feed the
pinned text/rodata/data/bss/noinit sections.
* kernel/mmu.c drops the mark_linker_section_pinned(lnkr_pinned_start,
...) call. The mark_linker_section_pinned() helper survives but is
now gated only on CONFIG_LINKER_USE_BOOT_SECTION.
* arch/common/init.c and include/zephyr/arch/common/init.h drop
arch_bss_zero_pinned(); arch/x86/core/ia32/crt0.S drops the call
to it.
* arch/x86/core/userspace.c drops the eager k_mem_page_in() of the
thread's privileged stack on user-mode entry. With the kernel
image fully resident the stack is already mapped.
* arch/x86/gen_mmu.py drops map_region("lnkr_pinned") and the
set_region_perms() calls for lnkr_pinned_text / lnkr_pinned_rodata.
* CMakeLists.txt drops the LINKER_USE_PINNED_SECTION block that
generated APP_SMEM_PINNED_* variables and the
pinned_partitions target property feeding gen_app_partitions.py.
cmake/modules/extensions.cmake removes the PINNED_RODATA /
PINNED_RAM_SECTIONS / PINNED_DATA_SECTIONS zephyr_linker_sources()
location keywords and their snippet files.
scripts/build/gen_app_partitions.py drops --pinoutput /
--pinpartitions arguments and the pinned-output branch.
subsys/testsuite/coverage/CMakeLists.txt drops its
CONFIG_DEMAND_PAGING-conditional fork.
* scripts/build/gen_kobject_list.py drops the
app_smem_pinned_start / _end fallback for kobject placement
validation.
* tests/arch/x86/pagetables and tests/kernel/mem_protect/userspace
drop their lnkr_pinned_text / lnkr_pinned_rodata branches.
* include/zephyr/arch/x86/ia32/arch.h folds IRQSTUBS_TEXT_SECTION
to the unconditional ".text.irqstubs" form.
* tests/subsys/llext/src/syscalls_ext.c drops a stale comment about
syscalls landing in .pinned_text.
Targeted retentions:
* arch/x86/core/bootargs.c keeps multiboot_cmdline and efi_bootargs
in .noinit (was __pinned_noinit, which decayed to __noinit when
LINKER_USE_PINNED_SECTION was unset). The multiboot and zefi loader
paths write these buffers before Zephyr's BSS-zero step, so
zeroing them at boot loses the cmdline.
* arch/x86/core/ia32/fatal.c keeps _df_esf and _df_stack in .noinit.
They are scratch space written by the double-fault handler and have
no zero-init requirement; keeping them in .noinit also preserves
the historical post-noinit alignment that gen_mmu.py relies on
(z_mapped_size is computed before CMake-injected iterable sections
are appended to the linker script, so the post-noinit page padding
is what keeps those sections within the mapped region).
* include/zephyr/arch/x86/ia32/syscall.h and
include/zephyr/arch/x86/arch.h wrap the per-arch
arch_syscall_invoke* / arch_is_user_context / arch_k_cycle_get_*
implementations in @cond INTERNAL_HIDDEN. The public Doxygen
contract lives on the prototypes in
include/zephyr/arch/arch_interface.h; the per-arch implementations
are internal. Without this, removing the __pinned_func attribute
exposes the implementations to the doxygen-coverage delta check
as 10 newly-undocumented APIs.
Documentation updates are deferred to a separate commit.
Issue: #108773
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-05-15 16:33:20 -04:00
|
|
|
SECTION_FUNC(TEXT, _kernel_oops_handler)
|
2025-03-25 12:19:43 -07:00
|
|
|
endbr32
|
2017-04-18 15:22:54 -07:00
|
|
|
push $0 /* dummy error code */
|
2019-12-18 14:12:54 -08:00
|
|
|
push $z_x86_do_kernel_oops
|
2017-04-18 15:22:54 -07:00
|
|
|
jmp _exception_enter
|