From: Michael Neuling <mikey@xxxxxxxxxxx> Add setting the address translation mode controlled by the AIL bits in the LPCR. Traditional untranslated mode is 0. The new mode used by Linux is 3, where exceptions will come in at 0xc000000000004000. This is set system wide hence we kick all cpus to ensure they've picked up this setting before returning. This also adds a kvmppc_power8_compatible() function to test to see if a guest is compatible with POWER8 or not. Note that interrupts synthesized by KVM are still delivered with relocation off to the vectors starting at 0. Modified by paulus to use kvmppc_update_lpcr(). Signed-off-by: Michael Neuling <mikey@xxxxxxxxxxx> Signed-off-by: Paul Mackerras <paulus@xxxxxxxxx> --- arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/kvm/book3s_hv.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index e86b008..bf57326 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -301,6 +301,7 @@ #define LPCR_RMLS_SH (63-37) #define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */ #define LPCR_AIL 0x01800000 /* Alternate interrupt location */ +#define LPCR_AIL_SH (63-40) #define LPCR_AIL_0 0x00000000 /* MMU off exception offset 0x0 */ #define LPCR_AIL_3 0x01800000 /* MMU on exception offset 0xc00...4xxx */ #define LPCR_ONL 0x00040000 /* online - PURR/SPURR count */ diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 2473400..0c309d9 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -549,6 +549,16 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu, vcpu->arch.dtl.dirty = true; } +static bool kvmppc_power8_compatible(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.vcore->arch_compat >= PVR_ARCH_207) + return true; + if ((!vcpu->arch.vcore->arch_compat) && + cpu_has_feature(CPU_FTR_ARCH_207S)) + return true; + return false; +} + static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, unsigned long resource, unsigned long value1, unsigned long value2) @@ -558,6 +568,26 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, int n; switch (resource) { + case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE: + if (!kvmppc_power8_compatible(vcpu)) + return H_P2; + if (value1) + return H_P3; + if (value2) + return H_P4; + switch (mflags) { + case 0: + case 2: + case 3: + mutex_lock(&kvm->lock); + kvmppc_update_lpcr(kvm, mflags << LPCR_AIL_SH, + LPCR_AIL); + mutex_unlock(&kvm->lock); + kick_all_cpus_sync(); + return H_SUCCESS; + default: + return H_UNSUPPORTED_FLAG_START; + } case H_SET_MODE_RESOURCE_LE: if (value1) return H_P3; -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html