diff mbox

[RFC,3/3] arm64: pass breakpoint/watchpoint info for target cpu

Message ID 1441788132-6286-4-git-send-email-tushar.jagad@linaro.org
State New
Headers show

Commit Message

Tushar Jagad Sept. 9, 2015, 8:42 a.m. UTC
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(-)
diff mbox

Patch

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4846892..23ca35f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -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);
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 3cbc4a0..aceaaab 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -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;
 
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index bd60889..39ff54b 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -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) {