[PATCH v6 1/4] kvmtool: ARM: Use KVM_ARM_PREFERRED_TARGET vm ioctl to determine target cpu

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead, of trying out each and every target type we should
use KVM_ARM_PREFERRED_TARGET vm ioctl to determine target type
for KVM ARM/ARM64.

If KVM_ARM_PREFERRED_TARGET vm ioctl fails then we fallback to
old method of trying all known target types.

If KVM_ARM_PREFERRED_TARGET vm ioctl succeeds but the returned
target type is not known to KVMTOOL then we forcefully init
VCPU with target type returned by KVM_ARM_PREFERRED_TARGET vm ioctl.

Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@xxxxxxxxxx>
Signed-off-by: Anup Patel <anup.patel@xxxxxxxxxx>
Reviewed-by: Andre Przywara <andre.przywara@xxxxxxx>
---
 tools/kvm/arm/aarch32/arm-cpu.c                 |    8 ++++
 tools/kvm/arm/aarch64/arm-cpu.c                 |    9 +++-
 tools/kvm/arm/include/arm-common/kvm-cpu-arch.h |    2 +
 tools/kvm/arm/kvm-cpu.c                         |   56 +++++++++++++++++++----
 4 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/tools/kvm/arm/aarch32/arm-cpu.c b/tools/kvm/arm/aarch32/arm-cpu.c
index 71b98fe..946e443 100644
--- a/tools/kvm/arm/aarch32/arm-cpu.c
+++ b/tools/kvm/arm/aarch32/arm-cpu.c
@@ -22,6 +22,12 @@ static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu)
 	return 0;
 }
 
+static struct kvm_arm_target target_generic_v7 = {
+	.id		= UINT_MAX,
+	.compatible	= "arm,arm-v7",
+	.init		= arm_cpu__vcpu_init,
+};
+
 static struct kvm_arm_target target_cortex_a15 = {
 	.id		= KVM_ARM_TARGET_CORTEX_A15,
 	.compatible	= "arm,cortex-a15",
@@ -36,6 +42,8 @@ static struct kvm_arm_target target_cortex_a7 = {
 
 static int arm_cpu__core_init(struct kvm *kvm)
 {
+	kvm_cpu__set_kvm_arm_generic_target(&target_generic_v7);
+
 	return (kvm_cpu__register_kvm_arm_target(&target_cortex_a15) ||
 		kvm_cpu__register_kvm_arm_target(&target_cortex_a7));
 }
diff --git a/tools/kvm/arm/aarch64/arm-cpu.c b/tools/kvm/arm/aarch64/arm-cpu.c
index ce5ea2f..88970de 100644
--- a/tools/kvm/arm/aarch64/arm-cpu.c
+++ b/tools/kvm/arm/aarch64/arm-cpu.c
@@ -16,13 +16,18 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
 	timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
-
 static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu)
 {
 	vcpu->generate_fdt_nodes = generate_fdt_nodes;
 	return 0;
 }
 
+static struct kvm_arm_target target_generic_v8 = {
+	.id		= UINT_MAX,
+	.compatible	= "arm,arm-v8",
+	.init		= arm_cpu__vcpu_init,
+};
+
 static struct kvm_arm_target target_aem_v8 = {
 	.id		= KVM_ARM_TARGET_AEM_V8,
 	.compatible	= "arm,arm-v8",
@@ -43,6 +48,8 @@ static struct kvm_arm_target target_cortex_a57 = {
 
 static int arm_cpu__core_init(struct kvm *kvm)
 {
+	kvm_cpu__set_kvm_arm_generic_target(&target_generic_v8);
+
 	return (kvm_cpu__register_kvm_arm_target(&target_aem_v8) ||
 		kvm_cpu__register_kvm_arm_target(&target_foundation_v8) ||
 		kvm_cpu__register_kvm_arm_target(&target_cortex_a57));
diff --git a/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h b/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h
index 83cd8b8..36c7872 100644
--- a/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h
@@ -34,6 +34,8 @@ struct kvm_arm_target {
 	int		(*init)(struct kvm_cpu *vcpu);
 };
 
+void kvm_cpu__set_kvm_arm_generic_target(struct kvm_arm_target *target);
+
 int kvm_cpu__register_kvm_arm_target(struct kvm_arm_target *target);
 
 static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data,
diff --git a/tools/kvm/arm/kvm-cpu.c b/tools/kvm/arm/kvm-cpu.c
index aeaa4cf..f165373 100644
--- a/tools/kvm/arm/kvm-cpu.c
+++ b/tools/kvm/arm/kvm-cpu.c
@@ -13,7 +13,14 @@ int kvm_cpu__get_debug_fd(void)
 	return debug_fd;
 }
 
+static struct kvm_arm_target *kvm_arm_generic_target;
 static struct kvm_arm_target *kvm_arm_targets[KVM_ARM_NUM_TARGETS];
+
+void kvm_cpu__set_kvm_arm_generic_target(struct kvm_arm_target *target)
+{
+	kvm_arm_generic_target = target;
+}
+
 int kvm_cpu__register_kvm_arm_target(struct kvm_arm_target *target)
 {
 	unsigned int i = 0;
@@ -34,6 +41,7 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	struct kvm_cpu *vcpu;
 	int coalesced_offset, mmap_size, err = -1;
 	unsigned int i;
+	struct kvm_vcpu_init preferred_init;
 	struct kvm_vcpu_init vcpu_init = {
 		.features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id)
 	};
@@ -55,19 +63,46 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	if (vcpu->kvm_run == MAP_FAILED)
 		die("unable to mmap vcpu fd");
 
-	/* Find an appropriate target CPU type. */
-	for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) {
-		if (!kvm_arm_targets[i])
-			continue;
-		target = kvm_arm_targets[i];
-		vcpu_init.target = target->id;
+	/*
+	 * If the preferred target ioctl is successful then
+	 * use preferred target else try each and every target type
+	 */
+	err = ioctl(kvm->vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init);
+	if (!err) {
+		/* Match preferred target CPU type. */
+		target = NULL;
+		for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) {
+			if (!kvm_arm_targets[i])
+				continue;
+			if (kvm_arm_targets[i]->id == preferred_init.target) {
+				target = kvm_arm_targets[i];
+				break;
+			}
+		}
+		if (!target) {
+			target = kvm_arm_generic_target;
+			vcpu_init.target = preferred_init.target;
+		} else {
+			vcpu_init.target = target->id;
+		}
 		err = ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_INIT, &vcpu_init);
-		if (!err)
-			break;
+	} else {
+		/* Find an appropriate target CPU type. */
+		for (i = 0; i < ARRAY_SIZE(kvm_arm_targets); ++i) {
+			if (!kvm_arm_targets[i])
+				continue;
+			target = kvm_arm_targets[i];
+			vcpu_init.target = target->id;
+			err = ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_INIT, &vcpu_init);
+			if (!err)
+				break;
+		}
+		if (err)
+			die("Unable to find matching target");
 	}
 
 	if (err || target->init(vcpu))
-		die("Unable to initialise ARM vcpu");
+		die("Unable to initialise vcpu");
 
 	coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION,
 				 KVM_CAP_COALESCED_MMIO);
@@ -78,9 +113,10 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	/* Populate the vcpu structure. */
 	vcpu->kvm		= kvm;
 	vcpu->cpu_id		= cpu_id;
-	vcpu->cpu_type		= target->id;
+	vcpu->cpu_type		= vcpu_init.target;
 	vcpu->cpu_compatible	= target->compatible;
 	vcpu->is_running	= true;
+
 	return vcpu;
 }
 
-- 
1.7.9.5

_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm




[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux