kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Remove duplicated stats definitions for debugfs
@ 2021-06-14  2:53 Jing Zhang
  2021-06-14  2:53 ` [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition Jing Zhang
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14  2:53 UTC (permalink / raw)
  To: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini, Fuad Tabba
  Cc: Jing Zhang

This is a follow-up patchset to binary stats interface patchset as below:
https://lore.kernel.org/kvm/20210611124624.1404010-1-jingzhangos@google.com

This patchset contains a commit to fix some missing stats and add static
check to make sure we have the right number of stats descriptors and add an
'offset' field in stats descriptor to make sure the or order of stats
descriptors is not relevant to the order of stats in vm/vcpu stats
structure. This will totally avoid the possibility of missing stats and
mismatched stats definitions.

The binary stats interface defines stats in another array of descriptors,
while the original stats debugfs interface uses array of kvm_stats_debugfs
item. To remove the duplicated stats definition, this patchset would
utilize only the stats descriptors to provide stats information to debugfs
interface. This patchset adds a 'mode' flag to support the read/write mode
of stats, which can be used to indicate the file permission of debugfs
stats files. It removes the usage of kvm_stats_debugfs_item and all the
debugfs_entries defined in all archs.

The patch also fixes an issue that read only stats could be cleared in
global level, though not permitted in VM level in the original debugfs
code.

---

Jing Zhang (4):
  KVM: stats: Make sure no missing or mismatched binary stats definition
  KVM: stats: Use binary stats descriptors for debugfs interface
  KVM: stats: Update documentation supporting stats mode and offset
  KVM: selftests: Update binary stats test for stats mode

 Documentation/virt/kvm/api.rst                |  33 +-
 arch/arm64/kvm/guest.c                        |  32 +-
 arch/mips/kvm/mips.c                          |  99 ++----
 arch/powerpc/kvm/book3s.c                     | 101 ++----
 arch/powerpc/kvm/booke.c                      |  79 ++---
 arch/s390/kvm/kvm-s390.c                      | 307 ++++++------------
 arch/x86/kvm/x86.c                            | 120 +++----
 include/linux/kvm_host.h                      | 186 ++++++-----
 include/uapi/linux/kvm.h                      |  11 +-
 .../selftests/kvm/kvm_binary_stats_test.c     |  13 +-
 virt/kvm/kvm_main.c                           | 105 ++++--
 11 files changed, 477 insertions(+), 609 deletions(-)


base-commit: 39be2e28180a2e87af5fbb8d83643812e1a3b371
-- 
2.32.0.272.g935e593368-goog


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition
  2021-06-14  2:53 [PATCH 0/4] Remove duplicated stats definitions for debugfs Jing Zhang
@ 2021-06-14  2:53 ` Jing Zhang
  2021-06-14  9:49   ` Fuad Tabba
  2021-06-16 12:55   ` kernel test robot
  2021-06-14  2:53 ` [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface Jing Zhang
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14  2:53 UTC (permalink / raw)
  To: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini, Fuad Tabba
  Cc: Jing Zhang

Add static check to make sure the number of stats descriptors equals
the number of stats defined in vm/vcpu stats structures.
Add offset field in stats descriptor to let us define stats
descriptors freely, don't have to be in the same order as
stats in vm/vcpu stats structures.
Also fix some missing/mismatched stats from previous patch.

Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
 arch/arm64/kvm/guest.c    |  16 +--
 arch/mips/kvm/mips.c      |  60 ++++++------
 arch/powerpc/kvm/book3s.c |  68 +++++++------
 arch/powerpc/kvm/booke.c  |  54 ++++++-----
 arch/s390/kvm/kvm-s390.c  | 199 +++++++++++++++++++-------------------
 arch/x86/kvm/x86.c        |  73 +++++++-------
 include/linux/kvm_host.h  | 151 ++++++++++++++++++-----------
 include/uapi/linux/kvm.h  |   4 +-
 8 files changed, 342 insertions(+), 283 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 7048603f4b26..99842e29c2de 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -31,6 +31,8 @@
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS()
 };
+static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
+		sizeof(struct kvm_vm_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vm_stats_header = {
 	{
@@ -44,13 +46,15 @@ struct _kvm_stats_header kvm_vm_stats_header = {
 
 struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
-	STATS_DESC_COUNTER("hvc_exit_stat"),
-	STATS_DESC_COUNTER("wfe_exit_stat"),
-	STATS_DESC_COUNTER("wfi_exit_stat"),
-	STATS_DESC_COUNTER("mmio_exit_user"),
-	STATS_DESC_COUNTER("mmio_exit_kernel"),
-	STATS_DESC_COUNTER("exits")
+	STATS_DESC_COUNTER(VCPU, hvc_exit_stat),
+	STATS_DESC_COUNTER(VCPU, wfe_exit_stat),
+	STATS_DESC_COUNTER(VCPU, wfi_exit_stat),
+	STATS_DESC_COUNTER(VCPU, mmio_exit_user),
+	STATS_DESC_COUNTER(VCPU, mmio_exit_kernel),
+	STATS_DESC_COUNTER(VCPU, exits)
 };
+static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
+		sizeof(struct kvm_vcpu_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vcpu_stats_header = {
 	{
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 8fc70539a83b..67404f0947aa 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -41,6 +41,8 @@
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS()
 };
+static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
+		sizeof(struct kvm_vm_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vm_stats_header = {
 	{
@@ -54,38 +56,38 @@ struct _kvm_stats_header kvm_vm_stats_header = {
 
 struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
-	STATS_DESC_COUNTER("wait_exits"),
-	STATS_DESC_COUNTER("cache_exits"),
-	STATS_DESC_COUNTER("signal_exits"),
-	STATS_DESC_COUNTER("int_exits"),
-	STATS_DESC_COUNTER("cop_unusable_exits"),
-	STATS_DESC_COUNTER("tlbmod_exits"),
-	STATS_DESC_COUNTER("tlbmiss_ld_exits"),
-	STATS_DESC_COUNTER("tlbmiss_st_exits"),
-	STATS_DESC_COUNTER("addrerr_st_exits"),
-	STATS_DESC_COUNTER("addrerr_ld_exits"),
-	STATS_DESC_COUNTER("syscall_exits"),
-	STATS_DESC_COUNTER("resvd_inst_exits"),
-	STATS_DESC_COUNTER("break_inst_exits"),
-	STATS_DESC_COUNTER("trap_inst_exits"),
-	STATS_DESC_COUNTER("msa_fpe_exits"),
-	STATS_DESC_COUNTER("fpe_exits"),
-	STATS_DESC_COUNTER("msa_disabled_exits"),
-	STATS_DESC_COUNTER("flush_dcache_exits"),
-#ifdef CONFIG_KVM_MIPS_VZ
-	STATS_DESC_COUNTER("vz_gpsi_exits"),
-	STATS_DESC_COUNTER("vz_gsfc_exits"),
-	STATS_DESC_COUNTER("vz_hc_exits"),
-	STATS_DESC_COUNTER("vz_grr_exits"),
-	STATS_DESC_COUNTER("vz_gva_exits"),
-	STATS_DESC_COUNTER("vz_ghfc_exits"),
-	STATS_DESC_COUNTER("vz_gpa_exits"),
-	STATS_DESC_COUNTER("vz_resvd_exits"),
+	STATS_DESC_COUNTER(VCPU, wait_exits),
+	STATS_DESC_COUNTER(VCPU, cache_exits),
+	STATS_DESC_COUNTER(VCPU, signal_exits),
+	STATS_DESC_COUNTER(VCPU, int_exits),
+	STATS_DESC_COUNTER(VCPU, cop_unusable_exits),
+	STATS_DESC_COUNTER(VCPU, tlbmod_exits),
+	STATS_DESC_COUNTER(VCPU, tlbmiss_ld_exits),
+	STATS_DESC_COUNTER(VCPU, tlbmiss_st_exits),
+	STATS_DESC_COUNTER(VCPU, addrerr_st_exits),
+	STATS_DESC_COUNTER(VCPU, addrerr_ld_exits),
+	STATS_DESC_COUNTER(VCPU, syscall_exits),
+	STATS_DESC_COUNTER(VCPU, resvd_inst_exits),
+	STATS_DESC_COUNTER(VCPU, break_inst_exits),
+	STATS_DESC_COUNTER(VCPU, trap_inst_exits),
+	STATS_DESC_COUNTER(VCPU, msa_fpe_exits),
+	STATS_DESC_COUNTER(VCPU, fpe_exits),
+	STATS_DESC_COUNTER(VCPU, msa_disabled_exits),
+	STATS_DESC_COUNTER(VCPU, flush_dcache_exits),
+	STATS_DESC_COUNTER(VCPU, vz_gpsi_exits),
+	STATS_DESC_COUNTER(VCPU, vz_gsfc_exits),
+	STATS_DESC_COUNTER(VCPU, vz_hc_exits),
+	STATS_DESC_COUNTER(VCPU, vz_grr_exits),
+	STATS_DESC_COUNTER(VCPU, vz_gva_exits),
+	STATS_DESC_COUNTER(VCPU, vz_ghfc_exits),
+	STATS_DESC_COUNTER(VCPU, vz_gpa_exits),
+	STATS_DESC_COUNTER(VCPU, vz_resvd_exits),
 #ifdef CONFIG_CPU_LOONGSON64
-	STATS_DESC_COUNTER("vz_cpucfg_exits"),
-#endif
+	STATS_DESC_COUNTER(VCPU, vz_cpucfg_exits),
 #endif
 };
+static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
+		sizeof(struct kvm_vcpu_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vcpu_stats_header = {
 	{
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index eff5a96aa638..15436484e521 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -40,9 +40,11 @@
 
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS(),
-	STATS_DESC_ICOUNTER("num_2M_pages"),
-	STATS_DESC_ICOUNTER("num_1G_pages")
+	STATS_DESC_ICOUNTER(VM, num_2M_pages),
+	STATS_DESC_ICOUNTER(VM, num_1G_pages)
 };
+static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
+		sizeof(struct kvm_vm_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vm_stats_header = {
 	{
@@ -56,37 +58,39 @@ struct _kvm_stats_header kvm_vm_stats_header = {
 
 struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
-	STATS_DESC_COUNTER("sum_exits"),
-	STATS_DESC_COUNTER("mmio_exits"),
-	STATS_DESC_COUNTER("signal_exits"),
-	STATS_DESC_COUNTER("light_exits"),
-	STATS_DESC_COUNTER("itlb_real_miss_exits"),
-	STATS_DESC_COUNTER("itlb_virt_miss_exits"),
-	STATS_DESC_COUNTER("dtlb_real_miss_exits"),
-	STATS_DESC_COUNTER("dtlb_virt_miss_exits"),
-	STATS_DESC_COUNTER("syscall_exits"),
-	STATS_DESC_COUNTER("isi_exits"),
-	STATS_DESC_COUNTER("dsi_exits"),
-	STATS_DESC_COUNTER("emulated_inst_exits"),
-	STATS_DESC_COUNTER("dec_exits"),
-	STATS_DESC_COUNTER("ext_intr_exits"),
-	STATS_DESC_TIME_NSEC("halt_wait_ns"),
-	STATS_DESC_COUNTER("halt_successful_wait"),
-	STATS_DESC_COUNTER("dbell_exits"),
-	STATS_DESC_COUNTER("gdbell_exits"),
-	STATS_DESC_COUNTER("ld"),
-	STATS_DESC_COUNTER("st"),
-	STATS_DESC_COUNTER("pf_storage"),
-	STATS_DESC_COUNTER("pf_instruc"),
-	STATS_DESC_COUNTER("sp_storage"),
-	STATS_DESC_COUNTER("sp_instruc"),
-	STATS_DESC_COUNTER("queue_intr"),
-	STATS_DESC_COUNTER("ld_slow"),
-	STATS_DESC_COUNTER("st_slow"),
-	STATS_DESC_COUNTER("pthru_all"),
-	STATS_DESC_COUNTER("pthru_host"),
-	STATS_DESC_COUNTER("pthru_bad_aff")
+	STATS_DESC_COUNTER(VCPU, sum_exits),
+	STATS_DESC_COUNTER(VCPU, mmio_exits),
+	STATS_DESC_COUNTER(VCPU, signal_exits),
+	STATS_DESC_COUNTER(VCPU, light_exits),
+	STATS_DESC_COUNTER(VCPU, itlb_real_miss_exits),
+	STATS_DESC_COUNTER(VCPU, itlb_virt_miss_exits),
+	STATS_DESC_COUNTER(VCPU, dtlb_real_miss_exits),
+	STATS_DESC_COUNTER(VCPU, dtlb_virt_miss_exits),
+	STATS_DESC_COUNTER(VCPU, syscall_exits),
+	STATS_DESC_COUNTER(VCPU, isi_exits),
+	STATS_DESC_COUNTER(VCPU, dsi_exits),
+	STATS_DESC_COUNTER(VCPU, emulated_inst_exits),
+	STATS_DESC_COUNTER(VCPU, dec_exits),
+	STATS_DESC_COUNTER(VCPU, ext_intr_exits),
+	STATS_DESC_TIME_NSEC(VCPU, halt_wait_ns),
+	STATS_DESC_COUNTER(VCPU, halt_successful_wait),
+	STATS_DESC_COUNTER(VCPU, dbell_exits),
+	STATS_DESC_COUNTER(VCPU, gdbell_exits),
+	STATS_DESC_COUNTER(VCPU, ld),
+	STATS_DESC_COUNTER(VCPU, st),
+	STATS_DESC_COUNTER(VCPU, pf_storage),
+	STATS_DESC_COUNTER(VCPU, pf_instruc),
+	STATS_DESC_COUNTER(VCPU, sp_storage),
+	STATS_DESC_COUNTER(VCPU, sp_instruc),
+	STATS_DESC_COUNTER(VCPU, queue_intr),
+	STATS_DESC_COUNTER(VCPU, ld_slow),
+	STATS_DESC_COUNTER(VCPU, st_slow),
+	STATS_DESC_COUNTER(VCPU, pthru_all),
+	STATS_DESC_COUNTER(VCPU, pthru_host),
+	STATS_DESC_COUNTER(VCPU, pthru_bad_aff)
 };
+static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
+		sizeof(struct kvm_vcpu_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vcpu_stats_header = {
 	{
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 5b0c4dff4f10..fbc9b7b6af57 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -38,9 +38,11 @@ unsigned long kvmppc_booke_handlers;
 
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS(),
-	STATS_DESC_ICOUNTER("num_2M_pages"),
-	STATS_DESC_ICOUNTER("num_1G_pages")
+	STATS_DESC_ICOUNTER(VM, num_2M_pages),
+	STATS_DESC_ICOUNTER(VM, num_1G_pages)
 };
+static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
+		sizeof(struct kvm_vm_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vm_stats_header = {
 	{
@@ -54,30 +56,32 @@ struct _kvm_stats_header kvm_vm_stats_header = {
 
 struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
-	STATS_DESC_COUNTER("sum_exits"),
-	STATS_DESC_COUNTER("mmio_exits"),
-	STATS_DESC_COUNTER("signal_exits"),
-	STATS_DESC_COUNTER("light_exits"),
-	STATS_DESC_COUNTER("itlb_real_miss_exits"),
-	STATS_DESC_COUNTER("itlb_virt_miss_exits"),
-	STATS_DESC_COUNTER("dtlb_real_miss_exits"),
-	STATS_DESC_COUNTER("dtlb_virt_miss_exits"),
-	STATS_DESC_COUNTER("syscall_exits"),
-	STATS_DESC_COUNTER("isi_exits"),
-	STATS_DESC_COUNTER("dsi_exits"),
-	STATS_DESC_COUNTER("emulated_inst_exits"),
-	STATS_DESC_COUNTER("dec_exits"),
-	STATS_DESC_COUNTER("ext_intr_exits"),
-	STATS_DESC_TIME_NSEC("halt_wait_ns"),
-	STATS_DESC_COUNTER("halt_successful_wait"),
-	STATS_DESC_COUNTER("dbell_exits"),
-	STATS_DESC_COUNTER("gdbell_exits"),
-	STATS_DESC_COUNTER("ld"),
-	STATS_DESC_COUNTER("st"),
-	STATS_DESC_COUNTER("pthru_all"),
-	STATS_DESC_COUNTER("pthru_host"),
-	STATS_DESC_COUNTER("pthru_bad_aff")
+	STATS_DESC_COUNTER(VCPU, sum_exits),
+	STATS_DESC_COUNTER(VCPU, mmio_exits),
+	STATS_DESC_COUNTER(VCPU, signal_exits),
+	STATS_DESC_COUNTER(VCPU, light_exits),
+	STATS_DESC_COUNTER(VCPU, itlb_real_miss_exits),
+	STATS_DESC_COUNTER(VCPU, itlb_virt_miss_exits),
+	STATS_DESC_COUNTER(VCPU, dtlb_real_miss_exits),
+	STATS_DESC_COUNTER(VCPU, dtlb_virt_miss_exits),
+	STATS_DESC_COUNTER(VCPU, syscall_exits),
+	STATS_DESC_COUNTER(VCPU, isi_exits),
+	STATS_DESC_COUNTER(VCPU, dsi_exits),
+	STATS_DESC_COUNTER(VCPU, emulated_inst_exits),
+	STATS_DESC_COUNTER(VCPU, dec_exits),
+	STATS_DESC_COUNTER(VCPU, ext_intr_exits),
+	STATS_DESC_TIME_NSEC(VCPU, halt_wait_ns),
+	STATS_DESC_COUNTER(VCPU, halt_successful_wait),
+	STATS_DESC_COUNTER(VCPU, dbell_exits),
+	STATS_DESC_COUNTER(VCPU, gdbell_exits),
+	STATS_DESC_COUNTER(VCPU, ld),
+	STATS_DESC_COUNTER(VCPU, st),
+	STATS_DESC_COUNTER(VCPU, pthru_all),
+	STATS_DESC_COUNTER(VCPU, pthru_host),
+	STATS_DESC_COUNTER(VCPU, pthru_bad_aff)
 };
+static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
+		sizeof(struct kvm_vcpu_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vcpu_stats_header = {
 	{
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 522a6ac2e347..b5ca41e04fa5 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -60,12 +60,14 @@
 
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS(),
-	STATS_DESC_COUNTER("inject_io"),
-	STATS_DESC_COUNTER("inject_float_mchk"),
-	STATS_DESC_COUNTER("inject_pfault_done"),
-	STATS_DESC_COUNTER("inject_service_signal"),
-	STATS_DESC_COUNTER("inject_virtio")
+	STATS_DESC_COUNTR(VM, inject_io),
+	STATS_DESC_COUNTR(VM, inject_float_mchk),
+	STATS_DESC_COUNTR(VM, inject_pfault_done),
+	STATS_DESC_COUNTR(VM, inject_service_signal),
+	STATS_DESC_COUNTR(VM, inject_virtio)
 };
+static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
+		sizeof(struct kvm_vm_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vm_stats_header = {
 	{
@@ -79,99 +81,102 @@ struct _kvm_stats_header kvm_vm_stats_header = {
 
 struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
-	STATS_DESC_COUNTER("exit_userspace"),
-	STATS_DESC_COUNTER("exit_null"),
-	STATS_DESC_COUNTER("exit_external_request"),
-	STATS_DESC_COUNTER("exit_io_request"),
-	STATS_DESC_COUNTER("exit_external_interrupt"),
-	STATS_DESC_COUNTER("exit_stop_request"),
-	STATS_DESC_COUNTER("exit_validity"),
-	STATS_DESC_COUNTER("exit_instruction"),
-	STATS_DESC_COUNTER("exit_pei"),
-	STATS_DESC_COUNTER("halt_no_poll_steal"),
-	STATS_DESC_COUNTER("instruction_lctl"),
-	STATS_DESC_COUNTER("instruction_lctlg"),
-	STATS_DESC_COUNTER("instruction_stctl"),
-	STATS_DESC_COUNTER("instruction_stctg"),
-	STATS_DESC_COUNTER("exit_program_interruption"),
-	STATS_DESC_COUNTER("exit_instr_and_program"),
-	STATS_DESC_COUNTER("exit_operation_exception"),
-	STATS_DESC_COUNTER("deliver_ckc"),
-	STATS_DESC_COUNTER("deliver_cputm"),
-	STATS_DESC_COUNTER("deliver_external_call"),
-	STATS_DESC_COUNTER("deliver_emergency_signal"),
-	STATS_DESC_COUNTER("deliver_service_signal"),
-	STATS_DESC_COUNTER("deliver_virtio"),
-	STATS_DESC_COUNTER("deliver_stop_signal"),
-	STATS_DESC_COUNTER("deliver_prefix_signal"),
-	STATS_DESC_COUNTER("deliver_restart_signal"),
-	STATS_DESC_COUNTER("deliver_program"),
-	STATS_DESC_COUNTER("deliver_io"),
-	STATS_DESC_COUNTER("deliver_machine_check"),
-	STATS_DESC_COUNTER("exit_wait_state"),
-	STATS_DESC_COUNTER("inject_ckc"),
-	STATS_DESC_COUNTER("inject_cputm"),
-	STATS_DESC_COUNTER("inject_external_call"),
-	STATS_DESC_COUNTER("inject_emergency_signal"),
-	STATS_DESC_COUNTER("inject_mchk"),
-	STATS_DESC_COUNTER("inject_pfault_init"),
-	STATS_DESC_COUNTER("inject_program"),
-	STATS_DESC_COUNTER("inject_restart"),
-	STATS_DESC_COUNTER("inject_set_prefix"),
-	STATS_DESC_COUNTER("inject_stop_signal"),
-	STATS_DESC_COUNTER("instruction_epsw"),
-	STATS_DESC_COUNTER("instruction_gs"),
-	STATS_DESC_COUNTER("instruction_io_other"),
-	STATS_DESC_COUNTER("instruction_lpsw"),
-	STATS_DESC_COUNTER("instruction_lpswe"),
-	STATS_DESC_COUNTER("instruction_pfmf"),
-	STATS_DESC_COUNTER("instruction_ptff"),
-	STATS_DESC_COUNTER("instruction_sck"),
-	STATS_DESC_COUNTER("instruction_sckpf"),
-	STATS_DESC_COUNTER("instruction_stidp"),
-	STATS_DESC_COUNTER("instruction_spx"),
-	STATS_DESC_COUNTER("instruction_stpx"),
-	STATS_DESC_COUNTER("instruction_stap"),
-	STATS_DESC_COUNTER("instruction_iske"),
-	STATS_DESC_COUNTER("instruction_ri"),
-	STATS_DESC_COUNTER("instruction_rrbe"),
-	STATS_DESC_COUNTER("instruction_sske"),
-	STATS_DESC_COUNTER("instruction_ipte_interlock"),
-	STATS_DESC_COUNTER("instruction_stsi"),
-	STATS_DESC_COUNTER("instruction_stfl"),
-	STATS_DESC_COUNTER("instruction_tb"),
-	STATS_DESC_COUNTER("instruction_tpi"),
-	STATS_DESC_COUNTER("instruction_tprot"),
-	STATS_DESC_COUNTER("instruction_tsch"),
-	STATS_DESC_COUNTER("instruction_sie"),
-	STATS_DESC_COUNTER("instruction_essa"),
-	STATS_DESC_COUNTER("instruction_sthyi"),
-	STATS_DESC_COUNTER("instruction_sigp_sense"),
-	STATS_DESC_COUNTER("instruction_sigp_sense_running"),
-	STATS_DESC_COUNTER("instruction_sigp_external_call"),
-	STATS_DESC_COUNTER("instruction_sigp_emergency"),
-	STATS_DESC_COUNTER("instruction_sigp_cond_emergency"),
-	STATS_DESC_COUNTER("instruction_sigp_start"),
-	STATS_DESC_COUNTER("instruction_sigp_stop"),
-	STATS_DESC_COUNTER("instruction_sigp_stop_store_status"),
-	STATS_DESC_COUNTER("instruction_sigp_store_status"),
-	STATS_DESC_COUNTER("instruction_sigp_store_adtl_status"),
-	STATS_DESC_COUNTER("instruction_sigp_arch"),
-	STATS_DESC_COUNTER("instruction_sigp_prefix"),
-	STATS_DESC_COUNTER("instruction_sigp_restart"),
-	STATS_DESC_COUNTER("instruction_sigp_init_cpu_reset"),
-	STATS_DESC_COUNTER("instruction_sigp_cpu_reset"),
-	STATS_DESC_COUNTER("instruction_sigp_unknown"),
-	STATS_DESC_COUNTER("diagnose_10"),
-	STATS_DESC_COUNTER("diagnose_44"),
-	STATS_DESC_COUNTER("diagnose_9c"),
-	STATS_DESC_COUNTER("diagnose_9c_ignored"),
-	STATS_DESC_COUNTER("diagnose_258"),
-	STATS_DESC_COUNTER("diagnose_308"),
-	STATS_DESC_COUNTER("diagnose_500"),
-	STATS_DESC_COUNTER("diagnose_other"),
-	STATS_DESC_COUNTER("pfault_sync")
+	STATS_DESC_COUNTER(VCPU, exit_userspace),
+	STATS_DESC_COUNTER(VCPU, exit_null),
+	STATS_DESC_COUNTER(VCPU, exit_external_request),
+	STATS_DESC_COUNTER(VCPU, exit_io_request),
+	STATS_DESC_COUNTER(VCPU, exit_external_interrupt),
+	STATS_DESC_COUNTER(VCPU, exit_stop_request),
+	STATS_DESC_COUNTER(VCPU, exit_validity),
+	STATS_DESC_COUNTER(VCPU, exit_instruction),
+	STATS_DESC_COUNTER(VCPU, exit_pei),
+	STATS_DESC_COUNTER(VCPU, halt_no_poll_steal),
+	STATS_DESC_COUNTER(VCPU, instruction_lctl),
+	STATS_DESC_COUNTER(VCPU, instruction_lctlg),
+	STATS_DESC_COUNTER(VCPU, instruction_stctl),
+	STATS_DESC_COUNTER(VCPU, instruction_stctg),
+	STATS_DESC_COUNTER(VCPU, exit_program_interruption),
+	STATS_DESC_COUNTER(VCPU, exit_instr_and_program),
+	STATS_DESC_COUNTER(VCPU, exit_operation_exception),
+	STATS_DESC_COUNTER(VCPU, deliver_ckc),
+	STATS_DESC_COUNTER(VCPU, deliver_cputm),
+	STATS_DESC_COUNTER(VCPU, deliver_external_call),
+	STATS_DESC_COUNTER(VCPU, deliver_emergency_signal),
+	STATS_DESC_COUNTER(VCPU, deliver_service_signal),
+	STATS_DESC_COUNTER(VCPU, deliver_virtio),
+	STATS_DESC_COUNTER(VCPU, deliver_stop_signal),
+	STATS_DESC_COUNTER(VCPU, deliver_prefix_signal),
+	STATS_DESC_COUNTER(VCPU, deliver_restart_signal),
+	STATS_DESC_COUNTER(VCPU, deliver_program),
+	STATS_DESC_COUNTER(VCPU, deliver_io),
+	STATS_DESC_COUNTER(VCPU, deliver_machine_check),
+	STATS_DESC_COUNTER(VCPU, exit_wait_state),
+	STATS_DESC_COUNTER(VCPU, inject_ckc),
+	STATS_DESC_COUNTER(VCPU, inject_cputm),
+	STATS_DESC_COUNTER(VCPU, inject_external_call),
+	STATS_DESC_COUNTER(VCPU, inject_emergency_signal),
+	STATS_DESC_COUNTER(VCPU, inject_mchk),
+	STATS_DESC_COUNTER(VCPU, inject_pfault_init),
+	STATS_DESC_COUNTER(VCPU, inject_program),
+	STATS_DESC_COUNTER(VCPU, inject_restart),
+	STATS_DESC_COUNTER(VCPU, inject_set_prefix),
+	STATS_DESC_COUNTER(VCPU, inject_stop_signal),
+	STATS_DESC_COUNTER(VCPU, instruction_epsw),
+	STATS_DESC_COUNTER(VCPU, instruction_gs),
+	STATS_DESC_COUNTER(VCPU, instruction_io_other),
+	STATS_DESC_COUNTER(VCPU, instruction_lpsw),
+	STATS_DESC_COUNTER(VCPU, instruction_lpswe),
+	STATS_DESC_COUNTER(VCPU, instruction_pfmf),
+	STATS_DESC_COUNTER(VCPU, instruction_ptff),
+	STATS_DESC_COUNTER(VCPU, instruction_sck),
+	STATS_DESC_COUNTER(VCPU, instruction_sckpf),
+	STATS_DESC_COUNTER(VCPU, instruction_stidp),
+	STATS_DESC_COUNTER(VCPU, instruction_spx),
+	STATS_DESC_COUNTER(VCPU, instruction_stpx),
+	STATS_DESC_COUNTER(VCPU, instruction_stap),
+	STATS_DESC_COUNTER(VCPU, instruction_iske),
+	STATS_DESC_COUNTER(VCPU, instruction_ri),
+	STATS_DESC_COUNTER(VCPU, instruction_rrbe),
+	STATS_DESC_COUNTER(VCPU, instruction_sske),
+	STATS_DESC_COUNTER(VCPU, instruction_ipte_interlock),
+	STATS_DESC_COUNTER(VCPU, instruction_stsi),
+	STATS_DESC_COUNTER(VCPU, instruction_stfl),
+	STATS_DESC_COUNTER(VCPU, instruction_tb),
+	STATS_DESC_COUNTER(VCPU, instruction_tpi),
+	STATS_DESC_COUNTER(VCPU, instruction_tprot),
+	STATS_DESC_COUNTER(VCPU, instruction_tsch),
+	STATS_DESC_COUNTER(VCPU, instruction_sie),
+	STATS_DESC_COUNTER(VCPU, instruction_essa),
+	STATS_DESC_COUNTER(VCPU, instruction_sthyi),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_sense),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_sense_running),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_external_call),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_emergency),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_cond_emergency),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_start),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_stop),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_stop_store_status),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_store_status),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_store_adtl_status),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_arch),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_prefix),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_restart),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_init_cpu_reset),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_cpu_reset),
+	STATS_DESC_COUNTER(VCPU, instruction_sigp_unknown),
+	STATS_DESC_COUNTER(VCPU, diagnose_10),
+	STATS_DESC_COUNTER(VCPU, diagnose_44),
+	STATS_DESC_COUNTER(VCPU, diagnose_9c),
+	STATS_DESC_COUNTER(VCPU, diagnose_9c_ignored),
+	STATS_DESC_COUNTER(VCPU, diagnose_9c_forward),
+	STATS_DESC_COUNTER(VCPU, diagnose_258),
+	STATS_DESC_COUNTER(VCPU, diagnose_308),
+	STATS_DESC_COUNTER(VCPU, diagnose_500),
+	STATS_DESC_COUNTER(VCPU, diagnose_other),
+	STATS_DESC_COUNTER(VCPU, pfault_sync)
 };
+static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
+		sizeof(struct kvm_vcpu_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vcpu_stats_header = {
 	{
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index acc28473dec7..84438573b529 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -225,17 +225,19 @@ EXPORT_SYMBOL_GPL(supported_xss);
 
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS(),
-	STATS_DESC_COUNTER("mmu_shadow_zapped"),
-	STATS_DESC_COUNTER("mmu_pte_write"),
-	STATS_DESC_COUNTER("mmu_pde_zapped"),
-	STATS_DESC_COUNTER("mmu_flooded"),
-	STATS_DESC_COUNTER("mmu_recycled"),
-	STATS_DESC_COUNTER("mmu_cache_miss"),
-	STATS_DESC_ICOUNTER("mmu_unsync"),
-	STATS_DESC_ICOUNTER("largepages"),
-	STATS_DESC_ICOUNTER("nx_largepages_splits"),
-	STATS_DESC_ICOUNTER("max_mmu_page_hash_collisions")
+	STATS_DESC_COUNTER(VM, mmu_shadow_zapped),
+	STATS_DESC_COUNTER(VM, mmu_pte_write),
+	STATS_DESC_COUNTER(VM, mmu_pde_zapped),
+	STATS_DESC_COUNTER(VM, mmu_flooded),
+	STATS_DESC_COUNTER(VM, mmu_recycled),
+	STATS_DESC_COUNTER(VM, mmu_cache_miss),
+	STATS_DESC_ICOUNTER(VM, mmu_unsync),
+	STATS_DESC_ICOUNTER(VM, lpages),
+	STATS_DESC_ICOUNTER(VM, nx_lpage_splits),
+	STATS_DESC_ICOUNTER(VM, max_mmu_page_hash_collisions)
 };
+static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
+		sizeof(struct kvm_vm_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vm_stats_header = {
 	{
@@ -249,30 +251,35 @@ struct _kvm_stats_header kvm_vm_stats_header = {
 
 struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	KVM_GENERIC_VCPU_STATS(),
-	STATS_DESC_COUNTER("pf_fixed"),
-	STATS_DESC_COUNTER("pf_guest"),
-	STATS_DESC_COUNTER("tlb_flush"),
-	STATS_DESC_COUNTER("invlpg"),
-	STATS_DESC_COUNTER("exits"),
-	STATS_DESC_COUNTER("io_exits"),
-	STATS_DESC_COUNTER("mmio_exits"),
-	STATS_DESC_COUNTER("signal_exits"),
-	STATS_DESC_COUNTER("irq_window_exits"),
-	STATS_DESC_COUNTER("nmi_window_exits"),
-	STATS_DESC_COUNTER("l1d_flush"),
-	STATS_DESC_COUNTER("halt_exits"),
-	STATS_DESC_COUNTER("request_irq_exits"),
-	STATS_DESC_COUNTER("irq_exits"),
-	STATS_DESC_COUNTER("host_state_reload"),
-	STATS_DESC_COUNTER("fpu_reload"),
-	STATS_DESC_COUNTER("insn_emulation"),
-	STATS_DESC_COUNTER("insn_emulation_fail"),
-	STATS_DESC_COUNTER("hypercalls"),
-	STATS_DESC_COUNTER("irq_injections"),
-	STATS_DESC_COUNTER("nmi_injections"),
-	STATS_DESC_COUNTER("req_event"),
-	STATS_DESC_COUNTER("nested_run")
+	STATS_DESC_COUNTER(VCPU, pf_fixed),
+	STATS_DESC_COUNTER(VCPU, pf_guest),
+	STATS_DESC_COUNTER(VCPU, tlb_flush),
+	STATS_DESC_COUNTER(VCPU, invlpg),
+	STATS_DESC_COUNTER(VCPU, exits),
+	STATS_DESC_COUNTER(VCPU, io_exits),
+	STATS_DESC_COUNTER(VCPU, mmio_exits),
+	STATS_DESC_COUNTER(VCPU, signal_exits),
+	STATS_DESC_COUNTER(VCPU, irq_window_exits),
+	STATS_DESC_COUNTER(VCPU, nmi_window_exits),
+	STATS_DESC_COUNTER(VCPU, l1d_flush),
+	STATS_DESC_COUNTER(VCPU, halt_exits),
+	STATS_DESC_COUNTER(VCPU, request_irq_exits),
+	STATS_DESC_COUNTER(VCPU, irq_exits),
+	STATS_DESC_COUNTER(VCPU, host_state_reload),
+	STATS_DESC_COUNTER(VCPU, fpu_reload),
+	STATS_DESC_COUNTER(VCPU, insn_emulation),
+	STATS_DESC_COUNTER(VCPU, insn_emulation_fail),
+	STATS_DESC_COUNTER(VCPU, hypercalls),
+	STATS_DESC_COUNTER(VCPU, irq_injections),
+	STATS_DESC_COUNTER(VCPU, nmi_injections),
+	STATS_DESC_COUNTER(VCPU, req_event),
+	STATS_DESC_COUNTER(VCPU, nested_run),
+	STATS_DESC_COUNTER(VCPU, directed_yield_attempted),
+	STATS_DESC_COUNTER(VCPU, directed_yield_successful),
+	STATS_DESC_ICOUNTER(VCPU, guest_mode)
 };
+static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
+		sizeof(struct kvm_vcpu_stat) / sizeof(u64));
 
 struct _kvm_stats_header kvm_vcpu_stats_header = {
 	{
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5e77f32abef5..692af9177c9f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1296,119 +1296,152 @@ struct _kvm_stats_desc {
 	{ n, offsetof(struct kvm_vcpu, stat.generic.x),			       \
 	  KVM_STAT_VCPU, ## __VA_ARGS__ }
 
-#define STATS_DESC(stat, type, unit, base, exp)			       \
+#define STATS_DESC_COMMON(type, unit, base, exp)			       \
+	.flags = type | unit | base |					       \
+	    BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |		       \
+	    BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |		       \
+	    BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),		       \
+	.exponent = exp,						       \
+	.size = 1
+
+#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp)		       \
 	{								       \
 		{							       \
-			.flags = type | unit | base |			       \
-			    BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |   \
-			    BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |   \
-			    BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),    \
-			.exponent = exp,				       \
-			.size = 1					       \
+			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			.offset = offsetof(struct kvm_vm_stat, generic.stat)   \
 		},							       \
-		.name = stat,						       \
+		.name = #stat,						       \
 	}
-#define STATS_DESC_CUMULATIVE(name, unit, base, exponent)		       \
-	STATS_DESC(name, KVM_STATS_TYPE_CUMULATIVE, unit, base, exponent)
-#define STATS_DESC_INSTANT(name, unit, base, exponent)			       \
-	STATS_DESC(name, KVM_STATS_TYPE_INSTANT, unit, base, exponent)
+#define VCPU_GENERIC_STATS_DESC(stat, type, unit, base, exp)		       \
+	{								       \
+		{							       \
+			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			.offset = offsetof(struct kvm_vcpu_stat, generic.stat) \
+		},							       \
+		.name = #stat,						       \
+	}
+#define VM_STATS_DESC(stat, type, unit, base, exp)			       \
+	{								       \
+		{							       \
+			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			.offset = offsetof(struct kvm_vm_stat, stat)	       \
+		},							       \
+		.name = #stat,						       \
+	}
+#define VCPU_STATS_DESC(stat, type, unit, base, exp)			       \
+	{								       \
+		{							       \
+			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			.offset = offsetof(struct kvm_vcpu_stat, stat)	       \
+		},							       \
+		.name = #stat,						       \
+	}
+/* SCOPE: VM, VM_GENERIC, VCPU, VCPU_GENERIC */
+#define STATS_DESC(SCOPE, stat, type, unit, base, exp)			       \
+	SCOPE##_STATS_DESC(stat, type, unit, base, exp)
+
+#define STATS_DESC_CUMULATIVE(SCOPE, name, unit, base, exponent)	       \
+	STATS_DESC(SCOPE, name, KVM_STATS_TYPE_CUMULATIVE,		       \
+		      unit, base, exponent)
+#define STATS_DESC_INSTANT(SCOPE, name, unit, base, exponent)		       \
+	STATS_DESC(SCOPE, name, KVM_STATS_TYPE_INSTANT, unit, base, exponent)  \
 
 /* Cumulative counter */
-#define STATS_DESC_COUNTER(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_NONE,		       \
+#define STATS_DESC_COUNTER(SCOPE, name)					       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_NONE,		       \
 		KVM_STATS_BASE_POW10, 0)
 /* Instantaneous counter */
-#define STATS_DESC_ICOUNTER(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_NONE,			       \
+#define STATS_DESC_ICOUNTER(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_NONE,		       \
 		KVM_STATS_BASE_POW10, 0)
 
 /* Cumulative clock cycles */
-#define STATS_DESC_CYCLE(name)						       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_CYCLES,		       \
+#define STATS_DESC_CYCLE(SCOPE, name)					       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_CYCLES,	       \
 		KVM_STATS_BASE_POW10, 0)
 /* Instantaneous clock cycles */
-#define STATS_DESC_ICYCLE(name)						       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_CYCLES,			       \
+#define STATS_DESC_ICYCLE(SCOPE, name)					       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_CYCLES,		       \
 		KVM_STATS_BASE_POW10, 0)
 
 /* Cumulative memory size in Byte */
-#define STATS_DESC_SIZE_BYTE(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_BYTES,		       \
+#define STATS_DESC_SIZE_BYTE(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_BYTES,	       \
 		KVM_STATS_BASE_POW2, 0)
 /* Cumulative memory size in KiByte */
-#define STATS_DESC_SIZE_KBYTE(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_BYTES,		       \
+#define STATS_DESC_SIZE_KBYTE(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_BYTES,	       \
 		KVM_STATS_BASE_POW2, 10)
 /* Cumulative memory size in MiByte */
-#define STATS_DESC_SIZE_MBYTE(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_BYTES,		       \
+#define STATS_DESC_SIZE_MBYTE(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_BYTES,	       \
 		KVM_STATS_BASE_POW2, 20)
 /* Cumulative memory size in GiByte */
-#define STATS_DESC_SIZE_GBYTE(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_BYTES,		       \
+#define STATS_DESC_SIZE_GBYTE(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_BYTES,	       \
 		KVM_STATS_BASE_POW2, 30)
 
 /* Instantaneous memory size in Byte */
-#define STATS_DESC_ISIZE_BYTE(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_BYTES,			       \
+#define STATS_DESC_ISIZE_BYTE(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_BYTES,		       \
 		KVM_STATS_BASE_POW2, 0)
 /* Instantaneous memory size in KiByte */
-#define STATS_DESC_ISIZE_KBYTE(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_BYTES,			       \
+#define STATS_DESC_ISIZE_KBYTE(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_BYTES,		       \
 		KVM_STATS_BASE_POW2, 10)
 /* Instantaneous memory size in MiByte */
-#define STATS_DESC_ISIZE_MBYTE(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_BYTES,			       \
+#define STATS_DESC_ISIZE_MBYTE(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_BYTES,		       \
 		KVM_STATS_BASE_POW2, 20)
 /* Instantaneous memory size in GiByte */
-#define STATS_DESC_ISIZE_GBYTE(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_BYTES,			       \
+#define STATS_DESC_ISIZE_GBYTE(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_BYTES,		       \
 		KVM_STATS_BASE_POW2, 30)
 
 /* Cumulative time in second */
-#define STATS_DESC_TIME_SEC(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_TIME_SEC(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_SECONDS,	       \
 		KVM_STATS_BASE_POW10, 0)
 /* Cumulative time in millisecond */
-#define STATS_DESC_TIME_MSEC(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_TIME_MSEC(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_SECONDS,	       \
 		KVM_STATS_BASE_POW10, -3)
 /* Cumulative time in microsecond */
-#define STATS_DESC_TIME_USEC(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_TIME_USEC(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_SECONDS,	       \
 		KVM_STATS_BASE_POW10, -6)
 /* Cumulative time in nanosecond */
-#define STATS_DESC_TIME_NSEC(name)					       \
-	STATS_DESC_CUMULATIVE(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_TIME_NSEC(SCOPE, name)				       \
+	STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_SECONDS,	       \
 		KVM_STATS_BASE_POW10, -9)
 
 /* Instantaneous time in second */
-#define STATS_DESC_ITIME_SEC(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_ITIME_SEC(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_SECONDS,		       \
 		KVM_STATS_BASE_POW10, 0)
 /* Instantaneous time in millisecond */
-#define STATS_DESC_ITIME_MSEC(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_ITIME_MSEC(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_SECONDS,		       \
 		KVM_STATS_BASE_POW10, -3)
 /* Instantaneous time in microsecond */
-#define STATS_DESC_ITIME_USEC(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_ITIME_USEC(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_SECONDS,		       \
 		KVM_STATS_BASE_POW10, -6)
 /* Instantaneous time in nanosecond */
-#define STATS_DESC_ITIME_NSEC(name)					       \
-	STATS_DESC_INSTANT(name, KVM_STATS_UNIT_SECONDS,		       \
+#define STATS_DESC_ITIME_NSEC(SCOPE, name)				       \
+	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_SECONDS,		       \
 		KVM_STATS_BASE_POW10, -9)
 
 #define KVM_GENERIC_VM_STATS()						       \
-	STATS_DESC_COUNTER("remote_tlb_flush")
+	STATS_DESC_COUNTER(VM_GENERIC, remote_tlb_flush)
 
 #define KVM_GENERIC_VCPU_STATS()					       \
-	STATS_DESC_COUNTER("halt_successful_poll"),			       \
-	STATS_DESC_COUNTER("halt_attempted_poll"),			       \
-	STATS_DESC_COUNTER("halt_poll_invalid"),			       \
-	STATS_DESC_COUNTER("halt_wakeup"),				       \
-	STATS_DESC_TIME_NSEC("halt_poll_success_ns"),			       \
-	STATS_DESC_TIME_NSEC("halt_poll_fail_ns")
+	STATS_DESC_COUNTER(VCPU_GENERIC, halt_successful_poll),		       \
+	STATS_DESC_COUNTER(VCPU_GENERIC, halt_attempted_poll),		       \
+	STATS_DESC_COUNTER(VCPU_GENERIC, halt_poll_invalid),		       \
+	STATS_DESC_COUNTER(VCPU_GENERIC, halt_wakeup),			       \
+	STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_success_ns),	       \
+	STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_fail_ns)
 
 extern struct kvm_stats_debugfs_item debugfs_entries[];
 extern struct dentry *kvm_debugfs_dir;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index df69a7abbb33..d6e97b577d01 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1940,8 +1940,8 @@ struct kvm_stats_desc {
 	__u32 flags;
 	__s16 exponent;
 	__u16 size;
-	__u32 unused1;
-	__u32 unused2;
+	__u32 offset;
+	__u32 unused;
 	char name[0];
 };
 
-- 
2.32.0.272.g935e593368-goog


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface
  2021-06-14  2:53 [PATCH 0/4] Remove duplicated stats definitions for debugfs Jing Zhang
  2021-06-14  2:53 ` [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition Jing Zhang
@ 2021-06-14  2:53 ` Jing Zhang
  2021-06-14  9:51   ` Paolo Bonzini
  2021-06-14  2:53 ` [PATCH 3/4] KVM: stats: Update documentation supporting stats mode and offset Jing Zhang
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Jing Zhang @ 2021-06-14  2:53 UTC (permalink / raw)
  To: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini, Fuad Tabba
  Cc: Jing Zhang

To avoid duplication, use the binary stats descriptors for
debugfs interface for KVM stats. Then we only have one stats
definitions for both binary and debugfs interface.

Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
 arch/arm64/kvm/guest.c    |  16 ------
 arch/mips/kvm/mips.c      |  39 --------------
 arch/powerpc/kvm/book3s.c |  37 +------------
 arch/powerpc/kvm/booke.c  |  25 ---------
 arch/s390/kvm/kvm-s390.c  | 108 --------------------------------------
 arch/x86/kvm/x86.c        |  51 +-----------------
 include/linux/kvm_host.h  |  65 ++++++++++-------------
 include/uapi/linux/kvm.h  |   7 +++
 virt/kvm/kvm_main.c       | 105 ++++++++++++++++++++++++++----------
 9 files changed, 117 insertions(+), 336 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 99842e29c2de..59486a9fef1a 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -66,22 +66,6 @@ struct _kvm_stats_header kvm_vcpu_stats_header = {
 	}
 };
 
-struct kvm_stats_debugfs_item debugfs_entries[] = {
-	VCPU_STAT_GENERIC("halt_successful_poll", halt_successful_poll),
-	VCPU_STAT_GENERIC("halt_attempted_poll", halt_attempted_poll),
-	VCPU_STAT_GENERIC("halt_poll_invalid", halt_poll_invalid),
-	VCPU_STAT_GENERIC("halt_wakeup", halt_wakeup),
-	VCPU_STAT("hvc_exit_stat", hvc_exit_stat),
-	VCPU_STAT("wfe_exit_stat", wfe_exit_stat),
-	VCPU_STAT("wfi_exit_stat", wfi_exit_stat),
-	VCPU_STAT("mmio_exit_user", mmio_exit_user),
-	VCPU_STAT("mmio_exit_kernel", mmio_exit_kernel),
-	VCPU_STAT("exits", exits),
-	VCPU_STAT_GENERIC("halt_poll_success_ns", halt_poll_success_ns),
-	VCPU_STAT_GENERIC("halt_poll_fail_ns", halt_poll_fail_ns),
-	{ NULL }
-};
-
 static bool core_reg_offset_is_vreg(u64 off)
 {
 	return off >= KVM_REG_ARM_CORE_REG(fp_regs.vregs) &&
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 67404f0947aa..606fe3b47075 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -99,45 +99,6 @@ struct _kvm_stats_header kvm_vcpu_stats_header = {
 	}
 };
 
-struct kvm_stats_debugfs_item debugfs_entries[] = {
-	VCPU_STAT("wait", wait_exits),
-	VCPU_STAT("cache", cache_exits),
-	VCPU_STAT("signal", signal_exits),
-	VCPU_STAT("interrupt", int_exits),
-	VCPU_STAT("cop_unusable", cop_unusable_exits),
-	VCPU_STAT("tlbmod", tlbmod_exits),
-	VCPU_STAT("tlbmiss_ld", tlbmiss_ld_exits),
-	VCPU_STAT("tlbmiss_st", tlbmiss_st_exits),
-	VCPU_STAT("addrerr_st", addrerr_st_exits),
-	VCPU_STAT("addrerr_ld", addrerr_ld_exits),
-	VCPU_STAT("syscall", syscall_exits),
-	VCPU_STAT("resvd_inst", resvd_inst_exits),
-	VCPU_STAT("break_inst", break_inst_exits),
-	VCPU_STAT("trap_inst", trap_inst_exits),
-	VCPU_STAT("msa_fpe", msa_fpe_exits),
-	VCPU_STAT("fpe", fpe_exits),
-	VCPU_STAT("msa_disabled", msa_disabled_exits),
-	VCPU_STAT("flush_dcache", flush_dcache_exits),
-	VCPU_STAT("vz_gpsi", vz_gpsi_exits),
-	VCPU_STAT("vz_gsfc", vz_gsfc_exits),
-	VCPU_STAT("vz_hc", vz_hc_exits),
-	VCPU_STAT("vz_grr", vz_grr_exits),
-	VCPU_STAT("vz_gva", vz_gva_exits),
-	VCPU_STAT("vz_ghfc", vz_ghfc_exits),
-	VCPU_STAT("vz_gpa", vz_gpa_exits),
-	VCPU_STAT("vz_resvd", vz_resvd_exits),
-#ifdef CONFIG_CPU_LOONGSON64
-	VCPU_STAT("vz_cpucfg", vz_cpucfg_exits),
-#endif
-	VCPU_STAT_GENERIC("halt_successful_poll", halt_successful_poll),
-	VCPU_STAT_GENERIC("halt_attempted_poll", halt_attempted_poll),
-	VCPU_STAT_GENERIC("halt_poll_invalid", halt_poll_invalid),
-	VCPU_STAT_GENERIC("halt_wakeup", halt_wakeup),
-	VCPU_STAT_GENERIC("halt_poll_success_ns", halt_poll_success_ns),
-	VCPU_STAT_GENERIC("halt_poll_fail_ns", halt_poll_fail_ns),
-	{NULL}
-};
-
 bool kvm_trace_guest_mode_change;
 
 int kvm_guest_mode_change_trace_reg(void)
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 15436484e521..d72588d64820 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -40,8 +40,8 @@
 
 struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS(),
-	STATS_DESC_ICOUNTER(VM, num_2M_pages),
-	STATS_DESC_ICOUNTER(VM, num_1G_pages)
+	STATS_DESC_ICOUNTER_RONLY(VM, num_2M_pages),
+	STATS_DESC_ICOUNTER_RONLY(VM, num_1G_pages)
 };
 static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
 		sizeof(struct kvm_vm_stat) / sizeof(u64));
@@ -102,39 +102,6 @@ struct _kvm_stats_header kvm_vcpu_stats_header = {
 	}
 };
 
-struct kvm_stats_debugfs_item debugfs_entries[] = {
-	VCPU_STAT("exits", sum_exits),
-	VCPU_STAT("mmio", mmio_exits),
-	VCPU_STAT("sig", signal_exits),
-	VCPU_STAT("sysc", syscall_exits),
-	VCPU_STAT("inst_emu", emulated_inst_exits),
-	VCPU_STAT("dec", dec_exits),
-	VCPU_STAT("ext_intr", ext_intr_exits),
-	VCPU_STAT("queue_intr", queue_intr),
-	VCPU_STAT_GENERIC("halt_poll_success_ns", halt_poll_success_ns),
-	VCPU_STAT_GENERIC("halt_poll_fail_ns", halt_poll_fail_ns),
-	VCPU_STAT("halt_wait_ns", halt_wait_ns),
-	VCPU_STAT_GENERIC("halt_successful_poll", halt_successful_poll),
-	VCPU_STAT_GENERIC("halt_attempted_poll", halt_attempted_poll),
-	VCPU_STAT("halt_successful_wait", halt_successful_wait),
-	VCPU_STAT_GENERIC("halt_poll_invalid", halt_poll_invalid),
-	VCPU_STAT_GENERIC("halt_wakeup", halt_wakeup),
-	VCPU_STAT("pf_storage", pf_storage),
-	VCPU_STAT("sp_storage", sp_storage),
-	VCPU_STAT("pf_instruc", pf_instruc),
-	VCPU_STAT("sp_instruc", sp_instruc),
-	VCPU_STAT("ld", ld),
-	VCPU_STAT("ld_slow", ld_slow),
-	VCPU_STAT("st", st),
-	VCPU_STAT("st_slow", st_slow),
-	VCPU_STAT("pthru_all", pthru_all),
-	VCPU_STAT("pthru_host", pthru_host),
-	VCPU_STAT("pthru_bad_aff", pthru_bad_aff),
-	VM_STAT("largepages_2M", num_2M_pages, .mode = 0444),
-	VM_STAT("largepages_1G", num_1G_pages, .mode = 0444),
-	{ NULL }
-};
-
 static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu,
 			unsigned long pending_now, unsigned long old_pending)
 {
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index fbc9b7b6af57..888885b574cf 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -93,31 +93,6 @@ struct _kvm_stats_header kvm_vcpu_stats_header = {
 	}
 };
 
-struct kvm_stats_debugfs_item debugfs_entries[] = {
-	VCPU_STAT("mmio", mmio_exits),
-	VCPU_STAT("sig", signal_exits),
-	VCPU_STAT("itlb_r", itlb_real_miss_exits),
-	VCPU_STAT("itlb_v", itlb_virt_miss_exits),
-	VCPU_STAT("dtlb_r", dtlb_real_miss_exits),
-	VCPU_STAT("dtlb_v", dtlb_virt_miss_exits),
-	VCPU_STAT("sysc", syscall_exits),
-	VCPU_STAT("isi", isi_exits),
-	VCPU_STAT("dsi", dsi_exits),
-	VCPU_STAT("inst_emu", emulated_inst_exits),
-	VCPU_STAT("dec", dec_exits),
-	VCPU_STAT("ext_intr", ext_intr_exits),
-	VCPU_STAT_GENERIC("halt_successful_poll", halt_successful_poll),
-	VCPU_STAT_GENERIC("halt_attempted_poll", halt_attempted_poll),
-	VCPU_STAT_GENERIC("halt_poll_invalid", halt_poll_invalid),
-	VCPU_STAT_GENERIC("halt_wakeup", halt_wakeup),
-	VCPU_STAT("doorbell", dbell_exits),
-	VCPU_STAT("guest doorbell", gdbell_exits),
-	VCPU_STAT_GENERIC("halt_poll_success_ns", halt_poll_success_ns),
-	VCPU_STAT_GENERIC("halt_poll_fail_ns", halt_poll_fail_ns),
-	VM_STAT_GENERIC("remote_tlb_flush", remote_tlb_flush),
-	{ NULL }
-};
-
 /* TODO: use vcpu_printf() */
 void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
 {
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index b5ca41e04fa5..31c40d62379e 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -188,114 +188,6 @@ struct _kvm_stats_header kvm_vcpu_stats_header = {
 	}
 };
 
-struct kvm_stats_debugfs_item debugfs_entries[] = {
-	VCPU_STAT("userspace_handled", exit_userspace),
-	VCPU_STAT("exit_null", exit_null),
-	VCPU_STAT("pfault_sync", pfault_sync),
-	VCPU_STAT("exit_validity", exit_validity),
-	VCPU_STAT("exit_stop_request", exit_stop_request),
-	VCPU_STAT("exit_external_request", exit_external_request),
-	VCPU_STAT("exit_io_request", exit_io_request),
-	VCPU_STAT("exit_external_interrupt", exit_external_interrupt),
-	VCPU_STAT("exit_instruction", exit_instruction),
-	VCPU_STAT("exit_pei", exit_pei),
-	VCPU_STAT("exit_program_interruption", exit_program_interruption),
-	VCPU_STAT("exit_instr_and_program_int", exit_instr_and_program),
-	VCPU_STAT("exit_operation_exception", exit_operation_exception),
-	VCPU_STAT_GENERIC("halt_successful_poll", halt_successful_poll),
-	VCPU_STAT_GENERIC("halt_attempted_poll", halt_attempted_poll),
-	VCPU_STAT_GENERIC("halt_poll_invalid", halt_poll_invalid),
-	VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),
-	VCPU_STAT_GENERIC("halt_wakeup", halt_wakeup),
-	VCPU_STAT_GENERIC("halt_poll_success_ns", halt_poll_success_ns),
-	VCPU_STAT_GENERIC("halt_poll_fail_ns", halt_poll_fail_ns),
-	VCPU_STAT("instruction_lctlg", instruction_lctlg),
-	VCPU_STAT("instruction_lctl", instruction_lctl),
-	VCPU_STAT("instruction_stctl", instruction_stctl),
-	VCPU_STAT("instruction_stctg", instruction_stctg),
-	VCPU_STAT("deliver_ckc", deliver_ckc),
-	VCPU_STAT("deliver_cputm", deliver_cputm),
-	VCPU_STAT("deliver_emergency_signal", deliver_emergency_signal),
-	VCPU_STAT("deliver_external_call", deliver_external_call),
-	VCPU_STAT("deliver_service_signal", deliver_service_signal),
-	VCPU_STAT("deliver_virtio", deliver_virtio),
-	VCPU_STAT("deliver_stop_signal", deliver_stop_signal),
-	VCPU_STAT("deliver_prefix_signal", deliver_prefix_signal),
-	VCPU_STAT("deliver_restart_signal", deliver_restart_signal),
-	VCPU_STAT("deliver_program", deliver_program),
-	VCPU_STAT("deliver_io", deliver_io),
-	VCPU_STAT("deliver_machine_check", deliver_machine_check),
-	VCPU_STAT("exit_wait_state", exit_wait_state),
-	VCPU_STAT("inject_ckc", inject_ckc),
-	VCPU_STAT("inject_cputm", inject_cputm),
-	VCPU_STAT("inject_external_call", inject_external_call),
-	VM_STAT("inject_float_mchk", inject_float_mchk),
-	VCPU_STAT("inject_emergency_signal", inject_emergency_signal),
-	VM_STAT("inject_io", inject_io),
-	VCPU_STAT("inject_mchk", inject_mchk),
-	VM_STAT("inject_pfault_done", inject_pfault_done),
-	VCPU_STAT("inject_program", inject_program),
-	VCPU_STAT("inject_restart", inject_restart),
-	VM_STAT("inject_service_signal", inject_service_signal),
-	VCPU_STAT("inject_set_prefix", inject_set_prefix),
-	VCPU_STAT("inject_stop_signal", inject_stop_signal),
-	VCPU_STAT("inject_pfault_init", inject_pfault_init),
-	VM_STAT("inject_virtio", inject_virtio),
-	VCPU_STAT("instruction_epsw", instruction_epsw),
-	VCPU_STAT("instruction_gs", instruction_gs),
-	VCPU_STAT("instruction_io_other", instruction_io_other),
-	VCPU_STAT("instruction_lpsw", instruction_lpsw),
-	VCPU_STAT("instruction_lpswe", instruction_lpswe),
-	VCPU_STAT("instruction_pfmf", instruction_pfmf),
-	VCPU_STAT("instruction_ptff", instruction_ptff),
-	VCPU_STAT("instruction_stidp", instruction_stidp),
-	VCPU_STAT("instruction_sck", instruction_sck),
-	VCPU_STAT("instruction_sckpf", instruction_sckpf),
-	VCPU_STAT("instruction_spx", instruction_spx),
-	VCPU_STAT("instruction_stpx", instruction_stpx),
-	VCPU_STAT("instruction_stap", instruction_stap),
-	VCPU_STAT("instruction_iske", instruction_iske),
-	VCPU_STAT("instruction_ri", instruction_ri),
-	VCPU_STAT("instruction_rrbe", instruction_rrbe),
-	VCPU_STAT("instruction_sske", instruction_sske),
-	VCPU_STAT("instruction_ipte_interlock", instruction_ipte_interlock),
-	VCPU_STAT("instruction_essa", instruction_essa),
-	VCPU_STAT("instruction_stsi", instruction_stsi),
-	VCPU_STAT("instruction_stfl", instruction_stfl),
-	VCPU_STAT("instruction_tb", instruction_tb),
-	VCPU_STAT("instruction_tpi", instruction_tpi),
-	VCPU_STAT("instruction_tprot", instruction_tprot),
-	VCPU_STAT("instruction_tsch", instruction_tsch),
-	VCPU_STAT("instruction_sthyi", instruction_sthyi),
-	VCPU_STAT("instruction_sie", instruction_sie),
-	VCPU_STAT("instruction_sigp_sense", instruction_sigp_sense),
-	VCPU_STAT("instruction_sigp_sense_running", instruction_sigp_sense_running),
-	VCPU_STAT("instruction_sigp_external_call", instruction_sigp_external_call),
-	VCPU_STAT("instruction_sigp_emergency", instruction_sigp_emergency),
-	VCPU_STAT("instruction_sigp_cond_emergency", instruction_sigp_cond_emergency),
-	VCPU_STAT("instruction_sigp_start", instruction_sigp_start),
-	VCPU_STAT("instruction_sigp_stop", instruction_sigp_stop),
-	VCPU_STAT("instruction_sigp_stop_store_status", instruction_sigp_stop_store_status),
-	VCPU_STAT("instruction_sigp_store_status", instruction_sigp_store_status),
-	VCPU_STAT("instruction_sigp_store_adtl_status", instruction_sigp_store_adtl_status),
-	VCPU_STAT("instruction_sigp_set_arch", instruction_sigp_arch),
-	VCPU_STAT("instruction_sigp_set_prefix", instruction_sigp_prefix),
-	VCPU_STAT("instruction_sigp_restart", instruction_sigp_restart),
-	VCPU_STAT("instruction_sigp_cpu_reset", instruction_sigp_cpu_reset),
-	VCPU_STAT("instruction_sigp_init_cpu_reset", instruction_sigp_init_cpu_reset),
-	VCPU_STAT("instruction_sigp_unknown", instruction_sigp_unknown),
-	VCPU_STAT("instruction_diag_10", diagnose_10),
-	VCPU_STAT("instruction_diag_44", diagnose_44),
-	VCPU_STAT("instruction_diag_9c", diagnose_9c),
-	VCPU_STAT("diag_9c_ignored", diagnose_9c_ignored),
-	VCPU_STAT("diag_9c_forward", diagnose_9c_forward),
-	VCPU_STAT("instruction_diag_258", diagnose_258),
-	VCPU_STAT("instruction_diag_308", diagnose_308),
-	VCPU_STAT("instruction_diag_500", diagnose_500),
-	VCPU_STAT("instruction_diag_other", diagnose_other),
-	{ NULL }
-};
-
 /* allow nested virtualization in KVM (if enabled by user space) */
 static int nested;
 module_param(nested, int, S_IRUGO);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 84438573b529..23b96839c6e4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -232,8 +232,8 @@ struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	STATS_DESC_COUNTER(VM, mmu_recycled),
 	STATS_DESC_COUNTER(VM, mmu_cache_miss),
 	STATS_DESC_ICOUNTER(VM, mmu_unsync),
-	STATS_DESC_ICOUNTER(VM, lpages),
-	STATS_DESC_ICOUNTER(VM, nx_lpage_splits),
+	STATS_DESC_ICOUNTER_RONLY(VM, lpages),
+	STATS_DESC_ICOUNTER_RONLY(VM, nx_lpage_splits),
 	STATS_DESC_ICOUNTER(VM, max_mmu_page_hash_collisions)
 };
 static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
@@ -291,53 +291,6 @@ struct _kvm_stats_header kvm_vcpu_stats_header = {
 	}
 };
 
-struct kvm_stats_debugfs_item debugfs_entries[] = {
-	VCPU_STAT("pf_fixed", pf_fixed),
-	VCPU_STAT("pf_guest", pf_guest),
-	VCPU_STAT("tlb_flush", tlb_flush),
-	VCPU_STAT("invlpg", invlpg),
-	VCPU_STAT("exits", exits),
-	VCPU_STAT("io_exits", io_exits),
-	VCPU_STAT("mmio_exits", mmio_exits),
-	VCPU_STAT("signal_exits", signal_exits),
-	VCPU_STAT("irq_window", irq_window_exits),
-	VCPU_STAT("nmi_window", nmi_window_exits),
-	VCPU_STAT("halt_exits", halt_exits),
-	VCPU_STAT_GENERIC("halt_successful_poll", halt_successful_poll),
-	VCPU_STAT_GENERIC("halt_attempted_poll", halt_attempted_poll),
-	VCPU_STAT_GENERIC("halt_poll_invalid", halt_poll_invalid),
-	VCPU_STAT_GENERIC("halt_wakeup", halt_wakeup),
-	VCPU_STAT("hypercalls", hypercalls),
-	VCPU_STAT("request_irq", request_irq_exits),
-	VCPU_STAT("irq_exits", irq_exits),
-	VCPU_STAT("host_state_reload", host_state_reload),
-	VCPU_STAT("fpu_reload", fpu_reload),
-	VCPU_STAT("insn_emulation", insn_emulation),
-	VCPU_STAT("insn_emulation_fail", insn_emulation_fail),
-	VCPU_STAT("irq_injections", irq_injections),
-	VCPU_STAT("nmi_injections", nmi_injections),
-	VCPU_STAT("req_event", req_event),
-	VCPU_STAT("l1d_flush", l1d_flush),
-	VCPU_STAT_GENERIC("halt_poll_success_ns", halt_poll_success_ns),
-	VCPU_STAT_GENERIC("halt_poll_fail_ns", halt_poll_fail_ns),
-	VCPU_STAT("nested_run", nested_run),
-	VCPU_STAT("directed_yield_attempted", directed_yield_attempted),
-	VCPU_STAT("directed_yield_successful", directed_yield_successful),
-	VCPU_STAT("guest_mode", guest_mode),
-	VM_STAT("mmu_shadow_zapped", mmu_shadow_zapped),
-	VM_STAT("mmu_pte_write", mmu_pte_write),
-	VM_STAT("mmu_pde_zapped", mmu_pde_zapped),
-	VM_STAT("mmu_flooded", mmu_flooded),
-	VM_STAT("mmu_recycled", mmu_recycled),
-	VM_STAT("mmu_cache_miss", mmu_cache_miss),
-	VM_STAT("mmu_unsync", mmu_unsync),
-	VM_STAT_GENERIC("remote_tlb_flush", remote_tlb_flush),
-	VM_STAT("largepages", lpages, .mode = 0444),
-	VM_STAT("nx_largepages_splitted", nx_lpage_splits, .mode = 0444),
-	VM_STAT("max_mmu_page_hash_collisions", max_mmu_page_hash_collisions),
-	{ NULL }
-};
-
 u64 __read_mostly host_xcr0;
 u64 __read_mostly supported_xcr0;
 EXPORT_SYMBOL_GPL(supported_xcr0);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 692af9177c9f..af7e972ae41a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1262,14 +1262,8 @@ enum kvm_stat_kind {
 
 struct kvm_stat_data {
 	struct kvm *kvm;
-	struct kvm_stats_debugfs_item *dbgfs_item;
-};
-
-struct kvm_stats_debugfs_item {
-	const char *name;
-	int offset;
+	struct _kvm_stats_desc *desc;
 	enum kvm_stat_kind kind;
-	int mode;
 };
 
 struct _kvm_stats_header {
@@ -1283,68 +1277,64 @@ struct _kvm_stats_desc {
 	char name[KVM_STATS_NAME_LEN];
 };
 
-#define KVM_DBGFS_GET_MODE(dbgfs_item)                                         \
-	((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)
-
-#define VM_STAT(n, x, ...)						       \
-	{ n, offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__ }
-#define VCPU_STAT(n, x, ...)						       \
-	{ n, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__ }
-#define VM_STAT_GENERIC(n, x, ...)					       \
-	{ n, offsetof(struct kvm, stat.generic.x), KVM_STAT_VM, ## __VA_ARGS__ }
-#define VCPU_STAT_GENERIC(n, x, ...)					       \
-	{ n, offsetof(struct kvm_vcpu, stat.generic.x),			       \
-	  KVM_STAT_VCPU, ## __VA_ARGS__ }
-
-#define STATS_DESC_COMMON(type, unit, base, exp)			       \
-	.flags = type | unit | base |					       \
+#define STATS_DESC_COMMON(type, unit, base, exp, mode)			       \
+	.flags = type | unit | base | mode |				       \
 	    BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |		       \
 	    BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |		       \
-	    BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),		       \
+	    BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK) |		       \
+	    BUILD_BUG_ON_ZERO(mode & ~KVM_STATS_MODE_MASK),		       \
 	.exponent = exp,						       \
 	.size = 1
 
-#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp)		       \
+#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp, mode)	       \
 	{								       \
 		{							       \
-			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			STATS_DESC_COMMON(type, unit, base, exp, mode),	       \
 			.offset = offsetof(struct kvm_vm_stat, generic.stat)   \
 		},							       \
 		.name = #stat,						       \
 	}
-#define VCPU_GENERIC_STATS_DESC(stat, type, unit, base, exp)		       \
+#define VCPU_GENERIC_STATS_DESC(stat, type, unit, base, exp, mode)	       \
 	{								       \
 		{							       \
-			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			STATS_DESC_COMMON(type, unit, base, exp, mode),	       \
 			.offset = offsetof(struct kvm_vcpu_stat, generic.stat) \
 		},							       \
 		.name = #stat,						       \
 	}
-#define VM_STATS_DESC(stat, type, unit, base, exp)			       \
+#define VM_STATS_DESC(stat, type, unit, base, exp, mode)		       \
 	{								       \
 		{							       \
-			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			STATS_DESC_COMMON(type, unit, base, exp, mode),	       \
 			.offset = offsetof(struct kvm_vm_stat, stat)	       \
 		},							       \
 		.name = #stat,						       \
 	}
-#define VCPU_STATS_DESC(stat, type, unit, base, exp)			       \
+#define VCPU_STATS_DESC(stat, type, unit, base, exp, mode)		       \
 	{								       \
 		{							       \
-			STATS_DESC_COMMON(type, unit, base, exp),	       \
+			STATS_DESC_COMMON(type, unit, base, exp, mode),	       \
 			.offset = offsetof(struct kvm_vcpu_stat, stat)	       \
 		},							       \
 		.name = #stat,						       \
 	}
 /* SCOPE: VM, VM_GENERIC, VCPU, VCPU_GENERIC */
-#define STATS_DESC(SCOPE, stat, type, unit, base, exp)			       \
-	SCOPE##_STATS_DESC(stat, type, unit, base, exp)
+#define STATS_DESC_RW(SCOPE, stat, type, unit, base, exp)		       \
+	SCOPE##_STATS_DESC(stat, type, unit, base, exp, KVM_STATS_MODE_RW)
+#define STATS_DESC_RONLY(SCOPE, stat, type, unit, base, exp)		       \
+	SCOPE##_STATS_DESC(stat, type, unit, base, exp, KVM_STATS_MODE_READ)
+#define STATS_DESC_WONLY(SCOPE, stat, type, unit, base, exp)		       \
+	SCOPE##_STATS_DESC(stat, type, unit, base, exp, KVM_STATS_MODE_WRITE)
 
 #define STATS_DESC_CUMULATIVE(SCOPE, name, unit, base, exponent)	       \
-	STATS_DESC(SCOPE, name, KVM_STATS_TYPE_CUMULATIVE,		       \
+	STATS_DESC_RW(SCOPE, name, KVM_STATS_TYPE_CUMULATIVE,		       \
 		      unit, base, exponent)
 #define STATS_DESC_INSTANT(SCOPE, name, unit, base, exponent)		       \
-	STATS_DESC(SCOPE, name, KVM_STATS_TYPE_INSTANT, unit, base, exponent)  \
+	STATS_DESC_RW(SCOPE, name, KVM_STATS_TYPE_INSTANT,		       \
+		   unit, base, exponent)
+#define STATS_DESC_INSTANT_RONLY(SCOPE, name, unit, base, exponent)	       \
+	STATS_DESC_RONLY(SCOPE, name, KVM_STATS_TYPE_INSTANT,		       \
+		   unit, base, exponent)
 
 /* Cumulative counter */
 #define STATS_DESC_COUNTER(SCOPE, name)					       \
@@ -1354,6 +1344,10 @@ struct _kvm_stats_desc {
 #define STATS_DESC_ICOUNTER(SCOPE, name)				       \
 	STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_NONE,		       \
 		KVM_STATS_BASE_POW10, 0)
+/* Instantaneous read only counter */
+#define STATS_DESC_ICOUNTER_RONLY(SCOPE, name)				       \
+	STATS_DESC_INSTANT_RONLY(SCOPE, name, KVM_STATS_UNIT_NONE,	       \
+		KVM_STATS_BASE_POW10, 0)
 
 /* Cumulative clock cycles */
 #define STATS_DESC_CYCLE(SCOPE, name)					       \
@@ -1443,7 +1437,6 @@ struct _kvm_stats_desc {
 	STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_success_ns),	       \
 	STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_fail_ns)
 
-extern struct kvm_stats_debugfs_item debugfs_entries[];
 extern struct dentry *kvm_debugfs_dir;
 extern struct _kvm_stats_header kvm_vm_stats_header;
 extern struct _kvm_stats_header kvm_vcpu_stats_header;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index d6e97b577d01..e546cb9b27c1 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1936,6 +1936,13 @@ struct kvm_stats_header {
 #define KVM_STATS_BASE_POW2		(0x1 << KVM_STATS_BASE_SHIFT)
 #define KVM_STATS_BASE_MAX		KVM_STATS_BASE_POW2
 
+#define KVM_STATS_MODE_SHIFT		12
+#define KVM_STATS_MODE_MASK		(0xF << KVM_STATS_MODE_SHIFT)
+#define KVM_STATS_MODE_RW		(0x0 << KVM_STATS_MODE_SHIFT)
+#define KVM_STATS_MODE_READ		(0x1 << KVM_STATS_MODE_SHIFT)
+#define KVM_STATS_MODE_WRITE		(0x2 << KVM_STATS_MODE_SHIFT)
+#define KVM_STATS_MODE_MAX		KVM_STATS_MODE_WRITE
+
 struct kvm_stats_desc {
 	__u32 flags;
 	__s16 exponent;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index f5bea71ea61c..4811323eeac5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -115,7 +115,6 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_running_vcpu);
 struct dentry *kvm_debugfs_dir;
 EXPORT_SYMBOL_GPL(kvm_debugfs_dir);
 
-static int kvm_debugfs_num_entries;
 static const struct file_operations stat_fops_per_vm;
 
 static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
@@ -860,9 +859,25 @@ static void kvm_free_memslots(struct kvm *kvm, struct kvm_memslots *slots)
 	kvfree(slots);
 }
 
+static umode_t kvm_stats_debugfs_mode(struct _kvm_stats_desc *pdesc)
+{
+	switch (pdesc->desc.flags & KVM_STATS_MODE_MASK) {
+	case KVM_STATS_MODE_RW:
+		return 0644;
+	case KVM_STATS_MODE_WRITE:
+		return 0222;
+	case KVM_STATS_MODE_READ:
+	default:
+		return 0444;
+	}
+}
+
+
 static void kvm_destroy_vm_debugfs(struct kvm *kvm)
 {
 	int i;
+	int kvm_debugfs_num_entries = kvm_vm_stats_header.header.count +
+				      kvm_vcpu_stats_header.header.count;
 
 	if (!kvm->debugfs_dentry)
 		return;
@@ -880,7 +895,10 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
 {
 	char dir_name[ITOA_MAX_LEN * 2];
 	struct kvm_stat_data *stat_data;
-	struct kvm_stats_debugfs_item *p;
+	struct _kvm_stats_desc *pdesc;
+	int i;
+	int kvm_debugfs_num_entries = kvm_vm_stats_header.header.count +
+				      kvm_vcpu_stats_header.header.count;
 
 	if (!debugfs_initialized())
 		return 0;
@@ -894,15 +912,32 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
 	if (!kvm->debugfs_stat_data)
 		return -ENOMEM;
 
-	for (p = debugfs_entries; p->name; p++) {
+	for (i = 0; i < kvm_vm_stats_header.header.count; ++i) {
+		pdesc = &kvm_vm_stats_desc[i];
 		stat_data = kzalloc(sizeof(*stat_data), GFP_KERNEL_ACCOUNT);
 		if (!stat_data)
 			return -ENOMEM;
 
 		stat_data->kvm = kvm;
-		stat_data->dbgfs_item = p;
-		kvm->debugfs_stat_data[p - debugfs_entries] = stat_data;
-		debugfs_create_file(p->name, KVM_DBGFS_GET_MODE(p),
+		stat_data->desc = pdesc;
+		stat_data->kind = KVM_STAT_VM;
+		kvm->debugfs_stat_data[i] = stat_data;
+		debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc),
+				    kvm->debugfs_dentry, stat_data,
+				    &stat_fops_per_vm);
+	}
+
+	for (i = 0; i < kvm_vcpu_stats_header.header.count; ++i) {
+		pdesc = &kvm_vcpu_stats_desc[i];
+		stat_data = kzalloc(sizeof(*stat_data), GFP_KERNEL_ACCOUNT);
+		if (!stat_data)
+			return -ENOMEM;
+
+		stat_data->kvm = kvm;
+		stat_data->desc = pdesc;
+		stat_data->kind = KVM_STAT_VCPU;
+		kvm->debugfs_stat_data[i] = stat_data;
+		debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc),
 				    kvm->debugfs_dentry, stat_data,
 				    &stat_fops_per_vm);
 	}
@@ -4953,7 +4988,7 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
 		return -ENOENT;
 
 	if (simple_attr_open(inode, file, get,
-		    KVM_DBGFS_GET_MODE(stat_data->dbgfs_item) & 0222
+		    kvm_stats_debugfs_mode(stat_data->desc) & 0222
 		    ? set : NULL,
 		    fmt)) {
 		kvm_put_kvm(stat_data->kvm);
@@ -4976,14 +5011,14 @@ static int kvm_debugfs_release(struct inode *inode, struct file *file)
 
 static int kvm_get_stat_per_vm(struct kvm *kvm, size_t offset, u64 *val)
 {
-	*val = *(u64 *)((void *)kvm + offset);
+	*val = *(u64 *)((void *)(&kvm->stat) + offset);
 
 	return 0;
 }
 
 static int kvm_clear_stat_per_vm(struct kvm *kvm, size_t offset)
 {
-	*(u64 *)((void *)kvm + offset) = 0;
+	*(u64 *)((void *)(&kvm->stat) + offset) = 0;
 
 	return 0;
 }
@@ -4996,7 +5031,7 @@ static int kvm_get_stat_per_vcpu(struct kvm *kvm, size_t offset, u64 *val)
 	*val = 0;
 
 	kvm_for_each_vcpu(i, vcpu, kvm)
-		*val += *(u64 *)((void *)vcpu + offset);
+		*val += *(u64 *)((void *)(&vcpu->stat) + offset);
 
 	return 0;
 }
@@ -5007,7 +5042,7 @@ static int kvm_clear_stat_per_vcpu(struct kvm *kvm, size_t offset)
 	struct kvm_vcpu *vcpu;
 
 	kvm_for_each_vcpu(i, vcpu, kvm)
-		*(u64 *)((void *)vcpu + offset) = 0;
+		*(u64 *)((void *)(&vcpu->stat) + offset) = 0;
 
 	return 0;
 }
@@ -5017,14 +5052,14 @@ static int kvm_stat_data_get(void *data, u64 *val)
 	int r = -EFAULT;
 	struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
 
-	switch (stat_data->dbgfs_item->kind) {
+	switch (stat_data->kind) {
 	case KVM_STAT_VM:
 		r = kvm_get_stat_per_vm(stat_data->kvm,
-					stat_data->dbgfs_item->offset, val);
+					stat_data->desc->desc.offset, val);
 		break;
 	case KVM_STAT_VCPU:
 		r = kvm_get_stat_per_vcpu(stat_data->kvm,
-					  stat_data->dbgfs_item->offset, val);
+					  stat_data->desc->desc.offset, val);
 		break;
 	}
 
@@ -5039,14 +5074,14 @@ static int kvm_stat_data_clear(void *data, u64 val)
 	if (val)
 		return -EINVAL;
 
-	switch (stat_data->dbgfs_item->kind) {
+	switch (stat_data->kind) {
 	case KVM_STAT_VM:
 		r = kvm_clear_stat_per_vm(stat_data->kvm,
-					  stat_data->dbgfs_item->offset);
+					  stat_data->desc->desc.offset);
 		break;
 	case KVM_STAT_VCPU:
 		r = kvm_clear_stat_per_vcpu(stat_data->kvm,
-					    stat_data->dbgfs_item->offset);
+					    stat_data->desc->desc.offset);
 		break;
 	}
 
@@ -5103,6 +5138,7 @@ static int vm_stat_clear(void *_offset, u64 val)
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, vm_stat_clear, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(vm_stat_readonly_fops, vm_stat_get, NULL, "%llu\n");
 
 static int vcpu_stat_get(void *_offset, u64 *val)
 {
@@ -5139,11 +5175,7 @@ static int vcpu_stat_clear(void *_offset, u64 val)
 
 DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, vcpu_stat_clear,
 			"%llu\n");
-
-static const struct file_operations *stat_fops[] = {
-	[KVM_STAT_VCPU] = &vcpu_stat_fops,
-	[KVM_STAT_VM]   = &vm_stat_fops,
-};
+DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_readonly_fops, vcpu_stat_get, NULL, "%llu\n");
 
 static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
 {
@@ -5197,15 +5229,32 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
 
 static void kvm_init_debug(void)
 {
-	struct kvm_stats_debugfs_item *p;
+	const struct file_operations *fops;
+	struct _kvm_stats_desc *pdesc;
+	int i;
 
 	kvm_debugfs_dir = debugfs_create_dir("kvm", NULL);
 
-	kvm_debugfs_num_entries = 0;
-	for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) {
-		debugfs_create_file(p->name, KVM_DBGFS_GET_MODE(p),
-				    kvm_debugfs_dir, (void *)(long)p->offset,
-				    stat_fops[p->kind]);
+	for (i = 0; i < kvm_vm_stats_header.header.count; ++i) {
+		pdesc = &kvm_vm_stats_desc[i];
+		if (kvm_stats_debugfs_mode(pdesc) & 0222)
+			fops = &vm_stat_fops;
+		else
+			fops = &vm_stat_readonly_fops;
+		debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc),
+				kvm_debugfs_dir,
+				(void *)(long)pdesc->desc.offset, fops);
+	}
+
+	for (i = 0; i < kvm_vcpu_stats_header.header.count; ++i) {
+		pdesc = &kvm_vcpu_stats_desc[i];
+		if (kvm_stats_debugfs_mode(pdesc) & 0222)
+			fops = &vcpu_stat_fops;
+		else
+			fops = &vcpu_stat_readonly_fops;
+		debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc),
+				kvm_debugfs_dir,
+				(void *)(long)pdesc->desc.offset, fops);
 	}
 }
 
-- 
2.32.0.272.g935e593368-goog


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] KVM: stats: Update documentation supporting stats mode and offset
  2021-06-14  2:53 [PATCH 0/4] Remove duplicated stats definitions for debugfs Jing Zhang
  2021-06-14  2:53 ` [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition Jing Zhang
  2021-06-14  2:53 ` [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface Jing Zhang
@ 2021-06-14  2:53 ` Jing Zhang
  2021-06-14  2:53 ` [PATCH 4/4] KVM: selftests: Update binary stats test for stats mode Jing Zhang
  2021-06-14  9:53 ` [PATCH 0/4] Remove duplicated stats definitions for debugfs Paolo Bonzini
  4 siblings, 0 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14  2:53 UTC (permalink / raw)
  To: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini, Fuad Tabba
  Cc: Jing Zhang

Update documentation to reflect that stats descriptor supports new
flags for read/write mode and an offset field is added in stats
descriptor.

Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
 Documentation/virt/kvm/api.rst | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index d1ad30212726..67979700a90e 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -5160,12 +5160,19 @@ below code block::
 	#define KVM_STATS_BASE_POW2		(0x1 << KVM_STATS_BASE_SHIFT)
 	#define KVM_STATS_BASE_MAX		KVM_STATS_BASE_POW2
 
+        #define KVM_STATS_MODE_SHIFT		12
+        #define KVM_STATS_MODE_MASK		(0xF << KVM_STATS_MODE_SHIFT)
+        #define KVM_STATS_MODE_RW		(0x0 << KVM_STATS_MODE_SHIFT)
+        #define KVM_STATS_MODE_READ		(0x1 << KVM_STATS_MODE_SHIFT)
+        #define KVM_STATS_MODE_WRITE		(0x2 << KVM_STATS_MODE_SHIFT)
+        #define KVM_STATS_MODE_MAX		KVM_STATS_MODE_WRITE
+
 	struct kvm_stats_desc {
 		__u32 flags;
 		__s16 exponent;
 		__u16 size;
-		__u32 unused1;
-		__u32 unused2;
+		__u32 offset;
+		__u32 unused;
 		char name[0];
 	};
 
@@ -5212,23 +5219,35 @@ Bits 4-7 of ``flags`` encode the unit:
     value is 200, ``exponent`` is 4, we can get the number of CPU clock cycles
     by ``value * pow(10, exponent) = 200 * pow(10, 4) = 2000000``.
 
-Bits 7-11 of ``flags`` encode the base:
+Bits 8-11 of ``flags`` encode the base:
   * ``KVM_STATS_BASE_POW10``
     The scale is based on power of 10. It is used for measurement of time and
     CPU clock cycles.
   * ``KVM_STATS_BASE_POW2``
     The scale is based on power of 2. It is used for measurement of memory size.
 
+Bits 12-15 of ``flags`` encode the mode:
+  * ``KVM_STATS_MODE_RW``
+    The corresponding statistics supports both read and write (clear).
+  * ``KVM_STATS_MODE_READ``
+    The corresponding statistics supports read only.
+  * ``KVM_STATS_MODE_WRITE``
+    The corresponding statistics supports write only. (Not used for now, added
+    for completeness)
+
 The ``exponent`` field is the scale of corresponding statistics data. For
 example, if the unit is ``KVM_STATS_UNIT_BYTES``, the base is
 ``KVM_STATS_BASE_POW2``, the ``exponent`` is 10, then we know that the real
 unit of the statistics data is KBytes a.k.a pow(2, 10) = 1024 bytes.
 
-The ``size`` field is the number of values of this statistics data. It is in the
-unit of ``unsigned long`` for VM or ``__u64`` for VCPU.
+The ``size`` field is the number of values (u64) of this statistics data. Its
+value is usually 1 for most of simple statistics.
+
+The ``offset`` field is the offset from the start of Data Block to the start of
+the corresponding statistics data.
 
-The ``unused1`` and ``unused2`` fields are reserved for future
-support for other types of statistics data, like log/linear histogram.
+The ``unused`` fields are reserved for future support for other types of
+statistics data, like log/linear histogram.
 
 The ``name`` field points to the name string of the statistics data. The name
 string starts at the end of ``struct kvm_stats_desc``.
-- 
2.32.0.272.g935e593368-goog


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] KVM: selftests: Update binary stats test for stats mode
  2021-06-14  2:53 [PATCH 0/4] Remove duplicated stats definitions for debugfs Jing Zhang
                   ` (2 preceding siblings ...)
  2021-06-14  2:53 ` [PATCH 3/4] KVM: stats: Update documentation supporting stats mode and offset Jing Zhang
@ 2021-06-14  2:53 ` Jing Zhang
  2021-06-14  9:53 ` [PATCH 0/4] Remove duplicated stats definitions for debugfs Paolo Bonzini
  4 siblings, 0 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14  2:53 UTC (permalink / raw)
  To: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini, Fuad Tabba
  Cc: Jing Zhang

Update binary stats selftest to support sanity test for stats
read/write mode and offset.

Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
 tools/testing/selftests/kvm/kvm_binary_stats_test.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c
index d85859a6815a..2a34b5e822e8 100644
--- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c
+++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c
@@ -77,6 +77,8 @@ static void stats_test(int stats_fd)
 				<= KVM_STATS_UNIT_MAX, "Unknown KVM stats unit");
 		TEST_ASSERT((pdesc->flags & KVM_STATS_BASE_MASK)
 				<= KVM_STATS_BASE_MAX, "Unknown KVM stats base");
