target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features

kvm_arm_create_scratch_host_vcpu() takes a struct kvm_vcpu_init
parameter. Rather than just using it as an output parameter to
pass back the preferred target, use it also as an input parameter,
allowing a caller to pass a selected target if they wish and to
also pass cpu features. If the caller doesn't want to select a
target they can pass -1 for the target which indicates they want
to use the preferred target and have it passed back like before.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Reviewed-by: Beata Michalska <beata.michalska@linaro.org>
Message-id: 20191031142734.8590-8-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Andrew Jones 2019-10-31 15:27:32 +01:00 committed by Peter Maydell
parent 14e99e0fbb
commit 0cdb4020b3
3 changed files with 25 additions and 7 deletions

View file

@ -66,7 +66,7 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
int *fdarray, int *fdarray,
struct kvm_vcpu_init *init) struct kvm_vcpu_init *init)
{ {
int ret, kvmfd = -1, vmfd = -1, cpufd = -1; int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
kvmfd = qemu_open("/dev/kvm", O_RDWR); kvmfd = qemu_open("/dev/kvm", O_RDWR);
if (kvmfd < 0) { if (kvmfd < 0) {
@ -86,7 +86,14 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
goto finish; goto finish;
} }
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init); if (init->target == -1) {
struct kvm_vcpu_init preferred;
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
if (!ret) {
init->target = preferred.target;
}
}
if (ret >= 0) { if (ret >= 0) {
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init); ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
if (ret < 0) { if (ret < 0) {
@ -98,10 +105,12 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
* creating one kind of guest CPU which is its preferred * creating one kind of guest CPU which is its preferred
* CPU type. * CPU type.
*/ */
struct kvm_vcpu_init try;
while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) { while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
init->target = *cpus_to_try++; try.target = *cpus_to_try++;
memset(init->features, 0, sizeof(init->features)); memcpy(try.features, init->features, sizeof(init->features));
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init); ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, &try);
if (ret >= 0) { if (ret >= 0) {
break; break;
} }
@ -109,6 +118,7 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
if (ret < 0) { if (ret < 0) {
goto err; goto err;
} }
init->target = try.target;
} else { } else {
/* Treat a NULL cpus_to_try argument the same as an empty /* Treat a NULL cpus_to_try argument the same as an empty
* list, which means we will fail the call since this must * list, which means we will fail the call since this must

View file

@ -53,7 +53,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
QEMU_KVM_ARM_TARGET_CORTEX_A15, QEMU_KVM_ARM_TARGET_CORTEX_A15,
QEMU_KVM_ARM_TARGET_NONE QEMU_KVM_ARM_TARGET_NONE
}; };
struct kvm_vcpu_init init; /*
* target = -1 informs kvm_arm_create_scratch_host_vcpu()
* to use the preferred target
*/
struct kvm_vcpu_init init = { .target = -1, };
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
return false; return false;

View file

@ -502,7 +502,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57,
QEMU_KVM_ARM_TARGET_NONE QEMU_KVM_ARM_TARGET_NONE
}; };
struct kvm_vcpu_init init; /*
* target = -1 informs kvm_arm_create_scratch_host_vcpu()
* to use the preferred target
*/
struct kvm_vcpu_init init = { .target = -1, };
if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
return false; return false;