Skip to content

Commit 80acc80

Browse files
Stanislav Kinsburskiiliuw
authored andcommitted
mshv: Introduce tracing support
Introduces various trace events and use them in the corresponding places in the driver. Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Signed-off-by: Wei Liu <wei.liu@kernel.org>
1 parent 1c80dd8 commit 80acc80

8 files changed

Lines changed: 629 additions & 15 deletions

File tree

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/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

drivers/hv/mshv_root_main.c

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,17 @@ mshv_vp_dispatch(struct mshv_vp *vp, u32 flags,
429429
status = hv_do_hypercall(HVCALL_DISPATCH_VP, input, output);
430430
vp->run.flags.root_sched_dispatched = 0;
431431

432+
trace_mshv_hvcall_dispatch_vp(vp->vp_partition->pt_id,
433+
vp->vp_index, flags,
434+
output->dispatch_state,
435+
output->dispatch_event,
436+
#if defined(CONFIG_X86_64)
437+
vp->vp_register_page->interrupt_vectors.as_uint64,
438+
#else
439+
0,
440+
#endif
441+
status);
442+
432443
*res = *output;
433444
preempt_enable();
434445

@@ -451,6 +462,9 @@ mshv_vp_clear_explicit_suspend(struct mshv_vp *vp)
451462
ret = mshv_set_vp_registers(vp->vp_index, vp->vp_partition->pt_id,
452463
1, &explicit_suspend);
453464

465+
trace_mshv_vp_clear_explicit_suspend(vp->vp_partition->pt_id,
466+
vp->vp_index, ret);
467+
454468
if (ret)
455469
vp_err(vp, "Failed to unsuspend\n");
456470

@@ -493,6 +507,12 @@ mshv_vp_wait_for_hv_kick(struct mshv_vp *vp)
493507
if (ret)
494508
return -EINTR;
495509

510+
trace_mshv_vp_wait_for_hv_kick(vp->vp_partition->pt_id,
511+
vp->vp_index,
512+
vp->run.kicked_by_hv,
513+
mshv_vp_dispatch_thread_blocked(vp),
514+
mshv_vp_interrupt_pending(vp));
515+
496516
vp->run.flags.root_sched_blocked = 0;
497517
vp->run.kicked_by_hv = 0;
498518

@@ -521,6 +541,12 @@ static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp)
521541

522542
if (__xfer_to_guest_mode_work_pending()) {
523543
ret = xfer_to_guest_mode_handle_work();
544+
545+
trace_mshv_xfer_to_guest_mode_work(vp->vp_partition->pt_id,
546+
vp->vp_index,
547+
read_thread_flags(),
548+
ret);
549+
524550
if (ret)
525551
break;
526552
}
@@ -681,13 +707,19 @@ static long mshv_vp_ioctl_run_vp(struct mshv_vp *vp, void __user *ret_msg)
681707
{
682708
long rc;
683709

710+
trace_mshv_run_vp_entry(vp->vp_partition->pt_id, vp->vp_index);
711+
684712
do {
685713
if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
686714
rc = mshv_run_vp_with_root_scheduler(vp);
687715
else
688716
rc = mshv_run_vp_with_hyp_scheduler(vp);
689717
} while (rc == 0 && mshv_vp_handle_intercept(vp));
690718

719+
trace_mshv_run_vp_exit(vp->vp_partition->pt_id, vp->vp_index,
720+
vp->vp_intercept_msg_page->header.message_type,
721+
rc);
722+
691723
if (rc)
692724
return rc;
693725

@@ -949,6 +981,8 @@ mshv_vp_release(struct inode *inode, struct file *filp)
949981
{
950982
struct mshv_vp *vp = filp->private_data;
951983

984+
trace_mshv_vp_release(vp->vp_partition->pt_id, vp->vp_index);
985+
952986
/* Rest of VP cleanup happens in destroy_partition() */
953987
mshv_partition_put(vp->vp_partition);
954988
return 0;
@@ -1121,7 +1155,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
11211155
partition->pt_vp_count++;
11221156
partition->pt_vp_array[args.vp_index] = vp;
11231157

1124-
return ret;
1158+
goto out;
11251159

11261160
remove_debugfs_vp:
11271161
mshv_debugfs_vp_remove(vp);
@@ -1147,6 +1181,8 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
11471181
intercept_msg_page, input_vtl_zero);
11481182
destroy_vp:
11491183
hv_call_delete_vp(partition->pt_id, args.vp_index);
1184+
out:
1185+
trace_mshv_create_vp(partition->pt_id, args.vp_index, ret);
11501186
return ret;
11511187
}
11521188