+		TEST_ASSERT((pdesc->flags & KVM_STATS_MODE_MASK)
+				<= KVM_STATS_MODE_MAX, "Unknown KVM stats mode");
 		/* Check exponent for stats unit
 		 * Exponent for counter should be greater than or equal to 0
 		 * Exponent for unit bytes should be greater than or equal to 0
@@ -106,11 +108,18 @@ static void stats_test(int stats_fd)
 	}
 	/* Check overlap */
 	TEST_ASSERT(header->data_offset >= header->desc_offset
-			|| header->data_offset + size_data <= header->desc_offset,
-			"Data block is overlapped with Descriptor block");
+		|| header->data_offset + size_data <= header->desc_offset,
+		"Data block is overlapped with Descriptor block");
 	/* Check validity of all stats data size */
 	TEST_ASSERT(size_data >= header->count * sizeof(stats_data->value[0]),
 			"Data size is not correct");
+	/* Check stats offset */
+	for (i = 0; i < header->count; ++i) {
+		pdesc = (void *)stats_desc + i * size_desc;
+		TEST_ASSERT(pdesc->offset < size_data,
+			"Invalid offset (%u) for stats: %s",
+			pdesc->offset, pdesc->name);
+	}
 
 	/* Allocate memory for stats data */
 	stats_data = malloc(size_data);
