diff options
| author | Jork Loeser <jloeser@linux.microsoft.com> | 2026-04-07 18:36:40 -0700 |
|---|---|---|
| committer | Wei Liu <wei.liu@kernel.org> | 2026-04-22 06:23:25 +0000 |
| commit | 5170a82e89211d876af17bf3d94a511fb2bb4921 (patch) | |
| tree | b136f2665a59adadb4c6f5fb13849de1bcd313a1 /include | |
| parent | f7ce370b525a02127527b0f54ee877413705a709 (diff) | |
x86/hyperv: Skip LP/VP creation on kexec
After a kexec the logical processors and virtual processors already
exist in the hypervisor because they were created by the previous
kernel. Attempting to add them again causes either a BUG_ON or
corrupted VP state leading to MCEs in the new kernel.
Add hv_lp_exists() to probe whether an LP is already present by
calling HVCALL_GET_LOGICAL_PROCESSOR_RUN_TIME. When it succeeds the
LP exists and we skip the add-LP and create-VP loops entirely.
Also add hv_call_notify_all_processors_started() which informs the
hypervisor that all processors are online. This is required after
adding LPs (fresh boot) and is a no-op on kexec since we skip that
path.
Co-developed-by: Anirudh Rayabharam <anrayabh@linux.microsoft.com>
Signed-off-by: Anirudh Rayabharam <anrayabh@linux.microsoft.com>
Co-developed-by: Stanislav Kinsburskii <stanislav.kinsburskii@gmail.com>
Signed-off-by: Stanislav Kinsburskii <stanislav.kinsburskii@gmail.com>
Co-developed-by: Mukesh Rathor <mrathor@linux.microsoft.com>
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
Signed-off-by: Jork Loeser <jloeser@linux.microsoft.com>
Reviewed-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-generic/mshyperv.h | 10 | ||||
| -rw-r--r-- | include/hyperv/hvgdk_mini.h | 1 | ||||
| -rw-r--r-- | include/hyperv/hvhdk_mini.h | 12 |
3 files changed, 23 insertions, 0 deletions
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index d37b68238c97..bf601d67cecb 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -347,6 +347,8 @@ bool hv_result_needs_memory(u64 status); int hv_deposit_memory_node(int node, u64 partition_id, u64 status); int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); +int hv_call_notify_all_processors_started(void); +bool hv_lp_exists(u32 lp_index); int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); #else /* CONFIG_MSHV_ROOT */ @@ -366,6 +368,14 @@ static inline int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id) { return -EOPNOTSUPP; } +static inline int hv_call_notify_all_processors_started(void) +{ + return -EOPNOTSUPP; +} +static inline bool hv_lp_exists(u32 lp_index) +{ + return false; +} static inline int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags) { return -EOPNOTSUPP; diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h index f9600f87186a..6a4e8b9d570f 100644 --- a/include/hyperv/hvgdk_mini.h +++ b/include/hyperv/hvgdk_mini.h @@ -435,6 +435,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */ /* HV_CALL_CODE */ #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003 +#define HVCALL_GET_LOGICAL_PROCESSOR_RUN_TIME 0x0004 #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008 #define HVCALL_SEND_IPI 0x000b #define HVCALL_ENABLE_VP_VTL 0x000f diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h index 091c03e26046..b4cb2fa26e9b 100644 --- a/include/hyperv/hvhdk_mini.h +++ b/include/hyperv/hvhdk_mini.h @@ -362,6 +362,7 @@ union hv_partition_event_input { enum hv_partition_event { HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2, + HV_PARTITION_ALL_LOGICAL_PROCESSORS_STARTED = 4, }; struct hv_input_notify_partition_event { @@ -369,6 +370,17 @@ struct hv_input_notify_partition_event { union hv_partition_event_input input; } __packed; +struct hv_input_get_logical_processor_run_time { + u32 lp_index; +} __packed; + +struct hv_output_get_logical_processor_run_time { + u64 global_time; + u64 local_run_time; + u64 rsvdz0; + u64 hypervisor_time; +} __packed; + struct hv_lp_startup_status { u64 hv_status; u64 substatus1; |
