KVM: PPC: Book3S HV: Don't access HFSCR, LPIDR or LPCR when running nested
When running as a nested hypervisor, this avoids reading hypervisor privileged registers (specifically HFSCR, LPIDR and LPCR) at startup; instead reasonable default values are used. This also avoids writing LPIDR in the single-vcpu entry/exit path. Also, this removes the check for CPU_FTR_HVMODE in kvmppc_mmu_hv_init() since its only caller already checks this. Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
9d0b048da7
commit
f3c99f97a3
@ -268,14 +268,13 @@ int kvmppc_mmu_hv_init(void)
|
|||||||
{
|
{
|
||||||
unsigned long host_lpid, rsvd_lpid;
|
unsigned long host_lpid, rsvd_lpid;
|
||||||
|
|
||||||
if (!cpu_has_feature(CPU_FTR_HVMODE))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
|
if (!mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* POWER7 has 10-bit LPIDs (12-bit in POWER8) */
|
/* POWER7 has 10-bit LPIDs (12-bit in POWER8) */
|
||||||
host_lpid = mfspr(SPRN_LPID);
|
host_lpid = 0;
|
||||||
|
if (cpu_has_feature(CPU_FTR_HVMODE))
|
||||||
|
host_lpid = mfspr(SPRN_LPID);
|
||||||
rsvd_lpid = LPID_RSVD;
|
rsvd_lpid = LPID_RSVD;
|
||||||
|
|
||||||
kvmppc_init_lpid(rsvd_lpid + 1);
|
kvmppc_init_lpid(rsvd_lpid + 1);
|
||||||
|
@ -2174,15 +2174,18 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm,
|
|||||||
* Set the default HFSCR for the guest from the host value.
|
* Set the default HFSCR for the guest from the host value.
|
||||||
* This value is only used on POWER9.
|
* This value is only used on POWER9.
|
||||||
* On POWER9, we want to virtualize the doorbell facility, so we
|
* On POWER9, we want to virtualize the doorbell facility, so we
|
||||||
* turn off the HFSCR bit, which causes those instructions to trap.
|
* don't set the HFSCR_MSGP bit, and that causes those instructions
|
||||||
|
* to trap and then we emulate them.
|
||||||
*/
|
*/
|
||||||
vcpu->arch.hfscr = mfspr(SPRN_HFSCR);
|
vcpu->arch.hfscr = HFSCR_TAR | HFSCR_EBB | HFSCR_PM | HFSCR_BHRB |
|
||||||
if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST))
|
HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP;
|
||||||
|
if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
||||||
|
vcpu->arch.hfscr &= mfspr(SPRN_HFSCR);
|
||||||
|
if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST))
|
||||||
|
vcpu->arch.hfscr |= HFSCR_TM;
|
||||||
|
}
|
||||||
|
if (cpu_has_feature(CPU_FTR_TM_COMP))
|
||||||
vcpu->arch.hfscr |= HFSCR_TM;
|
vcpu->arch.hfscr |= HFSCR_TM;
|
||||||
else if (!cpu_has_feature(CPU_FTR_TM_COMP))
|
|
||||||
vcpu->arch.hfscr &= ~HFSCR_TM;
|
|
||||||
if (cpu_has_feature(CPU_FTR_ARCH_300))
|
|
||||||
vcpu->arch.hfscr &= ~HFSCR_MSGP;
|
|
||||||
|
|
||||||
kvmppc_mmu_book3s_hv_init(vcpu);
|
kvmppc_mmu_book3s_hv_init(vcpu);
|
||||||
|
|
||||||
@ -4006,8 +4009,10 @@ int kvmhv_run_single_vcpu(struct kvm_run *kvm_run,
|
|||||||
|
|
||||||
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
||||||
|
|
||||||
mtspr(SPRN_LPID, kvm->arch.host_lpid);
|
if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
||||||
isync();
|
mtspr(SPRN_LPID, kvm->arch.host_lpid);
|
||||||
|
isync();
|
||||||
|
}
|
||||||
|
|
||||||
trace_hardirqs_off();
|
trace_hardirqs_off();
|
||||||
set_irq_happened(trap);
|
set_irq_happened(trap);
|
||||||
@ -4634,9 +4639,13 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
|
|||||||
kvm->arch.host_sdr1 = mfspr(SPRN_SDR1);
|
kvm->arch.host_sdr1 = mfspr(SPRN_SDR1);
|
||||||
|
|
||||||
/* Init LPCR for virtual RMA mode */
|
/* Init LPCR for virtual RMA mode */
|
||||||
kvm->arch.host_lpid = mfspr(SPRN_LPID);
|
if (cpu_has_feature(CPU_FTR_HVMODE)) {
|
||||||
kvm->arch.host_lpcr = lpcr = mfspr(SPRN_LPCR);
|
kvm->arch.host_lpid = mfspr(SPRN_LPID);
|
||||||
lpcr &= LPCR_PECE | LPCR_LPES;
|
kvm->arch.host_lpcr = lpcr = mfspr(SPRN_LPCR);
|
||||||
|
lpcr &= LPCR_PECE | LPCR_LPES;
|
||||||
|
} else {
|
||||||
|
lpcr = 0;
|
||||||
|
}
|
||||||
lpcr |= (4UL << LPCR_DPFD_SH) | LPCR_HDICE |
|
lpcr |= (4UL << LPCR_DPFD_SH) | LPCR_HDICE |
|
||||||
LPCR_VPM0 | LPCR_VPM1;
|
LPCR_VPM0 | LPCR_VPM1;
|
||||||
kvm->arch.vrma_slb_v = SLB_VSID_B_1T |
|
kvm->arch.vrma_slb_v = SLB_VSID_B_1T |
|
||||||
|
Loading…
Reference in New Issue
Block a user