-- 
2.32.0.272.g935e593368-goog


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition
  2021-06-14  2:53 ` [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition Jing Zhang
@ 2021-06-14  9:49   ` Fuad Tabba
  2021-06-14 13:28     ` Jing Zhang
  2021-06-16 12:55   ` kernel test robot
  1 sibling, 1 reply; 12+ messages in thread
From: Fuad Tabba @ 2021-06-14  9:49 UTC (permalink / raw)
  To: Jing Zhang; +Cc: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini

Hi Jing,

On Mon, Jun 14, 2021 at 3:53 AM Jing Zhang <jingzhangos@google.com> wrote:
>
> Add static check to make sure the number of stats descriptors equals
> the number of stats defined in vm/vcpu stats structures.
> Add offset field in stats descriptor to let us define stats
> descriptors freely, don't have to be in the same order as
> stats in vm/vcpu stats structures.
> Also fix some missing/mismatched stats from previous patch.
>
> Signed-off-by: Jing Zhang <jingzhangos@google.com>

I tested this for arm64, and it does assert if there's a mismatch. I
couldn't find any missing statistics under any of the architectures
either.

> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 5e77f32abef5..692af9177c9f 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -1296,119 +1296,152 @@ struct _kvm_stats_desc {
>         { n, offsetof(struct kvm_vcpu, stat.generic.x),                        \
>           KVM_STAT_VCPU, ## __VA_ARGS__ }
>
> -#define STATS_DESC(stat, type, unit, base, exp)                               \
> +#define STATS_DESC_COMMON(type, unit, base, exp)                              \
> +       .flags = type | unit | base |                                          \
> +           BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |                   \
> +           BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |                   \
> +           BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),                    \
> +       .exponent = exp,                                                       \
> +       .size = 1
> +

nit: you seem to be mixing tabs and spaces here

> +#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp)                    \
>         {                                                                      \
>                 {                                                              \
> -                       .flags = type | unit | base |                          \
> -                           BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |   \
> -                           BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |   \
> -                           BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),    \
> -                       .exponent = exp,                                       \
> -                       .size = 1                                              \
> +                       STATS_DESC_COMMON(type, unit, base, exp),              \
> +                       .offset = offsetof(struct kvm_vm_stat, generic.stat)   \
>                 },                                                             \
> -               .name = stat,                                                  \
> +               .name = #stat,                                                 \
>         }

