linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest
@ 2023-09-02 12:59 Haibo Xu
  2023-09-02 12:59 ` [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling Haibo Xu
                   ` (8 more replies)
  0 siblings, 9 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, wchen, Greentime Hu, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vipin Sharma, Aaron Lewis,
	David Matlack, Mingwei Zhang, Vitaly Kuznetsov, Ackerley Tng,
	Lei Wang, Maxim Levitsky, Peter Gonda, Thomas Huth, Like Xu,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	linux-kernel, linux-riscv, kvm, linux-kselftest, linux-arm-kernel,
	kvmarm, kvm-riscv

The RISC-V arch_timer selftest is used to validate Sstc timer
functionality in a guest, which sets up periodic timer interrupts
and check the basic interrupt status upon its receipt.

This KVM selftest was ported from aarch64 arch_timer and tested
with Linux v6.5-rc5 on a Qemu riscv64 virt machine.

---
Changed since v1:
  * Rebase to kvm-riscv/riscv_kvm_next
  * Cherry-pick Sean's kselftest guest printf patch set
    https://lore.kernel.org/all/20230729003643.1053367-1-seanjc@google.com/
  * Copy the entire csr.h verbatim
  * Unified the function names for exception vector table setup
    void vm_init_vector_tables(struct kvm_vm *vm);
    void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
  * Format the handler.S asm file per Andrew's comments
  * Consolidate the timer test code for arm64 and riscv
    based on Andrew's and Sean's suggestion

Haibo Xu (8):
  KVM: selftests: Unify the codes for guest exception handling
  KVM: arm64: selftest: Split arch_timer test code
  tools: riscv: Add header file csr.h
  KVM: riscv: selftests: Switch to use macro from csr.h
  KVM: riscv: selftests: Add exception handling support
  KVM: riscv: selftests: Add guest helper to get vcpu id
  KVM: riscv: selftest: Change vcpu_has_ext to a common function
  KVM: riscv: selftests: Add sstc timer test

 tools/arch/riscv/include/asm/csr.h            | 521 ++++++++++++++++++
 tools/testing/selftests/kvm/Makefile          |  11 +-
 .../selftests/kvm/aarch64/arch_timer.c        | 292 +---------
 .../selftests/kvm/aarch64/debug-exceptions.c  |   4 +-
 .../selftests/kvm/aarch64/page_fault_test.c   |   4 +-
 .../testing/selftests/kvm/aarch64/vgic_irq.c  |   4 +-
 tools/testing/selftests/kvm/arch_timer.c      | 261 +++++++++
 .../selftests/kvm/include/aarch64/processor.h |  12 +-
 .../selftests/kvm/include/kvm_util_base.h     |   9 +
 .../selftests/kvm/include/riscv/arch_timer.h  |  80 +++
 .../selftests/kvm/include/riscv/processor.h   |  60 +-
 .../selftests/kvm/include/timer_test.h        |  58 ++
 .../selftests/kvm/include/x86_64/processor.h  |   5 -
 .../selftests/kvm/lib/aarch64/processor.c     |   6 +-
 .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++
 .../selftests/kvm/lib/riscv/processor.c       |  86 +++
 .../selftests/kvm/lib/x86_64/processor.c      |   4 +-
 .../testing/selftests/kvm/riscv/arch_timer.c  | 130 +++++
 .../selftests/kvm/riscv/get-reg-list.c        |  14 -
 tools/testing/selftests/kvm/x86_64/amx_test.c |   4 +-
 .../selftests/kvm/x86_64/fix_hypercall_test.c |   4 +-
 .../selftests/kvm/x86_64/hyperv_evmcs.c       |   4 +-
 .../selftests/kvm/x86_64/hyperv_features.c    |   8 +-
 .../testing/selftests/kvm/x86_64/hyperv_ipi.c |   6 +-
 .../selftests/kvm/x86_64/kvm_pv_test.c        |   4 +-
 .../selftests/kvm/x86_64/monitor_mwait_test.c |   4 +-
 .../kvm/x86_64/pmu_event_filter_test.c        |   8 +-
 .../smaller_maxphyaddr_emulation_test.c       |   4 +-
 .../selftests/kvm/x86_64/svm_int_ctl_test.c   |   4 +-
 .../kvm/x86_64/svm_nested_shutdown_test.c     |   4 +-
 .../kvm/x86_64/svm_nested_soft_inject_test.c  |   4 +-
 .../kvm/x86_64/ucna_injection_test.c          |   8 +-
 .../kvm/x86_64/userspace_msr_exit_test.c      |   4 +-
 .../vmx_exception_with_invalid_guest_state.c  |   4 +-
 .../selftests/kvm/x86_64/vmx_pmu_caps_test.c  |   4 +-
 .../selftests/kvm/x86_64/xapic_ipi_test.c     |   4 +-
 .../selftests/kvm/x86_64/xcr0_cpuid_test.c    |   4 +-
 .../selftests/kvm/x86_64/xen_shinfo_test.c    |   4 +-
 38 files changed, 1376 insertions(+), 376 deletions(-)
 create mode 100644 tools/arch/riscv/include/asm/csr.h
 create mode 100644 tools/testing/selftests/kvm/arch_timer.c
 create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
 create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
 create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
 create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c

-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 11:15   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code Haibo Xu
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Sean Christopherson, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Paolo Bonzini, Shuah Khan,
	Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Anup Patel, Atish Patra, Guo Ren, Greentime Hu, wchen,
	Daniel Henrique Barboza, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu,
	Peter Gonda, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

Rename the vm_init_descriptor_tables() and vcpu_init_vector_tables()
prototypes to vm_init_vector_tables() and vcpu_init_vector_tables()
respectively, so that we can use common names for the architectures
(x86/aarch64/riscv) and then put them in a common header.

By the way, vm_install_exception_handler() prototype were also moved to
the common header since they are commonly used across the architectures.

The patch is a preparation to share the guest exception handling codes
in riscv.

Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/testing/selftests/kvm/aarch64/arch_timer.c          | 4 ++--
 tools/testing/selftests/kvm/aarch64/debug-exceptions.c    | 4 ++--
 tools/testing/selftests/kvm/aarch64/page_fault_test.c     | 4 ++--
 tools/testing/selftests/kvm/aarch64/vgic_irq.c            | 4 ++--
 tools/testing/selftests/kvm/include/aarch64/processor.h   | 8 +-------
 tools/testing/selftests/kvm/include/kvm_util_base.h       | 7 +++++++
 tools/testing/selftests/kvm/include/x86_64/processor.h    | 5 -----
 tools/testing/selftests/kvm/lib/aarch64/processor.c       | 6 +++---
 tools/testing/selftests/kvm/lib/x86_64/processor.c        | 4 ++--
 tools/testing/selftests/kvm/x86_64/amx_test.c             | 4 ++--
 tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c   | 4 ++--
 tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c         | 4 ++--
 tools/testing/selftests/kvm/x86_64/hyperv_features.c      | 8 ++++----
 tools/testing/selftests/kvm/x86_64/hyperv_ipi.c           | 6 +++---
 tools/testing/selftests/kvm/x86_64/kvm_pv_test.c          | 4 ++--
 tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c   | 4 ++--
 .../testing/selftests/kvm/x86_64/pmu_event_filter_test.c  | 8 ++++----
 .../kvm/x86_64/smaller_maxphyaddr_emulation_test.c        | 4 ++--
 tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c     | 4 ++--
 .../selftests/kvm/x86_64/svm_nested_shutdown_test.c       | 4 ++--
 .../selftests/kvm/x86_64/svm_nested_soft_inject_test.c    | 4 ++--
 tools/testing/selftests/kvm/x86_64/ucna_injection_test.c  | 8 ++++----
 .../selftests/kvm/x86_64/userspace_msr_exit_test.c        | 4 ++--
 .../kvm/x86_64/vmx_exception_with_invalid_guest_state.c   | 4 ++--
 tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c    | 4 ++--
 tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c       | 4 ++--
 tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c      | 4 ++--
 tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c      | 4 ++--
 28 files changed, 66 insertions(+), 70 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
index 274b8465b42a..b63859829a96 100644
--- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
+++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
@@ -377,7 +377,7 @@ static struct kvm_vm *test_vm_create(void)
 
 	vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
 
-	vm_init_descriptor_tables(vm);
+	vm_init_vector_tables(vm);
 	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, guest_irq_handler);
 
 	if (!test_args.offset.reserved) {
@@ -388,7 +388,7 @@ static struct kvm_vm *test_vm_create(void)
 	}
 
 	for (i = 0; i < nr_vcpus; i++)
-		vcpu_init_descriptor_tables(vcpus[i]);
+		vcpu_init_vector_tables(vcpus[i]);
 
 	test_init_timer_irq(vm);
 	gic_fd = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
index f5b6cb3a0019..38370f28183d 100644
--- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
+++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
@@ -429,8 +429,8 @@ static void test_guest_debug_exceptions(uint8_t bpn, uint8_t wpn, uint8_t ctx_bp
 
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT,
 				ESR_EC_BRK_INS, guest_sw_bp_handler);
diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
index 47bb914ab2fa..4503afe8a569 100644
--- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
+++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
@@ -541,8 +541,8 @@ static void load_exec_code_for_test(struct kvm_vm *vm)
 static void setup_abort_handlers(struct kvm_vm *vm, struct kvm_vcpu *vcpu,
 				 struct test_desc *test)
 {
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT,
 				ESR_EC_DABT, no_dabt_handler);
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
index 2e64b4856e38..76616d3c6333 100644
--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
@@ -756,8 +756,8 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
 
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	/* Setup the guest args page (so it gets the args). */
 	args_gva = vm_vaddr_alloc_page(vm);
diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index cb537253a6b9..69e7b08d3f99 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -121,14 +121,8 @@ enum {
 void aarch64_get_supported_page_sizes(uint32_t ipa,
 				      bool *ps4k, bool *ps16k, bool *ps64k);
 
-void vm_init_descriptor_tables(struct kvm_vm *vm);
-void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
-
-typedef void(*handler_fn)(struct ex_regs *);
-void vm_install_exception_handler(struct kvm_vm *vm,
-		int vector, handler_fn handler);
 void vm_install_sync_handler(struct kvm_vm *vm,
-		int vector, int ec, handler_fn handler);
+		int vector, int ec, exception_handler_fn handler);
 
 uint64_t *virt_get_pte_hva(struct kvm_vm *vm, vm_vaddr_t gva);
 
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index a18db6a7b3cf..135ae2eb5249 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -932,4 +932,11 @@ void kvm_selftest_arch_init(void);
 
 void kvm_arch_vm_post_create(struct kvm_vm *vm);
 
+void vm_init_vector_tables(struct kvm_vm *vm);
+void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
+
+struct ex_regs;
+typedef void(*exception_handler_fn)(struct ex_regs *);
+void vm_install_exception_handler(struct kvm_vm *vm, int vector, exception_handler_fn handler);
+
 #endif /* SELFTEST_KVM_UTIL_BASE_H */
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
index aa434c8f19c5..9eae8c3d191c 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -1057,11 +1057,6 @@ struct idt_entry {
 	uint32_t offset2; uint32_t reserved;
 };
 
-void vm_init_descriptor_tables(struct kvm_vm *vm);
-void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
-void vm_install_exception_handler(struct kvm_vm *vm, int vector,
-			void (*handler)(struct ex_regs *));
-
 /* If a toddler were to say "abracadabra". */
 #define KVM_EXCEPTION_MAGIC 0xabacadabaULL
 
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
index 3a0259e25335..51842d23cc39 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
@@ -415,10 +415,10 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
 }
 
 struct handlers {
-	handler_fn exception_handlers[VECTOR_NUM][ESR_EC_NUM];
+	exception_handler_fn exception_handlers[VECTOR_NUM][ESR_EC_NUM];
 };
 
-void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu)
+void vcpu_init_vector_tables(struct kvm_vcpu *vcpu)
 {
 	extern char vectors;
 
@@ -458,7 +458,7 @@ void route_exception(struct ex_regs *regs, int vector)
 	kvm_exit_unexpected_exception(vector, ec, valid_ec);
 }
 
-void vm_init_descriptor_tables(struct kvm_vm *vm)
+void vm_init_vector_tables(struct kvm_vm *vm)
 {
 	vm->handlers = __vm_vaddr_alloc(vm, sizeof(struct handlers),
 					vm->page_size, MEM_REGION_DATA);
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index d8288374078e..c728c1564f47 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -1093,7 +1093,7 @@ void route_exception(struct ex_regs *regs)
 		     regs->vector, regs->rip);
 }
 
-void vm_init_descriptor_tables(struct kvm_vm *vm)
+void vm_init_vector_tables(struct kvm_vm *vm)
 {
 	extern void *idt_handlers;
 	int i;
@@ -1106,7 +1106,7 @@ void vm_init_descriptor_tables(struct kvm_vm *vm)
 			DEFAULT_CODE_SELECTOR);
 }
 
-void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu)
+void vcpu_init_vector_tables(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vm *vm = vcpu->vm;
 	struct kvm_sregs sregs;
diff --git a/tools/testing/selftests/kvm/x86_64/amx_test.c b/tools/testing/selftests/kvm/x86_64/amx_test.c
index 11329e5ff945..4e36c54c2771 100644
--- a/tools/testing/selftests/kvm/x86_64/amx_test.c
+++ b/tools/testing/selftests/kvm/x86_64/amx_test.c
@@ -246,8 +246,8 @@ int main(int argc, char *argv[])
 	vcpu_regs_get(vcpu, &regs1);
 
 	/* Register #NM handler */
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 	vm_install_exception_handler(vm, NM_VECTOR, guest_nm_handler);
 
 	/* amx cfg for guest_code */
diff --git a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c
index 0f728f05ea82..ec50e5895e34 100644
--- a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c
+++ b/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c
@@ -110,8 +110,8 @@ static void test_fix_hypercall(bool disable_quirk)
 
 	vm = vm_create_with_one_vcpu(&vcpu, guest_main);
 
-	vm_init_descriptor_tables(vcpu->vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vcpu->vm);
+	vcpu_init_vector_tables(vcpu);
 	vm_install_exception_handler(vcpu->vm, UD_VECTOR, guest_ud_handler);
 
 	if (disable_quirk)
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
index 7bde0c4dfdbd..2ad3785d2795 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
@@ -257,8 +257,8 @@ int main(int argc, char *argv[])
 	vcpu_args_set(vcpu, 3, vmx_pages_gva, hv_pages_gva, addr_gva2gpa(vm, hcall_page));
 	vcpu_set_msr(vcpu, HV_X64_MSR_VP_INDEX, vcpu->id);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 	vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
 	vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
 
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_features.c b/tools/testing/selftests/kvm/x86_64/hyperv_features.c
index 9f28aa276c4e..0a5a8756b04d 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_features.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_features.c
@@ -156,8 +156,8 @@ static void guest_test_msrs_access(void)
 			vcpu_init_cpuid(vcpu, prev_cpuid);
 		}
 
-		vm_init_descriptor_tables(vm);
-		vcpu_init_descriptor_tables(vcpu);
+		vm_init_vector_tables(vm);
+		vcpu_init_vector_tables(vcpu);
 
 		/* TODO: Make this entire test easier to maintain. */
 		if (stage >= 21)
@@ -531,8 +531,8 @@ static void guest_test_hcalls_access(void)
 	while (true) {
 		vm = vm_create_with_one_vcpu(&vcpu, guest_hcall);
 
-		vm_init_descriptor_tables(vm);
-		vcpu_init_descriptor_tables(vcpu);
+		vm_init_vector_tables(vm);
+		vcpu_init_vector_tables(vcpu);
 
 		/* Hypercall input/output */
 		hcall_page = vm_vaddr_alloc_pages(vm, 2);
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_ipi.c b/tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
index 6feb5ddb031d..980eef6015a3 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
@@ -254,16 +254,16 @@ int main(int argc, char *argv[])
 	hcall_page = vm_vaddr_alloc_pages(vm, 2);
 	memset(addr_gva2hva(vm, hcall_page), 0x0, 2 * getpagesize());
 
-	vm_init_descriptor_tables(vm);
+	vm_init_vector_tables(vm);
 
 	vcpu[1] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_1, receiver_code);
-	vcpu_init_descriptor_tables(vcpu[1]);
+	vcpu_init_vector_tables(vcpu[1]);
 	vcpu_args_set(vcpu[1], 2, hcall_page, addr_gva2gpa(vm, hcall_page));
 	vcpu_set_msr(vcpu[1], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_1);
 	vcpu_set_hv_cpuid(vcpu[1]);
 
 	vcpu[2] = vm_vcpu_add(vm, RECEIVER_VCPU_ID_2, receiver_code);
-	vcpu_init_descriptor_tables(vcpu[2]);
+	vcpu_init_vector_tables(vcpu[2]);
 	vcpu_args_set(vcpu[2], 2, hcall_page, addr_gva2gpa(vm, hcall_page));
 	vcpu_set_msr(vcpu[2], HV_X64_MSR_VP_INDEX, RECEIVER_VCPU_ID_2);
 	vcpu_set_hv_cpuid(vcpu[2]);
diff --git a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c b/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
index 9e2879af7c20..dbbedea55cc9 100644
--- a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
+++ b/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
@@ -146,8 +146,8 @@ int main(void)
 
 	vcpu_clear_cpuid_entry(vcpu, KVM_CPUID_FEATURES);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	enter_guest(vcpu);
 	kvm_vm_free(vm);
