summaryrefslogtreecommitdiff
path: root/target/ppc/cpu.h
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2016-10-28 22:06:21 +1100
committerDavid Gibson <david@gibson.dropbear.id.au>2017-01-31 10:10:13 +1100
commit1d1be34d26b66069e20cbbcd798ea57763a0f152 (patch)
tree1299adce01019ee3e3b757edb3a5e38e27a662c4 /target/ppc/cpu.h
parent5b120785e70a9a48b43e3f1f156a10a015334a28 (diff)
downloadqemu-1d1be34d26b66069e20cbbcd798ea57763a0f152.tar.gz
ppc: Clean up and QOMify hypercall emulation
The pseries machine type is a bit unusual in that it runs a paravirtualized guest. The guest expects to interact with a hypervisor, and qemu emulates the functions of that hypervisor directly, rather than executing hypervisor code within the emulated system. To implement this in TCG, we need to intercept hypercall instructions and direct them to the machine's hypercall handlers, rather than attempting to perform a privilege change within TCG. This is controlled by a global hook - cpu_ppc_hypercall. This cleanup makes the handling a little cleaner and more extensible than a single global variable. Instead, each CPU to have hypercalls intercepted has a pointer set to a QOM object implementing a new virtual hypervisor interface. A method in that interface is called by TCG when it sees a hypercall instruction. It's possible we may want to add other methods in future. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Diffstat (limited to 'target/ppc/cpu.h')
-rw-r--r--target/ppc/cpu.h26
1 files changed, 24 insertions, 2 deletions
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 7a6ee3f05b..4fb4c20363 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1150,6 +1150,9 @@ do { \
env->wdt_period[3] = (d_); \
} while (0)
+typedef struct PPCVirtualHypervisor PPCVirtualHypervisor;
+typedef struct PPCVirtualHypervisorClass PPCVirtualHypervisorClass;
+
/**
* PowerPCCPU:
* @env: #CPUPPCState
@@ -1168,6 +1171,7 @@ struct PowerPCCPU {
int cpu_dt_id;
uint32_t max_compat;
uint32_t cpu_version;
+ PPCVirtualHypervisor *vhyp;
/* Fields related to migration compatibility hacks */
bool pre_2_8_migration;
@@ -1189,6 +1193,25 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
+struct PPCVirtualHypervisor {
+ Object parent;
+};
+
+struct PPCVirtualHypervisorClass {
+ InterfaceClass parent;
+ void (*hypercall)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
+};
+
+#define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor"
+#define PPC_VIRTUAL_HYPERVISOR(obj) \
+ OBJECT_CHECK(PPCVirtualHypervisor, (obj), TYPE_PPC_VIRTUAL_HYPERVISOR)
+#define PPC_VIRTUAL_HYPERVISOR_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PPCVirtualHypervisorClass, (klass), \
+ TYPE_PPC_VIRTUAL_HYPERVISOR)
+#define PPC_VIRTUAL_HYPERVISOR_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PPCVirtualHypervisorClass, (obj), \
+ TYPE_PPC_VIRTUAL_HYPERVISOR)
+
void ppc_cpu_do_interrupt(CPUState *cpu);
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
@@ -1261,6 +1284,7 @@ void store_booke_tcr (CPUPPCState *env, target_ulong val);
void store_booke_tsr (CPUPPCState *env, target_ulong val);
void ppc_tlb_invalidate_all (CPUPPCState *env);
void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
+void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp);
void cpu_ppc_set_papr(PowerPCCPU *cpu);
#endif
#endif
@@ -2435,8 +2459,6 @@ static inline bool lsw_reg_in_range(int start, int nregs, int rx)
(start + nregs > 32 && (rx >= start || rx < start + nregs - 32));
}
-extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
-
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
/**