nit: also here, mixing of tabs and spaces

Tested-by: Fuad Tabba <tabba@google.com> #arm64
Reviewed-by: Fuad Tabba <tabba@google.com>

Thanks,
/fuad

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface
  2021-06-14  2:53 ` [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface Jing Zhang
@ 2021-06-14  9:51   ` Paolo Bonzini
  2021-06-14 13:36     ` Jing Zhang
  0 siblings, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2021-06-14  9:51 UTC (permalink / raw)
  To: Jing Zhang, KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Fuad Tabba

On 14/06/21 04:53, Jing Zhang wrote:
> +	STATS_DESC_ICOUNTER_RONLY(VM, lpages),
> +	STATS_DESC_ICOUNTER_RONLY(VM, nx_lpage_splits),
>  	STATS_DESC_ICOUNTER(VM, max_mmu_page_hash_collisions)

I think we're now adding too many macros.

max_mmu_page_hash_collisions is the only remaining instant counter that 
is not read-only.  In fact, in the statsfs prototype we made all instant 
counters read-only.

You could add a third type in addition to instant and cumulative, let's 
call it "peak".  This essentially corresponds to the "max" aggregation 
function in the statsfs prototype.  Then instant counters would be read 
only, while cumulative and peak would be read-write.

Paolo


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] Remove duplicated stats definitions for debugfs
  2021-06-14  2:53 [PATCH 0/4] Remove duplicated stats definitions for debugfs Jing Zhang
                   ` (3 preceding siblings ...)
  2021-06-14  2:53 ` [PATCH 4/4] KVM: selftests: Update binary stats test for stats mode Jing Zhang
@ 2021-06-14  9:53 ` Paolo Bonzini
  2021-06-14 13:38   ` Jing Zhang
  4 siblings, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2021-06-14  9:53 UTC (permalink / raw)
  To: Jing Zhang, KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Fuad Tabba

On 14/06/21 04:53, Jing Zhang wrote:
> This is a follow-up patchset to binary stats interface patchset as below:
> https://lore.kernel.org/kvm/20210611124624.1404010-1-jingzhangos@google.com
> 
> This patchset contains a commit to fix some missing stats and add static
> check to make sure we have the right number of stats descriptors and add an
> 'offset' field in stats descriptor to make sure the or order of stats
> descriptors is not relevant to the order of stats in vm/vcpu stats
> structure. This will totally avoid the possibility of missing stats and
> mismatched stats definitions.
> 
> The binary stats interface defines stats in another array of descriptors,
> while the original stats debugfs interface uses array of kvm_stats_debugfs
> item. To remove the duplicated stats definition, this patchset would
> utilize only the stats descriptors to provide stats information to debugfs
> interface. This patchset adds a 'mode' flag to support the read/write mode
> of stats, which can be used to indicate the file permission of debugfs
> stats files. It removes the usage of kvm_stats_debugfs_item and all the
> debugfs_entries defined in all archs.
> 
> The patch also fixes an issue that read only stats could be cleared in
> global level, though not permitted in VM level in the original debugfs
> code.

Thanks for putting this together quickly.  I think we can drop the mode, 
see the suggestion in patch 2.

It's probably best to fold the v8 for the stats functionality, these 
patches (squashed appropriately) and Fuad's remars in a single posting. 
  But I'm quite confident that it can make it in 5.14.

Paolo


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition
  2021-06-14  9:49   ` Fuad Tabba
