qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: peter.maydell@linaro.org
Cc: agraf@suse.de, qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
	thuth@redhat.com, lvivier@redhat.com, aik@ozlabs.ru,
	mdroth@linux.vnet.ibm.com,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [PULL 17/67] ppc: Clean up and QOMify hypercall emulation
Date: Thu, 12 Jan 2017 13:02:37 +1100	[thread overview]
Message-ID: <20170112020327.24882-18-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20170112020327.24882-1-david@gibson.dropbear.id.au>

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>
---
 hw/ppc/spapr.c              |  8 +++++---
 hw/ppc/spapr_cpu_core.c     |  1 +
 target/ppc/cpu.h            | 26 ++++++++++++++++++++++++--
 target/ppc/excp_helper.c    | 11 ++++-------
 target/ppc/translate_init.c | 12 ++++++++++++
 5 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 52970db..b3bbad0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1005,7 +1005,8 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
     return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
 }
 
-static void emulate_spapr_hypercall(PowerPCCPU *cpu)
+static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp,
+                                    PowerPCCPU *cpu)
 {
     CPUPPCState *env = &cpu->env;
 
@@ -1843,8 +1844,6 @@ static void ppc_spapr_init(MachineState *machine)
 
     QLIST_INIT(&spapr->phbs);
 
-    cpu_ppc_hypercall = emulate_spapr_hypercall;
-
     /* Allocate RMA if necessary */
     rma_alloc_size = kvmppc_alloc_rma(&rma);
 
@@ -2680,6 +2679,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
     NMIClass *nc = NMI_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+    PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
 
     mc->desc = "pSeries Logical Partition (PAPR compliant)";
 
@@ -2711,6 +2711,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     fwc->get_dev_path = spapr_get_fw_dev_path;
     nc->nmi_monitor_handler = spapr_nmi;
     smc->phb_placement = spapr_phb_placement;
+    vhc->hypercall = emulate_spapr_hypercall;
 }
 
 static const TypeInfo spapr_machine_info = {
@@ -2726,6 +2727,7 @@ static const TypeInfo spapr_machine_info = {
         { TYPE_FW_PATH_PROVIDER },
         { TYPE_NMI },
         { TYPE_HOTPLUG_HANDLER },
+        { TYPE_PPC_VIRTUAL_HYPERVISOR },
         { }
     },
 };
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index f532689..9dddaeb 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -57,6 +57,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
     cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
 
     /* Enable PAPR mode in TCG or KVM */
+    cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
     cpu_ppc_set_papr(cpu);
 
     if (cpu->max_compat) {
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 7a6ee3f..4fb4c20 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);
 
 /**
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 93369d4..f4ee7aa 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -35,11 +35,6 @@
 #endif
 
 /*****************************************************************************/
-/* PowerPC Hypercall emulation */
-
-void (*cpu_ppc_hypercall)(PowerPCCPU *);
-
-/*****************************************************************************/
 /* Exception processing */
 #if defined(CONFIG_USER_ONLY)
 void ppc_cpu_do_interrupt(CPUState *cs)
@@ -318,8 +313,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         env->nip += 4;
 
         /* "PAPR mode" built-in hypercall emulation */
-        if ((lev == 1) && cpu_ppc_hypercall) {
-            cpu_ppc_hypercall(cpu);
+        if ((lev == 1) && cpu->vhyp) {
+            PPCVirtualHypervisorClass *vhc =
+                PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+            vhc->hypercall(cpu->vhyp, cpu);
             return;
         }
         if (lev == 1) {
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 626e031..82ed83b 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8857,6 +8857,11 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
 
 #if !defined(CONFIG_USER_ONLY)
 
+void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
+{
+    cpu->vhyp = vhyp;
+}
+
 void cpu_ppc_set_papr(PowerPCCPU *cpu)
 {
     CPUPPCState *env = &cpu->env;
@@ -10593,9 +10598,16 @@ static const TypeInfo ppc_cpu_type_info = {
     .class_init = ppc_cpu_class_init,
 };
 
+static const TypeInfo ppc_vhyp_type_info = {
+    .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(PPCVirtualHypervisorClass),
+};
+
 static void ppc_cpu_register_types(void)
 {
     type_register_static(&ppc_cpu_type_info);
+    type_register_static(&ppc_vhyp_type_info);
 }
 
 type_init(ppc_cpu_register_types)
-- 
2.9.3

  parent reply	other threads:[~2017-01-12  2:03 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-12  2:02 [Qemu-devel] [PULL 00/67] ppc-for-2.9 queue 20170112 David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 01/67] disas/ppc: Fix indefinite articles in comments David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 02/67] target-ppc: Consolidate instruction decode helpers David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 03/67] target-ppc: rename CRF_* defines as CRF_*_BIT David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 04/67] target-ppc: Fix xscmpodp and xscmpudp instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 05/67] target-ppc: Add xscmpexp[dp, qp] instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 06/67] target-ppc: Add xscmpoqp and xscmpuqp instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 07/67] target-ppc: implement lxsd and lxssp instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 08/67] target-ppc: implement stxsd and stxssp David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 09/67] target-ppc: implement lxv/lxvx and stxv/stxvx David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 10/67] target-ppc: Implement bcdcfsq. instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 11/67] target-ppc: Implement bcdctsq. instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 12/67] target-ppc: Implement bcdcpsgn. instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 13/67] target-ppc: Implement bcdsetsgn. instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 14/67] target-ppc: add vextu[bhw][lr]x instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 15/67] pseries: Always use core objects for CPU construction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 16/67] pseries: Make cpu_update during CAS unconditional David Gibson