@@ -1346,6 +1382,10 @@ mshv_map_user_memory(struct mshv_partition *partition,
13461382
break;
13471383
}
13481384

1385+
trace_mshv_map_user_memory(partition->pt_id, region->start_uaddr,
1386+
region->start_gfn, region->nr_pages,
1387+
region->hv_map_flags, ret);
1388+
13491389
if (ret)
13501390
goto errout;
13511391

@@ -1641,6 +1681,9 @@ disable_vp_dispatch(struct mshv_vp *vp)
16411681
if (ret)
16421682
vp_err(vp, "failed to suspend\n");
16431683

1684+
trace_mshv_disable_vp_dispatch(vp->vp_partition->pt_id,
1685+
vp->vp_index, ret);
1686+
16441687
return ret;
16451688
}
16461689

@@ -1689,6 +1732,8 @@ drain_vp_signals(struct mshv_vp *vp)
16891732
vp->run.kicked_by_hv = 0;
16901733
vp_signal_count = atomic64_read(&vp->run.vp_signaled_count);
16911734
}
1735+
1736+
trace_mshv_drain_vp_signals(vp->vp_partition->pt_id, vp->vp_index);
16921737
}
16931738

16941739
static void drain_all_vps(const struct mshv_partition *partition)
@@ -1742,6 +1787,8 @@ static void destroy_partition(struct mshv_partition *partition)
17421787
return;
17431788
}
17441789

1790+
trace_mshv_destroy_partition(partition->pt_id);
1791+
17451792
if (partition->pt_initialized) {
17461793
/*
17471794
* We only need to drain signals for root scheduler. This should be
@@ -1848,6 +1895,8 @@ mshv_partition_release(struct inode *inode, struct file *filp)
18481895
{
18491896
struct mshv_partition *partition = filp->private_data;
18501897

1898+
trace_mshv_partition_release(partition->pt_id);
1899+
18511900
mshv_eventfd_release(partition);
18521901

18531902
cleanup_srcu_struct(&partition->pt_irq_srcu);
@@ -1977,6 +2026,7 @@ mshv_ioctl_create_partition(void __user *user_arg, struct device *module_dev)
19772026
struct hv_partition_creation_properties creation_properties;
19782027
union hv_partition_isolation_properties isolation_properties;
19792028
struct mshv_partition *partition;
2029+
u64 pt_id = -1;
19802030
long ret;
19812031

19822032
ret = mshv_ioctl_process_pt_flags(user_arg, &creation_flags,
@@ -2016,30 +2066,38 @@ mshv_ioctl_create_partition(void __user *user_arg, struct device *module_dev)
20162066
ret = hv_call_create_partition(creation_flags,
20172067
creation_properties,
20182068
isolation_properties,
2019-
&partition->pt_id);
2069+
&pt_id);
20202070
if (ret)
20212071
goto cleanup_irq_srcu;
20222072

2073+
partition->pt_id = pt_id;
2074+
20232075
ret = add_partition(partition);
20242076
if (ret)
20252077
goto delete_partition;
20262078

20272079
ret = mshv_init_async_handler(partition);
2028-
if (!ret) {
2029-
ret = FD_ADD(O_CLOEXEC, anon_inode_getfile("mshv_partition",
2030-
&mshv_partition_fops,
2031-
partition, O_RDWR));
2032-
if (ret >= 0)
2033-
return ret;
2034-
}
2080+
if (ret)
2081+
goto remove_partition;
2082+
2083+
ret = FD_ADD(O_CLOEXEC, anon_inode_getfile("mshv_partition",
2084+
&mshv_partition_fops,
2085+
partition, O_RDWR));
2086+
if (ret < 0)
2087+
goto remove_partition;
2088+
2089+
goto out;
2090+
2091+
remove_partition:
20352092
remove_partition(partition);
20362093
delete_partition:
20372094
hv_call_delete_partition(partition->pt_id);
20382095
cleanup_irq_srcu:
20392096
cleanup_srcu_struct(&partition->pt_irq_srcu);
20402097
free_partition:
20412098
kfree(partition);
2042-
2099+
out:
2100+
trace_mshv_create_partition(pt_id, ret);
20432101
return ret;
20442102
}
20452103

drivers/hv/mshv_trace.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2026, Microsoft Corporation.
4+
*
5+
* Tracepoint definitions for mshv driver.
6+
*/
7+
8+
#define CREATE_TRACE_POINTS
9+
#include "mshv_trace.h"

0 commit comments

Comments
 (0)