[PATCH v4 09/18] KVM: arm64: selftests: Add guest support to get the vcpuid

Raghavendra Rao Ananta rananta at google.com
Wed Sep 8 18:38:09 PDT 2021


At times, such as when in the interrupt handler, the guest wants
to get the vcpuid that it's running on. As a result, introduce
get_vcpuid() that returns the vcpuid of the calling vcpu. At its
backend, the VMM prepares a map of vcpuid and mpidr during VM
initialization and exports the map to the guest for it to read.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 .../selftests/kvm/include/aarch64/processor.h |  3 ++
 .../selftests/kvm/lib/aarch64/processor.c     | 46 +++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index b6088c3c67a3..150f63101f4c 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -133,6 +133,7 @@ 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);
+void vm_vcpuid_map_init(struct kvm_vm *vm);
 
 static inline void cpu_relax(void)
 {
@@ -194,4 +195,6 @@ static inline void local_irq_disable(void)
 	asm volatile("msr daifset, #3" : : : "memory");
 }
 
+int get_vcpuid(void);
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
index 632b74d6b3ca..9844b62227b1 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
@@ -13,9 +13,17 @@
 #include "processor.h"
 
 #define DEFAULT_ARM64_GUEST_STACK_VADDR_MIN	0xac0000
+#define VM_VCPUID_MAP_INVAL			-1
 
 static vm_vaddr_t exception_handlers;
 
+struct vm_vcpuid_map {
+	uint64_t mpidr;
+	int vcpuid;
+};
+
+static struct vm_vcpuid_map vcpuid_map[KVM_MAX_VCPUS];
+
 static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
 {
 	return (v + vm->page_size) & ~(vm->page_size - 1);
@@ -426,3 +434,41 @@ void vm_install_exception_handler(struct kvm_vm *vm, int vector,
 	assert(vector < VECTOR_NUM);
 	handlers->exception_handlers[vector][0] = handler;
 }
+
+void vm_vcpuid_map_init(struct kvm_vm *vm)
+{
+	int i = 0;
+	struct vcpu *vcpu;
+	struct vm_vcpuid_map *map;
+
+	list_for_each_entry(vcpu, &vm->vcpus, list) {
+		map = &vcpuid_map[i++];
+		map->vcpuid = vcpu->id;
+		get_reg(vm, vcpu->id,
+			ARM64_SYS_KVM_REG(SYS_MPIDR_EL1), &map->mpidr);
+		map->mpidr &= MPIDR_HWID_BITMASK;
+	}
+
+	if (i < KVM_MAX_VCPUS)
+		vcpuid_map[i].vcpuid = VM_VCPUID_MAP_INVAL;
+
+	sync_global_to_guest(vm, vcpuid_map);
+}
+
+int get_vcpuid(void)
+{
+	int i, vcpuid;
+	uint64_t mpidr = read_sysreg(mpidr_el1) & MPIDR_HWID_BITMASK;
+
+	for (i = 0; i < KVM_MAX_VCPUS; i++) {
+		vcpuid = vcpuid_map[i].vcpuid;
+		GUEST_ASSERT_1(vcpuid != VM_VCPUID_MAP_INVAL, mpidr);
+
+		if (mpidr == vcpuid_map[i].mpidr)
+			return vcpuid;
+	}
+
+	/* We should not be reaching here */
+	GUEST_ASSERT_1(0, mpidr);
+	return -1;
+}
-- 
2.33.0.153.gba50c8fa24-goog




More information about the linux-arm-kernel mailing list