mirror of
https://github.com/qemu/qemu.git
synced 2024-12-12 05:03:42 +08:00
spapr: Move PAPR mode cpu setup fully to spapr code
cpu_ppc_set_papr() does several things: 1) it sets up the virtual hypervisor interface 2) it prevents the cpu from ever entering hypervisor mode 3) it tells KVM that we're emulating a cpu in PAPR mode and 4) it configures the LPCR and AMOR (hypervisor privileged registers) so that TCG will behave correctly for PAPR guests, without attempting to emulate the cpu in hypervisor mode (1) & (2) make sense for any virtual hypervisor (if another one ever exists). (3) belongs more properly in the machine type specific to a PAPR guest, so move it to spapr_cpu_init(). While we're at it, remove an ugly test on kvm_enabled() by making kvmppc_set_papr() a safe no-op on non-KVM. (4) also belongs more properly in the machine type specific code. (4) is done by mangling the default values of the SPRs, so that they will be set correctly at reset time. Manipulating usually-static parameters of the cpu model like this is kind of ugly, especially since the values used really have more to do with the platform than the cpu. The spapr code already has places for PAPR specific initializations of register state in spapr_cpu_reset(), so move this handling there. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Tested-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
f00bed9521
commit
da20aed12a
@ -28,6 +28,7 @@ static void spapr_cpu_reset(void *opaque)
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
target_ulong lpcr;
|
||||
|
||||
cpu_reset(cs);
|
||||
|
||||
@ -43,13 +44,42 @@ static void spapr_cpu_reset(void *opaque)
|
||||
|
||||
env->spr[SPR_HIOR] = 0;
|
||||
|
||||
lpcr = env->spr[SPR_LPCR];
|
||||
|
||||
/* Set emulated LPCR to not send interrupts to hypervisor. Note that
|
||||
* under KVM, the actual HW LPCR will be set differently by KVM itself,
|
||||
* the settings below ensure proper operations with TCG in absence of
|
||||
* a real hypervisor.
|
||||
*
|
||||
* Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
|
||||
* real mode accesses, which thankfully defaults to 0 and isn't
|
||||
* accessible in guest mode.
|
||||
*/
|
||||
lpcr &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
|
||||
lpcr |= LPCR_LPES0 | LPCR_LPES1;
|
||||
|
||||
/* Set RMLS to the max (ie, 16G) */
|
||||
lpcr &= ~LPCR_RMLS;
|
||||
lpcr |= 1ull << LPCR_RMLS_SHIFT;
|
||||
|
||||
/* Only enable Power-saving mode Exit Cause exceptions on the boot
|
||||
* CPU. The RTAS command start-cpu will enable them on secondaries.
|
||||
*/
|
||||
if (cs == first_cpu) {
|
||||
lpcr |= pcc->lpcr_pm;
|
||||
}
|
||||
|
||||
/* Disable Power-saving mode Exit Cause exceptions for the CPU.
|
||||
* This can cause issues when rebooting the guest if a secondary
|
||||
* is awaken */
|
||||
if (cs != first_cpu) {
|
||||
env->spr[SPR_LPCR] &= ~pcc->lpcr_pm;
|
||||
lpcr &= ~pcc->lpcr_pm;
|
||||
}
|
||||
|
||||
ppc_store_lpcr(cpu, lpcr);
|
||||
|
||||
/* Set a full AMOR so guest can use the AMR as it sees fit */
|
||||
env->spr[SPR_AMOR] = 0xffffffffffffffffull;
|
||||
}
|
||||
|
||||
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3)
|
||||
@ -74,8 +104,8 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
||||
/* Set time-base frequency to 512 MHz */
|
||||
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
|
||||
|
||||
/* Enable PAPR mode in TCG or KVM */
|
||||
cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
|
||||
cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
|
||||
kvmppc_set_papr(cpu);
|
||||
|
||||
qemu_register_reset(spapr_cpu_reset, cpu);
|
||||
spapr_cpu_reset(cpu);
|
||||
|
@ -1332,7 +1332,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_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp);
|
||||
void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -2088,6 +2088,10 @@ void kvmppc_set_papr(PowerPCCPU *cpu)
|
||||
CPUState *cs = CPU(cpu);
|
||||
int ret;
|
||||
|
||||
if (!kvm_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_PAPR, 0);
|
||||
if (ret) {
|
||||
error_report("This vCPU type or KVM version does not support PAPR");
|
||||
|
@ -8882,13 +8882,9 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void cpu_ppc_set_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
|
||||
void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
|
||||
{
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
|
||||
ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
cpu->vhyp = vhyp;
|
||||
|
||||
@ -8897,42 +8893,6 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
|
||||
* hypervisor mode itself
|
||||
*/
|
||||
env->msr_mask &= ~MSR_HVB;
|
||||
|
||||
/* Set emulated LPCR to not send interrupts to hypervisor. Note that
|
||||
* under KVM, the actual HW LPCR will be set differently by KVM itself,
|
||||
* the settings below ensure proper operations with TCG in absence of
|
||||
* a real hypervisor.
|
||||
*
|
||||
* Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
|
||||
* real mode accesses, which thankfully defaults to 0 and isn't
|
||||
* accessible in guest mode.
|
||||
*/
|
||||
lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
|
||||
lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
|
||||
|
||||
/* Set RMLS to the max (ie, 16G) */
|
||||
lpcr->default_value &= ~LPCR_RMLS;
|
||||
lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
|
||||
|
||||
/* Only enable Power-saving mode Exit Cause exceptions on the boot
|
||||
* CPU. The RTAS command start-cpu will enable them on secondaries.
|
||||
*/
|
||||
if (cs == first_cpu) {
|
||||
lpcr->default_value |= pcc->lpcr_pm;
|
||||
}
|
||||
|
||||
/* We should be followed by a CPU reset but update the active value
|
||||
* just in case...
|
||||
*/
|
||||
ppc_store_lpcr(cpu, lpcr->default_value);
|
||||
|
||||
/* Set a full AMOR so guest can use the AMR as it sees fit */
|
||||
env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
|
||||
|
||||
/* Tell KVM that we're in PAPR mode */
|
||||
if (kvm_enabled()) {
|
||||
kvmppc_set_papr(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||
|
Loading…
Reference in New Issue
Block a user