@@ -554,6 +554,19 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
pcc->radix_page_info->count *
sizeof(radix_AP_encodings[0]))));
}
+
+ /*
+ * We set this property to let the guest know that it can use the large
+ * decrementer and its width in bits. This means we must be on a processor
+ * with a large decrementer and the hypervisor must support it. In TCG the
+ * large decrementer is always supported, in KVM we check the hypervisor
+ * capability.
+ */
+ if (pcc->large_decr_bits && ((!kvm_enabled()) ||
+ kvmppc_has_cap_large_decr())) {
+ _FDT((fdt_setprop_u32(fdt, offset, "ibm,dec-bits",
+ pcc->large_decr_bits)));
+ }
}
static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
@@ -1328,6 +1341,11 @@ static void ppc_spapr_reset(void)
spapr_setup_hpt_and_vrma(spapr);
}
+ /* We have to do this after vcpus are created since it calls ioctls */
+ if (kvm_enabled()) {
+ kvmppc_check_cap_large_decr();
+ }
+
qemu_devices_reset();
/*
@@ -1091,6 +1091,37 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, target_ulong *addr,
return best_compat;
}
+static void cas_enable_large_decr(PowerPCCPU *cpu, sPAPRMachineState *spapr)
+{
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ bool guest_large_decr = false;
+
+ if (cpu->compat_pvr) {
+ guest_large_decr = cpu->compat_pvr >= CPU_POWERPC_LOGICAL_3_00;
+ } else {
+ guest_large_decr = (cpu->env.spr[SPR_PVR] & CPU_POWERPC_POWER_SERVER_MASK)
+ >= CPU_POWERPC_POWER9_BASE;
+ }
+
+ if (guest_large_decr && ((!kvm_enabled()) ||
+ kvmppc_has_cap_large_decr())) {
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ if (kvm_enabled()) {
+ kvmppc_configure_large_decrementer(cs, true);
+ } else {
+ set_spr(cs, SPR_LPCR, LPCR_LD, LPCR_LD);
+ }
+ }
+
+ spapr->large_decr_bits = pcc->large_decr_bits;
+ } else {
+ /* By default the large decrementer is already disabled */
+ spapr->large_decr_bits = 0;
+ }
+}
+
static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
target_ulong opcode,
@@ -1166,6 +1197,9 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
}
spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
OV1_PPC_3_00);
+
+ cas_enable_large_decr(cpu, spapr);
+
if (!spapr->cas_reboot) {
spapr->cas_reboot =
(spapr_h_cas_compose_response(spapr, args[1], args[2],
Let the guest use the large decrementer. We have support for TCG and KVM guests to use the large decrementer and to migrate guests using the large decrementer, so add the final bits to indicate this capability to the guest. The guest will use the large decrementer if the cpu model is >= POWER9 and the ibm,dec-bits device-tree property of the cpu node is present. Add the ibm,dec-bits property to the device-tree when the hypervisor can support it. After CAS enable the large decrementer if the guest is going to use it, this means setting the LPCR_LD bit. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> --- hw/ppc/spapr.c | 18 ++++++++++++++++++ hw/ppc/spapr_hcall.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)