diff --git a/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c b/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
index 80aa3d8b18f8..dbe861db569a 100644
--- a/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
+++ b/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
@@ -78,8 +78,8 @@ int main(int argc, char *argv[])
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 	vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_MWAIT);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	while (1) {
 		vcpu_run(vcpu);
diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index 40507ed9fe8a..314ba781c284 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -399,8 +399,8 @@ static void test_pmu_config_disable(void (*guest_code)(void))
 	vm_enable_cap(vm, KVM_CAP_PMU_CAPABILITY, KVM_PMU_CAP_DISABLE);
 
 	vcpu = vm_vcpu_add(vm, 0, guest_code);
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	TEST_ASSERT(!sanity_check_pmu(vcpu),
 		    "Guest should not be able to use disabled PMU.");
@@ -801,8 +801,8 @@ int main(int argc, char *argv[])
 
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	TEST_REQUIRE(sanity_check_pmu(vcpu));
 
diff --git a/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c
index 06edf00a97d6..37cd8cd230e3 100644
--- a/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c
+++ b/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c
@@ -60,8 +60,8 @@ int main(int argc, char *argv[])
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 	vcpu_args_set(vcpu, 1, kvm_is_tdp_enabled());
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vcpu_set_cpuid_maxphyaddr(vcpu, MAXPHYADDR);
 
diff --git a/tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c b/tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
index 32bef39bec21..c2c451cb3d47 100644
--- a/tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
+++ b/tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
@@ -93,8 +93,8 @@ int main(int argc, char *argv[])
 
 	vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vm_install_exception_handler(vm, VINTR_IRQ_NUMBER, vintr_irq_handler);
 	vm_install_exception_handler(vm, INTR_IRQ_NUMBER, intr_irq_handler);
diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c b/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
index d6fcdcc3af31..b06f2ee93e3b 100644
--- a/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
+++ b/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
@@ -48,8 +48,8 @@ int main(int argc, char *argv[])
 	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
 
 	vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vcpu_alloc_svm(vm, &svm_gva);
 
diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
index 7ee44496cf97..30f850ebaa4f 100644
--- a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
+++ b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
@@ -152,8 +152,8 @@ static void run_test(bool is_nmi)
 
 	vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vm_install_exception_handler(vm, NMI_VECTOR, guest_nmi_handler);
 	vm_install_exception_handler(vm, BP_VECTOR, guest_bp_handler);
diff --git a/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c b/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
index 85f34ca7e49e..c92065abe0fd 100644
--- a/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
+++ b/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
@@ -285,10 +285,10 @@ int main(int argc, char *argv[])
 	cmcidis_vcpu = create_vcpu_with_mce_cap(vm, 1, false, cmci_disabled_guest_code);
 	cmci_vcpu = create_vcpu_with_mce_cap(vm, 2, true, cmci_enabled_guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(ucna_vcpu);
-	vcpu_init_descriptor_tables(cmcidis_vcpu);
-	vcpu_init_descriptor_tables(cmci_vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(ucna_vcpu);
+	vcpu_init_vector_tables(cmcidis_vcpu);
+	vcpu_init_vector_tables(cmci_vcpu);
 	vm_install_exception_handler(vm, CMCI_VECTOR, guest_cmci_handler);
 	vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
 
diff --git a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c b/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
index 3533dc2fbfee..6e473e532c88 100644
--- a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
+++ b/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
@@ -544,8 +544,8 @@ static void test_msr_filter_allow(void)
 
 	vm_ioctl(vm, KVM_X86_SET_MSR_FILTER, &filter_allow);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
 
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c b/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
index a9b827c69f32..c5af48f73432 100644
--- a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
+++ b/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
@@ -115,8 +115,8 @@ int main(int argc, char *argv[])
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 	get_set_sigalrm_vcpu(vcpu);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vm_install_exception_handler(vm, UD_VECTOR, guest_ud_handler);
 
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
index ebbcb0a3f743..e9a2527a0319 100644
--- a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
+++ b/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
@@ -85,8 +85,8 @@ static void test_guest_wrmsr_perf_capabilities(union perf_capabilities host_cap)
 	struct ucall uc;
 	int r, i;
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	vcpu_set_msr(vcpu, MSR_IA32_PERF_CAPABILITIES, host_cap.capabilities);
 
diff --git a/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
index 67ac2a3292ef..d4f9d100b89a 100644
--- a/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
+++ b/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
@@ -410,8 +410,8 @@ int main(int argc, char *argv[])
 
 	vm = vm_create_with_one_vcpu(&params[0].vcpu, halter_guest_code);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(params[0].vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(params[0].vcpu);
 	vm_install_exception_handler(vm, IPI_VECTOR, guest_ipi_handler);
 
 	virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA);
diff --git a/tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c b/tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c
index 77d04a7bdadd..726b13c9e1f4 100644
--- a/tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c
+++ b/tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c
@@ -109,8 +109,8 @@ int main(int argc, char *argv[])
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 	run = vcpu->run;
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 
 	while (1) {
 		vcpu_run(vcpu);
diff --git a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c b/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
index 05898ad9f4d9..854e512d7963 100644
--- a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
+++ b/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
@@ -526,8 +526,8 @@ int main(int argc, char *argv[])
 	};
 	vm_ioctl(vm, KVM_XEN_HVM_SET_ATTR, &vec);
 
-	vm_init_descriptor_tables(vm);
-	vcpu_init_descriptor_tables(vcpu);
+	vm_init_vector_tables(vm);
+	vcpu_init_vector_tables(vcpu);
 	vm_install_exception_handler(vm, EVTCHN_VECTOR, evtchn_handler);
 
 	if (do_runstate_tests) {
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
  2023-09-02 12:59 ` [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 13:24   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 3/8] tools: riscv: Add header file csr.h Haibo Xu
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Daniel Henrique Barboza,
	Greentime Hu, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, Aaron Lewis, David Matlack, Vitaly Kuznetsov,
	Ackerley Tng, Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu,
	Peter Gonda, Maxim Levitsky, Thomas Huth,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	linux-kernel, linux-riscv, kvm, linux-kselftest, linux-arm-kernel,
	kvmarm, kvm-riscv

Split the arch-neutral test code out of aarch64/arch_timer.c
and put them into a common arch_timer.c. This is a preparation
to share timer test codes in riscv.

Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/testing/selftests/kvm/Makefile          |   9 +-
 .../selftests/kvm/aarch64/arch_timer.c        | 288 +-----------------
 tools/testing/selftests/kvm/arch_timer.c      | 252 +++++++++++++++
 .../selftests/kvm/include/timer_test.h        |  52 ++++
 4 files changed, 317 insertions(+), 284 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/arch_timer.c
 create mode 100644 tools/testing/selftests/kvm/include/timer_test.h

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 0b9c42fbce8c..fb8904e2c06a 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -140,7 +140,6 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
 
 TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
-TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
 TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
@@ -150,6 +149,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
 TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
+TEST_GEN_PROGS_aarch64 += arch_timer
 TEST_GEN_PROGS_aarch64 += demand_paging_test
 TEST_GEN_PROGS_aarch64 += dirty_log_test
 TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
@@ -188,6 +188,7 @@ TEST_GEN_PROGS_riscv += set_memory_region_test
 TEST_GEN_PROGS_riscv += kvm_binary_stats_test
 
 SPLIT_TESTS += get-reg-list
+SPLIT_TESTS += arch_timer
 
 TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
 TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
@@ -248,13 +249,10 @@ TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TESTS_OBJS))
 -include $(TEST_DEP_FILES)
 
 $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): %: %.o
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
 $(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
 
-$(SPLIT_TESTS_TARGETS): %: %.o $(SPLIT_TESTS_OBJS)
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
-
 EXTRA_CLEAN += $(LIBKVM_OBJS) $(TEST_DEP_FILES) $(TEST_GEN_OBJ) $(SPLIT_TESTS_OBJS) cscope.*
 
 x := $(shell mkdir -p $(sort $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
@@ -273,6 +271,7 @@ $(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
 x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
 $(TEST_GEN_PROGS): $(LIBKVM_OBJS)
 $(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
+$(SPLIT_TESTS_TARGETS): $(OUTPUT)/%: $(ARCH_DIR)/%.o
 
 cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
 cscope:
diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
index b63859829a96..ceb649548751 100644
--- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
+++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
@@ -1,91 +1,25 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * arch_timer.c - Tests the aarch64 timer IRQ functionality
- *
  * The test validates both the virtual and physical timer IRQs using
- * CVAL and TVAL registers. This consitutes the four stages in the test.
- * The guest's main thread configures the timer interrupt for a stage
- * and waits for it to fire, with a timeout equal to the timer period.
- * It asserts that the timeout doesn't exceed the timer period.
- *
- * On the other hand, upon receipt of an interrupt, the guest's interrupt
- * handler validates the interrupt by checking if the architectural state
- * is in compliance with the specifications.
- *
- * The test provides command-line options to configure the timer's
- * period (-p), number of vCPUs (-n), and iterations per stage (-i).
- * To stress-test the timer stack even more, an option to migrate the
- * vCPUs across pCPUs (-m), at a particular rate, is also provided.
+ * CVAL and TVAL registers.
  *
  * Copyright (c) 2021, Google LLC.
  */
 #define _GNU_SOURCE
 
-#include <stdlib.h>
-#include <pthread.h>
-#include <linux/kvm.h>
-#include <linux/sizes.h>
-#include <linux/bitmap.h>
-#include <sys/sysinfo.h>
-
-#include "kvm_util.h"
-#include "processor.h"
-#include "delay.h"
 #include "arch_timer.h"
+#include "delay.h"
 #include "gic.h"
+#include "processor.h"
+#include "timer_test.h"
 #include "vgic.h"
 
-#define NR_VCPUS_DEF			4
-#define NR_TEST_ITERS_DEF		5
-#define TIMER_TEST_PERIOD_MS_DEF	10
-#define TIMER_TEST_ERR_MARGIN_US	100
-#define TIMER_TEST_MIGRATION_FREQ_MS	2
-
-struct test_args {
-	int nr_vcpus;
-	int nr_iter;
-	int timer_period_ms;
-	int migration_freq_ms;
-	struct kvm_arm_counter_offset offset;
-};
-
-static struct test_args test_args = {
-	.nr_vcpus = NR_VCPUS_DEF,
-	.nr_iter = NR_TEST_ITERS_DEF,
-	.timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
-	.migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
-	.offset = { .reserved = 1 },
-};
-
-#define msecs_to_usecs(msec)		((msec) * 1000LL)
-
-#define GICD_BASE_GPA			0x8000000ULL
-#define GICR_BASE_GPA			0x80A0000ULL
-
-enum guest_stage {
-	GUEST_STAGE_VTIMER_CVAL = 1,
-	GUEST_STAGE_VTIMER_TVAL,
-	GUEST_STAGE_PTIMER_CVAL,
-	GUEST_STAGE_PTIMER_TVAL,
-	GUEST_STAGE_MAX,
-};
-
-/* Shared variables between host and guest */
-struct test_vcpu_shared_data {
-	int nr_iter;
-	enum guest_stage guest_stage;
-	uint64_t xcnt;
-};
-
-static struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
-static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
-static struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
+extern struct test_args test_args;
+extern struct kvm_vcpu *vcpus[];
+extern struct test_vcpu_shared_data vcpu_shared_data[];
 
 static int vtimer_irq, ptimer_irq;
 
-static unsigned long *vcpu_done_map;
-static pthread_mutex_t vcpu_done_map_lock;
-
 static void
 guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
 {
@@ -222,137 +156,6 @@ static void guest_code(void)
 	GUEST_DONE();
 }
 
-static void *test_vcpu_run(void *arg)
-{
-	unsigned int vcpu_idx = (unsigned long)arg;
-	struct ucall uc;
-	struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
-	struct kvm_vm *vm = vcpu->vm;
-	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
-
-	vcpu_run(vcpu);
-
-	/* Currently, any exit from guest is an indication of completion */
-	pthread_mutex_lock(&vcpu_done_map_lock);
-	__set_bit(vcpu_idx, vcpu_done_map);
-	pthread_mutex_unlock(&vcpu_done_map_lock);
-
-	switch (get_ucall(vcpu, &uc)) {
-	case UCALL_SYNC:
-	case UCALL_DONE:
-		break;
-	case UCALL_ABORT:
-		sync_global_from_guest(vm, *shared_data);
-		fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
-			vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
-		REPORT_GUEST_ASSERT(uc);
-		break;
-	default:
-		TEST_FAIL("Unexpected guest exit\n");
-	}
-
-	return NULL;
-}
-
-static uint32_t test_get_pcpu(void)
-{
-	uint32_t pcpu;
-	unsigned int nproc_conf;
-	cpu_set_t online_cpuset;
-
-	nproc_conf = get_nprocs_conf();
-	sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
-
-	/* Randomly find an available pCPU to place a vCPU on */
-	do {
-		pcpu = rand() % nproc_conf;
-	} while (!CPU_ISSET(pcpu, &online_cpuset));
-
-	return pcpu;
-}
-
-static int test_migrate_vcpu(unsigned int vcpu_idx)
-{
-	int ret;
-	cpu_set_t cpuset;
-	uint32_t new_pcpu = test_get_pcpu();
-
-	CPU_ZERO(&cpuset);
-	CPU_SET(new_pcpu, &cpuset);
-
-	pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
-
-	ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
-				     sizeof(cpuset), &cpuset);
-
-	/* Allow the error where the vCPU thread is already finished */
-	TEST_ASSERT(ret == 0 || ret == ESRCH,
-		    "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
-		    vcpu_idx, new_pcpu, ret);
-
-	return ret;
-}
-
-static void *test_vcpu_migration(void *arg)
-{
-	unsigned int i, n_done;
-	bool vcpu_done;
-
-	do {
-		usleep(msecs_to_usecs(test_args.migration_freq_ms));
-
-		for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
-			pthread_mutex_lock(&vcpu_done_map_lock);
-			vcpu_done = test_bit(i, vcpu_done_map);
-			pthread_mutex_unlock(&vcpu_done_map_lock);
-
-			if (vcpu_done) {
-				n_done++;
-				continue;
-			}
-
-			test_migrate_vcpu(i);
-		}
-	} while (test_args.nr_vcpus != n_done);
-
-	return NULL;
-}
-
-static void test_run(struct kvm_vm *vm)
-{
-	pthread_t pt_vcpu_migration;
-	unsigned int i;
-	int ret;
-
-	pthread_mutex_init(&vcpu_done_map_lock, NULL);
-	vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
-	TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
-
-	for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
-		ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
-				     (void *)(unsigned long)i);
-		TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
-	}
-
-	/* Spawn a thread to control the vCPU migrations */
-	if (test_args.migration_freq_ms) {
-		srand(time(NULL));
-
-		ret = pthread_create(&pt_vcpu_migration, NULL,
-					test_vcpu_migration, NULL);
-		TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
-	}
-
-
-	for (i = 0; i < test_args.nr_vcpus; i++)
-		pthread_join(pt_vcpu_run[i], NULL);
-
-	if (test_args.migration_freq_ms)
-		pthread_join(pt_vcpu_migration, NULL);
-
-	bitmap_free(vcpu_done_map);
-}
-
 static void test_init_timer_irq(struct kvm_vm *vm)
 {
 	/* Timer initid should be same for all the vCPUs, so query only vCPU-0 */
@@ -369,7 +172,7 @@ static void test_init_timer_irq(struct kvm_vm *vm)
 
 static int gic_fd;
 
-static struct kvm_vm *test_vm_create(void)
+struct kvm_vm *test_vm_create(void)
 {
 	struct kvm_vm *vm;
 	unsigned int i;
@@ -400,81 +203,8 @@ static struct kvm_vm *test_vm_create(void)
 	return vm;
 }
 
-static void test_vm_cleanup(struct kvm_vm *vm)
+void test_vm_cleanup(struct kvm_vm *vm)
 {
 	close(gic_fd);
 	kvm_vm_free(vm);
 }
-
-static void test_print_help(char *name)
-{
-	pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
-		name);
-	pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
-		NR_VCPUS_DEF, KVM_MAX_VCPUS);
-	pr_info("\t-i: Number of iterations per stage (default: %u)\n",
-		NR_TEST_ITERS_DEF);
-	pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
-		TIMER_TEST_PERIOD_MS_DEF);
-	pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
-		TIMER_TEST_MIGRATION_FREQ_MS);
-	pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
-	pr_info("\t-h: print this help screen\n");
-}
-
-static bool parse_args(int argc, char *argv[])
-{
-	int opt;
-
-	while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
-		switch (opt) {
-		case 'n':
-			test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
-			if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
-				pr_info("Max allowed vCPUs: %u\n",
-					KVM_MAX_VCPUS);
-				goto err;
-			}
-			break;
-		case 'i':
-			test_args.nr_iter = atoi_positive("Number of iterations", optarg);
-			break;
-		case 'p':
-			test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
-			break;
-		case 'm':
-			test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
-			break;
-		case 'o':
-			test_args.offset.counter_offset = strtol(optarg, NULL, 0);
-			test_args.offset.reserved = 0;
-			break;
-		case 'h':
-		default:
-			goto err;
-		}
-	}
-
-	return true;
-
-err:
-	test_print_help(argv[0]);
-	return false;
-}
-
-int main(int argc, char *argv[])
-{
-	struct kvm_vm *vm;
-
-	if (!parse_args(argc, argv))
-		exit(KSFT_SKIP);
-
-	__TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
-		       "At least two physical CPUs needed for vCPU migration");
-
-	vm = test_vm_create();
-	test_run(vm);
-	test_vm_cleanup(vm);
-
-	return 0;
-}
diff --git a/tools/testing/selftests/kvm/arch_timer.c b/tools/testing/selftests/kvm/arch_timer.c
new file mode 100644
index 000000000000..529024f58c98
--- /dev/null
+++ b/tools/testing/selftests/kvm/arch_timer.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * arch_timer.c - Tests the arch timer IRQ functionality
+ *
+ * The guest's main thread configures the timer interrupt for and waits
+ * for it to fire, with a timeout equal to the timer period.
+ * It asserts that the timeout doesn't exceed the timer period.
+ *
+ * On the other hand, upon receipt of an interrupt, the guest's interrupt
+ * handler validates the interrupt by checking if the architectural state
+ * is in compliance with the specifications.
+ *
+ * The test provides command-line options to configure the timer's
+ * period (-p), number of vCPUs (-n), and iterations per stage (-i).
+ * To stress-test the timer stack even more, an option to migrate the
+ * vCPUs across pCPUs (-m), at a particular rate, is also provided.
+ *
+ * Copyright (c) 2021, Google LLC.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <linux/sizes.h>
+#include <linux/bitmap.h>
+#include <sys/sysinfo.h>
+
+#include "timer_test.h"
+
+struct test_args test_args = {
+    .nr_vcpus = NR_VCPUS_DEF,
+    .nr_iter = NR_TEST_ITERS_DEF,
+    .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
+    .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
+#ifdef __aarch64__
+    .offset = { .reserved = 1 },
+#endif
+};
+
+struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
+struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
+
+static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
+static unsigned long *vcpu_done_map;
+static pthread_mutex_t vcpu_done_map_lock;
+
+static void *test_vcpu_run(void *arg)
+{
+	unsigned int vcpu_idx = (unsigned long)arg;
+	struct ucall uc;
+	struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
+	struct kvm_vm *vm = vcpu->vm;
+	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
+
+	vcpu_run(vcpu);
+
+	/* Currently, any exit from guest is an indication of completion */
+	pthread_mutex_lock(&vcpu_done_map_lock);
+	__set_bit(vcpu_idx, vcpu_done_map);
+	pthread_mutex_unlock(&vcpu_done_map_lock);
+
+	switch (get_ucall(vcpu, &uc)) {
+	case UCALL_SYNC:
+	case UCALL_DONE:
+		break;
+	case UCALL_ABORT:
+		sync_global_from_guest(vm, *shared_data);
+		fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
+		        vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
+		REPORT_GUEST_ASSERT(uc);
+		break;
+	default:
+		TEST_FAIL("Unexpected guest exit\n");
+	}
+
+	pr_info("PASS(vCPU-%d).\n", vcpu_idx);
+
+	return NULL;
+}
+
+static uint32_t test_get_pcpu(void)
+{
+	uint32_t pcpu;
+	unsigned int nproc_conf;
+	cpu_set_t online_cpuset;
+
+	nproc_conf = get_nprocs_conf();
+	sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
+
+	/* Randomly find an available pCPU to place a vCPU on */
+	do {
+		pcpu = rand() % nproc_conf;
+	} while (!CPU_ISSET(pcpu, &online_cpuset));
+
+	return pcpu;
+}
+
+static int test_migrate_vcpu(unsigned int vcpu_idx)
+{
+	int ret;
+	cpu_set_t cpuset;
+	uint32_t new_pcpu = test_get_pcpu();
+
+	CPU_ZERO(&cpuset);
+	CPU_SET(new_pcpu, &cpuset);
+
+	pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
+
+	ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
+				     sizeof(cpuset), &cpuset);
+
+	/* Allow the error where the vCPU thread is already finished */
+	TEST_ASSERT(ret == 0 || ret == ESRCH,
+		    "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
+		    vcpu_idx, new_pcpu, ret);
+
+	return ret;
+}
+
+static void *test_vcpu_migration(void *arg)
+{
+	unsigned int i, n_done;
+	bool vcpu_done;
+
+	do {
+		usleep(msecs_to_usecs(test_args.migration_freq_ms));
+
+		for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
+			pthread_mutex_lock(&vcpu_done_map_lock);
+			vcpu_done = test_bit(i, vcpu_done_map);
+			pthread_mutex_unlock(&vcpu_done_map_lock);
+
+			if (vcpu_done) {
+				n_done++;
+				continue;
+			}
+
+			test_migrate_vcpu(i);
+		}
+	} while (test_args.nr_vcpus != n_done);
+
+	return NULL;
+}
+
+static void test_run(struct kvm_vm *vm)
+{
+	pthread_t pt_vcpu_migration;
+	unsigned int i;
+	int ret;
+
+	pthread_mutex_init(&vcpu_done_map_lock, NULL);
+	vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
+	TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
+
+	for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
+		ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
+				     (void *)(unsigned long)i);
+		TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
+	}
+
+	/* Spawn a thread to control the vCPU migrations */
+	if (test_args.migration_freq_ms) {
+		srand(time(NULL));
+
+		ret = pthread_create(&pt_vcpu_migration, NULL,
+					test_vcpu_migration, NULL);
+		TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
+	}
+
+
+	for (i = 0; i < test_args.nr_vcpus; i++)
+		pthread_join(pt_vcpu_run[i], NULL);
+
+	if (test_args.migration_freq_ms)
+		pthread_join(pt_vcpu_migration, NULL);
+
+	bitmap_free(vcpu_done_map);
+}
+
+static void test_print_help(char *name)
+{
+	pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
+		name);
+	pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
+		NR_VCPUS_DEF, KVM_MAX_VCPUS);
+	pr_info("\t-i: Number of iterations per stage (default: %u)\n",
+		NR_TEST_ITERS_DEF);
+	pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
+		TIMER_TEST_PERIOD_MS_DEF);
+	pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
+		TIMER_TEST_MIGRATION_FREQ_MS);
+	pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
+	pr_info("\t-h: print this help screen\n");
+}
+
+static bool parse_args(int argc, char *argv[])
+{
+	int opt;
+
+	while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
+		switch (opt) {
+		case 'n':
+			test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
+			if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
+				pr_info("Max allowed vCPUs: %u\n",
+					KVM_MAX_VCPUS);
+				goto err;
+			}
+			break;
+		case 'i':
+			test_args.nr_iter = atoi_positive("Number of iterations", optarg);
+			break;
+		case 'p':
+			test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
+			break;
+		case 'm':
+			test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
+			break;
+		case 'o':
+			test_args.offset.counter_offset = strtol(optarg, NULL, 0);
+			test_args.offset.reserved = 0;
+			break;
+		case 'h':
+		default:
+			goto err;
+		}
+	}
+
+	return true;
+
+err:
+	test_print_help(argv[0]);
+	return false;
+}
+
+int main(int argc, char *argv[])
+{
+	struct kvm_vm *vm;
+
+	if (!parse_args(argc, argv))
+		exit(KSFT_SKIP);
+
+	__TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
+		       "At least two physical CPUs needed for vCPU migration");
+
+	vm = test_vm_create();
+	test_run(vm);
+	test_vm_cleanup(vm);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/kvm/include/timer_test.h b/tools/testing/selftests/kvm/include/timer_test.h
new file mode 100644
index 000000000000..109e4d635627
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/timer_test.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tools/testing/selftests/kvm/include/timer_test.h
+ *
+ * Copyright (C) 2018, Google LLC
+ */
+
+#ifndef SELFTEST_KVM_TIMER_TEST_H
+#define SELFTEST_KVM_TIMER_TEST_H
+
+#include "kvm_util.h"
+
+#define NR_VCPUS_DEF            4
+#define NR_TEST_ITERS_DEF       5
+#define TIMER_TEST_PERIOD_MS_DEF    10
+#define TIMER_TEST_ERR_MARGIN_US    100
+#define TIMER_TEST_MIGRATION_FREQ_MS    2
+
+#define msecs_to_usecs(msec)    ((msec) * 1000LL)
+
+#define GICD_BASE_GPA    0x8000000ULL
+#define GICR_BASE_GPA    0x80A0000ULL
+
+enum guest_stage {
+	GUEST_STAGE_VTIMER_CVAL=1,
+	GUEST_STAGE_VTIMER_TVAL,
+	GUEST_STAGE_PTIMER_CVAL,
+	GUEST_STAGE_PTIMER_TVAL,
+	GUEST_STAGE_MAX,
+};
+
+/* Timer test cmdline parameters */
+struct test_args
+{
+	int nr_vcpus;
+	int nr_iter;
+	int timer_period_ms;
+	int migration_freq_ms;
+	struct kvm_arm_counter_offset offset;
+};
+
+/* Shared variables between host and guest */
+struct test_vcpu_shared_data {
+	int nr_iter;
+	enum guest_stage guest_stage;
+	uint64_t xcnt;
+};
+
+struct kvm_vm* test_vm_create(void);
+void test_vm_cleanup(struct kvm_vm *vm);
+
+#endif /* SELFTEST_KVM_TIMER_TEST_H */
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
  2023-09-02 12:59 ` [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling Haibo Xu
  2023-09-02 12:59 ` [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 13:26   ` Andrew Jones
  2023-09-04 13:33   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h Haibo Xu
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Daniel Henrique Barboza,
	wchen, Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Vipin Sharma, Aaron Lewis, David Matlack, Vitaly Kuznetsov,
	Ackerley Tng, Mingwei Zhang, Lei Wang, Maxim Levitsky,
	Peter Gonda, Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

Borrow the csr definitions and operations from kernel's
arch/riscv/include/asm/csr.h to tools/ for riscv.

Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
 1 file changed, 521 insertions(+)
 create mode 100644 tools/arch/riscv/include/asm/csr.h

diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h
new file mode 100644
index 000000000000..4e86c82aacbd
--- /dev/null
+++ b/tools/arch/riscv/include/asm/csr.h
@@ -0,0 +1,521 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_CSR_H
+#define _ASM_RISCV_CSR_H
+
+#include <linux/bits.h>
+
+/* Status register flags */
+#define SR_SIE		_AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_MIE		_AC(0x00000008, UL) /* Machine Interrupt Enable */
+#define SR_SPIE		_AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_MPIE		_AC(0x00000080, UL) /* Previous Machine IE */
+#define SR_SPP		_AC(0x00000100, UL) /* Previously Supervisor */
+#define SR_MPP		_AC(0x00001800, UL) /* Previously Machine */
+#define SR_SUM		_AC(0x00040000, UL) /* Supervisor User Memory Access */
+
+#define SR_FS		_AC(0x00006000, UL) /* Floating-point Status */
+#define SR_FS_OFF	_AC(0x00000000, UL)
+#define SR_FS_INITIAL	_AC(0x00002000, UL)
+#define SR_FS_CLEAN	_AC(0x00004000, UL)
+#define SR_FS_DIRTY	_AC(0x00006000, UL)
+
+#define SR_VS		_AC(0x00000600, UL) /* Vector Status */
+#define SR_VS_OFF	_AC(0x00000000, UL)
+#define SR_VS_INITIAL	_AC(0x00000200, UL)
+#define SR_VS_CLEAN	_AC(0x00000400, UL)
+#define SR_VS_DIRTY	_AC(0x00000600, UL)
+
+#define SR_XS		_AC(0x00018000, UL) /* Extension Status */
+#define SR_XS_OFF	_AC(0x00000000, UL)
+#define SR_XS_INITIAL	_AC(0x00008000, UL)
+#define SR_XS_CLEAN	_AC(0x00010000, UL)
+#define SR_XS_DIRTY	_AC(0x00018000, UL)
+
+#define SR_FS_VS	(SR_FS | SR_VS) /* Vector and Floating-Point Unit */
+
+#ifndef CONFIG_64BIT
+#define SR_SD		_AC(0x80000000, UL) /* FS/VS/XS dirty */
+#else
+#define SR_SD		_AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
+#endif
+
+#ifdef CONFIG_64BIT
+#define SR_UXL		_AC(0x300000000, UL) /* XLEN mask for U-mode */
+#define SR_UXL_32	_AC(0x100000000, UL) /* XLEN = 32 for U-mode */
+#define SR_UXL_64	_AC(0x200000000, UL) /* XLEN = 64 for U-mode */
+#endif
+
+/* SATP flags */
+#ifndef CONFIG_64BIT
+#define SATP_PPN	_AC(0x003FFFFF, UL)
+#define SATP_MODE_32	_AC(0x80000000, UL)
+#define SATP_ASID_BITS	9
+#define SATP_ASID_SHIFT	22
+#define SATP_ASID_MASK	_AC(0x1FF, UL)
+#else
+#define SATP_PPN	_AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39	_AC(0x8000000000000000, UL)
+#define SATP_MODE_48	_AC(0x9000000000000000, UL)
+#define SATP_MODE_57	_AC(0xa000000000000000, UL)
+#define SATP_ASID_BITS	16
+#define SATP_ASID_SHIFT	44
+#define SATP_ASID_MASK	_AC(0xFFFF, UL)
+#endif
+
+/* Exception cause high bit - is an interrupt if set */
+#define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
+
+/* Interrupt causes (minus the high bit) */
+#define IRQ_S_SOFT		1
+#define IRQ_VS_SOFT		2
+#define IRQ_M_SOFT		3
+#define IRQ_S_TIMER		5
+#define IRQ_VS_TIMER		6
+#define IRQ_M_TIMER		7
+#define IRQ_S_EXT		9
+#define IRQ_VS_EXT		10
+#define IRQ_M_EXT		11
+#define IRQ_S_GEXT		12
+#define IRQ_PMU_OVF		13
+#define IRQ_LOCAL_MAX		(IRQ_PMU_OVF + 1)
+#define IRQ_LOCAL_MASK		GENMASK((IRQ_LOCAL_MAX - 1), 0)
+
+/* Exception causes */
+#define EXC_INST_MISALIGNED	0
+#define EXC_INST_ACCESS		1
+#define EXC_INST_ILLEGAL	2
+#define EXC_BREAKPOINT		3
+#define EXC_LOAD_MISALIGNED	4
+#define EXC_LOAD_ACCESS		5
+#define EXC_STORE_MISALIGNED	6
+#define EXC_STORE_ACCESS	7
+#define EXC_SYSCALL		8
+#define EXC_HYPERVISOR_SYSCALL	9
+#define EXC_SUPERVISOR_SYSCALL	10
+#define EXC_INST_PAGE_FAULT	12
+#define EXC_LOAD_PAGE_FAULT	13
+#define EXC_STORE_PAGE_FAULT	15
+#define EXC_INST_GUEST_PAGE_FAULT	20
+#define EXC_LOAD_GUEST_PAGE_FAULT	21
+#define EXC_VIRTUAL_INST_FAULT		22
+#define EXC_STORE_GUEST_PAGE_FAULT	23
+
+/* PMP configuration */
+#define PMP_R			0x01
+#define PMP_W			0x02
+#define PMP_X			0x04
+#define PMP_A			0x18
+#define PMP_A_TOR		0x08
+#define PMP_A_NA4		0x10
+#define PMP_A_NAPOT		0x18
+#define PMP_L			0x80
+
+/* HSTATUS flags */
+#ifdef CONFIG_64BIT
+#define HSTATUS_VSXL		_AC(0x300000000, UL)
+#define HSTATUS_VSXL_SHIFT	32
+#endif
+#define HSTATUS_VTSR		_AC(0x00400000, UL)
+#define HSTATUS_VTW		_AC(0x00200000, UL)
+#define HSTATUS_VTVM		_AC(0x00100000, UL)
+#define HSTATUS_VGEIN		_AC(0x0003f000, UL)
+#define HSTATUS_VGEIN_SHIFT	12
+#define HSTATUS_HU		_AC(0x00000200, UL)
+#define HSTATUS_SPVP		_AC(0x00000100, UL)
+#define HSTATUS_SPV		_AC(0x00000080, UL)
+#define HSTATUS_GVA		_AC(0x00000040, UL)
+#define HSTATUS_VSBE		_AC(0x00000020, UL)
+
+/* HGATP flags */
+#define HGATP_MODE_OFF		_AC(0, UL)
+#define HGATP_MODE_SV32X4	_AC(1, UL)
+#define HGATP_MODE_SV39X4	_AC(8, UL)
+#define HGATP_MODE_SV48X4	_AC(9, UL)
+#define HGATP_MODE_SV57X4	_AC(10, UL)
+
+#define HGATP32_MODE_SHIFT	31
+#define HGATP32_VMID_SHIFT	22
+#define HGATP32_VMID		GENMASK(28, 22)
+#define HGATP32_PPN		GENMASK(21, 0)
+
+#define HGATP64_MODE_SHIFT	60
+#define HGATP64_VMID_SHIFT	44
+#define HGATP64_VMID		GENMASK(57, 44)
+#define HGATP64_PPN		GENMASK(43, 0)
+
+#define HGATP_PAGE_SHIFT	12
+
+#ifdef CONFIG_64BIT
+#define HGATP_PPN		HGATP64_PPN
+#define HGATP_VMID_SHIFT	HGATP64_VMID_SHIFT
+#define HGATP_VMID		HGATP64_VMID
+#define HGATP_MODE_SHIFT	HGATP64_MODE_SHIFT
+#else
+#define HGATP_PPN		HGATP32_PPN
+#define HGATP_VMID_SHIFT	HGATP32_VMID_SHIFT
+#define HGATP_VMID		HGATP32_VMID
+#define HGATP_MODE_SHIFT	HGATP32_MODE_SHIFT
+#endif
+
+/* VSIP & HVIP relation */
+#define VSIP_TO_HVIP_SHIFT	(IRQ_VS_SOFT - IRQ_S_SOFT)
+#define VSIP_VALID_MASK		((_AC(1, UL) << IRQ_S_SOFT) | \
+				 (_AC(1, UL) << IRQ_S_TIMER) | \
+				 (_AC(1, UL) << IRQ_S_EXT))
+
+/* AIA CSR bits */
+#define TOPI_IID_SHIFT		16
+#define TOPI_IID_MASK		GENMASK(11, 0)
+#define TOPI_IPRIO_MASK		GENMASK(7, 0)
+#define TOPI_IPRIO_BITS		8
+
+#define TOPEI_ID_SHIFT		16
+#define TOPEI_ID_MASK		GENMASK(10, 0)
+#define TOPEI_PRIO_MASK		GENMASK(10, 0)
+
+#define ISELECT_IPRIO0		0x30
+#define ISELECT_IPRIO15		0x3f
+#define ISELECT_MASK		GENMASK(8, 0)
+
+#define HVICTL_VTI		BIT(30)
+#define HVICTL_IID		GENMASK(27, 16)
+#define HVICTL_IID_SHIFT	16
+#define HVICTL_DPR		BIT(9)
+#define HVICTL_IPRIOM		BIT(8)
+#define HVICTL_IPRIO		GENMASK(7, 0)
+
+/* xENVCFG flags */
+#define ENVCFG_STCE			(_AC(1, ULL) << 63)
+#define ENVCFG_PBMTE			(_AC(1, ULL) << 62)
+#define ENVCFG_CBZE			(_AC(1, UL) << 7)
+#define ENVCFG_CBCFE			(_AC(1, UL) << 6)
+#define ENVCFG_CBIE_SHIFT		4
+#define ENVCFG_CBIE			(_AC(0x3, UL) << ENVCFG_CBIE_SHIFT)
+#define ENVCFG_CBIE_ILL			_AC(0x0, UL)
+#define ENVCFG_CBIE_FLUSH		_AC(0x1, UL)
+#define ENVCFG_CBIE_INV			_AC(0x3, UL)
+#define ENVCFG_FIOM			_AC(0x1, UL)
+
+/* symbolic CSR names: */
+#define CSR_CYCLE		0xc00
+#define CSR_TIME		0xc01
+#define CSR_INSTRET		0xc02
+#define CSR_HPMCOUNTER3		0xc03
+#define CSR_HPMCOUNTER4		0xc04
+#define CSR_HPMCOUNTER5		0xc05
+#define CSR_HPMCOUNTER6		0xc06
+#define CSR_HPMCOUNTER7		0xc07
+#define CSR_HPMCOUNTER8		0xc08
+#define CSR_HPMCOUNTER9		0xc09
+#define CSR_HPMCOUNTER10	0xc0a
+#define CSR_HPMCOUNTER11	0xc0b
+#define CSR_HPMCOUNTER12	0xc0c
+#define CSR_HPMCOUNTER13	0xc0d
+#define CSR_HPMCOUNTER14	0xc0e
+#define CSR_HPMCOUNTER15	0xc0f
+#define CSR_HPMCOUNTER16	0xc10
+#define CSR_HPMCOUNTER17	0xc11
+#define CSR_HPMCOUNTER18	0xc12
+#define CSR_HPMCOUNTER19	0xc13
+#define CSR_HPMCOUNTER20	0xc14
+#define CSR_HPMCOUNTER21	0xc15
+#define CSR_HPMCOUNTER22	0xc16
+#define CSR_HPMCOUNTER23	0xc17
+#define CSR_HPMCOUNTER24	0xc18
+#define CSR_HPMCOUNTER25	0xc19
+#define CSR_HPMCOUNTER26	0xc1a
+#define CSR_HPMCOUNTER27	0xc1b
+#define CSR_HPMCOUNTER28	0xc1c
+#define CSR_HPMCOUNTER29	0xc1d
+#define CSR_HPMCOUNTER30	0xc1e
+#define CSR_HPMCOUNTER31	0xc1f
+#define CSR_CYCLEH		0xc80
+#define CSR_TIMEH		0xc81
+#define CSR_INSTRETH		0xc82
+#define CSR_HPMCOUNTER3H	0xc83
+#define CSR_HPMCOUNTER4H	0xc84
+#define CSR_HPMCOUNTER5H	0xc85
+#define CSR_HPMCOUNTER6H	0xc86
+#define CSR_HPMCOUNTER7H	0xc87
+#define CSR_HPMCOUNTER8H	0xc88
+#define CSR_HPMCOUNTER9H	0xc89
+#define CSR_HPMCOUNTER10H	0xc8a
+#define CSR_HPMCOUNTER11H	0xc8b
+#define CSR_HPMCOUNTER12H	0xc8c
+#define CSR_HPMCOUNTER13H	0xc8d
+#define CSR_HPMCOUNTER14H	0xc8e
+#define CSR_HPMCOUNTER15H	0xc8f
+#define CSR_HPMCOUNTER16H	0xc90
+#define CSR_HPMCOUNTER17H	0xc91
+#define CSR_HPMCOUNTER18H	0xc92
+#define CSR_HPMCOUNTER19H	0xc93
+#define CSR_HPMCOUNTER20H	0xc94
+#define CSR_HPMCOUNTER21H	0xc95
+#define CSR_HPMCOUNTER22H	0xc96
+#define CSR_HPMCOUNTER23H	0xc97
+#define CSR_HPMCOUNTER24H	0xc98
+#define CSR_HPMCOUNTER25H	0xc99
+#define CSR_HPMCOUNTER26H	0xc9a
+#define CSR_HPMCOUNTER27H	0xc9b
+#define CSR_HPMCOUNTER28H	0xc9c
+#define CSR_HPMCOUNTER29H	0xc9d
+#define CSR_HPMCOUNTER30H	0xc9e
+#define CSR_HPMCOUNTER31H	0xc9f
+
+#define CSR_SSCOUNTOVF		0xda0
+
+#define CSR_SSTATUS		0x100
+#define CSR_SIE			0x104
+#define CSR_STVEC		0x105
+#define CSR_SCOUNTEREN		0x106
+#define CSR_SSCRATCH		0x140
+#define CSR_SEPC		0x141
+#define CSR_SCAUSE		0x142
+#define CSR_STVAL		0x143
+#define CSR_SIP			0x144
+#define CSR_SATP		0x180
+
+#define CSR_STIMECMP		0x14D
+#define CSR_STIMECMPH		0x15D
+
+/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
+#define CSR_SISELECT		0x150
+#define CSR_SIREG		0x151
+
+/* Supervisor-Level Interrupts (AIA) */
+#define CSR_STOPEI		0x15c
+#define CSR_STOPI		0xdb0
+
+/* Supervisor-Level High-Half CSRs (AIA) */
+#define CSR_SIEH		0x114
+#define CSR_SIPH		0x154
+
+#define CSR_VSSTATUS		0x200
+#define CSR_VSIE		0x204
+#define CSR_VSTVEC		0x205
+#define CSR_VSSCRATCH		0x240
+#define CSR_VSEPC		0x241
+#define CSR_VSCAUSE		0x242
+#define CSR_VSTVAL		0x243
+#define CSR_VSIP		0x244
+#define CSR_VSATP		0x280
+#define CSR_VSTIMECMP		0x24D
+#define CSR_VSTIMECMPH		0x25D
+
+#define CSR_HSTATUS		0x600
+#define CSR_HEDELEG		0x602
+#define CSR_HIDELEG		0x603
+#define CSR_HIE			0x604
+#define CSR_HTIMEDELTA		0x605
+#define CSR_HCOUNTEREN		0x606
+#define CSR_HGEIE		0x607
+#define CSR_HENVCFG		0x60a
+#define CSR_HTIMEDELTAH		0x615
+#define CSR_HENVCFGH		0x61a
+#define CSR_HTVAL		0x643
+#define CSR_HIP			0x644
+#define CSR_HVIP		0x645
+#define CSR_HTINST		0x64a
+#define CSR_HGATP		0x680
+#define CSR_HGEIP		0xe12
+
+/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
+#define CSR_HVIEN		0x608
+#define CSR_HVICTL		0x609
+#define CSR_HVIPRIO1		0x646
+#define CSR_HVIPRIO2		0x647
+
+/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
+#define CSR_VSISELECT		0x250
+#define CSR_VSIREG		0x251
+
+/* VS-Level Interrupts (H-extension with AIA) */
+#define CSR_VSTOPEI		0x25c
+#define CSR_VSTOPI		0xeb0
+
+/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
+#define CSR_HIDELEGH		0x613
+#define CSR_HVIENH		0x618
+#define CSR_HVIPH		0x655
+#define CSR_HVIPRIO1H		0x656
+#define CSR_HVIPRIO2H		0x657
+#define CSR_VSIEH		0x214
+#define CSR_VSIPH		0x254
+
+#define CSR_MSTATUS		0x300
+#define CSR_MISA		0x301
+#define CSR_MIDELEG		0x303
+#define CSR_MIE			0x304
+#define CSR_MTVEC		0x305
+#define CSR_MENVCFG		0x30a
+#define CSR_MENVCFGH		0x31a
+#define CSR_MSCRATCH		0x340
+#define CSR_MEPC		0x341
+#define CSR_MCAUSE		0x342
+#define CSR_MTVAL		0x343
+#define CSR_MIP			0x344
+#define CSR_PMPCFG0		0x3a0
+#define CSR_PMPADDR0		0x3b0
+#define CSR_MVENDORID		0xf11
+#define CSR_MARCHID		0xf12
+#define CSR_MIMPID		0xf13
+#define CSR_MHARTID		0xf14
+
+/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
+#define CSR_MISELECT		0x350
+#define CSR_MIREG		0x351
+
+/* Machine-Level Interrupts (AIA) */
+#define CSR_MTOPEI		0x35c
+#define CSR_MTOPI		0xfb0
+
+/* Virtual Interrupts for Supervisor Level (AIA) */
+#define CSR_MVIEN		0x308
+#define CSR_MVIP		0x309
+
+/* Machine-Level High-Half CSRs (AIA) */
+#define CSR_MIDELEGH		0x313
+#define CSR_MIEH		0x314
+#define CSR_MVIENH		0x318
+#define CSR_MVIPH		0x319
+#define CSR_MIPH		0x354
+
+#define CSR_VSTART		0x8
+#define CSR_VCSR		0xf
+#define CSR_VL			0xc20
+#define CSR_VTYPE		0xc21
+#define CSR_VLENB		0xc22
+
+#ifdef CONFIG_RISCV_M_MODE
+# define CSR_STATUS	CSR_MSTATUS
+# define CSR_IE		CSR_MIE
+# define CSR_TVEC	CSR_MTVEC
+# define CSR_SCRATCH	CSR_MSCRATCH
+# define CSR_EPC	CSR_MEPC
+# define CSR_CAUSE	CSR_MCAUSE
+# define CSR_TVAL	CSR_MTVAL
+# define CSR_IP		CSR_MIP
+
+# define CSR_IEH		CSR_MIEH
+# define CSR_ISELECT	CSR_MISELECT
+# define CSR_IREG	CSR_MIREG
+# define CSR_IPH		CSR_MIPH
+# define CSR_TOPEI	CSR_MTOPEI
+# define CSR_TOPI	CSR_MTOPI
+
+# define SR_IE		SR_MIE
+# define SR_PIE		SR_MPIE
+# define SR_PP		SR_MPP
+
+# define RV_IRQ_SOFT		IRQ_M_SOFT
+# define RV_IRQ_TIMER	IRQ_M_TIMER
+# define RV_IRQ_EXT		IRQ_M_EXT
+#else /* CONFIG_RISCV_M_MODE */
+# define CSR_STATUS	CSR_SSTATUS
+# define CSR_IE		CSR_SIE
+# define CSR_TVEC	CSR_STVEC
+# define CSR_SCRATCH	CSR_SSCRATCH
+# define CSR_EPC	CSR_SEPC
+# define CSR_CAUSE	CSR_SCAUSE
+# define CSR_TVAL	CSR_STVAL
+# define CSR_IP		CSR_SIP
+
+# define CSR_IEH		CSR_SIEH
+# define CSR_ISELECT	CSR_SISELECT
+# define CSR_IREG	CSR_SIREG
+# define CSR_IPH		CSR_SIPH
+# define CSR_TOPEI	CSR_STOPEI
+# define CSR_TOPI	CSR_STOPI
+
+# define SR_IE		SR_SIE
+# define SR_PIE		SR_SPIE
+# define SR_PP		SR_SPP
+
+# define RV_IRQ_SOFT		IRQ_S_SOFT
+# define RV_IRQ_TIMER	IRQ_S_TIMER
+# define RV_IRQ_EXT		IRQ_S_EXT
+# define RV_IRQ_PMU	IRQ_PMU_OVF
+# define SIP_LCOFIP     (_AC(0x1, UL) << IRQ_PMU_OVF)
+
+#endif /* !CONFIG_RISCV_M_MODE */
+
+/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
+#define IE_SIE		(_AC(0x1, UL) << RV_IRQ_SOFT)
+#define IE_TIE		(_AC(0x1, UL) << RV_IRQ_TIMER)
+#define IE_EIE		(_AC(0x1, UL) << RV_IRQ_EXT)
+
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x)    x
+#else
+#define __ASM_STR(x)    #x
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define csr_swap(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
+			      : "=r" (__v) : "rK" (__v)		\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_read(csr)						\
+({								\
+	register unsigned long __v;				\
+	__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr)	\
+			      : "=r" (__v) :			\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_write(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0"	\
+			      : : "rK" (__v)			\
+			      : "memory");			\
+})
+
+#define csr_read_set(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
+			      : "=r" (__v) : "rK" (__v)		\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_set(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0"	\
+			      : : "rK" (__v)			\
+			      : "memory");			\
+})
+
+#define csr_read_clear(csr, val)				\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
+			      : "=r" (__v) : "rK" (__v)		\
+			      : "memory");			\
+	__v;							\
+})
+
+#define csr_clear(csr, val)					\
+({								\
+	unsigned long __v = (unsigned long)(val);		\
+	__asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0"	\
+			      : : "rK" (__v)			\
+			      : "memory");			\
+})
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_H */
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
                   ` (2 preceding siblings ...)
  2023-09-02 12:59 ` [PATCH v2 3/8] tools: riscv: Add header file csr.h Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 13:31   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 5/8] KVM: riscv: selftests: Add exception handling support Haibo Xu
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, wchen, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Vitaly Kuznetsov, Aaron Lewis, David Matlack, Mingwei Zhang,
	Ackerley Tng, Jim Mattson, Vipin Sharma, Maxim Levitsky,
	Peter Gonda, Like Xu, Philippe Mathieu-Daudé, Thomas Huth,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/testing/selftests/kvm/include/riscv/processor.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index 5b62a3d2aa9b..6810c887fadc 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -8,6 +8,7 @@
 #define SELFTEST_KVM_PROCESSOR_H
 
 #include "kvm_util.h"
+#include <asm/csr.h>
 #include <linux/stringify.h>
 
 static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
@@ -95,12 +96,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
 #define PGTBL_PAGE_SIZE				PGTBL_L0_BLOCK_SIZE
 #define PGTBL_PAGE_SIZE_SHIFT			PGTBL_L0_BLOCK_SHIFT
 
-#define SATP_PPN				_AC(0x00000FFFFFFFFFFF, UL)
 #define SATP_MODE_39				_AC(0x8000000000000000, UL)
 #define SATP_MODE_48				_AC(0x9000000000000000, UL)
-#define SATP_ASID_BITS				16
-#define SATP_ASID_SHIFT				44
-#define SATP_ASID_MASK				_AC(0xFFFF, UL)
 
 #define SBI_EXT_EXPERIMENTAL_START		0x08000000
 #define SBI_EXT_EXPERIMENTAL_END		0x08FFFFFF
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 5/8] KVM: riscv: selftests: Add exception handling support
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
                   ` (3 preceding siblings ...)
  2023-09-02 12:59 ` [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 13:46   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 6/8] KVM: riscv: selftests: Add guest helper to get vcpu id Haibo Xu
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, wchen, Daniel Henrique Barboza,
	Greentime Hu, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, Vitaly Kuznetsov, Aaron Lewis, David Matlack,
	Ackerley Tng, Mingwei Zhang, Vipin Sharma, Maxim Levitsky,
	Peter Gonda, Thomas Huth, Like Xu, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

Add the infrastructure for guest exception handling in riscv selftests.
Customized handlers can be enabled by vm_install_exception_handler(vector)
or vm_install_interrupt_handler().

The code is inspired from that of x86/arm64.

Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/include/riscv/processor.h   |  43 ++++++++
 .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++++++++++++++++
 .../selftests/kvm/lib/riscv/processor.c       |  69 ++++++++++++
 4 files changed, 214 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index fb8904e2c06a..01638027d059 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -53,6 +53,7 @@ LIBKVM_s390x += lib/s390x/diag318_test_handler.c
 LIBKVM_s390x += lib/s390x/processor.c
 LIBKVM_s390x += lib/s390x/ucall.c
 
+LIBKVM_riscv += lib/riscv/handlers.S
 LIBKVM_riscv += lib/riscv/processor.c
 LIBKVM_riscv += lib/riscv/ucall.c
 
diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index 6810c887fadc..d1e5d9f7ad45 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -42,6 +42,49 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
 #define RISCV_ISA_EXT_REG(idx)	__kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
 					     idx, KVM_REG_SIZE_ULONG)
 
+struct ex_regs {
+	unsigned long ra;
+	unsigned long sp;
+	unsigned long gp;
+	unsigned long tp;
+	unsigned long t0;
+	unsigned long t1;
+	unsigned long t2;
+	unsigned long s0;
+	unsigned long s1;
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+	unsigned long a4;
+	unsigned long a5;
+	unsigned long a6;
+	unsigned long a7;
+	unsigned long s2;
+	unsigned long s3;
+	unsigned long s4;
+	unsigned long s5;
+	unsigned long s6;
+	unsigned long s7;
+	unsigned long s8;
+	unsigned long s9;
+	unsigned long s10;
+	unsigned long s11;
+	unsigned long t3;
+	unsigned long t4;
+	unsigned long t5;
+	unsigned long t6;
+	unsigned long epc;
+	unsigned long status;
+	unsigned long cause;
+};
+
+#define NR_VECTORS  2
+#define NR_EXCEPTIONS  32
+#define EC_MASK  (NR_EXCEPTIONS - 1)
+
+void vm_install_interrupt_handler(struct kvm_vm *vm, exception_handler_fn handler);
+
 /* L3 index Bit[47:39] */
 #define PGTBL_L3_INDEX_MASK			0x0000FF8000000000ULL
 #define PGTBL_L3_INDEX_SHIFT			39
diff --git a/tools/testing/selftests/kvm/lib/riscv/handlers.S b/tools/testing/selftests/kvm/lib/riscv/handlers.S
new file mode 100644
index 000000000000..877ca32d8f94
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/riscv/handlers.S
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 Intel Corporation
+ */
+
+#ifndef __ASSEMBLY__
+#define __ASSEMBLY__
+#endif
+
+#include <asm/csr.h>
+
+.macro save_context
+	addi  sp, sp, (-8*34)
+	sd    x1, 0(sp)
+	sd    x2, 8(sp)
+	sd    x3, 16(sp)
+	sd    x4, 24(sp)
+	sd    x5, 32(sp)
+	sd    x6, 40(sp)
+	sd    x7, 48(sp)
+	sd    x8, 56(sp)
+	sd    x9, 64(sp)
+	sd    x10, 72(sp)
+	sd    x11, 80(sp)
+	sd    x12, 88(sp)
+	sd    x13, 96(sp)
+	sd    x14, 104(sp)
+	sd    x15, 112(sp)
+	sd    x16, 120(sp)
+	sd    x17, 128(sp)
+	sd    x18, 136(sp)
+	sd    x19, 144(sp)
+	sd    x20, 152(sp)
+	sd    x21, 160(sp)
+	sd    x22, 168(sp)
+	sd    x23, 176(sp)
+	sd    x24, 184(sp)
+	sd    x25, 192(sp)
+	sd    x26, 200(sp)
+	sd    x27, 208(sp)
+	sd    x28, 216(sp)
+	sd    x29, 224(sp)
+	sd    x30, 232(sp)
+	sd    x31, 240(sp)
+	csrr  s0, CSR_SEPC
+	csrr  s1, CSR_SSTATUS
+	csrr  s2, CSR_SCAUSE
+	sd    s0, 248(sp)
+	sd    s1, 256(sp)
+	sd    s2, 264(sp)
+.endm
+
+.macro restore_context
+	ld    s2, 264(sp)
+	ld    s1, 256(sp)
+	ld    s0, 248(sp)
+	csrw  CSR_SCAUSE, s2
+	csrw  CSR_SSTATUS, s1
+	csrw  CSR_SEPC, s0
+	ld    x31, 240(sp)
+	ld    x30, 232(sp)
+	ld    x29, 224(sp)
+	ld    x28, 216(sp)
+	ld    x27, 208(sp)
+	ld    x26, 200(sp)
+	ld    x25, 192(sp)
+	ld    x24, 184(sp)
+	ld    x23, 176(sp)
+	ld    x22, 168(sp)
+	ld    x21, 160(sp)
+	ld    x20, 152(sp)
+	ld    x19, 144(sp)
+	ld    x18, 136(sp)
+	ld    x17, 128(sp)
+	ld    x16, 120(sp)
+	ld    x15, 112(sp)
+	ld    x14, 104(sp)
+	ld    x13, 96(sp)
+	ld    x12, 88(sp)
+	ld    x11, 80(sp)
+	ld    x10, 72(sp)
+	ld    x9, 64(sp)
+	ld    x8, 56(sp)
+	ld    x7, 48(sp)
+	ld    x6, 40(sp)
+	ld    x5, 32(sp)
+	ld    x4, 24(sp)
+	ld    x3, 16(sp)
+	ld    x2, 8(sp)
+	ld    x1, 0(sp)
+	addi  sp, sp, (8*34)
+.endm
+
+.balign 4
+.global exception_vectors
+exception_vectors:
+	save_context
+	move  a0, sp
+	call  route_exception
+	restore_context
+	sret
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index d146ca71e0c0..efd9ac4b0198 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -13,6 +13,8 @@
 
 #define DEFAULT_RISCV_GUEST_STACK_VADDR_MIN	0xac0000
 
+static vm_vaddr_t exception_handlers;
+
 static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
 {
 	return (v + vm->page_size) & ~(vm->page_size - 1);
@@ -364,6 +366,73 @@ void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...)
 	va_end(ap);
 }
 
+void kvm_exit_unexpected_exception(int vector, int ec)
+{
+	ucall(UCALL_UNHANDLED, 2, vector, ec);
+}
+
 void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
 {
+	struct ucall uc;
+
+	if (get_ucall(vcpu, &uc) == UCALL_UNHANDLED) {
+		TEST_FAIL("Unexpected exception (vector:0x%lx, ec:0x%lx)",
+			uc.args[0], uc.args[1]);
+	}
+}
+
+struct handlers {
+	exception_handler_fn exception_handlers[NR_VECTORS][NR_EXCEPTIONS];
+};
+
+void route_exception(struct ex_regs *regs)
+{
+	struct handlers *handlers = (struct handlers *)exception_handlers;
+	int vector = 0, ec;
+
+	ec = regs->cause & ~CAUSE_IRQ_FLAG;
+	if (ec >= NR_EXCEPTIONS)
+		goto unexpected_exception;
+
+	/* Use the same handler for all the interrupts */
+	if (regs->cause & CAUSE_IRQ_FLAG) {
+		vector = 1;
+		ec = 0;
+	}
+
+	if (handlers && handlers->exception_handlers[vector][ec])
+		return handlers->exception_handlers[vector][ec](regs);
+
+unexpected_exception:
+	return kvm_exit_unexpected_exception(vector, ec);
+}
+
+void vcpu_init_vector_tables(struct kvm_vcpu *vcpu)
+{
+	extern char exception_vectors;
+
+	vcpu_set_reg(vcpu, RISCV_CSR_REG(stvec), (unsigned long)&exception_vectors);
+}
+
+void vm_init_vector_tables(struct kvm_vm *vm)
+{
+	vm->handlers = __vm_vaddr_alloc(vm, sizeof(struct handlers),
+				   vm->page_size, MEM_REGION_DATA);
+
+	*(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers;
+}
+
+void vm_install_exception_handler(struct kvm_vm *vm, int vector, exception_handler_fn handler)
+{
+	struct handlers *handlers = addr_gva2hva(vm, vm->handlers);
+
+	assert(vector < NR_EXCEPTIONS);
+	handlers->exception_handlers[0][vector] = handler;
+}
+
+void vm_install_interrupt_handler(struct kvm_vm *vm, exception_handler_fn handler)
+{
+	struct handlers *handlers = addr_gva2hva(vm, vm->handlers);
+
+	handlers->exception_handlers[1][0] = handler;
 }
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 6/8] KVM: riscv: selftests: Add guest helper to get vcpu id
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
                   ` (4 preceding siblings ...)
  2023-09-02 12:59 ` [PATCH v2 5/8] KVM: riscv: selftests: Add exception handling support Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 13:48   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function Haibo Xu
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Lei Wang, Vipin Sharma, Like Xu, Peter Gonda,
	Maxim Levitsky, Philippe Mathieu-Daudé, Thomas Huth,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

Add guest_get_vcpuid() helper to simplify accessing to per-cpu
private data. The sscratch CSR was used to store the vcpu id.

Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/testing/selftests/kvm/include/aarch64/processor.h | 4 ----
 tools/testing/selftests/kvm/include/kvm_util_base.h     | 2 ++
 tools/testing/selftests/kvm/lib/riscv/processor.c       | 8 ++++++++
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index 69e7b08d3f99..f41fcd63624f 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -219,8 +219,4 @@ void smccc_smc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
 	       uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
 	       uint64_t arg6, struct arm_smccc_res *res);
 
-
-
-uint32_t guest_get_vcpuid(void);
-
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index 135ae2eb5249..666438113d22 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -939,4 +939,6 @@ struct ex_regs;
 typedef void(*exception_handler_fn)(struct ex_regs *);
 void vm_install_exception_handler(struct kvm_vm *vm, int vector, exception_handler_fn handler);
 
+uint32_t guest_get_vcpuid(void);
+
 #endif /* SELFTEST_KVM_UTIL_BASE_H */
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index efd9ac4b0198..39a1e9902dec 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -316,6 +316,9 @@ struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
 	vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.sp), stack_vaddr + stack_size);
 	vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.pc), (unsigned long)guest_code);
 
