diff --git a/hw/ppc.h b/hw/ppc.h
index de13092..1251932 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -47,5 +47,8 @@ enum {
 #define FW_CFG_PPC_HEIGHT	(FW_CFG_ARCH_LOCAL + 0x01)
 #define FW_CFG_PPC_DEPTH	(FW_CFG_ARCH_LOCAL + 0x02)
 #define FW_CFG_PPC_TBFREQ	(FW_CFG_ARCH_LOCAL + 0x03)
+#define FW_CFG_PPC_IS_KVM       (FW_CFG_ARCH_LOCAL + 0x05)
+#define FW_CFG_PPC_KVM_HC       (FW_CFG_ARCH_LOCAL + 0x06)
+#define FW_CFG_PPC_KVM_PID      (FW_CFG_ARCH_LOCAL + 0x07)
 
 #define PPC_SERIAL_MM_BAUDBASE 399193
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index fbba9b6..f7c46b7 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -426,9 +426,16 @@ static void ppc_core99_init (ram_addr_t ram_size,
     fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
     fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
 
+    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
     if (kvm_enabled()) {
 #ifdef CONFIG_KVM
+        uint8_t *hypercall;
+
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
+        hypercall = qemu_malloc(16);
+        kvmppc_get_hypercall(env, hypercall, 16);
+        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
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 6b3ab89..6bd6555 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -398,9 +398,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
     fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
 
+    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
     if (kvm_enabled()) {
 #ifdef CONFIG_KVM
+        uint8_t *hypercall;
+
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
+        hypercall = qemu_malloc(16);
+        kvmppc_get_hypercall(env, hypercall, 16);
+        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
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 1079ce1..14d6365 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -327,6 +327,38 @@ uint32_t kvmppc_get_tbfreq(void)
     return retval;
 }
 
+int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
+{
+    uint32_t *hc = (uint32_t*)buf;
+
+#ifdef KVM_CAP_PPC_GET_PVINFO
+    struct kvm_ppc_pvinfo pvinfo;
+
+    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);
+
+        return 0;
+    }
+#endif
+
+    /*
+     * Fallback to always fail hypercalls:
+     *
+     *     li r3, -1
+     *     nop
+     *     nop
+     *     nop
+     */
+
+    hc[0] = 0x3860ffff;
+    hc[1] = 0x60000000;
+    hc[2] = 0x60000000;
+    hc[3] = 0x60000000;
+
+    return 0;
+}
+
 bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
     return true;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index e8d66e8..65e31c9 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -15,5 +15,6 @@ int kvmppc_read_host_property(const char *node_path, const char *prop,
                                      void *val, size_t len);
 
 uint32_t kvmppc_get_tbfreq(void);
+int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);
 
 #endif /* __KVM_PPC_H__ */
