target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL
The H_REGISTER_PROCESS_TABLE H_CALL is used by a guest to indicate to the
hypervisor where in memory its process table is and how translation should
be performed using this process table.
Provide the implementation of this H_CALL for a guest.
We first check for invalid flags, then parse the flags to determine the
operation, and then check the other parameters for valid values based on
the operation (register new table/deregister table/maintain registration).
The process table is then stored in the appropriate location and registered
with the hypervisor (if running under KVM), and the LPCR_[UPRT/GTSE] bits
are updated as required.
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
[dwg: Correct missing prototype and uninitialized variable]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 38db27b..c959b90 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -362,6 +362,37 @@
return radix_page_info;
}
+target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
+ bool radix, bool gtse,
+ uint64_t proc_tbl)
+{
+ CPUState *cs = CPU(cpu);
+ int ret;
+ uint64_t flags = 0;
+ struct kvm_ppc_mmuv3_cfg cfg = {
+ .process_table = proc_tbl,
+ };
+
+ if (radix) {
+ flags |= KVM_PPC_MMUV3_RADIX;
+ }
+ if (gtse) {
+ flags |= KVM_PPC_MMUV3_GTSE;
+ }
+ cfg.flags = flags;
+ ret = kvm_vm_ioctl(cs->kvm_state, KVM_PPC_CONFIGURE_V3_MMU, &cfg);
+ switch (ret) {
+ case 0:
+ return H_SUCCESS;
+ case -EINVAL:
+ return H_PARAMETER;
+ case -ENODEV:
+ return H_NOT_AVAILABLE;
+ default:
+ return H_HARDWARE;
+ }
+}
+
static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
{
if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) {