diff mbox

kvmppc: update "has-idle" property in hypervisor node

Message ID 1329472740-8173-1-git-send-email-yu.liu@freescale.com
State New
Headers show

Commit Message

Liu Yu-B13201 Feb. 17, 2012, 9:59 a.m. UTC
Check if host support ev_idle hypercall via pvinfo->flags,
If so, then set "has-idle" property in guest dts.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
---
 hw/ppc_newworld.c               |    2 +-
 hw/ppc_oldworld.c               |    2 +-
 hw/ppce500_mpc8544ds.c          |    6 +++++-
 scripts/update-linux-headers.sh |    3 +++
 target-ppc/kvm.c                |    6 +++++-
 target-ppc/kvm_ppc.h            |    3 ++-
 6 files changed, 17 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 506187b..3b9ee11 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -398,7 +398,7 @@  static void ppc_core99_init (ram_addr_t ram_size,
 
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
         hypercall = g_malloc(16);
-        kvmppc_get_hypercall(env, hypercall, 16);
+        kvmppc_get_hypercall(env, hypercall, 16, NULL);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
 #endif
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 9295a34..384e425 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -313,7 +313,7 @@  static void ppc_heathrow_init (ram_addr_t ram_size,
 
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
         hypercall = g_malloc(16);
-        kvmppc_get_hypercall(env, hypercall, 16);
+        kvmppc_get_hypercall(env, hypercall, 16, NULL);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
 #endif
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index d69f78c..1fc80d4 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -112,6 +112,8 @@  static int mpc8544_load_device_tree(CPUState *env,
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
 
     if (kvm_enabled()) {
+        uint32_t pv_flags;
+
         /* Read out host's frequencies */
         clock_freq = kvmppc_get_clockfreq();
         tb_freq = kvmppc_get_tbfreq();
@@ -119,9 +121,11 @@  static int mpc8544_load_device_tree(CPUState *env,
         /* indicate KVM hypercall interface */
         qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
                                     "linux,kvm");
-        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
+        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall), &pv_flags);
         qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
                              hypercall, sizeof(hypercall));
+        if(pv_flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)
+            qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
     }
 
     /* We need to generate the cpu nodes in reverse order, so Linux can pick
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 9d2a4bc..a8513f6 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -39,6 +39,9 @@  for arch in x86 powerpc s390; do
     if [ $arch = x86 ]; then
         cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86"
     fi
+    if [ $arch = powerpc ]; then
+        cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc"
+    fi
 done
 
 rm -rf "$output/linux-headers/linux"
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 50cfa02..96b522d 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -704,7 +704,8 @@  uint32_t kvmppc_get_dfp(void)
     return kvmppc_read_int_cpu_dt("ibm,dfp");
 }
 
-int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
+int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len,
+                         uint32_t *flags)
 {
     uint32_t *hc = (uint32_t*)buf;
 
@@ -713,6 +714,9 @@  int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
     if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
         !kvm_vm_ioctl(env->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) {
         memcpy(buf, pvinfo.hcall, buf_len);
+        if (flags) {
+            *flags = pvinfo.flags;
+        }
 
         return 0;
     }
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index f9c0198..68129fb 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -19,7 +19,8 @@  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_hypercall(CPUState *env, uint8_t *buf, int buf_len);
+int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len,
+                         uint32_t *flags);
 int kvmppc_set_interrupt(CPUState *env, int irq, int level);
 void kvmppc_set_papr(CPUState *env);
 int kvmppc_smt_threads(void);