summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-05 13:53:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-05 13:53:07 -0700
commit10b76a429a8716545cd6dcaf4578594e74dcd21b (patch)
tree0ce3cbf3e29de31eed3c837a57fd0e2b70a37e5b
parent2ab99ad7faef1f0a4529e8bae92009fa56242bd4 (diff)
parentb981e9e94c687b7b19ae8820963f005b842cb2f2 (diff)
Merge tag 'x86-urgent-2026-04-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: - Fix kexec crash on KCOV-instrumented kernels (Aleksandr Nogikh) - Fix Geode platform driver on-stack property data use-after-return bug (Dmitry Torokhov) * tag 'x86-urgent-2026-04-05' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/platform/geode: Fix on-stack property data use-after-return bug x86/kexec: Disable KCOV instrumentation after load_segments()
-rw-r--r--arch/x86/kernel/Makefile14
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/platform/geode/geode-common.c24
3 files changed, 34 insertions, 6 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index e9aeeeafad17..47a32f583930 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -44,6 +44,20 @@ KCOV_INSTRUMENT_unwind_orc.o := n
KCOV_INSTRUMENT_unwind_frame.o := n
KCOV_INSTRUMENT_unwind_guess.o := n
+# Disable KCOV to prevent crashes during kexec: load_segments() invalidates
+# the GS base, which KCOV relies on for per-CPU data.
+#
+# As KCOV and KEXEC compatibility should be preserved (e.g. syzkaller is
+# using it to collect crash dumps during kernel fuzzing), disabling
+# KCOV for KEXEC kernels is not an option. Selectively disabling KCOV
+# instrumentation for individual affected functions can be fragile, while
+# adding more checks to KCOV would slow it down.
+#
+# As a compromise solution, disable KCOV instrumentation for the whole
+# source code file. If its coverage is ever needed, other approaches
+# should be considered.
+KCOV_INSTRUMENT_machine_kexec_64.o := n
+
CFLAGS_head32.o := -fno-stack-protector
CFLAGS_head64.o := -fno-stack-protector
CFLAGS_irq.o := -I $(src)/../include/asm/trace
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 5b9908f13dcf..3a5364853eab 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -4,6 +4,8 @@ KCOV_INSTRUMENT_tlb.o := n
KCOV_INSTRUMENT_mem_encrypt.o := n
KCOV_INSTRUMENT_mem_encrypt_amd.o := n
KCOV_INSTRUMENT_pgprot.o := n
+# See the "Disable KCOV" comment in arch/x86/kernel/Makefile.
+KCOV_INSTRUMENT_physaddr.o := n
KASAN_SANITIZE_mem_encrypt.o := n
KASAN_SANITIZE_mem_encrypt_amd.o := n
diff --git a/arch/x86/platform/geode/geode-common.c b/arch/x86/platform/geode/geode-common.c
index 05189c5f7d2a..1843ae385e2d 100644
--- a/arch/x86/platform/geode/geode-common.c
+++ b/arch/x86/platform/geode/geode-common.c
@@ -28,8 +28,10 @@ static const struct software_node geode_gpio_keys_node = {
.properties = geode_gpio_keys_props,
};
-static struct property_entry geode_restart_key_props[] = {
- { /* Placeholder for GPIO property */ },
+static struct software_node_ref_args geode_restart_gpio_ref;
+
+static const struct property_entry geode_restart_key_props[] = {
+ PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &geode_restart_gpio_ref, 1),
PROPERTY_ENTRY_U32("linux,code", KEY_RESTART),
PROPERTY_ENTRY_STRING("label", "Reset button"),
PROPERTY_ENTRY_U32("debounce-interval", 100),
@@ -64,8 +66,7 @@ int __init geode_create_restart_key(unsigned int pin)
struct platform_device *pd;
int err;
- geode_restart_key_props[0] = PROPERTY_ENTRY_GPIO("gpios",
- &geode_gpiochip_node,
+ geode_restart_gpio_ref = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node,
pin, GPIO_ACTIVE_LOW);
err = software_node_register_node_group(geode_gpio_keys_swnodes);
@@ -99,6 +100,7 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
const struct software_node *group[MAX_LEDS + 2] = { 0 };
struct software_node *swnodes;
struct property_entry *props;
+ struct software_node_ref_args *gpio_refs;
struct platform_device_info led_info = {
.name = "leds-gpio",
.id = PLATFORM_DEVID_NONE,
@@ -127,6 +129,12 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
goto err_free_swnodes;
}
+ gpio_refs = kzalloc_objs(*gpio_refs, n_leds);
+ if (!gpio_refs) {
+ err = -ENOMEM;
+ goto err_free_props;
+ }
+
group[0] = &geode_gpio_leds_node;
for (i = 0; i < n_leds; i++) {
node_name = kasprintf(GFP_KERNEL, "%s:%d", label, i);
@@ -135,9 +143,11 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
goto err_free_names;
}
+ gpio_refs[i] = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node,
+ leds[i].pin,
+ GPIO_ACTIVE_LOW);
props[i * 3 + 0] =
- PROPERTY_ENTRY_GPIO("gpios", &geode_gpiochip_node,
- leds[i].pin, GPIO_ACTIVE_LOW);
+ PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &gpio_refs[i], 1);
props[i * 3 + 1] =
PROPERTY_ENTRY_STRING("linux,default-trigger",
leds[i].default_on ?
@@ -171,6 +181,8 @@ err_unregister_group:
err_free_names:
while (--i >= 0)
kfree(swnodes[i].name);
+ kfree(gpio_refs);
+err_free_props:
kfree(props);
err_free_swnodes:
kfree(swnodes);