+	/* Setup sscratch for guest_get_vcpuid() */
+	vcpu_set_reg(vcpu, RISCV_CSR_REG(sscratch), vcpu_id);
+
 	/* Setup default exception vector of guest */
 	vcpu_set_reg(vcpu, RISCV_CSR_REG(stvec), (unsigned long)guest_unexp_trap);
 
@@ -436,3 +439,8 @@ void vm_install_interrupt_handler(struct kvm_vm *vm, exception_handler_fn handle
 
 	handlers->exception_handlers[1][0] = handler;
 }
+
+uint32_t guest_get_vcpuid(void)
+{
+	return csr_read(CSR_SSCRATCH);
+}
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
                   ` (5 preceding siblings ...)
  2023-09-02 12:59 ` [PATCH v2 6/8] KVM: riscv: selftests: Add guest helper to get vcpu id Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 14:04   ` Andrew Jones
  2023-09-02 12:59 ` [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test Haibo Xu
  2023-09-05 10:36 ` [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Andrew Jones
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Daniel Henrique Barboza, wchen,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Jim Mattson, Lei Wang, Vipin Sharma,
	Maxim Levitsky, Like Xu, Peter Gonda, Thomas Huth,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	Paul Durrant, linux-kernel, linux-riscv, kvm, linux-kselftest,
	linux-arm-kernel, kvmarm, kvm-riscv

Move vcpu_has_ext to the processor.c so that other test cases
can use it for vCPU extension check.

Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 .../selftests/kvm/include/riscv/processor.h        |  2 ++
 tools/testing/selftests/kvm/lib/riscv/processor.c  |  9 +++++++++
 tools/testing/selftests/kvm/riscv/get-reg-list.c   | 14 --------------
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index d1e5d9f7ad45..6087c8fc263a 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
 #define RISCV_ISA_EXT_REG(idx)	__kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
 					     idx, KVM_REG_SIZE_ULONG)
 
+bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
+
 struct ex_regs {
 	unsigned long ra;
 	unsigned long sp;
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index 39a1e9902dec..5ececa566f24 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -15,6 +15,15 @@
 
 static vm_vaddr_t exception_handlers;
 
+bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
+{
+	unsigned long value = 0;
+
+	vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
+
+	return !!value;
+}
+
 static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
 {
 	return (v + vm->page_size) & ~(vm->page_size - 1);
diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index d8ecacd03ecf..c4028bf32e3f 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -44,20 +44,6 @@ bool check_reject_set(int err)
 	return err == EINVAL;
 }
 
-static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
-{
-	int ret;
-	unsigned long value;
-
-	ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
-	if (ret) {
-		printf("Failed to get ext %d", ext);
-		return false;
-	}
-
-	return !!value;
-}
-
 void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 {
 	struct vcpu_reg_sublist *s;
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
                   ` (6 preceding siblings ...)
  2023-09-02 12:59 ` [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function Haibo Xu
@ 2023-09-02 12:59 ` Haibo Xu
  2023-09-04 14:58   ` Andrew Jones
  2023-09-05 10:36 ` [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Andrew Jones
  8 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-02 12:59 UTC (permalink / raw)
  Cc: xiaobo55x, haibo1.xu, ajones, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Greentime Hu, wchen,
	Daniel Henrique Barboza, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, David Matlack, Aaron Lewis, Mingwei Zhang,
	Vitaly Kuznetsov, Ackerley Tng, Vipin Sharma, Maxim Levitsky,
	Peter Gonda, Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

Add a KVM selftest to validate the Sstc timer functionality.
The test was ported from arm64 arch timer test.

Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
---
 tools/testing/selftests/kvm/Makefile          |   1 +
 tools/testing/selftests/kvm/arch_timer.c      |   9 ++
 .../selftests/kvm/include/riscv/arch_timer.h  |  80 +++++++++++
 .../selftests/kvm/include/riscv/processor.h   |  10 ++
 .../selftests/kvm/include/timer_test.h        |   6 +
 .../testing/selftests/kvm/riscv/arch_timer.c  | 130 ++++++++++++++++++
 6 files changed, 236 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
 create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 01638027d059..7897d8051d8c 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -179,6 +179,7 @@ TEST_GEN_PROGS_s390x += rseq_test
 TEST_GEN_PROGS_s390x += set_memory_region_test
 TEST_GEN_PROGS_s390x += kvm_binary_stats_test
 
+TEST_GEN_PROGS_riscv += arch_timer
 TEST_GEN_PROGS_riscv += demand_paging_test
 TEST_GEN_PROGS_riscv += dirty_log_test
 TEST_GEN_PROGS_riscv += get-reg-list
diff --git a/tools/testing/selftests/kvm/arch_timer.c b/tools/testing/selftests/kvm/arch_timer.c
index 529024f58c98..691bd454e362 100644
--- a/tools/testing/selftests/kvm/arch_timer.c
+++ b/tools/testing/selftests/kvm/arch_timer.c
@@ -66,8 +66,13 @@ static void *test_vcpu_run(void *arg)
 		break;
 	case UCALL_ABORT:
 		sync_global_from_guest(vm, *shared_data);
+#ifdef __aarch64__
 		fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
 		        vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
+#else
+		fprintf(stderr, "Guest assert failed,  vcpu %u; iter: %u\n",
+		        vcpu_idx, shared_data->nr_iter);
+#endif
 		REPORT_GUEST_ASSERT(uc);
 		break;
 	default:
@@ -190,7 +195,9 @@ static void test_print_help(char *name)
 		TIMER_TEST_PERIOD_MS_DEF);
 	pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
 		TIMER_TEST_MIGRATION_FREQ_MS);
+#ifdef __aarch64__
 	pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
+#endif
 	pr_info("\t-h: print this help screen\n");
 }
 
@@ -217,10 +224,12 @@ static bool parse_args(int argc, char *argv[])
 		case 'm':
 			test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
 			break;
+#ifdef __aarch64__
 		case 'o':
 			test_args.offset.counter_offset = strtol(optarg, NULL, 0);
 			test_args.offset.reserved = 0;
 			break;
+#endif
 		case 'h':
 		default:
 			goto err;
diff --git a/tools/testing/selftests/kvm/include/riscv/arch_timer.h b/tools/testing/selftests/kvm/include/riscv/arch_timer.h
new file mode 100644
index 000000000000..897edcef8fc2
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/riscv/arch_timer.h
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0 */
+/*
+ * RISC-V Arch Timer(sstc) specific interface
+ *
+ * Copyright (c) 2023 Intel Corporation
+ */
+
+#ifndef SELFTEST_KVM_ARCH_TIMER_H
+#define SELFTEST_KVM_ARCH_TIMER_H
+
+#include <asm/csr.h>
+
+static unsigned long timer_freq;
+
+#define msec_to_cycles(msec)	\
+	((timer_freq) * (uint64_t)(msec) / 1000)
+
+#define usec_to_cycles(usec)	\
+	((timer_freq) * (uint64_t)(usec) / 1000000)
+
+#define cycles_to_usec(cycles) \
+	((uint64_t)(cycles) * 1000000 / (timer_freq))
+
+static inline uint64_t timer_get_cntct(void)
+{
+	return csr_read(CSR_TIME);
+}
+
+static inline void timer_set_cval(uint64_t cval)
+{
+	csr_write(CSR_STIMECMP, cval);
+}
+
+static inline uint64_t timer_get_cval(void)
+{
+	return csr_read(CSR_STIMECMP);
+}
+
+static inline void timer_irq_enable(void)
+{
+	csr_set(CSR_SIE, IE_TIE);
+}
+
+static inline void timer_irq_disable(void)
+{
+	csr_clear(CSR_SIE, IE_TIE);
+}
+
+static inline void timer_set_next_cval_ms(uint32_t msec)
+{
+	uint64_t now_ct = timer_get_cntct();
+	uint64_t next_ct = now_ct + msec_to_cycles(msec);
+
+	timer_set_cval(next_ct);
+}
+
+static inline void cpu_relax(void)
+{
+#ifdef __riscv_zihintpause
+	asm volatile("pause" ::: "memory");
+#else
+	/* Encoding of the pause instruction */
+	asm volatile(".4byte 0x100000F" ::: "memory");
+#endif
+}
+
+static inline void __delay(uint64_t cycles)
+{
+	uint64_t start = timer_get_cntct();
+
+	while ((timer_get_cntct() - start) < cycles)
+		cpu_relax();
+}
+
+static inline void udelay(unsigned long usec)
+{
+	__delay(usec_to_cycles(usec));
+}
+
+#endif /* SELFTEST_KVM_ARCH_TIMER_H */
diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index 6087c8fc263a..c69f36302d41 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -161,4 +161,14 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
 			unsigned long arg3, unsigned long arg4,
 			unsigned long arg5);
 
+static inline void local_irq_enable(void)
+{
+	csr_set(CSR_SSTATUS, SR_SIE);
+}
+
+static inline void local_irq_disable(void)
+{
+	csr_clear(CSR_SSTATUS, SR_SIE);
+}
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/include/timer_test.h b/tools/testing/selftests/kvm/include/timer_test.h
index 109e4d635627..091c05a14c93 100644
--- a/tools/testing/selftests/kvm/include/timer_test.h
+++ b/tools/testing/selftests/kvm/include/timer_test.h
@@ -18,6 +18,7 @@
 
 #define msecs_to_usecs(msec)    ((msec) * 1000LL)
 
+#ifdef __aarch64__
 #define GICD_BASE_GPA    0x8000000ULL
 #define GICR_BASE_GPA    0x80A0000ULL
 
@@ -28,6 +29,7 @@ enum guest_stage {
 	GUEST_STAGE_PTIMER_TVAL,
 	GUEST_STAGE_MAX,
 };
+#endif
 
 /* Timer test cmdline parameters */
 struct test_args
@@ -36,13 +38,17 @@ struct test_args
 	int nr_iter;
 	int timer_period_ms;
 	int migration_freq_ms;
+#ifdef __aarch64__
 	struct kvm_arm_counter_offset offset;
+#endif
 };
 
 /* Shared variables between host and guest */
 struct test_vcpu_shared_data {
 	int nr_iter;
+#ifdef __aarch64__
 	enum guest_stage guest_stage;
+#endif
 	uint64_t xcnt;
 };
 
diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
new file mode 100644
index 000000000000..c50a33c1e4f9
--- /dev/null
+++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
+ *
+ * The test validates the sstc timer IRQs using vstimecmp registers.
+ * It's ported from the aarch64 arch_timer test.
+ *
+ * Copyright (c) 2023, Intel Corporation.
+ */
+
+#define _GNU_SOURCE
+
+#include "arch_timer.h"
+#include "kvm_util.h"
+#include "processor.h"
+#include "timer_test.h"
+
+extern struct test_args test_args;
+extern struct kvm_vcpu *vcpus[];
+extern struct test_vcpu_shared_data vcpu_shared_data[];
+
+static int timer_irq = IRQ_S_TIMER;
+
+static void
+guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
+{
+	timer_set_next_cval_ms(test_args.timer_period_ms);
+	shared_data->xcnt = timer_get_cntct();
+	timer_irq_enable();
+}
+
+static void guest_validate_irq(unsigned int intid,
+				struct test_vcpu_shared_data *shared_data)
+{
+	uint64_t xcnt = 0, xcnt_diff_us, cval = 0;
+
+	timer_irq_disable();
+	xcnt = timer_get_cntct();
+	cval = timer_get_cval();
+
+	xcnt_diff_us = cycles_to_usec(xcnt - shared_data->xcnt);
+
+	/* Make sure we are dealing with the correct timer IRQ */
+	GUEST_ASSERT_EQ(intid, timer_irq);
+
+	__GUEST_ASSERT(xcnt >= cval,
+	               "xcnt = 0x%llx, cval = 0x%llx, xcnt_diff_us = 0x%llx",
+	               xcnt, cval, xcnt_diff_us);
+
+	WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter + 1);
+}
+
+static void guest_irq_handler(struct ex_regs *regs)
+{
+	unsigned int intid = regs->cause & ~CAUSE_IRQ_FLAG;
+	uint32_t cpu = guest_get_vcpuid();
+	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
+
+	guest_validate_irq(intid, shared_data);
+}
+
+static void guest_run(struct test_vcpu_shared_data *shared_data)
+{
+	uint32_t irq_iter, config_iter;
+
+	shared_data->nr_iter = 0;
+
+	for (config_iter = 0; config_iter < test_args.nr_iter; config_iter++) {
+		/* Setup the next interrupt */
+		guest_configure_timer_action(shared_data);
+
+		/* Setup a timeout for the interrupt to arrive */
+		udelay(msecs_to_usecs(test_args.timer_period_ms) +
+			TIMER_TEST_ERR_MARGIN_US);
+
+		irq_iter = READ_ONCE(shared_data->nr_iter);
+		GUEST_ASSERT_EQ(config_iter + 1, irq_iter);
+	}
+}
+
+static void guest_code(void)
+{
+	uint32_t cpu = guest_get_vcpuid();
+	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
+
+	local_irq_disable();
+	timer_irq_disable();
+	local_irq_enable();
+
+	guest_run(shared_data);
+
+	GUEST_DONE();
+}
+
+static void test_init_timer_freq(struct kvm_vm *vm)
+{
+	/* Timer frequency should be same for all the vCPUs, so query only vCPU-0 */
+	vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency), &timer_freq);
+	sync_global_to_guest(vm, timer_freq);
+
+	pr_debug("timer_freq: %lu\n", timer_freq);
+}
+
+struct kvm_vm *test_vm_create(void)
+{
+	struct kvm_vm *vm;
+	int nr_vcpus = test_args.nr_vcpus;
+
+	vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
+	__TEST_REQUIRE(vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
+				   "SSTC not available, skipping test\n");
+
+	vm_init_vector_tables(vm);
+	vm_install_interrupt_handler(vm, guest_irq_handler);
+
+	for (int i = 0; i < nr_vcpus; i++)
+		vcpu_init_vector_tables(vcpus[i]);
+
+	test_init_timer_freq(vm);
+
+	/* Make all the test's cmdline args visible to the guest */
+	sync_global_to_guest(vm, test_args);
+
+	return vm;
+}
+
+void test_vm_cleanup(struct kvm_vm *vm)
+{
+	kvm_vm_free(vm);
+}
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling
  2023-09-02 12:59 ` [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling Haibo Xu
@ 2023-09-04 11:15   ` Andrew Jones
  2023-09-06  2:15     ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 11:15 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Sean Christopherson, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Greentime Hu, wchen,
	Daniel Henrique Barboza, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu,
	Peter Gonda, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Sat, Sep 02, 2023 at 08:59:23PM +0800, Haibo Xu wrote:
> Rename the vm_init_descriptor_tables() and vcpu_init_vector_tables()
                                             ^ vcpu_init_descriptor_tables()

> prototypes to vm_init_vector_tables() and vcpu_init_vector_tables()
> respectively, so that we can use common names for the architectures
> (x86/aarch64/riscv) and then put them in a common header.
> 
> By the way, vm_install_exception_handler() prototype were also moved to
> the common header since they are commonly used across the architectures.
> 
> The patch is a preparation to share the guest exception handling codes
> in riscv.
> 
> Suggested-by: Andrew Jones <ajones@ventanamicro.com>
> Suggested-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/testing/selftests/kvm/aarch64/arch_timer.c          | 4 ++--
>  tools/testing/selftests/kvm/aarch64/debug-exceptions.c    | 4 ++--
>  tools/testing/selftests/kvm/aarch64/page_fault_test.c     | 4 ++--
>  tools/testing/selftests/kvm/aarch64/vgic_irq.c            | 4 ++--
>  tools/testing/selftests/kvm/include/aarch64/processor.h   | 8 +-------
>  tools/testing/selftests/kvm/include/kvm_util_base.h       | 7 +++++++
>  tools/testing/selftests/kvm/include/x86_64/processor.h    | 5 -----
>  tools/testing/selftests/kvm/lib/aarch64/processor.c       | 6 +++---
>  tools/testing/selftests/kvm/lib/x86_64/processor.c        | 4 ++--
>  tools/testing/selftests/kvm/x86_64/amx_test.c             | 4 ++--
>  tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c   | 4 ++--
>  tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c         | 4 ++--
>  tools/testing/selftests/kvm/x86_64/hyperv_features.c      | 8 ++++----
>  tools/testing/selftests/kvm/x86_64/hyperv_ipi.c           | 6 +++---
>  tools/testing/selftests/kvm/x86_64/kvm_pv_test.c          | 4 ++--
>  tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c   | 4 ++--
>  .../testing/selftests/kvm/x86_64/pmu_event_filter_test.c  | 8 ++++----
>  .../kvm/x86_64/smaller_maxphyaddr_emulation_test.c        | 4 ++--
>  tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c     | 4 ++--
>  .../selftests/kvm/x86_64/svm_nested_shutdown_test.c       | 4 ++--
>  .../selftests/kvm/x86_64/svm_nested_soft_inject_test.c    | 4 ++--
>  tools/testing/selftests/kvm/x86_64/ucna_injection_test.c  | 8 ++++----
>  .../selftests/kvm/x86_64/userspace_msr_exit_test.c        | 4 ++--
>  .../kvm/x86_64/vmx_exception_with_invalid_guest_state.c   | 4 ++--
>  tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c    | 4 ++--
>  tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c       | 4 ++--
>  tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c      | 4 ++--
>  tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c      | 4 ++--
>  28 files changed, 66 insertions(+), 70 deletions(-)
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-02 12:59 ` [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code Haibo Xu
@ 2023-09-04 13:24   ` Andrew Jones
  2023-09-06  2:14     ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 13:24 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Daniel Henrique Barboza,
	Greentime Hu, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, Aaron Lewis, David Matlack, Vitaly Kuznetsov,
	Ackerley Tng, Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu,
	Peter Gonda, Maxim Levitsky, Thomas Huth,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	linux-kernel, linux-riscv, kvm, linux-kselftest, linux-arm-kernel,
	kvmarm, kvm-riscv

On Sat, Sep 02, 2023 at 08:59:24PM +0800, Haibo Xu wrote:
> Split the arch-neutral test code out of aarch64/arch_timer.c
> and put them into a common arch_timer.c. This is a preparation
> to share timer test codes in riscv.
> 
> Suggested-by: Andrew Jones <ajones@ventanamicro.com>
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/testing/selftests/kvm/Makefile          |   9 +-
>  .../selftests/kvm/aarch64/arch_timer.c        | 288 +-----------------
>  tools/testing/selftests/kvm/arch_timer.c      | 252 +++++++++++++++
>  .../selftests/kvm/include/timer_test.h        |  52 ++++
>  4 files changed, 317 insertions(+), 284 deletions(-)
>  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
>  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
> 
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index 0b9c42fbce8c..fb8904e2c06a 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -140,7 +140,6 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test
>  TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
>  
>  TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
> -TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
>  TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
>  TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
>  TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> @@ -150,6 +149,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
>  TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
>  TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
>  TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
> +TEST_GEN_PROGS_aarch64 += arch_timer
>  TEST_GEN_PROGS_aarch64 += demand_paging_test
>  TEST_GEN_PROGS_aarch64 += dirty_log_test
>  TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
> @@ -188,6 +188,7 @@ TEST_GEN_PROGS_riscv += set_memory_region_test
>  TEST_GEN_PROGS_riscv += kvm_binary_stats_test
>  
>  SPLIT_TESTS += get-reg-list
> +SPLIT_TESTS += arch_timer
>  
>  TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
>  TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
> @@ -248,13 +249,10 @@ TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TESTS_OBJS))
>  -include $(TEST_DEP_FILES)
>  
>  $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): %: %.o
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
>  $(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
>  	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
>  
> -$(SPLIT_TESTS_TARGETS): %: %.o $(SPLIT_TESTS_OBJS)
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> -
>  EXTRA_CLEAN += $(LIBKVM_OBJS) $(TEST_DEP_FILES) $(TEST_GEN_OBJ) $(SPLIT_TESTS_OBJS) cscope.*
>  
>  x := $(shell mkdir -p $(sort $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
> @@ -273,6 +271,7 @@ $(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
>  x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
>  $(TEST_GEN_PROGS): $(LIBKVM_OBJS)
>  $(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
> +$(SPLIT_TESTS_TARGETS): $(OUTPUT)/%: $(ARCH_DIR)/%.o

The improvements to the Makefile to avoid SPLIT_TESTS_TARGETS needing its
own $(CC) line should preferably be done in a separate, preliminary patch.

>  
>  cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
>  cscope:
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index b63859829a96..ceb649548751 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -1,91 +1,25 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * arch_timer.c - Tests the aarch64 timer IRQ functionality
> - *
>   * The test validates both the virtual and physical timer IRQs using
> - * CVAL and TVAL registers. This consitutes the four stages in the test.
> - * The guest's main thread configures the timer interrupt for a stage
> - * and waits for it to fire, with a timeout equal to the timer period.
> - * It asserts that the timeout doesn't exceed the timer period.
> - *
> - * On the other hand, upon receipt of an interrupt, the guest's interrupt
> - * handler validates the interrupt by checking if the architectural state
> - * is in compliance with the specifications.
> - *
> - * The test provides command-line options to configure the timer's
> - * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> - * To stress-test the timer stack even more, an option to migrate the
> - * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> + * CVAL and TVAL registers.
>   *
>   * Copyright (c) 2021, Google LLC.
>   */
>  #define _GNU_SOURCE
>  
> -#include <stdlib.h>
> -#include <pthread.h>
> -#include <linux/kvm.h>
> -#include <linux/sizes.h>
> -#include <linux/bitmap.h>
> -#include <sys/sysinfo.h>
> -
> -#include "kvm_util.h"
> -#include "processor.h"
> -#include "delay.h"
>  #include "arch_timer.h"
> +#include "delay.h"
>  #include "gic.h"
> +#include "processor.h"
> +#include "timer_test.h"
>  #include "vgic.h"
>  
> -#define NR_VCPUS_DEF			4
> -#define NR_TEST_ITERS_DEF		5
> -#define TIMER_TEST_PERIOD_MS_DEF	10
> -#define TIMER_TEST_ERR_MARGIN_US	100
> -#define TIMER_TEST_MIGRATION_FREQ_MS	2
> -
> -struct test_args {
> -	int nr_vcpus;
> -	int nr_iter;
> -	int timer_period_ms;
> -	int migration_freq_ms;
> -	struct kvm_arm_counter_offset offset;
> -};
> -
> -static struct test_args test_args = {
> -	.nr_vcpus = NR_VCPUS_DEF,
> -	.nr_iter = NR_TEST_ITERS_DEF,
> -	.timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> -	.migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> -	.offset = { .reserved = 1 },
> -};
> -
> -#define msecs_to_usecs(msec)		((msec) * 1000LL)
> -
> -#define GICD_BASE_GPA			0x8000000ULL
> -#define GICR_BASE_GPA			0x80A0000ULL
> -
> -enum guest_stage {
> -	GUEST_STAGE_VTIMER_CVAL = 1,
> -	GUEST_STAGE_VTIMER_TVAL,
> -	GUEST_STAGE_PTIMER_CVAL,
> -	GUEST_STAGE_PTIMER_TVAL,
> -	GUEST_STAGE_MAX,
> -};
> -
> -/* Shared variables between host and guest */
> -struct test_vcpu_shared_data {
> -	int nr_iter;
> -	enum guest_stage guest_stage;
> -	uint64_t xcnt;
> -};
> -
> -static struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> -static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
> -static struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> +extern struct test_args test_args;
> +extern struct kvm_vcpu *vcpus[];
> +extern struct test_vcpu_shared_data vcpu_shared_data[];
>  
>  static int vtimer_irq, ptimer_irq;
>  
> -static unsigned long *vcpu_done_map;
> -static pthread_mutex_t vcpu_done_map_lock;
> -
>  static void
>  guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
>  {
> @@ -222,137 +156,6 @@ static void guest_code(void)
>  	GUEST_DONE();
>  }
>  
> -static void *test_vcpu_run(void *arg)
> -{
> -	unsigned int vcpu_idx = (unsigned long)arg;
> -	struct ucall uc;
> -	struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
> -	struct kvm_vm *vm = vcpu->vm;
> -	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
> -
> -	vcpu_run(vcpu);
> -
> -	/* Currently, any exit from guest is an indication of completion */
> -	pthread_mutex_lock(&vcpu_done_map_lock);
> -	__set_bit(vcpu_idx, vcpu_done_map);
> -	pthread_mutex_unlock(&vcpu_done_map_lock);
> -
> -	switch (get_ucall(vcpu, &uc)) {
> -	case UCALL_SYNC:
> -	case UCALL_DONE:
> -		break;
> -	case UCALL_ABORT:
> -		sync_global_from_guest(vm, *shared_data);
> -		fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
> -			vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> -		REPORT_GUEST_ASSERT(uc);
> -		break;
> -	default:
> -		TEST_FAIL("Unexpected guest exit\n");
> -	}
> -
> -	return NULL;
> -}
> -
> -static uint32_t test_get_pcpu(void)
> -{
> -	uint32_t pcpu;
> -	unsigned int nproc_conf;
> -	cpu_set_t online_cpuset;
> -
> -	nproc_conf = get_nprocs_conf();
> -	sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> -
> -	/* Randomly find an available pCPU to place a vCPU on */
> -	do {
> -		pcpu = rand() % nproc_conf;
> -	} while (!CPU_ISSET(pcpu, &online_cpuset));
> -
> -	return pcpu;
> -}
> -
> -static int test_migrate_vcpu(unsigned int vcpu_idx)
> -{
> -	int ret;
> -	cpu_set_t cpuset;
> -	uint32_t new_pcpu = test_get_pcpu();
> -
> -	CPU_ZERO(&cpuset);
> -	CPU_SET(new_pcpu, &cpuset);
> -
> -	pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
> -
> -	ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
> -				     sizeof(cpuset), &cpuset);
> -
> -	/* Allow the error where the vCPU thread is already finished */
> -	TEST_ASSERT(ret == 0 || ret == ESRCH,
> -		    "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> -		    vcpu_idx, new_pcpu, ret);
> -
> -	return ret;
> -}
> -
> -static void *test_vcpu_migration(void *arg)
> -{
> -	unsigned int i, n_done;
> -	bool vcpu_done;
> -
> -	do {
> -		usleep(msecs_to_usecs(test_args.migration_freq_ms));
> -
> -		for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> -			pthread_mutex_lock(&vcpu_done_map_lock);
> -			vcpu_done = test_bit(i, vcpu_done_map);
> -			pthread_mutex_unlock(&vcpu_done_map_lock);
> -
> -			if (vcpu_done) {
> -				n_done++;
> -				continue;
> -			}
> -
> -			test_migrate_vcpu(i);
> -		}
> -	} while (test_args.nr_vcpus != n_done);
> -
> -	return NULL;
> -}
> -
> -static void test_run(struct kvm_vm *vm)
> -{
> -	pthread_t pt_vcpu_migration;
> -	unsigned int i;
> -	int ret;
> -
> -	pthread_mutex_init(&vcpu_done_map_lock, NULL);
> -	vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
> -	TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> -
> -	for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
> -		ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
> -				     (void *)(unsigned long)i);
> -		TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> -	}
> -
> -	/* Spawn a thread to control the vCPU migrations */
> -	if (test_args.migration_freq_ms) {
> -		srand(time(NULL));
> -
> -		ret = pthread_create(&pt_vcpu_migration, NULL,
> -					test_vcpu_migration, NULL);
> -		TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> -	}
> -
> -
> -	for (i = 0; i < test_args.nr_vcpus; i++)
> -		pthread_join(pt_vcpu_run[i], NULL);
> -
> -	if (test_args.migration_freq_ms)
> -		pthread_join(pt_vcpu_migration, NULL);
> -
> -	bitmap_free(vcpu_done_map);
> -}
> -
>  static void test_init_timer_irq(struct kvm_vm *vm)
>  {
>  	/* Timer initid should be same for all the vCPUs, so query only vCPU-0 */
> @@ -369,7 +172,7 @@ static void test_init_timer_irq(struct kvm_vm *vm)
>  
>  static int gic_fd;
>  
> -static struct kvm_vm *test_vm_create(void)
> +struct kvm_vm *test_vm_create(void)
>  {
>  	struct kvm_vm *vm;
>  	unsigned int i;
> @@ -400,81 +203,8 @@ static struct kvm_vm *test_vm_create(void)
>  	return vm;
>  }
>  
> -static void test_vm_cleanup(struct kvm_vm *vm)
> +void test_vm_cleanup(struct kvm_vm *vm)
>  {
>  	close(gic_fd);
>  	kvm_vm_free(vm);
>  }
> -
> -static void test_print_help(char *name)
> -{
> -	pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
> -		name);
> -	pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
> -		NR_VCPUS_DEF, KVM_MAX_VCPUS);
> -	pr_info("\t-i: Number of iterations per stage (default: %u)\n",
> -		NR_TEST_ITERS_DEF);
> -	pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> -		TIMER_TEST_PERIOD_MS_DEF);
> -	pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> -		TIMER_TEST_MIGRATION_FREQ_MS);
> -	pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> -	pr_info("\t-h: print this help screen\n");
> -}
> -
> -static bool parse_args(int argc, char *argv[])
> -{
> -	int opt;
> -
> -	while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
> -		switch (opt) {
> -		case 'n':
> -			test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
> -			if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
> -				pr_info("Max allowed vCPUs: %u\n",
> -					KVM_MAX_VCPUS);
> -				goto err;
> -			}
> -			break;
> -		case 'i':
> -			test_args.nr_iter = atoi_positive("Number of iterations", optarg);
> -			break;
> -		case 'p':
> -			test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
> -			break;
> -		case 'm':
> -			test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
> -			break;
> -		case 'o':
> -			test_args.offset.counter_offset = strtol(optarg, NULL, 0);
> -			test_args.offset.reserved = 0;
> -			break;
> -		case 'h':
> -		default:
> -			goto err;
> -		}
> -	}
> -
> -	return true;
> -
> -err:
> -	test_print_help(argv[0]);
> -	return false;
> -}
> -
> -int main(int argc, char *argv[])
> -{
> -	struct kvm_vm *vm;
> -
> -	if (!parse_args(argc, argv))
> -		exit(KSFT_SKIP);
> -
> -	__TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
> -		       "At least two physical CPUs needed for vCPU migration");
> -
> -	vm = test_vm_create();
> -	test_run(vm);
> -	test_vm_cleanup(vm);
> -
> -	return 0;
> -}
> diff --git a/tools/testing/selftests/kvm/arch_timer.c b/tools/testing/selftests/kvm/arch_timer.c
> new file mode 100644
> index 000000000000..529024f58c98
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/arch_timer.c
> @@ -0,0 +1,252 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * arch_timer.c - Tests the arch timer IRQ functionality
> + *
> + * The guest's main thread configures the timer interrupt for and waits

It looks like the text was edited to remove the 'stage' references, which
is fine by me, but the 'for' should have also been removed.


> + * for it to fire, with a timeout equal to the timer period.
> + * It asserts that the timeout doesn't exceed the timer period.
> + *
> + * On the other hand, upon receipt of an interrupt, the guest's interrupt
> + * handler validates the interrupt by checking if the architectural state
> + * is in compliance with the specifications.
> + *
> + * The test provides command-line options to configure the timer's
> + * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> + * To stress-test the timer stack even more, an option to migrate the
> + * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> + *
> + * Copyright (c) 2021, Google LLC.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <stdlib.h>
> +#include <pthread.h>
> +#include <linux/sizes.h>
> +#include <linux/bitmap.h>
> +#include <sys/sysinfo.h>
> +
> +#include "timer_test.h"
> +
> +struct test_args test_args = {
> +    .nr_vcpus = NR_VCPUS_DEF,
> +    .nr_iter = NR_TEST_ITERS_DEF,
> +    .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> +    .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> +#ifdef __aarch64__
> +    .offset = { .reserved = 1 },
> +#endif

Please run checkpatch, there are spaces instead of tabs in the struct.

> +};
> +
> +struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> +struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> +
> +static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
> +static unsigned long *vcpu_done_map;
> +static pthread_mutex_t vcpu_done_map_lock;
> +
> +static void *test_vcpu_run(void *arg)
> +{
> +	unsigned int vcpu_idx = (unsigned long)arg;
> +	struct ucall uc;
> +	struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
> +	struct kvm_vm *vm = vcpu->vm;
> +	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
> +
> +	vcpu_run(vcpu);
> +
> +	/* Currently, any exit from guest is an indication of completion */
> +	pthread_mutex_lock(&vcpu_done_map_lock);
> +	__set_bit(vcpu_idx, vcpu_done_map);
> +	pthread_mutex_unlock(&vcpu_done_map_lock);
> +
> +	switch (get_ucall(vcpu, &uc)) {
> +	case UCALL_SYNC:
> +	case UCALL_DONE:
> +		break;
> +	case UCALL_ABORT:
> +		sync_global_from_guest(vm, *shared_data);
> +		fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
> +		        vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> +		REPORT_GUEST_ASSERT(uc);
> +		break;
> +	default:
> +		TEST_FAIL("Unexpected guest exit\n");
> +	}
> +
> +	pr_info("PASS(vCPU-%d).\n", vcpu_idx);

This is new. I can live with it, but generally we don't want to modify
functions while moving them.

> +
> +	return NULL;
> +}
> +
> +static uint32_t test_get_pcpu(void)
> +{
> +	uint32_t pcpu;
> +	unsigned int nproc_conf;
> +	cpu_set_t online_cpuset;
> +
> +	nproc_conf = get_nprocs_conf();
> +	sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> +
> +	/* Randomly find an available pCPU to place a vCPU on */
> +	do {
> +		pcpu = rand() % nproc_conf;
> +	} while (!CPU_ISSET(pcpu, &online_cpuset));
> +
> +	return pcpu;
> +}
> +
> +static int test_migrate_vcpu(unsigned int vcpu_idx)
> +{
> +	int ret;
> +	cpu_set_t cpuset;
> +	uint32_t new_pcpu = test_get_pcpu();
> +
> +	CPU_ZERO(&cpuset);
> +	CPU_SET(new_pcpu, &cpuset);
> +
> +	pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
> +
> +	ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
> +				     sizeof(cpuset), &cpuset);
> +
> +	/* Allow the error where the vCPU thread is already finished */
> +	TEST_ASSERT(ret == 0 || ret == ESRCH,
> +		    "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> +		    vcpu_idx, new_pcpu, ret);
> +
> +	return ret;
> +}
> +
> +static void *test_vcpu_migration(void *arg)
> +{
> +	unsigned int i, n_done;
> +	bool vcpu_done;
> +
> +	do {
> +		usleep(msecs_to_usecs(test_args.migration_freq_ms));
> +
> +		for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> +			pthread_mutex_lock(&vcpu_done_map_lock);
> +			vcpu_done = test_bit(i, vcpu_done_map);
> +			pthread_mutex_unlock(&vcpu_done_map_lock);
> +
> +			if (vcpu_done) {
> +				n_done++;
> +				continue;
> +			}
> +
> +			test_migrate_vcpu(i);
> +		}
> +	} while (test_args.nr_vcpus != n_done);
> +
> +	return NULL;
> +}
> +
> +static void test_run(struct kvm_vm *vm)
> +{
> +	pthread_t pt_vcpu_migration;
> +	unsigned int i;
> +	int ret;
> +
> +	pthread_mutex_init(&vcpu_done_map_lock, NULL);
> +	vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
> +	TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> +
> +	for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
> +		ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
> +				     (void *)(unsigned long)i);
> +		TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> +	}
> +
> +	/* Spawn a thread to control the vCPU migrations */
> +	if (test_args.migration_freq_ms) {
> +		srand(time(NULL));
> +
> +		ret = pthread_create(&pt_vcpu_migration, NULL,
> +					test_vcpu_migration, NULL);
> +		TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> +	}
> +
> +
> +	for (i = 0; i < test_args.nr_vcpus; i++)
> +		pthread_join(pt_vcpu_run[i], NULL);
> +
> +	if (test_args.migration_freq_ms)
> +		pthread_join(pt_vcpu_migration, NULL);
> +
> +	bitmap_free(vcpu_done_map);
> +}
> +
> +static void test_print_help(char *name)
> +{
> +	pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
> +		name);
> +	pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
> +		NR_VCPUS_DEF, KVM_MAX_VCPUS);
> +	pr_info("\t-i: Number of iterations per stage (default: %u)\n",
> +		NR_TEST_ITERS_DEF);
> +	pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> +		TIMER_TEST_PERIOD_MS_DEF);
> +	pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> +		TIMER_TEST_MIGRATION_FREQ_MS);
> +	pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> +	pr_info("\t-h: print this help screen\n");
> +}
> +
> +static bool parse_args(int argc, char *argv[])
> +{
> +	int opt;
> +
> +	while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
> +		switch (opt) {
> +		case 'n':
> +			test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
> +			if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
> +				pr_info("Max allowed vCPUs: %u\n",
> +					KVM_MAX_VCPUS);
> +				goto err;
> +			}
> +			break;
> +		case 'i':
> +			test_args.nr_iter = atoi_positive("Number of iterations", optarg);
> +			break;
> +		case 'p':
> +			test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
> +			break;
> +		case 'm':
> +			test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
> +			break;
> +		case 'o':
> +			test_args.offset.counter_offset = strtol(optarg, NULL, 0);
> +			test_args.offset.reserved = 0;
> +			break;
> +		case 'h':
> +		default:
> +			goto err;
> +		}
> +	}
> +
> +	return true;
> +
> +err:
> +	test_print_help(argv[0]);
> +	return false;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct kvm_vm *vm;
> +
> +	if (!parse_args(argc, argv))
> +		exit(KSFT_SKIP);
> +
> +	__TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
> +		       "At least two physical CPUs needed for vCPU migration");
> +
> +	vm = test_vm_create();
> +	test_run(vm);
> +	test_vm_cleanup(vm);
> +
> +	return 0;
> +}
> diff --git a/tools/testing/selftests/kvm/include/timer_test.h b/tools/testing/selftests/kvm/include/timer_test.h
> new file mode 100644
> index 000000000000..109e4d635627
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/include/timer_test.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * tools/testing/selftests/kvm/include/timer_test.h
> + *
> + * Copyright (C) 2018, Google LLC
> + */
> +
> +#ifndef SELFTEST_KVM_TIMER_TEST_H
> +#define SELFTEST_KVM_TIMER_TEST_H
> +
> +#include "kvm_util.h"
> +
> +#define NR_VCPUS_DEF            4
> +#define NR_TEST_ITERS_DEF       5
> +#define TIMER_TEST_PERIOD_MS_DEF    10
> +#define TIMER_TEST_ERR_MARGIN_US    100
> +#define TIMER_TEST_MIGRATION_FREQ_MS    2
> +
> +#define msecs_to_usecs(msec)    ((msec) * 1000LL)

I'd move the above to include/test_util.h

> +
> +#define GICD_BASE_GPA    0x8000000ULL
> +#define GICR_BASE_GPA    0x80A0000ULL

These defines belong in aarch64/arch_timer.c

