From b4db54132ffeadafa9516cc553ba9548e42d42ad Mon Sep 17 00:00:00 2001 From: Suraj Jitindar Singh Date: Mon, 20 Mar 2017 10:46:46 +1100 Subject: 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 Signed-off-by: Sam Bobroff [dwg: Correct missing prototype and uninitialized variable] Signed-off-by: David Gibson --- target/ppc/kvm.c | 31 +++++++++++++++++++++++++++++++ target/ppc/kvm_ppc.h | 10 ++++++++++ 2 files changed, 41 insertions(+) (limited to 'target') 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 @@ struct ppc_radix_page_info *kvm_get_radix_page_info(void) 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)) { diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 64189a4..4b2fd9a 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -33,6 +33,9 @@ int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits); int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits); int kvmppc_set_tcr(PowerPCCPU *cpu); int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu); +target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, + bool radix, bool gtse, + uint64_t proc_tbl); #ifndef CONFIG_USER_ONLY off_t kvmppc_alloc_rma(void **rma); bool kvmppc_spapr_use_multitce(void); @@ -159,6 +162,13 @@ static inline int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu) return -1; } +static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, + bool radix, bool gtse, + uint64_t proc_tbl) +{ + return 0; +} + #ifndef CONFIG_USER_ONLY static inline off_t kvmppc_alloc_rma(void **rma) { -- cgit v1.1