Skip to content

Commit 8fd12b0

Browse files
committed
Merge tag 'hyperv-next-signed-20260421' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux
Pull Hyper-V updates from Wei Liu: - Fix cross-compilation for hv tools (Aditya Garg) - Fix vmemmap_shift exceeding MAX_FOLIO_ORDER in mshv_vtl (Naman Jain) - Limit channel interrupt scan to relid high water mark (Michael Kelley) - Export hv_vmbus_exists() and use it in pci-hyperv (Dexuan Cui) - Fix cleanup and shutdown issues for MSHV (Jork Loeser) - Introduce more tracing support for MSHV (Stanislav Kinsburskii) * tag 'hyperv-next-signed-20260421' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: x86/hyperv: Skip LP/VP creation on kexec x86/hyperv: move stimer cleanup to hv_machine_shutdown() Drivers: hv: vmbus: fix hyperv_cpuhp_online variable shadowing mshv: Add tracepoint for GPA intercept handling mshv_vtl: Fix vmemmap_shift exceeding MAX_FOLIO_ORDER tools: hv: Fix cross-compilation Drivers: hv: vmbus: Export hv_vmbus_exists() and use it in pci-hyperv mshv: Introduce tracing support Drivers: hv: vmbus: Limit channel interrupt scan to relid high water mark
2 parents beaba8b + 5170a82 commit 8fd12b0

21 files changed

Lines changed: 783 additions & 51 deletions