> +
> +enum guest_stage {
> +	GUEST_STAGE_VTIMER_CVAL=1,
> +	GUEST_STAGE_VTIMER_TVAL,
> +	GUEST_STAGE_PTIMER_CVAL,
> +	GUEST_STAGE_PTIMER_TVAL,
> +	GUEST_STAGE_MAX,
> +};

This enum also belongs in aarch64/arch_timer.c

> +
> +/* Timer test cmdline parameters */
> +struct test_args
> +{
> +	int nr_vcpus;
> +	int nr_iter;
> +	int timer_period_ms;
> +	int migration_freq_ms;
> +	struct kvm_arm_counter_offset offset;
> +};
> +
> +/* Shared variables between host and guest */
> +struct test_vcpu_shared_data {
> +	int nr_iter;
> +	enum guest_stage guest_stage;
> +	uint64_t xcnt;
> +};
> +
> +struct kvm_vm* test_vm_create(void);

Move * next to function name.

> +void test_vm_cleanup(struct kvm_vm *vm);
> +
> +#endif /* SELFTEST_KVM_TIMER_TEST_H */
> -- 
> 2.34.1
>

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-02 12:59 ` [PATCH v2 3/8] tools: riscv: Add header file csr.h Haibo Xu
@ 2023-09-04 13:26   ` Andrew Jones
  2023-09-04 13:33   ` Andrew Jones
  1 sibling, 0 replies; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 13:26 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Daniel Henrique Barboza,
	wchen, Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Vipin Sharma, Aaron Lewis, David Matlack, Vitaly Kuznetsov,
	Ackerley Tng, Mingwei Zhang, Lei Wang, Maxim Levitsky,
	Peter Gonda, Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Sat, Sep 02, 2023 at 08:59:25PM +0800, Haibo Xu wrote:
> Borrow the csr definitions and operations from kernel's
> arch/riscv/include/asm/csr.h to tools/ for riscv.
> 
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
>  1 file changed, 521 insertions(+)
>  create mode 100644 tools/arch/riscv/include/asm/csr.h
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h
  2023-09-02 12:59 ` [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h Haibo Xu
@ 2023-09-04 13:31   ` Andrew Jones
  2023-09-06  6:56     ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 13:31 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, wchen, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Vitaly Kuznetsov, Aaron Lewis, David Matlack, Mingwei Zhang,
	Ackerley Tng, Jim Mattson, Vipin Sharma, Maxim Levitsky,
	Peter Gonda, Like Xu, Philippe Mathieu-Daudé, Thomas Huth,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Sat, Sep 02, 2023 at 08:59:26PM +0800, Haibo Xu wrote:
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/testing/selftests/kvm/include/riscv/processor.h | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index 5b62a3d2aa9b..6810c887fadc 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -8,6 +8,7 @@
>  #define SELFTEST_KVM_PROCESSOR_H
>  
>  #include "kvm_util.h"
> +#include <asm/csr.h>
>  #include <linux/stringify.h>
>  
>  static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> @@ -95,12 +96,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
>  #define PGTBL_PAGE_SIZE				PGTBL_L0_BLOCK_SIZE
>  #define PGTBL_PAGE_SIZE_SHIFT			PGTBL_L0_BLOCK_SHIFT
>  
> -#define SATP_PPN				_AC(0x00000FFFFFFFFFFF, UL)
>  #define SATP_MODE_39				_AC(0x8000000000000000, UL)
>  #define SATP_MODE_48				_AC(0x9000000000000000, UL)

SATP_MODE_39/48 are also in csr.h

> -#define SATP_ASID_BITS				16
> -#define SATP_ASID_SHIFT				44
> -#define SATP_ASID_MASK				_AC(0xFFFF, UL)
>  
>  #define SBI_EXT_EXPERIMENTAL_START		0x08000000
>  #define SBI_EXT_EXPERIMENTAL_END		0x08FFFFFF
> -- 
> 2.34.1
>

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-02 12:59 ` [PATCH v2 3/8] tools: riscv: Add header file csr.h Haibo Xu
  2023-09-04 13:26   ` Andrew Jones
@ 2023-09-04 13:33   ` Andrew Jones
  2023-09-06  6:35     ` Haibo Xu
  1 sibling, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 13:33 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Daniel Henrique Barboza,
	wchen, Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Vipin Sharma, Aaron Lewis, David Matlack, Vitaly Kuznetsov,
	Ackerley Tng, Mingwei Zhang, Lei Wang, Maxim Levitsky,
	Peter Gonda, Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Sat, Sep 02, 2023 at 08:59:25PM +0800, Haibo Xu wrote:
> Borrow the csr definitions and operations from kernel's
> arch/riscv/include/asm/csr.h to tools/ for riscv.
> 
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
>  1 file changed, 521 insertions(+)
>  create mode 100644 tools/arch/riscv/include/asm/csr.h
> 
> diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h
> new file mode 100644
> index 000000000000..4e86c82aacbd
> --- /dev/null
> +++ b/tools/arch/riscv/include/asm/csr.h
> @@ -0,0 +1,521 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2015 Regents of the University of California
> + */
> +
> +#ifndef _ASM_RISCV_CSR_H
> +#define _ASM_RISCV_CSR_H
> +
> +#include <linux/bits.h>
> +
> +/* Status register flags */
> +#define SR_SIE		_AC(0x00000002, UL) /* Supervisor Interrupt Enable */
> +#define SR_MIE		_AC(0x00000008, UL) /* Machine Interrupt Enable */
> +#define SR_SPIE		_AC(0x00000020, UL) /* Previous Supervisor IE */
> +#define SR_MPIE		_AC(0x00000080, UL) /* Previous Machine IE */
> +#define SR_SPP		_AC(0x00000100, UL) /* Previously Supervisor */
> +#define SR_MPP		_AC(0x00001800, UL) /* Previously Machine */
> +#define SR_SUM		_AC(0x00040000, UL) /* Supervisor User Memory Access */
> +
> +#define SR_FS		_AC(0x00006000, UL) /* Floating-point Status */
> +#define SR_FS_OFF	_AC(0x00000000, UL)
> +#define SR_FS_INITIAL	_AC(0x00002000, UL)
> +#define SR_FS_CLEAN	_AC(0x00004000, UL)
> +#define SR_FS_DIRTY	_AC(0x00006000, UL)
> +
> +#define SR_VS		_AC(0x00000600, UL) /* Vector Status */
> +#define SR_VS_OFF	_AC(0x00000000, UL)
> +#define SR_VS_INITIAL	_AC(0x00000200, UL)
> +#define SR_VS_CLEAN	_AC(0x00000400, UL)
> +#define SR_VS_DIRTY	_AC(0x00000600, UL)
> +
> +#define SR_XS		_AC(0x00018000, UL) /* Extension Status */
> +#define SR_XS_OFF	_AC(0x00000000, UL)
> +#define SR_XS_INITIAL	_AC(0x00008000, UL)
> +#define SR_XS_CLEAN	_AC(0x00010000, UL)
> +#define SR_XS_DIRTY	_AC(0x00018000, UL)
> +
> +#define SR_FS_VS	(SR_FS | SR_VS) /* Vector and Floating-Point Unit */
> +
> +#ifndef CONFIG_64BIT

How do we ensure CONFIG_64BIT is set?

Thanks,
drew

> +#define SR_SD		_AC(0x80000000, UL) /* FS/VS/XS dirty */
> +#else
> +#define SR_SD		_AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
> +#endif
> +
> +#ifdef CONFIG_64BIT
> +#define SR_UXL		_AC(0x300000000, UL) /* XLEN mask for U-mode */
> +#define SR_UXL_32	_AC(0x100000000, UL) /* XLEN = 32 for U-mode */
> +#define SR_UXL_64	_AC(0x200000000, UL) /* XLEN = 64 for U-mode */
> +#endif
> +
> +/* SATP flags */
> +#ifndef CONFIG_64BIT
> +#define SATP_PPN	_AC(0x003FFFFF, UL)
> +#define SATP_MODE_32	_AC(0x80000000, UL)
> +#define SATP_ASID_BITS	9
> +#define SATP_ASID_SHIFT	22
> +#define SATP_ASID_MASK	_AC(0x1FF, UL)
> +#else
> +#define SATP_PPN	_AC(0x00000FFFFFFFFFFF, UL)
> +#define SATP_MODE_39	_AC(0x8000000000000000, UL)
> +#define SATP_MODE_48	_AC(0x9000000000000000, UL)
> +#define SATP_MODE_57	_AC(0xa000000000000000, UL)
> +#define SATP_ASID_BITS	16
> +#define SATP_ASID_SHIFT	44
> +#define SATP_ASID_MASK	_AC(0xFFFF, UL)
> +#endif
> +
> +/* Exception cause high bit - is an interrupt if set */
> +#define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
> +
> +/* Interrupt causes (minus the high bit) */
> +#define IRQ_S_SOFT		1
> +#define IRQ_VS_SOFT		2
> +#define IRQ_M_SOFT		3
> +#define IRQ_S_TIMER		5
> +#define IRQ_VS_TIMER		6
> +#define IRQ_M_TIMER		7
> +#define IRQ_S_EXT		9
> +#define IRQ_VS_EXT		10
> +#define IRQ_M_EXT		11
> +#define IRQ_S_GEXT		12
> +#define IRQ_PMU_OVF		13
> +#define IRQ_LOCAL_MAX		(IRQ_PMU_OVF + 1)
> +#define IRQ_LOCAL_MASK		GENMASK((IRQ_LOCAL_MAX - 1), 0)
> +
> +/* Exception causes */
> +#define EXC_INST_MISALIGNED	0
> +#define EXC_INST_ACCESS		1
> +#define EXC_INST_ILLEGAL	2
> +#define EXC_BREAKPOINT		3
> +#define EXC_LOAD_MISALIGNED	4
> +#define EXC_LOAD_ACCESS		5
> +#define EXC_STORE_MISALIGNED	6
> +#define EXC_STORE_ACCESS	7
> +#define EXC_SYSCALL		8
> +#define EXC_HYPERVISOR_SYSCALL	9
> +#define EXC_SUPERVISOR_SYSCALL	10
> +#define EXC_INST_PAGE_FAULT	12
> +#define EXC_LOAD_PAGE_FAULT	13
> +#define EXC_STORE_PAGE_FAULT	15
> +#define EXC_INST_GUEST_PAGE_FAULT	20
> +#define EXC_LOAD_GUEST_PAGE_FAULT	21
> +#define EXC_VIRTUAL_INST_FAULT		22
> +#define EXC_STORE_GUEST_PAGE_FAULT	23
> +
> +/* PMP configuration */
> +#define PMP_R			0x01
> +#define PMP_W			0x02
> +#define PMP_X			0x04
> +#define PMP_A			0x18
> +#define PMP_A_TOR		0x08
> +#define PMP_A_NA4		0x10
> +#define PMP_A_NAPOT		0x18
> +#define PMP_L			0x80
> +
> +/* HSTATUS flags */
> +#ifdef CONFIG_64BIT
> +#define HSTATUS_VSXL		_AC(0x300000000, UL)
> +#define HSTATUS_VSXL_SHIFT	32
> +#endif
> +#define HSTATUS_VTSR		_AC(0x00400000, UL)
> +#define HSTATUS_VTW		_AC(0x00200000, UL)
> +#define HSTATUS_VTVM		_AC(0x00100000, UL)
> +#define HSTATUS_VGEIN		_AC(0x0003f000, UL)
> +#define HSTATUS_VGEIN_SHIFT	12
> +#define HSTATUS_HU		_AC(0x00000200, UL)
> +#define HSTATUS_SPVP		_AC(0x00000100, UL)
> +#define HSTATUS_SPV		_AC(0x00000080, UL)
> +#define HSTATUS_GVA		_AC(0x00000040, UL)
> +#define HSTATUS_VSBE		_AC(0x00000020, UL)
> +
> +/* HGATP flags */
> +#define HGATP_MODE_OFF		_AC(0, UL)
> +#define HGATP_MODE_SV32X4	_AC(1, UL)
> +#define HGATP_MODE_SV39X4	_AC(8, UL)
> +#define HGATP_MODE_SV48X4	_AC(9, UL)
> +#define HGATP_MODE_SV57X4	_AC(10, UL)
> +
> +#define HGATP32_MODE_SHIFT	31
> +#define HGATP32_VMID_SHIFT	22
> +#define HGATP32_VMID		GENMASK(28, 22)
> +#define HGATP32_PPN		GENMASK(21, 0)
> +
> +#define HGATP64_MODE_SHIFT	60
> +#define HGATP64_VMID_SHIFT	44
> +#define HGATP64_VMID		GENMASK(57, 44)
> +#define HGATP64_PPN		GENMASK(43, 0)
> +
> +#define HGATP_PAGE_SHIFT	12
> +
> +#ifdef CONFIG_64BIT
> +#define HGATP_PPN		HGATP64_PPN
> +#define HGATP_VMID_SHIFT	HGATP64_VMID_SHIFT
> +#define HGATP_VMID		HGATP64_VMID
> +#define HGATP_MODE_SHIFT	HGATP64_MODE_SHIFT
> +#else
> +#define HGATP_PPN		HGATP32_PPN
> +#define HGATP_VMID_SHIFT	HGATP32_VMID_SHIFT
> +#define HGATP_VMID		HGATP32_VMID
> +#define HGATP_MODE_SHIFT	HGATP32_MODE_SHIFT
> +#endif
> +
> +/* VSIP & HVIP relation */
> +#define VSIP_TO_HVIP_SHIFT	(IRQ_VS_SOFT - IRQ_S_SOFT)
> +#define VSIP_VALID_MASK		((_AC(1, UL) << IRQ_S_SOFT) | \
> +				 (_AC(1, UL) << IRQ_S_TIMER) | \
> +				 (_AC(1, UL) << IRQ_S_EXT))
> +
> +/* AIA CSR bits */
> +#define TOPI_IID_SHIFT		16
> +#define TOPI_IID_MASK		GENMASK(11, 0)
> +#define TOPI_IPRIO_MASK		GENMASK(7, 0)
> +#define TOPI_IPRIO_BITS		8
> +
> +#define TOPEI_ID_SHIFT		16
> +#define TOPEI_ID_MASK		GENMASK(10, 0)
> +#define TOPEI_PRIO_MASK		GENMASK(10, 0)
> +
> +#define ISELECT_IPRIO0		0x30
> +#define ISELECT_IPRIO15		0x3f
> +#define ISELECT_MASK		GENMASK(8, 0)
> +
> +#define HVICTL_VTI		BIT(30)
> +#define HVICTL_IID		GENMASK(27, 16)
> +#define HVICTL_IID_SHIFT	16
> +#define HVICTL_DPR		BIT(9)
> +#define HVICTL_IPRIOM		BIT(8)
> +#define HVICTL_IPRIO		GENMASK(7, 0)
> +
> +/* xENVCFG flags */
> +#define ENVCFG_STCE			(_AC(1, ULL) << 63)
> +#define ENVCFG_PBMTE			(_AC(1, ULL) << 62)
> +#define ENVCFG_CBZE			(_AC(1, UL) << 7)
> +#define ENVCFG_CBCFE			(_AC(1, UL) << 6)
> +#define ENVCFG_CBIE_SHIFT		4
> +#define ENVCFG_CBIE			(_AC(0x3, UL) << ENVCFG_CBIE_SHIFT)
> +#define ENVCFG_CBIE_ILL			_AC(0x0, UL)
> +#define ENVCFG_CBIE_FLUSH		_AC(0x1, UL)
> +#define ENVCFG_CBIE_INV			_AC(0x3, UL)
> +#define ENVCFG_FIOM			_AC(0x1, UL)
> +
> +/* symbolic CSR names: */
> +#define CSR_CYCLE		0xc00
> +#define CSR_TIME		0xc01
> +#define CSR_INSTRET		0xc02
> +#define CSR_HPMCOUNTER3		0xc03
> +#define CSR_HPMCOUNTER4		0xc04
> +#define CSR_HPMCOUNTER5		0xc05
> +#define CSR_HPMCOUNTER6		0xc06
> +#define CSR_HPMCOUNTER7		0xc07
> +#define CSR_HPMCOUNTER8		0xc08
> +#define CSR_HPMCOUNTER9		0xc09
> +#define CSR_HPMCOUNTER10	0xc0a
> +#define CSR_HPMCOUNTER11	0xc0b
> +#define CSR_HPMCOUNTER12	0xc0c
> +#define CSR_HPMCOUNTER13	0xc0d
> +#define CSR_HPMCOUNTER14	0xc0e
> +#define CSR_HPMCOUNTER15	0xc0f
> +#define CSR_HPMCOUNTER16	0xc10
> +#define CSR_HPMCOUNTER17	0xc11
> +#define CSR_HPMCOUNTER18	0xc12
> +#define CSR_HPMCOUNTER19	0xc13
> +#define CSR_HPMCOUNTER20	0xc14
> +#define CSR_HPMCOUNTER21	0xc15
> +#define CSR_HPMCOUNTER22	0xc16
> +#define CSR_HPMCOUNTER23	0xc17
> +#define CSR_HPMCOUNTER24	0xc18
> +#define CSR_HPMCOUNTER25	0xc19
> +#define CSR_HPMCOUNTER26	0xc1a
> +#define CSR_HPMCOUNTER27	0xc1b
> +#define CSR_HPMCOUNTER28	0xc1c
> +#define CSR_HPMCOUNTER29	0xc1d
> +#define CSR_HPMCOUNTER30	0xc1e
> +#define CSR_HPMCOUNTER31	0xc1f
> +#define CSR_CYCLEH		0xc80
> +#define CSR_TIMEH		0xc81
> +#define CSR_INSTRETH		0xc82
> +#define CSR_HPMCOUNTER3H	0xc83
> +#define CSR_HPMCOUNTER4H	0xc84
> +#define CSR_HPMCOUNTER5H	0xc85
> +#define CSR_HPMCOUNTER6H	0xc86
> +#define CSR_HPMCOUNTER7H	0xc87
> +#define CSR_HPMCOUNTER8H	0xc88
> +#define CSR_HPMCOUNTER9H	0xc89
> +#define CSR_HPMCOUNTER10H	0xc8a
> +#define CSR_HPMCOUNTER11H	0xc8b
> +#define CSR_HPMCOUNTER12H	0xc8c
> +#define CSR_HPMCOUNTER13H	0xc8d
> +#define CSR_HPMCOUNTER14H	0xc8e
> +#define CSR_HPMCOUNTER15H	0xc8f
> +#define CSR_HPMCOUNTER16H	0xc90
> +#define CSR_HPMCOUNTER17H	0xc91
> +#define CSR_HPMCOUNTER18H	0xc92
> +#define CSR_HPMCOUNTER19H	0xc93
> +#define CSR_HPMCOUNTER20H	0xc94
> +#define CSR_HPMCOUNTER21H	0xc95
> +#define CSR_HPMCOUNTER22H	0xc96
> +#define CSR_HPMCOUNTER23H	0xc97
> +#define CSR_HPMCOUNTER24H	0xc98
> +#define CSR_HPMCOUNTER25H	0xc99
> +#define CSR_HPMCOUNTER26H	0xc9a
> +#define CSR_HPMCOUNTER27H	0xc9b
> +#define CSR_HPMCOUNTER28H	0xc9c
> +#define CSR_HPMCOUNTER29H	0xc9d
> +#define CSR_HPMCOUNTER30H	0xc9e
> +#define CSR_HPMCOUNTER31H	0xc9f
> +
> +#define CSR_SSCOUNTOVF		0xda0
> +
> +#define CSR_SSTATUS		0x100
> +#define CSR_SIE			0x104
> +#define CSR_STVEC		0x105
> +#define CSR_SCOUNTEREN		0x106
> +#define CSR_SSCRATCH		0x140
> +#define CSR_SEPC		0x141
> +#define CSR_SCAUSE		0x142
> +#define CSR_STVAL		0x143
> +#define CSR_SIP			0x144
> +#define CSR_SATP		0x180
> +
> +#define CSR_STIMECMP		0x14D
> +#define CSR_STIMECMPH		0x15D
> +
> +/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
> +#define CSR_SISELECT		0x150
> +#define CSR_SIREG		0x151
> +
> +/* Supervisor-Level Interrupts (AIA) */
> +#define CSR_STOPEI		0x15c
> +#define CSR_STOPI		0xdb0
> +
> +/* Supervisor-Level High-Half CSRs (AIA) */
> +#define CSR_SIEH		0x114
> +#define CSR_SIPH		0x154
> +
> +#define CSR_VSSTATUS		0x200
> +#define CSR_VSIE		0x204
> +#define CSR_VSTVEC		0x205
> +#define CSR_VSSCRATCH		0x240
> +#define CSR_VSEPC		0x241
> +#define CSR_VSCAUSE		0x242
> +#define CSR_VSTVAL		0x243
> +#define CSR_VSIP		0x244
> +#define CSR_VSATP		0x280
> +#define CSR_VSTIMECMP		0x24D
> +#define CSR_VSTIMECMPH		0x25D
> +
> +#define CSR_HSTATUS		0x600
> +#define CSR_HEDELEG		0x602
> +#define CSR_HIDELEG		0x603
> +#define CSR_HIE			0x604
> +#define CSR_HTIMEDELTA		0x605
> +#define CSR_HCOUNTEREN		0x606
> +#define CSR_HGEIE		0x607
> +#define CSR_HENVCFG		0x60a
> +#define CSR_HTIMEDELTAH		0x615
> +#define CSR_HENVCFGH		0x61a
> +#define CSR_HTVAL		0x643
> +#define CSR_HIP			0x644
> +#define CSR_HVIP		0x645
> +#define CSR_HTINST		0x64a
> +#define CSR_HGATP		0x680
> +#define CSR_HGEIP		0xe12
> +
> +/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
> +#define CSR_HVIEN		0x608
> +#define CSR_HVICTL		0x609
> +#define CSR_HVIPRIO1		0x646
> +#define CSR_HVIPRIO2		0x647
> +
> +/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
> +#define CSR_VSISELECT		0x250
> +#define CSR_VSIREG		0x251
> +
> +/* VS-Level Interrupts (H-extension with AIA) */
> +#define CSR_VSTOPEI		0x25c
> +#define CSR_VSTOPI		0xeb0
> +
> +/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
> +#define CSR_HIDELEGH		0x613
> +#define CSR_HVIENH		0x618
> +#define CSR_HVIPH		0x655
> +#define CSR_HVIPRIO1H		0x656
> +#define CSR_HVIPRIO2H		0x657
> +#define CSR_VSIEH		0x214
> +#define CSR_VSIPH		0x254
> +
> +#define CSR_MSTATUS		0x300
> +#define CSR_MISA		0x301
> +#define CSR_MIDELEG		0x303
> +#define CSR_MIE			0x304
> +#define CSR_MTVEC		0x305
> +#define CSR_MENVCFG		0x30a
> +#define CSR_MENVCFGH		0x31a
> +#define CSR_MSCRATCH		0x340
> +#define CSR_MEPC		0x341
> +#define CSR_MCAUSE		0x342
> +#define CSR_MTVAL		0x343
> +#define CSR_MIP			0x344
> +#define CSR_PMPCFG0		0x3a0
> +#define CSR_PMPADDR0		0x3b0
> +#define CSR_MVENDORID		0xf11
> +#define CSR_MARCHID		0xf12
> +#define CSR_MIMPID		0xf13
> +#define CSR_MHARTID		0xf14
> +
> +/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
> +#define CSR_MISELECT		0x350
> +#define CSR_MIREG		0x351
> +
> +/* Machine-Level Interrupts (AIA) */
> +#define CSR_MTOPEI		0x35c
> +#define CSR_MTOPI		0xfb0
> +
> +/* Virtual Interrupts for Supervisor Level (AIA) */
> +#define CSR_MVIEN		0x308
> +#define CSR_MVIP		0x309
> +
> +/* Machine-Level High-Half CSRs (AIA) */
> +#define CSR_MIDELEGH		0x313
> +#define CSR_MIEH		0x314
> +#define CSR_MVIENH		0x318
> +#define CSR_MVIPH		0x319
> +#define CSR_MIPH		0x354
> +
> +#define CSR_VSTART		0x8
> +#define CSR_VCSR		0xf
> +#define CSR_VL			0xc20
> +#define CSR_VTYPE		0xc21
> +#define CSR_VLENB		0xc22
> +
> +#ifdef CONFIG_RISCV_M_MODE
> +# define CSR_STATUS	CSR_MSTATUS
> +# define CSR_IE		CSR_MIE
> +# define CSR_TVEC	CSR_MTVEC
> +# define CSR_SCRATCH	CSR_MSCRATCH
> +# define CSR_EPC	CSR_MEPC
> +# define CSR_CAUSE	CSR_MCAUSE
> +# define CSR_TVAL	CSR_MTVAL
> +# define CSR_IP		CSR_MIP
> +
> +# define CSR_IEH		CSR_MIEH
> +# define CSR_ISELECT	CSR_MISELECT
> +# define CSR_IREG	CSR_MIREG
> +# define CSR_IPH		CSR_MIPH
> +# define CSR_TOPEI	CSR_MTOPEI
> +# define CSR_TOPI	CSR_MTOPI
> +
> +# define SR_IE		SR_MIE
> +# define SR_PIE		SR_MPIE
> +# define SR_PP		SR_MPP
> +
> +# define RV_IRQ_SOFT		IRQ_M_SOFT
> +# define RV_IRQ_TIMER	IRQ_M_TIMER
> +# define RV_IRQ_EXT		IRQ_M_EXT
> +#else /* CONFIG_RISCV_M_MODE */
> +# define CSR_STATUS	CSR_SSTATUS
> +# define CSR_IE		CSR_SIE
> +# define CSR_TVEC	CSR_STVEC
> +# define CSR_SCRATCH	CSR_SSCRATCH
> +# define CSR_EPC	CSR_SEPC
> +# define CSR_CAUSE	CSR_SCAUSE
> +# define CSR_TVAL	CSR_STVAL
> +# define CSR_IP		CSR_SIP
> +
> +# define CSR_IEH		CSR_SIEH
> +# define CSR_ISELECT	CSR_SISELECT
> +# define CSR_IREG	CSR_SIREG
> +# define CSR_IPH		CSR_SIPH
> +# define CSR_TOPEI	CSR_STOPEI
> +# define CSR_TOPI	CSR_STOPI
> +
> +# define SR_IE		SR_SIE
> +# define SR_PIE		SR_SPIE
> +# define SR_PP		SR_SPP
> +
> +# define RV_IRQ_SOFT		IRQ_S_SOFT
> +# define RV_IRQ_TIMER	IRQ_S_TIMER
> +# define RV_IRQ_EXT		IRQ_S_EXT
> +# define RV_IRQ_PMU	IRQ_PMU_OVF
> +# define SIP_LCOFIP     (_AC(0x1, UL) << IRQ_PMU_OVF)
> +
> +#endif /* !CONFIG_RISCV_M_MODE */
> +
> +/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
> +#define IE_SIE		(_AC(0x1, UL) << RV_IRQ_SOFT)
> +#define IE_TIE		(_AC(0x1, UL) << RV_IRQ_TIMER)
> +#define IE_EIE		(_AC(0x1, UL) << RV_IRQ_EXT)
> +
> +#ifdef __ASSEMBLY__
> +#define __ASM_STR(x)    x
> +#else
> +#define __ASM_STR(x)    #x
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +
> +#define csr_swap(csr, val)					\
> +({								\
> +	unsigned long __v = (unsigned long)(val);		\
> +	__asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
> +			      : "=r" (__v) : "rK" (__v)		\
> +			      : "memory");			\
> +	__v;							\
> +})
> +
> +#define csr_read(csr)						\
> +({								\
> +	register unsigned long __v;				\
> +	__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr)	\
> +			      : "=r" (__v) :			\
> +			      : "memory");			\
> +	__v;							\
> +})
> +
> +#define csr_write(csr, val)					\
> +({								\
> +	unsigned long __v = (unsigned long)(val);		\
> +	__asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0"	\
> +			      : : "rK" (__v)			\
> +			      : "memory");			\
> +})
> +
> +#define csr_read_set(csr, val)					\
> +({								\
> +	unsigned long __v = (unsigned long)(val);		\
> +	__asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
> +			      : "=r" (__v) : "rK" (__v)		\
> +			      : "memory");			\
> +	__v;							\
> +})
> +
> +#define csr_set(csr, val)					\
> +({								\
> +	unsigned long __v = (unsigned long)(val);		\
> +	__asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0"	\
> +			      : : "rK" (__v)			\
> +			      : "memory");			\
> +})
> +
> +#define csr_read_clear(csr, val)				\
> +({								\
> +	unsigned long __v = (unsigned long)(val);		\
> +	__asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
> +			      : "=r" (__v) : "rK" (__v)		\
> +			      : "memory");			\
> +	__v;							\
> +})
> +
> +#define csr_clear(csr, val)					\
> +({								\
> +	unsigned long __v = (unsigned long)(val);		\
> +	__asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0"	\
> +			      : : "rK" (__v)			\
> +			      : "memory");			\
> +})
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _ASM_RISCV_CSR_H */
> -- 
> 2.34.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 5/8] KVM: riscv: selftests: Add exception handling support
  2023-09-02 12:59 ` [PATCH v2 5/8] KVM: riscv: selftests: Add exception handling support Haibo Xu
@ 2023-09-04 13:46   ` Andrew Jones
  0 siblings, 0 replies; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 13:46 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, wchen, Daniel Henrique Barboza,
	Greentime Hu, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, Vitaly Kuznetsov, Aaron Lewis, David Matlack,
	Ackerley Tng, Mingwei Zhang, Vipin Sharma, Maxim Levitsky,
	Peter Gonda, Thomas Huth, Like Xu, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Sat, Sep 02, 2023 at 08:59:27PM +0800, Haibo Xu wrote:
> Add the infrastructure for guest exception handling in riscv selftests.
> Customized handlers can be enabled by vm_install_exception_handler(vector)
> or vm_install_interrupt_handler().
> 
> The code is inspired from that of x86/arm64.
> 
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/testing/selftests/kvm/Makefile          |   1 +
>  .../selftests/kvm/include/riscv/processor.h   |  43 ++++++++
>  .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++++++++++++++++
>  .../selftests/kvm/lib/riscv/processor.c       |  69 ++++++++++++
>  4 files changed, 214 insertions(+)
>  create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 6/8] KVM: riscv: selftests: Add guest helper to get vcpu id
  2023-09-02 12:59 ` [PATCH v2 6/8] KVM: riscv: selftests: Add guest helper to get vcpu id Haibo Xu
@ 2023-09-04 13:48   ` Andrew Jones
  0 siblings, 0 replies; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 13:48 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Lei Wang, Vipin Sharma, Like Xu, Peter Gonda,
	Maxim Levitsky, Philippe Mathieu-Daudé, Thomas Huth,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Sat, Sep 02, 2023 at 08:59:28PM +0800, Haibo Xu wrote:
> Add guest_get_vcpuid() helper to simplify accessing to per-cpu
> private data. The sscratch CSR was used to store the vcpu id.
> 
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/testing/selftests/kvm/include/aarch64/processor.h | 4 ----
>  tools/testing/selftests/kvm/include/kvm_util_base.h     | 2 ++
>  tools/testing/selftests/kvm/lib/riscv/processor.c       | 8 ++++++++
>  3 files changed, 10 insertions(+), 4 deletions(-)
>

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function
  2023-09-02 12:59 ` [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function Haibo Xu
@ 2023-09-04 14:04   ` Andrew Jones
  2023-09-06 10:10     ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 14:04 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Daniel Henrique Barboza, wchen,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Jim Mattson, Lei Wang, Vipin Sharma,
	Maxim Levitsky, Like Xu, Peter Gonda, Thomas Huth,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	Paul Durrant, linux-kernel, linux-riscv, kvm, linux-kselftest,
	linux-arm-kernel, kvmarm, kvm-riscv

On Sat, Sep 02, 2023 at 08:59:29PM +0800, Haibo Xu wrote:
> Move vcpu_has_ext to the processor.c so that other test cases
> can use it for vCPU extension check.
> 
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  .../selftests/kvm/include/riscv/processor.h        |  2 ++
>  tools/testing/selftests/kvm/lib/riscv/processor.c  |  9 +++++++++
>  tools/testing/selftests/kvm/riscv/get-reg-list.c   | 14 --------------
>  3 files changed, 11 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index d1e5d9f7ad45..6087c8fc263a 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -42,6 +42,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
>  #define RISCV_ISA_EXT_REG(idx)	__kvm_reg_id(KVM_REG_RISCV_ISA_EXT, \
>  					     idx, KVM_REG_SIZE_ULONG)
>  
> +bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext);
> +
>  struct ex_regs {
>  	unsigned long ra;
>  	unsigned long sp;
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index 39a1e9902dec..5ececa566f24 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -15,6 +15,15 @@
>  
>  static vm_vaddr_t exception_handlers;
>  
> +bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> +{
> +	unsigned long value = 0;
> +
> +	vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> +
> +	return !!value;
> +}
> +
>  static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
>  {
>  	return (v + vm->page_size) & ~(vm->page_size - 1);
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index d8ecacd03ecf..c4028bf32e3f 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -44,20 +44,6 @@ bool check_reject_set(int err)
>  	return err == EINVAL;
>  }
>  
> -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> -{
> -	int ret;
> -	unsigned long value;
> -
> -	ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> -	if (ret) {
> -		printf("Failed to get ext %d", ext);
> -		return false;
> -	}
> -
> -	return !!value;

get-reg-list will now assert on get-reg when an extension isn't present,
rather than failing the __TEST_REQUIRE(), which would do a skip instead.
We need both the return false version and the assert version.

> -}
> -
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>  	struct vcpu_reg_sublist *s;
> -- 
> 2.34.1
>

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test
  2023-09-02 12:59 ` [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test Haibo Xu
@ 2023-09-04 14:58   ` Andrew Jones
  2023-09-07  4:20     ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-04 14:58 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Conor Dooley, Greentime Hu, wchen,
	Daniel Henrique Barboza, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, David Matlack, Aaron Lewis, Mingwei Zhang,
	Vitaly Kuznetsov, Ackerley Tng, Vipin Sharma, Maxim Levitsky,
	Peter Gonda, Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Sat, Sep 02, 2023 at 08:59:30PM +0800, Haibo Xu wrote:
> Add a KVM selftest to validate the Sstc timer functionality.
> The test was ported from arm64 arch timer test.
> 
> Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> ---
>  tools/testing/selftests/kvm/Makefile          |   1 +
>  tools/testing/selftests/kvm/arch_timer.c      |   9 ++
>  .../selftests/kvm/include/riscv/arch_timer.h  |  80 +++++++++++
>  .../selftests/kvm/include/riscv/processor.h   |  10 ++
>  .../selftests/kvm/include/timer_test.h        |   6 +
>  .../testing/selftests/kvm/riscv/arch_timer.c  | 130 ++++++++++++++++++
>  6 files changed, 236 insertions(+)
>  create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
>  create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c
> 
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index 01638027d059..7897d8051d8c 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -179,6 +179,7 @@ TEST_GEN_PROGS_s390x += rseq_test
>  TEST_GEN_PROGS_s390x += set_memory_region_test
>  TEST_GEN_PROGS_s390x += kvm_binary_stats_test
>  
> +TEST_GEN_PROGS_riscv += arch_timer
>  TEST_GEN_PROGS_riscv += demand_paging_test
>  TEST_GEN_PROGS_riscv += dirty_log_test
>  TEST_GEN_PROGS_riscv += get-reg-list
> diff --git a/tools/testing/selftests/kvm/arch_timer.c b/tools/testing/selftests/kvm/arch_timer.c
> index 529024f58c98..691bd454e362 100644
> --- a/tools/testing/selftests/kvm/arch_timer.c
> +++ b/tools/testing/selftests/kvm/arch_timer.c
> @@ -66,8 +66,13 @@ static void *test_vcpu_run(void *arg)
>  		break;
>  	case UCALL_ABORT:
>  		sync_global_from_guest(vm, *shared_data);
> +#ifdef __aarch64__
>  		fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
>  		        vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> +#else
> +		fprintf(stderr, "Guest assert failed,  vcpu %u; iter: %u\n",
> +		        vcpu_idx, shared_data->nr_iter);
> +#endif

We can avoid this #ifdef by just letting guest_stage output as zero for
riscv.

>  		REPORT_GUEST_ASSERT(uc);
>  		break;
>  	default:
> @@ -190,7 +195,9 @@ static void test_print_help(char *name)
>  		TIMER_TEST_PERIOD_MS_DEF);
>  	pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
>  		TIMER_TEST_MIGRATION_FREQ_MS);
> +#ifdef __aarch64__
>  	pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> +#endif

We can avoid this and the next #ifdef by changing this pr_info to

 "\t-o: Counter offset (in counter cycles, default: 0) [aarch64-only]\n"

>  	pr_info("\t-h: print this help screen\n");
>  }
>  
> @@ -217,10 +224,12 @@ static bool parse_args(int argc, char *argv[])
>  		case 'm':
>  			test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
>  			break;
> +#ifdef __aarch64__
>  		case 'o':
>  			test_args.offset.counter_offset = strtol(optarg, NULL, 0);
>  			test_args.offset.reserved = 0;
>  			break;
> +#endif
>  		case 'h':
>  		default:
>  			goto err;
> diff --git a/tools/testing/selftests/kvm/include/riscv/arch_timer.h b/tools/testing/selftests/kvm/include/riscv/arch_timer.h
> new file mode 100644
> index 000000000000..897edcef8fc2
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/include/riscv/arch_timer.h
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * RISC-V Arch Timer(sstc) specific interface
> + *
> + * Copyright (c) 2023 Intel Corporation
> + */
> +
> +#ifndef SELFTEST_KVM_ARCH_TIMER_H
> +#define SELFTEST_KVM_ARCH_TIMER_H
> +
> +#include <asm/csr.h>
> +
> +static unsigned long timer_freq;
> +
> +#define msec_to_cycles(msec)	\
> +	((timer_freq) * (uint64_t)(msec) / 1000)
> +
> +#define usec_to_cycles(usec)	\
> +	((timer_freq) * (uint64_t)(usec) / 1000000)
> +
> +#define cycles_to_usec(cycles) \
> +	((uint64_t)(cycles) * 1000000 / (timer_freq))
> +
> +static inline uint64_t timer_get_cntct(void)
> +{
> +	return csr_read(CSR_TIME);
> +}
> +
> +static inline void timer_set_cval(uint64_t cval)
> +{
> +	csr_write(CSR_STIMECMP, cval);
> +}
> +
> +static inline uint64_t timer_get_cval(void)
> +{
> +	return csr_read(CSR_STIMECMP);
> +}

The names in the above functions with cntct/cval are aarch64-isms. I'd
name the functions more explicitly: timer_get_cycles(), timer_set/get_cmp()

> +
> +static inline void timer_irq_enable(void)
> +{
> +	csr_set(CSR_SIE, IE_TIE);
> +}
> +
> +static inline void timer_irq_disable(void)
> +{
> +	csr_clear(CSR_SIE, IE_TIE);
> +}
> +
> +static inline void timer_set_next_cval_ms(uint32_t msec)

timer_set_next_cmp_ms()

> +{
> +	uint64_t now_ct = timer_get_cntct();
> +	uint64_t next_ct = now_ct + msec_to_cycles(msec);
> +
> +	timer_set_cval(next_ct);
> +}
> +
> +static inline void cpu_relax(void)
> +{
> +#ifdef __riscv_zihintpause
> +	asm volatile("pause" ::: "memory");
> +#else
> +	/* Encoding of the pause instruction */
> +	asm volatile(".4byte 0x100000F" ::: "memory");
> +#endif
> +}
> +
> +static inline void __delay(uint64_t cycles)
> +{
> +	uint64_t start = timer_get_cntct();
> +
> +	while ((timer_get_cntct() - start) < cycles)
> +		cpu_relax();
> +}
> +
> +static inline void udelay(unsigned long usec)
> +{
> +	__delay(usec_to_cycles(usec));
> +}
> +
> +#endif /* SELFTEST_KVM_ARCH_TIMER_H */
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index 6087c8fc263a..c69f36302d41 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -161,4 +161,14 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
>  			unsigned long arg3, unsigned long arg4,
>  			unsigned long arg5);
>  
> +static inline void local_irq_enable(void)
> +{
> +	csr_set(CSR_SSTATUS, SR_SIE);
> +}
> +
> +static inline void local_irq_disable(void)
> +{
> +	csr_clear(CSR_SSTATUS, SR_SIE);
> +}
> +
>  #endif /* SELFTEST_KVM_PROCESSOR_H */
> diff --git a/tools/testing/selftests/kvm/include/timer_test.h b/tools/testing/selftests/kvm/include/timer_test.h
> index 109e4d635627..091c05a14c93 100644
> --- a/tools/testing/selftests/kvm/include/timer_test.h
> +++ b/tools/testing/selftests/kvm/include/timer_test.h
> @@ -18,6 +18,7 @@
>  
>  #define msecs_to_usecs(msec)    ((msec) * 1000LL)
>  
> +#ifdef __aarch64__
>  #define GICD_BASE_GPA    0x8000000ULL
>  #define GICR_BASE_GPA    0x80A0000ULL
>  
> @@ -28,6 +29,7 @@ enum guest_stage {
>  	GUEST_STAGE_PTIMER_TVAL,
>  	GUEST_STAGE_MAX,
>  };
> +#endif

No need for this #ifdef, just move these aarch64 things to
aarch64/arch_timer.c

>  
>  /* Timer test cmdline parameters */
>  struct test_args
> @@ -36,13 +38,17 @@ struct test_args
>  	int nr_iter;
>  	int timer_period_ms;
>  	int migration_freq_ms;
> +#ifdef __aarch64__
>  	struct kvm_arm_counter_offset offset;
> +#endif

test_args shouldn't have aarch64 stuff in it. We can change it to
uint64_t offset, which riscv won't use, and aarch64 will pack it
into a struct kvm_arm_counter_offset when it needs to use it.

>  };
>  
>  /* Shared variables between host and guest */
>  struct test_vcpu_shared_data {
>  	int nr_iter;
> +#ifdef __aarch64__
>  	enum guest_stage guest_stage;
> +#endif

No need for #ifdef. Each arch can define it's own guest_stage enum in its
own test file. riscv won't have any stages defined.

>  	uint64_t xcnt;
>  };
>  
> diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> new file mode 100644
> index 000000000000..c50a33c1e4f9
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> @@ -0,0 +1,130 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
> + *
> + * The test validates the sstc timer IRQs using vstimecmp registers.
> + * It's ported from the aarch64 arch_timer test.
> + *
> + * Copyright (c) 2023, Intel Corporation.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include "arch_timer.h"
> +#include "kvm_util.h"
> +#include "processor.h"
> +#include "timer_test.h"
> +
> +extern struct test_args test_args;
> +extern struct kvm_vcpu *vcpus[];
> +extern struct test_vcpu_shared_data vcpu_shared_data[];
> +
> +static int timer_irq = IRQ_S_TIMER;
> +
> +static void
> +guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
> +{
> +	timer_set_next_cval_ms(test_args.timer_period_ms);
> +	shared_data->xcnt = timer_get_cntct();
> +	timer_irq_enable();
> +}
> +
> +static void guest_validate_irq(unsigned int intid,
> +				struct test_vcpu_shared_data *shared_data)
> +{
> +	uint64_t xcnt = 0, xcnt_diff_us, cval = 0;

Don't need to initialize xcnt and cval, they get overwritten right away.
(cval should be renamed to cmp)

> +
> +	timer_irq_disable();
> +	xcnt = timer_get_cntct();
> +	cval = timer_get_cval();
> +
> +	xcnt_diff_us = cycles_to_usec(xcnt - shared_data->xcnt);
> +
> +	/* Make sure we are dealing with the correct timer IRQ */
> +	GUEST_ASSERT_EQ(intid, timer_irq);
> +
> +	__GUEST_ASSERT(xcnt >= cval,
> +	               "xcnt = 0x%llx, cval = 0x%llx, xcnt_diff_us = 0x%llx",
> +	               xcnt, cval, xcnt_diff_us);
> +
> +	WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter + 1);
> +}
> +
> +static void guest_irq_handler(struct ex_regs *regs)
> +{
> +	unsigned int intid = regs->cause & ~CAUSE_IRQ_FLAG;
> +	uint32_t cpu = guest_get_vcpuid();
> +	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
> +
> +	guest_validate_irq(intid, shared_data);
> +}
> +
> +static void guest_run(struct test_vcpu_shared_data *shared_data)
> +{
> +	uint32_t irq_iter, config_iter;
> +
> +	shared_data->nr_iter = 0;
> +
> +	for (config_iter = 0; config_iter < test_args.nr_iter; config_iter++) {
> +		/* Setup the next interrupt */
> +		guest_configure_timer_action(shared_data);
> +
> +		/* Setup a timeout for the interrupt to arrive */
> +		udelay(msecs_to_usecs(test_args.timer_period_ms) +
> +			TIMER_TEST_ERR_MARGIN_US);
> +
> +		irq_iter = READ_ONCE(shared_data->nr_iter);
> +		GUEST_ASSERT_EQ(config_iter + 1, irq_iter);
> +	}
> +}

guest_run[_stage]() can be shared with aarch64, we just have a single
stage=0 for riscv.

> +
> +static void guest_code(void)
> +{
> +	uint32_t cpu = guest_get_vcpuid();
> +	struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
> +
> +	local_irq_disable();
> +	timer_irq_disable();
> +	local_irq_enable();

I don't think we need to disable all interrupts when disabling the timer
interrupt.

> +
> +	guest_run(shared_data);
> +
> +	GUEST_DONE();
> +}
> +
> +static void test_init_timer_freq(struct kvm_vm *vm)
> +{
> +	/* Timer frequency should be same for all the vCPUs, so query only vCPU-0 */
> +	vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency), &timer_freq);
> +	sync_global_to_guest(vm, timer_freq);
> +
> +	pr_debug("timer_freq: %lu\n", timer_freq);
> +}
> +
> +struct kvm_vm *test_vm_create(void)
> +{
> +	struct kvm_vm *vm;
> +	int nr_vcpus = test_args.nr_vcpus;
> +
> +	vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
> +	__TEST_REQUIRE(vcpu_has_ext(vcpus[0], KVM_RISCV_ISA_EXT_SSTC),
> +				   "SSTC not available, skipping test\n");

This will assert on get-one-reg rather than skip the test.

> +
> +	vm_init_vector_tables(vm);
> +	vm_install_interrupt_handler(vm, guest_irq_handler);
> +
> +	for (int i = 0; i < nr_vcpus; i++)
> +		vcpu_init_vector_tables(vcpus[i]);
> +
> +	test_init_timer_freq(vm);
> +
> +	/* Make all the test's cmdline args visible to the guest */
> +	sync_global_to_guest(vm, test_args);
> +
> +	return vm;
> +}
> +
> +void test_vm_cleanup(struct kvm_vm *vm)
> +{
> +	kvm_vm_free(vm);
> +}
> -- 
> 2.34.1
>

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest
  2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
                   ` (7 preceding siblings ...)
  2023-09-02 12:59 ` [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test Haibo Xu
@ 2023-09-05 10:36 ` Andrew Jones
  2023-09-06  1:23   ` Haibo Xu
  8 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-05 10:36 UTC (permalink / raw)
  To: Haibo Xu
  Cc: xiaobo55x, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, wchen, Greentime Hu, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vipin Sharma, Aaron Lewis,
	David Matlack, Mingwei Zhang, Vitaly Kuznetsov, Ackerley Tng,
	Lei Wang, Maxim Levitsky, Peter Gonda, Thomas Huth, Like Xu,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	linux-kernel, linux-riscv, kvm, linux-kselftest, linux-arm-kernel,
	kvmarm, kvm-riscv

Hi Haibo,

Some of your patch summaries say 'selftest' instead of 'selftests'. Please
correct those for the next version.

Thanks,
drew

On Sat, Sep 02, 2023 at 08:59:22PM +0800, Haibo Xu wrote:
> The RISC-V arch_timer selftest is used to validate Sstc timer
> functionality in a guest, which sets up periodic timer interrupts
> and check the basic interrupt status upon its receipt.
> 
> This KVM selftest was ported from aarch64 arch_timer and tested
> with Linux v6.5-rc5 on a Qemu riscv64 virt machine.
> 
> ---
> Changed since v1:
>   * Rebase to kvm-riscv/riscv_kvm_next
>   * Cherry-pick Sean's kselftest guest printf patch set
>     https://lore.kernel.org/all/20230729003643.1053367-1-seanjc@google.com/
>   * Copy the entire csr.h verbatim
>   * Unified the function names for exception vector table setup
>     void vm_init_vector_tables(struct kvm_vm *vm);
>     void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
>   * Format the handler.S asm file per Andrew's comments
>   * Consolidate the timer test code for arm64 and riscv
>     based on Andrew's and Sean's suggestion
> 
> Haibo Xu (8):
>   KVM: selftests: Unify the codes for guest exception handling
>   KVM: arm64: selftest: Split arch_timer test code
>   tools: riscv: Add header file csr.h
>   KVM: riscv: selftests: Switch to use macro from csr.h
>   KVM: riscv: selftests: Add exception handling support
>   KVM: riscv: selftests: Add guest helper to get vcpu id
>   KVM: riscv: selftest: Change vcpu_has_ext to a common function
>   KVM: riscv: selftests: Add sstc timer test
> 
>  tools/arch/riscv/include/asm/csr.h            | 521 ++++++++++++++++++
>  tools/testing/selftests/kvm/Makefile          |  11 +-
>  .../selftests/kvm/aarch64/arch_timer.c        | 292 +---------
>  .../selftests/kvm/aarch64/debug-exceptions.c  |   4 +-
>  .../selftests/kvm/aarch64/page_fault_test.c   |   4 +-
>  .../testing/selftests/kvm/aarch64/vgic_irq.c  |   4 +-
>  tools/testing/selftests/kvm/arch_timer.c      | 261 +++++++++
>  .../selftests/kvm/include/aarch64/processor.h |  12 +-
>  .../selftests/kvm/include/kvm_util_base.h     |   9 +
>  .../selftests/kvm/include/riscv/arch_timer.h  |  80 +++
>  .../selftests/kvm/include/riscv/processor.h   |  60 +-
>  .../selftests/kvm/include/timer_test.h        |  58 ++
>  .../selftests/kvm/include/x86_64/processor.h  |   5 -
>  .../selftests/kvm/lib/aarch64/processor.c     |   6 +-
>  .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++
>  .../selftests/kvm/lib/riscv/processor.c       |  86 +++
>  .../selftests/kvm/lib/x86_64/processor.c      |   4 +-
>  .../testing/selftests/kvm/riscv/arch_timer.c  | 130 +++++
>  .../selftests/kvm/riscv/get-reg-list.c        |  14 -
>  tools/testing/selftests/kvm/x86_64/amx_test.c |   4 +-
>  .../selftests/kvm/x86_64/fix_hypercall_test.c |   4 +-
>  .../selftests/kvm/x86_64/hyperv_evmcs.c       |   4 +-
>  .../selftests/kvm/x86_64/hyperv_features.c    |   8 +-
>  .../testing/selftests/kvm/x86_64/hyperv_ipi.c |   6 +-
>  .../selftests/kvm/x86_64/kvm_pv_test.c        |   4 +-
>  .../selftests/kvm/x86_64/monitor_mwait_test.c |   4 +-
>  .../kvm/x86_64/pmu_event_filter_test.c        |   8 +-
>  .../smaller_maxphyaddr_emulation_test.c       |   4 +-
>  .../selftests/kvm/x86_64/svm_int_ctl_test.c   |   4 +-
>  .../kvm/x86_64/svm_nested_shutdown_test.c     |   4 +-
>  .../kvm/x86_64/svm_nested_soft_inject_test.c  |   4 +-
>  .../kvm/x86_64/ucna_injection_test.c          |   8 +-
>  .../kvm/x86_64/userspace_msr_exit_test.c      |   4 +-
>  .../vmx_exception_with_invalid_guest_state.c  |   4 +-
>  .../selftests/kvm/x86_64/vmx_pmu_caps_test.c  |   4 +-
>  .../selftests/kvm/x86_64/xapic_ipi_test.c     |   4 +-
>  .../selftests/kvm/x86_64/xcr0_cpuid_test.c    |   4 +-
>  .../selftests/kvm/x86_64/xen_shinfo_test.c    |   4 +-
>  38 files changed, 1376 insertions(+), 376 deletions(-)
>  create mode 100644 tools/arch/riscv/include/asm/csr.h
>  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
>  create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
>  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
>  create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
>  create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c
> 
> -- 
> 2.34.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest
  2023-09-05 10:36 ` [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Andrew Jones
@ 2023-09-06  1:23   ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  1:23 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	wchen, Greentime Hu, Sean Christopherson, Ricardo Koller,
	Vishal Annapurve, Vipin Sharma, Aaron Lewis, David Matlack,
	Mingwei Zhang, Vitaly Kuznetsov, Ackerley Tng, Lei Wang,
	Maxim Levitsky, Peter Gonda, Thomas Huth, Like Xu,
	Philippe Mathieu-Daudé, David Woodhouse, Michal Luczaj,
	linux-kernel, linux-riscv, kvm, linux-kselftest, linux-arm-kernel,
	kvmarm, kvm-riscv

On Tue, Sep 5, 2023 at 6:36 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> Hi Haibo,
>
> Some of your patch summaries say 'selftest' instead of 'selftests'. Please
> correct those for the next version.
>

Sure, thanks for pointing that out!

> Thanks,
> drew
>
> On Sat, Sep 02, 2023 at 08:59:22PM +0800, Haibo Xu wrote:
> > The RISC-V arch_timer selftest is used to validate Sstc timer
> > functionality in a guest, which sets up periodic timer interrupts
> > and check the basic interrupt status upon its receipt.
> >
> > This KVM selftest was ported from aarch64 arch_timer and tested
> > with Linux v6.5-rc5 on a Qemu riscv64 virt machine.
> >
> > ---
> > Changed since v1:
> >   * Rebase to kvm-riscv/riscv_kvm_next
> >   * Cherry-pick Sean's kselftest guest printf patch set
> >     https://lore.kernel.org/all/20230729003643.1053367-1-seanjc@google.com/
> >   * Copy the entire csr.h verbatim
> >   * Unified the function names for exception vector table setup
> >     void vm_init_vector_tables(struct kvm_vm *vm);
> >     void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
> >   * Format the handler.S asm file per Andrew's comments
> >   * Consolidate the timer test code for arm64 and riscv
> >     based on Andrew's and Sean's suggestion
> >
> > Haibo Xu (8):
> >   KVM: selftests: Unify the codes for guest exception handling
> >   KVM: arm64: selftest: Split arch_timer test code
> >   tools: riscv: Add header file csr.h
> >   KVM: riscv: selftests: Switch to use macro from csr.h
> >   KVM: riscv: selftests: Add exception handling support
> >   KVM: riscv: selftests: Add guest helper to get vcpu id
> >   KVM: riscv: selftest: Change vcpu_has_ext to a common function
> >   KVM: riscv: selftests: Add sstc timer test
> >
> >  tools/arch/riscv/include/asm/csr.h            | 521 ++++++++++++++++++
> >  tools/testing/selftests/kvm/Makefile          |  11 +-
> >  .../selftests/kvm/aarch64/arch_timer.c        | 292 +---------
> >  .../selftests/kvm/aarch64/debug-exceptions.c  |   4 +-
> >  .../selftests/kvm/aarch64/page_fault_test.c   |   4 +-
> >  .../testing/selftests/kvm/aarch64/vgic_irq.c  |   4 +-
> >  tools/testing/selftests/kvm/arch_timer.c      | 261 +++++++++
> >  .../selftests/kvm/include/aarch64/processor.h |  12 +-
> >  .../selftests/kvm/include/kvm_util_base.h     |   9 +
> >  .../selftests/kvm/include/riscv/arch_timer.h  |  80 +++
> >  .../selftests/kvm/include/riscv/processor.h   |  60 +-
> >  .../selftests/kvm/include/timer_test.h        |  58 ++
> >  .../selftests/kvm/include/x86_64/processor.h  |   5 -
> >  .../selftests/kvm/lib/aarch64/processor.c     |   6 +-
> >  .../selftests/kvm/lib/riscv/handlers.S        | 101 ++++
> >  .../selftests/kvm/lib/riscv/processor.c       |  86 +++
> >  .../selftests/kvm/lib/x86_64/processor.c      |   4 +-
> >  .../testing/selftests/kvm/riscv/arch_timer.c  | 130 +++++
> >  .../selftests/kvm/riscv/get-reg-list.c        |  14 -
> >  tools/testing/selftests/kvm/x86_64/amx_test.c |   4 +-
> >  .../selftests/kvm/x86_64/fix_hypercall_test.c |   4 +-
> >  .../selftests/kvm/x86_64/hyperv_evmcs.c       |   4 +-
> >  .../selftests/kvm/x86_64/hyperv_features.c    |   8 +-
> >  .../testing/selftests/kvm/x86_64/hyperv_ipi.c |   6 +-
> >  .../selftests/kvm/x86_64/kvm_pv_test.c        |   4 +-
> >  .../selftests/kvm/x86_64/monitor_mwait_test.c |   4 +-
> >  .../kvm/x86_64/pmu_event_filter_test.c        |   8 +-
> >  .../smaller_maxphyaddr_emulation_test.c       |   4 +-
> >  .../selftests/kvm/x86_64/svm_int_ctl_test.c   |   4 +-
> >  .../kvm/x86_64/svm_nested_shutdown_test.c     |   4 +-
> >  .../kvm/x86_64/svm_nested_soft_inject_test.c  |   4 +-
> >  .../kvm/x86_64/ucna_injection_test.c          |   8 +-
> >  .../kvm/x86_64/userspace_msr_exit_test.c      |   4 +-
> >  .../vmx_exception_with_invalid_guest_state.c  |   4 +-
> >  .../selftests/kvm/x86_64/vmx_pmu_caps_test.c  |   4 +-
> >  .../selftests/kvm/x86_64/xapic_ipi_test.c     |   4 +-
> >  .../selftests/kvm/x86_64/xcr0_cpuid_test.c    |   4 +-
> >  .../selftests/kvm/x86_64/xen_shinfo_test.c    |   4 +-
> >  38 files changed, 1376 insertions(+), 376 deletions(-)
> >  create mode 100644 tools/arch/riscv/include/asm/csr.h
> >  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
> >  create mode 100644 tools/testing/selftests/kvm/include/riscv/arch_timer.h
> >  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
> >  create mode 100644 tools/testing/selftests/kvm/lib/riscv/handlers.S
> >  create mode 100644 tools/testing/selftests/kvm/riscv/arch_timer.c
> >
> > --
> > 2.34.1
> >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-04 13:24   ` Andrew Jones
@ 2023-09-06  2:14     ` Haibo Xu
  2023-09-06  3:44       ` Haibo Xu
  2023-09-06  6:41       ` Andrew Jones
  0 siblings, 2 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  2:14 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu, Peter Gonda,
	Maxim Levitsky, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Mon, Sep 4, 2023 at 9:24 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Sat, Sep 02, 2023 at 08:59:24PM +0800, Haibo Xu wrote:
> > Split the arch-neutral test code out of aarch64/arch_timer.c
> > and put them into a common arch_timer.c. This is a preparation
> > to share timer test codes in riscv.
> >
> > Suggested-by: Andrew Jones <ajones@ventanamicro.com>
> > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > ---
> >  tools/testing/selftests/kvm/Makefile          |   9 +-
> >  .../selftests/kvm/aarch64/arch_timer.c        | 288 +-----------------
> >  tools/testing/selftests/kvm/arch_timer.c      | 252 +++++++++++++++
> >  .../selftests/kvm/include/timer_test.h        |  52 ++++
> >  4 files changed, 317 insertions(+), 284 deletions(-)
> >  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
> >  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
> >
> > diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> > index 0b9c42fbce8c..fb8904e2c06a 100644
> > --- a/tools/testing/selftests/kvm/Makefile
> > +++ b/tools/testing/selftests/kvm/Makefile
> > @@ -140,7 +140,6 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test
> >  TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
> >
> >  TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
> > -TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
> >  TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
> >  TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
> >  TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> > @@ -150,6 +149,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
> >  TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
> >  TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
> >  TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
> > +TEST_GEN_PROGS_aarch64 += arch_timer
> >  TEST_GEN_PROGS_aarch64 += demand_paging_test
> >  TEST_GEN_PROGS_aarch64 += dirty_log_test
> >  TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
> > @@ -188,6 +188,7 @@ TEST_GEN_PROGS_riscv += set_memory_region_test
> >  TEST_GEN_PROGS_riscv += kvm_binary_stats_test
> >
> >  SPLIT_TESTS += get-reg-list
> > +SPLIT_TESTS += arch_timer
> >
> >  TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
> >  TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
> > @@ -248,13 +249,10 @@ TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TESTS_OBJS))
> >  -include $(TEST_DEP_FILES)
> >
> >  $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): %: %.o
> > -     $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
> > +     $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> >  $(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
> >       $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> >
> > -$(SPLIT_TESTS_TARGETS): %: %.o $(SPLIT_TESTS_OBJS)
> > -     $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> > -
> >  EXTRA_CLEAN += $(LIBKVM_OBJS) $(TEST_DEP_FILES) $(TEST_GEN_OBJ) $(SPLIT_TESTS_OBJS) cscope.*
> >
> >  x := $(shell mkdir -p $(sort $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
> > @@ -273,6 +271,7 @@ $(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
> >  x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
> >  $(TEST_GEN_PROGS): $(LIBKVM_OBJS)
> >  $(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
> > +$(SPLIT_TESTS_TARGETS): $(OUTPUT)/%: $(ARCH_DIR)/%.o
>
> The improvements to the Makefile to avoid SPLIT_TESTS_TARGETS needing its
> own $(CC) line should preferably be done in a separate, preliminary patch.
>

Yes, Will move the change to a separate patch.

> >
> >  cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
> >  cscope:
> > diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > index b63859829a96..ceb649548751 100644
> > --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > @@ -1,91 +1,25 @@
> >  // SPDX-License-Identifier: GPL-2.0-only
> >  /*
> > - * arch_timer.c - Tests the aarch64 timer IRQ functionality
> > - *
> >   * The test validates both the virtual and physical timer IRQs using
> > - * CVAL and TVAL registers. This consitutes the four stages in the test.
> > - * The guest's main thread configures the timer interrupt for a stage
> > - * and waits for it to fire, with a timeout equal to the timer period.
> > - * It asserts that the timeout doesn't exceed the timer period.
> > - *
> > - * On the other hand, upon receipt of an interrupt, the guest's interrupt
> > - * handler validates the interrupt by checking if the architectural state
> > - * is in compliance with the specifications.
> > - *
> > - * The test provides command-line options to configure the timer's
> > - * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> > - * To stress-test the timer stack even more, an option to migrate the
> > - * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> > + * CVAL and TVAL registers.
> >   *
> >   * Copyright (c) 2021, Google LLC.
> >   */
> >  #define _GNU_SOURCE
> >
> > -#include <stdlib.h>
> > -#include <pthread.h>
> > -#include <linux/kvm.h>
> > -#include <linux/sizes.h>
> > -#include <linux/bitmap.h>
> > -#include <sys/sysinfo.h>
> > -
> > -#include "kvm_util.h"
> > -#include "processor.h"
> > -#include "delay.h"
> >  #include "arch_timer.h"
> > +#include "delay.h"
> >  #include "gic.h"
> > +#include "processor.h"
> > +#include "timer_test.h"
> >  #include "vgic.h"
> >
> > -#define NR_VCPUS_DEF                 4
> > -#define NR_TEST_ITERS_DEF            5
> > -#define TIMER_TEST_PERIOD_MS_DEF     10
> > -#define TIMER_TEST_ERR_MARGIN_US     100
> > -#define TIMER_TEST_MIGRATION_FREQ_MS 2
> > -
> > -struct test_args {
> > -     int nr_vcpus;
> > -     int nr_iter;
> > -     int timer_period_ms;
> > -     int migration_freq_ms;
> > -     struct kvm_arm_counter_offset offset;
> > -};
> > -
> > -static struct test_args test_args = {
> > -     .nr_vcpus = NR_VCPUS_DEF,
> > -     .nr_iter = NR_TEST_ITERS_DEF,
> > -     .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> > -     .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> > -     .offset = { .reserved = 1 },
> > -};
> > -
> > -#define msecs_to_usecs(msec)         ((msec) * 1000LL)
> > -
> > -#define GICD_BASE_GPA                        0x8000000ULL
> > -#define GICR_BASE_GPA                        0x80A0000ULL
> > -
> > -enum guest_stage {
> > -     GUEST_STAGE_VTIMER_CVAL = 1,
> > -     GUEST_STAGE_VTIMER_TVAL,
> > -     GUEST_STAGE_PTIMER_CVAL,
> > -     GUEST_STAGE_PTIMER_TVAL,
> > -     GUEST_STAGE_MAX,
> > -};
> > -
> > -/* Shared variables between host and guest */
> > -struct test_vcpu_shared_data {
> > -     int nr_iter;
> > -     enum guest_stage guest_stage;
> > -     uint64_t xcnt;
> > -};
> > -
> > -static struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> > -static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
> > -static struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> > +extern struct test_args test_args;
> > +extern struct kvm_vcpu *vcpus[];
> > +extern struct test_vcpu_shared_data vcpu_shared_data[];
> >
> >  static int vtimer_irq, ptimer_irq;
> >
> > -static unsigned long *vcpu_done_map;
> > -static pthread_mutex_t vcpu_done_map_lock;
> > -
> >  static void
> >  guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
> >  {
> > @@ -222,137 +156,6 @@ static void guest_code(void)
> >       GUEST_DONE();
> >  }
> >
> > -static void *test_vcpu_run(void *arg)
> > -{
> > -     unsigned int vcpu_idx = (unsigned long)arg;
> > -     struct ucall uc;
> > -     struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
> > -     struct kvm_vm *vm = vcpu->vm;
> > -     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
> > -
> > -     vcpu_run(vcpu);
> > -
> > -     /* Currently, any exit from guest is an indication of completion */
> > -     pthread_mutex_lock(&vcpu_done_map_lock);
> > -     __set_bit(vcpu_idx, vcpu_done_map);
> > -     pthread_mutex_unlock(&vcpu_done_map_lock);
> > -
> > -     switch (get_ucall(vcpu, &uc)) {
> > -     case UCALL_SYNC:
> > -     case UCALL_DONE:
> > -             break;
> > -     case UCALL_ABORT:
> > -             sync_global_from_guest(vm, *shared_data);
> > -             fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
> > -                     vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> > -             REPORT_GUEST_ASSERT(uc);
> > -             break;
> > -     default:
> > -             TEST_FAIL("Unexpected guest exit\n");
> > -     }
> > -
> > -     return NULL;
> > -}
> > -
> > -static uint32_t test_get_pcpu(void)
> > -{
> > -     uint32_t pcpu;
> > -     unsigned int nproc_conf;
> > -     cpu_set_t online_cpuset;
> > -
> > -     nproc_conf = get_nprocs_conf();
> > -     sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> > -
> > -     /* Randomly find an available pCPU to place a vCPU on */
> > -     do {
> > -             pcpu = rand() % nproc_conf;
> > -     } while (!CPU_ISSET(pcpu, &online_cpuset));
> > -
> > -     return pcpu;
> > -}
> > -
> > -static int test_migrate_vcpu(unsigned int vcpu_idx)
> > -{
> > -     int ret;
> > -     cpu_set_t cpuset;
> > -     uint32_t new_pcpu = test_get_pcpu();
> > -
> > -     CPU_ZERO(&cpuset);
> > -     CPU_SET(new_pcpu, &cpuset);
> > -
> > -     pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
> > -
> > -     ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
> > -                                  sizeof(cpuset), &cpuset);
> > -
> > -     /* Allow the error where the vCPU thread is already finished */
> > -     TEST_ASSERT(ret == 0 || ret == ESRCH,
> > -                 "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> > -                 vcpu_idx, new_pcpu, ret);
> > -
> > -     return ret;
> > -}
> > -
> > -static void *test_vcpu_migration(void *arg)
> > -{
> > -     unsigned int i, n_done;
> > -     bool vcpu_done;
> > -
> > -     do {
> > -             usleep(msecs_to_usecs(test_args.migration_freq_ms));
> > -
> > -             for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> > -                     pthread_mutex_lock(&vcpu_done_map_lock);
> > -                     vcpu_done = test_bit(i, vcpu_done_map);
> > -                     pthread_mutex_unlock(&vcpu_done_map_lock);
> > -
> > -                     if (vcpu_done) {
> > -                             n_done++;
> > -                             continue;
> > -                     }
> > -
> > -                     test_migrate_vcpu(i);
> > -             }
> > -     } while (test_args.nr_vcpus != n_done);
> > -
> > -     return NULL;
> > -}
> > -
> > -static void test_run(struct kvm_vm *vm)
> > -{
> > -     pthread_t pt_vcpu_migration;
> > -     unsigned int i;
> > -     int ret;
> > -
> > -     pthread_mutex_init(&vcpu_done_map_lock, NULL);
> > -     vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
> > -     TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> > -
> > -     for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
> > -             ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
> > -                                  (void *)(unsigned long)i);
> > -             TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> > -     }
> > -
> > -     /* Spawn a thread to control the vCPU migrations */
> > -     if (test_args.migration_freq_ms) {
> > -             srand(time(NULL));
> > -
> > -             ret = pthread_create(&pt_vcpu_migration, NULL,
> > -                                     test_vcpu_migration, NULL);
> > -             TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> > -     }
> > -
> > -
> > -     for (i = 0; i < test_args.nr_vcpus; i++)
> > -             pthread_join(pt_vcpu_run[i], NULL);
> > -
> > -     if (test_args.migration_freq_ms)
> > -             pthread_join(pt_vcpu_migration, NULL);
> > -
> > -     bitmap_free(vcpu_done_map);
> > -}
> > -
> >  static void test_init_timer_irq(struct kvm_vm *vm)
> >  {
> >       /* Timer initid should be same for all the vCPUs, so query only vCPU-0 */
> > @@ -369,7 +172,7 @@ static void test_init_timer_irq(struct kvm_vm *vm)
> >
> >  static int gic_fd;
> >
> > -static struct kvm_vm *test_vm_create(void)
> > +struct kvm_vm *test_vm_create(void)
> >  {
> >       struct kvm_vm *vm;
> >       unsigned int i;
> > @@ -400,81 +203,8 @@ static struct kvm_vm *test_vm_create(void)
> >       return vm;
> >  }
> >
> > -static void test_vm_cleanup(struct kvm_vm *vm)
> > +void test_vm_cleanup(struct kvm_vm *vm)
> >  {
> >       close(gic_fd);
> >       kvm_vm_free(vm);
> >  }
> > -
> > -static void test_print_help(char *name)
> > -{
> > -     pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
> > -             name);
> > -     pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
> > -             NR_VCPUS_DEF, KVM_MAX_VCPUS);
> > -     pr_info("\t-i: Number of iterations per stage (default: %u)\n",
> > -             NR_TEST_ITERS_DEF);
> > -     pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> > -             TIMER_TEST_PERIOD_MS_DEF);
> > -     pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> > -             TIMER_TEST_MIGRATION_FREQ_MS);
> > -     pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> > -     pr_info("\t-h: print this help screen\n");
> > -}
> > -
> > -static bool parse_args(int argc, char *argv[])
> > -{
> > -     int opt;
> > -
> > -     while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
> > -             switch (opt) {
> > -             case 'n':
> > -                     test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
> > -                     if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
> > -                             pr_info("Max allowed vCPUs: %u\n",
> > -                                     KVM_MAX_VCPUS);
> > -                             goto err;
> > -                     }
> > -                     break;
> > -             case 'i':
> > -                     test_args.nr_iter = atoi_positive("Number of iterations", optarg);
> > -                     break;
> > -             case 'p':
> > -                     test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
> > -                     break;
> > -             case 'm':
> > -                     test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
> > -                     break;
> > -             case 'o':
> > -                     test_args.offset.counter_offset = strtol(optarg, NULL, 0);
> > -                     test_args.offset.reserved = 0;
> > -                     break;
> > -             case 'h':
> > -             default:
> > -                     goto err;
> > -             }
> > -     }
> > -
> > -     return true;
> > -
> > -err:
> > -     test_print_help(argv[0]);
> > -     return false;
> > -}
> > -
> > -int main(int argc, char *argv[])
> > -{
> > -     struct kvm_vm *vm;
> > -
> > -     if (!parse_args(argc, argv))
> > -             exit(KSFT_SKIP);
> > -
> > -     __TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
> > -                    "At least two physical CPUs needed for vCPU migration");
> > -
> > -     vm = test_vm_create();
> > -     test_run(vm);
> > -     test_vm_cleanup(vm);
> > -
> > -     return 0;
> > -}
> > diff --git a/tools/testing/selftests/kvm/arch_timer.c b/tools/testing/selftests/kvm/arch_timer.c
> > new file mode 100644
> > index 000000000000..529024f58c98
> > --- /dev/null
> > +++ b/tools/testing/selftests/kvm/arch_timer.c
> > @@ -0,0 +1,252 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * arch_timer.c - Tests the arch timer IRQ functionality
> > + *
> > + * The guest's main thread configures the timer interrupt for and waits
>
> It looks like the text was edited to remove the 'stage' references, which
> is fine by me, but the 'for' should have also been removed.
>
>