@ 2021-06-14 13:28     ` Jing Zhang
  0 siblings, 0 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14 13:28 UTC (permalink / raw)
  To: Fuad Tabba; +Cc: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Paolo Bonzini

Hi Fuad,

On Mon, Jun 14, 2021 at 4:50 AM Fuad Tabba <tabba@google.com> wrote:
>
> Hi Jing,
>
> On Mon, Jun 14, 2021 at 3:53 AM Jing Zhang <jingzhangos@google.com> wrote:
> >
> > Add static check to make sure the number of stats descriptors equals
> > the number of stats defined in vm/vcpu stats structures.
> > Add offset field in stats descriptor to let us define stats
> > descriptors freely, don't have to be in the same order as
> > stats in vm/vcpu stats structures.
> > Also fix some missing/mismatched stats from previous patch.
> >
> > Signed-off-by: Jing Zhang <jingzhangos@google.com>
>
> I tested this for arm64, and it does assert if there's a mismatch. I
> couldn't find any missing statistics under any of the architectures
> either.
>
> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > index 5e77f32abef5..692af9177c9f 100644
> > --- a/include/linux/kvm_host.h
> > +++ b/include/linux/kvm_host.h
> > @@ -1296,119 +1296,152 @@ struct _kvm_stats_desc {
> >         { n, offsetof(struct kvm_vcpu, stat.generic.x),                        \
> >           KVM_STAT_VCPU, ## __VA_ARGS__ }
> >
> > -#define STATS_DESC(stat, type, unit, base, exp)                               \
> > +#define STATS_DESC_COMMON(type, unit, base, exp)                              \
> > +       .flags = type | unit | base |                                          \
> > +           BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |                   \
> > +           BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |                   \
> > +           BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),                    \
> > +       .exponent = exp,                                                       \
> > +       .size = 1
> > +
>
> nit: you seem to be mixing tabs and spaces here
>
> > +#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp)                    \
> >         {                                                                      \
> >                 {                                                              \
> > -                       .flags = type | unit | base |                          \
> > -                           BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |   \
> > -                           BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |   \
> > -                           BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),    \
> > -                       .exponent = exp,                                       \
> > -                       .size = 1                                              \
> > +                       STATS_DESC_COMMON(type, unit, base, exp),              \
> > +                       .offset = offsetof(struct kvm_vm_stat, generic.stat)   \
> >                 },                                                             \
> > -               .name = stat,                                                  \
> > +               .name = #stat,                                                 \
> >         }
>
> nit: also here, mixing of tabs and spaces
>
> Tested-by: Fuad Tabba <tabba@google.com> #arm64
> Reviewed-by: Fuad Tabba <tabba@google.com>
>
> Thanks,
> /fuad
Thanks for the review and testing!

Jing

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface
  2021-06-14  9:51   ` Paolo Bonzini
