Skip to content

Commit 1268ed0

Browse files
kattisrinivasanKAGA-KOKO
authored andcommitted
x86/hyper-v: Fix the circular dependency in IPI enlightenment
The IPI hypercalls depend on being able to map the Linux notion of CPU ID to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides this mapping. Code for populating this array depends on the IPI functionality. Break this circular dependency. [ tglx: Use a proper define instead of '-1' with a u32 variable as pointed out by Vitaly ] Fixes: 68bb7bf ("X86/Hyper-V: Enable IPI enlightenments") Signed-off-by: K. Y. Srinivasan <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Michael Kelley <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent d0a8d93 commit 1268ed0

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

arch/x86/hyperv/hv_apic.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
114114
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
115115
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
116116
}
117+
if (nr_bank < 0)
118+
goto ipi_mask_ex_done;
117119
if (!nr_bank)
118120
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
119121

@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
158160

159161
for_each_cpu(cur_cpu, mask) {
160162
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
163+
if (vcpu == VP_INVAL)
164+
goto ipi_mask_done;
165+
161166
/*
162167
* This particular version of the IPI hypercall can
163168
* only target upto 64 CPUs.

arch/x86/hyperv/hv_init.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ void __init hyperv_init(void)
265265
{
266266
u64 guest_id, required_msrs;
267267
union hv_x64_msr_hypercall_contents hypercall_msr;
268-
int cpuhp;
268+
int cpuhp, i;
269269

270270
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
271271
return;
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
293293
if (!hv_vp_index)
294294
return;
295295

296+
for (i = 0; i < num_possible_cpus(); i++)
297+
hv_vp_index[i] = VP_INVAL;
298+
296299
hv_vp_assist_page = kcalloc(num_possible_cpus(),
297300
sizeof(*hv_vp_assist_page), GFP_KERNEL);
298301
if (!hv_vp_assist_page) {

arch/x86/include/asm/mshyperv.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <asm/hyperv-tlfs.h>
1010
#include <asm/nospec-branch.h>
1111

12+
#define VP_INVAL U32_MAX
13+
1214
struct ms_hyperv_info {
1315
u32 features;
1416
u32 misc_features;
@@ -20,7 +22,6 @@ struct ms_hyperv_info {
2022

2123
extern struct ms_hyperv_info ms_hyperv;
2224

23-
2425
/*
2526
* Generate the guest ID.
2627
*/
@@ -281,6 +282,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
281282
*/
282283
for_each_cpu(cpu, cpus) {
283284
vcpu = hv_cpu_number_to_vp_number(cpu);
285+
if (vcpu == VP_INVAL)
286+
return -1;
284287
vcpu_bank = vcpu / 64;
285288
vcpu_offset = vcpu % 64;
286289
__set_bit(vcpu_offset, (unsigned long *)

0 commit comments

Comments
 (0)