Sure!

> > + * for it to fire, with a timeout equal to the timer period.
> > + * It asserts that the timeout doesn't exceed the timer period.
> > + *
> > + * On the other hand, upon receipt of an interrupt, the guest's interrupt
> > + * handler validates the interrupt by checking if the architectural state
> > + * is in compliance with the specifications.
> > + *
> > + * The test provides command-line options to configure the timer's
> > + * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> > + * To stress-test the timer stack even more, an option to migrate the
> > + * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> > + *
> > + * Copyright (c) 2021, Google LLC.
> > + */
> > +
> > +#define _GNU_SOURCE
> > +
> > +#include <stdlib.h>
> > +#include <pthread.h>
> > +#include <linux/sizes.h>
> > +#include <linux/bitmap.h>
> > +#include <sys/sysinfo.h>
> > +
> > +#include "timer_test.h"
> > +
> > +struct test_args test_args = {
> > +    .nr_vcpus = NR_VCPUS_DEF,
> > +    .nr_iter = NR_TEST_ITERS_DEF,
> > +    .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> > +    .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> > +#ifdef __aarch64__
> > +    .offset = { .reserved = 1 },
> > +#endif
>
> Please run checkpatch, there are spaces instead of tabs in the struct.
>

Yes, the tabs were changed to spaces while copying. Will change it and
run checkpatch to catch this kind of error in next version.

> > +};
> > +
> > +struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> > +struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> > +
> > +static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
> > +static unsigned long *vcpu_done_map;
> > +static pthread_mutex_t vcpu_done_map_lock;
> > +
> > +static void *test_vcpu_run(void *arg)
> > +{
> > +     unsigned int vcpu_idx = (unsigned long)arg;
> > +     struct ucall uc;
> > +     struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
> > +     struct kvm_vm *vm = vcpu->vm;
> > +     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
> > +
> > +     vcpu_run(vcpu);
> > +
> > +     /* Currently, any exit from guest is an indication of completion */
> > +     pthread_mutex_lock(&vcpu_done_map_lock);
> > +     __set_bit(vcpu_idx, vcpu_done_map);
> > +     pthread_mutex_unlock(&vcpu_done_map_lock);
> > +
> > +     switch (get_ucall(vcpu, &uc)) {
> > +     case UCALL_SYNC:
> > +     case UCALL_DONE:
> > +             break;
> > +     case UCALL_ABORT:
> > +             sync_global_from_guest(vm, *shared_data);
> > +             fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
> > +                     vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> > +             REPORT_GUEST_ASSERT(uc);
> > +             break;
> > +     default:
> > +             TEST_FAIL("Unexpected guest exit\n");
> > +     }
> > +
> > +     pr_info("PASS(vCPU-%d).\n", vcpu_idx);
>
> This is new. I can live with it, but generally we don't want to modify
> functions while moving them.
>

Yes, this change was supposed to go with patch 8/8.

> > +
> > +     return NULL;
> > +}
> > +
> > +static uint32_t test_get_pcpu(void)
> > +{
> > +     uint32_t pcpu;
> > +     unsigned int nproc_conf;
> > +     cpu_set_t online_cpuset;
> > +
> > +     nproc_conf = get_nprocs_conf();
> > +     sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> > +
> > +     /* Randomly find an available pCPU to place a vCPU on */
> > +     do {
> > +             pcpu = rand() % nproc_conf;
> > +     } while (!CPU_ISSET(pcpu, &online_cpuset));
> > +
> > +     return pcpu;
> > +}
> > +
> > +static int test_migrate_vcpu(unsigned int vcpu_idx)
> > +{
> > +     int ret;
> > +     cpu_set_t cpuset;
> > +     uint32_t new_pcpu = test_get_pcpu();
> > +
> > +     CPU_ZERO(&cpuset);
> > +     CPU_SET(new_pcpu, &cpuset);
> > +
> > +     pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
> > +
> > +     ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
> > +                                  sizeof(cpuset), &cpuset);
> > +
> > +     /* Allow the error where the vCPU thread is already finished */
> > +     TEST_ASSERT(ret == 0 || ret == ESRCH,
> > +                 "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> > +                 vcpu_idx, new_pcpu, ret);
> > +
> > +     return ret;
> > +}
> > +
> > +static void *test_vcpu_migration(void *arg)
> > +{
> > +     unsigned int i, n_done;
> > +     bool vcpu_done;
> > +
> > +     do {
> > +             usleep(msecs_to_usecs(test_args.migration_freq_ms));
> > +
> > +             for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> > +                     pthread_mutex_lock(&vcpu_done_map_lock);
> > +                     vcpu_done = test_bit(i, vcpu_done_map);
> > +                     pthread_mutex_unlock(&vcpu_done_map_lock);
> > +
> > +                     if (vcpu_done) {
> > +                             n_done++;
> > +                             continue;
> > +                     }
> > +
> > +                     test_migrate_vcpu(i);
> > +             }
> > +     } while (test_args.nr_vcpus != n_done);
> > +
> > +     return NULL;
> > +}
> > +
> > +static void test_run(struct kvm_vm *vm)
> > +{
> > +     pthread_t pt_vcpu_migration;
> > +     unsigned int i;
> > +     int ret;
> > +
> > +     pthread_mutex_init(&vcpu_done_map_lock, NULL);
> > +     vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
> > +     TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> > +
> > +     for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
> > +             ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
> > +                                  (void *)(unsigned long)i);
> > +             TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> > +     }
> > +
> > +     /* Spawn a thread to control the vCPU migrations */
> > +     if (test_args.migration_freq_ms) {
> > +             srand(time(NULL));
> > +
> > +             ret = pthread_create(&pt_vcpu_migration, NULL,
> > +                                     test_vcpu_migration, NULL);
> > +             TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> > +     }
> > +
> > +
> > +     for (i = 0; i < test_args.nr_vcpus; i++)
> > +             pthread_join(pt_vcpu_run[i], NULL);
> > +
> > +     if (test_args.migration_freq_ms)
> > +             pthread_join(pt_vcpu_migration, NULL);
> > +
> > +     bitmap_free(vcpu_done_map);
> > +}
> > +
> > +static void test_print_help(char *name)
> > +{
> > +     pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
> > +             name);
> > +     pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
> > +             NR_VCPUS_DEF, KVM_MAX_VCPUS);
> > +     pr_info("\t-i: Number of iterations per stage (default: %u)\n",
> > +             NR_TEST_ITERS_DEF);
> > +     pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> > +             TIMER_TEST_PERIOD_MS_DEF);
> > +     pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> > +             TIMER_TEST_MIGRATION_FREQ_MS);
> > +     pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> > +     pr_info("\t-h: print this help screen\n");
> > +}
> > +
> > +static bool parse_args(int argc, char *argv[])
> > +{
> > +     int opt;
> > +
> > +     while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
> > +             switch (opt) {
> > +             case 'n':
> > +                     test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
> > +                     if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
> > +                             pr_info("Max allowed vCPUs: %u\n",
> > +                                     KVM_MAX_VCPUS);
> > +                             goto err;
> > +                     }
> > +                     break;
> > +             case 'i':
> > +                     test_args.nr_iter = atoi_positive("Number of iterations", optarg);
> > +                     break;
> > +             case 'p':
> > +                     test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
> > +                     break;
> > +             case 'm':
> > +                     test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
> > +                     break;
> > +             case 'o':
> > +                     test_args.offset.counter_offset = strtol(optarg, NULL, 0);
> > +                     test_args.offset.reserved = 0;
> > +                     break;
> > +             case 'h':
> > +             default:
> > +                     goto err;
> > +             }
> > +     }
> > +
> > +     return true;
> > +
> > +err:
> > +     test_print_help(argv[0]);
> > +     return false;
> > +}
> > +
> > +int main(int argc, char *argv[])
> > +{
> > +     struct kvm_vm *vm;
> > +
> > +     if (!parse_args(argc, argv))
> > +             exit(KSFT_SKIP);
> > +
> > +     __TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
> > +                    "At least two physical CPUs needed for vCPU migration");
> > +
> > +     vm = test_vm_create();
> > +     test_run(vm);
> > +     test_vm_cleanup(vm);
> > +
> > +     return 0;
> > +}
> > diff --git a/tools/testing/selftests/kvm/include/timer_test.h b/tools/testing/selftests/kvm/include/timer_test.h
> > new file mode 100644
> > index 000000000000..109e4d635627
> > --- /dev/null
> > +++ b/tools/testing/selftests/kvm/include/timer_test.h
> > @@ -0,0 +1,52 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * tools/testing/selftests/kvm/include/timer_test.h
> > + *
> > + * Copyright (C) 2018, Google LLC
> > + */
> > +
> > +#ifndef SELFTEST_KVM_TIMER_TEST_H
> > +#define SELFTEST_KVM_TIMER_TEST_H
> > +
> > +#include "kvm_util.h"
> > +
> > +#define NR_VCPUS_DEF            4
> > +#define NR_TEST_ITERS_DEF       5
> > +#define TIMER_TEST_PERIOD_MS_DEF    10
> > +#define TIMER_TEST_ERR_MARGIN_US    100
> > +#define TIMER_TEST_MIGRATION_FREQ_MS    2
> > +
> > +#define msecs_to_usecs(msec)    ((msec) * 1000LL)
>
> I'd move the above to include/test_util.h
>

