Message ID | 1399898246-4831-6-git-send-email-pranavkumar@linaro.org |
---|---|
State | New |
Headers | show |
On 12 May 2014 13:37, Pranavkumar Sawargaonkar <pranavkumar@linaro.org> wrote: > Introduce a common kvm_arm_vcpu_init() for doing KVM_ARM_VCPU_INIT > ioctl in KVM ARM and KVM ARM64. This also helps us factor-out few > common code lines from kvm_arch_init_vcpu() for KVM ARM/ARM64. Mostly OK, some minor tweaks below. > Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org> > Signed-off-by: Anup Patel <anup.patel@linaro.org> > --- > target-arm/cpu-qom.h | 3 +++ > target-arm/kvm.c | 16 ++++++++++++++++ > target-arm/kvm32.c | 18 ++++++++---------- > target-arm/kvm64.c | 24 ++++++++++++++---------- > target-arm/kvm_arm.h | 13 +++++++++++++ > 5 files changed, 54 insertions(+), 20 deletions(-) > > diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h > index edc7f26..2bd7df8 100644 > --- a/target-arm/cpu-qom.h > +++ b/target-arm/cpu-qom.h > @@ -102,6 +102,9 @@ typedef struct ARMCPU { > */ > uint32_t kvm_target; > > + /* KVM init features for this CPU */ > + uint32_t kvm_init_features[7]; > + > /* The instance init functions for implementation-specific subclasses > * set these fields to specify the implementation-dependent values of > * various constant registers and reset values of non-constant > diff --git a/target-arm/kvm.c b/target-arm/kvm.c > index 39202d7..74c90a7 100644 > --- a/target-arm/kvm.c > +++ b/target-arm/kvm.c > @@ -27,6 +27,22 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { > KVM_CAP_LAST_INFO > }; > > +int kvm_arm_vcpu_init(CPUState *cs) > +{ > + ARMCPU *cpu = ARM_CPU(cs); > + struct kvm_vcpu_init init; > + > + if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) { > + fprintf(stderr, "KVM is not supported for this guest CPU type\n"); > + return -EINVAL; > + } This check should stay in kvm_arch_init_vcpu(), not be moved to here. > + > + init.target = cpu->kvm_target; > + memcpy(init.features, cpu->kvm_init_features, sizeof(init.features)); > + > + return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); > +} > + > bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, > int *fdarray, > struct kvm_vcpu_init *init) > diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c > index a690d99..cc9cdfa 100644 > --- a/target-arm/kvm32.c > +++ b/target-arm/kvm32.c > @@ -166,7 +166,6 @@ static int compare_u64(const void *a, const void *b) > > int kvm_arch_init_vcpu(CPUState *cs) > { > - struct kvm_vcpu_init init; > int i, ret, arraylen; > uint64_t v; > struct kvm_one_reg r; > @@ -174,20 +173,19 @@ int kvm_arch_init_vcpu(CPUState *cs) > struct kvm_reg_list *rlp; > ARMCPU *cpu = ARM_CPU(cs); > > - if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) { > - fprintf(stderr, "KVM is not supported for this guest CPU type\n"); > - return -EINVAL; > - } > - > - init.target = cpu->kvm_target; > - memset(init.features, 0, sizeof(init.features)); > + /* Determine init features for this CPU */ > + memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features)); > + cpu->kvm_init_features[0] = 0; This = 0 line is just repeating work the memset() just did. > if (cpu->start_powered_off) { > - init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF; > + cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; > } > - ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); > + > + /* Do KVM_ARM_VCPU_INIT ioctl */ > + ret = kvm_arm_vcpu_init(cs); > if (ret) { > return ret; > } > + > /* Query the kernel to make sure it supports 32 VFP > * registers: QEMU's "cortex-a15" CPU is always a > * VFP-D32 core. The simplest way to do this is just > diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c > index e115879..528536f 100644 > --- a/target-arm/kvm64.c > +++ b/target-arm/kvm64.c > @@ -77,26 +77,30 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc) > > int kvm_arch_init_vcpu(CPUState *cs) > { > - ARMCPU *cpu = ARM_CPU(cs); > - struct kvm_vcpu_init init; > int ret; > + ARMCPU *cpu = ARM_CPU(cs); > > - if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE || > - !arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { > - fprintf(stderr, "KVM is not supported for this guest CPU type\n"); > + if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { > + fprintf(stderr, "KVM only support Aarch64 CPU type\n"); Again, you don't need to change this guard/error. > return -EINVAL; > } > > - init.target = cpu->kvm_target; > - memset(init.features, 0, sizeof(init.features)); > + /* Determine init features for this CPU */ > + memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features)); > + cpu->kvm_init_features[0] = 0; Unnecessary. > if (cpu->start_powered_off) { > - init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF; > + cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; > + } > + > + /* Do KVM_ARM_VCPU_INIT ioctl */ > + ret = kvm_arm_vcpu_init(cs); > + if (ret) { > + return ret; > } > - ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); > > /* TODO : support for save/restore/reset of system regs via tuple list */ > > - return ret; > + return 0; > } > > #define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ > diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h > index 137c567..31e845f 100644 > --- a/target-arm/kvm_arm.h > +++ b/target-arm/kvm_arm.h > @@ -15,6 +15,19 @@ > #include "exec/memory.h" > > /** > + * kvm_arm_vcpu_init: > + * @cs: CPUState > + * > + * KVM ARM and KVM ARM64 need to use KVM_ARM_VCPU_INIT ioctl for > + * init/re-init/reset the VCPU with given feature flags. > + * This is a common function for doing KVM_ARM_VCPU_INIT ioctl > + * independent of KVM ARM or KVM ARM64. I think it would be more informative if this read: * Initialize (or reinitialize) the VCPU by invoking the * KVM_ARM_VCPU_INIT ioctl with the CPU type and feature * bitmask specified in the CPUState. > + * > + * Returns: 0 if success else < 0 error code > + */ > +int kvm_arm_vcpu_init(CPUState *cs); > + > +/** > * kvm_arm_register_device: > * @mr: memory region for this device > * @devid: the KVM device ID > -- > 1.7.9.5 > thanks -- PMM
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index edc7f26..2bd7df8 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -102,6 +102,9 @@ typedef struct ARMCPU { */ uint32_t kvm_target; + /* KVM init features for this CPU */ + uint32_t kvm_init_features[7]; + /* The instance init functions for implementation-specific subclasses * set these fields to specify the implementation-dependent values of * various constant registers and reset values of non-constant diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 39202d7..74c90a7 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -27,6 +27,22 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; +int kvm_arm_vcpu_init(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + struct kvm_vcpu_init init; + + if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) { + fprintf(stderr, "KVM is not supported for this guest CPU type\n"); + return -EINVAL; + } + + init.target = cpu->kvm_target; + memcpy(init.features, cpu->kvm_init_features, sizeof(init.features)); + + return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); +} + bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, int *fdarray, struct kvm_vcpu_init *init) diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c index a690d99..cc9cdfa 100644 --- a/target-arm/kvm32.c +++ b/target-arm/kvm32.c @@ -166,7 +166,6 @@ static int compare_u64(const void *a, const void *b) int kvm_arch_init_vcpu(CPUState *cs) { - struct kvm_vcpu_init init; int i, ret, arraylen; uint64_t v; struct kvm_one_reg r; @@ -174,20 +173,19 @@ int kvm_arch_init_vcpu(CPUState *cs) struct kvm_reg_list *rlp; ARMCPU *cpu = ARM_CPU(cs); - if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) { - fprintf(stderr, "KVM is not supported for this guest CPU type\n"); - return -EINVAL; - } - - init.target = cpu->kvm_target; - memset(init.features, 0, sizeof(init.features)); + /* Determine init features for this CPU */ + memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features)); + cpu->kvm_init_features[0] = 0; if (cpu->start_powered_off) { - init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF; + cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; } - ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); + + /* Do KVM_ARM_VCPU_INIT ioctl */ + ret = kvm_arm_vcpu_init(cs); if (ret) { return ret; } + /* Query the kernel to make sure it supports 32 VFP * registers: QEMU's "cortex-a15" CPU is always a * VFP-D32 core. The simplest way to do this is just diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c index e115879..528536f 100644 --- a/target-arm/kvm64.c +++ b/target-arm/kvm64.c @@ -77,26 +77,30 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc) int kvm_arch_init_vcpu(CPUState *cs) { - ARMCPU *cpu = ARM_CPU(cs); - struct kvm_vcpu_init init; int ret; + ARMCPU *cpu = ARM_CPU(cs); - if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE || - !arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - fprintf(stderr, "KVM is not supported for this guest CPU type\n"); + if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + fprintf(stderr, "KVM only support Aarch64 CPU type\n"); return -EINVAL; } - init.target = cpu->kvm_target; - memset(init.features, 0, sizeof(init.features)); + /* Determine init features for this CPU */ + memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features)); + cpu->kvm_init_features[0] = 0; if (cpu->start_powered_off) { - init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF; + cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; + } + + /* Do KVM_ARM_VCPU_INIT ioctl */ + ret = kvm_arm_vcpu_init(cs); + if (ret) { + return ret; } - ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); /* TODO : support for save/restore/reset of system regs via tuple list */ - return ret; + return 0; } #define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h index 137c567..31e845f 100644 --- a/target-arm/kvm_arm.h +++ b/target-arm/kvm_arm.h @@ -15,6 +15,19 @@ #include "exec/memory.h" /** + * kvm_arm_vcpu_init: + * @cs: CPUState + * + * KVM ARM and KVM ARM64 need to use KVM_ARM_VCPU_INIT ioctl for + * init/re-init/reset the VCPU with given feature flags. + * This is a common function for doing KVM_ARM_VCPU_INIT ioctl + * independent of KVM ARM or KVM ARM64. + * + * Returns: 0 if success else < 0 error code + */ +int kvm_arm_vcpu_init(CPUState *cs); + +/** * kvm_arm_register_device: * @mr: memory region for this device * @devid: the KVM device ID