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....@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 --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); -- 1.6.4