File tree

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,12 @@ void hv_remove_crash_handler(void)
237237
#ifdef CONFIG_KEXEC_CORE
238238
static void hv_machine_shutdown(void)
239239
{
240-
if (kexec_in_progress && hv_kexec_handler)
241-
hv_kexec_handler();
240+
if (kexec_in_progress) {
241+
hv_stimer_global_cleanup();
242+
243+
if (hv_kexec_handler)
244+
hv_kexec_handler();
245+
}
242246

243247
/*
244248
* Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
@@ -427,13 +431,20 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
427431
}
428432

429433
#ifdef CONFIG_X86_64
434+
/* If AP LPs exist, we are in a kexec'd kernel and VPs already exist */
435+
if (num_present_cpus() == 1 || hv_lp_exists(1))
436+
return;
437+
430438
for_each_present_cpu(i) {
431439
if (i == 0)
432440
continue;
433441
ret = hv_call_add_logical_proc(numa_cpu_node(i), i, cpu_physical_id(i));
434442
BUG_ON(ret);
435443
}
436444

445+
ret = hv_call_notify_all_processors_started();
446+
WARN_ON(ret);
447+
437448
for_each_present_cpu(i) {
438449
if (i == 0)
439450
continue;

drivers/hv/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o
1616
mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \
1717
mshv_root_hv_call.o mshv_portid_table.o mshv_regions.o
1818
mshv_root-$(CONFIG_DEBUG_FS) += mshv_debugfs.o
19+
mshv_root-$(CONFIG_TRACEPOINTS) += mshv_trace.o
1920
mshv_vtl-y := mshv_vtl_main.o
2021

2122
# Code that must be built-in

drivers/hv/channel_mgmt.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,18 @@ static void free_channel(struct vmbus_channel *channel)
384384

385385
void vmbus_channel_map_relid(struct vmbus_channel *channel)
386386
{
387-
if (WARN_ON(channel->offermsg.child_relid >= MAX_CHANNEL_RELIDS))
387+
u32 new_relid = channel->offermsg.child_relid;
388+
389+
if (WARN_ON(new_relid >= MAX_CHANNEL_RELIDS))
388390
return;
391+
392+
/*
393+
* This function is always called in the tasklet for the connect CPU.
394+
* So updating the relid hiwater mark does not need to be atomic.
395+
*/
396+
if (new_relid > READ_ONCE(vmbus_connection.relid_hiwater))
397+
WRITE_ONCE(vmbus_connection.relid_hiwater, new_relid);
398+
389399
/*
390400
* The mapping of the channel's relid is visible from the CPUs that
391401
* execute vmbus_chan_sched() by the time that vmbus_chan_sched() will
@@ -411,9 +421,7 @@ void vmbus_channel_map_relid(struct vmbus_channel *channel)
411421
* of the VMBus driver and vmbus_chan_sched() can not run before
412422
* vmbus_bus_resume() has completed execution (cf. resume_noirq).
413423
*/
414-
virt_store_mb(
415-
vmbus_connection.channels[channel->offermsg.child_relid],
416-
channel);
424+
virt_store_mb(vmbus_connection.channels[new_relid], channel);
417425
}
418426

419427
void vmbus_channel_unmap_relid(struct vmbus_channel *channel)

drivers/hv/hv_proc.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,50 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
239239
return ret;
240240
}
241241
EXPORT_SYMBOL_GPL(hv_call_create_vp);
242+
243+
int hv_call_notify_all_processors_started(void)
244+
{
245+
struct hv_input_notify_partition_event *input;
246+
u64 status;
247+
unsigned long irq_flags;
248+
int ret = 0;
249+
250+
local_irq_save(irq_flags);
251+
input = *this_cpu_ptr(hyperv_pcpu_input_arg);
252+
memset(input, 0, sizeof(*input));
253+
input->event = HV_PARTITION_ALL_LOGICAL_PROCESSORS_STARTED;
254+
status = hv_do_hypercall(HVCALL_NOTIFY_PARTITION_EVENT,
255+
input, NULL);
256+
local_irq_restore(irq_flags);
257+
258+
if (!hv_result_success(status)) {
259+
hv_status_err(status, "\n");
260+
ret = hv_result_to_errno(status);
261+
}
262+
return ret;
263+
}
264+
265+
bool hv_lp_exists(u32 lp_index)
266+
{
267+
struct hv_input_get_logical_processor_run_time *input;
268+
struct hv_output_get_logical_processor_run_time *output;
269+
unsigned long flags;
270+
u64 status;
271+
272+
local_irq_save(flags);
273+
input = *this_cpu_ptr(hyperv_pcpu_input_arg);
274+
output = *this_cpu_ptr(hyperv_pcpu_output_arg);
275+
276+
input->lp_index = lp_index;
277+
status = hv_do_hypercall(HVCALL_GET_LOGICAL_PROCESSOR_RUN_TIME,
278+
input, output);
279+
local_irq_restore(flags);
280+
281+
if (!hv_result_success(status) &&
282+
hv_result(status) != HV_STATUS_INVALID_LP_INDEX) {
283+
hv_status_err(status, "\n");
284+
BUG();
285+
}
286+
287+
return hv_result_success(status);
288+
}

drivers/hv/hyperv_vmbus.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,9 @@ struct vmbus_connection {
276276
struct list_head chn_list;
277277
struct mutex channel_mutex;
278278

279-
/* Array of channels */
279+
/* Array of channel pointers, indexed by relid */
280280
struct vmbus_channel **channels;
281+
u32 relid_hiwater;
281282

282283
/*
283284
* An offer message is handled first on the work_queue, and then

drivers/hv/mshv_eventfd.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,14 @@ static int mshv_assign_ioeventfd(struct mshv_partition *pt,
733733
ret = mshv_register_doorbell(pt->pt_id, ioeventfd_mmio_write,
734734
(void *)pt, p->iovntfd_addr,
735735
p->iovntfd_datamatch, doorbell_flags);
736+
737+
trace_mshv_assign_ioeventfd(pt->pt_id, p->iovntfd_addr,
738+
p->iovntfd_length,
739+
p->iovntfd_datamatch,
740+
p->iovntfd_wildcard,
741+
p->iovntfd_eventfd,
742+
ret);
743+
736744
if (ret < 0)
737745
goto unlock_fail;
738746

@@ -780,6 +788,12 @@ static int mshv_deassign_ioeventfd(struct mshv_partition *pt,
780788
p->iovntfd_datamatch != args->datamatch)
781789
continue;
782790

791+
trace_mshv_deassign_ioeventfd(pt->pt_id, p->iovntfd_addr,
792+
p->iovntfd_length,
793+
p->iovntfd_datamatch,
794+
p->iovntfd_wildcard,
795+
p->iovntfd_eventfd);
796+
783797
hlist_del_rcu(&p->iovntfd_hnode);
784798
synchronize_rcu();
785799
ioeventfd_release(p, pt->pt_id);

drivers/hv/mshv_irq.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ int mshv_update_routing_table(struct mshv_partition *partition,
7171
mutex_unlock(&partition->pt_irq_lock);
7272

7373
synchronize_srcu_expedited(&partition->pt_irq_srcu);
74+
75+
trace_mshv_update_routing_table(partition->pt_id,
76+
old, new, numents);
77+
7478
new = old;
7579

7680
out:

drivers/hv/mshv_root.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/build_bug.h>
1818
#include <linux/mmu_notifier.h>
1919
#include <uapi/linux/mshv.h>
20+
#include "mshv_trace.h"
2021

2122
/*
2223
* Hypervisor must be between these version numbers (inclusive)

drivers/hv/mshv_root_hv_call.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ int hv_call_withdraw_memory(u64 count, int node, u64 partition_id)
4545
struct hv_output_withdraw_memory *output_page;
4646
struct page *page;
4747
u16 completed;
48-
unsigned long remaining = count;
49-
u64 status;
48+
u64 status, withdrawn = 0;
5049
int i;
5150
unsigned long flags;
5251

@@ -55,15 +54,15 @@ int hv_call_withdraw_memory(u64 count, int node, u64 partition_id)
5554
return -ENOMEM;
5655
output_page = page_address(page);
5756

58-
while (remaining) {
57+
while (withdrawn < count) {
5958
local_irq_save(flags);
6059

6160
input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
6261

6362
memset(input_page, 0, sizeof(*input_page));
6463
input_page->partition_id = partition_id;
6564
status = hv_do_rep_hypercall(HVCALL_WITHDRAW_MEMORY,
66-
min(remaining, HV_WITHDRAW_BATCH_SIZE),
65+
min(count - withdrawn, HV_WITHDRAW_BATCH_SIZE),
6766
0, input_page, output_page);
6867

6968
local_irq_restore(flags);
@@ -79,10 +78,12 @@ int hv_call_withdraw_memory(u64 count, int node, u64 partition_id)
7978
break;
8079
}
8180

82-
remaining -= completed;
81+
withdrawn += completed;
8382
}
8483
free_page((unsigned long)output_page);
8584

85+
trace_mshv_hvcall_withdraw_memory(partition_id, withdrawn, status);
86+
8687
return hv_result_to_errno(status);
8788
}
8889

@@ -126,6 +127,8 @@ int hv_call_create_partition(u64 flags,
126127
ret = hv_deposit_memory(hv_current_partition_id, status);
127128
} while (!ret);
128129

130+
trace_mshv_hvcall_create_partition(flags, ret ? ret : *partition_id);
131+
129132
return ret;
130133
}
131134

@@ -153,6 +156,8 @@ int hv_call_initialize_partition(u64 partition_id)
153156
ret = hv_deposit_memory(partition_id, status);
154157
} while (!ret);
155158

159+
trace_mshv_hvcall_initialize_partition(partition_id, status);
160+
156161
return ret;
157162
}
158163

@@ -165,6 +170,8 @@ int hv_call_finalize_partition(u64 partition_id)
165170
status = hv_do_fast_hypercall8(HVCALL_FINALIZE_PARTITION,
166171
*(u64 *)&input);
167172

173+
trace_mshv_hvcall_finalize_partition(partition_id, status);
174+
168175
return hv_result_to_errno(status);
169176
}
170177

@@ -176,6 +183,8 @@ int hv_call_delete_partition(u64 partition_id)
176183
input.partition_id = partition_id;
177184
status = hv_do_fast_hypercall8(HVCALL_DELETE_PARTITION, *(u64 *)&input);
178185

186+
trace_mshv_hvcall_delete_partition(partition_id, status);
187+
179188
return hv_result_to_errno(status);
180189
}
181190

@@ -573,6 +582,9 @@ static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
573582
ret = hv_deposit_memory(partition_id, status);
574583
} while (!ret);
575584

585+
trace_mshv_hvcall_map_vp_state_page(partition_id, vp_index,
586+
type, status);
587+
576588
return ret;
577589
}
578590

0 commit comments

Comments
 (0)