| From 1a8c0482bf07557b5b5b51802e835d6ecd657764 Mon Sep 17 00:00:00 2001 |
| From: Paul Mackerras <paulus@ozlabs.org> |
| Date: Mon, 26 Aug 2019 16:21:21 +1000 |
| Subject: [PATCH] KVM: PPC: Book3S: Enable XIVE native capability only if OPAL |
| has required functions |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit 2ad7a27deaf6d78545d97ab80874584f6990360e upstream. |
| |
| There are some POWER9 machines where the OPAL firmware does not support |
| the OPAL_XIVE_GET_QUEUE_STATE and OPAL_XIVE_SET_QUEUE_STATE calls. |
| The impact of this is that a guest using XIVE natively will not be able |
| to be migrated successfully. On the source side, the get_attr operation |
| on the KVM native device for the KVM_DEV_XIVE_GRP_EQ_CONFIG attribute |
| will fail; on the destination side, the set_attr operation for the same |
| attribute will fail. |
| |
| This adds tests for the existence of the OPAL get/set queue state |
| functions, and if they are not supported, the XIVE-native KVM device |
| is not created and the KVM_CAP_PPC_IRQ_XIVE capability returns false. |
| Userspace can then either provide a software emulation of XIVE, or |
| else tell the guest that it does not have a XIVE controller available |
| to it. |
| |
| Cc: stable@vger.kernel.org # v5.2+ |
| Fixes: 3fab2d10588e ("KVM: PPC: Book3S HV: XIVE: Activate XIVE exploitation mode") |
| Reviewed-by: David Gibson <david@gibson.dropbear.id.au> |
| Reviewed-by: Cédric Le Goater <clg@kaod.org> |
| Signed-off-by: Paul Mackerras <paulus@ozlabs.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h |
| index 2484e6a8f5ca..8e8514efb124 100644 |
| --- a/arch/powerpc/include/asm/kvm_ppc.h |
| +++ b/arch/powerpc/include/asm/kvm_ppc.h |
| @@ -598,6 +598,7 @@ extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu, |
| union kvmppc_one_reg *val); |
| extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, |
| union kvmppc_one_reg *val); |
| +extern bool kvmppc_xive_native_supported(void); |
| |
| #else |
| static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server, |
| diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h |
| index e4016985764e..3b48820fd5dd 100644 |
| --- a/arch/powerpc/include/asm/xive.h |
| +++ b/arch/powerpc/include/asm/xive.h |
| @@ -127,6 +127,7 @@ extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle, |
| extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle, |
| u32 qindex); |
| extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state); |
| +extern bool xive_native_has_queue_state_support(void); |
| |
| #else |
| |
| diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c |
| index 9524d92bc45d..d7fcdfa7fee4 100644 |
| --- a/arch/powerpc/kvm/book3s.c |
| +++ b/arch/powerpc/kvm/book3s.c |
| @@ -1083,9 +1083,11 @@ static int kvmppc_book3s_init(void) |
| if (xics_on_xive()) { |
| kvmppc_xive_init_module(); |
| kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS); |
| - kvmppc_xive_native_init_module(); |
| - kvm_register_device_ops(&kvm_xive_native_ops, |
| - KVM_DEV_TYPE_XIVE); |
| + if (kvmppc_xive_native_supported()) { |
| + kvmppc_xive_native_init_module(); |
| + kvm_register_device_ops(&kvm_xive_native_ops, |
| + KVM_DEV_TYPE_XIVE); |
| + } |
| } else |
| #endif |
| kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS); |
| diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c |
| index a998823f68a3..9d613d4ae2ab 100644 |
| --- a/arch/powerpc/kvm/book3s_xive_native.c |
| +++ b/arch/powerpc/kvm/book3s_xive_native.c |
| @@ -1171,6 +1171,11 @@ int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu, union kvmppc_one_reg *val) |
| return 0; |
| } |
| |
| +bool kvmppc_xive_native_supported(void) |
| +{ |
| + return xive_native_has_queue_state_support(); |
| +} |
| + |
| static int xive_native_debug_show(struct seq_file *m, void *private) |
| { |
| struct kvmppc_xive *xive = m->private; |
| diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c |
| index 993017dd83ca..81f9dc08b674 100644 |
| --- a/arch/powerpc/kvm/powerpc.c |
| +++ b/arch/powerpc/kvm/powerpc.c |
| @@ -571,7 +571,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| * a POWER9 processor) and the PowerNV platform, as |
| * nested is not yet supported. |
| */ |
| - r = xive_enabled() && !!cpu_has_feature(CPU_FTR_HVMODE); |
| + r = xive_enabled() && !!cpu_has_feature(CPU_FTR_HVMODE) && |
| + kvmppc_xive_native_supported(); |
| break; |
| #endif |
| |
| diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c |
| index cf156aadefe9..ad8ee7dd7f57 100644 |
| --- a/arch/powerpc/sysdev/xive/native.c |
| +++ b/arch/powerpc/sysdev/xive/native.c |
| @@ -811,6 +811,13 @@ int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex) |
| } |
| EXPORT_SYMBOL_GPL(xive_native_set_queue_state); |
| |
| +bool xive_native_has_queue_state_support(void) |
| +{ |
| + return opal_check_token(OPAL_XIVE_GET_QUEUE_STATE) && |
| + opal_check_token(OPAL_XIVE_SET_QUEUE_STATE); |
| +} |
| +EXPORT_SYMBOL_GPL(xive_native_has_queue_state_support); |
| + |
| int xive_native_get_vp_state(u32 vp_id, u64 *out_state) |
| { |
| __be64 state; |
| -- |
| 2.7.4 |
| |