@@ -828,6 +828,8 @@ static void machvirt_init(MachineState *machine)
ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
CPUClass *cc = CPU_CLASS(oc);
Object *cpuobj;
+ CPUState *cs;
+ ARMCPU *cpu;
Error *err = NULL;
char *cpuopts = g_strdup(cpustr[1]);
@@ -837,8 +839,11 @@ static void machvirt_init(MachineState *machine)
}
cpuobj = object_new(object_class_get_name(oc));
+ cs = CPU(cpuobj);
+ cpu = ARM_CPU(cs);
+
/* Handle any CPU options specified by the user */
- cc->parse_features(CPU(cpuobj), cpuopts, &err);
+ cc->parse_features(cs, cpuopts, &err);
g_free(cpuopts);
if (err) {
error_report_err(err);
@@ -863,6 +868,22 @@ static void machvirt_init(MachineState *machine)
}
object_property_set_bool(cpuobj, true, "realized", NULL);
+
+ if (object_property_find(cpuobj, "bpts", NULL)) {
+ cpu->bpts = object_property_get_int(cpuobj, "bpts", &error_abort);
+ if (cpu->bpts && cpu->bpts < 2) {
+ printf("Minimum number of breakpoints > 2\n");
+ exit(1);
+ }
+ }
+
+ if (object_property_find(cpuobj, "wpts", NULL)) {
+ cpu->wpts = object_property_get_int(cpuobj, "wpts", &error_abort);
+ if (cpu->wpts && cpu->wpts < 2) {
+ printf("Minimum number of watchpoints > 2\n");
+ exit(1);
+ }
+ }
}
g_strfreev(cpustr);
fdt_add_timer_nodes(vbi);
@@ -121,6 +121,12 @@ typedef struct ARMCPU {
/* KVM init features for this CPU */
uint32_t kvm_init_features[7];
+ /* Number of h/w breakpoints supported by the guest */
+ uint32_t bpts;
+
+ /* Number of h/w watchpoints supported by the guest */
+ uint32_t wpts;
+
/* Uniprocessor system with MP extensions */
bool mp_is_up;
@@ -105,6 +105,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
}
+ if (cpu->bpts)
+ cpu->kvm_init_features[KVM_ARM_VCPU_BPTS_FEATURES_IDX] |=
+ (cpu->bpts << KVM_ARM_VCPU_NUM_BPTS) & KVM_ARM_VCPU_BPTS_MASK;
+
+ if (cpu->wpts)
+ cpu->kvm_init_features[KVM_ARM_VCPU_WPTS_FEATURES_IDX] |=
+ (cpu->wpts << KVM_ARM_VCPU_NUM_WPTS) & KVM_ARM_VCPU_WPTS_MASK;
+
/* Do KVM_ARM_VCPU_INIT ioctl */
ret = kvm_arm_vcpu_init(cs);
if (ret) {
This patch adds support for passing user defined hardware properties to the host kernel for cross cpu environment. ARM cpu has a lot of implementation specific hardware features which differ from vendor to vendor. This pose a hurdle to run guests in a cross cpu type environment (for example: running cortex-a57 guests on x-gene and vice-versa). The implementation specific hardware properties like number of hardware breakpoints, watchpoints, etc needs to be defined for guest for the Cross CPU execution. This is specifically useful in an environment where a mix of hardware platforms are available and the guest cpu needs to be different from the host cpu. Qemu passes this information to the host kernel which reflects these properties accordingly in the guest vcpu. Signed-off-by: Tushar Jagad <tushar.jagad@linaro.org> --- hw/arm/virt.c | 23 ++++++++++++++++++++++- target-arm/cpu-qom.h | 6 ++++++ target-arm/kvm64.c | 8 ++++++++ 3 files changed, 36 insertions(+), 1 deletion(-)