summaryrefslogtreecommitdiffstats
path: root/hw/ppc
diff options
context:
space:
mode:
authorSuraj Jitindar Singh2017-03-01 07:54:36 +0100
committerDavid Gibson2017-03-03 01:30:59 +0100
commit9861bb3efd2a4def622cd40afb58af61542c4458 (patch)
tree57bfc014d65605bac4631c92a49cc0917ab6d2c6 /hw/ppc
parenttarget/ppc/POWER9: Add POWERPC_MMU_V3 bit (diff)
downloadqemu-9861bb3efd2a4def622cd40afb58af61542c4458.tar.gz
qemu-9861bb3efd2a4def622cd40afb58af61542c4458.tar.xz
qemu-9861bb3efd2a4def622cd40afb58af61542c4458.zip
target/ppc: Add patb_entry to sPAPRMachineState
ISA v3.00 adds the idea of a partition table which is used to store the address translation details for all partitions on the system. The partition table consists of double word entries indexed by partition id where the second double word contains the location of the process table in guest memory. The process table is registered by the guest via a h-call. We need somewhere to store the address of the process table so we add an entry to the sPAPRMachineState struct called patb_entry to represent the second doubleword of a single partition table entry corresponding to the current guest. We need to store this value so we know if the guest is using radix or hash translation and the location of the corresponding process table in guest memory. Since we only have a single guest per qemu instance, we only need one entry. Since the partition table is technically a hypervisor resource we require that access to it is abstracted by the virtual hypervisor through the get_patbe() call. Currently the value of the entry is never set (and thus defaults to 0 indicating hash), but it will be required to both implement POWER9 kvm support and tcg radix support. We also add this field to be migrated as part of the sPAPRMachineState as we will need it on the receiving side as the guest will never tell us this information again and we need it to perform translation. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc')
-rw-r--r--hw/ppc/spapr.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 81c6c1c27c..1cc5e008d7 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1055,6 +1055,13 @@ static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp,
}
}
+static uint64_t spapr_get_patbe(PPCVirtualHypervisor *vhyp)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+ return spapr->patb_entry;
+}
+
#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2))
#define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID)
#define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY)
@@ -1234,6 +1241,8 @@ static void ppc_spapr_reset(void)
/* Check for unknown sysbus devices */
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
+ spapr->patb_entry = 0;
+
/* Allocate and/or reset the hash page table */
spapr_reallocate_hpt(spapr,
spapr_hpt_shift_for_ramsize(machine->maxram_size),
@@ -1427,6 +1436,24 @@ static const VMStateDescription vmstate_spapr_ov5_cas = {
},
};
+static bool spapr_patb_entry_needed(void *opaque)
+{
+ sPAPRMachineState *spapr = opaque;
+
+ return !!spapr->patb_entry;
+}
+
+static const VMStateDescription vmstate_spapr_patb_entry = {
+ .name = "spapr_patb_entry",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = spapr_patb_entry_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(patb_entry, sPAPRMachineState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_spapr = {
.name = "spapr",
.version_id = 3,
@@ -1444,6 +1471,7 @@ static const VMStateDescription vmstate_spapr = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_spapr_ov5_cas,
+ &vmstate_spapr_patb_entry,
NULL
}
};
@@ -3049,6 +3077,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
vhc->map_hptes = spapr_map_hptes;
vhc->unmap_hptes = spapr_unmap_hptes;
vhc->store_hpte = spapr_store_hpte;
+ vhc->get_patbe = spapr_get_patbe;
xic->ics_get = spapr_ics_get;
xic->ics_resend = spapr_ics_resend;
xic->icp_get = spapr_icp_get;