Yes, msecs_to_usecs() macro should be a common API for all the tests.

> > +
> > +#define GICD_BASE_GPA    0x8000000ULL
> > +#define GICR_BASE_GPA    0x80A0000ULL
>
> These defines belong in aarch64/arch_timer.c
>

These 2 defines were also defined in other test cases, shall we move them
to an aarch64 specific header file? Maybe
tools/testing/selftests/kvm/include/aarch64/gic.h?

> > +
> > +enum guest_stage {
> > +     GUEST_STAGE_VTIMER_CVAL=1,
> > +     GUEST_STAGE_VTIMER_TVAL,
> > +     GUEST_STAGE_PTIMER_CVAL,
> > +     GUEST_STAGE_PTIMER_TVAL,
> > +     GUEST_STAGE_MAX,
> > +};
>
> This enum also belongs in aarch64/arch_timer.c
>

Yes, it should be in aarch64/arch_timer.c

> > +
> > +/* Timer test cmdline parameters */
> > +struct test_args
> > +{
> > +     int nr_vcpus;
> > +     int nr_iter;
> > +     int timer_period_ms;
> > +     int migration_freq_ms;
> > +     struct kvm_arm_counter_offset offset;
> > +};
> > +
> > +/* Shared variables between host and guest */
> > +struct test_vcpu_shared_data {
> > +     int nr_iter;
> > +     enum guest_stage guest_stage;
> > +     uint64_t xcnt;
> > +};
> > +
> > +struct kvm_vm* test_vm_create(void);
>
> Move * next to function name.
>

Sure, thanks!

> > +void test_vm_cleanup(struct kvm_vm *vm);
> > +
> > +#endif /* SELFTEST_KVM_TIMER_TEST_H */
> > --
> > 2.34.1
> >
>
> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling
  2023-09-04 11:15   ` Andrew Jones
@ 2023-09-06  2:15     ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  2:15 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Sean Christopherson, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Paolo Bonzini, Shuah Khan, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Zenghui Yu, Anup Patel,
	Atish Patra, Guo Ren, Greentime Hu, wchen,
	Daniel Henrique Barboza, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu,
	Peter Gonda, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Mon, Sep 4, 2023 at 7:16 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Sat, Sep 02, 2023 at 08:59:23PM +0800, Haibo Xu wrote:
> > Rename the vm_init_descriptor_tables() and vcpu_init_vector_tables()
>                                              ^ vcpu_init_descriptor_tables()
>
> > prototypes to vm_init_vector_tables() and vcpu_init_vector_tables()
> > respectively, so that we can use common names for the architectures
> > (x86/aarch64/riscv) and then put them in a common header.
> >
> > By the way, vm_install_exception_handler() prototype were also moved to
> > the common header since they are commonly used across the architectures.
> >
> > The patch is a preparation to share the guest exception handling codes
> > in riscv.
> >
> > Suggested-by: Andrew Jones <ajones@ventanamicro.com>
> > Suggested-by: Sean Christopherson <seanjc@google.com>
> > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > ---
> >  tools/testing/selftests/kvm/aarch64/arch_timer.c          | 4 ++--
> >  tools/testing/selftests/kvm/aarch64/debug-exceptions.c    | 4 ++--
> >  tools/testing/selftests/kvm/aarch64/page_fault_test.c     | 4 ++--
> >  tools/testing/selftests/kvm/aarch64/vgic_irq.c            | 4 ++--
> >  tools/testing/selftests/kvm/include/aarch64/processor.h   | 8 +-------
> >  tools/testing/selftests/kvm/include/kvm_util_base.h       | 7 +++++++
> >  tools/testing/selftests/kvm/include/x86_64/processor.h    | 5 -----
> >  tools/testing/selftests/kvm/lib/aarch64/processor.c       | 6 +++---
> >  tools/testing/selftests/kvm/lib/x86_64/processor.c        | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/amx_test.c             | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c   | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c         | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/hyperv_features.c      | 8 ++++----
> >  tools/testing/selftests/kvm/x86_64/hyperv_ipi.c           | 6 +++---
> >  tools/testing/selftests/kvm/x86_64/kvm_pv_test.c          | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c   | 4 ++--
> >  .../testing/selftests/kvm/x86_64/pmu_event_filter_test.c  | 8 ++++----
> >  .../kvm/x86_64/smaller_maxphyaddr_emulation_test.c        | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c     | 4 ++--
> >  .../selftests/kvm/x86_64/svm_nested_shutdown_test.c       | 4 ++--
> >  .../selftests/kvm/x86_64/svm_nested_soft_inject_test.c    | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/ucna_injection_test.c  | 8 ++++----
> >  .../selftests/kvm/x86_64/userspace_msr_exit_test.c        | 4 ++--
> >  .../kvm/x86_64/vmx_exception_with_invalid_guest_state.c   | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c    | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c       | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c      | 4 ++--
> >  tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c      | 4 ++--
> >  28 files changed, 66 insertions(+), 70 deletions(-)
> >
>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

Thanks for the review!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-06  2:14     ` Haibo Xu
@ 2023-09-06  3:44       ` Haibo Xu
  2023-09-06  7:01         ` Andrew Jones
  2023-09-06  6:41       ` Andrew Jones
  1 sibling, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  3:44 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu, Peter Gonda,
	Maxim Levitsky, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Wed, Sep 6, 2023 at 10:14 AM Haibo Xu <xiaobo55x@gmail.com> wrote:
>
> On Mon, Sep 4, 2023 at 9:24 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Sat, Sep 02, 2023 at 08:59:24PM +0800, Haibo Xu wrote:
> > > Split the arch-neutral test code out of aarch64/arch_timer.c
> > > and put them into a common arch_timer.c. This is a preparation
> > > to share timer test codes in riscv.
> > >
> > > Suggested-by: Andrew Jones <ajones@ventanamicro.com>
> > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > ---
> > >  tools/testing/selftests/kvm/Makefile          |   9 +-
> > >  .../selftests/kvm/aarch64/arch_timer.c        | 288 +-----------------
> > >  tools/testing/selftests/kvm/arch_timer.c      | 252 +++++++++++++++
> > >  .../selftests/kvm/include/timer_test.h        |  52 ++++
> > >  4 files changed, 317 insertions(+), 284 deletions(-)
> > >  create mode 100644 tools/testing/selftests/kvm/arch_timer.c
> > >  create mode 100644 tools/testing/selftests/kvm/include/timer_test.h
> > >
> > > diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> > > index 0b9c42fbce8c..fb8904e2c06a 100644
> > > --- a/tools/testing/selftests/kvm/Makefile
> > > +++ b/tools/testing/selftests/kvm/Makefile
> > > @@ -140,7 +140,6 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test
> > >  TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
> > >
> > >  TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
> > > -TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
> > >  TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
> > >  TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
> > >  TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> > > @@ -150,6 +149,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
> > >  TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
> > >  TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
> > >  TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
> > > +TEST_GEN_PROGS_aarch64 += arch_timer
> > >  TEST_GEN_PROGS_aarch64 += demand_paging_test
> > >  TEST_GEN_PROGS_aarch64 += dirty_log_test
> > >  TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
> > > @@ -188,6 +188,7 @@ TEST_GEN_PROGS_riscv += set_memory_region_test
> > >  TEST_GEN_PROGS_riscv += kvm_binary_stats_test
> > >
> > >  SPLIT_TESTS += get-reg-list
> > > +SPLIT_TESTS += arch_timer
> > >
> > >  TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
> > >  TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
> > > @@ -248,13 +249,10 @@ TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TESTS_OBJS))
> > >  -include $(TEST_DEP_FILES)
> > >
> > >  $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): %: %.o
> > > -     $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
> > > +     $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> > >  $(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
> > >       $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> > >
> > > -$(SPLIT_TESTS_TARGETS): %: %.o $(SPLIT_TESTS_OBJS)
> > > -     $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> > > -
> > >  EXTRA_CLEAN += $(LIBKVM_OBJS) $(TEST_DEP_FILES) $(TEST_GEN_OBJ) $(SPLIT_TESTS_OBJS) cscope.*
> > >
> > >  x := $(shell mkdir -p $(sort $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
> > > @@ -273,6 +271,7 @@ $(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
> > >  x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
> > >  $(TEST_GEN_PROGS): $(LIBKVM_OBJS)
> > >  $(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
> > > +$(SPLIT_TESTS_TARGETS): $(OUTPUT)/%: $(ARCH_DIR)/%.o
> >
> > The improvements to the Makefile to avoid SPLIT_TESTS_TARGETS needing its
> > own $(CC) line should preferably be done in a separate, preliminary patch.
> >
>
> Yes, Will move the change to a separate patch.
>
> > >
> > >  cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
> > >  cscope:
> > > diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > > index b63859829a96..ceb649548751 100644
> > > --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > > +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > > @@ -1,91 +1,25 @@
> > >  // SPDX-License-Identifier: GPL-2.0-only
> > >  /*
> > > - * arch_timer.c - Tests the aarch64 timer IRQ functionality
> > > - *
> > >   * The test validates both the virtual and physical timer IRQs using
> > > - * CVAL and TVAL registers. This consitutes the four stages in the test.
> > > - * The guest's main thread configures the timer interrupt for a stage
> > > - * and waits for it to fire, with a timeout equal to the timer period.
> > > - * It asserts that the timeout doesn't exceed the timer period.
> > > - *
> > > - * On the other hand, upon receipt of an interrupt, the guest's interrupt
> > > - * handler validates the interrupt by checking if the architectural state
> > > - * is in compliance with the specifications.
> > > - *
> > > - * The test provides command-line options to configure the timer's
> > > - * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> > > - * To stress-test the timer stack even more, an option to migrate the
> > > - * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> > > + * CVAL and TVAL registers.
> > >   *
> > >   * Copyright (c) 2021, Google LLC.
> > >   */
> > >  #define _GNU_SOURCE
> > >
> > > -#include <stdlib.h>
> > > -#include <pthread.h>
> > > -#include <linux/kvm.h>
> > > -#include <linux/sizes.h>
> > > -#include <linux/bitmap.h>
> > > -#include <sys/sysinfo.h>
> > > -
> > > -#include "kvm_util.h"
> > > -#include "processor.h"
> > > -#include "delay.h"
> > >  #include "arch_timer.h"
> > > +#include "delay.h"
> > >  #include "gic.h"
> > > +#include "processor.h"
> > > +#include "timer_test.h"
> > >  #include "vgic.h"
> > >
> > > -#define NR_VCPUS_DEF                 4
> > > -#define NR_TEST_ITERS_DEF            5
> > > -#define TIMER_TEST_PERIOD_MS_DEF     10
> > > -#define TIMER_TEST_ERR_MARGIN_US     100
> > > -#define TIMER_TEST_MIGRATION_FREQ_MS 2
> > > -
> > > -struct test_args {
> > > -     int nr_vcpus;
> > > -     int nr_iter;
> > > -     int timer_period_ms;
> > > -     int migration_freq_ms;
> > > -     struct kvm_arm_counter_offset offset;
> > > -};
> > > -
> > > -static struct test_args test_args = {
> > > -     .nr_vcpus = NR_VCPUS_DEF,
> > > -     .nr_iter = NR_TEST_ITERS_DEF,
> > > -     .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> > > -     .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> > > -     .offset = { .reserved = 1 },
> > > -};
> > > -
> > > -#define msecs_to_usecs(msec)         ((msec) * 1000LL)
> > > -
> > > -#define GICD_BASE_GPA                        0x8000000ULL
> > > -#define GICR_BASE_GPA                        0x80A0000ULL
> > > -
> > > -enum guest_stage {
> > > -     GUEST_STAGE_VTIMER_CVAL = 1,
> > > -     GUEST_STAGE_VTIMER_TVAL,
> > > -     GUEST_STAGE_PTIMER_CVAL,
> > > -     GUEST_STAGE_PTIMER_TVAL,
> > > -     GUEST_STAGE_MAX,
> > > -};
> > > -
> > > -/* Shared variables between host and guest */
> > > -struct test_vcpu_shared_data {
> > > -     int nr_iter;
> > > -     enum guest_stage guest_stage;
> > > -     uint64_t xcnt;
> > > -};
> > > -
> > > -static struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> > > -static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
> > > -static struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> > > +extern struct test_args test_args;
> > > +extern struct kvm_vcpu *vcpus[];
> > > +extern struct test_vcpu_shared_data vcpu_shared_data[];
> > >
> > >  static int vtimer_irq, ptimer_irq;
> > >
> > > -static unsigned long *vcpu_done_map;
> > > -static pthread_mutex_t vcpu_done_map_lock;
> > > -
> > >  static void
> > >  guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
> > >  {
> > > @@ -222,137 +156,6 @@ static void guest_code(void)
> > >       GUEST_DONE();
> > >  }
> > >
> > > -static void *test_vcpu_run(void *arg)
> > > -{
> > > -     unsigned int vcpu_idx = (unsigned long)arg;
> > > -     struct ucall uc;
> > > -     struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
> > > -     struct kvm_vm *vm = vcpu->vm;
> > > -     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
> > > -
> > > -     vcpu_run(vcpu);
> > > -
> > > -     /* Currently, any exit from guest is an indication of completion */
> > > -     pthread_mutex_lock(&vcpu_done_map_lock);
> > > -     __set_bit(vcpu_idx, vcpu_done_map);
> > > -     pthread_mutex_unlock(&vcpu_done_map_lock);
> > > -
> > > -     switch (get_ucall(vcpu, &uc)) {
> > > -     case UCALL_SYNC:
> > > -     case UCALL_DONE:
> > > -             break;
> > > -     case UCALL_ABORT:
> > > -             sync_global_from_guest(vm, *shared_data);
> > > -             fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
> > > -                     vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> > > -             REPORT_GUEST_ASSERT(uc);
> > > -             break;
> > > -     default:
> > > -             TEST_FAIL("Unexpected guest exit\n");
> > > -     }
> > > -
> > > -     return NULL;
> > > -}
> > > -
> > > -static uint32_t test_get_pcpu(void)
> > > -{
> > > -     uint32_t pcpu;
> > > -     unsigned int nproc_conf;
> > > -     cpu_set_t online_cpuset;
> > > -
> > > -     nproc_conf = get_nprocs_conf();
> > > -     sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> > > -
> > > -     /* Randomly find an available pCPU to place a vCPU on */
> > > -     do {
> > > -             pcpu = rand() % nproc_conf;
> > > -     } while (!CPU_ISSET(pcpu, &online_cpuset));
> > > -
> > > -     return pcpu;
> > > -}
> > > -
> > > -static int test_migrate_vcpu(unsigned int vcpu_idx)
> > > -{
> > > -     int ret;
> > > -     cpu_set_t cpuset;
> > > -     uint32_t new_pcpu = test_get_pcpu();
> > > -
> > > -     CPU_ZERO(&cpuset);
> > > -     CPU_SET(new_pcpu, &cpuset);
> > > -
> > > -     pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
> > > -
> > > -     ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
> > > -                                  sizeof(cpuset), &cpuset);
> > > -
> > > -     /* Allow the error where the vCPU thread is already finished */
> > > -     TEST_ASSERT(ret == 0 || ret == ESRCH,
> > > -                 "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> > > -                 vcpu_idx, new_pcpu, ret);
> > > -
> > > -     return ret;
> > > -}
> > > -
> > > -static void *test_vcpu_migration(void *arg)
> > > -{
> > > -     unsigned int i, n_done;
> > > -     bool vcpu_done;
> > > -
> > > -     do {
> > > -             usleep(msecs_to_usecs(test_args.migration_freq_ms));
> > > -
> > > -             for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> > > -                     pthread_mutex_lock(&vcpu_done_map_lock);
> > > -                     vcpu_done = test_bit(i, vcpu_done_map);
> > > -                     pthread_mutex_unlock(&vcpu_done_map_lock);
> > > -
> > > -                     if (vcpu_done) {
> > > -                             n_done++;
> > > -                             continue;
> > > -                     }
> > > -
> > > -                     test_migrate_vcpu(i);
> > > -             }
> > > -     } while (test_args.nr_vcpus != n_done);
> > > -
> > > -     return NULL;
> > > -}
> > > -
> > > -static void test_run(struct kvm_vm *vm)
> > > -{
> > > -     pthread_t pt_vcpu_migration;
> > > -     unsigned int i;
> > > -     int ret;
> > > -
> > > -     pthread_mutex_init(&vcpu_done_map_lock, NULL);
> > > -     vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
> > > -     TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> > > -
> > > -     for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
> > > -             ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
> > > -                                  (void *)(unsigned long)i);
> > > -             TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> > > -     }
> > > -
> > > -     /* Spawn a thread to control the vCPU migrations */
> > > -     if (test_args.migration_freq_ms) {
> > > -             srand(time(NULL));
> > > -
> > > -             ret = pthread_create(&pt_vcpu_migration, NULL,
> > > -                                     test_vcpu_migration, NULL);
> > > -             TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> > > -     }
> > > -
> > > -
> > > -     for (i = 0; i < test_args.nr_vcpus; i++)
> > > -             pthread_join(pt_vcpu_run[i], NULL);
> > > -
> > > -     if (test_args.migration_freq_ms)
> > > -             pthread_join(pt_vcpu_migration, NULL);
> > > -
> > > -     bitmap_free(vcpu_done_map);
> > > -}
> > > -
> > >  static void test_init_timer_irq(struct kvm_vm *vm)
> > >  {
> > >       /* Timer initid should be same for all the vCPUs, so query only vCPU-0 */
> > > @@ -369,7 +172,7 @@ static void test_init_timer_irq(struct kvm_vm *vm)
> > >
> > >  static int gic_fd;
> > >
> > > -static struct kvm_vm *test_vm_create(void)
> > > +struct kvm_vm *test_vm_create(void)
> > >  {
> > >       struct kvm_vm *vm;
> > >       unsigned int i;
> > > @@ -400,81 +203,8 @@ static struct kvm_vm *test_vm_create(void)
> > >       return vm;
> > >  }
> > >
> > > -static void test_vm_cleanup(struct kvm_vm *vm)
> > > +void test_vm_cleanup(struct kvm_vm *vm)
> > >  {
> > >       close(gic_fd);
> > >       kvm_vm_free(vm);
> > >  }
> > > -
> > > -static void test_print_help(char *name)
> > > -{
> > > -     pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
> > > -             name);
> > > -     pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
> > > -             NR_VCPUS_DEF, KVM_MAX_VCPUS);
> > > -     pr_info("\t-i: Number of iterations per stage (default: %u)\n",
> > > -             NR_TEST_ITERS_DEF);
> > > -     pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> > > -             TIMER_TEST_PERIOD_MS_DEF);
> > > -     pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> > > -             TIMER_TEST_MIGRATION_FREQ_MS);
> > > -     pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> > > -     pr_info("\t-h: print this help screen\n");
> > > -}
> > > -
> > > -static bool parse_args(int argc, char *argv[])
> > > -{
> > > -     int opt;
> > > -
> > > -     while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
> > > -             switch (opt) {
> > > -             case 'n':
> > > -                     test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
> > > -                     if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
> > > -                             pr_info("Max allowed vCPUs: %u\n",
> > > -                                     KVM_MAX_VCPUS);
> > > -                             goto err;
> > > -                     }
> > > -                     break;
> > > -             case 'i':
> > > -                     test_args.nr_iter = atoi_positive("Number of iterations", optarg);
> > > -                     break;
> > > -             case 'p':
> > > -                     test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
> > > -                     break;
> > > -             case 'm':
> > > -                     test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
> > > -                     break;
> > > -             case 'o':
> > > -                     test_args.offset.counter_offset = strtol(optarg, NULL, 0);
> > > -                     test_args.offset.reserved = 0;
> > > -                     break;
> > > -             case 'h':
> > > -             default:
> > > -                     goto err;
> > > -             }
> > > -     }
> > > -
> > > -     return true;
> > > -
> > > -err:
> > > -     test_print_help(argv[0]);
> > > -     return false;
> > > -}
> > > -
> > > -int main(int argc, char *argv[])
> > > -{
> > > -     struct kvm_vm *vm;
> > > -
> > > -     if (!parse_args(argc, argv))
> > > -             exit(KSFT_SKIP);
> > > -
> > > -     __TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
> > > -                    "At least two physical CPUs needed for vCPU migration");
> > > -
> > > -     vm = test_vm_create();
> > > -     test_run(vm);
> > > -     test_vm_cleanup(vm);
> > > -
> > > -     return 0;
> > > -}
> > > diff --git a/tools/testing/selftests/kvm/arch_timer.c b/tools/testing/selftests/kvm/arch_timer.c
> > > new file mode 100644
> > > index 000000000000..529024f58c98
> > > --- /dev/null
> > > +++ b/tools/testing/selftests/kvm/arch_timer.c
> > > @@ -0,0 +1,252 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * arch_timer.c - Tests the arch timer IRQ functionality
> > > + *
> > > + * The guest's main thread configures the timer interrupt for and waits
> >
> > It looks like the text was edited to remove the 'stage' references, which
> > is fine by me, but the 'for' should have also been removed.
> >
> >
>
> Sure!
>
> > > + * for it to fire, with a timeout equal to the timer period.
> > > + * It asserts that the timeout doesn't exceed the timer period.
> > > + *
> > > + * On the other hand, upon receipt of an interrupt, the guest's interrupt
> > > + * handler validates the interrupt by checking if the architectural state
> > > + * is in compliance with the specifications.
> > > + *
> > > + * The test provides command-line options to configure the timer's
> > > + * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> > > + * To stress-test the timer stack even more, an option to migrate the
> > > + * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> > > + *
> > > + * Copyright (c) 2021, Google LLC.
> > > + */
> > > +
> > > +#define _GNU_SOURCE
> > > +
> > > +#include <stdlib.h>
> > > +#include <pthread.h>
> > > +#include <linux/sizes.h>
> > > +#include <linux/bitmap.h>
> > > +#include <sys/sysinfo.h>
> > > +
> > > +#include "timer_test.h"
> > > +
> > > +struct test_args test_args = {
> > > +    .nr_vcpus = NR_VCPUS_DEF,
> > > +    .nr_iter = NR_TEST_ITERS_DEF,
> > > +    .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> > > +    .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> > > +#ifdef __aarch64__
> > > +    .offset = { .reserved = 1 },
> > > +#endif
> >
> > Please run checkpatch, there are spaces instead of tabs in the struct.
> >
>
> Yes, the tabs were changed to spaces while copying. Will change it and
> run checkpatch to catch this kind of error in next version.
>
> > > +};
> > > +
> > > +struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> > > +struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> > > +
> > > +static pthread_t pt_vcpu_run[KVM_MAX_VCPUS];
> > > +static unsigned long *vcpu_done_map;
> > > +static pthread_mutex_t vcpu_done_map_lock;
> > > +
> > > +static void *test_vcpu_run(void *arg)
> > > +{
> > > +     unsigned int vcpu_idx = (unsigned long)arg;
> > > +     struct ucall uc;
> > > +     struct kvm_vcpu *vcpu = vcpus[vcpu_idx];
> > > +     struct kvm_vm *vm = vcpu->vm;
> > > +     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[vcpu_idx];
> > > +
> > > +     vcpu_run(vcpu);
> > > +
> > > +     /* Currently, any exit from guest is an indication of completion */
> > > +     pthread_mutex_lock(&vcpu_done_map_lock);
> > > +     __set_bit(vcpu_idx, vcpu_done_map);
> > > +     pthread_mutex_unlock(&vcpu_done_map_lock);
> > > +
> > > +     switch (get_ucall(vcpu, &uc)) {
> > > +     case UCALL_SYNC:
> > > +     case UCALL_DONE:
> > > +             break;
> > > +     case UCALL_ABORT:
> > > +             sync_global_from_guest(vm, *shared_data);
> > > +             fprintf(stderr, "Guest assert failed,  vcpu %u; stage; %u; iter: %u\n",
> > > +                     vcpu_idx, shared_data->guest_stage, shared_data->nr_iter);
> > > +             REPORT_GUEST_ASSERT(uc);
> > > +             break;
> > > +     default:
> > > +             TEST_FAIL("Unexpected guest exit\n");
> > > +     }
> > > +
> > > +     pr_info("PASS(vCPU-%d).\n", vcpu_idx);
> >
> > This is new. I can live with it, but generally we don't want to modify
> > functions while moving them.
> >
>
> Yes, this change was supposed to go with patch 8/8.
>
> > > +
> > > +     return NULL;
> > > +}
> > > +
> > > +static uint32_t test_get_pcpu(void)
> > > +{
> > > +     uint32_t pcpu;
> > > +     unsigned int nproc_conf;
> > > +     cpu_set_t online_cpuset;
> > > +
> > > +     nproc_conf = get_nprocs_conf();
> > > +     sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> > > +
> > > +     /* Randomly find an available pCPU to place a vCPU on */
> > > +     do {
> > > +             pcpu = rand() % nproc_conf;
> > > +     } while (!CPU_ISSET(pcpu, &online_cpuset));
> > > +
> > > +     return pcpu;
> > > +}
> > > +
> > > +static int test_migrate_vcpu(unsigned int vcpu_idx)
> > > +{
> > > +     int ret;
> > > +     cpu_set_t cpuset;
> > > +     uint32_t new_pcpu = test_get_pcpu();
> > > +
> > > +     CPU_ZERO(&cpuset);
> > > +     CPU_SET(new_pcpu, &cpuset);
> > > +
> > > +     pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu_idx, new_pcpu);
> > > +
> > > +     ret = pthread_setaffinity_np(pt_vcpu_run[vcpu_idx],
> > > +                                  sizeof(cpuset), &cpuset);
> > > +
> > > +     /* Allow the error where the vCPU thread is already finished */
> > > +     TEST_ASSERT(ret == 0 || ret == ESRCH,
> > > +                 "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> > > +                 vcpu_idx, new_pcpu, ret);
> > > +
> > > +     return ret;
> > > +}
> > > +
> > > +static void *test_vcpu_migration(void *arg)
> > > +{
> > > +     unsigned int i, n_done;
> > > +     bool vcpu_done;
> > > +
> > > +     do {
> > > +             usleep(msecs_to_usecs(test_args.migration_freq_ms));
> > > +
> > > +             for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> > > +                     pthread_mutex_lock(&vcpu_done_map_lock);
> > > +                     vcpu_done = test_bit(i, vcpu_done_map);
> > > +                     pthread_mutex_unlock(&vcpu_done_map_lock);
> > > +
> > > +                     if (vcpu_done) {
> > > +                             n_done++;
> > > +                             continue;
> > > +                     }
> > > +
> > > +                     test_migrate_vcpu(i);
> > > +             }
> > > +     } while (test_args.nr_vcpus != n_done);
> > > +
> > > +     return NULL;
> > > +}
> > > +
> > > +static void test_run(struct kvm_vm *vm)
> > > +{
> > > +     pthread_t pt_vcpu_migration;
> > > +     unsigned int i;
> > > +     int ret;
> > > +
> > > +     pthread_mutex_init(&vcpu_done_map_lock, NULL);
> > > +     vcpu_done_map = bitmap_zalloc(test_args.nr_vcpus);
> > > +     TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> > > +
> > > +     for (i = 0; i < (unsigned long)test_args.nr_vcpus; i++) {
> > > +             ret = pthread_create(&pt_vcpu_run[i], NULL, test_vcpu_run,
> > > +                                  (void *)(unsigned long)i);
> > > +             TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> > > +     }
> > > +
> > > +     /* Spawn a thread to control the vCPU migrations */
> > > +     if (test_args.migration_freq_ms) {
> > > +             srand(time(NULL));
> > > +
> > > +             ret = pthread_create(&pt_vcpu_migration, NULL,
> > > +                                     test_vcpu_migration, NULL);
> > > +             TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> > > +     }
> > > +
> > > +
> > > +     for (i = 0; i < test_args.nr_vcpus; i++)
> > > +             pthread_join(pt_vcpu_run[i], NULL);
> > > +
> > > +     if (test_args.migration_freq_ms)
> > > +             pthread_join(pt_vcpu_migration, NULL);
> > > +
> > > +     bitmap_free(vcpu_done_map);
> > > +}
> > > +
> > > +static void test_print_help(char *name)
> > > +{
> > > +     pr_info("Usage: %s [-h] [-n nr_vcpus] [-i iterations] [-p timer_period_ms]\n",
> > > +             name);
> > > +     pr_info("\t-n: Number of vCPUs to configure (default: %u; max: %u)\n",
> > > +             NR_VCPUS_DEF, KVM_MAX_VCPUS);
> > > +     pr_info("\t-i: Number of iterations per stage (default: %u)\n",
> > > +             NR_TEST_ITERS_DEF);
> > > +     pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> > > +             TIMER_TEST_PERIOD_MS_DEF);
> > > +     pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> > > +             TIMER_TEST_MIGRATION_FREQ_MS);
> > > +     pr_info("\t-o: Counter offset (in counter cycles, default: 0)\n");
> > > +     pr_info("\t-h: print this help screen\n");
> > > +}
> > > +
> > > +static bool parse_args(int argc, char *argv[])
> > > +{
> > > +     int opt;
> > > +
> > > +     while ((opt = getopt(argc, argv, "hn:i:p:m:o:")) != -1) {
> > > +             switch (opt) {
> > > +             case 'n':
> > > +                     test_args.nr_vcpus = atoi_positive("Number of vCPUs", optarg);
> > > +                     if (test_args.nr_vcpus > KVM_MAX_VCPUS) {
> > > +                             pr_info("Max allowed vCPUs: %u\n",
> > > +                                     KVM_MAX_VCPUS);
> > > +                             goto err;
> > > +                     }
> > > +                     break;
> > > +             case 'i':
> > > +                     test_args.nr_iter = atoi_positive("Number of iterations", optarg);
> > > +                     break;
> > > +             case 'p':
> > > +                     test_args.timer_period_ms = atoi_positive("Periodicity", optarg);
> > > +                     break;
> > > +             case 'm':
> > > +                     test_args.migration_freq_ms = atoi_non_negative("Frequency", optarg);
> > > +                     break;
> > > +             case 'o':
> > > +                     test_args.offset.counter_offset = strtol(optarg, NULL, 0);
> > > +                     test_args.offset.reserved = 0;
> > > +                     break;
> > > +             case 'h':
> > > +             default:
> > > +                     goto err;
> > > +             }
> > > +     }
> > > +
> > > +     return true;
> > > +
> > > +err:
> > > +     test_print_help(argv[0]);
> > > +     return false;
> > > +}
> > > +
> > > +int main(int argc, char *argv[])
> > > +{
> > > +     struct kvm_vm *vm;
> > > +
> > > +     if (!parse_args(argc, argv))
> > > +             exit(KSFT_SKIP);
> > > +
> > > +     __TEST_REQUIRE(!test_args.migration_freq_ms || get_nprocs() >= 2,
> > > +                    "At least two physical CPUs needed for vCPU migration");
> > > +
> > > +     vm = test_vm_create();
> > > +     test_run(vm);
> > > +     test_vm_cleanup(vm);
> > > +
> > > +     return 0;
> > > +}
> > > diff --git a/tools/testing/selftests/kvm/include/timer_test.h b/tools/testing/selftests/kvm/include/timer_test.h
> > > new file mode 100644
> > > index 000000000000..109e4d635627
> > > --- /dev/null
> > > +++ b/tools/testing/selftests/kvm/include/timer_test.h
> > > @@ -0,0 +1,52 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +/*
> > > + * tools/testing/selftests/kvm/include/timer_test.h
> > > + *
> > > + * Copyright (C) 2018, Google LLC
> > > + */
> > > +
> > > +#ifndef SELFTEST_KVM_TIMER_TEST_H
> > > +#define SELFTEST_KVM_TIMER_TEST_H
> > > +
> > > +#include "kvm_util.h"
> > > +
> > > +#define NR_VCPUS_DEF            4
> > > +#define NR_TEST_ITERS_DEF       5
> > > +#define TIMER_TEST_PERIOD_MS_DEF    10
> > > +#define TIMER_TEST_ERR_MARGIN_US    100
> > > +#define TIMER_TEST_MIGRATION_FREQ_MS    2
> > > +
> > > +#define msecs_to_usecs(msec)    ((msec) * 1000LL)
> >
> > I'd move the above to include/test_util.h
> >
>
> Yes, msecs_to_usecs() macro should be a common API for all the tests.
>
> > > +
> > > +#define GICD_BASE_GPA    0x8000000ULL
> > > +#define GICR_BASE_GPA    0x80A0000ULL
> >
> > These defines belong in aarch64/arch_timer.c
> >
>
> These 2 defines were also defined in other test cases, shall we move them
> to an aarch64 specific header file? Maybe
> tools/testing/selftests/kvm/include/aarch64/gic.h?
>
> > > +
> > > +enum guest_stage {
> > > +     GUEST_STAGE_VTIMER_CVAL=1,
> > > +     GUEST_STAGE_VTIMER_TVAL,
> > > +     GUEST_STAGE_PTIMER_CVAL,
> > > +     GUEST_STAGE_PTIMER_TVAL,
> > > +     GUEST_STAGE_MAX,
> > > +};
> >
> > This enum also belongs in aarch64/arch_timer.c
> >
>
> Yes, it should be in aarch64/arch_timer.c
>

After moving the above enum definition to aarch64/arch_timer.c, the
below errors was reported
while compiling kvm/arch_timer.o

include/timer_test.h:37:26: error: field ‘guest_stage’ has incomplete type
   37 |         enum guest_stage guest_stage;
        |                                        ^~~~~~~~~~~

Since kvm/arch_timer.c was independent of kvm/aarch64/arch_timer.c
during OBJ compiling,
I think it may be not possible to move the enum definition to
aarch64/arch_timer.c

If we keep the definition in this header file, we can enclose it with
#ifdef __aarch64__ for aarch64 only.

> > > +
> > > +/* Timer test cmdline parameters */
> > > +struct test_args
> > > +{
> > > +     int nr_vcpus;
> > > +     int nr_iter;
> > > +     int timer_period_ms;
> > > +     int migration_freq_ms;
> > > +     struct kvm_arm_counter_offset offset;
> > > +};
> > > +
> > > +/* Shared variables between host and guest */
> > > +struct test_vcpu_shared_data {
> > > +     int nr_iter;
> > > +     enum guest_stage guest_stage;
> > > +     uint64_t xcnt;
> > > +};
> > > +
> > > +struct kvm_vm* test_vm_create(void);
> >
> > Move * next to function name.
> >
>
> Sure, thanks!
>
> > > +void test_vm_cleanup(struct kvm_vm *vm);
> > > +
> > > +#endif /* SELFTEST_KVM_TIMER_TEST_H */
> > > --
> > > 2.34.1
> > >
> >
> > Thanks,
> > drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-04 13:33   ` Andrew Jones
@ 2023-09-06  6:35     ` Haibo Xu
  2023-09-06  7:13       ` Andrew Jones
  0 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  6:35 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vipin Sharma, Aaron Lewis,
	David Matlack, Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang,
	Lei Wang, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Mon, Sep 4, 2023 at 9:33 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Sat, Sep 02, 2023 at 08:59:25PM +0800, Haibo Xu wrote:
