Message ID | 20240501145433.4070-5-manali.shukla@amd.com |
---|---|
State | New |
Headers | show |
Series | Add support for the Idle HLT intercept feature | expand |
On Wed, May 01, 2024 at 02:54:32PM GMT, Manali Shukla wrote: > From: Manali Shukla <Manali.Shukla@amd.com> > > The interface is used to read the data values of a specified vcpu stat > from the currenly available binary stats interface. > > Signed-off-by: Manali Shukla <Manali.Shukla@amd.com> > --- > .../testing/selftests/kvm/include/kvm_util.h | 66 +++++++++++++++++++ > tools/testing/selftests/kvm/lib/kvm_util.c | 32 +++++++++ > 2 files changed, 98 insertions(+) > > diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h > index 63c2aaae51f3..7dad3275a4d3 100644 > --- a/tools/testing/selftests/kvm/include/kvm_util.h > +++ b/tools/testing/selftests/kvm/include/kvm_util.h > @@ -518,6 +518,72 @@ static inline uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name) > return data; > } > > +/* > + * Ensure that the sequence of the enum vcpu_stat_types matches the order of > + * kvm_vcpu_stats_desc[]. Otherwise, vcpu_get_stat() may return incorrect data > + * because __vcpu_get_stat() uses the enum type as an index to get the > + * descriptor for a given stat and then uses read_stat_data() to get the stats > + * from the descriptor. > + */ > +enum vcpu_stat_types { > + HALT_SUCCESSFUL_POLL, > + HALT_ATTEMPTED_POLL, > + HALT_POLL_INVALID, > + HALT_WAKEUP, > + HALT_POLL_SUCCESS_NS, > + HALT_POLL_FAIL_NS, > + HALT_WAIT_NS, > + HALT_POLL_SUCCESS_HIST, > + HALT_POLL_FAIL_HIST, > + HALT_WAIT_HIST, > + BLOCKING, Everything below here is x86 specific, but this is an arch-neutral file. Please structure this in a way that each architecture can share the generic types and also provide its own. Thanks, drew > + PF_TAKEN, > + PF_FIXED, > + PF_EMULATE, > + PF_SPURIOUS, > + PF_FAST, > + PF_MMIO_SPTE_CREATED, > + PF_GUEST, > + TLB_FLUSH, > + INVLPG, > + EXITS, > + IO_EXITS, > + MMIO_EXITS, > + SIGNAL_EXITS, > + IRQ_WINDOW_EXITS, > + NMI_WINDOW_EXITS, > + LD_FLUSH, > + HALT_EXITS, > + REQUEST_IRQ_EXITS, > + IRQ_EXITS, > + HOST_STATE_RELOAD, > + FPU_RELOAD, > + INSN_EMULATION, > + INSN_EMULATION_FAIL, > + HYPERCALLS, > + IRQ_INJECTIONS, > + NMI_INJECTIONS, > + REQ_EVENT, > + NESTED_RUN, > + DIRECTED_YIELD_ATTEMPTED, > + DIRECTED_YIELD_SUCCESSFUL, > + PREEMPTION_REPORTED, > + PREEMPTION_OTHER, > + GUEST_MODE, > + NOTIFY_WINDOW_EXITS, > +}; > + > +void __vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type, uint64_t *data, > + size_t max_elements); > + > +static inline uint64_t vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type) > +{ > + uint64_t data; > + > + __vcpu_get_stat(vcpu, type, &data, 1); > + return data; > +} > + > void vm_create_irqchip(struct kvm_vm *vm); > > static inline int __vm_create_guest_memfd(struct kvm_vm *vm, uint64_t size, > diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c > index 6b2158655baa..3de292ca9280 100644 > --- a/tools/testing/selftests/kvm/lib/kvm_util.c > +++ b/tools/testing/selftests/kvm/lib/kvm_util.c > @@ -2256,6 +2256,38 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header, > desc->name, size, ret); > } > > +/* > + * Read the data of the named vcpu stat > + * > + * Input Args: > + * vcpu - the vcpu for which the stat should be read > + * stat_name - the name of the stat to read > + * max_elements - the maximum number of 8-byte values to read into data > + * > + * Output Args: > + * data - the buffer into which stat data should be read > + * > + * Read the data values of a specified stat from the binary stats interface. > + */ > +void __vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type, uint64_t *data, > + size_t max_elements) > +{ > + int vcpu_stats_fd; > + struct kvm_stats_header header; > + struct kvm_stats_desc *desc, *t_desc; > + size_t size_desc; > + > + vcpu_stats_fd = vcpu_get_stats_fd(vcpu); > + read_stats_header(vcpu_stats_fd, &header); > + > + desc = read_stats_descriptors(vcpu_stats_fd, &header); > + size_desc = get_stats_descriptor_size(&header); > + > + t_desc = (void *)desc + (type * size_desc); > + read_stat_data(vcpu_stats_fd, &header, t_desc, > + data, max_elements); > +} > + > /* > * Read the data of the named stat > * > -- > 2.34.1 >
On 5/2/2024 6:44 PM, Andrew Jones wrote: > On Wed, May 01, 2024 at 02:54:32PM GMT, Manali Shukla wrote: >> From: Manali Shukla <Manali.Shukla@amd.com> >> >> The interface is used to read the data values of a specified vcpu stat >> from the currenly available binary stats interface. >> >> Signed-off-by: Manali Shukla <Manali.Shukla@amd.com> >> --- >> .../testing/selftests/kvm/include/kvm_util.h | 66 +++++++++++++++++++ >> tools/testing/selftests/kvm/lib/kvm_util.c | 32 +++++++++ >> 2 files changed, 98 insertions(+) >> >> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h >> index 63c2aaae51f3..7dad3275a4d3 100644 >> --- a/tools/testing/selftests/kvm/include/kvm_util.h >> +++ b/tools/testing/selftests/kvm/include/kvm_util.h >> @@ -518,6 +518,72 @@ static inline uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name) >> return data; >> } >> >> +/* >> + * Ensure that the sequence of the enum vcpu_stat_types matches the order of >> + * kvm_vcpu_stats_desc[]. Otherwise, vcpu_get_stat() may return incorrect data >> + * because __vcpu_get_stat() uses the enum type as an index to get the >> + * descriptor for a given stat and then uses read_stat_data() to get the stats >> + * from the descriptor. >> + */ >> +enum vcpu_stat_types { >> + HALT_SUCCESSFUL_POLL, >> + HALT_ATTEMPTED_POLL, >> + HALT_POLL_INVALID, >> + HALT_WAKEUP, >> + HALT_POLL_SUCCESS_NS, >> + HALT_POLL_FAIL_NS, >> + HALT_WAIT_NS, >> + HALT_POLL_SUCCESS_HIST, >> + HALT_POLL_FAIL_HIST, >> + HALT_WAIT_HIST, >> + BLOCKING, > > Everything below here is x86 specific, but this is an arch-neutral file. > Please structure this in a way that each architecture can share the > generic types and also provide its own. > > Thanks, > drew Thank you for reviewing my patches. Sure. I will take care of it in the next version. -Manali > >> + PF_TAKEN, >> + PF_FIXED, >> + PF_EMULATE, >> + PF_SPURIOUS, >> + PF_FAST, >> + PF_MMIO_SPTE_CREATED, >> + PF_GUEST, >> + TLB_FLUSH, >> + INVLPG, >> + EXITS, >> + IO_EXITS, >> + MMIO_EXITS, >> + SIGNAL_EXITS, >> + IRQ_WINDOW_EXITS, >> + NMI_WINDOW_EXITS, >> + LD_FLUSH, >> + HALT_EXITS, >> + REQUEST_IRQ_EXITS, >> + IRQ_EXITS, >> + HOST_STATE_RELOAD, >> + FPU_RELOAD, >> + INSN_EMULATION, >> + INSN_EMULATION_FAIL, >> + HYPERCALLS, >> + IRQ_INJECTIONS, >> + NMI_INJECTIONS, >> + REQ_EVENT, >> + NESTED_RUN, >> + DIRECTED_YIELD_ATTEMPTED, >> + DIRECTED_YIELD_SUCCESSFUL, >> + PREEMPTION_REPORTED, >> + PREEMPTION_OTHER, >> + GUEST_MODE, >> + NOTIFY_WINDOW_EXITS, >> +}; >> + >> +void __vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type, uint64_t *data, >> + size_t max_elements); >> + >> +static inline uint64_t vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type) >> +{ >> + uint64_t data; >> + >> + __vcpu_get_stat(vcpu, type, &data, 1); >> + return data; >> +} >> + >> void vm_create_irqchip(struct kvm_vm *vm); >> >> static inline int __vm_create_guest_memfd(struct kvm_vm *vm, uint64_t size, >> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c >> index 6b2158655baa..3de292ca9280 100644 >> --- a/tools/testing/selftests/kvm/lib/kvm_util.c >> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c >> @@ -2256,6 +2256,38 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header, >> desc->name, size, ret); >> } >> >> +/* >> + * Read the data of the named vcpu stat >> + * >> + * Input Args: >> + * vcpu - the vcpu for which the stat should be read >> + * stat_name - the name of the stat to read >> + * max_elements - the maximum number of 8-byte values to read into data >> + * >> + * Output Args: >> + * data - the buffer into which stat data should be read >> + * >> + * Read the data values of a specified stat from the binary stats interface. >> + */ >> +void __vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type, uint64_t *data, >> + size_t max_elements) >> +{ >> + int vcpu_stats_fd; >> + struct kvm_stats_header header; >> + struct kvm_stats_desc *desc, *t_desc; >> + size_t size_desc; >> + >> + vcpu_stats_fd = vcpu_get_stats_fd(vcpu); >> + read_stats_header(vcpu_stats_fd, &header); >> + >> + desc = read_stats_descriptors(vcpu_stats_fd, &header); >> + size_desc = get_stats_descriptor_size(&header); >> + >> + t_desc = (void *)desc + (type * size_desc); >> + read_stat_data(vcpu_stats_fd, &header, t_desc, >> + data, max_elements); >> +} >> + >> /* >> * Read the data of the named stat >> * >> -- >> 2.34.1 >>
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 63c2aaae51f3..7dad3275a4d3 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -518,6 +518,72 @@ static inline uint64_t vm_get_stat(struct kvm_vm *vm, const char *stat_name) return data; } +/* + * Ensure that the sequence of the enum vcpu_stat_types matches the order of + * kvm_vcpu_stats_desc[]. Otherwise, vcpu_get_stat() may return incorrect data + * because __vcpu_get_stat() uses the enum type as an index to get the + * descriptor for a given stat and then uses read_stat_data() to get the stats + * from the descriptor. + */ +enum vcpu_stat_types { + HALT_SUCCESSFUL_POLL, + HALT_ATTEMPTED_POLL, + HALT_POLL_INVALID, + HALT_WAKEUP, + HALT_POLL_SUCCESS_NS, + HALT_POLL_FAIL_NS, + HALT_WAIT_NS, + HALT_POLL_SUCCESS_HIST, + HALT_POLL_FAIL_HIST, + HALT_WAIT_HIST, + BLOCKING, + PF_TAKEN, + PF_FIXED, + PF_EMULATE, + PF_SPURIOUS, + PF_FAST, + PF_MMIO_SPTE_CREATED, + PF_GUEST, + TLB_FLUSH, + INVLPG, + EXITS, + IO_EXITS, + MMIO_EXITS, + SIGNAL_EXITS, + IRQ_WINDOW_EXITS, + NMI_WINDOW_EXITS, + LD_FLUSH, + HALT_EXITS, + REQUEST_IRQ_EXITS, + IRQ_EXITS, + HOST_STATE_RELOAD, + FPU_RELOAD, + INSN_EMULATION, + INSN_EMULATION_FAIL, + HYPERCALLS, + IRQ_INJECTIONS, + NMI_INJECTIONS, + REQ_EVENT, + NESTED_RUN, + DIRECTED_YIELD_ATTEMPTED, + DIRECTED_YIELD_SUCCESSFUL, + PREEMPTION_REPORTED, + PREEMPTION_OTHER, + GUEST_MODE, + NOTIFY_WINDOW_EXITS, +}; + +void __vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type, uint64_t *data, + size_t max_elements); + +static inline uint64_t vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type) +{ + uint64_t data; + + __vcpu_get_stat(vcpu, type, &data, 1); + return data; +} + void vm_create_irqchip(struct kvm_vm *vm); static inline int __vm_create_guest_memfd(struct kvm_vm *vm, uint64_t size, diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 6b2158655baa..3de292ca9280 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2256,6 +2256,38 @@ void read_stat_data(int stats_fd, struct kvm_stats_header *header, desc->name, size, ret); } +/* + * Read the data of the named vcpu stat + * + * Input Args: + * vcpu - the vcpu for which the stat should be read + * stat_name - the name of the stat to read + * max_elements - the maximum number of 8-byte values to read into data + * + * Output Args: + * data - the buffer into which stat data should be read + * + * Read the data values of a specified stat from the binary stats interface. + */ +void __vcpu_get_stat(struct kvm_vcpu *vcpu, enum vcpu_stat_types type, uint64_t *data, + size_t max_elements) +{ + int vcpu_stats_fd; + struct kvm_stats_header header; + struct kvm_stats_desc *desc, *t_desc; + size_t size_desc; + + vcpu_stats_fd = vcpu_get_stats_fd(vcpu); + read_stats_header(vcpu_stats_fd, &header); + + desc = read_stats_descriptors(vcpu_stats_fd, &header); + size_desc = get_stats_descriptor_size(&header); + + t_desc = (void *)desc + (type * size_desc); + read_stat_data(vcpu_stats_fd, &header, t_desc, + data, max_elements); +} + /* * Read the data of the named stat *