@ 2021-06-14 13:36     ` Jing Zhang
  0 siblings, 0 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14 13:36 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Fuad Tabba

Hi Paolo,

On Mon, Jun 14, 2021 at 4:51 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 14/06/21 04:53, Jing Zhang wrote:
> > +     STATS_DESC_ICOUNTER_RONLY(VM, lpages),
> > +     STATS_DESC_ICOUNTER_RONLY(VM, nx_lpage_splits),
> >       STATS_DESC_ICOUNTER(VM, max_mmu_page_hash_collisions)
>
> I think we're now adding too many macros.
>
> max_mmu_page_hash_collisions is the only remaining instant counter that
> is not read-only.  In fact, in the statsfs prototype we made all instant
> counters read-only.
>
> You could add a third type in addition to instant and cumulative, let's
> call it "peak".  This essentially corresponds to the "max" aggregation
> function in the statsfs prototype.  Then instant counters would be read
> only, while cumulative and peak would be read-write.
>
> Paolo
>
Thanks for the suggestion. Will do that.
Jing

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] Remove duplicated stats definitions for debugfs
  2021-06-14  9:53 ` [PATCH 0/4] Remove duplicated stats definitions for debugfs Paolo Bonzini
@ 2021-06-14 13:38   ` Jing Zhang
  0 siblings, 0 replies; 12+ messages in thread
From: Jing Zhang @ 2021-06-14 13:38 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390, Fuad Tabba

On Mon, Jun 14, 2021 at 4:53 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 14/06/21 04:53, Jing Zhang wrote:
> > This is a follow-up patchset to binary stats interface patchset as below:
> > https://lore.kernel.org/kvm/20210611124624.1404010-1-jingzhangos@google.com
> >
> > This patchset contains a commit to fix some missing stats and add static
> > check to make sure we have the right number of stats descriptors and add an
> > 'offset' field in stats descriptor to make sure the or order of stats
> > descriptors is not relevant to the order of stats in vm/vcpu stats
> > structure. This will totally avoid the possibility of missing stats and
> > mismatched stats definitions.
> >
> > The binary stats interface defines stats in another array of descriptors,
> > while the original stats debugfs interface uses array of kvm_stats_debugfs
> > item. To remove the duplicated stats definition, this patchset would
> > utilize only the stats descriptors to provide stats information to debugfs
> > interface. This patchset adds a 'mode' flag to support the read/write mode
> > of stats, which can be used to indicate the file permission of debugfs
> > stats files. It removes the usage of kvm_stats_debugfs_item and all the
> > debugfs_entries defined in all archs.
> >
> > The patch also fixes an issue that read only stats could be cleared in
> > global level, though not permitted in VM level in the original debugfs
> > code.
>
> Thanks for putting this together quickly.  I think we can drop the mode,
> see the suggestion in patch 2.
>
> It's probably best to fold the v8 for the stats functionality, these
> patches (squashed appropriately) and Fuad's remars in a single posting.
>   But I'm quite confident that it can make it in 5.14.
>
> Paolo
>
Thanks. Will drop the mode, squash stats functionality with v8 and fold them
in another single posting (v9).

Jing

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition
  2021-06-14  2:53 ` [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition Jing Zhang
  2021-06-14  9:49   ` Fuad Tabba
@ 2021-06-16 12:55   ` kernel test robot
  1 sibling, 0 replies; 12+ messages in thread
From: kernel test robot @ 2021-06-16 12:55 UTC (permalink / raw)
  To: Jing Zhang, KVM, KVMARM, LinuxMIPS, KVMPPC, LinuxS390,
	Paolo Bonzini, Fuad Tabba
  Cc: kbuild-all, clang-built-linux, Jing Zhang

[-- Attachment #1: Type: text/plain, Size: 11375 bytes --]

Hi Jing,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on 39be2e28180a2e87af5fbb8d83643812e1a3b371]

url:    https://github.com/0day-ci/linux/commits/Jing-Zhang/Remove-duplicated-stats-definitions-for-debugfs/20210616-151523
base:   39be2e28180a2e87af5fbb8d83643812e1a3b371
config: s390-randconfig-r022-20210615 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 64720f57bea6a6bf033feef4a5751ab9c0c3b401)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/0day-ci/linux/commit/2145147a4e85c8196c004804d103c1a3d7adeffe
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jing-Zhang/Remove-duplicated-stats-definitions-for-debugfs/20210616-151523
        git checkout 2145147a4e85c8196c004804d103c1a3d7adeffe
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/s390/kvm/kvm-s390.c:23:
   In file included from include/linux/kvm_host.h:35:
   In file included from include/linux/kvm_para.h:5:
   In file included from include/uapi/linux/kvm_para.h:37:
   In file included from arch/s390/include/asm/kvm_para.h:25:
   In file included from arch/s390/include/asm/diag.h:12:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:36:59: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
                                                             ^
   include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
   #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
                                                        ^
   In file included from arch/s390/kvm/kvm-s390.c:23:
   In file included from include/linux/kvm_host.h:35:
   In file included from include/linux/kvm_para.h:5:
   In file included from include/uapi/linux/kvm_para.h:37:
   In file included from arch/s390/include/asm/kvm_para.h:25:
   In file included from arch/s390/include/asm/diag.h:12:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
   #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
                                                        ^
   In file included from arch/s390/kvm/kvm-s390.c:23:
   In file included from include/linux/kvm_host.h:35:
   In file included from include/linux/kvm_para.h:5:
   In file included from include/uapi/linux/kvm_para.h:37:
   In file included from arch/s390/include/asm/kvm_para.h:25:
   In file included from arch/s390/include/asm/diag.h:12:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:75:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> arch/s390/kvm/kvm-s390.c:63:2: error: implicit declaration of function 'STATS_DESC_COUNTR' [-Werror,-Wimplicit-function-declaration]
           STATS_DESC_COUNTR(VM, inject_io),
           ^
