On 28.06.2013, at 14:11, Mian M. Hamayun wrote: > From: "Mian M. Hamayun" <m.hamayun@xxxxxxxxxxxxxxxxxxxxxx> > > The init function tries to initialize with Foundation models first and on > failure retries initializing on Fast Models. > > Get and Put Registers deal with the basic state of Aarch64 CPUs for the moment. > > Signed-off-by: Mian M. Hamayun <m.hamayun@xxxxxxxxxxxxxxxxxxxxxx> > --- > linux-headers/linux/kvm.h | 1 + > target-arm/cpu.c | 8 +++ > target-arm/cpu.h | 1 + > target-arm/kvm.c | 120 +++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 130 insertions(+) > > diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h > index c614070..4df5292 100644 > --- a/linux-headers/linux/kvm.h > +++ b/linux-headers/linux/kvm.h > @@ -783,6 +783,7 @@ struct kvm_dirty_tlb { > #define KVM_REG_IA64 0x3000000000000000ULL > #define KVM_REG_ARM 0x4000000000000000ULL > #define KVM_REG_S390 0x5000000000000000ULL > +#define KVM_REG_ARM64 0x6000000000000000ULL > > #define KVM_REG_SIZE_SHIFT 52 > #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL This should be part of your header update patch. > diff --git a/target-arm/cpu.c b/target-arm/cpu.c > index 496a59f..34eba77 100644 > --- a/target-arm/cpu.c > +++ b/target-arm/cpu.c > @@ -601,6 +601,13 @@ static void cortex_a15_initfn(Object *obj) > define_arm_cp_regs(cpu, cortexa15_cp_reginfo); > } > > +static void cortex_a57_initfn(Object *obj) > +{ > + ARMCPU *cpu = ARM_CPU(obj); > + set_feature(&cpu->env, ARM_FEATURE_V8); > + cpu->env.aarch64 = 1; /* We force 64-bit mode for guests */ > +} > + > static void ti925t_initfn(Object *obj) > { > ARMCPU *cpu = ARM_CPU(obj); > @@ -781,6 +788,7 @@ static const ARMCPUInfo arm_cpus[] = { > { .name = "cortex-a8", .initfn = cortex_a8_initfn }, > { .name = "cortex-a9", .initfn = cortex_a9_initfn }, > { .name = "cortex-a15", .initfn = cortex_a15_initfn }, > + { .name = "cortex-a57", .initfn = cortex_a57_initfn }, > { .name = "ti925t", .initfn = ti925t_initfn }, > { .name = "sa1100", .initfn = sa1100_initfn }, > { .name = "sa1110", .initfn = sa1110_initfn }, > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index cd42814..f1cae7f 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -410,6 +410,7 @@ enum arm_features { > ARM_FEATURE_V6, > ARM_FEATURE_V6K, > ARM_FEATURE_V7, > + ARM_FEATURE_V8, > ARM_FEATURE_THUMB2, > ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */ > ARM_FEATURE_VFP3, > diff --git a/target-arm/kvm.c b/target-arm/kvm.c > index 27dcab9..0125f16 100644 > --- a/target-arm/kvm.c > +++ b/target-arm/kvm.c > @@ -23,6 +23,11 @@ > #include "cpu.h" > #include "hw/arm/arm.h" > > +#ifdef TARGET_AARCH64 > +#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ > + KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) > +#endif > + > const KVMCapabilityInfo kvm_arch_required_capabilities[] = { > KVM_CAP_LAST_INFO > }; > @@ -41,6 +46,28 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu) > return cpu->cpu_index; > } > > +#ifdef TARGET_AARCH64 > +int kvm_arch_init_vcpu(CPUState *cs) > +{ > + struct kvm_vcpu_init init; > + int ret; > + > + /* Try initializing with Foundation Models */ > + init.target = KVM_ARM_TARGET_FOUNDATION_V8; > + memset(init.features, 0, sizeof(init.features)); > + ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); > + if (ret) { > + /* Retry initializing with Fast Models */ > + init.target = KVM_ARM_TARGET_AEM_V8; > + ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); Not sure I understand this part. Do we have different CPU types for the different models? If so, they'd be different -cpu parameters, with -cpu host picking the same as the host's. > + if (ret) { > + return ret; > + } > + } > + > + return ret; > +} > +#else > int kvm_arch_init_vcpu(CPUState *cs) > { > struct kvm_vcpu_init init; > @@ -67,6 +94,7 @@ int kvm_arch_init_vcpu(CPUState *cs) > } > return ret; > } > +#endif > > /* We track all the KVM devices which need their memory addresses > * passing to the kernel in a list of these structures. > @@ -159,6 +187,7 @@ typedef struct Reg { > int offset; > } Reg; > > +#ifndef TARGET_AARCH64 > #define COREREG(KERNELNAME, QEMUFIELD) \ > { \ > KVM_REG_ARM | KVM_REG_SIZE_U32 | \ > @@ -239,7 +268,52 @@ static const Reg regs[] = { > VFPSYSREG(FPINST), > VFPSYSREG(FPINST2), > }; > +#endif > + > +#ifdef TARGET_AARCH64 > +int kvm_arch_put_registers(CPUState *cs, int level) How does the register transaction interface look like for aarch64 kvm? Are aarch32 registers mapped onto aarch64 ones or are they a separate set of registers? If they're a separate set, just add the aarch64 register sync to the aarch32 one. > +{ > + struct kvm_one_reg reg; > + int i; > + int ret; > + > + ARMCPU *cpu = ARM_CPU(cs); > + CPUARMState *env = &cpu->env; > + > + for (i = 0; i < 31; i++) { s/31/ARRAY_SIZE(...)/ > + reg.id = AARCH64_CORE_REG(regs.regs[i]); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]); reg.addr = (uintptr_t)&env->xregs[i]; Same below. Alex > + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + } > + > + reg.id = AARCH64_CORE_REG(regs.sp); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[31]); > + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + > + reg.id = AARCH64_CORE_REG(regs.pstate); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pstate); > + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > > + reg.id = AARCH64_CORE_REG(regs.pc); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pc); > + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + > + /* TODO: Set Rest of Registers */ > + return ret; > +} > +#else > int kvm_arch_put_registers(CPUState *cs, int level) > { > ARMCPU *cpu = ARM_CPU(cs); > @@ -321,7 +395,52 @@ int kvm_arch_put_registers(CPUState *cs, int level) > > return ret; > } > +#endif > + > +#ifdef TARGET_AARCH64 > +int kvm_arch_get_registers(CPUState *cs) > +{ > + struct kvm_one_reg reg; > + int i; > + int ret; > + > + ARMCPU *cpu = ARM_CPU(cs); > + CPUARMState *env = &cpu->env; > + > + for (i = 0; i < 31; i++) { > + reg.id = AARCH64_CORE_REG(regs.regs[i]); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]); > + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + } > > + reg.id = AARCH64_CORE_REG(regs.sp); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[31]); > + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + > + reg.id = AARCH64_CORE_REG(regs.pstate); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pstate); > + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + > + reg.id = AARCH64_CORE_REG(regs.pc); > + reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, pc); > + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); > + if (ret) { > + return ret; > + } > + > + /* TODO: Set Rest of Registers */ > + return ret; > +} > +#else > int kvm_arch_get_registers(CPUState *cs) > { > ARMCPU *cpu = ARM_CPU(cs); > @@ -416,6 +535,7 @@ int kvm_arch_get_registers(CPUState *cs) > > return 0; > } > +#endif > > void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) > { > -- > 1.7.9.5 > > _______________________________________________ > kvmarm mailing list > kvmarm@xxxxxxxxxxxxxxxxxxxxx > https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm