From: Manali Shukla <Manali.Shukla@xxxxxxx> 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@xxxxxxx> --- .../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, + 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