Version v3.00 of the ISA added a new compat level to the processor
compatibility register (PCR), an ISA v2.07 compatibility mode.
Upstream QEMU already supports this so it may as well go into the kernel
now.
Suraj Jitindar Singh (2):
powerpc: Define new ISA v3.00 logical PVR value and PCR register value
powerpc/kvm: Update kvmppc_set_arch_compat() for ISA v3.00
arch/powerpc/include/asm/reg.h | 2 ++
arch/powerpc/kvm/book3s_hv.c | 30 ++++++++++++++++++++++--------
2 files changed, 24 insertions(+), 8 deletions(-)
--
2.5.5
ISA 3.00 adds the logical PVR value 0x0f000005, so add a definition for
this.
Define PCR_ARCH_207 to reflect ISA 2.07 compatibility mode in the processor
compatibility register (PCR).
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
arch/powerpc/include/asm/reg.h | 2 ++
1 file changed, 2 insertions(+)
The function kvmppc_set_arch_compat() is used to determine the value of the
processor compatibility register (PCR) for a guest running in a given
compatibility mode. There is currently no support for v3.00 of the ISA.
Add support for v3.00 of the ISA which adds an ISA v2.07 compatilibity mode
to the PCR.
We also add a check to ensure the processor we are running on is capable of
emulating the chosen processor (for example a POWER7 cannot emulate a
POWER8, similarly with a POWER8 and a POWER9).
Finally the PCR value is masked based on the bits of the register which the
current processor is actually aware of.
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
arch/powerpc/kvm/book3s_hv.c | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
@@ -311,24 +311,38 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)*IfanarchbitissetinPCR,allthedefined*higher-orderarchbitsalsohavetobeset.*/-pcr=PCR_ARCH_206|PCR_ARCH_205;+pcr=PCR_ARCH_207|PCR_ARCH_206|PCR_ARCH_205;break;casePVR_ARCH_206:casePVR_ARCH_206p:-pcr=PCR_ARCH_206;+/* Must be at least v2.06 to emulate it */+if(!cpu_has_feature(CPU_FTR_ARCH_206))+return-EINVAL;+pcr=PCR_ARCH_207|PCR_ARCH_206;break;casePVR_ARCH_207:+/* Must be at least v2.07 to emulate it */+if(!cpu_has_feature(CPU_FTR_ARCH_207S))+return-EINVAL;+pcr=PCR_ARCH_207;break;+casePVR_ARCH_300:+/* Must be at least v3.00 to emulate it */+if(!cpu_has_feature(CPU_FTR_ARCH_300))+return-EINVAL;default:return-EINVAL;}-if(!cpu_has_feature(CPU_FTR_ARCH_207S)){-/* POWER7 can't emulate POWER8 */-if(!(pcr&PCR_ARCH_206))-return-EINVAL;-pcr&=~PCR_ARCH_206;-}+/*+*Maskthepcrbitswhichthecurrentprocessorknowsabout+*v2.06andaboveknowsaboutthev2.05compatbit+*v2,07andaboveknowsaboutthev2.06compatbit+*v3.00andaboveknowsaboutthev2.07compatbit+*/+pcr&=(cpu_has_feature(CPU_FTR_ARCH_300)<<3)|+(cpu_has_feature(CPU_FTR_ARCH_207S)<<2)|+(cpu_has_feature(CPU_FTR_ARCH_206)<<1);}spin_lock(&vc->lock);
@@ -311,24 +311,38 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)*IfanarchbitissetinPCR,allthedefined*higher-orderarchbitsalsohavetobeset.*/-pcr=PCR_ARCH_206|PCR_ARCH_205;+pcr=PCR_ARCH_207|PCR_ARCH_206|PCR_ARCH_205;break;casePVR_ARCH_206:casePVR_ARCH_206p:-pcr=PCR_ARCH_206;+/* Must be at least v2.06 to emulate it */+if(!cpu_has_feature(CPU_FTR_ARCH_206))+return-EINVAL;+pcr=PCR_ARCH_207|PCR_ARCH_206;break;casePVR_ARCH_207:+/* Must be at least v2.07 to emulate it */+if(!cpu_has_feature(CPU_FTR_ARCH_207S))+return-EINVAL;+pcr=PCR_ARCH_207;break;+casePVR_ARCH_300:+/* Must be at least v3.00 to emulate it */+if(!cpu_has_feature(CPU_FTR_ARCH_300))+return-EINVAL;default:return-EINVAL;}-if(!cpu_has_feature(CPU_FTR_ARCH_207S)){-/* POWER7 can't emulate POWER8 */-if(!(pcr&PCR_ARCH_206))-return-EINVAL;-pcr&=~PCR_ARCH_206;-}+/*+*Maskthepcrbitswhichthecurrentprocessorknowsabout+*v2.06andaboveknowsaboutthev2.05compatbit+*v2,07andaboveknowsaboutthev2.06compatbit+*v3.00andaboveknowsaboutthev2.07compatbit+*/+pcr&=(cpu_has_feature(CPU_FTR_ARCH_300)<<3)|+(cpu_has_feature(CPU_FTR_ARCH_207S)<<2)|+(cpu_has_feature(CPU_FTR_ARCH_206)<<1);
cpu_has_feature() returns a bool, so shifting the result of it is
dubious. It also uses jump labels these days, so I have no idea what
code that is going to generate.
Better to just do it the simple way IMHO.
cheers