]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arm64/arm: xen: enlighten: Fix KPTI checks
authorMark Rutland <mark.rutland@arm.com>
Mon, 16 Oct 2023 10:24:25 +0000 (11:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Nov 2023 10:57:02 +0000 (11:57 +0100)
[ Upstream commit 20f3b8eafe0ba5d3c69d5011a9b07739e9645132 ]

When KPTI is in use, we cannot register a runstate region as XEN
requires that this is always a valid VA, which we cannot guarantee. Due
to this, xen_starting_cpu() must avoid registering each CPU's runstate
region, and xen_guest_init() must avoid setting up features that depend
upon it.

We tried to ensure that in commit:

  f88af7229f6f22ce (" xen/arm: do not setup the runstate info page if kpti is enabled")

... where we added checks for xen_kernel_unmapped_at_usr(), which wraps
arm64_kernel_unmapped_at_el0() on arm64 and is always false on 32-bit
arm.

Unfortunately, as xen_guest_init() is an early_initcall, this happens
before secondary CPUs are booted and arm64 has finalized the
ARM64_UNMAP_KERNEL_AT_EL0 cpucap which backs
arm64_kernel_unmapped_at_el0(), and so this can subsequently be set as
secondary CPUs are onlined. On a big.LITTLE system where the boot CPU
does not require KPTI but some secondary CPUs do, this will result in
xen_guest_init() intializing features that depend on the runstate
region, and xen_starting_cpu() registering the runstate region on some
CPUs before KPTI is subsequent enabled, resulting the the problems the
aforementioned commit tried to avoid.

Handle this more robsutly by deferring the initialization of the
runstate region until secondary CPUs have been initialized and the
ARM64_UNMAP_KERNEL_AT_EL0 cpucap has been finalized. The per-cpu work is
moved into a new hotplug starting function which is registered later
when we're certain that KPTI will not be used.

Fixes: f88af7229f6f ("xen/arm: do not setup the runstate info page if kpti is enabled")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Bertrand Marquis <bertrand.marquis@arm.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm/xen/enlighten.c
include/linux/cpuhotplug.h

index 7d59765aef220b429afdf7a8d3a2a6ec0923c0b2..6cdcd39fb0961f86e4e741bec231809176c0f609 100644 (file)
@@ -164,9 +164,6 @@ static int xen_starting_cpu(unsigned int cpu)
        BUG_ON(err);
        per_cpu(xen_vcpu, cpu) = vcpup;
 
-       if (!xen_kernel_unmapped_at_usr())
-               xen_setup_runstate_info(cpu);
-
 after_register_vcpu_info:
        enable_percpu_irq(xen_events_irq, 0);
        return 0;
@@ -523,9 +520,6 @@ static int __init xen_guest_init(void)
                return -EINVAL;
        }
 
-       if (!xen_kernel_unmapped_at_usr())
-               xen_time_setup_guest();
-
        if (xen_initial_domain())
                pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
 
@@ -535,7 +529,13 @@ static int __init xen_guest_init(void)
 }
 early_initcall(xen_guest_init);
 
-static int __init xen_pm_init(void)
+static int xen_starting_runstate_cpu(unsigned int cpu)
+{
+       xen_setup_runstate_info(cpu);
+       return 0;
+}
+
+static int __init xen_late_init(void)
 {
        if (!xen_domain())
                return -ENODEV;
@@ -548,9 +548,16 @@ static int __init xen_pm_init(void)
                do_settimeofday64(&ts);
        }
 
-       return 0;
+       if (xen_kernel_unmapped_at_usr())
+               return 0;
+
+       xen_time_setup_guest();
+
+       return cpuhp_setup_state(CPUHP_AP_ARM_XEN_RUNSTATE_STARTING,
+                                "arm/xen_runstate:starting",
+                                xen_starting_runstate_cpu, NULL);
 }
-late_initcall(xen_pm_init);
+late_initcall(xen_late_init);
 
 
 /* empty stubs */
index 25b6e6e6ba6bc2c2dd2a7c6a6fea2c685382c5a7..f0231cc66746ec8c185577ff13658d33fd5ab2ad 100644 (file)
@@ -190,6 +190,7 @@ enum cpuhp_state {
        /* Must be the last timer callback */
        CPUHP_AP_DUMMY_TIMER_STARTING,
        CPUHP_AP_ARM_XEN_STARTING,
+       CPUHP_AP_ARM_XEN_RUNSTATE_STARTING,
        CPUHP_AP_ARM_CORESIGHT_STARTING,
        CPUHP_AP_ARM_CORESIGHT_CTI_STARTING,
        CPUHP_AP_ARM64_ISNDEP_STARTING,