2017-01-12  2:02 ` David Gibson [this message]
2017-01-12  2:02 ` [Qemu-devel] [PULL 18/67] ppc: Rename cpu_version to compat_pvr David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 19/67] ppc/spapr: implement H_SIGNAL_SYS_RESET David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 20/67] target-ppc: move ppc_vsr_t to common header David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 21/67] target-ppc: implement stop instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 22/67] target-ppc: implement xsabsqp/xsnabsqp instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 23/67] target-ppc: Implement bcd_is_valid function David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 24/67] target-ppc: implement xsnegqp instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 25/67] target-ppc: implement xscpsgnqp instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 26/67] target-ppc: Add xxperm and xxpermr instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 27/67] target-ppc: implement lxvl instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 28/67] target-ppc: implement lxvll instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 29/67] target-ppc: implement stxvl instruction David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 30/67] target-ppc: implement stxvll instructions David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 31/67] hw/ppc/spapr: Fix boot path of usb-host storage devices David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 32/67] prep: do not use global variable to access nvram David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 33/67] pseries: Add pseries-2.9 machine type David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 34/67] ppc: Rewrite ppc_set_compat() David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 35/67] ppc: Rewrite ppc_get_compat_smt_threads() David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 36/67] ppc: Validate compatibility modes when setting David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 37/67] qtest: add netfilter tests for ppc64 David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 38/67] qtest: add display-vga-test to ppc64 David Gibson
2017-01-12  2:02 ` [Qemu-devel] [PULL 39/67] libqos: fix spapr qpci_map() David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 40/67] qtest: convert ivshmem-test to use libqos David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 41/67] qtest: add ivshmem-test for ppc64 David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 42/67] hw/gpio: QOM'ify mpc8xxx.c David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 43/67] hw/ppc: QOM'ify e500.c David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 44/67] hw/ppc: QOM'ify ppce500_spin.c David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 45/67] hw/ppc: QOM'ify spapr_vio.c David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 46/67] target-ppc: Add xxextractuw instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 47/67] target-ppc: Add xxinsertw instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 48/67] prep: add PReP System I/O David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 49/67] prep: add IBM RS/6000 7020 (40p) memory controller David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 50/67] prep: add IBM RS/6000 7020 (40p) machine emulation David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 51/67] target-ppc: Use float64 arg in helper_compute_fprf() David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 52/67] target-ppc: Replace isden by float64_is_zero_or_denormal David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 53/67] target-ppc: Rename helper_compute_fprf to helper_compute_fprf_float64 David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 54/67] target-ppc: Add xscvdphp, xscvhpdp David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 55/67] target-ppc: Use correct precision for FPRF setting David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 56/67] target-ppc: Add xsxexpdp instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 57/67] target-ppc: Add xsxexpqp instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 58/67] target-ppc: Add xsxsigdp instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 59/67] target-ppc: Add xsxsigqp instructions David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 60/67] pxb: Restrict to x86 David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 61/67] pseries: Rewrite CAS PVR compatibility logic David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 62/67] ppc: Add ppc_set_compat_all() David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 63/67] target-ppc: Add xsaddqp instructions David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 64/67] target-ppc: Add xscvdpqp instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 65/67] target-ppc: Add xscvqpdp instruction David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 66/67] ppc: Prevent inifnite loop in decrementer auto-reload David Gibson
2017-01-12  2:03 ` [Qemu-devel] [PULL 67/67] ppc: Fix a warning in bcdcfz code and improve BCD_DIG_BYTE macro David Gibson
2017-01-12  3:42 ` [Qemu-devel] [PULL 00/67] ppc-for-2.9 queue 20170112 no-reply
2017-01-12 23:36   ` David Gibson
2017-01-13 10:54 ` Peter Maydell
2017-01-13 11:09   ` Laurent Vivier
2017-01-16 21:33   ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170112020327.24882-18-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=agraf@suse.de \
    --cc=aik@ozlabs.ru \
    --cc=lvivier@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).