>> arch/s390/kvm/kvm-s390.c:63:20: error: use of undeclared identifier 'VM'
           STATS_DESC_COUNTR(VM, inject_io),
                             ^
>> arch/s390/kvm/kvm-s390.c:63:24: error: use of undeclared identifier 'inject_io'
           STATS_DESC_COUNTR(VM, inject_io),
                                 ^
   arch/s390/kvm/kvm-s390.c:64:20: error: use of undeclared identifier 'VM'
           STATS_DESC_COUNTR(VM, inject_float_mchk),
                             ^
>> arch/s390/kvm/kvm-s390.c:64:24: error: use of undeclared identifier 'inject_float_mchk'
           STATS_DESC_COUNTR(VM, inject_float_mchk),
                                 ^
   arch/s390/kvm/kvm-s390.c:65:20: error: use of undeclared identifier 'VM'
           STATS_DESC_COUNTR(VM, inject_pfault_done),
                             ^
>> arch/s390/kvm/kvm-s390.c:65:24: error: use of undeclared identifier 'inject_pfault_done'
           STATS_DESC_COUNTR(VM, inject_pfault_done),
                                 ^
   arch/s390/kvm/kvm-s390.c:66:20: error: use of undeclared identifier 'VM'
           STATS_DESC_COUNTR(VM, inject_service_signal),
                             ^
