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

From: Raghavendra Rao Ananta
Date: Wed Sep 08 2021 - 21:39:23 EST


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@xxxxxxxxxx>
---
.../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