> > Borrow the csr definitions and operations from kernel's
> > arch/riscv/include/asm/csr.h to tools/ for riscv.
> >
> > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > ---
> >  tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
> >  1 file changed, 521 insertions(+)
> >  create mode 100644 tools/arch/riscv/include/asm/csr.h
> >
> > diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h
> > new file mode 100644
> > index 000000000000..4e86c82aacbd
> > --- /dev/null
> > +++ b/tools/arch/riscv/include/asm/csr.h
> > @@ -0,0 +1,521 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2015 Regents of the University of California
> > + */
> > +
> > +#ifndef _ASM_RISCV_CSR_H
> > +#define _ASM_RISCV_CSR_H
> > +
> > +#include <linux/bits.h>
> > +
> > +/* Status register flags */
> > +#define SR_SIE               _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
> > +#define SR_MIE               _AC(0x00000008, UL) /* Machine Interrupt Enable */
> > +#define SR_SPIE              _AC(0x00000020, UL) /* Previous Supervisor IE */
> > +#define SR_MPIE              _AC(0x00000080, UL) /* Previous Machine IE */
> > +#define SR_SPP               _AC(0x00000100, UL) /* Previously Supervisor */
> > +#define SR_MPP               _AC(0x00001800, UL) /* Previously Machine */
> > +#define SR_SUM               _AC(0x00040000, UL) /* Supervisor User Memory Access */
> > +
> > +#define SR_FS                _AC(0x00006000, UL) /* Floating-point Status */
> > +#define SR_FS_OFF    _AC(0x00000000, UL)
> > +#define SR_FS_INITIAL        _AC(0x00002000, UL)
> > +#define SR_FS_CLEAN  _AC(0x00004000, UL)
> > +#define SR_FS_DIRTY  _AC(0x00006000, UL)
> > +
> > +#define SR_VS                _AC(0x00000600, UL) /* Vector Status */
> > +#define SR_VS_OFF    _AC(0x00000000, UL)
> > +#define SR_VS_INITIAL        _AC(0x00000200, UL)
> > +#define SR_VS_CLEAN  _AC(0x00000400, UL)
> > +#define SR_VS_DIRTY  _AC(0x00000600, UL)
> > +
> > +#define SR_XS                _AC(0x00018000, UL) /* Extension Status */
> > +#define SR_XS_OFF    _AC(0x00000000, UL)
> > +#define SR_XS_INITIAL        _AC(0x00008000, UL)
> > +#define SR_XS_CLEAN  _AC(0x00010000, UL)
> > +#define SR_XS_DIRTY  _AC(0x00018000, UL)
> > +
> > +#define SR_FS_VS     (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
> > +
> > +#ifndef CONFIG_64BIT
>
> How do we ensure CONFIG_64BIT is set?
>

Currently, no explicit checking for this.
Shall we add a gatekeeper in this file to ensure it is set?

#ifndef CONFIG_64BIT
#error "CONFIG_64BIT was not set"
#endif

