@@ -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
@@ -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
@@ -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
@@ -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"
@@ -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;
}
@@ -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);
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(-)