linux/arch/x86/mm
Cedric Xing 4040b84ec0 x86: make page fault handling disable interrupts properly
[ Upstream commit 614da1d3d4 ]

There's a big comment in the x86 do_page_fault() about our interrupt
disabling code:

    * User address page fault handling might have reenabled
    * interrupts. Fixing up all potential exit points of
    * do_user_addr_fault() and its leaf functions is just not
    * doable w/o creating an unholy mess or turning the code
    * upside down.

but it turns out that comment is subtly wrong, and the code as a result
is also wrong.

Because it's certainly true that we may have re-enabled interrupts when
handling user page faults.  And it's most certainly true that we don't
want to bother fixing up all the cases.

But what isn't true is that it's limited to user address page faults.

The confusion stems from the fact that we have logic here that depends
on the address range of the access, but other code then depends on the
_context_ the access was done in.  The two are not related, even though
both of them are about user-vs-kernel.

In other words, both user and kernel addresses can cause interrupts to
have been enabled (eg when __bad_area_nosemaphore() gets called for user
accesses to kernel addresses).  As a result we should make sure to
disable interrupts again regardless of the address range before
returning to the low-level fault handling code.

The __bad_area_nosemaphore() code actually did disable interrupts again
after enabling them, just not consistently.  Ironically, as noted in the
original comment, fixing up all the cases is just not worth it, when the
simple solution is to just do it unconditionally in one single place.

So remove the incomplete case that unsuccessfully tried to do what the
comment said was "not doable" in commit ca4c6a9858 ("x86/traps: Make
interrupt enable/disable symmetric in C code"), and just make it do the
simple and straightforward thing.

Signed-off-by: Cedric Xing <cedric.xing@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Fixes: ca4c6a9858 ("x86/traps: Make interrupt enable/disable symmetric in C code")
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2026-01-30 10:32:22 +01:00
..
pat x86/mm: use pagetable_free() 2026-01-23 11:21:35 +01:00
amdtopology.c x86/platform/amd: Move the <asm/amd_nb.h> header to <asm/amd/nb.h> 2025-04-14 09:34:14 +02:00
cpu_entry_area.c x86/cpu_entry_area: Annotate percpu_setup_exception_stacks() as __init 2024-08-25 14:29:38 +02:00
debug_pagetables.c x86/bugs: Rename CONFIG_PAGE_TABLE_ISOLATION => CONFIG_MITIGATION_PAGE_TABLE_ISOLATION 2024-01-10 10:52:28 +01:00
dump_pagetables.c mm/ptdump: split effective_prot() into level specific callbacks 2025-05-11 17:48:19 -07:00
extable.c x86/fpu: Delay instruction pointer fixup until after warning 2025-06-25 16:28:06 -07:00
fault.c x86: make page fault handling disable interrupts properly 2026-01-30 10:32:22 +01:00
hugetlbpage.c mm: drop hugetlb_get_unmapped_area{_*} functions 2024-11-06 20:11:10 -08:00
ident_map.c x86/mm/ident_map: Fix theoretical virtual address overflow to zero 2025-03-19 11:12:29 +01:00
init.c mm, x86/mm: move creating the tlb_flush event back to x86 code 2025-09-13 16:55:14 -07:00
init_32.c Revert "mm/execmem: Unify early execmem_cache behaviour" 2025-06-11 11:20:52 +02:00
init_64.c x86/mm: use pagetable_free() 2026-01-23 11:21:35 +01:00
iomap_32.c io-mapping: Cleanup atomic iomap 2020-11-06 23:14:58 +01:00
ioremap.c mm, x86: use for_each_valid_pfn() from __ioremap_check_ram() 2025-05-12 23:50:44 -07:00
kasan_init_64.c kasan: call kasan_init_generic in kasan_init 2025-09-21 14:21:58 -07:00
kaslr.c x86/kaslr: Recognize all ZONE_DEVICE users as physaddr consumers 2026-01-23 11:21:25 +01:00
kmmio.c x86/mm/kmmio: Remove redundant preempt_disable() 2022-12-12 10:54:48 -05:00
kmsan_shadow.c x86: kmsan: handle CPU entry area 2022-10-03 14:03:26 -07:00
maccess.c x86/mm: Disallow vsyscall page read for copy_from_kernel_nofault() 2024-02-15 19:21:39 -08:00
Makefile Move the x86 page fault tracepoints to generic code, because 2025-05-26 21:18:59 -07:00
mem_encrypt.c x86/sev: Add Secure TSC support for SNP guests 2025-01-07 20:27:23 +01:00
mem_encrypt_amd.c x86/sev: Avoid global variable to store virtual address of SVSM area 2025-09-03 17:58:15 +02:00
mem_encrypt_boot.S x86/boot: Create a confined code area for startup code 2025-09-03 18:00:01 +02:00
mm_internal.h x86/mm: Consolidate initmem_init() 2025-04-09 22:02:30 +02:00
mmap.c mm: constify arch_pick_mmap_layout() for improved const-correctness 2025-09-21 14:22:14 -07:00
mmio-mod.c x86: Replace cpumask_weight() with cpumask_empty() where appropriate 2022-04-10 22:35:38 +02:00
numa.c Merge branch 'x86/mm' into x86/core, to resolve conflicts 2025-05-13 10:39:22 +02:00
pf_in.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
pf_in.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
pgprot.c mm: change vm_get_page_prot() to accept vm_flags_t argument 2025-07-09 22:42:13 -07:00
pgtable.c x86/mm: use 'ptdesc' when freeing PMD pages 2026-01-23 11:21:35 +01:00
pgtable_32.c mm: remove unneeded includes of <asm/pgalloc.h> 2020-08-07 11:33:26 -07:00
physaddr.c mm, x86/mm: Untangle address space layout definitions from basic pgtable type definitions 2019-12-10 10:12:55 +01:00
physaddr.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
pkeys.c x86/pkeys: Clarify PKRU_AD_KEY macro 2022-06-07 16:06:33 -07:00
pti.c - Untangle the Retbleed from the ITS mitigation on Intel. Allow for ITS 2025-07-29 16:34:45 -07:00
srat.c x86/mm: Don't print out SRAT table information 2024-08-08 17:23:40 +02:00
testmmiotrace.c x86/mm: add testmmiotrace MODULE_DESCRIPTION() 2024-09-01 20:43:31 -07:00
tlb.c x86/mm: Fix SMP ordering in switch_mm_irqs_off() 2025-10-13 13:55:53 -07:00