> Thanks,
> drew
>
> > +#define SR_SD                _AC(0x80000000, UL) /* FS/VS/XS dirty */
> > +#else
> > +#define SR_SD                _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
> > +#endif
> > +
> > +#ifdef CONFIG_64BIT
> > +#define SR_UXL               _AC(0x300000000, UL) /* XLEN mask for U-mode */
> > +#define SR_UXL_32    _AC(0x100000000, UL) /* XLEN = 32 for U-mode */
> > +#define SR_UXL_64    _AC(0x200000000, UL) /* XLEN = 64 for U-mode */
> > +#endif
> > +
> > +/* SATP flags */
> > +#ifndef CONFIG_64BIT
> > +#define SATP_PPN     _AC(0x003FFFFF, UL)
> > +#define SATP_MODE_32 _AC(0x80000000, UL)
> > +#define SATP_ASID_BITS       9
> > +#define SATP_ASID_SHIFT      22
> > +#define SATP_ASID_MASK       _AC(0x1FF, UL)
> > +#else
> > +#define SATP_PPN     _AC(0x00000FFFFFFFFFFF, UL)
> > +#define SATP_MODE_39 _AC(0x8000000000000000, UL)
> > +#define SATP_MODE_48 _AC(0x9000000000000000, UL)
> > +#define SATP_MODE_57 _AC(0xa000000000000000, UL)
> > +#define SATP_ASID_BITS       16
> > +#define SATP_ASID_SHIFT      44
> > +#define SATP_ASID_MASK       _AC(0xFFFF, UL)
> > +#endif
> > +
> > +/* Exception cause high bit - is an interrupt if set */
> > +#define CAUSE_IRQ_FLAG               (_AC(1, UL) << (__riscv_xlen - 1))
> > +
> > +/* Interrupt causes (minus the high bit) */
> > +#define IRQ_S_SOFT           1
> > +#define IRQ_VS_SOFT          2
> > +#define IRQ_M_SOFT           3
> > +#define IRQ_S_TIMER          5
> > +#define IRQ_VS_TIMER         6
> > +#define IRQ_M_TIMER          7
> > +#define IRQ_S_EXT            9
> > +#define IRQ_VS_EXT           10
> > +#define IRQ_M_EXT            11
> > +#define IRQ_S_GEXT           12
> > +#define IRQ_PMU_OVF          13
> > +#define IRQ_LOCAL_MAX                (IRQ_PMU_OVF + 1)
> > +#define IRQ_LOCAL_MASK               GENMASK((IRQ_LOCAL_MAX - 1), 0)
> > +
> > +/* Exception causes */
> > +#define EXC_INST_MISALIGNED  0
> > +#define EXC_INST_ACCESS              1
> > +#define EXC_INST_ILLEGAL     2
> > +#define EXC_BREAKPOINT               3
> > +#define EXC_LOAD_MISALIGNED  4
> > +#define EXC_LOAD_ACCESS              5
> > +#define EXC_STORE_MISALIGNED 6
> > +#define EXC_STORE_ACCESS     7
> > +#define EXC_SYSCALL          8
> > +#define EXC_HYPERVISOR_SYSCALL       9
> > +#define EXC_SUPERVISOR_SYSCALL       10
> > +#define EXC_INST_PAGE_FAULT  12
> > +#define EXC_LOAD_PAGE_FAULT  13
> > +#define EXC_STORE_PAGE_FAULT 15
> > +#define EXC_INST_GUEST_PAGE_FAULT    20
> > +#define EXC_LOAD_GUEST_PAGE_FAULT    21
> > +#define EXC_VIRTUAL_INST_FAULT               22
> > +#define EXC_STORE_GUEST_PAGE_FAULT   23
> > +
> > +/* PMP configuration */
> > +#define PMP_R                        0x01
> > +#define PMP_W                        0x02
> > +#define PMP_X                        0x04
> > +#define PMP_A                        0x18
> > +#define PMP_A_TOR            0x08
> > +#define PMP_A_NA4            0x10
> > +#define PMP_A_NAPOT          0x18
> > +#define PMP_L                        0x80
> > +
> > +/* HSTATUS flags */
> > +#ifdef CONFIG_64BIT
> > +#define HSTATUS_VSXL         _AC(0x300000000, UL)
> > +#define HSTATUS_VSXL_SHIFT   32
> > +#endif
> > +#define HSTATUS_VTSR         _AC(0x00400000, UL)
> > +#define HSTATUS_VTW          _AC(0x00200000, UL)
> > +#define HSTATUS_VTVM         _AC(0x00100000, UL)
> > +#define HSTATUS_VGEIN                _AC(0x0003f000, UL)
> > +#define HSTATUS_VGEIN_SHIFT  12
> > +#define HSTATUS_HU           _AC(0x00000200, UL)
> > +#define HSTATUS_SPVP         _AC(0x00000100, UL)
> > +#define HSTATUS_SPV          _AC(0x00000080, UL)
> > +#define HSTATUS_GVA          _AC(0x00000040, UL)
> > +#define HSTATUS_VSBE         _AC(0x00000020, UL)
> > +
> > +/* HGATP flags */
> > +#define HGATP_MODE_OFF               _AC(0, UL)
> > +#define HGATP_MODE_SV32X4    _AC(1, UL)
> > +#define HGATP_MODE_SV39X4    _AC(8, UL)
> > +#define HGATP_MODE_SV48X4    _AC(9, UL)
> > +#define HGATP_MODE_SV57X4    _AC(10, UL)
> > +
> > +#define HGATP32_MODE_SHIFT   31
> > +#define HGATP32_VMID_SHIFT   22
> > +#define HGATP32_VMID         GENMASK(28, 22)
> > +#define HGATP32_PPN          GENMASK(21, 0)
> > +
> > +#define HGATP64_MODE_SHIFT   60
> > +#define HGATP64_VMID_SHIFT   44
> > +#define HGATP64_VMID         GENMASK(57, 44)
> > +#define HGATP64_PPN          GENMASK(43, 0)
> > +
> > +#define HGATP_PAGE_SHIFT     12
> > +
> > +#ifdef CONFIG_64BIT
> > +#define HGATP_PPN            HGATP64_PPN
> > +#define HGATP_VMID_SHIFT     HGATP64_VMID_SHIFT
> > +#define HGATP_VMID           HGATP64_VMID
> > +#define HGATP_MODE_SHIFT     HGATP64_MODE_SHIFT
> > +#else
> > +#define HGATP_PPN            HGATP32_PPN
> > +#define HGATP_VMID_SHIFT     HGATP32_VMID_SHIFT
> > +#define HGATP_VMID           HGATP32_VMID
> > +#define HGATP_MODE_SHIFT     HGATP32_MODE_SHIFT
> > +#endif
> > +
> > +/* VSIP & HVIP relation */
> > +#define VSIP_TO_HVIP_SHIFT   (IRQ_VS_SOFT - IRQ_S_SOFT)
> > +#define VSIP_VALID_MASK              ((_AC(1, UL) << IRQ_S_SOFT) | \
> > +                              (_AC(1, UL) << IRQ_S_TIMER) | \
> > +                              (_AC(1, UL) << IRQ_S_EXT))
> > +
> > +/* AIA CSR bits */
> > +#define TOPI_IID_SHIFT               16
> > +#define TOPI_IID_MASK                GENMASK(11, 0)
> > +#define TOPI_IPRIO_MASK              GENMASK(7, 0)
> > +#define TOPI_IPRIO_BITS              8
> > +
> > +#define TOPEI_ID_SHIFT               16
> > +#define TOPEI_ID_MASK                GENMASK(10, 0)
> > +#define TOPEI_PRIO_MASK              GENMASK(10, 0)
> > +
> > +#define ISELECT_IPRIO0               0x30
> > +#define ISELECT_IPRIO15              0x3f
> > +#define ISELECT_MASK         GENMASK(8, 0)
> > +
> > +#define HVICTL_VTI           BIT(30)
> > +#define HVICTL_IID           GENMASK(27, 16)
> > +#define HVICTL_IID_SHIFT     16
> > +#define HVICTL_DPR           BIT(9)
> > +#define HVICTL_IPRIOM                BIT(8)
> > +#define HVICTL_IPRIO         GENMASK(7, 0)
> > +
> > +/* xENVCFG flags */
> > +#define ENVCFG_STCE                  (_AC(1, ULL) << 63)
> > +#define ENVCFG_PBMTE                 (_AC(1, ULL) << 62)
> > +#define ENVCFG_CBZE                  (_AC(1, UL) << 7)
> > +#define ENVCFG_CBCFE                 (_AC(1, UL) << 6)
> > +#define ENVCFG_CBIE_SHIFT            4
> > +#define ENVCFG_CBIE                  (_AC(0x3, UL) << ENVCFG_CBIE_SHIFT)
> > +#define ENVCFG_CBIE_ILL                      _AC(0x0, UL)
> > +#define ENVCFG_CBIE_FLUSH            _AC(0x1, UL)
> > +#define ENVCFG_CBIE_INV                      _AC(0x3, UL)
> > +#define ENVCFG_FIOM                  _AC(0x1, UL)
> > +
> > +/* symbolic CSR names: */
> > +#define CSR_CYCLE            0xc00
> > +#define CSR_TIME             0xc01
> > +#define CSR_INSTRET          0xc02
> > +#define CSR_HPMCOUNTER3              0xc03
> > +#define CSR_HPMCOUNTER4              0xc04
> > +#define CSR_HPMCOUNTER5              0xc05
> > +#define CSR_HPMCOUNTER6              0xc06
> > +#define CSR_HPMCOUNTER7              0xc07
> > +#define CSR_HPMCOUNTER8              0xc08
> > +#define CSR_HPMCOUNTER9              0xc09
> > +#define CSR_HPMCOUNTER10     0xc0a
> > +#define CSR_HPMCOUNTER11     0xc0b
> > +#define CSR_HPMCOUNTER12     0xc0c
> > +#define CSR_HPMCOUNTER13     0xc0d
> > +#define CSR_HPMCOUNTER14     0xc0e
> > +#define CSR_HPMCOUNTER15     0xc0f
> > +#define CSR_HPMCOUNTER16     0xc10
> > +#define CSR_HPMCOUNTER17     0xc11
> > +#define CSR_HPMCOUNTER18     0xc12
> > +#define CSR_HPMCOUNTER19     0xc13
> > +#define CSR_HPMCOUNTER20     0xc14
> > +#define CSR_HPMCOUNTER21     0xc15
> > +#define CSR_HPMCOUNTER22     0xc16
> > +#define CSR_HPMCOUNTER23     0xc17
> > +#define CSR_HPMCOUNTER24     0xc18
> > +#define CSR_HPMCOUNTER25     0xc19
> > +#define CSR_HPMCOUNTER26     0xc1a
> > +#define CSR_HPMCOUNTER27     0xc1b
> > +#define CSR_HPMCOUNTER28     0xc1c
> > +#define CSR_HPMCOUNTER29     0xc1d
> > +#define CSR_HPMCOUNTER30     0xc1e
> > +#define CSR_HPMCOUNTER31     0xc1f
> > +#define CSR_CYCLEH           0xc80
> > +#define CSR_TIMEH            0xc81
> > +#define CSR_INSTRETH         0xc82
> > +#define CSR_HPMCOUNTER3H     0xc83
> > +#define CSR_HPMCOUNTER4H     0xc84
> > +#define CSR_HPMCOUNTER5H     0xc85
> > +#define CSR_HPMCOUNTER6H     0xc86
> > +#define CSR_HPMCOUNTER7H     0xc87
> > +#define CSR_HPMCOUNTER8H     0xc88
> > +#define CSR_HPMCOUNTER9H     0xc89
> > +#define CSR_HPMCOUNTER10H    0xc8a
> > +#define CSR_HPMCOUNTER11H    0xc8b
> > +#define CSR_HPMCOUNTER12H    0xc8c
> > +#define CSR_HPMCOUNTER13H    0xc8d
> > +#define CSR_HPMCOUNTER14H    0xc8e
> > +#define CSR_HPMCOUNTER15H    0xc8f
> > +#define CSR_HPMCOUNTER16H    0xc90
> > +#define CSR_HPMCOUNTER17H    0xc91
> > +#define CSR_HPMCOUNTER18H    0xc92
> > +#define CSR_HPMCOUNTER19H    0xc93
> > +#define CSR_HPMCOUNTER20H    0xc94
> > +#define CSR_HPMCOUNTER21H    0xc95
> > +#define CSR_HPMCOUNTER22H    0xc96
> > +#define CSR_HPMCOUNTER23H    0xc97
> > +#define CSR_HPMCOUNTER24H    0xc98
> > +#define CSR_HPMCOUNTER25H    0xc99
> > +#define CSR_HPMCOUNTER26H    0xc9a
> > +#define CSR_HPMCOUNTER27H    0xc9b
> > +#define CSR_HPMCOUNTER28H    0xc9c
> > +#define CSR_HPMCOUNTER29H    0xc9d
> > +#define CSR_HPMCOUNTER30H    0xc9e
> > +#define CSR_HPMCOUNTER31H    0xc9f
> > +
> > +#define CSR_SSCOUNTOVF               0xda0
> > +
> > +#define CSR_SSTATUS          0x100
> > +#define CSR_SIE                      0x104
> > +#define CSR_STVEC            0x105
> > +#define CSR_SCOUNTEREN               0x106
> > +#define CSR_SSCRATCH         0x140
> > +#define CSR_SEPC             0x141
> > +#define CSR_SCAUSE           0x142
> > +#define CSR_STVAL            0x143
> > +#define CSR_SIP                      0x144
> > +#define CSR_SATP             0x180
> > +
> > +#define CSR_STIMECMP         0x14D
> > +#define CSR_STIMECMPH                0x15D
> > +
> > +/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
> > +#define CSR_SISELECT         0x150
> > +#define CSR_SIREG            0x151
> > +
> > +/* Supervisor-Level Interrupts (AIA) */
> > +#define CSR_STOPEI           0x15c
> > +#define CSR_STOPI            0xdb0
> > +
> > +/* Supervisor-Level High-Half CSRs (AIA) */
> > +#define CSR_SIEH             0x114
> > +#define CSR_SIPH             0x154
> > +
> > +#define CSR_VSSTATUS         0x200
> > +#define CSR_VSIE             0x204
> > +#define CSR_VSTVEC           0x205
> > +#define CSR_VSSCRATCH                0x240
> > +#define CSR_VSEPC            0x241
> > +#define CSR_VSCAUSE          0x242
> > +#define CSR_VSTVAL           0x243
> > +#define CSR_VSIP             0x244
> > +#define CSR_VSATP            0x280
> > +#define CSR_VSTIMECMP                0x24D
> > +#define CSR_VSTIMECMPH               0x25D
> > +
> > +#define CSR_HSTATUS          0x600
> > +#define CSR_HEDELEG          0x602
> > +#define CSR_HIDELEG          0x603
> > +#define CSR_HIE                      0x604
> > +#define CSR_HTIMEDELTA               0x605
> > +#define CSR_HCOUNTEREN               0x606
> > +#define CSR_HGEIE            0x607
> > +#define CSR_HENVCFG          0x60a
> > +#define CSR_HTIMEDELTAH              0x615
> > +#define CSR_HENVCFGH         0x61a
> > +#define CSR_HTVAL            0x643
> > +#define CSR_HIP                      0x644
> > +#define CSR_HVIP             0x645
> > +#define CSR_HTINST           0x64a
> > +#define CSR_HGATP            0x680
> > +#define CSR_HGEIP            0xe12
> > +
> > +/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
> > +#define CSR_HVIEN            0x608
> > +#define CSR_HVICTL           0x609
> > +#define CSR_HVIPRIO1         0x646
> > +#define CSR_HVIPRIO2         0x647
> > +
> > +/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
> > +#define CSR_VSISELECT                0x250
> > +#define CSR_VSIREG           0x251
> > +
> > +/* VS-Level Interrupts (H-extension with AIA) */
> > +#define CSR_VSTOPEI          0x25c
> > +#define CSR_VSTOPI           0xeb0
> > +
> > +/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
> > +#define CSR_HIDELEGH         0x613
> > +#define CSR_HVIENH           0x618
> > +#define CSR_HVIPH            0x655
> > +#define CSR_HVIPRIO1H                0x656
> > +#define CSR_HVIPRIO2H                0x657
> > +#define CSR_VSIEH            0x214
> > +#define CSR_VSIPH            0x254
> > +
> > +#define CSR_MSTATUS          0x300
> > +#define CSR_MISA             0x301
> > +#define CSR_MIDELEG          0x303
> > +#define CSR_MIE                      0x304
> > +#define CSR_MTVEC            0x305
> > +#define CSR_MENVCFG          0x30a
> > +#define CSR_MENVCFGH         0x31a
> > +#define CSR_MSCRATCH         0x340
> > +#define CSR_MEPC             0x341
> > +#define CSR_MCAUSE           0x342
> > +#define CSR_MTVAL            0x343
> > +#define CSR_MIP                      0x344
> > +#define CSR_PMPCFG0          0x3a0
> > +#define CSR_PMPADDR0         0x3b0
> > +#define CSR_MVENDORID                0xf11
> > +#define CSR_MARCHID          0xf12
> > +#define CSR_MIMPID           0xf13
> > +#define CSR_MHARTID          0xf14
> > +
> > +/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
> > +#define CSR_MISELECT         0x350
> > +#define CSR_MIREG            0x351
> > +
> > +/* Machine-Level Interrupts (AIA) */
> > +#define CSR_MTOPEI           0x35c
> > +#define CSR_MTOPI            0xfb0
> > +
> > +/* Virtual Interrupts for Supervisor Level (AIA) */
> > +#define CSR_MVIEN            0x308
> > +#define CSR_MVIP             0x309
> > +
> > +/* Machine-Level High-Half CSRs (AIA) */
> > +#define CSR_MIDELEGH         0x313
> > +#define CSR_MIEH             0x314
> > +#define CSR_MVIENH           0x318
> > +#define CSR_MVIPH            0x319
> > +#define CSR_MIPH             0x354
> > +
> > +#define CSR_VSTART           0x8
> > +#define CSR_VCSR             0xf
> > +#define CSR_VL                       0xc20
> > +#define CSR_VTYPE            0xc21
> > +#define CSR_VLENB            0xc22
> > +
> > +#ifdef CONFIG_RISCV_M_MODE
> > +# define CSR_STATUS  CSR_MSTATUS
> > +# define CSR_IE              CSR_MIE
> > +# define CSR_TVEC    CSR_MTVEC
> > +# define CSR_SCRATCH CSR_MSCRATCH
> > +# define CSR_EPC     CSR_MEPC
> > +# define CSR_CAUSE   CSR_MCAUSE
> > +# define CSR_TVAL    CSR_MTVAL
> > +# define CSR_IP              CSR_MIP
> > +
> > +# define CSR_IEH             CSR_MIEH
> > +# define CSR_ISELECT CSR_MISELECT
> > +# define CSR_IREG    CSR_MIREG
> > +# define CSR_IPH             CSR_MIPH
> > +# define CSR_TOPEI   CSR_MTOPEI
> > +# define CSR_TOPI    CSR_MTOPI
> > +
> > +# define SR_IE               SR_MIE
> > +# define SR_PIE              SR_MPIE
> > +# define SR_PP               SR_MPP
> > +
> > +# define RV_IRQ_SOFT         IRQ_M_SOFT
> > +# define RV_IRQ_TIMER        IRQ_M_TIMER
> > +# define RV_IRQ_EXT          IRQ_M_EXT
> > +#else /* CONFIG_RISCV_M_MODE */
> > +# define CSR_STATUS  CSR_SSTATUS
> > +# define CSR_IE              CSR_SIE
> > +# define CSR_TVEC    CSR_STVEC
> > +# define CSR_SCRATCH CSR_SSCRATCH
> > +# define CSR_EPC     CSR_SEPC
> > +# define CSR_CAUSE   CSR_SCAUSE
> > +# define CSR_TVAL    CSR_STVAL
> > +# define CSR_IP              CSR_SIP
> > +
> > +# define CSR_IEH             CSR_SIEH
> > +# define CSR_ISELECT CSR_SISELECT
> > +# define CSR_IREG    CSR_SIREG
> > +# define CSR_IPH             CSR_SIPH
> > +# define CSR_TOPEI   CSR_STOPEI
> > +# define CSR_TOPI    CSR_STOPI
> > +
> > +# define SR_IE               SR_SIE
> > +# define SR_PIE              SR_SPIE
> > +# define SR_PP               SR_SPP
> > +
> > +# define RV_IRQ_SOFT         IRQ_S_SOFT
> > +# define RV_IRQ_TIMER        IRQ_S_TIMER
> > +# define RV_IRQ_EXT          IRQ_S_EXT
> > +# define RV_IRQ_PMU  IRQ_PMU_OVF
> > +# define SIP_LCOFIP     (_AC(0x1, UL) << IRQ_PMU_OVF)
> > +
> > +#endif /* !CONFIG_RISCV_M_MODE */
> > +
> > +/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
> > +#define IE_SIE               (_AC(0x1, UL) << RV_IRQ_SOFT)
> > +#define IE_TIE               (_AC(0x1, UL) << RV_IRQ_TIMER)
> > +#define IE_EIE               (_AC(0x1, UL) << RV_IRQ_EXT)
> > +
> > +#ifdef __ASSEMBLY__
> > +#define __ASM_STR(x)    x
> > +#else
> > +#define __ASM_STR(x)    #x
> > +#endif
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +#define csr_swap(csr, val)                                   \
> > +({                                                           \
> > +     unsigned long __v = (unsigned long)(val);               \
> > +     __asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
> > +                           : "=r" (__v) : "rK" (__v)         \
> > +                           : "memory");                      \
> > +     __v;                                                    \
> > +})
> > +
> > +#define csr_read(csr)                                                \
> > +({                                                           \
> > +     register unsigned long __v;                             \
> > +     __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr)        \
> > +                           : "=r" (__v) :                    \
> > +                           : "memory");                      \
> > +     __v;                                                    \
> > +})
> > +
> > +#define csr_write(csr, val)                                  \
> > +({                                                           \
> > +     unsigned long __v = (unsigned long)(val);               \
> > +     __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0"     \
> > +                           : : "rK" (__v)                    \
> > +                           : "memory");                      \
> > +})
> > +
> > +#define csr_read_set(csr, val)                                       \
> > +({                                                           \
> > +     unsigned long __v = (unsigned long)(val);               \
> > +     __asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
> > +                           : "=r" (__v) : "rK" (__v)         \
> > +                           : "memory");                      \
> > +     __v;                                                    \
> > +})
> > +
> > +#define csr_set(csr, val)                                    \
> > +({                                                           \
> > +     unsigned long __v = (unsigned long)(val);               \
> > +     __asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0"     \
> > +                           : : "rK" (__v)                    \
> > +                           : "memory");                      \
> > +})
> > +
> > +#define csr_read_clear(csr, val)                             \
> > +({                                                           \
> > +     unsigned long __v = (unsigned long)(val);               \
> > +     __asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
> > +                           : "=r" (__v) : "rK" (__v)         \
> > +                           : "memory");                      \
> > +     __v;                                                    \
> > +})
> > +
> > +#define csr_clear(csr, val)                                  \
> > +({                                                           \
> > +     unsigned long __v = (unsigned long)(val);               \
> > +     __asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0"     \
> > +                           : : "rK" (__v)                    \
> > +                           : "memory");                      \
> > +})
> > +
> > +#endif /* __ASSEMBLY__ */
> > +
> > +#endif /* _ASM_RISCV_CSR_H */
> > --
> > 2.34.1
> >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-06  2:14     ` Haibo Xu
  2023-09-06  3:44       ` Haibo Xu
@ 2023-09-06  6:41       ` Andrew Jones
  2023-09-06  6:58         ` Haibo Xu
  1 sibling, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-06  6:41 UTC (permalink / raw)
  To: Haibo Xu
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu, Peter Gonda,
	Maxim Levitsky, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Wed, Sep 06, 2023 at 10:14:52AM +0800, Haibo Xu wrote:
> On Mon, Sep 4, 2023 at 9:24 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Sat, Sep 02, 2023 at 08:59:24PM +0800, Haibo Xu wrote:
...
> > > +
> > > +#include "kvm_util.h"
> > > +
> > > +#define NR_VCPUS_DEF            4
> > > +#define NR_TEST_ITERS_DEF       5
> > > +#define TIMER_TEST_PERIOD_MS_DEF    10
> > > +#define TIMER_TEST_ERR_MARGIN_US    100
> > > +#define TIMER_TEST_MIGRATION_FREQ_MS    2
> > > +
> > > +#define msecs_to_usecs(msec)    ((msec) * 1000LL)
> >
> > I'd move the above to include/test_util.h
> >
> 
> Yes, msecs_to_usecs() macro should be a common API for all the tests.
> 
> > > +
> > > +#define GICD_BASE_GPA    0x8000000ULL
> > > +#define GICR_BASE_GPA    0x80A0000ULL
> >
> > These defines belong in aarch64/arch_timer.c
> >
> 
> These 2 defines were also defined in other test cases, shall we move them
> to an aarch64 specific header file? Maybe
> tools/testing/selftests/kvm/include/aarch64/gic.h?

Even though currently all the aarch64 tests that use the gic are using
these defines for the base addresses, each test is free to choose whatever
base addresses it likes. I'd just move them back to aarch64/arch_timer.c
for now. Consolidating them into shared, default base addresses, if done
at all, is work for another series.

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h
  2023-09-04 13:31   ` Andrew Jones
@ 2023-09-06  6:56     ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  6:56 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, wchen, Greentime Hu, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vitaly Kuznetsov, Aaron Lewis,
	David Matlack, Mingwei Zhang, Ackerley Tng, Jim Mattson,
	Vipin Sharma, Maxim Levitsky, Peter Gonda, Like Xu,
	Philippe Mathieu-Daudé, Thomas Huth, David Woodhouse,
	Michal Luczaj, linux-kernel, linux-riscv, kvm, linux-kselftest,
	linux-arm-kernel, kvmarm, kvm-riscv

On Mon, Sep 4, 2023 at 9:31 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Sat, Sep 02, 2023 at 08:59:26PM +0800, Haibo Xu wrote:
> > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > ---
> >  tools/testing/selftests/kvm/include/riscv/processor.h | 5 +----
> >  1 file changed, 1 insertion(+), 4 deletions(-)
> >
> > diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> > index 5b62a3d2aa9b..6810c887fadc 100644
> > --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> > +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> > @@ -8,6 +8,7 @@
> >  #define SELFTEST_KVM_PROCESSOR_H
> >
> >  #include "kvm_util.h"
> > +#include <asm/csr.h>
> >  #include <linux/stringify.h>
> >
> >  static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> > @@ -95,12 +96,8 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t idx,
> >  #define PGTBL_PAGE_SIZE                              PGTBL_L0_BLOCK_SIZE
> >  #define PGTBL_PAGE_SIZE_SHIFT                        PGTBL_L0_BLOCK_SHIFT
> >
> > -#define SATP_PPN                             _AC(0x00000FFFFFFFFFFF, UL)
> >  #define SATP_MODE_39                         _AC(0x8000000000000000, UL)
> >  #define SATP_MODE_48                         _AC(0x9000000000000000, UL)
>
> SATP_MODE_39/48 are also in csr.h
>

Good catch! These 2 should also be removed. Will fix it in the next version.

> > -#define SATP_ASID_BITS                               16
> > -#define SATP_ASID_SHIFT                              44
> > -#define SATP_ASID_MASK                               _AC(0xFFFF, UL)
> >
> >  #define SBI_EXT_EXPERIMENTAL_START           0x08000000
> >  #define SBI_EXT_EXPERIMENTAL_END             0x08FFFFFF
> > --
> > 2.34.1
> >
>
> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-06  6:41       ` Andrew Jones
@ 2023-09-06  6:58         ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  6:58 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu, Peter Gonda,
	Maxim Levitsky, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Wed, Sep 6, 2023 at 2:41 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Wed, Sep 06, 2023 at 10:14:52AM +0800, Haibo Xu wrote:
> > On Mon, Sep 4, 2023 at 9:24 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > >
> > > On Sat, Sep 02, 2023 at 08:59:24PM +0800, Haibo Xu wrote:
> ...
> > > > +
> > > > +#include "kvm_util.h"
> > > > +
> > > > +#define NR_VCPUS_DEF            4
> > > > +#define NR_TEST_ITERS_DEF       5
> > > > +#define TIMER_TEST_PERIOD_MS_DEF    10
> > > > +#define TIMER_TEST_ERR_MARGIN_US    100
> > > > +#define TIMER_TEST_MIGRATION_FREQ_MS    2
> > > > +
> > > > +#define msecs_to_usecs(msec)    ((msec) * 1000LL)
> > >
> > > I'd move the above to include/test_util.h
> > >
> >
> > Yes, msecs_to_usecs() macro should be a common API for all the tests.
> >
> > > > +
> > > > +#define GICD_BASE_GPA    0x8000000ULL
> > > > +#define GICR_BASE_GPA    0x80A0000ULL
> > >
> > > These defines belong in aarch64/arch_timer.c
> > >
> >
> > These 2 defines were also defined in other test cases, shall we move them
> > to an aarch64 specific header file? Maybe
> > tools/testing/selftests/kvm/include/aarch64/gic.h?
>
> Even though currently all the aarch64 tests that use the gic are using
> these defines for the base addresses, each test is free to choose whatever
> base addresses it likes. I'd just move them back to aarch64/arch_timer.c
> for now. Consolidating them into shared, default base addresses, if done
> at all, is work for another series.
>

Ok, will move them to aarch64/arch_timer.c for this test.

> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-06  3:44       ` Haibo Xu
@ 2023-09-06  7:01         ` Andrew Jones
  2023-09-06  9:01           ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-06  7:01 UTC (permalink / raw)
  To: Haibo Xu
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu, Peter Gonda,
	Maxim Levitsky, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Wed, Sep 06, 2023 at 11:44:26AM +0800, Haibo Xu wrote:
> On Wed, Sep 6, 2023 at 10:14 AM Haibo Xu <xiaobo55x@gmail.com> wrote:
> >
> > On Mon, Sep 4, 2023 at 9:24 PM Andrew Jones <ajones@ventanamicro.com> wrote:
...
> > > > +
> > > > +enum guest_stage {
> > > > +     GUEST_STAGE_VTIMER_CVAL=1,
> > > > +     GUEST_STAGE_VTIMER_TVAL,
> > > > +     GUEST_STAGE_PTIMER_CVAL,
> > > > +     GUEST_STAGE_PTIMER_TVAL,
> > > > +     GUEST_STAGE_MAX,
> > > > +};
> > >
> > > This enum also belongs in aarch64/arch_timer.c
> > >
> >
> > Yes, it should be in aarch64/arch_timer.c
> >
> 
> After moving the above enum definition to aarch64/arch_timer.c, the
> below errors was reported
> while compiling kvm/arch_timer.o
> 
> include/timer_test.h:37:26: error: field ‘guest_stage’ has incomplete type
>    37 |         enum guest_stage guest_stage;
>         |                                        ^~~~~~~~~~~
> 
> Since kvm/arch_timer.c was independent of kvm/aarch64/arch_timer.c
> during OBJ compiling,
> I think it may be not possible to move the enum definition to
> aarch64/arch_timer.c
> 
> If we keep the definition in this header file, we can enclose it with
> #ifdef __aarch64__ for aarch64 only.
>

Let's change struct test_vcpu_shared_data to

 struct test_vcpu_shared_data {
        int nr_iter;
        int guest_stage;
        uint64_t xcnt;
 };

and then let the aarch64 code treat guest_stage as an enum and the riscv
code can completely ignore it (no need to create an unused enum).

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-06  6:35     ` Haibo Xu
@ 2023-09-06  7:13       ` Andrew Jones
  2023-09-06  9:09         ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-06  7:13 UTC (permalink / raw)
  To: Haibo Xu
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vipin Sharma, Aaron Lewis,
	David Matlack, Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang,
	Lei Wang, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Wed, Sep 06, 2023 at 02:35:42PM +0800, Haibo Xu wrote:
> On Mon, Sep 4, 2023 at 9:33 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Sat, Sep 02, 2023 at 08:59:25PM +0800, Haibo Xu wrote:
> > > Borrow the csr definitions and operations from kernel's
> > > arch/riscv/include/asm/csr.h to tools/ for riscv.
> > >
> > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > ---
> > >  tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
> > >  1 file changed, 521 insertions(+)
> > >  create mode 100644 tools/arch/riscv/include/asm/csr.h
> > >
> > > diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h
> > > new file mode 100644
> > > index 000000000000..4e86c82aacbd
> > > --- /dev/null
> > > +++ b/tools/arch/riscv/include/asm/csr.h
> > > @@ -0,0 +1,521 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +/*
> > > + * Copyright (C) 2015 Regents of the University of California
> > > + */
> > > +
> > > +#ifndef _ASM_RISCV_CSR_H
> > > +#define _ASM_RISCV_CSR_H
> > > +
> > > +#include <linux/bits.h>
> > > +
> > > +/* Status register flags */
> > > +#define SR_SIE               _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
> > > +#define SR_MIE               _AC(0x00000008, UL) /* Machine Interrupt Enable */
> > > +#define SR_SPIE              _AC(0x00000020, UL) /* Previous Supervisor IE */
> > > +#define SR_MPIE              _AC(0x00000080, UL) /* Previous Machine IE */
> > > +#define SR_SPP               _AC(0x00000100, UL) /* Previously Supervisor */
> > > +#define SR_MPP               _AC(0x00001800, UL) /* Previously Machine */
> > > +#define SR_SUM               _AC(0x00040000, UL) /* Supervisor User Memory Access */
> > > +
> > > +#define SR_FS                _AC(0x00006000, UL) /* Floating-point Status */
> > > +#define SR_FS_OFF    _AC(0x00000000, UL)
> > > +#define SR_FS_INITIAL        _AC(0x00002000, UL)
> > > +#define SR_FS_CLEAN  _AC(0x00004000, UL)
> > > +#define SR_FS_DIRTY  _AC(0x00006000, UL)
> > > +
> > > +#define SR_VS                _AC(0x00000600, UL) /* Vector Status */
> > > +#define SR_VS_OFF    _AC(0x00000000, UL)
> > > +#define SR_VS_INITIAL        _AC(0x00000200, UL)
> > > +#define SR_VS_CLEAN  _AC(0x00000400, UL)
> > > +#define SR_VS_DIRTY  _AC(0x00000600, UL)
> > > +
> > > +#define SR_XS                _AC(0x00018000, UL) /* Extension Status */
> > > +#define SR_XS_OFF    _AC(0x00000000, UL)
> > > +#define SR_XS_INITIAL        _AC(0x00008000, UL)
> > > +#define SR_XS_CLEAN  _AC(0x00010000, UL)
> > > +#define SR_XS_DIRTY  _AC(0x00018000, UL)
> > > +
> > > +#define SR_FS_VS     (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
> > > +
> > > +#ifndef CONFIG_64BIT
> >
> > How do we ensure CONFIG_64BIT is set?
> >
> 
> Currently, no explicit checking for this.
> Shall we add a gatekeeper in this file to ensure it is set?

Not in this file, since this file is shared by all the tools and...

> 
> #ifndef CONFIG_64BIT
> #error "CONFIG_64BIT was not set"
> #endif

...we'll surely hit this error right now since nothing is setting
CONFIG_64BIT when compiling KVM selftests.

We need to define CONFIG_64BIT in the build somewhere prior to any
headers which depend on it being included. Maybe we can simply
add -DCONFIG_64BIT to CFLAGS, since all KVM selftests supported
architectures are 64-bit.

(Please trim emails, as I've been doing, when discussing specific parts.)

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code
  2023-09-06  7:01         ` Andrew Jones
@ 2023-09-06  9:01           ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  9:01 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, Greentime Hu,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	Aaron Lewis, David Matlack, Vitaly Kuznetsov, Ackerley Tng,
	Mingwei Zhang, Vipin Sharma, Lei Wang, Like Xu, Peter Gonda,
	Maxim Levitsky, Thomas Huth, Philippe Mathieu-Daudé,
	David Woodhouse, Michal Luczaj, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Wed, Sep 6, 2023 at 3:01 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Wed, Sep 06, 2023 at 11:44:26AM +0800, Haibo Xu wrote:
> > On Wed, Sep 6, 2023 at 10:14 AM Haibo Xu <xiaobo55x@gmail.com> wrote:
> > >
> > > On Mon, Sep 4, 2023 at 9:24 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> ...
> > > > > +
> > > > > +enum guest_stage {
> > > > > +     GUEST_STAGE_VTIMER_CVAL=1,
> > > > > +     GUEST_STAGE_VTIMER_TVAL,
> > > > > +     GUEST_STAGE_PTIMER_CVAL,
> > > > > +     GUEST_STAGE_PTIMER_TVAL,
> > > > > +     GUEST_STAGE_MAX,
> > > > > +};
> > > >
> > > > This enum also belongs in aarch64/arch_timer.c
> > > >
> > >
> > > Yes, it should be in aarch64/arch_timer.c
> > >
> >
> > After moving the above enum definition to aarch64/arch_timer.c, the
> > below errors was reported
> > while compiling kvm/arch_timer.o
> >
> > include/timer_test.h:37:26: error: field ‘guest_stage’ has incomplete type
> >    37 |         enum guest_stage guest_stage;
> >         |                                        ^~~~~~~~~~~
> >
> > Since kvm/arch_timer.c was independent of kvm/aarch64/arch_timer.c
> > during OBJ compiling,
> > I think it may be not possible to move the enum definition to
> > aarch64/arch_timer.c
> >
> > If we keep the definition in this header file, we can enclose it with
> > #ifdef __aarch64__ for aarch64 only.
> >
>
> Let's change struct test_vcpu_shared_data to
>
>  struct test_vcpu_shared_data {
>         int nr_iter;
>         int guest_stage;
>         uint64_t xcnt;
>  };
>
> and then let the aarch64 code treat guest_stage as an enum and the riscv
> code can completely ignore it (no need to create an unused enum).
>

Good idea! Will fix it in v3.

> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-06  7:13       ` Andrew Jones
@ 2023-09-06  9:09         ` Haibo Xu
  2023-09-06 13:47           ` Andrew Jones
  0 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-06  9:09 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vipin Sharma, Aaron Lewis,
	David Matlack, Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang,
	Lei Wang, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Wed, Sep 6, 2023 at 3:13 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Wed, Sep 06, 2023 at 02:35:42PM +0800, Haibo Xu wrote:
> > On Mon, Sep 4, 2023 at 9:33 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > >
> > > On Sat, Sep 02, 2023 at 08:59:25PM +0800, Haibo Xu wrote:
> > > > Borrow the csr definitions and operations from kernel's
> > > > arch/riscv/include/asm/csr.h to tools/ for riscv.
> > > >
> > > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > > ---
> > > >  tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
> > > >  1 file changed, 521 insertions(+)
> > > >  create mode 100644 tools/arch/riscv/include/asm/csr.h
> > > >
> > > > diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h
> > > > new file mode 100644
> > > > index 000000000000..4e86c82aacbd
> > > > --- /dev/null
> > > > +++ b/tools/arch/riscv/include/asm/csr.h
> > > > @@ -0,0 +1,521 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > +/*
> > > > + * Copyright (C) 2015 Regents of the University of California
> > > > + */
> > > > +
> > > > +#ifndef _ASM_RISCV_CSR_H
> > > > +#define _ASM_RISCV_CSR_H
> > > > +
> > > > +#include <linux/bits.h>
> > > > +
> > > > +/* Status register flags */
> > > > +#define SR_SIE               _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
> > > > +#define SR_MIE               _AC(0x00000008, UL) /* Machine Interrupt Enable */
> > > > +#define SR_SPIE              _AC(0x00000020, UL) /* Previous Supervisor IE */
> > > > +#define SR_MPIE              _AC(0x00000080, UL) /* Previous Machine IE */
> > > > +#define SR_SPP               _AC(0x00000100, UL) /* Previously Supervisor */
> > > > +#define SR_MPP               _AC(0x00001800, UL) /* Previously Machine */
> > > > +#define SR_SUM               _AC(0x00040000, UL) /* Supervisor User Memory Access */
> > > > +
> > > > +#define SR_FS                _AC(0x00006000, UL) /* Floating-point Status */
> > > > +#define SR_FS_OFF    _AC(0x00000000, UL)
> > > > +#define SR_FS_INITIAL        _AC(0x00002000, UL)
> > > > +#define SR_FS_CLEAN  _AC(0x00004000, UL)
> > > > +#define SR_FS_DIRTY  _AC(0x00006000, UL)
> > > > +
> > > > +#define SR_VS                _AC(0x00000600, UL) /* Vector Status */
> > > > +#define SR_VS_OFF    _AC(0x00000000, UL)
> > > > +#define SR_VS_INITIAL        _AC(0x00000200, UL)
> > > > +#define SR_VS_CLEAN  _AC(0x00000400, UL)
> > > > +#define SR_VS_DIRTY  _AC(0x00000600, UL)
> > > > +
> > > > +#define SR_XS                _AC(0x00018000, UL) /* Extension Status */
> > > > +#define SR_XS_OFF    _AC(0x00000000, UL)
> > > > +#define SR_XS_INITIAL        _AC(0x00008000, UL)
> > > > +#define SR_XS_CLEAN  _AC(0x00010000, UL)
> > > > +#define SR_XS_DIRTY  _AC(0x00018000, UL)
> > > > +
> > > > +#define SR_FS_VS     (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
> > > > +
> > > > +#ifndef CONFIG_64BIT
> > >
> > > How do we ensure CONFIG_64BIT is set?
> > >
> >
> > Currently, no explicit checking for this.
> > Shall we add a gatekeeper in this file to ensure it is set?
>
> Not in this file, since this file is shared by all the tools and...
>
> >
> > #ifndef CONFIG_64BIT
> > #error "CONFIG_64BIT was not set"
> > #endif
>
> ...we'll surely hit this error right now since nothing is setting
> CONFIG_64BIT when compiling KVM selftests.
>
> We need to define CONFIG_64BIT in the build somewhere prior to any
> headers which depend on it being included. Maybe we can simply
> add -DCONFIG_64BIT to CFLAGS, since all KVM selftests supported
> architectures are 64-bit.
>

Make sense! Another option can be just add "#define CONFIG_64BIT" at
the begin of csr.h

> (Please trim emails, as I've been doing, when discussing specific parts.)
>

Sure, thanks for the suggestions!

> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function
  2023-09-04 14:04   ` Andrew Jones
@ 2023-09-06 10:10     ` Haibo Xu
  2023-09-07  3:57       ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-06 10:10 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, David Matlack, Aaron Lewis,
	Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang, Jim Mattson,
	Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu, Peter Gonda,
	Thomas Huth, Philippe Mathieu-Daudé, David Woodhouse,
	Michal Luczaj, Paul Durrant, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Mon, Sep 4, 2023 at 10:04 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Sat, Sep 02, 2023 at 08:59:29PM +0800, Haibo Xu wrote:
> > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > index d8ecacd03ecf..c4028bf32e3f 100644
> > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > @@ -44,20 +44,6 @@ bool check_reject_set(int err)
> >       return err == EINVAL;
> >  }
> >
> > -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > -{
> > -     int ret;
> > -     unsigned long value;
> > -
> > -     ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > -     if (ret) {
> > -             printf("Failed to get ext %d", ext);
> > -             return false;
> > -     }
> > -
> > -     return !!value;
>
> get-reg-list will now assert on get-reg when an extension isn't present,
> rather than failing the __TEST_REQUIRE(), which would do a skip instead.
> We need both the return false version and the assert version.
>

Ok, Will keep this one for get-reg-list and add another one for
arch-timer specific usage.

> > -}
> > -
> >  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> >  {
> >       struct vcpu_reg_sublist *s;
> > --
> > 2.34.1
> >
>
> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 3/8] tools: riscv: Add header file csr.h
  2023-09-06  9:09         ` Haibo Xu
@ 2023-09-06 13:47           ` Andrew Jones
  0 siblings, 0 replies; 40+ messages in thread
From: Andrew Jones @ 2023-09-06 13:47 UTC (permalink / raw)
  To: Haibo Xu
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, Vipin Sharma, Aaron Lewis,
	David Matlack, Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang,
	Lei Wang, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Wed, Sep 06, 2023 at 05:09:20PM +0800, Haibo Xu wrote:
> On Wed, Sep 6, 2023 at 3:13 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Wed, Sep 06, 2023 at 02:35:42PM +0800, Haibo Xu wrote:
> > > On Mon, Sep 4, 2023 at 9:33 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > > >
> > > > On Sat, Sep 02, 2023 at 08:59:25PM +0800, Haibo Xu wrote:
> > > > > Borrow the csr definitions and operations from kernel's
> > > > > arch/riscv/include/asm/csr.h to tools/ for riscv.
> > > > >
> > > > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > > > ---
> > > > >  tools/arch/riscv/include/asm/csr.h | 521 +++++++++++++++++++++++++++++
> > > > >  1 file changed, 521 insertions(+)
> > > > >  create mode 100644 tools/arch/riscv/include/asm/csr.h
> > > > >
> > > > > diff --git a/tools/arch/riscv/include/asm/csr.h b/tools/arch/riscv/include/asm/csr.h
> > > > > new file mode 100644
> > > > > index 000000000000..4e86c82aacbd
> > > > > --- /dev/null
> > > > > +++ b/tools/arch/riscv/include/asm/csr.h
> > > > > @@ -0,0 +1,521 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > > +/*
> > > > > + * Copyright (C) 2015 Regents of the University of California
> > > > > + */
> > > > > +
> > > > > +#ifndef _ASM_RISCV_CSR_H
> > > > > +#define _ASM_RISCV_CSR_H
> > > > > +
> > > > > +#include <linux/bits.h>
> > > > > +
> > > > > +/* Status register flags */
> > > > > +#define SR_SIE               _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
> > > > > +#define SR_MIE               _AC(0x00000008, UL) /* Machine Interrupt Enable */
> > > > > +#define SR_SPIE              _AC(0x00000020, UL) /* Previous Supervisor IE */
> > > > > +#define SR_MPIE              _AC(0x00000080, UL) /* Previous Machine IE */
> > > > > +#define SR_SPP               _AC(0x00000100, UL) /* Previously Supervisor */
> > > > > +#define SR_MPP               _AC(0x00001800, UL) /* Previously Machine */
> > > > > +#define SR_SUM               _AC(0x00040000, UL) /* Supervisor User Memory Access */
> > > > > +
> > > > > +#define SR_FS                _AC(0x00006000, UL) /* Floating-point Status */
> > > > > +#define SR_FS_OFF    _AC(0x00000000, UL)
> > > > > +#define SR_FS_INITIAL        _AC(0x00002000, UL)
> > > > > +#define SR_FS_CLEAN  _AC(0x00004000, UL)
> > > > > +#define SR_FS_DIRTY  _AC(0x00006000, UL)
> > > > > +
> > > > > +#define SR_VS                _AC(0x00000600, UL) /* Vector Status */
> > > > > +#define SR_VS_OFF    _AC(0x00000000, UL)
> > > > > +#define SR_VS_INITIAL        _AC(0x00000200, UL)
> > > > > +#define SR_VS_CLEAN  _AC(0x00000400, UL)
> > > > > +#define SR_VS_DIRTY  _AC(0x00000600, UL)
> > > > > +
> > > > > +#define SR_XS                _AC(0x00018000, UL) /* Extension Status */
> > > > > +#define SR_XS_OFF    _AC(0x00000000, UL)
> > > > > +#define SR_XS_INITIAL        _AC(0x00008000, UL)
> > > > > +#define SR_XS_CLEAN  _AC(0x00010000, UL)
> > > > > +#define SR_XS_DIRTY  _AC(0x00018000, UL)
> > > > > +
> > > > > +#define SR_FS_VS     (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
> > > > > +
> > > > > +#ifndef CONFIG_64BIT
> > > >
> > > > How do we ensure CONFIG_64BIT is set?
> > > >
> > >
> > > Currently, no explicit checking for this.
> > > Shall we add a gatekeeper in this file to ensure it is set?
> >
> > Not in this file, since this file is shared by all the tools and...
> >
> > >
> > > #ifndef CONFIG_64BIT
> > > #error "CONFIG_64BIT was not set"
> > > #endif
> >
> > ...we'll surely hit this error right now since nothing is setting
> > CONFIG_64BIT when compiling KVM selftests.
> >
> > We need to define CONFIG_64BIT in the build somewhere prior to any
> > headers which depend on it being included. Maybe we can simply
> > add -DCONFIG_64BIT to CFLAGS, since all KVM selftests supported
> > architectures are 64-bit.
> >
> 
> Make sense! Another option can be just add "#define CONFIG_64BIT" at
> the begin of csr.h

Nope, other tools/tests may want to include csr.h someday and they may or
may not be targeting 64-bit. They'll need to appropriately set
CONFIG_64BIT themselves. We could require

#define CONFIG_64BIT
#include <asm/csr.h>

everywhere we include it, but that's error prone since it'll get forgotten
and nothing will complain unless a define which isn't also present in
!CONFIG_64BIT is used.

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function
  2023-09-06 10:10     ` Haibo Xu
@ 2023-09-07  3:57       ` Haibo Xu
  2023-09-07  9:01         ` Andrew Jones
  0 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-07  3:57 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, David Matlack, Aaron Lewis,
	Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang, Jim Mattson,
	Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu, Peter Gonda,
	Thomas Huth, Philippe Mathieu-Daudé, David Woodhouse,
	Michal Luczaj, Paul Durrant, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Wed, Sep 6, 2023 at 6:10 PM Haibo Xu <xiaobo55x@gmail.com> wrote:
>
> On Mon, Sep 4, 2023 at 10:04 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Sat, Sep 02, 2023 at 08:59:29PM +0800, Haibo Xu wrote:
> > > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > index d8ecacd03ecf..c4028bf32e3f 100644
> > > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > @@ -44,20 +44,6 @@ bool check_reject_set(int err)
> > >       return err == EINVAL;
> > >  }
> > >
> > > -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > > -{
> > > -     int ret;
> > > -     unsigned long value;
> > > -
> > > -     ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > > -     if (ret) {
> > > -             printf("Failed to get ext %d", ext);
> > > -             return false;
> > > -     }
> > > -
> > > -     return !!value;
> >
> > get-reg-list will now assert on get-reg when an extension isn't present,
> > rather than failing the __TEST_REQUIRE(), which would do a skip instead.
> > We need both the return false version and the assert version.
> >
>
> Ok, Will keep this one for get-reg-list and add another one for
> arch-timer specific usage.
>

Just thought about it again, maybe we only need the "return false"
version for both get-reg-list
and arch-timer tests since if an extension was not available, the test
can be skipped with a message.

bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
{
       unsigned long value = 0;

       __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);

       return !!value;
}

> > > -}
> > > -
> > >  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
> > >  {
> > >       struct vcpu_reg_sublist *s;
> > > --
> > > 2.34.1
> > >
> >
> > Thanks,
> > drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test
  2023-09-04 14:58   ` Andrew Jones
@ 2023-09-07  4:20     ` Haibo Xu
  2023-09-07 19:01       ` Andrew Jones
  0 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-07  4:20 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Greentime Hu, wchen, Daniel Henrique Barboza,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Vipin Sharma, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Mon, Sep 4, 2023 at 10:58 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Sat, Sep 02, 2023 at 08:59:30PM +0800, Haibo Xu wrote:
> > Add a KVM selftest to validate the Sstc timer functionality.
> > The test was ported from arm64 arch timer test.
> >
> > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > ---

> > diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > new file mode 100644
> > index 000000000000..c50a33c1e4f9
> > --- /dev/null
> > +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > @@ -0,0 +1,130 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
> > + *
> > + * The test validates the sstc timer IRQs using vstimecmp registers.
> > + * It's ported from the aarch64 arch_timer test.
> > + *

> guest_run[_stage]() can be shared with aarch64, we just have a single
> stage=0 for riscv.
>

Yes, we can. But if we share the guest_run[_stage]() by moving it to
kvm/arch_timer.c
or kvm/include/timer_test.h, we need to declare extra sub-functions
somewhere in a
header file(etc. guest_configure_timer_action()).

> > +
> > +static void guest_code(void)
> > +{
> > +     uint32_t cpu = guest_get_vcpuid();
> > +     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
> > +
> > +     local_irq_disable();
> > +     timer_irq_disable();
> > +     local_irq_enable();
>
> I don't think we need to disable all interrupts when disabling the timer
> interrupt.
>

There is no local_irq_disable() protection during the initial debug
phase, but the test always
fail with below error messages:

Guest assert failed,  vcpu 0; stage; 0; iter: 0
==== Test Assertion Failure ====
  riscv/arch_timer.c:78: config_iter + 1 == irq_iter
  pid=585 tid=586 errno=4 - Interrupted system call
  (stack trace empty)
  0x1 != 0x0 (config_iter + 1 != irq_iter)

To be frank, I am not quite sure why the local_irq_disable/enable() matters.
One possible reason may be some timer irq was triggered before we set up the
timecmp register.

> > +
> > +     guest_run(shared_data);
> > +
> > +     GUEST_DONE();
> > +}
> > +
> > +void test_vm_cleanup(struct kvm_vm *vm)
> > +{
> > +     kvm_vm_free(vm);
> > +}
> > --
> > 2.34.1
> >
>
> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function
  2023-09-07  3:57       ` Haibo Xu
@ 2023-09-07  9:01         ` Andrew Jones
  2023-09-07  9:18           ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-07  9:01 UTC (permalink / raw)
  To: Haibo Xu
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, David Matlack, Aaron Lewis,
	Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang, Jim Mattson,
	Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu, Peter Gonda,
	Thomas Huth, Philippe Mathieu-Daudé, David Woodhouse,
	Michal Luczaj, Paul Durrant, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Thu, Sep 07, 2023 at 11:57:00AM +0800, Haibo Xu wrote:
> On Wed, Sep 6, 2023 at 6:10 PM Haibo Xu <xiaobo55x@gmail.com> wrote:
> >
> > On Mon, Sep 4, 2023 at 10:04 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > >
> > > On Sat, Sep 02, 2023 at 08:59:29PM +0800, Haibo Xu wrote:
> > > > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > > index d8ecacd03ecf..c4028bf32e3f 100644
> > > > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > > @@ -44,20 +44,6 @@ bool check_reject_set(int err)
> > > >       return err == EINVAL;
> > > >  }
> > > >
> > > > -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > > > -{
> > > > -     int ret;
> > > > -     unsigned long value;
> > > > -
> > > > -     ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > > > -     if (ret) {
> > > > -             printf("Failed to get ext %d", ext);
> > > > -             return false;
> > > > -     }
> > > > -
> > > > -     return !!value;
> > >
> > > get-reg-list will now assert on get-reg when an extension isn't present,
> > > rather than failing the __TEST_REQUIRE(), which would do a skip instead.
> > > We need both the return false version and the assert version.
> > >
> >
> > Ok, Will keep this one for get-reg-list and add another one for
> > arch-timer specific usage.
> >
> 
> Just thought about it again, maybe we only need the "return false"
> version for both get-reg-list
> and arch-timer tests since if an extension was not available, the test
> can be skipped with a message.
> 
> bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> {
>        unsigned long value = 0;
> 
>        __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> 
>        return !!value;
> }

Yup, I had actually seen that when reviewing a later patch in this series,
but I wasn't concerned if we added the assert type anyway, since we
frequently end up with the two function types for KVM queries. If we don't
have a need for an assert type yet, then we don't need to introduce it.
However, we should introduce the non-assert type as __vcpu_has_ext(),
reserving the vcpu_has_ext() name for the assert type, per the kvm
selftests naming convention.

Thanks,
drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function
  2023-09-07  9:01         ` Andrew Jones
@ 2023-09-07  9:18           ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-07  9:18 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Daniel Henrique Barboza, wchen, Sean Christopherson,
	Ricardo Koller, Vishal Annapurve, David Matlack, Aaron Lewis,
	Vitaly Kuznetsov, Ackerley Tng, Mingwei Zhang, Jim Mattson,
	Lei Wang, Vipin Sharma, Maxim Levitsky, Like Xu, Peter Gonda,
	Thomas Huth, Philippe Mathieu-Daudé, David Woodhouse,
	Michal Luczaj, Paul Durrant, linux-kernel, linux-riscv, kvm,
	linux-kselftest, linux-arm-kernel, kvmarm, kvm-riscv

On Thu, Sep 7, 2023 at 5:01 PM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Thu, Sep 07, 2023 at 11:57:00AM +0800, Haibo Xu wrote:
> > On Wed, Sep 6, 2023 at 6:10 PM Haibo Xu <xiaobo55x@gmail.com> wrote:
> > >
> > > On Mon, Sep 4, 2023 at 10:04 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > > >
> > > > On Sat, Sep 02, 2023 at 08:59:29PM +0800, Haibo Xu wrote:
> > > > > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > > > index d8ecacd03ecf..c4028bf32e3f 100644
> > > > > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > > > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > > > > @@ -44,20 +44,6 @@ bool check_reject_set(int err)
> > > > >       return err == EINVAL;
> > > > >  }
> > > > >
> > > > > -static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > > > > -{
> > > > > -     int ret;
> > > > > -     unsigned long value;
> > > > > -
> > > > > -     ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> > > > > -     if (ret) {
> > > > > -             printf("Failed to get ext %d", ext);
> > > > > -             return false;
> > > > > -     }
> > > > > -
> > > > > -     return !!value;
> > > >
> > > > get-reg-list will now assert on get-reg when an extension isn't present,
> > > > rather than failing the __TEST_REQUIRE(), which would do a skip instead.
> > > > We need both the return false version and the assert version.
> > > >
> > >
> > > Ok, Will keep this one for get-reg-list and add another one for
> > > arch-timer specific usage.
> > >
> >
> > Just thought about it again, maybe we only need the "return false"
> > version for both get-reg-list
> > and arch-timer tests since if an extension was not available, the test
> > can be skipped with a message.
> >
> > bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext)
> > {
> >        unsigned long value = 0;
> >
> >        __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value);
> >
> >        return !!value;
> > }
>
> Yup, I had actually seen that when reviewing a later patch in this series,
> but I wasn't concerned if we added the assert type anyway, since we
> frequently end up with the two function types for KVM queries. If we don't
> have a need for an assert type yet, then we don't need to introduce it.
> However, we should introduce the non-assert type as __vcpu_has_ext(),
> reserving the vcpu_has_ext() name for the assert type, per the kvm
> selftests naming convention.
>

Sure, thanks!

> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test
  2023-09-07  4:20     ` Haibo Xu
@ 2023-09-07 19:01       ` Andrew Jones
  2023-09-08  1:19         ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Andrew Jones @ 2023-09-07 19:01 UTC (permalink / raw)
  To: Haibo Xu
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Greentime Hu, wchen, Daniel Henrique Barboza,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Vipin Sharma, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

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

On Thu, Sep 07, 2023 at 12:20:29PM +0800, Haibo Xu wrote:
> On Mon, Sep 4, 2023 at 10:58 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Sat, Sep 02, 2023 at 08:59:30PM +0800, Haibo Xu wrote:
> > > Add a KVM selftest to validate the Sstc timer functionality.
> > > The test was ported from arm64 arch timer test.
> > >
> > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > ---
> 
> > > diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > > new file mode 100644
> > > index 000000000000..c50a33c1e4f9
> > > --- /dev/null
> > > +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > > @@ -0,0 +1,130 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
> > > + *
> > > + * The test validates the sstc timer IRQs using vstimecmp registers.
> > > + * It's ported from the aarch64 arch_timer test.
> > > + *
> 
> > guest_run[_stage]() can be shared with aarch64, we just have a single
> > stage=0 for riscv.
> >
> 
> Yes, we can. But if we share the guest_run[_stage]() by moving it to
> kvm/arch_timer.c
> or kvm/include/timer_test.h, we need to declare extra sub-functions
> somewhere in a
> header file(etc. guest_configure_timer_action()).

OK, whatever balances the reduction of duplicate code and avoidance of
exporting helper functions. BTW, riscv may not need/want all the same
helper functions as aarch64. Anyway, I guess I'll see how the next version
turns out.

> 
> > > +
> > > +static void guest_code(void)
> > > +{
> > > +     uint32_t cpu = guest_get_vcpuid();
> > > +     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
> > > +
> > > +     local_irq_disable();
> > > +     timer_irq_disable();
> > > +     local_irq_enable();
> >
> > I don't think we need to disable all interrupts when disabling the timer
> > interrupt.
> >
> 
> There is no local_irq_disable() protection during the initial debug
> phase, but the test always
> fail with below error messages:
> 
> Guest assert failed,  vcpu 0; stage; 0; iter: 0
> ==== Test Assertion Failure ====
>   riscv/arch_timer.c:78: config_iter + 1 == irq_iter
>   pid=585 tid=586 errno=4 - Interrupted system call
>   (stack trace empty)
>   0x1 != 0x0 (config_iter + 1 != irq_iter)
> 
> To be frank, I am not quite sure why the local_irq_disable/enable() matters.
> One possible reason may be some timer irq was triggered before we set up the
> timecmp register.

We should ensure we know the exact, expected state of the vcpu before,
during, and after the test. If a state doesn't match expectations,
then the test should assert and we should go investigate the test code
to see if setup/checking is correct. If it is, then we've found a bug
in KVM that we need to go investigate.

For Sstc, a pending timer interrupt completely depends on stimecmp, so
we need to watch that closely. Take a look at the attached simple timer
test I pulled together to illustrate how stimecmp, timer interrupt enable,
and all interrupt enable interact. You may want to use it to help port
the arch_timer.

Thanks,
drew

[-- Attachment #2: simple-riscv-timer-test.c --]
[-- Type: text/plain, Size: 2028 bytes --]

#include <stdio.h>

#define CONFIG_64BIT
#include "kvm_util.h"
#include "riscv/arch_timer.h"

static unsigned long timer_freq;
static unsigned int irq_fired;

void mdelay(unsigned long msecs)
{
	while (msecs--)
		udelay(1000);
}

static void guest_irq_handler(struct ex_regs *regs)
{
	GUEST_PRINTF("%s\n", __func__);

	GUEST_ASSERT_EQ(regs->cause & ~CAUSE_IRQ_FLAG, IRQ_S_TIMER);

	irq_fired = 1;

	csr_write(CSR_STIMECMP, -1);
	while (csr_read(CSR_SIP) & IE_TIE)
		cpu_relax();
}

static void guest_code(void)
{
	GUEST_PRINTF("stage 1\n");
	mdelay(1000);

	GUEST_ASSERT_EQ(irq_fired, 0);

	GUEST_PRINTF("stage 2\n");
	timer_set_next_cval_ms(500);
	mdelay(1000);

	GUEST_ASSERT_EQ(irq_fired, 1);
	irq_fired = 0;

	GUEST_PRINTF("stage 3\n");
	csr_clear(CSR_SIE, IE_TIE);
	timer_set_next_cval_ms(500);
	mdelay(1000);

	GUEST_ASSERT_EQ(irq_fired, 0);

	GUEST_PRINTF("stage 4\n");
	csr_set(CSR_SIE, IE_TIE);
	mdelay(1);

	GUEST_ASSERT_EQ(irq_fired, 1);
	irq_fired = 0;

	GUEST_PRINTF("stage 5\n");
	csr_clear(CSR_SSTATUS, SR_IE);
	timer_set_next_cval_ms(500);
	mdelay(1000);

	GUEST_ASSERT_EQ(irq_fired, 0);

	GUEST_PRINTF("stage 6\n");
	csr_set(CSR_SSTATUS, SR_IE);
	mdelay(1);

	GUEST_ASSERT_EQ(irq_fired, 1);
	irq_fired = 0;

	GUEST_PRINTF("guest done\n");
	GUEST_DONE();
}

int main(void)
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;
	struct ucall uc;
	uint64_t val;
	int done = 0;

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
	vm_init_vector_tables(vm);
	vm_install_interrupt_handler(vm, guest_irq_handler);
	vcpu_init_vector_tables(vcpu);
	vcpu_set_reg(vcpu, RISCV_CSR_REG(sstatus), SR_IE);
	vcpu_set_reg(vcpu, RISCV_CSR_REG(sie), IE_TIE);

	vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency), &timer_freq);
	sync_global_to_guest(vm, timer_freq);

	vcpu_get_reg(vcpu, RISCV_TIMER_REG(compare), &val);
	assert(val == -1);

	while (!done) {
		vcpu_run(vcpu);

		switch (get_ucall(vcpu, &uc)) {
		case UCALL_PRINTF:
			printf("%s", uc.buffer);
			break;
		case UCALL_DONE:
			printf("Done.\n");
			done = 1;
			break;
		}
	}
}

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test
  2023-09-07 19:01       ` Andrew Jones
@ 2023-09-08  1:19         ` Haibo Xu
  2023-09-08  2:36           ` Haibo Xu
  0 siblings, 1 reply; 40+ messages in thread
From: Haibo Xu @ 2023-09-08  1:19 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Greentime Hu, wchen, Daniel Henrique Barboza,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Vipin Sharma, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Fri, Sep 8, 2023 at 3:01 AM Andrew Jones <ajones@ventanamicro.com> wrote:
>
> On Thu, Sep 07, 2023 at 12:20:29PM +0800, Haibo Xu wrote:
> > On Mon, Sep 4, 2023 at 10:58 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > >
> > > On Sat, Sep 02, 2023 at 08:59:30PM +0800, Haibo Xu wrote:
> > > > Add a KVM selftest to validate the Sstc timer functionality.
> > > > The test was ported from arm64 arch timer test.
> > > >
> > > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > > ---
> >
> > > > diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > > > new file mode 100644
> > > > index 000000000000..c50a33c1e4f9
> > > > --- /dev/null
> > > > +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > > > @@ -0,0 +1,130 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > +/*
> > > > + * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
> > > > + *
> > > > + * The test validates the sstc timer IRQs using vstimecmp registers.
> > > > + * It's ported from the aarch64 arch_timer test.
> > > > + *
> >
> > > guest_run[_stage]() can be shared with aarch64, we just have a single
> > > stage=0 for riscv.
> > >
> >
> > Yes, we can. But if we share the guest_run[_stage]() by moving it to
> > kvm/arch_timer.c
> > or kvm/include/timer_test.h, we need to declare extra sub-functions
> > somewhere in a
> > header file(etc. guest_configure_timer_action()).
>
> OK, whatever balances the reduction of duplicate code and avoidance of
> exporting helper functions. BTW, riscv may not need/want all the same
> helper functions as aarch64. Anyway, I guess I'll see how the next version
> turns out.
>
> >
> > > > +
> > > > +static void guest_code(void)
> > > > +{
> > > > +     uint32_t cpu = guest_get_vcpuid();
> > > > +     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
> > > > +
> > > > +     local_irq_disable();
> > > > +     timer_irq_disable();
> > > > +     local_irq_enable();
> > >
> > > I don't think we need to disable all interrupts when disabling the timer
> > > interrupt.
> > >
> >
> > There is no local_irq_disable() protection during the initial debug
> > phase, but the test always
> > fail with below error messages:
> >
> > Guest assert failed,  vcpu 0; stage; 0; iter: 0
> > ==== Test Assertion Failure ====
> >   riscv/arch_timer.c:78: config_iter + 1 == irq_iter
> >   pid=585 tid=586 errno=4 - Interrupted system call
> >   (stack trace empty)
> >   0x1 != 0x0 (config_iter + 1 != irq_iter)
> >
> > To be frank, I am not quite sure why the local_irq_disable/enable() matters.
> > One possible reason may be some timer irq was triggered before we set up the
> > timecmp register.
>
> We should ensure we know the exact, expected state of the vcpu before,
> during, and after the test. If a state doesn't match expectations,
> then the test should assert and we should go investigate the test code
> to see if setup/checking is correct. If it is, then we've found a bug
> in KVM that we need to go investigate.
>
> For Sstc, a pending timer interrupt completely depends on stimecmp, so
> we need to watch that closely. Take a look at the attached simple timer
> test I pulled together to illustrate how stimecmp, timer interrupt enable,
> and all interrupt enable interact. You may want to use it to help port
> the arch_timer.
>

Thanks for sharing the test codes. Will have an investigation on it.

> Thanks,
> drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test
  2023-09-08  1:19         ` Haibo Xu
@ 2023-09-08  2:36           ` Haibo Xu
  0 siblings, 0 replies; 40+ messages in thread
From: Haibo Xu @ 2023-09-08  2:36 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Haibo Xu, Paul Walmsley, Palmer Dabbelt, Albert Ou, Paolo Bonzini,
	Shuah Khan, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Anup Patel, Atish Patra, Guo Ren,
	Conor Dooley, Greentime Hu, wchen, Daniel Henrique Barboza,
	Sean Christopherson, Ricardo Koller, Vishal Annapurve,
	David Matlack, Aaron Lewis, Mingwei Zhang, Vitaly Kuznetsov,
	Ackerley Tng, Vipin Sharma, Maxim Levitsky, Peter Gonda,
	Philippe Mathieu-Daudé, Thomas Huth, Like Xu,
	David Woodhouse, Michal Luczaj, zhang songyi, linux-kernel,
	linux-riscv, kvm, linux-kselftest, linux-arm-kernel, kvmarm,
	kvm-riscv

On Fri, Sep 8, 2023 at 9:19 AM Haibo Xu <xiaobo55x@gmail.com> wrote:
>
> On Fri, Sep 8, 2023 at 3:01 AM Andrew Jones <ajones@ventanamicro.com> wrote:
> >
> > On Thu, Sep 07, 2023 at 12:20:29PM +0800, Haibo Xu wrote:
> > > On Mon, Sep 4, 2023 at 10:58 PM Andrew Jones <ajones@ventanamicro.com> wrote:
> > > >
> > > > On Sat, Sep 02, 2023 at 08:59:30PM +0800, Haibo Xu wrote:
> > > > > Add a KVM selftest to validate the Sstc timer functionality.
> > > > > The test was ported from arm64 arch timer test.
> > > > >
> > > > > Signed-off-by: Haibo Xu <haibo1.xu@intel.com>
> > > > > ---
> > >
> > > > > diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > > > > new file mode 100644
> > > > > index 000000000000..c50a33c1e4f9
> > > > > --- /dev/null
> > > > > +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> > > > > @@ -0,0 +1,130 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > +/*
> > > > > + * arch_timer.c - Tests the riscv64 sstc timer IRQ functionality
> > > > > + *
> > > > > + * The test validates the sstc timer IRQs using vstimecmp registers.
> > > > > + * It's ported from the aarch64 arch_timer test.

> > >
> > > > > +
> > > > > +static void guest_code(void)
> > > > > +{
> > > > > +     uint32_t cpu = guest_get_vcpuid();
> > > > > +     struct test_vcpu_shared_data *shared_data = &vcpu_shared_data[cpu];
> > > > > +
> > > > > +     local_irq_disable();
> > > > > +     timer_irq_disable();
> > > > > +     local_irq_enable();
> > > >
> > > > I don't think we need to disable all interrupts when disabling the timer
> > > > interrupt.
> > > >
> > >
> > > There is no local_irq_disable() protection during the initial debug
> > > phase, but the test always
> > > fail with below error messages:
> > >
> > > Guest assert failed,  vcpu 0; stage; 0; iter: 0
> > > ==== Test Assertion Failure ====
> > >   riscv/arch_timer.c:78: config_iter + 1 == irq_iter
> > >   pid=585 tid=586 errno=4 - Interrupted system call
> > >   (stack trace empty)
> > >   0x1 != 0x0 (config_iter + 1 != irq_iter)
> > >
> > > To be frank, I am not quite sure why the local_irq_disable/enable() matters.
> > > One possible reason may be some timer irq was triggered before we set up the
> > > timecmp register.
> >
> > We should ensure we know the exact, expected state of the vcpu before,
> > during, and after the test. If a state doesn't match expectations,
> > then the test should assert and we should go investigate the test code
> > to see if setup/checking is correct. If it is, then we've found a bug
> > in KVM that we need to go investigate.
> >
> > For Sstc, a pending timer interrupt completely depends on stimecmp, so
> > we need to watch that closely. Take a look at the attached simple timer
> > test I pulled together to illustrate how stimecmp, timer interrupt enable,
> > and all interrupt enable interact. You may want to use it to help port
> > the arch_timer.
> >
>
> Thanks for sharing the test codes. Will have an investigation on it.
>

Hi Andrew,

You are right. The local_irq_disable() was not needed here.
It's my fault that I also removed the local_irq_enable() when trying
your suggestion.

Thanks for your review and help on this patch set!

Regards,
Haibo

> > Thanks,
> > drew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2023-09-08  2:36 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-02 12:59 [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Haibo Xu
2023-09-02 12:59 ` [PATCH v2 1/8] KVM: selftests: Unify the codes for guest exception handling Haibo Xu
2023-09-04 11:15   ` Andrew Jones
2023-09-06  2:15     ` Haibo Xu
2023-09-02 12:59 ` [PATCH v2 2/8] KVM: arm64: selftest: Split arch_timer test code Haibo Xu
2023-09-04 13:24   ` Andrew Jones
2023-09-06  2:14     ` Haibo Xu
2023-09-06  3:44       ` Haibo Xu
2023-09-06  7:01         ` Andrew Jones
2023-09-06  9:01           ` Haibo Xu
2023-09-06  6:41       ` Andrew Jones
2023-09-06  6:58         ` Haibo Xu
2023-09-02 12:59 ` [PATCH v2 3/8] tools: riscv: Add header file csr.h Haibo Xu
2023-09-04 13:26   ` Andrew Jones
2023-09-04 13:33   ` Andrew Jones
2023-09-06  6:35     ` Haibo Xu
2023-09-06  7:13       ` Andrew Jones
2023-09-06  9:09         ` Haibo Xu
2023-09-06 13:47           ` Andrew Jones
2023-09-02 12:59 ` [PATCH v2 4/8] KVM: riscv: selftests: Switch to use macro from csr.h Haibo Xu
2023-09-04 13:31   ` Andrew Jones
2023-09-06  6:56     ` Haibo Xu
2023-09-02 12:59 ` [PATCH v2 5/8] KVM: riscv: selftests: Add exception handling support Haibo Xu
2023-09-04 13:46   ` Andrew Jones
2023-09-02 12:59 ` [PATCH v2 6/8] KVM: riscv: selftests: Add guest helper to get vcpu id Haibo Xu
2023-09-04 13:48   ` Andrew Jones
2023-09-02 12:59 ` [PATCH v2 7/8] KVM: riscv: selftest: Change vcpu_has_ext to a common function Haibo Xu
2023-09-04 14:04   ` Andrew Jones
2023-09-06 10:10     ` Haibo Xu
2023-09-07  3:57       ` Haibo Xu
2023-09-07  9:01         ` Andrew Jones
2023-09-07  9:18           ` Haibo Xu
2023-09-02 12:59 ` [PATCH v2 8/8] KVM: riscv: selftests: Add sstc timer test Haibo Xu
2023-09-04 14:58   ` Andrew Jones
2023-09-07  4:20     ` Haibo Xu
2023-09-07 19:01       ` Andrew Jones
2023-09-08  1:19         ` Haibo Xu
2023-09-08  2:36           ` Haibo Xu
2023-09-05 10:36 ` [PATCH v2 0/8] RISCV: Add kvm Sstc timer selftest Andrew Jones
2023-09-06  1:23   ` Haibo Xu

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).