]> git.proxmox.com Git - qemu.git/commitdiff
PPC: KVM: set has-idle in guest device tree
authorStuart Yoder <stuart.yoder@freescale.com>
Thu, 3 Jan 2013 12:37:02 +0000 (12:37 +0000)
committerAlexander Graf <agraf@suse.de>
Mon, 7 Jan 2013 16:37:11 +0000 (17:37 +0100)
On e500mc, the platform doesn't provide a way for the CPU to go idle.

To still not uselessly burn CPU time, expose an idle hypercall to the guest
if kvm supports it.

Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
[agraf: adjust for current code base, add patch description, fix non-kvm case]
Signed-off-by: Alexander Graf <agraf@suse.de>
hw/ppc/e500.c
target-ppc/kvm.c
target-ppc/kvm_ppc.h

index b262f31e5a92404f84a88cc1deb34a317bcbb39c..5d70618f72e975469107e8510cac77da8949b7a3 100644 (file)
@@ -225,6 +225,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,
         kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
         qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
                              hypercall, sizeof(hypercall));
+        /* if KVM supports the idle hcall, set property indicating this */
+        if (kvmppc_get_hasidle(env)) {
+            qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
+        }
     }
 
     /* Create CPU nodes */
index 436ca474ff0b1ba13091db6d7a37d0f3d2e130c1..9fe949fbece3cdfc7966f114bb126e57534fac10 100644 (file)
@@ -989,18 +989,38 @@ uint32_t kvmppc_get_dfp(void)
     return kvmppc_read_int_cpu_dt("ibm,dfp");
 }
 
+static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
+ {
+     PowerPCCPU *cpu = ppc_env_get_cpu(env);
+     CPUState *cs = CPU(cpu);
+
+    if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
+        !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int kvmppc_get_hasidle(CPUPPCState *env)
+{
+    struct kvm_ppc_pvinfo pvinfo;
+
+    if (!kvmppc_get_pvinfo(env, &pvinfo) &&
+        (pvinfo.flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)) {
+        return 1;
+    }
+
+    return 0;
+}
+
 int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
 {
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
     uint32_t *hc = (uint32_t*)buf;
-
     struct kvm_ppc_pvinfo pvinfo;
 
-    if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
-        !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) {
+    if (!kvmppc_get_pvinfo(env, &pvinfo)) {
         memcpy(buf, pvinfo.hcall, buf_len);
-
         return 0;
     }
 
index 31eb9e6f22c46f75b7d531467793327ceb9cd1ec..9b0d500b501345ee671442dc18fc11aa9ba662bf 100644 (file)
@@ -19,6 +19,7 @@ uint32_t kvmppc_get_tbfreq(void);
 uint64_t kvmppc_get_clockfreq(void);
 uint32_t kvmppc_get_vmx(void);
 uint32_t kvmppc_get_dfp(void);
+int kvmppc_get_hasidle(CPUPPCState *env);
 int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
 int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
 void kvmppc_set_papr(PowerPCCPU *cpu);
@@ -55,6 +56,11 @@ static inline uint32_t kvmppc_get_dfp(void)
     return 0;
 }
 
+static inline int kvmppc_get_hasidle(CPUPPCState *env)
+{
+    return 0;
+}
+
 static inline int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
 {
     return -1;