>> arch/s390/kvm/kvm-s390.c:66:24: error: use of undeclared identifier 'inject_service_signal'
           STATS_DESC_COUNTR(VM, inject_service_signal),
                                 ^
   arch/s390/kvm/kvm-s390.c:67:20: error: use of undeclared identifier 'VM'
           STATS_DESC_COUNTR(VM, inject_virtio)
                             ^
>> arch/s390/kvm/kvm-s390.c:67:24: error: use of undeclared identifier 'inject_virtio'
           STATS_DESC_COUNTR(VM, inject_virtio)
                                 ^
>> arch/s390/kvm/kvm-s390.c:69:15: error: invalid application of 'sizeof' to an incomplete type 'struct _kvm_stats_desc []'
   static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
   ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:42:32: note: expanded from macro 'ARRAY_SIZE'
   #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
                                  ^
   include/linux/build_bug.h:77:50: note: expanded from macro 'static_assert'
   #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
                                    ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: expanded from macro '__static_assert'
   #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
                                                          ^~~~
   arch/s390/kvm/kvm-s390.c:75:12: error: invalid application of 'sizeof' to an incomplete type 'struct _kvm_stats_desc []'
                   .count = ARRAY_SIZE(kvm_vm_stats_desc),
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:42:32: note: expanded from macro 'ARRAY_SIZE'
   #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
                                  ^~~~~
   arch/s390/kvm/kvm-s390.c:78:10: error: invalid application of 'sizeof' to an incomplete type 'struct _kvm_stats_desc []'
                           sizeof(kvm_vm_stats_desc),
                                 ^~~~~~~~~~~~~~~~~~~
   12 warnings and 14 errors generated.


vim +/STATS_DESC_COUNTR +63 arch/s390/kvm/kvm-s390.c

    55	
    56	#define MEM_OP_MAX_SIZE 65536	/* Maximum transfer size for KVM_S390_MEM_OP */
    57	#define LOCAL_IRQS 32
    58	#define VCPU_IRQS_MAX_BUF (sizeof(struct kvm_s390_irq) * \
    59				   (KVM_MAX_VCPUS + LOCAL_IRQS))
    60	
    61	struct _kvm_stats_desc kvm_vm_stats_desc[] = {
    62		KVM_GENERIC_VM_STATS(),
  > 63		STATS_DESC_COUNTR(VM, inject_io),
  > 64		STATS_DESC_COUNTR(VM, inject_float_mchk),
  > 65		STATS_DESC_COUNTR(VM, inject_pfault_done),
  > 66		STATS_DESC_COUNTR(VM, inject_service_signal),
  > 67		STATS_DESC_COUNTR(VM, inject_virtio)
    68	};
  > 69	static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
    70			sizeof(struct kvm_vm_stat) / sizeof(u64));
    71	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 18386 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-06-16 12:55 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-14  2:53 [PATCH 0/4] Remove duplicated stats definitions for debugfs Jing Zhang
2021-06-14  2:53 ` [PATCH 1/4] KVM: stats: Make sure no missing or mismatched binary stats definition Jing Zhang
2021-06-14  9:49   ` Fuad Tabba
2021-06-14 13:28     ` Jing Zhang
2021-06-16 12:55   ` kernel test robot
2021-06-14  2:53 ` [PATCH 2/4] KVM: stats: Use binary stats descriptors for debugfs interface Jing Zhang
2021-06-14  9:51   ` Paolo Bonzini
2021-06-14 13:36     ` Jing Zhang
2021-06-14  2:53 ` [PATCH 3/4] KVM: stats: Update documentation supporting stats mode and offset Jing Zhang
2021-06-14  2:53 ` [PATCH 4/4] KVM: selftests: Update binary stats test for stats mode Jing Zhang
2021-06-14  9:53 ` [PATCH 0/4] Remove duplicated stats definitions for debugfs Paolo Bonzini
2021-06-14 13:38   ` Jing Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).