diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index cbb9eec832..8bd3e36c08 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -94,6 +94,9 @@ typedef struct ARMCPU { /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; + /* Should CPU start in PSCI powered-off state? */ + bool start_powered_off; + /* 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/cpu.c b/target-arm/cpu.c index 4c8d9c7ae1..03258159ed 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -20,6 +20,7 @@ #include "cpu.h" #include "qemu-common.h" +#include "hw/qdev-properties.h" #if !defined(CONFIG_USER_ONLY) #include "hw/loader.h" #endif @@ -944,6 +945,11 @@ static const ARMCPUInfo arm_cpus[] = { #endif }; +static Property arm_cpu_properties[] = { + DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false), + DEFINE_PROP_END_OF_LIST() +}; + static void arm_cpu_class_init(ObjectClass *oc, void *data) { ARMCPUClass *acc = ARM_CPU_CLASS(oc); @@ -952,6 +958,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) acc->parent_realize = dc->realize; dc->realize = arm_cpu_realizefn; + dc->props = arm_cpu_properties; acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 309845630b..80c58c5ab1 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -79,6 +79,9 @@ int kvm_arch_init_vcpu(CPUState *cs) init.target = KVM_ARM_TARGET_CORTEX_A15; memset(init.features, 0, sizeof(init.features)); + if (cpu->start_powered_off) { + init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF; + } ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); if (ret) { return ret;