diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 23:14:24 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 23:14:24 +0100 |
| commit | 133bffdb994e146623bb3aca55c83bd2a83946f3 (patch) | |
| tree | c59bc65b68b2c5166d2320d784f8c0ae54c857cb /arch | |
| parent | a7a99e76d203e7f6621804f33148cb7afa7818f2 (diff) | |
| parent | 7a035678fc2bdee81881170764ef08a91a076147 (diff) | |
| download | linux-next-history-133bffdb994e146623bb3aca55c83bd2a83946f3.tar.gz | |
Merge branch 'hyperv-next' of https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/hyperv/hv_vtl.c | 38 | ||||
| -rw-r--r-- | arch/x86/include/asm/acpi.h | 16 | ||||
| -rw-r--r-- | arch/x86/include/asm/topology.h | 3 | ||||
| -rw-r--r-- | arch/x86/include/asm/x86_init.h | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/acpi/madt_wakeup.c | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/devicetree.c | 47 | ||||
| -rw-r--r-- | arch/x86/kernel/x86_init.c | 3 | ||||
| -rw-r--r-- | arch/x86/realmode/init.c | 7 |
8 files changed, 125 insertions, 8 deletions
diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c index 9b6a9bc4ab760..07fac3d687c39 100644 --- a/arch/x86/hyperv/hv_vtl.c +++ b/arch/x86/hyperv/hv_vtl.c @@ -6,6 +6,9 @@ * Saurabh Sengar <ssengar@microsoft.com> */ +#include <linux/acpi.h> + +#include <asm/acpi.h> #include <asm/apic.h> #include <asm/boot.h> #include <asm/desc.h> @@ -59,6 +62,18 @@ static void __noreturn hv_vtl_restart(char __maybe_unused *cmd) hv_vtl_emergency_restart(); } +static inline bool within_page(u64 addr, u64 start) +{ + return addr >= start && addr < (start + PAGE_SIZE); +} + +static bool hv_vtl_is_private_mmio_tdx(u64 addr) +{ + u64 mb_addr = acpi_get_mp_wakeup_mailbox_paddr(); + + return mb_addr && within_page(addr, mb_addr); +} + void __init hv_vtl_init_platform(void) { /* @@ -68,8 +83,16 @@ void __init hv_vtl_init_platform(void) */ pr_info("Linux runs in Hyper-V Virtual Trust Level %d\n", ms_hyperv.vtl); - x86_platform.realmode_reserve = x86_init_noop; - x86_platform.realmode_init = x86_init_noop; + /* There is no paravisor present if we are here. */ + if (hv_isolation_type_tdx()) { + x86_init.resources.realmode_limit = SZ_4G; + x86_platform.hyper.is_private_mmio = hv_vtl_is_private_mmio_tdx; + + } else { + x86_platform.realmode_reserve = x86_init_noop; + x86_platform.realmode_init = x86_init_noop; + real_mode_header = &hv_vtl_real_mode_header; + } x86_init.irqs.pre_vector_init = x86_init_noop; x86_init.timers.timer_init = x86_init_noop; x86_init.resources.probe_roms = x86_init_noop; @@ -251,8 +274,15 @@ int __init hv_vtl_early_init(void) panic("XSAVE has to be disabled as it is not supported by this module.\n" "Please add 'noxsave' to the kernel command line.\n"); - real_mode_header = &hv_vtl_real_mode_header; - apic_update_callback(wakeup_secondary_cpu_64, hv_vtl_wakeup_secondary_cpu); + /* + * TDX confidential VMs do not trust the hypervisor and cannot use it to + * boot secondary CPUs. Instead, they will be booted using the wakeup + * mailbox if detected during boot. See setup_arch(). + * + * There is no paravisor present if we are here. + */ + if (!hv_isolation_type_tdx()) + apic_update_callback(wakeup_secondary_cpu_64, hv_vtl_wakeup_secondary_cpu); return 0; } diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index a03aa6f999d15..c4e6459bd56b1 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -182,6 +182,10 @@ void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size); #define acpi_os_ioremap acpi_os_ioremap #endif +void acpi_setup_mp_wakeup_mailbox(u64 addr); +struct acpi_madt_multiproc_wakeup_mailbox *acpi_get_mp_wakeup_mailbox(void); +u64 acpi_get_mp_wakeup_mailbox_paddr(void); + #else /* !CONFIG_ACPI */ #define acpi_lapic 0 @@ -200,6 +204,18 @@ static inline u64 x86_default_get_root_pointer(void) return 0; } +static inline void acpi_setup_mp_wakeup_mailbox(u64 addr) { } + +static inline struct acpi_madt_multiproc_wakeup_mailbox *acpi_get_mp_wakeup_mailbox(void) +{ + return NULL; +} + +static inline u64 acpi_get_mp_wakeup_mailbox_paddr(void) +{ + return 0; +} + #endif /* !CONFIG_ACPI */ #define ARCH_HAS_POWER_INIT 1 diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 0ba9bdb998717..8fb61d2465eb8 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -157,6 +157,8 @@ extern unsigned int __num_threads_per_package; extern unsigned int __num_cores_per_package; extern unsigned int __num_nodes_per_package; +struct cpuinfo_x86; + const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); @@ -265,6 +267,7 @@ extern bool x86_topology_update; #ifdef CONFIG_SCHED_MC_PRIO #include <asm/percpu.h> +#include <linux/cache.h> DECLARE_PER_CPU_READ_MOSTLY(int, sched_core_priority); extern bool __read_mostly sysctl_sched_itmt_enabled; diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 6c8a6ead84f6e..953d3199408ae 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -31,12 +31,15 @@ struct x86_init_mpparse { * platform * @memory_setup: platform specific memory setup * @dmi_setup: platform specific DMI setup + * @realmode_limit: platform specific address limit for the real mode trampoline + * (default 1M) */ struct x86_init_resources { void (*probe_roms)(void); void (*reserve_resources)(void); char *(*memory_setup)(void); void (*dmi_setup)(void); + unsigned long realmode_limit; }; /** diff --git a/arch/x86/kernel/acpi/madt_wakeup.c b/arch/x86/kernel/acpi/madt_wakeup.c index 6d7603511f52c..48734e4a6e8f5 100644 --- a/arch/x86/kernel/acpi/madt_wakeup.c +++ b/arch/x86/kernel/acpi/madt_wakeup.c @@ -247,3 +247,19 @@ int __init acpi_parse_mp_wake(union acpi_subtable_headers *header, return 0; } + +void __init acpi_setup_mp_wakeup_mailbox(u64 mailbox_paddr) +{ + acpi_mp_wake_mailbox_paddr = mailbox_paddr; + apic_update_callback(wakeup_secondary_cpu_64, acpi_wakeup_cpu); +} + +struct acpi_madt_multiproc_wakeup_mailbox *acpi_get_mp_wakeup_mailbox(void) +{ + return acpi_mp_wake_mailbox; +} + +u64 acpi_get_mp_wakeup_mailbox_paddr(void) +{ + return acpi_mp_wake_mailbox_paddr; +} diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index dd8748c45529a..318acaecb5ca1 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -18,6 +18,7 @@ #include <linux/of_pci.h> #include <linux/initrd.h> +#include <asm/acpi.h> #include <asm/irqdomain.h> #include <asm/hpet.h> #include <asm/apic.h> @@ -125,6 +126,51 @@ static void __init dtb_setup_hpet(void) #endif } +#if defined(CONFIG_X86_64) && defined(CONFIG_SMP) + +#define WAKEUP_MAILBOX_SIZE 0x1000 +#define WAKEUP_MAILBOX_ALIGN 0x1000 + +/** dtb_wakeup_mailbox_setup() - Parse the wakeup mailbox from the device tree + * + * Look for the presence of a wakeup mailbox in the DeviceTree. The mailbox is + * expected to follow the structure and operation described in the Multiprocessor + * Wakeup Structure of the ACPI specification. + */ +static void __init dtb_wakeup_mailbox_setup(void) +{ + struct device_node *node; + struct resource res; + + node = of_find_compatible_node(NULL, NULL, "intel,wakeup-mailbox"); + if (!node) + return; + + if (of_address_to_resource(node, 0, &res)) + goto done; + + /* The mailbox is a 4KB-aligned region.*/ + if (res.start & (WAKEUP_MAILBOX_ALIGN - 1)) + goto done; + + /* The mailbox has a size of 4KB. */ + if (res.end - res.start + 1 != WAKEUP_MAILBOX_SIZE) + goto done; + + /* Not supported when the mailbox is used. */ + cpu_hotplug_disable_offlining(); + + acpi_setup_mp_wakeup_mailbox(res.start); +done: + of_node_put(node); +} +#else /* !CONFIG_X86_64 || !CONFIG_SMP */ +static inline int dtb_wakeup_mailbox_setup(void) +{ + return -EOPNOTSUPP; +} +#endif /* CONFIG_X86_64 && CONFIG_SMP */ + #ifdef CONFIG_X86_LOCAL_APIC static void __init dtb_cpu_setup(void) @@ -287,6 +333,7 @@ static void __init x86_dtb_parse_smp_config(void) dtb_setup_hpet(); dtb_apic_setup(); + dtb_wakeup_mailbox_setup(); } void __init x86_flattree_get_config(void) diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index ebefb77c37bbd..252c5827d0634 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -9,6 +9,7 @@ #include <linux/export.h> #include <linux/pci.h> #include <linux/acpi.h> +#include <linux/sizes.h> #include <asm/acpi.h> #include <asm/bios_ebda.h> @@ -69,6 +70,8 @@ struct x86_init_ops x86_init __initdata = { .reserve_resources = reserve_standard_io_resources, .memory_setup = e820__memory_setup_default, .dmi_setup = dmi_setup, + /* Has to be under 1M so we can execute real-mode AP code. */ + .realmode_limit = SZ_1M, }, .mpparse = { diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c index 88be32026768c..694d80a5c68e1 100644 --- a/arch/x86/realmode/init.c +++ b/arch/x86/realmode/init.c @@ -46,7 +46,7 @@ void load_trampoline_pgtable(void) void __init reserve_real_mode(void) { - phys_addr_t mem; + phys_addr_t mem, limit = x86_init.resources.realmode_limit; size_t size = real_mode_size_needed(); if (!size) @@ -54,10 +54,9 @@ void __init reserve_real_mode(void) WARN_ON(slab_is_available()); - /* Has to be under 1M so we can execute real-mode AP code. */ - mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20); + mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, limit); if (!mem) - pr_info("No sub-1M memory is available for the trampoline\n"); + pr_info("No memory below %pa for the real-mode trampoline\n", &limit); else set_real_mode_mem(mem); |
